From 30c721089df4235a09829557005b029f9f5a7df1 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sun, 22 Apr 2018 18:49:53 +0200 Subject: Repairing mechanic for the builder. --- src/game/assets.cpp | 3 +++ src/game/game.cpp | 14 ++++++++++-- src/game/game.hpp | 9 +++++++- src/game/unit_builder.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 4 deletions(-) (limited to 'src/game') diff --git a/src/game/assets.cpp b/src/game/assets.cpp index aedad52..d34f312 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -69,6 +69,7 @@ void load(void) scientist.gather.load("assets/units/scientist/gather.ogg"); builder.body_idle.load("assets/units/builder/body_idle", 1, 1, 1); + builder.repairing.load("assets/units/builder/repairing_", 2); builder.head_idle.load("assets/units/builder/head_idle", 1, 1, 1); builder.dead.load("assets/units/builder/dead_", 1); builder.gibbing.load("assets/units/builder/gibbing_", 3); @@ -150,6 +151,8 @@ void load(void) ambients[AMBIENT_WATER].volume = 0.1f; ui.crystals.load("assets/ui/crystals_", 1); + ui.crystal_tick.load("assets/ui/crystal_tick.ogg"); + ui.crystal_tick.volume = 0.3f; } } // namespace game::assets diff --git a/src/game/game.cpp b/src/game/game.cpp index 30e4fba..986b5d2 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -182,7 +182,9 @@ enum { COMMAND_REPL_SCIENTIST, COMMAND_REPL_BUILDER, - COMMAND_GATHER + COMMAND_GATHER, + + COMMAND_REPAIR }; bool state_t::populate_pie_menu(std::vector &items) @@ -237,7 +239,7 @@ bool state_t::populate_pie_menu(std::vector &items) items.push_back((interface::pie_item_t){"Gather", COMMAND_GATHER}); if (builders) - items.push_back((interface::pie_item_t){"TODO", -1}); + items.push_back((interface::pie_item_t){"Repair", COMMAND_REPAIR}); if (repls) { items.push_back((interface::pie_item_t){"Spawn a soldier", COMMAND_REPL_SOLDIER}); @@ -334,6 +336,14 @@ static void command_builder(unit_builder_t *builder, v2f_t x, int number) case COMMAND_STOP: builder->stop_moving(); builder->say("Stop.", false); + builder->repair_marker.reset(); + break; + + case COMMAND_REPAIR: + builder->repairing = true; + builder->repairing_at = x; + builder->repair_marker = std::make_unique(builder->game, x); + builder->say("Idę naprawiać.", false); break; } } diff --git a/src/game/game.hpp b/src/game/game.hpp index b9b593e..dbf1e41 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -213,7 +213,7 @@ namespace game { typedef struct { render::oriented_sprite_4M_t head_idle, body_idle; - render::animated_texture_t dead, gibbing; + render::animated_texture_t dead, gibbing, repairing; render::animated_texture_t avatar; } builder_assets_t; @@ -250,6 +250,7 @@ namespace game { typedef struct { render::animated_texture_t crystals; + audio::sound_t crystal_tick; } ui_assets_t; extern soldier_assets_t soldier; @@ -425,12 +426,18 @@ namespace game { class unit_builder_t : public unit_t { bool gibbed = false; + ntime_t next_repair = 0, last_repair = 0; public: std::unique_ptr move_marker; + std::unique_ptr repair_marker; sf::Color selection_color; + bool repairing = false, repaired; + v2f_t repairing_at; + void repair(void); + unit_builder_t(game::state_t *game_); ~unit_builder_t(void) {}; void render_to(render::state_t *render); diff --git a/src/game/unit_builder.cpp b/src/game/unit_builder.cpp index 1f5b81c..fcb3b90 100644 --- a/src/game/unit_builder.cpp +++ b/src/game/unit_builder.cpp @@ -51,6 +51,52 @@ unit_builder_t::unit_builder_t(game::state_t *game) : unit_t(game, UNIT_BUILDER) health = max_health = 45; } +void unit_builder_t::repair(void) +{ + rectf_t rect; + world::trace_t trace; + unit_t *unit; + + if (!move.moving) + start_moving(repairing_at); + + if ((x - repairing_at).len() > 0.5f) + return; + + if (next_repair && next_repair > game->time) + return; + + trace = game->world.ray_v_all_p3d(x, repairing_at, CF_SOLID, CF_SURFACE, this); + if (!trace.hit || !trace.ent || trace.ent->type != ET_UNIT) { + repairing = false; + return; + } + + unit = dynamic_cast(trace.ent); + if (unit->type != UNIT_REPL || unit->health >= unit->max_health) { + repairing = false; + return; + } + + if (!game->crystals) { + say("Nie mam czym naprawiać!"); + return; + } + + game->crystals--; + assets::ui.crystal_tick.play(); + + if (unit->max_health - unit->health < 3) { + repairing = false; + unit->health = unit->max_health; + say("Naprawa ukończona."); + } else + unit->health += 2; + + next_repair = game->time + MSEC(250); + last_repair = game->time; +} + void unit_builder_t::on_think(void) { keep_moving(2.0); @@ -59,6 +105,11 @@ void unit_builder_t::on_think(void) if (!move.moving) move_marker.reset(); + if (repairing) + repair(); + else + repair_marker.reset(); + if (move.moving && (x - move.last_step).len() > 0.5f) { move.last_step = x; assets::soldier.step_stone.play_3d(x); @@ -121,7 +172,9 @@ void unit_builder_t::render_to(render::state_t *render) render->render(0.0, &assets::unit_selected, cmodel.bounds, selection_color); } - if (!dead) { + if (!dead && last_repair + MSEC(300) > game->time) { + render->render(game->now * 2.0f, &assets::builder.repairing, render_bounds); + } else if (!dead) { render::oriented_sprite_t *legs; if (move.moving && !move.blocked) -- cgit