id Tech Forums

id Tech 4 (Doom3/Prey/Q4) => id Tech 4 Mod Coding => Topic started by: spamclark15 on June 17, 2017, 03:40:59 PM

Title: Game Code That Removes idDebris
Post by: spamclark15 on June 17, 2017, 03:40:59 PM
I'm looking through the game code for where entities that are considered idDebris are removed so that I can add in an exception. Would anyone know where this is?
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 18, 2017, 12:55:34 PM
I don't believe the game code looks for the class type info idDebris specifically when removing entities, only when spawning them. What are you trying to do exactly?
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 18, 2017, 01:25:55 PM
I'm trying to disable the removal of barrelpiece, barrelpiece2, barreltop, and barreltop2 which are all idDebris that are created when an exploding barrel explodes, and then the "fuse" value in moveable.def for it decides how long until it's removed. Commenting out line 1012 in Moveable.cpp stops the burnaway effect on those 4 debris pieces, but they're still removed, and trying to work backwards by looking for where fuse is mentioned in the code has me stuck.

I do have Entity.cpp up in another tab which seems like the place where removal of entities might occur but fuse isn't mentioned in it at all.
Title: Re: Game Code That Removes idDebris
Post by: The Happy Friar on June 18, 2017, 08:32:03 PM
You would need to change the debris from idDebris to idMovable in the code.  The wile loop @ line 1013 in movables.cpp contains the declariation of idDebris.
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 18, 2017, 08:50:42 PM
while ( kv ) {
const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
if ( debris_args ) {
idEntity *ent;
idVec3 dir;
idDebris *debris;
//if ( first ) {
dir = physicsObj.GetAxis()[1];
// first = false;
//} else {
dir.x += gameLocal.random.CRandomFloat() * 4.0f;
dir.y += gameLocal.random.CRandomFloat() * 4.0f;
//dir.z = gameLocal.random.RandomFloat() * 8.0f;
//}
dir.Normalize();

gameLocal.SpawnEntityDef( *debris_args, &ent, false );
if ( !ent || !ent->IsType( idDebris::Type ) ) {
gameLocal.Error( "'projectile_debris' is not an idDebris" );
}

debris = static_cast<idDebris *>(ent);
debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
debris->Launch();
//                 debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
debris->UpdateVisuals();

}
kv = spawnArgs.MatchPrefix( "def_debris", kv );
}


Is replacing all instances of idDebris in the loop enough?
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 19, 2017, 12:04:59 AM
In that code snippet yes, at least it's worth a try. You should also change the "spawnclass" value to "idMoveable" as well for all the debris in the .def file if you do.
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 19, 2017, 05:15:40 AM
Changed loop to the following:

while ( kv ) {
const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
if ( debris_args ) {
idEntity *ent;
idVec3 dir;
//RPS idDebris *debris;
idMoveable *debris;
//if ( first ) {
dir = physicsObj.GetAxis()[1];
// first = false;
//} else {
dir.x += gameLocal.random.CRandomFloat() * 4.0f;
dir.y += gameLocal.random.CRandomFloat() * 4.0f;
//dir.z = gameLocal.random.RandomFloat() * 8.0f;
//}
dir.Normalize();

gameLocal.SpawnEntityDef( *debris_args, &ent, false );
//RPS if ( !ent || !ent->IsType( idDebris::Type ) ) {
if ( !ent || !ent->IsType( idMoveable::Type ) ) {
gameLocal.Error( "'projectile_debris' is not an idDebris" );
}

//RPS debris = static_cast<idDebris *>(ent);
debris = static_cast<idMoveable *>(ent);
debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
debris->Launch();
//RPS debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
debris->UpdateVisuals();

}
kv = spawnArgs.MatchPrefix( "def_debris", kv );
}

physicsObj.PutToRest();
CancelEvents( &EV_Explode );
CancelEvents( &EV_Activate );

f = spawnArgs.GetFloat( "respawn" );
if ( f > 0.0f ) {
PostEventSec( &EV_Respawn, f );
} else {
PostEventMS( &EV_Remove, 5000 );
}

if ( spawnArgs.GetBool( "triggerTargets" ) ) {
ActivateTargets( this );
}
}


It produces errors upon trying to build though:

Error    3   error C2039: 'Create' : is not a member of 'idMoveable'   1013   1   Game
Error    4   error C2039: 'Launch' : is not a member of 'idMoveable'   1014   1   Game
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 19, 2017, 05:45:44 AM
Ahh shoot. I shouldn't have assumed it would have been that easy. Apparently idMoveable doesn't have those methods defined. It is also missing members idDebris needs for it's effects. It's going to be a little bit more complicated than copying and pasting idDebris code into idMoveable. You'll have to declare and define these methods:

void Spawn( void );
void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis );
void Launch( void );
void Fizzle( void );

You'll also have to add these data members from idDebris to idMovable:

idEntityPtr<idEntity> owner;
idPhysics_RigidBody physicsObj;
const idDeclParticle * smokeFly;
int smokeFlyTime;
const idSoundShader * sndBounce;


