Compare commits

...

2 Commits

4 changed files with 73 additions and 45 deletions

View File

@ -327,10 +327,6 @@ NamespaceIndentation: None
PackConstructorInitializers: CurrentLine
PointerAlignment: Right
# Different ways to arrange specifiers and qualifiers (e.g. const/volatile).
QualifierAlignment: Custom
QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile']
# false:
# // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
# /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */

View File

@ -588,6 +588,37 @@ FP_GetClosestPortalMonkeyResult FP_GetClosestPortalMonkey(FP_Game *game, FP_Game
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)
{
TELY_AssetSpriteSheet *sheet = &game->atlas_sprite_sheet;
@ -1119,11 +1150,13 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
entity->building_patron = {};
// 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);
FP_GameEntityHandle mob_spawner = game->play.mob_spawners.data[mob_spawner_index];
Dqn_V2 target_pos = FP_Game_CalcEntityWorldPos(game, mob_spawner);
plane->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->play.chunk_pool);
uint32_t mob_spawner_index = Dqn_PCG32_Range(&game->play.rng, 0, DQN_CAST(uint32_t)game->play.mob_spawners.size);
mob_spawner = game->play.mob_spawners.data[mob_spawner_index];
mob_spawner_pos = FP_Game_CalcEntityWorldPos(game, mob_spawner);
plane->waypoints = FP_SentinelList_Init<FP_GameWaypoint>(game->play.chunk_pool);
FP_SentinelListLink<FP_GameWaypoint> *link = FP_SentinelList_MakeBefore(&plane->waypoints,
FP_SentinelList_Front(&plane->waypoints),
game->play.chunk_pool);
@ -1132,6 +1165,11 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
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);
}
} break;
@ -1876,14 +1914,13 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
// NOTE: Remove them from the queue
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_V2 exit_pos = Dqn_Rect_InterpolatedPoint(hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
Dqn_Rect building_hit_box = FP_Game_CalcEntityWorldHitBox(game, building->handle);
Dqn_V2 exit_pos = Dqn_Rect_InterpolatedPoint(building_hit_box, Dqn_V2_InitNx2(0.5f, 1.1f));
if (building->type == FP_EntityType_ClubTerry) {
FP_Game_EntityTransitionState(game, building, FP_EntityClubTerryState_PartyTime);
entity->local_pos = exit_pos; // TODO(doyle): Only works when parent world pos is 0,0
} else if (building->type == FP_EntityType_AirportTerry) {
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 {
DQN_ASSERT(building->type == FP_EntityType_ChurchTerry);
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);
FP_SentinelListLink<FP_GameEntityHandle> *link = FP_SentinelList_Make(&entity->spawn_list, game->play.chunk_pool);
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(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 mob_y_offset = (Dqn_PCG32_NextF32(&game->play.rng) * step_y) + (step_y * spawn_index);
Dqn_f32 one_meter = FP_Game_MetersToPixelsNx1(game->play, 1.f);
Dqn_V2 entity_world_pos = FP_Game_CalcEntityWorldPos(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 mob_y_offset = (Dqn_PCG32_NextF32(&game->play.rng) * step_y) + (step_y * spawn_index);
if (Dqn_PCG32_NextF32(&game->play.rng) >= .5f)
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 = mob->hp_cap;
for (FP_GameEntity *waypoint_entity = entity->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(&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;
}
FP_AppendMobSpawnerWaypoints(game, entity->handle, mob->handle);
game->play.enemies_spawned_this_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;
}
}
}
}

View File

@ -323,17 +323,26 @@ int main(int argc, char const **argv)
Dqn_String8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STRING_FMT(cmd));
} else {
Dqn_CPPBuild_ExecOrAbort(build_context, Dqn_CPPBuildMode_AlwaysRebuild);
Dqn_String8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/feely_pona_msvc.exe", DQN_STRING_FMT(build_dir));
bool exe_is_locked = false;
if (Dqn_Fs_Exists(exe_path)) {
Dqn_FsFile exe_file = Dqn_Fs_OpenFile(exe_path, Dqn_FsFileOpen_OpenIfExist, Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write);
exe_is_locked = exe_file.error_size;
}
if (!exe_is_locked) {
Dqn_CPPBuild_ExecOrAbort(build_context, Dqn_CPPBuildMode_AlwaysRebuild);
}
}
}
build_timings[1] = Dqn_OS_PerfCounterNow();
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "\n-- Dqn_CPPBuild Timings (%.2fms)", Dqn_OS_PerfCounterMs(build_timings[0], build_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " robocopy: %.2fms", Dqn_OS_PerfCounterMs(robocopy_timings[0], robocopy_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " raylib: %.2fms", Dqn_OS_PerfCounterMs(raylib_timings[0], raylib_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona sprite packer: %.2fms", Dqn_OS_PerfCounterMs(feely_pona_sprite_packer_timings[0], feely_pona_sprite_packer_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (no dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_no_dll_timings[0], feely_pona_no_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_dll_timings[0], feely_pona_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (platform): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_platform_timings[0], feely_pona_platform_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " robocopy: %.2fms", Dqn_OS_PerfCounterMs(robocopy_timings[0], robocopy_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " raylib: %.2fms", Dqn_OS_PerfCounterMs(raylib_timings[0], raylib_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona sprite packer: %.2fms", Dqn_OS_PerfCounterMs(feely_pona_sprite_packer_timings[0], feely_pona_sprite_packer_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (no dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_no_dll_timings[0], feely_pona_no_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (dll): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_dll_timings[0], feely_pona_dll_timings[1]));
Dqn_Print_StdLnF(Dqn_PrintStd_Out, " feely pona (platform-raylib): %.2fms", Dqn_OS_PerfCounterMs(feely_pona_platform_timings[0], feely_pona_platform_timings[1]));
return 0;
}

View File

@ -115,14 +115,21 @@ FP_SentinelListLink<T> *FP_SentinelList_Erase(FP_SentinelList<T> *list, FP_Senti
}
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)
return;
for (FP_SentinelListLink<T> *link = nullptr; FP_SentinelList_Iterate(list, &link); )
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);
*list = {};
}