Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
HomingSystem.cpp
Go to the documentation of this file.
1
7#include "RType/Math/Vec2.hpp"
9#include <limits>
10
11namespace rtp::server
12{
14 : _registry(registry)
15 {}
16
17 void HomingSystem::update(float dt)
18 {
25
26 // Early out if registry missing required arrays
27 auto homingRes = _registry.get<Homing>();
28 auto tfRes = _registry.get<Transform>();
29 auto velRes = _registry.get<Velocity>();
30 auto roomRes = _registry.get<RoomId>();
31 if (!homingRes || !tfRes || !velRes || !roomRes)
32 return;
33
34 auto &homings = homingRes->get();
35 auto &transforms = tfRes->get();
36 auto &vels = velRes->get();
37 auto &rooms = roomRes->get();
38
39 // We'll iterate candidates for targets
40 auto targetView = _registry.zipView<Transform, EntityType, Health, RoomId>();
41
42 for (auto &&[homing, tf, vel, room] : _registry.zipView<Homing, Transform, Velocity, RoomId>()) {
43 // find nearest hostile (Scout/Tank/Boss) in same room
44 float bestDist2 = std::numeric_limits<float>::infinity();
45 bool found = false;
46 rtp::Vec2f targetPos{0.0f, 0.0f};
47
48 for (auto &&[otf, otype, ohealth, oroom] : targetView) {
49 if (oroom.id != room.id)
50 continue;
51 // skip players and non-enemies
52 if (otype.type == net::EntityType::Player)
53 continue;
54 if (otype.type != net::EntityType::Scout &&
55 otype.type != net::EntityType::Tank &&
56 otype.type != net::EntityType::Boss &&
57 otype.type != net::EntityType::Boss2)
58 continue;
59
60 const float dx = otf.position.x - tf.position.x;
61 const float dy = otf.position.y - tf.position.y;
62 const float d2 = dx * dx + dy * dy;
63 if (d2 < bestDist2 && d2 <= homing.range * homing.range) {
64 bestDist2 = d2;
65 targetPos.x = otf.position.x;
66 targetPos.y = otf.position.y;
67 found = true;
68 }
69 }
70
71 if (!found)
72 continue;
73
74 // Compute desired normalized direction
75 rtp::Vec2f desired = rtp::Vec2f{targetPos.x - tf.position.x, targetPos.y - tf.position.y}.normalized();
76
77 if (vel.speed > 0.0f) {
78 // direction is normalized
79 rtp::Vec2f curr = vel.direction;
80 if (curr.squaredLength() == 0.0f) curr = desired;
81 else curr = curr.normalized();
82
83 // simple lerp by steering*dt
84 const float t = std::min(1.0f, homing.steering * dt);
85 rtp::Vec2f newDir = (curr * (1.0f - t) + desired * t).normalized();
86 vel.direction = newDir;
87 } else {
88 // direction is velocity vector in pixels/sec
89 const float currSpeed = vel.direction.length();
90 rtp::Vec2f currDir = currSpeed == 0.0f ? desired : vel.direction / currSpeed;
91 const float t = std::min(1.0f, homing.steering * dt);
92 rtp::Vec2f newDir = (currDir * (1.0f - t) + desired * t).normalized();
93 vel.direction = newDir * currSpeed;
94 }
95 }
96 }
97
98} // namespace rtp::server
Network packet implementation for R-Type protocol.
Declaration of the 2-dimensional vector class.
auto get(this const Self &self) -> std::expected< std::reference_wrapper< ConstLike< Self, SparseArray< T > > >, rtp::Error >
auto zipView(this Self &self)
void update(float dt) override
Update system logic for one frame.
HomingSystem(ecs::Registry &registry)
File : GameManager.hpp License: MIT Author : Elias Josué HAJJAR LLAUQUEN elias-josue....
constexpr auto length(this const Self &self) noexcept -> RealT
constexpr auto normalized(this const Self &self) noexcept -> std::remove_cvref_t< Self >
constexpr auto squaredLength(this const Self &self) noexcept -> T
Component representing an entity's health.
Definition Health.hpp:15
Marks an entity as homing and provides tuning parameters.
Definition Homing.hpp:17
Component representing a network identifier for an entity.
Definition RoomId.hpp:22
Component representing position, rotation, and scale of an entity.
Definition Transform.hpp:23
Component representing a 2D velocity.
Definition Velocity.hpp:17