#ifndef ACTIONNEEDEDMANAGER_H #define ACTIONNEEDEDMANAGER_H #include #include #include #include class Unit; class City; enum class ActionNeededType { UnitIdle = 0, CityNoProduction = 1, CityFreePopulation = 2, NoResearch = 3 }; struct ActionItem { ActionNeededType type = ActionNeededType::UnitIdle; int entityId = -1; double firstDetectedTime = 0.0; // Monotonic game time in seconds int auxValue = 0; // e.g. free population count bool dismissed = false; int dismissedAuxValue = 0; // Value at the time of dismissal QString getKey() const { return QString("%1_%2").arg(static_cast(type)).arg(entityId); } }; struct ActionNeededConfig { bool enabled = true; bool trackIdleUnits = true; bool trackCityNoProduction = true; bool trackCityFreePopulation = true; bool trackNoResearch = true; int maxVisibleItems = 8; int itemWidth = 155; int itemHeight = 42; int bottomOffset = 16; int itemSpacing = 8; int borderRadius = 6; bool pulseAnimation = true; float pulseSpeed = 3.0f; QColor unitIdleColor = QColor(60, 160, 255); QColor cityNoProdColor = QColor(255, 160, 40); QColor cityFreePopColor = QColor(70, 220, 130); QColor noResearchColor = QColor(56, 200, 255); QColor cardBgColor = QColor(18, 24, 34); int cardBgAlpha = 235; }; class ActionNeededManager { public: ActionNeededManager(); bool loadConfigFile(const QString &filePath); const ActionNeededConfig& config() const { return m_config; } void update(float deltaTime, int activePlayerId, const std::vector> &units, const std::vector &cities, bool needsResearch = false); std::vector getVisibleItems() const; int getVisibleCount() const; void dismissItem(ActionNeededType type, int entityId); void resetDismissals(); double getElapsedGameTime() const { return m_elapsedGameTime; } void reset(); private: ActionNeededConfig m_config; std::vector m_items; double m_elapsedGameTime; }; #endif // ACTIONNEEDEDMANAGER_H