From 2c8e84a3d2fe93f84d0ffca63967e81a03534c00 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sun, 1 Apr 2018 13:56:14 +0200 Subject: Split units.cpp. --- src/game/units.cpp | 436 +---------------------------------------------------- 1 file changed, 1 insertion(+), 435 deletions(-) (limited to 'src/game/units.cpp') 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(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 -- cgit