mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-23 02:40:26 +01:00
5badefaf90
Also changed all "if (this==NULL) return;"s. Fixes some -Wtautological-undefined-compare warnings. Quoting Clang: "'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false"
825 lines
36 KiB
C++
825 lines
36 KiB
C++
/* 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 <Engine/Base/Lists.h>
|
|
#include <Engine/Base/Relations.h>
|
|
#include <Engine/Templates/StaticStackArray.h>
|
|
#include <Engine/Templates/Selection.h>
|
|
#include <Engine/Math/Matrix.h>
|
|
#include <Engine/Math/AABBox.h>
|
|
#include <Engine/Math/Placement.h>
|
|
#include <Engine/Entities/EntityEvent.h>
|
|
#include <Engine/Entities/EntityPointer.h>
|
|
#include <Engine/Ska/ModelInstance.h>
|
|
|
|
|
|
#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 <Engine/Classes/BaseEvents.h>
|
|
#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<CEntity, ENF_SELECTED> 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<<ECB_COUNT)-1) // mask for one group
|
|
// what an entity is
|
|
#define ECB_IS 0
|
|
#define ECF_ISMASK (ECF_MASK<<ECB_IS)
|
|
// which other entities to test with
|
|
#define ECB_TEST 10
|
|
#define ECF_TESTMASK (ECF_MASK<<ECB_TEST)
|
|
// which tested entities to pass through
|
|
#define ECB_PASS 20
|
|
#define ECF_PASSMASK (ECF_MASK<<ECB_PASS)
|
|
|
|
// optimizations to completely ignore some types of entities
|
|
#define ECF_IGNOREBRUSHES (1UL<<30)
|
|
#define ECF_IGNOREMODELS (1UL<<31)
|
|
|
|
public:
|
|
enum RenderType en_RenderType; // how is it rendered
|
|
ULONG en_ulPhysicsFlags; // ways of interacting with environment
|
|
ULONG en_ulCollisionFlags; // which entities to collide with
|
|
|
|
ULONG en_ulFlags; // various flags
|
|
ULONG en_ulSpawnFlags; // in what game types is this entity active
|
|
INDEX en_ctReferences; // reference counter for delayed destruction
|
|
ULONG en_ulID; // unique entity identifier
|
|
|
|
CPlacement3D en_plPlacement; // placement in world space
|
|
FLOATmatrix3D en_mRotation; // precalc. matrix for object rotation
|
|
CEntityClass *en_pecClass; // class used to construct this entity
|
|
union { // rendering object
|
|
CBrush3D *en_pbrBrush; // brush -- if brush entity
|
|
CModelObject *en_pmoModelObject; // model -- if model entity
|
|
CModelInstance *en_pmiModelInstance; // ska model -- if ska model entity
|
|
CTerrain *en_ptrTerrain; // terrain -- if terrain entity
|
|
};
|
|
CShadingInfo *en_psiShadingInfo; // shading info for model entities
|
|
CCollisionInfo *en_pciCollisionInfo; // collision info for movable colliding entities
|
|
FLOAT en_fSpatialClassificationRadius; // radius for spatial classification
|
|
FLOATaabbox3D en_boxSpatialClassification; // box in object space for spatial classification
|
|
CLastPositions *en_plpLastPositions; // last positions of entity
|
|
|
|
class CWorld *en_pwoWorld; // the world this entity belongs to
|
|
|
|
public: // imagine that this is private
|
|
CRelationDst en_rdSectors; // relation to sectors this entity is in
|
|
public:
|
|
|
|
CEntity *en_penParent; // parent entity
|
|
public: // these must be public for iteration
|
|
CListNode en_lnInParent; // node in the parent entity
|
|
CListHead en_lhChildren; // list of child entities
|
|
public:
|
|
CPlacement3D en_plRelativeToParent; // placement relative to parent placement
|
|
|
|
public:
|
|
// reference counting functions
|
|
inline void AddReference(void);
|
|
inline void RemReference(void);
|
|
|
|
/* Get pointer to entity property from its packed identifier. */
|
|
class CEntityProperty *PropertyForTypeAndID(ULONG ulType, ULONG ulID);
|
|
/* Helpers for writing/reading entity pointers. */
|
|
void ReadEntityPointer_t(CTStream *istr, CEntityPointer &pen);
|
|
void WriteEntityPointer_t(CTStream *ostr, CEntityPointer pen);
|
|
/* Get pointer to entity component from its packed identifier. */
|
|
class CEntityComponent *ComponentForTypeAndID(ULONG ulType, ULONG ulID);
|
|
/* Get pointer to entity property from its name. */
|
|
class CEntityProperty *PropertyForName(const CTString &strPropertyName);
|
|
/* Copy one entity property from property of another entity. */
|
|
void CopyOneProperty( CEntityProperty &epPropertySrc, CEntityProperty &epPropertyDest,
|
|
CEntity &enOther, ULONG ulFlags);
|
|
|
|
/* Read all properties from a stream. */
|
|
void ReadProperties_t(CTStream &istrm); // throw char *
|
|
/* Write all properties to a stream. */
|
|
void WriteProperties_t(CTStream &ostrm); // throw char *
|
|
/* Copy entity properties from another entity of same class. */
|
|
void CopyEntityProperties(CEntity &enOther, ULONG ulFlags);
|
|
|
|
/* Internal versions for entity reinitialization (do not discard shadows etc.). */
|
|
void Initialize_internal(const CEntityEvent &eeInput);
|
|
void End_internal(void);
|
|
/* Reinitialize the entity. */
|
|
void Reinitialize(void);
|
|
|
|
// internal repositioning function
|
|
virtual void SetPlacement_internal(const CPlacement3D &plNew, const FLOATmatrix3D &mRotation,
|
|
BOOL bNear);
|
|
// Uncache shadows of each polygon in entity that has given gradient index
|
|
void UncacheShadowsForGradient(INDEX iGradient);
|
|
|
|
/* Find and remember shading info for this entity if invalid. */
|
|
void FindShadingInfo(void);
|
|
/* Find and remember collision info for this entity. */
|
|
void FindCollisionInfo(void);
|
|
// discard collision info for this entity
|
|
void DiscardCollisionInfo(void);
|
|
// copy collision info from some other entity
|
|
void CopyCollisionInfo(CEntity &enOrg);
|
|
/* Update range used for spatial clasification. */
|
|
void UpdateSpatialRange(void);
|
|
/* Find and remember all sectors that this entity is in. */
|
|
void FindSectorsAroundEntity(void);
|
|
void FindSectorsAroundEntityNear(void);
|
|
|
|
// add entity to collision grid
|
|
void AddToCollisionGrid(void);
|
|
|
|
/* Copy entity from another entity of same class. (NOTE: this doesn't copy placement!) */
|
|
#define COPY_REMAP (1UL<<0) // remap pointers
|
|
#define COPY_REINIT (1UL<<1) // reinit entity
|
|
// make predictor (complete raw copy with all states/variables and
|
|
// making predictor/predicted links)
|
|
#define COPY_PREDICTOR (1UL<<2)
|
|
virtual void Copy(CEntity &enOther, ULONG ulFlags);
|
|
virtual CEntity &operator=(CEntity &enOther) {ASSERT(FALSE); return *this;};
|
|
// find a pointer to another entity while copying
|
|
static CEntity *FindRemappedEntityPointer(CEntity *penOriginal);
|
|
/* Read from stream. */
|
|
virtual void Read_t( CTStream *istr); // throw char *
|
|
/* Write to stream. */
|
|
virtual void Write_t( CTStream *ostr); // throw char *
|
|
/* Precache components that might be needed. */
|
|
virtual void Precache(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 *
|
|
|
|
/* Handle all sent events. */
|
|
static void HandleSentEvents(void);
|
|
|
|
// find entities in a box (box must be around this entity)
|
|
void FindEntitiesInRange(const FLOATaabbox3D &boxRange, CDynamicContainer<CEntity> &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<FLOAT3D> &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 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<SLONG> 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. */
|
|
|