| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /*
- ** Command & Conquer Generals Zero Hour(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: DozerAIUpdate.h //////////////////////////////////////////////////////////////////////////
- // Author: Colin Day, February 2002
- // Desc: Dozer AI behavior
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef __DOZERAIUPDATE_H_
- #define __DOZERAIUPDATE_H_
- // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
- #include "GameLogic/Module/AIUpdate.h"
- // FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
- class AudioEventRTS;
- //-------------------------------------------------------------------------------------------------
- /** The Dozer primary state machine */
- //-------------------------------------------------------------------------------------------------
- class DozerPrimaryStateMachine : public StateMachine
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerPrimaryStateMachine, "DozerPrimaryStateMachine" );
- public:
- DozerPrimaryStateMachine( Object *owner );
- // virtual destructor prototypes provided by memory pool object
- //-----------------------------------------------------------------------------------------------
- // state transition conditions
- static Bool isBuildMostImportant( State *thisState, void* userData );
- static Bool isRepairMostImportant( State *thisState, void* userData );
- static Bool isFortifyMostImportant( State *thisState, void* userData );
- protected:
- // snapshot interface
- virtual void crc( Xfer *xfer );
- virtual void xfer( Xfer *xfer );
- virtual void loadPostProcess();
- };
- //-------------------------------------------------------------------------------------------------
- /** Dozer behaviors that use action sub state machines */
- //-------------------------------------------------------------------------------------------------
- enum DozerTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
- {
- DOZER_TASK_INVALID = -1,
- DOZER_TASK_FIRST = 0,
- DOZER_TASK_BUILD = DOZER_TASK_FIRST, ///< go build something
- DOZER_TASK_REPAIR = 1, ///< go repair something
- DOZER_TASK_FORTIFY = 2, ///< go fortify something
- DOZER_NUM_TASKS // keep this last
- };
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- enum DozerDockPoint // These enums are saved in the game save file, so DO NOT renumber them. jba.
- {
- DOZER_DOCK_POINT_START = 0,
- DOZER_DOCK_POINT_ACTION = 1,
- DOZER_DOCK_POINT_END = 2,
- DOZER_NUM_DOCK_POINTS // keep this one last
- };
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- enum DozerBuildSubTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
- {
- DOZER_SELECT_BUILD_DOCK_LOCATION = 0,
- DOZER_MOVING_TO_BUILD_DOCK_LOCATION = 1,
- DOZER_DO_BUILD_AT_DOCK = 2
- };
- // ------------------------------------------------------------------------------------------------
- /** This is no longer a leaf behavior. Someone else needs to combine this
- * with another major AIUpdate. So provide an interface to satisfy the people
- * who look this up by name. */
- // ------------------------------------------------------------------------------------------------
- class DozerAIInterface
- {
- // This is no longer a leaf behavior. Someone else needs to combine this
- // with another major AIUpdate. So provide an interface to satisfy the people
- // who look this up by name.
- public:
- virtual void onDelete( void ) = 0;
- virtual Real getRepairHealthPerSecond( void ) const = 0; ///< get health to repair per second
- virtual Real getBoredTime( void ) const = 0; ///< how long till we're bored
- virtual Real getBoredRange( void ) const = 0; ///< when we're bored, we look this far away to do things
- // methods to override for the dozer behaviors
- virtual Object *construct( const ThingTemplate *what,
- const Coord3D *pos, Real angle,
- Player *owningPlayer,
- Bool isRebuild ) = 0;
- // get task information
- virtual DozerTask getMostRecentCommand( void ) = 0; ///< return task that was most recently issued
- virtual Bool isTaskPending( DozerTask task ) = 0; ///< is there a desire to do the requested task
- virtual ObjectID getTaskTarget( DozerTask task ) = 0; ///< get target of task
- virtual Bool isAnyTaskPending( void ) = 0; ///< is there any dozer task pending
- virtual DozerTask getCurrentTask( void ) const = 0; ///< return the current task we're doing
- // the following should only be used from inside the Dozer state machine!
- // !!! *DO NOT CALL THIS AND SET THE TASK DIRECTLY TO AFFECT BEHAVIOR* !!! ///
- virtual void setCurrentTask( DozerTask task ) = 0; ///< set the current task of the dozer
- virtual Bool getIsRebuild( void ) = 0; ///< get whether or not this is a rebuild.
- // task actions
- virtual void newTask( DozerTask task, Object *target ) = 0; ///< set a desire to do the requrested task
- virtual void cancelTask( DozerTask task ) = 0; ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
- // internal methods to manage behavior from within the dozer state machine
- virtual void internalTaskComplete( DozerTask task ) = 0; ///< set a dozer task as successfully completed
- virtual void internalCancelTask( DozerTask task ) = 0; ///< cancel this task from the dozer
- virtual void internalTaskCompleteOrCancelled( DozerTask task ) = 0; ///< this is called when tasks are cancelled or completed
- /** return a dock point for the action and task (if valid) ... note it can return NULL
- if no point has been set for the combination of task and point */
- virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point ) = 0;
- virtual void setBuildSubTask( DozerBuildSubTask subTask ) = 0;
- virtual DozerBuildSubTask getBuildSubTask( void ) = 0;
- // repairing
- virtual Bool canAcceptNewRepair( Object *obj ) = 0;
- virtual void createBridgeScaffolding( Object *bridgeTower ) = 0;
- virtual void removeBridgeScaffolding( Object *bridgeTower ) = 0;
- virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID ) = 0;
- virtual void finishBuildingSound() = 0;
- };
- // ------------------------------------------------------------------------------------------------
- /** NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker */
- // ------------------------------------------------------------------------------------------------
- class DozerAIUpdateModuleData : public AIUpdateModuleData
- {
- public:
- DozerAIUpdateModuleData( void );
- // !!!
- // !!! NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker !!!
- // !!!
- Real m_repairHealthPercentPerSecond; ///< how many health points per second the dozer repairs at
- Real m_boredTime; ///< after this many frames, a dozer will try to find something to do on its own
- Real m_boredRange; ///< range the dozers try to auto repair when they're bored
- static void buildFieldParse( MultiIniFieldParse &p );
- };
- //-------------------------------------------------------------------------------------------------
- /** The Dozer AI Update interface. Dozers are workers that are capable of building all the
- * structures available to a player, as well as repairing building, and fortifying
- * civilian structures */
- //-------------------------------------------------------------------------------------------------
- class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerAIUpdate, "DozerAIUpdate" )
- MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DozerAIUpdate, DozerAIUpdateModuleData )
- public:
- static Bool findGoodBuildOrRepairPosition(const Object* me, const Object* target, Coord3D& positionOut);
- static Object* findGoodBuildOrRepairPositionAndTarget(Object* me, Object* target, Coord3D& positionOut);
- public:
- DozerAIUpdate( Thing *thing, const ModuleData* moduleData );
- // virtual destructor prototype provided by memory pool declaration
- virtual DozerAIInterface* getDozerAIInterface() {return this;}
- virtual const DozerAIInterface* getDozerAIInterface() const {return this;}
- virtual void onDelete( void );
- //
- // module data methods ... this is LAME, multiple inheritance off an interface with replicated
- // data and code, ick!
- // NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker
- //
- virtual Real getRepairHealthPerSecond( void ) const; ///< get health to repair per second
- virtual Real getBoredTime( void ) const; ///< how long till we're bored
- virtual Real getBoredRange( void ) const; ///< when we're bored, we look this far away to do things
- // methods to override for the dozer behaviors
- virtual Object* construct( const ThingTemplate *what,
- const Coord3D *pos, Real angle,
- Player *owningPlayer,
- Bool isRebuild ); ///< construct an object
- // get task information
- virtual DozerTask getMostRecentCommand( void ); ///< return task that was most recently issued
- virtual Bool isTaskPending( DozerTask task ); ///< is there a desire to do the requested task
- virtual ObjectID getTaskTarget( DozerTask task ); ///< get target of task
- virtual Bool isAnyTaskPending( void ); ///< is there any dozer task pending
- virtual DozerTask getCurrentTask( void ) const { return m_currentTask; } ///< return the current task we're doing
- virtual void setCurrentTask( DozerTask task ) { m_currentTask = task; } ///< set the current task of the dozer
- virtual Bool getIsRebuild( void ) { return m_isRebuild; } ///< get whether or not this building is a rebuild.
- // task actions
- virtual void newTask( DozerTask task, Object *target ); ///< set a desire to do the requrested task
- virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
- // internal methods to manage behavior from within the dozer state machine
- virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed
- virtual void internalCancelTask( DozerTask task ); ///< cancel this task from the dozer
- virtual void internalTaskCompleteOrCancelled( DozerTask task ); ///< this is called when tasks are cancelled or completed
- /** return a dock point for the action and task (if valid) ... note it can return NULL
- if no point has been set for the combination of task and point */
- virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point );
- virtual void setBuildSubTask( DozerBuildSubTask subTask ) { m_buildSubTask = subTask; };
- virtual DozerBuildSubTask getBuildSubTask( void ) { return m_buildSubTask; }
- virtual UpdateSleepTime update( void ); ///< the update entry point
- // repairing
- virtual Bool canAcceptNewRepair( Object *obj );
- virtual void createBridgeScaffolding( Object *bridgeTower );
- virtual void removeBridgeScaffolding( Object *bridgeTower );
- virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID );
- virtual void finishBuildingSound();
- //
- // the following methods must be overridden so that if a player issues a command the dozer
- // can exit the internal state machine and do whatever the player says
- //
- virtual void aiDoCommand(const AICommandParms* parms);
- protected:
- virtual void privateRepair( Object *obj, CommandSourceType cmdSource ); ///< repair the target
- virtual void privateResumeConstruction( Object *obj, CommandSourceType cmdSource ); ///< resume construction on obj
-
- struct DozerTaskInfo
- {
- ObjectID m_targetObjectID; ///< target object ID of task
- UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task
- } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask
- DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior
- DozerTask m_currentTask; ///< current task the dozer is attending to (if any)
- AudioEventRTS m_buildingSound; ///< sound is pulled from the object we are building!
- Bool m_isRebuild; ///< is this a rebuild of a previous building?
- //
- // the following info array can be used if we want to have more complicated approaches
- // to our target depending on our task
- //
- struct DozerDockPointInfo
- {
- Bool valid; ///< this point has been set and is valid
- Coord3D location; ///< WORLD location
- } m_dockPoint[ DOZER_NUM_TASKS ][ DOZER_NUM_DOCK_POINTS ];
- DozerBuildSubTask m_buildSubTask; ///< for building and actually docking for the build
- private:
- void createMachines( void ); ///< create our behavior machines we need
- };
- #endif // __DOZERAIUPDATE_H_
|