diff options
author | Paweł Redman <pawel.redman@gmail.com> | 2017-12-13 19:50:42 +0100 |
---|---|---|
committer | Paweł Redman <pawel.redman@gmail.com> | 2017-12-13 19:50:42 +0100 |
commit | 868c3ce7659b1042f27b15774976dd20a0be3f77 (patch) | |
tree | 582823b2ab1f8f684a61c2e7a92aa501e33978a2 /src/game/units.cpp | |
parent | b3b30521e50f1ed0046091b316b19daec646b4ac (diff) |
Introduce health and damage; better alien AI.
Diffstat (limited to 'src/game/units.cpp')
-rw-r--r-- | src/game/units.cpp | 116 |
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); } |