|
@@ -149,106 +149,6 @@ void apply_hold_mode_bonuses(Engine::Core::Entity *attacker,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-auto chase_target(Engine::Core::Entity *attacker, Engine::Core::Entity *target,
|
|
|
|
|
- float range, bool is_ranged) -> bool {
|
|
|
|
|
- auto *target_transform =
|
|
|
|
|
- target->get_component<Engine::Core::TransformComponent>();
|
|
|
|
|
- auto *attacker_transform =
|
|
|
|
|
- attacker->get_component<Engine::Core::TransformComponent>();
|
|
|
|
|
-
|
|
|
|
|
- if ((target_transform == nullptr) || (attacker_transform == nullptr)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- QVector3D const attacker_pos(attacker_transform->position.x, 0.0F,
|
|
|
|
|
- attacker_transform->position.z);
|
|
|
|
|
- QVector3D const target_pos(target_transform->position.x, 0.0F,
|
|
|
|
|
- target_transform->position.z);
|
|
|
|
|
- QVector3D desired_pos = target_pos;
|
|
|
|
|
- bool hold_position = false;
|
|
|
|
|
-
|
|
|
|
|
- bool const target_is_building =
|
|
|
|
|
- target->has_component<Engine::Core::BuildingComponent>();
|
|
|
|
|
-
|
|
|
|
|
- if (target_is_building) {
|
|
|
|
|
- float const scale_x = target_transform->scale.x;
|
|
|
|
|
- float const scale_z = target_transform->scale.z;
|
|
|
|
|
- float const target_radius = std::max(scale_x, scale_z) * 0.5F;
|
|
|
|
|
- QVector3D direction = target_pos - attacker_pos;
|
|
|
|
|
- float const distance_sq = direction.lengthSquared();
|
|
|
|
|
- if (distance_sq > 0.000001F) {
|
|
|
|
|
- float const distance = std::sqrt(distance_sq);
|
|
|
|
|
- direction /= distance;
|
|
|
|
|
- float const desired_distance =
|
|
|
|
|
- target_radius + std::max(range - 0.2F, 0.2F);
|
|
|
|
|
- if (distance > desired_distance + 0.15F) {
|
|
|
|
|
- desired_pos = target_pos - direction * desired_distance;
|
|
|
|
|
- } else {
|
|
|
|
|
- hold_position = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } else if (is_ranged) {
|
|
|
|
|
- QVector3D direction = target_pos - attacker_pos;
|
|
|
|
|
- float const distance_sq = direction.lengthSquared();
|
|
|
|
|
- if (distance_sq > 0.000001F) {
|
|
|
|
|
- float const distance = std::sqrt(distance_sq);
|
|
|
|
|
- direction /= distance;
|
|
|
|
|
- float const optimal_range = range * Constants::kOptimalRangeFactor;
|
|
|
|
|
- if (distance > optimal_range + Constants::kOptimalRangeBuffer) {
|
|
|
|
|
- desired_pos = target_pos - direction * optimal_range;
|
|
|
|
|
- } else {
|
|
|
|
|
- hold_position = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- auto *movement = attacker->get_component<Engine::Core::MovementComponent>();
|
|
|
|
|
- if (movement == nullptr) {
|
|
|
|
|
- movement = attacker->add_component<Engine::Core::MovementComponent>();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (movement != nullptr) {
|
|
|
|
|
- if (hold_position) {
|
|
|
|
|
- movement->has_target = false;
|
|
|
|
|
- movement->vx = 0.0F;
|
|
|
|
|
- movement->vz = 0.0F;
|
|
|
|
|
- movement->path.clear();
|
|
|
|
|
- movement->target_x = attacker_transform->position.x;
|
|
|
|
|
- movement->target_y = attacker_transform->position.z;
|
|
|
|
|
- movement->goal_x = attacker_transform->position.x;
|
|
|
|
|
- movement->goal_y = attacker_transform->position.z;
|
|
|
|
|
- } else {
|
|
|
|
|
- QVector3D planned_target(movement->target_x, 0.0F, movement->target_y);
|
|
|
|
|
- if (!movement->path.empty()) {
|
|
|
|
|
- const auto &final_node = movement->path.back();
|
|
|
|
|
- planned_target = QVector3D(final_node.first, 0.0F, final_node.second);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- float const diff_sq = (planned_target - desired_pos).lengthSquared();
|
|
|
|
|
- bool need_new_command = !movement->path_pending;
|
|
|
|
|
- float const threshold =
|
|
|
|
|
- Constants::kNewCommandThreshold * Constants::kNewCommandThreshold;
|
|
|
|
|
- if (movement->has_target && diff_sq <= threshold) {
|
|
|
|
|
- need_new_command = false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (need_new_command) {
|
|
|
|
|
- CommandService::MoveOptions options;
|
|
|
|
|
- options.clear_attack_intent = false;
|
|
|
|
|
- options.allow_direct_fallback = true;
|
|
|
|
|
- std::vector<Engine::Core::EntityID> const unit_ids = {
|
|
|
|
|
- attacker->get_id()};
|
|
|
|
|
- std::vector<QVector3D> const move_targets = {desired_pos};
|
|
|
|
|
- CommandService::moveUnits(
|
|
|
|
|
- *static_cast<Engine::Core::World *>(nullptr), unit_ids,
|
|
|
|
|
- move_targets, options);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return is_in_range(attacker, target, range);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
void spawn_arrows(Engine::Core::Entity *attacker, Engine::Core::Entity *target,
|
|
void spawn_arrows(Engine::Core::Entity *attacker, Engine::Core::Entity *target,
|
|
|
ArrowSystem *arrow_sys) {
|
|
ArrowSystem *arrow_sys) {
|
|
|
if (arrow_sys == nullptr) {
|
|
if (arrow_sys == nullptr) {
|