Gibs

From Valve Developer Community
Jump to: navigation, search
Deutsch Русский

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.

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.

Next, create your gib models. You can download a pack from Garrysmod.org if you want, However you will have to verify that you legally own Garry's Mod to download anything there.

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 oring the flags together.

Before you compile, make sure that you Precache the models you're using, or you will get with 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( 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: 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:

	// Рандомное появления кусков тела, 4 варианта
	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 );
 
		// Gibs ног через ентю
		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 );	
   }

Well, here's the basis of code... Oh! Watch the video! It's below!

Example Video

I recorded a video that demonstrated these effects. But I made, this effect on the "npc_zombine' :)

Look result: http://youtu.be/V36JwLtfJbY