fp: Make transported entities adopt the new mob spawner waypoints
This commit is contained in:
parent
22439814a8
commit
a064dc6d09
@ -327,10 +327,6 @@ NamespaceIndentation: None
|
|||||||
PackConstructorInitializers: CurrentLine
|
PackConstructorInitializers: CurrentLine
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
|
||||||
# Different ways to arrange specifiers and qualifiers (e.g. const/volatile).
|
|
||||||
QualifierAlignment: Custom
|
|
||||||
QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile']
|
|
||||||
|
|
||||||
# false:
|
# false:
|
||||||
# // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
|
# // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
|
||||||
# /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
|
# /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
|
||||||
|
@ -588,6 +588,37 @@ FP_GetClosestPortalMonkeyResult FP_GetClosestPortalMonkey(FP_Game *game, FP_Game
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FP_AppendMobSpawnerWaypoints(FP_Game *game, FP_GameEntityHandle src_handle, FP_GameEntityHandle dest_handle)
|
||||||
|
{
|
||||||
|
FP_GameEntity *src = FP_Game_GetEntity(game, src_handle);
|
||||||
|
FP_GameEntity *dest = FP_Game_GetEntity(game, dest_handle);
|
||||||
|
if (FP_Game_IsNilEntity(src) || FP_Game_IsNilEntity(dest))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Dqn_f32 one_meter = FP_Game_MetersToPixelsNx1(game->play, 1.f);
|
||||||
|
for (FP_GameEntity *waypoint_entity = src->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
|
||||||
|
if ((waypoint_entity->flags & FP_GameEntityFlag_MobSpawnerWaypoint) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// NOTE: Add the waypoint
|
||||||
|
FP_SentinelListLink<FP_GameWaypoint> *waypoint = FP_SentinelList_Make(&dest->waypoints, game->play.chunk_pool);
|
||||||
|
waypoint->data.entity = waypoint_entity->handle;
|
||||||
|
waypoint->data.arrive = FP_GameWaypointArrive_WhenWithinEntitySize;
|
||||||
|
waypoint->data.value = 1.5f;
|
||||||
|
|
||||||
|
uint32_t min_vary = DQN_CAST(uint32_t)(one_meter * .5f);
|
||||||
|
uint32_t max_vary = DQN_CAST(uint32_t)(one_meter * 2.f);
|
||||||
|
waypoint->data.offset += Dqn_V2_InitNx2(DQN_CAST(Dqn_f32) Dqn_PCG32_Range(&game->play.rng, min_vary, max_vary),
|
||||||
|
DQN_CAST(Dqn_f32) Dqn_PCG32_Range(&game->play.rng, min_vary, max_vary));
|
||||||
|
|
||||||
|
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
|
||||||
|
waypoint->data.offset.x *= -1;
|
||||||
|
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
|
||||||
|
waypoint->data.offset.y *= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
|
void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_PlatformInput *input, FP_GameEntity *entity, Dqn_V2 *acceleration_meters_per_s)
|
||||||
{
|
{
|
||||||
TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet;
|
TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet;
|
||||||
@ -1119,10 +1150,12 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
entity->building_patron = {};
|
entity->building_patron = {};
|
||||||
|
|
||||||
// NOTE: Add a waypoint for the plane to the mob spawn
|
// NOTE: Add a waypoint for the plane to the mob spawn
|
||||||
|
FP_GameEntityHandle mob_spawner = {};
|
||||||
|
Dqn_V2 mob_spawner_pos = {};
|
||||||
{
|
{
|
||||||
uint32_t mob_spawner_index = Dqn_PCG32_Range(&game->play.rng, 0, DQN_CAST(uint32_t)game->play.mob_spawners.size);
|
uint32_t mob_spawner_index = Dqn_PCG32_Range(&game->play.rng, 0, DQN_CAST(uint32_t)game->play.mob_spawners.size);
|
||||||
FP_GameEntityHandle mob_spawner = game->play.mob_spawners.data[mob_spawner_index];
|
mob_spawner = game->play.mob_spawners.data[mob_spawner_index];
|
||||||
Dqn_V2 target_pos = FP_Game_CalcEntityWorldPos(game, mob_spawner);
|
mob_spawner_pos = FP_Game_CalcEntityWorldPos(game, mob_spawner);
|
||||||
plane->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->play.chunk_pool);
|
plane->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->play.chunk_pool);
|
||||||
FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&plane->waypoints,
|
FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&plane->waypoints,
|
||||||
FP_SentinelList_Front(&plane->waypoints),
|
FP_SentinelList_Front(&plane->waypoints),
|
||||||
@ -1132,6 +1165,11 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
|||||||
waypoint->type = FP_GameWaypointType_ClosestSide;
|
waypoint->type = FP_GameWaypointType_ClosestSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Update the mob's waypoints to the mob spawner waypoints
|
||||||
|
FP_GameEntity *patron = FP_Game_GetEntity(game, plane->building_patron);
|
||||||
|
FP_SentinelList_Clear(&patron->waypoints, game->play.chunk_pool);
|
||||||
|
|
||||||
|
FP_AppendMobSpawnerWaypoints(game, entity->handle, plane->building_patron);
|
||||||
FP_Game_EntityTransitionState(game, entity, FP_EntityAirportTerryState_Idle);
|
FP_Game_EntityTransitionState(game, entity, FP_EntityAirportTerryState_Idle);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1876,14 +1914,13 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
// NOTE: Remove them from the queue
|
// NOTE: Remove them from the queue
|
||||||
Dqn_FArray_EraseRange(&waypoint_entity->building_queue, 0 /*index*/, 1 /*count*/, Dqn_ArrayErase_Stable);
|
Dqn_FArray_EraseRange(&waypoint_entity->building_queue, 0 /*index*/, 1 /*count*/, Dqn_ArrayErase_Stable);
|
||||||
|
|
||||||
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, building->handle);
|
Dqn_Rect building_hit_box = FP_Game_CalcEntityWorldHitBox(game, building->handle);
|
||||||
Dqn_V2 exit_pos = Dqn_Rect_InterpolatedPoint(hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
|
Dqn_V2 exit_pos = Dqn_Rect_InterpolatedPoint(building_hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
|
||||||
if (building->type == FP_EntityType_ClubTerry) {
|
if (building->type == FP_EntityType_ClubTerry) {
|
||||||
FP_Game_EntityTransitionState(game, building, FP_EntityClubTerryState_PartyTime);
|
FP_Game_EntityTransitionState(game, building, FP_EntityClubTerryState_PartyTime);
|
||||||
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
|
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
|
||||||
} else if (building->type == FP_EntityType_AirportTerry) {
|
} else if (building->type == FP_EntityType_AirportTerry) {
|
||||||
FP_Game_EntityTransitionState(game, building, FP_EntityAirportTerryState_FlyPassenger);
|
FP_Game_EntityTransitionState(game, building, FP_EntityAirportTerryState_FlyPassenger);
|
||||||
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
|
|
||||||
} else {
|
} else {
|
||||||
DQN_ASSERT(building->type == FP_EntityType_ChurchTerry);
|
DQN_ASSERT(building->type == FP_EntityType_ChurchTerry);
|
||||||
FP_Game_EntityTransitionState(game, building, FP_EntityChurchTerryState_ConvertPatron);
|
FP_Game_EntityTransitionState(game, building, FP_EntityChurchTerryState_ConvertPatron);
|
||||||
@ -2130,13 +2167,11 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
entity->next_spawn_timestamp_s = DQN_CAST(uint64_t)(input->timer_s + 2.5f);
|
entity->next_spawn_timestamp_s = DQN_CAST(uint64_t)(input->timer_s + 2.5f);
|
||||||
|
|
||||||
FP_SentinelListLink<FP_GameEntityHandle> *link = FP_SentinelList_Make(&entity->spawn_list, game->play.chunk_pool);
|
FP_SentinelListLink<FP_GameEntityHandle> *link = FP_SentinelList_Make(&entity->spawn_list, game->play.chunk_pool);
|
||||||
|
|
||||||
Dqn_f32 one_meter = FP_Game_MetersToPixelsNx1(game->play, 1.f);
|
|
||||||
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(game, entity->handle);
|
||||||
Dqn_Rect entity_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
|
Dqn_Rect entity_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
|
||||||
|
|
||||||
Dqn_f32 step_y = (entity_hit_box.size.h / spawn_count) * 1.5f;
|
Dqn_f32 step_y = (entity_hit_box.size.h / spawn_count) * 1.5f;
|
||||||
Dqn_f32 mob_y_offset = (Dqn_PCG32_NextF32(&game->play.rng) * step_y) + (step_y * spawn_index);
|
Dqn_f32 mob_y_offset = (Dqn_PCG32_NextF32(&game->play.rng) * step_y) + (step_y * spawn_index);
|
||||||
|
|
||||||
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
|
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
|
||||||
mob_y_offset *= -1;
|
mob_y_offset *= -1;
|
||||||
|
|
||||||
@ -2157,31 +2192,12 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
|||||||
mob->hp_cap *= hp_adjustment;
|
mob->hp_cap *= hp_adjustment;
|
||||||
mob->hp = mob->hp_cap;
|
mob->hp = mob->hp_cap;
|
||||||
|
|
||||||
for (FP_GameEntity *waypoint_entity = entity->first_child; waypoint_entity; waypoint_entity = waypoint_entity->next) {
|
FP_AppendMobSpawnerWaypoints(game, entity->handle, mob->handle);
|
||||||
if ((waypoint_entity->flags & FP_GameEntityFlag_MobSpawnerWaypoint) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// NOTE: Add the waypoint
|
|
||||||
FP_SentinelListLink<FP_GameWaypoint> *waypoint = FP_SentinelList_Make(&mob->waypoints, game->play.chunk_pool);
|
|
||||||
waypoint->data.entity = waypoint_entity->handle;
|
|
||||||
waypoint->data.arrive = FP_GameWaypointArrive_WhenWithinEntitySize;
|
|
||||||
waypoint->data.value = 1.5f;
|
|
||||||
|
|
||||||
uint32_t min_vary = DQN_CAST(uint32_t)(one_meter * .5f);
|
|
||||||
uint32_t max_vary = DQN_CAST(uint32_t)(one_meter * 2.f);
|
|
||||||
waypoint->data.offset += Dqn_V2_InitNx2(DQN_CAST(Dqn_f32)Dqn_PCG32_Range(&game->play.rng, min_vary, max_vary),
|
|
||||||
DQN_CAST(Dqn_f32)Dqn_PCG32_Range(&game->play.rng, min_vary, max_vary));
|
|
||||||
|
|
||||||
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
|
|
||||||
waypoint->data.offset *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
game->play.enemies_spawned_this_wave++;
|
game->play.enemies_spawned_this_wave++;
|
||||||
if (game->play.enemies_spawned_this_wave >= game->play.enemies_per_wave)
|
if (game->play.enemies_spawned_this_wave >= game->play.enemies_per_wave)
|
||||||
game->play.wave_cooldown_timestamp_ms = game->play.clock_ms + 30'000;
|
game->play.wave_cooldown_timestamp_ms = game->play.clock_ms + 30'000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +115,21 @@ FP_SentinelListLink<T> *FP_SentinelList_Erase(FP_SentinelList<T> *list, FP_Senti
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void FP_SentinelList_Deinit(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
|
void FP_SentinelList_Clear(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
|
||||||
{
|
{
|
||||||
if (!list || !pool)
|
if (!list || !pool)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (FP_SentinelListLink<T> *link = nullptr; FP_SentinelList_Iterate(list, &link); )
|
for (FP_SentinelListLink<T> *link = nullptr; FP_SentinelList_Iterate(list, &link); )
|
||||||
link = FP_SentinelList_Erase(list, link, pool);
|
link = FP_SentinelList_Erase(list, link, pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void FP_SentinelList_Deinit(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
|
||||||
|
{
|
||||||
|
if (!list || !pool)
|
||||||
|
return;
|
||||||
|
FP_SentinelList_Clear(list, pool);
|
||||||
TELY_ChunkPool_Dealloc(pool, list->sentinel);
|
TELY_ChunkPool_Dealloc(pool, list->sentinel);
|
||||||
*list = {};
|
*list = {};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user