|
|
@ -20,6 +20,7 @@ cvar_t mp_gravgun_players = { "mp_gravgun_players", "0", FCVAR_SERVER }; |
|
|
|
|
|
|
|
|
|
|
|
cvar_t mp_fixhornetbug = { "mp_fixhornetbug", "0", FCVAR_SERVER }; |
|
|
|
cvar_t mp_fixhornetbug = { "mp_fixhornetbug", "0", FCVAR_SERVER }; |
|
|
|
cvar_t mp_checkentities = { "mp_checkentities", "0", FCVAR_SERVER }; |
|
|
|
cvar_t mp_checkentities = { "mp_checkentities", "0", FCVAR_SERVER }; |
|
|
|
|
|
|
|
cvar_t mp_touchmenu = { "mp_touchmenu", "1", FCVAR_SERVER }; |
|
|
|
|
|
|
|
|
|
|
|
void Ent_RunGC_f( void ); |
|
|
|
void Ent_RunGC_f( void ); |
|
|
|
|
|
|
|
|
|
|
@ -38,6 +39,7 @@ void GGM_RegisterCVars( void ) |
|
|
|
CVAR_REGISTER( &mp_gravgun_players ); |
|
|
|
CVAR_REGISTER( &mp_gravgun_players ); |
|
|
|
CVAR_REGISTER( &mp_fixhornetbug ); |
|
|
|
CVAR_REGISTER( &mp_fixhornetbug ); |
|
|
|
CVAR_REGISTER( &mp_checkentities ); |
|
|
|
CVAR_REGISTER( &mp_checkentities ); |
|
|
|
|
|
|
|
CVAR_REGISTER( &mp_touchmenu ); |
|
|
|
g_engfuncs.pfnAddServerCommand( "ent_rungc", Ent_RunGC_f ); |
|
|
|
g_engfuncs.pfnAddServerCommand( "ent_rungc", Ent_RunGC_f ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -174,7 +176,7 @@ int Ent_CheckEntitySpawn( edict_t *pent ) |
|
|
|
|
|
|
|
|
|
|
|
void GGM_ClientPutinServer(edict_t *pEntity, CBasePlayer *pPlayer) |
|
|
|
void GGM_ClientPutinServer(edict_t *pEntity, CBasePlayer *pPlayer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( mp_coop.value && pPlayer->gravgunmod_data.m_state == STATE_UNINITIALIZED ) |
|
|
|
if( mp_touchmenu.value && pPlayer->gravgunmod_data.m_state == STATE_UNINITIALIZED ) |
|
|
|
g_engfuncs.pfnQueryClientCvarValue2( pEntity, "touch_enable", 111 ); |
|
|
|
g_engfuncs.pfnQueryClientCvarValue2( pEntity, "touch_enable", 111 ); |
|
|
|
|
|
|
|
|
|
|
|
pPlayer->gravgunmod_data.m_state = STATE_CONNECTED; |
|
|
|
pPlayer->gravgunmod_data.m_state = STATE_CONNECTED; |
|
|
@ -187,6 +189,8 @@ void GGM_ClientPutinServer(edict_t *pEntity, CBasePlayer *pPlayer) |
|
|
|
pPlayer->gravgunmod_data.uid[32] = 0; |
|
|
|
pPlayer->gravgunmod_data.uid[32] = 0; |
|
|
|
pPlayer->gravgunmod_data.m_flEntTime = 0; |
|
|
|
pPlayer->gravgunmod_data.m_flEntTime = 0; |
|
|
|
pPlayer->gravgunmod_data.m_flEntScope = 0; |
|
|
|
pPlayer->gravgunmod_data.m_flEntScope = 0; |
|
|
|
|
|
|
|
pPlayer->gravgunmod_data.menu.pPlayer = pPlayer; |
|
|
|
|
|
|
|
pPlayer->gravgunmod_data.menu.Clear(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void GGM_ClientFirstSpawn(CBasePlayer *pPlayer) |
|
|
|
void GGM_ClientFirstSpawn(CBasePlayer *pPlayer) |
|
|
@ -227,3 +231,275 @@ const char *GGM_GetPlayerID( edict_t *player ) |
|
|
|
|
|
|
|
|
|
|
|
return plr->gravgunmod_data.uid; |
|
|
|
return plr->gravgunmod_data.uid; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
=============================== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CMD_ARGV replacement |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We do not have access to engine's COM_TokenizeString, |
|
|
|
|
|
|
|
so perform all parsing here, allowing to change CMD_ARGV result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=============================== |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool cmd_used; |
|
|
|
|
|
|
|
// CMD_ARGS replacement
|
|
|
|
|
|
|
|
namespace GGM |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static int cmd_argc; |
|
|
|
|
|
|
|
static char *cmd_args; |
|
|
|
|
|
|
|
static char *cmd_argv[80]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *COM_ParseFile( char *data, char *token ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int c, len; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !token ) |
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
len = 0; |
|
|
|
|
|
|
|
token[0] = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !data ) |
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
// skip whitespace
|
|
|
|
|
|
|
|
skipwhite: |
|
|
|
|
|
|
|
while(( c = ((byte)*data)) <= ' ' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( c == 0 ) |
|
|
|
|
|
|
|
return NULL; // end of file;
|
|
|
|
|
|
|
|
data++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// skip // comments
|
|
|
|
|
|
|
|
if( c=='/' && data[1] == '/' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
while( *data && *data != '\n' ) |
|
|
|
|
|
|
|
data++; |
|
|
|
|
|
|
|
goto skipwhite; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// handle quoted strings specially
|
|
|
|
|
|
|
|
if( c == '\"' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
data++; |
|
|
|
|
|
|
|
while( 1 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
c = (byte)*data; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// unexpected line end
|
|
|
|
|
|
|
|
if( !c ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
token[len] = 0; |
|
|
|
|
|
|
|
return data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
data++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( c == '\\' && *data == '"' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
token[len++] = *data++; |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( c == '\"' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
token[len] = 0; |
|
|
|
|
|
|
|
return data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
token[len] = c; |
|
|
|
|
|
|
|
len++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// parse single characters
|
|
|
|
|
|
|
|
if( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ',' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
token[len] = c; |
|
|
|
|
|
|
|
len++; |
|
|
|
|
|
|
|
token[len] = 0; |
|
|
|
|
|
|
|
return data + 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// parse a regular word
|
|
|
|
|
|
|
|
do |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
token[len] = c; |
|
|
|
|
|
|
|
data++; |
|
|
|
|
|
|
|
len++; |
|
|
|
|
|
|
|
c = ((byte)*data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ',' ) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} while( c > 32 ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
token[len] = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void Cmd_TokenizeString( const char *text ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char cmd_token[256]; |
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// clear the args from the last string
|
|
|
|
|
|
|
|
for( i = 0; i < cmd_argc; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
delete [] cmd_argv[i]; |
|
|
|
|
|
|
|
cmd_argv[i] = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd_argc = 0; // clear previous args
|
|
|
|
|
|
|
|
cmd_args = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd_used = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !text ) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while( 1 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// skip whitespace up to a /n
|
|
|
|
|
|
|
|
while( *text && ((byte)*text) <= ' ' && *text != '\r' && *text != '\n' ) |
|
|
|
|
|
|
|
text++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( *text == '\n' || *text == '\r' ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// a newline seperates commands in the buffer
|
|
|
|
|
|
|
|
if( *text == '\r' && text[1] == '\n' ) |
|
|
|
|
|
|
|
text++; |
|
|
|
|
|
|
|
text++; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !*text ) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( cmd_argc == 1 ) |
|
|
|
|
|
|
|
cmd_args = (char*)text; |
|
|
|
|
|
|
|
text = COM_ParseFile( (char*)text, cmd_token ); |
|
|
|
|
|
|
|
if( !text ) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( cmd_argc < 80 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
cmd_argv[cmd_argc] = new char[strlen(cmd_token)+1]; |
|
|
|
|
|
|
|
strcpy(cmd_argv[cmd_argc], cmd_token); |
|
|
|
|
|
|
|
cmd_argc++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void Cmd_Reset( void ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
cmd_used = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int CMD_ARGC() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( cmd_used ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return GGM::cmd_argc; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return g_engfuncs.pfnCmd_Argc(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" const char *CMD_ARGS() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( cmd_used ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(!GGM::cmd_args) |
|
|
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
return GGM::cmd_args; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return g_engfuncs.pfnCmd_Args(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
extern "C" const char *CMD_ARGV( int i ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( cmd_used ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( i < 0 || i >= GGM::cmd_argc|| !GGM::cmd_argv[i] ) |
|
|
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
return GGM::cmd_argv[i]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return g_engfuncs.pfnCmd_Argv( i ); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GGM_PlayerMenu &GGM_PlayerMenu::Add(const char *name, const char *command) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( m_iCount > 4 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
ALERT( at_error, "GGM_PlayerMenu::Add: Only 5 menu items supported" ); |
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
strncpy( m_items[m_iCount].name, name, sizeof(m_items[m_iCount].name) - 1 ); |
|
|
|
|
|
|
|
strncpy( m_items[m_iCount].command, command, sizeof(m_items[m_iCount].command) - 1 ); |
|
|
|
|
|
|
|
m_iCount++; |
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
GGM_PlayerMenu &GGM_PlayerMenu::Clear() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_iCount = 0; |
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GGM_PlayerMenu &GGM_PlayerMenu::SetTitle(const char *title) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
strncpy( m_sTitle, title, sizeof(m_sTitle) - 1); |
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
GGM_PlayerMenu &GGM_PlayerMenu::New(const char *title) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
SetTitle(title); |
|
|
|
|
|
|
|
return Clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
extern int gmsgShowMenu; |
|
|
|
|
|
|
|
void GGM_PlayerMenu::Show() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( pPlayer->gravgunmod_data.m_fTouchMenu) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
#define MENU_STR(VAR) (#VAR) |
|
|
|
|
|
|
|
sprintf( buf, MENU_STR(slot10\ntouch_hide _coops*\ntouch_show _coops\ntouch_addbutton "_coopst" "#%s" "" 0.16 0.11 0.41 0.3 0 255 0 255 78 1.5\n), m_sTitle); |
|
|
|
|
|
|
|
CLIENT_COMMAND( pPlayer->edict(), buf); |
|
|
|
|
|
|
|
for( int i = 0; i < m_iCount; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sprintf( buf, MENU_STR(touch_settexture _coops%d "#%d. %s"\ntouch_show _coops%d\n), i+1, i+1, m_items[i].name, i + 1 ); |
|
|
|
|
|
|
|
CLIENT_COMMAND( pPlayer->edict(), buf); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char buf[128], *pbuf = buf; |
|
|
|
|
|
|
|
short int flags = 1<<9; |
|
|
|
|
|
|
|
pbuf += sprintf( pbuf, "^2%s:\n", m_sTitle ); |
|
|
|
|
|
|
|
for( int i = 0; i < m_iCount; i++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
pbuf += sprintf( pbuf, "^3%d.^7 %s\n", i+1, m_items[i].name); |
|
|
|
|
|
|
|
flags |= 1<<i; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pPlayer->pev); |
|
|
|
|
|
|
|
WRITE_SHORT( flags ); // slots
|
|
|
|
|
|
|
|
WRITE_CHAR( 255 ); // show time
|
|
|
|
|
|
|
|
WRITE_BYTE( 0 ); // need more
|
|
|
|
|
|
|
|
WRITE_STRING( buf ); |
|
|
|
|
|
|
|
MESSAGE_END(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// client.cpp
|
|
|
|
|
|
|
|
void ClientCommand( edict_t *pEntity ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool GGM_PlayerMenu::MenuSelect( int select ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( select > m_iCount || select < 1 ) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GGM::Cmd_TokenizeString( m_items[select-1].command ); |
|
|
|
|
|
|
|
ClientCommand( pPlayer->edict() ); |
|
|
|
|
|
|
|
GGM::Cmd_Reset(); |
|
|
|
|
|
|
|
} |
|
|
|