| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: ScriptEngine.h ///////////////////////////////////////////////////////////////////////////
- // Script evaluation engine.
- // Author: John Ahlquist, Nov. 2001
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef __SCRIPTENGINE_H_
- #define __SCRIPTENGINE_H_
- #include "Common/GameType.h"
- #include "Common/GameMemory.h"
- #include "Common/STLTypedefs.h"
- #include "Common/Science.h"
- #include "Common/Snapshot.h"
- #include "Common/SubsystemInterface.h"
- #include "GameLogic/Scripts.h"
- class DataChunkInput;
- struct DataChunkInfo;
- class DataChunkOutput;
- class Team;
- class Object;
- class ThingTemplate;
- class Player;
- class PolygonTrigger;
- class ObjectTypes;
- #ifdef _INTERNAL
- #define SPECIAL_SCRIPT_PROFILING
- #endif
- // Slightly odd place to put breeze info, but the breeze info is
- // set by script, so it's as good a place as any. john a.
- struct BreezeInfo
- {
- Real m_direction; ///< Direction of the breeze in radians. 0 == +x direction.
- Coord2D m_directionVec; ///< sin/cos of direction, for efficiency.
- Real m_intensity; ///< How far to sway back & forth in radians. 0 = none.
- Real m_lean; ///< How far to lean with the wind in radians. 0 = none.
- Real m_randomness; ///< Randomness 0=perfectly uniform, 1 = +- up to 50% randomly.
- Short m_breezePeriod; ///< How many frames it takes to sway forward & back.
- Short m_breezeVersion; ///< Incremented each time the settings are updated.
- };
- // This could belong elsewhere, but for now...
- struct NamedReveal
- {
- AsciiString m_revealName;
- AsciiString m_waypointName;
- Real m_radiusToReveal;
- AsciiString m_playerName;
- };
- struct TScriptListReadInfo
- {
- Int numLists;
- ScriptList *readLists[MAX_PLAYER_COUNT];
- };
- struct TCounter
- {
- Int value;
- AsciiString name;
- Bool isCountdownTimer;
- };
- struct TFlag
- {
- Bool value;
- AsciiString name;
- };
- typedef std::list<AsciiString> ListAsciiString;
- typedef std::list<AsciiString>::iterator ListAsciiStringIt;
- typedef std::pair<AsciiString, UnsignedInt> PairAsciiStringUINT;
- typedef std::list<PairAsciiStringUINT> ListAsciiStringUINT;
- typedef ListAsciiStringUINT::iterator ListAsciiStringUINTIt;
- typedef std::map< const ThingTemplate *, Int, std::less<const ThingTemplate *> > AttackPriorityMap;
- typedef std::pair<AsciiString, ObjectID> AsciiStringObjectIDPair;
- typedef std::list<AsciiStringObjectIDPair> ListAsciiStringObjectID;
- typedef std::list<AsciiStringObjectIDPair>::iterator ListAsciiStringObjectIDIt;
- typedef std::pair<AsciiString, Coord3D> AsciiStringCoord3DPair;
- typedef std::list<AsciiStringCoord3DPair> ListAsciiStringCoord3D;
- typedef ListAsciiStringCoord3D::iterator ListAsciiStringCoord3DIt;
- typedef std::map< AsciiString, Int > ObjectTypeCount;
- typedef std::vector<Player *> VectorPlayerPtr;
- typedef VectorPlayerPtr::iterator VectorPlayerPtrIt;
- typedef std::vector<ObjectTypes*> AllObjectTypes;
- typedef AllObjectTypes::iterator AllObjectTypesIt;
- typedef std::vector<NamedReveal> VecNamedReveal;
- typedef VecNamedReveal::iterator VecNamedRevealIt;
- class AttackPriorityInfo : public MemoryPoolObject, public Snapshot
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AttackPriorityInfo, "AttackPriorityInfo")
- // friend bad for MPOs. (srj)
- //friend class ScriptEngine;
- public:
- AttackPriorityInfo();
- //~AttackPriorityInfo();
- public:
- void setPriority(const ThingTemplate *tThing, Int priority);
- Int getPriority(const ThingTemplate *tThing) const;
- AsciiString getName(void) const {return m_name;}
- #ifdef _DEBUG
- void dumpPriorityInfo(void);
- #endif
- void friend_setName(const AsciiString& n) { m_name = n; }
- void friend_setDefaultPriority(Int n) { m_defaultPriority = n; }
- void reset(void);
- protected:
- // sanapshot methods
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess( void );
- AsciiString m_name;
- Int m_defaultPriority;
- AttackPriorityMap *m_priorityMap;
- };
- class SequentialScript : public MemoryPoolObject, public Snapshot
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(SequentialScript, "SequentialScript")
- public:
- enum { START_INSTRUCTION = -1 };
- Team *m_teamToExecOn;
- ObjectID m_objectID;
- Script *m_scriptToExecuteSequentially;
- Int m_currentInstruction; // Which action within m_scriptToExecuteSequentially am I currently executing?
- Int m_timesToLoop; // 0 = do once, >0, loop till 0, <0, loop infinitely
- Int m_framesToWait; // 0 = transition to next instruction, >0 = countdown to 0, <0 = advance on idle only
- Bool m_dontAdvanceInstruction; // Must be set every frame by the instruction requesting the wait.
- // so this parm tells us how many we've been idle so far.
- SequentialScript *m_nextScriptInSequence;
- SequentialScript();
- protected:
- // snapshot methods
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess( void );
- };
- EMPTY_DTOR(SequentialScript)
- #ifdef NOT_IN_USE
- class SequentialScriptStatus : public MemoryPoolObject, public Snapshot
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(SequentialScriptStatus, "SequentialScriptStatus")
- public:
- ObjectID m_objectID;
- AsciiString m_sequentialScriptCompleted;
- Bool m_isExecutingSequentially;
- protected:
- // snapshot methods
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess( void );
- };
- #endif
- //-----------------------------------------------------------------------------
- // ScriptEngine
- //-----------------------------------------------------------------------------
- /** Implementation for the Script Engine singleton */
- //-----------------------------------------------------------------------------
- class ScriptEngine : public SubsystemInterface,
- public Snapshot
- {
- public:
- enum {MAX_COUNTERS=256, MAX_FLAGS=256, MAX_ATTACK_PRIORITIES=256};
- enum TFade {FADE_NONE, FADE_SUBTRACT, FADE_ADD, FADE_SATURATE, FADE_MULTIPLY};
- ScriptEngine();
- virtual ~ScriptEngine();
- virtual void init( void ); ///< Init
- virtual void reset( void ); ///< Reset
- virtual void update( void ); ///< Update
- void appendSequentialScript(const SequentialScript *scriptToSequence);
- void removeSequentialScript(SequentialScript *scriptToRemove);
- void notifyOfTeamDestruction(Team *teamDestroyed);
- void notifyOfObjectCreationOrDestruction(void);
- UnsignedInt getFrameObjectCountChanged(void) {return m_frameObjectCountChanged;}
- void setSequentialTimer(Object *obj, Int frameCount);
- void setSequentialTimer(Team *team, Int frameCount);
-
- void removeAllSequentialScripts(Object *obj);
- void removeAllSequentialScripts(Team *team);
- AsciiString getStats(Real *curTime, Real *script1Time, Real *script2Time);
- virtual void newMap( ); ///< reset script engine for new map
- virtual const ActionTemplate *getActionTemplate( Int ndx); ///< Get the template for a script action.
- virtual const ConditionTemplate *getConditionTemplate( Int ndx); ///< Get the template for a script Condition.
- virtual void startEndGameTimer(void); ///< Starts the end game timer after a mission is won or lost.
- Bool isGameEnding( void ) { return m_endGameTimer >= 0; }
- virtual void startQuickEndGameTimer(void); ///< Starts the quick end game timer after a campaign is won or lost.
- virtual void startCloseWindowTimer(void); ///< Starts the timer to close windows after a mission is won or lost.
- virtual void runScript(const AsciiString& scriptName, Team *pThisTeam=NULL); ///< Runs a script.
- virtual void runObjectScript(const AsciiString& scriptName, Object *pThisObject=NULL); ///< Runs a script attached to this object.
- virtual Team *getTeamNamed(const AsciiString& teamName); ///< Gets the named team. May be null.
- virtual Player *getSkirmishEnemyPlayer(void); ///< Gets the ai's enemy Human player. May be null.
- virtual Player *getCurrentPlayer(void); ///< Gets the player that owns the current script. May be null.
- virtual Player *getPlayerFromAsciiString(const AsciiString& skirmishPlayerString);
- void setObjectsShouldReceiveDifficultyBonus(Bool receive) { m_objectsShouldReceiveDifficultyBonus = receive; }
- Bool getObjectsShouldReceiveDifficultyBonus() const { return m_objectsShouldReceiveDifficultyBonus; }
- void setChooseVictimAlwaysUsesNormal(Bool receive) { m_ChooseVictimAlwaysUsesNormal = receive; }
- Bool getChooseVictimAlwaysUsesNormal() const { return m_ChooseVictimAlwaysUsesNormal; }
- Bool hasShownMPLocalDefeatWindow(void);
- void markMPLocalDefeatWindowShown(void);
- // NOTE NOTE NOTE: do not store of the return value of this call (getObjectTypeList) beyond the life of the
- // function it will be used in, as it can be deleted from under you if maintenance is performed on the object.
- virtual ObjectTypes *getObjectTypes(const AsciiString& objectTypeList);
- virtual void doObjectTypeListMaintenance(const AsciiString& objectTypeList, const AsciiString& objectType, Bool addObject);
- /// Return the trigger area with the given name
- virtual PolygonTrigger *getQualifiedTriggerAreaByName( AsciiString name );
- // For other systems to evaluate Conditions, execute Actions, etc.
- ///< if pThisTeam is specified, then scripts in here can use <This Team> to mean the team this script is attached to.
- virtual Bool evaluateConditions( Script *pScript, Team *pThisTeam = NULL, Player *pPlayer=NULL );
- virtual void friend_executeAction( ScriptAction *pActionHead, Team *pThisTeam = NULL); ///< Use this at yer peril.
- virtual Object *getUnitNamed(const AsciiString& unitName); ///< Gets the named unit. May be null.
- virtual Bool didUnitExist(const AsciiString& unitName);
- virtual void addObjectToCache( Object* pNewObject );
- virtual void removeObjectFromCache( Object* pDeadObject );
- virtual void transferObjectName( const AsciiString& unitName, Object *pNewObject );
- virtual void notifyOfObjectDestruction( Object *pDeadObject );
- virtual void notifyOfCompletedVideo( const AsciiString& completedVideo ); ///< Notify the script engine that a video has completed
- virtual void notifyOfTriggeredSpecialPower( Int playerIndex, const AsciiString& completedPower, ObjectID sourceObj );
- virtual void notifyOfMidwaySpecialPower ( Int playerIndex, const AsciiString& completedPower, ObjectID sourceObj );
- virtual void notifyOfCompletedSpecialPower( Int playerIndex, const AsciiString& completedPower, ObjectID sourceObj );
- virtual void notifyOfCompletedUpgrade ( Int playerIndex, const AsciiString& upgrade, ObjectID sourceObj );
- virtual void notifyOfAcquiredScience ( Int playerIndex, ScienceType science );
-
- virtual void signalUIInteract(const AsciiString& hookName); ///< Notify that a UI button was pressed and some flag should go true, for one frame only.
- virtual Bool isVideoComplete( const AsciiString& completedVideo, Bool removeFromList ); ///< Determine whether a video has completed
- virtual Bool isSpeechComplete( const AsciiString& completedSpeech, Bool removeFromList ); ///< Determine whether a speech has completed
- virtual Bool isAudioComplete( const AsciiString& completedAudio, Bool removeFromList ); ///< Determine whether a sound has completed
- virtual Bool isSpecialPowerTriggered( Int playerIndex, const AsciiString& completedPower, Bool removeFromList, ObjectID sourceObj );
- virtual Bool isSpecialPowerMidway ( Int playerIndex, const AsciiString& completedPower, Bool removeFromList, ObjectID sourceObj );
- virtual Bool isSpecialPowerComplete ( Int playerIndex, const AsciiString& completedPower, Bool removeFromList, ObjectID sourceObj );
- virtual Bool isUpgradeComplete ( Int playerIndex, const AsciiString& upgrade, Bool removeFromList, ObjectID sourceObj );
- virtual Bool isScienceAcquired ( Int playerIndex, ScienceType science, Bool removeFromList );
- void setToppleDirection( const AsciiString& objectName, const Coord3D *direction );
- virtual void adjustToppleDirection( Object *object, Coord2D *direction);
- virtual void adjustToppleDirection( Object *object, Coord3D *direction);
- virtual const Script *findScriptByName(const AsciiString& scriptName) {return findScript(scriptName);} ///< Finds a script.
-
- const BreezeInfo& getBreezeInfo() const {return m_breezeInfo;}
-
- Bool isTimeFrozenScript( void ); ///< Ask whether a script has frozen time or not
- void doFreezeTime( void );
- void doUnfreezeTime( void );
- /// The following functions are used to update and query the debug window
- Bool isTimeFrozenDebug( void ); ///< Ask whether the debug window has requested a pause.
- Bool isTimeFast( void ); ///< Ask whether the debug window has requested a fast forward.
- void forceUnfreezeTime( void ); ///< Force that time becomes unfrozen temporarily.
- void AppendDebugMessage(const AsciiString& strToAdd, Bool forcePause);
- void AdjustDebugVariableData(const AsciiString& variableName, Int value, Bool forcePause);
- void clearTeamFlags(void); ///< Hack for dustin.
- void clearFlag(const AsciiString &name); ///< Hack for dustin.
- TFade getFade(void) {return m_fade;}
- Real getFadeValue(void) {return m_curFadeValue;}
- AsciiString getCurrentTrackName() const { return m_currentTrackName; }
- void setCurrentTrackName(AsciiString a) { m_currentTrackName = a; }
- GameDifficulty getGlobalDifficulty( void ) const { return m_gameDifficulty; }
- void setGlobalDifficulty( GameDifficulty difficulty );
- /// Attack priority stuff.
- const AttackPriorityInfo *getDefaultAttackInfo(void);
- const AttackPriorityInfo *getAttackInfo(const AsciiString& name);
-
- const TCounter *getCounter(const AsciiString& counterName);
-
- void createNamedMapReveal(const AsciiString& revealName, const AsciiString& waypointName, Real radiusToReveal, const AsciiString& playerName);
- void doNamedMapReveal(const AsciiString& revealName);
- void undoNamedMapReveal(const AsciiString& revealName);
- void removeNamedMapReveal(const AsciiString& revealName);
- Int getObjectCount(Int playerIndex, const AsciiString& objectTypeName) const;
- void setObjectCount(Int playerIndex, const AsciiString& objectTypeName, Int newCount);
- //Kris: Moved to public... so that I can refresh it when building abilities in script dialogs.
- void createNamedCache( void );
- ///Begin VTUNE
- void setEnableVTune(Bool value);
- Bool getEnableVTune() const;
- ///End VTUNE
- //#if defined(_DEBUG) || defined(_INTERNAL)
- void debugVictory( void );
- //#endif
- protected:
- // snapshot methods
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess( void );
- Int allocateCounter( const AsciiString& name);
- Int allocateFlag( const AsciiString& name);
- void executeScripts( Script *pScriptHead );
- void executeScript( Script *pScript );
- Script *findScript(const AsciiString& name);
- ScriptGroup *findGroup(const AsciiString& name);
- void setSway( ScriptAction *pAction );
- void setCounter( ScriptAction *pAction );
- void addCounter( ScriptAction *pAction );
- void subCounter( ScriptAction *pAction );
- void setFade( ScriptAction *pAction );
- void setFlag( ScriptAction *pAction );
- void pauseTimer( ScriptAction *pAction );
- void restartTimer( ScriptAction *pAction );
- void setTimer( ScriptAction *pAction, Bool milisecondTimer, Bool random);
- void adjustTimer( ScriptAction *pAction, Bool milisecondTimer, Bool add);
- void enableScript( ScriptAction *pAction );
- void disableScript( ScriptAction *pAction );
- void callSubroutine( ScriptAction *pAction );
- void checkConditionsForTeamNames(Script *pScript);
- Bool evaluateCounter( Condition *pCondition );
- Bool evaluateFlag( Condition *pCondition );
- Bool evaluateTimer( Condition *pCondition );
- Bool evaluateCondition( Condition *pCondition );
- void executeActions( ScriptAction *pActionHead );
- void setPriorityThing( ScriptAction *pAction );
- void setPriorityKind( ScriptAction *pAction );
- void setPriorityDefault( ScriptAction *pAction );
- // For Object types maintenance.
- void removeObjectTypes(ObjectTypes *typesToRemove);
- void particleEditorUpdate( void );
- void updateFades( void );
- AttackPriorityInfo *findAttackInfo(const AsciiString& name, Bool addIfNotFound);
- protected:
- /// Stuff to execute scripts sequentially
- typedef std::vector<SequentialScript*> VecSequentialScriptPtr;
- typedef VecSequentialScriptPtr::iterator VecSequentialScriptPtrIt;
- VecSequentialScriptPtr m_sequentialScripts;
-
- void evaluateAndProgressAllSequentialScripts( void );
- VecSequentialScriptPtrIt cleanupSequentialScript(VecSequentialScriptPtrIt it, Bool cleanDanglers);
- Bool hasUnitCompletedSequentialScript( Object *object, const AsciiString& sequentialScriptName );
- Bool hasTeamCompletedSequentialScript( Team *team, const AsciiString& sequentialScriptName );
-
- protected:
- ActionTemplate m_actionTemplates[ScriptAction::NUM_ITEMS];
- ConditionTemplate m_conditionTemplates[Condition::NUM_ITEMS];
- TCounter m_counters[MAX_COUNTERS];
- Int m_numCounters;
- TFlag m_flags[MAX_FLAGS];
- Int m_numFlags;
- AttackPriorityInfo m_attackPriorityInfo[MAX_ATTACK_PRIORITIES];
- Int m_numAttackInfo;
- Int m_endGameTimer;
- Int m_closeWindowTimer;
- Team *m_callingTeam; ///< Team that is calling script, used for THIS_TEAM
- Object *m_callingObject; ///< Object that is calling script, used for THIS_OBJECT
- Team *m_conditionTeam; ///< Team that is being used to evaluate conditions, used for THIS_TEAM
- Object *m_conditionObject; ///< Unit that is being used to evaluate conditions, used for THIS_OBJECT
- VecNamedRequests m_namedObjects;
- Bool m_firstUpdate;
- Player *m_currentPlayer;
- Player *m_skirmishHumanPlayer;
- AsciiString m_currentTrackName;
- TFade m_fade;
- Real m_minFade;
- Real m_maxFade;
- Real m_curFadeValue;
- Int m_curFadeFrame;
- Int m_fadeFramesIncrease;
- Int m_fadeFramesHold;
- Int m_fadeFramesDecrease;
- UnsignedInt m_frameObjectCountChanged;
- ObjectTypeCount m_objectCounts[MAX_PLAYER_COUNT];
- /// These are three separate lists rather than one to increase speed efficiency
- ListAsciiString m_completedVideo;
- ListAsciiStringUINT m_testingSpeech;
- ListAsciiStringUINT m_testingAudio;
- ListAsciiString m_uiInteractions;
-
- ListAsciiStringObjectID m_triggeredSpecialPowers[MAX_PLAYER_COUNT];
- ListAsciiStringObjectID m_midwaySpecialPowers [MAX_PLAYER_COUNT];
- ListAsciiStringObjectID m_finishedSpecialPowers [MAX_PLAYER_COUNT];
- ListAsciiStringObjectID m_completedUpgrades [MAX_PLAYER_COUNT];
- ScienceVec m_acquiredSciences [MAX_PLAYER_COUNT];
- ListAsciiStringCoord3D m_toppleDirections;
- VecNamedReveal m_namedReveals;
- BreezeInfo m_breezeInfo;
- GameDifficulty m_gameDifficulty;
- Bool m_freezeByScript;
- AllObjectTypes m_allObjectTypeLists;
- Bool m_objectsShouldReceiveDifficultyBonus;
- Bool m_ChooseVictimAlwaysUsesNormal;
-
- Bool m_shownMPLocalDefeatWindow;
- #ifdef SPECIAL_SCRIPT_PROFILING
- #ifdef DEBUG_LOGGING
- double m_numFrames;
- double m_totalUpdateTime;
- double m_maxUpdateTime;
- double m_curUpdateTime;
- #endif
- #endif
- }; // end class ScriptEngine
- extern ScriptEngine *TheScriptEngine; ///< singleton definition
-
- #endif // end __SCRIPTENGINE_H_
|