Updates for 0-05-xx + stuff to be released in 0-05-01
Client portion has adjusted HUD, small fixes here and there
This commit is contained in:
Victor Chow 2001-07-24 01:49:02 +00:00
parent 231ffd675d
commit 0d3a1a7009
8 changed files with 439 additions and 110 deletions

View file

@ -33,6 +33,7 @@ Elder: reset local zoom, then proceed with server action
*/
static void CG_DropWeapon_f (void) {
if ( !cg.snap ) {
//CG_Printf("No snapshot: normally exiting\n");
return;
}
@ -45,7 +46,11 @@ static void CG_DropWeapon_f (void) {
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) {
return;
}
//Elder: don't allow weapon dropping when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
CG_RQ3_Zoom1x();
trap_SendClientCommand("dropweapon");
}
@ -61,6 +66,7 @@ the client command to reduce bandwidth use slightly
*/
static void CG_Bandage_f (void) {
if ( !cg.snap ) {
//CG_Printf("No snapshot: normally exiting\n");
return;
}
@ -80,7 +86,6 @@ static void CG_Bandage_f (void) {
return;
}
//if (cg.snap->ps.stats[STAT_BANDAGE]) {
if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) {
CG_Printf("You are already bandaging!\n");
//cg.zoomed = 0;
@ -88,6 +93,10 @@ static void CG_Bandage_f (void) {
return;
}
//Elder: don't allow bandaging when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
//Elder: added to prevent bandaging while reloading or firing
//Moved below "already-bandaging" case and removed message
//if ( cg.snap->ps.weaponTime > 0 || cg.snap->ps.weaponstate == WEAPON_COCKED) {
@ -109,6 +118,7 @@ Elder: reset reload depressed flag
=================
*/
static void CG_ReloadReset_f (void) {
//CG_Printf("Releasing Reload\n");
cg.rq3_reloadDown = qfalse;
}
@ -118,6 +128,7 @@ static void CG_ReloadReset_f (void) {
CG_Reload_f
Elder: reset local zoom, then proceed with server action
Note: most of this doesn't work if it's a +button style
=================
*/
static void CG_Reload_f (void) {
@ -125,6 +136,7 @@ static void CG_Reload_f (void) {
cent = &cg_entities[cg.snap->ps.clientNum];
if ( !cg.snap ) {
//CG_Printf("No snapshot: normally exiting\n");
return;
}
@ -138,18 +150,23 @@ static void CG_Reload_f (void) {
return;
}
if (cg.rq3_reloadDown)
//Elder: don't allow reloading when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
cg.rq3_reloadDown = qtrue;
//Elder: prevent "reloading" when dead hehe
if ( cg.snap->ps.stats[STAT_HEALTH] < 0 ) {
CG_Printf("Nothing to reload - you are dead.\n");
if (cg.rq3_reloadDown == qtrue)
{
//CG_Printf("Reload down... exiting\n");
return;
}
//cg.rq3_reloadDown = qtrue;
//Elder: prevent "reloading" when dead hehe
if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) {
CG_Printf("Nothing to reload - you are dead.\n");
return;
}
//Elder: don't allow reloading until the weapon is free
//Don't cut-off here because we want to check for fast-reloads
@ -174,6 +191,7 @@ static void CG_Reload_f (void) {
if (cg.snap->ps.weapon == WP_SSG3000 && cg.zoomFirstReturn == -1)
cg.zoomFirstReturn = 0;
//CG_Printf("Sending reload command to server\n");
trap_SendClientCommand("reload");
}
@ -214,6 +232,18 @@ static void CG_Viewpos_f (void) {
(int)cg.refdefViewAngles[YAW]);
}
/*
=============
CG_PlayerOrigin_f
Debugging command to print player's origin
=============
*/
static void CG_PlayerOrigin_f (void) {
CG_Printf("(%i %i %i)\n", (int)cg.snap->ps.origin[0],
(int)cg.snap->ps.origin[1], (int)cg.snap->ps.origin[2]);
}
static void CG_ScoresDown_f( void ) {
@ -555,6 +585,64 @@ static void CG_StartOrbit_f( void ) {
}
/*
==================
CG_Say_f
Elder: Pre-validate say command to avoid text flooding
==================
*/
static void CG_Say_f ( void ) {
if (cg.time - cg.sayTime > 2000)
cg.sayCount = 0;
if (cg.sayCount == 0)
cg.sayTime = cg.time;
cg.sayCount++;
CG_Printf("sayCount: %i sayTime: %i\n", cg.sayCount, cg.sayTime);
if (cg.sayCount > 4 && cg.time - cg.sayTime < 2000)
{
CG_Printf("Cannot send messages.\n");
return;
}
trap_SendClientCommand("say");
}
/*
==================
CG_SayTeam_f
Elder: Pre-validate say_team command to avoid text flooding
==================
*/
static void CG_SayTeam_f ( void ) {
if (cg.time - cg.sayTime > 2000)
cg.sayCount = 0;
if (cg.sayCount == 0)
cg.sayTime = cg.time;
cg.sayCount++;
CG_Printf("sayCount: %i sayTime: %i\n", cg.sayCount, cg.sayTime);
if (cg.sayCount > 4 && cg.time - cg.sayTime < 2000)
{
CG_Printf("Cannot send messages.\n");
return;
}
trap_SendClientCommand("say_team");
}
typedef struct {
@ -570,6 +658,7 @@ static consoleCommand_t commands[] = {
{ "nextskin", CG_TestModelNextSkin_f },
{ "prevskin", CG_TestModelPrevSkin_f },
{ "viewpos", CG_Viewpos_f },
{ "playerorigin", CG_PlayerOrigin_f },
{ "+scores", CG_ScoresDown_f },
{ "-scores", CG_ScoresUp_f },
/* { "+zoom", CG_ZoomDown_f }, // hawkins not needed in Reaction
@ -584,6 +673,11 @@ static consoleCommand_t commands[] = {
{ "+reload", CG_Reload_f }, // Elder: added to reset zoom then goto server
{ "-reload", CG_ReloadReset_f}, // Elder: added to stop auto-throttle
{ "specialweapon", CG_SpecialWeapon_f }, // Elder: select special weapon
//Elder: added for manual sv_floodProtect check
{ "messagemode", CG_Say_f },
{ "messagemode2", CG_SayTeam_f },
{ "say", CG_Say_f },
{ "say_team", CG_SayTeam_f },
{ "tell_target", CG_TellTarget_f },
{ "tell_attacker", CG_TellAttacker_f },
{ "vtell_target", CG_VoiceTellTarget_f },
@ -699,4 +793,7 @@ void CG_InitConsoleCommands( void ) {
//Elder: try this
trap_AddCommand ("weapon");
trap_AddCommand ("specialweapon");
trap_AddCommand ("messagemode");
trap_AddCommand ("messagemode2");
trap_AddCommand ("playerorigin");
}

View file

@ -501,7 +501,7 @@ static void CG_DrawStatusBar( void ) {
int style;
centity_t *cent;
playerState_t *ps;
int value, value2;
int value;//, value2;
vec4_t hcolor;
vec3_t angles;
vec3_t origin;
@ -510,6 +510,7 @@ static void CG_DrawStatusBar( void ) {
//#ifdef MISSIONPACK
// qhandle_t handle;
//#endif
int i;
static float colors [4][4] = {
{ 0.0f, 1.0f, 0.0f, 1.0f } , //full green
@ -543,7 +544,7 @@ static void CG_DrawStatusBar( void ) {
hcolor[2] = 0;
hcolor[3] = (value <= 25) * (0.01 * value + 0.75) + (value > 25) * 1;
/* Elder: Old clamp routine for reference
/* Elder: Old clamp routine for reference -- more efficient since less stack usage?
for (i = 0; i < 4; i++) {
if (hcolor[i] > 1.0) {
CG_Printf ("Over one on %i\n",i);
@ -555,23 +556,72 @@ static void CG_DrawStatusBar( void ) {
}
}*/
CG_DrawPic(8, 440, 32, 32, hicon);
CG_DrawPic(8, 440, SMICON_SIZE, SMICON_SIZE, hicon);
UI_DrawProportionalString(44, 444, va("%d", value), style, hcolor);
//Elder: Draw weapon ammo and clips
style = UI_LEFT|UI_DROPSHADOW;
icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon;
icon = cg_weapons[ cg.predictedPlayerState.weapon ].weaponIcon;
if (icon)
CG_DrawPic(152, 440, 32, 32, icon);
CG_DrawPic(152, 440, SMICON_SIZE, SMICON_SIZE, icon);
icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon;
//Don't draw ammo icon if holding grenade or knife
if (icon &&
cg.predictedPlayerState.weapon != WP_KNIFE &&
cg.predictedPlayerState.weapon != WP_GRENADE)
CG_DrawPic(252, 440, SMICON_SIZE, SMICON_SIZE, icon);
if ( cent->currentState.weapon ) {
if ( cent->currentState.weapon )
{
value = ps->ammo[cent->currentState.weapon];
value2 = ps->stats[STAT_CLIPS];
if ( value > -1 ) {
UI_DrawProportionalString(188, 444, va("%d / %d", value, value2), style, colors[0]);
if ( value > -1 )
UI_DrawProportionalString(188, 444, va("%d", value), style, colors[0]);
//UI_DrawProportionalString(188, 444, "/"), style, colors[0]);
value = ps->stats[STAT_CLIPS];
if ( value > -1 &&
cg.predictedPlayerState.weapon != WP_KNIFE &&
cg.predictedPlayerState.weapon != WP_GRENADE)
UI_DrawProportionalString(288, 444, va("%d", value), style, colors[0]);
}
//Elder: draw grenades, if any, on the side
if (cg.snap->ps.ammo[ WP_GRENADE ] > 0)
{
icon = cg_weapons[ WP_GRENADE ].weaponIcon;
if (icon)
CG_DrawPic(640-SMICON_SIZE, 360, SMICON_SIZE, SMICON_SIZE, icon);
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])
{
for (i = 1; i < MAX_WEAPONS; i++)
{
if (i == WP_KNIFE ||
i == WP_PISTOL ||
i == WP_GRENADE ||
i == WP_AKIMBO)
continue;
if ( (1 << i) == ((1 << i) & cg.snap->ps.stats[STAT_WEAPONS]))
break;
}
if (i < MAX_WEAPONS)
{
icon = cg_weapons[i].weaponIcon;
if (icon)
CG_DrawPic(640-SMICON_SIZE, 400, SMICON_SIZE, SMICON_SIZE, icon);
}
}
}
/* Elder: old stuff
@ -1392,7 +1442,8 @@ CG_DrawLowerRight
static void CG_DrawLowerRight( void ) {
float y;
y = 480 - ICON_SIZE;
//y = 480 - ICON_SIZE;
y = 320 + SMICON_SIZE;
if ( cgs.gametype >= GT_TEAM && cg_drawTeamOverlay.integer == 2 ) {
y = CG_DrawTeamOverlay( y, qtrue, qfalse );
@ -1544,7 +1595,8 @@ static void CG_DrawHoldableItem( void ) {
value = cg.snap->ps.stats[STAT_HOLDABLE_ITEM];
if ( value ) {
CG_RegisterItemVisuals( value );
CG_DrawPic( 640-ICON_SIZE, (SCREEN_HEIGHT-ICON_SIZE)/2, ICON_SIZE, ICON_SIZE, cg_items[ value ].icon );
//CG_DrawPic( 640-ICON_SIZE, (SCREEN_HEIGHT-ICON_SIZE)/2, ICON_SIZE, ICON_SIZE, cg_items[ value ].icon );
CG_DrawPic( 640-SMICON_SIZE, 440, SMICON_SIZE, SMICON_SIZE, cg_items[ value ].icon );
}
}

View file

@ -693,16 +693,15 @@ void CG_BigExplode( vec3_t playerOrigin ) {
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
}
#define GLASS_VELOCITY 175
#define GLASS_JUMP 125
/*
==================
CG_LaunchGlass
==================
*/
//Elder: might want to rotate the model randomly or do it in break glass
void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation, qhandle_t hModel ) {
#define GLASS_VELOCITY 175
#define GLASS_JUMP 125
/*
==================
CG_LaunchGlass
==================
*/
void CG_LaunchGlass( vec3_t origin, vec3_t velocity, vec3_t rotation,
float bounce, qhandle_t hModel ) {
localEntity_t *le;
refEntity_t *re;
@ -711,9 +710,8 @@ void CG_BigExplode( vec3_t playerOrigin ) {
le->leType = LE_FRAGMENT;
le->startTime = cg.time;
le->endTime = le->startTime + (random() * 3000)+ cg_RQ3_glasstime.integer;// + 30000;
le->endTime = le->startTime + (random() * 3000)+ cg_RQ3_glasstime.integer; // + 30000;
VectorCopy( origin, re->origin );
AxisCopy( axisDefault, re->axis );
re->hModel = hModel;
@ -722,7 +720,7 @@ void CG_BigExplode( vec3_t playerOrigin ) {
VectorCopy( origin, le->pos.trBase );
VectorCopy( velocity, le->pos.trDelta );
le->pos.trTime = cg.time;
//Elder: added
//VectorCopy( origin, le->angles.trBase );
VectorCopy( velocity, le->angles.trBase );
@ -730,101 +728,147 @@ void CG_BigExplode( vec3_t playerOrigin ) {
VectorCopy( rotation, le->angles.trDelta );
le->angles.trTime = cg.time;
le->bounceFactor = 0.3f;
le->bounceFactor = bounce;
le->leFlags = LEF_TUMBLE;
le->leBounceSoundType = LEBS_BRASS;
le->leMarkType = LEMT_NONE;
}
/*
===================
CG_BreakGlass
/*
===================
CG_BreakGlass
Generated a bunch of glass shards launching out from the glass location
Elder: don't be mislead by the name - this breaks more than glass
===================
*/
Generated a bunch of glass shards launching out from the glass location
===================
*/
void CG_BreakGlass( vec3_t playerOrigin, int glassParm ) {
void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type ) {
vec3_t origin, velocity, rotation;
int value;
int count = 40; // How many shards to generate
int states[] = {1,2,3}; // The array of possible numbers
int count;
int states[] = {1,2,3}; // Select model variations
// Get the size of the array
int numstates = sizeof(states)/sizeof(states[0]);
// Elder: The handles to our debris models
qhandle_t debris1, debris2, debris3;
//Elder: check bit amount
if ( (glassParm & RQ3_DEBRIS_SMALL) == RQ3_DEBRIS_SMALL) {
count = 8 + rand() % 5;
}
//else if ( (glassParm & RQ3_DEBRIS_MEDIUM) == RQ3_DEBRIS_MEDIUM) {
else if ( (glassParm & RQ3_DEBRIS_LARGE) == RQ3_DEBRIS_LARGE) {
count = 40 + rand() % 15;
}
else if ( (glassParm & RQ3_DEBRIS_TONS) == RQ3_DEBRIS_TONS) {
// Elder: debris model handles
qhandle_t debris1;
qhandle_t debris2;
qhandle_t debris3;
int bounceFactor;
int newParm;
if ( (glassParm & RQ3_DEBRIS_MEDIUM) == RQ3_DEBRIS_MEDIUM &&
(glassParm & RQ3_DEBRIS_HIGH) == RQ3_DEBRIS_HIGH)
{
//Tons
count = 65 + rand() % 25;
}
else {
//medium is default
count = 22 + rand() % 7;
else if ( (glassParm & RQ3_DEBRIS_HIGH) == RQ3_DEBRIS_HIGH)
{
//Large
count = 40 + rand() % 15;
}
else if ( (glassParm & RQ3_DEBRIS_MEDIUM) == RQ3_DEBRIS_MEDIUM)
{
//Medium
count = 22 + rand() % 7;
}
else
{
//Small
count = 8 + rand() % 5;
}
CG_Printf("glassParm: %d\n", glassParm);
/*
===============================
TODO: Utilize variation bits!
==============================
*/
//Strip off amount info and revert eParm back to server-side size
newParm = glassParm & 15;
glassParm &= ~newParm;
glassParm = glassParm << (type * 4);
CG_Printf("glassParm: %i\n", glassParm);
//Elder: check debris type and assign debris models
//Using bit-op check b/c I will be stuffing the amount in there too
if ( (glassParm & RQ3_DEBRIS_WOOD) == RQ3_DEBRIS_WOOD) {
if ( (glassParm & RQ3_DEBRIS_WOOD) == RQ3_DEBRIS_WOOD)
{
CG_Printf("Launching wood\n");
debris1 = cgs.media.wood01;
debris2 = cgs.media.wood02;
debris3 = cgs.media.wood03;
bounceFactor = 0.8f;
}
else if ( (glassParm & RQ3_DEBRIS_METAL) == RQ3_DEBRIS_METAL) {
else if ( (glassParm & RQ3_DEBRIS_METAL) == RQ3_DEBRIS_METAL)
{
CG_Printf("Launching metal\n");
debris1 = cgs.media.metal01;
debris2 = cgs.media.metal02;
debris3 = cgs.media.metal03;
bounceFactor = 0.7f;
}
else if ( (glassParm & RQ3_DEBRIS_CERAMIC) == RQ3_DEBRIS_CERAMIC) {
else if ( (glassParm & RQ3_DEBRIS_CERAMIC) == RQ3_DEBRIS_CERAMIC)
{
CG_Printf("Launching ceramic\n");
debris1 = cgs.media.ceramic01;
debris2 = cgs.media.ceramic02;
debris3 = cgs.media.ceramic03;
bounceFactor = 0.7f;
}
else if ( (glassParm & RQ3_DEBRIS_PAPER) == RQ3_DEBRIS_PAPER) {
else if ( (glassParm & RQ3_DEBRIS_PAPER) == RQ3_DEBRIS_PAPER)
{
CG_Printf("Launching paper\n");
debris1 = cgs.media.paper01;
debris2 = cgs.media.paper02;
debris3 = cgs.media.paper03;
bounceFactor = 0.2f;
}
else if ( (glassParm & RQ3_DEBRIS_BRICK) == RQ3_DEBRIS_BRICK) {
else if ( (glassParm & RQ3_DEBRIS_BRICK) == RQ3_DEBRIS_BRICK)
{
CG_Printf("Launching brick\n");
debris1 = cgs.media.brick01;
debris2 = cgs.media.brick02;
debris3 = cgs.media.brick03;
bounceFactor = 0.4f;
}
else if ( (glassParm & RQ3_DEBRIS_CONCRETE) == RQ3_DEBRIS_CONCRETE) {
else if ( (glassParm & RQ3_DEBRIS_CONCRETE) == RQ3_DEBRIS_CONCRETE)
{
CG_Printf("Launching concrete\n");
debris1 = cgs.media.concrete01;
debris2 = cgs.media.concrete02;
debris3 = cgs.media.concrete03;
bounceFactor = 0.5f;
}
else {
/*
else if ( (glassParm & RQ3_DEBRIS_POPCAN) == RQ3_DEBRIS_POPCAN)
{
CG_Printf("Launching pop cans\n");
debris1 = cgs.media.popcan01;
debris2 = cgs.media.popcan02;
debris3 = cgs.media.popcan03;
}
*/
else
{
//glass is default
CG_Printf("Launching glass\n");
debris1 = cgs.media.glass01;
debris2 = cgs.media.glass02;
debris3 = cgs.media.glass03;
bounceFactor = 0.7f;
}
//launch loop
while ( count-- ) {
// Generate the random number every count so every shard is a
// of the three. If this is placed above it only gets a random
// number every time a piece of glass is broken.
value = states[rand()%numstates];
VectorCopy( playerOrigin, origin );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom() * GLASS_VELOCITY;
velocity[1] = crandom() * GLASS_VELOCITY;
velocity[2] = GLASS_JUMP + crandom() * GLASS_VELOCITY;
@ -832,16 +876,17 @@ void CG_BreakGlass( vec3_t playerOrigin, int glassParm ) {
rotation[0] = crandom() * GLASS_VELOCITY;
rotation[1] = crandom() * GLASS_VELOCITY;
rotation[2] = crandom() * GLASS_VELOCITY;
switch (value) {
switch (value)
{
case 1:
// If our random number was 1, generate the 1st shard piece
CG_LaunchGlass( origin, velocity, rotation, debris1 );
CG_LaunchGlass( origin, velocity, rotation, bounceFactor, debris1 );
break;
case 2:
CG_LaunchGlass( origin, velocity, rotation, debris2 );
CG_LaunchGlass( origin, velocity, rotation, bounceFactor, debris2 );
break;
case 3:
CG_LaunchGlass( origin, velocity, rotation, debris3 );
CG_LaunchGlass( origin, velocity, rotation, bounceFactor, debris3 );
break;
}
}

View file

@ -2120,14 +2120,24 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
}
CG_GibPlayer( cent->lerpOrigin );
break;
case EV_BREAK_GLASS:
DEBUGNAME("EV_BREAK_GLASS");
case EV_BREAK_GLASS1:
DEBUGNAME("EV_BREAK_GLASS1");
// Change cgs.media.gibSound to whatever sound you want it to use
// I think the gib sound sounds pretty good
//Elder: gonna move this into the function
trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.glassSound );
//Elder: modified
CG_BreakGlass( cent->lerpOrigin, es->eventParm );
CG_BreakGlass( cent->lerpOrigin, es->eventParm, 0 );
break;
case EV_BREAK_GLASS2:
DEBUGNAME("EV_BREAK_GLASS2");
trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.glassSound );
CG_BreakGlass( cent->lerpOrigin, es->eventParm, 1 );
break;
case EV_BREAK_GLASS3:
DEBUGNAME("EV_BREAK_GLASS3");
trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.glassSound );
CG_BreakGlass( cent->lerpOrigin, es->eventParm, 2 );
break;
case EV_STOPLOOPINGSOUND:
DEBUGNAME("EV_STOPLOOPINGSOUND");

View file

@ -47,6 +47,8 @@
#define STAT_MINUS 10 // num frame for '-' stats digit
#define ICON_SIZE 48
//Elder: small icon size added
#define SMICON_SIZE 32
#define CHAR_WIDTH 32
#define CHAR_HEIGHT 48
#define TEXT_ICON_SPACE 4
@ -629,6 +631,11 @@ typedef struct {
char testModelName[MAX_QPATH];
qboolean testGun;
// Elder: for message flooding protection
int sayTime;
int sayCount;
} cg_t;
@ -1194,6 +1201,8 @@ extern vmCvar_t cg_RQ3_ssgColorR;
extern vmCvar_t cg_RQ3_ssgColorG;
extern vmCvar_t cg_RQ3_ssgColorB;
extern vmCvar_t cg_RQ3_ssgColorA;
//Elder: smoke puffs, sparks, etc.
extern vmCvar_t cg_RQ3_impactEffects;
extern vmCvar_t cg_drawFriend;
extern vmCvar_t cg_teamChatsOnly;
@ -1463,7 +1472,8 @@ void CG_ScorePlum( int client, vec3_t org, int score );
void CG_GibPlayer( vec3_t playerOrigin );
void CG_BigExplode( vec3_t playerOrigin );
void CG_BreakGlass( vec3_t playerOrigin, int glassParm );// Blaze: Breakable glass Elder: modified
// Blaze: Breakable glass Elder: modified
void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type );
void CG_Bleed( vec3_t origin, int entityNum );
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,

View file

@ -151,6 +151,8 @@ vmCvar_t cg_RQ3_ssgColorR;
vmCvar_t cg_RQ3_ssgColorG;
vmCvar_t cg_RQ3_ssgColorB;
vmCvar_t cg_RQ3_ssgColorA;
//Elder: smoke puffs, sparks, etc.
vmCvar_t cg_RQ3_impactEffects;
vmCvar_t cg_drawFriend;
vmCvar_t cg_teamChatsOnly;
vmCvar_t cg_noVoiceChats;
@ -310,7 +312,8 @@ cvarTable_t cvarTable[] = {
{ &cg_RQ3_ssgColorR, "cg_RQ3_ssgColorR", "0.0", CVAR_ARCHIVE },
{ &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_RQ3_ssgColorA, "cg_RQ3_ssgColorA", "0.75", CVAR_ARCHIVE },
{ &cg_RQ3_impactEffects, "cg_RQ3_impactEffects", "1", CVAR_ARCHIVE }
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
};
@ -963,6 +966,7 @@ static void CG_RegisterGraphics( void ) {
cgs.media.glass03 = trap_R_RegisterModel( "models/breakables/glass03.md3" );
//Elder: additional debris
//Todo: load only if in the level
cgs.media.wood01 = trap_R_RegisterModel( "models/breakables/wood01.md3" );
cgs.media.wood02 = trap_R_RegisterModel( "models/breakables/wood02.md3" );
cgs.media.wood03 = trap_R_RegisterModel( "models/breakables/wood03.md3" );

View file

@ -561,8 +561,31 @@ void CG_PredictPlayerState( void ) {
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
}
//Elder: predict bursting here
/*
if ( (cg.snap->ps.weapon == WP_M4 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE) ||
(cg.snap->ps.weapon == WP_MP5 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_MP5MODE) == RQ3_MP5MODE))
{
if (cg_pmove.cmd.buttons & BUTTON_ATTACK)// && client->ps.stats[STAT_BURST] > 0)
{
if ( cg.snap->ps.stats[STAT_BURST] >= 0 && cg.snap->ps.stats[STAT_BURST] < 3)
cg_pmove.cmd.buttons |= BUTTON_ATTACK;
else
cg_pmove.cmd.buttons &= ~BUTTON_ATTACK;
}
else if (cg.snap->ps.stats[STAT_BURST] > 2)
{
cg.snap->ps.stats[STAT_BURST] = 0;
cg.snap->ps.weaponTime += 500;
}
else if (cg.snap->ps.stats[STAT_BURST] > 0)
cg_pmove.cmd.buttons |= BUTTON_ATTACK;
}*/
Pmove (&cg_pmove);
moved = qtrue;
// add push trigger movement effects

View file

@ -471,6 +471,7 @@ void CG_RegisterWeapon( int weaponNum ) {
break;
}
}
if ( !item->classname ) {
CG_Error( "Couldn't find weapon %i", weaponNum );
}
@ -492,9 +493,21 @@ void CG_RegisterWeapon( int weaponNum ) {
if ( ammo->giType == IT_AMMO && ammo->giTag == weaponNum ) {
break;
}
//Elder: hack for handcannon to use M3 ammo icon
else if (weaponNum == WP_HANDCANNON && ammo->giType == IT_AMMO && ammo->giTag == WP_M3)
{
break;
}
//Elder: hack for akimbos to use MK23 ammo icon
else if (weaponNum == WP_AKIMBO && ammo->giType == IT_AMMO && ammo->giTag == WP_PISTOL)
{
break;
}
}
if ( ammo->classname && ammo->world_model[0] ) {
weaponInfo->ammoModel = trap_R_RegisterModel( ammo->world_model[0] );
//Elder: added
weaponInfo->ammoIcon = trap_R_RegisterShader( ammo->icon );
}
strcpy( path, item->world_model[0] );
@ -1236,20 +1249,6 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
}
*/
//Elder: added to supress burst mode flashes + sounds when 'predicting'
// M4
if ( ps->weapon == WP_M4 && ps->stats[STAT_BURST] > 2 ) {
return;
}
// MP5
if ( ps->weapon == WP_MP5 && ps->stats[STAT_BURST] > 2 ) {
return;
}
// MK23
if ( ps->weapon == WP_PISTOL && ps->stats[STAT_BURST] > 0 ) {
return;
}
//Elder: re-added to fix loss of muzzle flashes!
// impulse flash
if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash ) {
@ -1608,6 +1607,10 @@ void CG_NextWeapon_f( void ) {
return;
}
//Elder: don't allow weapon switching when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
//Elder: in the middle of firing, reloading or weapon-switching
//cg.snap->ps.weaponstate == WEAPON_RELOADING when it's in
if (cg.snap->ps.weaponstate == WEAPON_DROPPING && cg.snap->ps.weaponTime > 0) {
@ -1640,6 +1643,7 @@ void CG_NextWeapon_f( void ) {
}
else {
CG_RQ3_Zoom1x();
trap_SendClientCommand("unzoom");
}
}
@ -1670,6 +1674,10 @@ void CG_PrevWeapon_f( void ) {
return;
}
//Elder: don't allow weapon switching when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
//Elder: in the middle of firing, reloading or weapon-switching
//cg.snap->ps.weaponstate == WEAPON_RELOADING when it's in
if (cg.snap->ps.weaponstate == WEAPON_DROPPING && cg.snap->ps.weaponTime > 0) {
@ -1701,6 +1709,7 @@ void CG_PrevWeapon_f( void ) {
}
else {
CG_RQ3_Zoom1x();
trap_SendClientCommand("unzoom");
}
}
@ -1717,8 +1726,10 @@ void CG_SpecialWeapon_f( void ) {
int original;
if ( !cg.snap ) {
//CG_Printf("No snapshot: normally exiting\n");
return;
}
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) {
return;
}
@ -1733,6 +1744,10 @@ void CG_SpecialWeapon_f( void ) {
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;
//Elder: in the middle of firing, reloading or weapon-switching
//cg.snap->ps.weaponstate == WEAPON_RELOADING when it's in
@ -1767,6 +1782,7 @@ void CG_SpecialWeapon_f( void ) {
}
else {
CG_RQ3_Zoom1x();
trap_SendClientCommand("unzoom");
}
}
@ -1790,7 +1806,6 @@ void CG_RQ3_SyncZoom ( void ) {
//CG_Printf("Zoomed out\n");
cg.zoomLevel = 0;
}
}
//Elder: save zoom level and do any other necessary housekeeping
@ -1877,7 +1892,7 @@ void CG_RQ3_Zoom1x () {
cg.zoomLevel = 0;
cg.zoomTime = cg.time;
}
trap_SendClientCommand("unzoom");
//trap_SendClientCommand("unzoom");
}
int CG_RQ3_GetGrenadeMode()
@ -1924,6 +1939,7 @@ void CG_Weapon_f( void ) {
int num;
if ( !cg.snap ) {
//CG_Printf("No snapshot: normally exiting\n");
return;
}
@ -1938,6 +1954,10 @@ void CG_Weapon_f( void ) {
return;
}
//Elder: don't allow weapon switching when in the middle of bursts
if (cg.snap->ps.stats[STAT_BURST] > 0)
return;
//Elder: in the middle of firing, reloading or weapon-switching
if (cg.snap->ps.weaponTime > 0) {
return;
@ -1966,6 +1986,8 @@ void CG_Weapon_f( void ) {
//do weapon select sound
}
trap_SendClientCommand("weapon");
//Elder: added to get out of function at this point
return;
}
num = atoi( CG_Argv( 1 ) );
@ -1992,6 +2014,7 @@ void CG_Weapon_f( void ) {
//cg.zoomLevel = 0;
CG_RQ3_Zoom1x();
trap_SendClientCommand("unzoom");
cg.weaponSelect = num;
}
@ -2065,6 +2088,27 @@ void CG_FireWeapon( centity_t *cent ) {
weap = &cg_weapons[ ent->weapon ];
//Elder: added to supress burst mode flashes + sounds when 'predicting'
// M4
if ( cg.snap->ps.weapon == WP_M4 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_M4MODE) == RQ3_M4MODE &&
cg.snap->ps.stats[STAT_BURST] > 2 )
{
return;
}
// MP5
if ( cg.snap->ps.weapon == WP_MP5 &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_MP5MODE) == RQ3_MP5MODE &&
cg.snap->ps.stats[STAT_BURST] > 2 ) {
return;
}
// MK23
if ( cg.snap->ps.weapon == WP_PISTOL &&
(cg.snap->ps.persistant[PERS_WEAPONMODES] & RQ3_MK23MODE) == RQ3_MK23MODE &&
cg.snap->ps.stats[STAT_BURST] > 0 ) {
return;
}
// mark the entity as muzzle flashing, so when it is added it will
// append the flash to the weapon model
cent->muzzleFlashTime = cg.time;
@ -2125,6 +2169,14 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
qboolean alphaFade;
qboolean isSprite;
int duration;
//Elder: for impact smoke marks
localEntity_t *smokePuff;
vec3_t puffOrigin;
vec3_t puffOffset;
vec3_t puffDir;
int i;
mark = 0;
radius = 32;
@ -2353,8 +2405,8 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
shader = cgs.media.grenadeExplosionShader;
sfx = cgs.media.sfx_rockexp;
mark = cgs.media.burnMarkShader;
radius = 64;
light = 300;
radius = 96; //64
light = 450; //300
isSprite = qtrue;
break;
@ -2380,7 +2432,9 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
break;
}
if ( sfx ) {
//Elder: 75% of the time render a bullet ricochet sound
i = (int)(random() * 35) % 4;
if ( sfx && i < 3) {
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
@ -2416,6 +2470,35 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
//} else {
CG_ImpactMark( mark, origin, dir, random()*360, 1,1,1,1, alphaFade, radius, qfalse );
//}
//Elder: 75% of the time render a smoke puff
i = (int)(random() * 100) % 4;
if (cg_RQ3_impactEffects.integer && i < 3)
{
switch ( weapon ) {
case WP_MP5:
case WP_M4:
case WP_PISTOL:
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.smokePuffShader );
break;
}
}
}
@ -2529,10 +2612,11 @@ static void CG_ShotgunPellet( vec3_t start, vec3_t end, int skipNum, int shellWe
CG_ShotgunPattern
Perform the same traces the server did to locate the
hit splashes (FIXME: ranom seed isn't synce anymore)
hit splashes (FIXME: random seed isn't synce anymore)
Elder: hopefully fixed the seed problem
================
*/
static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, int shotType ) {
static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, int shotType, int seed ) {
int i;
float r, u;
vec3_t end;
@ -2565,8 +2649,10 @@ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, i
for ( i = 0 ; i < count ; i++ ) {
if (shotType == WP_M3)
{
r = crandom() * DEFAULT_M3_HSPREAD * 16;
u = crandom() * DEFAULT_M3_VSPREAD * 16;
r = Q_crandom(&seed) * DEFAULT_M3_HSPREAD * 16;
u = Q_crandom(&seed) * DEFAULT_M3_VSPREAD * 16;
//r = crandom() * DEFAULT_M3_HSPREAD * 16;
//u = crandom() * DEFAULT_M3_VSPREAD * 16;
//r = crandom() * DEFAULT_SHOTGUN_SPREAD * 16;
//u = crandom() * DEFAULT_SHOTGUN_SPREAD * 16;
}
@ -2574,11 +2660,12 @@ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum, i
{
//Elder: fill in shotType
shotType = WP_HANDCANNON;
r = crandom() * DEFAULT_SHOTGUN_HSPREAD * 16 * 4;
u = crandom() * DEFAULT_SHOTGUN_VSPREAD * 16 * hc_multipler;
r = Q_crandom(&seed) * DEFAULT_SHOTGUN_HSPREAD * 16 * 4;
u = Q_crandom(&seed) * DEFAULT_SHOTGUN_VSPREAD * 16 * hc_multipler;
// r = crandom() * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
// u = crandom() * DEFAULT_HANDCANNON_SPREAD * 16 * 4;
} VectorMA( origin, 8192 * 16, forward, end);
}
VectorMA( origin, 8192 * 16, forward, end);
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
@ -2612,13 +2699,14 @@ void CG_ShotgunFire( entityState_t *es, qboolean ism3) {
//Elder: note param changes
if (ism3)
{
CG_ShotgunPattern( es->pos.trBase, es->origin2, es->otherEntityNum, WP_M3);
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->origin2[1] += 5;
CG_ShotgunPattern( es->pos.trBase, es->origin2, es->otherEntityNum, -1 );
CG_ShotgunPattern( es->pos.trBase, es->origin2, es->otherEntityNum, WP_HANDCANNON, es->eventParm);
es->angles2[1] += 20;
//es->origin2[1] += 5;
CG_ShotgunPattern( es->pos.trBase, es->origin2, es->otherEntityNum, -1, es->eventParm);
}
}