Real Gibs - source code

This commit is contained in:
ALord7 2024-09-19 21:11:10 +08:00
parent 5fcabc8f6a
commit e8e434a597
10 changed files with 174 additions and 17 deletions

View file

@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 2.8...3.22 FATAL_ERROR)
project(dhewm3sdk) project(dhewm3sdk)
option(BASE "Build the base (game/) game code" ON) option(BASE "Build the base (game/) game code" ON)
set(BASE_NAME "base" CACHE STRING "Name of the mod built from game/ (will result in \${BASE_NAME}.dll)") set(BASE_NAME "realgibs" CACHE STRING "Name of the mod built from game/ (will result in \${BASE_NAME}.dll)")
set(BASE_DEFS "GAME_DLL" CACHE STRING "Compiler definitions for the mod built from game/") set(BASE_DEFS "GAME_DLL" CACHE STRING "Compiler definitions for the mod built from game/")
option(D3XP "Build the d3xp/ game code" ON) option(D3XP "Build the d3xp/ game code" OFF)
set(D3XP_NAME "d3xp" CACHE STRING "Name of the mod built from d3xp/ (will result in \${D3XP_NAME}.dll)") set(D3XP_NAME "d3xp" CACHE STRING "Name of the mod built from d3xp/ (will result in \${D3XP_NAME}.dll)")
set(D3XP_DEFS "GAME_DLL;_D3XP;CTF" CACHE STRING "Compiler definitions for the mod built from d3xp/") set(D3XP_DEFS "GAME_DLL;_D3XP;CTF" CACHE STRING "Compiler definitions for the mod built from d3xp/")

View file

