summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/assets.cpp6
-rw-r--r--src/game/decos.cpp2
-rw-r--r--src/game/game.cpp23
-rw-r--r--src/game/game.hpp19
-rw-r--r--src/game/unit_scientist.cpp49
-rw-r--r--src/game/units.cpp1
-rw-r--r--src/math.hpp6
7 files changed, 88 insertions, 18 deletions
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<interface::pie_item_t> &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<interface::pie_item_t> &items)
switch (unit->type) {
case unit_t::UNIT_SOLDIER:
- can_move = true;
soldiers = true;
if (!dynamic_cast<unit_soldier_t*>(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<interface::pie_item_t> &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<interface::pie_item_t> &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<fx_aim_marker_t>(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<fx_move_marker_t> move_marker;
- std::unique_ptr<fx_aim_marker_t> aim_marker;
+ std::unique_ptr<fx_aim_marker_t> 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<deco_t*>(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<T, N> around(vec_t<T, N> v, T r)
+ {
+ vec_t<T, N> R(r, r);
+ return rect_t<T, N>(v - R, v + R);
+ }
+
friend bool operator&&(const rect_t<T, N> &a, const rect_t<T, N> &b)
{
for (size_t i = 0; i < N; i++)