summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_draw.c12
-rw-r--r--src/cgame/cg_event.c26
-rw-r--r--src/cgame/cg_local.h4
-rw-r--r--src/cgame/cg_main.c6
-rw-r--r--src/cgame/cg_servercmds.c26
-rw-r--r--src/cgame/cg_view.c65
-rw-r--r--src/game/bg_misc.c84
-rw-r--r--src/game/bg_pmove.c186
-rw-r--r--src/game/bg_public.h6
-rw-r--r--src/game/g_cmds.c126
-rw-r--r--src/game/g_main.c2
-rw-r--r--src/game/tremulous.h3
-rw-r--r--src/ui/ui_local.h1
-rw-r--r--src/ui/ui_main.c79
-rw-r--r--ui/menudef.h6
15 files changed, 471 insertions, 161 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index d9aff288..56bec3df 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -2686,6 +2686,8 @@ static void CG_DrawCrosshairNames( void )
//==============================================================================
+//FIXME: both vote notes are hardcoded, change to ownerdrawn?
+
/*
=================
CG_DrawVote
@@ -2712,10 +2714,8 @@ static void CG_DrawVote( void )
if( sec < 0 )
sec = 0;
- s = va( "VOTE(%i):%s yes:%i no:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo );
- CG_Text_Paint( 0, 58, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
- s = "or press ESC then click Vote";
- CG_Text_Paint( 0, 78, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
+ s = va( "VOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.voteString, cgs.voteYes, cgs.voteNo );
+ CG_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
}
/*
@@ -2751,10 +2751,10 @@ static void CG_DrawTeamVote( void )
if( sec < 0 )
sec = 0;
- s = va( "TEAMVOTE(%i):%s yes:%i no:%i", sec, cgs.teamVoteString[ cs_offset ],
+ s = va( "TEAMVOTE(%i): \"%s\" Yes:%i No:%i", sec, cgs.teamVoteString[ cs_offset ],
cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[ cs_offset ] );
- CG_Text_Paint( 0, 90, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
+ CG_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL );
}
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index abf9e821..4a5dcef6 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -536,6 +536,32 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
case EV_JUMP:
DEBUGNAME( "EV_JUMP" );
trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
+
+ if( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
+ {
+ vec3_t surfNormal, refNormal = { 0.0f, 0.0f, 1.0f };
+ vec3_t rotAxis;
+
+ if( clientNum != cg.predictedPlayerState.clientNum )
+ break;
+
+ //set surfNormal
+ VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );
+
+ //if we are moving from one surface to another smooth the transition
+ if( !VectorCompare( surfNormal, cg.lastNormal ) && surfNormal[ 2 ] != 1.0f )
+ {
+ CrossProduct( refNormal, surfNormal, rotAxis );
+ VectorNormalize( rotAxis );
+
+ //add the op
+ CG_addSmoothOp( rotAxis, 15.0f );
+ }
+
+ //copy the current normal to the lastNormal
+ VectorCopy( surfNormal, cg.lastNormal );
+ }
+
break;
case EV_TAUNT:
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 39d13c03..16649ab2 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1416,6 +1416,9 @@ extern vmCvar_t ui_carriage;
extern vmCvar_t ui_stages;
extern vmCvar_t ui_dialog;
extern vmCvar_t ui_loading;
+extern vmCvar_t ui_voteActive;
+extern vmCvar_t ui_alienTeamVoteActive;
+extern vmCvar_t ui_humanTeamVoteActive;
//
// cg_main.c
@@ -1444,6 +1447,7 @@ void CG_BuildSpectatorString( );
//
// cg_view.c
//
+void CG_addSmoothOp( vec3_t rotAxis, float rotAngle ); //TA
void CG_TestModel_f( void );
void CG_TestGun_f( void );
void CG_TestModelNextFrame_f( void );
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 5163e16e..7a024f4c 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -205,6 +205,9 @@ vmCvar_t ui_carriage;
vmCvar_t ui_stages;
vmCvar_t ui_dialog;
vmCvar_t ui_loading;
+vmCvar_t ui_voteActive;
+vmCvar_t ui_alienTeamVoteActive;
+vmCvar_t ui_humanTeamVoteActive;
typedef struct
@@ -300,6 +303,9 @@ static cvarTable_t cvarTable[ ] =
{ &ui_stages, "ui_stages", "0 0", 0 },
{ &ui_dialog, "ui_dialog", "Text not set", 0 },
{ &ui_loading, "ui_loading", "0", 0 },
+ { &ui_voteActive, "ui_voteActive", "0", 0 },
+ { &ui_humanTeamVoteActive, "ui_humanTeamVoteActive", "0", 0 },
+ { &ui_alienTeamVoteActive, "ui_alienTeamVoteActive", "0", 0 },
// the following variables are created in other parts of the system,
// but we also reference them here
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 2539660b..90e65139 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -291,6 +291,11 @@ static void CG_ConfigStringModified( void )
{
cgs.voteTime = atoi( str );
cgs.voteModified = qtrue;
+
+ if( cgs.voteTime )
+ trap_Cvar_Set( "ui_voteActive", "1" );
+ else
+ trap_Cvar_Set( "ui_voteActive", "0" );
}
else if( num == CS_VOTE_YES )
{
@@ -306,8 +311,25 @@ static void CG_ConfigStringModified( void )
Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
else if( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1 )
{
- cgs.teamVoteTime[ num - CS_TEAMVOTE_TIME ] = atoi( str );
- cgs.teamVoteModified[ num - CS_TEAMVOTE_TIME ] = qtrue;
+ int cs_offset = num - CS_TEAMVOTE_TIME;
+
+ cgs.teamVoteTime[ cs_offset ] = atoi( str );
+ cgs.teamVoteModified[ cs_offset ] = qtrue;
+
+ if( cs_offset == 0 )
+ {
+ if( cgs.teamVoteTime[ cs_offset ] )
+ trap_Cvar_Set( "ui_humanTeamVoteActive", "1" );
+ else
+ trap_Cvar_Set( "ui_humanTeamVoteActive", "0" );
+ }
+ else if( cs_offset == 1 )
+ {
+ if( cgs.teamVoteTime[ cs_offset ] )
+ trap_Cvar_Set( "ui_alienTeamVoteActive", "1" );
+ else
+ trap_Cvar_Set( "ui_alienTeamVoteActive", "0" );
+ }
}
else if( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1 )
{
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index 9baf32d1..1099b7a5 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -907,7 +907,7 @@ static void CG_DrawSurfNormal( void )
CG_addSmoothOp
===============
*/
-static void CG_addSmoothOp( vec3_t rotAxis, float rotAngle )
+void CG_addSmoothOp( vec3_t rotAxis, float rotAngle )
{
int i;
@@ -991,8 +991,8 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o
//if this op has time remaining, perform it
if( cg.time < cg.sList[ i ].time + cg_wwSmoothTime.integer )
{
- stLocal = 1.0 - ( ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer );
- sFraction = -( cos( stLocal * M_PI ) + 1 ) / 2;
+ stLocal = 1.0f - ( ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer );
+ sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f;
RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
@@ -1020,6 +1020,50 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o
/*
===============
+CG_smoothWJTransitions
+===============
+*/
+static void CG_smoothWJTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
+{
+ int i;
+ float stLocal, sFraction;
+ qboolean performed = qfalse;
+ vec3_t inAxis[ 3 ], outAxis[ 3 ];
+
+ AnglesToAxis( in, inAxis );
+
+ //iterate through ops
+ for( i = MAXSMOOTHS - 1; i >= 0; i-- )
+ {
+ //if this op has time remaining, perform it
+ if( cg.time < cg.sList[ i ].time + cg_wwSmoothTime.integer )
+ {
+ stLocal = ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer;
+ sFraction = 1.0f - ( ( cos( stLocal * M_PI * 2.0f ) + 1.0f ) / 2.0f );
+
+ RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
+ inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
+ RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis,
+ inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
+ RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis,
+ inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );
+
+ AxisCopy( outAxis, inAxis );
+ performed = qtrue;
+ }
+ }
+
+ //if we performed any ops then return the smoothed angles
+ //otherwise simply return the in angles
+ if( performed )
+ AxisToAngles( outAxis, out );
+ else
+ VectorCopy( in, out );
+}
+
+
+/*
+===============
CG_CalcViewValues
Sets cg.refdef view values
@@ -1031,10 +1075,6 @@ static int CG_CalcViewValues( void )
memset( &cg.refdef, 0, sizeof( cg.refdef ) );
- // strings for in game rendering
- // Q_strncpyz( cg.refdef.text[0], "Park Ranger", sizeof(cg.refdef.text[0]) );
- // Q_strncpyz( cg.refdef.text[1], "19", sizeof(cg.refdef.text[1]) );
-
// calculate size of 3D view
CG_CalcVrect( );
@@ -1059,11 +1099,18 @@ static int CG_CalcViewValues( void )
if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) )
CG_smoothWWTransitions( ps, ps->viewangles, cg.refdefViewAngles );
+ else if( BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
+ CG_smoothWJTransitions( ps, ps->viewangles, cg.refdefViewAngles );
else
VectorCopy( ps->viewangles, cg.refdefViewAngles );
- if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) )
- VectorSet( cg.lastNormal, 0.0f, 0.0f, 1.0f );
+ //clumsy logic, but it needs to be this way round because the CS propogation
+ //delay screws things up otherwise
+ if( !BG_ClassHasAbility( ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
+ {
+ if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING ) )
+ VectorSet( cg.lastNormal, 0.0f, 0.0f, 1.0f );
+ }
// add error decay
if( cg_errorDecay.value > 0 )
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 043e28bf..f5f19976 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -1186,6 +1186,40 @@ int BG_FindUniqueTestForBuildable( int bclass )
classAttributes_t bg_classList[ ] =
{
{
+ PCL_NONE, //int classnum;
+ "spectator", //char *className;
+ "Spectator", //char *humanName;
+ "", //char *modelname;
+ 1.0f, //float modelScale;
+ "", //char *skinname;
+ "", //char *hudname;
+ ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
+ { -15, -15, -15 }, //vec3_t mins;
+ { 15, 15, 15 }, //vec3_t maxs;
+ { 15, 15, 15 }, //vec3_t crouchmaxs;
+ { -15, -15, -15 }, //vec3_t deadmins;
+ { 15, 15, 15 }, //vec3_t deadmaxs;
+ 0, 0, //int viewheight, crouchviewheight;
+ 0, //int health;
+ 0.0f, //float fallDamage;
+ 0, //int regenRate;
+ 0, //int abilities;
+ WP_NONE, //weapon_t startWeapon
+ 0.0f, //float buildDist;
+ 90, //int fov;
+ 0.000f, //float bob;
+ 1.0f, //float bobCycle;
+ 350, //int steptime;
+ 100, //float speed;
+ 10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
+ 6.0f, //float friction;
+ 100.0f, //float stopSpeed;
+ 270.0f, //float jumpMagnitude;
+ { PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
+ 0 //int value;
+ },
+ {
PCL_A_B_BASE, //int classnum;
"builder", //char *className;
"Builder", //char *humanName;
@@ -1213,6 +1247,7 @@ classAttributes_t bg_classList[ ] =
350, //int steptime;
ABUILDER_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
100.0f, //float stopSpeed;
130.0f, //float jumpMagnitude;
@@ -1247,6 +1282,7 @@ classAttributes_t bg_classList[ ] =
200, //int steptime;
ABUILDER_UPG_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
100.0f, //float stopSpeed;
270.0f, //float jumpMagnitude;
@@ -1281,9 +1317,10 @@ classAttributes_t bg_classList[ ] =
25, //int steptime;
SOLDIER_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
400.0f, //float stopSpeed;
- 270.0f, //float jumpMagnitude;
+ 250.0f, //float jumpMagnitude;
{ PCL_A_O_LEV1, PCL_NONE, PCL_NONE }, //int children[ 3 ];
SOLDIER_VALUE //int value;
},
@@ -1316,6 +1353,7 @@ classAttributes_t bg_classList[ ] =
25, //int steptime;
HYDRA_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
300.0f, //float stopSpeed;
270.0f, //float jumpMagnitude;
@@ -1351,6 +1389,7 @@ classAttributes_t bg_classList[ ] =
25, //int steptime;
HYDRA_UPG_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
300.0f, //float stopSpeed;
270.0f, //float jumpMagnitude;
@@ -1371,7 +1410,7 @@ classAttributes_t bg_classList[ ] =
{ 22, 22, 22 }, //vec3_t crouchmaxs;
{ -22, -22, -4 }, //vec3_t deadmins;
{ 22, 22, 4 }, //vec3_t deadmaxs;
- 30, 30, //int viewheight, crouchviewheight;
+ 10, 10, //int viewheight, crouchviewheight;
CHIMERA_HEALTH, //int health;
0.0f, //float fallDamage;
CHIMERA_REGEN, //int regenRate;
@@ -1385,9 +1424,10 @@ classAttributes_t bg_classList[ ] =
60, //int steptime;
CHIMERA_SPEED, //float speed;
10.0f, //float acceleration;
+ 2.0f, //float airAcceleration;
6.0f, //float friction;
100.0f, //float stopSpeed;
- 270.0f, //float jumpMagnitude;
+ 400.0f, //float jumpMagnitude;
{ PCL_A_O_LEV3, PCL_A_O_LEV2_UPG, PCL_NONE }, //int children[ 3 ];
CHIMERA_VALUE //int value;
},
@@ -1405,7 +1445,7 @@ classAttributes_t bg_classList[ ] =
{ 24, 24, 24 }, //vec3_t crouchmaxs;
{ -24, -24, -4 }, //vec3_t deadmins;
{ 24, 24, 4 }, //vec3_t deadmaxs;
- 32, 32, //int viewheight, crouchviewheight;
+ 12, 12, //int viewheight, crouchviewheight;
CHIMERA_UPG_HEALTH, //int health;
0.0f, //float fallDamage;
CHIMERA_UPG_REGEN, //int regenRate;
@@ -1419,9 +1459,10 @@ classAttributes_t bg_classList[ ] =
60, //int steptime;
CHIMERA_UPG_SPEED, //float speed;
10.0f, //float acceleration;
+ 2.0f, //float airAcceleration;
6.0f, //float friction;
100.0f, //float stopSpeed;
- 270.0f, //float jumpMagnitude;
+ 400.0f, //float jumpMagnitude;
{ PCL_A_O_LEV3, PCL_NONE, PCL_NONE }, //int children[ 3 ];
CHIMERA_UPG_VALUE //int value;
},
@@ -1453,6 +1494,7 @@ classAttributes_t bg_classList[ ] =
25, //int steptime;
DRAGOON_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
200.0f, //float stopSpeed;
270.0f, //float jumpMagnitude;
@@ -1487,6 +1529,7 @@ classAttributes_t bg_classList[ ] =
25, //int steptime;
DRAGOON_UPG_SPEED, //float speed;
10.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
200.0f, //float stopSpeed;
270.0f, //float jumpMagnitude;
@@ -1521,9 +1564,10 @@ classAttributes_t bg_classList[ ] =
60, //int steptime;
BMOFO_SPEED, //float speed;
5.0f, //float acceleration;
+ 1.0f, //float airAcceleration;
6.0f, //float friction;
100.0f, //float stopSpeed;
- 270.0f, //float jumpMagnitude;
+ 170.0f, //float jumpMagnitude;
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
0, //int timetoevolve;
BMOFO_VALUE //int value;
@@ -1556,9 +1600,10 @@ classAttributes_t bg_classList[ ] =
200, //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;
+ 220.0f, //float jumpMagnitude;
{ PCL_NONE, PCL_NONE, PCL_NONE }, //int children[ 3 ];
0, //int timetoevolve;
0 //int value;
@@ -1574,7 +1619,7 @@ classAttributes_t bg_classList[ ] =
"bsuit", ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), { 0, 0, 0 }, { 0, 0, 0, },
{ 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 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, 270.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0
+ 0.0f, 1.0f, 0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 270.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0
}
};
@@ -1992,6 +2037,27 @@ float BG_FindAccelerationForClass( int pclass )
/*
==============
+BG_FindAirAccelerationForClass
+==============
+*/
+float BG_FindAirAccelerationForClass( int pclass )
+{
+ int i;
+
+ for( i = 0; i < bg_numPclasses; i++ )
+ {
+ if( bg_classList[ i ].classNum == pclass )
+ {
+ return bg_classList[ i ].airAcceleration;
+ }
+ }
+
+ Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindAirAccelerationForClass\n" );
+ return 1.0f;
+}
+
+/*
+==============
BG_FindFrictionForClass
==============
*/
@@ -2149,7 +2215,7 @@ int BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits, int num )
if( credits == 0 )
return 0;
- if( tclass == PCL_NONE )
+ if( fclass == PCL_NONE || tclass == PCL_NONE )
return 0;
for( i = 0; i < bg_numPclasses; i++ )
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 50082514..6781a530 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -388,7 +388,7 @@ static float PM_CmdScale( usercmd_t *cmd )
if( pm->ps->pm_type == PM_GRABBED )
modifier = 0.0f;
- if( pm->ps->persistant[ PERS_TEAM ] != TEAM_SPECTATOR )
+ if( pm->ps->pm_type != PM_SPECTATOR && pm->ps->pm_type != PM_NOCLIP )
{
if( BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) == 0.0f )
cmd->upmove = 0;
@@ -487,8 +487,6 @@ PM_CheckPounce
*/
static qboolean PM_CheckPounce( void )
{
- vec3_t forward;
-
if( pm->ps->weapon != WP_POUNCE &&
pm->ps->weapon != WP_POUNCE_UPG )
return qfalse;
@@ -512,9 +510,7 @@ static qboolean PM_CheckPounce( void )
pm->ps->groundEntityNum = ENTITYNUM_NONE;
- AngleVectors( pm->ps->viewangles, forward, NULL, NULL );
- VectorMA( pm->ps->velocity, pm->ps->stats[ STAT_MISC ], forward, pm->ps->velocity );
- pm->ps->velocity[ 2 ] += BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) / 2.0f;
+ VectorMA( pm->ps->velocity, pm->ps->stats[ STAT_MISC ], pml.forward, pm->ps->velocity );
PM_AddEvent( EV_JUMP );
@@ -542,6 +538,99 @@ static qboolean PM_CheckPounce( void )
/*
=============
+PM_CheckWallJump
+=============
+*/
+static qboolean PM_CheckWallJump( void )
+{
+ vec3_t dir, forward, right, temp;
+ vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
+ float normalFraction = 1.5f;
+ float cmdFraction = 1.0f;
+ float upFraction = 1.5f;
+
+ if( pm->ps->pm_flags & PMF_RESPAWNED )
+ return qfalse; // don't allow jump until all buttons are up
+
+ if( pm->cmd.upmove < 10 )
+ // not holding jump
+ return qfalse;
+
+ if( pm->ps->pm_flags & PMF_TIME_WALLJUMP )
+ return qfalse;
+
+ // must wait for jump to be released
+ if( pm->ps->pm_flags & PMF_JUMP_HELD &&
+ pm->ps->grapplePoint[ 2 ] == 1.0f )
+ {
+ // clear upmove so cmdscale doesn't lower running speed
+ pm->cmd.upmove = 0;
+ return qfalse;
+ }
+
+ pm->ps->pm_flags |= PMF_TIME_WALLJUMP;
+ pm->ps->pm_time = 200;
+
+ pml.groundPlane = qfalse; // jumping away
+ pml.walking = qfalse;
+ pm->ps->pm_flags |= PMF_JUMP_HELD;
+
+ pm->ps->groundEntityNum = ENTITYNUM_NONE;
+
+ ProjectPointOnPlane( forward, pml.forward, pm->ps->grapplePoint );
+ ProjectPointOnPlane( right, pml.right, pm->ps->grapplePoint );
+
+ VectorScale( pm->ps->grapplePoint, normalFraction, dir );
+
+ if( pm->cmd.forwardmove > 0 )
+ VectorMA( dir, cmdFraction, forward, dir );
+ else if( pm->cmd.forwardmove < 0 )
+ VectorMA( dir, -cmdFraction, forward, dir );
+
+ if( pm->cmd.rightmove > 0 )
+ VectorMA( dir, cmdFraction, right, dir );
+ else if( pm->cmd.rightmove < 0 )
+ VectorMA( dir, -cmdFraction, right, dir );
+
+ VectorMA( dir, upFraction, refNormal, dir );
+ VectorNormalize( dir );
+
+ VectorMA( pm->ps->velocity, BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ),
+ dir, pm->ps->velocity );
+
+ //for a long run of wall jumps the velocity can get pretty large, this caps it
+ if( VectorLength( pm->ps->velocity ) > CHIMERA_WALLJUMP_MAXSPEED )
+ {
+ VectorNormalize( pm->ps->velocity );
+ VectorScale( pm->ps->velocity, CHIMERA_WALLJUMP_MAXSPEED, pm->ps->velocity );
+ }
+
+ PM_AddEvent( EV_JUMP );
+
+ if( pm->cmd.forwardmove >= 0 )
+ {
+ if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) )
+ PM_ForceLegsAnim( LEGS_JUMP );
+ else
+ PM_ForceLegsAnim( NSPA_JUMP );
+
+ pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP;
+ }
+ else
+ {
+ if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) )
+ PM_ForceLegsAnim( LEGS_JUMPB );
+ else
+ PM_ForceLegsAnim( NSPA_JUMPBACK );
+
+ pm->ps->pm_flags |= PMF_BACKWARDS_JUMP;
+ }
+
+ return qtrue;
+}
+
+/*
+=============
PM_CheckJump
=============
*/
@@ -550,6 +639,9 @@ static qboolean PM_CheckJump( void )
if( BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) == 0.0f )
return qfalse;
+ if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
+ return PM_CheckWallJump( );
+
//can't jump and pounce charge at the same time
if( ( pm->ps->weapon == WP_POUNCE ||
pm->ps->weapon == WP_POUNCE_UPG ) &&
@@ -916,7 +1008,8 @@ static void PM_AirMove( void )
wishspeed *= scale;
// not on ground, so little effect on velocity
- PM_Accelerate( wishdir, wishspeed, pm_airaccelerate );
+ PM_Accelerate( wishdir, wishspeed,
+ BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] ) );
// we may have a ground plane that is very steep, even
// though we don't have a groundentity
@@ -1042,7 +1135,7 @@ static void PM_ClimbMove( void )
// when a player gets hit, they temporarily lose
// full control, which allows them to be moved a bit
if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK )
- accelerate = pm_airaccelerate;
+ accelerate = BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] );
else
accelerate = BG_FindAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] );
@@ -1162,7 +1255,7 @@ static void PM_WalkMove( void )
// when a player gets hit, they temporarily lose
// full control, which allows them to be moved a bit
if( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK )
- accelerate = pm_airaccelerate;
+ accelerate = BG_FindAirAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] );
else
accelerate = BG_FindAccelerationForClass( pm->ps->stats[ STAT_PCLASS ] );
@@ -1612,7 +1705,7 @@ PM_GroundClimbTrace
*/
static void PM_GroundClimbTrace( void )
{
- vec3_t surfNormal, movedir, lookdir, forward, right, point;
+ vec3_t surfNormal, movedir, lookdir, point;
vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
vec3_t toAngles, surfAngles;
@@ -1637,10 +1730,7 @@ static void PM_GroundClimbTrace( void )
VectorCopy( pm->ps->grapplePoint, surfNormal );
//construct a vector which reflects the direction the player is looking wrt the surface normal
- AngleVectors( pm->ps->viewangles, forward, NULL, NULL );
- CrossProduct( forward, surfNormal, right );
- VectorNormalize( right );
- CrossProduct( surfNormal, right, movedir );
+ ProjectPointOnPlane( movedir, pml.forward, surfNormal );
VectorNormalize( movedir );
VectorCopy( movedir, lookdir );
@@ -1651,7 +1741,7 @@ static void PM_GroundClimbTrace( void )
//allow strafe transitions
if( pm->cmd.rightmove )
{
- VectorCopy( right, movedir );
+ VectorCopy( pml.right, movedir );
if( pm->cmd.rightmove < 0 )
VectorNegate( movedir, movedir );
@@ -1668,13 +1758,13 @@ static void PM_GroundClimbTrace( void )
//trace into direction we are moving
VectorMA( pm->ps->origin, 0.25f, movedir, point );
- pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
break;
case 1:
//trace straight down anto "ground" surface
VectorMA( pm->ps->origin, -0.25f, surfNormal, point );
- pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
break;
case 2:
@@ -1694,7 +1784,7 @@ static void PM_GroundClimbTrace( void )
{
VectorMA( pm->ps->origin, -16.0f, surfNormal, point );
VectorMA( point, -16.0f, movedir, point );
- pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
}
else
continue;
@@ -1703,13 +1793,13 @@ static void PM_GroundClimbTrace( void )
case 4:
//fall back so we don't have to modify PM_GroundTrace too much
VectorCopy( pm->ps->origin, point );
- point[2] = pm->ps->origin[2] - 0.25f;
- pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
+ point[ 2 ] = pm->ps->origin[ 2 ] - 0.25f;
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
break;
}
//if we hit something
- if( trace.fraction < 1.0 && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) &&
+ if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) &&
!( trace.entityNum != ENTITYNUM_WORLD && i != 4 ) )
{
if( i == 2 || i == 3 )
@@ -1849,16 +1939,16 @@ static void PM_GroundClimbTrace( void )
//IMPORTANT: break out of the for loop if we've hit something
break;
}
- else if ( trace.allsolid )
+ else if( trace.allsolid )
{
// do something corrective if the trace starts in a solid...
//TA: fuck knows what this does with all my new stuff :(
- if ( !PM_CorrectAllSolid(&trace) )
+ if( !PM_CorrectAllSolid( &trace ) )
return;
}
}
- if ( trace.fraction >= 1.0 )
+ if ( trace.fraction >= 1.0f )
{
// if the trace didn't hit anything, we are in free fall
PM_GroundTraceMissed();
@@ -1899,7 +1989,8 @@ PM_GroundTrace
*/
static void PM_GroundTrace( void )
{
- vec3_t point, forward, srotAxis;
+ vec3_t point, srotAxis;
+ vec3_t movedir;
vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
trace_t trace;
float srotAngle;
@@ -1933,19 +2024,11 @@ static void PM_GroundTrace( void )
pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING;
pm->ps->eFlags &= ~EF_WALLCLIMB;
- //make sure that the surfNormal is reset to the ground
- if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) )
- VectorCopy( refNormal, pm->ps->grapplePoint );
-
point[ 0 ] = pm->ps->origin[ 0 ];
point[ 1 ] = pm->ps->origin[ 1 ];
point[ 2 ] = pm->ps->origin[ 2 ] - 0.25;
- //FIXME: hack until i find out where CONTENTS_BODY is getting unset for uhm.. bodies.
- if( pm->ps->pm_type == PM_DEAD )
- pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, MASK_PLAYERSOLID );
- else
- pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
pml.groundTrace = trace;
@@ -1954,6 +2037,9 @@ static void PM_GroundTrace( void )
if( !PM_CorrectAllSolid( &trace ) )
return;
+ //make sure that the surfNormal is reset to the ground
+ VectorCopy( refNormal, pm->ps->grapplePoint );
+
// if the trace didn't hit anything, we are in free fall
if( trace.fraction == 1.0 )
{
@@ -1961,6 +2047,38 @@ static void PM_GroundTrace( void )
pml.groundPlane = qfalse;
pml.walking = qfalse;
+ if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLJUMPER ) )
+ {
+ ProjectPointOnPlane( movedir, pml.forward, refNormal );
+ VectorNormalize( movedir );
+
+ if( pm->cmd.forwardmove < 0 )
+ VectorNegate( movedir, movedir );
+
+ //allow strafe transitions
+ if( pm->cmd.rightmove )
+ {
+ VectorCopy( pml.right, movedir );
+
+ if( pm->cmd.rightmove < 0 )
+ VectorNegate( movedir, movedir );
+ }
+
+ //trace into direction we are moving
+ VectorMA( pm->ps->origin, 0.25f, movedir, point );
+ pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask );
+
+ if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) &&
+ ( trace.entityNum == ENTITYNUM_WORLD ) )
+ {
+ if( !VectorCompare( trace.plane.normal, pm->ps->grapplePoint ) )
+ {
+ VectorCopy( trace.plane.normal, pm->ps->grapplePoint );
+ PM_CheckWallJump( );
+ }
+ }
+ }
+
return;
}
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 6fdb8546..c76132de 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -138,11 +138,11 @@ typedef enum
#define PMF_GRAPPLE_PULL 2048 // pull towards grapple location
#define PMF_FOLLOW 4096 // spectate following another player
#define PMF_SCOREBOARD 8192 // spectate as a scoreboard
-#define PMF_INVULEXPAND 16384 // invulnerability sphere set to full size
+#define PMF_TIME_WALLJUMP 16384 //TA: for limiting wall jumping
#define PMF_CHARGE 32768 //TA: keep track of pouncing
-#define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK)
+#define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK|PMF_TIME_WALLJUMP)
#define MAXTOUCH 32
typedef struct
@@ -895,6 +895,7 @@ typedef struct
float speed;
float acceleration;
+ float airAcceleration;
float friction;
float stopSpeed;
float jumpMagnitude;
@@ -1087,6 +1088,7 @@ float BG_FindBobForClass( int pclass );
float BG_FindBobCycleForClass( int pclass );
float BG_FindSpeedForClass( int pclass );
float BG_FindAccelerationForClass( int pclass );
+float BG_FindAirAccelerationForClass( int pclass );
float BG_FindFrictionForClass( int pclass );
float BG_FindStopSpeedForClass( int pclass );
float BG_FindJumpMagnitudeForClass( int pclass );
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 12cc7dff..9342c789 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -715,6 +715,7 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
char arg2[ MAX_STRING_TOKENS ];
team = ent->client->ps.stats[ STAT_PTEAM ];
+
if( team == PTE_HUMANS )
cs_offset = 0;
else if( team == PTE_ALIENS )
@@ -748,77 +749,51 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
// make sure it is a valid command to vote on
trap_Argv( 1, arg1, sizeof( arg1 ) );
- arg2[ 0 ] = '\0';
+ trap_Argv( 2, arg2, sizeof( arg2 ) );
- for( i = 2; i < trap_Argc( ); i++ )
- {
- if( i > 2 )
- strcat( arg2, " " );
-
- trap_Argv( i, &arg2[ strlen( arg2 ) ], sizeof( arg2 ) - strlen( arg2 ) );
- }
-
if( strchr( arg1, ';' ) || strchr( arg2, ';' ) )
{
- trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Invalid team vote string.\n\"" );
return;
}
+ if( !Q_stricmp( arg1, "teamkick" ) )
+ {
+ char netname[ MAX_NETNAME ], kickee[ MAX_NETNAME ];
- /*if ( !Q_stricmp( arg1, "leader" ) ) {
- char netname[MAX_NETNAME], leader[MAX_NETNAME];
-
- if ( !arg2[0] ) {
- i = ent->client->ps.clientNum;
+ Q_strncpyz( kickee, arg2, sizeof( kickee ) );
+ Q_CleanStr( kickee );
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ if( level.clients[ i ].pers.connected == CON_DISCONNECTED )
+ continue;
+
+ if( level.clients[ i ].ps.stats[ STAT_PTEAM ] != team )
+ continue;
+
+ Q_strncpyz( netname, level.clients[ i ].pers.netname, sizeof( netname ) );
+ Q_CleanStr( netname );
+
+ if( !Q_stricmp( netname, kickee ) )
+ break;
}
- else {
- // numeric values are just slot numbers
- for (i = 0; i < 3; i++) {
- if ( !arg2[i] || arg2[i] < '0' || arg2[i] > '9' )
- break;
- }
- if ( i >= 3 || !arg2[i]) {
- i = atoi( arg2 );
- if ( i < 0 || i >= level.maxclients ) {
- trap_SendServerCommand( ent-g_entities, va("print \"Bad client slot: %i\n\"", i) );
- return;
- }
-
- if ( !g_entities[i].inuse ) {
- trap_SendServerCommand( ent-g_entities, va("print \"Client %i is not active\n\"", i) );
- return;
- }
- }
- else {
- Q_strncpyz(leader, arg2, sizeof(leader));
- Q_CleanStr(leader);
- for ( i = 0 ; i < level.maxclients ; i++ ) {
- if ( level.clients[i].pers.connected == CON_DISCONNECTED )
- continue;
- if (level.clients[i].sess.sessionTeam != team)
- continue;
- Q_strncpyz(netname, level.clients[i].pers.netname, sizeof(netname));
- Q_CleanStr(netname);
- if ( !Q_stricmp(netname, leader) ) {
- break;
- }
- }
- if ( i >= level.maxclients ) {
- trap_SendServerCommand( ent-g_entities, va("print \"%s is not a valid player on your team.\n\"", arg2) );
- return;
- }
- }
+
+ if( i >= level.maxclients )
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"%s is not a valid player on your team.\n\"", arg2 ) );
+ return;
}
- Com_sprintf(arg2, sizeof(arg2), "%d", i);
- } else*/
+ }
+ else
{
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
- trap_SendServerCommand( ent-g_entities, "print \"Team vote commands are: leader <player>.\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Team vote commands are: teamkick <player>.\n\"" );
return;
}
-/* Com_sprintf( level.teamVoteString[ cs_offset ],
- sizeof( level.teamVoteString[ cs_offset ] ), "%s %s", arg1, arg2 );
+ Com_sprintf( level.teamVoteString[ cs_offset ],
+ sizeof( level.teamVoteString[ cs_offset ] ), "kick \"%s\"", arg2 );
for( i = 0 ; i < level.maxclients ; i++ )
{
@@ -836,7 +811,7 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
for( i = 0 ; i < level.maxclients ; i++ )
{
- if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == team)
+ if( level.clients[ i ].ps.stats[ STAT_PTEAM ] == team )
level.clients[ i ].ps.eFlags &= ~EF_TEAMVOTED;
}
@@ -845,7 +820,7 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va( "%i", level.teamVoteTime[ cs_offset ] ) );
trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteString[ cs_offset ] );
trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va( "%i", level.teamVoteYes[ cs_offset ] ) );
- trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va( "%i", level.teamVoteNo[ cs_offset ] ) );*/
+ trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va( "%i", level.teamVoteNo[ cs_offset ] ) );
}
@@ -1690,37 +1665,6 @@ void Cmd_Boost_f( gentity_t *ent )
/*
=================
-Cmd_Spawnbody_f
-=================
-*/
-void Cmd_Spawnbody_f( gentity_t *ent )
-{
- gentity_t *dummy = G_Spawn( );
- vec3_t forward;
-
- if( !CheatsOk( ent ) )
- return;
-
- AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
- forward[ 2 ] = 0.0f;
-
- VectorMA( ent->client->ps.origin, 128.0f, forward, dummy->r.currentOrigin );
- dummy->r.currentOrigin[ 2 ] += 64.0f;
-
- dummy->client = level.clients + MAX_CLIENTS;
-
- dummy->client->ps.stats[ STAT_PTEAM ] = PTE_HUMANS;
- dummy->client->ps.stats[ STAT_PCLASS ] = PCL_H_BASE;
-
- dummy->client->lasthurt_client = dummy->client->ps.clientNum = -1;
-
- SpawnCorpse( dummy );
-
- G_FreeEntity( dummy );
-}
-
-/*
-=================
Cmd_Test_f
=================
*/
@@ -1830,8 +1774,6 @@ void ClientCommand( int clientNum )
Cmd_TeamVote_f( ent );
else if( Q_stricmp( cmd, "setviewpos" ) == 0 )
Cmd_SetViewpos_f( ent );
- else if( Q_stricmp( cmd, "spawnbody" ) == 0 )
- Cmd_Spawnbody_f( ent );
else if( Q_stricmp( cmd, "test" ) == 0 )
Cmd_Test_f( ent );
else
diff --git a/src/game/g_main.c b/src/game/g_main.c
index f74f7e7d..0218ac58 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -1330,7 +1330,7 @@ void CheckVote( void )
if( level.voteExecuteTime && level.voteExecuteTime < level.time )
{
level.voteExecuteTime = 0;
- trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) );
+ trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) );
}
if( !level.voteTime )
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index b0ec7341..ca7c48d8 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -57,6 +57,7 @@
#define CHIMERA_DIRECTZAP_DMG ADM(100)
#define CHIMERA_DIRECTZAP_RANGE 200.0f
#define CHIMERA_DIRECTZAP_REPEAT 1500
+#define CHIMERA_WALLJUMP_MAXSPEED 1000.0f
#define DRAGOON_CLAW_DMG ADM(75)
#define DRAGOON_CLAW_RANGE 96.0f
@@ -64,7 +65,7 @@
#define DRAGOON_CLAW_U_REPEAT 500
#define DRAGOON_POUNCE_DMG ADM(200)
#define DRAGOON_POUNCE_RANGE 96.0f
-#define DRAGOON_POUNCE_SPEED 750
+#define DRAGOON_POUNCE_SPEED 600
#define DRAGOON_POUNCE_SPEED_MOD 0.75f
#define DRAGOON_POUNCE_TIME 1000
#define DRAGOON_SLOWBLOB_DMG ADM(20)
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index 4531790e..0519abdf 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -915,7 +915,6 @@ typedef struct {
int effectsColor;
qboolean inGameLoad;
-
} uiInfo_t;
extern uiInfo_t uiInfo;
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index 7a289e10..bf32f974 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -2611,9 +2611,73 @@ static void UI_OwnerDraw( float x, float y, float w, float h,
static qboolean UI_OwnerDrawVisible(int flags) {
qboolean vis = qtrue;
+ uiClientState_t cs;
+ pTeam_t team;
+ char info[ MAX_INFO_STRING ];
- while (flags) {
+ trap_GetClientState( &cs );
+ trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING );
+ team = atoi( Info_ValueForKey( info, "t" ) );
+
+ while (flags) {
+
+ if( flags & UI_SHOW_NOTSPECTATING )
+ {
+ if( team == PTE_NONE )
+ vis = qfalse;
+
+ flags &= ~UI_SHOW_NOTSPECTATING;
+ }
+
+ if( flags & UI_SHOW_VOTEACTIVE )
+ {
+ if( !trap_Cvar_VariableValue( "ui_voteActive" ) )
+ vis = qfalse;
+
+ flags &= ~UI_SHOW_VOTEACTIVE;
+ }
+
+ if( flags & UI_SHOW_CANVOTE )
+ {
+ if( trap_Cvar_VariableValue( "ui_voteActive" ) )
+ vis = qfalse;
+
+ flags &= ~UI_SHOW_CANVOTE;
+ }
+
+ if( flags & UI_SHOW_TEAMVOTEACTIVE )
+ {
+ if( team == PTE_ALIENS )
+ {
+ if( !trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) )
+ vis = qfalse;
+ }
+ else if( team == PTE_HUMANS )
+ {
+ if( !trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) )
+ vis = qfalse;
+ }
+
+ flags &= ~UI_SHOW_TEAMVOTEACTIVE;
+ }
+
+ if( flags & UI_SHOW_CANTEAMVOTE )
+ {
+ if( team == PTE_ALIENS )
+ {
+ if( trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) )
+ vis = qfalse;
+ }
+ else if( team == PTE_HUMANS )
+ {
+ if( trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) )
+ vis = qfalse;
+ }
+
+ flags &= ~UI_SHOW_CANTEAMVOTE;
+ }
+
if (flags & UI_SHOW_LEADER) {
// these need to show when this client can give orders to a player or a group
if (!uiInfo.teamLeader) {
@@ -4249,7 +4313,15 @@ static void UI_RunMenuScript(char **args) {
if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount) {
trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick %s\n",uiInfo.playerNames[uiInfo.playerIndex]) );
}
- } else if (Q_stricmp(name, "voteGame") == 0) {
+ }
+ else if( Q_stricmp( name, "voteTeamKick" ) == 0 )
+ {
+ if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
+ {
+ trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote teamkick %s\n", uiInfo.playerNames[ uiInfo.teamIndex ] ) );
+ }
+ }
+ else if (Q_stricmp(name, "voteGame") == 0) {
if (ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes) {
trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote g_gametype %i\n",uiInfo.gameTypes[ui_netGameType.integer].gtEnum) );
}
@@ -4257,7 +4329,8 @@ static void UI_RunMenuScript(char **args) {
if (uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount) {
trap_Cmd_ExecuteText( EXEC_APPEND, va("callteamvote leader %s\n",uiInfo.teamNames[uiInfo.teamIndex]) );
}
- } else if (Q_stricmp(name, "addBot") == 0) {
+ }
+ else if (Q_stricmp(name, "addBot") == 0) {
trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot %s %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") );
} else if (Q_stricmp(name, "addFavorite") == 0) {
if (ui_netSource.integer != AS_FAVORITES) {
diff --git a/ui/menudef.h b/ui/menudef.h
index a5247c53..1c2d8c48 100644
--- a/ui/menudef.h
+++ b/ui/menudef.h
@@ -117,8 +117,12 @@
#define UI_SHOW_NETANYTEAMGAME 0x00000800
#define UI_SHOW_NOTFAVORITESERVERS 0x00001000
+#define UI_SHOW_VOTEACTIVE 0x00002000
+#define UI_SHOW_CANVOTE 0x00004000
+#define UI_SHOW_TEAMVOTEACTIVE 0x00008000
+#define UI_SHOW_CANTEAMVOTE 0x00010000
-
+#define UI_SHOW_NOTSPECTATING 0x00020000
// owner draw types
// ideally these should be done outside of this file but