Code for the 0-10-0x VM releases
Client-side
This commit is contained in:
Victor Chow 2001-08-30 09:42:25 +00:00
parent 949ab8c2b0
commit 8ea88d097b
12 changed files with 572 additions and 170 deletions

View file

@ -137,7 +137,7 @@ static void CG_Bandage_f (void) {
//CG_Printf("You are too busy with your weapon!\n");
//return;
//}
if (cg.snap->ps.weaponTime > 0)
if (cg.snap->ps.weaponTime > 0 || cg.snap->ps.stats[STAT_RELOADTIME] > 0)
return;
if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_NEED) == RQ3_BANDAGE_NEED) {

View file

@ -517,12 +517,12 @@ static void CG_DrawStatusBar( void ) {
// qhandle_t handle;
//#endif
int i;
static float colors [4][4] = {
{ 0.0f, 1.0f, 0.0f, 1.0f } , //full green
{ 0.8f, 0.0f, 0.0f, 0.7f } , //
{ 0.6f, 0.0f, 0.0f, 0.7f } , //
{ 0.4f, 0.0f, 0.0f, 0.7f } }; //
{ 0.0f, 1.0f, 0.0f, 1.0f } , // full green
{ 0.6f, 0.6f, 0.6f, 1.0f } , // firing
{ 0.8f, 0.8f, 0.0f, 1.0f } , // not maximum
{ 0.8f, 0.0f, 0.0f, 1.0f } }; // out of ammo
cent = &cg_entities[cg.snap->ps.clientNum];
@ -563,6 +563,7 @@ static void CG_DrawStatusBar( void ) {
}*/
CG_DrawPic(8, 440, SMICON_SIZE, SMICON_SIZE, hicon);
//CG_DrawStringExt(44, 444, va("%d", value), hcolor, qtrue, qtrue, 24, 24, 3);
UI_DrawProportionalString(44, 444, va("%d", value), style, hcolor);
@ -584,11 +585,21 @@ static void CG_DrawStatusBar( void ) {
{
value = ps->ammo[cent->currentState.weapon];
if ( value > -1 )
UI_DrawProportionalString(188, 444, va("%d", value), style, colors[0]);
// Select colour
if ( cg.predictedPlayerState.weaponstate == WEAPON_FIRING && cg.predictedPlayerState.weaponTime > 100 )
color = 1;
else if ( ps->ammo[ cent->currentState.weapon ] == 0)
color = 3;
else if ( ps->ammo[ cent->currentState.weapon ] < ClipAmountForAmmo( cent->currentState.weapon ))
color = 2;
else
color = 0;
if ( value >= 0 )
UI_DrawProportionalString(188, 444, va("%d", value), style, colors[color]);
//UI_DrawProportionalString(188, 444, "/"), style, colors[0]);
value = ps->stats[STAT_CLIPS];
if ( value > -1 &&
cg.predictedPlayerState.weapon != WP_KNIFE &&
@ -596,6 +607,10 @@ static void CG_DrawStatusBar( void ) {
UI_DrawProportionalString(288, 444, va("%d", value), style, colors[0]);
}
// Elder: temporary
if (cg.snap->ps.stats[STAT_RELOADTIME] > 0)
UI_DrawProportionalString( 10, 400, va("%i", cg.snap->ps.stats[STAT_RELOADTIME]), style, colors[2]);
//Elder: draw grenades, if any, on the side
if (cg.snap->ps.ammo[ WP_GRENADE ] > 0)
{
@ -606,28 +621,24 @@ static void CG_DrawStatusBar( void ) {
}
//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 ||
i == WP_PISTOL ||
i == WP_GRENADE ||
i == WP_AKIMBO)
continue;
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);
}
//}
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
@ -2086,54 +2097,69 @@ static void CG_DrawCrosshair(void) {
//Elder: Sniper crosshairs - lots of hardcoded values :/
//if ( cg.snap->ps.weapon==WP_SSG3000 && cg.zoomLevel > 0 && cg.zoomLevel < 4) {
if ( cg.snap->ps.weapon == WP_SSG3000 &&
(cg.zoomFirstReturn == -1 || cg.snap->ps.weaponTime < ZOOM_TIME) &&
( (cg.zoomLevel & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW ||
(cg.zoomLevel & RQ3_ZOOM_MED) == RQ3_ZOOM_MED ) ) {
int zoomMag;
x = SCREEN_WIDTH / 2;
y = SCREEN_HEIGHT / 2;
//derive zoom level - seems complicated but they're only bit comparisions
if ( (cg.zoomLevel & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW &&
(cg.zoomLevel & RQ3_ZOOM_MED) == RQ3_ZOOM_MED ) {
zoomMag = 2;
}
else if ( (cg.zoomLevel & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW) {
zoomMag = 0;
}
else if ( (cg.zoomLevel & RQ3_ZOOM_MED) == RQ3_ZOOM_MED) {
zoomMag = 1;
}
else {
//Shouldn't need to be here
CG_Error("CG_DrawCrosshair: received no zoom value\n");
}
//Elder: Setup crosshair colours
crosshairColor[0] = cg_RQ3_ssgColorR.value;
crosshairColor[1] = cg_RQ3_ssgColorG.value;
crosshairColor[2] = cg_RQ3_ssgColorB.value;
crosshairColor[3] = cg_RQ3_ssgColorA.value;
//Clamp
for (i = 0; i < 4; i++)
// some pile of crap
// using SSG and zoomed in
if ( cg.snap->ps.weapon == WP_SSG3000 &&
( (cg.zoomLevel & RQ3_ZOOM_LOW) || (cg.zoomLevel & RQ3_ZOOM_MED) ) )
{
// out of ammo but not reloading
//if ( ( cg.zoomFirstReturn == -1 && cg.snap->ps.stats[STAT_RELOADTIME] <= 0) ||
//( cg.snap->ps.weaponTime == 0 && cg.snap->ps.stats[STAT_RELOADTIME] <= 0))
if ((cg.zoomFirstReturn == -1 || cg.snap->ps.weaponTime < ZOOM_TIME) &&
cg.snap->ps.stats[STAT_RELOADTIME] <= 0)
{
if (crosshairColor[i] > 1.0)
crosshairColor[i] = 1.0;
else if (crosshairColor[i] < 0)
crosshairColor[i] = 0;
}
/*
if ( (cg.zoomFirstReturn == -1 ||
(cg.snap->ps.weaponTime < ZOOM_TIME && cg.snap->ps.stats[STAT_RELOADTIME] < ZOOM_TIME)) &&
!(cg.snap->ps.stats[STAT_RQ3] & RQ3_FASTRELOADS) &&
!(cg.snap->ps.stats[STAT_RQ3] & RQ3_LOCKRELOADS) {
*/
int zoomMag;
trap_R_SetColor(crosshairColor);
//I can probably scale the zoom with the screen width -/+ keys
//But I'll do it later.
CG_DrawPic( x - 128, y - 128, 256, 256, cgs.media.ssgCrosshair[zoomMag]);
trap_R_SetColor(NULL);
return;
x = SCREEN_WIDTH / 2;
y = SCREEN_HEIGHT / 2;
//derive zoom level
if ( (cg.zoomLevel & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW &&
(cg.zoomLevel & RQ3_ZOOM_MED) == RQ3_ZOOM_MED ) {
zoomMag = 2;
}
else if ( (cg.zoomLevel & RQ3_ZOOM_LOW) == RQ3_ZOOM_LOW) {
zoomMag = 0;
}
else if ( (cg.zoomLevel & RQ3_ZOOM_MED) == RQ3_ZOOM_MED) {
zoomMag = 1;
}
else {
//Shouldn't need to be here
CG_Error("CG_DrawCrosshair: received no zoom value\n");
}
//Elder: Setup crosshair colours
crosshairColor[0] = cg_RQ3_ssgColorR.value;
crosshairColor[1] = cg_RQ3_ssgColorG.value;
crosshairColor[2] = cg_RQ3_ssgColorB.value;
crosshairColor[3] = cg_RQ3_ssgColorA.value;
//Clamp
for (i = 0; i < 4; i++)
{
if (crosshairColor[i] > 1.0f)
crosshairColor[i] = 1.0f;
else if (crosshairColor[i] < 0)
crosshairColor[i] = 0;
}
trap_R_SetColor(crosshairColor);
//I can probably scale the zoom with the screen width -/+ keys
//But I'll do it later.
CG_DrawPic( x - 128, y - 128, 256, 256, cgs.media.ssgCrosshair[zoomMag]);
trap_R_SetColor(NULL);
return;
}
}
else {
//else {
x = cg_crosshairX.integer;
y = cg_crosshairY.integer;
CG_AdjustFrom640( &x, &y, &w, &h );
@ -2143,7 +2169,7 @@ static void CG_DrawCrosshair(void) {
ca = 0;
}
hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ];
}
//}
trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w),
y + cg.refdef.y + 0.5 * (cg.refdef.height - h),

View file

@ -810,7 +810,9 @@ static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t co
trap_R_SetColor( color );
ax = x * cgs.screenXScale + cgs.screenXBias;
ay = y * cgs.screenXScale;
// Elder: typo in the mod source
//ay = y * cgs.screenXScale;
ay = y * cgs.screenYScale;
s = str;
while ( *s )

View file

@ -490,7 +490,7 @@ void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum, int numBursts )
int bloodCount = 0;
trace_t tr;
if ( !cg_blood.integer ) {
if ( !cg_blood.integer || cg_RQ3_bloodStyle.integer == 0) {
return;
}

View file

@ -1716,8 +1716,12 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
break;
}
#endif
} else {
} else if (item->giType == IT_HOLDABLE) {
// Elder: we want sounds for unique item pickup
trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
} else {
// Elder: no item pick-up sound
//trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
}
// show icon and name on status bar
@ -1783,9 +1787,17 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
//Elder: modified
CG_FireWeapon( cent, es->eventParm );
break;
case EV_RELOAD_WEAPON:
DEBUGNAME("EV_RELOAD_WEAPON");
CG_ReloadWeapon( cent, es->eventParm );
case EV_RELOAD_WEAPON0:
DEBUGNAME("EV_RELOAD_WEAPON0");
CG_ReloadWeapon( cent, 0 );
break;
case EV_RELOAD_WEAPON1:
DEBUGNAME("EV_RELOAD_WEAPON1");
CG_ReloadWeapon( cent, 1 );
break;
case EV_RELOAD_WEAPON2:
DEBUGNAME("EV_RELOAD_WEAPON2");
CG_ReloadWeapon( cent, 2 );
break;
case EV_USE_ITEM0:
DEBUGNAME("EV_USE_ITEM0");
@ -1955,7 +1967,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_KNIFE_MISS:
DEBUGNAME("EV_KNIFE_MISS");
ByteToDir( es->eventParm, dir );
CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT, RQ3_WPMOD_KNIFESLASH );
CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL, RQ3_WPMOD_KNIFESLASH );
break;
case EV_RAILTRAIL:
@ -1973,20 +1985,59 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_BULLET_HIT_WALL:
DEBUGNAME("EV_BULLET_HIT_WALL");
ByteToDir( es->eventParm, dir );
//Elder: added additional param
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, qfalse );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_DEFAULT);
break;
case EV_BULLET_HIT_METAL:
DEBUGNAME("EV_BULLET_HIT_METAL");
ByteToDir( es->eventParm, dir );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_METAL);
break;
case EV_BULLET_HIT_KEVLAR:
DEBUGNAME("EV_BULLET_HIT_KEVLAR");
ByteToDir( es->eventParm, dir );
VectorScale( dir, -1, dir );
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound);
if (cg_RQ3_impactEffects.integer)
{
vec3_t velocity;
vec3_t origin;
int sparkCount;
int i;
sparkCount = 20 + rand() % 15;
VectorCopy(es->pos.trBase, origin);
origin[2] += 12;
// Generate the particles
for (i = 0; i < sparkCount; i++)
{
VectorScale(dir, 150 + rand() % 30, velocity);
//random upwards sparks
if ( rand() % 5 < 1)
velocity[2] += 120 + rand() % 30;
velocity[0] += rand() % 80 - 40;
velocity[1] += rand() % 80 - 40;
CG_ParticleSparks(origin, velocity, 150 + rand() % 120, 2, 2, -4, 1);
}
}
break;
case EV_BULLET_HIT_FLESH:
DEBUGNAME("EV_BULLET_HIT_FLESH");
//ByteToDir( es->eventParm, dir );
//Elder: added additional param
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm, qfalse );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
break;
case EV_SSG3000_HIT_FLESH:
DEBUGNAME("EV_SSG3000_HIT_FLESH");
ByteToDir( es->eventParm, dir );
//Elder: added additional param
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm, qtrue );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH);
VectorAdd(es->pos.trBase, dir, dir);
CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum2, 16);
break;
case EV_JUMPKICK:

