healing_system.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "healing_system.h"
  2. #include "../core/component.h"
  3. #include "../core/world.h"
  4. #include "healing_beam_system.h"
  5. #include "healing_colors.h"
  6. #include "nation_id.h"
  7. #include <QDebug>
  8. #include <cmath>
  9. #include <qvectornd.h>
  10. #include <vector>
  11. namespace Game::Systems {
  12. void HealingSystem::update(Engine::Core::World *world, float delta_time) {
  13. process_healing(world, delta_time);
  14. }
  15. void HealingSystem::process_healing(Engine::Core::World *world,
  16. float delta_time) {
  17. auto healers = world->get_entities_with<Engine::Core::HealerComponent>();
  18. auto *healing_beam_system = world->get_system<HealingBeamSystem>();
  19. for (auto *healer : healers) {
  20. if (healer->has_component<Engine::Core::PendingRemovalComponent>()) {
  21. continue;
  22. }
  23. auto *healer_unit = healer->get_component<Engine::Core::UnitComponent>();
  24. auto *healer_transform =
  25. healer->get_component<Engine::Core::TransformComponent>();
  26. auto *healer_comp = healer->get_component<Engine::Core::HealerComponent>();
  27. if ((healer_unit == nullptr) || (healer_transform == nullptr) ||
  28. (healer_comp == nullptr)) {
  29. continue;
  30. }
  31. if (healer_unit->health <= 0) {
  32. continue;
  33. }
  34. healer_comp->time_since_last_heal += delta_time;
  35. if (healer_comp->time_since_last_heal < healer_comp->healing_cooldown) {
  36. continue;
  37. }
  38. bool healed_any = false;
  39. auto units = world->get_entities_with<Engine::Core::UnitComponent>();
  40. for (auto *target : units) {
  41. if (target->has_component<Engine::Core::PendingRemovalComponent>()) {
  42. continue;
  43. }
  44. auto *target_unit = target->get_component<Engine::Core::UnitComponent>();
  45. auto *target_transform =
  46. target->get_component<Engine::Core::TransformComponent>();
  47. if ((target_unit == nullptr) || (target_transform == nullptr)) {
  48. continue;
  49. }
  50. if (target_unit->health <= 0 ||
  51. target_unit->health >= target_unit->max_health) {
  52. continue;
  53. }
  54. if (target_unit->owner_id != healer_unit->owner_id) {
  55. continue;
  56. }
  57. float const dx =
  58. target_transform->position.x - healer_transform->position.x;
  59. float const dz =
  60. target_transform->position.z - healer_transform->position.z;
  61. float const dist = std::sqrt(dx * dx + dz * dz);
  62. if (dist <= healer_comp->healing_range) {
  63. target_unit->health += healer_comp->healing_amount;
  64. if (target_unit->health > target_unit->max_health) {
  65. target_unit->health = target_unit->max_health;
  66. }
  67. healer_comp->healing_target_x = target_transform->position.x;
  68. healer_comp->healing_target_z = target_transform->position.z;
  69. if (dist > 0.1F) {
  70. float const target_yaw = std::atan2(dx, dz) * 180.0F / 3.14159265F;
  71. healer_transform->desired_yaw = target_yaw;
  72. healer_transform->has_desired_yaw = true;
  73. }
  74. if (healing_beam_system != nullptr) {
  75. QVector3D const healer_pos(healer_transform->position.x,
  76. healer_transform->position.y + 1.2F,
  77. healer_transform->position.z);
  78. QVector3D const target_pos(target_transform->position.x,
  79. target_transform->position.y + 0.8F,
  80. target_transform->position.z);
  81. QVector3D const heal_color =
  82. get_healing_color(healer_unit->nation_id);
  83. healing_beam_system->spawn_beam(healer_pos, target_pos, heal_color,
  84. 0.7F);
  85. }
  86. healed_any = true;
  87. }
  88. }
  89. if (healed_any) {
  90. healer_comp->time_since_last_heal = 0.0F;
  91. healer_comp->is_healing_active = true;
  92. } else {
  93. healer_comp->is_healing_active = false;
  94. }
  95. }
  96. }
  97. } // namespace Game::Systems