272 lines
5.9 KiB
C++
272 lines
5.9 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Logfile:: /EF2/Code/DLLs/game/gibs.cpp $
|
|
// $Revision:: 12 $
|
|
// $Author:: Singlis $
|
|
// $Date:: 9/26/03 2:36p $
|
|
//
|
|
// Copyright (C) 1998 by Ritual Entertainment, Inc.
|
|
// All rights reserved.
|
|
//
|
|
// This source is may not be distributed and/or modified without
|
|
// expressly written permission by Ritual Entertainment, Inc.
|
|
//
|
|
//
|
|
// DESCRIPTION:
|
|
// Gibs - nuff said
|
|
|
|
#include "_pch_cpp.h"
|
|
#include "gibs.h"
|
|
#include "decals.h"
|
|
#include "mp_manager.hpp"
|
|
|
|
Event EV_ThrowGib
|
|
(
|
|
"throwgib",
|
|
EV_DEFAULT,
|
|
"eff",
|
|
"ent velocity scale",
|
|
"Throw a gib."
|
|
);
|
|
|
|
CLASS_DECLARATION( Entity, Gib, "gib" )
|
|
{
|
|
{ &EV_ThrowGib, &Gib::Throw },
|
|
{ &EV_Touch, &Gib::Splat },
|
|
{ &EV_Stop, &Gib::Stop },
|
|
{ &EV_Damage, &Gib::Damage },
|
|
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Gib::Gib( const str &name, qboolean blood_trail, const str &bloodtrailname, const str &bloodspurtname,
|
|
const str &bloodsplatname, float bloodsplatsize, float pitch )
|
|
{
|
|
animate = new Animate( this );
|
|
|
|
setSize(Vector(0, 0, 0), Vector(0, 0, 0));
|
|
|
|
if ( name.length() )
|
|
setModel( name.c_str() );
|
|
|
|
setMoveType( MOVETYPE_GIB );
|
|
setSolidType( SOLID_BBOX );
|
|
takedamage = DAMAGE_YES;
|
|
sprayed = false;
|
|
fadesplat = true;
|
|
scale = 2.0f;
|
|
|
|
next_bleed_time = 0;
|
|
|
|
final_pitch = pitch;
|
|
|
|
if ( blood_trail )
|
|
{
|
|
// Make a blood emitter and bind it to the head
|
|
blood = new Entity( ENTITY_CREATE_FLAG_ANIMATE );
|
|
|
|
if ( bloodtrailname.length() )
|
|
blood->setModel( bloodtrailname.c_str() );
|
|
|
|
blood->setMoveType( MOVETYPE_BOUNCE );
|
|
blood->setSolidType( SOLID_NOT );
|
|
blood->bind( this );
|
|
|
|
// Save the blood spurt name
|
|
|
|
if ( bloodspurtname.length() )
|
|
blood_spurt_name = bloodspurtname;
|
|
|
|
// Save the blood splat name
|
|
|
|
if ( bloodsplatname.length() )
|
|
blood_splat_name = bloodsplatname;
|
|
|
|
blood_splat_size = bloodsplatsize;
|
|
}
|
|
else
|
|
{
|
|
blood = NULL;
|
|
}
|
|
|
|
Sound( "snd_decap", CHAN_BODY, 1.0f, 300.0f );
|
|
}
|
|
|
|
Gib::~Gib()
|
|
{
|
|
if ( blood )
|
|
blood->PostEvent( EV_Remove, 0.0f );
|
|
blood = NULL;
|
|
}
|
|
|
|
Gib::Gib()
|
|
{
|
|
animate = new Animate( this );
|
|
|
|
if ( LoadingSavegame )
|
|
{
|
|
return;
|
|
}
|
|
|
|
setSize(Vector(0, 0, 0), Vector(0, 0, 0));
|
|
setModel("gib1.def");
|
|
setMoveType( MOVETYPE_GIB );
|
|
setSolidType( SOLID_BBOX );
|
|
sprayed = 0;
|
|
fadesplat = true;
|
|
scale = 2.0f;
|
|
}
|
|
|
|
void Gib::Stop( Event *ev )
|
|
{
|
|
//setSolidType( SOLID_NOT );
|
|
if ( blood )
|
|
blood->PostEvent( EV_Remove, 0.0f );
|
|
blood = NULL;
|
|
}
|
|
|
|
void Gib::Splat( Event *ev )
|
|
{
|
|
if ( multiplayerManager.inMultiplayer() )
|
|
return;
|
|
|
|
if ( sprayed > 3 )
|
|
{
|
|
//setSolidType(SOLID_NOT);
|
|
return;
|
|
}
|
|
|
|
sprayed++;
|
|
scale -= 0.2f;
|
|
|
|
// Stop spinning / force to final pitch
|
|
|
|
avelocity = vec_zero;
|
|
|
|
if ( final_pitch != NO_FINAL_PITCH )
|
|
{
|
|
angles[PITCH] = final_pitch;
|
|
setAngles( angles );
|
|
}
|
|
|
|
SprayBlood( origin );
|
|
Sound( "snd_gibhit" );
|
|
}
|
|
|
|
void Gib::Damage( Event *ev )
|
|
{
|
|
Vector direction;
|
|
Entity *blood;
|
|
Vector dir;
|
|
|
|
if ( next_bleed_time > level.time )
|
|
return;
|
|
|
|
direction = ev->GetVector ( 5 );
|
|
|
|
// Spawn a blood spurt
|
|
|
|
if ( blood_spurt_name.length() > 0 )
|
|
{
|
|
blood = new Entity( ENTITY_CREATE_FLAG_ANIMATE );
|
|
blood->setModel( blood_spurt_name.c_str() );
|
|
|
|
dir[0] = -direction[0];
|
|
dir[1] = -direction[1];
|
|
dir[2] = -direction[2];
|
|
|
|
blood->angles = dir.toAngles();
|
|
blood->setAngles( blood->angles );
|
|
|
|
blood->setOrigin( centroid );
|
|
blood->origin.copyTo( blood->edict->s.origin2 );
|
|
blood->setSolidType( SOLID_NOT );
|
|
|
|
blood->PostEvent( EV_Remove, 1.0f );
|
|
|
|
next_bleed_time = level.time + 0.5f;
|
|
}
|
|
}
|
|
|
|
void Gib::SprayBlood( const Vector &start )
|
|
{
|
|
Vector norm;
|
|
trace_t trace;
|
|
Vector trace_end;
|
|
|
|
trace_end = velocity;
|
|
trace_end.normalize();
|
|
trace_end *= 1000.0f;
|
|
trace_end += start;
|
|
|
|
trace = G_Trace( start, vec_zero, vec_zero, trace_end, this, MASK_SOLID, false, "Gib::SprayBlood" );
|
|
|
|
if ( HitSky( &level.impact_trace ) || ( !level.impact_trace.ent ) || ( level.impact_trace.ent->solid != SOLID_BSP ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Do a bloodsplat
|
|
if ( blood_splat_name.length() )
|
|
{
|
|
Decal *decal = new Decal;
|
|
decal->setShader( blood_splat_name );
|
|
decal->setOrigin( Vector( trace.endpos ) + ( Vector( level.impact_trace.plane.normal ) * 0.2f ) );
|
|
decal->setDirection( level.impact_trace.plane.normal );
|
|
decal->setOrientation( "random" );
|
|
decal->setRadius( blood_splat_size + G_Random( blood_splat_size ) );
|
|
}
|
|
}
|
|
|
|
void Gib::ClipGibVelocity( void )
|
|
{
|
|
if (velocity[0] < -400.0f)
|
|
velocity[0] = -400.0f;
|
|
else if (velocity[0] > 400.0f)
|
|
velocity[0] = 400.0f;
|
|
if (velocity[1] < -400.0f)
|
|
velocity[1] = -400.0f;
|
|
else if (velocity[1] > 400.0f)
|
|
velocity[1] = 400.0f;
|
|
if (velocity[2] < 200.0f)
|
|
velocity[2] = 200.0f; // always some upwards
|
|
else if (velocity[2] > 600.0f)
|
|
velocity[2] = 600.0f;
|
|
}
|
|
|
|
void Gib::SetVelocity( float damage )
|
|
{
|
|
velocity[0] = 100.0f * crandom();
|
|
velocity[1] = 100.0f * crandom();
|
|
velocity[2] = 200.0f + 100.0f * random();
|
|
|
|
avelocity = Vector( G_Random( 600.0f ), G_Random( 600.0f ), G_Random( 600.0f ) );
|
|
|
|
if ( ( damage < -150.0f ) && ( G_Random() > 0.95f ) )
|
|
velocity *= 2.0f;
|
|
else if ( damage < -100.0f )
|
|
velocity *= 1.5f;
|
|
|
|
ClipGibVelocity();
|
|
}
|
|
|
|
void Gib::Throw( Event *ev )
|
|
{
|
|
Entity *ent;
|
|
|
|
ent = ev->GetEntity(1);
|
|
|
|
if ( !ent )
|
|
return;
|
|
|
|
setOrigin(ent->centroid);
|
|
origin.copyTo(edict->s.origin2);
|
|
SetVelocity(ev->GetFloat(2));
|
|
edict->s.scale = ev->GetFloat(3);
|
|
PostEvent( EV_FadeOut, 10.0f + G_Random( 5.0f ) );
|
|
}
|
|
|
|
void CreateGibs( Entity * ent, float damage, float scale, int num, const char * modelname )
|
|
{
|
|
|
|
}
|