Difference between revisions of "Gibs"

From Valve Developer Community
Jump to: navigation, search
m (Little fix)
(Grammar fixes and general improvement of article.)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{otherlang2
 
{{otherlang2
 +
|ru=Gibs:ru
 
|de=Gibs:de
 
|de=Gibs:de
 
}}
 
}}
Hello there people of the coding world. Today, we are going to make gibs for the zombine. This can also work in other NPCs/Players if you do a bit of coding.
+
Today, we are going to learn to implement general gibbing using the CGibs class. This can work on NPCs/Players.
  
 
== Editing Event_Killed ==
 
== Editing Event_Killed ==
 
So first, open up the Zombine code (npc_zombine.cpp) and search for the void "Event_Killed" Delete everything in there except for <code>BaseClass::Event_Killed( info )</code>. This calls up the Regular Event_Killed so that we can still have a ragdoll and the zombine dies correctly.
 
So first, open up the Zombine code (npc_zombine.cpp) and search for the void "Event_Killed" Delete everything in there except for <code>BaseClass::Event_Killed( info )</code>. This calls up the Regular Event_Killed so that we can still have a ragdoll and the zombine dies correctly.
  
Next, create your gib models. You can download a pack from [http://www.garrysmod.org/downloads/?a=view&id=72352 Garrysmod.org] if you want, However you will have to verify that you legally own Garry's Mod to download anything there.
+
To get models for the giblets, you can download a pack from [https://garrysmods.org/download/12498/ Garrysmod.org] if youre into Garry's Mod Classic, You can also model your own that act like physics props and have a surface property of flesh.
  
 
Put those in your mod folder, and in the Event_Killed section, add this:
 
Put those in your mod folder, and in the Event_Killed section, add this:
Line 36: Line 37:
 
This will make it so that when you shoot the zombie with any gun that uses the Buckshot ammo (Shotgun), or when receiving explosive damage he will blow into many pieces, and will lose his torso. There are different DMGs in shareddefs.h, such as DMG_BURN, DMG_BULLET, etc., and replace (DMG_BUCKSHOT | DMG_BLAST) with whatever you want.
 
This will make it so that when you shoot the zombie with any gun that uses the Buckshot ammo (Shotgun), or when receiving explosive damage he will blow into many pieces, and will lose his torso. There are different DMGs in shareddefs.h, such as DMG_BURN, DMG_BULLET, etc., and replace (DMG_BUCKSHOT | DMG_BLAST) with whatever you want.
  
You can 'add' more types by oring the flags together.
+
You can 'add' more types by combining different flags together.
  
Before you compile, make sure that you Precache the models your using, or you will get with errors.
+
Before you compile, make sure that you Precache the models you're using, or you will get a lot of errors.
  
If you want the enemy to gib only when a significant amount of damage is done, add this if statement around the first one in the earlier example.
+
If you want the enemy to gib only when a significant amount of damage is done, add this 'if' conditional statement around the first one in the earlier example.
  
 
<source lang=cpp>
 
<source lang=cpp>
Line 187: Line 188:
 
</source>
 
</source>
  
'''UTIL_BloodSpray''' have position, collor of bool, amount of blood, and effects.
+
'''UTIL_BloodSpray''' have position, color of bool, amount of blood, and effects.
  
BLOOD_COLOR_RED - collor of blood. All define:
+
BLOOD_COLOR_RED - color of blood. All define:
 
* BLOOD_COLOR_RED
 
* BLOOD_COLOR_RED
 
* BLOOD_COLOR_YELLOW
 
* BLOOD_COLOR_YELLOW
Line 205: Line 206:
 
Random effect it's really good things! Because At explosion can tear off any part of the body, this time torn off the arm, the next legs. and etc. So, add this after our Vectors:
 
Random effect it's really good things! Because At explosion can tear off any part of the body, this time torn off the arm, the next legs. and etc. So, add this after our Vectors:
 
<source lang=cpp>
 
<source lang=cpp>
// Рандомное появления кусков тела, 4 варианта
 
 
m_RandomGib = random->RandomInt( 1, 2 );  
 
m_RandomGib = random->RandomInt( 1, 2 );  
 
</source>
 
</source>
Line 218: Line 218:
 
   if ( m_RandomGib == 1 )
 
   if ( m_RandomGib == 1 )
 
   {
 
   {
// Реализация крови
 
 
UTIL_BloodSpray( WorldSpaceCenter(), vecDamageDir, BLOOD_COLOR_RED, 17, FX_BLOODSPRAY_ALL );
 
UTIL_BloodSpray( WorldSpaceCenter(), vecDamageDir, BLOOD_COLOR_RED, 17, FX_BLOODSPRAY_ALL );
// Главная модель
 
 
SetModel( "models/zombie/classic_torso.mdl" );  
 
SetModel( "models/zombie/classic_torso.mdl" );  
 
// Gibs
 
// Gibs
 
CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/Gibs/HGIBS.mdl", 5 );
 
CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/Gibs/HGIBS.mdl", 5 );
  
// Gibs ног через ентю
 
 
CBaseEntity *pLegsGib = CreateRagGib( "models/zombie/classic_legs.mdl", GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
 
CBaseEntity *pLegsGib = CreateRagGib( "models/zombie/classic_legs.mdl", GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
 
if ( pLegsGib ) { CopyRenderColorTo( pLegsGib ); }
 
if ( pLegsGib ) { CopyRenderColorTo( pLegsGib ); }
Line 240: Line 237:
  
 
</source>
 
</source>
 
Well, here's the basis of code... Oh! Watch the video! It's below!
 
  
 
== Example Video ==
 
== Example Video ==
  
I recorded a video that demonstrated these effects. But I made, this effect on the "npc_zombine' :)
+
I recorded a video that demonstrates this effect.
  
Look result: http://youtu.be/V36JwLtfJbY
+
Look at the result of our work: http://youtu.be/V36JwLtfJbY
  
 
[[Category:Programming]]
 
[[Category:Programming]]

Latest revision as of 10:17, 18 August 2021

Deutsch Русский

Today, we are going to learn to implement general gibbing using the CGibs class. This can work on NPCs/Players.

Editing Event_Killed

So first, open up the Zombine code (npc_zombine.cpp) and search for the void "Event_Killed" Delete everything in there except for BaseClass::Event_Killed( info ). This calls up the Regular Event_Killed so that we can still have a ragdoll and the zombine dies correctly.

To get models for the giblets, you can download a pack from Garrysmod.org if youre into Garry's Mod Classic, You can also model your own that act like physics props and have a surface property of flesh.

Put those in your mod folder, and in the Event_Killed section, add this:

if( info.GetDamageType() & ( DMG_BUCKSHOT | DMG_BLAST ) )
{
	SetModel( "models/zombie/classic_legs.mdl" );

	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/pgib_p1.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/pgib_p2.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/pgib_p3.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/pgib_p4.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/pgib_p5.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/hgibs_jaw.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/hgibs_scapula.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/hgibs_scapula.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p1.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p2.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p3.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p4.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p5.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/rgib_p6.mdl", 5 );
	CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/gibs/gibhead.mdl", 5 );
}

This will make it so that when you shoot the zombie with any gun that uses the Buckshot ammo (Shotgun), or when receiving explosive damage he will blow into many pieces, and will lose his torso. There are different DMGs in shareddefs.h, such as DMG_BURN, DMG_BULLET, etc., and replace (DMG_BUCKSHOT | DMG_BLAST) with whatever you want.

You can 'add' more types by combining different flags together.

Before you compile, make sure that you Precache the models you're using, or you will get a lot of errors.

If you want the enemy to gib only when a significant amount of damage is done, add this 'if' conditional statement around the first one in the earlier example.

if( info.GetDamage() >= ( m_iMaxHealth * 0.75f ) )
{
	//Earlier Gib Function
}

In this case, if an enemy has 100 health, you'll have to take at least ~75% of their health within the killing blow for them to gib.

Fading/Removing Gibs

If you're working with the Multiplayer SDK, you may want to have your gibs fade after a period of time rather than stay on the world. The issue is that the SpawnSpecificGibs function doesn't use the argument for lifespan (5 seconds as noted in the previous example).

To fix this issue, load up the gibs source file (gib.cpp), find the function "CGib::SpawnSpecificGibs", and paste this in place of the original function.

void CGib::SpawnSpecificGibs(	CBaseEntity*	pVictim, 
								int				nNumGibs, 
								float			vMinVelocity, 
								float			vMaxVelocity, 
								const char*		cModelName,
								float			flLifetime)
{
	for ( int i = 0; i < nNumGibs; i++ )
	{
		CGib *pGib = CREATE_ENTITY( CGib, "gib" );
		pGib->Spawn( cModelName, flLifetime );
		pGib->m_nBody = i;
		pGib->InitGib( pVictim, vMinVelocity, vMaxVelocity );
		pGib->m_lifeTime = flLifetime;

		if ( pVictim != NULL )
		{
			pGib->SetOwnerEntity( pVictim );
		}
	}
}

The change between the two functions is that now the Spawn function uses the lifetime argument to know when to fade away.

Burning Gibs When Gibbing an Ignited Player

Let's say you hit an ignited player with a well aimed rocket, so you want him to chunk up into a bunch of flaming gibs. If so, just add this if statement that asks the game whether the victim is on fire, and if so, ignite his gibs as well.

void CGib::SpawnSpecificGibs(	CBaseEntity*	pVictim, 
								int				nNumGibs, 
								float			vMinVelocity, 
								float			vMaxVelocity, 
								const char*		cModelName,
								float			flLifetime)
{
	for ( int i = 0; i < nNumGibs; i++ )
	{
		CGib *pGib = CREATE_ENTITY( CGib, "gib" );
		pGib->Spawn( cModelName, flLifetime );
		pGib->m_nBody = i;
		pGib->InitGib( pVictim, vMinVelocity, vMaxVelocity );
		pGib->m_lifeTime = flLifetime;

		if ( pVictim != NULL )
		{
			pGib->SetOwnerEntity( pVictim );
		}

		//If pVictim is on fire, ignite pVictim's gibs as well.
		if ( pVictim->GetFlags() & FL_ONFIRE )
		{
			pGib->Ignite( ( flLifetime - 1 ), false );
		}
	}
}

Adding Ragdoll Gibs

Slam12f 06:59, 20 May 2013 (PDT) - Sorry for my English :)

So, it's very interesting lesson, but something does not suffice... To be exact lack the Ragdoll Gibs how said Pfannkuchen. For example, the explosion can tear only the legs and torso will be saved. But!

If you add Torse how gibs, this not work correct. For this we must use enty CBaseEntity *CreateRagGib.

Incidentally it's implemented when you chop off legsnpc_zombie using GravityGun and a blade of saw.

So, after:

void CNPC_Zombine::Event_Killed( const CTakeDamageInfo &info )
{

add this Vectors, he give position of our model, and time of fade:

	// Вектора для модели торса
	Vector vecLegsForce; // Даём понять что vecLegsForce это вектор
	vecLegsForce.x = random->RandomFloat( -400, 400 ); // Рандомное значение по оси X от -400 до 400
	vecLegsForce.y = random->RandomFloat( -400, 400 ); // Рандомное значение по оси Y от -400 до 400
	vecLegsForce.z = random->RandomFloat( 0, 250 ); // Рандомное значение по оси Z от -400 до 400
	float flFadeTime = 0.0; // Время исчезновения.

After or defore any CGib::SpawnSpecificGibs add this code:

		// Ragdoll Gibs торса через ентю
		CBaseEntity *pLegsGib = CreateRagGib( "models/zombie/classic_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
			if ( pLegsGib )	{ CopyRenderColorTo( pLegsGib ); }

I think you can understand all parameters of CreateRagGib.

If you use your model don't forget in void CNPC_Zombine::Precache( void ) after BaseClass::Precache(); add your model, for example:

PrecacheModel( "models/zombie/zombie_soldier_left_legs.mdl" ); // Кэширование левой ноги
PrecacheModel( "models/zombie/zombie_soldier_left_legs_up.mdl" ); // Кэширование левой ноги верхняя часть
PrecacheModel( "models/zombie/zombie_soldier_left_legs_down.mdl" ); // Кэширование левой ноги нижняя часть

But that's not all!!! I show how you can do Random gibs, and how add effect of blood.

Effect of Blood(BloodSpray)

That's effect I done with help UTIL_BloodSpray.

Note.png Note:  Please read all information about blood: UTIL_BloodDecalTrace UTIL_BloodDrips UTIL_BloodImpact UTIL_BloodSpray UTIL_BloodStream UTIL_ShouldShowBlood

I think you read about these effects, and now let's implement one of them. More concrete UTIL_BloodSpray.

The first, after our new vector add this:

	// Вектор для спрайта
	Vector vecDamageDir = info.GetDamageForce();

Our effect appears in the area damage. The next step, before CGib::SpawnSpecificGibs or CBaseEntity *pLegsGib = CreateRagGib add this code:

		// Реализация крови
		UTIL_BloodSpray( WorldSpaceCenter(), vecDamageDir, BLOOD_COLOR_RED, 13, FX_BLOODSPRAY_ALL );

UTIL_BloodSpray have position, color of bool, amount of blood, and effects.

BLOOD_COLOR_RED - color of blood. All define:

  • BLOOD_COLOR_RED
  • BLOOD_COLOR_YELLOW
  • BLOOD_COLOR_GREEN
  • BLOOD_COLOR_MECH

FX_BLOODSPRAY_ALL - concrete effect of blood

  • FX_BLOODSPRAY_DROPS // Капли
  • FX_BLOODSPRAY_GORE // Запёкшаяся кровь
  • FX_BLOODSPRAY_CLOUD // Облака (Этот эффект используется в ep2 когда сбиваешь зомбайна)
  • FX_BLOODSPRAY_ALL // Всё и сразу

Random gibs

Random effect it's really good things! Because At explosion can tear off any part of the body, this time torn off the arm, the next legs. and etc. So, add this after our Vectors:

	m_RandomGib = random->RandomInt( 1, 2 );

1 min value, 2 max value.

We have 2 variants. The first for example: Legs, Torso, HeadCrab and the skull. The Second: Body, headcrab and skull.

if( info.GetDamageType() & ( DMG_BLAST ) ) // this just that you don't get lost.
 { // это только чтобы вы не потерялись в вашем коде.
   if ( m_RandomGib == 1 )
   {
		UTIL_BloodSpray( WorldSpaceCenter(), vecDamageDir, BLOOD_COLOR_RED, 17, FX_BLOODSPRAY_ALL );
		SetModel( "models/zombie/classic_torso.mdl" ); 
		// Gibs
		CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/Gibs/HGIBS.mdl", 5 );

		CBaseEntity *pLegsGib = CreateRagGib( "models/zombie/classic_legs.mdl", GetAbsOrigin(), GetAbsAngles(), vecLegsForce, flFadeTime, ShouldIgniteZombieGib() );
			if ( pLegsGib )	{ CopyRenderColorTo( pLegsGib ); }		
   }
   if ( m_RandomGib == 2 ) // or you can write "else". ( m_RandomGib == 2 ) - this if you have 3 random value for example.
   {			 // или можете написать "else". ( m_RandomGib == 2 )- это если у вас допустим 3 рандомных значения.
		// Реализация крови
		UTIL_BloodSpray( WorldSpaceCenter(), vecDamageDir, BLOOD_COLOR_RED, 13, FX_BLOODSPRAY_ALL );
		// Главная модель
		SetModel( "models/zombie/zombie_soldier_torso.mdl" ); 
		// Gibs
		CGib::SpawnSpecificGibs( this, 1, 750, 1500, "models/Gibs/HGIBS.mdl", 5 );	
   }

Example Video

I recorded a video that demonstrates this effect.

Look at the result of our work: http://youtu.be/V36JwLtfJbY