📄 quantumd.cpp
字号:
//-----------------------------------------------------------------------------
//
// $Logfile:: /Quake 2 Engine/Sin/code/game/quantumd.cpp $
// $Revision:: 46 $
// $Author:: Aldie $
// $Date:: 11/18/98 8:28p $
//
// 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/quantumd.cpp $
//
// 46 11/18/98 8:28p Aldie
// Added NOION check for quantum overload
//
// 45 11/15/98 12:22a Markd
// Fixed pre-caching issues
//
// 44 11/09/98 3:46a Aldie
// Fixed health death problems
//
// 43 10/26/98 2:50p Aldie
// Fixed a bug with checking of NULL owners
//
// 42 10/24/98 12:42a Markd
// changed origins to worldorigins where appropriate
//
// 41 10/22/98 7:57p Markd
// put in proper pre-caching in all the classes
//
// 40 10/22/98 5:52p Aldie
// Went back to single mode firing
//
// 39 10/21/98 2:28a Aldie
// Fixed bug with destruct function
//
// 38 10/20/98 8:26p Markd
// Added Attacker to DamageSurface stuff
//
// 37 10/19/98 12:07a Jimdose
// made all code use fast checks for inheritance (no text lookups when
// possible)
// isSubclassOf no longer requires ::_classinfo()
//
// 36 10/18/98 7:58p Aldie
// Changed quantum to do a full trace
//
// 35 10/16/98 10:22p Aldie
// Updated single player damage settings
//
// 34 10/16/98 9:50p Aldie
// Added SecondaryAmmo command and flame effect
//
// 33 10/14/98 12:12a Aldie
// Took out seeking
//
// 32 10/13/98 7:33p Aldie
// Fixed event problem
//
// 31 10/13/98 7:14p Aldie
// Added seeking
//
// 30 10/11/98 5:33p Aldie
// Tweak damage
//
// 29 10/11/98 12:03a Aldie
// Change velocity
//
// 28 10/10/98 9:59p Aldie
// Added radius damage
//
// 27 10/10/98 5:58p Aldie
// More quantumdestab fixes
//
// 26 10/06/98 9:17p Aldie
// Make sure you kill all with quantum
//
// 25 10/06/98 2:51p Aldie
// Fix killing of the player for quantum
//
// 24 10/05/98 10:42p Aldie
// Fixed dropping of quantum bug
//
// 23 10/04/98 10:38p Markd
// Commented out player trapped in quantum code for the time being
//
// 22 10/04/98 10:28p Aldie
// Added multiple weapon changes. Damage, flashes, quantum stuff
//
// 21 10/01/98 8:01p Aldie
// Tweaked power
//
// 20 10/01/98 4:01p Markd
// Added Archive and Unarchive functions
//
// 19 9/30/98 1:26p Aldie
// Fixed damage function when quantum self destructs
//
// 18 9/29/98 11:46p Aldie
// Added unfreeze and killsight effects
//
// 17 9/25/98 2:59p Aldie
// Change rate of ammo
//
// 16 9/23/98 10:08p Aldie
// Added self destruct mechanism
//
// 15 9/22/98 8:10p Aldie
// Freeze stuff
//
// 14 9/21/98 5:31p Markd
// took out owner out of projectile subclasses, working on archive and
// unarchive
//
// 13 9/21/98 1:34a Aldie
// Made the quantum eat ammo
//
// 12 9/20/98 5:12p Aldie
// New effects for quantum
//
// 11 9/17/98 4:37p Aldie
// Temporary checkin
//
// 10 9/16/98 8:58p Aldie
// Added ability to do a hold down weapon charge
//
// 9 9/16/98 4:03p Aldie
// Intermediate checkin
//
// 8 9/11/98 3:54p Aldie
// Put in releasefire
//
// 7 8/18/98 5:51p Aldie
// Added support for dual mode weapons.
//
// 6 8/18/98 2:32p Aldie
// Fixed some bugs with animation control
//
// 5 8/06/98 10:53p Aldie
// Added weapon tweaks and kickback. Also modified blast radius damage and
// rocket jumping.
//
// 4 8/03/98 1:16p Aldie
// Changed ammo type
//
// 3 7/29/98 5:56p Aldie
// Changed classname
//
// 2 7/29/98 3:38p Aldie
// First version of QD
//
// 1 7/29/98 3:15p Aldie
//
// DESCRIPTION:
// Quantum Destabilizer
#include "quantumd.h"
#include "specialfx.h"
#include "explosion.h"
#include "player.h"
#include "surface.h"
#define ION_MODE 1
#define DESTAB_MODE 2
class EXPORT_FROM_DLL IonBurst : public Projectile
{
private:
float power;
public:
CLASS_PROTOTYPE( IonBurst );
IonBurst();
virtual void Setup( Entity *owner, Vector pos, float power );
virtual void Explode( Event *ev );
virtual void Archive( Archiver &arc );
virtual void Unarchive( Archiver &arc );
};
EXPORT_FROM_DLL void IonBurst::Archive
(
Archiver &arc
)
{
Projectile::Archive( arc );
arc.WriteFloat( power );
}
EXPORT_FROM_DLL void IonBurst::Unarchive
(
Archiver &arc
)
{
Projectile::Unarchive( arc );
arc.ReadFloat( &power );
}
class EXPORT_FROM_DLL Ion : public Projectile
{
private:
float power;
public:
CLASS_PROTOTYPE( Ion );
Ion();
virtual void Setup( Entity *owner, Vector pos, Vector dir, float power );
virtual void Explode( Event *ev );
qboolean CanSee( Entity *ent );
virtual void Seek( Event *ev );
float AdjustAngle( float maxadjust, float currangle, float targetangle );
virtual void Archive( Archiver &arc );
virtual void Unarchive( Archiver &arc );
};
EXPORT_FROM_DLL void Ion::Archive
(
Archiver &arc
)
{
Projectile::Archive( arc );
arc.WriteFloat( power );
}
EXPORT_FROM_DLL void Ion::Unarchive
(
Archiver &arc
)
{
Projectile::Unarchive( arc );
arc.ReadFloat( &power );
}
CLASS_DECLARATION( Projectile, IonBurst, NULL );
ResponseDef IonBurst::Responses[] =
{
{ &EV_Touch, ( Response )IonBurst::Explode },
{ NULL, NULL }
};
IonBurst::IonBurst
(
)
{
}
void IonBurst::Explode
(
Event *ev
)
{
Entity *other;
Entity *owner;
float damg;
other = ev->GetEntity( 1 );
assert( other );
// Do damage to what we hit
if ( other->isSubclassOf( Teleporter ) )
{
return;
}
if ( other->entnum == this->owner )
{
return;
}
// Hit the sky, so remove everything
if ( HitSky() )
{
PostEvent( EV_Remove, 0 );
return;
}
owner = G_GetEntity( this->owner );
if ( !owner )
owner = world;
damg = 20 + power * 20;
if ( other->takedamage )
{
other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 32, 0, MOD_ION, -1, -1, 1.0f );
PostEvent( EV_Remove, 0 );
}
}
void IonBurst::Setup
(
Entity *owner,
Vector pos,
float power
)
{
Event *event;
this->owner = owner->entnum;
edict->owner = owner->edict;
setMoveType( MOVETYPE_BOUNCE );
setSolidType( SOLID_BBOX );
edict->clipmask = MASK_PROJECTILE;
SetGravityAxis( owner->gravaxis );
showModel();
setModel( "qp_burst.def" );
RandomAnimate( "flyburst", NULL );
this->power = power;
// Set the flying velocity
velocity[0] = 300.0 * crandom() + 200 * power;
velocity[1] = 300.0 * crandom() + 200 * power;
velocity[2] = 300.0 + 300.0 * random() + 200 * power;
takedamage = DAMAGE_NO;
// Set the light and effects
edict->s.renderfx |= RF_DLIGHT;
edict->s.effects |= EF_EVERYFRAME;
edict->s.radius = 200;
edict->s.color_r = 1.0f;
edict->s.color_g = 0.2;
edict->s.color_b = 0.1;
setScale( 0.3 );
// Set size and origin
setSize( "-2 -2 -2", "2 2 2" );
setOrigin( pos );
worldorigin.copyTo(edict->s.old_origin);
event = new Event( EV_Remove );
PostEvent( event, 1.2 );
}
CLASS_DECLARATION( Projectile, Ion, NULL );
Event EV_Ion_Seek( "ionseek" );
ResponseDef Ion::Responses[] =
{
{ &EV_Touch, ( Response )Ion::Explode },
{ &EV_Ion_Seek, ( Response )Ion::Seek },
{ NULL, NULL }
};
Ion::Ion()
{
}
qboolean Ion::CanSee
(
Entity *ent
)
{
Vector delta;
Vector start;
Vector end;
trace_t trace;
start = worldorigin;
end = ent->centroid;
// Check if he's visible
trace = G_Trace( start, vec_zero, vec_zero, end, this, MASK_OPAQUE, "Ion::CanSee" );
if ( trace.fraction == 1.0 || trace.ent == ent->edict )
{
return true;
}
return false;
}
float Ion::AdjustAngle
(
float maxadjust,
float currangle,
float targetangle
)
{
float dangle;
float magangle;
dangle = currangle - targetangle;
if ( dangle )
{
magangle = ( float )fabs( dangle );
if ( magangle < maxadjust )
{
currangle = targetangle;
}
else
{
if ( magangle > 180.0f )
{
maxadjust = -maxadjust;
}
if ( dangle > 0 )
{
maxadjust = -maxadjust;
}
currangle += maxadjust;
}
}
while( currangle >= 360.0f )
{
currangle -= 360.0f;
}
while( currangle < 0.0f )
{
currangle += 360.0f;
}
return currangle;
}
void Ion::Seek
(
Event *ev
)
{
Entity *ent;
Vector delta;
float dist;
Entity *bestent = NULL;
float bestdist = 999999;
Vector newangles, newdir;
ent = findradius( NULL, worldorigin.vec3(), 256 );
while( ent )
{
if ( ( ent->entnum != owner ) && ( ent->takedamage ) && ent->isSubclassOf( Sentient ) )
{
delta = worldorigin - ent->centroid;
dist = delta.length();
if ( ( dist < bestdist ) && CanSee( ent ) )
{
bestent = ent;
bestdist = dist;
}
}
ent = findradius( ent, worldorigin.vec3(), 1000 );
}
if (!bestent)
{
PostEvent( ev, FRAMETIME );
return;
}
newdir = bestent->centroid - worldorigin;
newdir.normalize();
velocity = newdir * 250;
angles = newdir.toAngles();
angles[ PITCH ] = -angles[ PITCH ];
setAngles( angles );
PostEvent( ev, FRAMETIME );
}
void Ion::Explode
(
Event *ev
)
{
Entity *other;
Entity *owner;
int damg;
Vector v;
other = ev->GetEntity( 1 );
assert( other );
if ( other->isSubclassOf( Teleporter ) )
{
return;
}
if ( other->entnum == this->owner )
{
return;
}
owner = G_GetEntity( this->owner );
if ( !owner )
owner = world;
setSolidType( SOLID_NOT );
// Hit the sky, so remove everything
if ( HitSky() )
{
PostEvent( EV_Remove, 0 );
return;
}
damg = 50 + ( power * 200 );
// Single player packs a bigger punch
if ( !deathmatch->value && owner->isClient() )
damg *= 1.5;
if ( other->takedamage )
{
other->Damage( this, owner, damg, worldorigin, velocity, level.impact_trace.plane.normal, 0, 0, MOD_ION, -1, -1, 1.0f );
if ( other->isSubclassOf( Sentient ) )
{
Sentient *sent = (Sentient * )other;
sent->ProcessEvent( EV_Sentient_Freeze );
sent->PostEvent( EV_Sentient_UnFreeze, 1 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -