fp: Add quick tutorial at beginning of game
This commit is contained in:
parent
b4438c1510
commit
285cc9b5ad
22
build.bat
22
build.bat
@ -1,25 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
setlocal
|
setlocal
|
||||||
|
|
||||||
set script_dir_backslash=%~dp0
|
call build_all.bat --fast-dev-build || exit /b 1
|
||||||
set script_dir=%script_dir_backslash:~0,-1%
|
|
||||||
set build_dir=%script_dir%\Build
|
|
||||||
set code_dir=%script_dir%
|
|
||||||
|
|
||||||
REM Bootstrap a version
|
|
||||||
git show -s --date=format:%%Y-%%m-%%d --format=%%cd HEAD> feely_pona_version.txt
|
|
||||||
git rev-parse --short=8 HEAD>> feely_pona_version.txt
|
|
||||||
git rev-list --count HEAD>> feely_pona_version.txt
|
|
||||||
|
|
||||||
REM Bootstrap the build program
|
|
||||||
mkdir %build_dir% 2>nul
|
|
||||||
pushd %build_dir%
|
|
||||||
cl /nologo /Z7 /W4 %code_dir%\feely_pona_build.cpp || exit /B 1
|
|
||||||
copy feely_pona_build.exe %code_dir% 1>nul
|
|
||||||
popd
|
|
||||||
|
|
||||||
REM Run the build program
|
|
||||||
%code_dir%\feely_pona_build.exe %* || exit /B 1
|
|
||||||
|
|
||||||
popd
|
|
||||||
exit /B 1
|
|
||||||
|
25
build_all.bat
Normal file
25
build_all.bat
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set script_dir_backslash=%~dp0
|
||||||
|
set script_dir=%script_dir_backslash:~0,-1%
|
||||||
|
set build_dir=%script_dir%\Build
|
||||||
|
set code_dir=%script_dir%
|
||||||
|
|
||||||
|
REM Bootstrap a version
|
||||||
|
git show -s --date=format:%%Y-%%m-%%d --format=%%cd HEAD> feely_pona_version.txt
|
||||||
|
git rev-parse --short=8 HEAD>> feely_pona_version.txt
|
||||||
|
git rev-list --count HEAD>> feely_pona_version.txt
|
||||||
|
|
||||||
|
REM Bootstrap the build program
|
||||||
|
mkdir %build_dir% 2>nul
|
||||||
|
pushd %build_dir%
|
||||||
|
cl /nologo /Z7 /W4 %code_dir%\feely_pona_build.cpp || exit /B 1
|
||||||
|
copy feely_pona_build.exe %code_dir% 1>nul
|
||||||
|
popd
|
||||||
|
|
||||||
|
REM Run the build program
|
||||||
|
%code_dir%\feely_pona_build.exe %* || exit /B 1
|
||||||
|
|
||||||
|
popd
|
||||||
|
exit /B 1
|
172
feely_pona.cpp
172
feely_pona.cpp
@ -305,9 +305,22 @@ static void FP_PlayReset(FP_Game *game, TELY_OS *os)
|
|||||||
|
|
||||||
Dqn_V2 base_mid_p = Dqn_V2_InitNx2(1580, 0.f);
|
Dqn_V2 base_mid_p = Dqn_V2_InitNx2(1580, 0.f);
|
||||||
{
|
{
|
||||||
// NOTE: Mid lane mob spawner ==================================================================
|
|
||||||
Dqn_V2 mid_lane_mob_spawner_pos = Dqn_V2_InitNx2(play->map->local_hit_box_size.w * -0.5f + 128.f, 0.f);
|
Dqn_V2 mid_lane_mob_spawner_pos = Dqn_V2_InitNx2(play->map->local_hit_box_size.w * -0.5f + 128.f, 0.f);
|
||||||
|
Dqn_V2 bottom_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y + 932.f);
|
||||||
|
Dqn_V2 top_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y - 915.f);
|
||||||
Dqn_usize spawn_cap = 16;
|
Dqn_usize spawn_cap = 16;
|
||||||
|
|
||||||
|
// NOTE: Top lane spawner ===================================================================
|
||||||
|
{
|
||||||
|
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, top_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
||||||
|
FP_Game_PushParentEntity(game, mob_spawner);
|
||||||
|
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint");
|
||||||
|
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, +915.f), "Waypoint");
|
||||||
|
FP_Game_PopParentEntity(game);
|
||||||
|
Dqn_FArray_Add(&play->mob_spawners, mob_spawner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Mid lane mob spawner ==================================================================
|
||||||
{
|
{
|
||||||
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mid_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, mid_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
||||||
FP_Game_PushParentEntity(game, mob_spawner);
|
FP_Game_PushParentEntity(game, mob_spawner);
|
||||||
@ -317,8 +330,6 @@ static void FP_PlayReset(FP_Game *game, TELY_OS *os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Bottom lane spawner ===================================================================
|
// NOTE: Bottom lane spawner ===================================================================
|
||||||
#if 1
|
|
||||||
Dqn_V2 bottom_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y + 932.f);
|
|
||||||
{
|
{
|
||||||
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, bottom_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, bottom_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
||||||
FP_Game_PushParentEntity(game, mob_spawner);
|
FP_Game_PushParentEntity(game, mob_spawner);
|
||||||
@ -327,18 +338,6 @@ static void FP_PlayReset(FP_Game *game, TELY_OS *os)
|
|||||||
FP_Game_PopParentEntity(game);
|
FP_Game_PopParentEntity(game);
|
||||||
Dqn_FArray_Add(&play->mob_spawners, mob_spawner);
|
Dqn_FArray_Add(&play->mob_spawners, mob_spawner);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Top lane spawner ===================================================================
|
|
||||||
Dqn_V2 top_lane_mob_spawner_pos = Dqn_V2_InitNx2(mid_lane_mob_spawner_pos.x, mid_lane_mob_spawner_pos.y - 915.f);
|
|
||||||
{
|
|
||||||
FP_GameEntityHandle mob_spawner = FP_Entity_CreateMobSpawner(game, top_lane_mob_spawner_pos, spawn_cap, "Mob spawner");
|
|
||||||
FP_Game_PushParentEntity(game, mob_spawner);
|
|
||||||
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, 0.f), "Waypoint");
|
|
||||||
FP_Entity_CreateWaypointF(game, Dqn_V2_InitNx2(-top_lane_mob_spawner_pos.x + base_mid_p.x, +915.f), "Waypoint");
|
|
||||||
FP_Game_PopParentEntity(game);
|
|
||||||
Dqn_FArray_Add(&play->mob_spawners, mob_spawner);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Monkey ============================================================
|
// NOTE: Monkey ============================================================
|
||||||
@ -1300,9 +1299,10 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
|
|||||||
Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate);
|
Dqn_Profiler_ZoneScopeWithIndex("FP_Update", FP_ProfileZone_FPUpdate);
|
||||||
|
|
||||||
game->play.update_counter++;
|
game->play.update_counter++;
|
||||||
|
game->play.clock_ms = DQN_CAST(uint64_t)(os->input.timer_s * 1000.f);
|
||||||
|
|
||||||
Dqn_ProfilerZone update_zone = Dqn_Profiler_BeginZoneWithIndex(DQN_STR8("FP_Update: Entity loop"), FP_ProfileZone_FPUpdate_EntityLoop);
|
Dqn_ProfilerZone update_zone = Dqn_Profiler_BeginZoneWithIndex(DQN_STR8("FP_Update: Entity loop"), FP_ProfileZone_FPUpdate_EntityLoop);
|
||||||
if (game->play.state == FP_GameState_Play && game->play.perry_joined != FP_GamePerryJoins_Enters) {
|
if (game->play.state == FP_GameState_Play && game->play.perry_joined != FP_GamePerryJoins_Enters) {
|
||||||
game->play.clock_ms = DQN_CAST(uint64_t)(os->input.timer_s * 1000.f);
|
|
||||||
|
|
||||||
DQN_MSVC_WARNING_PUSH
|
DQN_MSVC_WARNING_PUSH
|
||||||
DQN_MSVC_WARNING_DISABLE(4127) // Conditional expression is constant 'FP_DEVELOPER_MODE'
|
DQN_MSVC_WARNING_DISABLE(4127) // Conditional expression is constant 'FP_DEVELOPER_MODE'
|
||||||
@ -2049,7 +2049,7 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Mob spawner =======================================================================
|
// NOTE: Mob spawner =======================================================================
|
||||||
if (entity->type == FP_EntityType_MobSpawner && !game->play.debug_disable_mobs) {
|
if (entity->type == FP_EntityType_MobSpawner && !game->play.debug_disable_mobs && game->play.state != FP_GameState_Tutorial) {
|
||||||
// NOTE: Flush any spawn entities that are dead
|
// NOTE: Flush any spawn entities that are dead
|
||||||
for (FP_SentinelListLink<FP_GameEntityHandle> *link = nullptr; FP_SentinelList_Iterate<FP_GameEntityHandle>(&entity->spawn_list, &link); ) {
|
for (FP_SentinelListLink<FP_GameEntityHandle> *link = nullptr; FP_SentinelList_Iterate<FP_GameEntityHandle>(&entity->spawn_list, &link); ) {
|
||||||
FP_GameEntity *spawned_entity = FP_Game_GetEntity(game, link->data);
|
FP_GameEntity *spawned_entity = FP_Game_GetEntity(game, link->data);
|
||||||
@ -2284,9 +2284,54 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Camera ================================================================================
|
// NOTE: Camera ================================================================================
|
||||||
|
|
||||||
FP_GamePlay *play = &game->play;
|
FP_GamePlay *play = &game->play;
|
||||||
FP_GameCamera *camera = &play->camera;
|
FP_GameCamera *camera = &play->camera;
|
||||||
|
|
||||||
|
if (game->play.state == FP_GameState_Tutorial) {
|
||||||
|
Dqn_f32 arrival_dist = Dqn_V2_LengthSq(camera->world_pos_target - camera->world_pos);
|
||||||
|
bool camera_arrived = arrival_dist < DQN_SQUARED(5.f);
|
||||||
|
|
||||||
|
switch (game->play.tutorial_state) {
|
||||||
|
case FP_GameStateTutorial_ShowPlayer: {
|
||||||
|
camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, game->play.players.data[0]) * game->play.camera.scale;
|
||||||
|
if (camera_arrived) {
|
||||||
|
game->play.tutorial_state = DQN_CAST(FP_GameStateTutorial)(DQN_CAST(uint32_t)game->play.tutorial_state + 1);
|
||||||
|
game->play.tutorial_wait_end_time_s = input->timer_s + 2.0;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_GameStateTutorial_ShowPortalOneWait: /*FALLTHRU*/
|
||||||
|
case FP_GameStateTutorial_ShowPortalTwoWait: /*FALLTHRU*/
|
||||||
|
case FP_GameStateTutorial_ShowPortalThreeWait: /*FALLTHRU*/
|
||||||
|
case FP_GameStateTutorial_ShowPlayerWait: {
|
||||||
|
if (input->timer_s > game->play.tutorial_wait_end_time_s) {
|
||||||
|
game->play.tutorial_state = DQN_CAST(FP_GameStateTutorial)(DQN_CAST(uint32_t)game->play.tutorial_state + 1);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_GameStateTutorial_ShowPortalOne: /*FALLTHRU*/
|
||||||
|
case FP_GameStateTutorial_ShowPortalTwo: /*FALLTHRU*/
|
||||||
|
case FP_GameStateTutorial_ShowPortalThree: {
|
||||||
|
if (game->play.tutorial_state == FP_GameStateTutorial_ShowPortalOne) {
|
||||||
|
camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, game->play.mob_spawners.data[0]) * game->play.camera.scale;
|
||||||
|
} else if (game->play.tutorial_state == FP_GameStateTutorial_ShowPortalTwo) {
|
||||||
|
camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, game->play.mob_spawners.data[1]) * game->play.camera.scale;
|
||||||
|
} else {
|
||||||
|
DQN_ASSERT(game->play.tutorial_state == FP_GameStateTutorial_ShowPortalThree);
|
||||||
|
camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, game->play.mob_spawners.data[2]) * game->play.camera.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera_arrived) {
|
||||||
|
game->play.tutorial_state = DQN_CAST(FP_GameStateTutorial)(DQN_CAST(uint32_t)game->play.tutorial_state + 1);
|
||||||
|
game->play.tutorial_wait_end_time_s = input->timer_s + 2.0;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FP_GameStateTutorial_Count: {
|
||||||
|
game->play.state = FP_GameState_Play;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
camera->world_pos_target = {};
|
camera->world_pos_target = {};
|
||||||
for (FP_GameEntityHandle camera_entity : game->play.camera_tracking_entity) {
|
for (FP_GameEntityHandle camera_entity : game->play.camera_tracking_entity) {
|
||||||
Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, camera_entity) * game->play.camera.scale;
|
Dqn_V2 entity_pos = FP_Game_CalcEntityWorldPos(game, camera_entity) * game->play.camera.scale;
|
||||||
@ -2295,11 +2340,11 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
|
|||||||
|
|
||||||
if (game->play.camera_tracking_entity.size)
|
if (game->play.camera_tracking_entity.size)
|
||||||
camera->world_pos_target /= DQN_CAST(Dqn_f32)game->play.camera_tracking_entity.size;
|
camera->world_pos_target /= DQN_CAST(Dqn_f32)game->play.camera_tracking_entity.size;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Clamp camera to map bounds ============================================================
|
// NOTE: Clamp camera to map bounds ============================================================
|
||||||
{
|
{
|
||||||
Dqn_V2 window_size = Dqn_V2_InitV2I(os->core.window_size);
|
Dqn_V2 window_size = Dqn_V2_InitV2I(os->core.window_size);
|
||||||
|
|
||||||
camera->scale = window_size / camera->size;
|
camera->scale = window_size / camera->size;
|
||||||
Dqn_V2 camera_size_screen = camera->size * camera->scale;
|
Dqn_V2 camera_size_screen = camera->size * camera->scale;
|
||||||
|
|
||||||
@ -2313,7 +2358,7 @@ static void FP_Update(TELY_OS *os, FP_Game *game, TELY_OSInput *input, TELY_Audi
|
|||||||
camera->world_pos_target.y = DQN_MIN(camera->world_pos_target.y, half_map_screen_size.h - (camera_size_screen.h * .5f));
|
camera->world_pos_target.y = DQN_MIN(camera->world_pos_target.y, half_map_screen_size.h - (camera_size_screen.h * .5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
camera->world_pos += (camera->world_pos_target - camera->world_pos) * (5.f * DQN_CAST(Dqn_f32)input->delta_s);
|
camera->world_pos += (camera->world_pos_target - camera->world_pos) * DQN_MIN(1.f, (5.f * DQN_CAST(Dqn_f32)input->delta_s));
|
||||||
Dqn_Profiler_EndZone(update_zone);
|
Dqn_Profiler_EndZone(update_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2961,7 +3006,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Render overlay UI =====================================================================
|
// NOTE: Render overlay UI =====================================================================
|
||||||
if (!game->play.debug_hide_hud && (game->play.state == FP_GameState_Pause || game->play.state == FP_GameState_Play)) {
|
if (!game->play.debug_hide_hud && (game->play.state == FP_GameState_Pause || game->play.state == FP_GameState_Play || game->play.state == FP_GameState_Tutorial)) {
|
||||||
|
|
||||||
// NOTE: Render the merchant menus for each player =========================================
|
// NOTE: Render the merchant menus for each player =========================================
|
||||||
FP_GamePlay *play = &game->play;
|
FP_GamePlay *play = &game->play;
|
||||||
@ -3764,15 +3809,88 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: Render the other game state modes =====================================================
|
||||||
|
Dqn_V4 const maroon_colour = TELY_Colour_V4InitRGBAU32(0x301010FF); // NOTE: Maroon
|
||||||
|
if (game->play.state == FP_GameState_Tutorial) {
|
||||||
|
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
||||||
|
TELY_Render_PushFontSize(renderer, game->talkco_font, game->large_talkco_font_size);
|
||||||
|
TELY_Render_PushColourV4(renderer, TELY_COLOUR_WHITE_V4);
|
||||||
|
DQN_DEFER {
|
||||||
|
TELY_Render_PopFont(renderer);
|
||||||
|
TELY_Render_PopTransform(renderer);
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: Calculate text bounds
|
||||||
|
struct LineSize {
|
||||||
|
Dqn_Str8 line;
|
||||||
|
Dqn_V2 size;
|
||||||
|
} lines[] = {
|
||||||
|
{DQN_STR8("Defend Terry's heart from the oncoming hordes!"), Dqn_V2_Zero},
|
||||||
|
};
|
||||||
|
|
||||||
|
Dqn_V2 origin = Dqn_V2_InitV2I(os->core.window_size) * Dqn_V2_InitNx2(.5f, .5f);
|
||||||
|
Dqn_f32 scaled_font_size = TELY_Render_FontSize(renderer) * os->core.dpi_scale;
|
||||||
|
Dqn_V2 text_min = Dqn_V2_InitNx2(origin.x, origin.y - scaled_font_size * .5f);
|
||||||
|
Dqn_V2 text_max = Dqn_V2_InitNx2(text_min.x, text_min.y + DQN_ARRAY_UCOUNT(lines) * scaled_font_size);
|
||||||
|
for (LineSize &line_size_ : lines) {
|
||||||
|
LineSize *line_size = &line_size_;
|
||||||
|
line_size->size = TELY_Asset_MeasureText(assets, TELY_Render_ActiveFont(renderer), line_size->line);
|
||||||
|
text_min.x = DQN_MIN(origin.x, origin.x - line_size->size.x * .5f);
|
||||||
|
text_max.x = DQN_MAX(origin.x, origin.x + line_size->size.x * .58f); // TODO: Wrong calc, but too lazy to figure it out
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Calculate terry avatar variables
|
||||||
|
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.intro_screen_terry);
|
||||||
|
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
|
||||||
|
Dqn_f32 desired_width = os->core.window_size.x * .1f;
|
||||||
|
Dqn_f32 tex_scalar = desired_width / tex_rect.size.w;
|
||||||
|
|
||||||
|
Dqn_Rect dest_rect = {};
|
||||||
|
dest_rect.size = tex_rect.size * tex_scalar;
|
||||||
|
dest_rect.pos = text_min - Dqn_V2_InitNx2(dest_rect.size.x * 1.f, dest_rect.size.y * .5f);
|
||||||
|
|
||||||
|
Dqn_Rect terry_bounding_rect = Dqn_Rect_ExpandV2(dest_rect, Dqn_V2_InitNx2(scaled_font_size * .5f, scaled_font_size * .25f));
|
||||||
|
|
||||||
|
// NOTE: Draw text
|
||||||
|
{
|
||||||
|
Dqn_V2 draw_p = Dqn_Rect_InterpolatedPoint(terry_bounding_rect, Dqn_V2_InitNx2(1.1f, 0.5f));
|
||||||
|
Dqn_Rect bounding_rect = Dqn_Rect_InitV2x2(text_min, text_max - text_min);
|
||||||
|
bounding_rect = Dqn_Rect_ExpandV2(bounding_rect, Dqn_V2_InitNx2(scaled_font_size * .1f, scaled_font_size * .1f));
|
||||||
|
|
||||||
|
Dqn_RectMinMax min_max_bounds = Dqn_Rect_MinMax(bounding_rect);
|
||||||
|
min_max_bounds.max.y = DQN_MAX(min_max_bounds.max.y, terry_bounding_rect.pos.y + terry_bounding_rect.size.y);
|
||||||
|
bounding_rect = Dqn_Rect_InitV2x2(min_max_bounds.min, min_max_bounds.max - min_max_bounds.min);
|
||||||
|
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(bounding_rect, 5.f), TELY_RenderShapeMode_Fill, TELY_COLOUR_BLACK_V4);
|
||||||
|
TELY_Render_RectColourV4(renderer, bounding_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(maroon_colour, 1.f));
|
||||||
|
|
||||||
|
for (LineSize &line_size_ : lines) {
|
||||||
|
LineSize *line_size = &line_size_;
|
||||||
|
TELY_Render_TextF(renderer, draw_p, Dqn_V2_Zero, "%.*s", DQN_STR_FMT(line_size->line));
|
||||||
|
draw_p.y += TELY_Render_FontSize(renderer) * os->core.dpi_scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Draw terry
|
||||||
|
TELY_Render_RectColourV4(renderer, Dqn_Rect_Expand(terry_bounding_rect, 5.f), TELY_RenderShapeMode_Fill, TELY_COLOUR_BLACK_V4);
|
||||||
|
TELY_Render_RectColourV4(renderer, terry_bounding_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(maroon_colour, 1.f));
|
||||||
|
TELY_Render_TextureColourV4(renderer,
|
||||||
|
game->atlas_sprite_sheet.tex_handle,
|
||||||
|
tex_rect,
|
||||||
|
dest_rect,
|
||||||
|
Dqn_V2_Zero /*rotate origin*/,
|
||||||
|
0.f /*rotation*/,
|
||||||
|
TELY_COLOUR_WHITE_V4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Add scanlines into the game for A E S T H E T I C S ===================================
|
// NOTE: Add scanlines into the game for A E S T H E T I C S ===================================
|
||||||
if (game->play.state == FP_GameState_Play) {
|
if (game->play.state == FP_GameState_Play || game->play.state == FP_GameState_Tutorial) {
|
||||||
Dqn_V2 screen_size = Dqn_V2_InitNx2(os->core.window_size.w, os->core.window_size.h);
|
Dqn_V2 screen_size = Dqn_V2_InitNx2(os->core.window_size.w, os->core.window_size.h);
|
||||||
Dqn_f32 scanline_gap = 4.0f;
|
Dqn_f32 scanline_gap = 4.0f;
|
||||||
Dqn_f32 scanline_thickness = 3.0f;
|
Dqn_f32 scanline_thickness = 3.0f;
|
||||||
FP_GameRenderScanlines(renderer, scanline_gap, scanline_thickness, screen_size);
|
FP_GameRenderScanlines(renderer, scanline_gap, scanline_thickness, screen_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Render the other game state modes =====================================================
|
|
||||||
if (game->play.state == FP_GameState_IntroScreen || game->play.state == FP_GameState_WinGame || game->play.state == FP_GameState_LoseGame || game->play.state == FP_GameState_Pause) {
|
if (game->play.state == FP_GameState_IntroScreen || game->play.state == FP_GameState_WinGame || game->play.state == FP_GameState_LoseGame || game->play.state == FP_GameState_Pause) {
|
||||||
|
|
||||||
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
|
||||||
@ -3784,7 +3902,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
|
|||||||
Dqn_V2 draw_p = Dqn_V2_InitNx2(min_inset, min_inset);
|
Dqn_V2 draw_p = Dqn_V2_InitNx2(min_inset, min_inset);
|
||||||
TELY_Render_PushColourV4(renderer, TELY_COLOUR_WHITE_V4);
|
TELY_Render_PushColourV4(renderer, TELY_COLOUR_WHITE_V4);
|
||||||
|
|
||||||
Dqn_V4 bg_colour = TELY_Colour_V4InitRGBAU32(0x301010FF); // NOTE: Maroon
|
Dqn_V4 bg_colour = maroon_colour;
|
||||||
TELY_Render_RectColourV4(
|
TELY_Render_RectColourV4(
|
||||||
renderer,
|
renderer,
|
||||||
Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)os->core.window_size.x, DQN_CAST(Dqn_f32)os->core.window_size.y),
|
Dqn_Rect_InitNx4(0, 0, DQN_CAST(Dqn_f32)os->core.window_size.x, DQN_CAST(Dqn_f32)os->core.window_size.y),
|
||||||
@ -3896,8 +4014,9 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
|
|||||||
|
|
||||||
if (game->play.state == FP_GameState_LoseGame)
|
if (game->play.state == FP_GameState_LoseGame)
|
||||||
FP_PlayReset(game, os);
|
FP_PlayReset(game, os);
|
||||||
|
|
||||||
if (FP_ListenForNewPlayer(input, game))
|
if (FP_ListenForNewPlayer(input, game))
|
||||||
game->play.state = FP_GameState_Play;
|
game->play.state = FP_GameState_Tutorial;
|
||||||
|
|
||||||
} else if (game->play.state == FP_GameState_Pause) {
|
} else if (game->play.state == FP_GameState_Pause) {
|
||||||
TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size);
|
TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size);
|
||||||
@ -3911,6 +4030,7 @@ static void FP_Render(FP_Game *game, TELY_OS *os, TELY_Renderer *renderer, TELY_
|
|||||||
|
|
||||||
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return))
|
if (TELY_OSInput_ScanKeyIsPressed(input, TELY_OSInputScanKey_Return))
|
||||||
game->play.state = FP_GameState_Play;
|
game->play.state = FP_GameState_Play;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DQN_ASSERT(game->play.state == FP_GameState_WinGame);
|
DQN_ASSERT(game->play.state == FP_GameState_WinGame);
|
||||||
TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size);
|
TELY_Render_PushFontSize(renderer, game->inter_regular_font, game->large_font_size);
|
||||||
@ -4240,7 +4360,7 @@ void TELY_OS_DLLFrameUpdate(TELY_OS *os)
|
|||||||
|
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
|
|
||||||
if (game->play.state == FP_GameState_Play) {
|
if (game->play.state == FP_GameState_Play || game->play.state == FP_GameState_Tutorial) {
|
||||||
if (TELY_OSInput_KeyWasDown(input->mouse_left) && TELY_OSInput_KeyIsDown(input->mouse_left)) {
|
if (TELY_OSInput_KeyWasDown(input->mouse_left) && TELY_OSInput_KeyIsDown(input->mouse_left)) {
|
||||||
if (game->play.prev_active_entity.id)
|
if (game->play.prev_active_entity.id)
|
||||||
game->play.active_entity = game->play.prev_active_entity;
|
game->play.active_entity = game->play.prev_active_entity;
|
||||||
|
@ -392,7 +392,7 @@ int main(int argc, char const **argv)
|
|||||||
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
|
Dqn_Str8 cmd = Dqn_CPPBuild_ToCommandLine(build_context, Dqn_CPPBuildMode_AlwaysRebuild, scratch.allocator);
|
||||||
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STR_FMT(cmd));
|
Dqn_Print_StdLnF(Dqn_PrintStd_Out, "%.*s\n", DQN_STR_FMT(cmd));
|
||||||
} else {
|
} else {
|
||||||
Dqn_Str8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/terry_cherry_dev_msvc.exe", DQN_STR_FMT(build_dir));
|
Dqn_Str8 exe_path = Dqn_FsPath_ConvertF(scratch.arena, "%.*s/terry_cherry_dev.exe", DQN_STR_FMT(build_dir));
|
||||||
bool exe_is_locked = false;
|
bool exe_is_locked = false;
|
||||||
if (Dqn_Fs_Exists(exe_path)) {
|
if (Dqn_Fs_Exists(exe_path)) {
|
||||||
Dqn_FsFile exe_file = Dqn_Fs_OpenFile(exe_path, Dqn_FsFileOpen_OpenIfExist, Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write);
|
Dqn_FsFile exe_file = Dqn_Fs_OpenFile(exe_path, Dqn_FsFileOpen_OpenIfExist, Dqn_FsFileAccess_Read | Dqn_FsFileAccess_Write);
|
||||||
|
@ -250,6 +250,7 @@ static FP_GameEntity *FP_Game_MakeEntityPointerFV(FP_Game *game, DQN_FMT_ATTRIB
|
|||||||
result->buildings_visited = FP_SentinelList_Init<FP_GameEntityHandle>(game->play.chunk_pool);
|
result->buildings_visited = FP_SentinelList_Init<FP_GameEntityHandle>(game->play.chunk_pool);
|
||||||
result->action.sprite_alpha = 1.f;
|
result->action.sprite_alpha = 1.f;
|
||||||
result->stamina_cap = 93;
|
result->stamina_cap = 93;
|
||||||
|
result->stamina = result->stamina_cap;
|
||||||
|
|
||||||
result->hp_cap = DQN_CAST(uint32_t)(FP_DEFAULT_DAMAGE * .8f);
|
result->hp_cap = DQN_CAST(uint32_t)(FP_DEFAULT_DAMAGE * .8f);
|
||||||
result->hp = result->hp_cap;
|
result->hp = result->hp_cap;
|
||||||
|
@ -340,6 +340,7 @@ enum FP_GameAudio
|
|||||||
enum FP_GameState
|
enum FP_GameState
|
||||||
{
|
{
|
||||||
FP_GameState_IntroScreen,
|
FP_GameState_IntroScreen,
|
||||||
|
FP_GameState_Tutorial,
|
||||||
FP_GameState_Play,
|
FP_GameState_Play,
|
||||||
FP_GameState_Pause,
|
FP_GameState_Pause,
|
||||||
FP_GameState_WinGame,
|
FP_GameState_WinGame,
|
||||||
@ -365,6 +366,19 @@ struct FP_Particle
|
|||||||
Dqn_usize end_ms;
|
Dqn_usize end_ms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FP_GameStateTutorial
|
||||||
|
{
|
||||||
|
FP_GameStateTutorial_ShowPlayer,
|
||||||
|
FP_GameStateTutorial_ShowPlayerWait,
|
||||||
|
FP_GameStateTutorial_ShowPortalOne,
|
||||||
|
FP_GameStateTutorial_ShowPortalOneWait,
|
||||||
|
FP_GameStateTutorial_ShowPortalTwo,
|
||||||
|
FP_GameStateTutorial_ShowPortalTwoWait,
|
||||||
|
FP_GameStateTutorial_ShowPortalThree,
|
||||||
|
FP_GameStateTutorial_ShowPortalThreeWait,
|
||||||
|
FP_GameStateTutorial_Count,
|
||||||
|
};
|
||||||
|
|
||||||
struct FP_GamePlay
|
struct FP_GamePlay
|
||||||
{
|
{
|
||||||
TELY_ChunkPool *chunk_pool;
|
TELY_ChunkPool *chunk_pool;
|
||||||
@ -429,6 +443,9 @@ struct FP_GamePlay
|
|||||||
|
|
||||||
FP_Particle particles[256];
|
FP_Particle particles[256];
|
||||||
uint32_t particle_next_index;
|
uint32_t particle_next_index;
|
||||||
|
|
||||||
|
FP_GameStateTutorial tutorial_state;
|
||||||
|
Dqn_f64 tutorial_wait_end_time_s;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FP_Game
|
struct FP_Game
|
||||||
|
Loading…
Reference in New Issue
Block a user