fp: Add a basic data plan visualisation

This commit is contained in:
doyle 2023-10-06 21:48:05 +11:00
parent cfb4106948
commit b5c8c45769
7 changed files with 69 additions and 11 deletions

BIN
Data/Talkco.otf (Stored with Git LFS) Normal file

Binary file not shown.

2
External/tely vendored

@ -1 +1 @@
Subproject commit 8576ce00dc74f817b346994efca8610001a8eafb
Subproject commit f4ab2fbd147623ac38be6f92fedf0e0049aeafb5

View File

@ -485,6 +485,7 @@ void TELY_DLL_Init(void *user_data)
game->inter_regular_font = platform->func_load_font(assets, DQN_STRING8("Inter (Regular)"), DQN_STRING8("Data/Inter-Regular.otf"), font_size);
game->inter_italic_font = platform->func_load_font(assets, DQN_STRING8("Inter (Italic)"), DQN_STRING8("Data/Inter-Italic.otf"), font_size);
game->jetbrains_mono_font = platform->func_load_font(assets, DQN_STRING8("JetBrains Mono NL (Regular)"), DQN_STRING8("Data/JetBrainsMonoNL-Regular.ttf"), font_size);
game->talkco_font = platform->func_load_font(assets, DQN_STRING8("Talkco"), DQN_STRING8("Data/Talkco.otf"), font_size);
game->audio[FP_GameAudio_TestAudio] = platform->func_load_audio(assets, DQN_STRING8("Test Audio"), DQN_STRING8("Data/Audio/Purrple Cat - Moonwinds.qoa"));
game->audio[FP_GameAudio_TerryHit] = platform->func_load_audio(assets, DQN_STRING8("Terry Hit"), DQN_STRING8("Data/Audio/terry_hit.ogg"));
game->audio[FP_GameAudio_Smooch] = platform->func_load_audio(assets, DQN_STRING8("Smooch"), DQN_STRING8("Data/Audio/smooch.mp3"));
@ -552,6 +553,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (entering_new_state) {
uint64_t duration_ms = render_data.sprite.anim->count * render_data.sprite.anim->ms_per_frame;
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
entity->terry_mobile_data_plan -= FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK;
}
if (action_has_finished) {
@ -1232,6 +1234,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
case FP_EntityType_Nil: break;
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
case FP_EntityType_PhoneMessageProjectile: break;
}
}
@ -1734,6 +1737,12 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
}
if (entity->type == FP_EntityType_Terry) {
entity->terry_mobile_data_plan =
DQN_MIN(entity->terry_mobile_data_plan + (FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK * .25f * PHYSICS_STEP),
entity->terry_mobile_data_plan_cap);
}
// NOTE: Derive dynmamic bounding boxes ====================================================
if (entity->flags & FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox) {
Dqn_Rect children_bbox = {};
@ -2166,8 +2175,41 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
}
}
}
}
// NOTE: Render player avatar HUD
Dqn_f32 ui_start_y = 32.f;
{
TELY_Render_PushTransform(renderer, Dqn_M2x3_Identity());
DQN_DEFER { TELY_Render_PopTransform(renderer); };
FP_GameEntity *player = FP_Game_GetEntity(game, game->player);
FP_EntityRenderData render_data = FP_Entity_GetRenderData(game, FP_EntityType_Terry, FP_EntityTerryState_Idle, FP_GameDirection_Down);
Dqn_Rect dest = {};
dest.size = render_data.render_size;
dest.pos.y = ui_start_y;
dest.pos.x = ui_start_y;
TELY_Render_TextureColourV4(renderer,
render_data.sheet->tex_handle,
render_data.sheet_rect,
dest,
Dqn_V2_Zero,
0.f,
TELY_COLOUR_WHITE_V4);
TELY_Render_PushFont(renderer, game->talkco_font);
Dqn_V2 next_pos = Dqn_Rect_InterpolatedPoint(dest, Dqn_V2_InitNx2(1.f, 0));
TELY_Render_TextF(renderer, next_pos, Dqn_V2_Zero, "Terry");
next_pos.y += TELY_Render_FontHeight(renderer, &platform->assets);
TELY_Render_TextF(renderer,
next_pos,
Dqn_V2_Zero,
"%$$$d/%$$$d",
player->terry_mobile_data_plan,
player->terry_mobile_data_plan_cap);
TELY_Render_PopFont(renderer);
}
if (!FP_Game_IsNilEntityHandle(game, game->clicked_entity)) {
@ -2213,7 +2255,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer)
FP_GamePlaceableBuilding building = PLACEABLE_BUILDINGS[building_index];
FP_EntityRenderData render_data = FP_Entity_GetRenderData(game, building.type, building.state, FP_GameDirection_Down);
Dqn_Rect rect = Dqn_Rect_InitNx4(start_x + (building_index * building_ui_size) + (padding * building_index),
32.f,
ui_start_y,
building_ui_size,
building_ui_size);

View File

@ -135,3 +135,5 @@ struct FP_EntityRenderData
Dqn_V2 render_size;
TELY_AssetAnimatedSprite sprite;
};
Dqn_usize const FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK = DQN_KILOBYTES(1);

View File

@ -444,6 +444,8 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_
entity->flags |= FP_GameEntityFlag_NonTraversable;
entity->flags |= FP_GameEntityFlag_Attackable;
entity->flags |= FP_GameEntityFlag_CameraTracking;
entity->terry_mobile_data_plan_cap = DQN_KILOBYTES(16);
entity->terry_mobile_data_plan = entity->terry_mobile_data_plan_cap;
return result;
}

View File

@ -737,12 +737,18 @@ static void FP_Game_EntityTransitionState(FP_Game *game, FP_GameEntity *entity,
{
switch (entity->type) {
case FP_EntityType_Terry: {
if (desired_state == FP_EntityTerryState_Attack) {
if (desired_state == FP_EntityTerryState_Attack ||
desired_state == FP_EntityTerryState_RangeAttack) {
if (!FP_Game_CanEntityAttack(entity, game->clock_ms)) {
// NOTE: Cooldown not met do not transition
return;
}
entity->last_attack_timestamp = game->clock_ms;
if (desired_state == FP_EntityTerryState_RangeAttack) {
if (entity->terry_mobile_data_plan < FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK)
return;
}
}
} break;

View File

@ -193,6 +193,8 @@ struct FP_GameEntity
Dqn_FArray<FP_GameEntityHandle, 4> projectiles;
uint64_t ttl_end_timestamp;
FP_SentinelList<FP_GameEntityHandle> buildings_visited;
Dqn_usize terry_mobile_data_plan;
Dqn_usize terry_mobile_data_plan_cap;
};
struct FP_GameEntityIterator
@ -231,6 +233,7 @@ struct FP_Game
TELY_AssetFontHandle inter_regular_font;
TELY_AssetFontHandle inter_italic_font;
TELY_AssetFontHandle jetbrains_mono_font;
TELY_AssetFontHandle talkco_font;
TELY_AssetAudioHandle audio[FP_GameAudio_Count];
Dqn_Slice<TELY_AssetSpriteAnimation> hero_sprite_anims;