//----------------------------------------------------------------------------- // // $Logfile:: /EF2/Code/DLLs/game/goo.cpp $ // $Revision:: 7 $ // $Author:: Singlis $ // $Date:: 9/26/03 2:36p $ // // Copyright (C) 1998 by Ritual Entertainment, Inc. // All rights reserved. // // This source may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // // // DESCRIPTION: // Goo Gun Projectile #include "_pch_cpp.h" #include "goo.h" Event EV_GooDebris_Prethink ( "_prethink", EV_CODEONLY, NULL, NULL, "Think function for the debris" ); CLASS_DECLARATION( Projectile, GooDebris, NULL ) { { &EV_GooDebris_Prethink, &GooDebris::Prethink }, { &EV_Touch, &GooDebris::Touch }, { NULL, NULL } }; GooDebris::GooDebris() { nexttouch = 0; } void GooDebris::Prethink( Event *ev ) { if ( ( velocity.length() < 30.0f ) && ( CurrentAnim() == gi.Anim_NumForName( edict->s.modelindex, "idle" ) ) ) { velocity = Vector( 0.0f, 0.0f, 0.0f ); animate->RandomAnimate( "splat" ); } if ( ( level.time - this->edict->spawntime ) > 5.0f ) { edict->s.scale *= 0.95f; } if ( edict->s.scale < 0.1f ) { PostEvent( EV_Remove, 0.0f ); } else { Event *ev1 = new Event( ev ); PostEvent( ev1, level.frametime ); } } void GooDebris::Touch( Event *ev ) { Entity *other; Entity *owner; Vector ang; other = ev->GetEntity( 1 ); if ( other == world ) { vectoangles( level.impact_trace.plane.normal, ang ); setAngles( ang ); } if ( level.time < nexttouch ) { return; } nexttouch = level.time + 0.5f; if ( !other || !other->isSubclassOf( Sentient ) ) { return; } owner = G_GetEntity( this->owner ); if ( !owner ) { owner = world; } if ( !other ) { return; } other->Damage( this, owner, damage, origin, Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), 0, 0, meansofdeath ); } Event EV_Goo_DebrisModel ( "goodebrismodel", EV_TIKIONLY, "s", "modelname", "Model name for the debris that is spawned on explosion" ); Event EV_Goo_DebrisCount ( "goodebriscount", EV_TIKIONLY, "i", "count", "Number of pieces of debris to spawn" ); CLASS_DECLARATION( Projectile, GooProjectile, NULL ) { { &EV_Goo_DebrisModel, &GooProjectile::SetDebrisModel }, { &EV_Goo_DebrisCount, &GooProjectile::SetDebrisCount }, { NULL, NULL } }; GooProjectile::GooProjectile() { m_debrismodel = "fx_goo_debris.tik"; m_debriscount = 3; } void GooProjectile::SetDebrisModel( Event *ev ) { m_debrismodel = ev->GetString( 1 ); } void GooProjectile::SetDebrisCount( Event *ev ) { m_debriscount = ev->GetInteger( 1 ); } void GooProjectile::Explode( Event *ev ) { int i; Entity *owner; Entity *ignoreEnt=NULL; if ( ev->NumArgs() == 1 ) ignoreEnt = ev->GetEntity( 1 ); // Get the owner of this projectile owner = G_GetEntity( this->owner ); // If the owner's not here, make the world the owner if ( !owner ) owner = world; takedamage = DAMAGE_NO; // Spawn an explosion model if ( explosionmodel.length() ) { // Move the projectile back off the surface a bit so we can see // explosion effects. Vector dir, v; v = velocity; v.normalize(); dir = v; v = origin - v * 36.0f; setOrigin( v ); ExplosionAttack( v, owner, explosionmodel, dir, ignoreEnt ); } CancelEventsOfType( EV_Projectile_UpdateBeam ); // Kill the beam if ( m_beam ) { m_beam->ProcessEvent( EV_Remove ); m_beam = NULL; } // When the goo hits something, spawn debris for ( i=0; iorigin, dir, this, m_debrismodel, 1.0f ); if ( !proj ) { warning( "GooProjectile::Explode", "Could not create debris projectile" ); return; } proj->owner = ENTITYNUM_WORLD; proj->setSolidType( SOLID_TRIGGER ); proj->avelocity = Vector( G_CRandom( 360.0f ), G_CRandom( 360.0f ), G_CRandom( 360.0f ) ); proj->setSize( Vector( -16.0f, -16.0f, 0.0f ) * proj->edict->s.scale, Vector( 16.0f ,16.0f ,32.0f ) * proj->edict->s.scale ); proj->setMoveType( MOVETYPE_TOSS ); proj->PostEvent( EV_GooDebris_Prethink, level.frametime ); } // Change to the splat if ( level.impact_trace.ent && ( level.impact_trace.ent->solid == SOLID_BSP ) ) { GooDebris *p; Vector ang; p = new GooDebris; vectoangles( level.impact_trace.plane.normal, ang ); p->setAngles( ang ); p->setModel( this->model ); p->ProcessInitCommands( p->edict->s.modelindex ); p->setSize( Vector( -16.0f, -16.0f, 0.0f ) * p->edict->s.scale, Vector( 16.0f, 16.0f, 32.0f ) * p->edict->s.scale ); p->setOrigin( this->origin ); p->velocity = Vector( 0.0f, 0.0f, 0.0f ); p->setMoveType( MOVETYPE_FLY ); p->setSolidType( SOLID_TRIGGER ); p->animate->RandomAnimate( "splat" ); p->owner = this->owner; p->PostEvent( EV_GooDebris_Prethink, level.frametime ); // shrink out } }