summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_misc.c51
-rw-r--r--src/game/bg_public.h8
-rw-r--r--src/game/g_client.c2
-rw-r--r--src/game/g_cmds.c147
4 files changed, 153 insertions, 55 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index fd79c380..1bc9333d 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -1957,19 +1957,44 @@ classAttributes_t bg_classList[ ] =
0 //int value;
},
{
- //this isn't a real class, but a dummy to force the client to precache the model
- //FIXME: one day do this in a less hacky fashion
- PCL_HUMAN_BSUIT, "human_bsuit", "bsuit",
-
- "keel",
- 1.0f,
- "default",
- 1.0f,
-
- "bsuit", ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), { 0, 0, 0 }, { 0, 0, 0, },
- { 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 0.0f, 0, 0, 0, 0.0f, 0, 0, WP_NONE, 0.0f, 0,
- 0.0f, 1.0f, 0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 270.0f, 1.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0
- }
+ PCL_HUMAN_BSUIT, //int classnum;
+ "human_bsuit", //char *classname;
+ "bsuit", //char *humanname;
+ "keel", //char *modelname;
+ 1.0f, //float modelScale;
+ "default", //char *skinname;
+ 1.0f, //float shadowScale;
+ "human_hud", //char *hudname;
+ ( 1 << S3 ), //int stages
+ { -15, -15, -38 }, //vec3_t mins;
+ { 15, 15, 38 }, //vec3_t maxs;
+ { 15, 15, 38 }, //vec3_t crouchmaxs;
+ { -15, -15, -4 }, //vec3_t deadmins;
+ { 15, 15, 4 }, //vec3_t deadmaxs;
+ -16.0f, //float zOffset
+ 35, 35, //int viewheight, crouchviewheight;
+ 100, //int health;
+ 1.0f, //float fallDamage;
+ 0, //int regenRate;
+ SCA_TAKESFALLDAMAGE|
+ SCA_CANUSELADDERS, //int abilities;
+ WP_NONE, //special-cased in g_client.c //weapon_t startWeapon
+ 110.0f, //float buildDist;
+ 90, //int fov;
+ 0.002f, //float bob;
+ 1.0f, //float bobCycle;
+ 100, //int steptime;
+ 1.0f, //float speed;
+ 10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
+ 6.0f, //float friction;
+ 100.0f, //float stopSpeed;
+ 270.0f, //float jumpMagnitude;
+ 1.0f, //float knockbackScale;
+ { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
+ 0, //int cost;
+ 0 //int value;
+ },
};
int bg_numPclasses = sizeof( bg_classList ) / sizeof( bg_classList[ 0 ] );
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 722aca47..0cc12e8f 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -585,6 +585,8 @@ typedef enum
MN_TEAM,
MN_A_TEAMFULL,
MN_H_TEAMFULL,
+ MN_A_TEAMCHANGEBUILDTIMER,
+ MN_H_TEAMCHANGEBUILDTIMER,
//alien stuff
MN_A_CLASS,
@@ -595,6 +597,7 @@ typedef enum
MN_A_NOEROOM,
MN_A_TOOCLOSE,
MN_A_NOOVMND_EVOLVE,
+ MN_A_EVOLVEBUILDTIMER,
//alien build
MN_A_SPWNWARN,
@@ -614,6 +617,11 @@ typedef enum
MN_H_NOSLOTS,
MN_H_NOFUNDS,
MN_H_ITEMHELD,
+ MN_H_NOENERGYAMMOHERE,
+ MN_H_NOARMOURYHERE,
+ MN_H_NOROOMBSUITON,
+ MN_H_NOROOMBSUITOFF,
+ MN_H_ARMOURYBUILDTIMER,
//human build
MN_H_REPEATER,
diff --git a/src/game/g_client.c b/src/game/g_client.c
index a2607cdf..75136661 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1065,7 +1065,7 @@ void ClientUserinfoChanged( int clientNum )
client->pers.maxHealth = 0;
// set model
- if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) )
+ if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN_BSUIT )
{
Com_sprintf( buffer, MAX_QPATH, "%s/%s", BG_FindModelNameForClass( PCL_HUMAN_BSUIT ),
BG_FindSkinNameForClass( PCL_HUMAN_BSUIT ) );
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index ea7ed83f..afd21ca7 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -755,8 +755,10 @@ void Cmd_Team_f( gentity_t *ent )
BG_InventoryContainsWeapon( WP_HBUILD2, ent->client->ps.stats ) ) &&
ent->client->ps.stats[ STAT_MISC ] > 0 )
{
- trap_SendServerCommand( ent-g_entities,
- va( "print \"You cannot change teams until build timer expires\n\"" ) );
+ if( ent->client->pers.teamSelection == PTE_ALIENS )
+ G_TriggerMenu( ent->client->ps.clientNum, MN_A_TEAMCHANGEBUILDTIMER );
+ else
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_TEAMCHANGEBUILDTIMER );
return;
}
@@ -1561,9 +1563,60 @@ void Cmd_SetViewpos_f( gentity_t *ent )
TeleportPlayer( ent, origin, angles );
}
-#define EVOLVE_TRACE_HEIGHT 128.0f
#define AS_OVER_RT3 ((ALIENSENSE_RANGE*0.5f)/M_ROOT3)
+static qboolean G_RoomForClassChange( gentity_t *ent, pClass_t class,
+ vec3_t newOrigin )
+{
+ vec3_t fromMins, fromMaxs;
+ vec3_t toMins, toMaxs;
+ vec3_t temp;
+ trace_t tr, tr2;
+ float nudgeHeight;
+ pClass_t oldClass = ent->client->ps.stats[ STAT_PCLASS ];
+
+ BG_FindBBoxForClass( oldClass, fromMins, fromMaxs, NULL, NULL, NULL );
+ BG_FindBBoxForClass( class, toMins, toMaxs, NULL, NULL, NULL );
+
+ VectorCopy( ent->s.pos.trBase, newOrigin );
+
+ // test by moving the player up the max required on a 60 degree slope
+ if( fabs( toMins[ 0 ] ) > fabs( toMins[ 1 ] ) )
+ nudgeHeight = ( fabs( toMins[ 0 ] ) * 2.0f ) + 1.0f;
+ else
+ nudgeHeight = ( fabs( toMins[ 1 ] ) * 2.0f ) + 1.0f;
+
+ newOrigin[ 2 ] += fabs( toMins[ 2 ] ) - fabs( fromMins[ 2 ] )
+ + BG_FindZOffsetForClass( class ) - BG_FindZOffsetForClass( oldClass )
+ + 1.0f;
+ VectorCopy( newOrigin, temp );
+ temp[ 2 ] += nudgeHeight;
+
+ toMins[ 0 ] += 1.0f;
+ toMins[ 1 ] += 1.0f;
+ toMaxs[ 0 ] -= 1.0f;
+ toMaxs[ 1 ] -= 1.0f;
+
+ //compute a place up in the air to start the real trace
+ trap_Trace( &tr, newOrigin, toMins, toMaxs, temp, ent->s.number, MASK_SHOT );
+ VectorCopy( newOrigin, temp );
+ temp[ 2 ] += ( nudgeHeight * tr.fraction ) - 1.0f;
+
+ //trace down to the ground so that we can evolve on slopes
+ trap_Trace( &tr, temp, toMins, toMaxs, newOrigin, ent->s.number, MASK_SHOT );
+ VectorCopy( tr.endpos, newOrigin );
+
+ //make REALLY sure
+ trap_Trace( &tr2, newOrigin, toMins, toMaxs, newOrigin,
+ ent->s.number, MASK_SHOT );
+
+ //check there is room to evolve
+ if( !tr.startsolid && tr2.fraction == 1.0f )
+ return qtrue;
+ else
+ return qfalse;
+}
+
/*
=================
Cmd_Class_f
@@ -1574,17 +1627,12 @@ void Cmd_Class_f( gentity_t *ent )
char s[ MAX_TOKEN_CHARS ];
int clientNum;
int i;
- trace_t tr, tr2;
vec3_t infestOrigin;
int allowedClasses[ PCL_NUM_CLASSES ];
int numClasses = 0;
pClass_t currentClass = ent->client->ps.stats[ STAT_PCLASS ];
pClass_t newClass;
-
int numLevels;
- vec3_t fromMins, fromMaxs, toMins, toMaxs;
- vec3_t temp;
-
int entityList[ MAX_GENTITIES ];
vec3_t range = { AS_OVER_RT3, AS_OVER_RT3, AS_OVER_RT3 };
vec3_t mins, maxs;
@@ -1656,8 +1704,7 @@ void Cmd_Class_f( gentity_t *ent )
currentClass == PCL_ALIEN_BUILDER0_UPG ) &&
ent->client->ps.stats[ STAT_MISC ] > 0 )
{
- trap_SendServerCommand( ent-g_entities,
- va( "print \"You cannot evolve until build timer expires\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_A_EVOLVEBUILDTIMER );
return;
}
@@ -1665,31 +1712,7 @@ void Cmd_Class_f( gentity_t *ent )
newClass,
(short)ent->client->ps.persistant[ PERS_CREDIT ], 0 );
- BG_FindBBoxForClass( currentClass,
- fromMins, fromMaxs, NULL, NULL, NULL );
- BG_FindBBoxForClass( newClass,
- toMins, toMaxs, NULL, NULL, NULL );
-
- VectorCopy( ent->s.pos.trBase, infestOrigin );
-
- infestOrigin[ 2 ] += ( fabs( toMins[ 2 ] ) - fabs( fromMins[ 2 ] ) ) + 1.0f;
- VectorCopy( infestOrigin, temp );
- temp[ 2 ] += EVOLVE_TRACE_HEIGHT;
-
- //compute a place up in the air to start the real trace
- trap_Trace( &tr, infestOrigin, toMins, toMaxs, temp, ent->s.number, MASK_SHOT );
- VectorCopy( infestOrigin, temp );
- temp[ 2 ] += ( EVOLVE_TRACE_HEIGHT * tr.fraction ) - 1.0f;
-
- //trace down to the ground so that we can evolve on slopes
- trap_Trace( &tr, temp, toMins, toMaxs, infestOrigin, ent->s.number, MASK_SHOT );
- VectorCopy( tr.endpos, infestOrigin );
-
- //make REALLY sure
- trap_Trace( &tr2, ent->s.pos.trBase, NULL, NULL, infestOrigin, ent->s.number, MASK_SHOT );
-
- //check there is room to evolve
- if( !tr.startsolid && tr2.fraction == 1.0f )
+ if( G_RoomForClassChange( ent, newClass, infestOrigin ) )
{
//...check we can evolve to that class
if( numLevels >= 0 &&
@@ -2062,8 +2085,7 @@ void Cmd_Buy_f( gentity_t *ent )
!G_BuildableRange( ent->client->ps.origin, 100, BA_H_REPEATER ) &&
!G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
{
- trap_SendServerCommand( ent-g_entities, va(
- "print \"You must be near a reactor, repeater or armoury\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOENERGYAMMOHERE );
return;
}
}
@@ -2072,7 +2094,7 @@ void Cmd_Buy_f( gentity_t *ent )
//no armoury nearby
if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
{
- trap_SendServerCommand( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE );
return;
}
}
@@ -2188,6 +2210,19 @@ void Cmd_Buy_f( gentity_t *ent )
G_GiveClientMaxAmmo( ent, buyingEnergyAmmo );
else
{
+ if( upgrade == UP_BATTLESUIT )
+ {
+ vec3_t newOrigin;
+
+ if( !G_RoomForClassChange( ent, PCL_HUMAN_BSUIT, newOrigin ) )
+ {
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITON );
+ return;
+ }
+ VectorCopy( newOrigin, ent->s.pos.trBase );
+ ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN_BSUIT;
+ }
+
//add to inventory
BG_AddUpgradeToInventory( upgrade, ent->client->ps.stats );
}
@@ -2237,7 +2272,7 @@ void Cmd_Sell_f( gentity_t *ent )
//no armoury nearby
if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) )
{
- trap_SendServerCommand( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE );
return;
}
@@ -2260,7 +2295,7 @@ void Cmd_Sell_f( gentity_t *ent )
if( ( weapon == WP_HBUILD || weapon == WP_HBUILD2 ) &&
ent->client->ps.stats[ STAT_MISC ] > 0 )
{
- trap_SendServerCommand( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER );
return;
}
@@ -2285,6 +2320,21 @@ void Cmd_Sell_f( gentity_t *ent )
//remove upgrade if carried
if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) )
{
+ // shouldn't really need to test for this, but just to be safe
+ if( upgrade == UP_BATTLESUIT )
+ {
+ vec3_t newOrigin;
+
+ if( !G_RoomForClassChange( ent, PCL_HUMAN, newOrigin ) )
+ {
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITOFF );
+ return;
+ }
+ VectorCopy( newOrigin, ent->s.pos.trBase );
+ ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN;
+ }
+
+ //add to inventory
BG_RemoveUpgradeFromInventory( upgrade, ent->client->ps.stats );
if( upgrade == UP_BATTPACK )
@@ -2302,7 +2352,7 @@ void Cmd_Sell_f( gentity_t *ent )
if( ( i == WP_HBUILD || i == WP_HBUILD2 ) &&
ent->client->ps.stats[ STAT_MISC ] > 0 )
{
- trap_SendServerCommand( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) );
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER );
continue;
}
@@ -2328,6 +2378,21 @@ void Cmd_Sell_f( gentity_t *ent )
if( BG_InventoryContainsUpgrade( i, ent->client->ps.stats ) &&
BG_FindPurchasableForUpgrade( i ) )
{
+
+ // shouldn't really need to test for this, but just to be safe
+ if( i == UP_BATTLESUIT )
+ {
+ vec3_t newOrigin;
+
+ if( !G_RoomForClassChange( ent, PCL_HUMAN, newOrigin ) )
+ {
+ G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITOFF );
+ continue;
+ }
+ VectorCopy( newOrigin, ent->s.pos.trBase );
+ ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN;
+ }
+
BG_RemoveUpgradeFromInventory( i, ent->client->ps.stats );
if( i == UP_BATTPACK )