OpenContain.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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: OpenContain.h ////////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, November 2001
  25. // Desc: The OpenContainer ContainModule allows objects to be contained inside of other
  26. // objects. There is a set of functionality that will be common to
  27. // all container modules that provides the actual containment
  28. // implementations, those implementations are found here
  29. ///////////////////////////////////////////////////////////////////////////////////////////////////
  30. #pragma once
  31. #ifndef __OPENCONTAIN_H_
  32. #define __OPENCONTAIN_H_
  33. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  34. #include "GameLogic/Module/BehaviorModule.h"
  35. #include "GameLogic/Module/CollideModule.h"
  36. #include "GameLogic/Module/ContainModule.h"
  37. #include "GameLogic/Module/UpdateModule.h"
  38. #include "GameLogic/Module/DieModule.h"
  39. #include "GameLogic/Module/DamageModule.h"
  40. #include "Common/AudioEventRTS.h"
  41. #include "Common/KindOf.h"
  42. #include "Common/GameMemory.h"
  43. #include "Common/ModelState.h"
  44. // ------------------------------------------------------------------------------------------------
  45. enum { CONTAIN_MAX_UNKNOWN = -1 }; // means we don't care, infinite, unassigned, whatever
  46. //-------------------------------------------------------------------------------------------------
  47. //-------------------------------------------------------------------------------------------------
  48. class OpenContainModuleData : public UpdateModuleData
  49. {
  50. public:
  51. DieMuxData m_dieMuxData;
  52. Int m_containMax; ///< how many things we can have inside (-1 = "I don't care")
  53. AudioEventRTS m_enterSound; ///< sound to play on entering
  54. AudioEventRTS m_exitSound; ///< sound to play on exiting
  55. Bool m_passengersAllowedToFire; ///< Can the passengers shoot out of us?
  56. Bool m_passengersInTurret; ///< The Firepoint bones are in our turret, not our chassis
  57. Int m_numberOfExitPaths; ///< Will alternate through ExitStart/End paths as we exit people.
  58. Real m_damagePercentageToUnits;
  59. Bool m_isBurnedDeathToUnits; ///< Turn off the hardcoded burn death when killing guys in transport
  60. UnsignedInt m_doorOpenTime;
  61. KindOfMaskType m_allowInsideKindOf; ///< objects must have at least one of these kind of bits set to be contained by us
  62. KindOfMaskType m_forbidInsideKindOf; ///< objects must have NONE of these kind of bits set to be contained by us
  63. Bool m_weaponBonusPassedToPassengers; ///< Do our passengers get to use our weapon bonuses?
  64. Bool m_allowAlliesInside; ///< allow allies inside us
  65. Bool m_allowEnemiesInside; ///< allow enemies inside us
  66. Bool m_allowNeutralInside; ///< allow neutral inside us
  67. OpenContainModuleData( void );
  68. static void buildFieldParse(MultiIniFieldParse& p);
  69. };
  70. //-------------------------------------------------------------------------------------------------
  71. /** An open container can actually contain other objects */
  72. //-------------------------------------------------------------------------------------------------
  73. class OpenContain : public UpdateModule,
  74. public ContainModuleInterface,
  75. public CollideModuleInterface,
  76. public DieModuleInterface,
  77. public DamageModuleInterface,
  78. public ExitInterface
  79. {
  80. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( OpenContain, "OpenContain" )
  81. MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( OpenContain, OpenContainModuleData )
  82. public:
  83. OpenContain( Thing *thing, const ModuleData* moduleData );
  84. // virtual destructor prototype provided by memory pool declaration
  85. virtual ContainModuleInterface* getContain() { return this; }
  86. virtual CollideModuleInterface* getCollide() { return this; }
  87. virtual DieModuleInterface* getDie() { return this; }
  88. virtual DamageModuleInterface* getDamage() { return this; }
  89. static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | (MODULEINTERFACE_CONTAIN) | (MODULEINTERFACE_COLLIDE) | (MODULEINTERFACE_DIE) | (MODULEINTERFACE_DAMAGE); }
  90. virtual void onDie( const DamageInfo *damageInfo ); ///< the die callback
  91. virtual void onDelete( void ); ///< Last possible moment cleanup
  92. virtual void onCapture( Player *oldOwner, Player *newOwner ){}
  93. // CollideModuleInterface
  94. virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
  95. virtual Bool wouldLikeToCollideWith(const Object* other) const { return false; }
  96. virtual Bool isCarBombCrateCollide() const { return false; }
  97. virtual Bool isHijackedVehicleCrateCollide() const { return false; }
  98. virtual Bool isRailroad() const { return false;}
  99. virtual Bool isSalvageCrateCollide() const { return false; }
  100. virtual Bool isSabotageBuildingCrateCollide() const { return FALSE; }
  101. // UpdateModule
  102. virtual UpdateSleepTime update(); ///< called once per frame
  103. // ContainModuleInterface
  104. virtual OpenContain *asOpenContain() { return this; } ///< treat as open container
  105. // DamageModuleInterface
  106. virtual void onDamage( DamageInfo *damageInfo ){}; ///< damage callback
  107. virtual void onHealing( DamageInfo *damageInfo ){}; ///< healing callback
  108. virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
  109. BodyDamageType oldState,
  110. BodyDamageType newState){}; ///< state change callback
  111. // our object changed position... react as appropriate.
  112. virtual void containReactToTransformChange();
  113. virtual Bool calcBestGarrisonPosition( Coord3D *sourcePos, const Coord3D *targetPos ) { return FALSE; }
  114. virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, Object *victim ) { return FALSE; }
  115. virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, const Coord3D *targetPos ) { return FALSE; }
  116. ///< if my object gets selected, then my visible passengers should, too
  117. ///< this gets called from
  118. virtual void clientVisibleContainedFlashAsSelected() {};
  119. virtual const Player* getApparentControllingPlayer(const Player* observingPlayer) const { return NULL; }
  120. virtual void recalcApparentControllingPlayer() { }
  121. virtual void onContaining( Object *obj, Bool wasSelected ); ///< object now contains 'obj'
  122. virtual void onRemoving( Object *obj ); ///< object no longer contains 'obj'
  123. virtual void onSelling();///< Container is being sold. Open responds by kicking people out
  124. virtual void orderAllPassengersToExit( CommandSourceType commandSource, Bool instantly ); ///< All of the smarts of exiting are in the passenger's AIExit. removeAllFrommContain is a last ditch system call, this is the game Evacuate
  125. virtual void orderAllPassengersToIdle( CommandSourceType commandSource ); ///< Just like it sounds
  126. virtual void orderAllPassengersToHackInternet( CommandSourceType ); ///< Just like it sounds
  127. virtual void markAllPassengersDetected(); ///< Cool game stuff got added to the system calls since this layer didn't exist, so this regains that functionality
  128. // default OpenContain has unlimited capacity...!
  129. virtual Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const;
  130. virtual void addToContain( Object *obj ); ///< add 'obj' to contain list
  131. virtual void addToContainList( Object *obj ); ///< The part of AddToContain that inheritors can override (Can't do whole thing because of all the private stuff involved)
  132. virtual void removeFromContain( Object *obj, Bool exposeStealthUnits = FALSE ); ///< remove 'obj' from contain list
  133. virtual void removeAllContained( Bool exposeStealthUnits = FALSE ); ///< remove all objects on contain list
  134. virtual void killAllContained( void ); ///< kill all objects on contain list
  135. virtual void harmAndForceExitAllContained( DamageInfo *info ); // apply canned damage against those containes
  136. virtual Bool isEnclosingContainerFor( const Object *obj ) const; ///< Does this type of Contain Visibly enclose its contents?
  137. virtual Bool isPassengerAllowedToFire( ObjectID id = INVALID_ID ) const; ///< Hey, can I shoot out of this container?
  138. virtual void setPassengerAllowedToFire( Bool permission = TRUE ) { m_passengerAllowedToFire = permission; } ///< Hey, can I shoot out of this container?
  139. virtual void setOverrideDestination( const Coord3D * ){} ///< Instead of falling peacefully towards a clear spot, I will now aim here
  140. virtual Bool isDisplayedOnControlBar() const {return FALSE;}///< Does this container display its contents on the ControlBar?
  141. virtual Int getExtraSlotsInUse( void ) { return 0; }
  142. virtual Bool isKickOutOnCapture(){ return TRUE; }///< By default, yes, all contain modules kick passengers out on capture
  143. // contain list access
  144. virtual void iterateContained( ContainIterateFunc func, void *userData, Bool reverse );
  145. virtual UnsignedInt getContainCount() const { return m_containListSize; }
  146. virtual const ContainedItemsList* getContainedItemsList() const { return &m_containList; }
  147. virtual const Object *friend_getRider() const{return NULL;} ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
  148. virtual Real getContainedItemsMass() const;
  149. virtual UnsignedInt getStealthUnitsContained() const { return m_stealthUnitsContained; }
  150. virtual PlayerMaskType getPlayerWhoEntered(void) const { return m_playerEnteredMask; }
  151. virtual Int getContainMax() const;
  152. // ExitInterface
  153. virtual Bool isExitBusy() const {return FALSE;} ///< Contain style exiters are getting the ability to space out exits, so ask this before reserveDoor as a kind of no-commitment check.
  154. virtual ExitDoorType reserveDoorForExit( const ThingTemplate* objType, Object *specificObject ) { return DOOR_1; }
  155. virtual void exitObjectViaDoor( Object *newObj, ExitDoorType exitDoor );
  156. virtual void exitObjectInAHurry( Object *newObj );
  157. virtual void unreserveDoorForExit( ExitDoorType exitDoor ) { /*nothing*/ }
  158. virtual void exitObjectByBudding( Object *newObj, Object *budHost ) { return; };
  159. virtual void setRallyPoint( const Coord3D *pos ); ///< define a "rally point" for units to move towards
  160. virtual const Coord3D *getRallyPoint( void ) const; ///< define a "rally point" for units to move towards
  161. virtual Bool getExitPosition(Coord3D& exitPosition ) const { return FALSE; }; ///< access to the "Door" position of the production object
  162. virtual Bool getNaturalRallyPoint( Coord3D& rallyPoint, Bool offset = TRUE ) const; ///< get the natural "rally point" for units to move towards
  163. virtual ExitInterface* getContainExitInterface() { return this; }
  164. virtual Bool isGarrisonable() const { return false; } ///< can this unit be Garrisoned? (ick)
  165. virtual Bool isBustable() const { return false; } ///< can this container get busted by a bunkerbuster
  166. virtual Bool isHealContain() const { return false; } ///< true when container only contains units while healing (not a transport!)
  167. virtual Bool isTunnelContain() const { return FALSE; }
  168. virtual Bool isRiderChangeContain() const { return FALSE; }
  169. virtual Bool isSpecialZeroSlotContainer() const { return false; }
  170. virtual Bool isImmuneToClearBuildingAttacks() const { return true; }
  171. virtual Bool isSpecialOverlordStyleContainer() const { return false; }
  172. virtual Bool isAnyRiderAttacking( void ) const;
  173. /**
  174. this is used for containers that must do something to allow people to enter or exit...
  175. eg, land (for Chinook), open door (whatever)... it's called with wants=WANTS_TO_ENTER
  176. when something is in the enter state, and wants=ENTS_NOTHING when the unit has
  177. either entered, or given up...
  178. */
  179. virtual void onObjectWantsToEnterOrExit(Object* obj, ObjectEnterExitType wants);
  180. // returns true iff there are objects currently waiting to enter.
  181. virtual Bool hasObjectsWantingToEnterOrExit() const;
  182. virtual void processDamageToContained(Real percentDamage); ///< Do our % damage to units now.
  183. virtual Bool isWeaponBonusPassedToPassengers() const;
  184. virtual WeaponBonusConditionFlags getWeaponBonusPassedToPassengers() const;
  185. virtual void enableLoadSounds( Bool enable ) { m_loadSoundsEnabled = enable; }
  186. Real getDamagePercentageToUnits( void );
  187. virtual Object* getClosestRider ( const Coord3D *pos );
  188. virtual void setEvacDisposition( EvacDisposition disp ) {};
  189. protected:
  190. virtual void monitorConditionChanges( void ); ///< check to see if we need to update our occupant postions from a model change or anything else
  191. virtual void putObjAtNextFirePoint( Object *obj ); ///< place object at position of the next fire point to use
  192. virtual void redeployOccupants( void ); ///< redeploy any objects at firepoints due to a model condition change
  193. const ContainedItemsList& getContainList() const { return m_containList; }
  194. void scatterToNearbyPosition(Object* obj);
  195. void removeFromContainViaIterator( ContainedItemsList::iterator it, Bool exposeStealthUnits = FALSE ); ///< remove item from contain list
  196. void removeFromPassengerViaIterator( ContainedItemsList::iterator it );///< remove item from passenger list
  197. virtual void doLoadSound();
  198. virtual void doUnloadSound();
  199. virtual void positionContainedObjectsRelativeToContainer(){}
  200. virtual void addOrRemoveObjFromWorld(Object* obj, Bool add);
  201. // exists primarily for TransportContain to override
  202. virtual void killRidersWhoAreNotFreeToExit() { }
  203. void pruneDeadWanters();
  204. ContainedItemsList m_containList; ///< the list of contained objects
  205. UnsignedInt m_containListSize; ///< size of contained list
  206. private:
  207. typedef std::map< ObjectID, ObjectEnterExitType, std::less<ObjectID> > ObjectEnterExitMap;
  208. ObjectEnterExitMap m_objectEnterExitInfo;
  209. UnsignedInt m_stealthUnitsContained; ///< number of stealth units that can't be seen by enemy players.
  210. Int m_whichExitPath; ///< Cycles from 1 to n and is used only in modules whose data has numberOfExitPaths > 1.
  211. UnsignedInt m_doorCloseCountdown; ///< When should I shut my door.
  212. std::list<ObjectID> m_xferContainIDList; ///< for loading m_containList from a save game
  213. PlayerMaskType m_playerEnteredMask; ///< Mask of player that entered last, if any.
  214. UnsignedInt m_lastUnloadSoundFrame; ///< last frame we did an un-loading sound
  215. UnsignedInt m_lastLoadSoundFrame; ///< last frame we did a loading sound
  216. /// @todo srj -- move this to a lazily-allocated subobject
  217. enum { MAX_FIRE_POINTS = 32 };
  218. ModelConditionFlags m_conditionState; ///< The Drawables current behavior state
  219. Matrix3D m_firePoints[ MAX_FIRE_POINTS ];
  220. Int m_firePointStart; ///< start firepoint index to use when building becomes occupied
  221. Int m_firePointNext; ///< next index to place objects at
  222. Int m_firePointSize; ///< how many entries in m_firePoint are valid
  223. Bool m_noFirePointsInArt; ///< TRUE when no fire point bones exist in the art
  224. Coord3D m_rallyPoint; ///< Where units should move to after they have reached the "natural" rally point
  225. Bool m_rallyPointExists; ///< Only move to the rally point if this is true
  226. Bool m_loadSoundsEnabled; ///< Don't serialize -- used for disabling sounds during payload creation.
  227. Bool m_passengerAllowedToFire; ///< Newly promoted from the template data to the module for upgrade overriding access
  228. };
  229. #endif // end __OPENCONTAIN_H_