fp: Make mobs attack in the direction of terry

This commit is contained in:
doyle 2023-09-29 16:53:20 +10:00
parent d3462f8dc9
commit f8e0af730f

View File

@ -1050,25 +1050,50 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
bool can_attack = !entity->is_dying; bool can_attack = !entity->is_dying;
if (can_attack) { if (can_attack) {
Dqn_V2 attack_dir_vectors[FP_GameDirection_Count] = {};
attack_dir_vectors[FP_GameDirection_Up] = Dqn_V2_InitNx2(+0, -1);
attack_dir_vectors[FP_GameDirection_Down] = Dqn_V2_InitNx2(+0, +1);
attack_dir_vectors[FP_GameDirection_Left] = Dqn_V2_InitNx2(-1, +0);
attack_dir_vectors[FP_GameDirection_Right] = Dqn_V2_InitNx2(+1, +0);
Dqn_V2 defender_entity_pos = FP_Game_CalcEntityWorldPos(game, waypoint_entity->handle);
Dqn_V2 entity_to_defender = defender_entity_pos - entity_pos;
Dqn_V2 entity_to_defender_norm = Dqn_V2_Normalise(entity_to_defender);
FP_GameDirection best_attack_dir = FP_GameDirection_Up;
Dqn_f32 best_attack_dir_scalar_projection_onto_entity_to_waypoint_vector = -1.1f;
DQN_FOR_UINDEX (dir_index, FP_GameDirection_Count) {
Dqn_V2 attack_dir = attack_dir_vectors[dir_index];
Dqn_f32 scalar_projection = Dqn_V2_Dot(attack_dir, entity_to_defender_norm);
if (scalar_projection > best_attack_dir_scalar_projection_onto_entity_to_waypoint_vector) {
best_attack_dir = DQN_CAST(FP_GameDirection)dir_index;
best_attack_dir_scalar_projection_onto_entity_to_waypoint_vector = scalar_projection;
}
}
switch (entity->type) { switch (entity->type) {
case FP_EntityType_Nil: /*FALLTHRU*/ case FP_EntityType_Nil: /*FALLTHRU*/
case FP_EntityType_Merchant: break; case FP_EntityType_Merchant: break;
case FP_EntityType_Terry: { case FP_EntityType_Terry: /*FALLTHRU*/
// TODO(doyle): We should check if it's valid to enter this new state case FP_EntityType_Smoochie: /*FALLTHRU*/
// from the entity's current state
entity->action.next_state = FP_EntityTerryState_Attack;
} break;
case FP_EntityType_Smoochie: {
// TODO(doyle): We should check if it's valid to enter this new state
// from the entity's current state
entity->action.next_state = FP_EntitySmoochieState_Attack;
} break;
case FP_EntityType_Clinger: { case FP_EntityType_Clinger: {
// 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;
} else if (entity->type == FP_EntityType_Smoochie) {
entity->action.next_state = FP_EntitySmoochieState_Attack;
} else {
DQN_ASSERT(entity->type == FP_EntityType_Clinger);
entity->action.next_state = FP_EntityClingerState_Attack; entity->action.next_state = FP_EntityClingerState_Attack;
}
entity->direction = best_attack_dir;
} break; } break;
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
} }
} }
@ -1181,6 +1206,27 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
if ((defender->flags & FP_GameEntityFlag_Attackable) == 0) if ((defender->flags & FP_GameEntityFlag_Attackable) == 0)
continue; continue;
bool permit_attack = true;
switch (attacker->type) {
case FP_EntityType_Smoochie: {
if (defender->type == FP_EntityType_Smoochie || defender->type == FP_EntityType_Clinger)
permit_attack = false;
} break;
case FP_EntityType_Clinger: {
if (defender->type == FP_EntityType_Smoochie || defender->type == FP_EntityType_Clinger)
permit_attack = false;
} break;
case FP_EntityType_Nil: /*FALLTRHU*/
case FP_EntityType_Terry: /*FALLTRHU*/
case FP_EntityType_Merchant: /*FALLTRHU*/
case FP_EntityType_Count: break;
}
if (!permit_attack)
continue;
Dqn_Rect defender_box = FP_Game_CalcEntityWorldHitBox(game, defender->handle); Dqn_Rect defender_box = FP_Game_CalcEntityWorldHitBox(game, defender->handle);
if (!Dqn_Rect_Intersects(attacker_box, defender_box)) if (!Dqn_Rect_Intersects(attacker_box, defender_box))
continue; continue;