guard_system.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "guard_system.h"
  2. #include "../core/component.h"
  3. #include "../core/world.h"
  4. #include "command_service.h"
  5. #include <QVector3D>
  6. #include <cmath>
  7. namespace Game::Systems {
  8. void GuardSystem::update(Engine::Core::World *world, float) {
  9. if (world == nullptr) {
  10. return;
  11. }
  12. auto entities = world->get_entities_with<Engine::Core::GuardModeComponent>();
  13. for (auto *entity : entities) {
  14. auto *guard_mode =
  15. entity->get_component<Engine::Core::GuardModeComponent>();
  16. auto *movement = entity->get_component<Engine::Core::MovementComponent>();
  17. auto *transform = entity->get_component<Engine::Core::TransformComponent>();
  18. auto *unit = entity->get_component<Engine::Core::UnitComponent>();
  19. if ((guard_mode == nullptr) || (movement == nullptr) ||
  20. (transform == nullptr) || (unit == nullptr)) {
  21. continue;
  22. }
  23. if (!guard_mode->active || !guard_mode->has_guard_target) {
  24. continue;
  25. }
  26. if (unit->health <= 0) {
  27. continue;
  28. }
  29. auto *attack_target =
  30. entity->get_component<Engine::Core::AttackTargetComponent>();
  31. if ((attack_target != nullptr) && attack_target->target_id != 0) {
  32. continue;
  33. }
  34. if (guard_mode->guarded_entity_id != 0) {
  35. auto *guarded_entity = world->get_entity(guard_mode->guarded_entity_id);
  36. if (guarded_entity != nullptr) {
  37. auto *guarded_transform =
  38. guarded_entity->get_component<Engine::Core::TransformComponent>();
  39. if (guarded_transform != nullptr) {
  40. float const new_guard_x = guarded_transform->position.x;
  41. float const new_guard_z = guarded_transform->position.z;
  42. float const dx = new_guard_x - transform->position.x;
  43. float const dz = new_guard_z - transform->position.z;
  44. float const dist_sq = dx * dx + dz * dz;
  45. constexpr float kFollowThresholdSq = 2.0F * 2.0F;
  46. if (dist_sq > kFollowThresholdSq) {
  47. guard_mode->guard_position_x = new_guard_x;
  48. guard_mode->guard_position_z = new_guard_z;
  49. bool const already_moving_to_target =
  50. movement->has_target &&
  51. std::abs(movement->goal_x - new_guard_x) < 0.5F &&
  52. std::abs(movement->goal_y - new_guard_z) < 0.5F;
  53. if (!already_moving_to_target) {
  54. CommandService::MoveOptions opts;
  55. opts.clear_attack_intent = false;
  56. opts.allow_direct_fallback = true;
  57. std::vector<Engine::Core::EntityID> const ids = {
  58. entity->get_id()};
  59. std::vector<QVector3D> const targets = {
  60. QVector3D(new_guard_x, 0.0F, new_guard_z)};
  61. CommandService::move_units(*world, ids, targets, opts);
  62. guard_mode->returning_to_guard_position = true;
  63. }
  64. }
  65. }
  66. }
  67. } else {
  68. if (!guard_mode->returning_to_guard_position) {
  69. float const dx = guard_mode->guard_position_x - transform->position.x;
  70. float const dz = guard_mode->guard_position_z - transform->position.z;
  71. float const dist_sq = dx * dx + dz * dz;
  72. float const kReturnThresholdSq =
  73. Engine::Core::Defaults::kGuardReturnThreshold *
  74. Engine::Core::Defaults::kGuardReturnThreshold;
  75. if (dist_sq > kReturnThresholdSq) {
  76. CommandService::MoveOptions opts;
  77. opts.clear_attack_intent = false;
  78. opts.allow_direct_fallback = true;
  79. std::vector<Engine::Core::EntityID> const ids = {entity->get_id()};
  80. std::vector<QVector3D> const targets = {
  81. QVector3D(guard_mode->guard_position_x, 0.0F,
  82. guard_mode->guard_position_z)};
  83. CommandService::move_units(*world, ids, targets, opts);
  84. guard_mode->returning_to_guard_position = true;
  85. }
  86. }
  87. }
  88. }
  89. }
  90. } // namespace Game::Systems