2001-12-31 16:16:59 +00:00
//-----------------------------------------------------------------------------
//
// $Id$
//
//-----------------------------------------------------------------------------
//
2001-12-31 16:28:42 +00:00
// $Log$
2005-02-15 16:33:39 +00:00
// Revision 1.120 2005/02/15 16:33:38 makro
// Tons of updates (entity tree attachment system, UI vectors)
//
2004-01-26 21:26:09 +00:00
// Revision 1.119 2004/01/26 21:26:08 makro
// no message
//
2003-07-30 16:05:47 +00:00
// Revision 1.118 2003/07/30 16:05:46 makro
// no message
//
2003-04-26 15:23:57 +00:00
// Revision 1.117 2003/04/26 15:23:57 jbravo
// grenade replacement fix. Version bumped to 3.1
//
2003-04-13 21:58:00 +00:00
// Revision 1.116 2003/04/13 21:58:00 slicer
// Added a Zoom Sensitivity Lock during fire sequence of ssg; removed unnecessary code
//
2003-04-06 23:20:18 +00:00
// Revision 1.115 2003/04/06 23:20:18 niceass
// changes to what models 3rd person akimbos use
//
2003-04-04 16:38:47 +00:00
// Revision 1.114 2003/04/04 16:38:47 niceass
// fixed gun2 lighting, possibly
//
2003-04-02 22:23:51 +00:00
// Revision 1.113 2003/04/02 22:23:51 jbravo
// More replacements tweaks. Added zcam_stfu
//
2003-04-02 17:58:03 +00:00
// Revision 1.112 2003/04/02 17:58:03 jbravo
// Ammo skin only replacements now work.
//
2003-03-29 23:04:56 +00:00
// Revision 1.111 2003/03/29 23:04:56 jbravo
// More post _skin cvar fixes
//
2003-03-29 18:53:41 +00:00
// Revision 1.110 2003/03/29 18:53:41 jbravo
// Fixed ammo bug when dropping bandolier. Added color to more errormessages
//
2003-03-29 17:00:11 +00:00
// Revision 1.109 2003/03/29 17:00:11 jbravo
// More replacement hiccups after skin cvars where removed
//
2003-03-29 15:04:03 +00:00
// Revision 1.108 2003/03/29 15:04:03 jbravo
// Removing skin replacement cvars
//
2003-03-28 10:36:03 +00:00
// Revision 1.107 2003/03/28 10:36:02 jbravo
// Tweaking the replacement system a bit. Reactionmale now the default model
//
2003-03-09 21:30:39 +00:00
// Revision 1.106 2003/03/09 21:30:38 jbravo
// Adding unlagged. Still needs work.
//
2003-03-08 10:04:12 +00:00
// Revision 1.105 2003/03/08 10:04:12 niceass
// small code change. should make no difference
//
2003-02-05 04:44:47 +00:00
// Revision 1.104 2003/02/05 04:44:47 niceass
// added support for tag_weapon2 (2 pistols for akimbo)
//
2003-02-01 02:15:31 +00:00
// Revision 1.103 2003/02/01 02:15:31 jbravo
// Replacement models and items
//
2003-01-08 04:46:26 +00:00
// Revision 1.102 2003/01/08 04:46:26 jbravo
// Wrote a new hackish model replacement system
//
2002-12-05 23:11:29 +00:00
// Revision 1.101 2002/12/05 23:11:29 blaze
// Added item replacement code
//
2002-12-02 19:52:05 +00:00
// Revision 1.100 2002/12/02 19:52:05 niceass
// water pressure & shell ejection stuff
//
2002-11-18 04:39:47 +00:00
// Revision 1.99 2002/11/18 04:39:47 jbravo
// Cleanup of cg_weapons.c
//
2002-10-26 00:37:18 +00:00
// Revision 1.98 2002/10/26 00:37:18 jbravo
// New multiple item code and added PB support to the UI
//
2002-10-20 21:24:32 +00:00
// Revision 1.97 2002/10/20 21:24:32 blaze
2002-11-18 04:39:47 +00:00
// Added cg_RQ3_gunname cvars. These can be used to choose weapon replacements. You will need 3 icons that I will upload to the ftp. These should go in the next pk3
2002-10-20 21:24:32 +00:00
//
2002-09-09 06:40:35 +00:00
// Revision 1.96 2002/09/09 06:40:35 niceass
// smoke puff less intrusive
//
2002-09-08 23:23:49 +00:00
// Revision 1.95 2002/09/08 23:23:49 niceass
// no first person pistol action when firing in semi-auto with predictweapons 0 fixed
//
2002-09-08 03:15:16 +00:00
// Revision 1.94 2002/09/08 03:14:17 niceass
// tracerchance now can be 0.0 to 0.4
//
2002-08-29 04:42:41 +00:00
// Revision 1.93 2002/08/29 04:42:41 blaze
// Anti OGC code
//
2002-08-25 03:34:11 +00:00
// Revision 1.92 2002/08/25 03:34:11 niceass
// puff added to silencer
//
2002-07-22 06:35:03 +00:00
// Revision 1.91 2002/07/22 06:30:12 niceass
// cleaned up the powerup code
//
2002-07-13 22:43:59 +00:00
// Revision 1.90 2002/07/13 22:42:18 makro
// Semi-working fog hull, semi-working sky portals (cgame code commented out)
// Basically, semi-working stuff :P
//
2002-07-08 04:41:12 +00:00
// Revision 1.89 2002/07/08 04:41:12 niceass
// no more shell ejection on LCA, I hope
//
2002-06-29 21:57:18 +00:00
// Revision 1.88 2002/06/29 21:57:18 niceass
// shotgun fixes
//
2002-06-29 20:56:23 +00:00
// Revision 1.87 2002/06/29 20:56:23 niceass
// Change to the way HC/Shotty act
//
2002-06-29 04:15:15 +00:00
// Revision 1.86 2002/06/29 04:15:15 jbravo
// CTF is now CTB. no weapons while the case is in hand other than pistol or knife
//
2002-06-23 04:36:27 +00:00
// Revision 1.85 2002/06/23 04:34:54 niceass
// change to foglaser
//
2002-06-21 04:11:34 +00:00
// Revision 1.84 2002/06/21 04:09:44 niceass
// fog laser
//
2002-06-17 03:53:31 +00:00
// Revision 1.83 2002/06/17 03:53:31 niceass
// m4 muzzle flash is smaller
//
2002-06-16 20:06:15 +00:00
// Revision 1.82 2002/06/16 20:06:13 jbravo
// Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap"
//
2002-06-16 19:12:52 +00:00
// Revision 1.81 2002/06/16 19:12:52 jbravo
// Removed the MISSIONPACK ifdefs and missionpack only code.
//
2002-06-12 17:05:14 +00:00
// Revision 1.80 2002/06/12 17:05:14 slicer
// Fixed a couple of problems related to the sniper zooming
//
2002-06-11 21:50:51 +00:00
// Revision 1.79 2002/06/11 21:50:51 niceass
// HC changes
//
2002-06-06 00:29:14 +00:00
// Revision 1.78 2002/06/06 00:29:14 blaze
// got rid of the out of ammo shader
//
2002-06-05 09:40:10 +00:00
// Revision 1.77 2002/06/05 09:40:10 niceass
// tracer fix
//
2002-06-03 01:09:33 +00:00
// Revision 1.76 2002/06/03 01:09:33 niceass
// silencer scale changes
//
2002-05-29 03:52:21 +00:00
// Revision 1.75 2002/05/29 03:52:21 niceass
// LAM code
//
2002-05-27 17:47:19 +00:00
// Revision 1.74 2002/05/27 17:47:19 jbravo
// Fixes and cleanups
//
2002-05-27 06:58:40 +00:00
// Revision 1.73 2002/05/27 06:58:40 niceass
// removed reflection stuff. Silencer stuff added
//
2002-05-18 03:55:35 +00:00
// Revision 1.72 2002/05/18 03:55:35 niceass
// many misc. changes
//
2002-05-12 14:40:28 +00:00
// Revision 1.71 2002/05/12 14:39:48 makro
// Wood, brick & ceramic impact sounds
//
2002-05-09 06:45:14 +00:00
// Revision 1.70 2002/05/09 06:40:37 niceass
// New tracers
//
2002-05-01 17:46:00 +00:00
// Revision 1.69 2002/05/01 17:46:00 slicer
// Only calling "unzoom" when switching from ssg ( less lag )
//
2002-05-01 03:28:07 +00:00
// Revision 1.68 2002/05/01 03:28:07 niceass
// mp5 scale change for silencer
//
2002-04-29 06:10:09 +00:00
// Revision 1.67 2002/04/29 06:10:09 niceass
// visible silencer
//
2002-04-07 02:10:42 +00:00
// Revision 1.66 2002/04/07 02:10:42 niceass
// shell ejection bug fixed
//
2002-04-06 21:43:59 +00:00
// Revision 1.65 2002/04/06 21:43:59 makro
// New surfaceparm system
//
2002-04-05 18:53:26 +00:00
// Revision 1.64 2002/04/05 18:53:26 jbravo
// Warning fixes
//
2002-04-03 03:13:49 +00:00
// Revision 1.63 2002/04/03 03:13:49 blaze
// NEW BREAKABLE CODE - will break all old breakables(wont appear in maps)
//
2002-04-01 22:23:38 +00:00
// Revision 1.62 2002/04/01 22:23:38 slicer
// Added "weapon" command buffering
//
2002-03-31 13:52:48 +00:00
// Revision 1.61 2002/03/31 13:52:48 jbravo
// More cleanups
//
2002-03-31 03:31:24 +00:00
// Revision 1.60 2002/03/31 03:31:24 jbravo
// Compiler warning cleanups
//
2002-03-31 02:00:42 +00:00
// Revision 1.59 2002/03/31 02:00:42 niceass
// shell stuff
//
2002-03-24 22:46:23 +00:00
// Revision 1.58 2002/03/24 22:46:23 niceass
// shell ejection stuff/handcannon fix
//
2002-03-21 02:17:39 +00:00
// Revision 1.57 2002/03/21 02:17:39 blaze
// more func_explosive goodness
//
2002-03-21 00:26:46 +00:00
// Revision 1.56 2002/03/21 00:26:11 blaze
// some fixing of func_explosive
//
2002-03-18 19:19:08 +00:00
// Revision 1.55 2002/03/18 19:19:08 slicer
// Fixed bandage bugs ( i hope )
//
2002-03-16 21:50:09 +00:00
// Revision 1.54 2002/03/16 21:48:39 niceass
// All new shell ejection code
//
2002-03-13 18:41:18 +00:00
// Revision 1.53 2002/03/13 18:41:18 slicer
// Adjusted some of elder's unzoom code for the new sniper system ( server side )
//
2002-03-11 03:25:41 +00:00
// Revision 1.52 2002/03/11 03:25:41 jbravo
// Minor fix for NA
//
2002-03-11 02:22:45 +00:00
// Revision 1.51 2002/03/11 02:22:45 niceass
// tag shell ejections
//
2002-02-24 20:49:07 +00:00
// Revision 1.50 2002/02/24 20:49:07 slicer
// Follow Spect Players- Draws the gun
//
2002-02-23 18:07:46 +00:00
// Revision 1.49 2002/02/23 18:07:46 slicer
// Changed Sniper code and Cam code
//
2002-02-08 18:00:34 +00:00
// Revision 1.48 2002/02/08 18:00:34 jbravo
// Fixing "No newline at end of file" Warnings Linux keeps giving me
//
2002-01-14 01:19:23 +00:00
// Revision 1.47 2002/01/14 01:19:23 niceass
// No more default 800 gravity on items - NiceAss
//
2002-01-12 15:18:20 +00:00
// Revision 1.46 2002/01/12 15:18:20 jbravo
// Added a fix from Niceass. (cg_drawgun affecting other player models)
//
2002-01-11 19:48:33 +00:00
// Revision 1.45 2002/01/11 19:48:29 jbravo
// Formatted the source in non DOS format.
//
2001-12-31 16:28:42 +00:00
// Revision 1.44 2001/12/31 16:28:41 jbravo
// I made a Booboo with the Log tag.
//
2001-12-31 16:16:59 +00:00
//
//-----------------------------------------------------------------------------
2001-07-28 12:32:54 +00:00
// Copyright (C) 1999-2000 Id Software, Inc.
2001-05-06 20:50:27 +00:00
//
// cg_weapons.c -- events and effects dealing with weapons
# include "cg_local.h"
2001-09-11 00:11:00 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_ParseWeaponSoundFile
Added by Elder
Reads information for frame - sound timing
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static qboolean CG_ParseWeaponSoundFile ( const char * filename , weaponInfo_t * weapon )
{
char * text_p ;
2003-02-01 02:15:31 +00:00
int len , i , skip ;
2002-06-16 20:06:15 +00:00
char * token ;
char text [ 20000 ] ;
fileHandle_t f ;
sfxWeapTiming_t * weapTiming ;
2001-09-11 00:11:00 +00:00
2001-10-11 22:50:58 +00:00
weapTiming = weapon - > animationSounds ;
2001-09-11 00:11:00 +00:00
// load the file
2002-06-16 20:06:15 +00:00
len = trap_FS_FOpenFile ( filename , & f , FS_READ ) ;
if ( len < = 0 ) {
2001-09-11 00:11:00 +00:00
return qfalse ;
}
2002-06-16 20:06:15 +00:00
if ( len > = sizeof ( text ) - 1 ) {
CG_Printf ( " File %s too long \n " , filename ) ;
2001-09-11 00:11:00 +00:00
return qfalse ;
}
2002-06-16 20:06:15 +00:00
trap_FS_Read ( text , len , f ) ;
2001-09-11 00:11:00 +00:00
text [ len ] = 0 ;
2002-06-16 20:06:15 +00:00
trap_FS_FCloseFile ( f ) ;
2001-11-11 20:03:09 +00:00
2001-09-11 00:11:00 +00:00
// parse the text
text_p = text ;
// Elder: uhh, what was this for?
2002-06-16 20:06:15 +00:00
skip = 0 ; // quite the compiler warning
2001-10-11 22:50:58 +00:00
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < MAX_ANIM_SOUNDS ; i + + ) {
2001-10-11 22:50:58 +00:00
// Grab frame number
2002-06-16 20:06:15 +00:00
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
2001-10-11 22:50:58 +00:00
// Add it to the array
2002-06-16 20:06:15 +00:00
if ( atoi ( token ) ) {
2001-10-11 22:50:58 +00:00
weapTiming - > sfxInfo [ i ] . frame = atoi ( token ) ;
2002-06-16 20:06:15 +00:00
} else
2001-10-11 22:50:58 +00:00
break ;
// Grab sound file path
2002-06-16 20:06:15 +00:00
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
2001-10-11 22:50:58 +00:00
2002-06-16 20:06:15 +00:00
weapTiming - > sfxInfo [ i ] . sound = trap_S_RegisterSound ( token , qfalse ) ;
2001-10-11 22:50:58 +00:00
}
2001-11-11 20:03:09 +00:00
2001-10-11 22:50:58 +00:00
// Store total number
weapTiming - > numFrames = i ;
return qtrue ;
2001-09-11 00:11:00 +00:00
}
2002-05-18 03:55:35 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_CalcMuzzlePoint
= = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static qboolean CG_CalcMuzzlePoint ( int entityNum , vec3_t muzzle )
{
vec3_t forward ;
centity_t * cent ;
int anim ;
2002-05-18 03:55:35 +00:00
2002-06-16 20:06:15 +00:00
if ( entityNum = = cg . snap - > ps . clientNum ) {
VectorCopy ( cg . snap - > ps . origin , muzzle ) ;
2002-05-18 03:55:35 +00:00
muzzle [ 2 ] + = cg . snap - > ps . viewheight ;
2002-06-16 20:06:15 +00:00
AngleVectors ( cg . snap - > ps . viewangles , forward , NULL , NULL ) ;
VectorMA ( muzzle , 14 , forward , muzzle ) ;
2002-05-18 03:55:35 +00:00
return qtrue ;
}
cent = & cg_entities [ entityNum ] ;
2002-06-16 20:06:15 +00:00
if ( ! cent - > currentValid ) {
2002-05-18 03:55:35 +00:00
return qfalse ;
}
2002-06-16 20:06:15 +00:00
VectorCopy ( cent - > currentState . pos . trBase , muzzle ) ;
2002-05-18 03:55:35 +00:00
2002-06-16 20:06:15 +00:00
AngleVectors ( cent - > currentState . apos . trBase , forward , NULL , NULL ) ;
2002-05-18 03:55:35 +00:00
anim = cent - > currentState . legsAnim & ~ ANIM_TOGGLEBIT ;
2002-06-16 20:06:15 +00:00
if ( anim = = LEGS_WALKCR | | anim = = LEGS_IDLECR ) {
2002-05-18 03:55:35 +00:00
muzzle [ 2 ] + = CROUCH_VIEWHEIGHT ;
} else {
muzzle [ 2 ] + = DEFAULT_VIEWHEIGHT ;
}
2002-06-16 20:06:15 +00:00
VectorMA ( muzzle , 14 , forward , muzzle ) ;
2002-05-18 03:55:35 +00:00
return qtrue ;
}
2001-07-28 02:49:18 +00:00
/* [QUARANTINE] - Weapon Animations - CG_ParseWeaponAnimFile
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_ParseWeaponAnimFile
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static qboolean CG_ParseWeaponAnimFile ( const char * filename , weaponInfo_t * weapon )
2001-09-16 04:04:31 +00:00
{
2003-02-01 02:15:31 +00:00
char * text_p , * token ;
int len , i , skip ;
2001-07-28 12:32:54 +00:00
float fps ;
char text [ 20000 ] ;
fileHandle_t f ;
animation_t * animations ;
animations = weapon - > animations ;
// load the file
2002-06-16 20:06:15 +00:00
len = trap_FS_FOpenFile ( filename , & f , FS_READ ) ;
if ( len < = 0 ) {
2001-07-28 12:32:54 +00:00
return qfalse ;
}
2002-06-16 20:06:15 +00:00
if ( len > = sizeof ( text ) - 1 ) {
CG_Printf ( " File %s too long \n " , filename ) ;
2001-07-28 12:32:54 +00:00
return qfalse ;
}
2002-06-16 20:06:15 +00:00
trap_FS_Read ( text , len , f ) ;
2001-07-28 12:32:54 +00:00
text [ len ] = 0 ;
2002-06-16 20:06:15 +00:00
trap_FS_FCloseFile ( f ) ;
2001-11-11 20:03:09 +00:00
2001-07-28 12:32:54 +00:00
// parse the text
text_p = text ;
2002-06-16 20:06:15 +00:00
skip = 0 ; // quite the compiler warning
2001-11-11 20:03:09 +00:00
2001-07-28 12:32:54 +00:00
// read information for each frame
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < MAX_WEAPON_ANIMATIONS ; i + + ) {
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
animations [ i ] . firstFrame = atoi ( token ) ;
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
animations [ i ] . numFrames = atoi ( token ) ;
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
animations [ i ] . loopFrames = atoi ( token ) ;
token = COM_Parse ( & text_p ) ;
if ( ! token )
break ;
fps = atof ( token ) ;
if ( fps = = 0 )
fps = 1 ;
2001-07-28 12:32:54 +00:00
animations [ i ] . frameLerp = 1000 / fps ;
animations [ i ] . initialLerp = 1000 / fps ;
}
2002-06-16 20:06:15 +00:00
if ( i ! = MAX_WEAPON_ANIMATIONS ) {
CG_Printf ( " Error parsing weapon animation file: %s " , filename ) ;
2001-07-28 12:32:54 +00:00
return qfalse ;
2001-11-11 20:03:09 +00:00
}
2001-07-28 02:49:18 +00:00
2001-07-28 12:32:54 +00:00
return qtrue ;
2001-07-28 02:49:18 +00:00
}
2002-06-16 20:06:15 +00:00
2001-07-28 02:49:18 +00:00
// END
2001-05-06 20:50:27 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_MachineGunEjectBrass
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
localEntity_t * CG_MachineGunEjectBrass ( centity_t * cent )
{
localEntity_t * le ;
refEntity_t * re ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( cg_brassTime . integer < = 0 ) {
2002-03-11 02:22:45 +00:00
return NULL ;
2001-05-06 20:50:27 +00:00
}
le = CG_AllocLocalEntity ( ) ;
re = & le - > refEntity ;
le - > leType = LE_FRAGMENT ;
le - > startTime = cg . time ;
2002-06-16 20:06:15 +00:00
le - > endTime = le - > startTime + cg_brassTime . integer + ( cg_brassTime . integer / 4 ) * random ( ) ;
2001-05-06 20:50:27 +00:00
le - > pos . trType = TR_GRAVITY ;
2002-06-16 20:06:15 +00:00
le - > pos . trTime = cg . time - ( rand ( ) & 15 ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
AxisCopy ( axisDefault , re - > axis ) ;
2002-03-11 02:22:45 +00:00
2002-03-16 21:50:09 +00:00
le - > bounceFactor = 0.5 ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( cent - > currentState . weapon = = WP_M4 | | cent - > currentState . weapon = = WP_SSG3000 ) {
2002-06-11 21:50:51 +00:00
re - > hModel = cgs . media . largeBrassModel ;
le - > bounceFactor * = 0.75 ;
2002-06-16 20:06:15 +00:00
} else
2002-06-11 21:50:51 +00:00
re - > hModel = cgs . media . machinegunBrassModel ;
2001-05-06 20:50:27 +00:00
le - > angles . trType = TR_LINEAR ;
le - > angles . trTime = cg . time ;
2002-03-11 02:22:45 +00:00
2002-06-16 20:06:15 +00:00
le - > angles . trDelta [ 0 ] = rand ( ) % 200 - 100 ;
le - > angles . trDelta [ 1 ] = rand ( ) % 200 - 100 ;
le - > angles . trDelta [ 2 ] = rand ( ) % 200 - 100 ;
2001-05-06 20:50:27 +00:00
le - > leFlags = LEF_TUMBLE ;
le - > leBounceSoundType = LEBS_BRASS ;
le - > leMarkType = LEMT_NONE ;
2002-03-11 02:22:45 +00:00
return le ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_ShotgunEjectBrass
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
localEntity_t * CG_ShotgunEjectBrass ( centity_t * cent )
{
localEntity_t * le ;
refEntity_t * re ;
int isHC ;
2002-06-11 21:50:51 +00:00
if ( cent - > currentState . weapon = = WP_HANDCANNON )
2002-06-16 20:06:15 +00:00
isHC = 1 ;
2002-06-11 21:50:51 +00:00
else
2002-06-16 20:06:15 +00:00
isHC = 0 ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( cg_brassTime . integer < = 0 ) {
2002-03-11 02:22:45 +00:00
return NULL ;
2001-05-06 20:50:27 +00:00
}
2002-06-16 20:06:15 +00:00
le = CG_AllocLocalEntity ( ) ;
re = & le - > refEntity ;
le - > leType = LE_FRAGMENT ;
le - > startTime = cg . time ;
le - > endTime = le - > startTime + cg_brassTime . integer * 3 + cg_brassTime . integer * random ( ) ;
le - > pos . trType = TR_GRAVITY ;
le - > pos . trTime = cg . time ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
AxisCopy ( axisDefault , re - > axis ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( isHC )
re - > hModel = cgs . media . HCBrassModel ;
else
re - > hModel = cgs . media . shotgunBrassModel ;
2002-06-11 21:50:51 +00:00
2002-06-16 20:06:15 +00:00
le - > bounceFactor = 0.3f ;
le - > angles . trType = TR_LINEAR ;
le - > angles . trTime = cg . time ;
le - > angles . trDelta [ 0 ] = rand ( ) % 200 - 100 ;
le - > angles . trDelta [ 1 ] = rand ( ) % 200 - 100 ;
le - > angles . trDelta [ 2 ] = rand ( ) % 200 - 100 ;
le - > leFlags = LEF_TUMBLE ;
le - > leBounceSoundType = LEBS_BRASS ;
le - > leMarkType = LEMT_NONE ;
2003-02-01 02:15:31 +00:00
2002-03-11 02:22:45 +00:00
return le ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_RailTrail
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_RailTrail ( clientInfo_t * ci , vec3_t start , vec3_t end )
{
2001-08-01 21:07:48 +00:00
vec3_t axis [ 36 ] , move , move2 , next_move , vec , temp ;
2002-06-16 20:06:15 +00:00
float len ;
int i , j , skip ;
localEntity_t * le ;
refEntity_t * re ;
2001-05-06 20:50:27 +00:00
2001-08-01 21:07:48 +00:00
# define RADIUS 4
# define ROTATION 1
# define SPACING 5
2001-11-11 20:03:09 +00:00
2001-08-01 21:07:48 +00:00
start [ 2 ] - = 4 ;
2002-06-16 20:06:15 +00:00
VectorCopy ( start , move ) ;
VectorSubtract ( end , start , vec ) ;
len = VectorNormalize ( vec ) ;
2001-08-01 21:07:48 +00:00
PerpendicularVector ( temp , vec ) ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 36 ; i + + ) {
RotatePointAroundVector ( axis [ i ] , vec , temp , i * 10 ) ; //banshee 2.4 was 10
2001-08-01 21:07:48 +00:00
}
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
le = CG_AllocLocalEntity ( ) ;
re = & le - > refEntity ;
le - > leType = LE_FADE_RGB ;
le - > startTime = cg . time ;
le - > endTime = cg . time + cg_railTrailTime . value ;
2002-06-16 20:06:15 +00:00
le - > lifeRate = 1.0 / ( le - > endTime - le - > startTime ) ;
2001-05-06 20:50:27 +00:00
re - > shaderTime = cg . time / 1000.0f ;
2001-08-01 21:07:48 +00:00
re - > reType = RT_RAIL_CORE ;
re - > customShader = cgs . media . railCoreShader ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
VectorCopy ( start , re - > origin ) ;
VectorCopy ( end , re - > oldorigin ) ;
2001-05-06 20:50:27 +00:00
2001-08-01 21:07:48 +00:00
re - > shaderRGBA [ 0 ] = ci - > color1 [ 0 ] * 255 ;
2002-06-16 20:06:15 +00:00
re - > shaderRGBA [ 1 ] = ci - > color1 [ 1 ] * 255 ;
re - > shaderRGBA [ 2 ] = ci - > color1 [ 2 ] * 255 ;
re - > shaderRGBA [ 3 ] = 255 ;
2001-08-01 21:07:48 +00:00
le - > color [ 0 ] = ci - > color1 [ 0 ] * 0.75 ;
le - > color [ 1 ] = ci - > color1 [ 1 ] * 0.75 ;
le - > color [ 2 ] = ci - > color1 [ 2 ] * 0.75 ;
2001-05-06 20:50:27 +00:00
le - > color [ 3 ] = 1.0f ;
2002-06-16 20:06:15 +00:00
AxisClear ( re - > axis ) ;
2001-05-06 20:50:27 +00:00
2001-08-01 21:07:48 +00:00
VectorMA ( move , 20 , vec , move ) ;
VectorCopy ( move , next_move ) ;
2002-06-16 20:06:15 +00:00
VectorScale ( vec , SPACING , vec ) ;
2001-08-01 21:07:48 +00:00
if ( cg_oldRail . integer ! = 0 ) {
// nudge down a bit so it isn't exactly in center
re - > origin [ 2 ] - = 8 ;
re - > oldorigin [ 2 ] - = 8 ;
return ;
}
skip = - 1 ;
2001-11-11 20:03:09 +00:00
2001-08-01 21:07:48 +00:00
j = 18 ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < len ; i + = SPACING ) {
2001-08-01 21:07:48 +00:00
if ( i ! = skip ) {
skip = i + SPACING ;
2002-06-16 20:06:15 +00:00
le = CG_AllocLocalEntity ( ) ;
re = & le - > refEntity ;
le - > leFlags = LEF_PUFF_DONT_SCALE ;
2001-08-01 21:07:48 +00:00
le - > leType = LE_MOVE_SCALE_FADE ;
2002-06-16 20:06:15 +00:00
le - > startTime = cg . time ;
le - > endTime = cg . time + ( i > > 1 ) + 600 ;
le - > lifeRate = 1.0 / ( le - > endTime - le - > startTime ) ;
re - > shaderTime = cg . time / 1000.0f ;
re - > reType = RT_SPRITE ;
re - > radius = 1.1f ;
2001-08-01 21:07:48 +00:00
re - > customShader = cgs . media . railRingsShader ;
2002-06-16 20:06:15 +00:00
re - > shaderRGBA [ 0 ] = ci - > color2 [ 0 ] * 255 ;
re - > shaderRGBA [ 1 ] = ci - > color2 [ 1 ] * 255 ;
re - > shaderRGBA [ 2 ] = ci - > color2 [ 2 ] * 255 ;
re - > shaderRGBA [ 3 ] = 255 ;
le - > color [ 0 ] = ci - > color2 [ 0 ] * 0.75 ;
le - > color [ 1 ] = ci - > color2 [ 1 ] * 0.75 ;
le - > color [ 2 ] = ci - > color2 [ 2 ] * 0.75 ;
le - > color [ 3 ] = 1.0f ;
le - > pos . trType = TR_LINEAR ;
le - > pos . trTime = cg . time ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorCopy ( move , move2 ) ;
VectorMA ( move2 , RADIUS , axis [ j ] , move2 ) ;
VectorCopy ( move2 , le - > pos . trBase ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
le - > pos . trDelta [ 0 ] = axis [ j ] [ 0 ] * 6 ;
le - > pos . trDelta [ 1 ] = axis [ j ] [ 1 ] * 6 ;
le - > pos . trDelta [ 2 ] = axis [ j ] [ 2 ] * 6 ;
2001-08-01 21:07:48 +00:00
}
2002-06-16 20:06:15 +00:00
VectorAdd ( move , vec , move ) ;
2001-08-01 21:07:48 +00:00
2002-06-16 20:06:15 +00:00
j = j + ROTATION < 36 ? j + ROTATION : ( j + ROTATION ) % 36 ;
2001-08-01 21:07:48 +00:00
}
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = =
CG_GrappleTrail
= = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_GrappleTrail ( centity_t * ent , const weaponInfo_t * wi )
{
vec3_t origin ;
entityState_t * es ;
vec3_t forward , up ;
refEntity_t beam ;
2001-05-06 20:50:27 +00:00
es = & ent - > currentState ;
2002-06-16 20:06:15 +00:00
CG_EvaluateTrajectory ( & es - > pos , cg . time , origin ) ;
2001-05-06 20:50:27 +00:00
ent - > trailTime = cg . time ;
2002-06-16 20:06:15 +00:00
memset ( & beam , 0 , sizeof ( beam ) ) ;
2001-05-06 20:50:27 +00:00
//FIXME adjust for muzzle position
2002-06-16 20:06:15 +00:00
VectorCopy ( cg_entities [ ent - > currentState . otherEntityNum ] . lerpOrigin , beam . origin ) ;
2001-05-06 20:50:27 +00:00
beam . origin [ 2 ] + = 26 ;
2002-06-16 20:06:15 +00:00
AngleVectors ( cg_entities [ ent - > currentState . otherEntityNum ] . lerpAngles , forward , NULL , up ) ;
VectorMA ( beam . origin , - 6 , up , beam . origin ) ;
VectorCopy ( origin , beam . oldorigin ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( Distance ( beam . origin , beam . oldorigin ) < 64 )
return ; // Don't draw if close
2001-05-06 20:50:27 +00:00
beam . reType = RT_LIGHTNING ;
beam . customShader = cgs . media . lightningShader ;
2002-06-16 20:06:15 +00:00
AxisClear ( beam . axis ) ;
2001-05-06 20:50:27 +00:00
beam . shaderRGBA [ 0 ] = 0xff ;
beam . shaderRGBA [ 1 ] = 0xff ;
beam . shaderRGBA [ 2 ] = 0xff ;
beam . shaderRGBA [ 3 ] = 0xff ;
2002-06-16 20:06:15 +00:00
trap_R_AddRefEntityToScene ( & beam ) ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = =
CG_RegisterWeapon
The server says this item is used on this level
= = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_RegisterWeapon ( int weaponNum )
{
weaponInfo_t * weaponInfo ;
gitem_t * item , * ammo ;
2003-03-29 23:04:56 +00:00
char path [ MAX_QPATH ] , str [ MAX_STRING_CHARS ] ;
2003-03-29 15:04:03 +00:00
char * model , * skin ;
2002-06-16 20:06:15 +00:00
vec3_t mins , maxs ;
2001-07-28 02:49:18 +00:00
// QUARANTINE - Weapon Animations - Added Variable
2002-06-16 20:06:15 +00:00
char filename [ MAX_QPATH ] ; //Used to open animation.cfg files
2001-07-28 02:49:18 +00:00
// END
2002-06-16 20:06:15 +00:00
int i ;
2001-05-06 20:50:27 +00:00
2002-11-18 04:39:47 +00:00
qboolean weapAnimLoad = qtrue ;
2001-05-06 20:50:27 +00:00
2003-03-28 10:36:03 +00:00
if ( weaponNum = = 0 | | weaponNum > = MAX_WEAPONS ) {
2001-05-06 20:50:27 +00:00
return ;
}
2003-03-28 10:36:03 +00:00
weaponInfo = & cg_weapons [ weaponNum ] ;
2002-06-16 20:06:15 +00:00
if ( weaponInfo - > registered ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
memset ( weaponInfo , 0 , sizeof ( * weaponInfo ) ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > registered = qtrue ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
for ( item = bg_itemlist + 1 ; item - > classname ; item + + ) {
if ( item - > giType = = IT_WEAPON & & item - > giTag = = weaponNum ) {
2001-05-06 20:50:27 +00:00
weaponInfo - > item = item ;
break ;
}
}
2002-11-18 04:39:47 +00:00
2002-06-16 20:06:15 +00:00
if ( ! item - > classname ) {
CG_Error ( " Couldn't find weapon %i " , weaponNum ) ;
2001-05-06 20:50:27 +00:00
}
2002-11-18 04:39:47 +00:00
2002-06-16 20:06:15 +00:00
CG_RegisterItemVisuals ( item - bg_itemlist ) ;
2002-11-18 04:39:47 +00:00
2003-01-08 04:46:26 +00:00
//
// load cmodel before model so filecache works
weaponInfo - > weaponModel = trap_R_RegisterModel ( item - > world_model [ 0 ] ) ;
2001-05-06 20:50:27 +00:00
// calc midpoint for rotation
2002-06-16 20:06:15 +00:00
trap_R_ModelBounds ( weaponInfo - > weaponModel , mins , maxs ) ;
for ( i = 0 ; i < 3 ; i + + ) {
weaponInfo - > weaponMidpoint [ i ] = mins [ i ] + 0.5 * ( maxs [ i ] - mins [ i ] ) ;
2001-05-06 20:50:27 +00:00
}
2003-01-08 04:46:26 +00:00
weaponInfo - > weaponIcon = trap_R_RegisterShader ( item - > icon ) ;
weaponInfo - > ammoIcon = trap_R_RegisterShader ( item - > icon ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
for ( ammo = bg_itemlist + 1 ; ammo - > classname ; ammo + + ) {
if ( ammo - > giType = = IT_AMMO & & ammo - > giTag = = weaponNum ) {
2001-05-06 20:50:27 +00:00
break ;
}
2001-07-24 01:49:02 +00:00
//Elder: hack for handcannon to use M3 ammo icon
2002-06-16 20:06:15 +00:00
else if ( weaponNum = = WP_HANDCANNON & & ammo - > giType = = IT_AMMO & & ammo - > giTag = = WP_M3 ) {
2001-07-24 01:49:02 +00:00
break ;
}
//Elder: hack for akimbos to use MK23 ammo icon
2002-06-16 20:06:15 +00:00
else if ( weaponNum = = WP_AKIMBO & & ammo - > giType = = IT_AMMO & & ammo - > giTag = = WP_PISTOL ) {
2001-07-24 01:49:02 +00:00
break ;
}
2001-05-06 20:50:27 +00:00
}
2002-06-16 20:06:15 +00:00
if ( ammo - > classname & & ammo - > world_model [ 0 ] ) {
weaponInfo - > ammoModel = trap_R_RegisterModel ( ammo - > world_model [ 0 ] ) ;
2001-07-24 01:49:02 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
weaponInfo - > ammoIcon = trap_R_RegisterShader ( ammo - > icon ) ;
2001-05-06 20:50:27 +00:00
}
2003-01-08 04:46:26 +00:00
strcpy ( path , item - > world_model [ 0 ] ) ;
2009-07-03 19:58:55 +00:00
COM_StripExtensionInPlace ( path ) ;
2002-06-16 20:06:15 +00:00
strcat ( path , " _flash.md3 " ) ;
weaponInfo - > flashModel = trap_R_RegisterModel ( path ) ;
2001-05-06 20:50:27 +00:00
2003-01-08 04:46:26 +00:00
strcpy ( path , item - > world_model [ 0 ] ) ;
2009-07-03 19:58:55 +00:00
COM_StripExtensionInPlace ( path ) ;
2002-06-16 20:06:15 +00:00
strcat ( path , " _barrel.md3 " ) ;
weaponInfo - > barrelModel = trap_R_RegisterModel ( path ) ;
2001-05-06 20:50:27 +00:00
2003-01-08 04:46:26 +00:00
strcpy ( path , item - > world_model [ 0 ] ) ;
2009-07-03 19:58:55 +00:00
COM_StripExtensionInPlace ( path ) ;
2002-06-16 20:06:15 +00:00
strcat ( path , " _hand.md3 " ) ;
weaponInfo - > handsModel = trap_R_RegisterModel ( path ) ;
2001-05-06 20:50:27 +00:00
2001-08-06 19:15:00 +00:00
//Elder: added to cache 1st-person models
2003-01-08 04:46:26 +00:00
strcpy ( path , item - > world_model [ 0 ] ) ;
2009-07-03 19:58:55 +00:00
COM_StripExtensionInPlace ( path ) ;
2002-06-16 20:06:15 +00:00
strcat ( path , " _1st.md3 " ) ;
weaponInfo - > firstModel = trap_R_RegisterModel ( path ) ;
2001-06-08 04:35:50 +00:00
2002-06-16 20:06:15 +00:00
if ( ! weaponInfo - > handsModel ) {
weaponInfo - > handsModel = trap_R_RegisterModel ( " models/weapons2/shotgun/shotgun_hand.md3 " ) ;
2001-06-08 04:35:50 +00:00
}
2001-07-09 00:32:10 +00:00
//Elder: if no _1st model, point to the weaponModel... this may get funky :)
2002-06-16 20:06:15 +00:00
if ( ! weaponInfo - > firstModel ) {
2001-08-18 20:01:21 +00:00
// Added warning message
2002-06-16 20:06:15 +00:00
CG_Printf ( " ^3Warning: %s first-person model not found; using world model^7 \n " ,
weaponInfo - > item - > pickup_name ) ;
2001-07-09 00:32:10 +00:00
weaponInfo - > firstModel = weaponInfo - > weaponModel ;
2001-05-06 20:50:27 +00:00
}
weaponInfo - > loopFireSound = qfalse ;
2001-11-11 20:03:09 +00:00
2003-03-29 23:04:56 +00:00
memset ( str , 0 , sizeof ( str ) ) ;
2002-06-16 20:06:15 +00:00
switch ( weaponNum ) {
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
//Blaze: Reaction Pistol
2001-05-06 20:50:27 +00:00
case WP_PISTOL :
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 1 , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/mk23/mk23fire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/mk23/mk23reload.wav " , qfalse ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_mk23 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 15:04:03 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-03-28 10:36:03 +00:00
}
}
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_MachineGunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2001-11-11 20:03:09 +00:00
2001-09-11 00:11:00 +00:00
// Load the animation information
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
weapAnimLoad = qfalse ;
}
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
2002-06-16 20:06:15 +00:00
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
}
2002-06-16 20:06:15 +00:00
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-07-28 02:49:18 +00:00
}
2001-09-11 00:11:00 +00:00
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-06-08 04:35:50 +00:00
case WP_KNIFE :
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 0.70f , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/knife/slash.wav " , qfalse ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_knife " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 18:53:41 +00:00
weaponInfo - > missileModel =
trap_R_RegisterModel ( va ( " models/weapons2/%s/knife.md3 " , model ) ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2001-09-11 00:11:00 +00:00
// Load the animation information
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
weapAnimLoad = qfalse ;
}
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_M4 :
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 1 , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/m4/m4fire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/m4/m4reload.wav " , qfalse ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_MachineGunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_m4 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
weapAnimLoad = qfalse ;
}
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-08-30 09:42:25 +00:00
}
2001-10-11 22:50:58 +00:00
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_SSG3000 :
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 0.5f , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/ssg3000/ssgfire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/ssg3000/ssgbolt.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 1 ] = trap_S_RegisterSound ( " sound/weapons/ssg3000/ssgin.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 2 ] = trap_S_RegisterSound ( " sound/weapons/ssg3000/ssgbolt.wav " , qfalse ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_MachineGunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ssg3000 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-08-25 00:05:20 +00:00
}
2001-10-11 22:50:58 +00:00
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-10-11 22:50:58 +00:00
}
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_MP5 :
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 0.75f , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/mp5/mp5fire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/mp5/mp5reload.wav " , qfalse ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_MachineGunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_mp5 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-10-30 23:23:04 +00:00
weapAnimLoad = qfalse ;
}
2001-11-11 20:03:09 +00:00
2001-11-08 02:37:11 +00:00
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-11-08 02:37:11 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-11-08 02:37:11 +00:00
}
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_HANDCANNON :
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 1 , 0 ) ;
2001-06-08 04:35:50 +00:00
//Elder: changed to hcfire from cannon_fire
2002-06-16 20:06:15 +00:00
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/handcannon/hcfire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/handcannon/hcreload.wav " , qfalse ) ;
2002-03-24 22:46:23 +00:00
weaponInfo - > ejectBrassFunc = CG_ShotgunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_handcannon " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
weapAnimLoad = qfalse ;
2001-08-17 14:28:52 +00:00
}
2001-10-11 22:50:58 +00:00
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-10-11 22:50:58 +00:00
}
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_M3 :
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 1 , 0 ) ;
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/m3/m3fire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 1 ] = trap_S_RegisterSound ( " sound/weapons/m3/m3in.wav " , qfalse ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_ShotgunEjectBrass ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_m3 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
weapAnimLoad = qfalse ;
2001-08-01 18:28:38 +00:00
}
2001-10-11 22:50:58 +00:00
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-10-11 22:50:58 +00:00
}
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_AKIMBO :
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 1 , 0.5f ) ;
2001-09-01 16:15:01 +00:00
// Elder: no more pseudo-dual sound needed :)
2002-06-16 20:06:15 +00:00
weaponInfo - > flashSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/mk23/mk23fire.wav " , qfalse ) ;
weaponInfo - > worldReloadSound [ 0 ] = trap_S_RegisterSound ( " sound/weapons/akimbo/akimboreload.wav " , qfalse ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > ejectBrassFunc = CG_MachineGunEjectBrass ;
2002-06-16 20:06:15 +00:00
cgs . media . bulletExplosionShader = trap_R_RegisterShader ( " bulletExplosion " ) ;
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_akimbo " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
weapAnimLoad = qfalse ;
}
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-09-01 16:15:01 +00:00
}
2001-10-11 22:50:58 +00:00
2001-05-06 20:50:27 +00:00
break ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
case WP_GRENADE :
2003-04-26 15:23:57 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_grenade " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2001-09-11 00:11:00 +00:00
//Use the projectile model
2003-04-26 15:23:57 +00:00
weaponInfo - > missileModel = trap_R_RegisterModel ( va ( " models/weapons2/%s/gren_projectile.md3 " , model ) ) ;
2001-05-06 20:50:27 +00:00
weaponInfo - > wiTrailTime = 700 ;
weaponInfo - > trailRadius = 32 ;
2002-06-16 20:06:15 +00:00
MAKERGB ( weaponInfo - > flashDlightColor , 1 , 0.70f , 0 ) ;
//Blaze: Make sure we load this as we may have exploding crates
2002-03-21 00:26:46 +00:00
//cgs.media.grenadeExplosionShader = trap_R_RegisterShader( "grenadeExplosion" );
2003-02-01 02:15:31 +00:00
// JBravo: skin replacements
2003-03-29 15:04:03 +00:00
// Makro - no longer using skin cvars
if ( strcmp ( skin , " default " ) ) {
weaponInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
if ( ! weaponInfo - > customSkin ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Weapon skin load failure: %s \n " , va ( " models/weapons2/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
}
2001-09-11 00:11:00 +00:00
// Load the animation information
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/animation.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponAnimFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon animation file %s \n " , filename ) ;
2001-09-11 00:11:00 +00:00
weapAnimLoad = qfalse ;
}
2001-10-11 22:50:58 +00:00
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
if ( weapAnimLoad ) {
2003-03-29 15:04:03 +00:00
Com_sprintf ( filename , sizeof ( filename ) , " models/weapons2/%s/sound.cfg " , model ) ;
2002-06-16 20:06:15 +00:00
if ( ! CG_ParseWeaponSoundFile ( filename , weaponInfo ) ) {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Failed to load weapon sound file %s \n " , filename ) ;
2001-10-11 22:50:58 +00:00
}
} else {
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Could not load sound.cfg because animation.cfg loading failed \n " ) ;
2001-10-11 22:50:58 +00:00
}
2001-05-06 20:50:27 +00:00
break ;
2002-06-16 20:06:15 +00:00
default :
2001-05-06 20:50:27 +00:00
break ;
}
}
/*
= = = = = = = = = = = = = = = = =
CG_RegisterItemVisuals
The server says this item is used on this level
= = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_RegisterItemVisuals ( int itemNum )
{
itemInfo_t * itemInfo ;
gitem_t * item ;
2003-03-29 17:00:11 +00:00
char * model , * skin , str [ MAX_TOKEN_CHARS ] ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
itemInfo = & cg_items [ itemNum ] ;
if ( itemInfo - > registered ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-12-05 23:11:29 +00:00
2002-06-16 20:06:15 +00:00
item = & bg_itemlist [ itemNum ] ;
2002-12-05 23:11:29 +00:00
2002-06-16 20:06:15 +00:00
memset ( itemInfo , 0 , sizeof ( & itemInfo ) ) ;
2001-05-06 20:50:27 +00:00
itemInfo - > registered = qtrue ;
2003-02-01 02:15:31 +00:00
itemInfo - > models [ 0 ] = trap_R_RegisterModel ( item - > world_model [ 0 ] ) ;
itemInfo - > icon = trap_R_RegisterShader ( item - > icon ) ;
if ( item - > giType = = IT_WEAPON ) {
CG_RegisterWeapon ( item - > giTag ) ;
2002-12-05 23:11:29 +00:00
}
2003-02-01 02:15:31 +00:00
// JBravo: replacement skins for items
2003-01-08 04:46:26 +00:00
if ( item - > giType = = IT_HOLDABLE ) {
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_kevlar " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_kevlar " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_silencer " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_silencer " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_laser " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_laser " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_bandolier " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_bandolier " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_slippers " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_slippers " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
2003-03-29 15:04:03 +00:00
if ( ! strcmp ( item - > classname , " item_helmet " ) ) {
2003-03-29 17:00:11 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_helmet " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
2003-03-29 15:04:03 +00:00
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/items/%s/%s.skin " , model , skin ) ) ;
if ( ! itemInfo - > customSkin )
2003-03-29 18:53:41 +00:00
Com_Printf ( " ^1Item skin load failure: %s \n " , va ( " models/items/%s/%s.skin " , model , skin ) ) ;
2003-02-01 02:15:31 +00:00
}
2002-12-05 23:11:29 +00:00
}
}
2001-05-06 20:50:27 +00:00
2003-04-02 17:58:03 +00:00
if ( item - > giType = = IT_AMMO ) {
if ( ! strcmp ( item - > classname , " ammo_mk23 " ) ) {
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ammo_mk23 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/ammo/%s.skin " , skin ) ) ;
if ( ! itemInfo - > customSkin )
Com_Printf ( " ^1Ammo skin load failure: %s \n " , va ( " models/ammo/%s.skin " , skin ) ) ;
}
}
if ( ! strcmp ( item - > classname , " ammo_shells " ) ) {
2003-04-02 22:23:51 +00:00
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ammo_m3 " , str , sizeof ( str ) ) ;
2003-04-02 17:58:03 +00:00
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/ammo/%s.skin " , skin ) ) ;
if ( ! itemInfo - > customSkin )
Com_Printf ( " ^1Ammo skin load failure: %s \n " , va ( " models/ammo/%s.skin " , skin ) ) ;
}
}
if ( ! strcmp ( item - > classname , " ammo_ssg3000 " ) ) {
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ammo_ssg3000 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/ammo/%s.skin " , skin ) ) ;
if ( ! itemInfo - > customSkin )
Com_Printf ( " ^1Ammo skin load failure: %s \n " , va ( " models/ammo/%s.skin " , skin ) ) ;
}
}
if ( ! strcmp ( item - > classname , " ammo_mp5 " ) ) {
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ammo_mp5 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/ammo/%s.skin " , skin ) ) ;
if ( ! itemInfo - > customSkin )
Com_Printf ( " ^1Ammo skin load failure: %s \n " , va ( " models/ammo/%s.skin " , skin ) ) ;
}
}
if ( ! strcmp ( item - > classname , " ammo_m4 " ) ) {
trap_Cvar_VariableStringBuffer ( " cg_RQ3_ammo_m4 " , str , sizeof ( str ) ) ;
model = modelFromStr ( str ) ;
skin = skinFromStr ( str ) ;
if ( strcmp ( skin , " default " ) ) {
itemInfo - > customSkin = trap_R_RegisterSkin ( va ( " models/ammo/%s.skin " , skin ) ) ;
if ( ! itemInfo - > customSkin )
Com_Printf ( " ^1Ammo skin load failure: %s \n " , va ( " models/ammo/%s.skin " , skin ) ) ;
}
}
}
2001-05-06 20:50:27 +00:00
//
// powerups have an accompanying ring or sphere
//
2002-06-16 20:06:15 +00:00
if ( item - > giType = = IT_POWERUP | | item - > giType = = IT_HEALTH | |
item - > giType = = IT_ARMOR | | item - > giType = = IT_HOLDABLE ) {
if ( item - > world_model [ 1 ] ) {
itemInfo - > models [ 1 ] = trap_R_RegisterModel ( item - > world_model [ 1 ] ) ;
2001-05-06 20:50:27 +00:00
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
VIEW WEAPON
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = =
CG_CalculateWeaponPosition
= = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static void CG_CalculateWeaponPosition ( vec3_t origin , vec3_t angles )
{
2003-02-01 02:15:31 +00:00
float scale , fracsin ;
2002-06-16 20:06:15 +00:00
int delta ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorCopy ( cg . refdef . vieworg , origin ) ;
VectorCopy ( cg . refdefViewAngles , angles ) ;
2001-05-06 20:50:27 +00:00
// on odd legs, invert some angles
2002-06-16 20:06:15 +00:00
if ( cg . bobcycle & 1 ) {
2001-05-06 20:50:27 +00:00
scale = - cg . xyspeed ;
} else {
scale = cg . xyspeed ;
}
// gun angles from bobbing
angles [ ROLL ] + = scale * cg . bobfracsin * 0.005 ;
angles [ YAW ] + = scale * cg . bobfracsin * 0.01 ;
angles [ PITCH ] + = cg . xyspeed * cg . bobfracsin * 0.005 ;
// drop the weapon when landing
delta = cg . time - cg . landTime ;
2002-06-16 20:06:15 +00:00
if ( delta < LAND_DEFLECT_TIME ) {
origin [ 2 ] + = cg . landChange * 0.25 * delta / LAND_DEFLECT_TIME ;
} else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) {
origin [ 2 ] + = cg . landChange * 0.25 * ( LAND_DEFLECT_TIME + LAND_RETURN_TIME - delta ) / LAND_RETURN_TIME ;
2001-05-06 20:50:27 +00:00
}
// idle drift
scale = cg . xyspeed + 40 ;
2002-06-16 20:06:15 +00:00
fracsin = sin ( cg . time * 0.001 ) ;
2001-05-06 20:50:27 +00:00
angles [ ROLL ] + = scale * fracsin * 0.01 ;
angles [ YAW ] + = scale * fracsin * 0.01 ;
angles [ PITCH ] + = scale * fracsin * 0.01 ;
}
/*
= = = = = = = = = = = = =
CG_AddPlayerWeapon
Used for both the view weapon ( ps is valid ) and the world modelother character models ( ps is NULL )
The main player will have this called for BOTH cases , so effects like light and
sound should only be done on the world model case .
= = = = = = = = = = = = =
*/
2003-02-05 04:44:47 +00:00
void CG_AddPlayerWeapon ( refEntity_t * parent , playerState_t * ps , centity_t * cent , int team )
2002-06-16 20:06:15 +00:00
{
2003-02-05 04:44:47 +00:00
// gun2 is for tag_weapon2. atm, only another pistol for akimbo in thirdperson
refEntity_t gun1 , gun2 ;
refEntity_t flash ;
refEntity_t silencer , laser ;
2002-06-16 20:06:15 +00:00
vec3_t angles ;
weapon_t weaponNum ;
weaponInfo_t * weapon ;
centity_t * nonPredictedCent ;
2002-03-16 21:50:09 +00:00
localEntity_t * shell = NULL ;
2001-05-06 20:50:27 +00:00
weaponNum = cent - > currentState . weapon ;
2003-02-05 04:44:47 +00:00
CG_RegisterWeapon ( weaponNum ) ;
weapon = & cg_weapons [ weaponNum ] ;
2001-05-06 20:50:27 +00:00
// add the weapon
2003-02-05 04:44:47 +00:00
memset ( & gun1 , 0 , sizeof ( gun1 ) ) ;
memset ( & gun2 , 0 , sizeof ( gun2 ) ) ;
VectorCopy ( parent - > lightingOrigin , gun1 . lightingOrigin ) ;
gun1 . shadowPlane = parent - > shadowPlane ;
gun1 . renderfx = parent - > renderfx ;
gun1 . shaderRGBA [ 0 ] = 255 ;
gun1 . shaderRGBA [ 1 ] = 255 ;
gun1 . shaderRGBA [ 2 ] = 255 ;
gun1 . shaderRGBA [ 3 ] = 255 ;
2005-02-15 16:33:39 +00:00
gun1 . nonNormalizedAxes = qtrue ;
2003-04-04 16:38:47 +00:00
VectorCopy ( parent - > lightingOrigin , gun2 . lightingOrigin ) ;
2003-02-05 04:44:47 +00:00
gun2 . shadowPlane = parent - > shadowPlane ;
gun2 . renderfx = parent - > renderfx ;
gun2 . shaderRGBA [ 0 ] = 255 ;
gun2 . shaderRGBA [ 1 ] = 255 ;
gun2 . shaderRGBA [ 2 ] = 255 ;
gun2 . shaderRGBA [ 3 ] = 255 ;
//Elder: We are in third person, use the third-person model (DEFAULT)
2002-06-16 20:06:15 +00:00
if ( ps = = NULL ) {
2003-02-05 04:44:47 +00:00
orientation_t tag ;
2003-04-06 23:20:18 +00:00
gun1 . hModel = weapon - > weaponModel ;
if ( weaponNum = = WP_AKIMBO & & trap_R_LerpTag ( & tag , parent - > hModel , 0 , 0 , 1 , " tag_weapon2 " ) )
gun2 . hModel = gun1 . hModel ;
2003-02-05 04:44:47 +00:00
}
//Elder: we are in first-person, use the first-person (NOT default) model
else {
gun1 . hModel = weapon - > firstModel ;
2001-05-06 20:50:27 +00:00
}
2001-11-11 20:03:09 +00:00
2003-02-05 04:44:47 +00:00
if ( ! gun1 . hModel ) {
2001-05-06 20:50:27 +00:00
return ;
}
2003-02-01 02:15:31 +00:00
// JBravo: activate the custom skin, if any
2003-02-05 04:44:47 +00:00
if ( weapon - > customSkin ) {
gun1 . customSkin = weapon - > customSkin ;
// NiceAss: Use on the second pistol for akimbo
if ( gun2 . hModel )
gun2 . customSkin = weapon - > customSkin ;
2003-02-01 02:15:31 +00:00
2001-05-06 20:50:27 +00:00
// add weapon ready sound
cent - > pe . lightningFiring = qfalse ;
2003-02-05 04:44:47 +00:00
if ( ( cent - > currentState . eFlags & EF_FIRING ) & & weapon - > firingSound ) {
2001-05-06 20:50:27 +00:00
// lightning gun and guantlet make a different sound when fire is held down
2003-02-05 04:44:47 +00:00
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin ,
weapon - > firingSound ) ;
2001-05-06 20:50:27 +00:00
cent - > pe . lightningFiring = qtrue ;
2003-02-05 04:44:47 +00:00
}
else if ( weapon - > readySound ) {
trap_S_AddLoopingSound ( cent - > currentState . number , cent - > lerpOrigin , vec3_origin ,
weapon - > readySound ) ;
2001-05-06 20:50:27 +00:00
}
}
2001-11-11 20:03:09 +00:00
2003-02-05 04:44:47 +00:00
if ( ! ps ) {
// Position the second pistol for akimbo if the model supports it
if ( gun2 . hModel )
CG_PositionEntityOnTag ( & gun2 , parent , parent - > hModel , " tag_weapon2 " ) ;
CG_PositionEntityOnTag ( & gun1 , parent , parent - > hModel , " tag_weapon " ) ;
}
else {
CG_WeaponAnimation ( cent , & gun1 . oldframe , & gun1 . frame , & gun1 . backlerp ) ;
CG_PositionWeaponOnTag ( & gun1 , parent , parent - > hModel , " tag_weapon " ) ;
2001-09-11 00:11:00 +00:00
// Elder: Local sound events will sync perfectly here
// However, we must remember to ignore the ones pmove will generate
// (for other clients to hear) or we'll get some nasty echo
// Temp hack because it isn't fully implemented
2002-06-16 20:06:15 +00:00
if ( weapon - > item - > giTag = = WP_PISTOL | |
weapon - > item - > giTag = = WP_AKIMBO | |
weapon - > item - > giTag = = WP_M4 | |
weapon - > item - > giTag = = WP_MP5 | |
weapon - > item - > giTag = = WP_M3 | |
weapon - > item - > giTag = = WP_HANDCANNON | |
weapon - > item - > giTag = = WP_SSG3000 | | weapon - > item - > giTag = = WP_GRENADE ) {
2001-10-11 22:50:58 +00:00
int i = 0 ;
qboolean noSound = qfalse ;
2001-11-25 23:17:41 +00:00
2003-02-05 04:44:47 +00:00
while ( gun1 . frame ! = weapon - > animationSounds - > sfxInfo [ i ] . frame ) {
2002-06-16 20:06:15 +00:00
if ( + + i = = weapon - > animationSounds - > numFrames ) {
2001-10-11 22:50:58 +00:00
noSound = qtrue ;
break ;
}
2001-09-11 00:11:00 +00:00
}
2001-10-11 22:50:58 +00:00
// reset the current sound
2003-02-05 04:44:47 +00:00
if ( cg . curSyncSound . played & & cg . curSyncSound . frame ! = gun1 . frame )
2001-10-11 22:50:58 +00:00
cg . curSyncSound . played = qfalse ;
2002-06-16 20:06:15 +00:00
if ( ! noSound ) {
2001-10-11 22:50:58 +00:00
// copy the struct to reset it
2003-02-05 04:44:47 +00:00
if ( cg . curSyncSound . frame ! = gun1 . frame )
2001-10-11 22:50:58 +00:00
cg . curSyncSound = weapon - > animationSounds - > sfxInfo [ i ] ;
2002-06-16 20:06:15 +00:00
if ( cg . curSyncSound . played = = qfalse ) {
2001-10-11 22:50:58 +00:00
cg . curSyncSound . played = qtrue ;
2002-06-16 20:06:15 +00:00
trap_S_StartLocalSound ( cg . curSyncSound . sound , CHAN_WEAPON ) ;
2001-09-11 00:11:00 +00:00
}
}
}
2001-11-11 20:03:09 +00:00
}
2001-05-06 20:50:27 +00:00
2001-08-30 09:42:25 +00:00
// Elder: break off here so we still have weapon animations on bolt out
2001-10-11 22:50:58 +00:00
// Elder: added ps so we see SSG in third-person zoomed
2003-02-05 04:44:47 +00:00
if ( cg . zoomed & & ps )
2001-08-30 09:42:25 +00:00
return ;
2003-02-05 04:44:47 +00:00
// JBravo: Adding a fix from NiceAss (cg_drawgun affecting other player models)
if ( ! cg_drawGun . integer & & ps )
2002-06-16 20:06:15 +00:00
return ;
2001-11-24 23:55:56 +00:00
2003-02-05 04:44:47 +00:00
trap_R_AddRefEntityToScene ( & gun1 ) ;
if ( gun2 . hModel )
trap_R_AddRefEntityToScene ( & gun2 ) ;
2001-05-06 20:50:27 +00:00
// make sure we aren't looking at cg.predictedPlayerEntity for LG
2003-02-05 04:44:47 +00:00
nonPredictedCent = & cg_entities [ cent - > currentState . clientNum ] ;
2001-05-06 20:50:27 +00:00
// if the index of the nonPredictedCent is not the same as the clientNum
// then this is a fake player (like on teh single player podiums), so
// go ahead and use the cent
2002-06-16 20:06:15 +00:00
if ( ( nonPredictedCent - cg_entities ) ! = cent - > currentState . clientNum ) {
2001-05-06 20:50:27 +00:00
nonPredictedCent = cent ;
}
2002-11-18 04:39:47 +00:00
2002-10-26 00:37:18 +00:00
if ( ps & & ( cg . snap - > ps . stats [ STAT_HOLDABLE_ITEM ] & ( 1 < < HI_SILENCER ) ) & &
2002-06-16 20:06:15 +00:00
( weaponNum = = WP_PISTOL | | weaponNum = = WP_MP5 | | weaponNum = = WP_SSG3000 ) ) {
2002-04-06 21:43:59 +00:00
//Makro - wasn't initialized, caused a warning in MSVC
2002-06-16 20:06:15 +00:00
vec3_t silencerEnd ;
float scale = 0.0f ;
vec3_t angles ;
if ( weaponNum = = WP_PISTOL )
scale = 1.2f ;
if ( weaponNum = = WP_SSG3000 )
scale = 2.5f ;
if ( weaponNum = = WP_MP5 )
scale = 1.3f ;
memset ( & silencer , 0 , sizeof ( silencer ) ) ;
2002-03-16 21:50:09 +00:00
silencer . hModel = cgs . media . rq3_silencerModel ;
silencer . shadowPlane = parent - > shadowPlane ;
silencer . renderfx = parent - > renderfx ;
angles [ YAW ] = 90 ;
angles [ PITCH ] = 0 ;
angles [ ROLL ] = 0 ;
2002-06-16 20:06:15 +00:00
AnglesToAxis ( angles , silencer . axis ) ;
2002-03-16 21:50:09 +00:00
2002-06-16 20:06:15 +00:00
VectorScale ( silencer . axis [ 0 ] , scale , silencer . axis [ 0 ] ) ;
VectorScale ( silencer . axis [ 1 ] , scale , silencer . axis [ 1 ] ) ;
VectorScale ( silencer . axis [ 2 ] , scale , silencer . axis [ 2 ] ) ;
2002-03-16 21:50:09 +00:00
2003-02-05 04:44:47 +00:00
CG_PositionRotatedOffsetEntityOnTag ( & silencer , & gun1 , weapon - > firstModel , " tag_silencer " , vec3_origin ) ;
2002-05-01 03:28:07 +00:00
// Offset weapon
2002-04-29 06:10:09 +00:00
VectorMA ( silencer . origin , - 7.2f , silencer . axis [ 1 ] , silencer . origin ) ;
2002-05-18 03:55:35 +00:00
VectorMA ( silencer . origin , 10.0f , silencer . axis [ 1 ] , silencerEnd ) ;
2002-05-29 03:52:21 +00:00
silencer . nonNormalizedAxes = qtrue ;
2002-04-29 06:10:09 +00:00
2003-02-05 04:44:47 +00:00
trap_R_AddRefEntityToScene ( & silencer ) ;
2002-05-18 03:55:35 +00:00
2003-02-05 04:44:47 +00:00
// NiceAss: Add a puff of smoke at the end of the silencer when fired.
2003-07-30 16:05:47 +00:00
//Makro - changed a bit, might look cooler
2002-08-25 03:34:11 +00:00
if ( cent - > muzzleFlashTime = = - 1 ) {
2003-07-30 16:05:47 +00:00
# define NUM_SILENCER_PUFFS 3
localEntity_t * smoke [ NUM_SILENCER_PUFFS ] ;
int i ;
2002-11-18 04:39:47 +00:00
vec3_t up ;
2002-05-18 03:55:35 +00:00
2002-08-25 03:34:11 +00:00
// Move the puff over to center on silencer end.
VectorMA ( silencerEnd , 5 , cg . refdef . viewaxis [ 1 ] , silencerEnd ) ;
VectorMA ( silencerEnd , 5 , cg . refdef . viewaxis [ 2 ] , silencerEnd ) ;
2002-05-18 03:55:35 +00:00
2003-07-30 16:05:47 +00:00
/*
2002-08-25 03:34:11 +00:00
VectorSet ( up , 0.0f , 0.0f , 15.0f ) ;
2003-02-05 04:44:47 +00:00
smoke = CG_SmokePuff ( silencerEnd , up , 0.5f , 1 , 1 , 1 , 0.5f , 300 , cg . time , 0 , 0 ,
2002-11-18 04:39:47 +00:00
cgs . media . shotgunSmokePuffShader ) ;
2002-08-25 03:34:11 +00:00
smoke - > leType = LE_SCALE_FADE ;
2003-07-30 16:05:47 +00:00
*/
//VectorSet(up, 0.0f, 45.0f, 0.0f);
for ( i = 0 ; i < NUM_SILENCER_PUFFS ; i + + )
{
VectorScale ( silencer . axis [ 1 ] , - ( 20 + random ( ) * 50 ) , up ) ;
2004-01-26 21:26:09 +00:00
smoke [ i ] = CG_SmokePuff ( silencerEnd , up , 0.2f , 1 , 1 , 1 , 0.25f + crandom ( ) * 0.1f , 200 + random ( ) * 200 , cg . time , 0 , 0 ,
2003-07-30 16:05:47 +00:00
cgs . media . shotgunSmokePuffShader ) ;
smoke [ i ] - > leType = LE_MOVE_SCALE_FADE ;
smoke [ i ] - > lifeRate = 0.75 / ( smoke [ i ] - > endTime - smoke [ i ] - > startTime ) ;
}
2002-05-18 03:55:35 +00:00
2002-08-25 03:34:11 +00:00
cent - > muzzleFlashTime = 0 ;
}
2002-03-16 21:50:09 +00:00
}
2001-12-17 15:06:41 +00:00
2002-10-26 00:37:18 +00:00
if ( ps & & ( cg . snap - > ps . stats [ STAT_HOLDABLE_ITEM ] & ( 1 < < HI_LASER ) ) & &
2002-06-16 20:06:15 +00:00
( weaponNum = = WP_PISTOL | | weaponNum = = WP_MP5 | | weaponNum = = WP_M4 ) ) {
float scale = 0.0f ;
vec3_t angles ;
2002-05-29 03:52:21 +00:00
2002-06-16 20:06:15 +00:00
if ( weaponNum = = WP_PISTOL )
scale = 0.66f ;
if ( weaponNum = = WP_MP5 )
scale = 0.675f ;
if ( weaponNum = = WP_M4 )
scale = 0.79f ;
2002-05-29 03:52:21 +00:00
2002-06-16 20:06:15 +00:00
memset ( & laser , 0 , sizeof ( laser ) ) ;
2002-05-29 03:52:21 +00:00
laser . hModel = cgs . media . rq3_laserModel ;
laser . shadowPlane = parent - > shadowPlane ;
laser . renderfx = parent - > renderfx ;
angles [ YAW ] = 90 ;
angles [ PITCH ] = 0 ;
angles [ ROLL ] = 0 ;
2002-06-16 20:06:15 +00:00
AnglesToAxis ( angles , laser . axis ) ;
2002-05-29 03:52:21 +00:00
2002-06-16 20:06:15 +00:00
VectorScale ( laser . axis [ 0 ] , scale , laser . axis [ 0 ] ) ;
VectorScale ( laser . axis [ 1 ] , scale , laser . axis [ 1 ] ) ;
VectorScale ( laser . axis [ 2 ] , scale , laser . axis [ 2 ] ) ;
2002-05-29 03:52:21 +00:00
2003-03-08 10:04:12 +00:00
CG_PositionRotatedEntityOnTag ( & laser , & gun1 , weapon - > firstModel , " tag_laser " ) ;
2002-05-29 03:52:21 +00:00
laser . nonNormalizedAxes = qtrue ;
2003-02-05 04:44:47 +00:00
trap_R_AddRefEntityToScene ( & laser ) ;
2002-05-29 03:52:21 +00:00
}
2003-02-05 04:44:47 +00:00
2002-07-08 04:41:12 +00:00
// NiceAss: fix for brass ejecting on LCA
if ( cg . lca )
cent - > ejectBrassTime = 0 ;
2002-03-11 02:22:45 +00:00
// NiceAss: Tag locations used for shell ejection
2002-03-24 22:46:23 +00:00
// The handcannon hacks have ruined my beautiful code =(
2002-06-16 20:06:15 +00:00
if ( cg . time > cent - > ejectBrassTime & & cent - > ejectBrassTime & & weapon - > ejectBrassFunc & &
( ps | | cg . renderingThirdPerson | | cent - > currentState . number ! = cg . predictedPlayerState . clientNum ) ) {
2002-12-02 19:52:05 +00:00
orientation_t tag ;
2002-03-16 21:50:09 +00:00
2002-06-16 20:06:15 +00:00
shell = weapon - > ejectBrassFunc ( cent ) ;
2002-03-16 21:50:09 +00:00
2003-02-05 04:44:47 +00:00
if ( shell ! = NULL & & trap_R_LerpTag ( & tag , gun1 . hModel , 0 , 0 , 1 , " tag_shell " ) ) {
2002-06-16 20:06:15 +00:00
float speed = 1.0f ;
int axis1 = 0 , axis2 = 0 ;
2002-04-07 02:10:42 +00:00
2003-02-05 04:44:47 +00:00
if ( ps ) {
2002-06-16 20:06:15 +00:00
if ( weapon - > item - > giTag = = WP_AKIMBO & & ! ps - > stats [ STAT_BURST ] )
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun1 , gun1 . hModel , " tag_shell2 " ) ;
2002-03-16 21:50:09 +00:00
else
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun1 , gun1 . hModel , " tag_shell " ) ;
}
else {
if ( weapon - > item - > giTag = = WP_AKIMBO & & ! cg . akimboFlash )
if ( gun2 . hModel & & trap_R_LerpTag ( & tag , gun2 . hModel , 0 , 0 , 1 , " tag_shell " ) )
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun2 , gun2 . hModel , " tag_shell " ) ;
else
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun1 , gun1 . hModel , " tag_shell2 " ) ;
2002-03-16 21:50:09 +00:00
else
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun1 , gun1 . hModel , " tag_shell " ) ;
2002-03-16 21:50:09 +00:00
}
2002-06-16 20:06:15 +00:00
VectorCopy ( shell - > refEntity . origin , shell - > pos . trBase ) ;
if ( trap_CM_PointContents ( shell - > pos . trBase , 0 ) = = CONTENTS_WATER )
speed = 0.5f ;
2002-03-16 21:50:09 +00:00
2002-05-18 03:55:35 +00:00
if ( weaponNum = = WP_HANDCANNON ) {
2002-06-16 20:06:15 +00:00
speed = - speed ; // horrible hacks
2002-06-11 21:50:51 +00:00
axis1 = 1 ;
2002-03-24 22:46:23 +00:00
}
2002-06-16 20:06:15 +00:00
vectoangles ( shell - > refEntity . axis [ axis1 ] , shell - > angles . trBase ) ;
VectorScale ( shell - > refEntity . axis [ axis2 ] , 160 * speed , shell - > pos . trDelta ) ;
VectorAdd ( shell - > pos . trDelta , cent - > currentState . pos . trDelta , shell - > pos . trDelta ) ;
2002-03-16 21:50:09 +00:00
}
2003-02-05 04:44:47 +00:00
2002-03-24 22:46:23 +00:00
// All this code for a SECOND shell on the HC
2003-02-05 04:44:47 +00:00
if ( weaponNum = = WP_HANDCANNON & & trap_R_LerpTag ( & tag , gun1 . hModel , 0 , 0 , 1 , " tag_shell2 " ) ) {
2002-06-16 20:06:15 +00:00
float speed = - 1.0f ;
shell = weapon - > ejectBrassFunc ( cent ) ;
2002-03-24 22:46:23 +00:00
if ( shell ! = NULL ) {
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & shell - > refEntity , & gun1 , gun1 . hModel , " tag_shell2 " ) ;
2002-06-16 20:06:15 +00:00
VectorCopy ( shell - > refEntity . origin , shell - > pos . trBase ) ;
2002-03-24 22:46:23 +00:00
2002-06-16 20:06:15 +00:00
if ( trap_CM_PointContents ( shell - > pos . trBase , 0 ) = = CONTENTS_WATER )
speed = - 0.5f ;
2002-03-24 22:46:23 +00:00
2002-06-16 20:06:15 +00:00
vectoangles ( shell - > refEntity . axis [ 1 ] , shell - > angles . trBase ) ;
VectorScale ( shell - > refEntity . axis [ 0 ] , 160 * speed , shell - > pos . trDelta ) ;
VectorAdd ( shell - > pos . trDelta , cent - > currentState . pos . trDelta , shell - > pos . trDelta ) ;
2002-03-24 22:46:23 +00:00
}
}
2002-03-16 21:50:09 +00:00
cent - > ejectBrassTime = 0 ;
2002-03-11 02:22:45 +00:00
}
2002-06-21 04:11:34 +00:00
2002-11-18 04:39:47 +00:00
if ( cent - > currentState . number ! = cg . predictedPlayerState . clientNum ) {
2002-06-21 04:11:34 +00:00
refEntity_t muzzle ;
2002-11-18 04:39:47 +00:00
2002-06-21 04:11:34 +00:00
memset ( & muzzle , 0 , sizeof ( muzzle ) ) ;
2003-02-05 04:44:47 +00:00
CG_PositionEntityOnTag ( & muzzle , & gun1 , weapon - > weaponModel , " tag_flash " ) ;
2002-11-18 04:39:47 +00:00
2002-06-23 04:36:27 +00:00
CG_DrawVisibleLaser ( muzzle . origin , cent - > currentState . clientNum , muzzle . axis [ 0 ] ) ;
2002-06-21 04:11:34 +00:00
}
2001-06-08 04:35:50 +00:00
//Elder: re-added to fix loss of muzzle flashes!
// impulse flash
2002-03-11 02:22:45 +00:00
2002-06-16 20:06:15 +00:00
if ( cg . time - cent - > muzzleFlashTime > MUZZLE_FLASH_TIME & & ! cent - > pe . railgunFlash ) {
2001-06-08 04:35:50 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
memset ( & flash , 0 , sizeof ( flash ) ) ;
2002-03-11 02:22:45 +00:00
2002-06-16 20:06:15 +00:00
VectorCopy ( parent - > lightingOrigin , flash . lightingOrigin ) ;
2001-05-06 20:50:27 +00:00
flash . shadowPlane = parent - > shadowPlane ;
flash . renderfx = parent - > renderfx ;
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
flash . hModel = weapon - > flashModel ;
if ( ! flash . hModel ) {
return ;
}
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
angles [ YAW ] = 0 ;
angles [ PITCH ] = 0 ;
angles [ ROLL ] = crandom ( ) * 10 ;
2002-06-16 20:06:15 +00:00
AnglesToAxis ( angles , flash . axis ) ;
2001-05-06 20:50:27 +00:00
2001-07-16 01:41:36 +00:00
//Elder: add conditional here so the dlight is still drawn when cg_RQ3_flash is 0
2002-03-11 02:22:45 +00:00
2002-06-16 20:06:15 +00:00
if ( cg_RQ3_flash . integer ) {
2001-06-08 04:35:50 +00:00
if ( ps ) {
2002-06-17 03:53:31 +00:00
float scale = 2.0f ;
2002-11-18 04:39:47 +00:00
if ( ps - > weapon = = WP_M4 )
scale = 1.5f ;
2002-06-17 03:53:31 +00:00
2001-08-30 09:42:25 +00:00
// Elder: draw flash based on first-person view
2002-06-16 20:06:15 +00:00
if ( ps - > weapon = = WP_AKIMBO ) {
2001-09-11 00:11:00 +00:00
// choose tag for akimbos
if ( ps - > stats [ STAT_BURST ] )
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > firstModel , " tag_flash " ) ;
2001-09-11 00:11:00 +00:00
else
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > firstModel , " tag_flash2 " ) ;
2002-06-16 20:06:15 +00:00
} else
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > firstModel , " tag_flash " ) ;
2001-09-11 00:11:00 +00:00
2001-08-30 09:42:25 +00:00
// Make flash larger to compensate for depth hack
2002-06-17 03:53:31 +00:00
VectorScale ( flash . axis [ 0 ] , scale , flash . axis [ 0 ] ) ;
VectorScale ( flash . axis [ 1 ] , scale , flash . axis [ 1 ] ) ;
VectorScale ( flash . axis [ 2 ] , scale , flash . axis [ 2 ] ) ;
2001-08-30 09:42:25 +00:00
flash . nonNormalizedAxes = qtrue ;
2003-02-05 04:44:47 +00:00
}
else {
2001-06-08 04:35:50 +00:00
//Elder: draw flash based on 3rd-person view
2002-06-16 20:06:15 +00:00
if ( weapon - > item - > giTag = = WP_AKIMBO ) {
2001-09-11 00:11:00 +00:00
// choose tag for akimbos
if ( cg . akimboFlash )
2003-02-05 04:44:47 +00:00
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > weaponModel , " tag_flash " ) ;
else {
if ( gun2 . hModel )
CG_PositionRotatedEntityOnTag ( & flash , & gun2 , weapon - > weaponModel , " tag_flash " ) ;
else
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > weaponModel , " tag_flash2 " ) ;
}
}
else
CG_PositionRotatedEntityOnTag ( & flash , & gun1 , weapon - > weaponModel , " tag_flash " ) ;
2001-06-08 04:35:50 +00:00
}
2002-06-16 20:06:15 +00:00
trap_R_AddRefEntityToScene ( & flash ) ;
} else {
2001-06-08 04:35:50 +00:00
//Elder: crappy way to get the dlight working w/o the flash model
2002-06-16 20:06:15 +00:00
if ( ps | | cg . renderingThirdPerson | | cent - > currentState . number ! = cg . predictedPlayerState . clientNum ) {
if ( weapon - > flashDlightColor [ 0 ] | | weapon - > flashDlightColor [ 1 ] | | weapon - > flashDlightColor [ 2 ] ) {
if ( ! cg_drawGun . value )
2003-02-05 04:44:47 +00:00
trap_R_AddLightToScene ( gun1 . origin , 300 + ( rand ( ) & 31 ) ,
2002-06-16 20:06:15 +00:00
weapon - > flashDlightColor [ 0 ] , weapon - > flashDlightColor [ 1 ] ,
weapon - > flashDlightColor [ 2 ] ) ;
2001-06-08 04:35:50 +00:00
}
}
return ;
}
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
if ( ps | | cg . renderingThirdPerson | | cent - > currentState . number ! = cg . predictedPlayerState . clientNum ) {
2001-05-06 20:50:27 +00:00
// add rail trail
2002-06-16 20:06:15 +00:00
if ( weapon - > flashDlightColor [ 0 ] | | weapon - > flashDlightColor [ 1 ] | | weapon - > flashDlightColor [ 2 ] ) {
trap_R_AddLightToScene ( flash . origin , 300 + ( rand ( ) & 31 ) , weapon - > flashDlightColor [ 0 ] ,
weapon - > flashDlightColor [ 1 ] , weapon - > flashDlightColor [ 2 ] ) ;
2001-05-06 20:50:27 +00:00
}
}
}
/*
= = = = = = = = = = = = = =
CG_AddViewWeapon
Add the weapon , and flash for the player ' s view
= = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_AddViewWeapon ( playerState_t * ps )
{
refEntity_t hand ;
centity_t * cent ;
float fovOffset ;
vec3_t angles ;
weaponInfo_t * weapon ;
2001-05-06 20:50:27 +00:00
//Blaze: Reaction vars for gun positions
2002-01-14 01:19:23 +00:00
//float rxn_gunx, rxn_guny, rxn_gunz;
2001-05-06 20:50:27 +00:00
2002-02-24 20:49:07 +00:00
//Slicer - Spect code for follow
2002-06-16 20:06:15 +00:00
if ( ps - > persistant [ PERS_TEAM ] = = TEAM_SPECTATOR & & ! ( ps - > pm_flags & PMF_FOLLOW ) ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( ps - > pm_type = = PM_INTERMISSION ) {
2001-05-06 20:50:27 +00:00
return ;
}
2001-08-01 21:07:48 +00:00
// no gun if in third person view or a camera is active
//if ( cg.renderingThirdPerson || cg.cameraMode) {
2002-06-16 20:06:15 +00:00
if ( cg . renderingThirdPerson ) {
2001-05-06 20:50:27 +00:00
return ;
}
// allow the gun to be completely removed
2001-08-17 20:38:54 +00:00
// Elder: don't draw if throwing
2001-11-24 23:55:56 +00:00
//Blaze: removed cg_drawGun checks and moved into other code.
2002-06-16 20:06:15 +00:00
if ( ( cg . snap - > ps . stats [ STAT_RQ3 ] & RQ3_THROWWEAPON ) = = RQ3_THROWWEAPON ) {
2001-05-06 20:50:27 +00:00
//Blaze: Removed these
2002-06-16 20:06:15 +00:00
if ( cg . predictedPlayerState . eFlags & EF_FIRING ) {
2001-12-17 15:06:41 +00:00
}
2001-05-06 20:50:27 +00:00
return ;
}
// don't draw if testing a gun model
2002-06-16 20:06:15 +00:00
if ( cg . testGun ) {
2001-05-06 20:50:27 +00:00
return ;
2001-11-11 20:03:09 +00:00
}
2001-05-06 20:50:27 +00:00
//Blaze end:
// drop gun lower at higher fov
2002-06-16 20:06:15 +00:00
if ( cg_fov . integer > 90 ) {
fovOffset = - 0.2 * ( cg_fov . integer - 90 ) ;
2001-05-06 20:50:27 +00:00
} else {
fovOffset = 0 ;
}
cent = & cg . predictedPlayerEntity ; // &cg_entities[cg.snap->ps.clientNum];
2002-06-16 20:06:15 +00:00
CG_RegisterWeapon ( ps - > weapon ) ;
weapon = & cg_weapons [ ps - > weapon ] ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
memset ( & hand , 0 , sizeof ( hand ) ) ;
2001-05-06 20:50:27 +00:00
// set up gun position
2002-06-16 20:06:15 +00:00
CG_CalculateWeaponPosition ( hand . origin , angles ) ;
2001-05-06 20:50:27 +00:00
//Blaze: Use above code instead
2001-06-08 04:35:50 +00:00
//Elder: reused so Cloud can adjust the models manually
2002-06-16 20:06:15 +00:00
VectorMA ( hand . origin , cg_gun_x . value , cg . refdef . viewaxis [ 0 ] , hand . origin ) ;
VectorMA ( hand . origin , cg_gun_y . value , cg . refdef . viewaxis [ 1 ] , hand . origin ) ;
VectorMA ( hand . origin , ( cg_gun_z . value + fovOffset ) , cg . refdef . viewaxis [ 2 ] , hand . origin ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
AnglesToAxis ( angles , hand . axis ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
// development tool
hand . frame = hand . oldframe = cg_gun_frame . integer ;
hand . backlerp = 0 ;
2001-07-28 12:32:54 +00:00
hand . hModel = weapon - > handsModel ;
2001-05-06 20:50:27 +00:00
hand . renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT ;
2005-02-15 16:33:39 +00:00
/*
hand . nonNormalizedAxes = qtrue ;
if ( cg_RQ3_leftHanded . integer )
{
VectorNegate ( hand . axis [ 1 ] , hand . axis [ 1 ] ) ;
}
*/
2001-05-06 20:50:27 +00:00
// add everything onto the hand
2002-06-16 20:06:15 +00:00
CG_AddPlayerWeapon ( & hand , ps , & cg . predictedPlayerEntity , ps - > persistant [ PERS_TEAM ] ) ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
WEAPON SELECTION
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = =
CG_DrawWeaponSelect
= = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_DrawWeaponSelect ( void )
{
2003-02-01 02:15:31 +00:00
int i , bits , count , x , y , w ;
2002-06-16 20:06:15 +00:00
char * name ;
float * color ;
2001-05-06 20:50:27 +00:00
// don't display if dead
2002-06-16 20:06:15 +00:00
if ( cg . predictedPlayerState . stats [ STAT_HEALTH ] < = 0 ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
color = CG_FadeColor ( cg . weaponSelectTime , WEAPON_SELECT_TIME ) ;
if ( ! color ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
trap_R_SetColor ( color ) ;
2001-05-06 20:50:27 +00:00
// showing weapon select clears pickup item display, but not the blend blob
cg . itemPickupTime = 0 ;
// count the number of weapons owned
2002-06-16 20:06:15 +00:00
bits = cg . snap - > ps . stats [ STAT_WEAPONS ] ;
2001-05-06 20:50:27 +00:00
count = 0 ;
2002-06-16 20:06:15 +00:00
for ( i = 1 ; i < 16 ; i + + ) {
if ( bits & ( 1 < < i ) ) {
2001-05-06 20:50:27 +00:00
count + + ;
}
}
x = 320 - count * 20 ;
y = 380 ;
2002-06-16 20:06:15 +00:00
for ( i = 1 ; i < 16 ; i + + ) {
if ( ! ( bits & ( 1 < < i ) ) ) {
2001-05-06 20:50:27 +00:00
continue ;
}
2002-06-16 20:06:15 +00:00
CG_RegisterWeapon ( i ) ;
2001-05-06 20:50:27 +00:00
// draw weapon icon
2002-06-16 20:06:15 +00:00
CG_DrawPic ( x , y , 32 , 32 , cg_weapons [ i ] . weaponIcon ) ;
2001-05-06 20:50:27 +00:00
// draw selection marker
2002-06-16 20:06:15 +00:00
if ( i = = cg . weaponSelect ) {
CG_DrawPic ( x - 4 , y - 4 , 40 , 40 , cgs . media . selectShader ) ;
2001-05-06 20:50:27 +00:00
}
// no ammo cross on top
x + = 40 ;
}
// draw the selected name
2002-06-16 20:06:15 +00:00
if ( cg_weapons [ cg . weaponSelect ] . item ) {
name = cg_weapons [ cg . weaponSelect ] . item - > pickup_name ;
if ( name ) {
w = CG_DrawStrlen ( name ) * BIGCHAR_WIDTH ;
x = ( SCREEN_WIDTH - w ) / 2 ;
2001-05-06 20:50:27 +00:00
CG_DrawBigStringColor ( x , y - 22 , name , color ) ;
}
}
2002-06-16 20:06:15 +00:00
trap_R_SetColor ( NULL ) ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = =
CG_WeaponSelectable
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static qboolean CG_WeaponSelectable ( int i )
{
2001-07-01 05:11:12 +00:00
//Elder: never switch to empty grenades/knives
2002-06-16 20:06:15 +00:00
if ( ! cg . snap - > ps . ammo [ i ] & & ( i = = WP_GRENADE | | i = = WP_KNIFE ) ) {
2001-05-06 20:50:27 +00:00
return qfalse ;
}
2001-07-01 05:11:12 +00:00
//Blaze: Check the amount of clips too for the weapon rotate code
//Elder: this won't work plus AQ2 lets you select empty weapons
2002-06-29 04:15:15 +00:00
// JBravo: lets not allow switching to weapons other than pistol or knife if the player has a case
if ( cg . snap - > ps . powerups [ PW_BLUEFLAG ] | | cg . snap - > ps . powerups [ PW_REDFLAG ] ) {
if ( i ! = WP_PISTOL & & i ! = WP_KNIFE )
return qfalse ;
}
2002-06-16 20:06:15 +00:00
if ( ! ( cg . snap - > ps . stats [ STAT_WEAPONS ] & ( 1 < < i ) ) ) {
2001-05-06 20:50:27 +00:00
return qfalse ;
}
return qtrue ;
}
/*
= = = = = = = = = = = = = = =
CG_NextWeapon_f
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_NextWeapon_f ( void )
{
2003-02-01 02:15:31 +00:00
int i , original ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( ! cg . snap ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . pm_flags & PMF_FOLLOW ) {
2001-05-06 20:50:27 +00:00
return ;
}
2001-07-01 05:11:12 +00:00
// if we are going into the intermission, don't do anything
2002-06-16 20:06:15 +00:00
if ( cg . intermissionStarted ) {
2001-07-01 05:11:12 +00:00
return ;
}
2001-06-08 04:35:50 +00:00
//Elder: added
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weaponstate = = WEAPON_BANDAGING ) {
2001-06-18 00:40:38 +00:00
CG_Printf ( " You are too busy bandaging... \n " ) ;
return ;
}
2001-07-24 01:49:02 +00:00
//Elder: don't allow weapon switching when in the middle of bursts
if ( cg . snap - > ps . stats [ STAT_BURST ] > 0 )
return ;
2001-06-24 02:07:17 +00:00
//Elder: in the middle of firing, reloading or weapon-switching
2001-05-06 20:50:27 +00:00
cg . weaponSelectTime = cg . time ;
original = cg . weaponSelect ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 16 ; i + + ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect + + ;
2002-06-16 20:06:15 +00:00
if ( cg . weaponSelect = = 16 ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect = 0 ;
}
2002-06-16 20:06:15 +00:00
if ( CG_WeaponSelectable ( cg . weaponSelect ) ) {
2001-05-06 20:50:27 +00:00
break ;
}
}
2002-06-16 20:06:15 +00:00
if ( i = = 16 ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect = original ;
}
2002-03-13 18:41:18 +00:00
//Slicer: Done Server Side
2001-07-01 05:11:12 +00:00
else {
2002-05-01 17:46:00 +00:00
//Slicer lets call unzoom for SSG only
2002-06-16 20:06:15 +00:00
if ( original = = WP_SSG3000 )
2002-05-01 17:46:00 +00:00
trap_SendClientCommand ( " unzoom " ) ;
2001-07-01 05:11:12 +00:00
}
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = =
CG_PrevWeapon_f
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_PrevWeapon_f ( void )
{
2003-02-01 02:15:31 +00:00
int i , original ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
if ( ! cg . snap ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . pm_flags & PMF_FOLLOW ) {
2001-05-06 20:50:27 +00:00
return ;
}
2001-07-01 05:11:12 +00:00
// if we are going into the intermission, don't do anything
2002-06-16 20:06:15 +00:00
if ( cg . intermissionStarted ) {
2001-07-01 05:11:12 +00:00
return ;
}
2001-06-08 04:35:50 +00:00
//Elder: added
2002-03-18 19:19:08 +00:00
// if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weaponstate = = WEAPON_BANDAGING ) {
2001-06-18 00:40:38 +00:00
CG_Printf ( " You are too busy bandaging... \n " ) ;
return ;
}
2001-07-24 01:49:02 +00:00
//Elder: don't allow weapon switching when in the middle of bursts
if ( cg . snap - > ps . stats [ STAT_BURST ] > 0 )
return ;
2001-06-24 02:07:17 +00:00
//Elder: in the middle of firing, reloading or weapon-switching
2001-05-06 20:50:27 +00:00
cg . weaponSelectTime = cg . time ;
original = cg . weaponSelect ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 16 ; i + + ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect - - ;
2002-06-16 20:06:15 +00:00
if ( cg . weaponSelect = = - 1 ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect = 15 ;
}
2002-06-16 20:06:15 +00:00
if ( CG_WeaponSelectable ( cg . weaponSelect ) ) {
2001-05-06 20:50:27 +00:00
break ;
}
}
2002-06-16 20:06:15 +00:00
if ( i = = 16 ) {
2001-05-06 20:50:27 +00:00
cg . weaponSelect = original ;
2002-06-16 20:06:15 +00:00
} else {
2002-03-13 18:41:18 +00:00
//Slicer: Done Server Side
2002-05-01 17:46:00 +00:00
//Slicer lets call unzoom for SSG only
2002-06-16 20:06:15 +00:00
if ( original = = WP_SSG3000 )
2002-05-01 17:46:00 +00:00
trap_SendClientCommand ( " unzoom " ) ;
2001-07-01 05:11:12 +00:00
}
2001-05-06 20:50:27 +00:00
}
2001-07-01 05:11:12 +00:00
/*
= = = = = = = = = = = = = = =
Added by Elder
2001-11-11 20:03:09 +00:00
2001-07-01 05:11:12 +00:00
CG_SpecialWeapon_f
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_SpecialWeapon_f ( void )
{
2003-02-01 02:15:31 +00:00
int i , original ;
2001-07-01 05:11:12 +00:00
2002-06-16 20:06:15 +00:00
if ( ! cg . snap ) {
2001-07-24 01:49:02 +00:00
//CG_Printf("No snapshot: normally exiting\n");
2001-07-01 05:11:12 +00:00
return ;
}
2001-07-24 01:49:02 +00:00
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . pm_flags & PMF_FOLLOW ) {
2001-07-01 05:11:12 +00:00
return ;
}
// if we are going into the intermission, don't do anything
2002-06-16 20:06:15 +00:00
if ( cg . intermissionStarted ) {
2001-07-01 05:11:12 +00:00
return ;
}
//Elder: added
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weaponstate = = WEAPON_BANDAGING ) {
2001-07-01 05:11:12 +00:00
CG_Printf ( " You are too busy bandaging... \n " ) ;
return ;
}
2001-07-24 01:49:02 +00:00
//Elder: don't allow weapon switching when in the middle of bursts
if ( cg . snap - > ps . stats [ STAT_BURST ] > 0 )
return ;
2001-07-01 05:11:12 +00:00
2002-06-29 04:15:15 +00:00
// JBravo: not in CTF
if ( cg . snap - > ps . powerups [ PW_BLUEFLAG ] | | cg . snap - > ps . powerups [ PW_REDFLAG ] )
return ;
2001-07-01 05:11:12 +00:00
//Elder: in the middle of firing, reloading or weapon-switching
cg . weaponSelectTime = cg . time ;
original = cg . weaponSelect ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < 16 ; i + + ) {
2001-07-01 05:11:12 +00:00
cg . weaponSelect + + ;
2002-06-16 20:06:15 +00:00
if ( cg . weaponSelect = = 16 ) {
2001-07-01 05:11:12 +00:00
cg . weaponSelect = 0 ;
}
//Skip normal weapons
switch ( cg . weaponSelect ) {
2002-06-16 20:06:15 +00:00
case WP_PISTOL :
case WP_AKIMBO :
case WP_KNIFE :
case WP_GRENADE :
continue ;
break ;
2001-07-01 05:11:12 +00:00
}
2002-06-16 20:06:15 +00:00
if ( CG_WeaponSelectable ( cg . weaponSelect ) ) {
2001-07-01 05:11:12 +00:00
break ;
}
}
2001-08-30 09:42:25 +00:00
// FIXME: 15 because of the stupid continue I used
2002-06-16 20:06:15 +00:00
if ( i > = 15 ) {
2001-07-01 05:11:12 +00:00
cg . weaponSelect = original ;
2002-06-16 20:06:15 +00:00
} else {
2002-03-13 18:41:18 +00:00
//Slicer: Done Server Side
2002-05-01 17:46:00 +00:00
//Slicer lets call unzoom for SSG only
2002-06-16 20:06:15 +00:00
if ( original = = WP_SSG3000 )
2002-05-01 17:46:00 +00:00
trap_SendClientCommand ( " unzoom " ) ;
2001-07-01 05:11:12 +00:00
}
}
2001-06-18 00:40:38 +00:00
//Elder: for returning to the zoom state in ps stats
2002-06-16 20:06:15 +00:00
void CG_RQ3_SyncZoom ( void )
{
if ( ( cg . snap - > ps . stats [ STAT_RQ3 ] & RQ3_ZOOM_LOW ) = = RQ3_ZOOM_LOW & &
( cg . snap - > ps . stats [ STAT_RQ3 ] & RQ3_ZOOM_MED ) = = RQ3_ZOOM_MED ) {
cg . zoomLevel = RQ3_ZOOM_LOW | RQ3_ZOOM_MED ;
} else if ( ( cg . snap - > ps . stats [ STAT_RQ3 ] & RQ3_ZOOM_LOW ) = = RQ3_ZOOM_LOW ) {
2001-07-16 01:41:36 +00:00
cg . zoomLevel = RQ3_ZOOM_LOW ;
2002-06-16 20:06:15 +00:00
} else if ( ( cg . snap - > ps . stats [ STAT_RQ3 ] & RQ3_ZOOM_MED ) = = RQ3_ZOOM_MED ) {
2001-07-16 01:41:36 +00:00
cg . zoomLevel = RQ3_ZOOM_MED ;
2002-06-16 20:06:15 +00:00
} else {
2001-07-16 01:41:36 +00:00
cg . zoomLevel = 0 ;
}
}
//Elder: save zoom level and do any other necessary housekeeping
2002-06-16 20:06:15 +00:00
void CG_RQ3_SaveZoomLevel ( )
{
2001-07-16 01:41:36 +00:00
cg . lastZoomLevel = cg . zoomLevel ;
2001-06-18 00:40:38 +00:00
}
2001-07-16 01:41:36 +00:00
//Elder: This should identical to the portion inside
//the weapon function in g_cmds.c
2003-04-13 21:58:00 +00:00
/*void CG_RQ3_Zoom(void)
2002-06-16 20:06:15 +00:00
{
2001-06-08 04:35:50 +00:00
//Elder: reworked SSG zoom
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weapon = = WP_SSG3000 ) {
2001-07-16 01:41:36 +00:00
CG_RQ3_SaveZoomLevel ( ) ;
2002-06-16 20:06:15 +00:00
if ( ( cg . zoomLevel & RQ3_ZOOM_LOW ) = = RQ3_ZOOM_LOW & & ( cg . zoomLevel & RQ3_ZOOM_MED ) = = RQ3_ZOOM_MED ) {
2001-07-16 01:41:36 +00:00
//Elder: zoom 1x
cg . zoomLevel & = ~ RQ3_ZOOM_LOW ;
cg . zoomLevel & = ~ RQ3_ZOOM_MED ;
2002-06-16 20:06:15 +00:00
} else if ( ( cg . zoomLevel & RQ3_ZOOM_MED ) = = RQ3_ZOOM_MED ) {
2001-07-16 01:41:36 +00:00
//Elder: zoom 6x
cg . zoomLevel | = RQ3_ZOOM_LOW ;
2002-06-16 20:06:15 +00:00
} else if ( ( cg . zoomLevel & RQ3_ZOOM_LOW ) = = RQ3_ZOOM_LOW ) {
2001-07-16 01:41:36 +00:00
//Elder: zoom 4x
cg . zoomLevel | = RQ3_ZOOM_MED ;
cg . zoomLevel & = ~ RQ3_ZOOM_LOW ;
2002-06-16 20:06:15 +00:00
} else {
2001-07-16 01:41:36 +00:00
//Elder: zoom 2x
cg . zoomLevel | = RQ3_ZOOM_LOW ;
}
2001-11-11 20:03:09 +00:00
2001-07-16 01:41:36 +00:00
cg . zoomTime = cg . time ;
}
}
2003-04-13 21:58:00 +00:00
*/
/*//Elder: reset locally and send server message
2002-06-16 20:06:15 +00:00
void CG_RQ3_Zoom1x ( )
{
if ( cg_RQ3_ssgZoomAssist . integer ) {
2001-07-16 01:41:36 +00:00
cg . lastZoomLevel = cg . zoomLevel ;
cg . zoomLevel = 0 ;
cg . zoomTime = cg . time ;
2001-06-18 00:40:38 +00:00
}
2001-07-16 01:41:36 +00:00
}
2003-04-13 21:58:00 +00:00
*/
2001-07-16 01:41:36 +00:00
int CG_RQ3_GetGrenadeMode ( )
{
int grenMode = 0 ;
2002-06-16 20:06:15 +00:00
if ( ( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENSHORT ) = = RQ3_GRENSHORT )
2001-07-16 01:41:36 +00:00
grenMode | = RQ3_GRENSHORT ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
if ( ( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENMED ) = = RQ3_GRENMED )
2001-07-16 01:41:36 +00:00
grenMode | = RQ3_GRENMED ;
2001-05-06 20:50:27 +00:00
2001-07-16 01:41:36 +00:00
return grenMode ;
2001-05-06 20:50:27 +00:00
}
2001-07-16 01:41:36 +00:00
//Print grenade mode message
void CG_RQ3_GrenadeMode ( )
{
//Print a message for the next mode in line
2002-06-16 20:06:15 +00:00
if ( ( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENSHORT ) = = RQ3_GRENSHORT & &
( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENMED ) = = RQ3_GRENMED ) {
2001-07-16 01:41:36 +00:00
CG_Printf ( " Prepared to make a short range throw \n " ) ;
2002-06-16 20:06:15 +00:00
} else if ( ( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENSHORT ) = = RQ3_GRENSHORT ) {
2001-07-16 01:41:36 +00:00
CG_Printf ( " Prepared to make a medium range throw \n " ) ;
2002-06-16 20:06:15 +00:00
} else if ( ( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_GRENMED ) = = RQ3_GRENMED ) {
2001-07-16 01:41:36 +00:00
CG_Printf ( " Prepared to make a long range throw \n " ) ;
}
}
2001-05-06 20:50:27 +00:00
/*
= = = = = = = = = = = = = = =
CG_Weapon_f
2001-06-08 04:35:50 +00:00
Elder : does local stuff , then proceeds to server
Used with Q3 ' s internal weapon switching " e.g. weapon 10 "
2001-05-06 20:50:27 +00:00
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_Weapon_f ( void )
{
2001-06-08 04:35:50 +00:00
int num ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
if ( ! cg . snap ) {
2001-07-24 01:49:02 +00:00
//CG_Printf("No snapshot: normally exiting\n");
2001-05-06 20:50:27 +00:00
return ;
}
2009-07-01 18:19:44 +00:00
///Elder: spectator?
if ( cg . snap - > ps . pm_flags & PMF_FOLLOW ) {
return ;
}
//JBravo: Not dead
if ( cg . snap - > ps . stats [ STAT_HEALTH ] < 0 ) {
return ;
}
2001-06-26 01:58:02 +00:00
// if we are going into the intermission, don't do anything
2002-06-16 20:06:15 +00:00
if ( cg . intermissionStarted ) {
2001-06-26 01:58:02 +00:00
return ;
}
2001-06-08 04:35:50 +00:00
// Hawkins (give 'weapon' dual meaning)
2002-06-16 20:06:15 +00:00
if ( trap_Argc ( ) = = 1 ) {
2001-06-08 04:35:50 +00:00
if ( cg . snap - > ps . weapon = = WP_SSG3000 ) {
2002-06-16 20:06:15 +00:00
//Slicer : had to comment this, it caused a bug on the zooming, and it really didn't make much sense for lagged players
2002-11-18 04:39:47 +00:00
}
2001-06-18 00:40:38 +00:00
trap_SendClientCommand ( " weapon " ) ;
2001-11-11 20:03:09 +00:00
2001-07-24 01:49:02 +00:00
//Elder: added to get out of function at this point
return ;
2001-06-08 04:35:50 +00:00
}
2002-04-01 22:23:38 +00:00
//Elder: added to prevent weapon switching while bandaging
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weaponstate = = WEAPON_BANDAGING ) {
2002-04-01 22:23:38 +00:00
CG_Printf ( " You are too busy bandaging... \n " ) ;
return ;
}
//Elder: don't allow weapon switching when in the middle of bursts
if ( cg . snap - > ps . stats [ STAT_BURST ] > 0 )
return ;
2002-06-16 20:06:15 +00:00
num = atoi ( CG_Argv ( 1 ) ) ;
2002-04-01 22:23:38 +00:00
2002-06-16 20:06:15 +00:00
if ( num < 1 | | num > 15 ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-29 04:15:15 +00:00
// JBravo: CTB provisions
if ( cg . snap - > ps . powerups [ PW_BLUEFLAG ] | | cg . snap - > ps . powerups [ PW_REDFLAG ] ) {
if ( num ! = WP_PISTOL & & num ! = WP_KNIFE )
return ;
}
2001-06-08 04:35:50 +00:00
//Elder: this point on is the regular Q3 weapon function - weird
2001-11-11 20:03:09 +00:00
2001-05-06 20:50:27 +00:00
cg . weaponSelectTime = cg . time ;
2002-06-16 20:06:15 +00:00
if ( ! ( cg . snap - > ps . stats [ STAT_WEAPONS ] & ( 1 < < num ) ) ) {
2001-05-06 20:50:27 +00:00
return ; // don't have the weapon
}
2001-06-08 04:35:50 +00:00
//Elder: If re-selecting SSG - leave function
2002-06-16 20:06:15 +00:00
if ( ( 1 < < num ) = = ( 1 < < WP_SSG3000 ) & & cg . snap - > ps . weapon = = WP_SSG3000 ) {
2001-06-08 04:35:50 +00:00
return ;
}
2002-03-13 18:41:18 +00:00
//Slicer : Done Server Side
2002-05-01 17:46:00 +00:00
//Slicer lets call unzoom for SSG only
2002-06-16 20:06:15 +00:00
if ( cg . weaponSelect = = WP_SSG3000 )
2002-05-01 17:46:00 +00:00
trap_SendClientCommand ( " unzoom " ) ;
2001-05-06 20:50:27 +00:00
cg . weaponSelect = num ;
}
/*
= = = = = = = = = = = = = = = = = = =
CG_OutOfAmmoChange
The current weapon has just run out of ammo
= = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_OutOfAmmoChange ( void )
{
2001-06-26 01:58:02 +00:00
if ( ! cg . snap )
return ;
//Select the pistol when we run out of grenades or knives
if ( cg . snap - > ps . weapon = = WP_KNIFE | | cg . snap - > ps . weapon = = WP_GRENADE ) {
cg . weaponSelectTime = cg . time ;
cg . weaponSelect = WP_PISTOL ;
}
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
WEAPON EVENTS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
CG_FireWeapon
Caused by an EV_FIRE_WEAPON event
= = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_FireWeapon ( centity_t * cent , int weapModification )
{
2001-05-06 20:50:27 +00:00
entityState_t * ent ;
2002-06-16 20:06:15 +00:00
int c , i ;
weaponInfo_t * weap ;
2002-05-18 03:55:35 +00:00
2001-05-06 20:50:27 +00:00
ent = & cent - > currentState ;
2002-06-16 20:06:15 +00:00
if ( ent - > weapon = = WP_NONE ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( ent - > weapon > = WP_NUM_WEAPONS ) {
CG_Error ( " CG_FireWeapon: ent->weapon >= WP_NUM_WEAPONS " ) ;
2001-05-06 20:50:27 +00:00
return ;
}
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
weap = & cg_weapons [ ent - > weapon ] ;
2001-05-06 20:50:27 +00:00
2001-07-24 01:49:02 +00:00
//Elder: added to supress burst mode flashes + sounds when 'predicting'
// M4
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weapon = = WP_M4 & &
( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_M4MODE ) = = RQ3_M4MODE & &
2002-09-08 23:23:49 +00:00
cg . snap - > ps . stats [ STAT_BURST ] > 2 & & cg_RQ3_predictWeapons . integer = = 1 ) {
2001-07-24 01:49:02 +00:00
return ;
}
// MP5
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weapon = = WP_MP5 & &
( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_MP5MODE ) = = RQ3_MP5MODE & &
2002-09-08 23:23:49 +00:00
cg . snap - > ps . stats [ STAT_BURST ] > 2 & & cg_RQ3_predictWeapons . integer = = 1 ) {
2001-07-24 01:49:02 +00:00
return ;
}
// MK23
2002-06-16 20:06:15 +00:00
if ( cg . snap - > ps . weapon = = WP_PISTOL & &
( cg . snap - > ps . persistant [ PERS_WEAPONMODES ] & RQ3_MK23MODE ) = = RQ3_MK23MODE & &
2002-09-08 23:23:49 +00:00
cg . snap - > ps . stats [ STAT_BURST ] > 0 & & cg_RQ3_predictWeapons . integer = = 1 ) {
2001-07-24 01:49:02 +00:00
return ;
}
2001-12-17 15:06:41 +00:00
// KNIFE
2002-03-11 02:22:45 +00:00
// NiceAss: This is if the knife slash is not the first (2,3,4,5)
2001-12-17 15:06:41 +00:00
if ( weapModification = = RQ3_WPMOD_KNIFENOMARK ) {
return ;
}
2002-03-11 02:22:45 +00:00
// NiceAss:
2002-03-16 21:50:09 +00:00
if ( ent - > weapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
cent - > ejectBrassTime = cg . time + 500 ;
2002-03-16 21:50:09 +00:00
else if ( ent - > weapon = = WP_SSG3000 )
2002-06-16 20:06:15 +00:00
cent - > ejectBrassTime = cg . time + 650 ;
2002-03-24 22:46:23 +00:00
else if ( ent - > weapon ! = WP_KNIFE & & ent - > weapon ! = WP_GRENADE & & ent - > weapon ! = WP_HANDCANNON )
2002-03-16 21:50:09 +00:00
cent - > ejectBrassTime = cg . time ;
2001-05-06 20:50:27 +00:00
// mark the entity as muzzle flashing, so when it is added it will
// append the flash to the weapon model
2001-07-28 14:12:11 +00:00
if ( weapModification ! = RQ3_WPMOD_SILENCER )
cent - > muzzleFlashTime = cg . time ;
2002-05-18 03:55:35 +00:00
else
cent - > muzzleFlashTime = - 1 ;
2001-09-01 16:15:01 +00:00
// Elder: choose alternate muzzle flashes for 3rd-person views
if ( ent - > weapon = = WP_AKIMBO ) {
if ( cg . akimboFlash ) {
cg . akimboFlash = 0 ;
} else {
cg . akimboFlash = 1 ;
}
}
2001-05-06 20:50:27 +00:00
2001-07-28 14:12:11 +00:00
//Elder: silencer stuff
2002-06-16 20:06:15 +00:00
if ( weapModification = = RQ3_WPMOD_SILENCER ) {
trap_S_StartSound ( NULL , ent - > number , CHAN_WEAPON , cgs . media . silencerSound ) ;
} else // if (cg.snap->ps.weapon != WP_KNIFE)
2001-07-28 14:12:11 +00:00
{
2001-07-27 00:21:23 +00:00
// play a sound
2002-06-16 20:06:15 +00:00
for ( c = 0 ; c < 4 ; c + + ) {
if ( ! weap - > flashSound [ c ] ) {
2001-07-27 00:21:23 +00:00
break ;
}
2001-05-06 20:50:27 +00:00
}
2001-07-27 00:21:23 +00:00
2002-06-16 20:06:15 +00:00
if ( c > 0 ) {
2001-07-27 00:21:23 +00:00
c = rand ( ) % c ;
2002-06-16 20:06:15 +00:00
if ( weap - > flashSound [ c ] ) {
trap_S_StartSound ( NULL , ent - > number , CHAN_WEAPON , weap - > flashSound [ c ] ) ;
2001-07-27 00:21:23 +00:00
}
2001-05-06 20:50:27 +00:00
}
2001-07-28 14:12:11 +00:00
}
2001-09-11 00:11:00 +00:00
// View kicks -- note this doesn't affect aim which is handled on the server-side
// even though it probably should
2002-06-16 20:06:15 +00:00
if ( ent - > clientNum = = cg . snap - > ps . clientNum ) {
2001-09-11 00:11:00 +00:00
vec3_t forward ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
switch ( cg . snap - > ps . weapon ) {
case WP_KNIFE :
AngleVectors ( cg . predictedPlayerState . viewangles , forward , NULL , NULL ) ;
VectorScale ( forward , - 2 , cg . kick_origin ) ;
cg . kick_angles [ 0 ] = - 2 ;
cg . kick_time = cg . time ;
cg . kick_duration = 200 ;
break ;
case WP_PISTOL :
for ( i = 0 ; i < 3 ; i + + ) {
cg . kick_origin [ i ] = crandom ( ) * 0.35f ;
cg . kick_angles [ i ] = crandom ( ) * 0.7f ;
}
cg . kick_origin [ 0 ] = crandom ( ) * 0.35f ;
cg . kick_time = cg . time ;
break ;
case WP_M3 :
AngleVectors ( cg . predictedPlayerState . viewangles , forward , NULL , NULL ) ;
VectorScale ( forward , - 2 , cg . kick_origin ) ;
cg . kick_angles [ 0 ] = - 2 ;
cg . kick_time = cg . time ;
break ;
case WP_M4 :
for ( i = 0 ; i < 3 ; i + + ) {
cg . kick_origin [ i ] = crandom ( ) * 0.25f ;
cg . kick_angles [ i ] = crandom ( ) * 0.5f ;
}
cg . kick_origin [ 0 ] = crandom ( ) * 0.35f ;
cg . kick_time = cg . time ;
break ;
case WP_MP5 :
for ( i = 0 ; i < 3 ; i + + ) {
cg . kick_origin [ i ] = crandom ( ) * 0.25f ;
cg . kick_angles [ i ] = crandom ( ) * 0.5f ;
}
cg . kick_origin [ 0 ] = crandom ( ) * 0.35f ;
cg . kick_time = cg . time ;
break ;
case WP_HANDCANNON :
AngleVectors ( cg . predictedPlayerState . viewangles , forward , NULL , NULL ) ;
VectorScale ( forward , - 2 , cg . kick_origin ) ;
cg . kick_angles [ 0 ] = - 2 ;
cg . kick_time = cg . time ;
break ;
case WP_AKIMBO :
for ( i = 0 ; i < 3 ; i + + ) {
cg . kick_origin [ i ] = crandom ( ) * 0.25f ;
cg . kick_angles [ i ] = crandom ( ) * 0.5f ;
}
cg . kick_origin [ 0 ] = crandom ( ) * 0.35f ;
cg . kick_time = cg . time ;
break ;
2001-09-11 00:11:00 +00:00
}
}
2003-03-09 21:30:39 +00:00
// JBravo: unlagged
2003-03-28 10:36:03 +00:00
//CG_PredictWeaponEffects(cent);
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = =
CG_MissileHitWall
Caused by an EV_MISSILE_MISS event , or directly by local bullet tracing
= = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_MissileHitWall ( int weapon , int clientNum , vec3_t origin ,
vec3_t dir , impactSound_t soundType , int weapModification )
{
2003-02-01 02:15:31 +00:00
qhandle_t mod , mark , shader ;
2002-06-16 20:06:15 +00:00
sfxHandle_t sfx ;
2003-02-01 02:15:31 +00:00
float radius , light ;
2004-01-26 21:26:09 +00:00
vec3_t lightColor , puffDir , velocity ;
2003-02-01 02:15:31 +00:00
localEntity_t * le , * smokePuff ;
int r , duration , angle , contentType , sparkCount , i ;
qboolean alphaFade , isSprite ;
2001-05-06 20:50:27 +00:00
mark = 0 ;
radius = 32 ;
sfx = 0 ;
mod = 0 ;
shader = 0 ;
light = 0 ;
lightColor [ 0 ] = 1 ;
lightColor [ 1 ] = 1 ;
lightColor [ 2 ] = 0 ;
// set defaults
isSprite = qfalse ;
duration = 600 ;
2002-06-16 20:06:15 +00:00
switch ( weapon ) {
2001-11-12 08:59:46 +00:00
// Elder: bullet weapons all fall under MK23 >:(
2002-06-16 20:06:15 +00:00
case WP_M4 :
case WP_MP5 :
case WP_PISTOL :
case WP_AKIMBO :
case WP_SSG3000 :
duration = 160 ;
mod = cgs . media . hitSparkModel ;
shader = cgs . media . hitSparkShader ;
radius = 8 ;
r = rand ( ) & 3 ;
if ( soundType = = IMPACTSOUND_METAL ) {
mark = cgs . media . metalMarkShader ;
if ( r < 2 )
sfx = cgs . media . sfx_metalric1 ;
else if ( r = = 2 )
sfx = cgs . media . sfx_metalric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_metalric3 ;
} else if ( soundType = = IMPACTSOUND_GLASS ) {
mark = cgs . media . glassMarkShader ;
if ( r < 2 )
sfx = cgs . media . sfx_glassric1 ;
else if ( r = = 2 )
sfx = cgs . media . sfx_glassric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_glassric3 ;
}
//Makro - added
else if ( soundType = = IMPACTSOUND_BRICK ) {
mark = cgs . media . bulletMarkShader ;
if ( r < 2 )
sfx = cgs . media . sfx_brickric1 ;
else if ( r = = 2 )
sfx = cgs . media . sfx_brickric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_brickric3 ;
}
//Makro - added
else if ( soundType = = IMPACTSOUND_WOOD ) {
mark = cgs . media . bulletMarkShader ;
if ( r < 2 )
sfx = cgs . media . sfx_woodric1 ;
else if ( r = = 2 )
sfx = cgs . media . sfx_woodric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_woodric3 ;
}
//Makro - added
else if ( soundType = = IMPACTSOUND_CERAMIC ) {
mark = cgs . media . bulletMarkShader ;
if ( r < 2 )
sfx = cgs . media . sfx_ceramicric1 ;
else if ( r = = 2 )
sfx = cgs . media . sfx_ceramicric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_ceramicric3 ;
2003-07-30 16:05:47 +00:00
}
//Makro - added
else if ( soundType = = IMPACTSOUND_SNOW ) {
radius = 3 ;
mark = cgs . media . snowMarkShader ;
sfx = cgs . media . footsteps [ FOOTSTEP_SNOW2 ] [ rand ( ) % 4 ] ;
2002-06-16 20:06:15 +00:00
} else {
mark = cgs . media . bulletMarkShader ;
if ( r = = 0 )
sfx = cgs . media . sfx_ric1 ;
else if ( r = = 1 )
sfx = cgs . media . sfx_ric2 ;
2001-10-30 23:23:04 +00:00
else
2002-06-16 20:06:15 +00:00
sfx = cgs . media . sfx_ric3 ;
}
break ;
2001-08-30 09:42:25 +00:00
2002-06-16 20:06:15 +00:00
case WP_M3 :
case WP_HANDCANNON :
duration = 200 ;
mod = cgs . media . hitSparkModel ;
shader = cgs . media . hitSparkShader ;
2003-07-30 16:05:47 +00:00
sfx = 0 ;
radius = 4 ;
2002-06-16 20:06:15 +00:00
if ( soundType = = IMPACTSOUND_GLASS )
mark = cgs . media . glassMarkShader ;
else if ( soundType = = IMPACTSOUND_METAL )
mark = cgs . media . metalMarkShader ;
2002-07-13 22:43:59 +00:00
//Makro - added
2003-07-30 16:05:47 +00:00
else if ( soundType = = IMPACTSOUND_SNOW ) {
mark = cgs . media . snowMarkShader ;
radius = 2 ;
} else
2002-06-16 20:06:15 +00:00
mark = cgs . media . bulletMarkShader ;
break ;
case WP_GRENADE :
mod = cgs . media . dishFlashModel ;
shader = cgs . media . grenadeExplosionShader ;
sfx = cgs . media . sfx_rockexp ;
mark = cgs . media . burnMarkShader ;
radius = 96 ; //64
light = 350 ; //300
isSprite = qtrue ;
break ;
case WP_KNIFE :
if ( weapModification = = RQ3_WPMOD_KNIFESLASH ) {
duration = 100 ;
2001-11-12 08:59:46 +00:00
mod = cgs . media . hitSparkModel ;
shader = cgs . media . hitSparkShader ;
2003-07-30 16:05:47 +00:00
//Makro - added for snow/grass
if ( soundType = = IMPACTSOUND_GRASS ) {
sfx = cgs . media . footsteps [ FOOTSTEP_GRASS ] [ rand ( ) % 4 ] ;
} else if ( soundType = = IMPACTSOUND_SNOW ) {
sfx = cgs . media . footsteps [ FOOTSTEP_SNOW ] [ rand ( ) % 4 ] ;
} else {
mark = cgs . media . slashMarkShader ;
sfx = cgs . media . knifeClankSound ;
}
2002-06-16 20:06:15 +00:00
radius = rand ( ) % 4 + 6 ;
} else {
duration = 180 ;
mod = cgs . media . hitSparkModel ;
shader = cgs . media . hitSparkShader ;
sfx = cgs . media . knifeClankSound ;
}
break ;
default :
break ;
2001-05-06 20:50:27 +00:00
}
2001-10-30 23:23:04 +00:00
//
// ricochet sound
//
2002-06-16 20:06:15 +00:00
if ( weapon = = WP_KNIFE | | weapon = = WP_SSG3000 | | weapon = = WP_GRENADE | | soundType = = IMPACTSOUND_METAL )
2001-08-13 17:25:06 +00:00
i = 1 ;
else
2001-08-30 09:42:25 +00:00
//Elder: 90% of the time render a bullet ricochet sound
i = rand ( ) % 10 ;
2001-08-13 17:25:06 +00:00
2002-06-16 20:06:15 +00:00
if ( sfx & & i < 9 ) {
trap_S_StartSound ( origin , ENTITYNUM_WORLD , CHAN_AUTO , sfx ) ;
2001-05-06 20:50:27 +00:00
}
//
// create the explosion
//
2002-06-16 20:06:15 +00:00
if ( mod ) {
if ( weapon = = WP_GRENADE ) {
le = CG_MakeExplosion ( origin , dir , mod , shader , duration , isSprite ) ;
2001-11-12 08:59:46 +00:00
le - > light = light ;
2002-06-16 20:06:15 +00:00
VectorCopy ( lightColor , le - > lightColor ) ;
2002-04-03 03:13:49 +00:00
2002-06-16 20:06:15 +00:00
} else if ( cg_RQ3_impactEffects . integer ) {
2001-11-12 08:59:46 +00:00
vec3_t temp , offsetDir ;
byte color [ 4 ] ;
int flashCount ;
float scale ;
2002-06-16 20:06:15 +00:00
switch ( weapon ) {
case WP_MP5 :
case WP_PISTOL :
case WP_AKIMBO :
flashCount = 3 + rand ( ) % 3 ;
color [ 0 ] = 224 ;
color [ 1 ] = 180 ;
color [ 2 ] = 128 ;
color [ 3 ] = 192 ;
break ;
case WP_M4 :
case WP_KNIFE :
flashCount = 3 + rand ( ) % 3 ;
color [ 0 ] = 192 ;
color [ 1 ] = 96 ;
color [ 2 ] = 64 ;
color [ 3 ] = 192 ;
break ;
case WP_M3 :
case WP_HANDCANNON :
flashCount = 2 + rand ( ) % 3 ;
color [ 0 ] = 192 ;
color [ 1 ] = 96 ;
color [ 2 ] = 64 ;
color [ 3 ] = 192 ;
break ;
case WP_SSG3000 :
default :
flashCount = 4 + rand ( ) % 3 ;
color [ 0 ] = 255 ;
color [ 1 ] = 224 ;
color [ 2 ] = 128 ;
color [ 3 ] = 192 ;
break ;
2001-11-12 08:59:46 +00:00
}
2001-11-25 23:04:08 +00:00
2001-11-12 08:59:46 +00:00
// Elder: should probably dump this into another function
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < flashCount ; i + + ) {
2001-11-12 08:59:46 +00:00
// introduce variance
2002-06-16 20:06:15 +00:00
VectorCopy ( dir , temp ) ;
2001-11-12 08:59:46 +00:00
scale = crandom ( ) + 1.8f ;
temp [ 0 ] + = ( crandom ( ) * 0.4f ) - 0.2f ;
temp [ 1 ] + = ( crandom ( ) * 0.4f ) - 0.2f ;
temp [ 2 ] + = ( crandom ( ) * 0.4f ) - 0.2f ;
// save result
2002-06-16 20:06:15 +00:00
VectorCopy ( temp , offsetDir ) ;
VectorScale ( temp , scale , temp ) ;
2001-11-12 08:59:46 +00:00
2002-06-16 20:06:15 +00:00
le = CG_MakeExplosion ( origin , dir , mod , shader , duration , isSprite ) ;
2001-11-12 08:59:46 +00:00
2002-06-16 20:06:15 +00:00
VectorMA ( origin , scale + 0.5f , temp , le - > refEntity . origin ) ;
2001-11-12 08:59:46 +00:00
VectorCopy ( temp , le - > refEntity . axis [ 0 ] ) ;
2001-11-25 23:04:08 +00:00
2001-11-12 08:59:46 +00:00
// set spark colour
le - > refEntity . shaderRGBA [ 0 ] = color [ 0 ] ;
le - > refEntity . shaderRGBA [ 1 ] = color [ 1 ] ;
le - > refEntity . shaderRGBA [ 2 ] = color [ 2 ] ;
le - > refEntity . shaderRGBA [ 3 ] = color [ 3 ] ;
2001-11-25 23:04:08 +00:00
2001-11-12 08:59:46 +00:00
// readjust behaviour
le - > leType = LE_MOVE_SCALE_FADE ;
le - > pos . trType = TR_LINEAR ;
le - > pos . trTime = cg . time ;
VectorCopy ( le - > refEntity . origin , le - > pos . trBase ) ;
VectorScale ( offsetDir , 30 , le - > pos . trDelta ) ;
2001-11-25 23:04:08 +00:00
2001-11-12 08:59:46 +00:00
le - > light = light ;
2002-06-16 20:06:15 +00:00
VectorCopy ( lightColor , le - > lightColor ) ;
2001-11-12 08:59:46 +00:00
}
}
2001-05-06 20:50:27 +00:00
}
//
// impact mark
//
2003-07-30 16:05:47 +00:00
alphaFade = ( mark = = cgs . media . energyMarkShader | | mark = = cgs . media . snowMarkShader ) ; // plasma fades alpha, all others fade color
2001-11-11 20:03:09 +00:00
2001-10-30 23:23:04 +00:00
// Elder: Our knife slashes are vertical
2003-07-30 16:05:47 +00:00
if ( weapon = = WP_KNIFE ) {
//Makro - changed
//angle = random() * 90;
angle = - 45 + random ( ) * 90 ;
if ( angle < 0 )
angle + = 360 ;
} else
2001-08-18 20:01:21 +00:00
angle = random ( ) * 360 ;
2002-06-16 20:06:15 +00:00
if ( mark )
CG_ImpactMark ( mark , origin , dir , angle , 1 , 1 , 1 , 1 , alphaFade , radius , qfalse ) ;
2001-05-06 20:50:27 +00:00
//}
2001-07-24 01:49:02 +00:00
2001-10-30 23:23:04 +00:00
//
// impact visual effects
//
2001-11-11 20:03:09 +00:00
2001-07-24 01:49:02 +00:00
//Elder: 75% of the time render a smoke puff
2004-01-26 21:26:09 +00:00
//Makro - I say we do it all the time
//i = rand() % 4;
2003-07-30 16:05:47 +00:00
//Makro - not for snow or grass surfaces
2004-01-26 21:26:09 +00:00
//if (cg_RQ3_impactEffects.integer && i < 3 && soundType != IMPACTSOUND_SNOW && soundType != IMPACTSOUND_GRASS) {
if ( cg_RQ3_impactEffects . integer & & soundType ! = IMPACTSOUND_SNOW & & soundType ! = IMPACTSOUND_GRASS ) {
2002-06-16 20:06:15 +00:00
contentType = trap_CM_PointContents ( origin , 0 ) ;
2001-09-01 16:15:01 +00:00
// no puff in water
2002-06-16 20:06:15 +00:00
if ( ! ( contentType & CONTENTS_WATER ) ) {
2004-01-26 21:26:09 +00:00
int count = 0 , speed = 0 ;
float size = 0 ;
2002-06-16 20:06:15 +00:00
switch ( weapon ) {
case WP_MP5 :
2004-01-26 21:26:09 +00:00
count = 3 ;
size = 2.0f ;
speed = 36 ;
break ;
2002-06-16 20:06:15 +00:00
case WP_M4 :
2004-01-26 21:26:09 +00:00
count = 5 ;
size = 4.5f ;
speed = 64 ;
break ;
2002-06-16 20:06:15 +00:00
case WP_PISTOL :
case WP_AKIMBO :
2004-01-26 21:26:09 +00:00
count = 4 ;
size = 3.0f ;
speed = 48 ;
break ;
2002-06-16 20:06:15 +00:00
case WP_SSG3000 :
2004-01-26 21:26:09 +00:00
count = 5 ;
size = 6.0f ;
speed = 80 ;
break ;
/*
//Makro - old code
2002-06-16 20:06:15 +00:00
puffDir [ 0 ] = 0 ;
puffDir [ 1 ] = 0 ;
puffDir [ 2 ] = 16 ;
VectorCopy ( dir , puffOffset ) ;
VectorNormalize ( puffOffset ) ;
VectorNegate ( puffOffset , puffOffset ) ;
VectorScale ( puffOffset , 13 , puffOffset ) ;
VectorSubtract ( origin , puffOffset , puffOrigin ) ;
smokePuff = CG_SmokePuff ( puffOrigin , puffDir ,
( int ) ( random ( ) * 100 ) % 4 + 13 ,
1 , 1 , 1 , 0.25f ,
650 ,
cg . time , 0 ,
LEF_PUFF_DONT_SCALE , cgs . media . smokePuffAnimShader ) ;
2004-01-26 21:26:09 +00:00
*/
default :
2002-06-16 20:06:15 +00:00
break ;
2001-09-01 16:15:01 +00:00
}
2004-01-26 21:26:09 +00:00
for ( i = 0 ; i < count ; i + + )
{
VectorScale ( dir , speed + crandom ( ) * 8 , puffDir ) ;
//VectorScale(silencer.axis[1], -(20+random()*50), up);
smokePuff = CG_SmokePuff ( origin , puffDir , size + random ( ) * size , .8f , .8f , .8f , 0.3f + crandom ( ) * 0.1f , 300 + random ( ) * 150 , cg . time - random ( ) * 100 , cg . time + random ( ) * 200 , 0 ,
cgs . media . shotgunSmokePuffShader ) ;
smokePuff - > leType = LE_MOVE_SCALE_FADE ;
smokePuff - > lifeRate = 1.0f / ( smokePuff - > endTime - smokePuff - > startTime ) ;
}
}
}
//Makro - particles for default, grass, wood, brick and ceramic materials
if ( cg_RQ3_impactEffects . integer & & ( soundType = = IMPACTSOUND_WOOD | | soundType = = IMPACTSOUND_DEFAULT | | soundType = = IMPACTSOUND_BRICK | | soundType = = IMPACTSOUND_CERAMIC | | soundType = = IMPACTSOUND_GRASS ) )
{
int count = rand ( ) % 5 ;
for ( i = 0 ; i < count ; i + + )
{
VectorScale ( dir , 96 + crandom ( ) * 16 , puffDir ) ;
CG_ParticleHitWall ( origin , puffDir , 300 + rand ( ) % 250 , 4 , 4 , - 1 , 1 ) ;
2001-07-24 01:49:02 +00:00
}
}
2001-08-30 09:42:25 +00:00
// Elder: Spark effect for metal surfaces
2002-06-16 20:06:15 +00:00
if ( cg_RQ3_impactEffects . integer & & soundType = = IMPACTSOUND_METAL ) {
if ( weapon ! = WP_GRENADE ) {
2001-08-30 09:42:25 +00:00
if ( weapon = = WP_M3 | | weapon = = WP_HANDCANNON )
sparkCount = 5 + rand ( ) % 5 ;
else if ( weapon = = WP_KNIFE )
sparkCount = 10 + rand ( ) % 10 ;
else if ( weapon = = WP_SSG3000 )
sparkCount = 25 + rand ( ) % 20 ;
else
sparkCount = 15 + rand ( ) % 15 ;
// Generate the particles
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < sparkCount ; i + + ) {
2001-08-30 09:42:25 +00:00
if ( weapon = = WP_KNIFE )
2002-05-27 06:58:40 +00:00
VectorScale ( dir , 50 + rand ( ) % 10 , velocity ) ;
2001-08-30 09:42:25 +00:00
else
2002-05-27 06:58:40 +00:00
VectorScale ( dir , 150 + rand ( ) % 30 , velocity ) ;
2001-08-30 09:42:25 +00:00
//random upwards sparks
2002-06-16 20:06:15 +00:00
if ( rand ( ) % 5 < 1 )
2001-08-30 09:42:25 +00:00
velocity [ 2 ] + = 120 + rand ( ) % 30 ;
velocity [ 0 ] + = rand ( ) % 50 - 25 ;
velocity [ 1 ] + = rand ( ) % 50 - 25 ;
2001-12-17 15:06:41 +00:00
// NiceAss: Longer life, faster sparks == more eye candy! =)
CG_ParticleSparks ( origin , velocity , 150 + rand ( ) % 120 , 2 , 2 , - 5 , 1 ) ;
2001-08-30 09:42:25 +00:00
}
}
}
2003-07-30 16:05:47 +00:00
//Makro: snow surfaces
if ( cg_RQ3_impactEffects . integer & & soundType = = IMPACTSOUND_SNOW ) {
if ( weapon ! = WP_GRENADE ) {
if ( weapon = = WP_M3 | | weapon = = WP_HANDCANNON )
sparkCount = 5 + rand ( ) % 5 ;
else if ( weapon = = WP_KNIFE )
sparkCount = 10 + rand ( ) % 10 ;
else if ( weapon = = WP_SSG3000 )
sparkCount = 25 + rand ( ) % 20 ;
else
sparkCount = 15 + rand ( ) % 15 ;
// Generate the particles
for ( i = 0 ; i < sparkCount ; i + + ) {
if ( weapon = = WP_KNIFE )
VectorScale ( dir , 60 + rand ( ) % 20 , velocity ) ;
else
VectorScale ( dir , 75 + rand ( ) % 25 , velocity ) ;
CG_ParticleHitSnow ( origin , velocity , 500 + rand ( ) % 150 , 2 , 2 , - 5 , 1 ) ;
}
}
}
//Makro: grass surfaces
if ( cg_RQ3_impactEffects . integer & & soundType = = IMPACTSOUND_GRASS ) {
if ( weapon ! = WP_GRENADE ) {
if ( weapon = = WP_M3 | | weapon = = WP_HANDCANNON )
sparkCount = 5 + rand ( ) % 5 ;
else if ( weapon = = WP_KNIFE )
sparkCount = 10 + rand ( ) % 10 ;
else if ( weapon = = WP_SSG3000 )
sparkCount = 25 + rand ( ) % 20 ;
else
sparkCount = 15 + rand ( ) % 15 ;
// Generate the particles
for ( i = 0 ; i < sparkCount ; i + + ) {
if ( weapon = = WP_KNIFE )
VectorScale ( dir , 60 + rand ( ) % 20 , velocity ) ;
else
VectorScale ( dir , 75 + rand ( ) % 25 , velocity ) ;
CG_ParticleHitGrass ( origin , velocity , 500 + rand ( ) % 150 , 2 , 2 , - 5 , 1 ) ;
}
}
}
2001-08-30 09:42:25 +00:00
// Elder: grenade explosion
2002-06-16 20:06:15 +00:00
if ( cg_RQ3_impactEffects . integer & & weapon = = WP_GRENADE ) {
2002-04-03 03:13:49 +00:00
2001-09-01 16:15:01 +00:00
vec3_t shrapnelDest ;
sparkCount = 60 + rand ( ) % 10 ;
2001-08-30 09:42:25 +00:00
origin [ 2 ] + = 32 ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < sparkCount ; i + + ) {
VectorScale ( dir , rand ( ) % 200 , velocity ) ;
2001-08-30 09:42:25 +00:00
velocity [ 0 ] + = rand ( ) % 200 - 100 ;
velocity [ 1 ] + = rand ( ) % 200 - 100 ;
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
if ( i % 8 = = 7 ) {
2001-09-01 16:15:01 +00:00
// Add shrapnel trace effect
VectorMA ( origin , 0.7f , velocity , shrapnelDest ) ;
CG_ShrapnelSpark ( origin , shrapnelDest , 10 , 280 ) ;
}
// Add sparks
2001-08-30 09:42:25 +00:00
CG_ParticleSparks ( origin , velocity , 900 + rand ( ) % 200 , 5 , 5 , - 2.5f , 3.5f ) ;
}
2001-09-01 16:15:01 +00:00
// Add smoke puff
puffDir [ 0 ] = 0 ;
puffDir [ 1 ] = 0 ;
puffDir [ 2 ] = 20 ;
origin [ 2 ] - = 16 ;
2002-06-16 20:06:15 +00:00
smokePuff = CG_SmokePuff ( origin , puffDir ,
rand ( ) % 12 + 48 ,
1 , 1 , 1 , 0.4f , 1750 , cg . time , 0 , 0 , cgs . media . smokePuffShader ) ;
2001-08-30 09:42:25 +00:00
}
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = =
CG_MissileHitPlayer
= = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_MissileHitPlayer ( int weapon , vec3_t origin , vec3_t dir , int entityNum )
{
CG_Bleed ( origin , entityNum ) ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
SHOTGUN TRACING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
CG_ShotgunPellet
2001-06-26 01:58:02 +00:00
Elder : added shellWeapon param
We are not going to show every HC impact
2001-05-06 20:50:27 +00:00
= = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
static void CG_ShotgunPellet ( vec3_t start , vec3_t end , int skipNum , int shellWeapon )
{
trace_t tr ;
2003-02-01 02:15:31 +00:00
int sourceContentType , destContentType , l , playerNum ;
2002-06-29 20:56:23 +00:00
vec3_t t_start ;
2002-04-06 21:43:59 +00:00
//Makro
2002-06-16 20:06:15 +00:00
int Material ;
2001-05-06 20:50:27 +00:00
2002-11-18 04:39:47 +00:00
VectorCopy ( start , t_start ) ;
2002-06-29 21:57:18 +00:00
playerNum = skipNum ;
2002-06-29 20:56:23 +00:00
// NiceAss: Allow M3/HC shots to go through teammates
for ( l = 0 ; l < 10 ; l + + ) {
CG_Trace ( & tr , t_start , NULL , NULL , end , skipNum , MASK_SHOT ) ;
2002-06-29 21:57:18 +00:00
if ( tr . entityNum < MAX_CLIENTS & & cgs . gametype > = GT_TEAM & &
2002-11-18 04:39:47 +00:00
cgs . clientinfo [ tr . entityNum ] . team = = cgs . clientinfo [ playerNum ] . team ) {
VectorCopy ( tr . endpos , t_start ) ;
2002-06-29 20:56:23 +00:00
skipNum = tr . entityNum ;
continue ;
}
break ;
}
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
sourceContentType = trap_CM_PointContents ( start , 0 ) ;
destContentType = trap_CM_PointContents ( tr . endpos , 0 ) ;
2001-05-06 20:50:27 +00:00
// FIXME: should probably move this cruft into CG_BubbleTrail
2002-06-16 20:06:15 +00:00
if ( sourceContentType = = destContentType ) {
if ( sourceContentType & CONTENTS_WATER ) {
CG_BubbleTrail ( start , tr . endpos , 32 ) ;
2001-05-06 20:50:27 +00:00
}
2002-06-16 20:06:15 +00:00
} else if ( sourceContentType & CONTENTS_WATER ) {
2001-05-06 20:50:27 +00:00
trace_t trace ;
2002-06-16 20:06:15 +00:00
trap_CM_BoxTrace ( & trace , end , start , NULL , NULL , 0 , CONTENTS_WATER ) ;
CG_BubbleTrail ( start , trace . endpos , 32 ) ;
} else if ( destContentType & CONTENTS_WATER ) {
2001-05-06 20:50:27 +00:00
trace_t trace ;
2002-06-16 20:06:15 +00:00
trap_CM_BoxTrace ( & trace , start , end , NULL , NULL , 0 , CONTENTS_WATER ) ;
CG_BubbleTrail ( tr . endpos , trace . endpos , 32 ) ;
2001-05-06 20:50:27 +00:00
}
2002-06-16 20:06:15 +00:00
if ( tr . surfaceFlags & SURF_NOIMPACT ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-06-16 20:06:15 +00:00
if ( cg_entities [ tr . entityNum ] . currentState . eType = = ET_PLAYER ) {
2001-05-06 20:50:27 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
2001-07-28 14:12:11 +00:00
//Elder: don't display so many blood stains - so we can reduce slow down
cg . shellHits + + ;
if ( cg . shellHits < MAX_SHELL_HITS )
2002-06-16 20:06:15 +00:00
CG_MissileHitPlayer ( WP_M3 , tr . endpos , tr . plane . normal , tr . entityNum ) ;
} else {
if ( tr . surfaceFlags & SURF_NOIMPACT ) {
2001-05-06 20:50:27 +00:00
// SURF_NOIMPACT will not make a flame puff or a mark
return ;
}
2002-04-06 21:43:59 +00:00
//Makro - new surfaceparm system
Material = GetMaterialFromFlag ( tr . surfaceFlags ) ;
2002-06-16 20:06:15 +00:00
if ( IsMetalMat ( Material ) ) {
2001-05-06 20:50:27 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
2001-06-26 01:58:02 +00:00
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_METAL , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2001-06-26 01:58:02 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_METAL , 0 ) ;
2001-11-11 20:03:09 +00:00
}
2001-07-28 14:12:11 +00:00
}
2002-06-16 20:06:15 +00:00
else if ( Material = = MAT_GLASS ) {
2001-10-11 22:50:58 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_GLASS , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2001-10-11 22:50:58 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_GLASS , 0 ) ;
2001-10-11 22:50:58 +00:00
}
}
2002-05-12 14:40:28 +00:00
//Makro - added
2002-06-16 20:06:15 +00:00
else if ( IsWoodMat ( Material ) ) {
2002-05-12 14:40:28 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_WOOD , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2002-05-12 14:40:28 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_WOOD , 0 ) ;
2002-05-12 14:40:28 +00:00
}
}
//Makro - added
2002-06-16 20:06:15 +00:00
else if ( Material = = MAT_BRICK ) {
2002-05-12 14:40:28 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_BRICK , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2002-05-12 14:40:28 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_BRICK , 0 ) ;
2002-05-12 14:40:28 +00:00
}
}
//Makro - added
2002-06-16 20:06:15 +00:00
else if ( Material = = MAT_CERAMIC ) {
2002-05-12 14:40:28 +00:00
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_CERAMIC , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2002-05-12 14:40:28 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_CERAMIC , 0 ) ;
2002-05-12 14:40:28 +00:00
}
2003-07-30 16:05:47 +00:00
}
//Makro - added
else if ( IsSnowMat ( Material ) ) {
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_SNOW , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
//Elder: show only approximately every other impact mark
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_SNOW , 0 ) ;
}
}
//Makro - added
else if ( Material = = MAT_GRASS ) {
//Blaze: Changed WP_SHOTGUN to WP_M3
if ( shellWeapon = = WP_M3 )
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_GRASS , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
//Elder: show only approximately every other impact mark
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_GRASS , 0 ) ;
}
2002-06-16 20:06:15 +00:00
} else {
2001-10-30 23:23:04 +00:00
// Elder: By default, the M3 and HC will spark on all surfaces
// Blaze: Changed WP_SHOTGUN to WP_M3
2001-06-26 01:58:02 +00:00
if ( shellWeapon = = WP_M3 )
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_M3 , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_METAL , 0 ) ;
else if ( shellWeapon = = WP_HANDCANNON & & crandom ( ) > 0.5 ) {
2001-06-26 01:58:02 +00:00
//Elder: show only approximately every other impact mark
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_HANDCANNON , 0 , tr . endpos , tr . plane . normal , IMPACTSOUND_METAL , 0 ) ;
2001-06-26 01:58:02 +00:00
}
2001-05-06 20:50:27 +00:00
}
}
}
/*
= = = = = = = = = = = = = = = =
CG_ShotgunPattern
Perform the same traces the server did to locate the
2001-08-01 21:07:48 +00:00
hit splashes
2001-05-06 20:50:27 +00:00
= = = = = = = = = = = = = = = =
*/
2003-03-09 21:30:39 +00:00
void CG_ShotgunPattern ( vec3_t origin , vec3_t origin2 , int otherEntNum , int shotType , int seed )
2002-06-16 20:06:15 +00:00
{
2003-02-01 02:15:31 +00:00
int i , count ;
2002-06-16 20:06:15 +00:00
float r , u ;
2003-02-01 02:15:31 +00:00
vec3_t end , forward , right , up ;
2002-06-16 20:06:15 +00:00
int hc_multipler = 0 ;
2001-06-24 02:07:17 +00:00
2001-05-06 20:50:27 +00:00
// derive the right and up vectors from the forward vector, because
// the client won't have any other information
2002-06-16 20:06:15 +00:00
VectorNormalize2 ( origin2 , forward ) ;
PerpendicularVector ( right , forward ) ;
CrossProduct ( forward , right , up ) ;
2001-05-06 20:50:27 +00:00
// generate the "random" spread pattern
2001-06-24 02:07:17 +00:00
//Elder: added
if ( shotType = = WP_M3 )
count = DEFAULT_M3_COUNT ;
else if ( shotType = = WP_HANDCANNON ) {
count = DEFAULT_HANDCANNON_COUNT ;
hc_multipler = 4 ;
2002-06-16 20:06:15 +00:00
} else {
2001-06-24 02:07:17 +00:00
count = DEFAULT_HANDCANNON_COUNT ;
hc_multipler = 5 ;
}
2001-07-28 14:12:11 +00:00
cg . shellHits = 0 ;
2002-06-16 20:06:15 +00:00
for ( i = 0 ; i < count ; i + + ) {
if ( shotType = = WP_M3 ) {
2001-07-24 01:49:02 +00:00
r = Q_crandom ( & seed ) * DEFAULT_M3_HSPREAD * 16 ;
u = Q_crandom ( & seed ) * DEFAULT_M3_VSPREAD * 16 ;
2002-06-16 20:06:15 +00:00
} else {
2001-06-26 01:58:02 +00:00
//Elder: fill in shotType
shotType = WP_HANDCANNON ;
2001-07-24 01:49:02 +00:00
r = Q_crandom ( & seed ) * DEFAULT_SHOTGUN_HSPREAD * 16 * 4 ;
u = Q_crandom ( & seed ) * DEFAULT_SHOTGUN_VSPREAD * 16 * hc_multipler ;
}
2002-06-16 20:06:15 +00:00
VectorMA ( origin , 8192 * 16 , forward , end ) ;
VectorMA ( end , r , right , end ) ;
VectorMA ( end , u , up , end ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
CG_ShotgunPellet ( origin , end , otherEntNum , shotType ) ;
2001-05-06 20:50:27 +00:00
}
2001-07-28 14:12:11 +00:00
//Reset shellHits once we're finished with it
cg . shellHits = 0 ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = =
CG_ShotgunFire
= = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_ShotgunFire ( entityState_t * es , qboolean ism3 )
{
vec3_t v ;
int contents ;
VectorSubtract ( es - > origin2 , es - > pos . trBase , v ) ;
VectorNormalize ( v ) ;
VectorScale ( v , 32 , v ) ;
VectorAdd ( es - > pos . trBase , v , v ) ;
if ( cgs . glconfig . hardwareType ! = GLHW_RAGEPRO ) {
2001-05-06 20:50:27 +00:00
// ragepro can't alpha fade, so don't even bother with smoke
2002-06-16 20:06:15 +00:00
vec3_t up ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
contents = trap_CM_PointContents ( es - > pos . trBase , 0 ) ;
if ( ! ( contents & CONTENTS_WATER ) ) {
VectorSet ( up , 0 , 0 , 8 ) ;
CG_SmokePuff ( v , up , 32 , 1 , 1 , 1 , 0.33f , 900 , cg . time , 0 , LEF_PUFF_DONT_SCALE ,
cgs . media . shotgunSmokePuffShader ) ;
2001-05-06 20:50:27 +00:00
}
}
2001-06-24 02:07:17 +00:00
//Elder: note param changes
2002-06-16 20:06:15 +00:00
if ( ism3 ) {
CG_ShotgunPattern ( es - > pos . trBase , es - > origin2 , es - > otherEntityNum , WP_M3 , es - > eventParm ) ;
} else {
CG_ShotgunPattern ( es - > pos . trBase , es - > origin2 , es - > otherEntityNum , WP_HANDCANNON , es - > eventParm ) ;
2001-07-24 01:49:02 +00:00
es - > angles2 [ 1 ] + = 20 ;
//es->origin2[1] += 5;
2002-06-16 20:06:15 +00:00
CG_ShotgunPattern ( es - > pos . trBase , es - > origin2 , es - > otherEntityNum , - 1 , es - > eventParm ) ;
2001-05-06 20:50:27 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
BULLETS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2002-05-09 06:45:14 +00:00
/*
= = = = = = = = = = = = = = =
2002-05-18 03:55:35 +00:00
CG_CreateTracer
2002-05-09 06:45:14 +00:00
- NiceAss
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_CreateTracer ( int entity , vec3_t start , vec3_t end )
{
localEntity_t * le ;
float dist ;
2003-02-01 02:15:31 +00:00
vec3_t dir , end2 , temp , midpoint ;
2002-09-08 03:15:16 +00:00
float tracerSpeed = 5000 ;
2002-05-09 06:45:14 +00:00
2002-06-16 20:06:15 +00:00
VectorSubtract ( end , start , dir ) ;
dist = VectorNormalize ( dir ) ;
2002-05-09 06:45:14 +00:00
2002-05-18 03:55:35 +00:00
if ( dist < 1.5 * cg_tracerLength . value )
return ;
2002-05-09 06:45:14 +00:00
2002-05-18 03:55:35 +00:00
// Stop right before the end
2002-06-16 20:06:15 +00:00
VectorMA ( end , - cg_tracerLength . value , dir , end2 ) ;
2002-05-09 06:45:14 +00:00
2002-06-16 20:06:15 +00:00
VectorSubtract ( end2 , start , temp ) ;
dist = VectorLength ( temp ) ;
2002-05-09 06:45:14 +00:00
le = CG_AllocLocalEntity ( ) ;
2002-05-18 03:55:35 +00:00
le - > leType = LE_TRACER ;
le - > startTime = cg . time ;
le - > endTime = le - > startTime + 1000.0 * ( dist / tracerSpeed ) ;
2002-05-09 06:45:14 +00:00
le - > pos . trType = TR_LINEAR ;
le - > pos . trTime = le - > startTime ;
2002-06-16 20:06:15 +00:00
VectorCopy ( start , le - > pos . trBase ) ;
VectorScale ( dir , tracerSpeed , le - > pos . trDelta ) ;
2002-05-09 06:45:14 +00:00
2002-06-16 20:06:15 +00:00
midpoint [ 0 ] = ( start [ 0 ] + end2 [ 0 ] ) * 0.5 ;
midpoint [ 1 ] = ( start [ 1 ] + end2 [ 1 ] ) * 0.5 ;
midpoint [ 2 ] = ( start [ 2 ] + end2 [ 2 ] ) * 0.5 ;
trap_S_StartSound ( midpoint , ENTITYNUM_WORLD , CHAN_AUTO , cgs . media . tracerSound ) ;
2002-05-09 06:45:14 +00:00
}
2001-05-06 20:50:27 +00:00
/*
= = = = = = = = = = = = = = =
CG_Tracer
= = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_Tracer ( vec3_t source , vec3_t dest )
{
2003-02-01 02:15:31 +00:00
vec3_t forward , right , line , start , finish ;
2002-06-16 20:06:15 +00:00
polyVert_t verts [ 4 ] ;
float len , begin , end ;
2001-05-06 20:50:27 +00:00
// tracer
2002-06-16 20:06:15 +00:00
VectorSubtract ( dest , source , forward ) ;
len = VectorNormalize ( forward ) ;
2001-05-06 20:50:27 +00:00
// start at least a little ways from the muzzle
2002-06-16 20:06:15 +00:00
if ( len < 100 ) {
2001-05-06 20:50:27 +00:00
return ;
}
2002-05-09 06:45:14 +00:00
2001-05-06 20:50:27 +00:00
begin = 50 + random ( ) * ( len - 60 ) ;
end = begin + cg_tracerLength . value ;
2002-06-16 20:06:15 +00:00
if ( end > len ) {
2001-05-06 20:50:27 +00:00
end = len ;
}
2002-06-16 20:06:15 +00:00
VectorMA ( source , begin , forward , start ) ;
VectorMA ( source , end , forward , finish ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
line [ 0 ] = DotProduct ( forward , cg . refdef . viewaxis [ 1 ] ) ;
line [ 1 ] = DotProduct ( forward , cg . refdef . viewaxis [ 2 ] ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorScale ( cg . refdef . viewaxis [ 1 ] , line [ 1 ] , right ) ;
VectorMA ( right , - line [ 0 ] , cg . refdef . viewaxis [ 2 ] , right ) ;
VectorNormalize ( right ) ;
2001-05-06 20:50:27 +00:00
2002-06-16 20:06:15 +00:00
VectorMA ( finish , cg_tracerWidth . value , right , verts [ 0 ] . xyz ) ;
2001-05-06 20:50:27 +00:00
verts [ 0 ] . st [ 0 ] = 0 ;
verts [ 0 ] . st [ 1 ] = 1 ;
verts [ 0 ] . modulate [ 0 ] = 255 ;
verts [ 0 ] . modulate [ 1 ] = 255 ;
verts [ 0 ] . modulate [ 2 ] = 255 ;
verts [ 0 ] . modulate [ 3 ] = 255 ;
2002-06-16 20:06:15 +00:00
VectorMA ( finish , - cg_tracerWidth . value , right , verts [ 1 ] . xyz ) ;
2001-05-06 20:50:27 +00:00
verts [ 1 ] . st [ 0 ] = 1 ;
verts [ 1 ] . st [ 1 ] = 0 ;
verts [ 1 ] . modulate [ 0 ] = 255 ;
verts [ 1 ] . modulate [ 1 ] = 255 ;
verts [ 1 ] . modulate [ 2 ] = 255 ;
verts [ 1 ] . modulate [ 3 ] = 255 ;
2002-06-16 20:06:15 +00:00
VectorMA ( start , - cg_tracerWidth . value , right , verts [ 2 ] . xyz ) ;
2001-05-06 20:50:27 +00:00
verts [ 2 ] . st [ 0 ] = 1 ;
verts [ 2 ] . st [ 1 ] = 1 ;
verts [ 2 ] . modulate [ 0 ] = 255 ;
verts [ 2 ] . modulate [ 1 ] = 255 ;
verts [ 2 ] . modulate [ 2 ] = 255 ;
verts [ 2 ] . modulate [ 3 ] = 255 ;
2002-06-16 20:06:15 +00:00
VectorMA ( start , cg_tracerWidth . value , right , verts [ 3 ] . xyz ) ;
2001-05-06 20:50:27 +00:00
verts [ 3 ] . st [ 0 ] = 0 ;
verts [ 3 ] . st [ 1 ] = 0 ;
verts [ 3 ] . modulate [ 0 ] = 255 ;
verts [ 3 ] . modulate [ 1 ] = 255 ;
verts [ 3 ] . modulate [ 2 ] = 255 ;
verts [ 3 ] . modulate [ 3 ] = 255 ;
2002-06-16 20:06:15 +00:00
trap_R_AddPolyToScene ( cgs . media . tracerShader , 4 , verts ) ;
2001-05-06 20:50:27 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = =
CG_Bullet
Renders bullet effects .
2001-08-30 09:42:25 +00:00
Elder : added soundType conditional
2001-05-06 20:50:27 +00:00
= = = = = = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_Bullet ( vec3_t end , int sourceEntityNum , vec3_t normal ,
qboolean flesh , int fleshEntityNum , impactSound_t soundType )
{
2002-11-18 04:39:47 +00:00
trace_t trace ;
int sourceContentType , destContentType ;
vec3_t start ;
centity_t * cent ;
float chance ;
2002-09-08 03:15:16 +00:00
chance = cg_tracerChance . value ;
if ( chance > 0.4f )
chance = 0.4f ;
2002-11-18 04:39:47 +00:00
2001-05-06 20:50:27 +00:00
// if the shooter is currently valid, calc a source point and possibly
// do trail effects
2002-09-08 03:15:16 +00:00
if ( sourceEntityNum > = 0 & & chance > 0 ) {
2002-06-16 20:06:15 +00:00
if ( CG_CalcMuzzlePoint ( sourceEntityNum , start ) ) {
sourceContentType = trap_CM_PointContents ( start , 0 ) ;
destContentType = trap_CM_PointContents ( end , 0 ) ;
2001-05-06 20:50:27 +00:00
// do a complete bubble trail if necessary
2002-06-16 20:06:15 +00:00
if ( ( sourceContentType = = destContentType ) & & ( sourceContentType & CONTENTS_WATER ) ) {
CG_BubbleTrail ( start , end , 32 ) ;
2001-05-06 20:50:27 +00:00
}
// bubble trail from water into air
2002-06-16 20:06:15 +00:00
else if ( ( sourceContentType & CONTENTS_WATER ) ) {
trap_CM_BoxTrace ( & trace , end , start , NULL , NULL , 0 , CONTENTS_WATER ) ;
CG_BubbleTrail ( start , trace . endpos , 32 ) ;
2001-05-06 20:50:27 +00:00
}
// bubble trail from air into water
2002-06-16 20:06:15 +00:00
else if ( ( destContentType & CONTENTS_WATER ) ) {
trap_CM_BoxTrace ( & trace , start , end , NULL , NULL , 0 , CONTENTS_WATER ) ;
CG_BubbleTrail ( trace . endpos , end , 32 ) ;
2001-09-01 16:15:01 +00:00
// TODO: water splash mark
2001-05-06 20:50:27 +00:00
}
// draw a tracer
2001-08-13 17:25:06 +00:00
// Elder: only if not using SSG, check if this client is the source
2002-06-16 20:06:15 +00:00
if ( sourceEntityNum = = cg . snap - > ps . clientNum ) {
2002-05-27 06:58:40 +00:00
if ( cg . snap - > ps . weapon ! = WP_SSG3000 & &
2002-10-26 00:37:18 +00:00
( cg . snap - > ps . stats [ STAT_HOLDABLE_ITEM ] & ( 1 < < HI_SILENCER ) ) ) {
2002-09-08 03:15:16 +00:00
if ( random ( ) < chance )
2002-06-16 20:06:15 +00:00
CG_CreateTracer ( sourceEntityNum , start , end ) ;
2001-08-13 17:25:06 +00:00
}
2002-06-16 20:06:15 +00:00
} else {
2001-08-13 17:25:06 +00:00
cent = & cg_entities [ sourceEntityNum ] ;
2002-06-16 20:06:15 +00:00
if ( cent - > currentValid & & cent - > currentState . weapon ! = WP_SSG3000 ) {
2002-09-08 03:15:16 +00:00
if ( random ( ) < chance & & cent - > muzzleFlashTime ! = - 1 ) {
2002-06-16 20:06:15 +00:00
CG_CreateTracer ( sourceEntityNum , start , end ) ;
2001-08-13 17:25:06 +00:00
}
}
2001-05-06 20:50:27 +00:00
}
}
}
// impact splash and mark
2002-06-16 20:06:15 +00:00
if ( flesh ) {
CG_Bleed ( end , fleshEntityNum ) ;
2001-05-06 20:50:27 +00:00
} else {
//Blaze: Changed WP_MACHINEGUN to WP_PISTOL
2002-06-16 20:06:15 +00:00
CG_MissileHitWall ( WP_PISTOL , 0 , end , normal , soundType , 0 ) ;
2001-05-06 20:50:27 +00:00
}
}
2001-07-28 14:12:11 +00:00
/*
= = = = = = = = = = = = = = = = = =
CG_LocalLaser
Elder :
Local laser dot if it is the client ' s own laser
= = = = = = = = = = = = = = = = = =
*/
2009-07-04 03:37:41 +00:00
static void CG_LocalLaser ( void )
2001-07-28 14:12:11 +00:00
{
2003-02-01 02:15:31 +00:00
vec3_t muzzle , forward , end ;
2002-06-16 20:06:15 +00:00
refEntity_t * re ;
trace_t tr ;
2001-11-11 20:03:09 +00:00
2001-07-28 14:12:11 +00:00
//Create the laser entity if it's not there
2002-06-16 20:06:15 +00:00
if ( cg . laserSight = = qfalse ) {
2001-07-28 14:12:11 +00:00
cg . laserSight = qtrue ;
cg . laserEnt = CG_AllocLocalEntity ( ) ;
cg . laserEnt - > startTime = cg . time ;
cg . laserEnt - > color [ 3 ] = 1.0 ;
}
//Setup refEntity stuff
re = & cg . laserEnt - > refEntity ;
re - > radius = 6 ;
re - > reType = RT_SPRITE ;
re - > rotation = 0 ;
re - > customShader = cgs . media . laserShader ;
//Calculate muzzle and endpoint
2002-06-16 20:06:15 +00:00
if ( CG_CalcMuzzlePoint ( cg . snap - > ps . clientNum , muzzle ) ) {
AngleVectors ( cg . snap - > ps . viewangles , forward , NULL , NULL ) ;
VectorMA ( muzzle , 8192 * 16 , forward , end ) ;
} else {
2001-07-28 14:12:11 +00:00
CG_Error ( " CG_LocalLaser: Could not calculate own muzzle point \n " ) ;
}
CG_Trace ( & tr , muzzle , NULL , NULL , end , cg . predictedPlayerState . clientNum , CONTENTS_SOLID ) ;
2001-11-11 20:03:09 +00:00
2001-07-28 14:12:11 +00:00
//Set position of laser dot
if ( tr . fraction ! = 1 )
2002-06-16 20:06:15 +00:00
VectorMA ( tr . endpos , - 4 , forward , tr . endpos ) ;
2001-07-28 14:12:11 +00:00
2001-08-17 20:38:54 +00:00
VectorCopy ( re - > origin , re - > oldorigin ) ;
2001-07-28 14:12:11 +00:00
VectorCopy ( tr . endpos , re - > origin ) ;
2001-11-11 20:03:09 +00:00
2001-07-28 14:12:11 +00:00
//Boost the endTime
cg . laserEnt - > endTime + = 10000 ;
//Don't render if it hits the sky
//if (!(tr.surfaceFlags & SURF_SKY))
2002-06-16 20:06:15 +00:00
trap_R_AddRefEntityToScene ( re ) ;
2001-07-28 14:12:11 +00:00
}
/*
= = = = = = = = = = = = = = = = = =
CG_CheckLaser
Elder :
Whether or not to use the local laser
Broken until I find a way to lerp an entity without a cent
= = = = = = = = = = = = = = = = = =
*/
void CG_CheckLaser ( )
{
//Elder: check for local laser
2002-10-26 00:37:18 +00:00
if ( ( cg . snap - > ps . stats [ STAT_HOLDABLE_ITEM ] & ( 1 < < HI_LASER ) ) & &
2002-06-16 20:06:15 +00:00
cg_RQ3_laserAssist . integer & &
( cg . snap - > ps . weapon = = WP_PISTOL | | cg . snap - > ps . weapon = = WP_MP5 | | cg . snap - > ps . weapon = = WP_M4 ) ) {
2001-07-28 14:12:11 +00:00
CG_LocalLaser ( ) ;
}
//Disable laser
2002-06-16 20:06:15 +00:00
else if ( cg . laserSight = = qtrue ) {
2001-11-15 07:04:46 +00:00
//CG_Printf("Destroying Local Laser...\n");
2001-07-28 14:12:11 +00:00
CG_FreeLocalEntity ( cg . laserEnt ) ;
cg . laserSight = qfalse ;
}
}
2001-08-06 19:15:00 +00:00
/*
= = = = = = = = = = = = = = = = = =
CG_ReloadWeapon
Elder : Does local reload effects like
reload shell drops , sounds , etc .
= = = = = = = = = = = = = = = = = =
*/
2002-06-16 20:06:15 +00:00
void CG_ReloadWeapon ( centity_t * cent , int reloadStage )
2001-08-06 19:15:00 +00:00
{
entityState_t * ent ;
2002-06-16 20:06:15 +00:00
weaponInfo_t * weap ;
2001-08-06 19:15:00 +00:00
ent = & cent - > currentState ;
2002-06-16 20:06:15 +00:00
if ( ent - > weapon = = WP_NONE )
2001-08-06 19:15:00 +00:00
return ;
2001-11-11 07:23:16 +00:00
2002-06-16 20:06:15 +00:00
if ( ent - > weapon > = WP_NUM_WEAPONS ) {
CG_Error ( " CG_ReloadWeapon: ent->weapon >= WP_NUM_WEAPONS " ) ;
2001-08-06 19:15:00 +00:00
return ;
}
2001-11-11 07:23:16 +00:00
weap = & cg_weapons [ ent - > weapon ] ;
2002-06-16 20:06:15 +00:00
switch ( reloadStage ) {
2001-11-11 07:23:16 +00:00
case 0 :
2002-06-16 20:06:15 +00:00
if ( weap - > worldReloadSound [ 0 ] & & ent - > clientNum ! = cg . snap - > ps . clientNum ) {
2001-11-11 07:23:16 +00:00
trap_S_StartSound ( cent - > lerpOrigin , ent - > number , CHAN_AUTO , weap - > worldReloadSound [ 0 ] ) ;
2001-11-24 23:55:56 +00:00
}
2001-11-11 07:23:16 +00:00
break ;
case 1 :
2002-06-16 20:06:15 +00:00
if ( weap - > worldReloadSound [ 1 ] & & ent - > clientNum ! = cg . snap - > ps . clientNum ) {
2001-11-11 07:23:16 +00:00
trap_S_StartSound ( cent - > lerpOrigin , ent - > number , CHAN_AUTO , weap - > worldReloadSound [ 1 ] ) ;
2001-11-24 23:55:56 +00:00
}
2001-11-11 20:03:09 +00:00
2002-06-16 20:06:15 +00:00
if ( ent - > weapon = = WP_HANDCANNON )
2002-03-24 22:46:23 +00:00
cent - > ejectBrassTime = cg . time ;
2002-06-16 20:06:15 +00:00
// CG_ShotgunEjectBrass( cent );
2001-11-11 07:23:16 +00:00
break ;
case 2 :
2002-06-16 20:06:15 +00:00
if ( weap - > worldReloadSound [ 2 ] & & ent - > clientNum ! = cg . snap - > ps . clientNum ) {
2001-11-11 07:23:16 +00:00
trap_S_StartSound ( cent - > lerpOrigin , ent - > number , CHAN_AUTO , weap - > worldReloadSound [ 2 ] ) ;
2001-11-24 23:55:56 +00:00
}
2001-11-25 23:17:41 +00:00
2001-11-11 07:23:16 +00:00
break ;
default :
CG_Error ( " CG_ReloadWeapon: Reload stage > 2 \n " ) ;
break ;
2001-08-06 19:15:00 +00:00
}
2002-05-27 17:47:19 +00:00
}