diff options
-rw-r--r-- | src/cgame/cg_event.c | 19 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 15 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 1 | ||||
-rw-r--r-- | src/cgame/cg_players.c | 15 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 64 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 213 | ||||
-rw-r--r-- | src/game/bg_misc.c | 46 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 8 | ||||
-rw-r--r-- | src/game/bg_public.h | 9 | ||||
-rw-r--r-- | src/game/g_active.c | 13 | ||||
-rw-r--r-- | src/game/g_cmds.c | 9 | ||||
-rw-r--r-- | src/game/g_local.h | 7 | ||||
-rw-r--r-- | src/game/g_weapon.c | 44 |
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 = ¢->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: |