| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- /*
- ** 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: ConvertToHijackedVehicleCrateCollide.cpp
- // Author: Mark Lorenzen, July 2002
- // Desc: A crate (actually a terrorist - mobile crate) that makes the target vehicle switch
- // sides, and kills its driver
- // @todo Needs to set the science of that vehicle (dozer) so still can build same stuff as always
- //
- ///////////////////////////////////////////////////////////////////////////////////////////////////
-
- // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "Common/Player.h"
- #include "Common/PlayerList.h"
- #include "Common/Radar.h"
- #include "Common/ThingTemplate.h"
- #include "Common/Xfer.h"
- #include "GameClient/Drawable.h"
- #include "GameClient/Eva.h"
- #include "GameClient/InGameUI.h" // useful for printing quick debug strings when we need to
- #include "GameLogic/ExperienceTracker.h"
- #include "GameLogic/Module/AIUpdate.h"
- #include "GameLogic/Module/ConvertToHijackedVehicleCrateCollide.h"
- #include "GameLogic/Module/HijackerUpdate.h"
- #include "GameLogic/Module/ContainModule.h"
- #include "GameLogic/Object.h"
- #include "GameLogic/PartitionManager.h"
- #include "GameLogic/ScriptEngine.h"
- #include "GameLogic/Module/DozerAIUpdate.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- ConvertToHijackedVehicleCrateCollide::ConvertToHijackedVehicleCrateCollide( Thing *thing, const ModuleData* moduleData ) : CrateCollide( thing, moduleData )
- {
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- ConvertToHijackedVehicleCrateCollide::~ConvertToHijackedVehicleCrateCollide( void )
- {
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- Bool ConvertToHijackedVehicleCrateCollide::isValidToExecute( const Object *other ) const
- {
- if( !CrateCollide::isValidToExecute(other) )
- {
- return FALSE;
- }
- if( other->isEffectivelyDead() )
- {
- return FALSE;// can't hijack a dead vehicle
- }
-
- if( other->isKindOf( KINDOF_IMMUNE_TO_CAPTURE ) )
- {
- return FALSE; //Kris: Patch 1.03 -- Prevent hijackers from being able to hijack battle buses.
- }
- if( other->isKindOf( KINDOF_AIRCRAFT ) || other->isKindOf( KINDOF_BOAT ) )
- {
- //Can't hijack planes and boats!
- return FALSE;
- }
- if( other->isKindOf( KINDOF_DRONE ) )
- {
- //Can't hijack drones!
- return FALSE;
- }
- if( other->getStatusBits().test( OBJECT_STATUS_HIJACKED ) )
- {
- return FALSE;// oops, sorry, I'll jack the next one.
- }
- Relationship r = getObject()->getRelationship( other );
- //Only hijack enemy objects
- if( r != ENEMIES )
- {
- return FALSE;
- }
- if( other->isKindOf( KINDOF_TRANSPORT ) )
- {
- //Kris: Allow empty transports to be hijacked.
- if( other->getContain() && other->getContain()->getContainCount() > 0 )
- {
- return FALSE;// dustin sez: do not jack vehicles that may carry hostile passengers
- }
- }
- //Kris: Make sure you can't hijack any aircraft (or hijack-enter).
- if( other->isKindOf( KINDOF_AIRCRAFT ) )
- {
- return FALSE;
- }
- //VeterancyLevel veterancyLevel = other->getVeterancyLevel();
- //if( veterancyLevel >= LEVEL_ELITE )
- //{
- // return FALSE;
- //}
- return TRUE;
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- Bool ConvertToHijackedVehicleCrateCollide::executeCrateBehavior( Object *other )
- {
- //Check to make sure that the other object is also the goal object in the AIUpdateInterface
- //in order to prevent an unintentional conversion simply by having the terrorist walk too close
- //to it.
- //Assume ai is valid because CrateCollide::isValidToExecute(other) checks it.
- Object *obj = getObject();
- AIUpdateInterface* ai = obj->getAIUpdateInterface();
- if (ai && ai->getGoalObject() != other)
- {
- return false;
- }
- TheRadar->tryInfiltrationEvent( other );
- //Before the actual defection takes place, play the "vehicle stolen" EVA
- //event if the local player is the victim!
- if( other->isLocallyControlled() )
- {
- TheEva->setShouldPlay( EVA_VehicleStolen );
- }
-
- other->setTeam( obj->getControllingPlayer()->getDefaultTeam() );
- other->setStatus( MAKE_OBJECT_STATUS_MASK( OBJECT_STATUS_HIJACKED ) );// I claim this car in the name of the GLA
- AIUpdateInterface* targetAI = other->getAIUpdateInterface();
- targetAI->aiMoveToPosition( other->getPosition(), CMD_FROM_AI );
- targetAI->aiIdle( CMD_FROM_AI );
- //Just in case this target is a dozer, lets make him stop al his dozer tasks, like building and repairing,
- //So the previous owner does not benefit from these tasks
- DozerAIInterface * dozerAI = targetAI->getDozerAIInterface();
- if ( dozerAI )
- {
- for (UnsignedInt task = DOZER_TASK_FIRST; task < DOZER_NUM_TASKS; ++task)
- {
- dozerAI->cancelTask( (DozerTask)task );
- }
- }
- AudioEventRTS hijackEvent( "HijackDriver", obj->getID() );
- TheAudio->addAudioEvent( &hijackEvent );
- //In order to make things easier for the designers, we are going to transfer the hijacker's name
- //to the car... so the designer can control the car with their scripts.
- TheScriptEngine->transferObjectName( obj->getName(), other );
- ExperienceTracker *targetExp = other->getExperienceTracker();
- ExperienceTracker *jackerExp = obj->getExperienceTracker();
- if ( targetExp && jackerExp )
- {
- VeterancyLevel highestLevel = MAX(targetExp->getVeterancyLevel(),jackerExp->getVeterancyLevel());
- jackerExp->setVeterancyLevel( highestLevel, FALSE );
- targetExp->setVeterancyLevel( highestLevel, FALSE );
- }
- Bool targetCanEject = FALSE;
- BehaviorModule **dmi = NULL;
- for( dmi = other->getBehaviorModules(); *dmi; ++dmi )
- {
- if( (*dmi)->getEjectPilotDieInterface() )
- {
- targetCanEject = TRUE;
- break;
- }
- } // end for dmi
- if ( ! targetCanEject )
- {
- TheGameLogic->destroyObject( obj );
- return TRUE;
- }
- // I we have made it this far, we are going to ride in this vehicle for a while
- // get the name of the hijackerupdate
- static NameKeyType key_HijackerUpdate = NAMEKEY( "HijackerUpdate" );
- HijackerUpdate *hijackerUpdate = (HijackerUpdate*)obj->findUpdateModule( key_HijackerUpdate );
- if( hijackerUpdate )
- {
- hijackerUpdate->setTargetObject( other );
- hijackerUpdate->setIsInVehicle( TRUE );
- hijackerUpdate->setUpdate( TRUE );
- // flag bits so hijacker won't be selectible or collideable
- //while within the vehicle
- obj->setStatus( MAKE_OBJECT_STATUS_MASK3( OBJECT_STATUS_NO_COLLISIONS, OBJECT_STATUS_MASKED, OBJECT_STATUS_UNSELECTABLE ) );
- }
- // THIS BLOCK HIDES THE HIJACKER AND REMOVES HIM FROM PARTITION MANAGER
- // remove object from its group (if any)
- obj->leaveGroup();
- if( ai )
- {
- //By setting him to idle, we will prevent him from entering the target after this gets called.
- ai->aiIdle( CMD_FROM_AI );
- }
- //This is kinda special... we will endow our new ride with our vision and shroud range, since we are driving
- other->setVisionRange(getObject()->getVisionRange());
- other->setShroudClearingRange(getObject()->getShroudClearingRange());
- // remove rider from partition manager
- ThePartitionManager->unRegisterObject( obj );
- // hide the drawable associated with rider
- if( obj->getDrawable() )
- obj->getDrawable()->setDrawableHidden( true );
- // By returning FALSE, we will not remove the object (Hijacker)
- return FALSE;
- // return TRUE;
- }
- // ------------------------------------------------------------------------------------------------
- /** CRC */
- // ------------------------------------------------------------------------------------------------
- void ConvertToHijackedVehicleCrateCollide::crc( Xfer *xfer )
- {
- // extend base class
- CrateCollide::crc( xfer );
- } // end crc
- // ------------------------------------------------------------------------------------------------
- /** Xfer method
- * Version Info:
- * 1: Initial version */
- // ------------------------------------------------------------------------------------------------
- void ConvertToHijackedVehicleCrateCollide::xfer( Xfer *xfer )
- {
- // version
- XferVersion currentVersion = 1;
- XferVersion version = currentVersion;
- xfer->xferVersion( &version, currentVersion );
- // extend base class
- CrateCollide::xfer( xfer );
- } // end xfer
- // ------------------------------------------------------------------------------------------------
- /** Load post process */
- // ------------------------------------------------------------------------------------------------
- void ConvertToHijackedVehicleCrateCollide::loadPostProcess( void )
- {
- // extend base class
- CrateCollide::loadPostProcess();
- } // end loadPostProcess
|