420 lines
23 KiB
C++
420 lines
23 KiB
C++
#if defined(_CLANGD)
|
|
#pragma once
|
|
#include "feely_pona_unity.h"
|
|
#endif
|
|
|
|
static bool FP_Entity_IsBuildingForMobs(FP_GameEntity *entity)
|
|
{
|
|
bool result = entity->type == FP_EntityType_AirportTerry ||
|
|
entity->type == FP_EntityType_ClubTerry ||
|
|
entity->type == FP_EntityType_ChurchTerry ||
|
|
entity->type == FP_EntityType_KennelTerry;
|
|
return result;
|
|
}
|
|
|
|
static Dqn_f32 FP_Entity_CalcSpriteScaleForDesiredHeight(FP_Game *game, FP_Meters height, Dqn_Rect sprite_rect)
|
|
{
|
|
Dqn_f32 sprite_in_meters = FP_Game_PixelsToMetersNx1(game->play, sprite_rect.size.y);
|
|
Dqn_f32 result = height.meters / sprite_in_meters;
|
|
return result;
|
|
}
|
|
|
|
static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType type, uint32_t raw_state, FP_GameDirection direction)
|
|
{
|
|
FP_EntityRenderData result = {};
|
|
result.sheet = &game->atlas_sprite_sheet;
|
|
|
|
switch (type) {
|
|
case FP_EntityType_Nil: {
|
|
} break;
|
|
|
|
case FP_EntityType_Map: {
|
|
result.height.meters = 41.9f;
|
|
result.anim_name = g_anim_names.map;
|
|
} break;
|
|
|
|
case FP_EntityType_Terry: {
|
|
result.height.meters = 1.8f;
|
|
FP_EntityTerryState state = DQN_CAST(FP_EntityTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityTerryState_Idle: result.anim_name = g_anim_names.terry_walk_idle; break;
|
|
|
|
case FP_EntityTerryState_Attack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: {
|
|
result.anim_name = g_anim_names.terry_attack_up;
|
|
result.height.meters *= 1.5f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Down: {
|
|
result.anim_name = g_anim_names.terry_attack_down;
|
|
result.height.meters *= 1.6f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Left: {
|
|
result.anim_name = g_anim_names.terry_attack_side;
|
|
result.height.meters *= 1.5f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Right: {
|
|
result.anim_name = g_anim_names.terry_attack_side;
|
|
result.height.meters *= 1.5f;
|
|
result.flip = TELY_AssetFlip_X;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_RangeAttack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.terry_attack_phone_up; result.height.meters *= 1.25f; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_attack_phone_down; result.height.meters *= 1.25f; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_attack_phone_side; result.height.meters *= 1.25f; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_attack_phone_side; result.height.meters *= 1.25f; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_Dash: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.terry_ghost; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_ghost; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_ghost; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_ghost; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_Run: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: {
|
|
result.anim_name = g_anim_names.terry_walk_up;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(tex_rect.size.w * .3f, 0.f);
|
|
} break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_walk_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_walk_left; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_walk_right; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_DeadGhost: {
|
|
result.anim_name = g_anim_names.terry_death; break;
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Perry: {
|
|
result.height.meters = 1.72f;
|
|
FP_EntityPerryState state = DQN_CAST(FP_EntityPerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityTerryState_Idle: {
|
|
result.anim_name = g_anim_names.perry_walk_idle;
|
|
} break;
|
|
|
|
case FP_EntityTerryState_Attack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: {
|
|
result.anim_name = g_anim_names.perry_attack_up;
|
|
result.height.meters *= 1.5f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Down: {
|
|
result.anim_name = g_anim_names.perry_attack_down;
|
|
result.height.meters *= 1.6f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Left: {
|
|
result.anim_name = g_anim_names.perry_attack_side;
|
|
result.height.meters *= 1.5f;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Right: {
|
|
result.anim_name = g_anim_names.perry_attack_side;
|
|
result.height.meters *= 1.5f;
|
|
result.flip = TELY_AssetFlip_X;
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
|
|
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
|
|
} break;
|
|
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_RangeAttack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.perry_attack_phone_up; result.height.meters *= 1.35f; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.perry_attack_phone_down; result.height.meters *= 1.35f; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.perry_attack_phone_side; result.height.meters *= 1.35f; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.perry_attack_phone_side; result.height.meters *= 1.35f; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_Dash: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.perry_ghost; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.perry_ghost; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.perry_ghost; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.perry_ghost; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_Run: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.perry_walk_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.perry_walk_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.perry_walk_right; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.perry_walk_right; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityTerryState_DeadGhost: {
|
|
result.anim_name = g_anim_names.perry_death; break;
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Smoochie: {
|
|
result.height.meters = 1.6f;
|
|
FP_EntitySmoochieState state = DQN_CAST(FP_EntitySmoochieState)raw_state;
|
|
switch (state) {
|
|
case FP_EntitySmoochieState_Idle: result.anim_name = g_anim_names.smoochie_walk_down; break;
|
|
case FP_EntitySmoochieState_Attack: result.anim_name = g_anim_names.smoochie_attack_down; break;
|
|
case FP_EntitySmoochieState_HurtSide: result.anim_name = g_anim_names.smoochie_hurt_side; result.flip = direction == FP_GameDirection_Right ? TELY_AssetFlip_X : TELY_AssetFlip_No; break;
|
|
case FP_EntitySmoochieState_Death: result.anim_name = g_anim_names.smoochie_death; break;
|
|
case FP_EntitySmoochieState_Run: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.smoochie_walk_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.smoochie_walk_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.smoochie_walk_left; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.smoochie_walk_right; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_MerchantTerry: {
|
|
result.height.meters = 3.66f;
|
|
FP_EntityMerchantTerryState state = DQN_CAST(FP_EntityMerchantTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityMerchantTerryState_Idle: result.anim_name = g_anim_names.merchant_terry; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_MerchantGraveyard: {
|
|
result.height.meters = 3.66f;
|
|
FP_EntityMerchantGraveyardState state = DQN_CAST(FP_EntityMerchantGraveyardState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityMerchantGraveyardState_Idle: result.anim_name = g_anim_names.merchant_graveyard; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_MerchantGym: {
|
|
result.height.meters = 3.66f;
|
|
result.anim_name = g_anim_names.merchant_gym;
|
|
FP_EntityMerchantGymState state = DQN_CAST(FP_EntityMerchantGymState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityMerchantGymState_Idle: result.anim_name = g_anim_names.merchant_gym; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_MerchantPhoneCompany: {
|
|
result.height.meters = 5.f;
|
|
FP_EntityMerchantPhoneCompanyState state = DQN_CAST(FP_EntityMerchantPhoneCompanyState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityMerchantPhoneCompanyState_Idle: result.anim_name = g_anim_names.merchant_phone_company; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_ClubTerry: {
|
|
result.height.meters = 4.f;
|
|
FP_EntityClubTerryState state = DQN_CAST(FP_EntityClubTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityClubTerryState_Idle: result.anim_name = g_anim_names.club_terry_dark; break;
|
|
case FP_EntityClubTerryState_PartyTime: result.anim_name = g_anim_names.club_terry_alive; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Clinger: {
|
|
result.height.meters = 1.6f;
|
|
FP_EntityClingerState state = DQN_CAST(FP_EntityClingerState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityClingerState_Idle: result.anim_name = g_anim_names.clinger_walk_down; break;
|
|
|
|
case FP_EntityClingerState_Attack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.clinger_attack_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.clinger_attack_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.clinger_attack_side; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.clinger_attack_side; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityClingerState_Death: result.anim_name = g_anim_names.clinger_death; break;
|
|
|
|
case FP_EntityClingerState_Run: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.clinger_walk_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.clinger_walk_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.clinger_walk_down; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.clinger_walk_down; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Heart: {
|
|
result.height.meters = 4.f;
|
|
FP_EntityHeartState state = DQN_CAST(FP_EntityHeartState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityHeartState_Idle: result.anim_name = g_anim_names.heart; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_AirportTerry: {
|
|
result.height.meters = 4.f;
|
|
FP_EntityAirportTerryState state = DQN_CAST(FP_EntityAirportTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityAirportTerryState_Idle: result.anim_name = g_anim_names.airport_terry; break;
|
|
case FP_EntityAirportTerryState_FlyPassenger: result.anim_name = g_anim_names.airport_terry; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Catfish: {
|
|
result.height.meters = 1.6f;
|
|
FP_EntityCatfishState state = DQN_CAST(FP_EntityCatfishState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityCatfishState_Idle: result.anim_name = g_anim_names.catfish_walk_down; break;
|
|
case FP_EntityCatfishState_Attack: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.catfish_attack_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.catfish_attack_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.catfish_attack_side; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.catfish_attack_side; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
case FP_EntityCatfishState_Death: result.anim_name = g_anim_names.catfish_death; break;
|
|
case FP_EntityCatfishState_Run: {
|
|
switch (direction) {
|
|
case FP_GameDirection_Up: result.anim_name = g_anim_names.catfish_walk_up; break;
|
|
case FP_GameDirection_Down: result.anim_name = g_anim_names.catfish_walk_down; break;
|
|
case FP_GameDirection_Left: result.anim_name = g_anim_names.catfish_walk_side; break;
|
|
case FP_GameDirection_Right: result.anim_name = g_anim_names.catfish_walk_side; result.flip = TELY_AssetFlip_X; break;
|
|
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_ChurchTerry: {
|
|
result.height.meters = 4.f;
|
|
FP_EntityChurchTerryState state = DQN_CAST(FP_EntityChurchTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityChurchTerryState_Idle: result.anim_name = g_anim_names.church_terry_dark; break;
|
|
case FP_EntityChurchTerryState_ConvertPatron: result.anim_name = g_anim_names.church_terry_alive; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_KennelTerry: {
|
|
result.height.meters = 3.f;
|
|
FP_EntityKennelTerryState state = DQN_CAST(FP_EntityKennelTerryState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityKennelTerryState_Idle: result.anim_name = g_anim_names.kennel_terry; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_PhoneMessageProjectile: {
|
|
result.height.meters = 1.f;
|
|
result.anim_name = g_anim_names.terry_attack_phone_message;
|
|
} break;
|
|
|
|
case FP_EntityType_AirportTerryPlane: {
|
|
result.height.meters = 1.5f;
|
|
result.anim_name = g_anim_names.airport_terry_plane;
|
|
} break;
|
|
|
|
case FP_EntityType_MobSpawner: {
|
|
result.height.meters = 3.f;
|
|
FP_EntityMobSpawnerState state = DQN_CAST(FP_EntityMobSpawnerState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityMobSpawnerState_Idle: result.anim_name = g_anim_names.portal; break;
|
|
case FP_EntityMobSpawnerState_Shutdown: {
|
|
result.anim_name = g_anim_names.portal_break;
|
|
result.height.meters = 3.5f;
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_PortalMonkey: {
|
|
result.height.meters = 1.f;
|
|
result.anim_name = g_anim_names.portal_monk; break;
|
|
} break;
|
|
|
|
case FP_EntityType_Billboard: {
|
|
result.height.meters = 7.5f;
|
|
FP_EntityBillboardState state = DQN_CAST(FP_EntityBillboardState)raw_state;
|
|
switch (state) {
|
|
case FP_EntityBillboardState_Attack: result.anim_name = g_anim_names.map_billboard_attack; break;
|
|
case FP_EntityBillboardState_Dash: result.anim_name = g_anim_names.map_billboard_dash; break;
|
|
case FP_EntityBillboardState_Monkey: result.anim_name = g_anim_names.map_billboard_monkey; break;
|
|
case FP_EntityBillboardState_RangeAttack: result.anim_name = g_anim_names.map_billboard_range_attack; break;
|
|
case FP_EntityBillboardState_Strafe: result.anim_name = g_anim_names.map_billboard_strafe; break;
|
|
}
|
|
} break;
|
|
|
|
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
|
|
}
|
|
|
|
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
|
|
if (sprite_anim) {
|
|
result.sheet_rect = result.sheet->rects.data[sprite_anim->index];
|
|
Dqn_f32 size_scale = FP_Entity_CalcSpriteScaleForDesiredHeight(game, result.height, result.sheet_rect);
|
|
result.render_size = result.sheet_rect.size * size_scale;
|
|
result.sprite = TELY_Asset_MakeAnimatedSprite(result.sheet, result.anim_name, result.flip);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|