| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- /*
- ** 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. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // Object.h ///////////////////////////////////////////////////////////////////
- // Simple base object
- // Author: Michael S. Booth, October 2000
- #pragma once
- #ifndef _OBJECT_H_
- #define _OBJECT_H_
- #include "Lib/BaseType.h"
- #include "Common/Geometry.h"
- #include "Common/Snapshot.h"
- #include "Common/SpecialPowerMaskType.h"
- #include "Common/DisabledTypes.h"
- #include "Common/Thing.h"
- #include "GameClient/Color.h"
- #include "GameLogic/WeaponBonusConditionFlags.h"
- #include "GameLogic/WeaponSet.h"
- #include "GameLogic/WeaponSetFlags.h"
- //-----------------------------------------------------------------------------
- // Forward References
- //-----------------------------------------------------------------------------
- class AIGroup;
- class AIUpdateInterface;
- class Anim2DTemplate;
- class BehaviorModule;
- class BehaviorModuleInterface;
- class BodyModuleInterface;
- class CollideModule;
- class CollideModuleInterface;
- class CommandButton;
- class ContainModuleInterface;
- class CreateModuleInterface;
- class DamageInfo;
- class DamageInfoInput;
- class DamageModule;
- class DamageModuleInterface;
- class DestroyModuleInterface;
- class DockUpdateInterface;
- class Dict;
- class DieModule;
- class DieModuleInterface;
- class ExitInterface;
- class ExperienceTracker;
- class FiringTracker;
- class Module;
- class PartitionData;
- class PhysicsBehavior;
- class PhysicsUpdate;
- class Player;
- class PolygonTrigger;
- class ProductionUpdateInterface;
- class RadarObject;
- class SightingInfo;
- class SpawnBehaviorInterface;
- class SpecialAbilityUpdate;
- class SpecialPowerCompletionDie;
- class SpecialPowerModuleInterface;
- class SpecialPowerTemplate;
- class SpecialPowerUpdateInterface;
- class Team;
- class UpdateModule;
- class UpdateModuleInterface;
- class UpgradeModule;
- class UpgradeModuleInterface;
- class UpgradeTemplate;
- class ObjectHeldHelper;
- class ObjectDisabledHelper;
- class ObjectSMCHelper;
- class ObjectRepulsorHelper;
- class ObjectWeaponStatusHelper;
- class ObjectDefectionHelper;
- enum CommandSourceType;
- enum DamageType;
- enum HackerAttackMode;
- enum NameKeyType;
- enum SpecialPowerType;
- enum WeaponBonusConditionType;
- enum WeaponChoiceCriteria;
- enum WeaponSetConditionType;
- enum WeaponSetType;
- enum WeaponStatus;
- enum RadarPriorityType;
- enum CanAttackResult;
- // For ObjectStatusBits and TheObjectStatusBitNames
- #include "GameLogic/ObjectStatusBits.h"
- // For ObjectScriptStatusBit
- #include "GameLogic/ObjectScriptStatusBits.h"
- //-----------------------------------------------------------------------------
- // Type Defines
- //-----------------------------------------------------------------------------
- struct TTriggerInfo
- {
- const PolygonTrigger* pTrigger; ///< The trigger area that the object is inside.
- Byte entered; ///< True if the object entered this trigger area this frame.
- Byte exited; ///< True if the object entered this trigger area this frame.
- Byte isInside; ///< True if the object is inside this trigger area this frame.
- Byte padding; ///< unused.
- TTriggerInfo() : entered(false), exited(false), isInside(false), padding(false), pTrigger(NULL) { }
- };
- //----------------------------------------------------
- enum CrushSquishTestType
- {
- TEST_CRUSH_ONLY,
- TEST_SQUISH_ONLY,
- TEST_CRUSH_OR_SQUISH
- };
- // ---------------------------------------------------
- /**
- * Object definition. Objects are manipulated via TheGameLogic singleton.
- * @todo Create an ObjectInterface class.
- */
- class Object : public Thing, public Snapshot
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Object, "ObjectPool" )
- /// destructor is non-public in order to require the use of TheGameLogic->destroyObject()
- MEMORY_POOL_DELETEINSTANCE_VISIBILITY(protected)
- public:
- /// Object constructor automatically attaches all objects to "TheGameLogic"
- Object(const ThingTemplate *thing, ObjectStatusBits statusBits, Team *team);
- void initObject();
- void onDestroy(); ///< run during TheGameLogic::destroyObject
- Object* getNextObject() { return m_next; }
- const Object* getNextObject() const { return m_next; }
- void updateObjValuesFromMapProperties(Dict* properties); ///< Brings in properties set in the editor.
- // ids and binding
- ObjectID getID() const { return m_id; } ///< this object's unique ID
- void friend_bindToDrawable( Drawable *draw ); ///< set drawable association. for use ONLY by GameLogic!
- Drawable* getDrawable() const { return m_drawable; } ///< drawable (if any) bound to obj
- ObjectID getProducerID() const { return m_producerID; }
- void setProducer(const Object* obj);
- ObjectID getBuilderID() const { return m_builderID; }
- void setBuilder( const Object *obj );
- void enterGroup( AIGroup *group ); ///< become a member of the AIGroup
- void leaveGroup( void ); ///< leave our current AIGroup
- AIGroup *getGroup(void);
- // physical properties
- Bool isMobile() const; ///< returns true if object is currently able to move
- Bool isAbleToAttack() const; ///< returns true if object currently has some kind of attack capability
- void maskObject( Bool mask ); ///< mask/unmask object
- // cannot set velocity, since this is calculated from position every frame
- Bool isDestroyed() const { return (m_status & OBJECT_STATUS_DESTROYED) != 0; } ///< Returns TRUE if object has been destroyed
- Bool isAirborneTarget() const { return (m_status & OBJECT_STATUS_AIRBORNE_TARGET) != 0; } ///< Our locomotor will control marking us as a valid target for anti air weapons or not
- Bool isUsingAirborneLocomotor( void ) const; ///< returns true if the current locomotor is an airborne one
- /// central place for us to put any additional capture logic
- void onCapture( Player *oldOwner, Player *newOwner );
- /// And game death logic. Destroy is deletion of object as code
- void onDie( DamageInfo *damageInfo );
- // health and damage
- void attemptDamage( DamageInfo *damageInfo ); ///< damage object as specified by the info
- void attemptHealing(Real amount, const Object* source); ///< heal object as specified by the info
- Bool attemptHealingFromSoleBenefactor ( Real amount, const Object* source, UnsignedInt duration );///< for the non-stacking healers like ambulance and propaganda
- ObjectID getSoleHealingBenefactor( void ) const;
- Real estimateDamage( DamageInfoInput& damageInfo ) const;
- void kill(); ///< do max health amount of kill damage to object
- void healCompletely(); ///< Restore max health to this Object
- void scoreTheKill( const Object *victim ); ///< I just killed this object.
- void onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel ); ///< I just achieved this level right this moment
- ExperienceTracker* getExperienceTracker() {return m_experienceTracker;}
- const ExperienceTracker* getExperienceTracker() const {return m_experienceTracker;}
- VeterancyLevel getVeterancyLevel() const;
- inline const AsciiString& getName() const { return m_name; }
- inline void setName( const AsciiString& newName ) { m_name = newName; }
- inline Team* getTeam() { return m_team; }
- inline const Team *getTeam() const { return m_team; }
- void restoreOriginalTeam();
- void setTeam( Team* team ); ///< sets the unit's team AND original team
- void setTemporaryTeam( Team* team ); ///< sets the unit's team BUT NOT its original team
- Player* getControllingPlayer() const;
- Relationship getRelationship(const Object *that) const;
- Color getIndicatorColor() const;
- Color getNightIndicatorColor() const;
- Bool hasCustomIndicatorColor() const { return m_indicatorColor != 0; }
- void setCustomIndicatorColor(Color c);
- void removeCustomIndicatorColor();
- Bool isLocallyControlled() const;
- Bool isNeutralControlled() const;
-
- Bool getIsUndetectedDefector(void) const { return BitTest(m_privateStatus, UNDETECTED_DEFECTOR); }
- void friend_setUndetectedDefector(Bool status);
- inline Bool isOffMap() const { return BitTest(m_privateStatus, OFF_MAP); }
- inline Bool isCaptured() const { return BitTest(m_privateStatus, CAPTURED); }
- void setCaptured(Bool isCaptured);
- inline const GeometryInfo& getGeometryInfo() const { return m_geometryInfo; }
- void setGeometryInfo(const GeometryInfo& geom);
- void setGeometryInfoZ( Real newZ );
- void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
-
- // access to modules
- //-----------------------------------------------------------------------------
-
- //This is a good creation inspector. There's been multitudes of issues with conflicts of
- //Objects getting constructed causing crashes either because the modules aren't created
- //yet, and there's stuff being done inside of setTeam() that cares.
- Bool areModulesReady() const { return m_modulesReady; }
- BehaviorModule** getBehaviorModules() const { return m_behaviors; }
- BodyModuleInterface* getBodyModule() const { return m_body; }
- ContainModuleInterface* getContain() const { return m_contain; }
- SpawnBehaviorInterface* getSpawnBehaviorInterface() const;
- // special case for the AIUpdateInterface, since it will be referred to a great deal
- inline AIUpdateInterface *getAIUpdateInterface() { return m_ai; }
- inline const AIUpdateInterface* getAIUpdateInterface() const { return m_ai; }
- inline AIUpdateInterface *getAI() { return m_ai; }
- inline const AIUpdateInterface* getAI() const { return m_ai; }
- inline PhysicsBehavior* getPhysics() { return m_physics; }
- inline const PhysicsBehavior* getPhysics() const { return m_physics; }
- void topple( const Coord3D *toppleDirection, Real toppleSpeed, UnsignedInt options );
- UpdateModule* findUpdateModule(NameKeyType key) const { return (UpdateModule*)findModule(key); }
- DamageModule* findDamageModule(NameKeyType key) const { return (DamageModule*)findModule(key); }
- Bool isSalvageCrate() const;
- //
- // Find us our production update interface if we have one. This method exists simply
- // because we do this in a lot of places in the code and I want a convenient way to get thsi (CBD)
- //
- ProductionUpdateInterface* getProductionUpdateInterface( void );
- //
- // Find us our dock update interface if we have one. Again, this method exists simple
- // because we want to do this in a lot of places throughout the code
- //
- DockUpdateInterface *getDockUpdateInterface( void );
- // Ditto for special powers -- Kris
- SpecialPowerModuleInterface* findSpecialPowerModuleInterface( SpecialPowerType type ) const;
- SpecialAbilityUpdate* findSpecialAbilityUpdate( SpecialPowerType type ) const;
- SpecialPowerCompletionDie* findSpecialPowerCompletionDie() const;
- SpecialPowerUpdateInterface* findSpecialPowerWithOverridableDestinationActive( SpecialPowerType type = SPECIAL_INVALID ) const;
- inline UnsignedInt getStatusBits() const { return m_status; }
- inline Bool testStatus(ObjectStatusBits bit) const { return (m_status & bit) != 0; }
- void setStatus( ObjectStatusBits bits, Bool set = true );
- inline void clearStatus( ObjectStatusBits bits ) { setStatus(bits, false); }
- void updateUpgradeModules(); ///< We need to go through our Upgrade Modules and see which should be activated
- Int64 getObjectCompletedUpgradeMask() const { return m_objectUpgradesCompleted; } ///< Upgrades I complete locally
- //This function sucks.
- //It was added for objects that can disguise as other objects and contain upgraded subobject overrides.
- //A concrete example is the bomb truck. Different payloads are displayed based on which upgrades have been
- //made. When the bomb truck disguises as something else, these subobjects are lost because the vector is
- //stored in W3DDrawModule. When we revert back to the original bomb truck, we call this function to
- //recalculate those upgraded subobjects.
- void forceRefreshSubObjectUpgradeStatus();
- // Useful for status bits that can be set by the scripting system
- inline Bool testScriptStatusBit(ObjectScriptStatusBit b) const { return BitTest(m_scriptStatus, b); }
- void setScriptStatus( ObjectScriptStatusBit bit, Bool set = true );
- inline void clearScriptStatus( ObjectScriptStatusBit bit ) { setScriptStatus(bit, false); }
- // Selectable is individually controlled on an object by object basis for design now.
- // It defaults to the thingTemplate->isKindof(KINDOF_SELECTABLE), however, it can be overridden on an
- // object by object basis. Finally, it can be temporarily overriden by the OBJECT_STATUS_UNSELECTABLE.
- // jba.
- void setSelectable(Bool selectable);
- Bool isSelectable() const;
-
- Bool isMassSelectable() const;
- // User specified formation.
- void setFormationID(enum FormationID id) {m_formationID = id;}
- enum FormationID getFormationID(void) const {return m_formationID;}
- void setFormationOffset(const Coord2D& offset) {m_formationOffset = offset;}
- void getFormationOffset(Coord2D* offset) const {*offset = m_formationOffset;}
-
- //THIS FUNCTION BELONGS AT THE OBJECT LEVEL BECAUSE THERE IS AT LEAST ONE SPECIAL UNIT
- //(ANGRY MOB) WHICH NEEDS LOGIC-SIDE POSITION CALC'S...
- //IT WOULD PROBABLY BE WISE TO MOVE ALL THE HARD-CODED DEFAULTS BELOW
- //INTO A new Drawable::getHealthBox..() WHICH USES GEOM0INFO, MODEL DATA, INI DATA, ETC.
- void getHealthBoxPosition(Coord3D& pos) const;
- Bool getHealthBoxDimensions(Real &healthBoxHeight, Real &healthBoxWidth) const;
- inline Bool isEffectivelyDead() const { return (m_privateStatus & EFFECTIVELY_DEAD) != 0; }
- void setEffectivelyDead(Bool dead);
- void markSingleUseCommandUsed() { m_singleUseCommandUsed = true; }
- Bool hasSingleUseCommandBeenUsed() const { return m_singleUseCommandUsed; }
-
- /// returns true iff the object can run over the other object.
- Bool canCrushOrSquish(Object *otherObj, CrushSquishTestType testType = TEST_CRUSH_OR_SQUISH) const;
- UnsignedByte getCrusherLevel() const;
- UnsignedByte getCrushableLevel() const;
- Bool hasUpgrade( const UpgradeTemplate *upgradeT ) const ; ///< does this object already have this upgrade
- Bool affectedByUpgrade( const UpgradeTemplate *upgradeT ) const ; ///< can the object even "have" this upgrade, will it do something?
- void giveUpgrade( const UpgradeTemplate *upgradeT ); ///< give upgrade to this object
- void removeUpgrade( const UpgradeTemplate *upgradeT ); ///< remove upgrade from this object
- void calcNaturalRallyPoint(Coord2D *pt); ///< calc the "natural" starting rally point
- void setConstructionPercent( Real percent ) { m_constructionPercent = percent; }
- Real getConstructionPercent() const { return m_constructionPercent; }
- void setLayer( PathfindLayerEnum layer );
- PathfindLayerEnum getLayer() const { return m_layer; }
- void setDestinationLayer( PathfindLayerEnum layer );
- PathfindLayerEnum getDestinationLayer() const { return m_destinationLayer; }
- void prependToList(Object **pListHead);
- void removeFromList(Object **pListHead);
- Bool isInList(Object **pListHead) const;
- // this is intended for use ONLY by GameLogic.
- void friend_deleteInstance() { deleteInstance(); }
- /// cache the partition module (should be called only by PartitionData)
- void friend_setPartitionData(PartitionData *pd) { m_partitionData = pd; }
- PartitionData *friend_getPartitionData() const { return m_partitionData; }
- const PartitionData *friend_getConstPartitionData() const { return m_partitionData; }
- void onPartitionCellChange();///< We have moved a 'significant' amount, so do maintenence that can be considered 'cell-based'
- void handlePartitionCellMaintenance(); ///< Undo and redo all shroud actions. Call when something has changed, like position or ownership or Death
- Real getVisionRange() const; ///< How far can you see? This is dynamic so it is in Object.
- void setVisionRange( Real newVisionRange ); ///< Access to setting someone's Vision distance
- Real getShroudRange() const; ///< How far can you shroud? Even more dynamic since it'll start at zero for everyone.
- void setShroudRange( Real newShroudRange ); ///< Access to setting someone's shrouding distance
- Real getShroudClearingRange() const; ///< How far do you clear shroud?
- void setShroudClearingRange( Real newShroudClearingRange ); ///< Access to setting someone's clear shroud distance
- // Both of these calls are intended to only be used by TerrainLogic, specifically setActiveBoundary()
- void friend_prepareForMapBoundaryAdjust(void);
- void friend_notifyOfNewMapBoundary(void);
- // data for the radar
- void friend_setRadarData( RadarObject *rd ) { m_radarData = rd; }
- RadarObject *friend_getRadarData() { return m_radarData; }
- RadarPriorityType getRadarPriority() const;
- // contained-by
- inline Object *getContainedBy() { return m_containedBy; }
- inline const Object *getContainedBy() const { return m_containedBy; }
- inline UnsignedInt getContainedByFrame() const { return m_containedByFrame; }
- inline Bool isContained() const { return m_containedBy != NULL; }
- void onContainedBy( Object *containedBy );
- void onRemovedFrom( Object *removedFrom );
- Int getTransportSlotCount() const;
- void friend_setContainedBy( Object *containedBy ) { m_containedBy = containedBy; }
- // Special Powers -------------------------------------------------------------------------------
- SpecialPowerModuleInterface *getSpecialPowerModule( const SpecialPowerTemplate *specialPowerTemplate ) const;
- void doSpecialPower( const SpecialPowerTemplate *specialPowerTemplate, UnsignedInt commandOptions, Bool forced = false ); ///< execute power
- void doSpecialPowerAtObject( const SpecialPowerTemplate *specialPowerTemplate, Object *obj, UnsignedInt commandOptions, Bool forced = false ); ///< execute power
- void doSpecialPowerAtLocation( const SpecialPowerTemplate *specialPowerTemplate, const Coord3D *loc, UnsignedInt commandOptions, Bool forced = false ); ///< execute power
- void doSpecialPowerAtMultipleLocations( const SpecialPowerTemplate *specialPowerTemplate,
- const Coord3D *locations, Int locCount, UnsignedInt commandOptions, Bool forced = false ); ///< execute power
- void doCommandButton( const CommandButton *commandButton, CommandSourceType cmdSource );
- void doCommandButtonAtObject( const CommandButton *commandButton, Object *obj, CommandSourceType cmdSource );
- void doCommandButtonAtPosition( const CommandButton *commandButton, const Coord3D *pos, CommandSourceType cmdSource );
-
- /**
- For Object specific dynamic command sets. Different from the Science specific ones handled in ThingTemplate
- */
- const AsciiString& getCommandSetString() const;
- void setCommandSetStringOverride( AsciiString newCommandSetString ) { m_commandSetStringOverride = newCommandSetString; }
- /// People are faking their commandsets, and, Suprise!, they are authoritative. Challenge everything.
- Bool Object::canProduceUpgrade( const UpgradeTemplate *upgrade );
- // Weapons & Damage -------------------------------------------------------------------------------------------------
- void reloadAllAmmo(Bool now);
- Bool isOutOfAmmo() const;
- Bool hasAnyWeapon() const;
- Bool hasAnyDamageWeapon() const; //Kris: a should be used for real weapons that directly inflict damage... not deploy, hack, etc.
- Bool hasWeaponToDealDamageType(DamageType typeToDeal) const;
- Real getLargestWeaponRange() const;
- Weapon* getWeaponInWeaponSlot(WeaponSlotType wslot) const { return m_weaponSet.getWeaponInWeaponSlot(wslot); }
- // see if this current weapon set's weapons has shared reload times
- const Bool isReloadTimeShared() const { return m_weaponSet.isSharedReloadTime(); }
- Weapon* getCurrentWeapon(WeaponSlotType* wslot = NULL);
- const Weapon* getCurrentWeapon(WeaponSlotType* wslot = NULL) const;
- void setFiringConditionForCurrentWeapon() const;
- void adjustModelConditionForWeaponStatus(); ///< Check to see if I should change my model condition.
- void fireCurrentWeapon(Object *target);
- void fireCurrentWeapon(const Coord3D* pos);
- void preFireCurrentWeapon( const Object *victim );
- UnsignedInt getLastShotFiredFrame() const; ///< Get the frame a shot was last fired on
- ObjectID getLastVictimID() const; ///< Get the last victim we shot at
- Weapon* findWaypointFollowingCapableWeapon();
- Bool getAmmoPipShowingInfo(Int& numTotal, Int& numFull) const;
- /**
- Determines if the unit has any weapon that could conceivably
- harm the victim. this does not take range, ammo, etc. into
- account, but immutable weapon properties, such as "can you
- target airborne victims".
- */
- /*
- NOTE: getAbleToAttackSpecificObject NO LONGER internally calls isAbleToAttack(),
- since that isn't an incredibly fast call, and this is called repeatedly in some inner loops
- where we already know that isAbleToAttack() == true. so you should always
- call isAbleToAttack prior to calling this! (srj)
- */
- CanAttackResult getAbleToAttackSpecificObject( AbleToAttackType t, const Object* target, CommandSourceType commandSource ) const;
- //Used for base defenses and otherwise stationary units to see if you can attack a position potentially out of range.
- CanAttackResult getAbleToUseWeaponAgainstTarget( AbleToAttackType attackType, const Object *victim, const Coord3D *pos, CommandSourceType commandSource ) const;
- /**
- Selects the best weapon for the given target, and sets it as the current weapon.
- If there is no weapon that can damage the target, false is returned (and the current-weapon is unchanged).
- Note that this DOES take weapon attack range into account.
- */
- Bool chooseBestWeaponForTarget(const Object* target, WeaponChoiceCriteria criteria, CommandSourceType cmdSource);
- // set and/or clear a single modelcondition flag
- void setModelConditionState( ModelConditionFlagType a );
- void clearModelConditionState( ModelConditionFlagType a );
- void clearAndSetModelConditionState( ModelConditionFlagType clr, ModelConditionFlagType set );
- //Special model states are states that are turned on for a period of time, and turned off
- //automatically -- used for cheer, and scripted special moment animations. Setting a special
- //state will automatically clear any other special states that may be turned on so you can only
- //have one at a time.
- void setSpecialModelConditionState( ModelConditionFlagType set, UnsignedInt frames = 0 );
- void clearSpecialModelConditionStates();
- // set and/or clear multiple modelcondition flags
- void clearModelConditionFlags( const ModelConditionFlags& clr );
- void setModelConditionFlags( const ModelConditionFlags& set );
- void clearAndSetModelConditionFlags( const ModelConditionFlags& clr, const ModelConditionFlags& set );
- void setWeaponSetFlag(WeaponSetType wst);
- void clearWeaponSetFlag(WeaponSetType wst);
- inline Bool testWeaponSetFlag(WeaponSetType wst) const { return m_curWeaponSetFlags.test(wst); }
- inline const WeaponSetFlags& getWeaponSetFlags() const { return m_curWeaponSetFlags; }
- Bool setWeaponLock( WeaponSlotType weaponSlot, WeaponLockType lockType ){ return m_weaponSet.setWeaponLock( weaponSlot, lockType ); }
- void releaseWeaponLock(WeaponLockType lockType){ m_weaponSet.releaseWeaponLock(lockType); }
- Bool isCurWeaponLocked() const { return m_weaponSet.isCurWeaponLocked(); }
- /// return true if the template has the specified special power flag set
- // @todo: inline
- Bool hasSpecialPower( SpecialPowerType type ) const;
- void setWeaponBonusCondition(WeaponBonusConditionType wst) { m_weaponBonusCondition |= (1 << wst); }
- void clearWeaponBonusCondition(WeaponBonusConditionType wst) { m_weaponBonusCondition &= ~(1 << wst); }
- // note, the !=0 at the end is important, to convert this into a boolean type! (srj)
- Bool testWeaponBonusCondition(WeaponBonusConditionType wst) const { return (m_weaponBonusCondition & (1 << wst)) != 0; }
- inline WeaponBonusConditionFlags getWeaponBonusCondition() const { return m_weaponBonusCondition; }
- Bool getSingleLogicalBonePosition(const char* boneName, Coord3D* position, Matrix3D* transform) const;
- Bool getSingleLogicalBonePositionOnTurret(WhichTurretType whichTurret, const char* boneName, Coord3D* position, Matrix3D* transform) const;
- Int getMultiLogicalBonePosition(const char* boneNamePrefix, Int maxBones, Coord3D* positions, Matrix3D* transforms, Bool convertToWorld = TRUE ) const;
-
- // Entered & exited.
- Bool didEnter(const PolygonTrigger *pTrigger) const;
- Bool didExit(const PolygonTrigger *pTrigger) const;
- Bool isInside(const PolygonTrigger *pTrigger) const;
- // exiting of any kind
- ExitInterface *getObjectExitInterface() const; ///< get exit interface is present
- Bool hasExitInterface() const { return getObjectExitInterface() != 0; }
- ObjectShroudStatus getShroudedStatus(Int playerIndex) const;
- DisabledMaskType getDisabledFlags() const { return m_disabledMask; }
- Bool isDisabled() const { return m_disabledMask.any(); }
- Bool clearDisabled( DisabledType type );
- void setDisabled( DisabledType type );
- void setDisabledUntil( DisabledType type, UnsignedInt frame );
- Bool isDisabledByType( DisabledType type ) const { return TEST_DISABLEDMASK( m_disabledMask, type ); }
- void pauseAllSpecialPowers( const Bool disabling ) const;
-
- //Checks any timers and clears disabled statii that have expired.
- void checkDisabledStatus();
-
- //When an AIAttackState is over, it needs to clean up any weapons that might be in leech range mode
- //or else those weapons will have unlimited range!
- void clearLeechRangeModeForAllWeapons();
-
- Int getNumConsecutiveShotsFiredAtTarget( const Object *victim) const;
- void setHealthBoxOffset( const Coord3D& offset ) { m_healthBoxOffset = offset; } ///< for special amorphous like angry mob
- void defect( Team *newTeam, UnsignedInt detectionTime );
- void goInvulnerable( UnsignedInt time );
-
- // This is public, since there is no Thing level master setting of Turret stuff. It is all done in a sleepy hamlet
- // of a module called TurretAI.
- virtual void reactToTurretChange( WhichTurretType turret, Real oldRotation, Real oldPitch );
- // Convenience function for checking certain kindof bits
- Bool isStructure(void) const;
-
- // Convenience function for checking certain kindof bits
- Bool isFactionStructure(void) const;
- // Convenience function for checking certain kindof bits
- Bool isNonFactionStructure(void) const;
- Bool getReceivingDifficultyBonus() const { return m_isReceivingDifficultyBonus; }
- void setReceivingDifficultyBonus(Bool receive);
- inline UnsignedInt getSafeOcclusionFrame(void) { return m_safeOcclusionFrame; } //< this is an object specific frame at which it's safe to enable building occlusion.
- inline void setSafeOcclusionFrame(UnsignedInt frame) { m_safeOcclusionFrame = frame;}
- // All of our cheating for radars and power go here.
- // This is the function that we now call in becomingTeamMember to adjust our power.
- // If incoming is true, we're working on the incoming player, if its false, we're on the outgoing
- // player. These are friend_s for player.
- void friend_adjustPowerForPlayer( Bool incoming );
- Bool isHero() const;
- protected:
- void setOrRestoreTeam( Team* team, Bool restoring );
- void onDisabledEdge(Bool becomingDisabled);
- // All of our cheating for radars and power go here.
- // snapshot methods
- void crc( Xfer *xfer );
- void xfer( Xfer *xfer );
- void loadPostProcess();
- void handleShroud();
- void handleValueMap();
- void handleThreatMap();
- // NOTE NOTE NOTE -- this is a private method. Do Not Ever Make It Public.
- // If you think you need to make it public, you are wrong. Don't do it.
- // It will go away someday. Yeah, right. Just like GlobalData.
- Module* findModule(NameKeyType key) const;
- Bool didEnterOrExit() const;
- void setID( ObjectID id );
- virtual Object *asObjectMeth() { return this; }
- virtual const Object *asObjectMeth() const { return this; }
- virtual Real calculateHeightAboveTerrain(void) const; // Calculates the actual height above terrain. Doesn't use cache.
- void updateTriggerAreaFlags(void);
- void setTriggerAreaFlagsForChangeInPosition(void);
-
- /// Look and unlook are protected. They should be called from Object::reasonToLook. Like Capture, or death.
- void look();
- void unlook();
- void shroud();
- void unshroud();
- /// value and threat functions are protected, and should only be called from handleValueMap
- void addValue();
- void removeValue();
- void addThreat();
- void removeThreat();
- virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle);
- private:
- // yes, private. No, really. Private. Don't expose.
- enum ObjectPrivateStatusBits
- {
- EFFECTIVELY_DEAD = (1 << 0), ///< Object is effectively dead
- UNDETECTED_DEFECTOR = (1 << 1), ///< set to true when I defect from my team; set to false when I attack anything or when time runs out
- CAPTURED = (1 << 2), ///< set to true if I've been captured, otherwise, its false. (Note: Never becomes false once it's true)
- OFF_MAP = (1 << 3) ///< set to true if I am known to be OFF the current map.
- // NOTE: Object currently only uses a Byte for this, so if you add status bits, you may need to enlarge that field.
- };
- ObjectID m_id; ///< this object's unique ID
- ObjectID m_producerID; ///< object that produced us, if any
- ObjectID m_builderID; ///< object that is building or has built us (dozers or workers are builders)
- Drawable* m_drawable; ///< drawable (if any) for this object
- AsciiString m_name; ///< internal name
- Object * m_next;
- Object * m_prev;
- UnsignedInt m_status; ///< status bits (see ObjectStatusBits enum)
- GeometryInfo m_geometryInfo;
- AIGroup* m_group; ///< if non-NULL, we are part of this group of agents
- // These will last for my lifetime. I will reuse them and reset them. The truly dynamic ones are in PartitionManager
- SightingInfo *m_partitionLastLook; ///< Where and for whom I last looked, so I can undo its effects when I stop
- SightingInfo *m_partitionLastShroud; ///< Where and for whom I last shrouded, so I can undo its effects when I stop
- SightingInfo *m_partitionLastThreat; ///< Where and for whom I last delt with threat, so I can undo its effects when I stop
- SightingInfo *m_partitionLastValue; ///< Where and for whom I last delt with value, so I can undo its effects when I stop
- Real m_visionRange; ///< looking range
- Real m_shroudClearingRange; ///< looking range for shroud ONLY
- Real m_shroudRange; ///< like looking range, this is how far I shroud others' looks
- DisabledMaskType m_disabledMask;
- UnsignedInt m_disabledTillFrame[ DISABLED_COUNT ];
- UnsignedInt m_smcUntil;
- enum { NUM_SLEEP_HELPERS = 5 };
- ObjectRepulsorHelper* m_repulsorHelper;
- ObjectSMCHelper* m_smcHelper;
- ObjectWeaponStatusHelper* m_wsHelper;
- ObjectDefectionHelper* m_defectionHelper;
- FiringTracker* m_firingTracker; ///< Tracker is really a "helper" and is included NUM_SLEEP_HELPERS
- // modules
- BehaviorModule** m_behaviors; // BehaviorModule, not BehaviorModuleInterface
- // cache these, for convenience
- ContainModuleInterface* m_contain;
- BodyModuleInterface* m_body;
- AIUpdateInterface* m_ai; ///< ai interface (if any), cached for handy access. (duplicate of entry in the module array!)
- PhysicsBehavior* m_physics; ///< physics interface (if any), cached for handy access. (duplicate of entry in the module array!)
- PartitionData* m_partitionData; ///< our PartitionData
- RadarObject* m_radarData; ///< radar data
- ExperienceTracker* m_experienceTracker; ///< Manages experience, gaining levels, and value when killed
- Object* m_containedBy; /**< an object can only be contained by at most one
- other object, this is that object (if present) */
- ObjectID m_xferContainedByID; ///< xfer uses IDs to store pointers and looks them up after
- UnsignedInt m_containedByFrame; ///< frame we were contained by m_containedBy
- Real m_constructionPercent; ///< for objects being built ... this is the amount completed (0.0 to 100.0)
- Int64 m_objectUpgradesCompleted; ///< Bit field of upgrades locally completed.
- Team* m_team; ///< team that is current owner of this guy
- AsciiString m_originalTeamName; ///< team that was the original ("birth") team of this guy
- Color m_indicatorColor; ///< if nonzero, use this instead of controlling player's color
- Coord3D m_healthBoxOffset; ///< generally zero, except for special amorphous ones like angry mob
-
- /// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
- MAKE_DLINK(Object, TeamMemberList) ///< other Things that are members of the same team
- // Weapons & Damage -------------------------------------------------------------------------------------------------
- WeaponSet m_weaponSet;
- WeaponSetFlags m_curWeaponSetFlags;
- WeaponBonusConditionFlags m_weaponBonusCondition;
- Byte m_lastWeaponCondition[WEAPONSLOT_COUNT];
- SpecialPowerMaskType m_specialPowerBits; ///< bits determining what kind of special abilities this object has access to.
- //////////////////////////////////////< for the non-stacking healers like ambulance and propaganda
- ObjectID m_soleHealingBenefactorID; ///< who is the only other object that can give me this non-stacking heal benefit?
- UnsignedInt m_soleHealingBenefactorExpirationFrame; ///< on what frame can I accept healing (thus to switch) from a new benefactor
- ///////////////////////////////////
- // Entered & exited housekeeping.
- enum { MAX_TRIGGER_AREA_INFOS = 5 };
- TTriggerInfo m_triggerInfo[MAX_TRIGGER_AREA_INFOS];
- UnsignedInt m_enteredOrExitedFrame;
- ICoord3D m_iPos;
-
- PathfindLayerEnum m_layer; // Layer object is pathing on.
- PathfindLayerEnum m_destinationLayer; // Layer of current path goal.
- // User formations.
- FormationID m_formationID;
- Coord2D m_formationOffset;
- AsciiString m_commandSetStringOverride;///< To allow specific object to switch command sets
-
- UnsignedInt m_safeOcclusionFrame; ///<flag used by occlusion renderer so it knows when objects have exited their production building.
- // --------- BYTE-SIZED THINGS GO HERE
- Bool m_isSelectable;
- Bool m_modulesReady;
- #if defined(_DEBUG) || defined(_INTERNAL)
- Bool m_hasDiedAlready;
- #endif
- UnsignedByte m_scriptStatus; ///< status as set by scripting, corresponds to ORed ObjectScriptStatusBits
- UnsignedByte m_privateStatus; ///< status bits that are never directly accessible to outside world
- Byte m_numTriggerAreasActive;
- Bool m_singleUseCommandUsed;
- Bool m_isReceivingDifficultyBonus;
- }; // end class Object
- #ifdef DEBUG_LOGGING
- // describe an object as an AsciiString: e.g. "Object 102 (KillerBuggy) [GLARocketBuggy, owned by player 2 (GLAIntroPlayer)]"
- AsciiString DescribeObject(const Object *obj);
- #endif // DEBUG_LOGGING
- #if defined(_DEBUG) || defined(_INTERNAL)
- #define DEBUG_OBJECT_ID_EXISTS
- #else
- #undef DEBUG_OBJECT_ID_EXISTS
- #endif
- #ifdef DEBUG_OBJECT_ID_EXISTS
- extern ObjectID TheObjectIDToDebug;
- #endif
- #endif // _OBJECT_H_
|