#ifndef GAMEMANAGER_H #define GAMEMANAGER_H #include #include #include #include "player.h" #include "unitconfig.h" #include "buildingconfig.h" #include "roadconfig.h" #include "unit.h" #include "city.h" #include "matrix2d.h" #include "terrain.h" #include "terrainyieldmanager.h" #include "actionneededmanager.h" #include "techconfig.h" enum class ActionMode { None, Move, Attack, BuildCity, BuildFarm, BuildRoad }; struct TileImprovement { QString improvementId; // "farm" int tileX; int tileY; int playerId; QVector3D worldPos; }; struct FloatingText { QString text; QVector3D worldPos; float life; // Remaining seconds float maxLife; QColor color; }; class GameManager { public: static GameManager& instance(); void init(const QString &baseDir, Matrix2D *mapPoints, int numPoints05); void update(float deltaTime, Matrix2D *mapPoints, int numPoints05); PlayerManager& players() { return m_playerManager; } const PlayerManager& players() const { return m_playerManager; } UnitConfigManager& unitConfigs() { return m_unitConfigManager; } const UnitConfigManager& unitConfigs() const { return m_unitConfigManager; } BuildingConfigManager& buildingConfigs() { return m_buildingConfigManager; } const BuildingConfigManager& buildingConfigs() const { return m_buildingConfigManager; } RoadConfigManager& roadConfigs() { return m_roadConfigManager; } const RoadConfigManager& roadConfigs() const { return m_roadConfigManager; } ActionNeededManager& actionNeededManager() { return m_actionNeededManager; } const ActionNeededManager& actionNeededManager() const { return m_actionNeededManager; } TechTreeManager& techTree() { return m_techTreeManager; } const TechTreeManager& techTree() const { return m_techTreeManager; } // Tech Tree View & Research System bool isTechTreeOpen() const { return m_isTechTreeOpen; } void openTechTree(); void closeTechTree(); void toggleTechTree(); int calculatePlayerSciencePerTick(int playerId, Matrix2D *mapPoints, int numPoints05) const; int getTechRemainingScience(const Player &player, const QString &techId) const; bool selectTechForPlayer(int playerId, const QString &targetTechId, bool appendToQueue = false); void removeTechFromPlayerQueue(int playerId, const QString &techId); void clearPlayerResearchQueue(int playerId); void advancePlayerResearch(Player &player, int scienceGenerated); QStringList getTechUnlocks(const QString &techId) const; QStringList getTechObsoletes(const QString &techId) const; const std::vector>& getUnits() const { return m_units; } const std::vector& getCities() const { return m_cities; } std::vector& getCitiesMutable() { return m_cities; } const std::vector& getFloatingTexts() const { return m_floatingTexts; } Unit* getSelectedUnit(); const Unit* getSelectedUnit() const; void selectUnit(int id); void deselectUnit(); ActionMode currentActionMode() const { return m_actionMode; } void setActionMode(ActionMode mode) { m_actionMode = mode; } Unit* getUnitAt(int tx, int ty); Unit* getUnitById(int id); City* getCityAt(int tx, int ty); City* getCityById(int id); // City View System bool isInCityView() const { return m_activeCityViewId != -1; } int getActiveCityViewId() const { return m_activeCityViewId; } City* getActiveCityView(); const City* getActiveCityView() const; void enterCityView(int cityId); void exitCityView(); CityYieldSummary calculateCityYields(const City &city, Matrix2D *mapPoints, int numPoints05) const; void processTickYields(Matrix2D *mapPoints, int numPoints05); QMap getTileYields(int tx, int ty, Matrix2D *mapPoints, int numPoints05) const; int getTileYield(int tx, int ty, const QString &res, Matrix2D *mapPoints, int numPoints05) const; QString getBestTileResource(int tx, int ty, Matrix2D *mapPoints, int numPoints05) const; bool isTileOwned(int tx, int ty, int *outOwnerCityId = nullptr) const; bool buyTileForCity(int cityId, int tx, int ty); void queueCityProject(int cityId, CityProjectType type, const QString &id); void setCityProject(int cityId, CityProjectType type, const QString &id); void cancelCityProject(int cityId); void removeQueuedCityProject(int cityId, int queueIndex); void completeCityProject(City &city, Matrix2D *mapPoints, int numPoints05); void getPlannedOriginTile(const Unit &unit, bool appendWithShift, int &outX, int &outY) const; bool scheduleOrStartUnitAction(Unit &unit, const UnitAction &action, bool appendWithShift, Matrix2D *mapPoints, int numPoints05); bool startUnitAction(Unit &unit, const UnitAction &action, Matrix2D *mapPoints, int numPoints05); void continueCurrentUnitAction(Unit &unit, Matrix2D *mapPoints, int numPoints05); bool commandMoveSelected(int targetX, int targetY, Matrix2D *mapPoints, int numPoints05, bool appendWithShift = false); bool commandAttack(Unit *target, Matrix2D *mapPoints = nullptr, int numPoints05 = 0, bool appendWithShift = false); bool commandBuildCityAtTileSelected(int targetX, int targetY, Matrix2D *mapPoints, int numPoints05, bool appendWithShift = false); bool commandBuildFarmAtTileSelected(int targetX, int targetY, Matrix2D *mapPoints, int numPoints05, bool appendWithShift = false); bool commandBuildRoadToTileSelected(int targetX, int targetY, Matrix2D *mapPoints, int numPoints05, bool appendWithShift = false); void commandBuildCitySelected(Matrix2D *mapPoints, int numPoints05); void commandBuildFarmSelected(Matrix2D *mapPoints, int numPoints05); void commandBuildRoadSelected(Matrix2D *mapPoints, int numPoints05); void advanceRoadRoute(Unit &unit, Matrix2D *mapPoints, int numPoints05); void completeUnitBuilding(Unit &unit, Matrix2D *mapPoints, int numPoints05); void processUnitActionQueue(Unit &unit, Matrix2D *mapPoints, int numPoints05); const std::map, TileImprovement>& getTileImprovements() const { return m_tileImprovements; } const TileImprovement* getImprovementAt(int tx, int ty) const; bool hasImprovementAt(int tx, int ty) const; const std::map, TileRoad>& getTileRoads() const { return m_tileRoads; } const TileRoad* getRoadAt(int tx, int ty) const; bool hasRoadAt(int tx, int ty) const; void addRoad(int tx, int ty, int playerId, const QString &roadTypeId = "dirt", Matrix2D *mapPoints = nullptr, int numPoints05 = 0); void removeRoad(int tx, int ty); void updateRoadConnections(int tx, int ty); float getRoadSpeedMultiplierBetween(int fromX, int fromY, int toX, int toY) const; float getTickDuration() const { return m_movementTickDuration; } void setTickDuration(float d) { m_movementTickDuration = std::max(1.0f, d); } float getTickTimer() const { return m_tickTimer; } float getSimSpeed() const { return m_simSpeedMultiplier; } void setSimSpeed(float s) { m_simSpeedMultiplier = std::max(0.2f, std::min(10.0f, s)); } int getMaxActionQueueSize() const { return m_maxActionQueueSize; } bool isActionQueueingAllowed() const { return m_allowActionQueueing; } bool isAutoQueueMoveWhenBusy() const { return m_autoQueueMoveWhenBusy; } void addFloatingText(const QString &text, const QVector3D &worldPos, const QColor &color, float duration = 1.8f); int getNextUnitId() { return ++m_nextUnitId; } int getNextCityId() { return ++m_nextCityId; } Unit* spawnUnit(const QString &configId, int playerId, int tileX, int tileY, Matrix2D *mapPoints, int numPoints05); private: GameManager(); ~GameManager() = default; PlayerManager m_playerManager; UnitConfigManager m_unitConfigManager; BuildingConfigManager m_buildingConfigManager; RoadConfigManager m_roadConfigManager; ActionNeededManager m_actionNeededManager; TechTreeManager m_techTreeManager; std::vector> m_units; std::vector m_cities; std::vector m_floatingTexts; std::map, TileImprovement> m_tileImprovements; std::map, TileRoad> m_tileRoads; int m_selectedUnitId; int m_activeCityViewId; bool m_isTechTreeOpen; ActionMode m_actionMode; float m_movementTickDuration; // Default 30.0s float m_tickTimer; float m_simSpeedMultiplier; // 1.0x, 2.0x, etc. int m_maxActionQueueSize; bool m_autoQueueMoveWhenBusy; bool m_allowActionQueueing; int m_nextUnitId; int m_nextCityId; bool m_initialized; }; #endif // GAMEMANAGER_H