From b914d67b4e683c2d3e43c1854d6ef48b1878e4b6 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Thu, 14 Dec 2017 18:40:11 +0100 Subject: Allow humans to shoot. --- src/game/assets.cpp | 3 ++ src/game/game.cpp | 3 +- src/game/game.hpp | 7 +++ src/game/units.cpp | 125 ++++++++++++++++++++++++++++++++++------------------ 4 files changed, 94 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/game/assets.cpp b/src/game/assets.cpp index 1034f92..dddd447 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -9,12 +9,15 @@ void load(void) { human.head_idle.load("assets/units/human/head_idle", 1, 1, 1); human.body_idle.load("assets/units/human/body_idle", 2, 2, 2); + human.body_aiming.load("assets/units/human/body_aiming", 2, 2, 2); + human.body_firing.load("assets/units/human/body_firing", 2, 2, 2); human.legs_idle.load("assets/units/human/legs_idle", 2, 2); human.legs_walking.load("assets/units/human/legs_walking", 2, 2); human.dead.load("assets/units/human/dead_", 1); alien.idle.load("assets/units/alien/idle", 2, 2, 2); alien.walking.load("assets/units/alien/walking", 2, 2, 2); + alien.dead.load("assets/units/alien/dead_", 1); world::register_tile(TILE_DIRT, 0); world::register_tile(TILE_WALL, CF_SOLID); diff --git a/src/game/game.cpp b/src/game/game.cpp index 48f852f..5067df7 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -129,7 +129,8 @@ void state_t::tick(double now_, double dt_) (*i)->sleep(); i = awake_units.erase(i); } else { - (*i)->think(); + if (!(*i)->dead) + (*i)->think(); i++; } } diff --git a/src/game/game.hpp b/src/game/game.hpp index fdb2348..d4aed5d 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -25,12 +25,14 @@ namespace game { namespace assets { typedef struct { render::oriented_sprite_4M_t head_idle, body_idle; + render::oriented_sprite_4M_t body_aiming, body_firing; render::oriented_sprite_4M2_t legs_idle, legs_walking; render::animated_texture_t dead; } human_assets_t; typedef struct { render::oriented_sprite_4M_t idle, walking; + render::animated_texture_t dead; } alien_assets_t; extern human_assets_t human; @@ -102,6 +104,11 @@ namespace game { }; class human_t : public unit_t { + double next_targetting = -INFINITY; + double last_target_time = -INFINITY; + v2f_t last_target_x; + double last_attack = -INFINITY; + public: human_t(game::state_t *game); void render_to(render::state_t *render); diff --git a/src/game/units.cpp b/src/game/units.cpp index 672e73f..2eb5dbe 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -211,6 +211,41 @@ void unit_t::try_attack(unit_t *target) target->damage(dmg_total, this); } +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; +} + human_t::human_t(game::state_t *game) : unit_t(game, UNIT_HUMAN) { cflags = CF_BODY; @@ -219,7 +254,6 @@ human_t::human_t(game::state_t *game) : unit_t(game, UNIT_HUMAN) size[1] = v2f_t(+0.4f, +0.4f); render_size[0] = v2f_t(-0.5f, -1.0f); render_size[1] = v2f_t(+0.5f, +0.5f); - render_layer = -1; name = text::get(text::UNIT_HUMAN); } @@ -233,6 +267,25 @@ void human_t::sleep(void) void human_t::think(void) { + if (game->now > next_targetting) { + unit_t *target; + + target = find_target(world, x, 10.0f, UNIT_ALIEN); + if (target) { + last_target_time = game->now; + last_target_x = target->x; + + if (last_attack + 0.5 < game->now) { + last_attack = game->now; + try_attack(target); + } + + //start_moving(target->x, CF_SOLID); + } + + next_targetting = game->now + 0.2; + } + if (!keep_moving(4.0)) say(text::get(text::SAY_BLOCKED)); } @@ -241,6 +294,7 @@ void human_t::die(void) { render_size[0] = v2f_t(-0.75f, -0.5f); render_size[1] = v2f_t(+0.75f, +0.5f); + render_layer = -1; unlink(); compute_bounds(); link(world); @@ -249,13 +303,29 @@ void human_t::die(void) void human_t::render_to(render::state_t *render) { if (!dead) { - bool moving; + render::oriented_sprite_t *legs, *body; + float body_angle; + + if (move.moving && !move.blocked) + legs = &assets::human.legs_walking; + else + legs = &assets::human.legs_idle; + + if (last_target_time + 3 > game->now) { + if (last_attack + 0.1 > game->now) + body = &assets::human.body_firing; + else + body = &assets::human.body_aiming; - moving = move.moving && !move.blocked; + body_angle = (last_target_x - x).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); + } else { + body = &assets::human.body_idle; + body_angle = move.angle; + } + + render->render(legs, render_bounds, move.angle); + render->render(body, render_bounds, body_angle); render->render(&assets::human.head_idle, render_bounds, move.angle); } else render->render(&assets::human.dead, render_bounds); @@ -297,41 +367,7 @@ void alien_t::sleep(void) void alien_t::die(void) { -} - -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; + render_layer = -1; } void alien_t::attack(unit_t *target, float range) @@ -374,8 +410,11 @@ void alien_t::render_to(render::state_t *render) moving = move.moving && !move.blocked; - render->render((moving ? &assets::alien.walking : - &assets::alien.idle), render_bounds, move.angle); + if (!dead) + render->render((moving ? &assets::alien.walking : + &assets::alien.idle), render_bounds, move.angle); + else + render->render(&assets::alien.dead, render_bounds); unit_t::render_to(render); } -- cgit