And you'll also have refactor some of idMovable's methods idDebris has as well, like Think() for instance.
/*
================
idDebris::Think
================
*/
void idDebris::Think( void ) {

// run physics
RunPhysics();
Present();

if ( smokeFly && smokeFlyTime ) {
if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) {
smokeFlyTime = 0;
}
}
}


versus

/*
================
idMoveable::Think
================
*/
void idMoveable::Think( void ) {
if ( thinkFlags & TH_THINK ) {
if ( !FollowInitialSplinePath() ) {
BecomeInactive( TH_THINK );
}
}
idEntity::Think();
}


It may be better to find out what causes debris to be removed so quickly then to refactor all of that. Perhaps set owner to NULL or to world object?
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 19, 2017, 08:05:59 AM
Thanks for the help. I replaced the code for think, but where do the other parts go?
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 20, 2017, 04:44:16 AM
The new methods and data members need to be added to where idMoveable is declared in Movable.h. Put the method definitions in Moveable.cpp.
Note that copying idDebris code into idMoveable might inadvertently change the behavior of all idMoveables so this isn't advised unless you add code to remedy the differences.
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 20, 2017, 07:45:46 AM
Error   582   error LNK2005: "public: virtual void __thiscall idDebris::Think(void)" (?Think@idDebris@@UAEXXZ) already defined in Moveable.obj Projectile.obj
Error   583   error LNK2001: unresolved external symbol "public: virtual void __thiscall idMoveable::Think(void)" (?Think@idMoveable@@UAEXXZ) Moveable.obj
Error   584   error LNK1120: 1 unresolved externals gamex86.dll


Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 20, 2017, 01:24:31 PM
Make sure there aren't multiple definitions of idDebris::Think, especially if you aren't going to being using idDebris anymore. The second error means idMoveable::Think was declared but never defined. That shouldn't happen as it already is defined in source code. Check your code.
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 20, 2017, 02:32:30 PM
Commented out copy in Projectile.cpp. The second error I'll show you the files for.
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 21, 2017, 03:12:24 AM
at line 405 in Moveable.cpp, you defined Think for idDebris, not idMoveable. idDebris::Think is being defined twice here and in projectile.cpp

Change this:
void idDebris::Think( void ) { //RPS

// run physics
RunPhysics();
Present();

if ( smokeFly && smokeFlyTime ) {
if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) {
smokeFlyTime = 0;
}
}
}


to this
void idMoveable::Think( void ) { // HERE -Phrozo

// run physics
RunPhysics();
Present();

if ( smokeFly && smokeFlyTime ) {
if ( !gameLocal.smokeParticles->EmitSmoke( smokeFly, smokeFlyTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) {
smokeFlyTime = 0;
}
}
}
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 21, 2017, 07:45:15 AM
Sorry about that.  :-[ It builds now. When I destroy the barrel I get:

loaded collision model models/mapobjects/fuel_barrel/exp_barrel2c.lwo
script\weapon_fists.script : weapon_fists::Fire
script\weapon_fists.script : weapon_fists::Fire
<NO FUNCTION>
--------- Game Map Shutdown ----------
--------------------------------------
********************
ERROR: script\weapon_fists.script(64): Thread 'thread_7': 'projectile_debris'
is not an idDebris

********************


I changed debris_barrelpiece, debris_barrelpiece2, debris_barreltop, and debris_barreltop2 spawnclass to idMoveable in moveable.def.
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 22, 2017, 12:05:38 AM
You need to re-read the code you modified. I'll detail the errors:

/*
================
idExplodingBarrel::Killed
================
*/
void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {

if ( IsHidden() || state == EXPLODING || state == BURNING ) {
return;
}

float f = spawnArgs.GetFloat( "burn" );
if ( f > 0.0f && state == NORMAL ) {
state = BURNING;
PostEventSec( &EV_Explode, f );
StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL );
AddParticles( spawnArgs.GetString ( "model_burn", "" ), true );
return;
} else {
state = EXPLODING;
if ( gameLocal.isServer ) {
idBitMsg msg;
byte msgBuf[MAX_EVENT_PARAM_SIZE];

msg.Init( msgBuf, sizeof( msgBuf ) );
msg.WriteLong( gameLocal.time );
ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 );
}
}

// do this before applying radius damage so the ent can trace to any damagable ents nearby
Hide();
physicsObj.SetContents( 0 );

const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" );
if ( splash && *splash ) {
gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash );
}

ExplodingEffects( );

