mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-01-19 08:01:55 +00:00
Elder:
For the coming 0-06-xx VMs Lots of item stuff + more
This commit is contained in:
parent
21b2fc4497
commit
058281a050
23 changed files with 978 additions and 154 deletions
|
@ -55,6 +55,36 @@ static void CG_DropWeapon_f (void) {
|
|||
trap_SendClientCommand("dropweapon");
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_DropItem_f
|
||||
|
||||
Elder: Do any client pre-processing here for drop item
|
||||
=================
|
||||
*/
|
||||
static void CG_DropItem_f (void) {
|
||||
if ( !cg.snap ) {
|
||||
//CG_Printf("No snapshot: normally exiting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// if we are going into the intermission, don't do anything
|
||||
if ( cg.intermissionStarted ) {
|
||||
return;
|
||||
}
|
||||
|
||||
///Elder: spectator?
|
||||
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Elder: don't allow item dropping when in the middle of bursts
|
||||
if (cg.snap->ps.stats[STAT_BURST] > 0)
|
||||
return;
|
||||
|
||||
trap_SendClientCommand("dropitem");
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Bandage_f
|
||||
|
@ -668,6 +698,7 @@ static consoleCommand_t commands[] = {
|
|||
{ "weapnext", CG_NextWeapon_f },
|
||||
{ "weapprev", CG_PrevWeapon_f },
|
||||
{ "weapon", CG_Weapon_f }, // Elder: it's for RQ3 and Q3A
|
||||
{ "dropitem", CG_DropItem_f },
|
||||
{ "dropweapon", CG_DropWeapon_f }, // Elder: added to reset zoom then goto server
|
||||
{ "bandage", CG_Bandage_f }, // Elder: added to reset zoom then goto server
|
||||
{ "+reload", CG_Reload_f }, // Elder: added to reset zoom then goto server
|
||||
|
@ -790,6 +821,7 @@ void CG_InitConsoleCommands( void ) {
|
|||
//trap_AddCommand ("drop"); // XRAY FMJ weap drop cmd - Elder: not used
|
||||
//Elder: added to give drop weapon auto-complete
|
||||
trap_AddCommand ("dropweapon");
|
||||
trap_AddCommand ("dropitem");
|
||||
//Elder: try this
|
||||
trap_AddCommand ("weapon");
|
||||
trap_AddCommand ("specialweapon");
|
||||
|
|
|
@ -599,9 +599,9 @@ static void CG_DrawStatusBar( void ) {
|
|||
UI_DrawProportionalString(580, 364, va("%d", cg.snap->ps.ammo[WP_GRENADE]), style, colors[0]);
|
||||
}
|
||||
|
||||
//Elder: draw special weapons, if any, on the side
|
||||
if (cg.snap->ps.stats[STAT_UNIQUEWEAPONS])
|
||||
{
|
||||
//Elder: draw a special weapon, if any, on the side
|
||||
//if (cg.snap->ps.stats[STAT_UNIQUEWEAPONS])
|
||||
//{
|
||||
for (i = 1; i < MAX_WEAPONS; i++)
|
||||
{
|
||||
if (i == WP_KNIFE ||
|
||||
|
@ -620,7 +620,7 @@ static void CG_DrawStatusBar( void ) {
|
|||
if (icon)
|
||||
CG_DrawPic(640-SMICON_SIZE, 400, SMICON_SIZE, SMICON_SIZE, icon);
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -462,7 +462,80 @@ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
|
|||
}
|
||||
|
||||
|
||||
//Elder: we need one that sprays blood
|
||||
/*
|
||||
=================
|
||||
CG_BleedSpray
|
||||
|
||||
Elder: This is a super blood spray for SSG hits
|
||||
Based on bubble trail code + other stuff
|
||||
=================
|
||||
*/
|
||||
#define MAX_SPRAY_BURSTS 16
|
||||
void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum )
|
||||
{
|
||||
//vec3_t dir;
|
||||
vec3_t trueEnd;
|
||||
vec3_t move;
|
||||
vec3_t vec;
|
||||
vec3_t velocity;
|
||||
|
||||
localEntity_t *blood;
|
||||
float len;
|
||||
int i;
|
||||
int spacing = 30;
|
||||
int bloodCount = 0;
|
||||
|
||||
if ( !cg_blood.integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy (end, move);
|
||||
VectorSubtract (end, start, vec);
|
||||
|
||||
//Calculate true length via start/end points
|
||||
VectorCopy (vec, trueEnd);
|
||||
VectorNormalize (trueEnd);
|
||||
|
||||
//VectorScale (trueEnd, 300 + rand() % 100, trueEnd);
|
||||
//VectorAdd (end, trueEnd, trueEnd);
|
||||
VectorMA(end, 300 + rand() % 100, trueEnd, trueEnd);
|
||||
VectorSubtract (trueEnd, start, vec);
|
||||
|
||||
len = VectorNormalize (vec);
|
||||
|
||||
//Set velocity
|
||||
VectorScale(vec, 10, velocity);
|
||||
velocity[2] += 30;
|
||||
|
||||
// advance a random amount first
|
||||
i = rand() % (int)spacing;
|
||||
VectorMA( move, i, vec, move );
|
||||
VectorScale (vec, spacing, vec);
|
||||
|
||||
|
||||
for ( ; i < len; i += spacing )
|
||||
{
|
||||
//restrict amount of spurts
|
||||
if (bloodCount++ > MAX_SPRAY_BURSTS)
|
||||
break;
|
||||
|
||||
blood = CG_SmokePuff(move, velocity, 8,
|
||||
1, 1, 1, 1,
|
||||
1500 + rand() % 250,
|
||||
cg.time, 0,
|
||||
LEF_TUMBLE|LEF_PUFF_DONT_SCALE,
|
||||
cgs.media.bloodTrailShader);
|
||||
|
||||
blood->refEntity.rotation = rand() % 360;
|
||||
blood->leMarkType = LEMT_BLOOD;
|
||||
blood->leType = LE_FRAGMENT;
|
||||
blood->pos.trType = TR_GRAVITY;
|
||||
blood->bounceFactor = 0.4f;
|
||||
VectorAdd (move, vec, move);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Bleed
|
||||
|
@ -701,7 +774,8 @@ CG_LaunchGlass
|
|||
==================
|
||||
*/
|
||||
void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation,
|
||||
float bounce, qhandle_t hModel ) {
|
||||
float bounce, qhandle_t hModel )//, qhandle_t altSkin )
|
||||
{
|
||||
localEntity_t *le;
|
||||
refEntity_t *re;
|
||||
|
||||
|
@ -715,7 +789,12 @@ void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation,
|
|||
VectorCopy( origin, re->origin );
|
||||
AxisCopy( axisDefault, re->axis );
|
||||
re->hModel = hModel;
|
||||
|
||||
|
||||
//Elder: custom shaders for debris?
|
||||
//if (altSkin)
|
||||
//re->customSkin = altSkin;
|
||||
|
||||
|
||||
le->pos.trType = TR_GRAVITY;
|
||||
VectorCopy( origin, le->pos.trBase );
|
||||
VectorCopy( velocity, le->pos.trDelta );
|
||||
|
@ -729,11 +808,11 @@ void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation,
|
|||
le->angles.trTime = cg.time;
|
||||
|
||||
le->bounceFactor = bounce;
|
||||
|
||||
|
||||
le->leFlags = LEF_TUMBLE;
|
||||
le->leBounceSoundType = LEBS_BRASS;
|
||||
le->leMarkType = LEMT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
|
@ -762,22 +841,22 @@ void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type ) {
|
|||
(glassParm & RQ3_DEBRIS_HIGH) == RQ3_DEBRIS_HIGH)
|
||||
{
|
||||
//Tons
|
||||
count = 65 + rand() % 25;
|
||||
count = 65 + rand() % 16;
|
||||
}
|
||||
else if ( (glassParm & RQ3_DEBRIS_HIGH) == RQ3_DEBRIS_HIGH)
|
||||
{
|
||||
//Large
|
||||
count = 40 + rand() % 15;
|
||||
count = 40 + rand() % 11;
|
||||
}
|
||||
else if ( (glassParm & RQ3_DEBRIS_MEDIUM) == RQ3_DEBRIS_MEDIUM)
|
||||
{
|
||||
//Medium
|
||||
count = 22 + rand() % 7;
|
||||
count = 20 + rand() % 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Small
|
||||
count = 8 + rand() % 5;
|
||||
count = 8 + rand() % 6;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "cg_local.h"
|
||||
|
||||
static void CG_LaserSight( centity_t *cent );
|
||||
|
||||
/*
|
||||
======================
|
||||
|
@ -308,6 +309,12 @@ static void CG_Item( centity_t *cent ) {
|
|||
VectorNegate(ent.axis[2], ent.axis[1]);
|
||||
VectorCopy(myvec, ent.axis[2]);
|
||||
}
|
||||
else if (item->giType == IT_HOLDABLE &&
|
||||
(es->pos.trDelta[0] != 0 || es->pos.trDelta[1] != 0 || es->pos.trDelta[2] != 0))
|
||||
{
|
||||
VectorCopy( cg.autoAnglesFast, cent->lerpAngles );
|
||||
AxisCopy( cg.autoAxisFast, ent.axis );
|
||||
}
|
||||
|
||||
wi = NULL;
|
||||
// the weapons have their origin where they attatch to player
|
||||
|
@ -350,9 +357,11 @@ static void CG_Item( centity_t *cent ) {
|
|||
}
|
||||
}
|
||||
|
||||
//Elder: what the heck is this?
|
||||
//Elder: ammo offset?
|
||||
if (item->giType == IT_AMMO)
|
||||
cent->lerpOrigin[2]-=12;
|
||||
else if (item->giType == IT_HOLDABLE)
|
||||
cent->lerpOrigin[2] -= 12;
|
||||
|
||||
ent.hModel = cg_items[es->modelindex].models[0];
|
||||
|
||||
|
@ -781,7 +790,7 @@ static void CG_InterpolateEntityPosition( centity_t *cent ) {
|
|||
// it would be an internal error to find an entity that interpolates without
|
||||
// a snapshot ahead of the current one
|
||||
if ( cg.nextSnap == NULL ) {
|
||||
CG_Error( "CG_InterpoateEntityPosition: cg.nextSnap == NULL" );
|
||||
CG_Error( "CG_InterpolateEntityPosition: cg.nextSnap == NULL" );
|
||||
}
|
||||
|
||||
f = cg.frameInterpolation;
|
||||
|
@ -1058,6 +1067,12 @@ static void CG_AddCEntity( centity_t *cent ) {
|
|||
case ET_TEAM:
|
||||
CG_TeamBase( cent );
|
||||
break;
|
||||
case ET_LASER:
|
||||
//Elder: the local laser call is checked in playerstate unless it is disabled
|
||||
//if (!cg_RQ3_laserAssist.integer || cent->currentState.clientNum != cg.snap->ps.clientNum)
|
||||
CG_LaserSight( cent );
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1115,3 +1130,34 @@ void CG_AddPacketEntities( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_LaserSight
|
||||
|
||||
Creates the laser dot
|
||||
Elder's Note: Client does not use this if the dot is his/her own -- see CG_LocalLaser
|
||||
==================
|
||||
*/
|
||||
|
||||
static void CG_LaserSight( centity_t *cent ) {
|
||||
refEntity_t ent;
|
||||
|
||||
// create the reference entity
|
||||
memset (&ent, 0, sizeof(ent));
|
||||
|
||||
VectorCopy( cent->lerpOrigin, ent.origin);
|
||||
VectorCopy( cent->lerpOrigin, ent.oldorigin);
|
||||
|
||||
if (cent->currentState.eventParm == 1)
|
||||
{
|
||||
ent.reType = RT_SPRITE;
|
||||
ent.radius = 3;
|
||||
ent.rotation = 0;
|
||||
ent.customShader = cgs.media.laserShader;
|
||||
trap_R_AddRefEntityToScene( &ent );
|
||||
}
|
||||
else {
|
||||
trap_R_AddLightToScene(ent.origin, 200, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1700,7 +1700,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
break;
|
||||
case EV_FIRE_WEAPON:
|
||||
DEBUGNAME("EV_FIRE_WEAPON");
|
||||
CG_FireWeapon( cent );
|
||||
//Elder: modified
|
||||
CG_FireWeapon( cent, es->eventParm );
|
||||
break;
|
||||
|
||||
// Reaction Zoom
|
||||
|
@ -1892,14 +1893,23 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
case EV_BULLET_HIT_WALL:
|
||||
DEBUGNAME("EV_BULLET_HIT_WALL");
|
||||
ByteToDir( es->eventParm, dir );
|
||||
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD );
|
||||
//Elder: added additional param
|
||||
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, qfalse );
|
||||
break;
|
||||
|
||||
case EV_BULLET_HIT_FLESH:
|
||||
DEBUGNAME("EV_BULLET_HIT_FLESH");
|
||||
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm );
|
||||
//Elder: added additional param
|
||||
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm, qfalse );
|
||||
break;
|
||||
|
||||
case EV_SSG3000_HIT_FLESH:
|
||||
DEBUGNAME("EV_SSG3000_HIT_FLESH");
|
||||
//Elder: added additional param
|
||||
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm, qtrue );
|
||||
break;
|
||||
|
||||
|
||||
case EV_SHOTGUN:
|
||||
DEBUGNAME("EV_SHOTGUN");
|
||||
CG_ShotgunFire( es ,qtrue);
|
||||
|
@ -1950,6 +1960,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
//Global sound
|
||||
trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.media.lcaSound);
|
||||
break;
|
||||
case RQ3_SOUND_KEVLARHIT:
|
||||
//TODO: make sparks from hit position
|
||||
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,9 @@
|
|||
#define ZOOM_LEVELS 3
|
||||
#define ZOOM_PREPTIME 10 //milliseconds
|
||||
|
||||
//Elder: max number of "blood" marks when hitting a player w/ shell weapons
|
||||
#define MAX_SHELL_HITS 6
|
||||
|
||||
typedef enum {
|
||||
FOOTSTEP_NORMAL,
|
||||
FOOTSTEP_BOOT,
|
||||
|
@ -641,6 +644,10 @@ typedef struct {
|
|||
int sayTime;
|
||||
int sayCount;
|
||||
|
||||
int shellHits; //Count number of successful shell hits
|
||||
|
||||
qboolean laserSight; //Whether to draw local laser sight
|
||||
localEntity_t *laserEnt; //Local model -- NULL if not in-use
|
||||
|
||||
} cg_t;
|
||||
|
||||
|
@ -759,6 +766,9 @@ typedef struct {
|
|||
qhandle_t backTileShader;
|
||||
qhandle_t noammoShader;
|
||||
|
||||
//Elder: C3A Laser tutorial
|
||||
qhandle_t laserShader;
|
||||
|
||||
//Elder: sniper crosshairs
|
||||
qhandle_t ssgCrosshair[ZOOM_LEVELS];
|
||||
|
||||
|
@ -865,6 +875,9 @@ typedef struct {
|
|||
sfxHandle_t headshotSound; //Elder: splat
|
||||
sfxHandle_t lcaSound; //Elder: lights, camera, action!
|
||||
sfxHandle_t lensSound; //Elder: sniper lens zoom
|
||||
sfxHandle_t silencerSound;
|
||||
sfxHandle_t kevlarHitSound;
|
||||
|
||||
sfxHandle_t quadSound;
|
||||
sfxHandle_t tracerSound;
|
||||
sfxHandle_t selectSound;
|
||||
|
@ -1209,6 +1222,8 @@ extern vmCvar_t cg_RQ3_ssgColorB;
|
|||
extern vmCvar_t cg_RQ3_ssgColorA;
|
||||
//Elder: smoke puffs, sparks, etc.
|
||||
extern vmCvar_t cg_RQ3_impactEffects;
|
||||
//Elder: toggle client-side laser drawing
|
||||
extern vmCvar_t cg_RQ3_laserAssist;
|
||||
//Blaze: anouncer sounds
|
||||
extern vmCvar_t cg_RQ3_anouncer;
|
||||
|
||||
|
@ -1422,11 +1437,11 @@ void CG_RQ3_GrenadeMode();
|
|||
void CG_RegisterWeapon( int weaponNum );
|
||||
void CG_RegisterItemVisuals( int itemNum );
|
||||
|
||||
void CG_FireWeapon( centity_t *cent );
|
||||
void CG_FireWeapon( centity_t *cent, int weapModification );
|
||||
void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, impactSound_t soundType );
|
||||
void CG_MissileHitPlayer( int weapon, vec3_t origin, vec3_t dir, int entityNum );
|
||||
void CG_ShotgunFire( entityState_t *es, qboolean ism3 );
|
||||
void CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum );
|
||||
void CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum, qboolean armorPiercing );
|
||||
|
||||
void CG_RailTrail( clientInfo_t *ci, vec3_t start, vec3_t end );
|
||||
void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi );
|
||||
|
@ -1435,6 +1450,8 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
void CG_DrawWeaponSelect( void );
|
||||
|
||||
void CG_OutOfAmmoChange( void ); // should this be in pmove?
|
||||
void CG_CheckLaser (); //Elder: check laser to see if it's our own
|
||||
|
||||
|
||||
//
|
||||
// cg_marks.c
|
||||
|
@ -1484,6 +1501,8 @@ void CG_BigExplode( vec3_t playerOrigin );
|
|||
// Blaze: Breakable glass Elder: modified
|
||||
void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type );
|
||||
void CG_Bleed( vec3_t origin, int entityNum );
|
||||
//Elder: for SSG shots
|
||||
void CG_BleedSpray ( vec3_t origin, vec3_t dir, int entityNum );
|
||||
|
||||
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
|
||||
qhandle_t hModel, qhandle_t shader, int msec,
|
||||
|
|
|
@ -153,9 +153,10 @@ vmCvar_t cg_RQ3_ssgColorB;
|
|||
vmCvar_t cg_RQ3_ssgColorA;
|
||||
//Elder: smoke puffs, sparks, etc.
|
||||
vmCvar_t cg_RQ3_impactEffects;
|
||||
//Elder: toggle client-side laser drawing
|
||||
vmCvar_t cg_RQ3_laserAssist;
|
||||
//Blaze: anouncer sounds
|
||||
vmCvar_t cg_RQ3_anouncer;
|
||||
|
||||
vmCvar_t cg_drawFriend;
|
||||
vmCvar_t cg_teamChatsOnly;
|
||||
vmCvar_t cg_noVoiceChats;
|
||||
|
@ -318,8 +319,14 @@ cvarTable_t cvarTable[] = {
|
|||
{ &cg_RQ3_ssgColorG, "cg_RQ3_ssgColorG", "1.0", CVAR_ARCHIVE },
|
||||
{ &cg_RQ3_ssgColorB, "cg_RQ3_ssgColorB", "0.0", CVAR_ARCHIVE },
|
||||
{ &cg_RQ3_ssgColorA, "cg_RQ3_ssgColorA", "0.75", CVAR_ARCHIVE },
|
||||
<<<<<<< cg_main.c
|
||||
{ &cg_RQ3_impactEffects, "cg_RQ3_impactEffects", "1", CVAR_ARCHIVE },
|
||||
//Elder: toggle client-side laser drawing
|
||||
{ &cg_RQ3_laserAssist, "cg_RQ3_laserAssist", "0", CVAR_ARCHIVE }
|
||||
=======
|
||||
{ &cg_RQ3_impactEffects, "cg_RQ3_impactEffects", "1", CVAR_ARCHIVE },
|
||||
{ &cg_RQ3_anouncer, "cg_RQ3_anouncer", "1", CVAR_ARCHIVE },
|
||||
>>>>>>> 1.9
|
||||
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
|
||||
};
|
||||
|
||||
|
@ -640,7 +647,9 @@ static void CG_RegisterSounds( void ) {
|
|||
cgs.media.lensSound = trap_S_RegisterSound( "sound/misc/lens.wav", qfalse);
|
||||
cgs.media.headshotSound = trap_S_RegisterSound( "sound/misc/headshot.wav", qfalse);
|
||||
cgs.media.lcaSound = trap_S_RegisterSound( "sound/misc/lca.wav", qfalse);
|
||||
|
||||
cgs.media.silencerSound = trap_S_RegisterSound( "sound/misc/silencer.wav", qfalse);
|
||||
cgs.media.kevlarHitSound = trap_S_RegisterSound( "sound/misc/vest.wav", qfalse);
|
||||
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
cgs.media.useInvulnerabilitySound = trap_S_RegisterSound( "sound/items/invul_activate.wav", qfalse );
|
||||
|
@ -1049,6 +1058,9 @@ static void CG_RegisterGraphics( void ) {
|
|||
cgs.media.medalAssist = trap_R_RegisterShaderNoMip( "medal_assist" );
|
||||
cgs.media.medalCapture = trap_R_RegisterShaderNoMip( "medal_capture" );
|
||||
|
||||
//Elder: C3A laser tutorial
|
||||
cgs.media.laserShader = trap_R_RegisterShader( "sprites/laser" );
|
||||
|
||||
//Elder: added for sniper crosshairs
|
||||
cgs.media.ssgCrosshair[0] = trap_R_RegisterShaderNoMip( "gfx/rq3_hud/ssg2x" );
|
||||
cgs.media.ssgCrosshair[1] = trap_R_RegisterShaderNoMip( "gfx/rq3_hud/ssg4x" );
|
||||
|
|
|
@ -587,6 +587,5 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -942,6 +942,9 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
|
|||
}
|
||||
CG_AddViewWeapon( &cg.predictedPlayerState );
|
||||
|
||||
//Elder: check local laser status
|
||||
//CG_CheckLaser();
|
||||
|
||||
// add buffered sounds
|
||||
CG_PlayBufferedSounds();
|
||||
|
||||
|
|
|
@ -2015,7 +2015,7 @@ CG_FireWeapon
|
|||
Caused by an EV_FIRE_WEAPON event
|
||||
================
|
||||
*/
|
||||
void CG_FireWeapon( centity_t *cent ) {
|
||||
void CG_FireWeapon( centity_t *cent, int weapModification ) {
|
||||
entityState_t *ent;
|
||||
int c;
|
||||
weaponInfo_t *weap;
|
||||
|
@ -2054,7 +2054,10 @@ void CG_FireWeapon( centity_t *cent ) {
|
|||
|
||||
// mark the entity as muzzle flashing, so when it is added it will
|
||||
// append the flash to the weapon model
|
||||
cent->muzzleFlashTime = cg.time;
|
||||
if (weapModification != RQ3_WPMOD_SILENCER)
|
||||
{
|
||||
cent->muzzleFlashTime = cg.time;
|
||||
}
|
||||
|
||||
// lightning gun only does this this on initial press
|
||||
//Blaze: no more Lighting gun
|
||||
|
@ -2071,7 +2074,13 @@ void CG_FireWeapon( centity_t *cent ) {
|
|||
trap_S_StartSound (NULL, cent->currentState.number, CHAN_ITEM, cgs.media.quadSound );
|
||||
}
|
||||
|
||||
|
||||
//Elder: silencer stuff
|
||||
if (weapModification == RQ3_WPMOD_SILENCER)
|
||||
{
|
||||
trap_S_StartSound( NULL, ent->number, CHAN_WEAPON, cgs.media.silencerSound );
|
||||
}
|
||||
else
|
||||
{
|
||||
// play a sound
|
||||
for ( c = 0 ; c < 4 ; c++ ) {
|
||||
if ( !weap->flashSound[c] ) {
|
||||
|
@ -2086,7 +2095,7 @@ void CG_FireWeapon( centity_t *cent ) {
|
|||
trap_S_StartSound( NULL, ent->number, CHAN_WEAPON, weap->flashSound[c] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// do brass ejection
|
||||
if ( weap->ejectBrassFunc && cg_brassTime.integer > 0 ) {
|
||||
weap->ejectBrassFunc( cent );
|
||||
|
@ -2523,27 +2532,39 @@ static void CG_ShotgunPellet( vec3_t start, vec3_t end, int skipNum, int shellWe
|
|||
return;
|
||||
}
|
||||
|
||||
if ( cg_entities[tr.entityNum].currentState.eType == ET_PLAYER ) {
|
||||
if ( cg_entities[tr.entityNum].currentState.eType == ET_PLAYER )
|
||||
{
|
||||
//Blaze: Changed WP_SHOTGUN to WP_M3
|
||||
CG_MissileHitPlayer( WP_M3, tr.endpos, tr.plane.normal, tr.entityNum );
|
||||
} else {
|
||||
if ( tr.surfaceFlags & SURF_NOIMPACT ) {
|
||||
//Elder: don't display so many blood stains - so we can reduce slow down
|
||||
cg.shellHits++;
|
||||
if (cg.shellHits < MAX_SHELL_HITS)
|
||||
CG_MissileHitPlayer( WP_M3, tr.endpos, tr.plane.normal, tr.entityNum );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( tr.surfaceFlags & SURF_NOIMPACT )
|
||||
{
|
||||
// SURF_NOIMPACT will not make a flame puff or a mark
|
||||
return;
|
||||
}
|
||||
if ( tr.surfaceFlags & SURF_METALSTEPS ) {
|
||||
if ( tr.surfaceFlags & SURF_METALSTEPS )
|
||||
{
|
||||
//Blaze: Changed WP_SHOTGUN to WP_M3
|
||||
if (shellWeapon == WP_M3)
|
||||
CG_MissileHitWall( WP_M3, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_METAL );
|
||||
else if (shellWeapon == WP_HANDCANNON && crandom() > 0.5) {
|
||||
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_METAL );
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//Blaze: Changed WP_SHOTGUN to WP_M3
|
||||
if (shellWeapon == WP_M3)
|
||||
CG_MissileHitWall( WP_M3, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_DEFAULT );
|
||||
else if (shellWeapon == WP_HANDCANNON && crandom() > 0.5) {
|
||||
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_DEFAULT );
|
||||
}
|
||||
|
@ -2590,7 +2611,7 @@ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, i
|
|||
hc_multipler = 5;
|
||||
}
|
||||
|
||||
|
||||
cg.shellHits = 0;
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
if (shotType == WP_M3)
|
||||
{
|
||||
|
@ -2616,6 +2637,8 @@ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, i
|
|||
|
||||
CG_ShotgunPellet( origin, end, otherEntNum, shotType );
|
||||
}
|
||||
//Reset shellHits once we're finished with it
|
||||
cg.shellHits = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2788,9 +2811,11 @@ static qboolean CG_CalcMuzzlePoint( int entityNum, vec3_t muzzle ) {
|
|||
CG_Bullet
|
||||
|
||||
Renders bullet effects.
|
||||
Elder: added armorPiercing conditional
|
||||
======================
|
||||
*/
|
||||
void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum ) {
|
||||
void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal,
|
||||
qboolean flesh, int fleshEntityNum, qboolean armorPiercing ) {
|
||||
trace_t trace;
|
||||
int sourceContentType, destContentType;
|
||||
vec3_t start;
|
||||
|
@ -2826,10 +2851,110 @@ void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, qboolean flesh,
|
|||
|
||||
// impact splash and mark
|
||||
if ( flesh ) {
|
||||
CG_Bleed( end, fleshEntityNum );
|
||||
//Elder: added
|
||||
if ( armorPiercing && CG_CalcMuzzlePoint( sourceEntityNum, start))
|
||||
CG_BleedSpray(start, end, fleshEntityNum);
|
||||
else
|
||||
CG_Bleed( end, fleshEntityNum );
|
||||
} else {
|
||||
//Blaze: Changed WP_MACHINEGUN to WP_PISTOL
|
||||
CG_MissileHitWall( WP_PISTOL, 0, end, normal, IMPACTSOUND_DEFAULT );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CG_LocalLaser
|
||||
|
||||
Elder:
|
||||
Local laser dot if it is the client's own laser
|
||||
==================
|
||||
*/
|
||||
static void CG_LocalLaser ()
|
||||
{
|
||||
vec3_t muzzle;
|
||||
vec3_t forward;
|
||||
vec3_t end;
|
||||
refEntity_t *re;
|
||||
trace_t tr;
|
||||
|
||||
//Create the laser entity if it's not there
|
||||
if (cg.laserSight == qfalse)
|
||||
{
|
||||
CG_Printf("Initializing Local Laser...\n");
|
||||
|
||||
cg.laserSight = qtrue;
|
||||
cg.laserEnt = CG_AllocLocalEntity();
|
||||
cg.laserEnt->startTime = cg.time;
|
||||
cg.laserEnt->color[3] = 1.0;
|
||||
//cg.laserEnt->pos.trType = TR_INTERPOLATE;
|
||||
}
|
||||
|
||||
//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
|
||||
if (CG_CalcMuzzlePoint(cg.snap->ps.clientNum, muzzle))
|
||||
{
|
||||
AngleVectors( cg.snap->ps.viewangles, forward, NULL, NULL );
|
||||
VectorMA( muzzle, 8192 * 16, forward, end );
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_Error("CG_LocalLaser: Could not calculate own muzzle point\n");
|
||||
}
|
||||
|
||||
CG_Trace(&tr, muzzle, NULL, NULL, end, cg.predictedPlayerState.clientNum, CONTENTS_SOLID);
|
||||
|
||||
//Set position of laser dot
|
||||
if (tr.fraction != 1)
|
||||
VectorMA(tr.endpos,-4, forward, tr.endpos);
|
||||
|
||||
|
||||
VectorCopy(tr.endpos, re->origin);
|
||||
//VectorCopy(tr.endpos, cg.laserEnt->pos.trBase);
|
||||
//BG_EvaluateTrajectory(&cg.laserEnt->pos, cg.time, re->origin);
|
||||
|
||||
//Boost the endTime
|
||||
cg.laserEnt->endTime += 10000;
|
||||
|
||||
//if (tr.surfaceFlags & SURF_NOIMPACT || tr.surfaceFlags & SURF_SKY)
|
||||
//Don't render if it hits the sky
|
||||
//if (!(tr.surfaceFlags & SURF_SKY))
|
||||
trap_R_AddRefEntityToScene( re );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
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
|
||||
if (bg_itemlist[cg.snap->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER &&
|
||||
cg_RQ3_laserAssist.integer &&
|
||||
(cg.snap->ps.weapon == WP_PISTOL ||
|
||||
cg.snap->ps.weapon == WP_MP5 ||
|
||||
cg.snap->ps.weapon == WP_M4))
|
||||
{
|
||||
CG_LocalLaser();
|
||||
}
|
||||
//Disable laser
|
||||
else if (cg.laserSight == qtrue)
|
||||
{
|
||||
CG_Printf("Destroying Local Laser...\n");
|
||||
CG_FreeLocalEntity(cg.laserEnt);
|
||||
cg.laserSight = qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ extern int c_pmove;
|
|||
void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce );
|
||||
void PM_AddTouchEnt( int entityNum );
|
||||
void PM_AddEvent( int newEvent );
|
||||
//Elder: added
|
||||
void PM_AddEvent2( int newEvent, int eventParm );
|
||||
|
||||
qboolean PM_SlideMove( qboolean gravity );
|
||||
void PM_StepSlideMove( qboolean gravity );
|
||||
|
|
|
@ -329,10 +329,10 @@ gitem_t bg_itemlist[] =
|
|||
//
|
||||
// AMMO ITEMS
|
||||
//
|
||||
/*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
/*QUAKED ammo_mk23 (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
*/
|
||||
{
|
||||
"ammo_bullets",
|
||||
"ammo_mk23",
|
||||
"sound/misc/am_pkup.wav",
|
||||
{ "models/ammo/mk23.md3",
|
||||
0, 0, 0},
|
||||
|
@ -351,28 +351,28 @@ gitem_t bg_itemlist[] =
|
|||
{
|
||||
"ammo_shells",
|
||||
"sound/misc/am_pkup.wav",
|
||||
{ "models/ammo/m4.md3",
|
||||
{ "models/ammo/m3.md3",
|
||||
0, 0, 0},
|
||||
/* icon */ "icons/icona_m4clip",
|
||||
/* pickup */ "M4 Clip",
|
||||
1,
|
||||
/* icon */ "icons/icona_shells",
|
||||
/* pickup */ "Shotgun Shells",
|
||||
7,
|
||||
IT_AMMO,
|
||||
//Blaze: changed from WP_SHOTGUN to WP_M4
|
||||
WP_M4,
|
||||
//Blaze: Changed from WP_ROCKET_LAUNCHER to WP_SHOTGUN
|
||||
WP_M3,
|
||||
/* precache */ "",
|
||||
/* sounds */ ""
|
||||
},
|
||||
|
||||
|
||||
/*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
/*QUAKED ammo_ssg3000 (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
*/
|
||||
{
|
||||
"ammo_slugs",
|
||||
"ammo_ssg3000",
|
||||
"sound/misc/am_pkup.wav",
|
||||
{ "models/ammo/ssg3000.md3",
|
||||
0, 0, 0},
|
||||
/* icon */ "icons/icona_ssgammo",
|
||||
/* pickup */ "Sniper Ammo",
|
||||
/* pickup */ "AP Sniper Ammo",
|
||||
10,
|
||||
IT_AMMO,
|
||||
//Blaze: Changed from WP_RAILGUN to WP_GRENADE
|
||||
|
@ -381,10 +381,10 @@ gitem_t bg_itemlist[] =
|
|||
/* sounds */ ""
|
||||
},
|
||||
|
||||
/*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
/*QUAKED ammo_mp5 (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
*/
|
||||
{
|
||||
"ammo_cells",
|
||||
"ammo_mp5",
|
||||
"sound/misc/am_pkup.wav",
|
||||
{ "models/ammo/mp5.md3",
|
||||
0, 0, 0},
|
||||
|
@ -416,6 +416,7 @@ gitem_t bg_itemlist[] =
|
|||
/* sounds */ //""
|
||||
// },
|
||||
|
||||
//Elder: just leaving this in for now
|
||||
/*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
*/
|
||||
{
|
||||
|
@ -433,6 +434,23 @@ gitem_t bg_itemlist[] =
|
|||
/* sounds */ ""
|
||||
},
|
||||
|
||||
/*QUAKED ammo_m4 (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
|
||||
*/
|
||||
{
|
||||
"ammo_m4",
|
||||
"sound/misc/am_pkup.wav",
|
||||
{ "models/ammo/m4.md3",
|
||||
0, 0, 0},
|
||||
/* icon */ "icons/icona_m4clip",
|
||||
/* pickup */ "M4 Clip",
|
||||
1,
|
||||
IT_AMMO,
|
||||
//Blaze: changed from WP_SHOTGUN to WP_M4
|
||||
WP_M4,
|
||||
/* precache */ "",
|
||||
/* sounds */ ""
|
||||
},
|
||||
|
||||
|
||||
/*QUAKED team_CTF_redflag (1 0 0) (-16 -16 -16) (16 16 16)
|
||||
Only in CTF games
|
||||
|
@ -1318,6 +1336,7 @@ char *eventnames[] = {
|
|||
|
||||
"EV_BULLET_HIT_FLESH",
|
||||
"EV_BULLET_HIT_WALL",
|
||||
"EV_SSG3000_HIT_FLESH", //Elder: SSG3000 blood spray
|
||||
|
||||
"EV_MISSILE_HIT",
|
||||
"EV_MISSILE_MISS",
|
||||
|
|
|
@ -104,6 +104,17 @@ void PM_AddEvent( int newEvent ) {
|
|||
BG_AddPredictableEventToPlayerstate( newEvent, 0, pm->ps );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_AddEvent
|
||||
|
||||
Elder: stuffs event parameters
|
||||
===============
|
||||
*/
|
||||
void PM_AddEvent2( int newEvent, int eventParm ) {
|
||||
BG_AddPredictableEventToPlayerstate( newEvent, eventParm, pm->ps );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_AddTouchEnt
|
||||
|
@ -1907,14 +1918,16 @@ static void PM_Weapon( void ) {
|
|||
}
|
||||
|
||||
// check for item using
|
||||
// Elder: removed
|
||||
/*
|
||||
if ( pm->cmd.buttons & BUTTON_USE_HOLDABLE ) {
|
||||
if ( ! ( pm->ps->pm_flags & PMF_USE_ITEM_HELD ) ) {
|
||||
|
||||
/* Blaze: No more medkit
|
||||
if ( bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_MEDKIT
|
||||
&& pm->ps->stats[STAT_HEALTH] >= (125) ) { //medikit check pm->ps->stats[STAT_MAX_HEALTH] + 25) ) {
|
||||
// Blaze: No more medkit
|
||||
//if ( bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_MEDKIT
|
||||
//&& pm->ps->stats[STAT_HEALTH] >= (125) ) { //medikit check pm->ps->stats[STAT_MAX_HEALTH] + 25) ) {
|
||||
// don't use medkit if at max health
|
||||
} else {*/
|
||||
//} else {
|
||||
pm->ps->pm_flags |= PMF_USE_ITEM_HELD;
|
||||
PM_AddEvent( EV_USE_ITEM0 + bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag );
|
||||
pm->ps->stats[STAT_HOLDABLE_ITEM] = 0;
|
||||
|
@ -1924,6 +1937,7 @@ static void PM_Weapon( void ) {
|
|||
} else {
|
||||
pm->ps->pm_flags &= ~PMF_USE_ITEM_HELD;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// make weapon function
|
||||
|
@ -2144,7 +2158,16 @@ static void PM_Weapon( void ) {
|
|||
|
||||
|
||||
// fire weapon
|
||||
PM_AddEvent( EV_FIRE_WEAPON );
|
||||
//Elder: check for silencer
|
||||
if (bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_SILENCER &&
|
||||
(pm->ps->weapon == WP_PISTOL ||
|
||||
pm->ps->weapon == WP_MP5 ||
|
||||
pm->ps->weapon == WP_SSG3000))
|
||||
{
|
||||
PM_AddEvent2( EV_FIRE_WEAPON, RQ3_WPMOD_SILENCER );
|
||||
}
|
||||
else
|
||||
PM_AddEvent( EV_FIRE_WEAPON );
|
||||
|
||||
switch( pm->ps->weapon ) {
|
||||
default:
|
||||
|
|
|
@ -42,10 +42,13 @@
|
|||
|
||||
#define MINS_Z -24
|
||||
#define DEFAULT_VIEWHEIGHT 26
|
||||
#define CROUCH_VIEWHEIGHT 12
|
||||
//Elder: changed to 8 like AQ2 source BUT is it sync-ed?
|
||||
#define CROUCH_VIEWHEIGHT 8
|
||||
//#define CROUCH_VIEWHEIGHT 12
|
||||
#define DEAD_VIEWHEIGHT -16
|
||||
|
||||
//Elder: New breakable bit definitions
|
||||
//Enum materials?
|
||||
//No amount bits = Low ... both amount bits = Tons
|
||||
#define RQ3_DEBRIS_MEDIUM 0x00000001
|
||||
#define RQ3_DEBRIS_HIGH 0x00000002
|
||||
|
@ -154,10 +157,20 @@
|
|||
#define RQ3_LASER_NAME "Lasersight"
|
||||
|
||||
//Elder: sound events for EV_RQ3_SOUND
|
||||
#define RQ3_SOUND_KICK 0
|
||||
#define RQ3_SOUND_HEADSHOT 1
|
||||
#define RQ3_SOUND_KNIFEDEATH 2
|
||||
#define RQ3_SOUND_LCA 3 //lights, camera, action!
|
||||
typedef enum {
|
||||
RQ3_SOUND_KICK,
|
||||
RQ3_SOUND_HEADSHOT,
|
||||
RQ3_SOUND_KNIFEDEATH,
|
||||
RQ3_SOUND_LCA, //lights, camera, action!
|
||||
RQ3_SOUND_KEVLARHIT,
|
||||
|
||||
RQ3_SOUND_TOTAL
|
||||
} rq3_sounds_t;
|
||||
|
||||
//#define RQ3_SOUND_KICK 0
|
||||
//#define RQ3_SOUND_HEADSHOT 1
|
||||
//#define RQ3_SOUND_KNIFEDEATH 2
|
||||
//#define RQ3_SOUND_LCA 3 //lights, camera, action!
|
||||
|
||||
//Elder: Weapon damage and spread stats
|
||||
#define PISTOL_DAMAGE 90
|
||||
|
@ -270,6 +283,8 @@
|
|||
//Elder: special flag needed in both games
|
||||
#define FL_THROWN_KNIFE 0x00040000 // Elder: thrown knife special case
|
||||
|
||||
//Elder: weapon modifications -- right now only silencer
|
||||
#define RQ3_WPMOD_SILENCER 1
|
||||
|
||||
//
|
||||
// config strings are a general means of communicating variable length strings
|
||||
|
@ -430,25 +445,26 @@ void Pmove (pmove_t *pmove);
|
|||
// NOTE: may not have more than 16
|
||||
typedef enum {
|
||||
STAT_HEALTH,
|
||||
STAT_HOLDABLE_ITEM,
|
||||
STAT_HOLDABLE_ITEM, // Elder: Used to hold unique items in Reaction
|
||||
#ifdef MISSIONPACK
|
||||
STAT_PERSISTANT_POWERUP,
|
||||
#endif
|
||||
STAT_WEAPONS, // 16 bit fields
|
||||
STAT_ARMOR, // Elder: technically we don't need this anymore - maybe for vest
|
||||
STAT_DEAD_YAW, // look this direction when dead (FIXME: get rid of?)
|
||||
// Begin Duffman
|
||||
|
||||
|
||||
STAT_CLIENTS_READY, // bit mask of clients wishing to exit the intermission (FIXME: configstring?)
|
||||
// STAT_MAX_HEALTH, // health / armor limit, changable by handicap
|
||||
|
||||
//These are RQ3-related specific stats
|
||||
STAT_CLIPS, // Num Clips player currently has
|
||||
STAT_STREAK,
|
||||
// End Duffman
|
||||
// Homer: for bursting
|
||||
STAT_BURST, // number of shots in burst
|
||||
STAT_CLIENTS_READY, // bit mask of clients wishing to exit the intermission (FIXME: configstring?)
|
||||
// STAT_MAX_HEALTH, // health / armor limit, changable by handicap
|
||||
STAT_JUMPTIME, //Blaze RE: Double jump
|
||||
STAT_UNIQUEWEAPONS,
|
||||
STAT_BURST, // number of shots in burst
|
||||
STAT_JUMPTIME, // Blaze RE: Double jump
|
||||
//STAT_UNIQUEWEAPONS, // Elder - wasteful stat - moved to gclient_s
|
||||
STAT_FALLDAMAGE,
|
||||
STAT_RQ3, //Blaze: Will hold a few flags for bandage, etc info
|
||||
STAT_RQ3, // Blaze: Will hold a few flags for bandage, etc info
|
||||
} statIndex_t;
|
||||
|
||||
//STAT_RQ3 stat info
|
||||
|
@ -547,6 +563,7 @@ typedef enum {
|
|||
typedef enum {
|
||||
HI_NONE,
|
||||
|
||||
//TODO: remove the baseQ3 ones
|
||||
HI_TELEPORTER,
|
||||
HI_MEDKIT,
|
||||
HI_KAMIKAZE,
|
||||
|
@ -681,6 +698,7 @@ typedef enum {
|
|||
|
||||
EV_BULLET_HIT_FLESH,
|
||||
EV_BULLET_HIT_WALL,
|
||||
EV_SSG3000_HIT_FLESH,
|
||||
|
||||
EV_MISSILE_HIT,
|
||||
EV_MISSILE_MISS,
|
||||
|
@ -1008,6 +1026,7 @@ typedef enum {
|
|||
ET_INVISIBLE,
|
||||
ET_GRAPPLE, // grapple hooked on wall
|
||||
ET_TEAM,
|
||||
ET_LASER, // lasersight entity type
|
||||
|
||||
ET_EVENTS // any of the EV_* events can be added freestanding
|
||||
// by setting eType to ET_EVENTS + eventNum
|
||||
|
|
|
@ -22,6 +22,7 @@ global pain sound events for all clients.
|
|||
===============
|
||||
*/
|
||||
void P_DamageFeedback( gentity_t *player ) {
|
||||
gentity_t *tent;
|
||||
gclient_t *client;
|
||||
float count, side;
|
||||
vec3_t angles, v;
|
||||
|
@ -127,10 +128,21 @@ void P_DamageFeedback( gentity_t *player ) {
|
|||
//Elder: headshot sound
|
||||
case LOCATION_HEAD:
|
||||
case LOCATION_FACE:
|
||||
tent = G_TempEntity2(client->ps.origin, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
|
||||
//Elder: takes more bandwidth but guarantees a headshot sound
|
||||
G_Sound(player, CHAN_AUTO, G_SoundIndex("sound/misc/headshot.wav"));
|
||||
//G_Sound(player, CHAN_AUTO, G_SoundIndex("sound/misc/headshot.wav"));
|
||||
//G_AddEvent ( player, EV_RQ3_SOUND, RQ3_SOUND_HEADSHOT);
|
||||
break;
|
||||
case LOCATION_CHEST:
|
||||
//Play metal impact if vest was hit
|
||||
if (client->damage_vest == qtrue)
|
||||
{
|
||||
tent = G_TempEntity2(client->ps.origin, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT);
|
||||
client->damage_vest = qfalse;
|
||||
}
|
||||
else
|
||||
G_AddEvent( player, EV_PAIN, player->health );
|
||||
break;
|
||||
default:
|
||||
G_AddEvent( player, EV_PAIN, player->health );
|
||||
break;
|
||||
|
@ -828,6 +840,7 @@ static int StuckInOtherClient(gentity_t *ent) {
|
|||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ThrowWeapon
|
||||
|
@ -867,7 +880,7 @@ void ThrowWeapon( gentity_t *ent )
|
|||
|
||||
|
||||
weap = 0;
|
||||
if (client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
|
||||
if (client->uniqueWeapons > 0)
|
||||
{
|
||||
weap = client->ps.stats[STAT_WEAPONS];
|
||||
if ((client->ps.stats[STAT_WEAPONS] & (1 << WP_M4) ) == (1 << WP_M4))
|
||||
|
@ -893,10 +906,58 @@ void ThrowWeapon( gentity_t *ent )
|
|||
client->ps.stats[STAT_WEAPONS] &= ~( 1 << weap);
|
||||
xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );
|
||||
xr_drop->count= -1; // XRAY FMJ 0 is already taken, -1 means no ammo
|
||||
client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
client->uniqueWeapons--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ThrowItem
|
||||
|
||||
Used to toss an item much like weapons except a bit leaner
|
||||
=============
|
||||
*/
|
||||
|
||||
void ThrowItem( gentity_t *ent )
|
||||
{
|
||||
gclient_t *client;
|
||||
usercmd_t *ucmd;
|
||||
gitem_t *xr_item;
|
||||
gentity_t *xr_drop;
|
||||
int item;
|
||||
|
||||
client = ent->client;
|
||||
ucmd = &ent->client->pers.cmd;
|
||||
|
||||
//Elder: TODO: have to add a reloading case:
|
||||
//itemonTime > 0 or itemonState == itemon_dropping? Or both?
|
||||
//Still firing
|
||||
if ( (ucmd->buttons & BUTTON_ATTACK) == BUTTON_ATTACK || client->ps.weaponTime > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Elder: Bandaging case
|
||||
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging...\n\""));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//item = 0;
|
||||
if (client->uniqueItems > 0)
|
||||
{
|
||||
item = bg_itemlist[client->ps.stats[STAT_HOLDABLE_ITEM]].giTag;
|
||||
xr_item = BG_FindItemForHoldable( item );
|
||||
client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
|
||||
//Elder: Just going to re-use the dropWeapon function
|
||||
xr_drop= dropWeapon( ent, xr_item, 0, FL_DROPPED_ITEM | FL_THROWN_ITEM );
|
||||
xr_drop->count= -1; // XRAY FMJ 0 is already taken, -1 means no ammo
|
||||
client->uniqueItems--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Elder: wtf?
|
||||
void BotTestSolid(vec3_t origin);
|
||||
|
||||
/*
|
||||
|
@ -1396,9 +1457,9 @@ while a slow client may have multiple ClientEndFrame between ClientThink.
|
|||
void ClientEndFrame( gentity_t *ent ) {
|
||||
int i;
|
||||
clientPersistant_t *pers;
|
||||
gitem_t *rq3_item;
|
||||
gentity_t *rq3_temp;
|
||||
vec3_t spawn_origin, spawn_angles;
|
||||
// gitem_t *rq3_item;
|
||||
// gentity_t *rq3_temp;
|
||||
//vec3_t spawn_origin, spawn_angles;
|
||||
if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
|
||||
SpectatorClientEndFrame( ent );
|
||||
return;
|
||||
|
@ -1466,14 +1527,9 @@ void ClientEndFrame( gentity_t *ent ) {
|
|||
// Blaze: Do Bleed
|
||||
// if(ent->client->bleeding)
|
||||
// CheckBleeding(ent); // perform once-a-second actions
|
||||
if (level.time % 30000 < 1)
|
||||
{
|
||||
G_Printf("Spawn an Item\n");
|
||||
//rq3_item = BG_FindItem( "Kevlar Vest" );
|
||||
rq3_item = BG_FindItemForHoldable( HI_SLIPPERS );
|
||||
rq3_temp = SelectSpawnPoint(ent->client->ps.origin,spawn_origin, spawn_angles);
|
||||
Drop_Item (rq3_temp, rq3_item, 0);
|
||||
}
|
||||
|
||||
//Elder: moved unique item spawning to new function called RQ3_CheckUniqueItems
|
||||
|
||||
// Begin Duffman
|
||||
//Update the clips Amount in weapon for the client
|
||||
ent->client->ps.stats[STAT_CLIPS] = ent->client->numClips[ent->client->ps.weapon];
|
||||
|
@ -1510,7 +1566,32 @@ void ClientEndFrame( gentity_t *ent ) {
|
|||
ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - ent->client->consecutiveShots * -0.7);
|
||||
ent->client->consecutiveShots = 0;
|
||||
}
|
||||
|
||||
|
||||
if ( bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER )
|
||||
{
|
||||
//Disable laser if switching weapons, bandaging, etc.
|
||||
if (ent->client->lasersight && ent->client->ps.weaponstate == WEAPON_DROPPING)
|
||||
{
|
||||
Laser_Gen(ent, qfalse);
|
||||
}
|
||||
//Using M4/MP5/MK23 but not on yet so turn it on
|
||||
else if (ent->client->lasersight == NULL &&
|
||||
(ent->client->ps.weapon == WP_M4 ||
|
||||
ent->client->ps.weapon == WP_MP5 ||
|
||||
ent->client->ps.weapon == WP_PISTOL))
|
||||
{
|
||||
Laser_Gen(ent, qtrue);
|
||||
}
|
||||
//Not using M4/MP5/MK23 -- turn it off
|
||||
else if (ent->client->lasersight &&
|
||||
!( ent->client->ps.weapon == WP_M4 ||
|
||||
ent->client->ps.weapon == WP_MP5 ||
|
||||
ent->client->ps.weapon == WP_PISTOL))
|
||||
{
|
||||
Laser_Gen(ent, qfalse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G_SetClientSound (ent);
|
||||
|
||||
|
|
|
@ -1692,7 +1692,7 @@ void Cmd_Reload( gentity_t *ent ) {
|
|||
int ammotoadd;
|
||||
int delay = 0;
|
||||
|
||||
G_Printf("(%i) Cmd_Reload: Attempting reload\n", ent->s.clientNum);
|
||||
//G_Printf("(%i) Cmd_Reload: Attempting reload\n", ent->s.clientNum);
|
||||
|
||||
//Elder: added for redundant check but shouldn't need to come here - handled in cgame
|
||||
//if (ent->client->isBandaging == qtrue) {
|
||||
|
@ -2292,10 +2292,10 @@ void Cmd_Unzoom(gentity_t *ent)
|
|||
|
||||
/*
|
||||
=================
|
||||
Cmd_Drop_f XRAY FMJ
|
||||
Cmd_DropWeapon_f XRAY FMJ
|
||||
=================
|
||||
*/
|
||||
void Cmd_Drop_f( gentity_t *ent ) {
|
||||
void Cmd_DropWeapon_f( gentity_t *ent ) {
|
||||
|
||||
//Elder: added
|
||||
//if (ent->client->isBandaging == qtrue) {
|
||||
|
@ -2314,6 +2314,49 @@ void Cmd_Drop_f( gentity_t *ent ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_DropItem_f
|
||||
=================
|
||||
*/
|
||||
void Cmd_DropItem_f( gentity_t *ent )
|
||||
{
|
||||
if ( (ent->client->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK)
|
||||
{
|
||||
trap_SendServerCommand( ent-g_entities, va("print \"You are too busy bandaging!\n\""));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Elder: reset item totals if using bandolier
|
||||
if (bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_BANDOLIER)
|
||||
{
|
||||
if (ent->client->numClips[WP_PISTOL] > RQ3_PISTOL_MAXCLIP)
|
||||
{
|
||||
ent->client->numClips[WP_PISTOL] = RQ3_PISTOL_MAXCLIP;
|
||||
ent->client->numClips[WP_AKIMBO] = RQ3_PISTOL_MAXCLIP;
|
||||
}
|
||||
if (ent->client->numClips[WP_M3] > RQ3_M3_MAXCLIP)
|
||||
{
|
||||
ent->client->numClips[WP_M3] = RQ3_M3_MAXCLIP;
|
||||
ent->client->numClips[WP_HANDCANNON] = RQ3_M3_MAXCLIP;
|
||||
}
|
||||
if (ent->client->numClips[WP_M4] > RQ3_M4_MAXCLIP)
|
||||
ent->client->numClips[WP_M4] = RQ3_M4_MAXCLIP;
|
||||
if (ent->client->numClips[WP_MP5] > RQ3_MP5_MAXCLIP)
|
||||
ent->client->numClips[WP_MP5] = RQ3_MP5_MAXCLIP;
|
||||
if (ent->client->numClips[WP_KNIFE] > RQ3_KNIFE_MAXCLIP)
|
||||
ent->client->numClips[WP_KNIFE] = RQ3_KNIFE_MAXCLIP;
|
||||
if (ent->client->numClips[WP_GRENADE] > RQ3_GRENADE_MAXCLIP)
|
||||
ent->client->numClips[WP_GRENADE] = RQ3_GRENADE_MAXCLIP;
|
||||
}
|
||||
else if (bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER)
|
||||
Laser_Gen(ent, qfalse);
|
||||
|
||||
ThrowItem( ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -2427,7 +2470,7 @@ void ClientCommand( int clientNum ) {
|
|||
//Elder: add to reload queue if using fast-reloadable weapons
|
||||
if (ent->client->ps.weapon == WP_M3 || ent->client->ps.weapon == WP_SSG3000)
|
||||
ent->client->reloadAttempts++;
|
||||
G_Printf("Trying a reload...\n");
|
||||
//G_Printf("Trying a reload...\n");
|
||||
Cmd_Reload( ent );
|
||||
}
|
||||
// End Duffman
|
||||
|
@ -2445,7 +2488,10 @@ void ClientCommand( int clientNum ) {
|
|||
Cmd_Unzoom (ent);
|
||||
// end hawkins
|
||||
else if (Q_stricmp (cmd, "dropweapon") == 0) // XRAY FMJ
|
||||
Cmd_Drop_f( ent );
|
||||
Cmd_DropWeapon_f( ent );
|
||||
//Elder: stuff for dropping items
|
||||
else if (Q_stricmp (cmd, "dropitem") == 0)
|
||||
Cmd_DropItem_f( ent );
|
||||
else
|
||||
trap_SendServerCommand( clientNum, va("print \"unknown cmd %s\n\"", cmd ) );
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ void TossClientItems( gentity_t *self ) {
|
|||
item = BG_FindItemForWeapon( WP_M3 );
|
||||
Drop_Item( self, item, angle);
|
||||
self->client->pers.hadUniqueWeapon[ WP_M3 ] = qfalse;
|
||||
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
self->client->uniqueWeapons--;
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ void TossClientItems( gentity_t *self ) {
|
|||
item = BG_FindItemForWeapon( WP_M4 );
|
||||
Drop_Item( self, item, angle);
|
||||
self->client->pers.hadUniqueWeapon[ WP_M4 ] = qfalse;
|
||||
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
self->client->uniqueWeapons--;
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ void TossClientItems( gentity_t *self ) {
|
|||
item = BG_FindItemForWeapon( WP_MP5 );
|
||||
Drop_Item( self, item, angle);
|
||||
self->client->pers.hadUniqueWeapon[ WP_MP5 ] = qfalse;
|
||||
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
self->client->uniqueWeapons--;
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ void TossClientItems( gentity_t *self ) {
|
|||
item = BG_FindItemForWeapon( WP_HANDCANNON );
|
||||
Drop_Item( self, item, angle);
|
||||
self->client->pers.hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
|
||||
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
self->client->uniqueWeapons--;
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ void TossClientItems( gentity_t *self ) {
|
|||
item = BG_FindItemForWeapon( WP_SSG3000 );
|
||||
Drop_Item( self, item, angle);
|
||||
self->client->pers.hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
|
||||
self->client->ps.stats[STAT_UNIQUEWEAPONS]--;
|
||||
self->client->uniqueWeapons--;
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
|
@ -158,6 +158,13 @@ void TossClientItems( gentity_t *self ) {
|
|||
if ( self->client->ps.ammo[ WP_KNIFE ] > 0) {
|
||||
item = BG_FindItemForWeapon( WP_KNIFE );
|
||||
Drop_Item (self, item, angle);
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
if ( self->client->ps.stats[STAT_HOLDABLE_ITEM] )
|
||||
{
|
||||
Drop_Item(self, &bg_itemlist[self->client->ps.stats[STAT_HOLDABLE_ITEM]], angle);
|
||||
angle += 30;
|
||||
}
|
||||
|
||||
// drop all the powerups if not in teamplay
|
||||
|
@ -1652,14 +1659,15 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
}
|
||||
case (LOCATION_CHEST):
|
||||
{
|
||||
|
||||
//Vest stuff
|
||||
if (bg_itemlist[targ->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_KEVLAR)
|
||||
{
|
||||
|
||||
if ((attacker->client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000)) == (1 << WP_SSG3000))
|
||||
//if ((attacker->client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000)) == (1 << WP_SSG3000))
|
||||
if (attacker->client->ps.weapon == WP_SSG3000)
|
||||
{ trap_SendServerCommand(attacker-g_entities, va("print \"%s has a Kevlar Vest, too bad you have AP rounds...\n\"",targ->client->pers.netname));
|
||||
trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed some of %s's AP sniper round\n\"",attacker->client->pers.netname));
|
||||
take = take * .325;
|
||||
take = take * 0.325;
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -1667,7 +1675,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
trap_SendServerCommand( targ-g_entities, va("print \"Kevlar Vest absorbed most of %s shot\n\"", attacker->client->pers.netname ));
|
||||
take = take/10;
|
||||
bleeding = 0;
|
||||
}
|
||||
}
|
||||
//Elder: flag for sound in feedback
|
||||
targ->client->damage_vest = qtrue;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -176,24 +176,38 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) {
|
|||
|
||||
int Pickup_Holdable( gentity_t *ent, gentity_t *other ) {
|
||||
|
||||
//Elder: why it's implemented like this I have no idea
|
||||
other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item - bg_itemlist;
|
||||
//other->client->ps.stats[STAT_HOLDABLE_ITEM] = ent->item->giTag;
|
||||
other->client->uniqueItems++;
|
||||
|
||||
//Fire up the laser if it's picked up
|
||||
if (ent->item->giTag == HI_LASER)
|
||||
{
|
||||
Laser_Gen(other, qtrue);
|
||||
}
|
||||
|
||||
/* Blaze: No Kamikazie
|
||||
if( ent->item->giTag == HI_KAMIKAZE ) {
|
||||
other->client->ps.eFlags |= EF_KAMIKAZE;
|
||||
}*/
|
||||
|
||||
return RESPAWN_HOLDABLE;
|
||||
//Elder: our unique items don't respawn
|
||||
return -1;
|
||||
//return RESPAWN_HOLDABLE;
|
||||
}
|
||||
|
||||
|
||||
//======================================================================
|
||||
|
||||
void Add_Ammo (gentity_t *ent, int weapon, int count)
|
||||
void Add_Ammo (gentity_t *ent, int weapon, int count, int bandolierFactor)
|
||||
{
|
||||
|
||||
//Blaze: Reaction stuff, add to clip when picking up ammo packs
|
||||
//Elder: Modified to use constants def'd in bg_public.h
|
||||
ent->client->numClips[weapon] += count;
|
||||
|
||||
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
|
@ -201,32 +215,32 @@ void Add_Ammo (gentity_t *ent, int weapon, int count)
|
|||
//Blaze: you get more knifes by picking up the "gun" as opposed to ammo
|
||||
break;
|
||||
case WP_PISTOL:
|
||||
if (ent->client->numClips[weapon] > RQ3_PISTOL_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_PISTOL_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_PISTOL_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_PISTOL_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_AKIMBO:
|
||||
if (ent->client->numClips[weapon] > RQ3_AKIMBO_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_AKIMBO_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_AKIMBO_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_AKIMBO_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_MP5:
|
||||
if (ent->client->numClips[weapon] > RQ3_MP5_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_MP5_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_MP5_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_MP5_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_M4:
|
||||
if (ent->client->numClips[weapon] > RQ3_M4_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_M4_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_M4_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_M4_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_M3:
|
||||
if (ent->client->numClips[weapon] > RQ3_M3_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_M3_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_M3_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_M3_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
if (ent->client->numClips[weapon] > RQ3_HANDCANNON_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_HANDCANNON_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_HANDCANNON_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_HANDCANNON_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_SSG3000:
|
||||
if (ent->client->numClips[weapon] > RQ3_SSG3000_MAXCLIP)
|
||||
ent->client->numClips[weapon] = RQ3_SSG3000_MAXCLIP;
|
||||
if (ent->client->numClips[weapon] > RQ3_SSG3000_MAXCLIP * bandolierFactor)
|
||||
ent->client->numClips[weapon] = RQ3_SSG3000_MAXCLIP * bandolierFactor;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
//Blaze: you get more knifes by picking up the "gun" as opposed to ammo
|
||||
|
@ -258,7 +272,7 @@ void Add_Ammo (gentity_t *ent, int weapon, int count)
|
|||
//}
|
||||
}
|
||||
|
||||
int Pickup_Ammo (gentity_t *ent, gentity_t *other)
|
||||
int Pickup_Ammo (gentity_t *ent, gentity_t *other, int bandolierFactor)
|
||||
{
|
||||
int quantity;
|
||||
|
||||
|
@ -267,7 +281,7 @@ int Pickup_Ammo (gentity_t *ent, gentity_t *other)
|
|||
} else {
|
||||
quantity = ent->item->quantity;
|
||||
}
|
||||
Add_Ammo (other, ent->item->giTag, quantity);
|
||||
Add_Ammo (other, ent->item->giTag, quantity, bandolierFactor);
|
||||
|
||||
return RESPAWN_AMMO;
|
||||
}
|
||||
|
@ -275,7 +289,7 @@ int Pickup_Ammo (gentity_t *ent, gentity_t *other)
|
|||
//======================================================================
|
||||
|
||||
|
||||
int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
||||
int Pickup_Weapon (gentity_t *ent, gentity_t *other, int bandolierFactor) {
|
||||
int quantity,ammotoadd;
|
||||
|
||||
if ( ent->count < 0 ) {
|
||||
|
@ -351,15 +365,15 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
break;
|
||||
case WP_MP5:
|
||||
ammotoadd= RQ3_MP5_AMMO;
|
||||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
other->client->uniqueWeapons++;
|
||||
break;
|
||||
case WP_M4:
|
||||
ammotoadd= RQ3_M4_AMMO;
|
||||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
other->client->uniqueWeapons++;
|
||||
break;
|
||||
case WP_M3:
|
||||
ammotoadd= RQ3_M3_AMMO;
|
||||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
other->client->uniqueWeapons++;
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
ammotoadd= RQ3_HANDCANNON_AMMO;
|
||||
|
@ -369,20 +383,20 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
|
|||
//When it's dropped
|
||||
//other->client->numClips[ WP_HANDCANNON ] += 5;
|
||||
//other->client->numClips[ WP_M3 ] += 5;
|
||||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
other->client->uniqueWeapons++;
|
||||
break;
|
||||
case WP_SSG3000:
|
||||
ammotoadd= RQ3_SSG3000_AMMO;
|
||||
other->client->ps.stats[STAT_UNIQUEWEAPONS]++;
|
||||
other->client->uniqueWeapons++;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
if (other->client->ps.ammo[WP_GRENADE] < RQ3_GRENADE_MAXCLIP)
|
||||
if (other->client->ps.ammo[WP_GRENADE] < RQ3_GRENADE_MAXCLIP * bandolierFactor)
|
||||
{
|
||||
ammotoadd=other->client->ps.ammo[WP_GRENADE] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ammotoadd= RQ3_GRENADE_MAXCLIP;
|
||||
ammotoadd= RQ3_GRENADE_MAXCLIP * bandolierFactor;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -573,6 +587,8 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
|
||||
int respawn;
|
||||
qboolean predict;
|
||||
int bandolierFactor;
|
||||
|
||||
|
||||
if (!other->client)
|
||||
return;
|
||||
|
@ -585,6 +601,12 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
|
||||
predict = other->client->pers.predictItemPickup;
|
||||
|
||||
if (bg_itemlist[other->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_BANDOLIER)
|
||||
bandolierFactor = 2;
|
||||
else
|
||||
bandolierFactor = 1;
|
||||
|
||||
|
||||
//Elder: should check if the item was recently thrown ... if it was, then
|
||||
//don't allow it to be picked up ... or something like that
|
||||
|
||||
|
@ -602,18 +624,18 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
//Specials: if you have more than/equal to limit (remember bando later), leave
|
||||
case WP_KNIFE:
|
||||
if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_KNIFE) ) == (1 << WP_KNIFE) ) &&
|
||||
(other->client->ps.ammo[ent->item->giTag] >= RQ3_KNIFE_MAXCLIP) )
|
||||
(other->client->ps.ammo[ent->item->giTag] >= RQ3_KNIFE_MAXCLIP * bandolierFactor))
|
||||
return;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_GRENADE) )== (1 << WP_GRENADE) ) &&
|
||||
(other->client->ps.ammo[ent->item->giTag] >= RQ3_GRENADE_MAXCLIP) )
|
||||
(other->client->ps.ammo[ent->item->giTag] >= RQ3_GRENADE_MAXCLIP * bandolierFactor) )
|
||||
return;
|
||||
break;
|
||||
case WP_PISTOL:
|
||||
//Elder: always have pistol - but extra ones give akimbo or clips
|
||||
if ( ( (other->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO) ) == (1 << WP_AKIMBO) ) &&
|
||||
other->client->numClips[WP_PISTOL] >= RQ3_PISTOL_MAXCLIP ) {
|
||||
other->client->numClips[WP_PISTOL] >= RQ3_PISTOL_MAXCLIP * bandolierFactor) {
|
||||
//leave if we have max clips and akimbos
|
||||
return;
|
||||
}
|
||||
|
@ -624,7 +646,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
case WP_M4:
|
||||
case WP_SSG3000:
|
||||
//Elder: check to see if it's in mid-air
|
||||
if (other->client->ps.stats[STAT_UNIQUEWEAPONS] >= g_RQ3_maxWeapons.integer ||
|
||||
if (other->client->uniqueWeapons >= g_RQ3_maxWeapons.integer ||
|
||||
ent->s.pos.trDelta[2] != 0)
|
||||
return;
|
||||
break;
|
||||
|
@ -696,11 +718,8 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
}
|
||||
*/
|
||||
|
||||
//Elder: Moved after checks so we don't print a billion log messages
|
||||
G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );
|
||||
|
||||
|
||||
respawn = Pickup_Weapon(ent, other);
|
||||
respawn = Pickup_Weapon(ent, other, bandolierFactor);
|
||||
|
||||
|
||||
//Elder: added pistol and knife condition
|
||||
|
@ -724,31 +743,31 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
if (other->client->numClips[ent->item->giTag] >= 0) return;//No clips for knifes
|
||||
break;
|
||||
case WP_PISTOL:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_PISTOL_MAXCLIP ) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_PISTOL_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_M3:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_M3_MAXCLIP) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_M3_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_HANDCANNON_MAXCLIP) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_HANDCANNON_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_MP5:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_MP5_MAXCLIP ) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_MP5_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_M4:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_M4_MAXCLIP ) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_M4_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_SSG3000:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_SSG3000_MAXCLIP ) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_SSG3000_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_AKIMBO:
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_AKIMBO_MAXCLIP ) return;
|
||||
if (other->client->numClips[ent->item->giTag] >= RQ3_AKIMBO_MAXCLIP * bandolierFactor) return;
|
||||
break;
|
||||
case WP_GRENADE:
|
||||
if (other->client->numClips[ent->item->giTag] >= 0 ) return;//no clips for grenades
|
||||
break;
|
||||
}
|
||||
respawn = Pickup_Ammo(ent, other);
|
||||
respawn = Pickup_Ammo(ent, other, bandolierFactor);
|
||||
// predict = qfalse;
|
||||
break;
|
||||
case IT_ARMOR:
|
||||
|
@ -770,6 +789,10 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
respawn = Pickup_Team(ent, other);
|
||||
break;
|
||||
case IT_HOLDABLE:
|
||||
//Elder: check to see if it's in mid-air
|
||||
if (other->client->uniqueItems >= 1 || //g_RQ3_maxWeapons.integer ||
|
||||
ent->s.pos.trDelta[2] != 0)
|
||||
return;
|
||||
respawn = Pickup_Holdable(ent, other);
|
||||
break;
|
||||
default:
|
||||
|
@ -780,6 +803,9 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
|
|||
return;
|
||||
}
|
||||
|
||||
//Elder: Moved after checks so we don't print a billion log messages
|
||||
G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );
|
||||
|
||||
// play the normal pickup sound
|
||||
if (predict) {
|
||||
G_AddPredictableEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
|
||||
|
@ -919,10 +945,17 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity, int xr_fla
|
|||
//Don't forget to condition it when we get teamplay in
|
||||
else if ( item->giType == IT_WEAPON &&
|
||||
item->giTag != WP_GRENADE && item->giTag != WP_PISTOL &&
|
||||
item->giTag != WP_AKIMBO && item->giTag != WP_KNIFE ) {
|
||||
item->giTag != WP_AKIMBO && item->giTag != WP_KNIFE )
|
||||
{
|
||||
dropped->think = RQ3_DroppedWeaponThink;
|
||||
dropped->nextthink = level.time + RQ3_RESPAWNTIME_DEFAULT;
|
||||
}
|
||||
//Elder: for unique items in deathmatch ... remember to condition for teamplay
|
||||
else if ( item->giType == IT_HOLDABLE)
|
||||
{
|
||||
dropped->think = RQ3_DroppedItemThink;
|
||||
dropped->nextthink = level.time + RQ3_RESPAWNTIME_DEFAULT;
|
||||
}
|
||||
|
||||
else { // auto-remove after 30 seconds
|
||||
dropped->think = G_FreeEntity;
|
||||
|
@ -951,7 +984,8 @@ Modified by Elder
|
|||
dropWeapon XRAY FMJ
|
||||
================
|
||||
*/
|
||||
gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags ) { // XRAY FMJ
|
||||
gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags )
|
||||
{
|
||||
vec3_t velocity;
|
||||
vec3_t angles;
|
||||
vec3_t origin;
|
||||
|
@ -1182,6 +1216,13 @@ void ClearRegisteredItems( void ) {
|
|||
//Blaze: Changed WP_MACHINEGUN to WP_PISTOL and WP_GAUNTLET to WP_KNIFE
|
||||
RegisterItem( BG_FindItemForWeapon( WP_PISTOL ) );
|
||||
RegisterItem( BG_FindItemForWeapon( WP_KNIFE ) );
|
||||
//Elder: add unique items here
|
||||
RegisterItem( BG_FindItemForHoldable( HI_KEVLAR ) );
|
||||
RegisterItem( BG_FindItemForHoldable( HI_SLIPPERS ) );
|
||||
RegisterItem( BG_FindItemForHoldable( HI_SILENCER ) );
|
||||
RegisterItem( BG_FindItemForHoldable( HI_BANDOLIER ) );
|
||||
RegisterItem( BG_FindItemForHoldable( HI_LASER ) );
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
if( g_gametype.integer == GT_HARVESTER ) {
|
||||
RegisterItem( BG_FindItem( "Red Cube" ) );
|
||||
|
@ -1513,3 +1554,41 @@ void RQ3_ResetWeapon( int weapon ) {
|
|||
|
||||
//return rent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
Added by Elder
|
||||
|
||||
RQ3_DroppedItemThink
|
||||
Items respawn themselves after a period of time
|
||||
Based on the AQ2 item code which was based off Q2 CTF techs
|
||||
==============
|
||||
*/
|
||||
void RQ3_DroppedItemThink(gentity_t *ent) {
|
||||
gitem_t *rq3_item;
|
||||
gentity_t *rq3_temp;
|
||||
float angle = rand() % 360;
|
||||
|
||||
switch (ent->item->giTag)
|
||||
{
|
||||
case HI_KEVLAR:
|
||||
case HI_LASER:
|
||||
case HI_SILENCER:
|
||||
case HI_BANDOLIER:
|
||||
case HI_SLIPPERS:
|
||||
//Free entity and reset position in unique item array
|
||||
//level.uniqueItemsUsed &= ~(1 << ent->item->giTag);
|
||||
rq3_item = BG_FindItemForHoldable( ent->item->giTag );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
G_FreeEntity(ent);
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
G_Printf("RQ3_DroppedItemThink: Freeing item entity + respawning\n");
|
||||
break;
|
||||
default:
|
||||
//Elder: shouldn't have to come here
|
||||
G_Printf("RQ3_DroppedItemThink: Out of range or invalid item %d\n", ent->item->giTag);
|
||||
G_FreeEntity(ent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,6 +296,7 @@ struct gclient_s {
|
|||
int damage_knockback; // impact damage
|
||||
vec3_t damage_from; // origin for vector calculation
|
||||
qboolean damage_fromWorld; // if true, don't use the damage_from vector
|
||||
qboolean damage_vest; // Elder: if true, play the vest-hit sound
|
||||
|
||||
int accurateCount; // for "impressive" reward sound
|
||||
|
||||
|
@ -332,8 +333,12 @@ struct gclient_s {
|
|||
qboolean openDoor;//Blaze: used to hold if someone has hit opendoor key
|
||||
// timeResidual is used to handle events that happen every second
|
||||
// like health / armor countdowns and regeneration
|
||||
|
||||
int timeResidual;
|
||||
|
||||
//Elder: C3A laser tutorial
|
||||
gentity_t *lasersight; // lasersight OR flashlight if in use
|
||||
|
||||
int bleeding; //Blaze: remaining points to bleed away
|
||||
int bleed_remain; //Blaze: How much left to bleed
|
||||
int bleedloc; //Blaze: Where are we bleeding
|
||||
|
@ -361,15 +366,16 @@ struct gclient_s {
|
|||
//qboolean isBandaging; //Elder: player in the process of bandaging
|
||||
// end Homer
|
||||
|
||||
//Elder: added for 3rb and akimbos
|
||||
int weaponfireNextTime; //for akimbos and burst modes
|
||||
int weaponfireNextTime; // for akimbos
|
||||
int lastzoom; // Elder: save last zoom state when firing
|
||||
|
||||
int fastReloads; //Elder: for queuing M3/SSG reloads
|
||||
int lastReloadTime; //Elder: for queuing M3/SSG reloads
|
||||
int reloadAttempts; //Elder: for queueing M3/SSG reloads
|
||||
int fastReloads; // Elder: for queuing M3/SSG reloads
|
||||
int lastReloadTime; // Elder: for queuing M3/SSG reloads
|
||||
int reloadAttempts; // Elder: for queuing M3/SSG reloads
|
||||
|
||||
int consecutiveShots; //Elder: for M4 ride-up/kick
|
||||
int consecutiveShots; // Elder: for M4 ride-up/kick
|
||||
int uniqueWeapons; // Elder: formerly a stat, now just a server var
|
||||
int uniqueItems;
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
gentity_t *persistantPowerup;
|
||||
|
@ -475,6 +481,7 @@ typedef struct {
|
|||
#ifdef MISSIONPACK
|
||||
int portalSequence;
|
||||
#endif
|
||||
|
||||
} level_locals_t;
|
||||
//
|
||||
// rxn_game.c
|
||||
|
@ -484,6 +491,7 @@ void CheckBleeding(gentity_t *targ);
|
|||
void StartBandage(gentity_t *ent);
|
||||
|
||||
void ThrowWeapon( gentity_t *ent );
|
||||
void ThrowItem( gentity_t *ent );
|
||||
gentity_t *dropWeapon( gentity_t *ent, gitem_t *item, float angle, int xr_flags ); // XRAY FMJ
|
||||
//Blaze Reaction knife stuff
|
||||
//Elder: commented out - unused?
|
||||
|
@ -509,6 +517,10 @@ void SetTeam( gentity_t *ent, char *s );
|
|||
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
|
||||
void Cmd_Unzoom(gentity_t *ent);
|
||||
void Cmd_OpenDoor(gentity_t *ent);
|
||||
//Elder: C3A laser tutorial
|
||||
void Laser_Gen (gentity_t *ent, qboolean enabled);
|
||||
void Laser_Think( gentity_t *self );
|
||||
|
||||
//Elder: commented out for Homer
|
||||
//void toggleSemi(gentity_t *ent);
|
||||
|
||||
|
@ -528,7 +540,8 @@ void G_SpawnItem (gentity_t *ent, gitem_t *item);
|
|||
void FinishSpawningItem( gentity_t *ent );
|
||||
void Think_Weapon (gentity_t *ent);
|
||||
int ArmorIndex (gentity_t *ent);
|
||||
void Add_Ammo (gentity_t *ent, int weapon, int count);
|
||||
//Elder: added bandolier factor
|
||||
void Add_Ammo (gentity_t *ent, int weapon, int count, int bandolierfactor);
|
||||
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace);
|
||||
|
||||
void ClearRegisteredItems( void );
|
||||
|
@ -536,6 +549,7 @@ void RegisterItem( gitem_t *item );
|
|||
void SaveRegisteredItems( void );
|
||||
|
||||
//Elder: added
|
||||
void RQ3_DroppedItemThink(gentity_t *ent);
|
||||
void RQ3_DroppedWeaponThink(gentity_t *ent);
|
||||
void RQ3_ResetWeapon( int weapon );
|
||||
|
||||
|
@ -673,6 +687,8 @@ int TeamLeader( int team );
|
|||
team_t PickTeam( int ignoreClientNum );
|
||||
void SetClientViewAngle( gentity_t *ent, vec3_t angle );
|
||||
gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles );
|
||||
//Elder: added because I use it in g_main.c and g_items.c for item spawning
|
||||
gentity_t *SelectRandomDeathmatchSpawnPoint( void );
|
||||
void CopyToBodyQue( gentity_t *ent );
|
||||
void respawn (gentity_t *ent);
|
||||
void BeginIntermission (void);
|
||||
|
@ -727,6 +743,8 @@ void QDECL G_LogPrintf( const char *fmt, ... );
|
|||
void SendScoreboardMessageToAllClients( void );
|
||||
void QDECL G_Printf( const char *fmt, ... );
|
||||
void QDECL G_Error( const char *fmt, ... );
|
||||
//Elder: added
|
||||
void RQ3_StartUniqueItems ( void );
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
|
|
|
@ -471,6 +471,9 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
|
|||
G_CheckTeamItems();
|
||||
}
|
||||
|
||||
//Elder: spawn unique items.
|
||||
RQ3_StartUniqueItems();
|
||||
|
||||
SaveRegisteredItems();
|
||||
|
||||
G_Printf ("-----------------------------------\n");
|
||||
|
@ -1805,6 +1808,14 @@ start = trap_Milliseconds();
|
|||
}
|
||||
end = trap_Milliseconds();
|
||||
|
||||
// Elder: added for unique items
|
||||
//if (level.time - level.uniqueItemsTime >= 30000)
|
||||
//if (level.time % 30000 < 1)
|
||||
//{
|
||||
//level.uniqueItemsTime = level.time;
|
||||
//RQ3_CheckUniqueItems();
|
||||
//}
|
||||
|
||||
// see if it is time to do a tournement restart
|
||||
CheckTournament();
|
||||
|
||||
|
@ -1831,3 +1842,52 @@ end = trap_Milliseconds();
|
|||
trap_Cvar_Set("g_listEntity", "0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
Added by Elder
|
||||
|
||||
RQ3_StartUniqueItems
|
||||
Spawns items at the beginning of a level
|
||||
==============
|
||||
*/
|
||||
void RQ3_StartUniqueItems ( void )
|
||||
{
|
||||
gitem_t *rq3_item;
|
||||
gentity_t *rq3_temp;
|
||||
float angle = 0;
|
||||
|
||||
G_Printf("RQ3_StartUniqueItems: Starting unique item spawn code...\n");
|
||||
|
||||
rq3_item = BG_FindItemForHoldable( HI_SLIPPERS );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
angle += 30;
|
||||
|
||||
rq3_item = BG_FindItemForHoldable( HI_KEVLAR );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
angle += 30;
|
||||
|
||||
rq3_item = BG_FindItemForHoldable( HI_SILENCER );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
angle += 30;
|
||||
|
||||
rq3_item = BG_FindItemForHoldable( HI_BANDOLIER );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
angle += 30;
|
||||
|
||||
rq3_item = BG_FindItemForHoldable( HI_LASER );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
angle += 30;
|
||||
|
||||
//rq3_item = BG_FindItem( "Kevlar Vest" );
|
||||
//rq3_item = BG_FindItemForHoldable( HI_SLIPPERS );
|
||||
//rq3_temp = SelectSpawnPoint(ent->client->ps.origin,spawn_origin, spawn_angles);
|
||||
//Drop_Item (rq3_temp, rq3_item, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -271,6 +271,38 @@ qboolean G_CallSpawn( gentity_t *ent ) {
|
|||
return qfalse;
|
||||
}
|
||||
//Blaze: allow for Reaction specific spawns to be used
|
||||
//Elder: map Q3DM weapons -> RQ3 weapons
|
||||
if (!strcmp(ent->classname,"weapon_gauntlet"))
|
||||
ent->classname = "weapon_knife";
|
||||
else if (!strcmp(ent->classname,"weapon_machinegun"))
|
||||
ent->classname = "weapon_pistol";
|
||||
else if (!strcmp(ent->classname,"weapon_shotgun"))
|
||||
ent->classname = "weapon_m3";
|
||||
else if (!strcmp(ent->classname,"weapon_plasmagun"))
|
||||
ent->classname = "weapon_mp5";
|
||||
else if (!strcmp(ent->classname,"weapon_rocketlauncher"))
|
||||
ent->classname = "weapon_handcannon";
|
||||
else if (!strcmp(ent->classname,"weapon_railgun"))
|
||||
ent->classname = "weapon_ssg3000";
|
||||
else if (!strcmp(ent->classname,"weapon_bfg"))
|
||||
ent->classname = "weapon_m4";
|
||||
else if (!strcmp(ent->classname,"ammo_grenades"))
|
||||
ent->classname = "weapon_grenade";
|
||||
|
||||
//Elder: map Q3DM ammo -> RQ3 ammo
|
||||
if (!strcmp(ent->classname,"ammo_bullets"))
|
||||
ent->classname = "ammo_mk23";
|
||||
else if (!strcmp(ent->classname, "ammo_slugs"))
|
||||
ent->classname = "ammo_ssg3000";
|
||||
else if (!strcmp(ent->classname, "ammo_cells"))
|
||||
ent->classname = "ammo_mp5";
|
||||
else if (!strcmp(ent->classname, "ammo_bfg"))
|
||||
ent->classname = "ammo_m4";
|
||||
else if (!strcmp(ent->classname, "ammo_rockets"))
|
||||
ent->classname = "ammo_shells";
|
||||
|
||||
/*
|
||||
//Elder: old stuff
|
||||
if (!strcmp(ent->classname,"weapon_gauntlet")) ent->classname = "weapon_knife";
|
||||
else if (!strcmp(ent->classname,"weapon_railgun")) ent->classname = "weapon_ssg3000";
|
||||
else if (!strcmp(ent->classname,"weapon_shotgun")) ent->classname = "weapon_m3";
|
||||
|
@ -279,6 +311,7 @@ qboolean G_CallSpawn( gentity_t *ent ) {
|
|||
else if (!strcmp(ent->classname,"weapon_bfg")) ent->classname = "weapon_m4";
|
||||
else if (!strcmp(ent->classname,"weapon_grenadelauncher")) ent->classname = "weapon_pistol";
|
||||
else if (!strcmp(ent->classname,"ammo_grenades")) ent->classname = "weapon_grenade";
|
||||
*/
|
||||
// check item spawn functions
|
||||
for ( item=bg_itemlist+1 ; item->classname ; item++ ) {
|
||||
if ( !strcmp(item->classname, ent->classname) ) {
|
||||
|
|
|
@ -111,7 +111,7 @@ qboolean JumpKick( gentity_t *ent )
|
|||
tent->s.weapon = ent->s.weapon;
|
||||
}
|
||||
|
||||
if (traceEnt->client && traceEnt->client->ps.stats[STAT_UNIQUEWEAPONS] > 0)
|
||||
if (traceEnt->client && traceEnt->client->uniqueWeapons > 0)
|
||||
{
|
||||
//Elder: toss a unique weapon if kicked
|
||||
//Todo: Need to make sure to cancel any reload attempts
|
||||
|
@ -1127,7 +1127,18 @@ int RQ3_Spread (gentity_t *ent, int spread)
|
|||
else
|
||||
stage = 1;
|
||||
|
||||
//TODO: add laser advantage
|
||||
//added laser advantage
|
||||
if (bg_itemlist[ent->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_LASER &&
|
||||
(ent->client->ps.weapon == WP_PISTOL ||
|
||||
ent->client->ps.weapon == WP_MP5 ||
|
||||
ent->client->ps.weapon == WP_M4))
|
||||
{
|
||||
//G_Printf("Using laser advantage\n");
|
||||
if (stage == 1)
|
||||
stage = 0;
|
||||
else
|
||||
stage = 1;
|
||||
}
|
||||
|
||||
|
||||
return (int)(spread * factor[stage]);
|
||||
|
@ -1381,7 +1392,8 @@ void Weapon_SSG3000_Fire (gentity_t *ent) {
|
|||
// send impacts
|
||||
if ( traceEnt->client )
|
||||
{
|
||||
tent[unlinked] = G_TempEntity( trace.endpos, EV_BULLET_HIT_FLESH );
|
||||
tent[unlinked] = G_TempEntity( trace.endpos, EV_SSG3000_HIT_FLESH );
|
||||
//tent[unlinked]->s.eventParm = DirToByte( trace.plane.normal );
|
||||
tent[unlinked]->s.eventParm = traceEnt->s.number;
|
||||
}
|
||||
else
|
||||
|
@ -2073,3 +2085,94 @@ void G_StartKamikaze( gentity_t *ent ) {
|
|||
te->s.eventParm = GTS_KAMIKAZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Laser Sight Stuff
|
||||
|
||||
Laser Sight / Flash Light Functions
|
||||
============
|
||||
*/
|
||||
|
||||
void Laser_Gen( gentity_t *ent, qboolean enabled ) {
|
||||
gentity_t *las;
|
||||
//Elder: force it to laser
|
||||
int type = 1;
|
||||
|
||||
//Get rid of you?
|
||||
if ( ent->client->lasersight && !enabled)
|
||||
{
|
||||
G_FreeEntity( ent->client->lasersight );
|
||||
ent->client->lasersight = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
las = G_Spawn();
|
||||
|
||||
las->nextthink = level.time + 10;
|
||||
las->think = Laser_Think;
|
||||
|
||||
las->s.clientNum = ent->s.number;
|
||||
las->r.ownerNum = ent->s.number;
|
||||
las->parent = ent;
|
||||
las->s.eType = ET_LASER;
|
||||
//Elder: added to enable lerping in cgame
|
||||
las->s.pos.trType = TR_INTERPOLATE;
|
||||
|
||||
//Lets tell it if flashlight or laser
|
||||
if (type == 2) {
|
||||
las->s.eventParm = 2; //tells CG that it is a flashlight
|
||||
las->classname = "flashlight";
|
||||
}
|
||||
else {
|
||||
las->s.eventParm = 1; //tells CG that it is a laser sight
|
||||
las->classname = "lasersight";
|
||||
}
|
||||
|
||||
ent->client->lasersight = las;
|
||||
}
|
||||
|
||||
|
||||
void Laser_Think( gentity_t *self )
|
||||
{
|
||||
vec3_t end, start, forward, up;
|
||||
trace_t tr;
|
||||
|
||||
//If Player Dies, You Die -> now thanks to Camouflage!
|
||||
if (self->parent->client->ps.pm_type == PM_DEAD) {
|
||||
G_FreeEntity(self);
|
||||
return;
|
||||
}
|
||||
|
||||
//Set Aiming Directions
|
||||
AngleVectors(self->parent->client->ps.viewangles, forward, right, up);
|
||||
CalcMuzzlePoint(self->parent, forward, right, up, start);
|
||||
VectorMA (start, 8192 * 16, forward, end);
|
||||
|
||||
//Trace Position
|
||||
trap_Trace (&tr, start, NULL, NULL, end, self->parent->s.number, MASK_SHOT );
|
||||
|
||||
//Did you not hit anything?
|
||||
if (tr.surfaceFlags & SURF_NOIMPACT || tr.surfaceFlags & SURF_SKY) {
|
||||
self->nextthink = level.time + 10;
|
||||
trap_UnlinkEntity(self);
|
||||
return;
|
||||
}
|
||||
|
||||
//Move you forward to keep you visible
|
||||
if (tr.fraction != 1)
|
||||
VectorMA(tr.endpos,-4,forward,tr.endpos);
|
||||
|
||||
//Set Your position
|
||||
VectorCopy( tr.endpos, self->r.currentOrigin );
|
||||
VectorCopy( tr.endpos, self->s.pos.trBase );
|
||||
|
||||
vectoangles(tr.plane.normal, self->s.angles);
|
||||
|
||||
trap_LinkEntity(self);
|
||||
|
||||
//Prep next move
|
||||
self->nextthink = level.time + 10;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ void CheckBleeding(gentity_t *targ)
|
|||
targ->client->bleedBandageCount < 1)
|
||||
{
|
||||
//Elder: skip damage being dealt
|
||||
//TODO: check bleed_remain again -- if it's > 11, then reset bleedBandageCount?
|
||||
//That would probably remove the long-time AQ2 headshot bandage bug
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue