From 760a85015720ba4177a116678cfd305fe1ff2ea9 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sat, 21 Apr 2018 19:42:06 +0200 Subject: Gathering mechanic for scientists. --- src/game/assets.cpp | 6 +++++- src/game/decos.cpp | 2 +- src/game/game.cpp | 23 +++++++++++++++------ src/game/game.hpp | 19 ++++++++++-------- src/game/unit_scientist.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++-- src/game/units.cpp | 1 + src/math.hpp | 6 ++++++ 7 files changed, 88 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/game/assets.cpp b/src/game/assets.cpp index 8278e6d..1a84b62 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -63,6 +63,10 @@ void load(void) scientist.head_idle.load("assets/units/scientist/head_idle", 1, 1, 1); scientist.avatar.load("assets/units/scientist/avatar_", 1); + scientist.laugh.load("assets/units/scientist/laugh1.ogg"); + scientist.laugh.load("assets/units/scientist/laugh2.ogg"); + scientist.gather.load("assets/units/scientist/gather.ogg"); + spider.idle.load("assets/units/spider/idle", 2, 2, 2); spider.walking.load("assets/units/spider/walking", 2, 2, 2); spider.dead.load("assets/units/spider/dead_", 1); @@ -110,7 +114,7 @@ void load(void) deco.spike_small.load("assets/deco/spike_small_", 1); deco.wart.load("assets/deco/wart_", 1); deco.crystal.load("assets/deco/crystal_", 3); - deco.crystal_broken.load("assets/deco/crystal_broken_", 0); + deco.crystal_broken.load("assets/deco/crystal_broken_", 1); unit_selected.load("assets/units/selected_", 1); unit_selected_halo.load("assets/units/selected_halo_", 1); diff --git a/src/game/decos.cpp b/src/game/decos.cpp index e250f72..92ea973 100644 --- a/src/game/decos.cpp +++ b/src/game/decos.cpp @@ -73,7 +73,7 @@ static const struct { }, { &assets::deco.crystal, - {-0.4f, -0.4f}, {+0.4f, +0.4f}, CF_SOLID, + {-0.4f, -0.4f}, {+0.4f, +0.4f}, CF_DECOS, {-0.4f, -0.4f}, {+0.4f, +0.4f}, 0.0 }, { diff --git a/src/game/game.cpp b/src/game/game.cpp index 70bd040..a74a906 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -178,12 +178,14 @@ enum { COMMAND_STOP, COMMAND_REPL_SOLDIER, - COMMAND_REPL_SCIENTIST + COMMAND_REPL_SCIENTIST, + + COMMAND_GATHER }; bool state_t::populate_pie_menu(std::vector &items) { - bool can_move = false, soldiers = false, repls = false, rockets = false; + bool soldiers = false, repls = false, rockets = false, scientists = false; items.clear(); @@ -196,14 +198,13 @@ bool state_t::populate_pie_menu(std::vector &items) switch (unit->type) { case unit_t::UNIT_SOLDIER: - can_move = true; soldiers = true; if (!dynamic_cast(unit)->rocket_fired) rockets = true; break; case unit_t::UNIT_SCIENTIST: - can_move = true; + scientists = true; break; case unit_t::UNIT_REPL: @@ -214,7 +215,7 @@ bool state_t::populate_pie_menu(std::vector &items) } } - if (can_move) { + if (soldiers || scientists) { items.push_back((interface::pie_item_t){"Move", COMMAND_MOVE}); items.push_back((interface::pie_item_t){"Stop", COMMAND_STOP}); } @@ -225,6 +226,9 @@ bool state_t::populate_pie_menu(std::vector &items) items.push_back((interface::pie_item_t){"Fire a rocket", COMMAND_FIRE_ROCKET}); } + if (scientists) + items.push_back((interface::pie_item_t){"Gather", COMMAND_GATHER}); + if (repls) { items.push_back((interface::pie_item_t){"Spawn a soldier", COMMAND_REPL_SOLDIER}); items.push_back((interface::pie_item_t){"Spawn a scientist", COMMAND_REPL_SCIENTIST}); @@ -292,7 +296,14 @@ static void command_scientist(unit_scientist_t *scientist, v2f_t x, int number) case COMMAND_STOP: scientist->stop_moving(); scientist->say("Стоп.", false); - scientist->aim_marker.reset(); + scientist->gather_marker.reset(); + break; + + case COMMAND_GATHER: + scientist->gathering = true; + scientist->gathering_at = x; + scientist->gather_marker = std::make_unique(scientist->game, x); + scientist->say("Я собираю.", false); break; } } diff --git a/src/game/game.hpp b/src/game/game.hpp index 2a472b7..bc9c249 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -205,6 +205,8 @@ namespace game { render::oriented_sprite_4M_t body_idle, body_walking; render::oriented_sprite_4M_t head_idle; render::animated_texture_t avatar; + + audio::sound_t laugh, gather; } scientist_assets_t; typedef struct { @@ -382,16 +384,17 @@ namespace game { }; class unit_scientist_t : public unit_t { + ntime_t last_laugh = 0; + public: std::unique_ptr move_marker; - std::unique_ptr aim_marker; + std::unique_ptr gather_marker; sf::Color selection_color; - void check_area(void); - void shoot(v2f_t from, v2f_t at, int damage); - void fire_shotgun(v2f_t aim); - void target_and_attack(void); + bool gathering = false, gathered; + v2f_t gathering_at; + void gather_crystals(void); unit_scientist_t(game::state_t *game_); ~unit_scientist_t(void) {}; @@ -399,9 +402,9 @@ namespace game { void render_late_to(render::state_t *render); void on_think(void); - void on_spawn(void) {}; + void on_spawn(void); void on_wake(void) {}; - void on_damage(unit_t *attacker); + void on_damage(unit_t *attacker) {}; void on_death(void); }; @@ -569,9 +572,9 @@ namespace game { } deco_type_t; class deco_t : public game::entity_t { + public: deco_type_t type; - public: double phase_shift; deco_t(game::state_t *game, deco_type_t type_); diff --git a/src/game/unit_scientist.cpp b/src/game/unit_scientist.cpp index a432241..bac2a23 100644 --- a/src/game/unit_scientist.cpp +++ b/src/game/unit_scientist.cpp @@ -51,11 +51,55 @@ unit_scientist_t::unit_scientist_t(game::state_t *game) : unit_t(game, UNIT_SCIE health = max_health = 15; } +void unit_scientist_t::gather_crystals(void) +{ + rectf_t rect; + world::trace_t trace; + bool found = true; + deco_t *deco; + + if (!move.moving) + start_moving(gathering_at); + + if ((x - gathering_at).len() > 0.5f) + return; + + trace = game->world.ray_v_all(x, gathering_at, CF_SOLID|CF_DECOS, this); + if (!trace.hit || !trace.ent || trace.ent->type != ET_DECO) { + found = false; + goto out; + } + + deco = dynamic_cast(trace.ent); + if (deco->type != DECO_CRYSTAL) { + found = false; + goto out; + } + + deco->type = DECO_CRYSTAL_BROKEN; + assets::scientist.gather.play_3d(x); + + if (!last_laugh || game->time - last_laugh > MSEC(750)) { + assets::scientist.laugh.play_3d(x); + last_laugh = game->time; + } + +out: + if (!found) + say("Здесь ничего нет!"); + + gathering = false; + gather_marker.reset(); +} + void unit_scientist_t::on_think(void) { keep_moving(4.0); game->wake_area(x); + if (gathering) + gather_crystals(); + if (!move.moving) move_marker.reset(); @@ -65,9 +109,10 @@ void unit_scientist_t::on_think(void) } } -void unit_scientist_t::on_damage(unit_t *attacker) +void unit_scientist_t::on_spawn(void) { - + assets::scientist.laugh.play_3d(x); + last_laugh = game->time; } void unit_scientist_t::on_death(void) diff --git a/src/game/units.cpp b/src/game/units.cpp index ef74b74..26cf808 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -198,6 +198,7 @@ void unit_t::damage(int points, unit_t *attacker) switch (type) { case UNIT_SOLDIER: + case UNIT_SCIENTIST: alien = false; break; diff --git a/src/math.hpp b/src/math.hpp index 97e3b6b..d0b474e 100644 --- a/src/math.hpp +++ b/src/math.hpp @@ -388,6 +388,12 @@ public: return true; } + static rect_t around(vec_t v, T r) + { + vec_t R(r, r); + return rect_t(v - R, v + R); + } + friend bool operator&&(const rect_t &a, const rect_t &b) { for (size_t i = 0; i < N; i++) -- cgit