#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) : time {0.0}, _registry {}, spawner {scenario.last_team(), scenario.radius, 0.1} { const auto repo = universe::load_sample(); Builder build {_registry, spawner}; for (const auto& ship : scenario.ships) { const auto entity = build(repo->ship_type(ship.type), ship.team); _registry.emplace(entity, ship.identifier); auto& state = _registry.get(entity); for (const auto& turret_type : ship.turrets) { auto def = repo->turret_type(turret_type); build(def, entity); state.keep_at_range = std::min(state.keep_at_range, def.optimal_range); } manager.add(ship.team, entity); // registry supports on construction events } } entt::registry& BaseBattle::registry() { return _registry; } entt::dispatcher& BaseBattle::dispatcher() { return _dispatcher; } void BaseBattle::update(const float dt) { time += dt; pick_random_targets(); keep_at_range(); update(dt); update(dt); kill_off_dead(); manager.clear(_registry); // registry supports on destructions events manager.update(_dispatcher); } 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 BaseBattle::keep_at_range() { auto view = _registry.view(); for (auto&& [entity, self, ai] : view.each()) { if (!_registry.valid(ai.target)) continue; const auto target = _registry.get(ai.target); const Point offset = target.position - self.position; ai.destination = target.position - offset.normalized().scale(ai.keep_at_range); } } void BaseBattle::kill_off_dead() { auto view = _registry.view(); for (auto&& [entity, points] : view.each()) { if (points.health > 0.0) continue; if (_registry.all_of(entity)) { const auto& [identifier, team] = _registry.get(entity); _dispatcher.trigger(stats::ShipLeft{time, identifier, team.id, true}); } _registry.destroy(entity); } } } // namespace sim } // namespace kurator