515 lines
14 KiB
C++
515 lines
14 KiB
C++
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $Logfile:: /Quake 2 Engine/Sin/code/game/bullet.cpp $
|
||
|
// $Revision:: 71 $
|
||
|
// $Author:: Markd $
|
||
|
// $Date:: 10/22/98 7:57p $
|
||
|
//
|
||
|
// Copyright (C) 1997 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/bullet.cpp $
|
||
|
//
|
||
|
// 71 10/22/98 7:57p Markd
|
||
|
// put in proper pre-caching in all the classes
|
||
|
//
|
||
|
// 70 10/20/98 8:26p Markd
|
||
|
// Added Attacker to DamageSurface stuff
|
||
|
//
|
||
|
// 69 10/13/98 5:27p Markd
|
||
|
// revamped ricochet stuff
|
||
|
//
|
||
|
// 68 10/13/98 12:35p Markd
|
||
|
// Fixed tracers and bullet holes on non-player guys
|
||
|
//
|
||
|
// 67 10/05/98 11:30p Markd
|
||
|
// Added MakeBreakingSound when firing at things
|
||
|
//
|
||
|
// 66 10/04/98 10:36p Markd
|
||
|
// put in ricochet code
|
||
|
//
|
||
|
// 65 9/27/98 3:53p Aldie
|
||
|
// Put in some debugging information
|
||
|
//
|
||
|
// 64 9/18/98 8:14p Markd
|
||
|
// rewrote surface system so that surfaces are now damaged by surface name
|
||
|
// instead of by surfinfo
|
||
|
//
|
||
|
// 63 8/31/98 7:45p Aldie
|
||
|
// Updated surface data structure and removed surfinfo field
|
||
|
//
|
||
|
// 62 8/29/98 9:39p Jimdose
|
||
|
// Added call info to G_Trace
|
||
|
//
|
||
|
// 61 8/29/98 5:27p Markd
|
||
|
// added specialfx, replaced misc with specialfx where appropriate
|
||
|
//
|
||
|
// 60 8/25/98 7:55p Markd
|
||
|
// Fixed weapon angles
|
||
|
//
|
||
|
// 59 8/19/98 6:38p Markd
|
||
|
// Moved Assault rifle tracer into def file
|
||
|
//
|
||
|
// 58 8/14/98 5:37p Aldie
|
||
|
// Moved blood stuff to sentient
|
||
|
//
|
||
|
// 57 8/13/98 8:09p Aldie
|
||
|
// Moved blood particles to armor damage.
|
||
|
//
|
||
|
// 56 8/10/98 6:52p Aldie
|
||
|
// Added scale to bloodsplats
|
||
|
//
|
||
|
// 55 8/06/98 10:53p Aldie
|
||
|
// Added weapon tweaks and kickback. Also modified blast radius damage and
|
||
|
// rocket jumping.
|
||
|
//
|
||
|
// 54 8/04/98 3:27p Aldie
|
||
|
// Revert back to sending PITCH and YAW
|
||
|
//
|
||
|
// 53 8/03/98 3:28p Aldie
|
||
|
// Only send over the PITCH of the gun when firing it
|
||
|
//
|
||
|
// 52 8/01/98 4:39p Aldie
|
||
|
// Put some debug prints
|
||
|
//
|
||
|
// 51 8/01/98 3:24p Aldie
|
||
|
// Added server effects flag for specific weapons
|
||
|
//
|
||
|
// 50 7/31/98 7:42p Aldie
|
||
|
// Client side bullet effects
|
||
|
//
|
||
|
// 49 7/25/98 5:48p Aldie
|
||
|
// Remove shotgun effect
|
||
|
//
|
||
|
// 48 7/24/98 10:03p Aldie
|
||
|
// Fixed bullet damage with invalid traces
|
||
|
//
|
||
|
// 47 7/23/98 6:17p Aldie
|
||
|
// Updated damage system and fixed some damage related bugs. Also put tracers
|
||
|
// back to the way they were, and added gib event to funcscriptmodels
|
||
|
//
|
||
|
// 46 7/22/98 10:41p Aldie
|
||
|
// Fixed tracers
|
||
|
//
|
||
|
// 45 7/21/98 1:10p Aldie
|
||
|
// Added meansofdeath to obituaries
|
||
|
//
|
||
|
// 44 7/17/98 7:57p Markd
|
||
|
// Added radius to FullTrace
|
||
|
//
|
||
|
// 43 7/15/98 9:57p Markd
|
||
|
// Added shields support
|
||
|
//
|
||
|
// 42 6/20/98 7:48p Markd
|
||
|
// using FullTrace now, also checking to make sure we have a valid intersection
|
||
|
// before trying to determine group num etc.
|
||
|
//
|
||
|
// 41 6/19/98 9:29p Jimdose
|
||
|
// Moved gun orientation code to Weapon
|
||
|
//
|
||
|
// 40 6/15/98 10:52p Jimdose
|
||
|
// Disabled fulltrace until bmodels are checked.
|
||
|
//
|
||
|
// 39 6/15/98 10:07p Jimdose
|
||
|
// Made bullet weapons use G_FullTrace
|
||
|
//
|
||
|
// 38 6/11/98 3:34p Jimdose
|
||
|
// TraceAttack was damaging the entity before checking the blood and sparks
|
||
|
// flags, so if the entity died before the check, we got a NULL pointer
|
||
|
// TraceAttack was doing the ricochet trace before checking if it should
|
||
|
// ricochet
|
||
|
//
|
||
|
// 37 6/10/98 2:10p Aldie
|
||
|
// Updated damage function.
|
||
|
//
|
||
|
// 36 6/08/98 11:35a Aldie
|
||
|
// Updated location based damage stuff
|
||
|
//
|
||
|
// 35 6/05/98 6:23p Aldie
|
||
|
// Added location to AddMultiDamage
|
||
|
//
|
||
|
// 34 5/27/98 7:34p Markd
|
||
|
// commented out damage reduction if not hitting body part
|
||
|
//
|
||
|
// 33 5/27/98 5:21p Markd
|
||
|
// fixed up ray intersection a bit
|
||
|
//
|
||
|
// 32 5/27/98 5:02a Markd
|
||
|
// increased nominal multiplier to 0.5f
|
||
|
//
|
||
|
// 31 5/26/98 8:44p Markd
|
||
|
// Put in DamageSkin suport
|
||
|
//
|
||
|
// 30 5/26/98 4:22p Markd
|
||
|
// Working on tri-ray intersection stuff
|
||
|
//
|
||
|
// 29 5/23/98 4:46p Aldie
|
||
|
// Added bulletholes.
|
||
|
//
|
||
|
// 28 5/05/98 7:38p Markd
|
||
|
// Added timeofs to ricochets in bulllet smoke events
|
||
|
//
|
||
|
// 27 5/03/98 8:08p Markd
|
||
|
// Took out old code
|
||
|
//
|
||
|
// 26 5/03/98 4:30p Jimdose
|
||
|
// Changed Vector class
|
||
|
//
|
||
|
// 25 5/02/98 8:41p Markd
|
||
|
// Put in recursive bullet attacks and got rid of ricochets
|
||
|
//
|
||
|
// 24 4/10/98 1:22a Markd
|
||
|
// Added FL_BLOOD support
|
||
|
//
|
||
|
// 23 4/07/98 6:42p Jimdose
|
||
|
// Rewrote weapon code.
|
||
|
// Added order to rank
|
||
|
//
|
||
|
// 22 4/06/98 7:52p Aldie
|
||
|
// Increased range of bullets.
|
||
|
//
|
||
|
// 21 4/04/98 7:31p Jimdose
|
||
|
// Bullets don't spark or ricochet against sky
|
||
|
//
|
||
|
// 20 4/02/98 4:48p Jimdose
|
||
|
// Changed TraceAttack to properly place bloodsplats
|
||
|
//
|
||
|
// 19 3/30/98 2:35p Jimdose
|
||
|
// Moved firing from Magnum to make more general
|
||
|
// Added Ammo
|
||
|
// Added world models
|
||
|
//
|
||
|
// 18 3/27/98 6:34p Jimdose
|
||
|
// Added sparks to show impact of bullets
|
||
|
//
|
||
|
// 17 3/26/98 8:16p Jimdose
|
||
|
// Added precaching of sounds
|
||
|
//
|
||
|
// 16 3/23/98 1:31p Jimdose
|
||
|
// Revamped event and command system
|
||
|
//
|
||
|
// 15 3/05/98 5:44p Aldie
|
||
|
// Support for ricochet flag.
|
||
|
//
|
||
|
// 14 3/04/98 8:02p Aldie
|
||
|
// More support for damage surfaces.
|
||
|
//
|
||
|
// 13 3/04/98 5:12p Aldie
|
||
|
// Added support for damage surfaces.
|
||
|
//
|
||
|
// 12 2/19/98 2:35p Jimdose
|
||
|
// Updated to work with Q2 based progs
|
||
|
//
|
||
|
// 10 12/11/97 3:30p Markd
|
||
|
// Moved SpawnBlood to Weapon
|
||
|
//
|
||
|
// 9 11/18/97 5:28p Markd
|
||
|
// Commented out shotgun
|
||
|
//
|
||
|
// 8 11/11/97 9:41p Markd
|
||
|
// tweaked minimum scale in blood splats
|
||
|
//
|
||
|
// 7 11/11/97 9:38p Markd
|
||
|
// made blood splats be based off of distance as well as damage.
|
||
|
//
|
||
|
// 6 10/31/97 9:02p Jimdose
|
||
|
// Made it so that bsp objects don't leave bloodsplats
|
||
|
//
|
||
|
// 5 10/31/97 7:18p Markd
|
||
|
// Put in BloodSpray
|
||
|
//
|
||
|
// 4 10/31/97 4:28p Jimdose
|
||
|
// Removed redefinition of owner in base class Weapon, so any reference to
|
||
|
// gunoffset through owner had to use type overriding.
|
||
|
//
|
||
|
// 3 10/27/97 3:29p Jimdose
|
||
|
// Removed dependency on quakedef.h
|
||
|
//
|
||
|
// 2 9/26/97 4:43p Jimdose
|
||
|
// Added standard Ritual header
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
// Base class for all bullet (hitscan) weapons. Includes definition for shotgun.
|
||
|
//
|
||
|
|
||
|
#include "g_local.h"
|
||
|
#include "specialfx.h"
|
||
|
#include "misc.h"
|
||
|
#include "bullet.h"
|
||
|
#include "q_shared.h"
|
||
|
#include "surface.h"
|
||
|
|
||
|
CLASS_DECLARATION( Weapon, BulletWeapon, NULL );
|
||
|
|
||
|
ResponseDef BulletWeapon::Responses[] =
|
||
|
{
|
||
|
{ NULL, NULL }
|
||
|
};
|
||
|
|
||
|
BulletWeapon::BulletWeapon()
|
||
|
{
|
||
|
modelIndex( "sprites/tracer.spr" );
|
||
|
modelIndex( "sprites/bullethole.spr" );
|
||
|
}
|
||
|
|
||
|
void BulletWeapon::TraceAttack
|
||
|
(
|
||
|
Vector start,
|
||
|
Vector end,
|
||
|
int damage,
|
||
|
trace_t *trace,
|
||
|
int numricochets,
|
||
|
int kick,
|
||
|
int dflags,
|
||
|
int meansofdeath,
|
||
|
qboolean server_effects
|
||
|
)
|
||
|
|
||
|
{
|
||
|
Vector org;
|
||
|
Vector dir;
|
||
|
Vector endpos;
|
||
|
int surfflags;
|
||
|
int surftype;
|
||
|
int timeofs;
|
||
|
Entity *ent;
|
||
|
qboolean ricochet;
|
||
|
|
||
|
if ( HitSky( trace ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ricochet = false;
|
||
|
dir = end - start;
|
||
|
dir.normalize();
|
||
|
|
||
|
org = end - dir;
|
||
|
|
||
|
ent = trace->ent->entity;
|
||
|
|
||
|
if ( !trace->surface )
|
||
|
{
|
||
|
surfflags = 0;
|
||
|
surftype = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
surfflags = trace->surface->flags;
|
||
|
surftype = SURFACETYPE_FROM_FLAGS( surfflags );
|
||
|
surfaceManager.DamageSurface( trace, damage, owner );
|
||
|
|
||
|
if ( surfflags & SURF_RICOCHET )
|
||
|
ricochet = true;
|
||
|
}
|
||
|
if ( trace->intersect.valid && ent )
|
||
|
{
|
||
|
//
|
||
|
// see if the parent group has ricochet turned on
|
||
|
//
|
||
|
if ( trace->intersect.parentgroup >= 0 )
|
||
|
{
|
||
|
int flags;
|
||
|
|
||
|
flags = gi.Group_Flags( ent->edict->s.modelindex, trace->intersect.parentgroup );
|
||
|
if ( flags & MDL_GROUP_RICOCHET )
|
||
|
{
|
||
|
surftype = ( flags >> 8 ) & 0xf;
|
||
|
ricochet = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ent )
|
||
|
{
|
||
|
if ( !(ent->flags & FL_SHIELDS) )
|
||
|
{
|
||
|
if ( ent->flags & FL_SPARKS )
|
||
|
{
|
||
|
// Take care of ricochet effects on the server
|
||
|
if ( server_effects && !ricochet )
|
||
|
{
|
||
|
timeofs = MAX_RICOCHETS - numricochets;
|
||
|
if ( timeofs > 0xf )
|
||
|
{
|
||
|
timeofs = 0xf;
|
||
|
}
|
||
|
gi.WriteByte( svc_temp_entity );
|
||
|
gi.WriteByte( TE_GUNSHOT );
|
||
|
gi.WritePosition( org.vec3() );
|
||
|
gi.WriteDir( trace->plane.normal );
|
||
|
gi.WriteByte( 0 );
|
||
|
gi.multicast( org.vec3(), MULTICAST_PVS );
|
||
|
}
|
||
|
MadeBreakingSound( org, owner );
|
||
|
}
|
||
|
|
||
|
if ( ent->takedamage )
|
||
|
{
|
||
|
if ( trace->intersect.valid )
|
||
|
{
|
||
|
// We hit a valid group so send in location based damage
|
||
|
ent->Damage( this,
|
||
|
owner,
|
||
|
damage,
|
||
|
trace->endpos,
|
||
|
dir,
|
||
|
trace->plane.normal,
|
||
|
kick,
|
||
|
dflags,
|
||
|
meansofdeath,
|
||
|
trace->intersect.parentgroup,
|
||
|
-1,
|
||
|
trace->intersect.damage_multiplier );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// We didn't hit any groups, so send in generic damage
|
||
|
ent->Damage( this,
|
||
|
owner,
|
||
|
damage,
|
||
|
trace->endpos,
|
||
|
dir,
|
||
|
trace->plane.normal,
|
||
|
kick,
|
||
|
dflags,
|
||
|
meansofdeath,
|
||
|
-1,
|
||
|
-1,
|
||
|
1 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
surftype = SURF_TYPE_METAL;
|
||
|
ricochet = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ricochet && ( server_effects || ( numricochets < MAX_RICOCHETS ) ) )
|
||
|
{
|
||
|
timeofs = MAX_RICOCHETS - numricochets;
|
||
|
if ( timeofs > 0xf )
|
||
|
{
|
||
|
timeofs = 0xf;
|
||
|
}
|
||
|
gi.WriteByte( svc_temp_entity );
|
||
|
gi.WriteByte( TE_GUNSHOT );
|
||
|
gi.WritePosition( org.vec3() );
|
||
|
gi.WriteDir( trace->plane.normal );
|
||
|
gi.WriteByte( timeofs );
|
||
|
gi.multicast( org.vec3(), MULTICAST_PVS );
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
ricochet &&
|
||
|
numricochets &&
|
||
|
damage
|
||
|
)
|
||
|
{
|
||
|
dir += Vector( trace->plane.normal ) * 2;
|
||
|
endpos = org + dir * 8192;
|
||
|
|
||
|
//
|
||
|
// since this is a ricochet, we don't ignore the wewapon owner this time.
|
||
|
//
|
||
|
*trace = G_FullTrace( org, vec_zero, vec_zero, endpos, 5, NULL, MASK_SHOT, "BulletWeapon::TraceAttack" );
|
||
|
if ( trace->fraction != 1.0 )
|
||
|
{
|
||
|
endpos = trace->endpos;
|
||
|
TraceAttack( org, endpos, damage * 0.8f, trace, numricochets - 1, kick, dflags, meansofdeath, true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void BulletWeapon::FireBullets
|
||
|
(
|
||
|
int numbullets,
|
||
|
Vector spread,
|
||
|
int mindamage,
|
||
|
int maxdamage,
|
||
|
int dflags,
|
||
|
int meansofdeath,
|
||
|
qboolean server_effects
|
||
|
)
|
||
|
|
||
|
{
|
||
|
Vector src;
|
||
|
Vector dir;
|
||
|
Vector end;
|
||
|
trace_t trace;
|
||
|
Vector right;
|
||
|
Vector up;
|
||
|
int i;
|
||
|
|
||
|
assert( owner );
|
||
|
if ( !owner )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GetMuzzlePosition( &src, &dir );
|
||
|
|
||
|
owner->angles.AngleVectors( NULL, &right, &up );
|
||
|
|
||
|
angles = dir.toAngles();
|
||
|
setAngles( angles );
|
||
|
|
||
|
for( i = 0; i < numbullets; i++ )
|
||
|
{
|
||
|
end = src +
|
||
|
dir * 8192 +
|
||
|
right * G_CRandom() * spread.x +
|
||
|
up * G_CRandom() * spread.y;
|
||
|
|
||
|
trace = G_FullTrace( src, vec_zero, vec_zero, end, 5, owner, MASK_SHOT, "BulletWeapon::FireBullets" );
|
||
|
#if 0
|
||
|
Com_Printf("Server OWNER Angles:%0.2f %0.2f %0.2f\n",owner->angles[0],owner->angles[1],owner->angles[2]);
|
||
|
Com_Printf("Server Bullet Angles:%0.2f %0.2f %0.2f\n",angles[0],angles[1],angles[2]);
|
||
|
Com_Printf("Right :%0.2f %0.2f %0.2f\n",right[0],right[1],right[2]);
|
||
|
Com_Printf("Up :%0.2f %0.2f %0.2f\n",up[0],up[1],up[2]);
|
||
|
Com_Printf("Direction :%0.2f %0.2f %0.2f\n",dir[0],dir[1],dir[2]);
|
||
|
Com_Printf("Endpoint :%0.2f %0.2f %0.2f\n",end[0],end[1],end[2]);
|
||
|
Com_Printf("Server Trace Start :%0.2f %0.2f %0.2f\n",src[0],src[1],src[2]);
|
||
|
Com_Printf("Server Trace End :%0.2f %0.2f %0.2f\n",trace.endpos[0],trace.endpos[1],trace.endpos[2]);
|
||
|
Com_Printf("\n");
|
||
|
#endif
|
||
|
if ( trace.fraction != 1.0 )
|
||
|
{
|
||
|
TraceAttack( src, trace.endpos, mindamage + (int)G_Random( maxdamage - mindamage + 1 ), &trace, MAX_RICOCHETS, kick, dflags, meansofdeath, server_effects );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void BulletWeapon::FireTracer( void )
|
||
|
{
|
||
|
Entity *tracer;
|
||
|
Vector src,dir,end;
|
||
|
trace_t trace;
|
||
|
|
||
|
GetMuzzlePosition( &src, &dir );
|
||
|
end = src + dir * 8192;
|
||
|
trace = G_Trace( src, vec_zero, vec_zero, end, owner, MASK_SHOT, "BulletWeapon::FireTracer" );
|
||
|
|
||
|
tracer = new Entity;
|
||
|
|
||
|
tracer->angles = dir.toAngles();
|
||
|
tracer->angles[ PITCH ] = -tracer->angles[ PITCH ] + 90;
|
||
|
//tracer->angles[PITCH] *= -1;
|
||
|
|
||
|
tracer->setAngles( tracer->angles );
|
||
|
|
||
|
tracer->setMoveType( MOVETYPE_NONE );
|
||
|
tracer->setSolidType( SOLID_NOT );
|
||
|
tracer->setModel( "sprites/tracer.spr" );
|
||
|
tracer->setSize( "0 0 0", "0 0 0" );
|
||
|
tracer->setOrigin( trace.endpos );
|
||
|
tracer->edict->s.renderfx &= ~RF_FRAMELERP;
|
||
|
|
||
|
VectorCopy( src, tracer->edict->s.old_origin );
|
||
|
tracer->PostEvent(EV_Remove,0.1f);
|
||
|
}
|