fp: Draw the particles for drunk-ness and church-ness

This commit is contained in:
doyle 2023-10-22 22:41:21 +11:00
parent 5c8fda7f9b
commit b78338bafc
2 changed files with 83 additions and 16 deletions

View File

@ -14,6 +14,19 @@ struct FP_ParticleDescriptor
Dqn_usize duration_ms;
};
static FP_ParticleDescriptor FP_DefaultFloatUpParticleDescriptor(Dqn_String8 anim_name, Dqn_usize duration_ms)
{
FP_ParticleDescriptor result = {};
result.anim_name = anim_name;
result.velocity.y = -16.f;
result.velocity_variance.y = (result.velocity.y * .5f);
result.velocity_variance.x = DQN_ABS(result.velocity.y);
result.colour_begin = TELY_COLOUR_WHITE_V4;
result.colour_end = TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, 0.f);
result.duration_ms = duration_ms;
return result;
}
static void FP_EmitParticle(FP_GamePlay *play, FP_ParticleDescriptor descriptor, Dqn_usize count)
{
DQN_FOR_UINDEX (index, count) {
@ -1026,6 +1039,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
if (entering_new_state) {
uint64_t duration_ms = 5000;
FP_Game_EntityActionReset(game, entity->handle, duration_ms, render_data.sprite);
TELY_Audio_Play(audio, game->audio[FP_GameAudio_Plane], 1.f);
}
if (action_has_finished) {
@ -1173,6 +1187,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
patron->flags &= ~(FP_GameEntityFlag_OccupiedInBuilding | FP_GameEntityFlag_RespondsToBuildings);
patron->faction = FP_GameEntityFaction_Friendly;
patron->converted_faction = true;
TELY_Audio_Play(audio, game->audio[FP_GameAudio_Church], 1.f);
}
entity->building_patron = {};
FP_Game_EntityTransitionState(game, entity, FP_EntityChurchTerryState_Idle);
@ -2031,6 +2046,19 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
}
entity->trauma01 = DQN_MAX(0.f, entity->trauma01 - 0.05f);
Dqn_Rect world_hit_box = FP_Game_CalcEntityWorldHitBox(game, entity->handle);
if (entity->is_drunk) {
if (game->play.clock_ms > entity->drunk_particles_end_ms) {
Dqn_usize duration_ms = 2000;
FP_ParticleDescriptor particle_desc = FP_DefaultFloatUpParticleDescriptor(g_anim_names.particle_drunk, duration_ms);
particle_desc.velocity_variance.x *= 2.f;
particle_desc.pos = Dqn_Rect_InterpolatedPoint(world_hit_box, Dqn_V2_InitNx2(0.5f, -0.1f));
particle_desc.colour_begin.a = .8f;
entity->drunk_particles_end_ms = game->play.clock_ms + duration_ms;
FP_EmitParticle(&game->play, particle_desc, 3);
}
}
// NOTE: Derive dynmamic bounding boxes ====================================================
if (entity->flags & FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox) {
@ -2490,11 +2518,6 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotate radians*/,
sprite_colour);
if (entity->converted_faction) {
Dqn_V2 label_p = Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0, -0.25f));
TELY_Render_TextF(renderer, label_p, Dqn_V2_InitNx2(0.f, 0.1f), "CONVERTED");
}
}
DQN_FOR_UINDEX(anim_index, entity->extra_cosmetic_anims.size) {
@ -2547,6 +2570,57 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
TELY_COLOUR_WHITE_V4);
}
if (entity->is_drunk) {
bool show_martini = entity->handle.id & 1;
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, show_martini ? g_anim_names.particle_drunk_martini : g_anim_names.particle_drunk_bottle);
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect dest_rect = {};
dest_rect.size = tex_rect.size;
if (show_martini) {
dest_rect.size *= 1.5f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box,
Dqn_V2_InitNx2(0.0f, 0.0f)) - (Dqn_V2_InitNx2(dest_rect.size.x * .6f, dest_rect.size.y * .7f));
dest_rect.pos.y += (DQN_SINF(DQN_CAST(Dqn_f32)input->timer_s * 2.f) + 1.f / 2.f) * dest_rect.size.y * .005f;
} else {
dest_rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box,
Dqn_V2_InitNx2(0.0f, 0.0f)) - (Dqn_V2_InitNx2(dest_rect.size.x * .7f, dest_rect.size.y * .9f));
}
dest_rect.pos.y += (DQN_SINF(DQN_CAST(Dqn_f32)input->timer_s * 2.f) + 1.f / 2.f) * dest_rect.size.y * .1f;
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);
}
if (entity->converted_faction) {
bool show_halo = entity->handle.id & 1;
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, show_halo ? g_anim_names.particle_church_halo : g_anim_names.particle_church_cross);
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect dest_rect = {};
dest_rect.size = tex_rect.size;
if (show_halo) {
dest_rect.size *= .6f;
dest_rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box,
Dqn_V2_InitNx2(0.5f, 0.0f)) - (Dqn_V2_InitNx2(dest_rect.size.x * .5f, dest_rect.size.y * 1.2f));
} else {
dest_rect.pos = Dqn_Rect_InterpolatedPoint(world_hit_box,
Dqn_V2_InitNx2(0.5f, 0.0f)) - (Dqn_V2_InitNx2(dest_rect.size.x * .5f, dest_rect.size.y * .9f));
}
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);
}
if (entity->handle != game->play.heart && entity->hp != entity->hp_cap && entity->hp) {
// NOTE: We don't draw health bar for the player either
bool current_entity_is_a_player = false;
@ -2906,18 +2980,9 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
}
// NOTE: Render the player(s) HUD and merchant menu interaction ============================
FP_ParticleDescriptor dollar_buy_particle = {};
{
dollar_buy_particle.anim_name = g_anim_names.particle_purchase;
dollar_buy_particle.velocity.y = -16.f;
dollar_buy_particle.velocity_variance.y = (dollar_buy_particle.velocity.y * .5f);
dollar_buy_particle.velocity_variance.x = DQN_ABS(dollar_buy_particle.velocity.y);
dollar_buy_particle.colour_begin = TELY_COLOUR_WHITE_V4;
dollar_buy_particle.colour_end = TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, 0.f);
dollar_buy_particle.duration_ms = 2000;
}
FP_ParticleDescriptor dollar_buy_particle = FP_DefaultFloatUpParticleDescriptor(g_anim_names.particle_purchase, 2000 /*duration*/);
Dqn_Rect first_player_avatar_rect = {};
DQN_FOR_UINDEX (player_index, game->play.players.size) {
FP_GameEntityHandle player_handle = game->play.players.data[player_index];
FP_GameEntity *player = FP_Game_GetEntity(game, player_handle);

View File

@ -271,6 +271,8 @@ struct FP_GameEntity
uint32_t base_attack;
bool is_drunk;
Dqn_usize drunk_particles_end_ms;
bool converted_faction;
FP_GameEntityFaction faction;