auto_engagement.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "auto_engagement.h"
  2. #include "../../core/component.h"
  3. #include "../../core/world.h"
  4. #include "combat_types.h"
  5. #include "combat_utils.h"
  6. #include <cmath>
  7. namespace Game::Systems::Combat {
  8. void AutoEngagement::process(Engine::Core::World *world, float delta_time) {
  9. auto all_units = world->get_entities_with<Engine::Core::UnitComponent>();
  10. for (auto it = m_engagement_cooldowns.begin();
  11. it != m_engagement_cooldowns.end();) {
  12. it->second -= delta_time;
  13. if (it->second <= 0.0F) {
  14. it = m_engagement_cooldowns.erase(it);
  15. } else {
  16. ++it;
  17. }
  18. }
  19. for (auto *unit : all_units) {
  20. if (unit->has_component<Engine::Core::PendingRemovalComponent>()) {
  21. continue;
  22. }
  23. auto *unit_comp = unit->get_component<Engine::Core::UnitComponent>();
  24. if ((unit_comp == nullptr) || unit_comp->health <= 0) {
  25. continue;
  26. }
  27. if (unit->has_component<Engine::Core::BuildingComponent>()) {
  28. continue;
  29. }
  30. auto *attack_comp = unit->get_component<Engine::Core::AttackComponent>();
  31. if ((attack_comp == nullptr) || !attack_comp->can_melee) {
  32. continue;
  33. }
  34. if (attack_comp->can_ranged &&
  35. attack_comp->preferred_mode !=
  36. Engine::Core::AttackComponent::CombatMode::Melee) {
  37. continue;
  38. }
  39. if (!should_auto_engage_melee(unit)) {
  40. continue;
  41. }
  42. if (m_engagement_cooldowns.find(unit->get_id()) !=
  43. m_engagement_cooldowns.end()) {
  44. continue;
  45. }
  46. auto *guard_mode = unit->get_component<Engine::Core::GuardModeComponent>();
  47. bool const in_guard_mode = (guard_mode != nullptr) && guard_mode->active;
  48. if (!in_guard_mode && !is_unit_idle(unit)) {
  49. continue;
  50. }
  51. float detection_range = unit_comp->vision_range;
  52. if (in_guard_mode) {
  53. detection_range = std::min(detection_range, guard_mode->guard_radius);
  54. }
  55. auto *nearest_enemy =
  56. find_nearest_enemy_from_list(unit, all_units, world, detection_range);
  57. if (nearest_enemy != nullptr) {
  58. auto *attack_target =
  59. unit->get_component<Engine::Core::AttackTargetComponent>();
  60. if (attack_target == nullptr) {
  61. attack_target =
  62. unit->add_component<Engine::Core::AttackTargetComponent>();
  63. }
  64. if (attack_target != nullptr) {
  65. attack_target->target_id = nearest_enemy->get_id();
  66. attack_target->should_chase = !in_guard_mode;
  67. m_engagement_cooldowns[unit->get_id()] =
  68. Constants::k_engagement_cooldown;
  69. }
  70. }
  71. }
  72. }
  73. } // namespace Game::Systems::Combat