| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793 |
- /*
- ** 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. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // SupplyTruckAIUpdate.cpp ////////////
- // Author: Graham Smallwood, February 2002
- // Desc: State machine that controls when and with who a Truck docks
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "Common/Player.h"
- #include "Common/ResourceGatheringManager.h"
- #include "Common/ThingTemplate.h"
- #include "GameLogic/Object.h"
- #include "GameLogic/PartitionManager.h"
- #include "GameLogic/Module/SupplyTruckAIUpdate.h"
- #include "GameLogic/Module/SupplyCenterDockUpdate.h"
- #include "GameLogic/Module/SupplyWarehouseDockUpdate.h"
- #include "GameLogic/Module/WorkerAIUpdate.h"
- #include "GameClient/Drawable.h"
- #include "GameClient/InGameUI.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- #define NO_DEBUG_SUPPLY_STATE
- #ifdef DEBUG_SUPPLY_STATE
- static const char* statenames[] =
- {
- "ST_IDLE", ///< Not doing anything. Should I autopilot?
- "ST_BUSY", ///< Direct player involvement (move) has taken me off autopilot
- "ST_WANTING", ///< Search for warehouse or center and dock with it
- "ST_REGROUPING", ///< Wanting failed, so hang out at base until something changes. Still on autopilot, but resting.
- "ST_DOCKING" ///< Docking substates are running, wait for them to finish
- };
- #endif
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- AIStateMachine* SupplyTruckAIUpdate::makeStateMachine()
- {
- return newInstance(AIStateMachine)( getObject(), "SupplyTruckAIUpdateMachine");
- }
- //-------------------------------------------------------------------------------------------------
- SupplyTruckAIUpdate::SupplyTruckAIUpdate( Thing *thing, const ModuleData* moduleData ) : AIUpdateInterface( thing, moduleData )
- {
- m_supplyTruckStateMachine = NULL;
- m_preferredDock = INVALID_ID;
- m_numberBoxes = 0;
- m_forcePending = FALSE;
- m_forcedBusyPending = FALSE;
- m_supplyTruckStateMachine = newInstance(SupplyTruckStateMachine)( getObject() );
- m_supplyTruckStateMachine->initDefaultState();
-
- m_suppliesDepletedVoice = getSupplyTruckAIUpdateModuleData()->m_suppliesDepletedVoice;
- }
- //-------------------------------------------------------------------------------------------------
- SupplyTruckAIUpdate::~SupplyTruckAIUpdate( void )
- {
- m_supplyTruckStateMachine->deleteInstance();
- }
- //-------------------------------------------------------------------------------------------------
- UpdateSleepTime SupplyTruckAIUpdate::update( void )
- {
- StateReturnType stRet = m_supplyTruckStateMachine->updateStateMachine();
- UpdateSleepTime mine = IS_STATE_SLEEP(stRet) ? UPDATE_SLEEP(GET_STATE_SLEEP_FRAMES(stRet)) : UPDATE_SLEEP_NONE;
- // extend
- UpdateSleepTime ret = AIUpdateInterface::update();
- return (mine < ret) ? mine : ret;
- }
- //-------------------------------------------------------------------------------------------------
- Bool SupplyTruckAIUpdate::isCurrentlyFerryingSupplies() const
- {
- if (m_supplyTruckStateMachine)
- {
- switch (m_supplyTruckStateMachine->getCurrentStateID())
- {
- case ST_IDLE:
- case ST_BUSY:
- case ST_REGROUPING:
- return false;
- case ST_WANTING:
- case ST_DOCKING:
- return true;
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- Bool SupplyTruckAIUpdate::isAvailableForSupplying() const
- {
- return true;
- }
- //-------------------------------------------------------------------------------------------------
- Bool SupplyTruckAIUpdate::loseOneBox()
- {
- if( m_numberBoxes == 0 )
- return FALSE;
- --m_numberBoxes;
- Drawable *draw = getObject()->getDrawable();
- if( draw )
- {
- draw->updateDrawableSupplyStatus( getSupplyTruckAIUpdateModuleData()->m_maxBoxesData, m_numberBoxes );
- }
- return TRUE;
- }
- //-------------------------------------------------------------------------------------------------
- Bool SupplyTruckAIUpdate::gainOneBox( Int remainingStock )
- {
- if( getSupplyTruckAIUpdateModuleData() && m_numberBoxes >= getSupplyTruckAIUpdateModuleData()->m_maxBoxesData )
- return FALSE;
- ++m_numberBoxes;
- //if I just took the last box,
- //i will announce that this supply source is now empty
- if (remainingStock == 0)
- {
- Object* bestWarehouse = getObject()->getControllingPlayer()->getResourceGatheringManager()->findBestSupplyWarehouse( getObject() );
-
- Bool playDepleted = FALSE;
- if ( bestWarehouse )
- {
- //figure out whether the best one is considerably far from the previous one (current position)
- Coord3D delta = *getObject()->getPosition();
- delta.sub( bestWarehouse->getPosition() );
- if ( delta.length() > getWarehouseScanDistance()/4)
- playDepleted = TRUE;
- }
- else
- playDepleted = TRUE;
- if (playDepleted && m_suppliesDepletedVoice.getEventName().isEmpty() == false)
- {
- m_suppliesDepletedVoice.setObjectID(getObject()->getID());
- m_suppliesDepletedVoice.setPlayingHandle(TheAudio->addAudioEvent(&m_suppliesDepletedVoice));
- }
- }
- Drawable *draw = getObject()->getDrawable();
- if( draw )
- {
- draw->updateDrawableSupplyStatus( getSupplyTruckAIUpdateModuleData()->m_maxBoxesData, m_numberBoxes );
- }
- return TRUE;
- }
- //----------------------------------------------------------------------------------------
- void SupplyTruckAIUpdate::privateIdle(CommandSourceType cmdSource)
- {
- // If the user gives a stop command, I have to turn off autopilot
- if( cmdSource == CMD_FROM_PLAYER )
- setForceBusyState(TRUE);
- AIUpdateInterface::privateIdle(cmdSource);
- }
- //----------------------------------------------------------------------------------------
- void SupplyTruckAIUpdate::privateDock( Object *dock, CommandSourceType cmdSource )
- {
- AIUpdateInterface::privateDock( dock, cmdSource );
- // If this is a command from a player, I will remember this as my favorite dock to override
- // ResourceManager searches.
- if ((cmdSource == CMD_FROM_PLAYER) && dock)
- {
- // Please note, there is not a separate Warehouse and Center memory by Design. Because
- // we lack a UI way to click Warehouse and drag to center to set up a specific path, the
- // practical realization has been made that you do not want separate memory.
- m_preferredDock = dock->getID();
- }
- }
- //----------------------------------------------------------------------------------------
- UnsignedInt SupplyTruckAIUpdate::getActionDelayForDock( Object *dock )
- {
- // Decide whether to use my Center or Warehouse delay time
- static const NameKeyType key_warehouseUpdate = NAMEKEY("SupplyWarehouseDockUpdate");
- SupplyWarehouseDockUpdate *warehouseModule = (SupplyWarehouseDockUpdate*) dock->findUpdateModule( key_warehouseUpdate );
- if (warehouseModule) {
- return getSupplyTruckAIUpdateModuleData()->m_warehouseDelay;
- }
- static const NameKeyType key_centerUpdate = NAMEKEY("SupplyCenterDockUpdate");
- SupplyCenterDockUpdate *centerModule = (SupplyCenterDockUpdate*) dock->findUpdateModule( key_centerUpdate );
- if (centerModule) {
- return getSupplyTruckAIUpdateModuleData()->m_centerDelay;
- }
- return 0;
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- Real SupplyTruckAIUpdate::getWarehouseScanDistance() const
- {
- // Ai players get larger scan range. jba.
- if (getObject()->getControllingPlayer()->getPlayerType() == PLAYER_COMPUTER) {
- return 2 * getSupplyTruckAIUpdateModuleData()->m_warehouseScanDistance;
- }
- return getSupplyTruckAIUpdateModuleData()->m_warehouseScanDistance;
- }
- // ------------------------------------------------------------------------------------------------
- /** CRC */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckAIUpdate::crc( Xfer *xfer )
- {
- // extend base class
- AIUpdateInterface::crc(xfer);
- } // end crc
- // ------------------------------------------------------------------------------------------------
- /** Xfer method
- * Version Info:
- * 1: Initial version */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckAIUpdate::xfer( Xfer *xfer )
- {
- XferVersion currentVersion = 1;
- XferVersion version = currentVersion;
- xfer->xferVersion( &version, currentVersion );
-
- // extend base class
- AIUpdateInterface::xfer(xfer);
- xfer->xferSnapshot(m_supplyTruckStateMachine);
- xfer->xferObjectID(&m_preferredDock);
- xfer->xferInt(&m_numberBoxes);
- xfer->xferBool(&m_forcePending);
- } // end xfer
- // ------------------------------------------------------------------------------------------------
- /** Load post process */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckAIUpdate::loadPostProcess( void )
- {
- // extend base class
- AIUpdateInterface::loadPostProcess();
- } // end loadPostProcess
- //----------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------
- class SupplyTruckBusyState : public State
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(SupplyTruckBusyState, "SupplyTruckBusyState")
- protected:
- // snapshot interface STUBBED.
- virtual void crc( Xfer *xfer ){};
- virtual void xfer( Xfer *xfer ){};
- virtual void loadPostProcess(){};
- public:
- SupplyTruckBusyState( StateMachine *machine ) : State( machine, "SupplyTruckBusyState" ) { }
- virtual StateReturnType onEnter()
- {
- if( getMachineOwner() && getMachineOwner()->getAI() )
- {
- // Have to check, since constructor sets a state. Phhbbt. Constructor = set up, init = do first thing.
- SupplyTruckAIInterface *update = getMachineOwner()->getAI()->getSupplyTruckAIInterface();
- if( update )
- {
- // Turn off the Busy latch when we make it to Busy
- update->setForceBusyState( FALSE );
- }
- }
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("entering busy state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return STATE_CONTINUE;
- }
- virtual StateReturnType update()
- {
- return STATE_CONTINUE;
- }
- virtual void onExit(StateExitType status)
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("exiting busy state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- }
- };
- EMPTY_DTOR(SupplyTruckBusyState)
- //-----------------------------------------------------------------------------------------------------------
- class SupplyTruckIdleState : public State
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(SupplyTruckIdleState, "SupplyTruckIdleState")
- protected:
- // snapshot interface STUBBED.
- virtual void crc( Xfer *xfer ){};
- virtual void xfer( Xfer *xfer ){};
- virtual void loadPostProcess(){};
- public:
- SupplyTruckIdleState( StateMachine *machine ) : State( machine, "SupplyTruckIdleState" ) { }
- virtual StateReturnType onEnter();
- virtual StateReturnType update()
- {
- return STATE_CONTINUE;
- }
- virtual void onExit(StateExitType status)
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("exiting idle state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- }
- };
- EMPTY_DTOR(SupplyTruckIdleState)
- StateReturnType SupplyTruckIdleState::onEnter()
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("entering idle state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
-
- Object *owner = getMachineOwner();
- if (owner != NULL) {
- AIUpdateInterface * ownerAI = owner->getAIUpdateInterface();
- if (ownerAI != NULL) {
- // This is to get idle workers to always show up on the
- // "idle worker button."
- // Basically if you have a worker interface, and we are entering
- // the idle state for the supply truck, we let the worker interface
- // know so it can decide which idle state it wants us to actually
- // be in from its perspective.
- WorkerAIInterface *workerAI = ownerAI->getWorkerAIInterface();
- if (workerAI != NULL) {
- workerAI->exitingSupplyTruckState();
- }
- }
- }
- return STATE_CONTINUE;
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- SupplyTruckStateMachine::SupplyTruckStateMachine( Object *owner ) : StateMachine( owner, "SupplyTruckStateMachine" )
- {
- static const StateConditionInfo busyConditions[] =
- {
- StateConditionInfo(ownerIdle, ST_IDLE, NULL),
- StateConditionInfo(ownerDocking, ST_DOCKING, NULL),
- StateConditionInfo(NULL, NULL, NULL) // keep last
- };
- static const StateConditionInfo idleConditions[] =
- {
- StateConditionInfo(isForcedIntoBusyState, ST_BUSY, NULL),
- StateConditionInfo(isForcedIntoWantingState, ST_WANTING, NULL),
- StateConditionInfo(ownerDocking, ST_DOCKING, NULL),
- StateConditionInfo(ownerNotDockingOrIdle, ST_BUSY, NULL),
- StateConditionInfo(NULL, NULL, NULL) // keep last
- };
- static const StateConditionInfo wantingConditions[] =
- {
- StateConditionInfo(ownerDocking, ST_DOCKING, NULL),
- StateConditionInfo(ownerNotDockingOrIdle, ST_BUSY, NULL),
- StateConditionInfo(NULL, NULL, NULL) // keep last
- };
- static const StateConditionInfo regroupingConditions[] =
- {
- StateConditionInfo(ownerIdle, ST_IDLE, NULL),
- StateConditionInfo(ownerDocking, ST_DOCKING, NULL),
- StateConditionInfo(NULL, NULL, NULL) // keep last
- };
- static const StateConditionInfo dockingConditions[] =
- {
- StateConditionInfo(isForcedIntoBusyState, ST_BUSY, NULL),
- StateConditionInfo(ownerAvailableForSupplying, ST_WANTING, NULL),
- StateConditionInfo(ownerNotDockingOrIdle, ST_BUSY, NULL),
- StateConditionInfo(NULL, NULL, NULL) // keep last
- };
- // order matters: first state is the default state.
- defineState( ST_BUSY, newInstance(SupplyTruckBusyState)( this ), ST_BUSY, ST_BUSY, busyConditions );
- defineState( ST_IDLE, newInstance(SupplyTruckIdleState)( this ), ST_BUSY, ST_BUSY, idleConditions );
- defineState( ST_WANTING, newInstance(SupplyTruckWantsToPickUpOrDeliverBoxesState)( this ), ST_BUSY, ST_REGROUPING, wantingConditions );
- defineState( ST_REGROUPING, newInstance(RegroupingState)( this ), ST_WANTING, ST_BUSY, regroupingConditions );
- defineState( ST_DOCKING, newInstance(DockingState)( this ), ST_BUSY, ST_BUSY, dockingConditions );
- }
- //-------------------------------------------------------------------------------------------------
- SupplyTruckStateMachine::~SupplyTruckStateMachine()
- {
- }
- // ------------------------------------------------------------------------------------------------
- /** CRC */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckStateMachine::crc( Xfer *xfer )
- {
- StateMachine::crc(xfer);
- } // end crc
- // ------------------------------------------------------------------------------------------------
- /** Xfer Method */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckStateMachine::xfer( Xfer *xfer )
- {
- XferVersion cv = 1;
- XferVersion v = cv;
- xfer->xferVersion( &v, cv );
- StateMachine::xfer(xfer);
- } // end xfer
- // ------------------------------------------------------------------------------------------------
- /** Load post process */
- // ------------------------------------------------------------------------------------------------
- void SupplyTruckStateMachine::loadPostProcess( void )
- {
- StateMachine::loadPostProcess();
- } // end loadPostProcess
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- StateReturnType SupplyTruckWantsToPickUpOrDeliverBoxesState::onEnter()
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("entering wanting state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return STATE_CONTINUE;
- }
- //-------------------------------------------------------------------------------------------------
- void SupplyTruckWantsToPickUpOrDeliverBoxesState::onExit(StateExitType status)
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("exiting wanting state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- }
- //-------------------------------------------------------------------------------------------------
- StateReturnType SupplyTruckWantsToPickUpOrDeliverBoxesState::update()
- {
- Object* owner = getMachineOwner();
- AIUpdateInterface* ownerAI = owner->getAIUpdateInterface();
- if (!ownerAI)
- return STATE_FAILURE;
- Player* ownerPlayer = owner->getControllingPlayer();
- ResourceGatheringManager *manager = ownerPlayer->getResourceGatheringManager();
- SupplyTruckAIInterface* update = ownerAI->getSupplyTruckAIInterface();
- if (!update)
- return STATE_FAILURE;
- if (!update->isAvailableForSupplying())
- {
- DEBUG_CRASH(("SupplyTruckWantsToPickUpOrDeliverBoxesState: isAvailableForSupplying==false; should not get here"));
- return STATE_FAILURE;
- }
- Int numBoxes = update->getNumberBoxes();
- if (numBoxes > 0)
- {
- // want a center.
- Object *bestCenter = manager->findBestSupplyCenter( owner );
- if( bestCenter )
- {
- ownerAI->aiDock( bestCenter, CMD_FROM_AI );
- return STATE_SUCCESS;
- }
- }
- else
- {
- // want a warehouse.
- Object* bestWarehouse = manager->findBestSupplyWarehouse( owner );
- if( bestWarehouse )
- {
- ownerAI->aiDock( bestWarehouse, CMD_FROM_AI );
- return STATE_SUCCESS;
- }
- }
- return STATE_FAILURE;// we aren't going to wait right here, we will go back to base and wait for
- // wanting to succeed some place safe.
- }
- //-------------------------------------------------------------------------------------------------
- StateReturnType RegroupingState::onEnter()
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("entering regrouping state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- // I have failed to find a dock, so my first choice is to go hang out at a Supply Center (I may have
- // failed to find a Warehouse). My second choices is to go to a ConYard. My last choice is just to
- // go to a friendly building.
- Object* owner = getMachineOwner();
- AIUpdateInterface* ownerAI = owner->getAIUpdateInterface();
- Player* ownerPlayer = owner->getControllingPlayer();
- if( !ownerPlayer || !ownerAI )
- return STATE_FAILURE;
- ownerAI->ignoreObstacle( NULL );
- SupplyTruckAIInterface *update = owner->getAIUpdateInterface()->getSupplyTruckAIInterface();
- if( !update )
- {
- return STATE_FAILURE;
- }
- Int numBoxes = update->getNumberBoxes();
- // If we are forced to regroup, and we have boxes, we want to wait for the player to
- // rebuild a supply center & go to it.
- Bool wanting = numBoxes > 0;
- update->setForceWantingState( wanting );
- Object *destinationObject = NULL;
-
- KindOfMaskType kindof;
- KindOfMaskType kindofnot;
- kindof.set(KINDOF_CASH_GENERATOR);
- kindofnot.clear();
- // can't do best supply center of the player's resource brain, because that adds canTransfer checks.
- destinationObject = ownerPlayer->findClosestByKindOf( owner, kindof, kindofnot );
- if( !destinationObject )
- {
- kindof.clear();
- kindof.set(KINDOF_COMMANDCENTER);
- kindofnot.clear();
- destinationObject = ownerPlayer->findClosestByKindOf( owner, kindof, kindofnot );
- }
- if( !destinationObject )
- {
- kindof.clear();
- kindof.set( KINDOF_STRUCTURE );
- kindofnot.clear();
- destinationObject = ownerPlayer->findClosestByKindOf( owner, kindof, kindofnot );
- }
- if( !destinationObject )
- {
- return STATE_FAILURE;
- }
- Coord3D destination;
- FindPositionOptions fpOptions;
- fpOptions.minRadius = 0.0f;
- fpOptions.maxRadius = 100.0f;
- if( ! ThePartitionManager->findPositionAround( destinationObject->getPosition(), &fpOptions, &destination ) )
- return STATE_FAILURE;
- ownerAI->aiMoveToPosition( &destination, CMD_FROM_AI );
- return STATE_CONTINUE;// Remember to say continue when you change ai command inside a state
- }
- //-------------------------------------------------------------------------------------------------
- void RegroupingState::onExit(StateExitType status)
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("exiting regroup state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- }
- //-------------------------------------------------------------------------------------------------
- StateReturnType DockingState::onEnter()
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("entering docking state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- Object *owner = getMachineOwner();
- SupplyTruckAIInterface *update = owner->getAIUpdateInterface()->getSupplyTruckAIInterface();
- if( !update )
- {
- return STATE_FAILURE;
- }
- // after we dock the first time, we clear this, and then follow our normal state machine path
- update->setForceWantingState(false);
- return STATE_CONTINUE;
- }
- //-------------------------------------------------------------------------------------------------
- StateReturnType DockingState::update()
- {
- return STATE_CONTINUE;
- }
- //-------------------------------------------------------------------------------------------------
- void DockingState::onExit(StateExitType status)
- {
- #ifdef DEBUG_SUPPLY_STATE
- TheInGameUI->DEBUG_addFloatingText("exiting docking state", getMachineOwner()->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::isForcedIntoWantingState( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- SupplyTruckAIInterface *update = ai->getSupplyTruckAIInterface();
- if( !update )
- return false;
- if (update->isForcedIntoWantingState())
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("isForcedIntoWantingState returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::isForcedIntoBusyState( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- SupplyTruckAIInterface *update = ai->getSupplyTruckAIInterface();
- if( !update )
- return false;
- if (update->isForcedIntoBusyState())
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("isForcedIntoBusytate returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::ownerDocking( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- AIStateType masterState = ai->getAIStateType();
- if (masterState == AI_DOCK)
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("ownerDocking returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::ownerIdle( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- if (ai->isIdle())
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("ownerIdle returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::ownerAvailableForSupplying( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- SupplyTruckAIInterface *update = ai->getSupplyTruckAIInterface();
- if( !update )
- return false;
- if (update->isAvailableForSupplying() && ai->isIdle())
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("ownerAvailableForSupplying returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------
- /* static */ Bool SupplyTruckStateMachine::ownerNotDockingOrIdle( State *thisState, void* userData )
- {
- Object *owner = thisState->getMachineOwner();
- AIUpdateInterface *ai = owner->getAIUpdateInterface();
- if( !ai )
- return false;
- if (!ai->isIdle() && ai->getAIStateType() != AI_DOCK)
- {
- #ifdef DEBUG_SUPPLY_STATE
- AsciiString tmp;
- tmp.format("ownerNotDockingOrIdle returns true (%s)",statenames[thisState->getID()]);
- TheInGameUI->DEBUG_addFloatingText(tmp, owner->getPosition(), GameMakeColor(255, 0, 0, 255));
- #endif
- return true;
- }
- return false;
- }
|