Port over NSMoverEntity as idMover.
Add idFX class. Add idEngine::NumForEdict() and idEngine::EdictForNum() Port over various methods.
This commit is contained in:
parent
1739999520
commit
a7a4333ec9
17 changed files with 765 additions and 28 deletions
|
@ -10,7 +10,6 @@ void obj_tree2::obj_tree2( void ) {
|
|||
|
||||
void obj_tree2::Spawn( void ) {
|
||||
SetModel( "models/tree2.mdl" );
|
||||
AddEffect( EF_DARKFIELD );
|
||||
}
|
||||
|
||||
void obj_tree2::Precache( void ) {
|
||||
|
|
|
@ -206,13 +206,14 @@ typedef enumflags
|
|||
EF_BRIGHTFIELD = 1,
|
||||
EF_MUZZLEFLASH = 2,
|
||||
EF_BRIGHTLIGHT = 4,
|
||||
EF_TORCHLIGHT = 6,
|
||||
EF_DIMLIGHT = 8,
|
||||
EF_DARKLIGHT = 16,
|
||||
EF_DARKFIELD = 32,
|
||||
EF_LIGHT = 64,
|
||||
EF_NODRAW = 128
|
||||
} effects_t;
|
||||
/* make the compiler shut up */
|
||||
#define EF_TORCHLIGHT 6
|
||||
#else
|
||||
typedef enumflags
|
||||
{
|
||||
|
@ -285,4 +286,6 @@ typedef enum
|
|||
#define SCALE_ORIGIN_BOTTOM 32 // Scaling origin at object bottom
|
||||
#define SCALE_ORIGIN_TOP 64 // Scaling origin at object top
|
||||
#define DRF_TRANSLUCENT 128
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const vector g_vec_null = [0.0, 0.0, 0.0];
|
|
@ -14,7 +14,7 @@ idEntity idPlayerStart::MovePlayerToStart( idPlayer player ) {
|
|||
idEntity point = gameEngine.Find( ( idEntity ) world, ::classname, "idPlayerStart" );
|
||||
|
||||
if ( point ) {
|
||||
player.Transport( point.GetOrigin(), point.GetAngles() );
|
||||
player.Transport( point.GetOrigin(), point.GetAngles(), false );
|
||||
return point;
|
||||
} else {
|
||||
gameEngine.Error( "Cannot find idPlayerStart on level." );
|
||||
|
|
|
@ -14,7 +14,7 @@ void idTriggerTeleport::TeleporterTouched( idEntity toucher ) {
|
|||
idEntity destination = FindFirstTarget();
|
||||
|
||||
if ( destination ) {
|
||||
toucher.Transport( destination.GetOrigin(), destination.GetAngles() );
|
||||
toucher.Transport( destination.GetOrigin(), destination.GetAngles(), true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,7 @@ idActor.qh
|
|||
idPlayer.qh
|
||||
idRules.qh
|
||||
idItem.qh
|
||||
idMover.qh
|
||||
idFX.qh
|
||||
classes.qh
|
||||
#endlist
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
void idActor::idActor ( void ) {
|
||||
|
||||
}
|
||||
|
||||
void idActor::_InternalPostSpawn ( void ) {
|
||||
/* monsters are auto-aim by default */
|
||||
SetTakedamage( DAMAGE_AIM );
|
||||
SetSolid( SOLID_SLIDEBOX );
|
||||
SetMovetype( MOVETYPE_STEP );
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
class idActor : idEntity {
|
||||
void idActor( void );
|
||||
|
||||
virtual void _InternalPostSpawn( void );
|
||||
};
|
|
@ -296,3 +296,20 @@ void idEngine::MultiCast( vector where, multicast_t set ) {
|
|||
multicast(where, set);
|
||||
#endif
|
||||
}
|
||||
|
||||
float idEngine::NumForEdict( idEntity targetEnt ) {
|
||||
/* this requires denormals, may not work on custom engines */
|
||||
return (float)(__variant)targetEnt / (float)(__variant)nextent(world);
|
||||
}
|
||||
|
||||
idEntity idEngine::EdictForNum( float targetNum ) {
|
||||
idEntity e = ( idEntity ) world;
|
||||
|
||||
while ( ( e = NextEnt( e ) ) ) {
|
||||
if ( NumForEdict( e ) == targetNum )
|
||||
return (e);
|
||||
}
|
||||
|
||||
Error( "idEngine::EdictForNum: edict not found\n" );
|
||||
return __NULL__;
|
||||
}
|
||||
|
|
|
@ -64,10 +64,14 @@ class idEngine {
|
|||
nonvirtual void SetSpawnParms( idEntity e );
|
||||
|
||||
/* natively implemented by QuakeWorld */
|
||||
nonvirtual void LogFrag(idEntity killer, idEntity victim);
|
||||
nonvirtual string InfoKey(idEntity e, string key);
|
||||
nonvirtual float StringToFloat(string s);
|
||||
nonvirtual void MultiCast(vector where, float set);
|
||||
nonvirtual void LogFrag( idEntity killer, idEntity victim );
|
||||
nonvirtual string InfoKey( idEntity e, string key );
|
||||
nonvirtual float StringToFloat( string s );
|
||||
nonvirtual void MultiCast( vector where, float set );
|
||||
|
||||
/* custom builtins that we can do within QC */
|
||||
virtual float NumForEdict( idEntity targetEnt );
|
||||
virtual idEntity EdictForNum( float targetNum );
|
||||
};
|
||||
|
||||
idEngine gameEngine;
|
||||
|
|
|
@ -6,15 +6,29 @@ void idEntity::idEntity( void ) {
|
|||
if (g_world_initialized == false) {
|
||||
Precache();
|
||||
}
|
||||
_InternalPreSpawn();
|
||||
Spawn();
|
||||
_InternalPostSpawn();
|
||||
}
|
||||
|
||||
void idEntity::Precache( void ) {
|
||||
}
|
||||
|
||||
void idEntity::_InternalPreSpawn( void ) {
|
||||
}
|
||||
|
||||
void idEntity::_InternalPostSpawn( void ) {
|
||||
}
|
||||
|
||||
void idEntity::Spawn( void ) {
|
||||
}
|
||||
|
||||
void idEntity::Death( void ) {
|
||||
}
|
||||
|
||||
void idEntity::Pain( void ) {
|
||||
}
|
||||
|
||||
/* set functions */
|
||||
void idEntity::SetModelindex( float value ) {
|
||||
modelindex = value;
|
||||
|
@ -78,9 +92,6 @@ void idEntity::SetSize( vector min, vector max ) {
|
|||
gameEngine.SetSize( this, min, max );
|
||||
}
|
||||
|
||||
void idEntity::ScheduleThink( void ( void ) func, float timer ) {
|
||||
}
|
||||
|
||||
void idEntity::SetHealth( float value ) {
|
||||
health = value;
|
||||
|
||||
|
@ -461,7 +472,7 @@ bool idEntity::IsPlayer( void ) {
|
|||
return HasFlag(FL_CLIENT);
|
||||
}
|
||||
|
||||
bool idEntity::IsMonster( void ) {
|
||||
bool idEntity::IsActor( void ) {
|
||||
return HasFlag(FL_MONSTER);
|
||||
}
|
||||
|
||||
|
@ -481,13 +492,18 @@ void idEntity::InitTrigger( void ) {
|
|||
SetModelindex(0);
|
||||
}
|
||||
|
||||
void idEntity::Transport( vector new_pos, vector new_ang ) {
|
||||
float flSpeed = vlen(this.GetVelocity());
|
||||
gameEngine.MakeVectors(new_ang);
|
||||
SetVelocity(v_forward * flSpeed);
|
||||
void idEntity::Transport( vector newPosition, vector newAngle, bool retainVelocity ) {
|
||||
|
||||
SetOrigin(new_pos);
|
||||
SetAngles(new_ang);
|
||||
if (retainVelocity == true) {
|
||||
float flSpeed = gameEngine.VLen(this.GetVelocity());
|
||||
gameEngine.MakeVectors(newAngle);
|
||||
SetVelocity(v_forward * flSpeed);
|
||||
} else {
|
||||
SetVelocity([0,0,0]);
|
||||
}
|
||||
|
||||
SetOrigin(newPosition);
|
||||
SetAngles(newAngle);
|
||||
ForceUpdateClientAngle();
|
||||
}
|
||||
|
||||
|
@ -495,10 +511,83 @@ idEntity idEntity::FindFirstTarget( void ) {
|
|||
return gameEngine.Find( (idEntity) world, ::targetname, target);
|
||||
}
|
||||
|
||||
void idEntity::Death( void ) {
|
||||
|
||||
void idEntity::ClearVelocity( void ) {
|
||||
velocity = g_vec_null;
|
||||
avelocity = g_vec_null;
|
||||
}
|
||||
|
||||
void idEntity::Pain( void ) {
|
||||
float idEntity::GetTime(void)
|
||||
{
|
||||
return (movetype == MOVETYPE_PUSH) ? ltime : time;
|
||||
}
|
||||
|
||||
void idEntity::ReleaseThink( void ) {
|
||||
think = __NULL__;
|
||||
nextthink = 0.0f;
|
||||
}
|
||||
|
||||
void idEntity::SetThink( void ( void ) func ) {
|
||||
think = func;
|
||||
}
|
||||
|
||||
void idEntity::SetNextThink( float fl ) {
|
||||
float flTime = GetTime() + fl;
|
||||
|
||||
/* HACK: to make sure things happen post-spawn */
|
||||
if ( flTime == 0.0f )
|
||||
flTime = 0.1f;
|
||||
|
||||
if ( flTime >= 0 )
|
||||
nextthink = flTime;
|
||||
}
|
||||
|
||||
void idEntity::ScheduleThink( void ( void ) func, float fl ) {
|
||||
SetThink( func );
|
||||
SetNextThink( fl );
|
||||
}
|
||||
|
||||
/* this is where Hexen 2 specific methods begin. They will be mostly stubbed */
|
||||
void idEntity::SetScale( float modelScale ) {
|
||||
#ifdef TARGET_HEXEN2
|
||||
scale = modelScale;
|
||||
#endif
|
||||
}
|
||||
|
||||
float idEntity::GetScale( void ) {
|
||||
#ifdef TARGET_HEXEN2
|
||||
return scale;
|
||||
#else
|
||||
return 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void idEntity::SetScaleOrigin( scaleOrigin_t scaleOrg ) {
|
||||
#ifdef TARGET_HEXEN2
|
||||
drawflags &= ~SCALE_ORIGIN_MASKOUT;
|
||||
|
||||
switch ( scaleOrg ) {
|
||||
case SCALEORIGIN_CENTER:
|
||||
drawflags |= SCALE_ORIGIN_CENTER;
|
||||
break;
|
||||
case SCALEORIGIN_BOTTOM:
|
||||
drawflags |= SCALE_ORIGIN_BOTTOM;
|
||||
break;
|
||||
case SCALEORIGIN_TOP:
|
||||
drawflags |= SCALE_ORIGIN_TOP;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
scaleOrigin_t idEntity::GetScaleOrigin( void ) {
|
||||
#ifdef TARGET_HEXEN2
|
||||
if (drawflags & SCALE_ORIGIN_BOTTOM)
|
||||
return SCALEORIGIN_BOTTOM;
|
||||
else if (drawflags & SCALE_ORIGIN_TOP)
|
||||
return SCALEORIGIN_TOP;
|
||||
else
|
||||
return SCALEORIGIN_CENTER;
|
||||
#else
|
||||
return SCALEORIGIN_CENTER;
|
||||
#endif
|
||||
}
|
|
@ -1,4 +1,12 @@
|
|||
typedef enum
|
||||
{
|
||||
SCALEORIGIN_CENTER,
|
||||
SCALEORIGIN_BOTTOM,
|
||||
SCALEORIGIN_TOP
|
||||
} scaleOrigin_t;
|
||||
|
||||
class idEntity {
|
||||
public:
|
||||
void idEntity( void );
|
||||
|
||||
/* core engine tracked fields */
|
||||
|
@ -33,8 +41,21 @@ class idEntity {
|
|||
nonvirtual void ClearEffects( void );
|
||||
/** Sets the size of the entity, relative to its pivot point/origin. */
|
||||
nonvirtual void SetSize( vector, vector );
|
||||
/** Schedules a think, first parameter is function to call, second parm is the seconds to wait. */
|
||||
/** Schedules a think timer. You can only have one going at any given time.
|
||||
This is the preferred way of setting think timers.
|
||||
Note that when an entity of movement type `MOVETYPE_PUSH` is not moving,
|
||||
it will never get to think. */
|
||||
nonvirtual void ScheduleThink( void (), float );
|
||||
/** Call to prevent the entity from executing its think timer. */
|
||||
nonvirtual void ReleaseThink( void );
|
||||
/** Overrides the Think function of the entity.
|
||||
Only use it when you want to retain a think timer that's already been set for the entity. */
|
||||
nonvirtual void SetThink( void ( void ) );
|
||||
/** Sets the next think timer of the entity.
|
||||
It has to be a positive value. For example `::SetNextThink(1.5f); will trigger the think
|
||||
1.5 seconds from then on.*/
|
||||
nonvirtual void SetNextThink( float );
|
||||
|
||||
/** Sets the health of the entity. Will clamp to its maximum health. */
|
||||
nonvirtual void SetHealth( float );
|
||||
/** Adds a frag to the entity its info. */
|
||||
|
@ -193,20 +214,44 @@ class idEntity {
|
|||
nonvirtual string GetNoiseValue4( void );
|
||||
nonvirtual string GetInfoKey( string );
|
||||
|
||||
/** Sets the model scale of the entity, normalized value. 1.0 being normal size. */
|
||||
nonvirtual void SetScale( float );
|
||||
/** Returns the model scale of the entity. In Quake will always return 1.0. */
|
||||
nonvirtual float GetScale( void );
|
||||
/** Sets the origin from which the model scales. See scaleOrigin_t for types. */
|
||||
nonvirtual void SetScaleOrigin( scaleOrigin_t );
|
||||
/** Returns the origin at which the model scales. See scaleOrigin_t for types. */
|
||||
nonvirtual scaleOrigin_t GetScaleOrigin( void );
|
||||
|
||||
/** Returns true/false whether this idEntity is a player. */
|
||||
nonvirtual bool IsPlayer( void );
|
||||
nonvirtual bool IsMonster( void );
|
||||
/** Returns true/false whether this idEntity is an actor. */
|
||||
nonvirtual bool IsActor( void );
|
||||
/** Returns true/false whether this idEntity is part of the world. */
|
||||
nonvirtual bool IsWorld( void );
|
||||
|
||||
/** Will turn the entity into an invisible trigger. */
|
||||
nonvirtual void InitTrigger( void );
|
||||
nonvirtual void Transport( vector, vector );
|
||||
/** Will transport the entity to a given position, facing a specific angle while retaining the original velocity if desired. */
|
||||
nonvirtual void Transport( vector, vector, bool );
|
||||
/** Will return an entity handle of the first entity it finds that was named after SetTarget() 'ing it. */
|
||||
nonvirtual idEntity FindFirstTarget( void );
|
||||
|
||||
nonvirtual float GetTime( void );
|
||||
nonvirtual void ClearVelocity( void );
|
||||
|
||||
/** Overridable: When the entity has initialized, it will execute this method. */
|
||||
virtual void Spawn( void );
|
||||
/** Overridable: When the entity spawns on level-load, execute this method. */
|
||||
virtual void Precache( void );
|
||||
/** Overridable: Called when the entity dies. Only valid when the entity has health and can take damage. See SetTakedamage() and SetHealth(), as well as SetMaxHealth(). */
|
||||
virtual void Death( void );
|
||||
/** Overridable: Called when the entity felt pain. Only valid when the entity has health and can take damage. See SetTakedamage() and SetHealth(), as well as SetMaxHealth(). */
|
||||
virtual void Pain( void );
|
||||
|
||||
private:
|
||||
virtual void _InternalPreSpawn( void );
|
||||
virtual void _InternalPostSpawn( void );
|
||||
};
|
||||
|
||||
var bool g_world_initialized;
|
177
src/system/idFX.qc
Normal file
177
src/system/idFX.qc
Normal file
|
@ -0,0 +1,177 @@
|
|||
#ifdef TARGET_QUAKEWORLD
|
||||
#define FX_MSGTYPE MSG_MULTICAST
|
||||
#else
|
||||
#define FX_MSGTYPE MSG_BROADCAST
|
||||
#endif
|
||||
|
||||
void idFX::CastMuzzleFlash( idEntity targetEntity ) {
|
||||
/* the entity is already emitting a light of sorts. */
|
||||
if (targetEntity.effects > 1)
|
||||
return;
|
||||
|
||||
targetEntity.effects = EF_MUZZLEFLASH;
|
||||
}
|
||||
|
||||
void idFX::CastSpike( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_SPIKE );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.MultiCast(targetPos, MULTICAST_PHS);
|
||||
}
|
||||
|
||||
void idFX::CastSuperSpike( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_SUPERSPIKE );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PHS );
|
||||
}
|
||||
|
||||
void idFX::CastGunShot( vector targetPos, float shotCount ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_GUNSHOT );
|
||||
#ifdef TARGET_QUAKEWORLD
|
||||
gameEngine.WriteByte( FX_MSGTYPE, shotCount );
|
||||
#endif
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PVS );
|
||||
}
|
||||
|
||||
void idFX::CastExplosion( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_EXPLOSION );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PHS );
|
||||
}
|
||||
|
||||
void idFX::CastTarExplosion( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_TAREXPLOSION );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PHS );
|
||||
}
|
||||
|
||||
void idFX::CastLightning( idEntity boltOwner, vector startPos, vector endPos, lightningStyle_t lightningStyle ) {
|
||||
gameEngine.WriteByte (FX_MSGTYPE, SVC_TEMP_ENTITY);
|
||||
|
||||
switch ( lightningStyle ) {
|
||||
case FXLIGHTNING_TYPE1:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING1);
|
||||
break;
|
||||
case FXLIGHTNING_TYPE2:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING2);
|
||||
break;
|
||||
case FXLIGHTNING_TYPE3:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING3);
|
||||
break;
|
||||
default:
|
||||
float r = gameEngine.RInt(gameEngine.Random() * 2.0);
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING1);
|
||||
}
|
||||
|
||||
gameEngine.WriteEntity(FX_MSGTYPE, boltOwner);
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[0] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[1] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[2] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[0] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[1] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[2] );
|
||||
gameEngine.MultiCast( startPos, MULTICAST_PHS );
|
||||
}
|
||||
|
||||
void idFX::CastWizardSpike( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_WIZSPIKE );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.MultiCast(targetPos, MULTICAST_PHS);
|
||||
}
|
||||
|
||||
void idFX::CastKnightSpike( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_KNIGHTSPIKE );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.MultiCast(targetPos, MULTICAST_PHS);
|
||||
}
|
||||
|
||||
void idFX::CastLavaSplash( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_LAVASPLASH );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PVS );
|
||||
}
|
||||
|
||||
void idFX::CastTeleport( vector targetPos ) {
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_TELEPORT );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PVS );
|
||||
}
|
||||
|
||||
void idFX::CastBlood( vector targetPos ) {
|
||||
#ifdef TARGET_QUAKEWORLD
|
||||
gameEngine.WriteByte( FX_MSGTYPE, SVC_TEMP_ENTITY );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, TE_BLOOD );
|
||||
gameEngine.WriteByte( FX_MSGTYPE, 1 );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[0] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[1] );
|
||||
gameEngine.WriteCoord( FX_MSGTYPE, targetPos[2] );
|
||||
gameEngine.MultiCast( targetPos, MULTICAST_PVS );
|
||||
#else
|
||||
gameEngine.Particle( targetPos, [0, 0, 0], 73, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void idFX::CastLightningBlood( idEntity boltOwner, vector startPos, vector endPos, lightningStyle_t lightningStyle ) {
|
||||
gameEngine.WriteByte (FX_MSGTYPE, SVC_TEMP_ENTITY);
|
||||
|
||||
/* QW exclusive effect, substitute the other games with a separate blood impact */
|
||||
#ifdef TARGET_QUAKEWORLD
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNINGBLOOD);
|
||||
#else
|
||||
switch ( lightningStyle ) {
|
||||
case FXLIGHTNING_TYPE1:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING1);
|
||||
break;
|
||||
case FXLIGHTNING_TYPE2:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING2);
|
||||
break;
|
||||
case FXLIGHTNING_TYPE3:
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING3);
|
||||
break;
|
||||
default:
|
||||
float r = gameEngine.RInt(gameEngine.Random() * 2.0);
|
||||
gameEngine.WriteByte(FX_MSGTYPE, TE_LIGHTNING1);
|
||||
}
|
||||
#endif
|
||||
|
||||
gameEngine.WriteEntity(FX_MSGTYPE, boltOwner);
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[0] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[1] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, startPos[2] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[0] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[1] );
|
||||
gameEngine.WriteCoord(FX_MSGTYPE, endPos[2] );
|
||||
gameEngine.MultiCast( startPos, MULTICAST_PHS );
|
||||
|
||||
/* substitute for NQ/H2 */
|
||||
#ifndef TARGET_QUAKEWORLD
|
||||
CastBlood(endPos);
|
||||
#endif
|
||||
}
|
40
src/system/idFX.qh
Normal file
40
src/system/idFX.qh
Normal file
|
@ -0,0 +1,40 @@
|
|||
typedef enum
|
||||
{
|
||||
FXLIGHTNING_RANDOM,
|
||||
FXLIGHTNING_TYPE1,
|
||||
FXLIGHTNING_TYPE2,
|
||||
FXLIGHTNING_TYPE3
|
||||
} lightningStyle_t;
|
||||
|
||||
/** The idFX class contains helper functions for effects included in NQ/QW/H2. Keep in mind that a lot of these assume that your palette is organized similarily to how they are in their respective games. So if you use a custom palette, you may want to avoid using this namespace. */
|
||||
class idFX
|
||||
{
|
||||
/** Causes the target entity to cast a muzzleflash. */
|
||||
nonvirtual void CastMuzzleFlash( idEntity );
|
||||
/** Create a spike impact at the specified position. */
|
||||
nonvirtual void CastSpike( vector );
|
||||
/** Create a super-spike impact at the specified position. */
|
||||
nonvirtual void CastSuperSpike( vector );
|
||||
/** Create a gun shot impact at the specified position. */
|
||||
nonvirtual void CastGunShot( vector, float );
|
||||
/** Create an explosion at the specified position. */
|
||||
nonvirtual void CastExplosion( vector );
|
||||
/** Create a tar explosion at the specified position. */
|
||||
nonvirtual void CastTarExplosion( vector );
|
||||
/** Create a lightning strike between to positions. */
|
||||
nonvirtual void CastLightning( idEntity, vector, vector, lightningStyle_t );
|
||||
/** Create a wizard spike impact at the specified position. */
|
||||
nonvirtual void CastWizardSpike( vector );
|
||||
/** Create a knight spike impact at the specified position. */
|
||||
nonvirtual void CastKnightSpike( vector );
|
||||
/** Create a lava splash at the specified position. */
|
||||
nonvirtual void CastLavaSplash( vector );
|
||||
/** Create a teleport effect at the specified position. */
|
||||
nonvirtual void CastTeleport( vector );
|
||||
/** Create a blood splash specified position. */
|
||||
nonvirtual void CastBlood( vector );
|
||||
/** Create a lightning bolt between two points + blood splash at the specified position. */
|
||||
nonvirtual void CastLightningBlood( idEntity, vector, vector, lightningStyle_t );
|
||||
};
|
||||
|
||||
noref idFX gameFX;
|
|
@ -1,13 +1,15 @@
|
|||
|
||||
.float item;
|
||||
|
||||
void idItem::idItem(void) {
|
||||
}
|
||||
|
||||
void idItem::SetID(float a) {
|
||||
// item = a;
|
||||
item = a;
|
||||
}
|
||||
|
||||
float idItem::GetID(void) {
|
||||
//return item;
|
||||
return item;
|
||||
}
|
||||
|
||||
void idItem::PrimaryAttack(void) {
|
||||
|
|
261
src/system/idMover.qc
Normal file
261
src/system/idMover.qc
Normal file
|
@ -0,0 +1,261 @@
|
|||
void idMover::idMover( void ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
vector
|
||||
idMover::GetDirectionalPosition(vector vecAngle, float flLip)
|
||||
{
|
||||
vector vecMoveDir = g_vec_null;
|
||||
vector vecPos = g_vec_null;
|
||||
|
||||
/* editor angle */
|
||||
if (vecAngle == [0,-1,0]) {
|
||||
vecMoveDir = [0,0,1];
|
||||
} else if (vecAngle == [0,-2,0]) {
|
||||
vecMoveDir = [0,0,-1];
|
||||
} else {
|
||||
/* manually specified angle */
|
||||
gameEngine.MakeVectors(vecAngle);
|
||||
vecMoveDir = v_forward;
|
||||
}
|
||||
|
||||
vecPos = (GetOrigin() + vecMoveDir * (gameEngine.AbsoluteFloat(vecMoveDir * size) - flLip));
|
||||
return vecPos;
|
||||
}
|
||||
|
||||
vector
|
||||
idMover::GetDirectionalRotation(vector normalizedAngle, float travelDistance)
|
||||
{
|
||||
vector vecMoveDir = normalizedAngle;
|
||||
return (GetAngles() + vecMoveDir * travelDistance);
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverState(moverState_t val)
|
||||
{
|
||||
m_moverState = val;
|
||||
}
|
||||
|
||||
moverState_t
|
||||
idMover::GetMoverState(void)
|
||||
{
|
||||
return m_moverState;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverType(moverType_t val)
|
||||
{
|
||||
m_moverType = val;
|
||||
}
|
||||
|
||||
moverType_t
|
||||
idMover::GetMoverType(void)
|
||||
{
|
||||
|
||||
return m_moverType;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverPosition1(vector val)
|
||||
{
|
||||
m_vecPos1 = val;
|
||||
}
|
||||
|
||||
vector
|
||||
idMover::GetMoverPosition1(void)
|
||||
{
|
||||
return m_vecPos1;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverPosition2(vector val)
|
||||
{
|
||||
m_vecPos2 = val;
|
||||
}
|
||||
|
||||
vector
|
||||
idMover::GetMoverPosition2(void)
|
||||
{
|
||||
return m_vecPos2;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverRotation1(vector val)
|
||||
{
|
||||
m_vecPos3 = val;
|
||||
}
|
||||
|
||||
vector
|
||||
idMover::GetMoverRotation1(void)
|
||||
{
|
||||
return m_vecPos3;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::SetMoverRotation2(vector val)
|
||||
{
|
||||
m_vecPos4 = val;
|
||||
}
|
||||
|
||||
vector
|
||||
idMover::GetMoverRotation2(void)
|
||||
{
|
||||
return m_vecPos4;
|
||||
}
|
||||
|
||||
void
|
||||
idMover::MoveToPosition(vector vecDest, float flSpeed)
|
||||
{
|
||||
MoveAndRotateToPosition(vecDest, GetAngles(), flSpeed);
|
||||
}
|
||||
|
||||
void
|
||||
idMover::MoveAndRotateToPosition(vector vecDest, vector vecAngle, float flSpeed)
|
||||
{
|
||||
vector vecDifference;
|
||||
vector vecAngleDifference;
|
||||
float flTravel;
|
||||
float fTravelTime;
|
||||
|
||||
/* selects which end method to trigger based on state. */
|
||||
static void MoveToRotPosition_Done(float travelTime) {
|
||||
if (m_moverState == MOVER_1TO2) {
|
||||
ScheduleThink(_ArrivedAtRotPosition2, travelTime);
|
||||
} else if (m_moverState == MOVER_2TO1) {
|
||||
ScheduleThink(_ArrivedAtRotPosition1, travelTime);
|
||||
}
|
||||
MoverStartsMoving();
|
||||
}
|
||||
|
||||
/* selects which end positition to set based on state */
|
||||
static void MoveToRotPosition_SetDest(vector vecDest, vector vecAngle) {
|
||||
if (m_moverState == MOVER_POS2) {
|
||||
m_vecPos1 = vecDest;
|
||||
m_vecPos3 = vecAngle;
|
||||
m_moverState = MOVER_2TO1;
|
||||
} else {
|
||||
m_moverState = MOVER_1TO2;
|
||||
m_vecPos2 = vecDest;
|
||||
m_vecPos4 = vecAngle;
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if no speed is defined whatsoever */
|
||||
if (!flSpeed) {
|
||||
gameEngine.ObjError("idMover::MoveToPosition: No speed defined!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the appropriate attribute */
|
||||
MoveToRotPosition_SetDest(vecDest, vecAngle);
|
||||
|
||||
/* calculate travel distance and time */
|
||||
vecDifference = (vecDest - GetOrigin());
|
||||
vecAngleDifference = (vecAngle - GetAngles());
|
||||
flTravel = gameEngine.VLen(vecDifference);
|
||||
fTravelTime = (flTravel / flSpeed);
|
||||
|
||||
/* if we won't move far enough, we may rotate? */
|
||||
if (!flTravel) {
|
||||
flTravel = gameEngine.VLen(vecAngleDifference);
|
||||
fTravelTime = (flTravel / flSpeed);
|
||||
}
|
||||
|
||||
/* if we're already there, don't bother and trigger it right now. */
|
||||
if (fTravelTime <= 0.0) {
|
||||
|
||||
if (m_moverState == MOVER_1TO2) {
|
||||
MoverStartsMoving();
|
||||
_ArrivedAtRotPosition2();
|
||||
MoverFinishesMoving();
|
||||
} else if (m_moverState == MOVER_2TO1) {
|
||||
MoverStartsMoving();
|
||||
_ArrivedAtRotPosition1();
|
||||
MoverFinishesMoving();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* schedule the movement and proceed to trigger the end after a certain time */
|
||||
MoveToRotPosition_Done(fTravelTime);
|
||||
SetVelocity(vecDifference * (1.0f / fTravelTime));
|
||||
SetAngularVelocity((vecAngleDifference * (1.0 / fTravelTime)));
|
||||
}
|
||||
|
||||
void
|
||||
idMover::MoveToReverse(float flSpeed)
|
||||
{
|
||||
if ((GetMoverState() == MOVER_POS2) || (GetMoverState() == MOVER_1TO2)){
|
||||
MoveToPosition(GetMoverPosition1(), flSpeed);
|
||||
} else {
|
||||
MoveToPosition(GetMoverPosition2(), flSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
idMover::RotateToPosition(vector vecAngle, float flSpeed)
|
||||
{
|
||||
MoveAndRotateToPosition(GetOrigin(), vecAngle, flSpeed);
|
||||
}
|
||||
|
||||
void
|
||||
idMover::RotateToReverse(float flSpeed)
|
||||
{
|
||||
if ((GetMoverState() == MOVER_POS2) || (GetMoverState() == MOVER_1TO2)){
|
||||
RotateToPosition(GetMoverRotation1(), flSpeed);
|
||||
} else {
|
||||
RotateToPosition(GetMoverRotation2(), flSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
idMover::IsMoving(void)
|
||||
{
|
||||
switch (GetMoverState()) {
|
||||
case MOVER_POS1:
|
||||
case MOVER_POS2:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
idMover::_ArrivedAtRotPosition1(void)
|
||||
{
|
||||
SetOrigin(m_vecPos1);
|
||||
SetAngles(m_vecPos3);
|
||||
ClearVelocity();
|
||||
ReleaseThink();
|
||||
m_moverState = MOVER_POS1;
|
||||
MoverFinishesMoving();
|
||||
}
|
||||
|
||||
void
|
||||
idMover::_ArrivedAtRotPosition2(void)
|
||||
{
|
||||
SetOrigin(m_vecPos2);
|
||||
SetAngles(m_vecPos4);
|
||||
ClearVelocity();
|
||||
ReleaseThink();
|
||||
m_moverState = MOVER_POS2;
|
||||
MoverFinishesMoving();
|
||||
}
|
||||
|
||||
void
|
||||
idMover::_BeginMoving(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
idMover::MoverStartsMoving(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
idMover::MoverFinishesMoving(void)
|
||||
{
|
||||
}
|
87
src/system/idMover.qh
Normal file
87
src/system/idMover.qh
Normal file
|
@ -0,0 +1,87 @@
|
|||
/** The state the NSMoverEntity is in. */
|
||||
typedef enum
|
||||
{
|
||||
MOVER_POS1, /**< At the initial starting position. */
|
||||
MOVER_POS2, /**< At the final destination. */
|
||||
MOVER_1TO2, /**< On its way to the final destination. */
|
||||
MOVER_2TO1 /**< on its way back to the starting position. */
|
||||
} moverState_t;
|
||||
|
||||
/** The movement type of the NSMoverEntity. */
|
||||
typedef enum
|
||||
{
|
||||
MOVERTYPE_LINEAR, /**< Moves in a linear fashion. */
|
||||
MOVERTYPE_ACCELERATED, /**< Moved in an accelerated fashion. */
|
||||
} moverType_t;
|
||||
|
||||
class idMover:idEntity
|
||||
{
|
||||
public:
|
||||
void idMover(void);
|
||||
|
||||
/** Returns a directional position from the current one. */
|
||||
nonvirtual vector GetDirectionalPosition(vector, float);
|
||||
/** Returns a directional angle from the current one. */
|
||||
nonvirtual vector GetDirectionalRotation(vector, float);
|
||||
|
||||
/** Set the movement state. */
|
||||
nonvirtual void SetMoverState(moverState_t);
|
||||
/** Returns the movement state. */
|
||||
nonvirtual moverState_t GetMoverState(void);
|
||||
|
||||
/** Set the movement type. */
|
||||
nonvirtual void SetMoverType(moverType_t);
|
||||
/** Returns the movement type. */
|
||||
nonvirtual moverType_t GetMoverType(void);
|
||||
|
||||
/** Sets the initial starting position. */
|
||||
nonvirtual void SetMoverPosition1(vector);
|
||||
/** Returns the starting position. */
|
||||
nonvirtual vector GetMoverPosition1(void);
|
||||
|
||||
/** Sets the final destination. */
|
||||
nonvirtual void SetMoverPosition2(vector);
|
||||
/** Returns the final destination. */
|
||||
nonvirtual vector GetMoverPosition2(void);
|
||||
|
||||
/** Sets the initial starting angle. */
|
||||
nonvirtual void SetMoverRotation1(vector);
|
||||
/** Returns the starting angle. */
|
||||
nonvirtual vector GetMoverRotation1(void);
|
||||
|
||||
/** Sets the final destination angle. */
|
||||
nonvirtual void SetMoverRotation2(vector);
|
||||
/** Returns the final destination angle. */
|
||||
nonvirtual vector GetMoverRotation2(void);
|
||||
|
||||
/** Moves this entity to the specified position. */
|
||||
nonvirtual void MoveToPosition(vector, float);
|
||||
/** Rotates this entity to the desired angle. */
|
||||
nonvirtual void RotateToPosition(vector, float);
|
||||
/** Moves and rotates this entity to a desired location. */
|
||||
nonvirtual void MoveAndRotateToPosition(vector, vector, float);
|
||||
|
||||
/** Moves to the reverse state. If a mover is at pos1, it'll go to pos2, etc. */
|
||||
nonvirtual void MoveToReverse(float);
|
||||
/** Rotates to the reversed state. */
|
||||
nonvirtual void RotateToReverse(float);
|
||||
/** Returns if the NSMoverEntity is currently moving. */
|
||||
nonvirtual bool IsMoving(void);
|
||||
|
||||
/** Overridable: Called when the mover starts moving from its position to another. */
|
||||
virtual void MoverStartsMoving(void);
|
||||
/** Overridable: Called when the mover completes its movement to a destination. */
|
||||
virtual void MoverFinishesMoving(void);
|
||||
|
||||
private:
|
||||
nonvirtual void _ArrivedAtRotPosition1(void);
|
||||
nonvirtual void _ArrivedAtRotPosition2(void);
|
||||
nonvirtual void _BeginMoving(void);
|
||||
};
|
||||
|
||||
.vector m_vecPos1;
|
||||
.vector m_vecPos2;
|
||||
.vector m_vecPos3;
|
||||
.vector m_vecPos4;
|
||||
.moverState_t m_moverState;
|
||||
.moverType_t m_moverType;
|
|
@ -1,9 +1,11 @@
|
|||
#includelist
|
||||
idEngine.qc
|
||||
idEntity.qc
|
||||
idActor.qc
|
||||
idPlayer.qc
|
||||
idRules.qc
|
||||
idItem.qc
|
||||
idMover.qc
|
||||
idFX.qc
|
||||
idEngine.qc
|
||||
classes.qc
|
||||
#endlist
|
||||
|
|
Loading…
Reference in a new issue