View file

@ -99,7 +99,9 @@ void CG_LoadingClient( int clientNum ) {
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
// Elder: changed
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, DEFAULT_SKIN );
//Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( loadingPlayerIcons[loadingPlayerIconCount] ) {

View file

@ -29,9 +29,11 @@
#define DUCK_TIME 100
#define PAIN_TWITCH_TIME 200
#define WEAPON_SELECT_TIME 1400
#define ITEM_SCALEUP_TIME 1000
// Elder: decreased from 1000
#define ITEM_SCALEUP_TIME 250
#define ZOOM_TIME 150
#define ITEM_BLOB_TIME 200
// Elder: increased from 200
#define ITEM_BLOB_TIME 300
#define MUZZLE_FLASH_TIME 20
#define SINK_TIME 1000 // time for fragments to sink into ground before going away
#define ATTACKER_HEAD_TIME 10000
@ -65,23 +67,33 @@
#define TEAM_OVERLAY_MAXNAME_WIDTH 12
#define TEAM_OVERLAY_MAXLOCATION_WIDTH 16
#define DEFAULT_MODEL "sarge"
//#define DEFAULT_MODEL "sarge"
// Elder: changed to good ol' resdog
#define DEFAULT_MODEL "grunt"
// Elder: this is added
#define DEFAULT_SKIN "resdog"
#ifdef MISSIONPACK
#define DEFAULT_TEAM_MODEL "james"
#define DEFAULT_TEAM_HEAD "*james"
#else
#define DEFAULT_TEAM_MODEL "sarge"
#define DEFAULT_TEAM_HEAD "sarge"
#define DEFAULT_TEAM_MODEL "grunt"
#define DEFAULT_TEAM_HEAD "grunt"
#endif
#define DEFAULT_REDTEAM_NAME "Stroggs"
#define DEFAULT_BLUETEAM_NAME "Pagans"
// Elder: Changed
#define DEFAULT_REDTEAM_NAME "Reservoir Dogs"
#define DEFAULT_BLUETEAM_NAME "Psychos"
//Elder: Some ssg stuff
// Elder: Some ssg stuff
#define ZOOM_LEVELS 3
#define ZOOM_PREPTIME 10 //milliseconds
// Elder: Zoom status
#define ZOOM_OUTOFAMMO -1 // stay in current FOV even when firing
#define ZOOM_IDLE 0 // stay in current FOV if not firing or reloading
#define ZOOM_OUT 1 // switch to 90 degree FOV
//Elder: max number of "blood" marks when hitting a player w/ shell weapons
// Elder: max number of "blood" marks when hitting a player w/ shell weapons
#define MAX_SHELL_HITS 6
typedef enum {
@ -388,7 +400,7 @@ typedef struct weaponInfo_s {
qhandle_t firstModel; //Elder: view model
qhandle_t animHandModel; //Blaze: for animations
animation_t animations[MAX_WEAPON_ANIMATIONS];
animation_t animations[MAX_WEAPON_ANIMATIONS];
vec3_t weaponMidpoint; // so it will rotate centered instead of by tag
@ -919,6 +931,12 @@ typedef struct {
sfxHandle_t sfx_ric1;
sfxHandle_t sfx_ric2;
sfxHandle_t sfx_ric3;
// Elder: Metal ricochet sounds
sfxHandle_t sfx_metalric1;
sfxHandle_t sfx_metalric2;
sfxHandle_t sfx_metalric3;
sfxHandle_t sfx_railg;
sfxHandle_t sfx_rockexp;
sfxHandle_t sfx_plasmaexp;
@ -1481,7 +1499,7 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
vec3_t dir, impactSound_t soundType, int weapModification ); //Elder: added weapMod
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, qboolean armorPiercing );
void CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean flesh, int fleshEntityNum, impactSound_t soundType);
void CG_RailTrail( clientInfo_t *ci, vec3_t start, vec3_t end );
void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi );
@ -1794,7 +1812,7 @@ void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent);
void CG_AddParticleShrapnel (localEntity_t *le);
void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent);
void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration);
void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed);
void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed, float scale);
void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir);
void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha);
void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd);

