Gibs
Hallo Freunde der Programmierung, Heute werden wir Gibs für Zombines erstellen. Dies funktioniert auch für andere NPCs/Spieler, wenn du ein wenig programmierst.
Event_Killed Bearbeiten
Als erstes öffnest du den Zombine-Code (npc_zombine.cpp), suchst nach "Event_Killed" und löschst alles mit Ausnahme von BaseClass::Event_Killed( info )
. Dies ruft das reguläre Event_Killed, sodass wir immernoch einen Ragdoll haben und der Zombine korrekt stirbt.
Als nächstes erstellst du die Gib-Modelle. Du kannst ein Paket von Garrysmod.org herunterladen, wenn du willst. In diesem Fall musst du bestätigen, dass du Garys Mod legal besitzt, um dort irgendetwas herunterladen zu können.
Pack die Modelle in dein Mod-Verzeichnis und füge in dem Event_Killed-Abschnitt folgendes ein:
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 );
}
Dies sorgt dafür, dass, wenn du den Zombine mit einer Waffe mit Buckshot Ammo (Schrotflinte) anschießt oder der Zombine Explosivschaden nimmt, dass er in viele Stücke zerspringt und sein Torso verliert. Es gibt verschiedene DMGs in shareddefs.h, wie DMG_BURN oder DMG_BULLET, also kannst du (DMG_BUCKSHOT | DMG_BLAST) mit den Schadensarten deiner Wahl ersetzen.
Du kannst mit einem | mehr Schadensarten 'hinzufügen'.
Vor dem Kompilieren solltest du sicher gehen, dass du die verwendeten Models Precachest, da du sonst Fehler bekommst.
Wenn du dieses Verhalten des Gegners nur ab einer bestimmten Menge von Schaden herbaiführen willst, dann füge diese Bedingung zur Vorherigen im oberen Beispiel hinzu:
if( info.GetDamage() >= ( m_iMaxHealth * 0.75f ) )
{
//Earlier Gib Function
}
In diesem Fall muss dem Gegner ein Schaden von ~75 % seiner maximalen Lebensenergie verpasst werden.
Ausblenden/Entfernen von Gibs
Wenn du mit dem Multiplayer SDK arbeitest, willst du, dass deine Gibs nach einer Weile ausgeblendet werden, statt in der Welt zu verbleiben. Das Problem ist, dass die SpawnSpecificGibs-Funktion keinen Parameter für eine Lebensdauer entgegennimmt (5 Sekunden, wie im letzten Beispiel erwähnt).
Um diesen Fehler zu beheben, lade die Quelldatei (gib.cpp), finde die Funktion "CGib::SpawnSpecificGibs" und füge dies an Stelle der ursprünglichen Funktion ein.
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 );
}
}
}
Der Unterschied zwischen den beiden Funktionen ist, dass die Spawn-Funktion jetzt den Lebensdauer-Parameter verwendet, um den Zeitpunkt des Ausblendens zu wissen.
Brennende Gibs durch entflammte Player
Mal angenommen, du triffst einen entzündeten Spieler gut gezielt mit einer Rakete, also willst du ihn vielleicht in brennende Einzelteile zerspringen lassen. Wenn ja, dann musst du lediglich die folgende Bedingung einfügen, welche das Spiel fragt, ob das Opfer brennt und ggf. seine Einzelteile ebenfalls anzündet.
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 07:02, 20 May 2013 (PDT) - Sorry for my English :) (translate into German please)
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.
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, collor of bool, amount of blood, and effects.
BLOOD_COLOR_RED - collor 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