#include "BaseBattle.h" #include #include #include #include #include #include namespace kurator { namespace battles { int total_teams_in(const Scenario& scenario); BaseBattle::BaseBattle(const Scenario& scenario) : _registry {}, spawner {total_teams_in(scenario), 2.5, 0.1} { const auto repo = universe::load_sample(); for (const auto& ship : scenario.ships) { const auto entity = _registry.create(); const auto type = repo->ship_type(ship.type); _registry.emplace::type>(entity, type); _registry.emplace(entity, ship.team); _registry.emplace(entity, spawner.get(ship.team)); _registry.emplace(entity, 0.4); _registry.emplace(entity, Point{0.0, 0.0}); _registry.emplace(entity, type.base_health_points); for (const auto& turret_name : ship.turrets) { const auto turret = _registry.create(); const auto def = repo->turret_type(turret_name); _registry.emplace::type>(turret, def); _registry.emplace(turret, 0.0, entity); _registry.emplace(turret, Point{0.0, 0.0}, 0.0, entity); } manager.add(ship.team, entity); // registry supports on construction events } } entt::registry& BaseBattle::registry() { return _registry; } void BaseBattle::update(const float dt) { auto view = _registry.view(); for (auto&& [entity, team, transform, state, movement] : view.each()) { if (!_registry.valid(state.target)) state.target = manager.random((team.id + 1) % 2); if (!_registry.valid(state.target)) continue; const auto target = _registry.get(state.target); const double speed = movement.speed * dt; const Point diff = target.position - transform.position; const Point dest = target.position - diff.normalized(); const Point move = dest - transform.position; if (move.magnitude() > speed) { const Point eff = move.normalized().scale(speed); transform.position.x += eff.x; transform.position.y += eff.y; } } auto view2 = _registry.view(); for (auto&& [entity, points] : view2.each()) { if (points.health <= 0.0) _registry.destroy(entity); } auto view3 = _registry.view(); for (auto&& [entity, control, def] : view3.each()) { // split into systems! if (!_registry.valid(control.owner)) { _registry.destroy(entity); continue; } const auto& state = _registry.get(control.owner); // no checks if (!_registry.valid(state.target)) continue; if (control.reload > 0.0) control.reload -= dt; if (control.reload <= 0.0) { auto& target_points = _registry.get(state.target); target_points.health -= def.base_damage; control.reload = def.rate_of_fire; } } manager.clear(_registry); // registry supports on destructions events } int total_teams_in(const Scenario& scenario) { int last_team = 0; for (const auto& ship : scenario.ships) { if (ship.team > last_team) last_team = ship.team; } return last_team + 1; } } // namespace battles } // namespace kurator