mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00

This improves clarity for using weapon commands. Also the mask was incorrect for protocol above version 8 (mohaas and mohaab)
709 lines
20 KiB
C
709 lines
20 KiB
C
/*
|
|
===========================================================================
|
|
Copyright (C) 2008-2024 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
//
|
|
// DESCRIPTION:
|
|
// text commands typed in at the local console, or executed by a key binding
|
|
|
|
#include "cg_local.h"
|
|
#include "../fgame/bg_voteoptions.h"
|
|
|
|
void CG_TargetCommand_f(void);
|
|
|
|
/*
|
|
=================
|
|
CG_SizeUp_f
|
|
|
|
Keybinding command
|
|
=================
|
|
*/
|
|
static void CG_SizeUp_f(void)
|
|
{
|
|
cgi.Cvar_Set("viewsize", va("%i", (int)(cg_viewsize->integer + 10)));
|
|
}
|
|
|
|
/*
|
|
=================
|
|
CG_SizeDown_f
|
|
|
|
Keybinding command
|
|
=================
|
|
*/
|
|
static void CG_SizeDown_f(void)
|
|
{
|
|
cgi.Cvar_Set("viewsize", va("%i", (int)(cg_viewsize->integer - 10)));
|
|
}
|
|
|
|
/*
|
|
=============
|
|
CG_Viewpos_f
|
|
|
|
Debugging command to print the current position
|
|
=============
|
|
*/
|
|
static void CG_Viewpos_f(void)
|
|
{
|
|
cgi.Printf(
|
|
"(%i %i %i) : %i\n",
|
|
(int)cg.refdef.vieworg[0],
|
|
(int)cg.refdef.vieworg[1],
|
|
(int)cg.refdef.vieworg[2],
|
|
(int)cg.refdefViewAngles[YAW]
|
|
);
|
|
}
|
|
|
|
void CG_SetDesiredObjectiveAlpha(float fAlpha)
|
|
{
|
|
cg.ObjectivesDesiredAlpha = fAlpha;
|
|
cg.ObjectivesAlphaTime = (float)(cg.time + 250);
|
|
cg.ObjectivesBaseAlpha = cg.ObjectivesCurrentAlpha;
|
|
}
|
|
|
|
void CG_ScoresDown_f(void)
|
|
{
|
|
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
|
if (!cg.scoresRequestTime) {
|
|
cg.scoresRequestTime = cg.time;
|
|
CG_SetDesiredObjectiveAlpha(1.0f);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (cg.scoresRequestTime + 2000 >= cg.time) {
|
|
// send another request
|
|
cg.showScores = qtrue;
|
|
CG_PrepScoreBoardInfo();
|
|
cgi.UI_ShowScoreBoard(cg.scoresMenuName);
|
|
return;
|
|
}
|
|
|
|
cg.scoresRequestTime = cg.time;
|
|
cgi.SendClientCommand("score");
|
|
|
|
if (!cg.showScores) {
|
|
// don't display anything until first score returns
|
|
cg.showScores = qtrue;
|
|
CG_PrepScoreBoardInfo();
|
|
cgi.UI_ShowScoreBoard(cg.scoresMenuName);
|
|
}
|
|
}
|
|
|
|
void CG_ScoresUp_f(void)
|
|
{
|
|
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
|
if (cg.scoresRequestTime) {
|
|
cg.scoresRequestTime = 0;
|
|
CG_SetDesiredObjectiveAlpha(0.0f);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (!cg.showScores) {
|
|
return;
|
|
}
|
|
|
|
cg.showScores = qfalse;
|
|
cgi.UI_HideScoreBoard();
|
|
}
|
|
|
|
baseshader_t *CG_GetShaderUnderCrosshair(qboolean bVerbose, trace_t *pRetTrace)
|
|
{
|
|
vec3_t vPos, vEnd;
|
|
vec3_t axis[3];
|
|
baseshader_t *pShader;
|
|
trace_t trace;
|
|
|
|
AnglesToAxis(cg.refdefViewAngles, axis);
|
|
vPos[0] = cg.refdef.vieworg[0];
|
|
vPos[1] = cg.refdef.vieworg[1];
|
|
vPos[2] = cg.refdef.vieworg[2];
|
|
VectorMA(vPos, 4096.0, axis[0], vEnd);
|
|
|
|
CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_SHOT, 0, 0, "CG_GetShaderUnderCrosshair");
|
|
|
|
if (trace.startsolid || trace.fraction == 1.0) {
|
|
return NULL;
|
|
}
|
|
|
|
if (bVerbose) {
|
|
cgi.Printf("Surface hit at (%i %i %i)\n", (int)trace.endpos[0], (int)trace.endpos[1], (int)trace.endpos[2]);
|
|
}
|
|
|
|
pShader = cgi.GetShader(trace.shaderNum);
|
|
if (pRetTrace) {
|
|
*pRetTrace = trace;
|
|
}
|
|
|
|
return pShader;
|
|
}
|
|
|
|
static void CG_PrintContentTypes(int iContentFlags)
|
|
{
|
|
if (iContentFlags & CONTENTS_SOLID) {
|
|
cgi.Printf(" solid");
|
|
}
|
|
if (iContentFlags & CONTENTS_LAVA) {
|
|
cgi.Printf(" lava");
|
|
}
|
|
if (iContentFlags & CONTENTS_SLIME) {
|
|
cgi.Printf(" slime");
|
|
}
|
|
if (iContentFlags & CONTENTS_WATER) {
|
|
cgi.Printf(" water");
|
|
}
|
|
if (iContentFlags & CONTENTS_FOG) {
|
|
cgi.Printf(" fog");
|
|
}
|
|
if (iContentFlags & CONTENTS_FENCE) {
|
|
cgi.Printf(" fence");
|
|
}
|
|
if (iContentFlags & CONTENTS_AREAPORTAL) {
|
|
cgi.Printf(" areaportal");
|
|
}
|
|
if (iContentFlags & CONTENTS_PLAYERCLIP) {
|
|
cgi.Printf(" playerclip");
|
|
}
|
|
if (iContentFlags & CONTENTS_VEHICLECLIP) {
|
|
cgi.Printf(" vehicleclip");
|
|
}
|
|
if (iContentFlags & CONTENTS_MONSTERCLIP) {
|
|
cgi.Printf(" monsterclip");
|
|
}
|
|
if (iContentFlags & CONTENTS_WEAPONCLIP) {
|
|
cgi.Printf(" weaponclip");
|
|
}
|
|
if (iContentFlags & CONTENTS_SHOOTONLY) {
|
|
cgi.Printf(" shootableonly");
|
|
}
|
|
if (iContentFlags & CONTENTS_ORIGIN) {
|
|
cgi.Printf(" origin");
|
|
}
|
|
if (iContentFlags & CONTENTS_TRANSLUCENT) {
|
|
cgi.Printf(" trans");
|
|
}
|
|
}
|
|
|
|
static void CG_PrintSurfaceProperties(int iSurfaceFlags)
|
|
{
|
|
if (iSurfaceFlags & SURF_NODAMAGE) {
|
|
cgi.Printf(" nodamage");
|
|
}
|
|
if (iSurfaceFlags & SURF_SLICK) {
|
|
cgi.Printf(" slick");
|
|
}
|
|
if (iSurfaceFlags & SURF_SKY) {
|
|
cgi.Printf(" sky");
|
|
}
|
|
if (iSurfaceFlags & SURF_LADDER) {
|
|
cgi.Printf(" ladder");
|
|
}
|
|
if (iSurfaceFlags & SURF_NOIMPACT) {
|
|
cgi.Printf(" noimpact");
|
|
}
|
|
if (iSurfaceFlags & SURF_NOMARKS) {
|
|
cgi.Printf(" nomarks");
|
|
}
|
|
if (iSurfaceFlags & SURF_CASTSHADOW) {
|
|
cgi.Printf(" castshadow");
|
|
}
|
|
if (iSurfaceFlags & SURF_NODRAW) {
|
|
cgi.Printf(" nodraw");
|
|
}
|
|
if (iSurfaceFlags & SURF_NOLIGHTMAP) {
|
|
cgi.Printf(" nolightmap");
|
|
}
|
|
if (iSurfaceFlags & SURF_ALPHASHADOW) {
|
|
cgi.Printf(" alphashadow");
|
|
}
|
|
if (iSurfaceFlags & SURF_NOSTEPS) {
|
|
cgi.Printf(" nofootsteps");
|
|
}
|
|
if (iSurfaceFlags & SURF_NONSOLID) {
|
|
cgi.Printf(" nonsolid");
|
|
}
|
|
if (iSurfaceFlags & SURF_OVERBRIGHT) {
|
|
cgi.Printf(" overbright");
|
|
}
|
|
if (iSurfaceFlags & SURF_BACKSIDE) {
|
|
cgi.Printf(" backside");
|
|
}
|
|
if (iSurfaceFlags & SURF_NODLIGHT) {
|
|
cgi.Printf(" nodlight");
|
|
}
|
|
if (iSurfaceFlags & SURF_HINT) {
|
|
cgi.Printf(" hint");
|
|
}
|
|
if (iSurfaceFlags & SURF_PATCH) {
|
|
cgi.Printf(" patch");
|
|
}
|
|
}
|
|
|
|
static void CG_PrintSurfaceType(int iSurfType)
|
|
{
|
|
switch (iSurfType & MASK_SURF_TYPE) {
|
|
case SURF_FOLIAGE:
|
|
cgi.Printf("foliage");
|
|
break;
|
|
case SURF_SNOW:
|
|
cgi.Printf("snow");
|
|
break;
|
|
case SURF_CARPET:
|
|
cgi.Printf("carpet");
|
|
break;
|
|
case SURF_SAND:
|
|
cgi.Printf("sand");
|
|
break;
|
|
case SURF_PUDDLE:
|
|
cgi.Printf("puddle");
|
|
break;
|
|
case SURF_GLASS:
|
|
cgi.Printf("glass");
|
|
break;
|
|
case SURF_GRAVEL:
|
|
cgi.Printf("gravel");
|
|
break;
|
|
case SURF_MUD:
|
|
cgi.Printf("mud");
|
|
break;
|
|
case SURF_DIRT:
|
|
cgi.Printf("dirt");
|
|
break;
|
|
case SURF_GRILL:
|
|
cgi.Printf("metal grill");
|
|
break;
|
|
case SURF_GRASS:
|
|
cgi.Printf("grass");
|
|
break;
|
|
case SURF_ROCK:
|
|
cgi.Printf("rock");
|
|
break;
|
|
case SURF_PAPER:
|
|
cgi.Printf("paper");
|
|
break;
|
|
case SURF_WOOD:
|
|
cgi.Printf("wood");
|
|
break;
|
|
case SURF_METAL:
|
|
cgi.Printf("metal");
|
|
break;
|
|
default:
|
|
cgi.Printf("!!*none specified*!!");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CG_GetCHShader(void)
|
|
{
|
|
trace_t trace;
|
|
baseshader_t *pShader;
|
|
|
|
pShader = CG_GetShaderUnderCrosshair(qtrue, &trace);
|
|
cgi.Printf("\n");
|
|
if (pShader) {
|
|
if (pShader->surfaceFlags & SURF_SKY) {
|
|
cgi.Printf("Hit the sky\n");
|
|
} else {
|
|
cgi.Printf("Shader: %s\n", pShader->shader);
|
|
cgi.Printf("Shader Contents:");
|
|
CG_PrintContentTypes(pShader->contentFlags);
|
|
cgi.Printf("\n");
|
|
cgi.Printf("Shader Surface Properties:");
|
|
CG_PrintSurfaceProperties(pShader->surfaceFlags);
|
|
cgi.Printf("\n");
|
|
cgi.Printf("Shader Surfacetype: ");
|
|
CG_PrintSurfaceType(pShader->surfaceFlags);
|
|
cgi.Printf("\n");
|
|
cgi.Printf("Trace Contents:");
|
|
CG_PrintContentTypes(trace.contents);
|
|
cgi.Printf("\n");
|
|
cgi.Printf("Trace Surface Properties:");
|
|
CG_PrintSurfaceProperties(trace.surfaceFlags);
|
|
cgi.Printf("\n");
|
|
cgi.Printf("Trace Surfacetype: ");
|
|
CG_PrintSurfaceType(trace.surfaceFlags);
|
|
cgi.Printf("\n\n");
|
|
}
|
|
} else {
|
|
cgi.Printf("No surface selected\n");
|
|
}
|
|
}
|
|
|
|
void CG_EditCHShader(void)
|
|
{
|
|
char name[1024];
|
|
baseshader_t *pShader;
|
|
|
|
pShader = CG_GetShaderUnderCrosshair(qfalse, NULL);
|
|
if (pShader) {
|
|
Q_strncpyz(name, "editspecificshader ", sizeof(name));
|
|
Q_strcat(name, sizeof(name), pShader->shader);
|
|
Q_strcat(name, sizeof(name), "\n");
|
|
cgi.AddCommand(name);
|
|
} else {
|
|
cgi.Printf("No surface selected\n");
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
MODEL TESTING
|
|
|
|
The viewthing and gun positioning tools from Q2 have been integrated and
|
|
enhanced into a single model testing facility.
|
|
|
|
Model viewing can begin with either "testmodel <modelname>" or "testgun <modelname>".
|
|
|
|
The names must be the full pathname after the basedir, like
|
|
"models/weapons/v_launch/tris.md3" or "players/male/tris.md3"
|
|
|
|
Testmodel will create a fake entity 100 units in front of the current view
|
|
position, directly facing the viewer. It will remain immobile, so you can
|
|
move around it to view it from different angles.
|
|
|
|
Testgun will cause the model to follow the player around and supress the real
|
|
view weapon model. The default frame 0 of most guns is completely off screen,
|
|
so you will probably have to cycle a couple frames to see it.
|
|
|
|
"nextframe", "prevframe", "nextskin", and "prevskin" commands will change the
|
|
frame or skin of the testmodel. These are bound to F5, F6, F7, and F8 in
|
|
q3default.cfg.
|
|
|
|
Note that none of the model testing features update while the game is paused, so
|
|
it may be convenient to test with deathmatch set to 1 so that bringing down the
|
|
console doesn't pause the game.
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
CG_TestModel_f
|
|
|
|
Creates an entity in front of the current position, which
|
|
can then be moved around
|
|
=================
|
|
*/
|
|
void CG_TestModel_f (void) {
|
|
vec3_t angles;
|
|
|
|
memset( &cg.testModelEntity, 0, sizeof(cg.testModelEntity) );
|
|
if ( cgi.Argc() < 2 ) {
|
|
return;
|
|
}
|
|
|
|
Q_strncpyz (cg.testModelName, cgi.Argv( 1 ), MAX_QPATH );
|
|
cg.testModelEntity.hModel = cgi.R_RegisterModel( cg.testModelName );
|
|
|
|
if ( cgi.Argc() == 3 ) {
|
|
cg.testModelEntity.backlerp = atof( cgi.Argv( 2 ) );
|
|
cg.testModelEntity.frame = 1;
|
|
cg.testModelEntity.oldframe = 0;
|
|
}
|
|
if (! cg.testModelEntity.hModel ) {
|
|
cgi.Printf( "Can't register model\n" );
|
|
return;
|
|
}
|
|
|
|
VectorMA( cg.refdef.vieworg, 100, cg.refdef.viewaxis[0], cg.testModelEntity.origin );
|
|
|
|
angles[PITCH] = 0;
|
|
angles[YAW] = 180 + cg.refdefViewAngles[1];
|
|
angles[ROLL] = 0;
|
|
|
|
AnglesToAxis( angles, cg.testModelEntity.axis );
|
|
cg.testGun = qfalse;
|
|
}
|
|
|
|
void CG_TestModelNextFrame_f (void) {
|
|
cg.testModelEntity.frame++;
|
|
cgi.Printf( "frame %i\n", cg.testModelEntity.frame );
|
|
}
|
|
|
|
void CG_TestModelPrevFrame_f (void) {
|
|
cg.testModelEntity.frame--;
|
|
cgi.Printf( "frame %i\n", cg.testModelEntity.frame );
|
|
}
|
|
|
|
void CG_TestModelNextSkin_f (void) {
|
|
cg.testModelEntity.skinNum++;
|
|
cgi.Printf( "skin %i\n", cg.testModelEntity.skinNum );
|
|
}
|
|
|
|
void CG_TestModelPrevSkin_f (void) {
|
|
cg.testModelEntity.skinNum--;
|
|
if ( cg.testModelEntity.skinNum < 0 ) {
|
|
cg.testModelEntity.skinNum = 0;
|
|
}
|
|
cgi.Printf( "skin %i\n", cg.testModelEntity.skinNum );
|
|
}
|
|
|
|
void CG_AddTestModel (void) {
|
|
// re-register the model, because the level may have changed
|
|
cg.testModelEntity.hModel = cgi.R_RegisterModel( cg.testModelName );
|
|
if (! cg.testModelEntity.hModel ) {
|
|
cgi.Printf ("Can't register model\n");
|
|
return;
|
|
}
|
|
cgi.R_AddRefEntityToScene( &cg.testModelEntity );
|
|
}
|
|
|
|
#endif
|
|
|
|
typedef struct {
|
|
char *cmd;
|
|
void (*function)(void);
|
|
} consoleCommand_t;
|
|
|
|
static consoleCommand_t commands[] = {
|
|
{"useweaponclass", &CG_UseWeaponClass_f },
|
|
{"weapnext", &CG_NextWeapon_f },
|
|
{"weapprev", &CG_PrevWeapon_f },
|
|
{"uselast", &CG_UseLastWeapon_f },
|
|
{"holster", &CG_HolsterWeapon_f },
|
|
{"weapdrop", &CG_DropWeapon_f },
|
|
{"toggleitem", &CG_ToggleItem_f },
|
|
{"+scores", &CG_ScoresDown_f },
|
|
{"-scores", &CG_ScoresUp_f },
|
|
{"viewpos", &CG_Viewpos_f },
|
|
{"sizeup", &CG_SizeUp_f },
|
|
{"sizedown", &CG_SizeDown_f },
|
|
{"cg_eventlist", &CG_EventList_f },
|
|
{"cg_eventhelp", &CG_EventHelp_f },
|
|
{"cg_dumpevents", &CG_DumpEventHelp_f },
|
|
{"cg_pendingevents", &CG_PendingEvents_f },
|
|
{"cg_classlist", &CG_ClassList_f },
|
|
{"cg_classtree", &CG_ClassTree_f },
|
|
{"cg_classevents", &CG_ClassEvents_f },
|
|
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
|
|
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
|
|
{"testemitter", &CG_TestEmitter_f },
|
|
{"triggertestemitter", &CG_TriggerTestEmitter_f },
|
|
{"prevemittercommand", &CG_PrevEmitterCommand_f },
|
|
{"nextemittercommand", &CG_NextEmitterCommand_f },
|
|
{"newemittercommand", &CG_NewEmitterCommand_f },
|
|
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
|
|
{"dumpemitter", &CG_DumpEmitter_f },
|
|
{"loademitter", &CG_LoadEmitter_f },
|
|
{"resetvss", &CG_ResetVSSSources },
|
|
{"getchshader", &CG_GetCHShader },
|
|
{"editchshader", &CG_EditCHShader },
|
|
{"messagemode", &CG_MessageMode_f },
|
|
{"messagemode_all", &CG_MessageMode_All_f },
|
|
{"messagemode_team", &CG_MessageMode_Team_f },
|
|
{"messagemode_private", &CG_MessageMode_Private_f },
|
|
{"say", &CG_MessageSingleAll_f },
|
|
{"sayteam", &CG_MessageSingleTeam_f },
|
|
{"teamsay", &CG_MessageSingleTeam_f },
|
|
{"sayprivate", &CG_MessageSingleClient_f },
|
|
{"sayone", &CG_MessageSingleClient_f },
|
|
{"wisper", &CG_MessageSingleClient_f },
|
|
{"instamsg_main", &CG_InstaMessageMain_f },
|
|
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
|
|
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
|
|
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
|
|
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
|
|
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
|
|
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
|
|
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
|
|
// Added in 2.0
|
|
{"pushcallvote", &CG_PushCallVote_f },
|
|
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
|
|
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
|
|
{"pushcallvotesubinteger", &CG_PushCallVoteSubInteger_f},
|
|
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
|
|
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
|
|
{"pushvote", &CG_PushVote_f },
|
|
{"callentryvote", &CG_CallEntryVote_f },
|
|
};
|
|
|
|
/*
|
|
=================
|
|
CG_ConsoleCommand
|
|
|
|
The string has been tokenized and can be retrieved with
|
|
Cmd_Argc() / Cmd_Argv()
|
|
=================
|
|
*/
|
|
qboolean CG_ConsoleCommand(void)
|
|
{
|
|
const char *cmd;
|
|
int i;
|
|
|
|
cmd = cgi.Argv(0);
|
|
|
|
for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
|
if (!Q_stricmp(cmd, commands[i].cmd)) {
|
|
commands[i].function();
|
|
return qtrue;
|
|
}
|
|
}
|
|
|
|
return qfalse;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
CG_InitConsoleCommands
|
|
|
|
Let the client system know about all of our commands
|
|
so it can perform tab completion
|
|
=================
|
|
*/
|
|
void CG_InitConsoleCommands(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
|
cgi.AddCommand(commands[i].cmd);
|
|
}
|
|
|
|
cgi.AddCommand("callvote");
|
|
cgi.AddCommand("vote");
|
|
}
|
|
|
|
void CG_Mapinfo_f(void)
|
|
{
|
|
cgi.Printf("---------------------\n");
|
|
cgi.R_PrintBSPFileSizes();
|
|
cgi.CM_PrintBSPFileSizes();
|
|
cgi.Printf("---------------------\n");
|
|
}
|
|
|
|
void CG_PushMenuTeamSelect_f(void)
|
|
{
|
|
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
|
return;
|
|
}
|
|
|
|
cgi.Cmd_Execute(EXEC_NOW, "ui_getplayermodel\n");
|
|
switch (cgs.gametype) {
|
|
case GT_FFA:
|
|
cgi.Cmd_Execute(EXEC_NOW, "pushmenu SelectFFAModel\n");
|
|
break;
|
|
case GT_OBJECTIVE:
|
|
cgi.Cmd_Execute(EXEC_NOW, "pushmenu ObjSelectTeam\n");
|
|
break;
|
|
default:
|
|
cgi.Cmd_Execute(EXEC_NOW, "pushmenu SelectTeam\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CG_PushMenuWeaponSelect_f(void)
|
|
{
|
|
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
|
return;
|
|
}
|
|
|
|
cgi.Cmd_Execute(EXEC_NOW, "pushmenu SelectPrimaryWeapon\n");
|
|
}
|
|
|
|
void CG_UseWeaponClass_f(void)
|
|
{
|
|
const char *cmd;
|
|
|
|
cmd = cgi.Argv(1);
|
|
|
|
if (!Q_stricmp(cmd, "pistol")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_PISTOL;
|
|
} else if (!Q_stricmp(cmd, "rifle")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_RIFLE;
|
|
} else if (!Q_stricmp(cmd, "smg")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_SMG;
|
|
} else if (!Q_stricmp(cmd, "mg")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_MG;
|
|
} else if (!Q_stricmp(cmd, "grenade")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_GRENADE;
|
|
} else if (!Q_stricmp(cmd, "heavy")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_HEAVY;
|
|
} else if (!Q_stricmp(cmd, "item1") || !Q_stricmp(cmd, "item")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_ITEM1;
|
|
} else if (!Q_stricmp(cmd, "item2")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_ITEM2;
|
|
} else if (!Q_stricmp(cmd, "item3")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_ITEM3;
|
|
} else if (!Q_stricmp(cmd, "item4")) {
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_ITEM4;
|
|
}
|
|
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_NextWeapon_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_NEXT_WEAPON;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_PrevWeapon_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_PREV_WEAPON;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_UseLastWeapon_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_LAST_WEAPON;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_HolsterWeapon_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_HOLSTER;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_DropWeapon_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_DROP;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
void CG_ToggleItem_f(void)
|
|
{
|
|
cg.iWeaponCommand = WEAPON_COMMAND_USE_ITEM1;
|
|
cg.iWeaponCommandSend = 0;
|
|
}
|
|
|
|
int CG_WeaponCommandButtonBits(void)
|
|
{
|
|
int iShiftedWeaponCommand;
|
|
|
|
if (!cg.iWeaponCommand) {
|
|
return 0;
|
|
}
|
|
|
|
iShiftedWeaponCommand = cg.iWeaponCommand << 7;
|
|
|
|
cg.iWeaponCommandSend++;
|
|
if (cg.iWeaponCommandSend > 2) {
|
|
cg.iWeaponCommand = 0;
|
|
}
|
|
|
|
return iShiftedWeaponCommand & GetWeaponCommandMask(cg_protocol >= PROTOCOL_MOHTA_MIN ? WEAPON_COMMAND_MAX_VER17 : WEAPON_COMMAND_MAX_VER6);
|
|
}
|