@ -1104,6 +1104,8 @@ idAFEntity_Gibbable::SpawnGibs
*/ */
void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefName ) { void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefName ) {
int i; int i;
float gibPower; // darknar
float gibTime; // darknar
bool gibNonSolid; bool gibNonSolid;
idVec3 entityCenter, velocity; idVec3 entityCenter, velocity;
idList<idEntity *> list; idList<idEntity *> list;
@ -1114,7 +1116,8 @@ void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefNam
if ( !damageDef ) { if ( !damageDef ) {
gameLocal.Error( "Unknown damageDef '%s'", damageDefName ); gameLocal.Error( "Unknown damageDef '%s'", damageDefName );
} }
gibPower = g_gib_power.GetFloat(); // darknar
gibTime = g_gib_remove_time.GetFloat(); // darknar
// spawn gib articulated figures // spawn gib articulated figures
idAFEntity_Base::DropAFs( this, "gib", &list ); idAFEntity_Base::DropAFs( this, "gib", &list );
@ -1131,16 +1134,34 @@ void idAFEntity_Gibbable::SpawnGibs( const idVec3 &dir, const char *damageDefNam
list[i]->GetPhysics()->UnlinkClip(); list[i]->GetPhysics()->UnlinkClip();
list[i]->GetPhysics()->PutToRest(); list[i]->GetPhysics()->PutToRest();
} else { } else {
list[i]->GetPhysics()->SetContents( CONTENTS_CORPSE );
//list[i]->GetPhysics()->SetContents( CONTENTS_CORPSE );
list[i]->GetPhysics()->SetContents( 0 ); // darknar
list[i]->GetPhysics()->SetClipMask( CONTENTS_SOLID ); list[i]->GetPhysics()->SetClipMask( CONTENTS_SOLID );
velocity = list[i]->GetPhysics()->GetAbsBounds().GetCenter() - entityCenter; velocity = list[i]->GetPhysics()->GetAbsBounds().GetCenter() - entityCenter;
velocity.NormalizeFast(); velocity.NormalizeFast();
velocity += ( i & 1 ) ? dir : -dir; velocity += ( i & 1 ) ? dir : -dir;
list[i]->GetPhysics()->SetLinearVelocity( velocity * 75.0f );
// list[i]->GetPhysics()->SetLinearVelocity( velocity * 75.0f );
list[i]->GetPhysics()->SetLinearVelocity( velocity * gibPower ); // darknar gib power
} }
// darknar start change
/*
list[i]->GetRenderEntity()->noShadow = true; list[i]->GetRenderEntity()->noShadow = true;
list[i]->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; list[i]->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f;
list[i]->PostEventSec(&EV_Remove, 4.0f); list[i]->PostEventSec(&EV_Remove, 4.0f);
*/
if ( !g_gib_shadows.GetBool() ) {
list[i]->GetRenderEntity()->noShadow = true; // shadows can be optional, 1 = enable shadows, 0 = no shadows ( default )
}
//list[i]->GetRenderEntity()->shaderParms[SHADERPARM_TIME_OF_DEATH] = gameLocal.time * 0.001f; // disable burn effect for now
if ( gibTime > 0.0f ) { // darknar, if the float is > to 0, do the remove after x seconds
list[i]->PostEventSec(&EV_Remove, gibTime); // darknar, define a float in Cvar, gibs are removed after thes time
}
// darknar end change
} }
} }
@ -1173,14 +1194,20 @@ void idAFEntity_Gibbable::Gib( const idVec3 &dir, const char *damageDefName ) {
UnlinkCombat(); UnlinkCombat();
if ( g_bloodEffects.GetBool() ) { if ( g_bloodEffects.GetBool() ) {
if ( gameLocal.time > gameLocal.GetGibTime() ) { // Real Gibs - Taken from the repository (https://github.com/RobertBeckebans/Sikkpin-Feedback)
// sikk - Since "nextGibTime" is a member of idGameLocal and not idAFEntity||idAFEntity_Gibbable
// the folloing if statement is only true once per damage event instead of per entity being damaged.
// This is why only one entity will get gibbed while the rest just disappear after a few seconds.
// I commented this out instead of moving the variable to the proper class because it's easier and
// the delay is only 200ms so the difference should be unnoticable
//if ( gameLocal.time > gameLocal.GetGibTime() ) {
gameLocal.SetGibTime( gameLocal.time + GIB_DELAY ); gameLocal.SetGibTime( gameLocal.time + GIB_DELAY );
SpawnGibs( dir, damageDefName ); SpawnGibs( dir, damageDefName );
renderEntity.noShadow = true; renderEntity.noShadow = true;
renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f; renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f;
StartSound( "snd_gibbed", SND_CHANNEL_ANY, 0, false, NULL ); StartSound( "snd_gibbed", SND_CHANNEL_ANY, 0, false, NULL );
gibbed = true; gibbed = true;
} //}
} else { } else {
gibbed = true; gibbed = true;
} }

View file

@ -2134,6 +2134,10 @@ void idActor::Gib( const idVec3 &dir, const char *damageDefName ) {
if ( head.GetEntity() ) { if ( head.GetEntity() ) {
head.GetEntity()->Hide(); head.GetEntity()->Hide();
} }
// darknar
if (spawnArgs.GetBool("gib_remove")) {
Hide();
}
StopSound( SND_CHANNEL_VOICE, false ); StopSound( SND_CHANNEL_VOICE, false );
} }
@ -2191,7 +2195,7 @@ void idActor::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir
health = -999; health = -999;
} }
Killed( inflictor, attacker, damage, dir, location ); Killed( inflictor, attacker, damage, dir, location );
if ( ( health < -20 ) && spawnArgs.GetBool( "gib" ) && damageDef->GetBool( "gib" ) ) { if ( (health < spawnArgs.GetInt("health_gib")) && spawnArgs.GetBool( "gib" ) && damageDef->GetBool( "gib" ) ) { // darknar
Gib( dir, damageDefName ); Gib( dir, damageDefName );
} }
} else { } else {

View file

@ -870,6 +870,7 @@ idMoveableItem::idMoveableItem() {
trigger = NULL; trigger = NULL;
smoke = NULL; smoke = NULL;
smokeTime = 0; smokeTime = 0;
nextSoundTime = 0; // darknar collide data
} }
/* /*
@ -895,6 +896,8 @@ void idMoveableItem::Save( idSaveGame *savefile ) const {
savefile->WriteParticle( smoke ); savefile->WriteParticle( smoke );
savefile->WriteInt( smokeTime ); savefile->WriteInt( smokeTime );
savefile->WriteString( fxCollide ); // darknar collide data
savefile->WriteInt( nextSoundTime ); // darknar collide data
} }
/* /*
@ -910,6 +913,8 @@ void idMoveableItem::Restore( idRestoreGame *savefile ) {
savefile->ReadParticle( smoke ); savefile->ReadParticle( smoke );
savefile->ReadInt( smokeTime ); savefile->ReadInt( smokeTime );
savefile->ReadString( fxCollide ); // darknar collide data
savefile->ReadInt( nextSoundTime ); // darknar collide data
} }
/* /*
@ -945,7 +950,7 @@ void idMoveableItem::Spawn( void ) {
if ( spawnArgs.GetBool( "clipshrink" ) ) { if ( spawnArgs.GetBool( "clipshrink" ) ) {
trm.Shrink( CM_CLIP_EPSILON ); trm.Shrink( CM_CLIP_EPSILON );
} }
fxCollide = spawnArgs.GetString( "fx_collide" ); // darknar collide data
// get rigid body properties // get rigid body properties
spawnArgs.GetFloat( "density", "0.5", density ); spawnArgs.GetFloat( "density", "0.5", density );
density = idMath::ClampFloat( 0.001f, 1000.0f, density ); density = idMath::ClampFloat( 0.001f, 1000.0f, density );
@ -968,6 +973,7 @@ void idMoveableItem::Spawn( void ) {
smoke = NULL; smoke = NULL;
smokeTime = 0; smokeTime = 0;
nextSoundTime = 0; // darknar collide data
const char *smokeName = spawnArgs.GetString( "smoke_trail" ); const char *smokeName = spawnArgs.GetString( "smoke_trail" );
if ( *smokeName != '\0' ) { if ( *smokeName != '\0' ) {
smoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) ); smoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) );
@ -1000,6 +1006,32 @@ void idMoveableItem::Think( void ) {
Present(); Present();
} }
/*
=================
idMoveableItem::Collide // darknar collide data, allows idMoveableGibItem and idMoveableItem spawn a collide fx when collides. I was using a idMoveable to make the gib splats, if that was causing lag, this can help to make the blood decals.
=================
*/
bool idMoveableItem::Collide( const trace_t &collision, const idVec3 &velocity ) {
float v, f;
v = -( velocity * collision.c.normal );
if ( v > 80 && gameLocal.time > nextSoundTime ) {
if ( fxCollide.Length() ) {
idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
}
f = v > 200 ? 1.0f : idMath::Sqrt( v - 80 ) * 0.091f;
if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
// don't set the volume unless there is a bounce sound as it overrides the entire channel
// which causes footsteps on ai's to not honor their shader parms
SetSoundVolume( f );
}
nextSoundTime = gameLocal.time + 500;
}
return false;
}
/* /*
================ ================
idMoveableItem::Pickup idMoveableItem::Pickup
@ -1356,3 +1388,18 @@ void idObjectiveComplete::Event_HideObjective( idEntity *e ) {
} }
} }
} }
// darknar start change
/*
================
idMoveableGibItem
================
*/
CLASS_DECLARATION( idMoveableItem, idMoveableGibItem )
END_CLASS
// darknar end change

