summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_event.c19
-rw-r--r--src/cgame/cg_local.h15
-rw-r--r--src/cgame/cg_main.c1
-rw-r--r--src/cgame/cg_players.c15
-rw-r--r--src/cgame/cg_view.c64
-rw-r--r--src/cgame/cg_weapons.c213
-rw-r--r--src/game/bg_misc.c46
-rw-r--r--src/game/bg_pmove.c8
-rw-r--r--src/game/bg_public.h9
-rw-r--r--src/game/g_active.c13
-rw-r--r--src/game/g_cmds.c9
-rw-r--r--src/game/g_local.h7
-rw-r--r--src/game/g_weapon.c44
13 files changed, 273 insertions, 190 deletions
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index 6dc12f29..27d8ada8 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -812,19 +812,15 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
break;
case EV_FIRE_WEAPON:
DEBUGNAME("EV_FIRE_WEAPON");
- CG_FireWeapon( cent );
+ CG_FireWeapon( cent, 0 );
break;
case EV_FIRE_WEAPON2:
DEBUGNAME("EV_FIRE_WEAPON2");
- CG_FireWeapon( cent ); //FIXME:??
+ CG_FireWeapon( cent, 1 ); //FIXME:??
break;
case EV_FIRE_WEAPON3:
DEBUGNAME("EV_FIRE_WEAPON3");
- CG_FireWeapon( cent ); //FIXME:??
- break;
- case EV_FIRE_WEAPONBOTH:
- DEBUGNAME("EV_FIRE_WEAPONBOTH");
- CG_FireWeapon( cent ); //FIXME:??
+ CG_FireWeapon( cent, 2 ); //FIXME:??
break;
case EV_USE_ITEM0:
DEBUGNAME("EV_USE_ITEM0");
@@ -1039,8 +1035,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
velocity[ 1 ] = ( 2 * random( ) - 1.0f ) * MASS_EJECTION_VEL;
velocity[ 2 ] = ( 2 * random( ) - 1.0f ) * MASS_EJECTION_VEL;
- CG_LaunchSprite( origin, velocity, accel, 0.999, 4.0f, 2.0f, 255, 0, rand( ) % 360,
- cg.time, 5000 + ( crandom( ) * 3000 ),
+ CG_LaunchSprite( origin, velocity, accel, 0.0f, 0.5f, 4.0f, 2.0f, 255, 0, rand( ) % 360,
+ cg.time, cg.time, 5000 + ( crandom( ) * 3000 ),
spark, qfalse, qfalse );
}
@@ -1158,6 +1154,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
cg.lastBuildAttempt = cg.time;
break;
+ case EV_POISONCLOUD:
+ DEBUGNAME("EV_POISONCLOUD");
+ cg.firstPoisonedTime = cg.time;
+ break;
+
case EV_PLAYER_RESPAWN:
DEBUGNAME("EV_PLAYER_RESPAWN");
if( es->number == cg.clientNum )
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 30e07080..6324de79 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -174,6 +174,8 @@ typedef struct centity_s {
qboolean currentValid; // true if cg.frame holds this entity
int muzzleFlashTime; // move to playerEntity?
+ int muzzleFlashTime2; // move to playerEntity?
+ int muzzleFlashTime3; // move to playerEntity?
int previousEvent;
int teleportFlag;
@@ -203,6 +205,8 @@ typedef struct centity_s {
//TA:
buildableAnimNumber_t buildableAnim; //persistant anim number
int flamerTime; //limit flameball count
+ int poisonTime; //limit poison count
+ int firstPoisonTime; //when poison cloud starts
int jetTime; //limit jet count
} centity_t;
@@ -712,6 +716,9 @@ typedef struct {
int rightMoveTime;
int upMoveTime;
+ int poisonedTime; //TA: poison cloud
+ int firstPoisonedTime; //TA: poison cloud
+
float charModelFraction; //TA: loading percentages
float mediaFraction;
float buildablesFraction;
@@ -834,6 +841,7 @@ typedef struct {
qhandle_t greenBloodMarkShader;
qhandle_t greenBloodExplosionShader;
qhandle_t explosionTrailShader;
+ qhandle_t poisonCloudShader;
qhandle_t humanNV;
qhandle_t humanTorch8;
@@ -1407,11 +1415,12 @@ void CG_InitBuildables( );
// cg_spriter.c
//
void CG_Spriter( centity_t *cent );
-void CG_LaunchSprite( const vec3_t p, const vec3_t vel, const vec3_t accel, float bounce,
+void CG_LaunchSprite( const vec3_t p, const vec3_t vel, const vec3_t accel,
+ float spread, float bounce,
float initRad, float finalRad,
float initAlp, float finalAlp,
float rotation,
- int startTime, int duration,
+ int startTime, int shaderTime, int duration,
qhandle_t hShader, qboolean overdraw, qboolean realLight );
//
@@ -1469,7 +1478,7 @@ void CG_RegisterUpgrade( int upgradeNum );
void CG_InitWeapons( );
void CG_RegisterWeapon( int weaponNum );
-void CG_FireWeapon( centity_t *cent );
+void CG_FireWeapon( centity_t *cent, int mode );
void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, impactSound_t soundType, int damage );
void CG_Explosion( int clientNum, vec3_t origin, vec3_t dir );
void CG_MissileHitPlayer( int weapon, vec3_t origin, vec3_t dir, int entityNum, int damage );
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index b2a12e80..57fb621e 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -718,6 +718,7 @@ static void CG_RegisterGraphics( void ) {
cgs.media.greenBloodExplosionShader = trap_R_RegisterShader( "greenBloodExplosion" );
cgs.media.greenBloodMarkShader = trap_R_RegisterShader( "greenBloodMark" );
cgs.media.explosionTrailShader = trap_R_RegisterShader( "explosionTrail" );
+ cgs.media.poisonCloudShader = trap_R_RegisterShader( "poisonCloud" );
for( i = 0; i < 32; i++ )
cgs.media.flameShader[ i ] = trap_R_RegisterShader( va( "fireball%d", i + 1 ) );
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c
index 7f9dc88d..ee0ce936 100644
--- a/src/cgame/cg_players.c
+++ b/src/cgame/cg_players.c
@@ -1384,8 +1384,6 @@ static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso )
vec3_t right = { 0.0f, 1.0f, 0.0f };
vec3_t pvel;
int addTime;
- float fspread = tan( DEG2RAD( ( random( ) * JET_SPREAD ) - ( JET_SPREAD / 2 ) ) );
- float rspread = tan( DEG2RAD( ( random( ) * JET_SPREAD ) - ( JET_SPREAD / 2 ) ) );
held = cent->currentState.modelindex;
active = cent->currentState.modelindex2;
@@ -1432,13 +1430,10 @@ static void CG_PlayerUpgrades( centity_t *cent, refEntity_t *torso )
VectorScale( cent->currentState.pos.trDelta, 0.75f, pvel );
VectorAdd( vel, pvel, vel );
-
- VectorMA( vel, fspread, forward, vel );
- VectorMA( vel, rspread, right, vel );
- CG_LaunchSprite( origin, vel, acc,
+ CG_LaunchSprite( origin, vel, acc, JET_SPREAD,
0.5f, 4.0f, 20.0f, 128.0f, 0.0f,
- rand( ) % 360, cg.time, JET_LIFETIME,
+ rand( ) % 360, cg.time, cg.time, JET_LIFETIME,
cgs.media.smokePuffShader, qfalse, qfalse );
//set next ball time
@@ -1895,7 +1890,8 @@ void CG_Player( centity_t *cent )
AnglesToAxis( cent->lerpAngles, tempAxis );
//rotate lerpAngles to floor
- if( BG_rotateAxis( es->angles2, tempAxis, tempAxis2, qtrue, es->eFlags & EF_WALLCLIMBCEILING ) )
+ if( es->eFlags & EF_WALLCLIMB &&
+ BG_rotateAxis( es->angles2, tempAxis, tempAxis2, qtrue, es->eFlags & EF_WALLCLIMBCEILING ) )
AxisToAngles( tempAxis2, angles );
else
VectorCopy( cent->lerpAngles, angles );
@@ -1908,7 +1904,8 @@ void CG_Player( centity_t *cent )
CG_PlayerAngles( cent, angles, legs.axis, torso.axis, head.axis );
//rotate the legs axis to back to the wall
- if( BG_rotateAxis( es->angles2, legs.axis, tempAxis, qfalse, es->eFlags & EF_WALLCLIMBCEILING ) )
+ if( es->eFlags & EF_WALLCLIMB &&
+ BG_rotateAxis( es->angles2, legs.axis, tempAxis, qfalse, es->eFlags & EF_WALLCLIMBCEILING ) )
AxisCopy( tempAxis, legs.axis );
// get the animation state (after rotation, to allow feet shuffle)
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index 3002c66b..eb9cfacd 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -225,10 +225,15 @@ static void CG_OffsetThirdPersonView( void )
float forwardScale, sideScale;
vec3_t surfNormal;
- if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
- VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
+ if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
+ {
+ if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
+ VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
+ else
+ VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );
+ }
else
- VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );
+ VectorSet( surfNormal, 0.0f, 0.0f, 1.0f );
VectorMA( cg.refdef.vieworg, cg.predictedPlayerState.viewheight, surfNormal, cg.refdef.vieworg );
@@ -326,6 +331,14 @@ static void CG_StepOffset( void )
cg.refdef.vieworg[2] -= stepChange;
}
}
+
+#define PCLOUD_ROLL_AMPLITUDE 25.0f
+#define PCLOUD_ROLL_FREQUENCY 0.4f
+#define PCLOUD_ZOOM_AMPLITUDE 15
+#define PCLOUD_ZOOM_FREQUENCY 0.7f
+#define PCLOUD_SPRITE_GAP 25
+
+
/*
===============
CG_OffsetFirstPersonView
@@ -506,6 +519,40 @@ static void CG_OffsetFirstPersonView( void ) {
cg.upMoveTime = cg.time;
}
+ if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED )
+ {
+ float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY );
+ float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY );
+
+ fraction *= 1.0f - ( ( cg.time - cg.firstPoisonedTime ) / (float)PCLOUD_TIME );
+ pitchFraction *= 1.0f - ( ( cg.time - cg.firstPoisonedTime ) / (float)PCLOUD_TIME );
+
+ angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE;
+ angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE;
+ angles[ PITCH ] += pitchFraction * PCLOUD_ROLL_AMPLITUDE / 2.0f;
+
+ if( cg.time > cg.poisonedTime )
+ {
+ vec3_t accel = { 0.0f, 0.0f, 300.0f };
+ vec3_t forward, right, up;
+ vec3_t spriteOrigin;
+
+ AngleVectors( angles, forward, right, NULL );
+ forward[ 2 ] = 0.0f;
+ VectorCopy( cg.predictedPlayerState.velocity, up );
+ up[ 2 ] += 32.0f;
+ VectorMA( origin, 32.0f, forward, spriteOrigin );
+ VectorMA( spriteOrigin, ( rand( ) % 128 ) - 64, right, spriteOrigin );
+
+ CG_LaunchSprite( spriteOrigin, up, accel, 0.0f,
+ 0.5f, 10.0f, 40.0f, 127.0f, 0.0f,
+ rand( ) % 360, cg.time, rand( ) % 10000, 500,
+ cgs.media.poisonCloudShader, qfalse, qfalse );
+
+ cg.poisonedTime = cg.time + PCLOUD_SPRITE_GAP;
+ }
+ }
+
//TA: this *feels* more realisitic for humans
if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
{
@@ -618,6 +665,7 @@ Fixed fov at intermissions, otherwise account for fov variable and zooms.
*/
#define WAVE_AMPLITUDE 1
#define WAVE_FREQUENCY 0.4
+
#define FOVWARPTIME 400.0
static int CG_CalcFov( void ) {
@@ -710,6 +758,16 @@ static int CG_CalcFov( void ) {
inwater = qfalse;
}
+ if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
+ cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 )
+ {
+ phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2;
+ v = PCLOUD_ZOOM_AMPLITUDE * sin( phase );
+ v *= 1.0f - ( ( cg.time - cg.firstPoisonedTime ) / (float)PCLOUD_TIME );
+ fov_x += v;
+ fov_y += v;
+ }
+
// set it
cg.refdef.fov_x = fov_x;
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index 855ae926..a2e1bf3e 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -1019,30 +1019,43 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
}
+#define POISONCLOUD_LIFETIME 800
+#define POISONCLOUD_SPEED 80.0f
+#define POISONCLOUD_GAP 40
+#define POISONCLOUD_LAG 0.75f
+#define POISONCLOUD_SPREAD 160.0f
+
/*
===============
-CG_FlameTrail
+CG_PoisonCloud
===============
*/
-static void CG_FlameTrail( centity_t *cent, vec3_t origin )
+static void CG_PoisonCloud( centity_t *cent, int firstPoisonTime )
{
vec3_t forward, right, up;
vec3_t muzzlePoint;
vec3_t velocity;
vec3_t pVelocity;
+ vec3_t accel = { 0.0f, 0.0f, 2.0f };
+ vec3_t surfNormal;
+ entityState_t *es = &cent->currentState;
- if( cent->currentState.weapon != WP_FLAMER )
+ if( cent->currentState.weapon != WP_GRAB_CLAW_UPG )
return;
+ //finite lifetime
+ if( firstPoisonTime + POISONCLOUD_LIFETIME < cg.time )
+ return;
+
//not time for the next ball yet
- if( cg.time < cent->flamerTime )
+ if( cg.time < cent->poisonTime )
return;
if( cent->currentState.clientNum == cg.predictedPlayerState.clientNum && !cg.renderingThirdPerson )
{
AngleVectors( cg.refdefViewAngles, forward, right, up );
VectorCopy( cg.refdef.vieworg, muzzlePoint );
- VectorScale( cg.predictedPlayerState.velocity, FIREBALL_LAG, pVelocity );
+ VectorScale( cg.predictedPlayerState.velocity, POISONCLOUD_LAG, pVelocity );
}
else
{
@@ -1051,44 +1064,80 @@ static void CG_FlameTrail( centity_t *cent, vec3_t origin )
//FIXME: this is gonna look weird when crouching
muzzlePoint[ 2 ] += DEFAULT_VIEWHEIGHT;
- VectorScale( cent->currentState.pos.trDelta, FIREBALL_LAG, pVelocity );
+ VectorScale( cent->currentState.pos.trDelta, POISONCLOUD_LAG, pVelocity );
}
- VectorMA( pVelocity, FIREBALL_SPEED, forward, velocity );
+ VectorMA( pVelocity, POISONCLOUD_SPEED, forward, velocity );
- //FIXME: tweak these numbers when (if?) the flamer model is done
VectorMA( muzzlePoint, 24.0f, forward, muzzlePoint );
- VectorMA( muzzlePoint, 6.0f, right, muzzlePoint );
VectorMA( muzzlePoint, -6.0f, up, muzzlePoint );
+
+ if( es->eFlags & EF_WALLCLIMBCEILING )
+ VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
+ else
+ VectorCopy( es->angles2, surfNormal );
- CG_LaunchSprite( muzzlePoint, velocity, vec3_origin,
- 0.1f, 4.0f, 40.0f, 255.0f, 255.0f,
- rand( ) % 360, cg.time, FIREBALL_LIFETIME,
- cgs.media.flameShader[ 0 ], qfalse, qfalse );
+ VectorMA( velocity, -33.0f, surfNormal, velocity );
+
+ CG_LaunchSprite( muzzlePoint, velocity, accel, POISONCLOUD_SPREAD,
+ 0.5f, 10.0f, 40.0f, 127.0f, 0.0f,
+ rand( ) % 360, cg.time, cg.time, POISONCLOUD_LIFETIME,
+ cgs.media.poisonCloudShader, qfalse, qfalse );
//set next ball time
- cent->flamerTime = cg.time + FIREBALL_GAP;
+ cent->poisonTime = cg.time + POISONCLOUD_GAP;
}
/*
===============
-CG_SpawnRailTrail
-
-Origin will be the exact tag point, which is slightly
-different than the muzzle point used for determining hits.
+CG_FlameTrail
===============
*/
-static void CG_SpawnRailTrail( centity_t *cent, vec3_t origin )
+static void CG_FlameTrail( centity_t *cent )
{
-/* if ( cent->currentState.weapon != WP_RAILGUN )
+ vec3_t forward, right, up;
+ vec3_t muzzlePoint;
+ vec3_t velocity;
+ vec3_t pVelocity;
+
+ if( cent->currentState.weapon != WP_FLAMER )
return;
- if ( !cent->pe.railgunFlash )
+ //not time for the next ball yet
+ if( cg.time < cent->flamerTime )
return;
-
- cent->pe.railgunFlash = qtrue;
- CG_RailTrail( origin, cent->pe.railgunImpact );*/
+
+ if( cent->currentState.clientNum == cg.predictedPlayerState.clientNum && !cg.renderingThirdPerson )
+ {
+ AngleVectors( cg.refdefViewAngles, forward, right, up );
+ VectorCopy( cg.refdef.vieworg, muzzlePoint );
+ VectorScale( cg.predictedPlayerState.velocity, FIREBALL_LAG, pVelocity );
+ }
+ else
+ {
+ AngleVectors( cent->lerpAngles, forward, right, up );
+ VectorCopy( cent->lerpOrigin, muzzlePoint );
+
+ //FIXME: this is gonna look weird when crouching
+ muzzlePoint[ 2 ] += DEFAULT_VIEWHEIGHT;
+ VectorScale( cent->currentState.pos.trDelta, FIREBALL_LAG, pVelocity );
+ }
+
+ VectorMA( pVelocity, FIREBALL_SPEED, forward, velocity );
+
+ //FIXME: tweak these numbers when (if?) the flamer model is done
+ VectorMA( muzzlePoint, 24.0f, forward, muzzlePoint );
+ VectorMA( muzzlePoint, 6.0f, right, muzzlePoint );
+ VectorMA( muzzlePoint, -6.0f, up, muzzlePoint );
+
+ CG_LaunchSprite( muzzlePoint, velocity, vec3_origin, 0.0f,
+ 0.1f, 4.0f, 40.0f, 255.0f, 255.0f,
+ rand( ) % 360, cg.time, cg.time, FIREBALL_LIFETIME,
+ cgs.media.flameShader[ 0 ], qfalse, qfalse );
+
+ //set next ball time
+ cent->flamerTime = cg.time + FIREBALL_GAP;
}
@@ -1160,7 +1209,8 @@ The main player will have this called for BOTH cases, so effects like light and
sound should only be done on the world model case.
=============
*/
-void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ) {
+void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent )
+{
refEntity_t gun;
refEntity_t barrel;
refEntity_t flash;
@@ -1172,7 +1222,7 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
weaponNum = cent->currentState.weapon;
CG_RegisterWeapon( weaponNum );
- weapon = &cg_weapons[weaponNum];
+ weapon = &cg_weapons[ weaponNum ];
// add the weapon
memset( &gun, 0, sizeof( gun ) );
@@ -1181,25 +1231,12 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
gun.renderfx = parent->renderfx;
// set custom shading for railgun refire rate
- if ( ps )
+ if( ps )
{
-/* if ( cg.predictedPlayerState.weapon == WP_RAILGUN
- && cg.predictedPlayerState.weaponstate == WEAPON_FIRING )
- {
- float f;
-
- f = (float)cg.predictedPlayerState.weaponTime / 1500;
- gun.shaderRGBA[1] = 0;
- gun.shaderRGBA[0] =
- gun.shaderRGBA[2] = 255 * ( 1.0 - f );
- }
- else*/
- {
- gun.shaderRGBA[0] = 255;
- gun.shaderRGBA[1] = 255;
- gun.shaderRGBA[2] = 255;
- gun.shaderRGBA[3] = 255;
- }
+ gun.shaderRGBA[ 0 ] = 255;
+ gun.shaderRGBA[ 1 ] = 255;
+ gun.shaderRGBA[ 2 ] = 255;
+ gun.shaderRGBA[ 3 ] = 255;
//set weapon[1/2]Time when respective buttons change state
if( cg.weapon1Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING ) )
@@ -1216,28 +1253,30 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
}
gun.hModel = weapon->weaponModel;
- if (!gun.hModel) {
+ if( !gun.hModel )
return;
- }
- if ( !ps ) {
+ if( !ps )
+ {
// add weapon ready sound
cent->pe.lightningFiring = qfalse;
- if ( ( cent->currentState.eFlags & EF_FIRING ) && weapon->firingSound ) {
+ if( ( cent->currentState.eFlags & EF_FIRING ) && weapon->firingSound )
+ {
// lightning gun and guantlet make a different sound when fire is held down
trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->firingSound );
cent->pe.lightningFiring = qtrue;
- } else if ( weapon->readySound ) {
- trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound );
}
+ else if( weapon->readySound )
+ trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound );
}
- CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon");
+ CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" );
CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );
// add the spinning barrel
- if( weapon->barrelModel ) {
+ if( weapon->barrelModel )
+ {
memset( &barrel, 0, sizeof( barrel ) );
VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
barrel.shadowPlane = parent->shadowPlane;
@@ -1255,25 +1294,27 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
}
// make sure we aren't looking at cg.predictedPlayerEntity for LG
- nonPredictedCent = &cg_entities[cent->currentState.clientNum];
+ nonPredictedCent = &cg_entities[ cent->currentState.clientNum ];
// if the index of the nonPredictedCent is not the same as the clientNum
// then this is a fake player (like on teh single player podiums), so
// go ahead and use the cent
- if( ( nonPredictedCent - cg_entities ) != cent->currentState.clientNum ) {
+ if( ( nonPredictedCent - cg_entities ) != cent->currentState.clientNum )
nonPredictedCent = cent;
- }
+
+ CG_PoisonCloud( nonPredictedCent, cent->firstPoisonTime );
// add the flash
- if ( ( weaponNum == WP_TESLAGEN || weaponNum == WP_FLAMER ) &&
- ( nonPredictedCent->currentState.eFlags & EF_FIRING ) )
+ if( ( weaponNum == WP_TESLAGEN || weaponNum == WP_FLAMER ) &&
+ ( nonPredictedCent->currentState.eFlags & EF_FIRING ) )
{
// continuous flash
- } else {
+ }
+ else
+ {
// impulse flash
- if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash ) {
+ if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash )
return;
- }
}
memset( &flash, 0, sizeof( flash ) );
@@ -1282,41 +1323,30 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
flash.renderfx = parent->renderfx;
flash.hModel = weapon->flashModel;
- if (!flash.hModel) {
+ if( !flash.hModel )
return;
- }
- angles[YAW] = 0;
- angles[PITCH] = 0;
- angles[ROLL] = crandom() * 10;
- AnglesToAxis( angles, flash.axis );
-
- // colorize the railgun blast
-/* if ( weaponNum == WP_RAILGUN ) {
- clientInfo_t *ci;
- ci = &cgs.clientinfo[ cent->currentState.clientNum ];
- flash.shaderRGBA[0] = 255 * ci->color1[0];
- flash.shaderRGBA[1] = 255 * ci->color1[1];
- flash.shaderRGBA[2] = 255 * ci->color1[2];
- }*/
+ angles[ YAW ] = 0;
+ angles[ PITCH ] = 0;
+ angles[ ROLL ] = crandom( ) * 10;
+ AnglesToAxis( angles, flash.axis );
- CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
+ CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash" );
trap_R_AddRefEntityToScene( &flash );
- if ( ps || cg.renderingThirdPerson ||
- cent->currentState.number != cg.predictedPlayerState.clientNum ) {
+ if( ps || cg.renderingThirdPerson ||
+ cent->currentState.number != cg.predictedPlayerState.clientNum )
+ {
// add lightning bolt
CG_LightningBolt( nonPredictedCent, flash.origin );
- CG_FlameTrail( nonPredictedCent, flash.origin );
-
- // add rail trail
- CG_SpawnRailTrail( cent, flash.origin );
+ CG_FlameTrail( nonPredictedCent );
// make a dlight for the flash
- if ( weapon->flashDlightColor[0] || weapon->flashDlightColor[1] || weapon->flashDlightColor[2] ) {
- trap_R_AddLightToScene( flash.origin, 300 + (rand()&31), weapon->flashDlightColor[0],
- weapon->flashDlightColor[1], weapon->flashDlightColor[2] );
+ if( weapon->flashDlightColor[ 0 ] || weapon->flashDlightColor[ 1 ] || weapon->flashDlightColor[ 2 ] )
+ {
+ trap_R_AddLightToScene( flash.origin, 300 + ( rand( ) & 31 ), weapon->flashDlightColor[ 0 ],
+ weapon->flashDlightColor[ 1 ], weapon->flashDlightColor[ 2 ] );
}
}
}
@@ -1368,7 +1398,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
VectorCopy( cg.refdef.vieworg, origin );
VectorMA( origin, -8, cg.refdef.viewaxis[2], origin );
CG_LightningBolt( &cg_entities[ps->clientNum], origin );
- CG_FlameTrail( &cg_entities[ps->clientNum], origin );
+ CG_FlameTrail( &cg_entities[ ps->clientNum ] );
}
return;
}
@@ -1803,7 +1833,8 @@ CG_FireWeapon
Caused by an EV_FIRE_WEAPON event
================
*/
-void CG_FireWeapon( centity_t *cent ) {
+void CG_FireWeapon( centity_t *cent, int mode )
+{
entityState_t *ent;
int c;
weaponInfo_t *weap;
@@ -1822,6 +1853,9 @@ void CG_FireWeapon( centity_t *cent ) {
// append the flash to the weapon model
cent->muzzleFlashTime = cg.time;
+ if( ent->weapon == WP_GRAB_CLAW_UPG && mode == 1 )
+ cent->firstPoisonTime = cg.time;
+
// lightning gun only does this this on initial press
if ( ent->weapon == WP_TESLAGEN ) {
if ( cent->pe.lightningFiring ) {
@@ -1981,8 +2015,9 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
velocity[ 1 ] = ( 2 * random( ) - 1.0f ) * LCANON_EJECTION_VEL;
velocity[ 2 ] = ( 2 * random( ) - 1.0f ) * LCANON_EJECTION_VEL;
- CG_LaunchSprite( origin, velocity, accel, 0.9, 1.0f, 40.0f, 255, 0, rand( ) % 360,
- cg.time, 2000 + ( crandom( ) * 1000 ),
+ CG_LaunchSprite( origin, velocity, accel, 0.0f,
+ 0.9f, 1.0f, 40.0f, 255, 0, rand( ) % 360,
+ cg.time, cg.time, 2000 + ( crandom( ) * 1000 ),
spark, qfalse, qfalse );
}
break;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 8967f09b..43f01c44 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -2140,7 +2140,6 @@ weaponAttributes_t bg_weapons[ ] =
2000, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2163,7 +2162,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2186,7 +2184,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2209,7 +2206,6 @@ weaponAttributes_t bg_weapons[ ] =
2000, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2232,7 +2228,6 @@ weaponAttributes_t bg_weapons[ ] =
2000, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2255,7 +2250,6 @@ weaponAttributes_t bg_weapons[ ] =
2000, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2278,7 +2272,6 @@ weaponAttributes_t bg_weapons[ ] =
2000, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2301,7 +2294,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2324,7 +2316,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
10000, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2347,7 +2338,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qtrue, //qboolean purchasable;
5000, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2370,7 +2360,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
10000, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2393,7 +2382,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
5000, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2416,7 +2404,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2439,7 +2426,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2462,7 +2448,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2485,7 +2470,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2508,7 +2492,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2531,7 +2514,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2554,7 +2536,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qtrue, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2577,7 +2558,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_ALIENS //WUTeam_t team;
@@ -2600,7 +2580,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2623,7 +2602,6 @@ weaponAttributes_t bg_weapons[ ] =
0, //int reloadTime;
qfalse, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
- qfalse, //qboolean synced;
qfalse, //qboolean purchasable;
0, //int buildDelay;
WUT_HUMANS //WUTeam_t team;
@@ -2938,26 +2916,6 @@ qboolean BG_WeaponHasThirdMode( int weapon )
/*
==============
-BG_WeaponModesAreSynced
-==============
-*/
-qboolean BG_WeaponModesAreSynced( int weapon )
-{
- int i;
-
- for( i = 0; i < bg_numWeapons; i++ )
- {
- if( bg_weapons[ i ].weaponNum == weapon )
- {
- return bg_weapons[ i ].synced;
- }
- }
-
- return qfalse;
-}
-
-/*
-==============
BG_FindPurchasableForWeapon
==============
*/
@@ -3520,7 +3478,6 @@ char *eventnames[] = {
"EV_FIRE_WEAPON",
"EV_FIRE_WEAPON2",
"EV_FIRE_WEAPON3",
- "EV_FIRE_WEAPONBOTH",
"EV_USE_ITEM0",
"EV_USE_ITEM1",
@@ -3593,7 +3550,8 @@ char *eventnames[] = {
"EV_TAUNT_GUARDBASE",
"EV_TAUNT_PATROL",
- "EV_MENU" //TA: menu event
+ "EV_MENU", //TA: menu event
+ "EV_POISONCLOUD" //TA: client poisoned
};
/*
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 9b274e2f..0539294e 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -2346,10 +2346,7 @@ static void PM_Weapon( void )
{
if( BG_WeaponHasAltMode( pm->ps->weapon ) )
{
- if( BG_WeaponModesAreSynced( pm->ps->weapon ) && attack1 )
- PM_AddEvent( EV_FIRE_WEAPONBOTH );
- else
- PM_AddEvent( EV_FIRE_WEAPON2 );
+ PM_AddEvent( EV_FIRE_WEAPON2 );
}
else
{
@@ -2523,7 +2520,8 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd )
//convert viewangles -> axis
AnglesToAxis( tempang, axis );
- if( !BG_rotateAxis( ps->grapplePoint, axis, rotaxis, qfalse,
+ if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) ||
+ !BG_rotateAxis( ps->grapplePoint, axis, rotaxis, qfalse,
ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) )
AxisCopy( axis, rotaxis );
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 361ae0ce..393d278d 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -49,6 +49,8 @@
#define LC_TOTAL_CHARGE 255
#define LC_CHARGE_TIME 2000.0f
+#define PCLOUD_TIME 10000
+
//
// config strings are a general means of communicating variable length strings
// from the server to all connected clients.
@@ -248,6 +250,7 @@ typedef enum {
#define SS_HOVELING 0x00000100
#define SS_BOOSTED 0x00000200
#define SS_SLOWLOCKED 0x00000400
+#define SS_POISONCLOUDED 0x00000800
#define SB_VALID_TOGGLEBIT 0x00004000
@@ -510,7 +513,6 @@ typedef enum {
EV_FIRE_WEAPON,
EV_FIRE_WEAPON2,
EV_FIRE_WEAPON3,
- EV_FIRE_WEAPONBOTH,
EV_USE_ITEM0,
EV_USE_ITEM1,
@@ -584,7 +586,8 @@ typedef enum {
EV_TAUNT_PATROL,
EV_MENU, //TA: menu event
- EV_BUILD_DELAY //TA: can't build yet
+ EV_BUILD_DELAY, //TA: can't build yet
+ EV_POISONCLOUD //TA: client poisoned
} entity_event_t;
typedef enum
@@ -973,7 +976,6 @@ typedef struct
qboolean hasAltMode;
qboolean hasThirdMode;
- qboolean synced;
qboolean purchasable;
@@ -1090,7 +1092,6 @@ int BG_FindRepeatRateForWeapon( int weapon );
int BG_FindReloadTimeForWeapon( int weapon );
qboolean BG_WeaponHasAltMode( int weapon );
qboolean BG_WeaponHasThirdMode( int weapon );
-qboolean BG_WeaponModesAreSynced( int weapon );
qboolean BG_FindPurchasableForWeapon( int weapon );
int BG_FindBuildDelayForWeapon( int weapon );
WUTeam_t BG_FindTeamForWeapon( int weapon );
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 6e61fe2e..934e2b78 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -545,6 +545,10 @@ void ClientTimerActions( gentity_t *ent, int msec )
{
client->time1000 -= 1000;
+ //client is poisoned
+ if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED )
+ G_Damage( ent, NULL, NULL, NULL, NULL, 5, 0, MOD_VENOM );
+
//replenish alien health
if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
{
@@ -659,11 +663,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
FireWeapon3( ent );
break;
- case EV_FIRE_WEAPONBOTH:
- FireWeapon( ent );
- FireWeapon2( ent );
- break;
-
case EV_USE_ITEM1: // teleporter
// drop flags in CTF
item = NULL;
@@ -900,6 +899,10 @@ void ClientThink_real( gentity_t *ent ) {
client->lastBoostedTime + 20000 < level.time )
client->ps.stats[ STAT_STATE ] &= ~SS_BOOSTED;
+ if( client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
+ client->lastPoisonCloudedTime + PCLOUD_TIME < level.time )
+ client->ps.stats[ STAT_STATE ] &= ~SS_POISONCLOUDED;
+
client->ps.gravity = g_gravity.value;
if( BG_gotItem( UP_ANTITOXIN, client->ps.stats ) &&
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 331326ae..ef2b5b9f 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2454,12 +2454,9 @@ void Cmd_Spawnbody_f( gentity_t *ent )
void Cmd_Test_f( gentity_t *ent )
{
- int ammo, clips, maxclips;
- playerState_t *ps = &ent->client->ps;
-
- BG_unpackAmmoArray( WP_MACHINEGUN, ps->ammo, ps->powerups, &ammo, &clips, &maxclips );
- G_Printf( "%d %d\n", ammo, clips );
- BG_packAmmoArray( WP_MACHINEGUN, ps->ammo, ps->powerups, 0, 1, maxclips );
+ ent->client->ps.stats[ STAT_STATE ] |= SS_POISONCLOUDED;
+ ent->client->lastPoisonCloudedTime = level.time;
+ G_AddPredictableEvent( ent, EV_POISONCLOUD, 0 );
}
/*
diff --git a/src/game/g_local.h b/src/game/g_local.h
index e414e608..bacf2f82 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -341,9 +341,10 @@ struct gclient_s {
gentity_t *infestBody; //TA: body that is being infested. must be persistant
int lastPoisonTime;
- int lastGrabTime; //TA: yuck yuck hack urgh
- int lastLockTime; //TA: " "
- int lastSlowTime; //TA: " "
+ int lastPoisonCloudedTime;
+ int lastGrabTime;
+ int lastLockTime;
+ int lastSlowTime;
int lastBoostedTime;
int pouncePayload; //TA: amount of damage pounce attack will do
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 53d4cf59..59fe1877 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -559,14 +559,6 @@ qboolean CheckVenomAttack( gentity_t *ent )
}
G_Damage( traceEnt, ent, ent, forward, tr.endpos, 100, DAMAGE_NO_KNOCKBACK, MOD_VENOM );
-/* if( traceEnt->client )
- {
- if( !( traceEnt->client->ps.stats[ STAT_STATE ] & SS_POISONED ) )
- {
- traceEnt->client->ps.stats[ STAT_STATE ] |= SS_POISONED;
- traceEnt->client->lastPoisonTime = level.time;
- }
- }*/
return qtrue;
}
@@ -603,7 +595,7 @@ void CheckGrabAttack( gentity_t *ent )
traceEnt = &g_entities[ tr.entityNum ];
- if( !traceEnt->takedamage)
+ if( !traceEnt->takedamage )
return;
if( !traceEnt->client )
return;
@@ -614,12 +606,43 @@ void CheckGrabAttack( gentity_t *ent )
VectorCopy( traceEnt->client->ps.viewangles, traceEnt->client->ps.grapplePoint );
traceEnt->client->ps.stats[ STAT_STATE ] |= SS_GRABBED;
- traceEnt->client->lastLockTime = level.time;
+ traceEnt->client->lastGrabTime = level.time;
//FIXME: event for some client side grab effect?
}
/*
+===============
+poisonCloud
+===============
+*/
+void poisonCloud( gentity_t *ent )
+{
+ int entityList[ MAX_GENTITIES ];
+ vec3_t range = { 200, 200, 200 };
+ vec3_t mins, maxs, dir;
+ int i, num;
+ gentity_t *humanPlayer;
+ float modifier = 1.0f;
+
+ VectorAdd( ent->client->ps.origin, range, maxs );
+ VectorSubtract( ent->client->ps.origin, range, mins );
+
+ num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+ for( i = 0; i < num; i++ )
+ {
+ humanPlayer = &g_entities[ entityList[ i ] ];
+
+ if( humanPlayer->client && humanPlayer->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
+ {
+ humanPlayer->client->ps.stats[ STAT_STATE ] |= SS_POISONCLOUDED;
+ humanPlayer->client->lastPoisonCloudedTime = level.time;
+ G_AddPredictableEvent( humanPlayer, EV_POISONCLOUD, 0 );
+ }
+ }
+}
+
+/*
======================================================================
CLAW AND POUNCE
@@ -913,6 +936,7 @@ void FireWeapon2( gentity_t *ent )
switch( ent->s.weapon )
{
case WP_GRAB_CLAW_UPG:
+ poisonCloud( ent );
break;
case WP_POUNCE:
case WP_POUNCE_UPG: