diff options
author | Paweł Redman <pawel.redman@gmail.com> | 2017-12-18 17:33:49 +0000 |
---|---|---|
committer | Paweł Redman <pawel.redman@gmail.com> | 2017-12-18 17:33:49 +0000 |
commit | c6489d36f6de7464c555f04d5d4324f50fa6c51f (patch) | |
tree | fde3f3d3a0d720a328f8b74ac2d0d14a0d463f02 /src/game/units.cpp | |
parent | 41bebb262aa8f346ce6cdaefd854c9077ae84f97 (diff) |
Start experimenting with fear.
Diffstat (limited to 'src/game/units.cpp')
-rw-r--r-- | src/game/units.cpp | 129 |
1 files changed, 118 insertions, 11 deletions
diff --git a/src/game/units.cpp b/src/game/units.cpp index cbc3f1a..24b9567 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -46,7 +46,7 @@ void unit_t::render_to(render::state_t *render) float height; text_pos = render_bounds[0] + v2f_t(render_bounds.dim(0) / 2, -render_bounds.dim(1) * 0.1); - height = size.dim_min() * 0.20f; + height = size.dim_min() * 0.50f; render->render_text(text_pos, height, say_text, render::ALIGN_CENTER_BOTTOM, sf::Color::White); @@ -65,6 +65,9 @@ void unit_t::render_to(render::state_t *render) else ss << "S"; + if (controllable) + ss << "C"; + text_pos = render_bounds[0] + v2f_t(render_bounds.dim(0) / 2, -render_bounds.dim(1) * 0.1); height = size.dim_min() * 0.40f; text_pos[1] -= height; @@ -119,7 +122,7 @@ bool unit_t::keep_moving(double speed) } cmodel_next.bounds = size + x_new; - cmodel_next.cflags = cmodel.cflags; + cmodel_next.cflags = move.cflags; if (!world->test_rect(&cmodel_next, this)) { x = x_new; cmodel = cmodel_next; @@ -142,7 +145,7 @@ bool unit_t::keep_moving(double speed) return rv; } -bool unit_t::start_moving(v2f_t dst, world::cflags_t cflags) +bool unit_t::start_moving(v2f_t dst) { world::cmodel_t rep; @@ -154,7 +157,7 @@ bool unit_t::start_moving(v2f_t dst, world::cflags_t cflags) move.dst = dst; move.path.clear(); - rep.cflags = cflags; + rep.cflags = move.cflags; rep.bounds = cmodel.bounds; if (!world->find_path(x, move.dst, &rep, this, &move.path)) { @@ -270,6 +273,7 @@ unit_soldier_t::unit_soldier_t(game::state_t *game) : unit_t(game, UNIT_SOLDIER) render_size[0] = v2f_t(-0.5f, -1.0f); render_size[1] = v2f_t(+0.5f, +0.5f); cmodel.cflags = CF_BODY; + move.cflags = CF_SOLID | CF_BODY | CF_WATER; name = text::get(text::UNIT_NAME_SOLDIER); @@ -283,6 +287,51 @@ unit_soldier_t::unit_soldier_t(game::state_t *game) : unit_t(game, UNIT_SOLDIER) cs.hit_die = die_t(8); } +void unit_soldier_t::check_area(void) +{ + rectf_t bounds; + + bounds[0] = x - v2f_t(10, 10); + bounds[1] = x + v2f_t(10, 10); + + willpower_bonus = 0; + fear_dc = 0; + + for (world::entity_t *went : game->world.get_entities(bounds, -1)) { + auto ent = dynamic_cast<game::entity_t*>(went); + unit_t *unit; + + // WTF? + if (!ent) + continue; + + // Wake everything around. + if (!ent->ignore_waking) { + ent->wake_time = game->now; + + if (!ent->awake) + ent->wake(); + } + + if (ent->type != ET_UNIT) + continue; + + unit = (unit_t*)ent; + + if (unit->dead) + continue; + + if (unit->friendly) + willpower_bonus += 3; + else { + if (unit->type == UNIT_NEST) + fear_dc += 4; + else + fear_dc += 2; + } + } +} + void unit_soldier_t::target_and_attack(void) { unit_t *target; @@ -317,12 +366,64 @@ void unit_soldier_t::target_and_attack(void) void unit_soldier_t::on_think(void) { - game->wake_everything(x, 10); + check_area(); - target_and_attack(); + if (!panic && fear_dc > 1 && game->now > next_fear_test) { + size_t roll; + bool success; + std::stringstream ss; + + roll = game->roll(die_t(20)); + success = roll + willpower_bonus >= fear_dc; + + ss << name << " " << text::get(text::UNIT_SAVING_THROW_WILLPOWER); + ss << ": " << roll << " + " << willpower_bonus << " = " << roll + willpower_bonus; + ss << " vs " << fear_dc << ": "; + + if (success) + ss << text::get(text::UNIT_SAVING_THROW_SUCCESS); + else + ss << text::get(text::UNIT_SAVING_THROW_FAILURE); + + game->interface->print(ss.str()); + + if (!success) { + say(text::get(text::SAY_PANIC)); + panic = true; + panic_end = game->now + 10; + panic_turn = -INFINITY; + controllable = false; + } + + next_fear_test = game->now + 3; + } + + if (panic && game->now > panic_end) { + move.moving = false; + move.path.clear(); + panic = false; + controllable = true; + } + + if (!panic) { + target_and_attack(); + + if (!keep_moving(4.0)) + say(text::get(text::SAY_BLOCKED)); + } else { + if (!keep_moving(4.0)) + panic_turn = -INFINITY; + + if (game->now >= panic_turn) { + v2f_t t; - if (!keep_moving(4.0)) - say(text::get(text::SAY_BLOCKED)); + t = game->dice_prng.unit_vec2(); + + move.path.clear(); + move.path.push_back(x + t * 10); + panic_turn = game->now + 0.5; + } + } } void unit_soldier_t::on_death(void) @@ -345,7 +446,7 @@ void unit_soldier_t::render_to(render::state_t *render) else legs = &assets::soldier.legs_idle; - if (last_target_time + 3 > game->now) { + if (!panic && last_target_time + 3 > game->now) { if (last_attack + 0.1 > game->now) body = &assets::soldier.body_firing; else @@ -359,7 +460,12 @@ void unit_soldier_t::render_to(render::state_t *render) } render->render(game->now * 10, legs, render_bounds, move.angle); - render->render(game->now * 10, body, render_bounds, body_angle); + + if (panic) + render->render(game->now * 10, &assets::soldier.body_panic, render_bounds); + else + render->render(game->now * 10, body, render_bounds, body_angle); + render->render(game->now * 10, &assets::soldier.head_idle, render_bounds, body_angle); } else render->render(game->now * 10, &assets::soldier.dead, render_bounds); @@ -374,6 +480,7 @@ unit_spider_t::unit_spider_t(game::state_t *game) : unit_t(game, UNIT_SPIDER) render_size[0] = v2f_t(-0.3f, -0.3f); render_size[1] = v2f_t(+0.3f, +0.3f); cmodel.cflags = CF_BODY_SMALL; + move.cflags = CF_SOLID | CF_WATER; name = text::get(text::UNIT_NAME_SPIDER); @@ -394,7 +501,7 @@ void unit_spider_t::target_and_attack(void) if (!target) return; - start_moving(target->x, CF_SOLID | CF_WATER); + start_moving(target->x); next_targetting = game->now + 0.2; if (last_attack + 0.5 > game->now) |