diff --git a/Data/Talkco.otf b/Data/Talkco.otf new file mode 100644 index 0000000..a6ae81d --- /dev/null +++ b/Data/Talkco.otf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8f55cbff360561de70ddc08a7e6e78023a5a3c5b591224fbd1880fd252739d6 +size 38508 diff --git a/External/tely b/External/tely index 8576ce0..f4ab2fb 160000 --- a/External/tely +++ b/External/tely @@ -1 +1 @@ -Subproject commit 8576ce00dc74f817b346994efca8610001a8eafb +Subproject commit f4ab2fbd147623ac38be6f92fedf0e0049aeafb5 diff --git a/feely_pona.cpp b/feely_pona.cpp index b6cb157..a4e75d2 100644 --- a/feely_pona.cpp +++ b/feely_pona.cpp @@ -482,9 +482,10 @@ void TELY_DLL_Init(void *user_data) uint16_t font_size = 18; game->camera.scale = Dqn_V2_InitNx1(1); - 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->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,9 +2255,9 @@ 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, - building_ui_size, - building_ui_size); + ui_start_y, + building_ui_size, + building_ui_size); Dqn_V4 texture_colour = TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, .5f); Dqn_V4 outline_colour = TELY_COLOUR_WHITE_PALE_GOLDENROD_V4; diff --git a/feely_pona_entity.h b/feely_pona_entity.h index 77043b8..c35a005 100644 --- a/feely_pona_entity.h +++ b/feely_pona_entity.h @@ -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); diff --git a/feely_pona_entity_create.cpp b/feely_pona_entity_create.cpp index 5b7ae7e..660f8a8 100644 --- a/feely_pona_entity_create.cpp +++ b/feely_pona_entity_create.cpp @@ -441,9 +441,11 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_ entity->attack_cooldown_ms = 500; entity->local_hit_box_size = FP_Game_MetersToPixelsNx2(game, 0.5f, entity->sprite_height.meters * .6f); FP_Entity_AddDebugEditorFlags(game, result); - entity->flags |= FP_GameEntityFlag_NonTraversable; - entity->flags |= FP_GameEntityFlag_Attackable; - entity->flags |= FP_GameEntityFlag_CameraTracking; + 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; } diff --git a/feely_pona_game.cpp b/feely_pona_game.cpp index 9ccae21..600502e 100644 --- a/feely_pona_game.cpp +++ b/feely_pona_game.cpp @@ -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; diff --git a/feely_pona_game.h b/feely_pona_game.h index e02f359..43be8c4 100644 --- a/feely_pona_game.h +++ b/feely_pona_game.h @@ -193,6 +193,8 @@ struct FP_GameEntity Dqn_FArray projectiles; uint64_t ttl_end_timestamp; FP_SentinelList 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 hero_sprite_anims;