summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-12-16 22:41:48 +0000
committerPaweł Redman <pawel.redman@gmail.com>2017-12-16 22:41:48 +0000
commit38edebe4bdeb8caedccf6127a86fddfe9c5808a8 (patch)
tree466cf659201a66a12d922943337e636b5125bccb /src
parent5c7d962e605e123e1ce4e0610e8f330b1f4f5e82 (diff)
Fully working nests.
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp4
-rw-r--r--src/game/assets.cpp5
-rw-r--r--src/game/decos.cpp5
-rw-r--r--src/game/effects.cpp3
-rw-r--r--src/game/game.cpp14
-rw-r--r--src/game/game.hpp30
-rw-r--r--src/game/text.cpp6
-rw-r--r--src/game/units.cpp103
-rw-r--r--src/game/worldgen.cpp18
-rw-r--r--src/procgen.cpp7
10 files changed, 149 insertions, 46 deletions
diff --git a/src/common.hpp b/src/common.hpp
index 872a40d..02e8b1a 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -25,6 +25,7 @@ namespace procgen {
uint32_t next(void);
float next_float(void);
void unit_vec(float out[2]);
+ v2f_t unit_vec2(void);
};
@@ -210,12 +211,11 @@ namespace game {
std::unordered_set<entity_t*> awake_entities;
std::unordered_set<unit_t*> selected_units;
-
- procgen::prng_t dice_prng;
public:
world::world_t world;
interface::state_t *interface;
double now, dt;
+ procgen::prng_t dice_prng;
void start(void);
void stop(void);
diff --git a/src/game/assets.cpp b/src/game/assets.cpp
index a4a03e5..6751435 100644
--- a/src/game/assets.cpp
+++ b/src/game/assets.cpp
@@ -4,6 +4,7 @@ namespace game::assets {
soldier_assets_t soldier;
spider_assets_t spider;
+nest_assets_t nest;
fx_assets_t fx;
deco_assets_t deco;
@@ -21,11 +22,13 @@ void load(void)
spider.walking.load("assets/units/spider/walking", 2, 2, 2);
spider.dead.load("assets/units/spider/dead_", 1);
+ nest.idle.load("assets/units/nest/idle_", 5);
+ nest.dead.load("assets/units/nest/dead_", 1);
+
fx.blood.load("assets/units/blood_", 4);
deco.stone.load("assets/deco/stone_", 1);
deco.eyething.load("assets/deco/eyething_", 2);
- deco.nest.load("assets/deco/nest_", 5);
world::register_tile(TILE_DIRT, 0);
render::register_tile(TILE_DIRT, "assets/tiles/dirt.png");
diff --git a/src/game/decos.cpp b/src/game/decos.cpp
index 7f81bbb..07e6b10 100644
--- a/src/game/decos.cpp
+++ b/src/game/decos.cpp
@@ -23,11 +23,6 @@ static const struct {
&assets::deco.eyething,
{-0.4f, +0.1f}, {+0.4f, +0.4f}, CF_SOLID,
{-0.4f, -1.2f}, {+0.4f, +0.4f}, 0.3
- },
- {
- &assets::deco.nest,
- {-0.6f, +0.2f}, {+0.6f, +0.6f}, CF_SOLID,
- {-0.6f, -0.6f}, {+0.6f, +0.6f}, 1.0
}
};
diff --git a/src/game/effects.cpp b/src/game/effects.cpp
index 8e7d2d7..844f365 100644
--- a/src/game/effects.cpp
+++ b/src/game/effects.cpp
@@ -4,7 +4,8 @@ namespace game {
effect_t::effect_t(state_t *game_) : game::entity_t(game_, ET_EFFECT)
{
- always_awake = true;
+ ignore_waking = true;
+ wake();
}
void effect_t::on_think(void)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 9584817..64dd224 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -32,7 +32,7 @@ void entity_t::place(world::world_t *world_)
if (do_spawn)
on_spawn();
- if (always_awake)
+ if (!ignore_waking)
wake();
}
@@ -51,7 +51,7 @@ void entity_t::wake(void)
wake_time = game->now;
game->awake_entities.insert(this);
- if (!always_awake)
+ if (!ignore_waking)
on_wake();
}
@@ -64,7 +64,6 @@ void entity_t::sleep(void)
void state_t::start(void)
{
unit_soldier_t *soldier;
- unit_spider_t *spider;
world.generator = worldgen;
world.generator_data = (void*)this;
@@ -75,13 +74,6 @@ void state_t::start(void)
soldier->place(&world, v2f_t(1.5, 0.5));
soldier = new unit_soldier_t(this);
soldier->place(&world, v2f_t(2.5, 0.5));
-
- spider = new unit_spider_t(this);
- spider->place(&world, v2f_t(15.5, -2.5));
- spider = new unit_spider_t(this);
- spider->place(&world, v2f_t(14.5, -2.5));
- spider = new unit_spider_t(this);
- spider->place(&world, v2f_t(13.5, -2.5));
}
void state_t::stop(void)
@@ -171,7 +163,7 @@ void state_t::wake_everything(v2f_t x, float range)
if (!ent)
continue;
- if (ent->always_awake || ent->awake)
+ if (ent->ignore_waking || ent->awake)
continue;
ent->wake();
diff --git a/src/game/game.hpp b/src/game/game.hpp
index b2bf0dd..e2ac514 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -40,15 +40,20 @@ namespace game {
} spider_assets_t;
typedef struct {
+ render::animated_texture_t idle, dead;
+ } nest_assets_t;
+
+ typedef struct {
render::animated_texture_t blood;
} fx_assets_t;
typedef struct {
- render::animated_texture_t stone, eyething, nest;
+ render::animated_texture_t stone, eyething;
} deco_assets_t;
extern soldier_assets_t soldier;
extern spider_assets_t spider;
+ extern nest_assets_t nest;
extern fx_assets_t fx;
extern deco_assets_t deco;
@@ -70,6 +75,7 @@ namespace game {
SAY_MOVING,
UNIT_NAME_SPIDER,
UNIT_NAME_SOLDIER,
+ UNIT_NAME_NEST,
UNIT_DEATH,
UNIT_ATTACK,
UNIT_MISS,
@@ -94,7 +100,7 @@ namespace game {
void place(world::world_t *world);
void place(world::world_t *world, v2f_t x_);
- bool always_awake = false;
+ bool ignore_waking = false;
bool awake = false;
double wake_time = -INFINITY;
void wake(void);
@@ -115,7 +121,8 @@ namespace game {
typedef enum {
UNIT_SOLDIER,
- UNIT_SPIDER
+ UNIT_SPIDER,
+ UNIT_NEST
} type_t;
type_t type;
@@ -189,6 +196,20 @@ namespace game {
void on_death(void);
};
+ class unit_nest_t : public unit_t {
+ double next_spawning = -INFINITY;
+
+ public:
+ unit_nest_t(game::state_t *game_);
+ ~unit_nest_t(void) {};
+ void render_to(render::state_t *render);
+
+ void on_think(void);
+ void on_spawn(void);
+ void on_death(void);
+ void on_wake(void) {};
+ };
+
class effect_t : public game::entity_t {
public:
double ttl = +INFINITY;
@@ -225,8 +246,7 @@ namespace game {
typedef enum {
DECO_STONE,
DECO_STONE_SMALL,
- DECO_EYETHING,
- DECO_NEST
+ DECO_EYETHING
} deco_type_t;
class deco_t : public game::entity_t {
diff --git a/src/game/text.cpp b/src/game/text.cpp
index 3b611e2..bdd68ed 100644
--- a/src/game/text.cpp
+++ b/src/game/text.cpp
@@ -29,6 +29,9 @@ static std::string get_english(index_t index)
case UNIT_NAME_SOLDIER:
return soldier_names[rand() % count(soldier_names)];
+ case UNIT_NAME_NEST:
+ return "Nest";
+
case UNIT_DEATH:
return "died";
@@ -73,6 +76,9 @@ static std::string get_polish(index_t index)
case UNIT_NAME_SOLDIER:
return soldier_names[rand() % count(soldier_names)];
+ case UNIT_NAME_NEST:
+ return "Gniazdo";
+
case UNIT_DEATH:
return "nie żyje";
diff --git a/src/game/units.cpp b/src/game/units.cpp
index a1e233c..49ae050 100644
--- a/src/game/units.cpp
+++ b/src/game/units.cpp
@@ -164,9 +164,14 @@ void unit_t::damage(int points, unit_t *attacker)
void unit_t::die(unit_t *killer)
{
game->interface->print(name + " " + text::get(text::UNIT_DEATH) + ".");
+
dead = true;
death_time = game->now;
cmodel.cflags = 0;
+
+ sleep();
+ ignore_waking = true;
+
on_death();
}
@@ -203,7 +208,7 @@ void unit_t::try_attack(unit_t *target)
}
static unit_t *find_target(world::world_t *world, v2f_t x, float r,
- unit_t::type_t type)
+ bool friendly)
{
rectf_t rect;
float nearest_dist = INFINITY;
@@ -221,7 +226,7 @@ static unit_t *find_target(world::world_t *world, v2f_t x, float r,
unit = (unit_t*)ent;
- if (unit->type != type)
+ if (unit->friendly != friendly)
continue;
if (unit->dead)
@@ -247,26 +252,24 @@ unit_soldier_t::unit_soldier_t(game::state_t *game) : unit_t(game, UNIT_SOLDIER)
name = text::get(text::UNIT_NAME_SOLDIER);
- always_awake = true;
+ ignore_waking = true; // Always awake.
+ wake();
friendly = true;
controllable = true;
health = max_health = 20;
cs.armor_class = 10;
- cs.hit_die = die_t(4);
+ cs.hit_die = die_t(8);
}
void unit_soldier_t::on_think(void)
{
- if (dead)
- return;
-
game->wake_everything(x, 10);
if (game->now > next_targetting) {
unit_t *target;
- target = find_target(world, x, 10.0f, UNIT_SPIDER);
+ target = find_target(world, x, 10.0f, false);
if (target) {
last_target_time = game->now;
last_target_x = target->x;
@@ -348,19 +351,16 @@ unit_spider_t::unit_spider_t(game::state_t *game) : unit_t(game, UNIT_SPIDER)
name = text::get(text::UNIT_NAME_SPIDER);
health = max_health = 4;
- cs.armor_class = 5;
- cs.hit_die = die_t(3, 6, 1);
+ cs.armor_class = 15;
+ cs.hit_die = die_t(3, 6);
}
void unit_spider_t::on_think(void)
{
- if (dead)
- return;
-
if (game->now > next_targetting) {
unit_t *target;
- target = find_target(world, x, 10.0f, UNIT_SOLDIER);
+ target = find_target(world, x, 10.0f, true);
if (target) {
if (last_attack + 0.5 < game->now) {
world::trace_t trace;
@@ -381,6 +381,9 @@ void unit_spider_t::on_think(void)
}
keep_moving(7.0);
+
+ if (!move.moving && wake_time + 5 > game->now)
+ sleep();
}
void unit_spider_t::on_wake(void)
@@ -409,4 +412,76 @@ void unit_spider_t::render_to(render::state_t *render)
unit_t::render_to(render);
}
+unit_nest_t::unit_nest_t(game::state_t *game_) : unit_t(game_, UNIT_NEST)
+{
+ size[0] = {-0.6f, +0.2f};
+ size[1] = {+0.6f, +0.6f};
+ render_size[0] = {-0.6f, -0.6f};
+ render_size[1] = {+0.6f, +0.6f};
+ cmodel.cflags = CF_BACKGROUND;
+
+ name = text::get(text::UNIT_NAME_NEST);
+
+ health = max_health = 45;
+ cs.armor_class = 5;
+
+ next_spawning = game->now + 5.0;
+}
+
+void spawn_spider(game::state_t *game, v2f_t nest)
+{
+ for (size_t i = 0; i < 5; i++) { // Try a few times before giving up.
+ v2f_t offset, x;
+ world::cmodel_t cmodel;
+ unit_spider_t *spider;
+
+ offset = game->dice_prng.unit_vec2();
+ x = nest + offset * (game->dice_prng.next_float() * 0.2 + 0.4);
+
+ cmodel.bounds = rectf_t(v2f_t(-0.5f, -0.5f), v2f_t(0.5f, 0.5f)) + x;
+ cmodel.cflags = CF_BODY_SMALL;
+ if (game->world.test_rect(&cmodel, NULL))
+ continue;
+
+ spider = new unit_spider_t(game);
+ spider->place(&game->world, x);
+ return;
+ }
+}
+
+void unit_nest_t::on_think(void)
+{
+ if (wake_time + 30 > game->now)
+ sleep();
+
+ if (next_spawning > game->now)
+ return;
+
+ spawn_spider(game, x);
+ next_spawning = game->now + game->dice_prng.next_float() * 10 + 5;
+}
+
+void unit_nest_t::on_spawn(void)
+{
+ spawn_spider(game, x);
+ spawn_spider(game, x);
+ spawn_spider(game, x);
+}
+
+void unit_nest_t::on_death(void)
+{
+ render_layer = -1;
+ cmodel.cflags = CF_BACKGROUND;
+}
+
+void unit_nest_t::render_to(render::state_t *render)
+{
+ if (!dead)
+ render->render(game->now, &assets::nest.idle, render_bounds);
+ else
+ render->render(game->now, &assets::nest.dead, render_bounds);
+
+ unit_t::render_to(render);
+}
+
} // namespace game
diff --git a/src/game/worldgen.cpp b/src/game/worldgen.cpp
index e5f19c8..18a98b5 100644
--- a/src/game/worldgen.cpp
+++ b/src/game/worldgen.cpp
@@ -13,19 +13,23 @@ void add_decoration(world_t *world, state_t *game, v2f_t x, float noise)
if (noise < 0.3)
return;
- if (noise > 0.5)
- type = DECO_NEST;
- else if (noise > 0.40)
+ offset[0] = world->perlin.get(x, 0.17331f);
+ offset[1] = world->perlin.get(x, 0.19571f);
+ center = x + v2f_t(0.5f, 0.5f) + offset.norm() * 0.1;
+
+ if (noise > 0.5) {
+ unit_nest_t *nest = new unit_nest_t(game);
+ nest->place(world, center);
+ return;
+ }
+
+ if (noise > 0.40)
type = DECO_EYETHING;
else if (noise > 0.35)
type = DECO_STONE;
else
type = DECO_STONE_SMALL;
- offset[0] = world->perlin.get(x, 0.17331f);
- offset[1] = world->perlin.get(x, 0.19571f);
- center = x + v2f_t(0.5f, 0.5f) + offset.norm() * 0.1;
-
deco = new deco_t(game, type);
deco->phase_shift = offset[0] * 500.0;
deco->place(world, x);
diff --git a/src/procgen.cpp b/src/procgen.cpp
index bfff2c4..a57ed3a 100644
--- a/src/procgen.cpp
+++ b/src/procgen.cpp
@@ -32,6 +32,13 @@ void prng_t::unit_vec(float out[2])
out[1] = sin(t);
}
+v2f_t prng_t::unit_vec2(void)
+{
+ float t;
+ t = next_float() * 2.0f * M_PI;
+ return {cos(t), sin(t)};
+}
+
void perlin_noise_t::generate(prng_t *prng, size_t size_)
{
if (table)