fp: Improve swarming of buildings

This commit is contained in:
2023-10-07 19:14:09 +11:00
parent 11cab9a726
commit d564ad225d
4 changed files with 159 additions and 111 deletions
+28 -16
View File
@@ -667,7 +667,7 @@ static Dqn_Slice<Dqn_V2I> FP_Game_AStarPathFind(FP_Game *game,
return result;
}
static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameWaypoint const *waypoint)
static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameEntityHandle src_entity, FP_GameWaypoint const *waypoint)
{
Dqn_V2 result = {};
if (!game || !waypoint)
@@ -683,26 +683,38 @@ static Dqn_V2 FP_Game_CalcWaypointWorldPos(FP_Game *game, FP_GameWaypoint const
result = FP_Game_CalcEntityWorldPos(game, waypoint_entity->handle);
} break;
case FP_GameWaypointType_ClosestSide: /*FALLTHRU*/
case FP_GameWaypointType_Side: {
// NOTE: Sweep entity with half the radius of the source entity
Dqn_Rect src_rect = FP_Game_CalcEntityWorldHitBox(game, src_entity);
Dqn_Rect entity_rect = FP_Game_CalcEntityWorldHitBox(game, waypoint_entity->handle);
switch (waypoint->type_direction) {
case FP_GameDirection_Up: {
result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y - entity_rect.size.h * .1f);
} break;
entity_rect.pos -= (src_rect.size * .5f);
entity_rect.size += src_rect.size;
case FP_GameDirection_Down: {
result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y + entity_rect.size.h + entity_rect.size.h * .1f);
} break;
Dqn_V2 side_pos_list[FP_GameDirection_Count] = {};
side_pos_list[FP_GameDirection_Up] = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y - entity_rect.size.h * .1f);
side_pos_list[FP_GameDirection_Down] = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w * .5f, entity_rect.pos.y + entity_rect.size.h + entity_rect.size.h * .1f);
side_pos_list[FP_GameDirection_Left] = Dqn_V2_InitNx2(entity_rect.pos.x - entity_rect.size.w * .1f, entity_rect.pos.y + entity_rect.size.h * .5f);
side_pos_list[FP_GameDirection_Right] = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w + entity_rect.size.w * .1f, entity_rect.pos.y + entity_rect.size.h * .5f);
case FP_GameDirection_Left: {
result = Dqn_V2_InitNx2(entity_rect.pos.x - entity_rect.size.w * .1f, entity_rect.pos.y + entity_rect.size.h * .5f);
} break;
if (waypoint->type == FP_GameWaypointType_Side) {
result = side_pos_list[waypoint->type_direction];
} else {
Dqn_f32 best_dist = DQN_F32_MAX;
for (Dqn_V2 target_pos : side_pos_list) {
Dqn_f32 dist_squared = Dqn_V2_LengthSq_V2x2(src_rect.pos, target_pos);
if (dist_squared < best_dist) {
best_dist = dist_squared;
result = target_pos;
}
}
case FP_GameDirection_Right: {
result = Dqn_V2_InitNx2(entity_rect.pos.x + entity_rect.size.w + entity_rect.size.w * .1f, entity_rect.pos.y + entity_rect.size.h * .5f);
} break;
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
Dqn_f32 curr_dist_to_entity = Dqn_V2_LengthSq_V2x2(entity_rect.pos, src_rect.pos);
if (curr_dist_to_entity < best_dist) {
// NOTE: We are already closer to the entity than the closest calculated side,
// we assume we're at the entity already.
result = FP_Game_CalcEntityWorldPos(game, src_entity);
}
}
} break;