summaryrefslogtreecommitdiff
path: root/src/game/units.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/units.cpp')
-rw-r--r--src/game/units.cpp116
1 files changed, 105 insertions, 11 deletions
diff --git a/src/game/units.cpp b/src/game/units.cpp
index 4c4e828..abdf216 100644
--- a/src/game/units.cpp
+++ b/src/game/units.cpp
@@ -46,7 +46,6 @@ void unit_t::place(world::world_t *world_, v2f_t x_)
world = world_;
x = x_;
move.moving = false;
- cflags = 1;
unlink();
cmodel = make_cmodel(x);
@@ -138,8 +137,22 @@ bool unit_t::start_moving(v2f_t dst_, double now)
return true;
}
+void unit_t::damage(double now, int points)
+{
+ health -= points;
+ if (health < 0) {
+ printf("%p died\n", this);
+ dead = true;
+ death_time = now;
+ cflags = 0;
+ die(now);
+ }
+}
+
human_t::human_t() : unit_t(UNIT_HUMAN)
{
+ cflags = CF_HUMAN;
+ health = 20;
size[0] = v2f_t(-0.4f, -0.4f);
size[1] = v2f_t(+0.4f, +0.4f);
render_size[0] = v2f_t(-0.5f, -1.0f);
@@ -159,16 +172,28 @@ void human_t::think(double now, double dt)
keep_moving(now, dt, 4.0);
}
+void human_t::die(double now)
+{
+ render_size[0] = v2f_t(-0.75f, -0.5f);
+ render_size[1] = v2f_t(+0.75f, +0.5f);
+ unlink();
+ compute_bounds();
+ link(world);
+}
+
void human_t::render_to(render::state_t *render)
{
- bool moving;
+ if (!dead) {
+ bool moving;
- moving = move.moving && !move.blocked;
+ moving = move.moving && !move.blocked;
- render->render((moving ? &assets::human.legs_walking :
- &assets::human.legs_idle), render_bounds, move.angle);
- render->render(&assets::human.body_idle, render_bounds, move.angle);
- render->render(&assets::human.head_idle, render_bounds, move.angle);
+ render->render((moving ? &assets::human.legs_walking :
+ &assets::human.legs_idle), render_bounds, move.angle);
+ render->render(&assets::human.body_idle, render_bounds, move.angle);
+ render->render(&assets::human.head_idle, render_bounds, move.angle);
+ } else
+ render->render(&assets::human.dead, render_bounds);
if (say_time + 5.0 > render->now) {
v2f_t text_pos;
@@ -186,6 +211,8 @@ void human_t::render_to(render::state_t *render)
alien_t::alien_t() : unit_t(UNIT_ALIEN)
{
+ cflags = CF_SOLID;
+ health = 4;
size[0] = v2f_t(-0.2f, -0.2f);
size[1] = v2f_t(+0.2f, +0.2f);
render_size[0] = v2f_t(-0.3f, -0.3f);
@@ -194,18 +221,85 @@ alien_t::alien_t() : unit_t(UNIT_ALIEN)
void alien_t::wake(double now, unit_t *by_whom)
{
- target = by_whom;
- printf("the alien is now awake\n");
+ start_moving(by_whom->x, now);
+ next_targetting = now + 0.4;
}
void alien_t::sleep(double now)
{
- printf("the alien is now sleeping\n");
+}
+
+void alien_t::die(double now)
+{
+
+}
+
+static unit_t *find_target(world::world_t *world, v2f_t x, float r,
+ unit_t::type_t type)
+{
+ rectf_t rect;
+ float nearest_dist = INFINITY;
+ unit_t *nearest = NULL;
+
+ rect[0] = x - v2f_t(r, r);
+ rect[1] = x + v2f_t(r, r);
+
+ for (world::entity_t *ent : world->get_entities(rect, -1)) {
+ unit_t *unit;
+ float dist;
+
+ if (ent->type != ET_UNIT)
+ continue;
+
+ unit = (unit_t*)ent;
+
+ if (unit->type != type)
+ continue;
+
+ if (unit->dead)
+ continue;
+
+ dist = (unit->x - x).len();
+ if (dist < nearest_dist) {
+ nearest_dist = dist;
+ nearest = unit;
+ }
+ }
+
+ return nearest;
+}
+
+void alien_t::attack(double now, unit_t *target, float range)
+{
+ world::trace_t trace;
+
+ if (now < next_attack)
+ return;
+
+ if ((x - target->x).len() > range)
+ return;
+
+ trace = world->trace(x, target->x, CF_SOLID);
+ if (!trace.hit)
+ target->damage(now, 12);
+
+ next_attack = now + 1.0;
}
void alien_t::think(double now, double dt)
{
- start_moving(target->x, now);
+ if (now > next_targetting) {
+ unit_t *target;
+
+ target = find_target(world, x, 5.0f, UNIT_HUMAN);
+ if (target) {
+ attack(now, target, 0.75f);
+ start_moving(target->x, now);
+ }
+
+ next_targetting = now + 0.2;
+ }
+
keep_moving(now, dt, 7.0);
}