diff --git a/src/dxd_math.cpp b/src/dxd_math.cpp index 96f88a9..cb63645 100644 --- a/src/dxd_math.cpp +++ b/src/dxd_math.cpp @@ -42,6 +42,11 @@ bool operator>(vec2 const &a, vec2 const &b) return a.x > b.x && a.y > b.y; } +bool operator==(vec2 const &a, vec2 const &b) +{ + return a.x == b.x && a.y == b.y; +} + bool operator<(vec2i const &a, vec2i const &b) { return a.x < b.x && a.y < b.y; diff --git a/src/dxd_math.hpp b/src/dxd_math.hpp index 8046713..2481325 100644 --- a/src/dxd_math.hpp +++ b/src/dxd_math.hpp @@ -26,6 +26,7 @@ vec2 operator*(vec2 const &a, float const &b); vec2 operator/(vec2 const &a, float const &b); bool operator<(vec2 const &a, vec2 const &b); bool operator>(vec2 const &a, vec2 const &b); +bool operator==(vec2 const &a, vec2 const &b); // vec2i operators bool operator<(vec2i const &a, vec2i const &b); diff --git a/src/sim/af_spawner.cpp b/src/sim/af_spawner.cpp index d4489c8..dc17602 100644 --- a/src/sim/af_spawner.cpp +++ b/src/sim/af_spawner.cpp @@ -56,6 +56,8 @@ dxd::sim::Airfield *dxd::sim::AFSpawner::get_random_airfield(Airfield *exclude) auto it = _airfields.begin(); for (; it != _airfields.end() && sel; ++it, --sel); af = it->second; + if (!af->is_active()) + af = exclude; } while(af == exclude); return af; diff --git a/src/sim/af_spawner.hpp b/src/sim/af_spawner.hpp index afc071c..ce18978 100644 --- a/src/sim/af_spawner.hpp +++ b/src/sim/af_spawner.hpp @@ -19,7 +19,7 @@ private: int _next_spawn; const int _SPAWN_BOUNDS = 150; - const int _GRID_STRIDE = 4; + const int _GRID_STRIDE = 10; const int _GRID_MARGIN = 5; const int _GRID_BOUNDS = (_SPAWN_BOUNDS - _GRID_MARGIN * 2) / _GRID_STRIDE; const float _GRID_JITTER = (float)_GRID_STRIDE * 0.4f; diff --git a/src/sim/aircraft.cpp b/src/sim/aircraft.cpp index 7f26a4b..86da0b9 100644 --- a/src/sim/aircraft.cpp +++ b/src/sim/aircraft.cpp @@ -3,7 +3,17 @@ void dxd::sim::Aircraft::tick(float timestep, World *world) { - (void)world; + // Refactor into own function + float target_dist = norm2(_target - _position); + if (target_dist < _TARGET_REACHED_DIST2) + { + if (_target == _destination->get_position()) + { + _destination->arrived_at(); + world->remove_obj(this); + } + _target = _destination->get_position(); + } float target_angle = vec2_angle(_target - _position); float target_deviation = target_angle - _direction; diff --git a/src/sim/aircraft.hpp b/src/sim/aircraft.hpp index 538173b..a1f05f0 100644 --- a/src/sim/aircraft.hpp +++ b/src/sim/aircraft.hpp @@ -2,6 +2,7 @@ #include "../dxd_math.hpp" #include "world_object.hpp" +#include "airfield.hpp" namespace dxd::sim { @@ -12,6 +13,7 @@ private: vec2 _position; float _direction; float _speed; + Airfield *_destination; vec2 _target; int _trail_cooldown; @@ -19,12 +21,16 @@ private: const int _TRAIL_DURATION = 600; const float _MAX_TURN_RATE = 0.3f; const float _SPD_TO_KTS = 60.0f; + const float _TARGET_REACHED_DIST = 0.5f; + const float _TARGET_REACHED_DIST2 = _TARGET_REACHED_DIST*_TARGET_REACHED_DIST; public: - Aircraft(vec2 position, float direction, float speed, vec2 target) - : _position(position), _direction(direction), _speed(speed), _target(target) + Aircraft(vec2 position, float direction, float speed, Airfield *destination) + : _position(position), _direction(direction), _speed(speed), _destination(destination) { _trail_cooldown = _TRAIL_DELAY; + _target = destination->get_approach_point(); + destination->going_to(); } void tick(float timestep, World *world) override; diff --git a/src/sim/airfield.cpp b/src/sim/airfield.cpp index 0937aa3..24a501b 100644 --- a/src/sim/airfield.cpp +++ b/src/sim/airfield.cpp @@ -5,10 +5,13 @@ void dxd::sim::Airfield::tick(float timestep, World *world) { (void)timestep; - if (--_ttl == 0) + if (--_ttl <= 0) { - world->remove_obj(this); - //TODO: Free space in af_spawner + if (_pending_arrivals == 0) + { + world->remove_obj(this); + //TODO: Free space in af_spawner + } return; } @@ -17,9 +20,8 @@ void dxd::sim::Airfield::tick(float timestep, World *world) vec2 pos = _position + polar_to_vec2(_rw_heading, _RW_LENGTH+0.5); Airfield *target = _parent->get_random_airfield(this); - vec2 tgt_pos = target->get_position(); - Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt_pos); + Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, target); world->add_obj(af); _next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY); @@ -37,3 +39,8 @@ void dxd::sim::Airfield::draw(Renderer *rend) vec2 b = _position + polar_to_vec2(_rw_heading, -_RW_LENGTH); rend->line(a, b); } + +vec2 dxd::sim::Airfield::get_approach_point() +{ + return _position - polar_to_vec2(_rw_heading, _RW_LENGTH + _APPROACH_DIST); +} diff --git a/src/sim/airfield.hpp b/src/sim/airfield.hpp index 6786fef..faaf4b8 100644 --- a/src/sim/airfield.hpp +++ b/src/sim/airfield.hpp @@ -20,9 +20,12 @@ private: int _next_spawn; float _rw_heading; + int _pending_arrivals; + int const _MIN_TAKEOFF_DELAY = 600; int const _MAX_TAKEOFF_DELAY = 3000; int const _RW_LENGTH = 6; + float const _APPROACH_DIST = 20.0f; public: Airfield(AFSpawner *parent, vec2 position, int ttl, float rw_heading) @@ -32,6 +35,10 @@ public: } vec2 get_position() { return _position; } + vec2 get_approach_point(); + void going_to() { ++_pending_arrivals; } + void arrived_at() { --_pending_arrivals; } + bool is_active() { return _ttl > 0; } void tick(float timestep, World *world) override; void draw(Renderer *rend) override;