GameLogic.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: GameLogic.h //////////////////////////////////////////////////////////////////////////////
  24. // GameLogic singleton class - defines interface to GameLogic methods and objects
  25. // Author: Michael S. Booth, October 2000
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef _GAME_LOGIC_H_
  29. #define _GAME_LOGIC_H_
  30. #include "Common/GameCommon.h" // ensure we get DUMP_PERF_STATS, or not
  31. #include "Common/GameType.h"
  32. #include "Common/Snapshot.h"
  33. #include "Common/STLTypedefs.h"
  34. #include "Common/ObjectStatusTypes.h"
  35. #include "GameNetwork/NetworkDefs.h"
  36. #include "Common/STLTypedefs.h"
  37. #include "GameLogic/Module/UpdateModule.h" // needed for DIRECT_UPDATEMODULE_ACCESS
  38. /*
  39. At one time, we distinguished between sleepy and nonsleepy
  40. update modules, and kept a separate list for each. however,
  41. now that the bulk of update modules are sleepy, profiling shows
  42. that there is no real advantage to having the separate list,
  43. so to simplify the world, I am removing it. If ALLOW_NONSLEEPY_UPDATES
  44. is still undefined when we ship, please just nuke all the undefed
  45. code. (srj)
  46. */
  47. #define NO_ALLOW_NONSLEEPY_UPDATES
  48. // forward declarations
  49. class AudioEventRTS;
  50. class Object;
  51. class Drawable;
  52. class Player;
  53. class ThingTemplate;
  54. class Team;
  55. class CommandList;
  56. class GameMessage;
  57. class LoadScreen;
  58. class WindowLayout;
  59. class TerrainLogic;
  60. class GhostObjectManager;
  61. class CommandButton;
  62. enum BuildableStatus;
  63. typedef const CommandButton* ConstCommandButtonPtr;
  64. // What kind of game we're in.
  65. enum
  66. {
  67. GAME_SINGLE_PLAYER,
  68. GAME_LAN,
  69. GAME_SKIRMISH,
  70. GAME_REPLAY,
  71. GAME_SHELL,
  72. GAME_INTERNET,
  73. GAME_NONE
  74. };
  75. enum
  76. {
  77. CRC_CACHED,
  78. CRC_RECALC
  79. };
  80. /// Function pointers for use by GameLogic callback functions.
  81. typedef void (*GameLogicFuncPtr)( Object *obj, void *userData );
  82. //typedef std::hash_map<ObjectID, Object *, rts::hash<ObjectID>, rts::equal_to<ObjectID> > ObjectPtrHash;
  83. //typedef ObjectPtrHash::const_iterator ObjectPtrIter;
  84. typedef std::vector<Object*> ObjectPtrVector;
  85. // ------------------------------------------------------------------------------------------------
  86. /**
  87. * The implementation of GameLogic
  88. */
  89. class GameLogic : public SubsystemInterface, public Snapshot
  90. {
  91. public:
  92. GameLogic( void );
  93. virtual ~GameLogic();
  94. // subsytem methods
  95. virtual void init( void ); ///< Initialize or re-initialize the instance
  96. virtual void reset( void ); ///< Reset the logic system
  97. virtual void update( void ); ///< update the world
  98. #if defined(_DEBUG) || defined(_INTERNAL)
  99. Int getNumberSleepyUpdates() const {return m_sleepyUpdates.size();} //For profiling, so not in Release.
  100. #endif
  101. void processCommandList( CommandList *list ); ///< process the command list
  102. void prepareNewGame( Int gameMode, GameDifficulty diff, Int rankPoints ); ///< prepare for new game
  103. void logicMessageDispatcher( GameMessage *msg,
  104. void *userData ); ///< Logic command list processing
  105. void registerObject( Object *obj ); ///< Given an object, register it with the GameLogic and give it a unique ID
  106. void addObjectToLookupTable( Object *obj ); ///< add object ID to hash lookup table
  107. void removeObjectFromLookupTable( Object *obj );///< remove object ID from hash lookup table
  108. /// @todo Change this to refer to a Region3D as an extent of the world
  109. void setWidth( Real width ); ///< Sets the width of the world
  110. Real getWidth( void ); ///< Returns the width of the world
  111. void setHeight( Real height ); ///< Sets the height of the world
  112. Real getHeight( void ); ///< Returns the height of the world
  113. Bool isInGameLogicUpdate( void ) const { return m_isInUpdate; }
  114. UnsignedInt getFrame( void ); ///< Returns the current simulation frame number
  115. UnsignedInt getCRC( Int mode = CRC_CACHED, AsciiString deepCRCFileName = AsciiString::TheEmptyString ); ///< Returns the CRC
  116. void setObjectIDCounter( ObjectID nextObjID ) { m_nextObjID = nextObjID; }
  117. ObjectID getObjectIDCounter( void ) { return m_nextObjID; }
  118. //-----------------------------------------------------------------------------------------------
  119. void setBuildableStatusOverride(const ThingTemplate* tt, BuildableStatus bs);
  120. Bool findBuildableStatusOverride(const ThingTemplate* tt, BuildableStatus& bs) const;
  121. void setControlBarOverride(const AsciiString& commandSetName, Int slot, ConstCommandButtonPtr commandButton);
  122. Bool findControlBarOverride(const AsciiString& commandSetName, Int slot, ConstCommandButtonPtr& commandButton) const;
  123. //-----------------------------------------------------------------------------------------------
  124. /// create an object given the thing template. (Only for use by ThingFactory.)
  125. Object *friend_createObject( const ThingTemplate *thing, const ObjectStatusMaskType &objectStatusMask, Team *team );
  126. void destroyObject( Object *obj ); ///< Mark object as destroyed for later deletion
  127. Object *findObjectByID( ObjectID id ); ///< Given an ObjectID, return a pointer to the object.
  128. Object *getFirstObject( void ); ///< Returns the "first" object in the world. When used with the object method "getNextObject()", all objects in the world can be iterated.
  129. ObjectID allocateObjectID( void ); ///< Returns a new unique object id
  130. // super hack
  131. void startNewGame( Bool loadSaveGame );
  132. void loadMapINI( AsciiString mapName );
  133. void updateLoadProgress( Int progress );
  134. void deleteLoadScreen( void );
  135. //Kris: Cut setGameLoading() and replaced with setLoadingMap() and setLoadingSave() -- reason: nomenclature
  136. //void setGameLoading( Bool loading ) { m_loadingScene = loading; }
  137. void setLoadingMap( Bool loading ) { m_loadingMap = loading; }
  138. void setLoadingSave( Bool loading ) { m_loadingSave = loading; }
  139. void setClearingGameData( Bool clearing ) { m_clearingGameData = clearing; }
  140. void setGameMode( Int mode );
  141. Int getGameMode( void );
  142. Bool isInGame( void );
  143. Bool isInLanGame( void );
  144. Bool isInSinglePlayerGame( void );
  145. Bool isInSkirmishGame( void );
  146. Bool isInReplayGame( void );
  147. Bool isInInternetGame( void );
  148. Bool isInShellGame( void );
  149. Bool isInMultiplayerGame( void );
  150. //Kris: Cut isLoadingGame() and replaced with isLoadingMap() and isLoadingSave() -- reason: nomenclature
  151. //Bool isLoadingGame() const { return m_loadingScene; } // This is the old function that isn't very clear on it's definition.
  152. Bool isLoadingMap() const { return m_loadingMap; } // Whenever a map is in the process of loading.
  153. Bool isLoadingSave() const { return m_loadingSave; } // Whenever a saved game is in the process of loading.
  154. Bool isClearingGameData() const { return m_clearingGameData; }
  155. void enableScoring(Bool score) { m_isScoringEnabled = score; }
  156. Bool isScoringEnabled() const { return m_isScoringEnabled; }
  157. void setShowBehindBuildingMarkers(Bool b) { m_showBehindBuildingMarkers = b; }
  158. Bool getShowBehindBuildingMarkers() const { return m_showBehindBuildingMarkers; }
  159. void setDrawIconUI(Bool b) { m_drawIconUI = b; }
  160. Bool getDrawIconUI() const { return m_drawIconUI; }
  161. void setShowDynamicLOD(Bool b) { m_showDynamicLOD = b; }
  162. Bool getShowDynamicLOD() const { return m_showDynamicLOD; }
  163. void setHulkMaxLifetimeOverride(Int b) { m_scriptHulkMaxLifetimeOverride = b; }
  164. Int getHulkMaxLifetimeOverride() const { return m_scriptHulkMaxLifetimeOverride; }
  165. Bool isIntroMoviePlaying();
  166. void updateObjectsChangedTriggerAreas(void) {m_frameObjectsChangedTriggerAreas = m_frame;}
  167. UnsignedInt getFrameObjectsChangedTriggerAreas(void) {return m_frameObjectsChangedTriggerAreas;}
  168. void clearGameData(Bool showScoreScreen = TRUE); ///< Clear the game data
  169. void closeWindows( void );
  170. void sendObjectCreated( Object *obj );
  171. void sendObjectDestroyed( Object *obj );
  172. void bindObjectAndDrawable(Object* obj, Drawable* draw);
  173. void setGamePaused( Bool paused, Bool pauseMusic = TRUE );
  174. Bool isGamePaused( void );
  175. Bool getInputEnabledMemory( void ) { return m_inputEnabledMemory; }
  176. void processProgress(Int playerId, Int percentage);
  177. void processProgressComplete(Int playerId);
  178. Bool isProgressComplete( void );
  179. void timeOutGameStart( void );
  180. void initTimeOutValues( void );
  181. UnsignedInt getObjectCount( void );
  182. Int getRankLevelLimit() const { return m_rankLevelLimit; }
  183. void setRankLevelLimit(Int limit)
  184. {
  185. if (limit < 1) limit = 1;
  186. m_rankLevelLimit = limit;
  187. }
  188. // We need to allow access to this, because on a restartGame, we need to restart with the settings we started with
  189. Int getRankPointsToAddAtGameStart() const { return m_rankPointsToAddAtGameStart; }
  190. UnsignedShort getSuperweaponRestriction( void ) const; ///< Get any optional limits on superweapons
  191. void setSuperweaponRestriction( void );
  192. #ifdef DUMP_PERF_STATS
  193. void getAIMetricsStatistics( UnsignedInt *numAI, UnsignedInt *numMoving, UnsignedInt *numAttacking, UnsignedInt *numWaitingForPath, UnsignedInt *overallFailedPathfinds );
  194. void resetOverallFailedPathfinds() { m_overallFailedPathfinds = 0; }
  195. void incrementOverallFailedPathfinds() { m_overallFailedPathfinds++; }
  196. UnsignedInt getOverallFailedPathfinds() const { return m_overallFailedPathfinds; }
  197. #endif
  198. // NOTE: selectObject and deselectObject should be called *only* by logical things, NEVER by the
  199. // client. These will cause the client to select or deselect the object, if affectClient is true.
  200. // If createToSelection is TRUE, this object causes a new group to be selected.
  201. void selectObject(Object *obj, Bool createNewSelection, PlayerMaskType playerMask, Bool affectClient = FALSE);
  202. void deselectObject(Object *obj, PlayerMaskType playerMask, Bool affectClient = FALSE);
  203. // this should be called only by UpdateModule, thanks.
  204. void friend_awakenUpdateModule(Object* obj, UpdateModulePtr update, UnsignedInt whenToWakeUp);
  205. protected:
  206. // snapshot methods
  207. virtual void crc( Xfer *xfer );
  208. virtual void xfer( Xfer *xfer );
  209. virtual void loadPostProcess( void );
  210. private:
  211. void pushSleepyUpdate(UpdateModulePtr u);
  212. UpdateModulePtr peekSleepyUpdate() const;
  213. void popSleepyUpdate();
  214. void eraseSleepyUpdate(Int i);
  215. void rebalanceSleepyUpdate(Int i);
  216. Int rebalanceParentSleepyUpdate(Int i);
  217. Int rebalanceChildSleepyUpdate(Int i);
  218. void remakeSleepyUpdate();
  219. void validateSleepyUpdate() const;
  220. private:
  221. /**
  222. overrides to thing template buildable status. doesn't really belong here,
  223. but has to go somewhere. (srj)
  224. */
  225. typedef std::hash_map< AsciiString, BuildableStatus, rts::hash<AsciiString>, rts::equal_to<AsciiString> > BuildableMap;
  226. BuildableMap m_thingTemplateBuildableOverrides;
  227. /**
  228. overrides to control bars. doesn't really belong here, but has to go somewhere. (srj)
  229. */
  230. typedef std::hash_map< AsciiString, ConstCommandButtonPtr, rts::hash<AsciiString>, rts::equal_to<AsciiString> > ControlBarOverrideMap;
  231. ControlBarOverrideMap m_controlBarOverrides;
  232. Real m_width, m_height; ///< Dimensions of the world
  233. UnsignedInt m_frame; ///< Simulation frame number
  234. // CRC cache system -----------------------------------------------------------------------------
  235. UnsignedInt m_CRC; ///< Cache of previous CRC value
  236. std::map<Int, UnsignedInt> m_cachedCRCs; ///< CRCs we've seen this frame
  237. Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame?
  238. //-----------------------------------------------------------------------------------------------
  239. //Added By Sadullah Nader
  240. //Used to for load scene
  241. //Bool m_loadingScene;
  242. Bool m_loadingMap;
  243. Bool m_loadingSave;
  244. Bool m_clearingGameData;
  245. Bool m_isInUpdate;
  246. Int m_rankPointsToAddAtGameStart;
  247. Bool m_isScoringEnabled;
  248. Bool m_showBehindBuildingMarkers; //used by designers to override the user setting for cinematics
  249. Bool m_drawIconUI;
  250. Bool m_showDynamicLOD; //used by designers to override the user setting for cinematics
  251. Int m_scriptHulkMaxLifetimeOverride; ///< Scripts can change the lifetime of a hulk -- defaults to off (-1) in frames.
  252. /// @todo remove this hack
  253. Bool m_startNewGame;
  254. WindowLayout *m_background;
  255. Object* m_objList; ///< All of the objects in the world.
  256. // ObjectPtrHash m_objHash; ///< Used for ObjectID lookups
  257. ObjectPtrVector m_objVector;
  258. // this is a vector, but is maintained as a priority queue.
  259. // never modify it directly; please use the proper access methods.
  260. // (for an excellent discussion of priority queues, please see:
  261. // http://dogma.net/markn/articles/pq_stl/priority.htm)
  262. std::vector<UpdateModulePtr> m_sleepyUpdates;
  263. #ifdef ALLOW_NONSLEEPY_UPDATES
  264. // this is a plain old list, not a pq.
  265. std::list<UpdateModulePtr> m_normalUpdates;
  266. #endif
  267. UpdateModulePtr m_curUpdateModule;
  268. ObjectPointerList m_objectsToDestroy; ///< List of things that need to be destroyed at end of frame
  269. ObjectID m_nextObjID; ///< For allocating object id's
  270. void setDefaults( Bool loadSaveGame ); ///< Set default values of class object
  271. void processDestroyList( void ); ///< Destroy all pending objects on the destroy list
  272. void destroyAllObjectsImmediate(); ///< destroy, and process destroy list immediately
  273. /// factory for TheTerrainLogic, called from init()
  274. virtual TerrainLogic *createTerrainLogic( void );
  275. virtual GhostObjectManager *createGhostObjectManager(void);
  276. Int m_gameMode;
  277. Int m_rankLevelLimit;
  278. UnsignedShort m_superweaponRestriction;
  279. LoadScreen *getLoadScreen( Bool loadSaveGame );
  280. LoadScreen *m_loadScreen;
  281. Bool m_gamePaused;
  282. Bool m_inputEnabledMemory;// Latches used to remember what to restore to after we unpause
  283. Bool m_mouseVisibleMemory;
  284. Bool m_progressComplete[MAX_SLOTS];
  285. enum { PROGRESS_COMPLETE_TIMEOUT = 60000 }; ///< Timeout we wait for when we've completed our Load
  286. Int m_progressCompleteTimeout[MAX_SLOTS];
  287. void testTimeOut( void );
  288. void lastHeardFrom( Int playerId );
  289. Bool m_forceGameStartByTimeOut; ///< If we timeout someone we're waiting to load, set this flag to start the game
  290. #ifdef DUMP_PERF_STATS
  291. UnsignedInt m_overallFailedPathfinds;
  292. #endif
  293. UnsignedInt m_frameObjectsChangedTriggerAreas; ///< Last frame objects moved into/outof trigger areas, or were created/destroyed. jba.
  294. // ----------------------------------------------------------------------------------------------
  295. struct ObjectTOCEntry
  296. {
  297. AsciiString name;
  298. UnsignedShort id;
  299. };
  300. typedef std::list< ObjectTOCEntry > ObjectTOCList;
  301. typedef ObjectTOCList::iterator ObjectTOCListIterator;
  302. ObjectTOCList m_objectTOC; ///< the object TOC
  303. void addTOCEntry( AsciiString name, UnsignedShort id ); ///< add a new name/id TOC pair
  304. ObjectTOCEntry *findTOCEntryByName( AsciiString name ); ///< find ObjectTOC by name
  305. ObjectTOCEntry *findTOCEntryById( UnsignedShort id ); ///< find ObjectTOC by id
  306. void xferObjectTOC( Xfer *xfer ); ///< save/load object TOC for current state of map
  307. void prepareLogicForObjectLoad( void ); ///< prepare engine for object data from game file
  308. };
  309. // INLINE /////////////////////////////////////////////////////////////////////////////////////////
  310. inline void GameLogic::setWidth( Real width ) { m_width = width; }
  311. inline Real GameLogic::getWidth( void ) { return m_width; }
  312. inline void GameLogic::setHeight( Real height ) { m_height = height; }
  313. inline Real GameLogic::getHeight( void ) { return m_height; }
  314. inline UnsignedInt GameLogic::getFrame( void ) { return m_frame; }
  315. inline Bool GameLogic::isInGame( void ) { return !(m_gameMode == GAME_NONE); }
  316. inline void GameLogic::setGameMode( Int mode ) { m_gameMode = mode; }
  317. inline Int GameLogic::getGameMode( void ) { return m_gameMode; }
  318. inline Bool GameLogic::isInLanGame( void ) { return (m_gameMode == GAME_LAN); }
  319. inline Bool GameLogic::isInSkirmishGame( void ) { return (m_gameMode == GAME_SKIRMISH); }
  320. inline Bool GameLogic::isInMultiplayerGame( void ) { return ((m_gameMode == GAME_LAN) || (m_gameMode == GAME_INTERNET)) ; }
  321. inline Bool GameLogic::isInReplayGame( void ) { return (m_gameMode == GAME_REPLAY); }
  322. inline Bool GameLogic::isInInternetGame( void ) { return (m_gameMode == GAME_INTERNET); }
  323. inline Bool GameLogic::isInShellGame( void ) { return (m_gameMode == GAME_SHELL); }
  324. inline UnsignedShort GameLogic::getSuperweaponRestriction() const { return m_superweaponRestriction; }
  325. inline Object* GameLogic::findObjectByID( ObjectID id )
  326. {
  327. if( id == INVALID_ID )
  328. return NULL;
  329. // ObjectPtrHash::iterator it = m_objHash.find(id);
  330. // if (it == m_objHash.end())
  331. // return NULL;
  332. //
  333. // return (*it).second;
  334. if( (Int)id < m_objVector.size() )
  335. return m_objVector[(Int)id];
  336. return NULL;
  337. }
  338. // the singleton
  339. extern GameLogic *TheGameLogic;
  340. #endif // _GAME_LOGIC_H_