832 lines
17 KiB
C++
832 lines
17 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Logfile:: /Quake 2 Engine/Sin/code/game/spidermine.cpp $
|
|
// $Revision:: 50 $
|
|
// $Author:: Markd $
|
|
// $Date:: 6/07/99 2:29p $
|
|
//
|
|
// 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.
|
|
//
|
|
// $Log:: /Quake 2 Engine/Sin/code/game/spidermine.cpp $
|
|
//
|
|
// 50 6/07/99 2:29p Markd
|
|
// fixed null pointer bug
|
|
//
|
|
// 49 11/18/98 1:27a Jimdose
|
|
// Fixed sliding and orientation issues with gravaxis
|
|
//
|
|
// 48 11/16/98 9:44p Jimdose
|
|
// fixed sticking on alternate gravaxis
|
|
//
|
|
// 47 11/16/98 3:12a Jimdose
|
|
// mine takes gravity of owner
|
|
//
|
|
// 46 11/15/98 10:31p Jimdose
|
|
// view of spidermine is now towards direction it's moving
|
|
//
|
|
// 45 11/13/98 8:00p Markd
|
|
// Fixed spider mine bug with owner being reset to world too soon
|
|
//
|
|
// 44 11/13/98 3:30p Markd
|
|
// put in more precaching on weapons
|
|
//
|
|
// 43 11/13/98 2:35a Aldie
|
|
// Lowered the rank of spidermines
|
|
//
|
|
// 42 11/11/98 5:12p Aldie
|
|
// Spidermine fix when player dies - don't drop it
|
|
//
|
|
// 41 11/09/98 2:52a Aldie
|
|
// increase health
|
|
//
|
|
// 40 11/09/98 12:12a Aldie
|
|
// Made it so you can reclaim your mines when you die, and mines are now shootable
|
|
//
|
|
// 39 10/26/98 2:50p Aldie
|
|
// Fixed a bug with checking of NULL owners
|
|
//
|
|
// 38 10/24/98 12:42a Markd
|
|
// changed origins to worldorigins where appropriate
|
|
//
|
|
// 37 10/22/98 7:57p Markd
|
|
// put in proper pre-caching in all the classes
|
|
//
|
|
// 36 10/22/98 4:33p Aldie
|
|
// Fix for spidermine and detonators
|
|
//
|
|
// 35 10/21/98 12:09a Aldie
|
|
// Removed friction
|
|
//
|
|
// 34 10/20/98 8:26p Markd
|
|
// Added Attacker to DamageSurface stuff
|
|
//
|
|
// 33 10/19/98 12:07a Jimdose
|
|
// made all code use fast checks for inheritance (no text lookups when possible)
|
|
// isSubclassOf no longer requires ::_classinfo()
|
|
//
|
|
// 32 10/16/98 10:22p Aldie
|
|
// Updated single player damage settings
|
|
//
|
|
// 31 10/16/98 2:30p Aldie
|
|
// Check for NULL detonator
|
|
//
|
|
// 30 10/10/98 9:14p Aldie
|
|
// Damage tweak and detonator tweak
|
|
//
|
|
// 29 10/10/98 7:14p Aldie
|
|
// Tweaked damage
|
|
//
|
|
// 28 10/08/98 12:03a Jimdose
|
|
// Got rid of unused variables speed and direction from Mine
|
|
//
|
|
// 27 10/05/98 10:20p Aldie
|
|
// Changed damage a bit
|
|
//
|
|
// 26 10/02/98 5:47p Aldie
|
|
// Add MOD to RadiusDamage
|
|
//
|
|
// 25 9/18/98 8:14p Markd
|
|
// rewrote surface system so that surfaces are now damaged by surface name instead
|
|
// of by surfinfo
|
|
//
|
|
// 24 9/13/98 8:37p Aldie
|
|
// Don't autoswitch to detonator
|
|
//
|
|
// 23 9/11/98 3:19p Aldie
|
|
// Make mines bounce of entities that take damage.
|
|
//
|
|
// 22 9/05/98 12:13p Aldie
|
|
// Made explosion driven by animation of the spidermine.
|
|
//
|
|
// 21 9/01/98 7:53p Aldie
|
|
// Removed sound error
|
|
//
|
|
// 20 9/01/98 7:46p Aldie
|
|
// Added area checking for spidermines
|
|
//
|
|
// 19 9/01/98 3:05p Markd
|
|
// Rewrote explosion code
|
|
//
|
|
// 18 8/29/98 9:46p Jimdose
|
|
// Added call info to G_Trace
|
|
//
|
|
// 17 8/27/98 2:31p Aldie
|
|
// Fix for dead owner
|
|
//
|
|
// 16 8/26/98 6:19p Aldie
|
|
// Update fov to 120 and remove the proximity stuff
|
|
//
|
|
// 15 8/25/98 7:39p Aldie
|
|
// Made spidermine immediately switch to detonator.
|
|
//
|
|
// 14 8/25/98 5:29p Aldie
|
|
// New version of the spidermine which uses cameras
|
|
//
|
|
// 13 8/22/98 9:36p Jimdose
|
|
// Added support for alternate gravity axis
|
|
//
|
|
// 12 8/18/98 11:08p Markd
|
|
// Added new Alias System
|
|
//
|
|
// 11 7/25/98 7:10p Markd
|
|
// Put in EV_Removes for demo
|
|
//
|
|
// 10 7/22/98 9:57p Markd
|
|
// Defined weapon type
|
|
//
|
|
// 9 6/27/98 7:58p Aldie
|
|
// Minor adjustments to stuff
|
|
//
|
|
// 8 6/19/98 9:30p Jimdose
|
|
// Moved gun orientation code to Weapon
|
|
//
|
|
// 7 6/10/98 2:10p Aldie
|
|
// Updated damage function.
|
|
//
|
|
// 6 6/08/98 9:04p Aldie
|
|
// Updated doneFiring event
|
|
//
|
|
// 5 6/08/98 8:43p Aldie
|
|
// Added ReadyToUse support
|
|
//
|
|
// 4 6/08/98 8:21p Aldie
|
|
// Updated spidermines with new anims and logic
|
|
//
|
|
// 3 6/08/98 11:34a Aldie
|
|
// New version of spidermines.
|
|
//
|
|
// 2 5/11/98 11:24a Markd
|
|
// First time
|
|
//
|
|
// 1 5/11/98 11:10a Markd
|
|
//
|
|
// 1 5/11/98 10:24a Markd
|
|
//
|
|
// 1 5/11/98 10:20a Markd
|
|
//
|
|
// 1 5/11/98 10:18a Markd
|
|
//
|
|
// 1 5/11/98 9:55a Markd
|
|
//
|
|
// DESCRIPTION:
|
|
// Spider Mine
|
|
//
|
|
|
|
#include "g_local.h"
|
|
#include "spidermine.h"
|
|
#include "explosion.h"
|
|
#include "player.h"
|
|
#include "surface.h"
|
|
|
|
CLASS_DECLARATION( Projectile, Mine, "Mine" );
|
|
|
|
Event EV_Mine_Explode( "mine_explode" );
|
|
Event EV_Mine_CheckForTargets( "mine_targets" );
|
|
Event EV_Mine_Run( "mine_run" );
|
|
|
|
ResponseDef Mine::Responses[] =
|
|
{
|
|
{ &EV_Touch, ( Response )Mine::SlideOrStick },
|
|
{ &EV_Killed, ( Response )Mine::Explode },
|
|
{ &EV_Mine_Explode, ( Response )Mine::Explode },
|
|
{ &EV_Trigger_Effect, ( Response )Mine::SlideOrStick },
|
|
{ &EV_Mine_CheckForTargets, ( Response )Mine::CheckForTargets },
|
|
{ &EV_Mine_Run, ( Response )Mine::Run },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
|
|
void Mine::Run
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
RandomAnimate( "run", NULL );
|
|
}
|
|
|
|
void Mine::CheckForTargets
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity *ent;
|
|
Event *event;
|
|
trace_t trace;
|
|
|
|
// Playtest
|
|
return;
|
|
|
|
if (detonate)
|
|
return;
|
|
|
|
ent = findradius( NULL, worldorigin, 150 );
|
|
while( ent )
|
|
{
|
|
if ( ( ent != this ) &&
|
|
( !ent->deadflag ) &&
|
|
( ent->entnum != owner ) &&
|
|
( ent->takedamage ) &&
|
|
( !(ent->flags & FL_NOTARGET) ) &&
|
|
( strcmp(ent->getClassname(),"Mine") ) )
|
|
{
|
|
detonate = true;
|
|
trace = G_Trace( worldorigin, vec_zero, vec_zero, ent->worldorigin, ent, MASK_PROJECTILE, "Mine::CheckForTargets" );
|
|
if (trace.fraction != 1.0f)
|
|
detonate = false;
|
|
else
|
|
break;
|
|
}
|
|
ent = findradius( ent, worldorigin, 150 );
|
|
}
|
|
|
|
if (detonate)
|
|
{
|
|
RandomGlobalSound("spider_arm",1);
|
|
event = new Event(EV_Mine_Explode);
|
|
PostEvent(event,0.5f);
|
|
}
|
|
else
|
|
{
|
|
event = new Event(EV_Mine_CheckForTargets);
|
|
PostEvent(event,0.5f);
|
|
}
|
|
}
|
|
|
|
|
|
void Mine::SlideOrStick
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity *other;
|
|
Event *event;
|
|
Vector norm;
|
|
Vector addSpeed;
|
|
|
|
if (detonate)
|
|
return;
|
|
|
|
other = ev->GetEntity( 1 );
|
|
assert( other );
|
|
|
|
if ( other->takedamage )
|
|
{
|
|
setMoveType(MOVETYPE_BOUNCE);
|
|
return;
|
|
}
|
|
|
|
// Check to see if we hit the ground, if so then slide along,
|
|
// otherwise stick to the wall.
|
|
if (( (level.impact_trace.plane.normal[ gravity_axis[ gravaxis ].z ] * gravity_axis[ gravaxis ].sign ) > 0.7 ) &&
|
|
!sticky)
|
|
{
|
|
setMoveType(MOVETYPE_SLIDE);
|
|
event = new Event(EV_Mine_CheckForTargets);
|
|
PostEvent(event,2.5);
|
|
}
|
|
else
|
|
{
|
|
// So that we can shoot our own mines
|
|
edict->owner = world->edict;
|
|
|
|
CancelEventsOfType(EV_Mine_Run);
|
|
setMoveType(MOVETYPE_NONE);
|
|
RandomAnimate( "stick", NULL );
|
|
norm = level.impact_trace.plane.normal;
|
|
angles = norm.toAngles();
|
|
angles.x = -angles.x;
|
|
setAngles(angles);
|
|
velocity = "0 0 0";
|
|
|
|
// Check to see if we are on the floor and adjust origin
|
|
if (!sticky)
|
|
{
|
|
CheckGround();
|
|
if (groundentity)
|
|
setOrigin(origin + "0 0 12" );
|
|
}
|
|
|
|
setOrigin(origin);
|
|
event = new Event(EV_Mine_CheckForTargets);
|
|
PostEvent(event,0.7f);
|
|
}
|
|
}
|
|
|
|
|
|
void Mine::Explode
|
|
(
|
|
Event *ev
|
|
)
|
|
{
|
|
int damg;
|
|
Vector v;
|
|
Vector norm;
|
|
Player *client;
|
|
Camera *cam;
|
|
Entity *owner;
|
|
|
|
|
|
detonate = true;
|
|
takedamage = DAMAGE_NO;
|
|
|
|
stopsound( CHAN_VOICE );
|
|
setSolidType( SOLID_NOT );
|
|
|
|
if ( HitSky() )
|
|
{
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
owner = G_GetEntity( this->owner );
|
|
|
|
if ( !owner )
|
|
owner = world;
|
|
|
|
damg = 100;
|
|
|
|
if ( !deathmatch->value && owner->isClient() )
|
|
damg *= 1.5;
|
|
|
|
surfaceManager.DamageSurface (&level.impact_trace, damg, owner );
|
|
|
|
v = velocity;
|
|
v.normalize();
|
|
v = worldorigin - v * 24;
|
|
|
|
RadiusDamage( this, owner, damg, this, MOD_SPIDERSPLASH );
|
|
|
|
if ( owner->isSubclassOf( Player ) )
|
|
{
|
|
client = ( Player * )owner;
|
|
cam = client->CurrentCamera();
|
|
|
|
// If we are in the camera, get out of it
|
|
if ( cam == ( Camera * )this )
|
|
client->SetCamera( NULL );
|
|
}
|
|
|
|
// Remove the mine from the detonator
|
|
if ( detonator )
|
|
detonator->RemoveMine( this );
|
|
|
|
RandomAnimate( "explode", NULL );
|
|
PostEvent( EV_Remove, 0.2 );
|
|
}
|
|
|
|
void Mine::SetDetonator
|
|
(
|
|
Detonator *det
|
|
)
|
|
|
|
{
|
|
detonator = det;
|
|
}
|
|
|
|
qboolean Mine::IsOwner
|
|
(
|
|
Sentient *sent
|
|
)
|
|
|
|
{
|
|
return ( sent == G_GetEntity( this->owner ) );
|
|
}
|
|
|
|
void Mine::Setup
|
|
(
|
|
Entity *owner,
|
|
Vector pos,
|
|
Vector dir
|
|
)
|
|
|
|
{
|
|
Event *ev;
|
|
Vector t[ 3 ];
|
|
Vector forward;
|
|
Vector right;
|
|
Vector up;
|
|
|
|
this->owner = owner->entnum;
|
|
|
|
edict->owner = owner->edict;
|
|
|
|
setModel( "spidermine.def" );
|
|
|
|
showModel();
|
|
setMoveType( MOVETYPE_SLIDE );
|
|
setSolidType( SOLID_BBOX );
|
|
edict->clipmask = MASK_PROJECTILE;
|
|
RandomAnimate( "open", EV_Mine_Run );
|
|
|
|
SetGravityAxis( owner->gravaxis );
|
|
velocity = dir * 600;
|
|
sticky = false;
|
|
|
|
const gravityaxis_t &grav = gravity_axis[ gravaxis ];
|
|
|
|
setAngles( Vector( 0, dir.toYaw(), 0 ) );
|
|
|
|
angles.AngleVectors( &t[0], &t[1], &t[2] );
|
|
forward[ grav.x ] = t[ 0 ][ 0 ];
|
|
forward[ grav.y ] = t[ 0 ][ 1 ] * grav.sign;
|
|
forward[ grav.z ] = t[ 0 ][ 2 ] * grav.sign;
|
|
right[ grav.x ] = t[ 1 ][ 0 ];
|
|
right[ grav.y ] = t[ 1 ][ 1 ] * grav.sign;
|
|
right[ grav.z ] = t[ 1 ][ 2 ] * grav.sign;
|
|
up[ grav.x ] = t[ 2 ][ 0 ];
|
|
up[ grav.y ] = t[ 2 ][ 1 ] * grav.sign;
|
|
up[ grav.z ] = t[ 2 ][ 2 ] * grav.sign;
|
|
VectorsToEulerAngles( forward.vec3(), right.vec3(), up.vec3(), angles.vec3() );
|
|
setAngles( angles );
|
|
|
|
ev = new Event( EV_Mine_Explode );
|
|
ev->AddEntity( world );
|
|
PostEvent( ev, 180 );
|
|
|
|
takedamage = DAMAGE_YES;
|
|
health = 150;
|
|
edict->svflags |= ( SVF_SHOOTABLE );
|
|
setSize("-4 -4 -4", "4 4 4");
|
|
|
|
setOrigin( pos );
|
|
worldorigin.copyTo(edict->s.old_origin);
|
|
detonate = false;
|
|
|
|
fov = 120;
|
|
|
|
if ( owner->isClient() && owner->client->ps.pmove.pm_flags & PMF_DUCKED )
|
|
{
|
|
setMoveType( MOVETYPE_TOSS );
|
|
sticky = true;
|
|
}
|
|
}
|
|
|
|
CLASS_DECLARATION( Weapon, SpiderMine, NULL);
|
|
|
|
ResponseDef SpiderMine::Responses[] =
|
|
{
|
|
{ &EV_Weapon_Shoot, ( Response )SpiderMine::Shoot },
|
|
{ &EV_Weapon_DoneFiring, ( Response )SpiderMine::DoneFiring },
|
|
{ &EV_Weapon_SecondaryUse, ( Response )SpiderMine::ChangeToDetonator },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
SpiderMine::SpiderMine
|
|
(
|
|
)
|
|
|
|
{
|
|
#ifdef SIN_DEMO
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
#endif
|
|
SetModels( "mines.def", "view_mines.def" );
|
|
SetAmmo( "SpiderMines", 1, 0 );
|
|
SetRank( 60, 5 );
|
|
SetType( WEAPON_1HANDED );
|
|
modelIndex( "spidermine.def" );
|
|
modelIndex( "mine.def" );
|
|
|
|
currentMine = 0;
|
|
}
|
|
|
|
qboolean SpiderMine::IsDroppable
|
|
(
|
|
void
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void SpiderMine::SetOwner
|
|
(
|
|
Sentient *sent
|
|
)
|
|
|
|
{
|
|
Detonator *detonator;
|
|
int num;
|
|
|
|
assert( sent );
|
|
if ( !sent )
|
|
{
|
|
// return to avoid any buggy behaviour
|
|
return;
|
|
}
|
|
|
|
Item::SetOwner( sent );
|
|
|
|
setOrigin( vec_zero );
|
|
setAngles( vec_zero );
|
|
|
|
if ( !viewmodel.length() )
|
|
{
|
|
error( "setOwner", "Weapon without viewmodel set" );
|
|
}
|
|
|
|
setModel( viewmodel );
|
|
|
|
// Give the owner a detonator and setup the link
|
|
|
|
detonator = ( Detonator * )sent->FindItem( "Detonator" );
|
|
|
|
if ( !detonator )
|
|
{
|
|
detonator = ( Detonator * )sent->giveWeapon( "Detonator" );
|
|
}
|
|
|
|
SetDetonator( detonator );
|
|
|
|
|
|
// Check the world for any spidermines in existence and
|
|
// if the player owns them, add them to the minelist.
|
|
num = 0;
|
|
while( ( num = G_FindClass( num, "Mine" ) ) != NULL )
|
|
{
|
|
Mine *mine = ( Mine * )G_GetEntity( num );
|
|
|
|
if ( mine->IsOwner( sent ) )
|
|
{
|
|
detonator->AddMine( mine );
|
|
mine->SetDetonator( detonator );
|
|
}
|
|
}
|
|
}
|
|
|
|
void SpiderMine::DoneFiring
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
assert( owner );
|
|
|
|
weaponstate = WEAPON_HOLSTERED;
|
|
DetachGun();
|
|
StopAnimating();
|
|
|
|
if ( owner )
|
|
{
|
|
owner->SetCurrentWeapon( detonator );
|
|
}
|
|
}
|
|
|
|
void SpiderMine::ChangeToDetonator
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( owner && detonator->mineList.NumObjects() )
|
|
owner->ChangeWeapon( detonator );
|
|
}
|
|
|
|
qboolean SpiderMine::ReadyToUse
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
Event *ev;
|
|
|
|
if ( HasAmmo() )
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if ( owner->isClient() )
|
|
{
|
|
// Check to see if detonator has mines active
|
|
if ( detonator && detonator->mineList.NumObjects() )
|
|
{
|
|
ev = new Event( "use" );
|
|
ev->AddString( "Detonator" );
|
|
owner->PostEvent( ev, 0 );
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void SpiderMine::SetDetonator
|
|
(
|
|
Detonator *det
|
|
)
|
|
|
|
{
|
|
detonator = det;
|
|
}
|
|
|
|
void SpiderMine::Shoot
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Vector pos;
|
|
Vector dir;
|
|
Mine *mine;
|
|
Event *event;
|
|
|
|
assert( owner );
|
|
if ( !owner )
|
|
{
|
|
return;
|
|
}
|
|
|
|
GetMuzzlePosition( &pos, &dir );
|
|
|
|
|
|
if ( currentMine )
|
|
{
|
|
event = new Event(EV_Mine_Explode);
|
|
currentMine->ProcessEvent( event );
|
|
}
|
|
else
|
|
{
|
|
mine = new Mine;
|
|
mine->Setup( owner, pos, dir );
|
|
mine->SetDetonator( detonator );
|
|
detonator->AddMine( mine );
|
|
}
|
|
|
|
NextAttack( 1.8f );
|
|
}
|
|
|
|
CLASS_DECLARATION( Weapon, Detonator, NULL);
|
|
|
|
ResponseDef Detonator::Responses[] =
|
|
{
|
|
{ &EV_Weapon_Shoot, ( Response )Detonator::Shoot },
|
|
{ &EV_Weapon_DoneFiring, ( Response )Detonator::DoneFiring },
|
|
{ &EV_Weapon_SecondaryUse, ( Response )Detonator::CycleCamera },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Detonator::Detonator
|
|
(
|
|
)
|
|
|
|
{
|
|
#ifdef SIN_DEMO
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
#endif
|
|
SetModels( NULL, "view_detonator.def" );
|
|
SetType( WEAPON_1HANDED );
|
|
currentMine = 0;
|
|
}
|
|
|
|
void Detonator::RemoveMine
|
|
(
|
|
Mine *mine
|
|
)
|
|
|
|
{
|
|
mineList.RemoveObject( MinePtr( mine ) );
|
|
}
|
|
|
|
void Detonator::AddMine
|
|
(
|
|
Mine *mine
|
|
)
|
|
|
|
{
|
|
mineList.AddObject( MinePtr( mine ) );
|
|
}
|
|
|
|
void Detonator::CycleCamera
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Player *client;
|
|
int numMines;
|
|
Mine *mine;
|
|
|
|
assert( owner );
|
|
if ( !owner )
|
|
{
|
|
return;
|
|
}
|
|
|
|
numMines = mineList.NumObjects();
|
|
|
|
if ( !numMines )
|
|
return;
|
|
|
|
currentMine++;
|
|
|
|
mine = mineList.ObjectAt( ( currentMine % numMines ) + 1 );
|
|
if ( !mine )
|
|
{
|
|
mineList.RemoveObjectAt( ( currentMine % numMines ) + 1 );
|
|
return;
|
|
}
|
|
|
|
client = ( Player * )( Entity * ) owner;
|
|
if ( client->edict->areanum == mine->edict->areanum )
|
|
client->SetCamera( mine );
|
|
else
|
|
{
|
|
gi.cprintf(client->edict, PRINT_HIGH, "Spidermine %d out of range\n", ( currentMine % numMines ) + 1 );
|
|
}
|
|
}
|
|
|
|
void Detonator::DoneFiring
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Weapon *weapon;
|
|
|
|
weaponstate = WEAPON_READY;
|
|
|
|
if ( owner )
|
|
{
|
|
owner->ProcessEvent( EV_Sentient_WeaponDoneFiring );
|
|
}
|
|
|
|
// Change back to spidermines if there is ammo, otherwise change weapons.
|
|
|
|
weapon = ( Weapon * )owner->FindItem( "SpiderMine" );
|
|
|
|
if ( !weapon || !weapon->HasAmmo() )
|
|
{
|
|
weapon = owner->BestWeapon();
|
|
}
|
|
|
|
owner->ChangeWeapon( weapon );
|
|
}
|
|
|
|
void Detonator::Shoot
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int num,i;
|
|
Player *player;
|
|
Entity *cameraMine;
|
|
Event *event;
|
|
|
|
// If the owner is in a camera, the only detonate that mine,
|
|
// otherwise detonate them all
|
|
|
|
NextAttack( 0.1 );
|
|
|
|
if ( owner->isClient() )
|
|
{
|
|
player = ( Player * )( Entity * )owner;
|
|
|
|
cameraMine = player->CurrentCamera();
|
|
|
|
if ( cameraMine && cameraMine->isSubclassOf( Mine ) )
|
|
{
|
|
event = new Event(EV_Mine_Explode);
|
|
cameraMine->PostEvent( event, 0 );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Go through all the mines and detonate them
|
|
|
|
num = mineList.NumObjects();
|
|
|
|
for( i = num; i >= 1; i-- )
|
|
{
|
|
Event *explodeEvent;
|
|
Mine *mine;
|
|
|
|
mine = mineList.ObjectAt( i );
|
|
explodeEvent = new Event(EV_Mine_Explode);
|
|
mine->PostEvent( explodeEvent, 0 );
|
|
}
|
|
}
|
|
|
|
qboolean Detonator::IsDroppable
|
|
(
|
|
void
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
qboolean Detonator::AutoChange
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
return false;
|
|
}
|