fp: Hook up the buildings to the merchant UI

This commit is contained in:
doyle 2023-10-07 12:21:31 +11:00
parent d5ceea9c94
commit 4628731bef
2 changed files with 155 additions and 67 deletions

View File

@ -5,7 +5,6 @@
Dqn_f32 const PHYSICS_STEP = 1 / 60.f;
Dqn_Rect FP_Game_GetBuildingPlacementRectForEntity(FP_Game *game, FP_GamePlaceableBuilding placeable_building, FP_GameEntityHandle handle)
{
Dqn_Rect result = {};
@ -527,13 +526,18 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
}
if (we_are_clicked_entity) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_K) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_Y)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
} else if (acceleration_meters_per_s->x || acceleration_meters_per_s->y) {
if (game->active_menu == FP_GameActiveMenu_Nil) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_K) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_Y)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
}
}
if (action->next_state == action->state && (acceleration_meters_per_s->x || acceleration_meters_per_s->y)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run);
}
}
@ -569,14 +573,18 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
}
if (we_are_clicked_entity) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_K) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_Y)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_LeftControl) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_A)) {
if (game->active_menu == FP_GameActiveMenu_Nil) {
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_K) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_Y)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_RangeAttack);
}
}
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_LeftControl) ||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_A)) {
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Dash);
}
}
@ -619,8 +627,9 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
case FP_GameDirection_Right: {
dir_vector.x = +1.f;
entity->attack_box_offset = Dqn_V2_InitNx2(entity->local_hit_box_offset.x + entity->attack_box_size.w,
entity->local_hit_box_offset.y);
entity->attack_box_offset = Dqn_V2_InitNx2(
entity->local_hit_box_offset.x + entity->attack_box_size.w,
entity->local_hit_box_offset.y);
} break;
case FP_GameDirection_Up: {
@ -1708,7 +1717,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
if (game->build_mode_can_place_building &&
TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F)) {
TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J)) {
if (placeable_building.type == FP_EntityType_ClubTerry) {
FP_Entity_CreateClubTerry(game, placement_pos, "Club Terry");
} else if (placeable_building.type == FP_EntityType_ChurchTerry) {
@ -2196,11 +2205,13 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
struct FP_MerchantToMenuMapping {
FP_GameEntityHandle merchant;
Dqn_String8 menu_anim;
Dqn_String8 building;
Dqn_V2 building_offset01;
} merchants[] = {
{game->merchant_terry, g_anim_names.merchant_terry_menu},
{game->merchant_graveyard, g_anim_names.merchant_graveyard_menu},
{game->merchant_gym, g_anim_names.merchant_gym_menu},
{game->merchant_phone_company, g_anim_names.merchant_phone_company_menu},
{game->merchant_terry, g_anim_names.merchant_terry_menu, g_anim_names.club_terry_dark, Dqn_V2_InitNx2(0.015f, +0.04f)},
{game->merchant_graveyard, g_anim_names.merchant_graveyard_menu, g_anim_names.airport_terry, Dqn_V2_InitNx2(0, -0.1f)},
{game->merchant_gym, g_anim_names.merchant_gym_menu, g_anim_names.church_terry_dark, Dqn_V2_InitNx2(0.04f, -0.15f)},
{game->merchant_phone_company, g_anim_names.merchant_phone_company_menu, g_anim_names.kennel_terry, Dqn_V2_InitNx2(0, +0)},
};
bool activated_merchant = false;
@ -2213,8 +2224,9 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
continue;
activated_merchant = true;
// NOTE: Render animated merchant menu
Dqn_Rect merchant_menu_rect = {};
// NOTE: Render animated merchant menu =============================
uint64_t const buy_duration_ms = 500;
Dqn_Rect merchant_menu_rect = {};
{
FP_GameRenderSprite *sprite = &game->player_merchant_menu;
if (!sprite->asset.anim || sprite->asset.anim->label != mapping.menu_anim) {
@ -2222,17 +2234,6 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
sprite->started_at_clock_ms = game->clock_ms;
}
bool trigger_buy_anim = false;
uint64_t buy_duration_ms = 500;
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J)) {
game->player_trigger_purchase_timestamp = game->clock_ms + buy_duration_ms;
} else if (TELY_Platform_InputScanCodeIsDown(input, TELY_PlatformInputScanCode_J)) {
trigger_buy_anim = true;
if (game->clock_ms > game->player_trigger_purchase_timestamp) {
// TODO(doyle): Do buy logic
}
}
uint64_t elapsed_ms = game->clock_ms - sprite->started_at_clock_ms;
uint16_t raw_anim_frame = DQN_CAST(uint16_t)(elapsed_ms / sprite->asset.anim->ms_per_frame);
uint16_t anim_frame = raw_anim_frame % sprite->asset.anim->count;
@ -2252,40 +2253,126 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/,
TELY_COLOUR_WHITE_V4);
if (trigger_buy_anim) {
uint64_t start_buy_time = game->player_trigger_purchase_timestamp - buy_duration_ms;
uint64_t elapsed_time = game->clock_ms - start_buy_time;
Dqn_f32 buy_t = DQN_MIN(elapsed_time / DQN_CAST(Dqn_f32)buy_duration_ms, 1.f);
Dqn_Rect buy_lerp_rect = {};
buy_lerp_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.68f, 0.215f));
buy_lerp_rect.size.w = (merchant_menu_rect.size.w * 0.211f) * buy_t;
buy_lerp_rect.size.h = merchant_menu_rect.size.h * .611f;
TELY_Render_RectColourV4(renderer, buy_lerp_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, 0.5f));
}
}
// NOTE: Render the merchant button
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 dest_rect = {};
dest_rect.size = button_rect.size * 1.5f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.75f, 0.5f));
TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle,
button_rect,
dest_rect,
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/,
TELY_COLOUR_WHITE_V4);
TELY_Render_PushColourV4(renderer, TELY_COLOUR_WHITE_V4);
TELY_Render_PushFont(renderer, game->talkco_font_large);
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0.5f, -1)), Dqn_V2_InitNx2(0.5, 0.f), "$2");
TELY_Render_PopFont(renderer);
TELY_Render_PopColourV4(renderer);
DQN_DEFER {
TELY_Render_PopFont(renderer);
TELY_Render_PopColourV4(renderer);
};
// NOTE: Render the merchant button for buildings ==================
{
// NOTE: Buy trigger + animation ===============================
{
TELY_PlatformInputScanCode key = TELY_PlatformInputScanCode_J;
bool trigger_buy_anim = false;
if (TELY_Platform_InputScanCodeIsPressed(input, key)) {
game->player_trigger_purchase_building_timestamp = game->clock_ms + buy_duration_ms;
} else if (TELY_Platform_InputScanCodeIsDown(input, key)) {
trigger_buy_anim = true;
if (game->clock_ms > game->player_trigger_purchase_building_timestamp) {
// TODO(doyle): Do buy logic
}
}
if (trigger_buy_anim) {
uint64_t start_buy_time = game->player_trigger_purchase_building_timestamp - buy_duration_ms;
uint64_t elapsed_time = game->clock_ms - start_buy_time;
Dqn_f32 buy_t = DQN_MIN(elapsed_time / DQN_CAST(Dqn_f32)buy_duration_ms, 1.f);
Dqn_Rect buy_lerp_rect = {};
buy_lerp_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.297f, 0.215f));
buy_lerp_rect.size.w = (merchant_menu_rect.size.w * 0.38f) * buy_t;
buy_lerp_rect.size.h = merchant_menu_rect.size.h * .611f;
TELY_Render_RectColourV4(renderer, buy_lerp_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(TELY_COLOUR_BLUE_CADET_V4, 0.5f));
}
}
// NOTE: Render the (A) button =================================
{
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 dest_rect = {};
dest_rect.size = button_rect.size * 1.5f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.345f, 0.5f));
TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle,
button_rect,
dest_rect,
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/,
TELY_COLOUR_WHITE_V4);
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0.5f, -1)), Dqn_V2_InitNx2(0.5, 0.f), "$2");
}
// NOTE: Render the merchant shop item building ================
{
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, mapping.building);
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect dest_rect = {};
dest_rect.size = tex_rect.size * 0.35f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.42f, 0.25f) + mapping.building_offset01);
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: Render the merchant button for buildings
{
// NOTE: Buy trigger + animation ===============================
{
TELY_PlatformInputScanCode key = TELY_PlatformInputScanCode_K;
bool trigger_buy_anim = false;
if (TELY_Platform_InputScanCodeIsPressed(input, key)) {
game->player_trigger_purchase_upgrade_timestamp = game->clock_ms + buy_duration_ms;
} else if (TELY_Platform_InputScanCodeIsDown(input, key)) {
trigger_buy_anim = true;
if (game->clock_ms > game->player_trigger_purchase_upgrade_timestamp) {
// TODO(doyle): Do buy logic
}
}
if (trigger_buy_anim) {
uint64_t start_buy_time = game->player_trigger_purchase_upgrade_timestamp - buy_duration_ms;
uint64_t elapsed_time = game->clock_ms - start_buy_time;
Dqn_f32 buy_t = DQN_MIN(elapsed_time / DQN_CAST(Dqn_f32)buy_duration_ms, 1.f);
Dqn_Rect buy_lerp_rect = {};
buy_lerp_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.68f, 0.215f));
buy_lerp_rect.size.w = (merchant_menu_rect.size.w * 0.211f) * buy_t;
buy_lerp_rect.size.h = merchant_menu_rect.size.h * .611f;
TELY_Render_RectColourV4(renderer, buy_lerp_rect, TELY_RenderShapeMode_Fill, TELY_Colour_V4Alpha(TELY_COLOUR_RED_TOMATO_V4, 0.5f));
}
}
// NOTE: Render the (B) button =================================
{
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 dest_rect = {};
dest_rect.size = button_rect.size * 1.5f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(merchant_menu_rect, Dqn_V2_InitNx2(0.75f, 0.5f));
TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle,
button_rect,
dest_rect,
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/,
TELY_COLOUR_WHITE_V4);
TELY_Render_TextF(renderer, Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0.5f, -1)), Dqn_V2_InitNx2(0.5, 0.f), "$2");
}
}
}
if (activated_merchant) {

View File

@ -260,7 +260,8 @@ struct FP_Game
FP_GameEntityHandle player;
FP_GameRenderSprite player_merchant_menu;
uint64_t player_trigger_purchase_timestamp;
uint64_t player_trigger_purchase_upgrade_timestamp;
uint64_t player_trigger_purchase_building_timestamp;
FP_GameEntityHandle merchant_terry;
FP_GameEntityHandle merchant_graveyard;