feat: Primitive airfield navigation
This commit is contained in:
@@ -2,17 +2,10 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
||||
void dxd::sim::AFSpawner::spawn_airfield(World *world)
|
||||
{
|
||||
(void)timestep;
|
||||
|
||||
if (--_next_spawn != 0)
|
||||
return;
|
||||
|
||||
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
||||
|
||||
vec2i base_pos;
|
||||
//TODO: Set limiter
|
||||
//TODO: Iter limiter
|
||||
do
|
||||
base_pos = rand_v2i({ -_GRID_BOUNDS, -_GRID_BOUNDS }, { _GRID_BOUNDS, _GRID_BOUNDS });
|
||||
while (_airfields.find(base_pos) != _airfields.end());
|
||||
@@ -20,13 +13,50 @@ void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
||||
vec2 off = rand_v2({ -_GRID_JITTER, -_GRID_JITTER }, { _GRID_JITTER, _GRID_JITTER });
|
||||
vec2 pos = v2i_to_v2(base_pos) * _GRID_STRIDE + off;
|
||||
|
||||
Airfield *af = new Airfield(pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
|
||||
Airfield *af = new Airfield(this, pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
|
||||
world->add_obj(af);
|
||||
_airfields.emplace(base_pos, af);
|
||||
}
|
||||
|
||||
void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
||||
{
|
||||
(void)timestep;
|
||||
|
||||
if (_next_spawn == -1) //Init
|
||||
{
|
||||
spawn_airfield(world);
|
||||
spawn_airfield(world);
|
||||
_next_spawn = _MIN_SPAWN_DELAY;
|
||||
return;
|
||||
}
|
||||
|
||||
if (--_next_spawn != 0)
|
||||
return;
|
||||
|
||||
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
||||
|
||||
spawn_airfield(world);
|
||||
}
|
||||
|
||||
void dxd::sim::AFSpawner::draw(Renderer *rend)
|
||||
{
|
||||
rend->color(0, 127, 0);
|
||||
rend->rect(vec2_zero, _SPAWN_BOUNDS*2);
|
||||
}
|
||||
|
||||
dxd::sim::Airfield *dxd::sim::AFSpawner::get_random_airfield(Airfield *exclude)
|
||||
{
|
||||
int count = (int)_airfields.size();
|
||||
Airfield *af = exclude;
|
||||
|
||||
//TODO: Iter limiter
|
||||
do
|
||||
{
|
||||
int sel = rand_int(0, count);
|
||||
auto it = _airfields.begin();
|
||||
for (; it != _airfields.end() && sel; ++it, --sel);
|
||||
af = it->second;
|
||||
} while(af == exclude);
|
||||
|
||||
return af;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
namespace dxd::sim
|
||||
{
|
||||
|
||||
class Airfield;
|
||||
|
||||
class AFSpawner : public WorldObject
|
||||
{
|
||||
private:
|
||||
@@ -27,15 +29,19 @@ private:
|
||||
const int _MIN_AF_TTL = 3000;
|
||||
const int _MAX_AF_TTL = 9000;
|
||||
|
||||
void spawn_airfield(World *world);
|
||||
|
||||
public:
|
||||
AFSpawner()
|
||||
{
|
||||
_airfields = std::map<vec2i, Airfield*>();
|
||||
_next_spawn = 1;
|
||||
_next_spawn = -1;
|
||||
}
|
||||
|
||||
void tick(float timestep, World *world) override;
|
||||
void draw(Renderer *rend) override;
|
||||
|
||||
Airfield *get_random_airfield(Airfield *exclude);
|
||||
};
|
||||
|
||||
} // namespace dxd::sim
|
||||
|
||||
@@ -16,7 +16,7 @@ private:
|
||||
int _trail_cooldown;
|
||||
|
||||
const int _TRAIL_DELAY = 120;
|
||||
const int _TRAIL_DURATION = 420;
|
||||
const int _TRAIL_DURATION = 600;
|
||||
const float _MAX_TURN_RATE = 0.3f;
|
||||
const float _SPD_TO_KTS = 60.0f;
|
||||
|
||||
|
||||
@@ -8,15 +8,20 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
|
||||
if (--_ttl == 0)
|
||||
{
|
||||
world->remove_obj(this);
|
||||
//TODO: Free space in af_spawner
|
||||
return;
|
||||
}
|
||||
|
||||
if (--_next_spawn == 0)
|
||||
{
|
||||
vec2 pos = _position + polar_to_vec2(_rw_heading, _WR_LENGTH+0.5);
|
||||
vec2 tgt = _position + polar_to_vec2(SDL_randf()*2*M_PIf, 30);
|
||||
Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt);
|
||||
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);
|
||||
world->add_obj(af);
|
||||
|
||||
_next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +33,7 @@ void dxd::sim::Airfield::draw(Renderer *rend)
|
||||
rend->diamond(_position, 5);
|
||||
|
||||
rend->color(64, 64, 255);
|
||||
vec2 a = _position + polar_to_vec2(_rw_heading, +_WR_LENGTH);
|
||||
vec2 b = _position + polar_to_vec2(_rw_heading, -_WR_LENGTH);
|
||||
vec2 a = _position + polar_to_vec2(_rw_heading, +_RW_LENGTH);
|
||||
vec2 b = _position + polar_to_vec2(_rw_heading, -_RW_LENGTH);
|
||||
rend->line(a, b);
|
||||
}
|
||||
|
||||
@@ -4,29 +4,35 @@
|
||||
|
||||
#include "../dxd_math.hpp"
|
||||
#include "world_object.hpp"
|
||||
#include "af_spawner.hpp"
|
||||
|
||||
namespace dxd::sim
|
||||
{
|
||||
|
||||
class AFSpawner;
|
||||
|
||||
class Airfield : public WorldObject
|
||||
{
|
||||
private:
|
||||
AFSpawner *_parent;
|
||||
vec2 _position;
|
||||
int _ttl;
|
||||
int _next_spawn;
|
||||
float _rw_heading;
|
||||
|
||||
const int _MIN_TAKEOFF_DELAY = 240;
|
||||
const int _MAX_TAKEOFF_DELAY = 600;
|
||||
const int _WR_LENGTH = 6;
|
||||
int const _MIN_TAKEOFF_DELAY = 600;
|
||||
int const _MAX_TAKEOFF_DELAY = 3000;
|
||||
int const _RW_LENGTH = 6;
|
||||
|
||||
public:
|
||||
Airfield(vec2 position, int ttl, float rw_heading)
|
||||
: _position(position), _ttl(ttl), _rw_heading(rw_heading)
|
||||
Airfield(AFSpawner *parent, vec2 position, int ttl, float rw_heading)
|
||||
: _parent(parent), _position(position), _ttl(ttl), _rw_heading(rw_heading)
|
||||
{
|
||||
_next_spawn = _MIN_TAKEOFF_DELAY;
|
||||
}
|
||||
|
||||
vec2 get_position() { return _position; }
|
||||
|
||||
void tick(float timestep, World *world) override;
|
||||
void draw(Renderer *rend) override;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user