patrol_system.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "patrol_system.h"
  2. #include "../core/component.h"
  3. #include "../core/world.h"
  4. #include <QVector3D>
  5. #include <cmath>
  6. namespace Game::Systems {
  7. void PatrolSystem::update(Engine::Core::World *world, float) {
  8. if (world == nullptr) {
  9. return;
  10. }
  11. auto entities = world->get_entities_with<Engine::Core::PatrolComponent>();
  12. for (auto *entity : entities) {
  13. auto *patrol = entity->get_component<Engine::Core::PatrolComponent>();
  14. auto *movement = entity->get_component<Engine::Core::MovementComponent>();
  15. auto *transform = entity->get_component<Engine::Core::TransformComponent>();
  16. auto *unit = entity->get_component<Engine::Core::UnitComponent>();
  17. if ((patrol == nullptr) || (movement == nullptr) ||
  18. (transform == nullptr) || (unit == nullptr)) {
  19. continue;
  20. }
  21. if (!patrol->patrolling || patrol->waypoints.size() < 2) {
  22. continue;
  23. }
  24. if (unit->health <= 0) {
  25. patrol->patrolling = false;
  26. continue;
  27. }
  28. auto *attack_target =
  29. entity->get_component<Engine::Core::AttackTargetComponent>();
  30. if ((attack_target != nullptr) && attack_target->target_id != 0) {
  31. continue;
  32. }
  33. bool enemy_nearby = false;
  34. auto all_entities = world->get_entities_with<Engine::Core::UnitComponent>();
  35. for (auto *other : all_entities) {
  36. auto *other_unit = other->get_component<Engine::Core::UnitComponent>();
  37. auto *other_transform =
  38. other->get_component<Engine::Core::TransformComponent>();
  39. if ((other_unit == nullptr) || (other_transform == nullptr) ||
  40. other_unit->health <= 0) {
  41. continue;
  42. }
  43. if (other_unit->owner_id == unit->owner_id) {
  44. continue;
  45. }
  46. if (other->has_component<Engine::Core::BuildingComponent>()) {
  47. continue;
  48. }
  49. float const dx = other_transform->position.x - transform->position.x;
  50. float const dz = other_transform->position.z - transform->position.z;
  51. float const dist_sq = dx * dx + dz * dz;
  52. if (dist_sq < 25.0F) {
  53. enemy_nearby = true;
  54. if (attack_target == nullptr) {
  55. entity->add_component<Engine::Core::AttackTargetComponent>();
  56. attack_target =
  57. entity->get_component<Engine::Core::AttackTargetComponent>();
  58. }
  59. if (attack_target != nullptr) {
  60. attack_target->target_id = other->get_id();
  61. attack_target->should_chase = false;
  62. }
  63. break;
  64. }
  65. }
  66. if (enemy_nearby) {
  67. continue;
  68. }
  69. auto waypoint = patrol->waypoints[patrol->current_waypoint];
  70. float target_x = waypoint.first;
  71. float target_z = waypoint.second;
  72. float const dx = target_x - transform->position.x;
  73. float const dz = target_z - transform->position.z;
  74. float const dist_sq = dx * dx + dz * dz;
  75. if (dist_sq < 1.0F) {
  76. patrol->current_waypoint =
  77. (patrol->current_waypoint + 1) % patrol->waypoints.size();
  78. waypoint = patrol->waypoints[patrol->current_waypoint];
  79. target_x = waypoint.first;
  80. target_z = waypoint.second;
  81. }
  82. movement->has_target = true;
  83. movement->target_x = target_x;
  84. movement->target_y = target_z;
  85. movement->goal_x = target_x;
  86. movement->goal_y = target_z;
  87. }
  88. }
  89. } // namespace Game::Systems