transition_function #7
@ -415,7 +415,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
|
||||
switch (*state) {
|
||||
case FP_EntityTerryState_Nil: {
|
||||
action->next_state = FP_EntityTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityTerryState_Idle: {
|
||||
@ -429,7 +429,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_J) ||
|
||||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_X)) {
|
||||
} else if (dir_vector.x || dir_vector.y) {
|
||||
action->next_state = FP_EntityTerryState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@ -452,7 +452,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
}
|
||||
|
||||
if (action_has_finished) {
|
||||
action->next_state = FP_EntityTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Idle);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -475,15 +475,15 @@ 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)) {
|
||||
action->next_state = FP_EntityTerryState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
||||
} else if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_LeftShift) ||
|
||||
TELY_Platform_InputGamepadButtonCodeIsPressed(input, 0, TELY_PlatformInputGamepadButtonCode_A)) {
|
||||
action->next_state = FP_EntityTerryState_Dash;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Dash);
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity_has_velocity) {
|
||||
action->next_state = FP_EntityTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Idle);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -511,9 +511,9 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
if (action_has_finished) {
|
||||
if (entity_has_velocity) {
|
||||
// TODO(doyle): Not sure if this branch triggers properly.
|
||||
action->next_state = FP_EntityTerryState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Run);
|
||||
} else {
|
||||
action->next_state = FP_EntityTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Idle);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@ -571,7 +571,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
|
||||
switch (*state) {
|
||||
case FP_EntitySmoochieState_Nil: {
|
||||
action->next_state = FP_EntitySmoochieState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntitySmoochieState_Idle: {
|
||||
@ -585,14 +585,14 @@ 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)) {
|
||||
action->next_state = FP_EntitySmoochieState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
||||
} else if (dir_vector.x || dir_vector.y) {
|
||||
action->next_state = FP_EntitySmoochieState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity_has_velocity) {
|
||||
action->next_state = FP_EntitySmoochieState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Run);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -641,7 +641,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
}
|
||||
|
||||
// NOTE: Transition out of the action
|
||||
action->next_state = FP_EntitySmoochieState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Idle);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -654,7 +654,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
}
|
||||
|
||||
if (action_has_finished)
|
||||
action->next_state = FP_EntitySmoochieState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntitySmoochieState_AttackHeart: {
|
||||
@ -692,18 +692,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)) {
|
||||
action->next_state = FP_EntitySmoochieState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity_has_velocity) {
|
||||
action->next_state = FP_EntitySmoochieState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Idle);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
if (entity->is_dying && *state != FP_EntitySmoochieState_Death) {
|
||||
action->next_state = FP_EntitySmoochieState_Death;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Death);
|
||||
}
|
||||
|
||||
if (*state == FP_EntitySmoochieState_Attack) {
|
||||
@ -743,7 +743,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
|
||||
switch (*state) {
|
||||
case FP_EntityClingerState_Nil: {
|
||||
action->next_state = FP_EntityClingerState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityClingerState_Idle: {
|
||||
@ -756,14 +756,14 @@ 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)) {
|
||||
action->next_state = FP_EntityClingerState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||
} else if (dir_vector.x || dir_vector.y) {
|
||||
action->next_state = FP_EntityClingerState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity_has_velocity) {
|
||||
action->next_state = FP_EntityClingerState_Run;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Run);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -786,7 +786,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
}
|
||||
|
||||
if (action_has_finished)
|
||||
action->next_state = FP_EntityClingerState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityClingerState_Death: {
|
||||
@ -821,18 +821,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)) {
|
||||
action->next_state = FP_EntityClingerState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||
}
|
||||
}
|
||||
|
||||
if (!entity_has_velocity) {
|
||||
action->next_state = FP_EntityClingerState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
if (entity->is_dying && *state != FP_EntityClingerState_Death) {
|
||||
action->next_state = FP_EntityClingerState_Death;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Death);
|
||||
}
|
||||
|
||||
if (*state == FP_EntityClingerState_Attack) { // NOTE: Position the attack box
|
||||
@ -870,7 +870,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
TELY_AssetSpriteSheet *sheet = &game->terry_merchant_sprite_sheet;
|
||||
switch (*state) {
|
||||
case FP_EntityTerryMerchantState_Nil: {
|
||||
action->next_state = FP_EntityTerryMerchantState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityTerryMerchantState_Idle: {
|
||||
@ -890,7 +890,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
|
||||
switch (*state) {
|
||||
case FP_EntityClubTerryState_Nil: {
|
||||
action->next_state = FP_EntityClubTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClubTerryState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityClubTerryState_Idle: {
|
||||
@ -916,7 +916,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
patron->base_acceleration_per_s.meters *= .5f;
|
||||
entity->club_terry_patron = {};
|
||||
}
|
||||
action->next_state = FP_EntityClubTerryState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClubTerryState_Idle);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@ -929,7 +929,7 @@ void FP_EntityActionStateMachine(FP_Game *game, TELY_Audio *audio, TELY_Platform
|
||||
|
||||
switch (*state) {
|
||||
case FP_EntityMapState_Nil: {
|
||||
action->next_state = FP_EntityMapState_Idle;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityMapState_Idle);
|
||||
} break;
|
||||
|
||||
case FP_EntityMapState_Idle: {
|
||||
@ -1173,7 +1173,7 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
||||
FP_GameEntity *club = waypoint_entity;
|
||||
if (FP_Game_IsNilEntityHandle(game, club->club_terry_patron)) {
|
||||
club->club_terry_patron = entity->handle;
|
||||
club->action.next_state = FP_EntityClubTerryState_PartyTime;
|
||||
FP_Game_EntityTransitionState(game, club, FP_EntityClubTerryState_PartyTime);
|
||||
entity->flags |= FP_GameEntityFlag_PartyingAtClubTerry;
|
||||
|
||||
Dqn_Rect hit_box = FP_Game_CalcEntityWorldHitBox(game, club->handle);
|
||||
@ -1216,12 +1216,12 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
|
||||
// TODO(doyle): We should check if it's valid to enter this new state
|
||||
// from the entity's current state
|
||||
if (entity->type == FP_EntityType_Terry) {
|
||||
entity->action.next_state = FP_EntityTerryState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityTerryState_Attack);
|
||||
} else if (entity->type == FP_EntityType_Smoochie) {
|
||||
entity->action.next_state = FP_EntitySmoochieState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntitySmoochieState_Attack);
|
||||
} else {
|
||||
DQN_ASSERT(entity->type == FP_EntityType_Clinger);
|
||||
entity->action.next_state = FP_EntityClingerState_Attack;
|
||||
FP_Game_EntityTransitionState(game, entity, FP_EntityClingerState_Attack);
|
||||
}
|
||||
|
||||
entity->direction = best_attack_dir;
|
||||
|
@ -56,6 +56,7 @@ static FP_GameEntityHandle FP_Entity_CreateClinger(FP_Game *game, Dqn_V2 pos, DQ
|
||||
entity->base_acceleration_per_s.meters = 8.f;
|
||||
entity->local_pos = pos;
|
||||
entity->sprite_height.meters = 1.6f;
|
||||
entity->attack_cooldown_ms = 1000;
|
||||
|
||||
entity->local_hit_box_size = FP_Game_MetersToPixelsNx2(game, 0.4f, entity->sprite_height.meters * .5f);
|
||||
FP_Entity_AddDebugEditorFlags(game, entity->handle);
|
||||
@ -78,6 +79,7 @@ static FP_GameEntityHandle FP_Entity_CreateSmoochie(FP_Game *game, Dqn_V2 pos, D
|
||||
entity->is_dying = false;
|
||||
entity->local_pos = pos;
|
||||
entity->sprite_height.meters = 1.6f;
|
||||
entity->attack_cooldown_ms = 1000;
|
||||
entity->local_hit_box_size = FP_Game_MetersToPixelsNx2(game, 0.4f, entity->sprite_height.meters * .6f);
|
||||
FP_Entity_AddDebugEditorFlags(game, entity->handle);
|
||||
entity->flags |= FP_GameEntityFlag_NonTraversable;
|
||||
@ -142,6 +144,7 @@ static FP_GameEntityHandle FP_Entity_CreateTerry(FP_Game *game, Dqn_V2 pos, DQN_
|
||||
entity->local_pos = pos;
|
||||
entity->base_acceleration_per_s.meters = 16.f;
|
||||
entity->sprite_height.meters = 1.8f;
|
||||
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;
|
||||
@ -191,3 +194,4 @@ static FP_GameEntityHandle FP_Entity_CreateClubTerry(FP_Game *game, Dqn_V2 pos,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -715,3 +715,29 @@ FP_GameFindClosestEntityResult FP_Game_FindClosestEntityWithType(FP_Game *game,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool FP_Game_CanEntityAttack(FP_GameEntity *entity, uint64_t current_time_ms)
|
||||
{
|
||||
bool result = (current_time_ms - entity->last_attack_timestamp) >= entity->attack_cooldown_ms;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void FP_Game_EntityTransitionState(FP_Game *game, FP_GameEntity *entity, uint32_t desired_state)
|
||||
{
|
||||
switch (desired_state) {
|
||||
case FP_EntityClingerState_Attack: {
|
||||
if (entity->type == FP_EntityType_ClubTerry) {
|
||||
break;
|
||||
}
|
||||
if (!FP_Game_CanEntityAttack(entity, game->clock_ms)) {
|
||||
// NOTE: Cooldown not met do not transition
|
||||
return;
|
||||
}
|
||||
|
||||
entity->last_attack_timestamp = game->clock_ms;
|
||||
} break;
|
||||
}
|
||||
// NOTE: If no returns are hit above we proceed with the state change
|
||||
entity->action.next_state = desired_state;
|
||||
}
|
||||
|
@ -168,6 +168,8 @@ struct FP_GameEntity
|
||||
Dqn_V2 attack_box_offset;
|
||||
bool attack_processed;
|
||||
bool is_dying;
|
||||
uint64_t last_attack_timestamp;
|
||||
uint64_t attack_cooldown_ms;
|
||||
|
||||
Dqn_FArray<Dqn_V2, 8> spawner_waypoints;
|
||||
FP_SentinelList<FP_GameEntityHandle> spawn_list;
|
||||
|
Loading…
Reference in New Issue
Block a user