summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-12-13 16:27:34 +0100
committerPaweł Redman <pawel.redman@gmail.com>2017-12-13 16:30:24 +0100
commitb3b30521e50f1ed0046091b316b19daec646b4ac (patch)
tree94da0045602da71c5c76b692f4ea4e8c510ca4b7 /src
parent15f4780dd94a06bec5616155c05810c731d2e4af (diff)
Basic alien AI.
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp1
-rw-r--r--src/game/game.cpp48
-rw-r--r--src/game/game.hpp29
-rw-r--r--src/game/units.cpp40
-rw-r--r--src/path_finder.cpp2
-rw-r--r--src/world.cpp6
6 files changed, 107 insertions, 19 deletions
diff --git a/src/common.hpp b/src/common.hpp
index 20c5a12..948e829 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -186,6 +186,7 @@ namespace game {
std::unordered_set<unit_t*> units;
std::unordered_set<unit_t*> selected_units;
+ std::unordered_set<unit_t*> awake_units;
public:
world::world_t world;
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 71d24ac..b9a46db 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -16,8 +16,7 @@ void state_t::start(void)
units.insert(human);
alien = new alien_t;
- alien->place(&world, v2f_t(5.5, 5.5));
- units.insert(alien);
+ alien->place(&world, v2f_t(15.5, -2.5));
}
void state_t::stop(void)
@@ -41,6 +40,10 @@ void state_t::select(rectf_t x)
continue;
unit = (unit_t*)ent;
+
+ if (unit->type != unit_t::UNIT_HUMAN)
+ continue;
+
unit->selected = selection_cookie;
selected_units.insert(unit);
}
@@ -62,8 +65,45 @@ void state_t::tick(double now_, double dt_)
now = now_;
dt = dt_;
- for (unit_t *unit : units)
- unit->keep_moving(now, dt);
+ for (unit_t *unit : units) {
+ rectf_t wake_range;
+
+ wake_range[0] = unit->x - v2f_t(10, 10);
+ wake_range[1] = unit->x + v2f_t(10, 10);
+
+ for (world::entity_t *ent : world.get_entities(wake_range, -1)) {
+ unit_t *enemy;
+
+ if (ent->type != ET_UNIT)
+ continue;
+
+ enemy = (unit_t*)ent;
+ enemy->wake_time = now;
+
+ if (enemy->awake)
+ continue;
+
+ if (enemy->type == unit_t::UNIT_HUMAN)
+ continue;
+
+ enemy->awake = true;
+ awake_units.insert(enemy);
+ enemy->wake(now, unit);
+ }
+
+ unit->think(now, dt);
+ }
+
+ for (auto i = std::begin(awake_units); i != std::end(awake_units);) {
+ if (now - (*i)->wake_time >= 5.0) {
+ (*i)->awake = false;
+ (*i)->sleep(now);
+ i = awake_units.erase(i);
+ } else {
+ (*i)->think(now, dt);
+ i++;
+ }
+ }
}
bool load_assets(void)
diff --git a/src/game/game.hpp b/src/game/game.hpp
index f45aecf..f141e85 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -45,7 +45,14 @@ namespace game {
world::cflags_t cflags;
size_t selected = 0;
- unit_t();
+ typedef enum {
+ UNIT_HUMAN,
+ UNIT_ALIEN
+ } type_t;
+
+ type_t type;
+
+ unit_t(type_t type_);
struct {
bool moving = false;
@@ -62,23 +69,39 @@ namespace game {
const wchar_t *say_text;
double say_time = -INFINITY;
+ bool awake = false;
+ double wake_time = -INFINITY;
+
void render_to(render::state_t *render);
void say(const wchar_t *wstr, double now);
void place(world::world_t *world_, v2f_t x_);
- bool keep_moving(double now, double dt);
+ bool keep_moving(double now, double dt, double speed);
bool start_moving(v2f_t dst_, double now);
+
+ virtual void wake(double now, unit_t *by_whom) = 0;
+ virtual void sleep(double now) = 0;
+ virtual void think(double now, double dt) = 0;
};
class human_t : public unit_t {
public:
human_t();
void render_to(render::state_t *render);
- bool keep_moving(double now, double dt);
+
+ void wake(double now, unit_t *by_whom);
+ void sleep(double now);
+ void think(double now, double dt);
};
class alien_t : public unit_t {
+ unit_t *target;
+
public:
alien_t();
void render_to(render::state_t *render);
+
+ void wake(double now, unit_t *by_whom);
+ void sleep(double now);
+ void think(double now, double dt);
};
};
diff --git a/src/game/units.cpp b/src/game/units.cpp
index d695050..4c4e828 100644
--- a/src/game/units.cpp
+++ b/src/game/units.cpp
@@ -20,8 +20,9 @@ void unit_t::compute_bounds()
}
-unit_t::unit_t() : entity_t(ET_UNIT)
+unit_t::unit_t(unit_t::type_t type_) : entity_t(ET_UNIT)
{
+ type = type_;
}
void unit_t::render_to(render::state_t *render)
@@ -53,7 +54,7 @@ void unit_t::place(world::world_t *world_, v2f_t x_)
link(world);
}
-bool unit_t::keep_moving(double now, double dt)
+bool unit_t::keep_moving(double now, double dt, double speed)
{
float time;
@@ -63,7 +64,7 @@ bool unit_t::keep_moving(double now, double dt)
if (move.blocked && now < move.next_attempt)
return false;
- time = dt * 10;
+ time = dt * speed;
while (time > 0.0f) {
v2f_t delta, next, x_new;
@@ -137,7 +138,7 @@ bool unit_t::start_moving(v2f_t dst_, double now)
return true;
}
-human_t::human_t()
+human_t::human_t() : unit_t(UNIT_HUMAN)
{
size[0] = v2f_t(-0.4f, -0.4f);
size[1] = v2f_t(+0.4f, +0.4f);
@@ -145,9 +146,17 @@ human_t::human_t()
render_size[1] = v2f_t(+0.5f, +0.5f);
}
-bool human_t::keep_moving(double now, double dt)
+void human_t::wake(double now, unit_t *by_whom)
{
- unit_t::keep_moving(now, dt);
+}
+
+void human_t::sleep(double now)
+{
+}
+
+void human_t::think(double now, double dt)
+{
+ keep_moving(now, dt, 4.0);
}
void human_t::render_to(render::state_t *render)
@@ -175,7 +184,7 @@ void human_t::render_to(render::state_t *render)
unit_t::render_to(render);
}
-alien_t::alien_t()
+alien_t::alien_t() : unit_t(UNIT_ALIEN)
{
size[0] = v2f_t(-0.2f, -0.2f);
size[1] = v2f_t(+0.2f, +0.2f);
@@ -183,6 +192,23 @@ alien_t::alien_t()
render_size[1] = v2f_t(+0.3f, +0.3f);
}
+void alien_t::wake(double now, unit_t *by_whom)
+{
+ target = by_whom;
+ printf("the alien is now awake\n");
+}
+
+void alien_t::sleep(double now)
+{
+ printf("the alien is now sleeping\n");
+}
+
+void alien_t::think(double now, double dt)
+{
+ start_moving(target->x, now);
+ keep_moving(now, dt, 7.0);
+}
+
void alien_t::render_to(render::state_t *render)
{
bool moving;
diff --git a/src/path_finder.cpp b/src/path_finder.cpp
index c8cd253..30e9ebd 100644
--- a/src/path_finder.cpp
+++ b/src/path_finder.cpp
@@ -12,7 +12,7 @@ static const tile_index_t path_offsets[8] = {
path_finder_t::~path_finder_t()
{
- delete nodes;
+ delete[] nodes;
}
void path_finder_t::setup_nodes(v2f_t src_, v2f_t dst_, cflags_t cflags_)
diff --git a/src/world.cpp b/src/world.cpp
index f4aca63..71a7ae7 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -162,9 +162,10 @@ std::list<sector_t*> world_t::get_sectors(rectf_t rect)
return list;
}
+static size_t cookie = 0;
+
std::list<entity_t*> world_t::get_entities(rectf_t rect, cflags_t cflags)
{
- static size_t cookie = 0;
std::list<entity_t*> list;
cookie++;
@@ -190,7 +191,6 @@ std::list<entity_t*> world_t::get_entities(rectf_t rect, cflags_t cflags)
std::list<entity_t*> world_t::get_render_entities(rectf_t rect)
{
- static size_t cookie = 0;
std::list<entity_t*> list;
cookie++;
@@ -213,8 +213,6 @@ std::list<entity_t*> world_t::get_render_entities(rectf_t rect)
bool world_t::test_rect(const cmodel_t *cmodel, const entity_t *ignore)
{
- static size_t cookie = 0;
-
cookie++;
for (sector_t *sector : get_sectors(cmodel->bounds)) {