#include "BaseBattle.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "Builder.h" namespace kurator { namespace sim { BaseBattle::BaseBattle(const campaign::Scenario& scenario) : _registry {}, spawner {scenario.last_team(), scenario.radius, 0.1} { Builder build {_registry, spawner}; for (const auto& ship : scenario.ships) { const auto entity = build(ship.loadout.type, ship.team); _registry.emplace(entity, ship.identifier); auto& state = _registry.get(entity); for (const auto& turret_type : ship.loadout.turrets) { build(turret_type, entity); state.keep_at_range = std::min(state.keep_at_range, turret_type.optimal_range); } manager.add(ship.team, entity); // registry supports on construction events } } entt::registry& BaseBattle::registry() { return _registry; } entt::dispatcher& BaseBattle::dispatcher() { return _dispatcher; } static void keep_at_range(engine::Context& ctx); static void kill_off_dead(engine::Context& ctx); void BaseBattle::update(engine::Context& ctx) { pick_random_targets(); keep_at_range(ctx); FloatingMovement::update(ctx); TurretControl::update(ctx); kill_off_dead(ctx); manager.update(ctx); } void BaseBattle::pick_random_targets() { auto view = _registry.view(); for (auto&& [entity, team, ai] : view.each()) { if (!_registry.valid(ai.target)) ai.target = manager.random(team.id); } } void keep_at_range(engine::Context& ctx) { auto view = ctx.registry.view(); for (auto&& [entity, self, ai] : view.each()) { if (!ctx.registry.valid(ai.target)) continue; const auto target = ctx.registry.get(ai.target); const auto offset = target.position - self.position; ai.destination = target.position - offset.normalized().scale(ai.keep_at_range); } } void kill_off_dead(engine::Context& ctx) { auto view = ctx.registry.view(); for (auto&& [entity, points] : view.each()) { if (points.is_alive()) continue; if (ctx.registry.all_of(entity)) { const auto& [identifier, team] = ctx.registry.get(entity); ctx.dispatcher.trigger(stats::ShipLeft{ctx.clock.game, identifier, team.id, true}); ctx.dispatcher.trigger(Destroyed{entity}); } ctx.registry.destroy(entity); } } } // namespace sim } // namespace kurator