/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SE_INCL_ENTITY_H #define SE_INCL_ENTITY_H #ifdef PRAGMA_ONCE #pragma once #endif #include #include #include #include #include #include #include #include #include #include #define DUMPVECTOR(v) \ strm.FPrintF_t(#v ": %g,%g,%g %08x,%08x,%08x\n", \ (v)(1), (v)(2), (v)(3), (ULONG&)(v)(1), (ULONG&)(v)(2), (ULONG&)(v)(3)) #define DUMPVECTOR2(strDes, v) \ strm.FPrintF_t( "%s: %g,%g,%g\n", strDes, (v)(1), (v)(2), (v)(3)) #define DUMPLONG(l) \ strm.FPrintF_t(#l ": %08x\n", l) #define DUMPPLACEMENT(plname, pl) \ strm.FPrintF_t("%s:\n", plname); \ DUMPVECTOR2( "Position", pl.pl_PositionVector); \ DUMPVECTOR2( "Orientation", pl.pl_OrientationAngle); // force infulence at a point in space class CForceStrength { public: FLOAT3D fs_vDirection; // direction of the force (must be normalized) FLOAT fs_fAcceleration; // acceleration of the force (m/s2) (along the direction) FLOAT fs_fVelocity; // max. velocity that force can give (m/s) (along the direction) }; #define DECL_DLL ENGINE_API #include #undef DECL_DLL /* * Flags determining whether some entity is active in some game type or difficulty level. */ // difficulty levels #define SPF_EASY (1L<<0) // active at easy difficulty #define SPF_NORMAL (1L<<1) // active at normal difficulty #define SPF_HARD (1L<<2) // active at hard difficulty #define SPF_EXTREME (1L<<3) // active at extreme difficulty #define SPF_TOURIST (1L<<4) // active at tourist difficulty #define SPF_MASK_DIFFICULTY 0x0000FFFFL // mask for difficulty level flags // game types #define SPF_SINGLEPLAYER (1L<<16) // active in single player mode #define SPF_DEATHMATCH (1L<<17) // active in deathmatch mode #define SPF_COOPERATIVE (1L<<18) // active in cooperative mode #define SPF_FLYOVER (1L<<19) // active in flyover (camera) mode #define SPF_MASK_GAMEMODE 0xFFFF0000L // mask for game type flags /* * Various other entity flags */ #define ENF_SELECTED (1L<< 0) // set if selected #define ENF_ZONING (1L<< 1) // brush that defines spatial classification #define ENF_DELETED (1L<< 2) // set if the entity does not exist anymore #define ENF_ALIVE (1L<< 3) // set if the entity is currently a living being #define ENF_INRENDERING (1L<< 4) // set if the entity is currently active in rendering #define ENF_VALIDSHADINGINFO (1L<< 5) // set if shading info is valid #define ENF_SEETHROUGH (1L<< 6) // set if cast ray can see through #define ENF_FOUNDINGRIDSEARCH (1L<< 7) // set if the entity is already found in grid search #define ENF_CLUSTERSHADOWS (1L<< 8) // model that has cluster shadows #define ENF_BACKGROUND (1L<< 9) // brush or model that is used for background rendering #define ENF_ANCHORED (1L<<10) // set if cannot be moved in editor without special allowance #define ENF_HASPARTICLES (1L<<11) // entity renders particles #define ENF_INVISIBLE (1L<<12) // entity is invisible (for AI purposes) #define ENF_DYNAMICSHADOWS (1L<<13) // moving brush that causes automatic shadow recalculation #define ENF_NOTIFYLEVELCHANGE (1L<<14) // entity is notified when level is changed #define ENF_CROSSESLEVELS (1L<<15) // entity must be carried when level is changed #define ENF_PREDICTABLE (1L<<16) // this entity can be predicted #define ENF_PREDICTOR (1L<<17) // this entity is predictor for another entity #define ENF_PREDICTED (1L<<18) // this entity has its predictor #define ENF_WILLBEPREDICTED (1L<<19) // this entity will be predicted #define ENF_TEMPPREDICTOR (1L<<20) // predictor that was spawned during prediction (doesn't have a predictor) #define ENF_HIDDEN (1L<<21) // set if the entity is hidden (for editing) #define ENF_NOSHADINGINFO (1L<<22) // the entity doesn't need FindShadingInfo(), it will set its own shading // selections of entities typedef CSelection CEntitySelection; /* * General structure of an entity instance. */ class ENGINE_API CEntity { public: // type of function pointer used as AI event handler typedef BOOL (CEntity::*pEventHandler)(const CEntityEvent &ee); enum RenderType { RT_ILLEGAL = 1, RT_NONE = 2, // not rendered ever -- used internally RT_MODEL = 3, // drawn as model RT_BRUSH = 4, // rendered as brush RT_EDITORMODEL = 5, // rendered as model, but only in editor RT_VOID = 7, // not rendered ever RT_FIELDBRUSH = 8, // brush used for field effects (like triggers, force fields etc.) RT_SKAMODEL = 9, // render as ska model RT_SKAEDITORMODEL = 10, // render as ska model, but only in editor RT_TERRAIN = 11, // render as terrain }; /* Entity physics flags. */ #define EPF_ORIENTEDBYGRAVITY (1UL<<0) // set if gravity influences its orientation #define EPF_TRANSLATEDBYGRAVITY (1UL<<1) // set if gravity can move it #define EPF_PUSHABLE (1UL<<2) // set if can be pushed by other objects #define EPF_STICKYFEET (1UL<<3) // entity always falls to nearest surface #define EPF_RT_SYNCHRONIZED (1UL<<4) // set if rotation and translation are synchronized #define EPF_ABSOLUTETRANSLATE (1UL<<5) // set if entity is translated absolute and not relative to its position #define EPF_NOACCELERATION (1UL<<6) // set if entity can change its speed immediately #define EPF_HASLUNGS (1UL<<7) // set if entity has lungs #define EPF_HASGILLS (1UL<<8) // set if entity has gills #define EPF_MOVABLE (1UL<<9) // set if derived from CMovableEntity #define EPF_NOIMPACT (1UL<<10)// entities are not damaged when hitting this one #define EPF_NOIMPACTTHISTICK (1UL<<11)// this one is not damaged by impact this tick #define EPF_CANFADESPINNING (1UL<<12)// desired rotation can be reduced by contents (like water) #define EPF_ONSTEEPSLOPE (1UL<<13)// while sliding down a steep slope (valid only if entity has reference) #define EPF_ORIENTINGTOGRAVITY (1UL<<14)// while beeing re-oriented by gravity #define EPF_FLOATING (1UL<<15)// while bouyancy causes floating in fluid #define EPF_FORCEADDED (1UL<<16)// set if force-added to movers // what to do when colliding #define EPF_ONBLOCK_MASK (7UL<<29) #define EPF_ONBLOCK_STOP (0UL<<29) // stop moving #define EPF_ONBLOCK_SLIDE (1UL<<29) // slide along #define EPF_ONBLOCK_CLIMBORSLIDE (2UL<<29) // clim up a stair or slide along #define EPF_ONBLOCK_BOUNCE (3UL<<29) // bounce off #define EPF_ONBLOCK_PUSH (4UL<<29) // push the obstacle #define EPF_ONBLOCK_STOPEXACT (5UL<<29) // stop moving, but exactly at collision position // entity collision flags are divided in 3 groups #define ECB_COUNT 10 // max number of flags per group #define ECF_MASK ((1< &cen, BOOL bCollidingOnly); // find first entity touching a field (this entity must be a field brush) CEntity *TouchingEntity(BOOL (*ConsiderEntity)(CEntity *), CEntity *penHintMaybeInside); public: // DLL class interface /* Initialize for being virtual entity that is not rendered. */ void InitAsVoid(void); /* Initialize for beeing a model object. */ void InitAsModel(void); void InitAsSkaModel(void); /* Initialize for beeing a terrain object. */ void InitAsTerrain(void); /* Initialize for beeing an editor model object. */ void InitAsEditorModel(void); void InitAsSkaEditorModel(void); /* Initialize for beeing a brush object. */ void InitAsBrush(void); /* Initialize for beeing a field brush object. */ void InitAsFieldBrush(void); /* Switch to Model/Editor model */ void SwitchToModel(void); void SwitchToEditorModel(void); /* Set all properties to default values. - overridden by ecc */ virtual void SetDefaultProperties(void); /* Get a filename for a component of given type and id. */ const CTFileName &FileNameForComponent(SLONG slType, SLONG slID); // Get data for a texture component CTextureData *GetTextureDataForComponent(SLONG slID); // Get data for a model component CModelData *GetModelDataForComponent(SLONG slID); // model manipulation functions -- only for RT_MODEL/RT_EDITORMODEL /* Set the model data for model entity. */ void SetModel(const CTFileName &fnmModel); void SetModel(SLONG idModelComponent); BOOL SetSkaModel(const CTString &fnmModel); void SetSkaModel_t(const CTString &fnmModel); void SetSkaColisionInfo(); /* Get the model data for model entity. */ const CTFileName &GetModel(void); /* Start new animation for model entity. */ void StartModelAnim(INDEX iNewModelAnim, ULONG ulFlags); /* Play a given sound object. */ void PlaySound(CSoundObject &so, SLONG idSoundComponent, SLONG slPlayType); void PlaySound(CSoundObject &so, const CTFileName &fnmSound, SLONG slPlayType); double GetSoundLength(SLONG idSoundComponent); // set/get model main blend color COLOR GetModelColor(void) const; void SetModelColor( const COLOR colBlend); /* Set the main texture data for model entity. */ void SetModelMainTexture(SLONG idTextureComponent); void SetModelMainTexture(const CTFileName &fnmTexture); /* Get the main texture data for model entity. */ const CTFileName &GetModelMainTexture(void); /* Start new animation for main texture of model entity. */ void StartModelMainTextureAnim(INDEX iNewTextureAnim); /* Set the reflection texture data for model entity. */ void SetModelReflectionTexture(SLONG idTextureComponent); /* Set the specular texture data for model entity. */ void SetModelSpecularTexture(SLONG idTextureComponent); /* Add attachment to model */ void AddAttachment(INDEX iAttachment, ULONG ulIDModel, ULONG ulIDTexture); void AddAttachment(INDEX iAttachment, CTFileName fnModel, CTFileName fnTexture); /* Remove attachment from model */ void RemoveAttachment(INDEX iAttachment); /* Set the reflection texture data for model attachment entity. */ void SetModelAttachmentReflectionTexture(INDEX iAttachment, SLONG idTextureComponent); /* Set the specular texture data for model attachment entity. */ void SetModelAttachmentSpecularTexture(INDEX iAttachment, SLONG idTextureComponent); // Get all vertices of model entity in absolute space void GetModelVerticesAbsolute( CStaticStackArray &avVertices, FLOAT fNormalOffset, FLOAT fMipFactor); // Returns true if bone exists and sets two given vectors as start and end point of specified bone in abs space BOOL GetBoneAbsPosition(INDEX iBoneID, FLOAT3D &vStartPoint, FLOAT3D &vEndPoint); // Returns true if bone exists and sets two given vectors as start and end point of specified bone in relative space BOOL GetBoneRelPosition(INDEX iBoneID, FLOAT3D &vStartPoint, FLOAT3D &vEndPoint); // Callback function for aditional bone adjustment virtual void AdjustBones(); // Callback function for aditional shader params adjustment virtual void AdjustShaderParams(INDEX iSurfaceID,CShader *pShader,ShaderParams &spParams); // precache given component void PrecacheModel(SLONG slID); void PrecacheTexture(SLONG slID); void PrecacheSound(SLONG slID); void PrecacheClass(SLONG slID, INDEX iUser = -1); /* Create a new entity of given class in this world. */ CEntity *CreateEntity(const CPlacement3D &plPlacement, SLONG idModelComponent); /* Apply some damage directly to one entity. */ void InflictDirectDamage(CEntity *penToDamage, CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection); /* Apply some damage to all entities in some range (this tests for obstacles). */ void InflictRangeDamage(CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOAT3D &vCenter, FLOAT fHotSpotRange, FLOAT fFallOffRange); /* Apply some damage to all entities in a box (this doesn't test for obstacles). */ void InflictBoxDamage(CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOATaabbox3D &box); // notify engine that gravity defined by this entity has changed void NotifyGravityChanged(void); // notify engine that collision of this entity was changed void NotifyCollisionChanged(void); // get a pseudo-random number (safe for network gaming) ULONG IRnd(void); // [0x0000 , 0xFFFF] FLOAT FRnd(void); // [0.0f , 1.0f] // DLL class overridables /* Called after creating and setting its properties. */ virtual void OnInitialize(const CEntityEvent &eeInput); /* Called before releasing entity. */ virtual void OnEnd(void); // these functions are dummy in CEntity, but are implemented in CRationalEntity /* Jump to a new state. */ void Jump(SLONG slThisState, SLONG slTargetState, BOOL bOverride, const CEntityEvent &eeInput) {}; /* Call a subautomaton. */ void Call(SLONG slThisState, SLONG slTargetState, BOOL bOverride, const CEntityEvent &eeInput) {}; /* Return from a subautomaton. */ void Return(SLONG slThisState, const CEntityEvent &eeReturn) {}; // print stack to debug output virtual const char *PrintStackDebug(void); void SetTimerAt(TIME timeAbsolute) {}; void SetTimerAfter(TIME timeDelta) {}; void UnsetTimer(void) {}; // return opacity of the entity (1 is default) virtual FLOAT GetOpacity(void) { return 1.0f; }; // returns ammount of memory used by entity virtual SLONG GetUsedMemory(void); public: // construction/destruction /* Default constructor. */ CEntity(void); /* Destructor. */ virtual ~CEntity(void); /* Clear the object. */ void Clear(void) {}; // entities can be selected IMPLEMENT_SELECTING(en_ulFlags); // access functions /* Prepare entity (call after setting properties). */ void Initialize(const CEntityEvent &eeInput = _eeVoid); /* Clean-up entity. */ void End(void); /* Destroy this entity (entity must not be targetable). */ void Destroy(void); /* Get state transition for given state and event code. */ virtual CEntity::pEventHandler HandlerForStateAndEvent(SLONG slState, SLONG slEvent); /* Handle an event, return false if the event is not handled. */ virtual BOOL HandleEvent(const CEntityEvent &ee); // get/set functions for use in WEd and/or entity class DLLs void SetPlacement(const CPlacement3D &plNew); // use this only in WEd void FallDownToFloor( void); inline const CPlacement3D &GetPlacement(void) const { return en_plPlacement; }; inline const FLOATmatrix3D &GetRotationMatrix(void) const { return en_mRotation; }; // this one is used in rendering - gets lerped placement between ticks virtual CPlacement3D GetLerpedPlacement(void) const; /* Find first sector that entity is in */ CBrushSector *GetFirstSector(void); /* Find first sector that entity is in (for UI purpuses) */ CBrushSector *GetFirstSectorWithName(void); // teleport this entity to a new location -- takes care of telefrag damage void Teleport(const CPlacement3D &plNew, BOOL bTelefrag=TRUE); void SetFlags(ULONG ulFlags); inline ULONG GetFlags(void) const { return en_ulFlags; }; inline void SetSpawnFlags(ULONG ulFlags) { en_ulSpawnFlags = ulFlags; } inline ULONG GetSpawnFlags(void) const { return en_ulSpawnFlags; }; void SetPhysicsFlags(ULONG ulFlags); inline ULONG GetPhysicsFlags(void) const { return en_ulPhysicsFlags; }; void SetCollisionFlags(ULONG ulFlags); inline ULONG GetCollisionFlags(void) const { return en_ulCollisionFlags; }; inline BOOL IsPredictor(void) const { return en_ulFlags&ENF_PREDICTOR; }; inline BOOL IsPredicted(void) const { return en_ulFlags&ENF_PREDICTED; }; inline BOOL IsPredictable(void) const { return en_ulFlags&ENF_PREDICTABLE; }; CEntity *GetPredictor(void); CEntity *GetPredicted(void); // become predictable/unpredictable void SetPredictable(BOOL bON); // check if this instance is head of prediction chain BOOL IsPredictionHead(void); // get the prediction original (predicted), or self if not predicting CEntity *GetPredictionTail(void); // check if active for prediction now BOOL IsAllowedForPrediction(void) const; // check an event for prediction, returns true if already predicted BOOL CheckEventPrediction(ULONG ulTypeID, ULONG ulEventID); inline enum RenderType GetRenderType(void) { return en_RenderType; }; inline CEntityClass *GetClass(void) { return en_pecClass; }; inline CWorld *GetWorld(void) { return en_pwoWorld; }; inline CBrush3D *GetBrush(void) { return en_pbrBrush; }; inline CModelObject *GetModelObject(void) { return en_pmoModelObject; }; inline CModelInstance *GetModelInstance(void) { return en_pmiModelInstance; }; inline CTerrain *GetTerrain(void) { return en_ptrTerrain; }; inline CEntity *GetParent(void) { return en_penParent; }; void SetParent(CEntity *penNewParent); // find first child of given class CEntity *GetChildOfClass(const char *strClass); /* Test if the entity is an empty brush. */ BOOL IsEmptyBrush(void) const; /* Return max Game Players */ static INDEX GetMaxPlayers(void); /* Return Player Entity */ static CEntity *GetPlayerEntity(INDEX iPlayer); /* Get bounding box of this entity - for AI purposes only. */ void GetBoundingBox(FLOATaabbox3D &box); /* Get size of this entity - for UI purposes only. */ void GetSize(FLOATaabbox3D &box); /* Get last positions structure for particles. */ CLastPositions *GetLastPositions(INDEX ctPositions); /* Get nearest position of nearest brush polygon to this entity if available. */ CBrushPolygon *GetNearestPolygon(FLOAT3D &vPoint, FLOATplane3D &plPlane, FLOAT &fDistanceToEdge); /* Get absolute position of point on entity given relative to its size. */ void GetEntityPointRatio(const FLOAT3D &vRatio, FLOAT3D &vAbsPoint, BOOL bLerped=FALSE); /* Get absolute position of point on entity given in meters. */ void GetEntityPointFixed(const FLOAT3D &vFixed, FLOAT3D &vAbsPoint); /* Get sector that given point is in - point must be inside this entity. */ CBrushSector *GetSectorFromPoint(const FLOAT3D &vPointAbs); // map world polygon to/from indices CBrushPolygon *GetWorldPolygonPointer(INDEX ibpo); INDEX GetWorldPolygonIndex(CBrushPolygon *pbpo); // virtual functions that are overridden to implement class specific behavior /* Get name of this entity. */ virtual const CTString &GetName(void) const; virtual const CTString &GetDescription(void) const; // name + some more verbose data /* Get first target of this entity. */ virtual CEntity *GetTarget(void) const; /* Check if entity can be used as a target. */ virtual BOOL IsTargetable(void) const; /* Check if entity is marker */ virtual BOOL IsMarker(void) const; /* Check if entity is important */ virtual BOOL IsImportant(void) const; /* Check if entity is moved on a route set up by its targets. */ virtual BOOL MovesByTargetedRoute(CTString &strTargetProperty) const; /* Check if entity can drop marker for making linked route. */ virtual BOOL DropsMarker(CTFileName &fnmMarkerClass, CTString &strTargetProperty) const; /* Get light source information - return NULL if not a light source. */ virtual CLightSource *GetLightSource(void); /* Is target valid. */ virtual BOOL IsTargetValid(SLONG slPropertyOffset, CEntity *penTarget); /* Get force type name, return empty string if not used. */ virtual const CTString &GetForceName(INDEX iForce); /* Get forces in given point. */ virtual void GetForce(INDEX iForce, const FLOAT3D &vPoint, CForceStrength &fsGravity, CForceStrength &fsField); /* Get entity that controls the force, used for change notification checking. */ virtual CEntity *GetForceController(INDEX iForce); /* Get fog type name, return empty string if not used. */ virtual const CTString &GetFogName(INDEX iFog); /* Get fog, return FALSE for none. */ virtual BOOL GetFog(INDEX iFog, class CFogParameters &fpFog); /* Get haze type name, return empty string if not used. */ virtual const CTString &GetHazeName(INDEX iHaze); /* Get haze, return FALSE for none. */ virtual BOOL GetHaze(INDEX iHaze, class CHazeParameters &hpHaze, FLOAT3D &vViewDir); /* Get mirror type name, return empty string if not used. */ virtual const CTString &GetMirrorName(INDEX iMirror); /* Get mirror, return FALSE for none. */ virtual BOOL GetMirror(INDEX iMirror, class CMirrorParameters &mpMirror); /* Get gradient type name, return empty string if not used. */ virtual const CTString &GetGradientName(INDEX iGradient); /* Get gradient, return FALSE for none. */ virtual BOOL GetGradient(INDEX iGradient, class CGradientParameters &gpGradient); /* Get classification box stretching vector. */ virtual FLOAT3D GetClassificationBoxStretch(void); /* Get anim data for given animation property - return NULL for none. */ virtual CAnimData *GetAnimData(SLONG slPropertyOffset); /* Adjust model shading parameters if needed - return TRUE if needs model shadows. */ virtual BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient); /* Adjust model mip factor if needed. */ virtual void AdjustMipFactor(FLOAT &fMipFactor); // get a different model object for rendering - so entity can change its appearance dynamically // NOTE: base model is always used for other things (physics, etc). virtual CModelObject *GetModelForRendering(void); virtual CModelInstance *GetModelInstanceForRendering(void); /* Get field information - return NULL if not a field. */ virtual CFieldSettings *GetFieldSettings(void); /* Render particles made by this entity. */ virtual void RenderParticles(void); /* Get current collision box index for this entity. */ virtual INDEX GetCollisionBoxIndex(void); /* Get current collision box - override for custom collision boxes. */ virtual void GetCollisionBoxParameters(INDEX iBox, FLOATaabbox3D &box, INDEX &iEquality); /* Render game view */ virtual void RenderGameView(CDrawPort *pdp, void *pvUserData); // apply mirror and stretch to the entity if supported virtual void MirrorAndStretch(FLOAT fStretch, BOOL bMirrorX); // get offset for depth-sorting of alpha models (in meters, positive is nearer) virtual FLOAT GetDepthSortOffset(void); // get visibility tweaking bits virtual ULONG GetVisTweaks(void); /* Get max tessellation level. */ virtual FLOAT GetMaxTessellationLevel(void); // get/set pointer to your predictor/predicted (autogenerated by ECC feature) virtual CEntity *GetPredictionPair(void); virtual void SetPredictionPair(CEntity *penPair); // add this entity to prediction void AddToPrediction(void); // called by other entities to set time prediction parameter virtual void SetPredictionTime(TIME tmAdvance); // give time interval in advance to set // called by engine to get the upper time limit virtual TIME GetPredictionTime(void); // return moment in time up to which to predict this entity // get maximum allowed range for predicting this entity virtual FLOAT GetPredictionRange(void); // add to prediction entities that this entity depends on virtual void AddDependentsToPrediction(void); // copy for prediction virtual void CopyForPrediction(CEntity &enOrg); /* Send an event to this entity. */ void SendEvent(const CEntityEvent &ee); /* Send an event to all entities in a box (box must be around this entity). */ void SendEventInRange(const CEntityEvent &ee, const FLOATaabbox3D &boxRange); /* apply some damage to the entity (see event EDamage for more info) */ virtual void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection); /* Receive item through event - for AI purposes only */ virtual BOOL ReceiveItem(const CEntityEvent &ee); /* Get entity info - for AI purposes only */ virtual void *GetEntityInfo(void); /* Fill in entity statistics - for AI purposes only */ virtual BOOL FillEntityStatistics(struct EntityStats *pes); /* Model change notify */ void ModelChangeNotify(void); /* Terrain change notify */ void TerrainChangeNotify(void); }; // check if entity is of given class BOOL ENGINE_API IsOfClass(CEntity *pen, const char *pstrClassName); BOOL ENGINE_API IsOfSameClass(CEntity *pen1, CEntity *pen2); // check if entity is of given class or derived from BOOL ENGINE_API IsDerivedFromClass(CEntity *pen, const char *pstrClassName); // all standard smart pointer functions are here as inlines inline CEntityPointer::CEntityPointer(void) : ep_pen(NULL) {}; inline CEntityPointer::~CEntityPointer(void) { ep_pen->RemReference(); }; inline CEntityPointer::CEntityPointer(const CEntityPointer &penOther) : ep_pen(penOther.ep_pen) { ep_pen->AddReference(); }; inline CEntityPointer::CEntityPointer(CEntity *pen) : ep_pen(pen) { ep_pen->AddReference(); }; inline const CEntityPointer &CEntityPointer::operator=(CEntity *pen) { pen->AddReference(); // must first add, then remove! ep_pen->RemReference(); ep_pen = pen; return *this; } inline const CEntityPointer &CEntityPointer::operator=(const CEntityPointer &penOther) { penOther.ep_pen->AddReference(); // must first add, then remove! ep_pen->RemReference(); ep_pen = penOther.ep_pen; return *this; } inline CEntity* CEntityPointer::operator->(void) const { return ep_pen; } inline CEntity* CEntityPointer::get(void) const { return ep_pen; } inline CEntityPointer::operator CEntity*(void) const { return ep_pen; } inline CEntity& CEntityPointer::operator*(void) const { return *ep_pen; } ///////////////////////////////////////////////////////////////////// // Reference counting functions inline void CEntity::AddReference(void) { ASSERT(this!=NULL); ASSERT(en_ctReferences>=0); en_ctReferences++; }; inline void CEntity::RemReference(void) { ASSERT(this!=NULL); ASSERT(en_ctReferences>0); en_ctReferences--; if(en_ctReferences==0) { delete this; } }; /* * Entity that is alive (has health). */ class ENGINE_API CLiveEntity : public CEntity { public: FLOAT en_fHealth; // health of the entity /* Copy entity from another entity of same class. */ virtual void Copy(CEntity &enOther, ULONG ulFlags); /* Read from stream. */ virtual void Read_t( CTStream *istr); // throw char * /* Write to stream. */ virtual void Write_t( CTStream *ostr); // throw char * public: /* Set health of the entity. (Use only for initialization!) */ void SetHealth(FLOAT fHealth) { en_fHealth = fHealth; }; public: /* Constructor. */ CLiveEntity(void); /* Get health of the entity. */ FLOAT GetHealth(void) const { return en_fHealth; }; // apply some damage to the entity (see event EDamage for more info) virtual void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType, FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection); // returns bytes of memory used by this object inline SLONG GetUsedMemory(void) { return( sizeof(CLiveEntity) - sizeof(CEntity) + CEntity::GetUsedMemory()); }; }; // flag for entities that are not waiting for thinking #define THINKTIME_NEVER (-1.f) /* * Entity that can percept things and make decisions (one that has its own AI). */ class ENGINE_API CRationalEntity : public CLiveEntity { public: CListNode en_lnInTimers; // node in list of waiting timers - sorted by wait time public: TIME en_timeTimer; // moment in time this entity waits for timer CStaticStackArray en_stslStateStack; // stack of states for entity AI /* Calculate physics for moving. */ virtual void ClearMovingTemp(void); virtual void PreMoving(void); virtual void DoMoving(void); virtual void PostMoving(void); // create a checksum value for sync-check virtual void ChecksumForSync(ULONG &ulCRC, INDEX iExtensiveSyncCheck); // dump sync data to text file virtual void DumpSync_t(CTStream &strm, INDEX iExtensiveSyncCheck); // throw char * /* Copy entity from another entity of same class. */ virtual void Copy(CEntity &enOther, ULONG ulFlags); /* Read from stream. */ virtual void Read_t( CTStream *istr); // throw char * /* Write to stream. */ virtual void Write_t( CTStream *ostr); // throw char * /* Unwind stack to a given state. */ void UnwindStack(SLONG slThisState); public: /* Jump to a new state. */ void Jump(SLONG slThisState, SLONG slTargetState, BOOL bOverride, const CEntityEvent &eeInput); /* Call a subautomaton. */ void Call(SLONG slThisState, SLONG slTargetState, BOOL bOverride, const CEntityEvent &eeInput); /* Return from a subautomaton. */ void Return(SLONG slThisState, const CEntityEvent &eeReturn); // print stack to debug output const char *PrintStackDebug(void); /* Set next timer event to occur at given moment time. */ void SetTimerAt(TIME timeAbsolute); /* Set next timer event to occur after given time has elapsed. */ void SetTimerAfter(TIME timeDelta); /* Cancel eventual pending timer. */ void UnsetTimer(void); /* Called after creating and setting its properties. */ virtual void OnInitialize(const CEntityEvent &eeInput); /* Called before releasing entity. */ virtual void OnEnd(void); public: /* Constructor. */ CRationalEntity(void); /* Handle an event - return false if event was not handled. */ virtual BOOL HandleEvent(const CEntityEvent &ee); // returns bytes of memory used by this object inline SLONG GetUsedMemory(void) { SLONG slUsedMemory = sizeof(CRationalEntity) - sizeof(CLiveEntity) + CLiveEntity::GetUsedMemory(); slUsedMemory += en_stslStateStack.sa_Count * sizeof(SLONG); return slUsedMemory; }; }; ENGINE_API void EntityAdjustBonesCallback(void *pData); ENGINE_API void EntityAdjustShaderParamsCallback(void *pData,INDEX iSurfaceID,CShader *pShader,ShaderParams &spParams); extern "C" ENGINE_API class CDLLEntityClass CEntity_DLLClass; extern "C" ENGINE_API class CDLLEntityClass CLiveEntity_DLLClass; extern "C" ENGINE_API class CDLLEntityClass CRationalEntity_DLLClass; #endif /* include-once check. */