View file

@ -161,6 +161,7 @@ public:
void Spawn( void ); void Spawn( void );
virtual void Think( void ); virtual void Think( void );
virtual bool Collide( const trace_t &collision, const idVec3 &velocity ); // darknar, probably this can be useful if the splat fx moveable gib was causing lag. Allow idMoveableItem class spawn fx on collision
virtual bool Pickup( idPlayer *player ); virtual bool Pickup( idPlayer *player );
static void DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list ); static void DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list );
@ -174,7 +175,8 @@ private:
idClipModel * trigger; idClipModel * trigger;
const idDeclParticle * smoke; const idDeclParticle * smoke;
int smokeTime; int smokeTime;
int nextSoundTime; // darknar, fx collide data
idStr fxCollide; // darknar, fx collide data
void Gib( const idVec3 &dir, const char *damageDefName ); void Gib( const idVec3 &dir, const char *damageDefName );
void Event_DropToFloor( void ); void Event_DropToFloor( void );
@ -226,4 +228,20 @@ private:
void Event_GetPlayerPos(); void Event_GetPlayerPos();
}; };
// darknar start change
/*
===============================================================================
idMoveableGibItem
===============================================================================
*/
class idMoveableGibItem : public idMoveableItem {
public:
CLASS_PROTOTYPE(idMoveableGibItem);
};
// darknar end change
#endif /* !__GAME_ITEM_H__ */ #endif /* !__GAME_ITEM_H__ */

View file

