Port entity tools from engine, begin refactoring gravgunmod stuff

This commit is contained in:
mittorn 2017-11-11 16:17:49 +00:00
parent 4a7e928520
commit ab29b25db0
11 changed files with 916 additions and 80 deletions

View File

@ -52,6 +52,7 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
effects.cpp \
egon.cpp \
explode.cpp \
enttools.cpp \
flyingmonster.cpp \
func_break.cpp \
func_tank.cpp \
@ -134,7 +135,8 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
../pm_shared/pm_math.c \
../pm_shared/pm_shared.c \
coop.cpp \
gateofbabylon.cpp
gateofbabylon.cpp \
gravgunmod.cpp \
# ../game_shared/voice_gamemgr.cpp
LOCAL_LDLIBS := -llog

View File

@ -563,7 +563,7 @@ void ClientCommand( edict_t *pEntity )
MENU_STR(touch_addbutton "_coops5" "#" "menuselect 5;touch_hide _coops*" 0.16 0.61 0.39 0.7 255 255 255 255 335 1.5;wait;slot10\n)
);
}
else
else if( !Ent_ProcessClientCommand( pEntity ) )
{
// tell the user they entered an unknown command
char command[128];
@ -595,7 +595,7 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer )
return;
// msg everyone if someone changes their name, and it isn't the first time (changing no name to current name)
if ( pEntity->v.netname && STRING(pEntity->v.netname)[0] != 0 && !FStrEq( STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" )) )
if ( pEntity->v.netname && (STRING(pEntity->v.netname))[0] != 0 && !FStrEq( STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" )) )
{
char sName[256];
char *pName = g_engfuncs.pfnInfoKeyValue( infobuffer, "name" );

View File

@ -2,7 +2,8 @@
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "coop_util.h""
#include "coop_util.h"
#include "gravgunmod.h"
GlobalMenu g_GlobalMenu;
@ -11,6 +12,24 @@ struct SavedCoords g_SavedCoords, s_SavedCoords;
static float msglimittime1, msglimittime2;
cvar_t mp_coop = { "mp_coop", "0", FCVAR_SERVER };
cvar_t mp_coop_changelevel = { "mp_coop_changelevel", "0", FCVAR_SERVER };
cvar_t mp_coop_nofriendlyfire = { "mp_coop_nofriendlyfire", "0", FCVAR_SERVER };
cvar_t mp_coop_disabledmap = { "mp_coop_disabledmap", "", FCVAR_SERVER };
cvar_t mp_coop_reconnect_hack = { "mp_coop_reconnect_hack", "0", FCVAR_SERVER };
cvar_t mp_coop_noangry = { "mp_coop_noangry", "0", FCVAR_SERVER };
cvar_t mp_coop_checkpoints = { "mp_coop_checkpoints", "1", FCVAR_SERVER };
cvar_t mp_skipdefaults = { "mp_skipdefaults", "0", FCVAR_SERVER };
cvar_t mp_coop_strongcheckpoints = { "mp_coop_strongcheckpoints", "0", FCVAR_SERVER };
cvar_t mp_unduck = { "mp_unduck", "0", FCVAR_SERVER };
cvar_t mp_semclip = { "mp_semclip", "0", FCVAR_SERVER };
cvar_t mp_spectator = { "mp_spectator", "0", FCVAR_SERVER };
cvar_t materials_txt = { "materials_txt", "sound/materials.txt", FCVAR_SERVER };
cvar_t sentences_txt = { "sentences_txt", "sound/sentences.txt", FCVAR_SERVER };
void UTIL_CoopPlayerMessage( CBaseEntity *pPlayer, int channel, float time, unsigned int color1, unsigned int color2, float x, float y, const char *format, ... )
{
@ -858,6 +877,8 @@ int UTIL_CheckForEntTools( edict_t *pent )
return 0;
}
int UTIL_CoopCheckSpawn( edict_t *pent )
{
if( mp_checkentities.value )
@ -908,3 +929,22 @@ int UTIL_CoopCheckSpawn( edict_t *pent )
}
return 0;
}
void COOP_RegisterCVars()
{
CVAR_REGISTER( &mp_coop );
CVAR_REGISTER( &mp_coop_changelevel );
CVAR_REGISTER( &mp_coop_nofriendlyfire );
CVAR_REGISTER( &mp_coop_disabledmap );
CVAR_REGISTER( &mp_unduck );
CVAR_REGISTER( &mp_semclip );
CVAR_REGISTER( &mp_coop_reconnect_hack );
CVAR_REGISTER( &mp_coop_noangry );
CVAR_REGISTER( &mp_spectator );
CVAR_REGISTER( &mp_coop_checkpoints );
CVAR_REGISTER( &mp_skipdefaults );
CVAR_REGISTER( &mp_coop_strongcheckpoints );
CVAR_REGISTER( &sentences_txt );
CVAR_REGISTER( &materials_txt );
}

View File

@ -1,17 +1,5 @@
#ifndef COOP_UTIL_H
#define COOP_UTIL_H
extern cvar_t cvar_allow_gravgun;
extern cvar_t cvar_allow_ar2;
extern cvar_t cvar_ar2_mp5;
extern cvar_t cvar_ar2_bullets;
extern cvar_t cvar_ar2_balls;
extern cvar_t cvar_wresptime;
extern cvar_t cvar_iresptime;
extern cvar_t cvar_gibtime;
extern cvar_t cvar_hgibcount;
extern cvar_t cvar_agibcount;
extern cvar_t mp_gravgun_players;
extern cvar_t mp_coop;
extern cvar_t mp_coop_changelevel;
@ -26,9 +14,6 @@ extern cvar_t mp_unduck;
extern cvar_t mp_semclip;
extern cvar_t mp_coop_reconnect_hack;
extern cvar_t mp_coop_noangry;
extern cvar_t mp_spectator;
extern cvar_t mp_fixhornetbug;
extern cvar_t mp_checkentities;
extern cvar_t sentences_txt;
@ -77,6 +62,7 @@ void UTIL_CoopPrintMessage( const char *format, ... );
void UTIL_CoopHudMessage( int channel, float time, unsigned int color1, unsigned int color2, float x, float y, const char *format, ... );
void UTIL_CoopPlayerMessage( CBaseEntity *pPlayer, int channel, float time, unsigned int color1, unsigned int color2, float x, float y, const char *format, ... );
void COOP_RegisterCVars( void );
#ifdef PLAYER_H
void UTIL_CoopKickPlayer(CBaseEntity *pPlayer);

792
dlls/enttools.cpp Normal file
View File

@ -0,0 +1,792 @@
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "game.h"
#define Ent_IsValidEdict( e ) ( e && !e->free )
bool Q_isdigit( const char *str )
{
if( str && *str )
{
while( isdigit( *str )) str++;
if( !*str ) return true;
}
return false;
}
bool Q_stricmpext( const char *pattern, const char *text );
static bool Q_starcmp( const char *pattern, const char *text )
{
char c, c1;
const char *p = pattern, *t = text;
while(( c = *p++ ) == '?' || c == '*' )
{
if( c == '?' && *t++ == '\0' )
return false;
}
if( c == '\0' ) return true;
for( c1 = (( c == '\\' ) ? *p : c ); ; )
{
if( tolower( *t ) == c1 && Q_stricmpext( p - 1, t ))
return true;
if( *t++ == '\0' ) return false;
}
}
bool Q_stricmpext( const char *pattern, const char *text )
{
char c;
while(( c = *pattern++ ) != '\0' )
{
switch( c )
{
case '?':
if( *text++ == '\0' )
return false;
break;
case '\\':
if( tolower( *pattern++ ) != tolower( *text++ ))
return false;
break;
case '*':
return Q_starcmp( pattern, text );
default:
if( tolower( c ) != tolower( *text++ ))
return false;
}
}
return true;
}
void Ent_ClientPrintf( edict_t *player, const char *format, ... )
{
va_list argptr;
char string[256];
va_start( argptr, format );
int len = vsnprintf( string, 256, format, argptr );
va_end( argptr );
string[len] = 0;
MESSAGE_BEGIN( MSG_ONE, 8, g_vecZero, player ); // svc_print
WRITE_BYTE( 0 ); // PRINT_LOW
WRITE_STRING( string );
MESSAGE_END();
}
static edict_t *Ent_GetCrossEnt( edict_t *player )
{
edict_t *ent = g_engfuncs.pfnPEntityOfEntIndex(1);
edict_t *closest = NULL;
float flMaxDot = 0.94;
Vector forward;
int i;
float maxLen = 1000;
UTIL_MakeVectorsPrivate( player->v.v_angle, forward, NULL, NULL );
Vector viewPos = player->v.origin + player->v.view_ofs;
// find bmodels by trace
{
TraceResult tr;
UTIL_TraceLine(viewPos, viewPos + forward * 1000, missile, player, &tr);
closest = tr.pHit;
maxLen = (viewPos - tr.vecEndPos).Length() + 30;
}
// check untraceable entities
for ( i = 1; i < gpGlobals->maxEntities; i++, ent++ )
{
Vector vecLOS;
Vector vecOrigin;
float flDot, traceLen;
if( ent->free )
continue;
if( ent->v.solid == SOLID_BSP || ent->v.movetype == MOVETYPE_PUSHSTEP )
continue; //bsp models will be found by trace later
// do not touch following weapons
if( ent->v.movetype == MOVETYPE_FOLLOW )
continue;
if( ent == player )
continue;
vecOrigin = VecBModelOrigin(&ent->v);
vecLOS = vecOrigin - viewPos;
traceLen = vecLOS.Length();
if( traceLen > maxLen )
continue;
vecLOS = UTIL_ClampVectorToBox(vecLOS, ent->v.size * 0.5);
flDot = DotProduct(vecLOS , forward);
if ( flDot <= flMaxDot )
continue;
TraceResult tr;
UTIL_TraceLine(viewPos, vecOrigin, missile, player, &tr);
if( (tr.vecEndPos - viewPos).Length() + 30 < traceLen )
continue;
closest = ent, flMaxDot = flDot;
}
return closest;
}
/*
===============
Ent_List_f
Print list of entities to client
===============
*/
void Ent_List_f( edict_t *player )
{
edict_t *ent = NULL;
int i;
for( i = 0; i < gpGlobals->maxEntities; i++ )
{
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( !Ent_IsValidEdict( ent )) continue;
// filter by string
if( CMD_ARGC() > 1 )
if( !Q_stricmpext( CMD_ARGV( 1 ), STRING( ent->v.classname ) ) && !Q_stricmpext( CMD_ARGV( 1 ), STRING( ent->v.targetname ) ) )
continue;
Vector borigin = VecBModelOrigin( &ent->v );
Ent_ClientPrintf( player, "%5i origin: %.f %.f %.f", i, ent->v.origin[0], ent->v.origin[1], ent->v.origin[2] );
Ent_ClientPrintf( player, "%5i borigin: %.f %.f %.f", i, borigin[0], borigin[1], borigin[2] );
if( ent->v.classname )
Ent_ClientPrintf( player, ", class: %s", STRING( ent->v.classname ));
if( ent->v.globalname )
Ent_ClientPrintf( player, ", global: %s", STRING( ent->v.globalname ));
if( ent->v.targetname )
Ent_ClientPrintf( player, ", name: %s", STRING( ent->v.targetname ));
if( ent->v.target )
Ent_ClientPrintf( player, ", target: %s", STRING( ent->v.target ));
if( ent->v.model )
Ent_ClientPrintf( player, ", model: %s", STRING( ent->v.model ));
Ent_ClientPrintf( player, "\n" );
}
}
edict_t *Ent_FindSingle( edict_t *player, const char *pattern )
{
edict_t *ent = NULL;
int i = 0;
if( Q_isdigit( pattern ) )
{
i = atoi( pattern );
if( i >= gpGlobals->maxEntities )
return NULL;
}
else if( !stricmp( pattern, "!cross" ) )
{
ent = Ent_GetCrossEnt( player );
if( !Ent_IsValidEdict( ent ) )
return NULL;
i = ENTINDEX( ent );
}
else if( pattern[0] == '!' ) // Check for correct instanse with !(num)_(serial)
{
const char *p = pattern + 1;
i = atoi( p );
while( isdigit(*p) ) p++;
if( *p++ != '_' )
return NULL;
if( i >= gpGlobals->maxEntities )
return NULL;
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( ent->serialnumber != atoi( p ) )
return NULL;
}
else
{
for( i = gpGlobals->maxClients + 1; i < gpGlobals->maxEntities; i++ )
{
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( !Ent_IsValidEdict( ent ) )
continue;
if( Q_stricmpext( pattern, STRING( ent->v.targetname ) ) )
break;
}
}
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( !Ent_IsValidEdict( ent ) )
return NULL;
return ent;
}
/*
===============
Ent_Info_f
Print specified entity information to client
===============
*/
void Ent_Info_f( edict_t *player )
{
edict_t *ent = NULL;
if( CMD_ARGC() != 2 )
{
Ent_ClientPrintf( player, "Use ent_info <index|name|inst>\n" );
return;
}
ent = Ent_FindSingle( player, CMD_ARGV( 1 ) );
if( !Ent_IsValidEdict( ent )) return;
Vector borigin = VecBModelOrigin( &ent->v );
Ent_ClientPrintf( player, "origin: %.f %.f %.f\n", ent->v.origin[0], ent->v.origin[1], ent->v.origin[2] );
Ent_ClientPrintf( player, "angles: %.f %.f %.f\n", ent->v.angles[0], ent->v.angles[1], ent->v.angles[2] );
Ent_ClientPrintf( player, "borigin: %.f %.f %.f\n", borigin[0], borigin[1], borigin[2] );
if( ent->v.classname )
Ent_ClientPrintf( player, "class: %s\n", STRING( ent->v.classname ));
if( ent->v.globalname )
Ent_ClientPrintf( player, "global: %s\n", STRING( ent->v.globalname ));
if( ent->v.targetname )
Ent_ClientPrintf( player, "name: %s\n", STRING( ent->v.targetname ));
if( ent->v.target )
Ent_ClientPrintf( player, "target: %s\n", STRING( ent->v.target ));
if( ent->v.model )
Ent_ClientPrintf( player, "model: %s\n", STRING( ent->v.model ));
Ent_ClientPrintf( player, "health: %.f\n", ent->v.health );
if( ent->v.gravity != 1.0f )
Ent_ClientPrintf( player, "gravity: %.2f\n", ent->v.gravity );
Ent_ClientPrintf( player, "movetype: %d\n", ent->v.movetype );
Ent_ClientPrintf( player, "rendermode: %d\n", ent->v.rendermode );
Ent_ClientPrintf( player, "renderfx: %d\n", ent->v.renderfx );
Ent_ClientPrintf( player, "renderamt: %f\n", ent->v.renderamt );
Ent_ClientPrintf( player, "rendercolor: %f %f %f\n", ent->v.rendercolor[0], ent->v.rendercolor[1], ent->v.rendercolor[2] );
Ent_ClientPrintf( player, "maxspeed: %f\n", ent->v.maxspeed );
if( ent->v.solid )
Ent_ClientPrintf( player, "solid: %d\n", ent->v.solid );
Ent_ClientPrintf( player, "flags: 0x%x\n", ent->v.flags );
Ent_ClientPrintf( player, "spawnflags: 0x%x\n", ent->v.spawnflags );
}
void Ent_SendVars( edict_t *player, edict_t *ent )
{
if( !ent )
return;
CLIENT_COMMAND( player, UTIL_VarArgs( "set ent_last_name \"%s\"\n", STRING( ent->v.targetname ) ));
CLIENT_COMMAND( player, UTIL_VarArgs( "set ent_last_num %i\n", ENTINDEX( ent ) ));
CLIENT_COMMAND( player, UTIL_VarArgs( "set ent_last_inst !%i_%i\n", ENTINDEX( ent ), ent->serialnumber ));
CLIENT_COMMAND( player, UTIL_VarArgs( "set ent_last_origin \"%f %f %f\"\n", ent->v.origin[0], ent->v.origin[1], ent->v.origin[2]));
CLIENT_COMMAND( player, UTIL_VarArgs( "set ent_last_class \"%s\"\n", STRING( ent->v.classname )));
CLIENT_COMMAND( player, "ent_getvars_cb\n" );
}
void Ent_GetVars_f( edict_t *player )
{
edict_t *ent = NULL;
if( CMD_ARGC() != 2 )
{
Ent_ClientPrintf( player, "Use ent_getvars <index|name|inst>\n" );
return;
}
ent = Ent_FindSingle( player, CMD_ARGV( 1 ) );
if( CMD_ARGC() )
if( !Ent_IsValidEdict( ent )) return;
Ent_SendVars( player, ent );
}
/*
===============
Ent_Fire_f
Perform some actions
===============
*/
void Ent_Fire_f( edict_t *player )
{
edict_t *ent = NULL;
int i = 1, count = 0;
qboolean single; // true if user specified something that match single entity
if( CMD_ARGC() < 3 )
{
Ent_ClientPrintf( player, "Use ent_fire <index||pattern> <command> [<values>]\n"
"Use ent_fire 0 help to get command list\n" );
return;
}
if( ( single = Q_isdigit( CMD_ARGV( 1 ) ) ) )
{
i = atoi( CMD_ARGV( 1 ) );
if( i < 0 || i >= gpGlobals->maxEntities )
return;
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
}
else if( ( single = !stricmp( CMD_ARGV( 1 ), "!cross" ) ) )
{
ent = Ent_GetCrossEnt( player );
if( !Ent_IsValidEdict( ent ) )
return;
i = ENTINDEX( ent );
}
else if( ( single = ( CMD_ARGV( 1 )[0] == '!') ) ) // Check for correct instanse with !(num)_(serial)
{
const char *cmd = CMD_ARGV( 1 ) + 1;
i = atoi( cmd );
while( isdigit( *cmd ) ) cmd++;
if( *cmd++ != '_' )
return;
if( i < 0 || i >= gpGlobals->maxEntities )
return;
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( ent->serialnumber != atoi( cmd ) )
return;
}
else
{
i = gpGlobals->maxClients + 1;
}
for( ; ( i < gpGlobals->maxEntities ) && ( count < mp_enttools_maxfire.value ); i++ )
{
ent = g_engfuncs.pfnPEntityOfEntIndex( i );
if( !Ent_IsValidEdict( ent ))
{
// Ent_ClientPrintf( player, "Got invalid entity\n" );
if( single )
break;
continue;
}
// if user specified not a number, try find such entity
if( !single )
{
if( !Q_stricmpext( CMD_ARGV( 1 ), STRING( ent->v.targetname ) ) && !Q_stricmpext( CMD_ARGV( 1 ), STRING( ent->v.classname ) ))
continue;
}
Ent_ClientPrintf( player, "entity %i\n", i );
count++;
if( !stricmp( CMD_ARGV( 2 ), "health" ) )
ent->v.health = atoi( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "gravity" ) )
ent->v.gravity = atof( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "movetype" ) )
ent->v.movetype = atoi( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "solid" ) )
ent->v.solid = atoi( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "rename" ) )
ent->v.targetname = ALLOC_STRING( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "settarget" ) )
ent->v.target = ALLOC_STRING( CMD_ARGV ( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "setmodel" ) )
SET_MODEL( ent, CMD_ARGV( 3 ) );
else if( !stricmp( CMD_ARGV( 2 ), "set" ) )
{
char keyname[256];
char value[256];
KeyValueData pkvd;
if( CMD_ARGC() != 5 )
return;
pkvd.szClassName = (char*)STRING( ent->v.classname );
strncpy( keyname, CMD_ARGV( 3 ), 256 );
strncpy( value, CMD_ARGV( 4 ), 256 );
keyname[255] = value[255] = 0;
pkvd.szKeyName = keyname;
pkvd.szValue = value;
pkvd.fHandled = false;
DispatchKeyValue( ent, &pkvd );
if( pkvd.fHandled )
Ent_ClientPrintf( player, "value set successfully!\n" );
}
else if( !stricmp( CMD_ARGV( 2 ), "touch" ) )
{
if( CMD_ARGC() == 4 )
{
edict_t *other = Ent_FindSingle( player, CMD_ARGV( 3 ) );
if( other && other->pvPrivateData )
DispatchTouch( ent, other );
}
else
DispatchTouch( ent, player );
}
else if( !stricmp( CMD_ARGV( 2 ), "use" ) )
{
if( CMD_ARGC() == 4 )
{
edict_t *other = Ent_FindSingle( player, CMD_ARGV( 3 ) );
if( other && other->pvPrivateData )
DispatchUse( ent, other );
}
else
DispatchUse( ent, player );
}
else if( !stricmp( CMD_ARGV( 2 ), "movehere" ) )
UTIL_SetOrigin( &ent->v, player->v.origin + Vector( 100 * cos( player->v.angles[1]/180*M_PI ), 100 * sin( player->v.angles[1]/180*M_PI), 25 ) );
else if( !stricmp( CMD_ARGV( 2 ), "drop2floor" ) )
DROP_TO_FLOOR( ent );
else if( !stricmp( CMD_ARGV( 2 ), "moveup" ) )
{
float dist = 25;
if( CMD_ARGC() >= 4 )
dist = atof( CMD_ARGV( 3 ) );
ent->v.origin[2] += dist;
if( CMD_ARGC() >= 5 )
ent->v.origin = ent->v.origin + Vector( cos( player->v.angles[1]/180*M_PI ), sin( player->v.angles[1]/180*M_PI), 0 ) * atof( CMD_ARGV( 4 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "becomeowner" ) )
{
if( CMD_ARGC() == 4 )
ent->v.owner = Ent_FindSingle( player, CMD_ARGV( 3 ) );
else
ent->v.owner = player;
}
else if( !stricmp( CMD_ARGV( 2 ), "becomeenemy" ) )
{
if( CMD_ARGC() == 4 )
ent->v.enemy = Ent_FindSingle( player, CMD_ARGV( 3 ) );
else
ent->v.enemy = player;
}
else if( !stricmp( CMD_ARGV( 2 ), "becomeaiment" ) )
{
if( CMD_ARGC() == 4 )
ent->v.aiment= Ent_FindSingle( player, CMD_ARGV( 3 ) );
else
ent->v.aiment = player;
}
else if( !stricmp( CMD_ARGV( 2 ), "hullmin" ) )
{
if( CMD_ARGC() != 6 )
return;
ent->v.mins[0] = atof( CMD_ARGV( 3 ) );
ent->v.mins[1] = atof( CMD_ARGV( 4 ) );
ent->v.mins[2] = atof( CMD_ARGV( 5 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "hullmax" ) )
{
if( CMD_ARGC() != 6 )
return;
ent->v.maxs[0] = atof( CMD_ARGV( 3 ) );
ent->v.maxs[1] = atof( CMD_ARGV( 4 ) );
ent->v.maxs[2] = atof( CMD_ARGV( 5 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "rendercolor" ) )
{
if( CMD_ARGC() != 6 )
return;
ent->v.rendercolor[0] = atof( CMD_ARGV( 3 ) );
ent->v.rendercolor[1] = atof( CMD_ARGV( 4 ) );
ent->v.rendercolor[2] = atof( CMD_ARGV( 5 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "renderamt" ) )
{
ent->v.renderamt = atof( CMD_ARGV( 3 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "renderfx" ) )
{
ent->v.renderfx = atoi( CMD_ARGV( 3 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "rendermode" ) )
{
ent->v.rendermode = atoi( CMD_ARGV( 3 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "angles" ) )
{
ent->v.angles[0] = atof( CMD_ARGV( 3 ) );
ent->v.angles[1] = atof( CMD_ARGV( 4 ) );
ent->v.angles[2] = atof( CMD_ARGV( 5 ) );
}
else if( !stricmp( CMD_ARGV( 2 ), "setflag" ) )
{
ent->v.flags |= 1U << atoi( CMD_ARGV ( 3 ) );
Ent_ClientPrintf( player, "flags set to 0x%x\n", ent->v.flags );
}
else if( !stricmp( CMD_ARGV( 2 ), "clearflag" ) )
{
ent->v.flags &= ~( 1U << atoi( CMD_ARGV ( 3 ) ) );
Ent_ClientPrintf( player, "flags set to 0x%x\n", ent->v.flags );
}
else if( !stricmp( CMD_ARGV( 2 ), "setspawnflag" ) )
{
ent->v.spawnflags |= 1U << atoi( CMD_ARGV ( 3 ) );
Ent_ClientPrintf( player, "spawnflags set to 0x%x\n", ent->v.spawnflags );
}
else if( !stricmp( CMD_ARGV( 2 ), "clearspawnflag" ) )
{
ent->v.spawnflags &= ~( 1U << atoi( CMD_ARGV ( 3 ) ) );
Ent_ClientPrintf( player, "spawnflags set to 0x%x\n", ent->v.flags );
}
else if( !stricmp( CMD_ARGV( 2 ), "help" ) )
{
Ent_ClientPrintf( player, "Availiavle commands:\n"
"Set fields:\n"
" (Only set entity field, does not call any functions)\n"
" health\n"
" gravity\n"
" movetype\n"
" solid\n"
" rendermode\n"
" rendercolor (vector)\n"
" renderfx\n"
" renderamt\n"
" hullmin (vector)\n"
" hullmax (vector)\n"
"Actions\n"
" rename: set entity targetname\n"
" settarget: set entity target (only targetnames)\n"
" setmodel: set entity model\n"
" set: set <key> <value> by server library\n"
" See game FGD to get list.\n"
" command takes two arguments\n"
" touch: touch entity by current player.\n"
" use: use entity by current player.\n"
" movehere: place entity in player fov.\n"
" drop2floor: place entity to nearest floor surface\n"
" moveup: move entity to 25 units up\n"
"Flags:\n"
" (Set/clear specified flag bit, arg is bit number)\n"
" setflag\n"
" clearflag\n"
" setspawnflag\n"
" clearspawnflag\n"
);
return;
}
else
{
Ent_ClientPrintf( player, "Unknown command %s!\nUse \"ent_fire 0 help\" to list commands.\n", CMD_ARGV( 2 ) );
return;
}
if( single )
break;
}
}
/*
===============
Ent_Create_f
Create new entity with specified name.
===============
*/
void Ent_Create_f( edict_t *player )
{
edict_t *ent = NULL;
int i = 0;
string_t classname;
if( CMD_ARGC() < 2 )
{
Ent_ClientPrintf( player, "Use ent_create <classname> <key1> <value1> <key2> <value2> ...\n" );
return;
}
classname = ALLOC_STRING( CMD_ARGV( 1 ) );
ent = CREATE_NAMED_ENTITY( classname );
if( !ent )
{
Ent_ClientPrintf( player, "Invalid entity!\n" );
return;
}
// choose default origin
UTIL_SetOrigin( &ent->v, player->v.origin + Vector( 100 * cos( player->v.angles[1]/180*M_PI ), 100 * sin( player->v.angles[1]/180*M_PI), 25 ));
// apply keyvales
for( i = 2; i < CMD_ARGC() - 1; i++ )
{
KeyValueData pkvd;
// allow split keyvalues to prespawn and postspawn
if( !strcmp( CMD_ARGV( i ), "|" ) )
{
i++;
break;
}
pkvd.fHandled = false;
pkvd.szClassName = (char*)STRING( ent->v.classname );
pkvd.szKeyName = (char*)CMD_ARGV( i );
i++;
pkvd.szValue = (char*)CMD_ARGV( i );
DispatchKeyValue( ent, &pkvd );
if( pkvd.fHandled )
Ent_ClientPrintf( player, "value \"%s\" set to \"%s\"!\n", pkvd.szKeyName, pkvd.szValue );
}
// set default targetname
if( !ent->v.targetname )
{
char newname[256], clientname[256];
for( i = 0; i < 32; i++ )
{
char c = tolower( (STRING( player->v.netname ))[i] );
if( c < 'a' || c > 'z' )
c = '_';
if( !(STRING( player->v.netname ))[i] )
{
clientname[i] = 0;
break;
}
clientname[i] = c;
}
// generate name based on nick name and index
snprintf( newname, 255, "%s_%i_e%i", clientname, GETPLAYERUSERID( player ), ENTINDEX( ent ) );
newname[255] = 0;
// i know, it may break strict aliasing rules
// but we will not lose anything in this case.
//Q_strnlwr( newname, newname, 256 );
ent->v.targetname = ALLOC_STRING( newname );
Ent_SendVars( player, ent );
}
Ent_ClientPrintf( player, "Created %i: %s, targetname %s\n", ENTINDEX( ent ), CMD_ARGV( 1 ), STRING( ent->v.targetname ) );
DispatchSpawn( ent );
// now drop entity to floor.
g_engfuncs.pfnDropToFloor( ent );
// force think. Otherwise given weapon may crash server if player touch it before.
DispatchThink( ent );
g_engfuncs.pfnDropToFloor( ent );
// apply postspawn keyvales
for( i = i; i < CMD_ARGC() - 1; i++ )
{
KeyValueData pkvd;
pkvd.fHandled = false;
pkvd.szClassName = (char*)STRING( ent->v.classname );
pkvd.szKeyName = (char*)CMD_ARGV( i );
i++;
pkvd.szValue = (char*)CMD_ARGV( i );
DispatchKeyValue( ent, &pkvd );
if( pkvd.fHandled )
Ent_ClientPrintf( player, "value \"%s\" set to \"%s\"!\n", pkvd.szKeyName, pkvd.szValue );
}
}
typedef struct ucmd_s
{
const char *name;
void (*func)( edict_t *player );
} ucmd_t;
ucmd_t enttoolscmds[] =
{
{ "ent_list", Ent_List_f },
{ "ent_info", Ent_Info_f },
{ "ent_fire", Ent_Fire_f },
{ "ent_create", Ent_Create_f },
{ "ent_getvars", Ent_GetVars_f },
{ NULL, NULL }
};
bool Ent_ProcessClientCommand( edict_t *player )
{
ucmd_t *u;
if( !mp_enttools_enable.value )
return false;
for( u = enttoolscmds; u->name; u++ )
{
if( !strcmp( CMD_ARGV( 0 ), u->name ))
{
ALERT( at_console, "enttools->%s(): %s\n", u->name, CMD_ARGS() );
ALERT( at_logged, "\"%s<%i><%s><>\" performed: %s\n", STRING(player->v.netname),
GETPLAYERUSERID(player), GETPLAYERAUTHID(player), g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( player ), "ip" ), CMD_ARGS() );
if( u->func ) u->func( player );
return true;
}
}
return false;
}
cvar_t mp_enttools_enable = { "mp_enttools_enable", "0", FCVAR_SERVER };
cvar_t mp_enttools_maxfire = { "mp_enttools_maxfire", "5", FCVAR_SERVER };
void ENT_RegisterCVars( void )
{
CVAR_REGISTER( &mp_enttools_enable );
CVAR_REGISTER( &mp_enttools_maxfire );
}

9
dlls/enttools.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef ENTTOOLS_H
#define ENTTOOLS_H
extern cvar_t mp_enttools_maxfire;
extern cvar_t mp_enttools_enable;
bool Ent_ProcessClientCommand( edict_t *player );
void ENT_RegisterCVars( void );
#endif // ENTTOOLS_H

View File

@ -38,36 +38,8 @@ cvar_t teamlist = { "mp_teamlist","hgrunt;scientist", FCVAR_SERVER };
cvar_t teamoverride = { "mp_teamoverride","1" };
cvar_t defaultteam = { "mp_defaultteam","0" };
cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER };
cvar_t cvar_allow_gravgun = { "mp_allow_gravgun","1", FCVAR_SERVER };
cvar_t cvar_allow_ar2 = { "mp_allow_ar2","0", FCVAR_SERVER };
cvar_t cvar_ar2_mp5 = { "mp_ar2_mp5","0", FCVAR_SERVER };
cvar_t cvar_ar2_balls = { "mp_ar2_balls","0", FCVAR_SERVER };
cvar_t cvar_ar2_bullets = { "mp_ar2_bullets","0", FCVAR_SERVER };
cvar_t cvar_wresptime = { "mp_wresptime","20", FCVAR_SERVER };
cvar_t cvar_iresptime = { "mp_iresptime","30", FCVAR_SERVER };
cvar_t cvar_gibtime = { "mp_gibtime","250", FCVAR_SERVER };
cvar_t cvar_hgibcount = { "mp_hgibcount","12", FCVAR_SERVER };
cvar_t cvar_agibcount = { "mp_agibcount","8", FCVAR_SERVER };
cvar_t mp_chattime = { "mp_chattime","10", FCVAR_SERVER };
cvar_t mp_gravgun_players = { "mp_gravgun_players", "0", FCVAR_SERVER };
cvar_t mp_coop = { "mp_coop", "0", FCVAR_SERVER };
cvar_t mp_coop_changelevel = { "mp_coop_changelevel", "0", FCVAR_SERVER };
cvar_t mp_coop_nofriendlyfire = { "mp_coop_nofriendlyfire", "0", FCVAR_SERVER };
cvar_t mp_coop_disabledmap = { "mp_coop_disabledmap", "", FCVAR_SERVER };
cvar_t mp_coop_reconnect_hack = { "mp_coop_reconnect_hack", "0", FCVAR_SERVER };
cvar_t mp_coop_noangry = { "mp_coop_noangry", "0", FCVAR_SERVER };
cvar_t mp_coop_checkpoints = { "mp_coop_checkpoints", "1", FCVAR_SERVER };
cvar_t mp_skipdefaults = { "mp_skipdefaults", "0", FCVAR_SERVER };
cvar_t mp_coop_strongcheckpoints = { "mp_coop_strongcheckpoints", "0", FCVAR_SERVER };
cvar_t mp_unduck = { "mp_unduck", "0", FCVAR_SERVER };
cvar_t mp_semclip = { "mp_semclip", "0", FCVAR_SERVER };
cvar_t mp_spectator = { "mp_spectator", "0", FCVAR_SERVER };
cvar_t mp_fixhornetbug = { "mp_fixhornetbug", "0", FCVAR_SERVER };
cvar_t mp_checkentities = { "mp_checkentities", "0", FCVAR_SERVER };
cvar_t materials_txt = { "materials_txt", "sound/materials.txt", FCVAR_SERVER };
cvar_t sentences_txt = { "sentences_txt", "sound/sentences.txt", FCVAR_SERVER };
// Engine Cvars
cvar_t *g_psv_gravity = NULL;
@ -480,6 +452,9 @@ void GameDLLInit( void )
g_footsteps = CVAR_GET_POINTER( "mp_footsteps" );
CVAR_REGISTER( &displaysoundlist );
GGM_RegisterCVars();
COOP_RegisterCVars();
ENT_RegisterCVars();
CVAR_REGISTER( &teamplay );
CVAR_REGISTER( &fraglimit );
@ -499,37 +474,6 @@ void GameDLLInit( void )
CVAR_REGISTER( &teamoverride );
CVAR_REGISTER( &defaultteam );
CVAR_REGISTER( &allowmonsters );
CVAR_REGISTER( &cvar_allow_ar2 );
CVAR_REGISTER( &cvar_allow_gravgun );
CVAR_REGISTER( &cvar_ar2_mp5 );
CVAR_REGISTER( &cvar_ar2_bullets );
CVAR_REGISTER( &cvar_ar2_balls );
CVAR_REGISTER( &cvar_wresptime );
CVAR_REGISTER( &cvar_iresptime );
CVAR_REGISTER( &cvar_gibtime );
CVAR_REGISTER( &cvar_hgibcount );
CVAR_REGISTER( &cvar_agibcount );
CVAR_REGISTER( &mp_gravgun_players );
CVAR_REGISTER( &mp_coop );
CVAR_REGISTER( &mp_coop_changelevel );
CVAR_REGISTER( &mp_coop_nofriendlyfire );
CVAR_REGISTER( &mp_coop_disabledmap );
CVAR_REGISTER( &mp_unduck );
CVAR_REGISTER( &mp_semclip );
CVAR_REGISTER( &mp_coop_reconnect_hack );
CVAR_REGISTER( &mp_coop_noangry );
CVAR_REGISTER( &mp_spectator );
CVAR_REGISTER( &mp_coop_checkpoints );
CVAR_REGISTER( &mp_skipdefaults );
CVAR_REGISTER( &mp_coop_strongcheckpoints );
CVAR_REGISTER( &mp_fixhornetbug );
CVAR_REGISTER( &mp_checkentities );
CVAR_REGISTER( &sentences_txt );
CVAR_REGISTER( &materials_txt );
CVAR_REGISTER( &mp_chattime );

View File

@ -37,6 +37,8 @@ extern cvar_t defaultteam;
extern cvar_t allowmonsters;
#include "coop_util.h"
#include "enttools.h"
#include "gravgunmod.h"
// Engine Cvars
extern cvar_t *g_psv_gravity;

37
dlls/gravgunmod.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "gravgunmod.h"
#include "coop_util.h"
cvar_t cvar_allow_gravgun = { "mp_allow_gravgun","1", FCVAR_SERVER };
cvar_t cvar_allow_ar2 = { "mp_allow_ar2","0", FCVAR_SERVER };
cvar_t cvar_ar2_mp5 = { "mp_ar2_mp5","0", FCVAR_SERVER };
cvar_t cvar_ar2_balls = { "mp_ar2_balls","0", FCVAR_SERVER };
cvar_t cvar_ar2_bullets = { "mp_ar2_bullets","0", FCVAR_SERVER };
cvar_t cvar_wresptime = { "mp_wresptime","20", FCVAR_SERVER };
cvar_t cvar_iresptime = { "mp_iresptime","30", FCVAR_SERVER };
cvar_t cvar_gibtime = { "mp_gibtime","250", FCVAR_SERVER };
cvar_t cvar_hgibcount = { "mp_hgibcount","12", FCVAR_SERVER };
cvar_t cvar_agibcount = { "mp_agibcount","8", FCVAR_SERVER };
cvar_t mp_gravgun_players = { "mp_gravgun_players", "0", FCVAR_SERVER };
cvar_t mp_fixhornetbug = { "mp_fixhornetbug", "0", FCVAR_SERVER };
cvar_t mp_checkentities = { "mp_checkentities", "0", FCVAR_SERVER };
void GGM_RegisterCVars( void )
{
CVAR_REGISTER( &cvar_allow_ar2 );
CVAR_REGISTER( &cvar_allow_gravgun );
CVAR_REGISTER( &cvar_ar2_mp5 );
CVAR_REGISTER( &cvar_ar2_bullets );
CVAR_REGISTER( &cvar_ar2_balls );
CVAR_REGISTER( &cvar_wresptime );
CVAR_REGISTER( &cvar_iresptime );
CVAR_REGISTER( &cvar_gibtime );
CVAR_REGISTER( &cvar_hgibcount );
CVAR_REGISTER( &cvar_agibcount );
CVAR_REGISTER( &mp_gravgun_players );
CVAR_REGISTER( &mp_fixhornetbug );
CVAR_REGISTER( &mp_checkentities );
}

24
dlls/gravgunmod.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef GRAVGUNMOD_H
#define GRAVGUNMOD_H
extern cvar_t cvar_allow_gravgun;
extern cvar_t cvar_allow_ar2;
extern cvar_t cvar_ar2_mp5;
extern cvar_t cvar_ar2_bullets;
extern cvar_t cvar_ar2_balls;
extern cvar_t cvar_wresptime;
extern cvar_t cvar_iresptime;
extern cvar_t cvar_gibtime;
extern cvar_t cvar_hgibcount;
extern cvar_t cvar_agibcount;
extern cvar_t mp_spectator;
extern cvar_t mp_fixhornetbug;
extern cvar_t mp_checkentities;
void GGM_RegisterCVars( void );
#endif // GRAVGUNMOD_H

View File

@ -1135,7 +1135,7 @@ void CFuncTrackTrain::Next( void )
}
// prevent train without players going to other map
if( mp_coop.value && pev->globalname && STRING( pev->globalname )[0] )
if( mp_coop.value && pev->globalname && (STRING( pev->globalname ))[0] )
{
CBaseEntity *pList;
Vector mins = pev->absmin;