summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Levin <risujin@fastmail.fm>2009-10-03 11:29:53 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:15:03 +0000
commit81e17582608465935041812242d0dbbf8a152727 (patch)
tree83d199721faa67fbc0a4f97dc4a290a73d3a6dd2
parentc8b36fe5697a41f87495d04fc80b920c76842742 (diff)
* Lucifer Cannon projectile and bounding box shrunk a little to fit muzzle box restrictions
* Buying a weapon with a number greater than 15 while having a Construction Kit will not give you zero ammo * Human viewheight shrunk to prevent flamer and new Lucifer Cannon shots from exploding inside the ceiling because on account of the muzzle box -- better aligned with the model now too. This should prevent the flamer from burning people in vents. * Some BG functions made more efficient; BG_GetPlayerWeapon should be used to get a Human's weapon because it may be switching * Adv. Dragoon barbs regenerate 10 seconds after being shot, not at regular intervals * Build weapons should no longer need to be in a block in bg_public.h * Tremulous doesn't use multiple weapons but the G_GiveClientMaxAmmo function will properly restore regular ammunition when a energy weapon is selected * MN_H_NOENERGYAMMOHERE obsolete; Changed some text to acknowledge that energy ammo is now available at armoury * Particles can set 'physicsRadius #' to use a fixed bounding box for collisions * Various HUD elements will immediately update to the new weapon when switching weapons Flamer changes: * Bounding box shrunk slightly * Client-side particles now used a static bounding box that matches the server projectile
-rw-r--r--models/weapons/lcannon/weapon.cfg2
-rw-r--r--overrides/classes/human_base.cfg4
-rw-r--r--scripts/weapons.particle8
-rw-r--r--src/cgame/cg_draw.c79
-rw-r--r--src/cgame/cg_local.h1
-rw-r--r--src/cgame/cg_particles.c20
-rw-r--r--src/cgame/cg_servercmds.c9
-rw-r--r--src/game/bg_misc.c44
-rw-r--r--src/game/bg_pmove.c17
-rw-r--r--src/game/bg_public.h2
-rw-r--r--src/game/g_active.c35
-rw-r--r--src/game/g_buildable.c7
-rw-r--r--src/game/g_cmds.c82
-rw-r--r--src/game/g_local.h8
-rw-r--r--src/game/g_missile.c4
-rw-r--r--src/game/g_weapon.c68
-rw-r--r--src/game/tremulous.h12
17 files changed, 195 insertions, 207 deletions
diff --git a/models/weapons/lcannon/weapon.cfg b/models/weapons/lcannon/weapon.cfg
index 06cf1b4b..e1977d43 100644
--- a/models/weapons/lcannon/weapon.cfg
+++ b/models/weapons/lcannon/weapon.cfg
@@ -6,7 +6,7 @@ idleSound models/weapons/lcannon/idle.wav
primary
{
missileSprite 16 gfx/lcannon/primary
- missileSpriteCharge 0.27
+ missileSpriteCharge 0.25
missileSound models/weapons/lcannon/missle.wav
missileParticleSystem models/weapons/lcannon/missilePS
diff --git a/overrides/classes/human_base.cfg b/overrides/classes/human_base.cfg
index c3bb971e..415c916c 100644
--- a/overrides/classes/human_base.cfg
+++ b/overrides/classes/human_base.cfg
@@ -7,8 +7,8 @@ hud human_hud
mins -15 -15 -24
maxs 15 15 32
crouchMaxs 15 15 16
-viewHeight 28
-crouchViewHeight 15
+viewHeight 24
+crouchViewHeight 7
deadMins -15 -15 -4
deadMaxs 15 15 4
zOffset -2.0
diff --git a/scripts/weapons.particle b/scripts/weapons.particle
index dc69fbc9..70d3c221 100644
--- a/scripts/weapons.particle
+++ b/scripts/weapons.particle
@@ -316,7 +316,9 @@ models/weapons/flamer/muzzlePS
accelerationType static
accelerationDir linear
accelerationMagnitude 50
- acceleration 0 0 1 ~0
+ acceleration 0 0 1 ~0
+
+ physicsRadius 8
radius 0 4.0 40.0
alpha 0 1.0 1.0
@@ -551,7 +553,7 @@ models/weapons/lcannon/impactPS
alpha 0 1.0 0.0
rotation 0 ~360 -
- scaleWithCharge 0.13
+ scaleWithCharge 0.10
lifeTime 250
}
@@ -619,7 +621,7 @@ models/weapons/lcannon/impactPS
rotation 0 ~360 -
bounce 1.0
- scaleWithCharge 0.13
+ scaleWithCharge 0.10
lifeTime 1000~1000
}
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 24121df5..5ae1093a 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -510,10 +510,12 @@ static void CG_DrawPlayerClipsRing( rectDef_t *rect, vec4_t color, qhandle_t sha
float buildTime = ps->stats[ STAT_MISC ];
float progress;
float maxDelay;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
+ weapon = BG_GetPlayerWeapon( ps );
- switch( cent->currentState.weapon )
+ switch( weapon )
{
case WP_ABUILD:
case WP_ABUILD2:
@@ -675,22 +677,22 @@ static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color )
int value;
centity_t *cent;
playerState_t *ps;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
ps = &cg.snap->ps;
+ weapon = BG_GetPlayerWeapon( ps );
- if( cent->currentState.weapon )
+ if( weapon )
{
- switch( cent->currentState.weapon )
+ switch( weapon )
{
case WP_ABUILD:
case WP_ABUILD2:
- //percentage of BP remaining
value = cgs.alienBuildPoints;
break;
case WP_HBUILD:
- //percentage of BP remaining
value = cgs.humanBuildPoints;
break;
@@ -777,13 +779,13 @@ static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
int index;
centity_t *cent;
playerState_t *ps;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
ps = &cg.snap->ps;
+ weapon = BG_GetPlayerWeapon( ps );
- if( ( cent->currentState.weapon != WP_ABUILD &&
- cent->currentState.weapon != WP_ABUILD2 &&
- cent->currentState.weapon != WP_HBUILD ) ||
+ if( ( weapon != WP_ABUILD && weapon != WP_ABUILD2 && weapon != WP_HBUILD ) ||
ps->stats[ STAT_MISC ] <= 0 )
return;
@@ -812,30 +814,30 @@ static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color )
int value;
centity_t *cent;
playerState_t *ps;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
ps = &cg.snap->ps;
+ weapon = BG_GetPlayerWeapon( ps );
- if( cent->currentState.weapon )
+ switch( weapon )
{
- switch( cent->currentState.weapon )
- {
- case WP_ABUILD:
- case WP_ABUILD2:
- case WP_HBUILD:
- break;
+ case WP_ABUILD:
+ case WP_ABUILD2:
+ case WP_HBUILD:
+ case 0:
+ break;
- default:
- value = ps->clips;
+ default:
+ value = ps->clips;
- if( value > -1 )
- {
- trap_R_SetColor( color );
- CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
- trap_R_SetColor( NULL );
- }
- break;
- }
+ if( value > -1 )
+ {
+ trap_R_SetColor( color );
+ CG_DrawField( rect->x, rect->y, 4, rect->w / 4, rect->h, value );
+ trap_R_SetColor( NULL );
+ }
+ break;
}
}
@@ -1270,18 +1272,20 @@ float CG_GetValue( int ownerDraw )
{
centity_t *cent;
playerState_t *ps;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
ps = &cg.snap->ps;
+ weapon = BG_GetPlayerWeapon( ps );
switch( ownerDraw )
{
case CG_PLAYER_AMMO_VALUE:
- if( cent->currentState.weapon )
+ if( weapon )
return ps->ammo;
break;
case CG_PLAYER_CLIPS_VALUE:
- if( cent->currentState.weapon )
+ if( weapon )
return ps->clips;
break;
case CG_PLAYER_HEALTH:
@@ -2076,22 +2080,24 @@ void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color )
int maxAmmo;
centity_t *cent;
playerState_t *ps;
+ weapon_t weapon;
cent = &cg_entities[ cg.snap->ps.clientNum ];
ps = &cg.snap->ps;
+ weapon = BG_GetPlayerWeapon( ps );
- BG_FindAmmoForWeapon( cent->currentState.weapon, &maxAmmo, NULL );
+ BG_FindAmmoForWeapon( weapon, &maxAmmo, NULL );
// don't display if dead
if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
return;
- if( cent->currentState.weapon == 0 )
+ if( weapon == 0 )
return;
- CG_RegisterWeapon( cent->currentState.weapon );
+ CG_RegisterWeapon( weapon );
- if( ps->clips == 0 && !BG_FindInfinteAmmoForWeapon( cent->currentState.weapon ) )
+ if( ps->clips == 0 && !BG_FindInfinteAmmoForWeapon( weapon ) )
{
float ammoPercent = (float)ps->ammo / (float)maxAmmo;
@@ -2114,7 +2120,8 @@ void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color )
}
trap_R_SetColor( color );
- CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_weapons[ cent->currentState.weapon ].weaponIcon );
+ CG_DrawPic( rect->x, rect->y, rect->w, rect->h,
+ cg_weapons[ weapon ].weaponIcon );
trap_R_SetColor( NULL );
}
@@ -2140,12 +2147,15 @@ static void CG_DrawCrosshair( void )
qhandle_t hShader;
float x, y;
weaponInfo_t *wi;
+ weapon_t weapon;
+
+ weapon = BG_GetPlayerWeapon( &cg.snap->ps );
if( cg_drawCrosshair.integer == CROSSHAIR_ALWAYSOFF )
return;
if( cg_drawCrosshair.integer == CROSSHAIR_RANGEDONLY &&
- !BG_FindLongRangedForWeapon( cg.snap->ps.weapon ) )
+ !BG_FindLongRangedForWeapon( weapon ) )
return;
if( ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) ||
@@ -2156,10 +2166,9 @@ static void CG_DrawCrosshair( void )
if( cg.renderingThirdPerson )
return;
- wi = &cg_weapons[ cg.snap->ps.weapon ];
+ wi = &cg_weapons[ weapon ];
w = h = wi->crossHairSize * cg_crosshairSize.value;
-
w *= cgDC.aspectScale;
x = cg_crosshairX.integer;
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 2c04f4e6..74e43bea 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -278,6 +278,7 @@ typedef struct baseParticle_s
float bounceSoundCountRandFrac;
pLerpValues_t radius;
+ int physicsRadius;
pLerpValues_t alpha;
pLerpValues_t rotation;
diff --git a/src/cgame/cg_particles.c b/src/cgame/cg_particles.c
index f38b17d8..195c5ff3 100644
--- a/src/cgame/cg_particles.c
+++ b/src/cgame/cg_particles.c
@@ -1167,6 +1167,14 @@ static qboolean CG_ParseParticle( baseParticle_t *bp, char **text_p )
continue;
}
+ else if( !Q_stricmp( token, "physicsRadius" ) )
+ {
+ token = COM_Parse( text_p );
+ if( !token )
+ break;
+
+ bp->physicsRadius = atoi( token );
+ }
else if( !Q_stricmp( token, "alpha" ) )
{
token = COM_Parse( text_p );
@@ -2098,11 +2106,13 @@ static void CG_EvaluateParticlePhysics( particle_t *p )
acceleration );
}
- radius = CG_LerpValues( p->radius.initial,
- p->radius.final,
- CG_CalculateTimeFrac( p->birthTime,
- p->lifeTime,
- p->radius.delay ) );
+ // Some particles have a visual radius that differs from their collision radius
+ if( bp->physicsRadius )
+ radius = bp->physicsRadius;
+ else
+ radius = CG_LerpValues( p->radius.initial, p->radius.final,
+ CG_CalculateTimeFrac( p->birthTime, p->lifeTime,
+ p->radius.delay ) );
VectorSet( mins, -radius, -radius, -radius );
VectorSet( maxs, radius, radius, radius );
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index aba89b8a..7b609c90 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -688,18 +688,11 @@ void CG_Menu( int menu, int arg )
case MN_H_NOARMOURYHERE:
longMsg = "You must be near a powered Armoury in order to purchase "
- "weapons, upgrades or non-energy ammunition.";
+ "weapons, upgrades or ammunition.";
shortMsg = "You must be near a powered Armoury";
type = DT_ARMOURYEVOLVE;
break;
- case MN_H_NOENERGYAMMOHERE:
- longMsg = "You must be near an Armoury, Reactor or Repeater in order "
- "to purchase energy ammunition.";
- shortMsg = "You must be near an Armoury, Reactor or Repeater";
- type = DT_ARMOURYEVOLVE;
- break;
-
case MN_H_NOROOMBSUITON:
longMsg = "There is not enough room here to put on a Battle Suit. "
"Make sure you have enough head room to climb in.";
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 9b988371..54650521 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -5143,7 +5143,7 @@ qboolean BG_WeaponIsFull( weapon_t weapon, int stats[ ], int ammo, int clips )
BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips );
if( BG_InventoryContainsUpgrade( UP_BATTPACK, stats ) )
- maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
+ maxAmmo *= BATTPACK_MODIFIER;
return ( maxAmmo == ammo ) && ( maxClips == clips );
}
@@ -5157,14 +5157,10 @@ Give a player a weapon
*/
void BG_AddWeaponToInventory( int weapon, int stats[ ] )
{
- int weaponList;
-
- weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
-
- weaponList |= ( 1 << weapon );
-
- stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
- stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
+ if( weapon <= 15 )
+ stats[ STAT_WEAPONS ] |= 1 << weapon;
+ else
+ stats[ STAT_WEAPONS2 ] |= 1 << ( weapon - 16 );
if( stats[ STAT_SLOTS ] & BG_FindSlotsForWeapon( weapon ) )
Com_Printf( S_COLOR_YELLOW "WARNING: Held items conflict with weapon %d\n", weapon );
@@ -5181,15 +5177,11 @@ Take a weapon from a player
*/
void BG_RemoveWeaponFromInventory( int weapon, int stats[ ] )
{
- int weaponList;
-
- weaponList = ( stats[ STAT_WEAPONS ] & 0x0000FFFF ) | ( ( stats[ STAT_WEAPONS2 ] << 16 ) & 0xFFFF0000 );
-
- weaponList &= ~( 1 << weapon );
-
- stats[ STAT_WEAPONS ] = weaponList & 0x0000FFFF;
- stats[ STAT_WEAPONS2 ] = ( weaponList & 0xFFFF0000 ) >> 16;
-
+ if( weapon <= 15 )
+ stats[ STAT_WEAPONS ] &= ~( 1 << weapon );
+ else
+ stats[ STAT_WEAPONS2 ] &= ~( 1 << ( weapon - 16 ) );
+
stats[ STAT_SLOTS ] &= ~BG_FindSlotsForWeapon( weapon );
}
@@ -5464,6 +5456,22 @@ int BG_PlayerPoisonCloudTime( playerState_t *ps )
}
/*
+=================
+BG_GetPlayerWeapon
+
+Returns the players current weapon or the weapon they are switching to.
+Only needs to be used for human weapons.
+=================
+*/
+weapon_t BG_GetPlayerWeapon( playerState_t *ps )
+{
+ if( ps->persistant[ PERS_NEWWEAPON ] &&
+ ps->persistant[ PERS_NEWWEAPON ] != ps->weapon )
+ return ps->persistant[ PERS_NEWWEAPON ];
+ return ps->weapon;
+}
+
+/*
===============
atof_neg
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index a6dc15cf..46d55cc2 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -3017,7 +3017,7 @@ static void PM_Weapon( void )
if( BG_FindUsesEnergyForWeapon( pm->ps->weapon ) &&
BG_InventoryContainsUpgrade( UP_BATTPACK, pm->ps->stats ) )
- pm->ps->ammo = (int)( (float)pm->ps->ammo * BATTPACK_MODIFIER );
+ pm->ps->ammo *= BATTPACK_MODIFIER;
//allow some time for the weapon to be raised
pm->ps->weaponstate = WEAPON_RAISING;
@@ -3027,18 +3027,15 @@ static void PM_Weapon( void )
}
// check for end of clip
- if( ( !pm->ps->ammo || pm->ps->pm_flags & PMF_WEAPON_RELOAD ) && pm->ps->clips )
+ if( ( !pm->ps->ammo || ( pm->ps->pm_flags & PMF_WEAPON_RELOAD ) ) && pm->ps->clips )
{
pm->ps->pm_flags &= ~PMF_WEAPON_RELOAD;
-
pm->ps->weaponstate = WEAPON_RELOADING;
//drop the weapon
PM_StartTorsoAnim( TORSO_DROP );
- addTime = BG_FindReloadTimeForWeapon( pm->ps->weapon );
-
- pm->ps->weaponTime += addTime;
+ pm->ps->weaponTime += BG_FindReloadTimeForWeapon( pm->ps->weapon );
return;
}
@@ -3264,7 +3261,8 @@ static void PM_Weapon( void )
pm->ps->weaponstate = WEAPON_FIRING;
// take an ammo away if not infinite
- if( !BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) )
+ if( !BG_FindInfinteAmmoForWeapon( pm->ps->weapon ) ||
+ ( pm->ps->weapon == WP_ALEVEL3_UPG && attack3 ) )
{
// Special case for lcannon
if( pm->ps->weapon == WP_LUCIFER_CANNON && attack1 && !attack2 )
@@ -3277,11 +3275,6 @@ static void PM_Weapon( void )
if( pm->ps->ammo < 0 )
pm->ps->ammo = 0;
}
- else if( pm->ps->weapon == WP_ALEVEL3_UPG && attack3 )
- {
- //special case for slowblob
- pm->ps->ammo--;
- }
//FIXME: predicted angles miss a problem??
if( pm->ps->weapon == WP_CHAINGUN )
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 7ad0b2a0..30afb07f 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -625,7 +625,6 @@ typedef enum
MN_H_NOFUNDS,
MN_H_ITEMHELD,
MN_H_TEAMCHANGEBUILDTIMER,
- MN_H_NOENERGYAMMOHERE,
MN_H_NOARMOURYHERE,
MN_H_NOROOMBSUITON,
MN_H_NOROOMBSUITOFF,
@@ -1134,6 +1133,7 @@ void BG_PositionBuildableRelativeToPlayer( const playerState_t *ps,
int BG_GetValueOfPlayer( playerState_t *ps );
qboolean BG_PlayerCanChangeWeapon( playerState_t *ps );
int BG_PlayerPoisonCloudTime( playerState_t *ps );
+weapon_t BG_GetPlayerWeapon( playerState_t *ps );
int BG_FindValueOfBuildable( int bclass );
int BG_FindBuildNumForName( char *name );
diff --git a/src/game/g_active.c b/src/game/g_active.c
index e30f8bf4..e4ba5c9b 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -593,10 +593,11 @@ void ClientTimerActions( gentity_t *ent, int msec )
client = ent->client;
client->time100 += msec;
client->time1000 += msec;
- client->time10000 += msec;
while ( client->time100 >= 100 )
{
+ weapon_t weapon = BG_GetPlayerWeapon( &client->ps );
+
client->time100 -= 100;
// Restore or subtract stamina
@@ -613,10 +614,10 @@ void ClientTimerActions( gentity_t *ent, int msec )
else if( client->ps.stats[ STAT_STAMINA ] < -MAX_STAMINA )
client->ps.stats[ STAT_STAMINA ] = -MAX_STAMINA;
- if( client->ps.weapon == WP_ABUILD || client->ps.weapon == WP_ABUILD2 ||
+ if( weapon == WP_ABUILD || weapon == WP_ABUILD2 ||
BG_InventoryContainsWeapon( WP_HBUILD, client->ps.stats ) )
{
- //update build timer
+ // Update build timer
if( client->ps.stats[ STAT_MISC ] > 0 )
client->ps.stats[ STAT_MISC ] -= 100;
@@ -624,12 +625,13 @@ void ClientTimerActions( gentity_t *ent, int msec )
client->ps.stats[ STAT_MISC ] = 0;
}
- switch( client->ps.weapon )
+ switch( weapon )
{
case WP_ABUILD:
case WP_ABUILD2:
case WP_HBUILD:
- //set validity bit on buildable
+
+ // Set validity bit on buildable
if( ( client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE )
{
int dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] );
@@ -655,7 +657,6 @@ void ClientTimerActions( gentity_t *ent, int msec )
for( i = 0; i < MAX_MISC; i++ )
client->ps.misc[ i ] = 0;
}
-
break;
default:
@@ -813,20 +814,24 @@ void ClientTimerActions( gentity_t *ent, int msec )
}
}
- while( client->time10000 >= 10000 )
+ // Regenerate Adv. Dragoon barbs
+ if( client->ps.weapon == WP_ALEVEL3_UPG )
{
- client->time10000 -= 10000;
+ int maxAmmo;
- if( client->ps.weapon == WP_ALEVEL3_UPG )
+ BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL );
+
+ if( client->ps.ammo < maxAmmo )
{
- int maxAmmo;
-
- BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL );
-
- if( client->ps.ammo < maxAmmo )
+ if( ent->timestamp + LEVEL3_BOUNCEBALL_REGEN < level.time )
+ {
client->ps.ammo++;
+ ent->timestamp = level.time;
+ }
}
- }
+ else
+ ent->timestamp = level.time;
+ }
}
/*
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index dd4a9672..33424d61 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -1656,13 +1656,10 @@ Use for human power repeater
*/
void HRepeater_Use( gentity_t *self, gentity_t *other, gentity_t *activator )
{
- if( self->health <= 0 )
- return;
-
- if( !self->spawned )
+ if( self->health <= 0 || !self->spawned )
return;
- if( other )
+ if( other && other->client )
G_GiveClientMaxAmmo( other, qtrue );
}
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 01abca02..86c48495 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -1949,61 +1949,28 @@ Cmd_Buy_f
*/
void Cmd_Buy_f( gentity_t *ent )
{
- char s[ MAX_TOKEN_CHARS ];
- int i;
- int weapon, upgrade, numItems = 0;
- int maxAmmo, maxClips;
- qboolean buyingEnergyAmmo = qfalse;
- qboolean hasEnergyWeapon = qfalse;
-
- for( i = UP_NONE; i < UP_NUM_UPGRADES; i++ )
- {
- if( BG_InventoryContainsUpgrade( i, ent->client->ps.stats ) )
- numItems++;
- }
-
- for( i = WP_NONE; i < WP_NUM_WEAPONS; i++ )
- {
- if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) )
- {
- if( BG_FindUsesEnergyForWeapon( i ) )
- hasEnergyWeapon = qtrue;
- numItems++;
- }
- }
+ char s[ MAX_TOKEN_CHARS ];
+ int i, weapon, upgrade, maxAmmo, maxClips;
+ qboolean energyOnly;
trap_Argv( 1, s, sizeof( s ) );
weapon = BG_FindWeaponNumForName( s );
upgrade = BG_FindUpgradeNumForName( s );
- //special case to keep norf happy
- if( weapon == WP_NONE && upgrade == UP_AMMO )
- {
- buyingEnergyAmmo = hasEnergyWeapon;
- }
-
- if( buyingEnergyAmmo )
- {
- //no armoury nearby
- if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_REACTOR ) &&
- !G_BuildableRange( ent->client->ps.origin, 100, BA_H_REPEATER ) &&
- !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
- {
- G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOENERGYAMMOHERE );
- return;
- }
- }
+ // Seems odd to let people 'buy ammo' from a Reactor but allow this
+ // and make sure we only give energy ammo in this case
+ if( G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
+ energyOnly = qfalse;
+ else if( G_BuildableRange( ent->client->ps.origin, 100, BA_H_REACTOR ) ||
+ G_BuildableRange( ent->client->ps.origin, 100, BA_H_REPEATER ) )
+ energyOnly = qtrue;
else
{
- //no armoury nearby
- if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
- {
- G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE );
- return;
- }
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE );
+ return;
}
-
+
if( weapon != WP_NONE )
{
//already got this?
@@ -2027,9 +1994,9 @@ void Cmd_Buy_f( gentity_t *ent )
return;
}
+ // Only humans can buy stuff
if( BG_FindTeamForWeapon( weapon ) != WUT_HUMANS )
{
- //shouldn't need a fancy dialog
trap_SendServerCommand( ent-g_entities, va( "print \"You can't buy alien items\n\"" ) );
return;
}
@@ -2048,6 +2015,7 @@ void Cmd_Buy_f( gentity_t *ent )
return;
}
+ // In some instances, weapons can't be changed
if( !BG_PlayerCanChangeWeapon( &ent->client->ps ) )
return;
@@ -2057,8 +2025,8 @@ void Cmd_Buy_f( gentity_t *ent )
if( BG_FindUsesEnergyForWeapon( weapon ) &&
BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
- maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
-
+ maxAmmo *= BATTPACK_MODIFIER;
+
ent->client->ps.ammo = maxAmmo;
ent->client->ps.clips = maxClips;
@@ -2093,9 +2061,9 @@ void Cmd_Buy_f( gentity_t *ent )
return;
}
+ // Only humans can buy stuff
if( BG_FindTeamForUpgrade( upgrade ) != WUT_HUMANS )
{
- //shouldn't need a fancy dialog
trap_SendServerCommand( ent-g_entities, va( "print \"You can't buy alien items\n\"" ) );
return;
}
@@ -2115,7 +2083,7 @@ void Cmd_Buy_f( gentity_t *ent )
}
if( upgrade == UP_AMMO )
- G_GiveClientMaxAmmo( ent, buyingEnergyAmmo );
+ G_GiveClientMaxAmmo( ent, qfalse );
else
{
if( upgrade == UP_BATTLESUIT )
@@ -2143,9 +2111,7 @@ void Cmd_Buy_f( gentity_t *ent )
G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse );
}
else
- {
G_TriggerMenu( ent->client->ps.clientNum, MN_H_UNKNOWNITEM );
- }
//update ClientInfo
ClientUserinfoChanged( ent->client->ps.clientNum );
@@ -2177,6 +2143,8 @@ void Cmd_Sell_f( gentity_t *ent )
if( weapon != WP_NONE )
{
+ weapon_t selected = BG_GetPlayerWeapon( &ent->client->ps );
+
if( !BG_PlayerCanChangeWeapon( &ent->client->ps ) )
return;
@@ -2204,7 +2172,7 @@ void Cmd_Sell_f( gentity_t *ent )
}
//if we have this weapon selected, force a new selection
- if( weapon == ent->client->ps.weapon )
+ if( weapon == selected )
G_ForceWeaponChange( ent, WP_NONE );
}
else if( upgrade != UP_NONE )
@@ -2245,6 +2213,8 @@ void Cmd_Sell_f( gentity_t *ent )
}
else if( !Q_stricmp( s, "weapons" ) )
{
+ weapon_t selected = BG_GetPlayerWeapon( &ent->client->ps );
+
if( !BG_PlayerCanChangeWeapon( &ent->client->ps ) )
return;
@@ -2267,7 +2237,7 @@ void Cmd_Sell_f( gentity_t *ent )
}
//if we have this weapon selected, force a new selection
- if( i == ent->client->ps.weapon )
+ if( i == selected )
G_ForceWeaponChange( ent, WP_NONE );
}
}
@@ -2305,7 +2275,7 @@ void Cmd_Sell_f( gentity_t *ent )
}
}
else
- trap_SendServerCommand( ent-g_entities, va( "print \"Unknown item\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_UNKNOWNITEM );
//update ClientInfo
ClientUserinfoChanged( ent->client->ps.clientNum );
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 66196ed4..2a70b514 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -435,12 +435,8 @@ struct gclient_s
int switchTeamTime; // time the player switched teams
- // timeResidual is used to handle events that happen every second
- // like health / armor countdowns and regeneration
- // two timers, one every 100 msecs, another every sec
- int time100;
- int time1000;
- int time10000;
+ int time100; // timer for 100ms interval events
+ int time1000; // timer for one second interval events
char *areabits;
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index 81f8268f..642a7fd7 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -325,8 +325,8 @@ gentity_t *fire_flamer( gentity_t *self, vec3_t start, vec3_t dir )
bolt->splashMethodOfDeath = MOD_FLAMER_SPLASH;
bolt->clipmask = MASK_SHOT;
bolt->target_ent = NULL;
- bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -15.0f;
- bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 15.0f;
+ bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -FLAMER_SIZE;
+ bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = FLAMER_SIZE;
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index a74848f4..759a1a04 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -50,8 +50,6 @@ void G_ForceWeaponChange( gentity_t *ent, weapon_t weapon )
ps->weaponstate = WEAPON_READY;
}
- ps->pm_flags |= PMF_WEAPON_SWITCH;
-
if( weapon == WP_NONE ||
!BG_InventoryContainsWeapon( weapon, ps->stats ) )
{
@@ -77,6 +75,9 @@ void G_ForceWeaponChange( gentity_t *ent, weapon_t weapon )
// force this here to prevent flamer effect from continuing
ps->generic1 = WPM_NOTFIRING;
+
+ // The PMove will do an animated drop, raise, and set the new weapon
+ ps->pm_flags |= PMF_WEAPON_SWITCH;
}
/*
@@ -86,41 +87,42 @@ G_GiveClientMaxAmmo
*/
void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
{
- int i;
- int maxAmmo, maxClips;
- qboolean weaponType, restoredAmmo = qfalse;
+ int i, maxAmmo, maxClips;
+ qboolean restoredAmmo = qfalse, restoredEnergy = qfalse;
for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
{
- if( buyingEnergyAmmo )
- weaponType = BG_FindUsesEnergyForWeapon( i );
- else
- weaponType = !BG_FindUsesEnergyForWeapon( i );
-
- if( BG_InventoryContainsWeapon( i, ent->client->ps.stats ) &&
- weaponType && !BG_FindInfinteAmmoForWeapon( i ) &&
- !BG_WeaponIsFull( i, ent->client->ps.stats,
- ent->client->ps.ammo, ent->client->ps.clips ) )
+ qboolean energyWeapon;
+
+ energyWeapon = BG_FindUsesEnergyForWeapon( i );
+ if( !BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ||
+ BG_FindInfinteAmmoForWeapon( i ) ||
+ BG_WeaponIsFull( i, ent->client->ps.stats,
+ ent->client->ps.ammo, ent->client->ps.clips ) ||
+ ( buyingEnergyAmmo && !energyWeapon ) )
+ continue;
+
+ BG_FindAmmoForWeapon( i, &maxAmmo, &maxClips );
+
+ // Apply battery pack modifier
+ if( energyWeapon &&
+ BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
{
- BG_FindAmmoForWeapon( i, &maxAmmo, &maxClips );
-
- if( buyingEnergyAmmo )
- {
- G_AddEvent( ent, EV_RPTUSE_SOUND, 0 );
-
- if( BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
- maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER );
- }
+ maxAmmo *= BATTPACK_MODIFIER;
+ restoredEnergy = qtrue;
+ }
- ent->client->ps.ammo = maxAmmo;
- ent->client->ps.clips = maxClips;
+ ent->client->ps.ammo = maxAmmo;
+ ent->client->ps.clips = maxClips;
- restoredAmmo = qtrue;
- }
+ restoredAmmo = qtrue;
}
if( restoredAmmo )
G_ForceWeaponChange( ent, ent->client->ps.weapon );
+
+ if( restoredEnergy )
+ G_AddEvent( ent, EV_RPTUSE_SOUND, 0 );
}
/*
@@ -736,20 +738,20 @@ void painSawFire( gentity_t *ent )
tr.endpos[ 2 ] -= 5.0f;
// send blood impact
- if( traceEnt->client )
- {
+ if( traceEnt->client )
+ {
BloodSpurt( ent, traceEnt, &tr );
- }
- else
+ }
+ else
{
VectorCopy( tr.endpos, temp );
- tent = G_TempEntity( temp, EV_MISSILE_MISS );
+ tent = G_TempEntity( temp, EV_MISSILE_MISS );
tent->s.eventParm = DirToByte( tr.plane.normal );
tent->s.weapon = ent->s.weapon;
tent->s.generic1 = ent->s.generic1; //weaponMode
}
- G_Damage( traceEnt, ent, ent, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW );
+ G_Damage( traceEnt, ent, ent, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW );
}
/*
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index b243f69c..fa02360e 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -106,6 +106,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL3_BOUNCEBALL_REPEAT 1000
#define LEVEL3_BOUNCEBALL_SPEED 1000.0f
#define LEVEL3_BOUNCEBALL_RADIUS 30
+#define LEVEL3_BOUNCEBALL_REGEN 10000 // msec until new barb
#define LEVEL4_CLAW_DMG ADM(100)
#define LEVEL4_CLAW_RANGE 116.0f
@@ -446,10 +447,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define FLAMER_REPEAT 200
#define FLAMER_K_SCALE 1.0f
#define FLAMER_DMG HDM(20)
-#define FLAMER_RADIUS 50
-#define FLAMER_LIFETIME 800.0f
+#define FLAMER_RADIUS 50 // splash radius
+#define FLAMER_SIZE 8 // missile bounding box
+#define FLAMER_LIFETIME 600.0f
#define FLAMER_SPEED 300.0f
-#define FLAMER_LAG 0.65f //the amount of player velocity that is added to the fireball
+#define FLAMER_LAG 0.65f // the amount of player velocity that is added to the fireball
#define LCANNON_PRICE 600
#define LCANNON_AMMO 80
@@ -458,10 +460,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LCANNON_RELOAD 0
#define LCANNON_DAMAGE HDM(265)
#define LCANNON_RADIUS 150 // primary splash damage radius
-#define LCANNON_SIZE 10 // bounding box radius for full charge
+#define LCANNON_SIZE 8 // bounding box radius for full charge
#define LCANNON_SECONDARY_DAMAGE HDM(30)
#define LCANNON_SECONDARY_RADIUS 75 // secondary splash damage radius
-#define LCANNON_SECONDARY_SIZE 3 // bounding box radius
+#define LCANNON_SECONDARY_SIZE 4 // bounding box radius
#define LCANNON_SECONDARY_SPEED 1400
#define LCANNON_SECONDARY_RELOAD 2000
#define LCANNON_SECONDARY_REPEAT 1000