From 2d9ab8a588afa1b8f990b74ce324eb4f61c2c695 Mon Sep 17 00:00:00 2001 From: "Tony J. White" Date: Tue, 3 Apr 2007 03:39:26 +0000 Subject: * PCL_HUMAN_BSUIT is now a full fledged player class now. This means that the overrides/classes/human_bsuit.cfg file can set all the goodies such as viewHeight and bounding box size. Also, bsuit corpses work now. * added MN_A_TEAMCHANGEBUILDTIMER, MN_H_TEAMCHANGEBUILDTIMER, MN_A_EVOLVEBUILDTIMER, and MN_H_ARMOURYBUILDTIMER for the error dialogs you get when trying to do something that's not allowed with an active build timer. * added MN_H_NOARMOURYHERE and MN_H_NOENERGYAMMOHERE error dialogs for trying to buy/sell when not near the necessary buildables. * added MN_H_NOROOMBSUITON and MN_H_NOROOMBSUITOFF error dialogs for when there is no room to change class between PCL_HUMAN and PCL_HUMAN_BSUIT * removed an unused variable from my recent big ui commit --- src/cgame/cg_servercmds.c | 55 +++++++++++++++++ src/game/bg_misc.c | 51 ++++++++++++---- src/game/bg_public.h | 8 +++ src/game/g_client.c | 2 +- src/game/g_cmds.c | 147 +++++++++++++++++++++++++++++++++------------- src/ui/ui_gameinfo.c | 1 - 6 files changed, 208 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index 6fcae7eb..7fb3e060 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -540,6 +540,19 @@ void CG_Menu( int menu ) cmd = "menu tremulous_human_dialog\n"; break; + case MN_A_TEAMCHANGEBUILDTIMER: + longMsg = "You cannot leave the Alien team until your build timer " + "has expired."; + shortMsg = "You cannot change teams until your build timer expires.\n"; + cmd = "menu tremulous_alien_dialog\n"; + break; + + case MN_H_TEAMCHANGEBUILDTIMER: + longMsg = "You cannot leave the Human team until your build timer " + "has expired."; + shortMsg = "You cannot change teams until your build timer expires.\n"; + cmd = "menu tremulous_human_dialog\n"; + break; //=============================== @@ -634,6 +647,42 @@ void CG_Menu( int menu ) cmd = "menu tremulous_human_dialog\n"; break; + case MN_H_NOARMOURYHERE: + longMsg = "You must be near a powered Armoury in order to purchase " + "weapons, upgrades or non-energy ammunition."; + shortMsg = "You must be near a powered Armoury\n"; + cmd = "menu tremulous_human_dialog\n"; + 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\n"; + cmd = "menu tremulous_human_dialog\n"; + 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."; + shortMsg = "Not enough room here to put on a Battle Suit\n"; + cmd = "menu tremulous_human_dialog\n"; + break; + + case MN_H_NOROOMBSUITOFF: + longMsg = "There is not enough room here to take off your Battle Suit. " + "Make sure you have enough head room to climb out."; + shortMsg = "Not enough room here to take off your Battle Suit\n"; + cmd = "menu tremulous_human_dialog\n"; + break; + + case MN_H_ARMOURYBUILDTIMER: + longMsg = "You are not allowed to buy or sell weapons until your " + "build timer has expired."; + shortMsg = "You can not buy or sell weapos until your build timer " + "expires\n"; + cmd = "menu tremulous_human_dialog\n"; + break; + //=============================== @@ -716,6 +765,12 @@ void CG_Menu( int menu ) cmd = "menu tremulous_alien_dialog\n"; break; + case MN_A_EVOLVEBUILDTIMER: + longMsg = "You cannot Evolve until your build timer has expired."; + shortMsg = "You cannot Evolve until your build timer expires\n"; + cmd = "menu tremulous_alien_dialog\n"; + break; + case MN_A_HOVEL_OCCUPIED: longMsg = "This Hovel is already occupied by another builder."; shortMsg = "This Hovel is already occupied by another builder\n"; 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 ) diff --git a/src/ui/ui_gameinfo.c b/src/ui/ui_gameinfo.c index 90047b9d..43639e56 100644 --- a/src/ui/ui_gameinfo.c +++ b/src/ui/ui_gameinfo.c @@ -309,7 +309,6 @@ char *UI_GetBotNameByNumber( int num ) { void UI_ServerInfo( void ) { char info[ MAX_INFO_VALUE ]; - int i; info[0] = '\0'; if( trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ) ) -- cgit