//FIXME: need to precache all the debris stuff here and in the projectiles
const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
// bool first = true;
while ( kv ) {
const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
if ( debris_args ) {
idEntity *ent;
idVec3 dir;
idDebris *debris;     // error 1a
//RPS idMoveable *debris; //error 1b
//if ( first ) {
dir = physicsObj.GetAxis()[1];
// first = false;
//} else {
dir.x += gameLocal.random.CRandomFloat() * 4.0f;
dir.y += gameLocal.random.CRandomFloat() * 4.0f;
//dir.z = gameLocal.random.RandomFloat() * 8.0f;
//}
dir.Normalize();

gameLocal.SpawnEntityDef( *debris_args, &ent, false );
if ( !ent || !ent->IsType( idDebris::Type ) ) { // error2a
//RPS if ( !ent || !ent->IsType( idMoveable::Type ) ) { // error 2b
gameLocal.Error( "'projectile_debris' is not an idDebris" ); // error 3
}

debris = static_cast<idDebris *>(ent); // error 4a
//RPS debris = static_cast<idMoveable *>(ent); // error 4b
debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
debris->Launch();
//RPS debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
debris->UpdateVisuals();

}
kv = spawnArgs.MatchPrefix( "def_debris", kv );
}

physicsObj.PutToRest();
CancelEvents( &EV_Explode );
CancelEvents( &EV_Activate );

f = spawnArgs.GetFloat( "respawn" );
if ( f > 0.0f ) {
PostEventSec( &EV_Respawn, f );
} else {
PostEventMS( &EV_Remove, 5000 );
}

if ( spawnArgs.GetBool( "triggerTargets" ) ) {
ActivateTargets( this );
}
}


error 1: you declared debris to be of the type idMoveable* but commented it out and left it like it originally was
error 2: you modifed the type check to check for idMoveable::Type but comment it out and left it like it origionally was
error 3: you did not update the error message that you just saw printed to better reflect the changes you intended to make
error 4: you commented out the static_cast to type idMoveable* but commented it out

Your code still behaves like it did before you modified it, and the code did exactly what it was supposed to.
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 22, 2017, 01:30:26 AM
I'm not sure if I wanted to mark the changed lines and put the comment on the wrong side or if I wanted to go back to original behavior for some reason... It has a couple of unresolved symbols in class idMoveable, Create and Launch, and I'm not sure if they're added to the wrong place in Moveable.h:


class idMoveable : public idEntity {
public:
CLASS_PROTOTYPE( idMoveable );

idMoveable( void );
~idMoveable( void );

void Spawn( void );

void Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ); //RPS
void Launch( void ); //RPS
void Fizzle( void ); //RPS



error LNK2019: unresolved external symbol "public: void __thiscall idMoveable::Launch(void)" referenced in function "public: virtual void __thiscall idExplodingBarrel::Killed(class idEntity *,class idEntity *,int,class idVec3 const &,int)"

error LNK2019: unresolved external symbol "public: void __thiscall idMoveable::Create(class idEntity *,class idVec3 const &,class idMat3 const &)" referenced in function "public: virtual void __thiscall idExplodingBarrel::Killed(class idEntity *,class idEntity *,int,class idVec3 const &,int)"


Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 22, 2017, 02:00:40 AM
That is the right place to declare members for class idMoveable, but you still need to define the methods in idMoveable.cpp
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 22, 2017, 02:45:28 AM
Getting angry yet? The whole reason I asked for help is because this is alien to me.

I added idDebris::Launch and idDebris::Fizzle as idMoveable::Launch and idMoveable::Debris from Projectile.cpp into Moveable.cpp and added EV_Fizzle under the CLASS_DECLARATION as it showed an error about that, and now EV_Fizzle is listed as an undeclared identifier and Event_Fizzile not a member of idMoveable, added EV_Fizzle as a constant at the top of idMoveable from idProjectile and Event_Fizzle in Moveable.h under 'protected:' where the rest of the Event_ lines are listed as

void               Event_Fizzle( void );

and now running into protected: void __thiscall idMoveable:Event_Fizile(void)* and public: void __thiscall idMoveable::Create as unresolved symbols.
Title: Re: Game Code That Removes idDebris
Post by: The Happy Friar on June 22, 2017, 08:02:54 AM
Is it possible to not use the debris or C++ code at all and attach a script to the barrel def that spawns and throws out func_movables?
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 22, 2017, 10:44:56 AM
I'm just trying to do what I need to do however it takes to get this working. Coding is not something I know but then none of the details of the game I know very well which is why I asked for help.
Title: Re: Game Code That Removes idDebris
Post by: Phrozo on June 22, 2017, 11:11:49 AM
What you want requires refactoring the code which is not a small task, so it is essential you understand what you are doing. Most of your errors are from declaring a function in the class definition but not later defining it. Again, you need to define idMoveable:Event_Fizzle( void ) and idMoveable::Create( idEntity *owner, const idVec3 &start, const idMat3 &axis ). If you don't know the difference between a declaration and a definition you really should consider picking up a beginners book in C++.

I also took a second look at this problem and you also need to define events which I'm not sure how well they work. In all honesty this is not the right approach. Modify idDebris or try THF's new idea...
Title: Re: Game Code That Removes idDebris
Post by: spamclark15 on June 22, 2017, 12:57:21 PM
Alright, moveables.def contains the 4 pieces of debris, what is involved?