@ -175,6 +175,10 @@ void idMoveable::Spawn( void ) {
if ( spawnArgs.GetBool( "nonsolid" ) ) { if ( spawnArgs.GetBool( "nonsolid" ) ) {
BecomeNonSolid(); BecomeNonSolid();
} }
if ( spawnArgs.GetBool( "gibclear" ) ) { // makes the moveable burn at spawn, i don't know if this works!!!
GetRenderEntity()->shaderParms[SHADERPARM_TIME_OF_DEATH] = gameLocal.time * 0.001f; // darknar, test custom gib clear for splat moveable for optimization
PostEventMS( &EV_Remove, 4000 ); // darknar, remove this after 4 seconds
}
allowStep = spawnArgs.GetBool( "allowStep", "1" ); allowStep = spawnArgs.GetBool( "allowStep", "1" );

View file

@ -1004,6 +1004,12 @@ void idMover::Event_PartBlocked( idEntity *blockingEntity ) {
if ( g_debugMover.GetBool() ) { if ( g_debugMover.GetBool() ) {
gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockingEntity->name.c_str() ); gameLocal.Printf( "%d: '%s' blocked by '%s'\n", gameLocal.time, name.c_str(), blockingEntity->name.c_str() );
} }
if ( blockingEntity->IsType( idMoveableGibItem::Type ) ) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS( &EV_Remove, 4.0 );
}
if (blockingEntity->IsType( idMoveableItem::Type ) ) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS( &EV_Remove, 4.0 );
}
} }
/* /*
@ -3790,6 +3796,12 @@ void idDoor::Event_PartBlocked( idEntity *blockingEntity ) {
if ( damage > 0.0f ) { 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 );
} }
if (blockingEntity->IsType(idMoveableGibItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
if (blockingEntity->IsType(idMoveableItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
} }
/* /*
@ -4227,6 +4239,12 @@ void idPlat::Event_PartBlocked( idEntity *blockingEntity ) {
if ( damage > 0.0f ) { 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 );
} }
if (blockingEntity->IsType(idMoveableGibItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
if (blockingEntity->IsType(idMoveableItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
} }
@ -4318,6 +4336,12 @@ void idMover_Periodic::Event_PartBlocked( idEntity *blockingEntity ) {
if ( damage > 0.0f ) { 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 );
} }
if (blockingEntity->IsType(idMoveableGibItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
if (blockingEntity->IsType(idMoveableItem::Type)) { // darknar, remove gib if is blocking the mover
blockingEntity->PostEventMS(&EV_Remove, 4.0);
}
} }
/* /*

View file

@ -261,6 +261,22 @@ void Cmd_KillMovables_f( const idCmdArgs &args ) {
KillEntities(args, idMoveable::Type); KillEntities(args, idMoveable::Type);
} }
// darknar start change
/*
==================
Cmd_ClearGibs_f
Kill all gib moveable in a level.
==================
*/
void Cmd_ClearGibs_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() ) {
return;
}
KillEntities( args, idMoveableGibItem::Type );
}
// darknar end change
/* /*
================== ==================
Cmd_KillRagdolls_f Cmd_KillRagdolls_f
@ -2334,6 +2350,13 @@ void idGameLocal::InitConsoleCommands( void ) {
cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName ); cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName );
cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" ); cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" );
cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" ); cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" );
// darlnar start change
cmdSystem->AddCommand( "ClearGibs", Cmd_ClearGibs_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all gibs spawned" );
// darknar end change
cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" ); cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" );
cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" ); cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" );
cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" ); cmdSystem->AddCommand( "addarrow", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug arrow" );

View file

@ -335,3 +335,8 @@ idCVar mod_validSkins( "mod_validSkins", "skins/characters/player/marine_mp
idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" ); idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" );
idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" ); idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" );
idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, separated by ;" ); idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, separated by ;" );
// darknar add
idCVar g_gib_power( "g_gib_power", "75.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "gibs are launched with this force when the monster gibs, default is 75.0" );
idCVar g_gib_shadows( "g_gib_shadows", "0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_BOOL, "enable shadows for spawned gibs, default is 0, no shadows" );
idCVar g_gib_remove_time( "g_gib_remove_time", "0.0", CVAR_GAME | CVAR_NOCHEAT | CVAR_ARCHIVE | CVAR_FLOAT, "remove the gibs after x seconds, default is 0.0" );

View file

@ -250,6 +250,11 @@ extern idCVar si_spectators;
extern idCVar net_clientSelfSmoothing; extern idCVar net_clientSelfSmoothing;
extern idCVar net_clientLagOMeter; extern idCVar net_clientLagOMeter;
// darknar add
extern idCVar g_gib_power;
extern idCVar g_gib_shadows;
extern idCVar g_gib_remove_time;
extern const char *si_gameTypeArgs[]; extern const char *si_gameTypeArgs[];
extern const char *ui_skinArgs[]; extern const char *ui_skinArgs[];