View file

@ -785,6 +785,11 @@ static void CG_RegisterSounds( void ) {
cgs.media.sfx_ric1 = trap_S_RegisterSound ("sound/weapons/machinegun/ric1.wav", qfalse);
cgs.media.sfx_ric2 = trap_S_RegisterSound ("sound/weapons/machinegun/ric2.wav", qfalse);
cgs.media.sfx_ric3 = trap_S_RegisterSound ("sound/weapons/machinegun/ric3.wav", qfalse);
// Elder: added
cgs.media.sfx_metalric1 = trap_S_RegisterSound ("sound/world/impactmetal01.wav", qfalse);
cgs.media.sfx_metalric2 = trap_S_RegisterSound ("sound/world/impactmetal02.wav", qfalse);
cgs.media.sfx_metalric3 = trap_S_RegisterSound ("sound/world/impactmetal03.wav", qfalse);
cgs.media.sfx_railg = trap_S_RegisterSound ("sound/weapons/railgun/railgf1a.wav", qfalse);
cgs.media.sfx_rockexp = trap_S_RegisterSound ("sound/weapons/rocket/rocklx1a.wav", qfalse);
cgs.media.sfx_plasmaexp = trap_S_RegisterSound ("sound/weapons/plasma/plasmx1a.wav", qfalse);

View file

@ -1450,10 +1450,12 @@ void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration)
p->alpha = 1.0;
p->alphavel = 0;
/*
p->height = 0.5;
p->width = 0.5;
p->endheight = 0.5;
p->endwidth = 0.5;
*/
p->pshader = cgs.media.tracerShader;
@ -2067,7 +2069,8 @@ void CG_ParticleBloodCloud (centity_t *cent, vec3_t origin, vec3_t dir)
}
void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed)
// Elder: modified to suit our impact marks
void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed, float scale)
{
cparticle_t *p;
@ -2086,10 +2089,17 @@ void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y,
p->alpha = 0.4f;
p->alphavel = 0;
/*
// Elder: old settings
p->height = 0.5;
p->width = 0.5;
p->endheight = 0.5;
p->endwidth = 0.5;
*/
p->height = 1.5 * scale;
p->width = 1.5 * scale;
p->endheight = 0.75 * scale;
p->endwidth = 0.75 * scale;
p->pshader = cgs.media.tracerShader;
@ -2104,7 +2114,10 @@ void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y,
p->vel[1] = vel[1];
p->vel[2] = vel[2];
p->accel[0] = p->accel[1] = p->accel[2] = 0;
// Elder: old settings
//p->accel[0] = p->accel[1] = p->accel[2] = 0;
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY * 4;
p->vel[0] += (crandom() * 4);
p->vel[1] += (crandom() * 4);

View file

@ -666,7 +666,8 @@ static void CG_LoadClientInfo( clientInfo_t *ci ) {
CG_Error( "DEFAULT_TEAM_MODEL / skin (%s/%s) failed to register", DEFAULT_TEAM_MODEL, ci->skinName );
}
} else {
if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default", DEFAULT_MODEL, "default", teamname ) ) {
if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, DEFAULT_SKIN, DEFAULT_MODEL, DEFAULT_SKIN, teamname ) ) {
//if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default", DEFAULT_MODEL, "default", teamname ) ) {
CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL );
}
}
@ -1272,6 +1273,8 @@ void CG_WeaponAnimation( centity_t *cent, int *weaponOld, int *weapon, float *we
{
clientInfo_t *ci;
int clientNum;
int stateAnimNum;
int weapAnimNum;
clientNum = cent->currentState.clientNum;
@ -1282,6 +1285,47 @@ void CG_WeaponAnimation( centity_t *cent, int *weaponOld, int *weapon, float *we
ci = &cgs.clientinfo[ clientNum ];
// Elder: FIXME? - hack hehe
// Compare master copy with existing animation frames
// The only time when they are supposed to be mismatched is when
// switching to a new animation (handled in first condition)
// Even if they are wrong, yet identical, you can still work with it
// TODO: Should also check loop and flipflop but should suffice for 99% of the cases
stateAnimNum = cent->currentState.generic1 & ~ANIM_TOGGLEBIT;
weapAnimNum = cent->pe.weapon.animationNumber & ~ANIM_TOGGLEBIT;
if (stateAnimNum == weapAnimNum)
{
if (cg_weapons[cent->currentState.weapon].animations[stateAnimNum].firstFrame == cent->pe.weapon.animation->firstFrame &&
cg_weapons[cent->currentState.weapon].animations[stateAnimNum].numFrames == cent->pe.weapon.animation->numFrames)
{
// don't compile my test spam
#if 0
CG_Printf("Animation info okay: (%i versus %i) and (%i versus %i)\n",
cg_weapons[cent->currentState.weapon].animations[stateAnimNum].firstFrame,
cent->pe.weapon.animation->firstFrame,
cg_weapons[cent->currentState.weapon].animations[stateAnimNum].numFrames,
cent->pe.weapon.animation->numFrames);
#endif
}
else
{
// don't compile my test spam
#if 0
CG_Printf("Mismatch of animation info (%i versus %i) and (%i versus %i)\n",
cg_weapons[cent->currentState.weapon].animations[stateAnimNum].firstFrame,
cent->pe.weapon.animation->firstFrame,
cg_weapons[cent->currentState.weapon].animations[stateAnimNum].numFrames,
cent->pe.weapon.animation->numFrames);
CG_Printf("Compensating...\n");
#endif
cent->pe.weapon.animation = &cg_weapons[cent->currentState.weapon].animations[stateAnimNum];
}
}
else
{
//CG_Printf("Mismatch of animation number (%i versus %i)\n", stateAnimNum, weapAnimNum);
}
CG_RunLerpFrame( ci, &cent->pe.weapon, cent->currentState.generic1, 1, qtrue );
// QUARANTINE - Debug - Animations
@ -1562,6 +1606,69 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v
//==========================================================================
/*
===============
CG_HCSmokeTrail
Added by Elder
===============
*/
static void CG_HCSmokeTrail( centity_t *cent ) {
localEntity_t *smoke;
vec3_t origin;
vec3_t velocity;
int anim;
int smokeTime;
if ( cg_noProjectileTrail.integer || cent->trailTime > cg.time ) {
return;
}
anim = cent->pe.legs.animationNumber & ~ANIM_TOGGLEBIT;
if ( anim != BOTH_DEATH1 && anim != BOTH_DEAD1 &&
anim != BOTH_DEATH2 && anim != BOTH_DEAD2 &&
anim != BOTH_DEATH3 && anim != BOTH_DEAD3 ) {
return;
}
// setup smoke depending on state
if (anim == BOTH_DEAD1 || anim == BOTH_DEAD2 || anim == BOTH_DEAD3)
{
velocity[0] = rand() % 10 - 5;
velocity[1] = rand() % 8 - 4;
velocity[2] = 24 + rand() % 40;
cent->trailTime += 350;
smokeTime = 2250 + rand() % 250;
}
else
{
velocity[0] = 0;
velocity[1] = 0;
velocity[2] = 10 + rand() % 16;
cent->trailTime += 150;
smokeTime = 1400 + rand() % 200;
}
if ( cent->trailTime < cg.time ) {
cent->trailTime = cg.time;
}
VectorCopy( cent->lerpOrigin, origin );
origin[2] -= 6;
smoke = CG_SmokePuff( origin, velocity,
20 + rand() % 4,
1, 1, 1, 0.33f,
smokeTime,
cg.time,
0,
0,
cgs.media.smokePuffShader );
// use the optimized local entity add
smoke->leType = LE_SCALE_FADE;
}
/*
===============
CG_HasteTrail
@ -1962,6 +2069,11 @@ static void CG_PlayerPowerups( centity_t *cent, refEntity_t *torso ) {
if ( powerups & ( 1 << PW_HASTE ) ) {
CG_HasteTrail( cent );
}
// Elder: HC Smoke
//if ( powerups & ( 1 << PW_HANDCANNON_SMOKED) ) {
//CG_HCSmokeTrail( cent );
//}
}
@ -2668,6 +2780,11 @@ void CG_Player( centity_t *cent ) {
// add powerups floating behind the player
CG_PlayerPowerups( cent, &torso );
// Elder: HC Smoke
if ( cent->currentState.eFlags & EF_HANDCANNON_SMOKED ) {
CG_HCSmokeTrail( cent );
}
}

View file

@ -578,7 +578,8 @@ static int CG_CalcFov( void ) {
fov_x = fov_x + f * ( zoomFov - fov_x );
}
//Idle state or out of ammo
else if (cg.snap->ps.weaponTime == 0)
else if (cg.snap->ps.weaponTime == 0 &&
cg.snap->ps.stats[STAT_RELOADTIME] == 0)
{
fov_x = CG_RQ3_GetFov();
if (fov_x == 90)
@ -590,17 +591,20 @@ static int CG_CalcFov( void ) {
//cg.zoomFirstReturn = -1;
//else
if (cg.lowAmmoWarning)
cg.zoomFirstReturn = -1;
cg.zoomFirstReturn = ZOOM_OUTOFAMMO;
else
cg.zoomFirstReturn = 0;
cg.zoomFirstReturn = ZOOM_IDLE;
}
//Zoom back in after a reload or fire or weapon switch
else if (cg.snap->ps.weaponTime < ZOOM_TIME)
else if (cg.snap->ps.weaponTime < ZOOM_TIME &&
cg.snap->ps.stats[STAT_RELOADTIME] < ZOOM_TIME &&
!(cg.snap->ps.stats[STAT_RQ3] & RQ3_FASTRELOADS))
{
if (cg.zoomFirstReturn == 1)
if (cg.zoomFirstReturn == ZOOM_OUT ||
cg.zoomFirstReturn == ZOOM_OUTOFAMMO && cg.snap->ps.stats[STAT_RELOADTIME] > 0)
{
cg.zoomTime = cg.time;
cg.zoomFirstReturn = 0;
cg.zoomFirstReturn = ZOOM_IDLE;
}
fov_x = 90;
@ -612,7 +616,7 @@ static int CG_CalcFov( void ) {
cg.zoomed = qtrue;
f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
if ( f > 1.0 || cg.zoomFirstReturn == -1)
if ( f > 1.0 || cg.zoomFirstReturn == ZOOM_OUTOFAMMO)
fov_x = zoomFov;
else
fov_x = fov_x + f * ( zoomFov - fov_x );
@ -621,15 +625,17 @@ static int CG_CalcFov( void ) {
//first time after a shot or reload - zoom out
else
{
if (cg.zoomFirstReturn == 0)
if (cg.zoomFirstReturn == ZOOM_IDLE)
{
cg.zoomTime = cg.time;
cg.zoomFirstReturn = 1;
cg.zoomFirstReturn = ZOOM_OUT;
}
fov_x = CG_RQ3_GetFov();
if (cg.zoomFirstReturn == -1)
if (cg.zoomFirstReturn == ZOOM_OUTOFAMMO &&
cg.snap->ps.stats[STAT_RELOADATTEMPTS] == 0)// &&
//cg.snap->ps.weaponstate != WEAPON_RELOADING)
zoomFov = fov_x;
else
zoomFov = 90;

View file

@ -786,8 +786,13 @@ void CG_RegisterWeapon( int weaponNum ) {
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m4/m4fire.wav", qfalse );
weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass;
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/m4/m4out.wav", qfalse );
weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/m4/m4in.wav", qfalse );
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m4/m4in.wav", qfalse );
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
Com_sprintf( filename, sizeof(filename), "models/weapons2/m4/animation.cfg" );
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
Com_Printf("Failed to load weapon animation file %s\n", filename);
}
break;
case WP_SSG3000:
@ -795,6 +800,9 @@ void CG_RegisterWeapon( int weaponNum ) {
MAKERGB( weaponInfo->flashDlightColor, 1, 0.5f, 0 );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgfire.wav", qfalse );
weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass;
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgbolt.wav", qfalse );
weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgin.wav", qfalse );
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgbolt.wav", qfalse );
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
Com_sprintf( filename, sizeof(filename), "models/weapons2/ssg3000/animation.cfg" );
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
@ -807,6 +815,9 @@ void CG_RegisterWeapon( int weaponNum ) {
MAKERGB( weaponInfo->flashDlightColor, 1, 0.75f, 0 );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/mp5/mp5fire.wav", qfalse );
weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass;
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mp5/mp5out.wav", qfalse );
weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mp5/mp5in.wav", qfalse );
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mp5/mp5slide.wav", qfalse );
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
break;
@ -817,7 +828,10 @@ void CG_RegisterWeapon( int weaponNum ) {
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/handcannon/hcfire.wav", qfalse );
weaponInfo->ejectBrassFunc = CG_ShotgunEjectBrass;
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/handcannon/hcopen.wav", qfalse );
weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/handcannon/hcout.wav", qfalse );
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/handcannon/hcclose.wav", qfalse );
Com_sprintf( filename, sizeof(filename), "models/weapons2/handcannon/animation.cfg" );
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
Com_Printf("Failed to load weapon animation file %s\n", filename);
@ -827,7 +841,7 @@ void CG_RegisterWeapon( int weaponNum ) {
case WP_M3:
MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m3/m3fire.wav", qfalse );
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/m3/m3in.wav", qfalse );
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m3/m3in.wav", qfalse );
weaponInfo->ejectBrassFunc = CG_ShotgunEjectBrass;
Com_sprintf( filename, sizeof(filename), "models/weapons2/m3/animation.cfg" );
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
@ -1269,6 +1283,10 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
CG_PositionWeaponOnTag( &gun, parent, parent->hModel, "tag_weapon");
}
// Elder: break off here so we still have weapon animations on bolt out
if (cg.zoomed)
return;
CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );
// add the spinning barrel
@ -1356,8 +1374,13 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
//Elder: add conditional here so the dlight is still drawn when cg_RQ3_flash is 0
if ( cg_RQ3_flash.integer ) {
if (ps) {
//Elder: draw flash based on first-person view
// Elder: draw flash based on first-person view
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash");
// Make flash larger to compensate for depth hack
VectorScale( flash.axis[0], 2.0f, flash.axis[0] );
VectorScale( flash.axis[1], 2.0f, flash.axis[1] );
VectorScale( flash.axis[2], 2.0f, flash.axis[2] );
flash.nonNormalizedAxes = qtrue;
}
else {
//Elder: draw flash based on 3rd-person view
@ -1444,10 +1467,11 @@ void CG_AddViewWeapon( playerState_t *ps ) {
}
// Hawkins- don't draw gun if zoomed
// Elder: we'll break it off later because we still need to perform animation operations
/*
if(cg.zoomed)
return;
*/
// don't draw if testing a gun model
if ( cg.testGun ) {
return;
@ -1515,7 +1539,8 @@ void CG_AddViewWeapon( playerState_t *ps ) {
ps->weapon == WP_PISTOL ||
ps->weapon == WP_M3 ||
ps->weapon == WP_HANDCANNON ||
ps->weapon == WP_SSG3000) {
ps->weapon == WP_SSG3000 ||
ps->weapon == WP_M4) {
// development tool
hand.frame = hand.oldframe = cg_gun_frame.integer;
hand.backlerp = 0;
@ -1673,11 +1698,10 @@ void CG_NextWeapon_f( void ) {
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_RELOADING && cg.snap->ps.weaponTime > 0) {
//if (cg.snap->ps.weaponTime > 0) {
return;
}
}*/
//Elder: added
//cg.zoomed = qfalse;
@ -1827,18 +1851,21 @@ void CG_SpecialWeapon_f( void ) {
//Skip normal weapons
switch (cg.weaponSelect) {
case WP_PISTOL:
case WP_AKIMBO:
case WP_KNIFE:
case WP_GRENADE:
continue;
case WP_PISTOL:
case WP_AKIMBO:
case WP_KNIFE:
case WP_GRENADE:
continue;
break;
}
if ( CG_WeaponSelectable( cg.weaponSelect ) ) {
break;
}
}
if ( i == 16 ) {
// FIXME: 15 because of the stupid continue I used
if ( i >= 15 ) {
cg.weaponSelect = original;
}
else {
@ -2020,7 +2047,7 @@ void CG_Weapon_f( void ) {
return;
//Elder: in the middle of firing, reloading or weapon-switching
if (cg.snap->ps.weaponTime > 0) {
if (cg.snap->ps.weaponTime > 0 || cg.snap->ps.stats[STAT_RELOADTIME] > 0) {
return;
}
@ -2252,6 +2279,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
vec3_t puffOffset;
vec3_t puffDir;
//Elder: for impact sparks
vec3_t velocity;
int sparkCount;
int i;
mark = 0;
@ -2277,12 +2308,25 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
if (soundType == IMPACTSOUND_METAL)
{
if ( r < 2 ) {
sfx = cgs.media.sfx_metalric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_metalric2;
} else {
sfx = cgs.media.sfx_metalric3;
}
}
else
{
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
}
}
radius = 8;
@ -2294,16 +2338,85 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
if (soundType == IMPACTSOUND_METAL)
{
if ( r < 2 ) {
sfx = cgs.media.sfx_metalric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_metalric2;
} else {
sfx = cgs.media.sfx_metalric3;
}
}
else
{
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
}
}
radius = 8;
break;
case WP_SSG3000:
mod = cgs.media.bulletFlashModel;
shader = cgs.media.bulletExplosionShader;
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
if (soundType == IMPACTSOUND_METAL)
{
if ( r < 2 ) {
sfx = cgs.media.sfx_metalric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_metalric2;
} else {
sfx = cgs.media.sfx_metalric3;
}
}
else
{
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
}
}
radius = 8;
break;
case WP_AKIMBO:
mod = cgs.media.bulletFlashModel;
shader = cgs.media.bulletExplosionShader;
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
if (soundType == IMPACTSOUND_METAL)
{
if ( r < 2 ) {
sfx = cgs.media.sfx_metalric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_metalric2;
} else {
sfx = cgs.media.sfx_metalric3;
}
}
else
{
if ( r < 2 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
}
}
radius = 8;
break;
//Blaze: Reaction MP5
case WP_MP5:
mod = cgs.media.bulletFlashModel;
@ -2311,14 +2424,26 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
if ( r == 0 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 1 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
if (soundType == IMPACTSOUND_METAL)
{
if ( r < 2 ) {
sfx = cgs.media.sfx_metalric1;
} else if ( r == 2 ) {
sfx = cgs.media.sfx_metalric2;
} else {
sfx = cgs.media.sfx_metalric3;
}
}
else
{
if ( r == 0 ) {
sfx = cgs.media.sfx_ric1;
} else if ( r == 1 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
}
}
radius = 8;
break;
//Blaze: Reaction Shotgun
@ -2336,13 +2461,6 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
sfx = 0;
radius = 4;
break;
case WP_AKIMBO:
mod = cgs.media.bulletFlashModel;
shader = cgs.media.bulletExplosionShader;
mark = cgs.media.bulletMarkShader;
sfx = 0;
radius = 4;
break;
case WP_GRENADE:
mod = cgs.media.dishFlashModel;
shader = cgs.media.grenadeExplosionShader;
@ -2383,14 +2501,14 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
break;
}
// Knives always play sound
if (weapon == WP_KNIFE)
// Knives, SSG, and grenades always play sound
if (weapon == WP_KNIFE || weapon == WP_SSG3000 || weapon == WP_GRENADE)
i = 1;
else
//Elder: 75% of the time render a bullet ricochet sound
i = (int)(random() * 35) % 4;
//Elder: 90% of the time render a bullet ricochet sound
i = rand() % 10;
if ( sfx && i < 3) {
if ( sfx && i < 9) {
trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
}
@ -2437,13 +2555,14 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
//Elder: 75% of the time render a smoke puff
i = (int)(random() * 100) % 4;
i = rand() % 4;
if (cg_RQ3_impactEffects.integer && i < 3)
{
switch ( weapon ) {
case WP_MP5:
case WP_M4:
case WP_PISTOL:
case WP_SSG3000:
puffDir[0] = 0;
puffDir[1] = 0;
puffDir[2] = 16;
@ -2463,6 +2582,53 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin,
break;
}
}
// Elder: Spark effect for metal surfaces
if (cg_RQ3_impactEffects.integer && soundType == IMPACTSOUND_METAL)
{
if (weapon != WP_GRENADE)
{
if (weapon == WP_M3 || weapon == WP_HANDCANNON)
sparkCount = 5 + rand() % 5;
else if (weapon == WP_KNIFE)
sparkCount = 10 + rand() % 10;
else if (weapon == WP_SSG3000)
sparkCount = 25 + rand() % 20;
else
sparkCount = 15 + rand() % 15;
// Generate the particles
for (i = 0; i < sparkCount; i++)
{
if (weapon == WP_KNIFE)
VectorScale(dir, 50 + rand() % 10, velocity);
else
VectorScale(dir, 150 + rand() % 30, velocity);
//random upwards sparks
if ( rand() % 5 < 1)
velocity[2] += 120 + rand() % 30;
velocity[0] += rand() % 50 - 25;
velocity[1] += rand() % 50 - 25;
CG_ParticleSparks(origin, velocity, 100 + rand() % 120, 2, 2, -4, 1);
}
}
}
// Elder: grenade explosion
if (cg_RQ3_impactEffects.integer && weapon == WP_GRENADE)
{
sparkCount = 60 + rand() % 15;
origin[2] += 32;
for (i = 0; i < sparkCount; i++)
{
VectorScale (dir, rand() % 200, velocity);
velocity[0] += rand() % 200 - 100;
velocity[1] += rand() % 200 - 100;
CG_ParticleSparks(origin, velocity, 900 + rand() % 200, 5, 5, -2.5f, 3.5f);
}
}
}
@ -2820,11 +2986,11 @@ static qboolean CG_CalcMuzzlePoint( int entityNum, vec3_t muzzle ) {
CG_Bullet
Renders bullet effects.
Elder: added armorPiercing conditional
Elder: added soundType conditional
======================
*/
void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal,
qboolean flesh, int fleshEntityNum, qboolean armorPiercing ) {
qboolean flesh, int fleshEntityNum, impactSound_t soundType) {
trace_t trace;
int sourceContentType, destContentType;
vec3_t start;
@ -2877,14 +3043,10 @@ void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal,
// impact splash and mark
if ( flesh ) {
//Elder: added
if ( armorPiercing && CG_CalcMuzzlePoint( sourceEntityNum, start))
CG_BleedSpray(start, end, fleshEntityNum, 16);
else
CG_Bleed( end, fleshEntityNum );
CG_Bleed( end, fleshEntityNum );
} else {
//Blaze: Changed WP_MACHINEGUN to WP_PISTOL
CG_MissileHitWall( WP_PISTOL, 0, end, normal, IMPACTSOUND_DEFAULT, 0 );
CG_MissileHitWall( WP_PISTOL, 0, end, normal, soundType, 0 );
}
}