fp: Add different bindings for buildings+upgrades

This commit is contained in:
doyle 2023-10-18 22:59:40 +11:00
parent 5159763baa
commit 270e57acfc
2 changed files with 88 additions and 35 deletions

View File

@ -550,6 +550,8 @@ void TELY_DLL_Init(void *user_data)
controls->build_mode.scan_code = TELY_PlatformInputScanCode_H; controls->build_mode.scan_code = TELY_PlatformInputScanCode_H;
controls->strafe.scan_code = TELY_PlatformInputScanCode_L; controls->strafe.scan_code = TELY_PlatformInputScanCode_L;
controls->dash.scan_code = TELY_PlatformInputScanCode_N; controls->dash.scan_code = TELY_PlatformInputScanCode_N;
controls->buy_building.scan_code = TELY_PlatformInputScanCode_U;
controls->buy_upgrade.scan_code = TELY_PlatformInputScanCode_I;
} }
struct FP_GetClosestPortalMonkeyResult struct FP_GetClosestPortalMonkeyResult
@ -650,7 +652,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
} }
if (we_are_clicked_entity) { if (we_are_clicked_entity) {
if (game->play.in_game_menu == FP_GameInGameMenu_Nil) { if (game->play.in_game_menu != FP_GameInGameMenu_Build) {
bool picked_up_monkey_this_frame = false; bool picked_up_monkey_this_frame = false;
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) { if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
// NOTE: Check if we are nearby a monkey and picking it up // NOTE: Check if we are nearby a monkey and picking it up
@ -718,7 +720,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (we_are_clicked_entity) { if (we_are_clicked_entity) {
bool picked_up_monkey_this_frame = false; bool picked_up_monkey_this_frame = false;
if (game->play.in_game_menu == FP_GameInGameMenu_Nil) { if (game->play.in_game_menu != FP_GameInGameMenu_Build) {
if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) { if (FP_Game_IsNilEntityHandle(game, entity->carried_monkey)) {
// NOTE: Check if we are nearby a monkey and picking it up // NOTE: Check if we are nearby a monkey and picking it up
FP_GetClosestPortalMonkeyResult closest_monkey = FP_GetClosestPortalMonkey(game, entity->handle); FP_GetClosestPortalMonkeyResult closest_monkey = FP_GetClosestPortalMonkey(game, entity->handle);
@ -2375,6 +2377,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
TELY_Render_PushColourV4(renderer, TELY_COLOUR_BLACK_V4); TELY_Render_PushColourV4(renderer, TELY_COLOUR_BLACK_V4);
// NOTE: Draw entities ========================================================================= // NOTE: Draw entities =========================================================================
Dqn_V4 const colour_accent_yellow = TELY_Colour_V4InitRGBU32(0xFFE726);
for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->play.root_entity); ) { for (FP_GameEntityIterator it = {}; FP_Game_DFSPostOrderWalkEntityTree(game, &it, game->play.root_entity); ) {
FP_GameEntity *entity = it.entity; FP_GameEntity *entity = it.entity;
if (entity->flags & FP_GameEntityFlag_OccupiedInBuilding) if (entity->flags & FP_GameEntityFlag_OccupiedInBuilding)
@ -2660,7 +2663,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
case FP_EntityBillboardState_Attack: { case FP_EntityBillboardState_Attack: {
key_bind = &game->controls.attack; key_bind = &game->controls.attack;
draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.65f, 0.2f)); draw_p = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.65f, 0.2f));
colour = TELY_Colour_V4InitRGBU32(0xFFE726); colour = colour_accent_yellow;
} break; } break;
case FP_EntityBillboardState_Dash: { case FP_EntityBillboardState_Dash: {
@ -2809,21 +2812,22 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
// NOTE: Render the merchant button for buildings ================== // NOTE: Render the merchant button for buildings ==================
uint64_t const buy_duration_ms = 500; uint64_t const buy_duration_ms = 500;
Dqn_V4 keybind_btn_shadow_colour = Dqn_V4_InitNx4(0.4f, 0.4f, 0.4f, 1.f);
{ {
bool const have_enough_coins = player->coins >= *mapping.building_base_price; bool const have_enough_coins = player->coins >= *mapping.building_base_price;
FP_GameKeyBind key_bind = game->controls.buy_building;
// NOTE: Buy trigger + animation =============================== // NOTE: Buy trigger + animation ===============================
{ {
TELY_PlatformInputScanCode key = game->controls.attack.scan_code;
bool trigger_buy_anim = false; bool trigger_buy_anim = false;
if (have_enough_coins) { if (have_enough_coins) {
if (TELY_Platform_InputScanCodeIsPressed(input, key)) { if (TELY_Platform_InputScanCodeIsPressed(input, key_bind.scan_code)) {
game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms + buy_duration_ms; game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms + buy_duration_ms;
} else if (TELY_Platform_InputScanCodeIsDown(input, key)) { } else if (TELY_Platform_InputScanCodeIsDown(input, key_bind.scan_code)) {
trigger_buy_anim = true; trigger_buy_anim = true;
if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp)
game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms; game->play.player_trigger_purchase_building_timestamp = game->play.clock_ms;
} else if (TELY_Platform_InputScanCodeIsReleased(input, key)) { } else if (TELY_Platform_InputScanCodeIsReleased(input, key_bind.scan_code)) {
if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) { if (game->play.clock_ms > game->play.player_trigger_purchase_building_timestamp) {
if (mapping.inventory_count) { if (mapping.inventory_count) {
player->coins -= *mapping.building_base_price; player->coins -= *mapping.building_base_price;
@ -2861,21 +2865,45 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
// NOTE: Render the (A) button ================================= // NOTE: Render the (A) button =================================
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f); Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
{
// NOTE: Render the gamepad button
Dqn_Rect gamepad_btn_rect = {};
{ {
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_a); TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_a);
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index]; Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect dest_rect = {}; gamepad_btn_rect.size = button_rect.size * 1.5f;
dest_rect.size = button_rect.size * 1.5f; gamepad_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.345f, 0.41f));
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.345f, 0.5f));
TELY_Render_TextureColourV4(renderer, TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle, game->atlas_sprite_sheet.tex_handle,
button_rect, button_rect,
dest_rect, gamepad_btn_rect,
Dqn_V2_Zero /*rotate origin*/, Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/, 0.f /*rotation*/,
tex_mod_colour); tex_mod_colour);
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0.5f, -1)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.building_base_price); }
// NOTE: Render the $ cost
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(0.5f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.building_base_price);
// NOTE: Render the keyboard binding =======================================
{
DQN_ASSERT(key_bind.scan_code >= TELY_PlatformInputScanCode_A && key_bind.scan_code <= TELY_PlatformInputScanCode_Z);
char scan_code_ch = DQN_CAST(char)('A' + (key_bind.scan_code - TELY_PlatformInputScanCode_A));
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
Dqn_String8 key_bind_label = Dqn_String8_InitF(scratch.allocator, "[%c]", scan_code_ch);
Dqn_Rect key_bind_rect = {};
key_bind_rect.pos = Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(-0.1f, 1.1f));
key_bind_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
key_bind_rect = Dqn_Rect_Expand(key_bind_rect, 2.f);
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
TELY_Render_RectColourV4(renderer, key_bind_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
TELY_Render_PopColourV4(renderer);
}
} }
// NOTE: Render the merchant shop item building ================ // NOTE: Render the merchant shop item building ================
@ -2898,19 +2926,19 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
// NOTE: Render the merchant button for buildings // NOTE: Render the merchant button for buildings
{ {
bool const have_enough_coins = player->coins >= *mapping.upgrade_base_price; bool const have_enough_coins = player->coins >= *mapping.upgrade_base_price;
FP_GameKeyBind key_bind = game->controls.buy_upgrade;
// NOTE: Buy trigger + animation =============================== // NOTE: Buy trigger + animation ===============================
{ {
TELY_PlatformInputScanCode key = game->controls.range_attack.scan_code;
bool trigger_buy_anim = false; bool trigger_buy_anim = false;
if (have_enough_coins) { if (have_enough_coins) {
if (TELY_Platform_InputScanCodeIsPressed(input, key)) { if (TELY_Platform_InputScanCodeIsPressed(input, key_bind.scan_code)) {
game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms + buy_duration_ms; game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms + buy_duration_ms;
} else if (TELY_Platform_InputScanCodeIsDown(input, key)) { } else if (TELY_Platform_InputScanCodeIsDown(input, key_bind.scan_code)) {
trigger_buy_anim = true; trigger_buy_anim = true;
if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp)
game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms; game->play.player_trigger_purchase_upgrade_timestamp = game->play.clock_ms;
} else if (TELY_Platform_InputScanCodeIsReleased(input, key)) { } else if (TELY_Platform_InputScanCodeIsReleased(input, key_bind.scan_code)) {
if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) { if (game->play.clock_ms > game->play.player_trigger_purchase_upgrade_timestamp) {
player->coins -= *mapping.upgrade_base_price; player->coins -= *mapping.upgrade_base_price;
*mapping.upgrade_base_price *= 1; *mapping.upgrade_base_price *= 1;
@ -2950,29 +2978,31 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f); Dqn_V4 tex_mod_colour = have_enough_coins ? TELY_COLOUR_WHITE_V4 : TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, .5f);
{ {
Dqn_V2 interp_pos01 = {}; Dqn_V2 interp_pos01 = {};
Dqn_Rect gamepad_btn_rect = {};
// NOTE: Render the gamepad button
{ {
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_b); TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.merchant_button_b);
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index]; Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
interp_pos01 = Dqn_V2_InitNx2(0.71f, 0.5f); interp_pos01 = Dqn_V2_InitNx2(0.71f, 0.41f);
Dqn_Rect dest_rect = {}; gamepad_btn_rect.size = button_rect.size * 1.5f;
dest_rect.size = button_rect.size * 1.5f; gamepad_btn_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01);
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01);
TELY_Render_TextureColourV4(renderer, TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle, game->atlas_sprite_sheet.tex_handle,
button_rect, button_rect,
dest_rect, gamepad_btn_rect,
Dqn_V2_Zero /*rotate origin*/, Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/, 0.f /*rotation*/,
tex_mod_colour); tex_mod_colour);
} }
// NOTE: Render the building
{ {
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, mapping.upgrade_icon); TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, mapping.upgrade_icon);
Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index]; Dqn_Rect button_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect dest_rect = {}; Dqn_Rect dest_rect = {};
dest_rect.size = button_rect.size * .75f; dest_rect.size = button_rect.size * .75f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01 + Dqn_V2_InitNx2(0.12f, 0.08f)) - (dest_rect.size * .5f); dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, interp_pos01 + Dqn_V2_InitNx2(0.12f, 0.15f)) - (dest_rect.size * .5f);
TELY_Render_TextureColourV4(renderer, TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle, game->atlas_sprite_sheet.tex_handle,
button_rect, button_rect,
@ -2982,7 +3012,28 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
tex_mod_colour); tex_mod_colour);
} }
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.78f, 0.28f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.upgrade_base_price); // NOTE: Render the $ cost
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(1.f, -0.8f)), Dqn_V2_InitNx2(0.5, 0.f), "$%u", *mapping.upgrade_base_price);
// NOTE: Render the keyboard binding =======================================
{
DQN_ASSERT(key_bind.scan_code >= TELY_PlatformInputScanCode_A && key_bind.scan_code <= TELY_PlatformInputScanCode_Z);
char scan_code_ch = DQN_CAST(char)('A' + (key_bind.scan_code - TELY_PlatformInputScanCode_A));
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
TELY_AssetFont const *font = TELY_Render_Font(renderer, assets);
Dqn_String8 key_bind_label = Dqn_String8_InitF(scratch.allocator, "[%c]", scan_code_ch);
Dqn_Rect key_bind_rect = {};
key_bind_rect.pos = Dqn_Rect_InterpolatedPoint(gamepad_btn_rect, Dqn_V2_InitNx2(-0.1f, 1.1f));
key_bind_rect.size = TELY_Asset_MeasureText(font, key_bind_label);
key_bind_rect = Dqn_Rect_Expand(key_bind_rect, 2.f);
TELY_Render_PushColourV4(renderer, TELY_Colour_V4Alpha(colour_accent_yellow, tex_mod_colour.a));
TELY_Render_RectColourV4(renderer, key_bind_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(keybind_btn_shadow_colour, tex_mod_colour.a));
TELY_Render_Text(renderer, Dqn_Rect_InterpolatedPoint(key_bind_rect, Dqn_V2_InitNx1(0.5f)), Dqn_V2_InitNx1(0.5f), key_bind_label);
TELY_Render_PopColourV4(renderer);
}
} }
} }
} }

View File

@ -374,6 +374,8 @@ struct FP_GameControls
FP_GameKeyBind left; FP_GameKeyBind left;
FP_GameKeyBind right; FP_GameKeyBind right;
FP_GameKeyBind attack; FP_GameKeyBind attack;
FP_GameKeyBind buy_building;
FP_GameKeyBind buy_upgrade;
FP_GameKeyBind range_attack; FP_GameKeyBind range_attack;
FP_GameKeyBind build_mode; FP_GameKeyBind build_mode;
FP_GameKeyBind strafe; FP_GameKeyBind strafe;