patrol_system.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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->getEntitiesWith<Engine::Core::PatrolComponent>();
  12. for (auto *entity : entities) {
  13. auto *patrol = entity->getComponent<Engine::Core::PatrolComponent>();
  14. auto *movement = entity->getComponent<Engine::Core::MovementComponent>();
  15. auto *transform = entity->getComponent<Engine::Core::TransformComponent>();
  16. auto *unit = entity->getComponent<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->getComponent<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->getEntitiesWith<Engine::Core::UnitComponent>();
  35. for (auto *other : all_entities) {
  36. auto *other_unit = other->getComponent<Engine::Core::UnitComponent>();
  37. auto *other_transform =
  38. other->getComponent<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. float const dx = other_transform->position.x - transform->position.x;
  47. float const dz = other_transform->position.z - transform->position.z;
  48. float const dist_sq = dx * dx + dz * dz;
  49. if (dist_sq < 25.0F) {
  50. enemy_nearby = true;
  51. if (attack_target == nullptr) {
  52. entity->addComponent<Engine::Core::AttackTargetComponent>();
  53. attack_target =
  54. entity->getComponent<Engine::Core::AttackTargetComponent>();
  55. }
  56. if (attack_target != nullptr) {
  57. attack_target->target_id = other->getId();
  58. attack_target->shouldChase = false;
  59. }
  60. break;
  61. }
  62. }
  63. if (enemy_nearby) {
  64. continue;
  65. }
  66. auto waypoint = patrol->waypoints[patrol->currentWaypoint];
  67. float target_x = waypoint.first;
  68. float target_z = waypoint.second;
  69. float const dx = target_x - transform->position.x;
  70. float const dz = target_z - transform->position.z;
  71. float const dist_sq = dx * dx + dz * dz;
  72. if (dist_sq < 1.0F) {
  73. patrol->currentWaypoint =
  74. (patrol->currentWaypoint + 1) % patrol->waypoints.size();
  75. waypoint = patrol->waypoints[patrol->currentWaypoint];
  76. target_x = waypoint.first;
  77. target_z = waypoint.second;
  78. }
  79. movement->hasTarget = true;
  80. movement->target_x = target_x;
  81. movement->target_y = target_z;
  82. movement->goalX = target_x;
  83. movement->goalY = target_z;
  84. }
  85. }
  86. } // namespace Game::Systems