summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2018-04-25 12:40:23 +0200
committerPaweł Redman <pawel.redman@gmail.com>2018-04-25 12:40:23 +0200
commit7fe865d745fede7e2628ecf0c91b38bb15154cb3 (patch)
treeb14b8cde1a717a2c71ec6ac46cd9999d5ab3beca /src/game
parente0085775caa56d249dbdc0f5928a3ca455bad7a8 (diff)
Building mechanic.
Diffstat (limited to 'src/game')
-rw-r--r--src/game/assets.cpp1
-rw-r--r--src/game/game.cpp28
-rw-r--r--src/game/game.hpp35
-rw-r--r--src/game/unit_builder.cpp88
-rw-r--r--src/game/unit_repl.cpp12
5 files changed, 134 insertions, 30 deletions
diff --git a/src/game/assets.cpp b/src/game/assets.cpp
index d34f312..99ef734 100644
--- a/src/game/assets.cpp
+++ b/src/game/assets.cpp
@@ -94,6 +94,7 @@ void load(void)
nest.death.load("assets/units/nest/death.ogg");
repl.idle.load("assets/units/repl/idle_", 4);
+ repl.unfinished.load("assets/units/repl/unfinished_", 1);
repl.avatar.load("assets/units/repl/avatar_", 1);
repl.sound.load("assets/units/repl/sound.ogg");
repl.damage.load("assets/units/repl/damage1.ogg");
diff --git a/src/game/game.cpp b/src/game/game.cpp
index a19eecc..f6fa420 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -35,7 +35,9 @@ entity_t::entity_t(game::state_t *game_, int type_) : world::entity_t(type_)
entity_t::~entity_t(void)
{
sleep();
- unlink();
+
+ if (world)
+ unlink();
}
void entity_t::place(world::world_t *world_)
@@ -85,6 +87,8 @@ void state_t::start(void)
repl = new unit_repl_t(this);
repl->place(&world, v2f_t(5.3, 4.2));
+ repl->constructed = true;
+ repl->health = repl->max_health;
select_unit(repl, SELECT_NEW);
resume();
@@ -185,7 +189,8 @@ enum {
COMMAND_GATHER,
- COMMAND_REPAIR
+ COMMAND_REPAIR,
+ COMMAND_BUILD_REPL
};
bool state_t::populate_pie_menu(std::vector<interface::pie_item_t> &items)
@@ -199,7 +204,7 @@ bool state_t::populate_pie_menu(std::vector<interface::pie_item_t> &items)
return false;
for (unit_t *unit : selected_units) {
- if (unit->dead || !unit->controllable)
+ if (unit->dead || !unit->controllable || !unit->constructed)
continue;
switch (unit->type) {
@@ -239,8 +244,10 @@ bool state_t::populate_pie_menu(std::vector<interface::pie_item_t> &items)
if (scientists)
items.push_back((interface::pie_item_t){"Gather", COMMAND_GATHER});
- if (builders)
+ if (builders) {
items.push_back((interface::pie_item_t){"Repair", COMMAND_REPAIR});
+ items.push_back((interface::pie_item_t){"Build a replicator", COMMAND_BUILD_REPL});
+ }
if (repls) {
items.push_back((interface::pie_item_t){"Spawn a soldier", COMMAND_REPL_SOLDIER});
@@ -335,16 +342,15 @@ static void command_builder(unit_builder_t *builder, v2f_t x, int number)
break;
case COMMAND_STOP:
- builder->stop_moving();
- builder->say("Stop.", false);
- builder->repair_marker.reset();
+ builder->command_stop();
break;
case COMMAND_REPAIR:
- builder->repairing = true;
- builder->repairing_at = x;
- builder->repair_marker = std::make_unique<fx_aim_marker_t>(builder->game, x);
- builder->say("Idę naprawiać.", false);
+ builder->command_repair(x);
+ break;
+
+ case COMMAND_BUILD_REPL:
+ builder->command_build(x, unit_t::UNIT_REPL);
break;
}
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index dbf1e41..31001f7 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -147,7 +147,8 @@ namespace game {
bool populate_pie_menu(std::vector<interface::pie_item_t> &items);
void command(v2f_t x, int number);
- size_t crystals = 150;
+ size_t crystals = 9999;
+ //size_t crystals = 150;
};
enum {
@@ -170,12 +171,13 @@ namespace game {
enum {
CF_SURFACE = 1,
- CF_BACKGROUND = 2,
- CF_SOLID = 4,
- CF_BODY = 8,
- CF_BODY_SMALL = 16,
- CF_WATER = 32,
- CF_DECOS = 64
+ CF_SURFACE2 = 2, // entities on the surface (FIXME: the name)
+ CF_BACKGROUND = 4,
+ CF_SOLID = 8,
+ CF_BODY = 16,
+ CF_BODY_SMALL = 32,
+ CF_WATER = 64,
+ CF_DECOS = 128
};
enum {
@@ -230,7 +232,7 @@ namespace game {
} nest_assets_t;
typedef struct {
- render::animated_texture_t idle, avatar;
+ render::animated_texture_t idle, unfinished, avatar;
audio::sound_t sound, damage;
} repl_assets_t;
@@ -352,6 +354,9 @@ namespace game {
void try_attack(unit_t *target);
void die(unit_t *killer);
+ // FIXME: move buildings to another class
+ bool constructed = true;
+
virtual void on_damage(unit_t *attacker) = 0;
virtual void on_death(void) = 0;
@@ -426,18 +431,18 @@ namespace game {
class unit_builder_t : public unit_t {
bool gibbed = false;
+
+ bool repairing = false, building;
+ v2f_t repairing_at;
+ void repair(void);
ntime_t next_repair = 0, last_repair = 0;
+ std::unique_ptr<fx_aim_marker_t> repair_marker;
public:
std::unique_ptr<fx_move_marker_t> move_marker;
- std::unique_ptr<fx_aim_marker_t> 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);
@@ -448,6 +453,10 @@ namespace game {
void on_wake(void) {};
void on_damage(unit_t *attacker);
void on_death(void);
+
+ void command_repair(v2f_t where);
+ void command_build(v2f_t where, type_t what);
+ void command_stop(void);
};
class unit_spider_t : public unit_t {
diff --git a/src/game/unit_builder.cpp b/src/game/unit_builder.cpp
index fcb3b90..1ed7f58 100644
--- a/src/game/unit_builder.cpp
+++ b/src/game/unit_builder.cpp
@@ -51,6 +51,78 @@ unit_builder_t::unit_builder_t(game::state_t *game) : unit_t(game, UNIT_BUILDER)
health = max_health = 45;
}
+void unit_builder_t::command_stop(void)
+{
+ stop_moving();
+ move_marker.reset();
+
+ repairing = false;
+ repair_marker.reset();
+
+ say("Stop.", false);
+}
+
+void unit_builder_t::command_repair(v2f_t where)
+{
+ repairing = true;
+ building = false;
+ repairing_at = where;
+ repair_marker = std::make_unique<fx_aim_marker_t>(game, where);
+ say("Idę naprawiać.", false);
+}
+
+void unit_builder_t::command_build(v2f_t where, type_t what)
+{
+ world::trace_t trace;
+ unit_t *built;
+ size_t price;
+ world::cmodel_t cmodel;
+
+ if ((x - where).len() > 1.3f) {
+ say("Tak daleko tego nie postawię!");
+ return;
+ }
+
+ trace = world->ray_v_all(x, where, CF_SOLID|CF_WATER|CF_DECOS, this);
+ if (trace.hit) {
+ say("Coś stoi mi na drodze.");
+ return;
+ }
+
+ switch (what) {
+ case UNIT_REPL:
+ built = new unit_repl_t(game);
+ price = 250;
+ break;
+
+ default:
+ abort();
+ }
+
+ if (price > game->crystals) {
+ game->interface.print("Insufficient crystals; " + std::to_string(price - game->crystals) + " more needed");
+ delete built;
+ return;
+ }
+
+ cmodel.bounds[0] = where + built->size[0];
+ cmodel.bounds[1] = where + built->size[1];
+ cmodel.cflags = CF_SOLID|CF_SURFACE2|CF_WATER|CF_DECOS;
+
+ if (world->test_rect(&cmodel, nullptr)) {
+ say("Nie ma tutaj miejsca.");
+ delete built;
+ return;
+ }
+
+ game->crystals -= price;
+ built->place(world, where);
+
+ repairing = true;
+ building = true;
+ repairing_at = where;
+}
+
void unit_builder_t::repair(void)
{
rectf_t rect;
@@ -66,7 +138,7 @@ void unit_builder_t::repair(void)
if (next_repair && next_repair > game->time)
return;
- trace = game->world.ray_v_all_p3d(x, repairing_at, CF_SOLID, CF_SURFACE, this);
+ trace = game->world.ray_v_all_p3d(x, repairing_at, CF_SOLID, CF_SURFACE2, this);
if (!trace.hit || !trace.ent || trace.ent->type != ET_UNIT) {
repairing = false;
return;
@@ -79,7 +151,11 @@ void unit_builder_t::repair(void)
}
if (!game->crystals) {
- say("Nie mam czym naprawiać!");
+ game->interface.print("Insufficient crystals; 1 more needed.");
+ if (building)
+ say("Nie mam czym konstruować!", false);
+ else
+ say("Nie mam czym naprawiać!", false);
return;
}
@@ -89,7 +165,13 @@ void unit_builder_t::repair(void)
if (unit->max_health - unit->health < 3) {
repairing = false;
unit->health = unit->max_health;
- say("Naprawa ukończona.");
+ unit->constructed = true;
+
+ if (building)
+ say("Budowa zakończona.");
+ else
+ say("Naprawa ukończona.");
+
} else
unit->health += 2;
diff --git a/src/game/unit_repl.cpp b/src/game/unit_repl.cpp
index ddea8b0..2e0c3fd 100644
--- a/src/game/unit_repl.cpp
+++ b/src/game/unit_repl.cpp
@@ -25,14 +25,16 @@ unit_repl_t::unit_repl_t(game::state_t *game_) : unit_t(game_, UNIT_REPL)
size[1] = {+0.4f, +0.4f};
render_size = size;
render_layer = render::LAYER_FLAT;
- cmodel.cflags = CF_SURFACE;
+ cmodel.cflags = CF_SURFACE2;
name = "Replicator";
ignore_waking = false;
- health = max_health = 35;
+ max_health = 35;
+ health = 5;
friendly = true;
controllable = true;
+ constructed = false;
}
void unit_repl_t::on_damage(unit_t *attacker)
@@ -48,7 +50,11 @@ void unit_repl_t::on_death(void)
void unit_repl_t::render_to(render::state_t *render)
{
- render->render(game->now, &assets::repl.idle, render_bounds);
+ if (constructed)
+ render->render(game->now, &assets::repl.idle, render_bounds);
+ else
+ render->render(game->now, &assets::repl.unfinished, render_bounds);
+
unit_t::render_to(render);
}