//----------------------------------------------------------------------------- // // $Logfile:: /Code/DLLs/game/entity.h $ // $Revision:: 124 $ // $Author:: Steven $ // $Date:: 10/13/03 9:43a $ // // Copyright (C) 2002 by Ritual Entertainment, Inc. // All rights reserved. // // This source is may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // // // DESCRIPTION: // Base class for all enities that are controlled by the game. If you have any // object that should be called on a periodic basis and it is not an entity, // then you have to have an dummy entity that calls it. // // An entity in the game is any object that is not part of the world. Any non-world // object that is visible in the game is an entity, although it is not required that // all entities be visible to the player. Some objects are basically just virtual // constructs that act as an instigator of certain actions, for example, some // triggers are invisible and cannot be touched, but when activated by other // objects can cause things to happen. // // All entities are capable of receiving messages from Sin or from other entities. // Messages received by an entity may be ignored, passed on to their superclass, // or acted upon by the entity itself. The programmer must decide on the proper // action for the entity to take to any message. There will be many messages // that are completely irrelevant to an entity and should be ignored. Some messages // may require certain states to exist and if they are received by an entity when // it these states don't exist may indicate a logic error on the part of the // programmer or map designer and should be reported as warnings (if the problem is // not severe enough for the game to be halted) or as errors (if the problem should // not be ignored at any cost). // class BindInfo; class MorphInfo; class Entity; #ifndef __ENTITY_H__ #define __ENTITY_H__ #include "program.h" #include "g_local.h" #include "class.h" #include "vector.h" #include "script.h" #include "listener.h" #include "scriptvariable.h" #include "DamageModification.hpp" #include "UseData.h" // modification flags #define FLAG_IGNORE 0 #define FLAG_CLEAR 1 #define FLAG_ADD 2 typedef enum { DAMAGE_NO, DAMAGE_YES, // will take damage if hit DAMAGE_AIM // auto targeting recognizes this } damage_t; //deadflag #define DEAD_NO 0 #define DEAD_DYING 1 #define DEAD_DEAD 2 #define DEAD_RESPAWNABLE 3 // flags #define FL_FLY (1<<0) #define FL_SWIM (1<<1) // implied immunity to drowining #define FL_INWATER (1<<2) #define FL_GODMODE (1<<3) #define FL_NOTARGET (1<<4) #define FL_PARTIALGROUND (1<<5) // not all corners are valid #define FL_TEAMSLAVE (1<<6) // not the first on the team #define FL_NO_KNOCKBACK (1<<7) #define FL_THINK (1<<8) #define FL_BLOOD (1<<9) // when hit, it should bleed. #define FL_DIE_GIBS (1<<10) // when it dies, it should gib #define FL_DIE_EXPLODE (1<<11) // when it dies, it will explode #define FL_ROTATEDBOUNDS (1<<12) // model uses rotated mins and maxs #define FL_DONTSAVE (1<<13) // don't add to the savegame #define FL_IMMOBILE (1<<14) // entity has been immobolized somehow #define FL_PARTIAL_IMMOBILE (1<<15) // entity has been immobolized somehow #define FL_STUNNED (1<<16) #define FL_POSTTHINK (1<<17) // call a think function after the physics have been run #define FL_TOUCH_TRIGGERS (1<<18) // should this entity touch triggers #define FL_AUTOAIM (1<<19) // Autoaim on this entity // Create falgs #define ENTITY_CREATE_FLAG_ANIMATE (1<<0) #define ENTITY_CREATE_FLAG_MOVER (1<<1) // damage flags #define DAMAGE_RADIUS 0x00000001 // damage was indirect #define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage #define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon #define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles #define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets) #define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect #define DAMAGE_NO_SKILL 0x00000040 // damage is not affected by skill level extern Event EV_ClientMove; extern Event EV_ClientEndFrame; // Generic entity events extern Event EV_Classname; extern Event EV_Activate; extern Event EV_Use; extern Event EV_FadeNoRemove; extern Event EV_FadeOut; extern Event EV_FadeIn; extern Event EV_Fade; extern Event EV_Killed; extern Event EV_GotKill; extern Event EV_Pain; extern Event EV_Damage; extern Event EV_Stun; extern Event EV_Gib; extern Event EV_Kill; extern Event EV_DeathSinkStart; extern Event EV_TouchTriggers; extern Event EV_DoRadiusDamage; // Physics events extern Event EV_MoveDone; extern Event EV_Touch; extern Event EV_Contact; extern Event EV_LostContact; extern Event EV_Blocked; extern Event EV_Attach; extern Event EV_AttachModel; extern Event EV_RemoveAttachedModel; extern Event EV_RemoveAttachedModelByTargetname; extern Event EV_Detach; extern Event EV_UseBoundingBox; // Animation events extern Event EV_NewAnim; extern Event EV_LastFrame; extern Event EV_TakeDamage; extern Event EV_NoDamage; extern Event EV_SetCinematicAnim ; // script stuff extern Event EV_Model; extern Event EV_Hide; extern Event EV_Show; extern Event EV_BecomeSolid; extern Event EV_BecomeNonSolid; extern Event EV_Sound; extern Event EV_StopSound; extern Event EV_Bind; extern Event EV_Unbind; extern Event EV_JoinTeam; extern Event EV_QuitTeam; extern Event EV_SetHealth; extern Event EV_SetMaxHealth; extern Event EV_SetSize; extern Event EV_SetAlpha; extern Event EV_SetOrigin; extern Event EV_Warp; extern Event EV_SetTargetName; extern Event EV_SetTarget; extern Event EV_SetKillTarget; extern Event EV_SetAngles; extern Event EV_SetAngle; extern Event EV_RegisterAlias; extern Event EV_Anim; extern Event EV_StartAnimating; extern Event EV_SurfaceModelEvent; extern Event EV_ProcessInitCommands; extern Event EV_Stop; extern Event EV_StopLoopSound; extern Event EV_SetControllerAngles; extern Event EV_DisplayEffect; extern Event EV_ForceAlpha; extern Event EV_SetFloatVar; extern Event EV_SetVectorVar; extern Event EV_SetStringVar; extern Event EV_GetFloatVar; extern Event EV_GetVectorVar; extern Event EV_GetStringVar; extern Event EV_RemoveVariable; extern Event EV_DoesVarExist; extern Event EV_UseDataAnim; extern Event EV_UseDataType; extern Event EV_UseDataThread; extern Event EV_UseDataMaxDist; extern Event EV_UseData; extern Event EV_CreateEarthquake; extern Event EV_SpawnEffect; // Morph stuff extern Event EV_Morph; extern Event EV_Unmorph; // dir is 1 // power is 2 // minsize is 3 // maxsize is 4 // percentage is 5 // thickness 6 // entity is 7 // origin 8 // AI sound events extern Event EV_BroadcastSound; extern Event EV_HeardSound; extern Event EV_Hurt; extern Event EV_IfSkill; extern Event EV_SetArchetype; extern Event EV_SetGameplayHealth; extern Event EV_SetGameplayDamage; extern Event EV_ProcessGameplayData; extern Event EV_StopStasis; extern Event EV_AddHealthOverTime; extern Event EV_SimplePlayDialog; // Define ScriptMaster class ScriptMaster; // // Spawn args // // "spawnflags" // "alpha" default 1.0 // "model" // "origin" // "targetname" // "target" // #define MAX_MODEL_CHILDREN 8 class Entity; class Animate; class Mover; class BindInfo { public: // Model Binding variables int numchildren; int children[MAX_MODEL_CHILDREN]; // Team variables str moveteam; Entity *teamchain; Entity *teammaster; // Binding variables Entity *bindmaster; qboolean bind_use_my_angles; //Vector localorigin; //Vector localangles; qboolean detach_at_death; BindInfo(); void Archive( Archiver &arc ); }; inline BindInfo::BindInfo() { int i; // model binding variables numchildren = 0; for( i = 0 ; i < MAX_MODEL_CHILDREN ; i++ ) children[i] = ENTITYNUM_NONE; detach_at_death = true; // team variables teamchain = NULL; teammaster = NULL; // bind variables bindmaster = NULL; bind_use_my_angles = false; } inline void BindInfo::Archive(Archiver &arc) { arc.ArchiveInteger( &numchildren ); arc.ArchiveRaw( children, sizeof( children ) ); arc.ArchiveString( &moveteam ); arc.ArchiveObjectPointer( ( Class ** )&teamchain ); arc.ArchiveObjectPointer( ( Class ** )&teammaster ); arc.ArchiveObjectPointer( ( Class ** )&bindmaster ); arc.ArchiveBoolean( &bind_use_my_angles ); arc.ArchiveBoolean( &detach_at_death ); } BindInfo *CreateBindInfo( void ); typedef struct { int index; float current_percent; float speed; float final_percent; qboolean return_to_zero; int channel; } morph_t; class MorphInfo { public: MorphInfo(); morph_t controllers[ NUM_MORPH_CONTROLLERS ]; qboolean controller_on; void Archive( Archiver &arc ); }; inline MorphInfo::MorphInfo() { int i; for( i = 0 ; i < NUM_MORPH_CONTROLLERS ; i++ ) { controllers[ i ].index = -1; controllers[ i ].current_percent = 0.0; } controller_on = false; } inline void MorphInfo::Archive(Archiver &arc) { int i; for( i = 0 ; i < NUM_MORPH_CONTROLLERS ; i++ ) { arc.ArchiveInteger( &controllers[ i ].index ); arc.ArchiveFloat( &controllers[ i ].current_percent ); arc.ArchiveFloat( &controllers[ i ].speed ); arc.ArchiveFloat( &controllers[ i ].final_percent ); arc.ArchiveBoolean( &controllers[ i ].return_to_zero ); arc.ArchiveInteger( &controllers[ i ].channel ); } arc.ArchiveBoolean( &controller_on ); } MorphInfo *CreateMorphInfo( void ); typedef SafePtr EntityPtr; class Program; class Entity : public Listener { private: Vector _localOrigin; Container _lastTouchedList ; bool _fulltrace ; int _groupID; str _archetype; bool _missionObjective; str _targetPos; bool _networkDetail; protected: void buildUseData(); public: CLASS_PROTOTYPE( Entity ); // Construction / destruction Entity(); Entity( int create_flag ); virtual ~Entity(); // Spawning variables int entnum; gentity_t *edict; gclient_t *client; int spawnflags; // Standard variables str model; // Physics variables Vector total_delta; // total unprocessed movement Vector mins; Vector maxs; Vector absmin; Vector absmax; Vector centroid; Vector velocity; Vector avelocity; Vector origin; Vector angles; Vector size; int movetype; int mass; float gravity; // per entity gravity multiplier (1.0 is normal) float orientation[3][3]; Vector localangles; // Ground variables gentity_t *groundentity; cplane_t groundplane; int groundcontents; // Surface variables int numsurfaces; // Light variables float lightRadius; // Targeting variables str target; str targetname; str killtarget; // Character state float health; float max_health; int deadflag; int flags; // underwater variables int watertype; int waterlevel; // Pain and damage variables damage_t takedamage; int damage_type; qboolean look_at_me; bool projectilesCanStickToMe; str explosionModel; ScriptVariableList entityVars; unsigned int _affectingViewModes; Vector watch_offset; // Pluggable modules Animate *animate; Mover *mover; BindInfo *bind_info; MorphInfo *morph_info; Program *ObjectProgram; DamageModificationSystem *damageModSystem; UseData *useData; void Setup(); static Entity* FindEntityByName( const str &entityName ); void SetEntNum( int num ); void ClassnameEvent( Event *ev ); void SpawnFlagsEvent( Event *ev ); const Vector InterceptTarget( const Vector &targetPosition, const Vector &targetVelocity, const float maxSpeed) const; const Vector InterceptTargetXY( const Vector &targetPosition, const Vector &targetVelocity, const float maxSpeed) const; float DistanceTo( const Vector &pos ); float DistanceTo( const Entity *ent ); qboolean WithinDistance( const Vector &pos, float dist ); qboolean WithinDistance( const Entity *ent, float dist ); bool WithinDistanceXY( const Vector &pos , float dist ); bool WithinDistanceXY( const Entity *ent , float dist ); const char *Target( void ); void SetTarget( const char *target ); qboolean Targeted( void ); const char *TargetName( void ); void SetTargetName( const char *target ); void SetKillTarget( const char *killtarget ); const char *KillTarget( void ); const Vector & GetLocalOrigin( void ) const { return _localOrigin; } void SetLocalOrigin( const Vector &localOrigin ) { _localOrigin = localOrigin; } virtual void setModel( const char *model ); void setModel( const str &mdl ); virtual void setViewModel( const char *model ); void setViewModel( const str &mdl ); void SetModelEvent( Event *ev ); void SetTeamEvent( Event *ev ); virtual void TriggerEvent( Event *ev ); void hideModel( void ); void EventHideModel( Event *ev ); virtual void showModel( void ); void EventShowModel( Event *ev ); qboolean hidden( void ); void ProcessInitCommandsEvent( Event *ev ); void ProcessInitCommands( int index, qboolean cache = false ); void setAlpha( float alpha ); float alpha( void ); void setMoveType( int type ); void setMoveType( Event *ev ); int getMoveType( void ); void setSolidType( solid_t type ); int getSolidType( void ); virtual Vector getParentVector( const Vector &vec ); Vector getLocalVector( const Vector &vec ); virtual void setSize( Vector min, Vector max ); virtual void setOrigin( const Vector &org ); virtual void setOrigin( void ); virtual void addOrigin( const Vector &org ); virtual void setOriginEveryFrame( Event *ev ); void GetRawTag( int tagnum, orientation_t * orient, bodypart_t part = legs ); qboolean GetRawTag( const char * tagname, orientation_t * orient, bodypart_t part = legs ); void GetTag( int tagnum, orientation_t * orient ); qboolean GetTag( const char *name, orientation_t * orient ); void GetTag( int tagnum, Vector *pos, Vector *forward = NULL, Vector *left = NULL, Vector *up = NULL ); qboolean GetTag( const char *name, Vector *pos, Vector *forward = NULL, Vector *left = NULL, Vector *up = NULL ); virtual int CurrentFrame( bodypart_t part = legs ); virtual int CurrentAnim( bodypart_t part = legs ); virtual void setAngles( const Vector &ang ); virtual void setAngles( void ); virtual void SetOrigin( Event *ev ); void GetOrigin( Event *ev ); Vector GetControllerAngles( int num ); void SetControllerAngles( int num, vec3_t angles ); void SetControllerAngles( Event *ev ); void SetControllerTag( int num, int tag_num ); void link( void ); void unlink( void ); void setContents( int type ); int getContents( void ); void setScale( float scale ); qboolean droptofloor( float maxfall ); qboolean isClient( void ); virtual void SetDeltaAngles( void ); virtual void DamageEvent( Event *event ); void Damage( Entity *inflictor, Entity *attacker, float damage, const Vector &position, const Vector &direction, const Vector &normal, int knockback, int flags, int meansofdeath, int surface_number = -1, int bone_number = -1, Entity *weapon = 0); void Stun( float time ); void DamageType( Event *ev ); virtual qboolean CanDamage( const Entity *target, const Entity *skip_ent = NULL ); qboolean IsTouching( const Entity *e1 ); void FadeNoRemove( Event *ev ); void FadeOut( Event *ev ); void FadeIn( Event *ev ); void Fade( Event *ev ); virtual void CheckGround( void ); virtual qboolean HitSky( const trace_t *trace ); virtual qboolean HitSky( void ); void BecomeSolid( Event *ev ); void BecomeNonSolid( Event *ev ); void SetHealth( Event *ev ); void GetHealth( Event *ev ); void SetMaxHealth( Event *ev ); void SetSize( Event *ev ); void SetMins( Event *ev ); void SetMaxs( Event *ev ); void GetMins( Event* ev ); void GetMaxs( Event* ev ); void SetScale( Event *ev ); void setRandomScale( Event *ev ); void SetAlpha( Event *ev ); void SetTargetName( Event *ev ); void GetTargetName( Event *ev ); void GetRawTargetName( Event *ev ); void SetTarget( Event *ev ); void getTarget( Event *ev ); void GetTargetEntity( Event *ev ); void SetKillTarget( Event *ev ); void GetModelName(Event* ev); void SetAngles( Event *ev ); void GetAngles(Event* ev); void SetAngleEvent( Event *ev ); void TouchTriggersEvent( Event *ev ); void IncreaseShotCount( Event *ev ); void GetVelocity( Event *ev ); void SetVelocity( Event *ev ); // Support for checking/setting fulltrace flag void SetFullTraceEvent( Event *ev ); void setFullTrace( bool fulltrace ) { _fulltrace = fulltrace; } bool usesFullTrace() { return _fulltrace ; } Vector GetClosestCorner( const Vector &position ); str GetRandomAlias( const str &name ); void SetWaterType( void ); // model binding functions qboolean attach( int parent_entity_num, int tag_num, qboolean use_angles = true, Vector attach_offset = Vector(0, 0, 0), Vector attach_angles_offset = Vector(0, 0, 0) ); void detach( void ); void RegisterAlias( Event *ev ); void RegisterAliasAndCache( Event *ev ); void Cache( Event *ev ); qboolean GlobalAliasExists( const char *name ); qboolean AliasExists( const char *name ); // Sound Stuff void Sound( Event *ev ); virtual void Sound( const str &sound_name, int channel = CHAN_BODY, float volume = -1.0f, float min_dist = -1.0f, Vector *origin = NULL, float pitch_modifier = 1.0f, qboolean onlySendToThisEntity = false ); void StopSound( int channel ); void StopSound( Event *ev ); void LoopSound( Event *ev ); void LoopSound( const str &sound_name, float volume = -1.0f, float min_dist = -1.0f ); void StopLoopSound( Event *ev ); void StopLoopSound( void ); // Light Stuff void SetLight(Event *ev); void LightOn(Event *ev); void LightOff(Event *ev); void LightRed(Event *ev); void LightGreen(Event *ev); void LightBlue(Event *ev); void LightRadius(Event *ev); void LightStyle(Event *ev); void Flags( Event *ev ); void Effects( Event *ev ); void RenderEffects( Event *ev ); void SVFlags( Event *ev ); void BroadcastSound( float pos = SOUND_RADIUS, int soundType = SOUNDTYPE_GENERAL ); void BroadcastSound( Event *ev ); float ModifyFootstepSoundRadius( float radius , int soundTypeIdx ); void Kill( Event *ev ); void SurfaceModelEvent( Event *ev ); void SurfaceCommand( const char * surf_name, const char * token ); virtual void Postthink( void ); virtual void Think( void ); void DamageSkin( trace_t * trace, float damage ); void AttachEvent( Event *ev ); void AttachModelEvent( Event *ev ); void RemoveAttachedModelEvent( Event *ev ); void removeAttachedModelByTargetname( Event *ev ); void removeAttachedModelByTargetname( const str &targetNameToRemove ); void DetachEvent( Event *ev ); void TakeDamageEvent( Event *ev ); void NoDamageEvent( Event *ev ); void Gravity( Event *ev ); //void GiveOxygen( float time ); void UseBoundingBoxEvent( Event *ev ); void HurtEvent( Event *ev ); void IfSkillEvent( Event *ev ); void SetMassEvent( Event *ev ); void Censor( Event *ev ); void Ghost( Event *ev ); void StationaryEvent( Event *ev ); void Explosion( Event *ev ); void SelfDetonate( Event *ev ); void DoRadiusDamage( Event *ev ); void Shader( Event *ev ); void KillAttach( Event *ev ); //void SetBloodModel( Event *ev ); void DropToFloorEvent( Event *ev ); void SetAnimOnAttachedModel( Event *ev ); void SetAnimOnAttachedModel( const str &AnimName, const str &TagName ); void SetEntityExplosionModel( Event *ev ); virtual void SetCinematicAnim( const str &AnimName); virtual void SetCinematicAnim( Event *ev ); virtual void CinematicAnimDone( void ); virtual void CinematicAnimDone( Event *ev ); // Binding methods void joinTeam( Entity *teammember ); void quitTeam( void ); qboolean isBoundTo( const Entity *master ); virtual void bind( Entity *master, qboolean use_my_angles=false ); virtual void unbind( void ); void JoinTeam( Event *ev ); void EventQuitTeam( Event *ev ); void BindEvent( Event *ev ); void EventUnbind( Event *ev ); void AddToSoundManager( Event *ev ); void NoLerpThisFrame( void ); virtual void addAngles( const Vector &add ); void DeathSinkStart( Event *ev ); void DeathSink( Event *ev ); void LookAtMe( Event *ev ); void ProjectilesCanStickToMe( Event *ev ); void DetachAllChildren( Event *ev ); void MorphEvent( Event *ev ); void UnmorphEvent( Event *ev ); void MorphControl( Event *ev ); int GetMorphChannel( const char *morph_name ); void StartMorphController( void ); qboolean MorphChannelMatches( int morph_channel1, int morph_channel2 ); void ProjectileAtk( Event *ev ); void ProjectileAttackPoint( Event *ev ); void ProjectileAttackEntity( Event *ev ); void ProjectileAttackFromTag( Event *ev ); void ProjectileAttackFromPoint( Event *ev ); void TraceAtk( Event *ev ); virtual void VelocityModified( void ); virtual void Archive( Archiver &arc ); virtual void PassToAnimate( Event *ev ); void SetObjectProgram( Event *ev ); void SetWatchOffset( Event *ev ); void ExecuteProgram( Event *ev ); void Contents(Event* ev); void setMask(Event* ev); void hideFeaturesForFade( void ); void showFeaturesForFade( void ); void DisplayEffect( Event *ev ); void clearDisplayEffects( void ); void getCustomShaderInfo( const str &customShader, str &shaderName, str &soundName ); void setCustomShader( const char *customShader ); void setCustomShader( Event *ev ); void clearCustomShader( const char *customShader = NULL ); void clearCustomShader( Event *ev ); bool hasCustomShader( const char *customShader = NULL ); void setCustomEmitter( const char *customEmitter ); void setCustomEmitter( Event *ev ); void clearCustomEmitter( const char *customEmitter = NULL ); void clearCustomEmitter( Event *ev ); Entity *SpawnEffect( const str &name, const Vector &origin, const Vector &angles, float removeTime ); Entity *SpawnSound( const str &sound, const Vector &pos, float volume , float removeTime ); void SpawnEffect( Event *ev ); void attachEffect( const str &modelName, const str &tagName, float removeTime ); void attachEffect( Event *ev ); void ForceAlpha( Event *ev ); void CreateEarthquake( Event *ev ); void SetFloatVar( Event *ev ); void SetVectorVar( Event *ev ); void SetStringVar( Event *ev ); void GetFloatVar( Event *ev ); void doesVarExist( Event *ev ); void RemoveVariable( Event* ev ); void GetVectorVar( Event *ev ); void GetStringVar( Event *ev ); void SetUserVar1( Event *ev ); void SetUserVar2( Event *ev ); void SetUserVar3( Event *ev ); void SetUserVar4( Event *ev ); void isWithinDistanceOf( Event *ev ); void affectingViewMode( Event *ev ); void addAffectingViewModes( unsigned int mask ); void removeAffectingViewModes( unsigned int mask ); void TikiNote( Event *ev ); void TikiTodo( Event *ev ); void AddDamageModifier( Event *ev ); void ResolveDamage( ::Damage &damage ); // Health interface float getHealth( void ) { return health; }; float getMaxHealth( void ) { return max_health; }; void setHealth( float newHealth ) { health = newHealth; }; void setMaxHealth( float newMaxHealth ) { max_health = newMaxHealth; }; void addHealth( float healthToAdd, float maxHealth = 0.0f ); void addHealthOverTime( Event *ev ); // Group Number Interface void SetGroupID(Event *ev); void AddToGroup( int ID ); void SetGroupID(int ID) { _groupID = ID; } int GetGroupID() { return _groupID; }; void MultiplayerEvent( Event *ev ); Container& GetLastTouchedList() { return _lastTouchedList ; } // Archetype name virtual void setArchetype( Event *ev ); const str getArchetype() const; virtual const str getName() const { return ""; } void setMissionObjective(Event* ev); // Usable Entity functions void useDataAnim( Event *ev ); void useDataType( Event *ev ); void useDataThread( Event *ev ); void useDataMaxDist( Event *ev ); void useDataCount( Event *ev ); void useDataEvent( Event *ev ); bool hasUseData(); // GameplayManager interfaces to health and damage void setGameplayHealth( Event *ev ); void setGameplayDamage( Event *ev ); virtual void processGameplayData( Event* ) {} // Think interface void turnThinkOn( void ) { flags |= FL_THINK; } void turnThinkOff( void ) { flags &= ~FL_THINK; } bool isThinkOn( void ) { return (flags & FL_THINK) ? true : false; } void startStasis( void ); void stopStasis( void ); void startStasis( Event *ev ); void stopStasis( Event *ev ); void setTargetPos( Event *ev ); void setTargetPos( const str &targetPos ); str getTargetPos(); void simplePlayDialog( Event *ev ); void warp( Event *ev ); void traceHitsEntity( Event *ev ); void setNetworkDetail( Event *ev ); bool isNetworkDetail( void ); }; inline bool Entity::hasUseData() { if ( useData ) return true; return false; } inline int Entity::getSolidType() { return edict->solid; } inline const Vector Entity::InterceptTarget( const Vector &targetPosition, const Vector &targetVelocity, const float maxSpeed) const { Vector myPosition (origin); Vector predictedPosition = targetPosition + targetVelocity * ( Vector::Distance(targetPosition, myPosition) / maxSpeed ); Vector desiredDirection = predictedPosition - myPosition; return desiredDirection.toAngles(); } inline const Vector Entity::InterceptTargetXY( const Vector &targetPosition, const Vector &targetVelocity, const float maxSpeed) const { Vector myPosition (origin); float distanceToTargetPosition = Vector::Distance(targetPosition, myPosition); if ( !fSmallEnough( distanceToTargetPosition, 0.1f ) ) { Vector predictedPosition = targetPosition + targetVelocity * ( distanceToTargetPosition / maxSpeed ); Vector desiredDirection = predictedPosition - myPosition; desiredDirection.z = 0.0f; return desiredDirection.toAngles(); } return angles; } inline float Entity::DistanceTo(const Vector &pos) { Vector delta; delta = origin - pos; return delta.length(); } inline float Entity::DistanceTo(const Entity *ent) { Vector delta; assert( ent ); if ( !ent ) return 999999.0f; // "Infinite" distance delta = origin - ent->origin; return delta.length(); } inline qboolean Entity::WithinDistance(const Vector &pos, float dist) { Vector delta; delta = origin - pos; // check squared distance return ( ( delta * delta ) < ( dist * dist ) ); } inline qboolean Entity::WithinDistance(const Entity *ent, float dist) { Vector delta; //assert( ent ); if ( !ent ) return false; delta = origin - ent->origin; // check squared distance return ( ( delta * delta ) < ( dist * dist ) ); } inline bool Entity::WithinDistanceXY( const Vector &pos, float dist ) { float distance = Vector::DistanceXY( origin , pos ); return distance <= dist; } inline bool Entity::WithinDistanceXY( const Entity *ent , float dist ) { if ( !ent ) return false; float distance = Vector::DistanceXY( origin , ent->origin ); return distance <= dist; } inline const char *Entity::Target() { return target.c_str(); } inline qboolean Entity::Targeted() { if ( !targetname.length() ) return false; return true; } inline const char *Entity::TargetName() { return targetname.c_str(); } inline const char * Entity::KillTarget() { return killtarget.c_str(); } inline qboolean Entity::hidden() { if ( edict->s.renderfx & RF_DONTDRAW ) return true; return false; } inline void Entity::setModel(const str &mdl) { setModel( mdl.c_str() ); } inline void Entity::setViewModel(const str &mdl) { setViewModel( mdl.c_str() ); } inline void Entity::SetModelEvent(Event *ev) { char modelname[256] ; strcpy(modelname, ev->GetString( 1 ) ); char *tmpPtr = strstr(modelname, "*"); if (tmpPtr) { ev->SetString( 1, tmpPtr); } setModel( ev->GetString( 1 ) ); } inline void Entity::hideModel() { edict->s.renderfx |= RF_DONTDRAW; if ( getSolidType() <= SOLID_TRIGGER ) edict->svflags |= SVF_NOCLIENT; } inline void Entity::showModel() { edict->s.renderfx &= ~RF_DONTDRAW; edict->svflags &= ~SVF_NOCLIENT; } inline float Entity::alpha() { return edict->s.alpha; } inline void Entity::setMoveType(int type) { movetype = type; } inline int Entity::getMoveType() { return movetype; } inline void Entity::unlink() { gi.unlinkentity( edict ); } inline void Entity::setContents(int type) { edict->contents = type; } inline int Entity::getContents() { return edict->contents; } inline qboolean Entity::isClient() { if ( client ) return true; return false; } inline void Entity::SetDeltaAngles() { int i; if ( !client ) return; for( i = 0; i < 3; i++ ) client->ps.delta_angles[ i ] = ANGLE2SHORT( client->ps.viewangles[ i ] ); } inline qboolean Entity::GlobalAliasExists(const char *name) { assert( name ); return ( gi.GlobalAlias_FindRandom( name ) != NULL ); } inline qboolean Entity::AliasExists(const char *name) { assert( name ); return ( gi.Alias_FindRandom( edict->s.modelindex, name ) != NULL ); } inline str Entity::GetRandomAlias(const str &name) { str realname; const char *s; s = gi.Alias_FindRandom( edict->s.modelindex, name.c_str() ); if ( s ) realname = s; else { s = gi.GlobalAlias_FindRandom( name.c_str() ); if ( s ) realname = s; } return realname; } #include "worldspawn.h" #endif