mirror of
https://github.com/dhewm/dhewm3-sdk.git
synced 2025-04-15 05:40:57 +00:00
Add modified source code in framework and game directory (part 1)
This commit is contained in:
parent
835ccde40d
commit
cdc61a1a53
20 changed files with 3624 additions and 69 deletions
|
@ -46,6 +46,7 @@ const int BUTTON_RUN = BIT(1);
|
|||
const int BUTTON_ZOOM = BIT(2);
|
||||
const int BUTTON_SCORES = BIT(3);
|
||||
const int BUTTON_MLOOK = BIT(4);
|
||||
const int BUTTON_ATTACK2 = BIT(5); // Zeroth404
|
||||
const int BUTTON_5 = BIT(5);
|
||||
const int BUTTON_6 = BIT(6);
|
||||
const int BUTTON_7 = BIT(7);
|
||||
|
@ -82,6 +83,12 @@ const int IMPULSE_27 = 27; // <unused>
|
|||
const int IMPULSE_28 = 28; // vote yes
|
||||
const int IMPULSE_29 = 29; // vote no
|
||||
const int IMPULSE_40 = 40; // use vehicle
|
||||
// Zeroth
|
||||
const int IMPULSE_41 = 41; // hec Inventory Scroll Right
|
||||
const int IMPULSE_42 = 42; // hec Inventory Scroll Left
|
||||
const int IMPULSE_43 = 43; // hec use selected item
|
||||
const int IMPULSE_44 = 44; // hec drop selected item
|
||||
const int IMPULSE_45 = 45; // toggle automap
|
||||
|
||||
// usercmd_t->flags
|
||||
const int UCF_IMPULSE_SEQUENCE = 0x0001; // toggled every time an impulse command is sent
|
||||
|
|
|
@ -377,10 +377,10 @@ Pass damage to body at the bindjoint
|
|||
============
|
||||
*/
|
||||
void idAFAttachment::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
|
||||
const char *damageDefName, const float damageScale, const int location ) {
|
||||
const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint ) {
|
||||
|
||||
if ( body ) {
|
||||
body->Damage( inflictor, attacker, dir, damageDefName, damageScale, attachJoint );
|
||||
body->Damage( inflictor, attacker, dir, damageDefName, damageScale, attachJoint, iPoint );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1087,11 +1087,11 @@ void idAFEntity_Gibbable::Present( void ) {
|
|||
idAFEntity_Gibbable::Damage
|
||||
================
|
||||
*/
|
||||
void idAFEntity_Gibbable::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location ) {
|
||||
void idAFEntity_Gibbable::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, idVec3 &iPoint ) {
|
||||
if ( !fl.takedamage ) {
|
||||
return;
|
||||
}
|
||||
idAFEntity_Base::Damage( inflictor, attacker, dir, damageDefName, damageScale, location );
|
||||
idAFEntity_Base::Damage( inflictor, attacker, dir, damageDefName, damageScale, location, iPoint );
|
||||
if ( health < -20 && spawnArgs.GetBool( "gib" ) ) {
|
||||
Gib( dir, damageDefName );
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
virtual void ApplyImpulse( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse );
|
||||
virtual void AddForce( idEntity *ent, int id, const idVec3 &point, const idVec3 &force );
|
||||
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint );
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
|
||||
void SetCombatModel( void );
|
||||
|
@ -225,7 +225,7 @@ public:
|
|||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
virtual void Present( void );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, idVec3 &iPoint );
|
||||
virtual void SpawnGibs( const idVec3 &dir, const char *damageDefName );
|
||||
|
||||
protected:
|
||||
|
|
107
game/Actor.cpp
107
game/Actor.cpp
|
@ -1825,6 +1825,27 @@ idActor *idActor::ClosestEnemyToPoint( const idVec3 &pos ) {
|
|||
return bestEnt;
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
/*
|
||||
================
|
||||
idActor::IsEnemy
|
||||
================
|
||||
*/
|
||||
bool idActor::IsEnemy( idEntity *test ) {
|
||||
idActor *ent;
|
||||
for( ent = enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) {
|
||||
if ( ent->fl.hidden ) {
|
||||
continue;
|
||||
}
|
||||
gameLocal.Printf(" [%s] - [%s]", ent->name.c_str(), test->name.c_str());
|
||||
if ( ent->name.c_str() == test->name.c_str() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idActor::EnemyWithMostHealth
|
||||
|
@ -2158,7 +2179,7 @@ calls Damage()
|
|||
============
|
||||
*/
|
||||
void idActor::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
|
||||
const char *damageDefName, const float damageScale, const int location ) {
|
||||
const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint ) {
|
||||
if ( !fl.takedamage ) {
|
||||
return;
|
||||
}
|
||||
|
@ -2258,10 +2279,25 @@ bool idActor::Pain( idEntity *inflictor, idEntity *attacker, int damage, const i
|
|||
return false;
|
||||
}
|
||||
|
||||
// set the pain anim
|
||||
idStr damageGroup = GetDamageGroup( location );
|
||||
|
||||
painAnim = "";
|
||||
if ( g_debugDamage.GetBool() ) {
|
||||
gameLocal.Printf( "Damage: joint: '%s', zone '%s', anim '%s'\n", animator.GetJointName( ( jointHandle_t )location ),
|
||||
damageGroup.c_str(), painAnim.c_str() );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth: don't do pain anims for trigger types
|
||||
if ( inflictor ) {
|
||||
if ( inflictor->IsType( idTrigger_Hurt::Type ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( inflictor->IsType( idTrigger_Touch::Type ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set the pain anim
|
||||
if ( animPrefix.Length() ) {
|
||||
if ( damageGroup.Length() && ( damageGroup != "legs" ) ) {
|
||||
sprintf( painAnim, "%s_pain_%s", animPrefix.c_str(), damageGroup.c_str() );
|
||||
|
@ -2293,11 +2329,6 @@ bool idActor::Pain( idEntity *inflictor, idEntity *attacker, int damage, const i
|
|||
painAnim = "pain";
|
||||
}
|
||||
|
||||
if ( g_debugDamage.GetBool() ) {
|
||||
gameLocal.Printf( "Damage: joint: '%s', zone '%s', anim '%s'\n", animator.GetJointName( ( jointHandle_t )location ),
|
||||
damageGroup.c_str(), painAnim.c_str() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2403,11 +2434,49 @@ idActor::Event_EnableEyeFocus
|
|||
void idActor::PlayFootStepSound( void ) {
|
||||
const char *sound = NULL;
|
||||
const idMaterial *material;
|
||||
idPlayer *player;
|
||||
|
||||
if ( !GetPhysics()->HasGroundContacts() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
if ( this->IsType( idPlayer::Type ) ) {
|
||||
player = static_cast< idPlayer* >( this );
|
||||
|
||||
// no footstep sounds when flying (wings of wrath)
|
||||
if ( player->FreeMove ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( player->inWater ) {
|
||||
waterLevel_t level = static_cast< idPhysics_Player* >( player->GetPlayerPhysics() )->GetWaterLevel();
|
||||
|
||||
if ( level == WATERLEVEL_FEET ) {
|
||||
sound = spawnArgs.GetString( "snd_footstep_water_feet" );
|
||||
} else if ( level == WATERLEVEL_WAIST ) {
|
||||
sound = spawnArgs.GetString( "snd_footstep_water_waist" );
|
||||
} else if ( level == WATERLEVEL_HEAD ) {
|
||||
sound = spawnArgs.GetString( "snd_footstep_water_head" );
|
||||
} else {
|
||||
sound = spawnArgs.GetString( "snd_footstep_water_feet" );
|
||||
}
|
||||
|
||||
if ( *sound != '\0' ) {
|
||||
StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, SSF_NO_DUPS, false, NULL );
|
||||
}
|
||||
|
||||
return;
|
||||
} else if ( player->leftWater != 0 && gameLocal.time < player->leftWater + 3000 ) {
|
||||
sound = spawnArgs.GetString( "snd_footstep_wet" );
|
||||
|
||||
if ( *sound != '\0' ) {
|
||||
StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, SSF_NO_DUPS, false, NULL );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// start footstep sound based on material type
|
||||
material = GetPhysics()->GetContact( 0 ).material;
|
||||
if ( material != NULL ) {
|
||||
|
@ -2417,7 +2486,7 @@ void idActor::PlayFootStepSound( void ) {
|
|||
sound = spawnArgs.GetString( "snd_footstep" );
|
||||
}
|
||||
if ( *sound != '\0' ) {
|
||||
StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, 0, false, NULL );
|
||||
StartSoundShader( declManager->FindSound( sound ), SND_CHANNEL_BODY, SSF_NO_DUPS, false, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3120,22 +3189,30 @@ idActor::Event_AnimLength
|
|||
================
|
||||
*/
|
||||
void idActor::Event_AnimLength( int channel, const char *animname ) {
|
||||
idThread::ReturnFloat( GetAnimLength(channel, animname) );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
/*
|
||||
================
|
||||
idActor::GetAnimLength
|
||||
================
|
||||
*/
|
||||
float idActor::GetAnimLength( int channel, const char *animname ) {
|
||||
int anim;
|
||||
|
||||
anim = GetAnim( channel, animname );
|
||||
if ( anim ) {
|
||||
if ( channel == ANIMCHANNEL_HEAD ) {
|
||||
if ( head.GetEntity() ) {
|
||||
idThread::ReturnFloat( MS2SEC( head.GetEntity()->GetAnimator()->AnimLength( anim ) ) );
|
||||
return;
|
||||
return MS2SEC( head.GetEntity()->GetAnimator()->AnimLength( anim ) );
|
||||
}
|
||||
} else {
|
||||
idThread::ReturnFloat( MS2SEC( animator.AnimLength( anim ) ) );
|
||||
return;
|
||||
}
|
||||
return MS2SEC( animator.AnimLength( anim ) );
|
||||
}
|
||||
}
|
||||
|
||||
idThread::ReturnFloat( 0.0f );
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
11
game/Actor.h
11
game/Actor.h
|
@ -165,7 +165,7 @@ public:
|
|||
|
||||
// damage
|
||||
void SetupDamageGroups( void );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint );
|
||||
int GetDamageForLocation( int damage, int location );
|
||||
const char * GetDamageGroup( int location );
|
||||
void ClearPain( void );
|
||||
|
@ -318,6 +318,15 @@ private:
|
|||
void Event_SetState( const char *name );
|
||||
void Event_GetState( void );
|
||||
void Event_GetHead( void );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
protected:
|
||||
void Event_VecForward( float spread ); // return a forward vector for the direction we're facing, with some random spread (like projectiles)
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
bool IsEnemy( idEntity *test );
|
||||
float GetAnimLength( int channel, const char *animname );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_ACTOR_H__ */
|
||||
|
|
|
@ -39,8 +39,8 @@ CLASS_DECLARATION( idEntity, idBrittleFracture )
|
|||
EVENT( EV_Touch, idBrittleFracture::Event_Touch )
|
||||
END_CLASS
|
||||
|
||||
const int SHARD_ALIVE_TIME = 5000;
|
||||
const int SHARD_FADE_START = 2000;
|
||||
const int SHARD_ALIVE_TIME = 5000; // HEXEN : Zeroth - changed from 5000
|
||||
const int SHARD_FADE_START = 3500; // HEXEN : Zeroth - changed from 2000
|
||||
|
||||
static const char *brittleFracture_SnapshotName = "_BrittleFracture_Snapshot_";
|
||||
|
||||
|
@ -772,13 +772,39 @@ void idBrittleFracture::ProjectDecal( const idVec3 &point, const idVec3 &dir, co
|
|||
idBrittleFracture::DropShard
|
||||
================
|
||||
*/
|
||||
void idBrittleFracture::DropShard( shard_t *shard, const idVec3 &point, const idVec3 &dir, const float impulse, const int time ) {
|
||||
void idBrittleFracture::DropShard( shard_t *shard, const idVec3 &point, const idVec3 &odir, const float oimpulse, const int time ) {
|
||||
int i, j, clipModelId;
|
||||
float dist, f;
|
||||
idVec3 dir2, origin;
|
||||
idMat3 axis;
|
||||
shard_t *neighbour;
|
||||
|
||||
idVec3 dir = odir; // HEXEN : Zeroth
|
||||
float impulse = oimpulse; // HEXEN : Zeroth
|
||||
|
||||
// HEXEN : Zeroth
|
||||
if ( dir.Length() < 5 ) { // 5 is just an (whats that word?)
|
||||
dir = idVec3(0,0,-1) * spawnArgs.GetFloat( "forceIfZero", "0" );
|
||||
impulse = dir.Normalize();
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
if ( spawnArgs.GetBool( "blastBothWays", "0" ) ) {
|
||||
dir = -dir;
|
||||
//m = dir.Normalize();
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
if ( spawnArgs.GetBool( "randomDir", "0" ) ) {
|
||||
float len = dir.Length();
|
||||
dir.x = gameLocal.random.RandomFloat() - 0.5;
|
||||
dir.y = gameLocal.random.RandomFloat() - 0.5;
|
||||
dir.z = gameLocal.random.RandomFloat() - 0.5;
|
||||
dir.Normalize();
|
||||
dir *= len;
|
||||
//m = dir.Normalize();
|
||||
}
|
||||
|
||||
// don't display decals on dropped shards
|
||||
shard->decals.DeleteContents( true );
|
||||
|
||||
|
@ -818,10 +844,26 @@ void idBrittleFracture::DropShard( shard_t *shard, const idVec3 &point, const id
|
|||
shard->physicsObj.SetAxis( axis );
|
||||
shard->physicsObj.SetBouncyness( bouncyness );
|
||||
shard->physicsObj.SetFriction( 0.6f, 0.6f, friction );
|
||||
shard->physicsObj.SetGravity( gameLocal.GetGravity() );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
float grv = spawnArgs.GetFloat( "shardGravity", "0" );
|
||||
if ( grv ) {
|
||||
shard->physicsObj.SetGravity( idVec3(0,0,-1) * grv );
|
||||
} else {
|
||||
shard->physicsObj.SetGravity( gameLocal.GetGravity() );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
float velScale = 1;
|
||||
if ( spawnArgs.GetBool( "shardRandomVelocity", "0" ) ) {
|
||||
velScale = gameLocal.random.RandomFloat();
|
||||
} else {
|
||||
velScale = 1;
|
||||
}
|
||||
|
||||
shard->physicsObj.SetContents( CONTENTS_RENDERMODEL );
|
||||
shard->physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP );
|
||||
shard->physicsObj.ApplyImpulse( 0, origin, impulse * linearVelocityScale * dir );
|
||||
shard->physicsObj.ApplyImpulse( 0, origin, impulse * linearVelocityScale * dir * velScale ); // HEXEN : Zeroth: added velScale
|
||||
shard->physicsObj.SetAngularVelocity( dir.Cross( dir2 ) * ( f * angularVelocityScale ) );
|
||||
|
||||
shard->clipModel->SetId( clipModelId );
|
||||
|
@ -884,7 +926,10 @@ void idBrittleFracture::Shatter( const idVec3 &point, const idVec3 &impulse, con
|
|||
DropShard( shard, point, dir, m, time );
|
||||
}
|
||||
|
||||
DropFloatingIslands( point, impulse, time );
|
||||
// HEXEN : Zeroth
|
||||
if ( spawnArgs.GetBool( "dropFloatingIsland", "1" ) ) {
|
||||
DropFloatingIslands( point, dir, time ); // impulse changed to dir
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -895,12 +940,13 @@ idBrittleFracture::DropFloatingIslands
|
|||
void idBrittleFracture::DropFloatingIslands( const idVec3 &point, const idVec3 &impulse, const int time ) {
|
||||
int i, j, numIslands;
|
||||
int queueStart, queueEnd;
|
||||
float m; // HEXEN : Zeroth
|
||||
shard_t *curShard, *nextShard, **queue;
|
||||
bool touchesEdge;
|
||||
idVec3 dir;
|
||||
|
||||
dir = impulse;
|
||||
dir.Normalize();
|
||||
m = dir.Normalize(); // HEXEN : Zeroth - added 'm = '
|
||||
|
||||
numIslands = 0;
|
||||
queue = (shard_t **) _alloca16( shards.Num() * sizeof(shard_t **) );
|
||||
|
@ -955,7 +1001,7 @@ void idBrittleFracture::DropFloatingIslands( const idVec3 &point, const idVec3 &
|
|||
// if the island is not connected to the world at any edges
|
||||
if ( !touchesEdge ) {
|
||||
for ( j = 0; j < queueEnd; j++ ) {
|
||||
DropShard( queue[j], point, dir, 0.0f, time );
|
||||
DropShard( queue[j], point, dir, m, time ); // HEXEN : Zeroth - 0.0f to m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -969,6 +1015,7 @@ idBrittleFracture::Break
|
|||
void idBrittleFracture::Break( void ) {
|
||||
fl.takedamage = false;
|
||||
physicsObj.SetContents( CONTENTS_RENDERMODEL | CONTENTS_TRIGGER );
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -141,7 +141,14 @@ public:
|
|||
|
||||
idList< idEntityPtr<idEntity> > targets; // when this entity is activated these entities entity are activated
|
||||
|
||||
int health; // FIXME: do all objects really need health?
|
||||
// HEXEN : Zeroth
|
||||
protected:
|
||||
int nextFlame;
|
||||
int fireJoint;
|
||||
public:
|
||||
int health;
|
||||
int onFire;
|
||||
|
||||
|
||||
struct entityFlags_s {
|
||||
bool notarget :1; // if true never attack or target this entity
|
||||
|
@ -158,6 +165,16 @@ public:
|
|||
bool networkSync :1; // if true the entity is synchronized over the network
|
||||
} fl;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
bool gravityMod;
|
||||
bool inWater;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
idVec3 curGrav( void );
|
||||
idVec3 curNorm( void );
|
||||
|
||||
public:
|
||||
ABSTRACT_PROTOTYPE( idEntity );
|
||||
|
||||
|
@ -177,6 +194,16 @@ public:
|
|||
// clients generate views based on all the player specific options,
|
||||
// cameras have custom code, and everything else just uses the axis orientation
|
||||
virtual renderView_t * GetRenderView();
|
||||
void ShutdownThreads( void );
|
||||
void UpdateScript( void );
|
||||
void SetState( const char *statename );
|
||||
void SetState( const function_t *newState );
|
||||
const function_t *GetScriptFunction( const char *funcname );
|
||||
const char *WaitState( void ) const;
|
||||
void SetWaitState( const char *_waitstate );
|
||||
//idThread *ConstructScriptObject( void );
|
||||
//void idEntity::FinishSetup( void );
|
||||
//bool IsInUse( void ); // HEXEN : Zeroth
|
||||
|
||||
// thinking
|
||||
virtual void Think( void );
|
||||
|
@ -302,7 +329,7 @@ public:
|
|||
// returns true if this entity can be damaged from the given origin
|
||||
virtual bool CanDamage( const idVec3 &origin, idVec3 &damagePoint ) const;
|
||||
// applies damage to this entity
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint );
|
||||
// adds a damage effect like overlays, blood, sparks, debris etc.
|
||||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
// callback function for when another entity received damage from this entity. damage can be adjusted and returned to the caller.
|
||||
|
@ -361,11 +388,24 @@ public:
|
|||
void ServerSendEvent( int eventId, const idBitMsg *msg, bool saveEvent, int excludeClient ) const;
|
||||
void ClientSendEvent( int eventId, const idBitMsg *msg ) const;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// ****** thanks SnoopJeDi ( http://www.doom3world.org/phpbb2/viewtopic.php?f=56&t=12469&p=214427#p214427 )
|
||||
void FadeMusic( int channel, float to, float over );
|
||||
// ******
|
||||
|
||||
protected:
|
||||
renderEntity_t renderEntity; // used to present a model to the renderer
|
||||
int modelDefHandle; // handle to static renderer model
|
||||
refSound_t refSound; // used to present sound to the audio engine
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// state variables
|
||||
const function_t *state;
|
||||
const function_t *idealState;
|
||||
// script variables
|
||||
idThread * scriptThread;
|
||||
idStr waitState;
|
||||
|
||||
private:
|
||||
idPhysics_Static defaultPhysicsObj; // default physics object
|
||||
idPhysics * physics; // physics used for this entity
|
||||
|
@ -381,6 +421,7 @@ private:
|
|||
signalList_t * signals;
|
||||
|
||||
int mpGUIState; // local cache to avoid systematic SetStateInt
|
||||
idThread * thread;
|
||||
|
||||
private:
|
||||
void FixupLocalizedStrings();
|
||||
|
@ -465,6 +506,32 @@ private:
|
|||
void Event_HasFunction( const char *name );
|
||||
void Event_CallFunction( const char *name );
|
||||
void Event_SetNeverDormant( int enable );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
private:
|
||||
idDict projectileDict;
|
||||
idEntity *projectileEnt;
|
||||
void Event_GetState( void );
|
||||
void Event_SetState( const char *name );
|
||||
void Event_SetNextState( const char *name );
|
||||
|
||||
void Event_SetGravity( const idVec3 &grav );
|
||||
void Event_GetGravity( void );
|
||||
void Event_GetGravityNormal( void );
|
||||
void Event_GetSelfEntity( void );
|
||||
void Event_SetHealth( float newHealth );
|
||||
void Event_GetHealth( void );
|
||||
void Event_GetType( void );
|
||||
void Event_SpawnProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower );
|
||||
void Event_CreateProjectile( void );
|
||||
void Event_GetMaster( void );
|
||||
void Event_GetModelDims( void );
|
||||
void Event_ReplaceMaterial( const char * replacee, const char * replacer );
|
||||
void Event_ResetGravity( void );
|
||||
void Event_HudMessage( const char *message );
|
||||
public:
|
||||
idAngles GetAngles( void );
|
||||
idVec3 GetModelDims( void );
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -509,6 +576,7 @@ public:
|
|||
virtual void AddDamageEffect( const trace_t &collision, const idVec3 &velocity, const char *damageDefName );
|
||||
void AddLocalDamageEffect( jointHandle_t jointNum, const idVec3 &localPoint, const idVec3 &localNormal, const idVec3 &localDir, const idDeclEntityDef *def, const idMaterial *collisionMaterial );
|
||||
void UpdateDamageEffects( void );
|
||||
void EmitFlames( void );
|
||||
|
||||
virtual bool ClientReceiveEvent( int event, int time, const idBitMsg &msg );
|
||||
|
||||
|
@ -529,6 +597,15 @@ private:
|
|||
void Event_SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
|
||||
void Event_GetJointPos( jointHandle_t jointnum );
|
||||
void Event_GetJointAngle( jointHandle_t jointnum );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
private:
|
||||
void Event_TransitionJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &to, const idAngles &from, float seconds, float transitions );
|
||||
public:
|
||||
idVec3 idAnimatedEntity::GetJointPos( jointHandle_t jointnum );
|
||||
void TransitionJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &to, const idAngles &from, float seconds, float transitions );
|
||||
void SetJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, const idAngles &angles );
|
||||
idAngles GetJointAngle( jointHandle_t jointnum );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_ENTITY_H__ */
|
||||
|
|
|
@ -34,6 +34,11 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#define SCRIPT_DEFAULT "script/doom_main.script"
|
||||
#define SCRIPT_DEFAULTFUNC "doom_main"
|
||||
|
||||
// HEXEN : Zeroth
|
||||
#define NUM_UNIQUE_ARTIFACTS (16)
|
||||
#define EOC_NUM_VMODES (15)
|
||||
#define EOC_RELEASE (1)
|
||||
|
||||
#define LAGO_IMG_WIDTH 64
|
||||
#define LAGO_IMG_HEIGHT 64
|
||||
#define LAGO_WIDTH 64
|
||||
|
@ -50,7 +55,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#define GAME_VERSION "baseDOOM-1"
|
||||
|
||||
#define MAX_CLIENTS 32
|
||||
#define GENTITYNUM_BITS 12
|
||||
#define GENTITYNUM_BITS 13
|
||||
#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
|
||||
#define ENTITYNUM_NONE (MAX_GENTITIES-1)
|
||||
#define ENTITYNUM_WORLD (MAX_GENTITIES-2)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -80,6 +80,10 @@ class idThread;
|
|||
class idEditEntities;
|
||||
class idLocationEntity;
|
||||
|
||||
//============================================================================
|
||||
// HEXEN : Zeroth - Forward Declarations
|
||||
|
||||
|
||||
//============================================================================
|
||||
extern const int NUM_RENDER_PORTAL_BITS;
|
||||
|
||||
|
@ -96,6 +100,13 @@ extern const int NUM_RENDER_PORTAL_BITS;
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
// HEXEN : Zeroth
|
||||
struct r_vmodes_type {
|
||||
int width;
|
||||
int height;
|
||||
int ratio;
|
||||
};
|
||||
|
||||
typedef struct entityState_s {
|
||||
int entityNumber;
|
||||
idBitMsg state;
|
||||
|
@ -232,6 +243,7 @@ public:
|
|||
int firstFreeIndex; // first free index in the entities array
|
||||
int num_entities; // current number <= MAX_GENTITIES
|
||||
idHashIndex entityHash; // hash table to quickly find entities by name
|
||||
idHashIndex entypeHash; // hash table to quickly find entities by type (works in paralel with entityHash)
|
||||
idWorldspawn * world; // world entity
|
||||
idLinkList<idEntity> spawnedEntities; // all spawned entities
|
||||
idLinkList<idEntity> activeEntities; // all thinking entities (idEntity::thinkFlags != 0)
|
||||
|
@ -273,6 +285,7 @@ public:
|
|||
int previousTime; // time in msec of last frame
|
||||
int time; // in msec
|
||||
static const int msec = USERCMD_MSEC; // time since last update in milliseconds
|
||||
bool paused;
|
||||
|
||||
int vacuumAreaNum; // -1 if level doesn't have any outside areas
|
||||
|
||||
|
@ -294,6 +307,15 @@ public:
|
|||
idEntityPtr<idEntity> lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f
|
||||
int lastGUI; // last GUI on the lastGUIEnt
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
idEntityPtr<idEntity> portalSkyEnt;
|
||||
bool portalSkyActive;
|
||||
void SetPortalSkyEnt( idEntity *ent );
|
||||
bool IsPortalSkyAcive();
|
||||
r_vmodes_type r_vmodes[EOC_NUM_VMODES];
|
||||
int r_vmode;
|
||||
|
||||
// ---------------------- Public idGame Interface -------------------
|
||||
|
||||
idGameLocal();
|
||||
|
@ -387,6 +409,9 @@ public:
|
|||
bool InPlayerPVS( idEntity *ent ) const;
|
||||
bool InPlayerConnectedArea( idEntity *ent ) const;
|
||||
|
||||
public:
|
||||
pvsHandle_t GetPlayerPVS() { return playerPVS; };
|
||||
|
||||
void SetCamera( idCamera *cam );
|
||||
idCamera * GetCamera( void ) const;
|
||||
bool SkipCinematic( void );
|
||||
|
@ -402,12 +427,16 @@ public:
|
|||
static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) );
|
||||
idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const;
|
||||
idEntity * FindEntity( const char *name ) const;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
idEntity * FindEntityType( const idTypeInfo &type ) const;
|
||||
|
||||
idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const;
|
||||
int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const;
|
||||
|
||||
void KillBox( idEntity *ent, bool catch_teleport = false );
|
||||
void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f );
|
||||
void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake );
|
||||
void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake, const bool notlocalplayer=false, const bool notprojectiles=true );
|
||||
void RadiusPushClipModel( const idVec3 &origin, const float push, const idClipModel *clipModel );
|
||||
|
||||
void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 );
|
||||
|
@ -448,6 +477,31 @@ public:
|
|||
|
||||
bool NeedRestart();
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// ****** thanks SnoopJeDi ( http://www.doom3world.org/phpbb2/viewtopic.php?f=56&t=12469&p=214427#p214427 )
|
||||
idList<int> musicSpeakers; //SnoopJeDi - holds entitynum values for speakers with s_music set
|
||||
// ******
|
||||
void SetLocalPlayerSpawnPoint(idStr point);
|
||||
// void FoliageRendering( void );
|
||||
idStr eoc_MapPath;
|
||||
void InitHub(void);
|
||||
void SendLocalUserHudMessage( const char *message );
|
||||
void SendLocalUserHudMessage( idStr message );
|
||||
void UpdateFog( void );
|
||||
void SetPersistentRemove( const char *name );
|
||||
void SetPersistentLightOn( const char *name, bool state );
|
||||
void SetPersistentLightBroken( const char *name );
|
||||
void SetPersistentTrigger( const char *type, const char *name, const bool state );
|
||||
void SetPersistentTriggerInt( const char *type, const char *var, const char *name, int val );
|
||||
void SavePersistentMoveables(void);
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
idStr eoc_LocalPlayerSpawnPoint;
|
||||
float eoc_MapLoading;
|
||||
float eoc_MapLoadingPrev;
|
||||
idStr mapNameForCheat;
|
||||
idList<idVec3 *> BanishLocationList;
|
||||
|
||||
private:
|
||||
const static int INITIAL_SPAWN_COUNT = 1;
|
||||
const static int INTERNAL_SAVEGAME_VERSION = 1; // DG: added this for >= 1305 savegames
|
||||
|
@ -653,6 +707,7 @@ typedef enum {
|
|||
} gameSoundChannel_t;
|
||||
|
||||
extern const float DEFAULT_GRAVITY;
|
||||
const idVec3 DEFAULT_GRAVITY_NORMAL = idVec3( 0, 0, -1 ); // HEXEN : Zeroth
|
||||
extern const idVec3 DEFAULT_GRAVITY_VEC3;
|
||||
extern const int CINEMATIC_SKIP_DELAY;
|
||||
|
||||
|
|
|
@ -589,6 +589,19 @@ void idGameLocal::ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &ms
|
|||
numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS );
|
||||
pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// Add portalSky areas to PVS
|
||||
if ( portalSkyEnt.GetEntity() ) {
|
||||
pvsHandle_t otherPVS, newPVS;
|
||||
idEntity *skyEnt = portalSkyEnt.GetEntity();
|
||||
|
||||
otherPVS = gameLocal.pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() );
|
||||
newPVS = gameLocal.pvs.MergeCurrentPVS( pvsHandle, otherPVS );
|
||||
pvs.FreeCurrentPVS( pvsHandle );
|
||||
pvs.FreeCurrentPVS( otherPVS );
|
||||
pvsHandle = newPVS;
|
||||
}
|
||||
|
||||
#if ASYNC_WRITE_TAGS
|
||||
idRandom tagRandom;
|
||||
tagRandom.SetSeed( random.RandomInt() );
|
||||
|
@ -1120,6 +1133,19 @@ void idGameLocal::ClientReadSnapshot( int clientNum, int sequence, const int gam
|
|||
numSourceAreas = gameRenderWorld->BoundsInAreas( spectated->GetPlayerPhysics()->GetAbsBounds(), sourceAreas, idEntity::MAX_PVS_AREAS );
|
||||
pvsHandle = gameLocal.pvs.SetupCurrentPVS( sourceAreas, numSourceAreas, PVS_NORMAL );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// Add portalSky areas to PVS
|
||||
if ( portalSkyEnt.GetEntity() ) {
|
||||
pvsHandle_t otherPVS, newPVS;
|
||||
idEntity *skyEnt = portalSkyEnt.GetEntity();
|
||||
|
||||
otherPVS = gameLocal.pvs.SetupCurrentPVS( skyEnt->GetPVSAreas(), skyEnt->GetNumPVSAreas() );
|
||||
newPVS = gameLocal.pvs.MergeCurrentPVS( pvsHandle, otherPVS );
|
||||
pvs.FreeCurrentPVS( pvsHandle );
|
||||
pvs.FreeCurrentPVS( otherPVS );
|
||||
pvsHandle = newPVS;
|
||||
}
|
||||
|
||||
// read the PVS from the snapshot
|
||||
#if ASYNC_WRITE_PVS
|
||||
int serverPVS[idEntity::MAX_PVS_AREAS];
|
||||
|
|
507
game/Item.cpp
507
game/Item.cpp
|
@ -50,6 +50,18 @@ const idEventDef EV_RespawnFx( "<respawnFx>" );
|
|||
const idEventDef EV_GetPlayerPos( "<getplayerpos>" );
|
||||
const idEventDef EV_HideObjective( "<hideobjective>", "e" );
|
||||
const idEventDef EV_CamShot( "<camshot>" );
|
||||
const idEventDef EV_SetNextState( "setNextState", "s" );
|
||||
const idEventDef EV_SetState( "setState", "s" );
|
||||
const idEventDef EV_GetState( "getState", NULL, 's' );
|
||||
// HEXEN : Zeroth
|
||||
const idEventDef EV_ArtifactStart( "ArtifactStart" );
|
||||
const idEventDef EV_ArtifactCoolDown( "ArtifactCoolDown" );
|
||||
const idEventDef EV_ArtifactDone( "ArtifactDone" );
|
||||
const idEventDef EV_SetArtifactActive( "ArtifactActive", "f" );
|
||||
const idEventDef EV_OwnerLaunchProjectiles( "OwnerLaunchProjectiles", "dffff" );
|
||||
const idEventDef EV_OwnerCreateProjectile( "OwnerCreateProjectile", NULL, 'e' );
|
||||
const idEventDef EV_GetOwner( "GetOwner", NULL, 'e' );
|
||||
const idEventDef EV_HideMultiModel( "HideMultiModel" );
|
||||
|
||||
CLASS_DECLARATION( idEntity, idItem )
|
||||
EVENT( EV_DropToFloor, idItem::Event_DropToFloor )
|
||||
|
@ -57,6 +69,18 @@ CLASS_DECLARATION( idEntity, idItem )
|
|||
EVENT( EV_Activate, idItem::Event_Trigger )
|
||||
EVENT( EV_RespawnItem, idItem::Event_Respawn )
|
||||
EVENT( EV_RespawnFx, idItem::Event_RespawnFx )
|
||||
// EVENT( EV_SetNextState, idItem::Event_SetNextState )
|
||||
// EVENT( EV_SetState, idItem::Event_SetState )
|
||||
// EVENT( EV_GetState, idItem::Event_GetState )
|
||||
// HEXEN : Zeroth
|
||||
EVENT( EV_ArtifactStart, idItem::Event_ArtifactStart )
|
||||
EVENT( EV_ArtifactDone, idItem::Event_ArtifactDone )
|
||||
EVENT( EV_ArtifactCoolDown, idItem::Event_ArtifactCoolDown )
|
||||
EVENT( EV_SetArtifactActive, idItem::Event_SetArtifactActive )
|
||||
EVENT( EV_OwnerLaunchProjectiles, idItem::Event_OwnerLaunchProjectiles )
|
||||
EVENT( EV_OwnerCreateProjectile, idItem::Event_OwnerCreateProjectile )
|
||||
EVENT( EV_GetOwner, idItem::Event_GetOwner )
|
||||
EVENT( EV_HideMultiModel, idItem::Event_HideMultiModel )
|
||||
END_CLASS
|
||||
|
||||
|
||||
|
@ -76,6 +100,12 @@ idItem::idItem() {
|
|||
orgOrigin.Zero();
|
||||
canPickUp = true;
|
||||
fl.networkSync = true;
|
||||
|
||||
owner = NULL;
|
||||
DeleteMe = false;
|
||||
Cooling = false;
|
||||
ArtifactActive = false;
|
||||
Processing = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,6 +118,99 @@ idItem::~idItem() {
|
|||
if ( itemShellHandle != -1 ) {
|
||||
gameRenderWorld->FreeEntityDef( itemShellHandle );
|
||||
}
|
||||
|
||||
if ( multimodel ) {
|
||||
delete multimodel;
|
||||
}
|
||||
|
||||
//z.todo: necessary???
|
||||
// delete scriptThread;
|
||||
// DeconstructScriptObject();
|
||||
// scriptObject.Free();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Hide
|
||||
================
|
||||
*/
|
||||
void idItem::Hide( void ) {
|
||||
if ( !idEntity::IsHidden() ) {
|
||||
idEntity::Hide();
|
||||
if ( multimodel ) {
|
||||
multimodel->Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_ArtifactStart
|
||||
================
|
||||
*/
|
||||
void idItem::Event_ArtifactStart( void ) {
|
||||
if ( owner != NULL ) {
|
||||
Processing = true;
|
||||
|
||||
owner->RemoveInventoryItem(spawnArgs.GetString("inv_name"));
|
||||
owner->UpdateHudArtifacts();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_ArtifactDone
|
||||
================
|
||||
*/
|
||||
void idItem::Event_ArtifactDone( void ) {
|
||||
if ( owner != NULL ) {
|
||||
Cooling = false;
|
||||
DeleteMe = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_ArtifactCoolDown
|
||||
================
|
||||
*/
|
||||
void idItem::Event_ArtifactCoolDown( void ) {
|
||||
if ( owner != NULL ) {
|
||||
Cooling = true;
|
||||
owner->UpdateHudActiveArtifacts();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_SetArtifactActive
|
||||
================
|
||||
*/
|
||||
void idItem::Event_SetArtifactActive( const float yesorno ) {
|
||||
if ( owner != NULL ) {
|
||||
if ( yesorno ) {
|
||||
ArtifactActive = true;
|
||||
owner->UpdateHudActiveArtifacts();
|
||||
} else {
|
||||
ArtifactActive = false;
|
||||
owner->UpdateHudActiveArtifacts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_GetOwner
|
||||
================
|
||||
*/
|
||||
void idItem::Event_GetOwner( void ) {
|
||||
idThread::ReturnEntity( owner );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -108,6 +231,42 @@ void idItem::Save( idSaveGame *savefile ) const {
|
|||
savefile->WriteInt( inViewTime );
|
||||
savefile->WriteInt( lastCycle );
|
||||
savefile->WriteInt( lastRenderViewTime );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->WriteObject( scriptThread );
|
||||
savefile->WriteString( waitState );
|
||||
|
||||
//FIXME: this is unneccesary
|
||||
idToken token;
|
||||
// HEXEN : Zeroth
|
||||
if ( state ) {
|
||||
idLexer src( state->Name(), idStr::Length( state->Name() ), "idItem::Save" );
|
||||
|
||||
src.ReadTokenOnLine( &token );
|
||||
src.ExpectTokenString( "::" );
|
||||
src.ReadTokenOnLine( &token );
|
||||
|
||||
savefile->WriteString( token );
|
||||
} else {
|
||||
savefile->WriteString( "" );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
if ( idealState ) {
|
||||
idLexer src( idealState->Name(), idStr::Length( idealState->Name() ), "idItem::Save" );
|
||||
|
||||
src.ReadTokenOnLine( &token );
|
||||
src.ExpectTokenString( "::" );
|
||||
src.ReadTokenOnLine( &token );
|
||||
|
||||
savefile->WriteString( token );
|
||||
} else {
|
||||
savefile->WriteString( "" );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->WriteObject( projectileEnt );
|
||||
savefile->WriteObject( multimodel );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -130,6 +289,35 @@ void idItem::Restore( idRestoreGame *savefile ) {
|
|||
savefile->ReadInt( lastRenderViewTime );
|
||||
|
||||
itemShellHandle = -1;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>( scriptThread ) );
|
||||
savefile->ReadString( waitState );
|
||||
idStr statename;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->ReadString( statename );
|
||||
if ( statename.Length() > 0 ) {
|
||||
state = GetScriptFunction( statename );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->ReadString( statename );
|
||||
if ( statename.Length() > 0 ) {
|
||||
idealState = GetScriptFunction( statename );
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( spawnArgs.GetString( "def_projectile" ), false );
|
||||
if ( projectileDef ) {
|
||||
projectileDict = projectileDef->dict;
|
||||
} else {
|
||||
projectileDict.Clear();
|
||||
}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>( projectileEnt ) );
|
||||
savefile->ReadObject( reinterpret_cast<idClass *&>( multimodel ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,7 +415,7 @@ void idItem::Think( void ) {
|
|||
ang.yaw = ( gameLocal.time & 4095 ) * 360.0f / -4096.0f;
|
||||
SetAngles( ang );
|
||||
|
||||
float scale = 0.005f + entityNumber * 0.00001f;
|
||||
float scale = 0.005f;
|
||||
|
||||
org = orgOrigin;
|
||||
org.z += 4.0f + cos( ( gameLocal.time + 2000 ) * scale ) * 4.0f;
|
||||
|
@ -236,6 +424,11 @@ void idItem::Think( void ) {
|
|||
}
|
||||
|
||||
Present();
|
||||
|
||||
if ( !IsHidden() && multimodel ) {
|
||||
multimodel->GetPhysics()->SetOrigin( GetPhysics()->GetOrigin() ); // bob up and down in unison
|
||||
multimodel->SetAngles( -GetAngles() ); // make it spin the opposite direction
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -275,6 +468,30 @@ void idItem::Spawn( void ) {
|
|||
idStr giveTo;
|
||||
idEntity * ent;
|
||||
float tsize;
|
||||
const char *projectileName;
|
||||
|
||||
state = NULL;
|
||||
idealState = NULL;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// get the projectile
|
||||
projectileDict.Clear();
|
||||
|
||||
projectileName = spawnArgs.GetString( "def_projectile" );
|
||||
if ( projectileName[0] != '\0' ) {
|
||||
const idDeclEntityDef *projectileDef = gameLocal.FindEntityDef( projectileName, false );
|
||||
if ( !projectileDef ) {
|
||||
gameLocal.Warning( "Unknown projectile '%s' in item '%s'", projectileName, spawnArgs.GetString("inv_name") );
|
||||
} else {
|
||||
const char *spawnclass = projectileDef->dict.GetString( "spawnclass" );
|
||||
idTypeInfo *cls = idClass::GetClass( spawnclass );
|
||||
if ( !cls || !cls->IsType( idProjectile::Type ) ) {
|
||||
gameLocal.Warning( "Invalid spawnclass '%s' on projectile '%s' (used by item '%s')", spawnclass, projectileName, spawnArgs.GetString("inv_name") );
|
||||
} else {
|
||||
projectileDict = projectileDef->dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( spawnArgs.GetBool( "dropToFloor" ) ) {
|
||||
PostEventMS( &EV_DropToFloor, 0 );
|
||||
|
@ -317,6 +534,18 @@ void idItem::Spawn( void ) {
|
|||
lastCycle = -1;
|
||||
itemShellHandle = -1;
|
||||
shellMaterial = declManager->FindMaterial( "itemHighlightShell" );
|
||||
|
||||
multimodel=NULL;
|
||||
idStr mstr=spawnArgs.GetString("multimodel");
|
||||
|
||||
if ( mstr != "" ) {
|
||||
const idDict *multimodeldef = gameLocal.FindEntityDefDict( mstr.c_str() );
|
||||
if ( gameLocal.SpawnEntityDef( *multimodeldef, &multimodel ) && multimodel ) {
|
||||
multimodel->GetPhysics()->SetOrigin( GetPhysics()->GetOrigin() ); // bob up and down in unison
|
||||
multimodel->SetAngles( -GetAngles() ); // make it spin the opposite direction
|
||||
spawnArgs.Set( "multimodel_name", multimodel->GetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -346,11 +575,26 @@ bool idItem::GiveToPlayer( idPlayer *player ) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool val = false;
|
||||
|
||||
if ( spawnArgs.GetBool( "inv_carry" ) ) {
|
||||
return player->GiveInventoryItem( &spawnArgs );
|
||||
val = player->GiveInventoryItem( this );
|
||||
} else {
|
||||
val = player->GiveItem( this );
|
||||
}
|
||||
|
||||
return player->GiveItem( this );
|
||||
if ( val ) {
|
||||
if ( spawnArgs.GetString("scriptobject") != "" ) {
|
||||
if ( !g_noPickupNotification.GetBool() && !spawnArgs.GetBool("dontNotifyOnPickup") ) {
|
||||
CallFunc( "pickup_message" );
|
||||
}
|
||||
CallFunc( "pickup_effect" );
|
||||
}
|
||||
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -369,7 +613,9 @@ bool idItem::Pickup( idPlayer *player ) {
|
|||
}
|
||||
|
||||
// play pickup sound
|
||||
StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL );
|
||||
if ( !g_noPickupNotification.GetBool() ) {
|
||||
StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL );
|
||||
}
|
||||
|
||||
// trigger our targets
|
||||
ActivateTargets( player );
|
||||
|
@ -508,15 +754,46 @@ idItem::Event_Touch
|
|||
================
|
||||
*/
|
||||
void idItem::Event_Touch( idEntity *other, trace_t *trace ) {
|
||||
idPlayer *player;
|
||||
|
||||
if ( !other->IsType( idPlayer::Type ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
player = static_cast<idPlayer *>( other );
|
||||
|
||||
if ( !canPickUp ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pickup( static_cast<idPlayer *>(other) );
|
||||
|
||||
player->CleanupArtifactItems();
|
||||
|
||||
// pickup delay for this player, to prevent instant pickup after drop.
|
||||
|
||||
if ( player == lastOwner && spawnArgs.GetBool( "eoc_dropped" ) ) {
|
||||
if ( PickupDelayTime < MS2SEC( gameLocal.realClientTime ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// I don't know why this happens, but it does. seems the player can hit an item multiple times and trigger this pickupevent before he has a chance to disappear after picking it up the first time.
|
||||
if ( player == owner ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( spawnArgs.GetBool( "instantEffect" ) && player->ActiveArtifact( spawnArgs.GetString( "inv_name" ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't pickup if we're full on 'em
|
||||
if ( spawnArgs.FindKey("artifact") ) {
|
||||
if ( spawnArgs.GetInt( "max_inventory" ) > 0 && player->InventoryItemQty(spawnArgs.GetString( "inv_name" )) >= spawnArgs.GetInt( "max_inventory" ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Pickup( static_cast<idPlayer *>( other ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -637,9 +914,141 @@ bool idItemPowerup::GiveToPlayer( idPlayer *player ) {
|
|||
return false;
|
||||
}
|
||||
player->GivePowerUp( type, time * 1000 );
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_OwnerLaunchProjectiles
|
||||
================
|
||||
*/
|
||||
void idItem::Event_OwnerLaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower ) {
|
||||
idProjectile *proj;
|
||||
idEntity *ent;
|
||||
int i;
|
||||
idVec3 dir;
|
||||
float ang;
|
||||
float spin;
|
||||
float distance;
|
||||
trace_t tr;
|
||||
idVec3 start;
|
||||
idVec3 muzzle_pos;
|
||||
idBounds ownerBounds, projBounds;
|
||||
|
||||
idVec3 playerViewOrigin;
|
||||
idMat3 playerViewAxis;
|
||||
idVec3 zzero;
|
||||
|
||||
zzero.Zero();
|
||||
|
||||
playerViewOrigin.Zero();
|
||||
playerViewAxis.Zero();
|
||||
|
||||
playerViewOrigin = owner->firstPersonViewOrigin;
|
||||
playerViewAxis = owner->firstPersonViewAxis;
|
||||
|
||||
if ( !projectileDict.GetNumKeyVals() ) {
|
||||
const char *classname = this->spawnArgs.GetString("inv_name");
|
||||
gameLocal.Warning( "No projectile defined on '%s'", classname );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gameLocal.isClient ) {
|
||||
// predict instant hit projectiles
|
||||
if ( projectileDict.GetBool( "net_instanthit" ) ) {
|
||||
float spreadRad = DEG2RAD( spread );
|
||||
muzzle_pos = playerViewOrigin + playerViewAxis[ 0 ] * 2.0f;
|
||||
for( i = 0; i < num_projectiles; i++ ) {
|
||||
ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() );
|
||||
spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat();
|
||||
dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) );
|
||||
dir.Normalize();
|
||||
gameLocal.clip.Translation( tr, muzzle_pos, muzzle_pos + dir * 4096.0f, NULL, mat3_identity, MASK_SHOT_RENDERMODEL, owner );
|
||||
if ( tr.fraction < 1.0f ) {
|
||||
idProjectile::ClientPredictionCollide( this, projectileDict, tr, vec3_origin, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ownerBounds = owner->GetPhysics()->GetAbsBounds();
|
||||
|
||||
owner->AddProjectilesFired( num_projectiles );
|
||||
|
||||
float spreadRad = DEG2RAD( spread );
|
||||
for( i = 0; i < num_projectiles; i++ ) {
|
||||
ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() );
|
||||
spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat();
|
||||
dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) );
|
||||
dir.Normalize();
|
||||
|
||||
if ( projectileEnt ) {
|
||||
ent = projectileEnt;
|
||||
ent->Show();
|
||||
ent->Unbind();
|
||||
projectileEnt = NULL;
|
||||
} else {
|
||||
gameLocal.SpawnEntityDef( projectileDict, &ent, false );
|
||||
}
|
||||
|
||||
if ( !ent || !ent->IsType( idProjectile::Type ) ) {
|
||||
const char *projectileName = this->spawnArgs.GetString( "def_projectile" );
|
||||
gameLocal.Error( "'%s' is not an idProjectile", projectileName );
|
||||
}
|
||||
|
||||
if ( projectileDict.GetBool( "net_instanthit" ) ) {
|
||||
// don't synchronize this on top of the already predicted effect
|
||||
ent->fl.networkSync = false;
|
||||
}
|
||||
|
||||
proj = static_cast<idProjectile *>(ent);
|
||||
proj->Create( owner, playerViewOrigin, dir );
|
||||
|
||||
projBounds = proj->GetPhysics()->GetBounds().Rotate( proj->GetPhysics()->GetAxis() );
|
||||
|
||||
// make sure the projectile starts inside the bounding box of the owner
|
||||
if ( i == 0 ) {
|
||||
muzzle_pos = playerViewOrigin + playerViewAxis[ 0 ] * 2.0f;
|
||||
if ( ( ownerBounds - projBounds).RayIntersection( muzzle_pos, playerViewAxis[0], distance ) ) {
|
||||
start = muzzle_pos + distance * playerViewAxis[0];
|
||||
} else {
|
||||
start = ownerBounds.GetCenter();
|
||||
}
|
||||
gameLocal.clip.Translation( tr, start, muzzle_pos, proj->GetPhysics()->GetClipModel(), proj->GetPhysics()->GetClipModel()->GetAxis(), MASK_SHOT_RENDERMODEL, owner );
|
||||
muzzle_pos = tr.endpos;
|
||||
}
|
||||
|
||||
proj->Launch( muzzle_pos, dir, zzero, fuseOffset, launchPower, dmgPower );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_OwnerCreateProjectile
|
||||
================
|
||||
*/
|
||||
void idItem::Event_OwnerCreateProjectile( void ) {
|
||||
if ( !gameLocal.isClient ) {
|
||||
projectileEnt = NULL;
|
||||
gameLocal.SpawnEntityDef( projectileDict, &projectileEnt, false );
|
||||
if ( projectileEnt ) {
|
||||
projectileEnt->SetOrigin( GetPhysics()->GetOrigin() );
|
||||
projectileEnt->Bind( owner, false );
|
||||
projectileEnt->Hide();
|
||||
}
|
||||
idThread::ReturnEntity( projectileEnt );
|
||||
} else {
|
||||
idThread::ReturnEntity( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -712,6 +1121,43 @@ void idObjective::Event_CamShot( ) {
|
|||
renderView_t fullView = *view;
|
||||
fullView.width = SCREEN_WIDTH;
|
||||
fullView.height = SCREEN_HEIGHT;
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// HACK : always draw sky-portal view if there is one in the map, this isn't real-time
|
||||
if ( gameLocal.portalSkyEnt.GetEntity() && g_enablePortalSky.GetBool() ) {
|
||||
renderView_t portalView = fullView;
|
||||
portalView.vieworg = gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetOrigin();
|
||||
|
||||
// setup global fixup projection vars
|
||||
#if 1
|
||||
int vidWidth, vidHeight;
|
||||
idVec2 shiftScale;
|
||||
|
||||
renderSystem->GetGLSettings( vidWidth, vidHeight );
|
||||
|
||||
float pot;
|
||||
int temp;
|
||||
|
||||
int w = vidWidth;
|
||||
for (temp = 1 ; temp < w ; temp<<=1) {
|
||||
}
|
||||
pot = (float)temp;
|
||||
shiftScale.x = (float)w / pot;
|
||||
|
||||
int h = vidHeight;
|
||||
for (temp = 1 ; temp < h ; temp<<=1) {
|
||||
}
|
||||
pot = (float)temp;
|
||||
shiftScale.y = (float)h / pot;
|
||||
|
||||
fullView.shaderParms[4] = shiftScale.x;
|
||||
fullView.shaderParms[5] = shiftScale.y;
|
||||
#endif
|
||||
|
||||
gameRenderWorld->RenderScene( &portalView );
|
||||
renderSystem->CaptureRenderToImage( "_currentRender" );
|
||||
}
|
||||
|
||||
// draw a view to a texture
|
||||
renderSystem->CropRenderSize( 256, 256, true );
|
||||
gameRenderWorld->RenderScene( &fullView );
|
||||
|
@ -821,6 +1267,7 @@ bool idVideoCDItem::GiveToPlayer( idPlayer *player ) {
|
|||
if ( player && str.Length() ) {
|
||||
player->GiveVideo( str, &spawnArgs );
|
||||
}
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -845,6 +1292,7 @@ bool idPDAItem::GiveToPlayer(idPlayer *player) {
|
|||
if ( player ) {
|
||||
player->GivePDA( str, &spawnArgs );
|
||||
}
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1203,6 +1651,7 @@ bool idMoveablePDAItem::GiveToPlayer(idPlayer *player) {
|
|||
if ( player ) {
|
||||
player->GivePDA( str, &spawnArgs );
|
||||
}
|
||||
gameLocal.SetPersistentRemove( name.c_str() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1356,3 +1805,51 @@ void idObjectiveComplete::Event_HideObjective( idEntity *e ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::SetOwner
|
||||
================
|
||||
*/
|
||||
void idItem::SetOwner( idPlayer *_owner ) {
|
||||
assert( !owner );
|
||||
owner = _owner;
|
||||
lastOwner = _owner;
|
||||
// SetName( va( "%s_weapon", owner->name.c_str() ) );
|
||||
|
||||
// if ( worldModel.GetEntity() ) {
|
||||
// worldModel.GetEntity()->SetName( va( "%s_weapon_worldmodel", owner->name.c_str() ) );
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::CallFunc
|
||||
================
|
||||
*/
|
||||
bool idItem::CallFunc( char *funcName ) {
|
||||
const function_t *func = GetScriptFunction( (const char*) funcName );
|
||||
if ( !func ) {
|
||||
assert( 0 );
|
||||
gameLocal.Error( "Can't find function use' in object '%s'", scriptObject.GetTypeName() );
|
||||
return false;
|
||||
}
|
||||
|
||||
SetState( func );
|
||||
UpdateScript();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idItem::Event_HideMultiModel
|
||||
================
|
||||
*/
|
||||
void idItem::Event_HideMultiModel() {
|
||||
if ( multimodel ) {
|
||||
multimodel->Hide();
|
||||
}
|
||||
}
|
||||
|
|
51
game/Item.h
51
game/Item.h
|
@ -56,6 +56,14 @@ public:
|
|||
virtual bool Pickup( idPlayer *player );
|
||||
virtual void Think( void );
|
||||
virtual void Present();
|
||||
void Hide();
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
void SetOwner( idPlayer *owner );
|
||||
idPlayer* GetOwner( void );
|
||||
idPlayer* GetLastOwner( void );
|
||||
bool CallFunc( char *funcName );
|
||||
|
||||
enum {
|
||||
EVENT_PICKUP = idEntity::EVENT_MAXEVENTS,
|
||||
|
@ -71,6 +79,20 @@ public:
|
|||
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsgDelta &msg );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
bool DeleteMe; // whether this artifact should be deleted in the next artifact cleanup (in player.cpp)
|
||||
bool ArtifactActive; // whether this artifact is active (valid for time-based effects)
|
||||
bool Processing; // whether this artifacts script is busy
|
||||
bool Cooling; // whether artifact is in cooldown mode
|
||||
int PickupDelayTime; // time in seconds for how long we should wait before letting a player pick up the item he dropped (necessary to prevent instant pickup afte drop)
|
||||
|
||||
// HEXEN : Zeroth
|
||||
private:
|
||||
idPlayer* owner;
|
||||
idPlayer* lastOwner;
|
||||
|
||||
|
||||
private:
|
||||
idVec3 orgOrigin;
|
||||
bool spin;
|
||||
|
@ -95,6 +117,27 @@ private:
|
|||
void Event_Trigger( idEntity *activator );
|
||||
void Event_Respawn( void );
|
||||
void Event_RespawnFx( void );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
private:
|
||||
idDict projectileDict;
|
||||
idEntity *projectileEnt;
|
||||
// void Event_GetState( void );
|
||||
// void Event_SetState( const char *name );
|
||||
// void Event_SetNextState( const char *name );
|
||||
void Event_ArtifactStart( void );
|
||||
void Event_Artifact( void );
|
||||
void Event_ArtifactDone( void );
|
||||
void Event_ArtifactCoolDown( void );
|
||||
void Event_SetArtifactActive( const float yesorno );
|
||||
void Event_OwnerLaunchProjectiles( int num_projectiles, float spread, float fuseOffset, float launchPower, float dmgPower );
|
||||
void Event_OwnerCreateProjectile( void );
|
||||
void Event_GetOwner( void );
|
||||
|
||||
// MultiModel
|
||||
void Event_HideMultiModel( void );
|
||||
public:
|
||||
idEntity *multimodel;
|
||||
};
|
||||
|
||||
class idItemPowerup : public idItem {
|
||||
|
@ -226,4 +269,12 @@ private:
|
|||
void Event_GetPlayerPos();
|
||||
};
|
||||
|
||||
ID_INLINE idPlayer* idItem::GetOwner( void ) {
|
||||
return owner;
|
||||
}
|
||||
|
||||
ID_INLINE idPlayer* idItem::GetLastOwner( void ) {
|
||||
return lastOwner;
|
||||
}
|
||||
|
||||
#endif /* !__GAME_ITEM_H__ */
|
||||
|
|
|
@ -567,6 +567,7 @@ idLight::On
|
|||
================
|
||||
*/
|
||||
void idLight::On( void ) {
|
||||
gameLocal.SetPersistentLightOn( name.c_str(), true );
|
||||
currentLevel = levels;
|
||||
// offset the start time of the shader to sync it to the game time
|
||||
renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
|
||||
|
@ -584,6 +585,7 @@ idLight::Off
|
|||
================
|
||||
*/
|
||||
void idLight::Off( void ) {
|
||||
gameLocal.SetPersistentLightOn( name.c_str(), false );
|
||||
currentLevel = 0;
|
||||
// kill any sound it was making
|
||||
if ( refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) {
|
||||
|
@ -646,6 +648,7 @@ idLight::BecomeBroken
|
|||
================
|
||||
*/
|
||||
void idLight::BecomeBroken( idEntity *activator ) {
|
||||
gameLocal.SetPersistentLightBroken( name.c_str() );
|
||||
const char *damageDefName;
|
||||
|
||||
fl.takedamage = false;
|
||||
|
|
383
game/Misc.cpp
383
game/Misc.cpp
|
@ -2305,13 +2305,60 @@ CLASS_DECLARATION( idEntity, idLiquid )
|
|||
EVENT( EV_Touch, idLiquid::Event_Touch )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idLiquid::idLiquid
|
||||
================
|
||||
*/
|
||||
idLiquid::idLiquid( void ) {
|
||||
clipModel = NULL;
|
||||
touchingEntities.Clear();
|
||||
flagEntities.Clear();
|
||||
//resistTimeEntities.Clear();
|
||||
|
||||
// HEXEN : Zeroth - for limit entity types
|
||||
dontTripby_LocalPlayer = false;
|
||||
limitEntityType = false;
|
||||
tripby_idPlayer = false;
|
||||
tripby_idAI = false;
|
||||
tripby_idMoveable = false;
|
||||
tripby_idItem = false;
|
||||
tripby_idActor = false;
|
||||
tripby_idProjectile = false;
|
||||
|
||||
particleOnExit = false; // whether to spawn a particle when something leaves the water
|
||||
moveResistance = 0;
|
||||
moveDir.Zero();
|
||||
moveAmt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idLiquid::Save
|
||||
================
|
||||
*/
|
||||
void idLiquid::Save( idSaveGame *savefile ) const {
|
||||
// Nothing to save
|
||||
// HEXEN : Zeroth
|
||||
savefile->WriteClipModel( clipModel );
|
||||
savefile->WriteBool( limitEntityType );
|
||||
savefile->WriteBool( dontTripby_LocalPlayer );
|
||||
savefile->WriteBool( tripby_idPlayer );
|
||||
savefile->WriteBool( tripby_idAI );
|
||||
savefile->WriteBool( tripby_idMoveable );
|
||||
savefile->WriteBool( tripby_idItem );
|
||||
savefile->WriteBool( tripby_idActor );
|
||||
savefile->WriteBool( tripby_idProjectile );
|
||||
savefile->WriteBool( particleOnExit );
|
||||
savefile->WriteVec3( moveDir );
|
||||
savefile->WriteFloat( moveAmt );
|
||||
savefile->WriteFloat( moveResistance );
|
||||
|
||||
savefile->WriteInt( touchingEntities.Num() );
|
||||
for ( int i = 0; i < touchingEntities.Num(); i++ ) {
|
||||
savefile->WriteString( touchingEntities[i] );
|
||||
savefile->WriteBool( flagEntities[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2322,6 +2369,32 @@ idLiquid::Restore
|
|||
void idLiquid::Restore( idRestoreGame *savefile ) {
|
||||
//FIXME: NO!
|
||||
Spawn();
|
||||
|
||||
// HEXEN : Zeroth
|
||||
savefile->ReadClipModel( clipModel );
|
||||
savefile->ReadBool( limitEntityType );
|
||||
savefile->ReadBool( dontTripby_LocalPlayer );
|
||||
savefile->ReadBool( tripby_idPlayer );
|
||||
savefile->ReadBool( tripby_idAI );
|
||||
savefile->ReadBool( tripby_idMoveable );
|
||||
savefile->ReadBool( tripby_idItem );
|
||||
savefile->ReadBool( tripby_idActor );
|
||||
savefile->ReadBool( tripby_idProjectile );
|
||||
savefile->ReadBool( particleOnExit );
|
||||
savefile->ReadVec3( moveDir );
|
||||
savefile->ReadFloat( moveAmt );
|
||||
savefile->ReadFloat( moveResistance );
|
||||
|
||||
bool bol;
|
||||
int num;
|
||||
idStr str;
|
||||
savefile->ReadInt( num );
|
||||
for ( int i = 0; i < num; i++ ) {
|
||||
savefile->ReadString( str );
|
||||
touchingEntities.Append( str );
|
||||
savefile->ReadBool( bol );
|
||||
flagEntities.Append( bol );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2338,6 +2411,56 @@ void idLiquid::Spawn() {
|
|||
model->Reset();
|
||||
GetPhysics()->SetContents( CONTENTS_TRIGGER );
|
||||
*/
|
||||
// HEXEN : Zeroth - create clip model. copied from idTrigger_Touch
|
||||
clipModel = new idClipModel( GetPhysics()->GetClipModel() ); // get the clip model
|
||||
//GetPhysics()->SetClipModel( NULL, 1.0f ); // remove the collision model from the physics object
|
||||
BecomeActive( TH_THINK );
|
||||
|
||||
// HEXEN : Zeroth - for limit entity types
|
||||
spawnArgs.GetBool( "dontTripby_LocalPlayer", "0", dontTripby_LocalPlayer );
|
||||
spawnArgs.GetBool( "limitEntityType", "0", limitEntityType );
|
||||
spawnArgs.GetBool( "tripby_idPlayer", "0", tripby_idPlayer );
|
||||
spawnArgs.GetBool( "tripby_idAI", "0", tripby_idAI );
|
||||
spawnArgs.GetBool( "tripby_idMoveable", "0", tripby_idMoveable );
|
||||
spawnArgs.GetBool( "tripby_idItem", "0", tripby_idItem );
|
||||
spawnArgs.GetBool( "tripby_idActor", "0", tripby_idActor );
|
||||
spawnArgs.GetBool( "tripby_idProjectile", "0", tripby_idProjectile );
|
||||
spawnArgs.GetBool( "doParticleOnExit", "0", particleOnExit );
|
||||
|
||||
splashParticleRipple = NULL;
|
||||
splashParticleTiny = NULL;
|
||||
splashParticleSmall = NULL;
|
||||
splashParticleBig = NULL;
|
||||
splashParticleHuge = NULL;
|
||||
|
||||
const char *splashName = spawnArgs.GetString( "smoke_ripple" );
|
||||
if ( *splashName != '\0' ) {
|
||||
splashParticleRipple = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, splashName ) );
|
||||
}
|
||||
|
||||
splashName = spawnArgs.GetString( "smoke_splashTiny" );
|
||||
if ( *splashName != '\0' ) {
|
||||
splashParticleTiny = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, splashName ) );
|
||||
}
|
||||
|
||||
splashName = spawnArgs.GetString( "smoke_splashSmall" );
|
||||
if ( *splashName != '\0' ) {
|
||||
splashParticleSmall = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, splashName ) );
|
||||
}
|
||||
|
||||
splashName = spawnArgs.GetString( "smoke_splashBig" );
|
||||
if ( *splashName != '\0' ) {
|
||||
splashParticleBig = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, splashName ) );
|
||||
}
|
||||
|
||||
splashName = spawnArgs.GetString( "smoke_splashHuge" );
|
||||
if ( *splashName != '\0' ) {
|
||||
splashParticleHuge = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, splashName ) );
|
||||
}
|
||||
|
||||
spawnArgs.GetVector( "moveDir", "0 0 0", moveDir );
|
||||
spawnArgs.GetFloat( "moveAmt", "0", moveAmt );
|
||||
spawnArgs.GetFloat( "moveResistance", "0", moveResistance );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2355,6 +2478,201 @@ void idLiquid::Event_Touch( idEntity *other, trace_t *trace ) {
|
|||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idLiquid::Event_Touch
|
||||
================
|
||||
*/
|
||||
void idLiquid::TouchEntities( void ) { // Z.TODO: this is getting messy, maybe split it into separate entities?
|
||||
int numClipModels, i, c;
|
||||
idBounds bounds;
|
||||
idClipModel *cm, *clipModelList[ MAX_GENTITIES ];
|
||||
|
||||
// HEXEN : Zeroth - for limit entity type
|
||||
idEntity *entity = NULL;
|
||||
bool dontSplash;
|
||||
idVec3 cmOrigin;
|
||||
idMat3 cmAxis;
|
||||
cmHandle_t cmHandle;
|
||||
idVec3 myOrigin;
|
||||
idMat3 myAxis;
|
||||
|
||||
if ( clipModel == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( c = 0; c < touchingEntities.Num(); c++ ) {
|
||||
entity = gameLocal.FindEntity( touchingEntities[c].c_str() );
|
||||
// remove entities from list which are no longer touching or no longer exist
|
||||
if ( !flagEntities[c] || !entity ) {
|
||||
if ( entity ) {
|
||||
if ( !gameLocal.isClient ) {
|
||||
// entity->StartSound( "snd_splashexit", SND_CHANNEL_ANY, 0, false, NULL );
|
||||
const idSoundShader *shader = declManager->FindSound( spawnArgs.GetString( "snd_splashexit" ) );
|
||||
entity->StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL );
|
||||
|
||||
|
||||
// spawn the exit splash
|
||||
if ( particleOnExit ) {
|
||||
// gameLocal.smokeParticles->EmitSmoke( splashParticle, gameLocal.time, gameLocal.random.CRandomFloat(), entity->GetPhysics()->GetOrigin(), idAngles( 0, gameLocal.random.CRandomFloat() * 360, 0 ).ToMat3() );
|
||||
}
|
||||
|
||||
entity->inWater = false;
|
||||
if ( entity->IsType( idPlayer::Type ) ) {
|
||||
static_cast< idPlayer* >( entity )->leftWater = gameLocal.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
touchingEntities.RemoveIndex( c );
|
||||
touchingEntities.Condense();
|
||||
flagEntities.RemoveIndex( c );
|
||||
flagEntities.Condense();
|
||||
c--;
|
||||
} else {
|
||||
// flag all entities as NOT touching, test if they are during the clip tests
|
||||
flagEntities[c] = false;
|
||||
}
|
||||
}
|
||||
|
||||
bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() );
|
||||
numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES );
|
||||
|
||||
for ( i = 0; i < numClipModels; i++ ) {
|
||||
cm = clipModelList[ i ];
|
||||
if ( !cm->IsTraceModel() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity = clipModelList[ i ]->GetEntity();
|
||||
if ( !entity ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( entity->spawnArgs.GetBool("nosplash") ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cmOrigin = cm->GetOrigin();
|
||||
cmAxis = cm->GetAxis();
|
||||
cmHandle = clipModel->Handle();
|
||||
myOrigin = clipModel->GetOrigin();
|
||||
myAxis = clipModel->GetAxis();
|
||||
|
||||
if ( !gameLocal.clip.ContentsModel( cmOrigin, cm, cmAxis, -1, cmHandle, myOrigin, myAxis ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the intersection point so we know where to spawn the effect
|
||||
// gameLocal.clip.Translation( trace, cmOrigin, cmOrigin, cm, cmAxis, -1, this );
|
||||
|
||||
if (limitEntityType) {
|
||||
if ( ( !tripby_idPlayer && entity->IsType( idPlayer::Type ) ) ||
|
||||
( !tripby_idAI && entity->IsType( idAI::Type ) ) ||
|
||||
( !tripby_idActor && entity->IsType( idActor::Type ) ) ||
|
||||
( !tripby_idProjectile && entity->IsType( idProjectile::Type ) ) ||
|
||||
( !tripby_idItem && entity->IsType( idItem::Type ) ) ||
|
||||
( !tripby_idMoveable && entity->IsType( idMoveable::Type ) ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dontTripby_LocalPlayer && entity->IsType( idPlayer::Type ) && gameLocal.GetLocalPlayer() == ( static_cast<idPlayer *>( entity ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the entity is still touching, dont splash
|
||||
dontSplash = false;
|
||||
for ( c = 0; c < touchingEntities.Num(); c++ ) {
|
||||
if ( touchingEntities[c] == entity->GetName() ) {
|
||||
flagEntities[c] = true; // flag it as touching
|
||||
dontSplash = true;
|
||||
entity->inWater = true; // if the entity leaves another body of water, it will be set to false. it's still in this one, so keep it true.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the entity was not in our list, add it. else don't trigger.
|
||||
if ( !dontSplash ) {
|
||||
touchingEntities.Append( idStr( entity->GetName() ) );
|
||||
flagEntities.Append( true );
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
//if the entity is already in water, dont splash
|
||||
if ( entity->inWater ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity->inWater = true;
|
||||
|
||||
if ( !gameLocal.isClient ) {
|
||||
const idDeclParticle * prt = NULL;
|
||||
idVec3 v = entity->GetPhysics()->GetLinearVelocity();
|
||||
float vel = v.Length();
|
||||
|
||||
int whichPrt, maxPrt;
|
||||
float m = entity->GetPhysics()->GetMass();
|
||||
// static const unsigned long double const * foo = NULL; // hahaha!
|
||||
float a = spawnArgs.GetFloat( "rippleObjectMass" );
|
||||
float b = spawnArgs.GetFloat( "tinyObjectMass" );
|
||||
float c = spawnArgs.GetFloat( "smallObjectMass" );
|
||||
float d = spawnArgs.GetFloat( "bigObjectMass" );
|
||||
float e = spawnArgs.GetFloat( "largeObjectMass" );
|
||||
|
||||
if ( m <= a ) {
|
||||
maxPrt = 0;
|
||||
} else if ( m <= b ) {
|
||||
maxPrt = 1;
|
||||
} else if ( m <= c ) {
|
||||
maxPrt = 2;
|
||||
} else if ( m <= d ) {
|
||||
maxPrt = 3;
|
||||
} else {
|
||||
maxPrt = 4;
|
||||
}
|
||||
|
||||
whichPrt = ( vel / spawnArgs.GetFloat( "velocityForMaxiumSplash" ) ) * maxPrt;
|
||||
|
||||
if ( maxPrt == 0) {
|
||||
prt = splashParticleRipple;
|
||||
} else if ( whichPrt == 1 || maxPrt == 1) {
|
||||
prt = splashParticleTiny;
|
||||
} else if ( whichPrt == 2 || maxPrt == 2 ) {
|
||||
prt = splashParticleSmall;
|
||||
} else if ( whichPrt == 3 || maxPrt == 3 ) {
|
||||
prt = splashParticleBig;
|
||||
} else if ( whichPrt == 4 || maxPrt == 4 ) {
|
||||
prt = splashParticleHuge;
|
||||
}
|
||||
|
||||
if ( maxPrt != 0 ) {
|
||||
// entity->StartSound( "snd_splash", SND_CHANNEL_ANY, 0, false, NULL );
|
||||
const idSoundShader *shader = declManager->FindSound( spawnArgs.GetString( "snd_splash" ) );
|
||||
entity->StartSoundShader( shader, SND_CHANNEL_ANY, SSF_GLOBAL, false, NULL );
|
||||
}
|
||||
|
||||
if ( prt ) {
|
||||
gameLocal.smokeParticles->EmitSmoke( prt, gameLocal.time, gameLocal.random.CRandomFloat(), entity->GetPhysics()->GetOrigin(), idAngles( 0, gameLocal.random.CRandomFloat() * 360, 0 ).ToMat3() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Zeroth
|
||||
idLiquid::Think
|
||||
===============
|
||||
*/
|
||||
void idLiquid::Think( void ) {
|
||||
if ( thinkFlags & TH_THINK ) {
|
||||
TouchEntities();
|
||||
}
|
||||
idEntity::Think();
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
@ -3156,3 +3474,66 @@ void idPhantomObjects::Think( void ) {
|
|||
BecomeInactive( TH_THINK );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Zeroth
|
||||
idPortalSky
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_DECLARATION( idEntity, idPortalSky )
|
||||
EVENT( EV_PostSpawn, idPortalSky::Event_PostSpawn )
|
||||
EVENT( EV_Activate, idPortalSky::Event_Activate )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
===============
|
||||
Zeroth
|
||||
idPortalSky::idPortalSky
|
||||
===============
|
||||
*/
|
||||
idPortalSky::idPortalSky( void ) { }
|
||||
|
||||
/*
|
||||
===============
|
||||
Zeroth
|
||||
idPortalSky::~idPortalSky
|
||||
===============
|
||||
*/
|
||||
idPortalSky::~idPortalSky( void ) { }
|
||||
|
||||
/*
|
||||
===============
|
||||
Zeroth
|
||||
idPortalSky::Spawn
|
||||
===============
|
||||
*/
|
||||
void idPortalSky::Spawn( void ) {
|
||||
if ( !spawnArgs.GetBool( "triggered" ) ) {
|
||||
PostEventMS( &EV_PostSpawn, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idPortalSky::Event_PostSpawn
|
||||
================
|
||||
*/
|
||||
void idPortalSky::Event_PostSpawn() {
|
||||
gameLocal.SetPortalSkyEnt( this );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idPortalSky::Event_Activate
|
||||
================
|
||||
*/
|
||||
void idPortalSky::Event_Activate( idEntity *activator ) {
|
||||
gameLocal.SetPortalSkyEnt( this );
|
||||
}
|
||||
|
|
53
game/Misc.h
53
game/Misc.h
|
@ -548,13 +548,44 @@ class idLiquid : public idEntity {
|
|||
public:
|
||||
CLASS_PROTOTYPE( idLiquid );
|
||||
|
||||
idLiquid( void ); // HEXEN : Zeroth
|
||||
|
||||
void Spawn( void );
|
||||
void Think( void ); // HEXEN : Zeroth
|
||||
|
||||
void Save( idSaveGame *savefile ) const;
|
||||
void Restore( idRestoreGame *savefile );
|
||||
|
||||
private:
|
||||
void Event_Touch( idEntity *other, trace_t *trace );
|
||||
void Event_Touch( idEntity *other, trace_t *trace ); // HEXEN : Zeroth - was commented out
|
||||
|
||||
// Zeroth
|
||||
idClipModel * clipModel;
|
||||
void TouchEntities( void );
|
||||
bool particleOnExit; // whether to spawn a particle when something leaves the water
|
||||
const idDeclParticle * splashParticleRipple;
|
||||
const idDeclParticle * splashParticleTiny;
|
||||
const idDeclParticle * splashParticleSmall;
|
||||
const idDeclParticle * splashParticleBig;
|
||||
const idDeclParticle * splashParticleHuge;
|
||||
float moveResistance;
|
||||
idVec3 moveDir;
|
||||
float moveAmt;
|
||||
idList<idStr> touchingEntities; // list of entities touching the trigger
|
||||
idList<bool> flagEntities; // used to test if touchingEntities[x] is still touching, if not to be removed from list
|
||||
// idList<int> resistTimeEntities;
|
||||
|
||||
|
||||
// HEXEN : Zeroth - for limit entity types
|
||||
private:
|
||||
bool dontTripby_LocalPlayer;
|
||||
bool limitEntityType;
|
||||
bool tripby_idPlayer;
|
||||
bool tripby_idAI;
|
||||
bool tripby_idMoveable;
|
||||
bool tripby_idItem;
|
||||
bool tripby_idActor;
|
||||
bool tripby_idProjectile;
|
||||
|
||||
|
||||
idRenderModelLiquid *model;
|
||||
|
@ -765,4 +796,24 @@ private:
|
|||
idList<idVec3> lastTargetPos;
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Zeroth
|
||||
idPortalSky
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
class idPortalSky : public idEntity {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idPortalSky );
|
||||
|
||||
idPortalSky();
|
||||
~idPortalSky();
|
||||
|
||||
void Spawn( void );
|
||||
void Event_PostSpawn();
|
||||
void Event_Activate( idEntity *activator );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_MISC_H__ */
|
||||
|
|
1253
game/Moveable.cpp
1253
game/Moveable.cpp
File diff suppressed because it is too large
Load diff
|
@ -88,8 +88,13 @@ protected:
|
|||
int nextDamageTime; // next time the movable can hurt the player
|
||||
int nextSoundTime; // next time the moveable can make a sound
|
||||
|
||||
// HEXEN : Zeroth
|
||||
protected:
|
||||
bool brokenScript; // call ::Broken on killed.
|
||||
bool removeWhenBroken; // removes entity after it's "fuse" delay
|
||||
|
||||
|
||||
const idMaterial * GetRenderModelMaterial( void ) const;
|
||||
void BecomeNonSolid( void );
|
||||
void InitInitialSpline( int startTime );
|
||||
bool FollowInitialSplinePath( void );
|
||||
|
||||
|
@ -98,6 +103,19 @@ protected:
|
|||
void Event_SetOwnerFromSpawnArgs( void );
|
||||
void Event_IsAtRest( void );
|
||||
void Event_EnableDamage( float enable );
|
||||
void Event_DirectDamage( idEntity *damageTarget, const char *damageDefName );
|
||||
|
||||
void DirectDamage( const char *meleeDefName, idEntity *ent );
|
||||
// HEXEN : Zeroth
|
||||
protected:
|
||||
void Event_BecomeSolid( void );
|
||||
|
||||
// HEXEN : Zeroth
|
||||
public:
|
||||
void BecomeNonSolid( void );
|
||||
void BecomeSolid( void );
|
||||
public:
|
||||
bool savePersistentInfo;
|
||||
};
|
||||
|
||||
|
||||
|
@ -160,7 +178,7 @@ public:
|
|||
|
||||
virtual void Think( void );
|
||||
virtual void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
|
||||
const char *damageDefName, const float damageScale, const int location );
|
||||
const char *damageDefName, const float damageScale, const int location, const idVec3 &iPoint );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
|
||||
virtual void WriteToSnapshot( idBitMsgDelta &msg ) const;
|
||||
|
@ -201,4 +219,65 @@ private:
|
|||
void Event_TriggerTargets();
|
||||
};
|
||||
|
||||
#if 0
|
||||
// HEXEN : Zeroth
|
||||
// for idWood and other entities with renderModels that need more vertex/face info
|
||||
class Destructible_FaceData_t {
|
||||
public:
|
||||
// this could be a bit more effiecient with idVec3 pointers that point to surface geometry...
|
||||
idList< idVec3 > verts;
|
||||
idVec3 center; // center of face
|
||||
float area;
|
||||
idPlane * plane;
|
||||
idList< int > adjacent; // stores indexes of adjacent faces
|
||||
// idVec3 worldCenter(void) const;
|
||||
// idVec3 worldNotm(void) const;
|
||||
};
|
||||
|
||||
|
||||
//ID_INLINE idVec3 faceData_t::worldCenter(void) const {
|
||||
// return center + physicsObj.GetOrigin() * physicsObj.GetAxis();
|
||||
//}
|
||||
|
||||
//ID_INLINE idVec3 faceData_t::worldNorm(void) const {
|
||||
// return norm + physicsObj.GetOrigin() * physicsObj.GetAxis();
|
||||
//}
|
||||
|
||||
class Destructible_ModelData_t {
|
||||
public:
|
||||
idList<Destructible_FaceData_t> faces;
|
||||
idVec3 center;
|
||||
float area;
|
||||
float avgArea;
|
||||
// idVec3 worldCenter(void) const;
|
||||
};
|
||||
|
||||
//ID_INLINE idVec3 geoData_t::worldCenter(void) const {
|
||||
// return geo.center + physicsObj.GetOrigin() * physicsObj.GetAxis();
|
||||
//}
|
||||
|
||||
// HEXEN : Zeroth
|
||||
class idWood : public idMoveable {
|
||||
public:
|
||||
CLASS_PROTOTYPE( idWood );
|
||||
|
||||
idWood::idWood( void );
|
||||
|
||||
void Spawn( void );
|
||||
virtual void Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||||
void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
|
||||
const char *damageDefName, const float damageScale, const int location, idVec3 &iPoint );
|
||||
bool CheckFloating( idWood *caller, idWood *chain[], int c );
|
||||
|
||||
bool geoConstructed;
|
||||
Destructible_ModelData_t geo;
|
||||
|
||||
idVec3 lastiPoint; // last damage position
|
||||
|
||||
private:
|
||||
void ConstructGeo( void );
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* !__GAME_MOVEABLE_H__ */
|
||||
|
|
189
game/Mover.cpp
189
game/Mover.cpp
|
@ -90,6 +90,11 @@ const idEventDef EV_StartSpline( "startSpline", "e" );
|
|||
const idEventDef EV_StopSpline( "stopSpline", NULL );
|
||||
const idEventDef EV_IsMoving( "isMoving", NULL, 'd' );
|
||||
const idEventDef EV_IsRotating( "isRotating", NULL, 'd' );
|
||||
const idEventDef EV_EnableClip( "enableClip" );
|
||||
const idEventDef EV_DisableClip( "disableClip" );
|
||||
const idEventDef EV_CanBecomeSolid( "canBecomeSolid", NULL, 'f' );
|
||||
const idEventDef EV_MoverBecomeSolid( "becomeSolid" );
|
||||
const idEventDef EV_MoverBecomeNonSolid( "becomeNonSolid" );
|
||||
|
||||
CLASS_DECLARATION( idEntity, idMover )
|
||||
EVENT( EV_FindGuiTargets, idMover::Event_FindGuiTargets )
|
||||
|
@ -131,6 +136,11 @@ CLASS_DECLARATION( idEntity, idMover )
|
|||
EVENT( EV_Activate, idMover::Event_Activate )
|
||||
EVENT( EV_IsMoving, idMover::Event_IsMoving )
|
||||
EVENT( EV_IsRotating, idMover::Event_IsRotating )
|
||||
EVENT( EV_EnableClip, idMover::Event_EnableClip )
|
||||
EVENT( EV_DisableClip, idMover::Event_DisableClip )
|
||||
EVENT( EV_CanBecomeSolid, idMover::Event_CanBecomeSolid )
|
||||
EVENT( EV_MoverBecomeSolid, idMover::Event_BecomeSolid )
|
||||
EVENT( EV_MoverBecomeNonSolid, idMover::Event_BecomeNonSolid )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
|
@ -345,7 +355,9 @@ void idMover::Spawn( void ) {
|
|||
spawnArgs.GetFloat( "damage" , "0", damage );
|
||||
|
||||
dest_position = GetPhysics()->GetOrigin();
|
||||
SetPersistentPos(dest_position);
|
||||
dest_angles = GetPhysics()->GetAxis().ToAngles();
|
||||
SetPersistentAng(dest_angles);
|
||||
|
||||
physicsObj.SetSelf( this );
|
||||
physicsObj.SetClipModel( new idClipModel( GetPhysics()->GetClipModel() ), 1.0f );
|
||||
|
@ -999,7 +1011,7 @@ idMover::Event_PartBlocked
|
|||
*/
|
||||
void idMover::Event_PartBlocked( idEntity *blockingEntity ) {
|
||||
if ( damage > 0.0f ) {
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT, idVec3( 0, 0, 0 ) );
|
||||
}
|
||||
if ( g_debugMover.GetBool() ) {
|
||||
gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockingEntity->name.c_str() );
|
||||
|
@ -1034,6 +1046,18 @@ void idMover::Event_SetMoveTime( float time ) {
|
|||
move_time = SEC2MS( time );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idMover::eoc_SetMoveTime
|
||||
================
|
||||
*/
|
||||
void idMover::eoc_SetMoveTime( float time ) {
|
||||
Event_SetMoveTime( time );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
idMover::Event_SetAccellerationTime
|
||||
|
@ -1071,9 +1095,54 @@ void idMover::Event_MoveTo( idEntity *ent ) {
|
|||
}
|
||||
|
||||
dest_position = GetLocalCoordinates( ent->GetPhysics()->GetOrigin() );
|
||||
SetPersistentPos( dest_position );
|
||||
BeginMove( idThread::CurrentThread() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idMover::SetPersistentPos
|
||||
================
|
||||
*/
|
||||
void idMover::SetPersistentPos( idVec3 &pos ) {
|
||||
// for removing items/creatures/etc after returning to a level (hubs)
|
||||
idStr name_str, st;
|
||||
|
||||
name_str = gameLocal.GetMapName();
|
||||
name_str += "_mover_pos";
|
||||
|
||||
gameLocal.persistentLevelInfo.SetVector( name_str, pos );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idMover::SetPersistentAng
|
||||
================
|
||||
*/
|
||||
void idMover::SetPersistentAng( idAngles &ang ) {
|
||||
// for removing items/creatures/etc after returning to a level (hubs)
|
||||
idStr name_str, st;
|
||||
|
||||
name_str = gameLocal.GetMapName();
|
||||
name_str += "_mover_ang";
|
||||
|
||||
gameLocal.persistentLevelInfo.SetAngles( name_str, ang );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
================
|
||||
Zeroth
|
||||
idMover::eoc_MoveToPos
|
||||
================
|
||||
*/
|
||||
void idMover::eoc_MoveToPos( const idVec3 &pos ) {
|
||||
MoveToPos( pos );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
idMover::MoveToPos
|
||||
|
@ -1081,6 +1150,7 @@ idMover::MoveToPos
|
|||
*/
|
||||
void idMover::MoveToPos( const idVec3 &pos ) {
|
||||
dest_position = GetLocalCoordinates( pos );
|
||||
SetPersistentPos( dest_position );
|
||||
BeginMove( NULL );
|
||||
}
|
||||
|
||||
|
@ -1105,6 +1175,7 @@ void idMover::Event_MoveDir( float angle, float distance ) {
|
|||
physicsObj.GetLocalOrigin( org );
|
||||
VectorForDir( angle, dir );
|
||||
dest_position = org + dir * distance;
|
||||
SetPersistentPos( dest_position );
|
||||
|
||||
BeginMove( idThread::CurrentThread() );
|
||||
}
|
||||
|
@ -1456,6 +1527,10 @@ idMover::Event_Activate
|
|||
================
|
||||
*/
|
||||
void idMover::Event_Activate( idEntity *activator ) {
|
||||
if ( spawnArgs.GetBool( "NoActivateWhenTriggered", "0" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Show();
|
||||
Event_StartSpline( this );
|
||||
}
|
||||
|
@ -1535,6 +1610,112 @@ void idMover::SetPortalState( bool open ) {
|
|||
gameLocal.SetPortalState( areaPortal, open ? PS_BLOCK_NONE : PS_BLOCK_ALL );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::Event_EnableClip
|
||||
================
|
||||
*/
|
||||
void idMover::Event_EnableClip( void ) {
|
||||
physicsObj.SetClipMask( MASK_SOLID );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::Event_DisableClip
|
||||
================
|
||||
*/
|
||||
void idMover::Event_DisableClip( void ) {
|
||||
physicsObj.SetClipMask( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::Event_CanBecomeSolid
|
||||
================
|
||||
*/
|
||||
void idMover::Event_CanBecomeSolid( void ) {
|
||||
idThread::ReturnFloat( CanBecomeSolid() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::CanBecomeSolid
|
||||
================
|
||||
*/
|
||||
bool idMover::CanBecomeSolid( void ) {
|
||||
int i;
|
||||
int num;
|
||||
idEntity * hit;
|
||||
idClipModel *cm;
|
||||
idClipModel *clipModels[ MAX_GENTITIES ];
|
||||
|
||||
num = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), MASK_MONSTERSOLID, clipModels, MAX_GENTITIES );
|
||||
for ( i = 0; i < num; i++ ) {
|
||||
cm = clipModels[ i ];
|
||||
|
||||
// don't check render entities
|
||||
if ( cm->IsRenderModel() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hit = cm->GetEntity();
|
||||
if ( ( hit == this ) || !hit->fl.takedamage ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( physicsObj.ClipContents( cm ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::Event_BecomeSolid
|
||||
================
|
||||
*/
|
||||
void idMover::Event_BecomeSolid( void ) {
|
||||
BecomeSolid( );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::BecomeSolid
|
||||
================
|
||||
*/
|
||||
void idMover::BecomeSolid( void ) {
|
||||
physicsObj.SetContents( MASK_SOLID );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::Event_BecomeNonSolid
|
||||
================
|
||||
*/
|
||||
void idMover::Event_BecomeNonSolid( void ) {
|
||||
BecomeNonSolid();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
HEXEN
|
||||
idMover::BecomeSolid
|
||||
================
|
||||
*/
|
||||
void idMover::BecomeNonSolid( void ) {
|
||||
physicsObj.SetContents( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -3788,7 +3969,7 @@ idDoor::Event_PartBlocked
|
|||
*/
|
||||
void idDoor::Event_PartBlocked( idEntity *blockingEntity ) {
|
||||
if ( damage > 0.0f ) {
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT, idVec3( 0, 0, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4225,7 +4406,7 @@ idPlat::Event_PartBlocked
|
|||
*/
|
||||
void idPlat::Event_PartBlocked( idEntity *blockingEntity ) {
|
||||
if ( damage > 0.0f ) {
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT, idVec3( 0, 0, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4316,7 +4497,7 @@ idMover_Periodic::Event_PartBlocked
|
|||
*/
|
||||
void idMover_Periodic::Event_PartBlocked( idEntity *blockingEntity ) {
|
||||
if ( damage > 0.0f ) {
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT );
|
||||
blockingEntity->Damage( this, this, vec3_origin, "damage_moverCrush", damage, INVALID_JOINT, idVec3( 0, 0, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
game/Mover.h
20
game/Mover.h
|
@ -66,6 +66,26 @@ public:
|
|||
|
||||
void SetPortalState( bool open );
|
||||
|
||||
void Event_EnableClip( void );
|
||||
void Event_DisableClip( void );
|
||||
void Event_BecomeSolid( void );
|
||||
void Event_CanBecomeSolid( void );
|
||||
void Event_BecomeNonSolid( void );
|
||||
bool CanBecomeSolid( void );
|
||||
void BecomeSolid( void );
|
||||
void BecomeNonSolid( void );
|
||||
|
||||
// only for use with hub-style map initialization
|
||||
void SetDestPos( const idVec3 &pos ) { dest_position=pos; }
|
||||
void SetDestAng( const idAngles &ang ) { dest_angles=ang; }
|
||||
|
||||
// HEXEN : Zeroth
|
||||
// void eoc_SetMoveTime( float time );
|
||||
// void eoc_MoveToPos( const idVec3 &pos );
|
||||
|
||||
void SetPersistentPos( idVec3 &pos );
|
||||
void SetPersistentAng( idAngles &ang );
|
||||
|
||||
protected:
|
||||
typedef enum {
|
||||
ACCELERATION_STAGE,
|
||||
|
|
Loading…
Reference in a new issue