diff options
author | Paweł Redman <pawel.redman@gmail.com> | 2018-04-01 13:56:14 +0200 |
---|---|---|
committer | Paweł Redman <pawel.redman@gmail.com> | 2018-04-01 13:56:14 +0200 |
commit | 2c8e84a3d2fe93f84d0ffca63967e81a03534c00 (patch) | |
tree | 508859df1523d85afc5bc618e8511306a3b4b821 /src/game | |
parent | be628dc7f9c32ca84674c8717f07cc15a40f333c (diff) |
Split units.cpp.
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/game.hpp | 2 | ||||
-rw-r--r-- | src/game/unit_nest.cpp | 96 | ||||
-rw-r--r-- | src/game/unit_soldier.cpp | 301 | ||||
-rw-r--r-- | src/game/unit_spider.cpp | 104 | ||||
-rw-r--r-- | src/game/units.cpp | 436 |
5 files changed, 504 insertions, 435 deletions
diff --git a/src/game/game.hpp b/src/game/game.hpp index 331c1d1..517f74a 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -164,6 +164,8 @@ namespace game { class fx_move_marker_t; + unit_t *find_target(world::world_t *world, v2f_t x, float r, bool friendly); + class unit_t : public entity_t { protected: double next_targetting = -INFINITY; diff --git a/src/game/unit_nest.cpp b/src/game/unit_nest.cpp new file mode 100644 index 0000000..326741e --- /dev/null +++ b/src/game/unit_nest.cpp @@ -0,0 +1,96 @@ +/* +This file is part of Minitrem. + +Minitrem is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +Minitrem is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitrem. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "game.hpp" + +namespace game { + + +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); + + ignore_waking = false; + + health = max_health = 45; + + 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_SOLID | CF_WATER | 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); +} + +} diff --git a/src/game/unit_soldier.cpp b/src/game/unit_soldier.cpp new file mode 100644 index 0000000..152f475 --- /dev/null +++ b/src/game/unit_soldier.cpp @@ -0,0 +1,301 @@ +/* +This file is part of Minitrem. + +Minitrem is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +Minitrem is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitrem. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "game.hpp" + +namespace game { + +unit_soldier_t::unit_soldier_t(game::state_t *game) : unit_t(game, UNIT_SOLDIER) +{ + size[0] = v2f_t(-0.3f, +0.0f); + size[1] = v2f_t(+0.3f, +0.3f); + render_size[0] = v2f_t(-0.5f, -1.2f); + render_size[1] = v2f_t(+0.5f, +0.3f); + cmodel.cflags = CF_BODY; + move.cflags = CF_SOLID | CF_BODY | CF_WATER; + + name = text::get(text::UNIT_NAME_SOLDIER); + + wake(); + friendly = true; + controllable = true; + + health = max_health = 20; +} + +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; + + if (ent == this) + 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 += 6; + else { + if (unit->type == UNIT_NEST) + fear_dc += 6; + else + fear_dc += 4; + } + } +} + +static v2f_t spread_aim(v2f_t aim, float cof, procgen::prng_t *prng) +{ + float t; + + t = prng->next_float(-cof / 2, cof / 2); + + return v2f_t(cos(t) * aim[0] - sin(t) * aim[1], + sin(t) * aim[0] + cos(t) * aim[1]); +} + +void unit_soldier_t::shoot(v2f_t aim) +{ + v2f_t end; + world::trace_t trace; + v2f_t muzzle_point; + fx_tracer_t *tracer; + fx_flash_t *flash; + + end = x + (aim - x).norm() * 40; + + trace = world->trace(x, end, CF_SOLID); + + muzzle_point = x + v2f_t(0, -1.0f); + + tracer = new fx_tracer_t(game, muzzle_point, trace.end); + tracer->place(&game->world); + + flash = new fx_flash_t(game, muzzle_point, 5.0f); + flash->place(&game->world); + + last_attack = game->now; + assets::soldier.fire.play_3d(x); + //target->damage(3, this); FIXME +} + +void unit_soldier_t::target_and_attack(void) +{ + unit_t *target; + v2f_t aim; + + if (manual_firing) { + aim = manual_firing_target; + last_target_x = aim; + goto skip_targetting; + } + + if (game->now < next_targetting) + return; + + next_targetting = game->now + 0.2; + + target = find_target(world, x, 5.0f, false); + if (!target) + return; + aim = target->x; + + last_target_time = game->now; + last_target_x = target->x; + +skip_targetting: + if (last_attack + game->dice_prng.next_float(1.4f, 1.6f) > game->now) + return; + + shoot(spread_aim(aim, 0.2, &game->dice_prng)); +} + +void unit_soldier_t::on_think(void) +{ + check_area(); + + if (panic && game->now > panic_end) { + move.moving = false; + move.path.clear(); + panic = false; + controllable = true; + } + + if (health == max_health) + willpower_bonus += 3; + else if (fear_dc > 1 && health < max_health / 2) + fear_dc += 3; + + 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) { + target_and_attack(); + + keep_moving(2.0); + if (!move.moving) + move_marker.reset(); + } else { + move.moving = true; + keep_moving(3.0); + + if (game->now >= panic_turn) { + v2f_t t; + + t = game->dice_prng.unit_vec2(); + + move.path.clear(); + move.path.push_back(x + t * 10); + panic_turn = game->now + 0.3; + } + } + + if (move.moving && (x - move.last_step).len() > 0.5f) { + move.last_step = x; + assets::soldier.step_stone.play_3d(x); + } +} + +void unit_soldier_t::on_death(void) +{ + render_size[0] = v2f_t(-0.75f, -0.5f); + render_size[1] = v2f_t(+0.75f, +0.5f); + render_layer = -1; + cmodel.cflags = CF_BACKGROUND; + place(world, x); + controllable = false; + game->selected_units.erase(this); + move_marker.reset(); +} + +void unit_soldier_t::render_to(render::state_t *render) +{ + sf::Color selection_color; + + if (selected == selection_cookie) { + if (health == max_health) + selection_color = sf::Color::Green; + else if (health >= max_health / 2) + selection_color = sf::Color::Yellow; + else if (dead) + selection_color = sf::Color::Black; + else + selection_color = sf::Color::Red; + + if (panic && (game->now - floor(game->now) > 0.5)) + selection_color = sf::Color::Blue; + + render->render(0.0, &assets::unit_selected, cmodel.bounds, selection_color); + } + + if (!dead) { + render::oriented_sprite_t *legs, *body; + float body_angle; + + if (move.moving && !move.blocked) + legs = &assets::soldier.legs_walking; + else + legs = &assets::soldier.legs_idle; + + if (!panic && (manual_firing || last_target_time + 3 > game->now)) { + if (last_attack + 0.1 > game->now) + body = &assets::soldier.body_firing; + else + body = &assets::soldier.body_aiming; + + body_angle = (last_target_x - x).angle(); + + } else { + body = &assets::soldier.body_idle; + body_angle = move.angle; + } + + render->render(game->now * 10, legs, render_bounds, move.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); + + unit_t::render_to(render); +} + +void unit_soldier_t::render_late_to(render::state_t *render) +{ + if (selected == selection_cookie) + render->render(0.0, &assets::unit_selected_halo, cmodel.bounds, selection_color); +} + +} diff --git a/src/game/unit_spider.cpp b/src/game/unit_spider.cpp new file mode 100644 index 0000000..ed6b0f0 --- /dev/null +++ b/src/game/unit_spider.cpp @@ -0,0 +1,104 @@ +/* +This file is part of Minitrem. + +Minitrem is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +Minitrem is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Minitrem. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "game.hpp" + +namespace game { + +unit_spider_t::unit_spider_t(game::state_t *game) : unit_t(game, UNIT_SPIDER) +{ + size[0] = v2f_t(-0.2f, +0.0f); + size[1] = v2f_t(+0.2f, +0.3f); + 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 | CF_BODY_SMALL; + + name = text::get(text::UNIT_NAME_SPIDER); + + ignore_waking = false; + + health = max_health = 4; +} + +void unit_spider_t::target_and_attack(void) +{ + unit_t *target; + world::trace_t trace; + + if (game->now < next_targetting) + return; + + target = find_target(world, x, 10.0f, true); + if (!target) + return; + + start_moving(target->x); + next_targetting = game->now + game->dice_prng.next_float(0.2f, 0.4f); + + if (last_attack + 0.5 > game->now) + return; + + if ((x - target->x).len() >= 1.0f) + return; + + trace = world->trace(x, target->x, CF_SOLID); + if (trace.hit) + return; + + last_attack = game->now; + target->damage(15, this); +} + +void unit_spider_t::on_think(void) +{ + return; + + target_and_attack(); + + keep_moving(4.0); + + if (!move.moving && wake_time + 5 < game->now) + sleep(); +} + +void unit_spider_t::on_wake(void) +{ +} + +void unit_spider_t::on_death(void) +{ + render_layer = -1; + cmodel.cflags = CF_BACKGROUND; +} + +void unit_spider_t::render_to(render::state_t *render) +{ + bool moving; + + moving = move.moving && !move.blocked; + + if (!dead) + render->render(game->now * 20, (moving ? &assets::spider.walking : + &assets::spider.idle), render_bounds, move.angle); + else + render->render(game->now * 20, &assets::spider.dead, render_bounds); + + unit_t::render_to(render); +} + +} diff --git a/src/game/units.cpp b/src/game/units.cpp index 63c16db..bbddd93 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -222,7 +222,7 @@ void unit_t::die(unit_t *killer) on_death(); } -static unit_t *find_target(world::world_t *world, v2f_t x, float r, +unit_t *find_target(world::world_t *world, v2f_t x, float r, bool friendly) { rectf_t rect; @@ -257,438 +257,4 @@ static unit_t *find_target(world::world_t *world, v2f_t x, float r, return nearest; } -unit_soldier_t::unit_soldier_t(game::state_t *game) : unit_t(game, UNIT_SOLDIER) -{ - size[0] = v2f_t(-0.3f, +0.0f); - size[1] = v2f_t(+0.3f, +0.3f); - render_size[0] = v2f_t(-0.5f, -1.2f); - render_size[1] = v2f_t(+0.5f, +0.3f); - cmodel.cflags = CF_BODY; - move.cflags = CF_SOLID | CF_BODY | CF_WATER; - - name = text::get(text::UNIT_NAME_SOLDIER); - - wake(); - friendly = true; - controllable = true; - - health = max_health = 20; -} - -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; - - if (ent == this) - 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 += 6; - else { - if (unit->type == UNIT_NEST) - fear_dc += 6; - else - fear_dc += 4; - } - } -} - -static v2f_t spread_aim(v2f_t aim, float cof, procgen::prng_t *prng) -{ - float t; - - t = prng->next_float(-cof / 2, cof / 2); - - return v2f_t(cos(t) * aim[0] - sin(t) * aim[1], - sin(t) * aim[0] + cos(t) * aim[1]); -} - -void unit_soldier_t::shoot(v2f_t aim) -{ - v2f_t end; - world::trace_t trace; - v2f_t muzzle_point; - fx_tracer_t *tracer; - fx_flash_t *flash; - - end = x + (aim - x).norm() * 40; - - trace = world->trace(x, end, CF_SOLID); - - muzzle_point = x + v2f_t(0, -1.0f); - - tracer = new fx_tracer_t(game, muzzle_point, trace.end); - tracer->place(&game->world); - - flash = new fx_flash_t(game, muzzle_point, 5.0f); - flash->place(&game->world); - - last_attack = game->now; - assets::soldier.fire.play_3d(x); - //target->damage(3, this); FIXME -} - -void unit_soldier_t::target_and_attack(void) -{ - unit_t *target; - v2f_t aim; - - if (manual_firing) { - aim = manual_firing_target; - last_target_x = aim; - goto skip_targetting; - } - - if (game->now < next_targetting) - return; - - next_targetting = game->now + 0.2; - - target = find_target(world, x, 5.0f, false); - if (!target) - return; - aim = target->x; - - last_target_time = game->now; - last_target_x = target->x; - -skip_targetting: - if (last_attack + game->dice_prng.next_float(1.4f, 1.6f) > game->now) - return; - - shoot(spread_aim(aim, 0.2, &game->dice_prng)); -} - -void unit_soldier_t::on_think(void) -{ - check_area(); - - if (panic && game->now > panic_end) { - move.moving = false; - move.path.clear(); - panic = false; - controllable = true; - } - - if (health == max_health) - willpower_bonus += 3; - else if (fear_dc > 1 && health < max_health / 2) - fear_dc += 3; - - 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) { - target_and_attack(); - - keep_moving(2.0); - if (!move.moving) - move_marker.reset(); - } else { - move.moving = true; - keep_moving(3.0); - - if (game->now >= panic_turn) { - v2f_t t; - - t = game->dice_prng.unit_vec2(); - - move.path.clear(); - move.path.push_back(x + t * 10); - panic_turn = game->now + 0.3; - } - } - - if (move.moving && (x - move.last_step).len() > 0.5f) { - move.last_step = x; - assets::soldier.step_stone.play_3d(x); - } -} - -void unit_soldier_t::on_death(void) -{ - render_size[0] = v2f_t(-0.75f, -0.5f); - render_size[1] = v2f_t(+0.75f, +0.5f); - render_layer = -1; - cmodel.cflags = CF_BACKGROUND; - place(world, x); - controllable = false; - game->selected_units.erase(this); - move_marker.reset(); -} - -void unit_soldier_t::render_to(render::state_t *render) -{ - sf::Color selection_color; - - if (selected == selection_cookie) { - if (health == max_health) - selection_color = sf::Color::Green; - else if (health >= max_health / 2) - selection_color = sf::Color::Yellow; - else if (dead) - selection_color = sf::Color::Black; - else - selection_color = sf::Color::Red; - - if (panic && (game->now - floor(game->now) > 0.5)) - selection_color = sf::Color::Blue; - - render->render(0.0, &assets::unit_selected, cmodel.bounds, selection_color); - } - - if (!dead) { - render::oriented_sprite_t *legs, *body; - float body_angle; - - if (move.moving && !move.blocked) - legs = &assets::soldier.legs_walking; - else - legs = &assets::soldier.legs_idle; - - if (!panic && (manual_firing || last_target_time + 3 > game->now)) { - if (last_attack + 0.1 > game->now) - body = &assets::soldier.body_firing; - else - body = &assets::soldier.body_aiming; - - body_angle = (last_target_x - x).angle(); - - } else { - body = &assets::soldier.body_idle; - body_angle = move.angle; - } - - render->render(game->now * 10, legs, render_bounds, move.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); - - unit_t::render_to(render); -} - -void unit_soldier_t::render_late_to(render::state_t *render) -{ - if (selected == selection_cookie) - render->render(0.0, &assets::unit_selected_halo, cmodel.bounds, selection_color); -} - -unit_spider_t::unit_spider_t(game::state_t *game) : unit_t(game, UNIT_SPIDER) -{ - size[0] = v2f_t(-0.2f, +0.0f); - size[1] = v2f_t(+0.2f, +0.3f); - 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 | CF_BODY_SMALL; - - name = text::get(text::UNIT_NAME_SPIDER); - - ignore_waking = false; - - health = max_health = 4; -} - -void unit_spider_t::target_and_attack(void) -{ - unit_t *target; - world::trace_t trace; - - if (game->now < next_targetting) - return; - - target = find_target(world, x, 10.0f, true); - if (!target) - return; - - start_moving(target->x); - next_targetting = game->now + game->dice_prng.next_float(0.2f, 0.4f); - - if (last_attack + 0.5 > game->now) - return; - - if ((x - target->x).len() >= 1.0f) - return; - - trace = world->trace(x, target->x, CF_SOLID); - if (trace.hit) - return; - - last_attack = game->now; - target->damage(15, this); -} - -void unit_spider_t::on_think(void) -{ - return; - - target_and_attack(); - - keep_moving(4.0); - - if (!move.moving && wake_time + 5 < game->now) - sleep(); -} - -void unit_spider_t::on_wake(void) -{ -} - -void unit_spider_t::on_death(void) -{ - render_layer = -1; - cmodel.cflags = CF_BACKGROUND; -} - -void unit_spider_t::render_to(render::state_t *render) -{ - bool moving; - - moving = move.moving && !move.blocked; - - if (!dead) - render->render(game->now * 20, (moving ? &assets::spider.walking : - &assets::spider.idle), render_bounds, move.angle); - else - render->render(game->now * 20, &assets::spider.dead, render_bounds); - - 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); - - ignore_waking = false; - - health = max_health = 45; - - 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_SOLID | CF_WATER | 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 |