| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #include "global_stats_registry.h"
- #include "../core/component.h"
- #include "../core/world.h"
- #include "../units/troop_config.h"
- #include "core/event_manager.h"
- #include "owner_registry.h"
- #include "units/spawn_type.h"
- #include <chrono>
- #include <unordered_map>
- namespace Game::Systems {
- auto GlobalStatsRegistry::instance() -> GlobalStatsRegistry & {
- static GlobalStatsRegistry inst;
- return inst;
- }
- void GlobalStatsRegistry::initialize() {
- m_unit_spawned_subscription =
- Engine::Core::ScopedEventSubscription<Engine::Core::UnitSpawnedEvent>(
- [this](const Engine::Core::UnitSpawnedEvent &e) {
- on_unit_spawned(e);
- });
- m_unit_died_subscription =
- Engine::Core::ScopedEventSubscription<Engine::Core::UnitDiedEvent>(
- [this](const Engine::Core::UnitDiedEvent &e) { on_unit_died(e); });
- m_barrack_captured_subscription =
- Engine::Core::ScopedEventSubscription<Engine::Core::BarrackCapturedEvent>(
- [this](const Engine::Core::BarrackCapturedEvent &e) {
- on_barrack_captured(e);
- });
- }
- void GlobalStatsRegistry::clear() { m_player_stats.clear(); }
- auto GlobalStatsRegistry::get_stats(int owner_id) const -> const PlayerStats * {
- auto it = m_player_stats.find(owner_id);
- if (it != m_player_stats.end()) {
- return &it->second;
- }
- return nullptr;
- }
- auto GlobalStatsRegistry::get_stats(int owner_id) -> PlayerStats * {
- auto it = m_player_stats.find(owner_id);
- if (it != m_player_stats.end()) {
- return &it->second;
- }
- return nullptr;
- }
- void GlobalStatsRegistry::mark_game_start(int owner_id) {
- auto &stats = m_player_stats[owner_id];
- stats.game_start_time = std::chrono::steady_clock::now();
- stats.game_ended = false;
- stats.play_time_sec = 0.0F;
- }
- void GlobalStatsRegistry::mark_game_end(int owner_id) {
- auto it = m_player_stats.find(owner_id);
- if (it != m_player_stats.end() && !it->second.game_ended) {
- it->second.game_end_time = std::chrono::steady_clock::now();
- it->second.game_ended = true;
- auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
- it->second.game_end_time - it->second.game_start_time);
- it->second.play_time_sec = duration.count() / 1000.0F;
- }
- }
- void GlobalStatsRegistry::on_unit_spawned(
- const Engine::Core::UnitSpawnedEvent &event) {
- if (event.is_initial_spawn) {
- if (event.spawn_type == Game::Units::SpawnType::Barracks) {
- auto &stats = m_player_stats[event.owner_id];
- stats.barracks_owned++;
- }
- return;
- }
- auto &stats = m_player_stats[event.owner_id];
- if (event.spawn_type == Game::Units::SpawnType::Barracks) {
- stats.barracks_owned++;
- } else if (event.spawn_type != Game::Units::SpawnType::DefenseTower &&
- event.spawn_type != Game::Units::SpawnType::Home) {
- int const production_cost =
- Game::Units::TroopConfig::instance().getProductionCost(
- event.spawn_type);
- stats.troops_recruited += production_cost;
- }
- }
- void GlobalStatsRegistry::on_unit_died(
- const Engine::Core::UnitDiedEvent &event) {
- if (event.spawn_type != Game::Units::SpawnType::Barracks &&
- event.spawn_type != Game::Units::SpawnType::DefenseTower &&
- event.spawn_type != Game::Units::SpawnType::Home) {
- auto it = m_player_stats.find(event.owner_id);
- if (it != m_player_stats.end()) {
- int const production_cost =
- Game::Units::TroopConfig::instance().getProductionCost(
- event.spawn_type);
- it->second.losses += production_cost;
- }
- }
- if (event.spawn_type == Game::Units::SpawnType::Barracks) {
- auto it = m_player_stats.find(event.owner_id);
- if (it != m_player_stats.end()) {
- it->second.barracks_owned--;
- if (it->second.barracks_owned < 0) {
- it->second.barracks_owned = 0;
- }
- }
- }
- if (event.killer_owner_id != 0 && event.killer_owner_id != event.owner_id) {
- auto &owner_registry = OwnerRegistry::instance();
- if (owner_registry.are_enemies(event.killer_owner_id, event.owner_id)) {
- auto &stats = m_player_stats[event.killer_owner_id];
- if (event.spawn_type != Game::Units::SpawnType::Barracks &&
- event.spawn_type != Game::Units::SpawnType::DefenseTower &&
- event.spawn_type != Game::Units::SpawnType::Home) {
- int const production_cost =
- Game::Units::TroopConfig::instance().getProductionCost(
- event.spawn_type);
- stats.enemies_killed += production_cost;
- }
- }
- }
- }
- void GlobalStatsRegistry::on_barrack_captured(
- const Engine::Core::BarrackCapturedEvent &event) {
- auto prev_it = m_player_stats.find(event.previous_owner_id);
- if (prev_it != m_player_stats.end() && event.previous_owner_id != -1) {
- prev_it->second.barracks_owned--;
- if (prev_it->second.barracks_owned < 0) {
- prev_it->second.barracks_owned = 0;
- }
- }
- auto &new_stats = m_player_stats[event.new_owner_id];
- new_stats.barracks_owned++;
- }
- void GlobalStatsRegistry::rebuild_from_world(Engine::Core::World &world) {
- std::unordered_map<int, std::chrono::steady_clock::time_point> start_times;
- std::unordered_map<int, int> troops_recruited_values;
- std::unordered_map<int, int> enemies_killed_values;
- std::unordered_map<int, int> losses_values;
- for (auto &[owner_id, stats] : m_player_stats) {
- start_times[owner_id] = stats.game_start_time;
- troops_recruited_values[owner_id] = stats.troops_recruited;
- enemies_killed_values[owner_id] = stats.enemies_killed;
- losses_values[owner_id] = stats.losses;
- }
- m_player_stats.clear();
- for (auto &[owner_id, start_time] : start_times) {
- m_player_stats[owner_id].game_start_time = start_time;
- m_player_stats[owner_id].troops_recruited =
- troops_recruited_values[owner_id];
- m_player_stats[owner_id].enemies_killed = enemies_killed_values[owner_id];
- m_player_stats[owner_id].losses = losses_values[owner_id];
- }
- auto entities = world.get_entities_with<Engine::Core::UnitComponent>();
- for (auto *e : entities) {
- auto *unit = e->get_component<Engine::Core::UnitComponent>();
- if ((unit == nullptr) || unit->health <= 0) {
- continue;
- }
- auto &stats = m_player_stats[unit->owner_id];
- if (unit->spawn_type == Game::Units::SpawnType::Barracks) {
- stats.barracks_owned++;
- }
- }
- }
- } // namespace Game::Systems
|