Added Nobuild series of commands (Issue 128)
This commit is contained in:
1 parent
86a37bbb72
commit
7596b65f3e
7 files changed
+327
-8
No files matched your search
@@ -24,7 +24,7 @@ endif
|
||||
BUILD_CLIENT = 0
|
||||
BUILD_CLIENT_SMP = 0
|
||||
BUILD_SERVER = 0
|
||||
BUILD_GAME_SO = 1
|
||||
BUILD_GAME_SO = 0
|
||||
BUILD_GAME_QVM = 1
|
||||
|
||||
#############################################################################
|
||||
|
||||
+63
-1
@@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "g_local.h"
|
||||
|
||||
void NoThink(gentity_t *ent);
|
||||
// big ugly global buffer for use with buffered printing of long outputs
|
||||
static char g_bfb[ 32000 ];
|
||||
|
||||
@@ -195,6 +196,16 @@ g_admin_cmd_t g_admin_cmds[ ] =
|
||||
"[^3mapname^7]"
|
||||
},
|
||||
|
||||
{"nobuild", G_admin_nobuild, "L",
|
||||
"make an area nobuild",
|
||||
"[^3game units^7]"
|
||||
},
|
||||
|
||||
{"nobuildsave", G_admin_nobuildsave, "L",
|
||||
"save a map's nobuild markers",
|
||||
""
|
||||
},
|
||||
|
||||
{"listadmins", G_admin_listadmins, "D",
|
||||
"display a list of all server admins and their levels",
|
||||
"(^5name|start admin#^7) (^5minimum level to display^7)"
|
||||
@@ -2837,6 +2848,14 @@ qboolean G_admin_layoutsave( gentity_t *ent, int skiparg )
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
qboolean G_admin_nobuildsave( gentity_t *ent, int skiparg )
|
||||
{
|
||||
|
||||
trap_SendConsoleCommand( EXEC_APPEND, "nobuildsave" );
|
||||
AP( va( "print \"^3!nobuildsave: ^7nobuild saved by %s\n\"", ( ent ) ? ent->client->pers.netname : "console" ) );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
qboolean G_admin_mute( gentity_t *ent, int skiparg )
|
||||
{
|
||||
int pids[ MAX_CLIENTS ];
|
||||
@@ -7708,4 +7727,47 @@ qboolean G_admin_fireworks( gentity_t *ent, int skiparg )
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean G_admin_nobuild( gentity_t *ent, int skiparg )
|
||||
{
|
||||
int minargc;
|
||||
char units[ MAX_STRING_CHARS ];
|
||||
gentity_t *nb;
|
||||
vec3_t low;
|
||||
int units2;
|
||||
minargc = 2 + skiparg;
|
||||
|
||||
if( G_SayArgc() < minargc )
|
||||
{
|
||||
ADMP( "^3!buildno: ^7usage: !nobuild [game units]\n" );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
ADMP( "^3!nobuild: ^7console cannot use this command\n" );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
G_SayArgv( 1 + skiparg, units, sizeof( units ) );
|
||||
|
||||
VectorAdd( ent->s.origin, ent->r.mins, low );
|
||||
|
||||
units2 = atoi(units);
|
||||
low[0] = ent->s.origin[0];
|
||||
low[1] = ent->s.origin[1];
|
||||
|
||||
nb = G_Spawn( );
|
||||
nb->s.modelindex = 1337;
|
||||
nb->think = NoThink;
|
||||
nb->nextthink = level.time;
|
||||
VectorCopy( low, nb->s.pos.trBase );
|
||||
VectorCopy( low, nb->r.currentOrigin );
|
||||
trap_LinkEntity( nb );
|
||||
nb->nobuilder = qtrue;
|
||||
nb->nobuildarea = units2;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
@@ -269,6 +269,8 @@ qboolean G_admin_customgrav( gentity_t *ent, int skiparg );
|
||||
qboolean G_admin_explode( gentity_t *ent, int skiparg );
|
||||
qboolean G_admin_outlaw( gentity_t *ent, int skiparg );
|
||||
qboolean G_admin_fireworks( gentity_t *ent, int skiparg );
|
||||
qboolean G_admin_nobuild( gentity_t *ent, int skiparg );
|
||||
qboolean G_admin_nobuildsave( gentity_t *ent, int skiparg );
|
||||
|
||||
void G_admin_print( gentity_t *ent, char *m );
|
||||
void G_admin_buffer_print( gentity_t *ent, char *m );
|
||||
|
||||
+213
-6
@@ -26,6 +26,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// from g_combat.c
|
||||
extern char *modNames[ ];
|
||||
|
||||
|
||||
void NoThink(gentity_t *ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
G_SetBuildableAnim
|
||||
@@ -3028,20 +3034,23 @@ Checks to see if a buildable can be built
|
||||
itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin )
|
||||
{
|
||||
vec3_t angles;
|
||||
vec3_t entity_origin, normal;
|
||||
vec3_t entity_origin, normal, tmp;
|
||||
vec3_t mins, maxs, mins1, maxs1;
|
||||
int num;
|
||||
int entitylist[ MAX_GENTITIES ];
|
||||
trace_t tr1, tr2, tr3;
|
||||
int i;
|
||||
itemBuildError_t reason = IBE_NONE;
|
||||
gentity_t *tempent;
|
||||
int num;
|
||||
float minNormal;
|
||||
qboolean invert;
|
||||
int contents;
|
||||
playerState_t *ps = &ent->client->ps;
|
||||
int buildPoints;
|
||||
|
||||
vec3_t mins3, maxs3, range;
|
||||
int i, num2;
|
||||
int entitylist[ MAX_GENTITIES ];
|
||||
gentity_t *nb;
|
||||
gentity_t *nbent;
|
||||
|
||||
BG_FindBBoxForBuildable( buildable, mins, maxs );
|
||||
|
||||
BG_PositionBuildableRelativeToPlayer( ps, mins, maxs, trap_Trace, entity_origin, angles, &tr1 );
|
||||
@@ -3056,7 +3065,48 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
|
||||
VectorCopy( tr1.plane.normal, normal );
|
||||
minNormal = BG_FindMinNormalForBuildable( buildable );
|
||||
invert = BG_FindInvertNormalForBuildable( buildable );
|
||||
|
||||
VectorCopy( entity_origin, tmp );
|
||||
|
||||
tmp[2] += mins[2];
|
||||
|
||||
nb = G_Spawn( );
|
||||
nb->s.modelindex = 1337; //Coder humor is awesome isn't it?
|
||||
nb->think = NoThink;
|
||||
nb->nextthink = level.time;
|
||||
VectorCopy( tmp, nb->s.pos.trBase );
|
||||
VectorCopy( tmp, nb->r.currentOrigin );
|
||||
trap_LinkEntity( nb );
|
||||
|
||||
|
||||
for ( i = 1, nbent = g_entities + i; i < level.num_entities; i++, nbent++ )
|
||||
{
|
||||
if( nbent->nobuilder == qtrue )
|
||||
{
|
||||
|
||||
range[0] = nbent->nobuildarea;
|
||||
range[1] = nbent->nobuildarea;
|
||||
range[2] = 0;
|
||||
|
||||
VectorAdd( nbent->r.currentOrigin, range, maxs3 );
|
||||
VectorSubtract( nbent->r.currentOrigin, range, mins3 );
|
||||
maxs[2] += 5;
|
||||
|
||||
num2 = trap_EntitiesInBox( mins3, maxs3, entitylist, MAX_GENTITIES );
|
||||
for(i = 0; i < num2; i++)
|
||||
{
|
||||
gentity_t *tent2 = &g_entities[ entitylist[ i ] ];
|
||||
|
||||
if( tent2 == nb )
|
||||
{
|
||||
reason = IBE_PERMISSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G_FreeEntity( nb );
|
||||
|
||||
//can we build at this angle?
|
||||
if( !( normal[ 2 ] >= minNormal || ( invert && normal[ 2 ] <= -minNormal ) ) )
|
||||
reason = IBE_NORMAL;
|
||||
@@ -3077,6 +3127,7 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
gentity_t *tent = &g_entities[ entitylist[ i ] ];
|
||||
|
||||
if( tent->s.eType == ET_PLAYER )
|
||||
{
|
||||
reason = IBE_NOROOM;
|
||||
@@ -3571,7 +3622,6 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori
|
||||
|
||||
trap_LinkEntity( built );
|
||||
|
||||
|
||||
if( builder->client )
|
||||
{
|
||||
builder->client->pers.statscounters.structsbuilt++;
|
||||
@@ -4417,3 +4467,160 @@ char *G_FindBuildLogName( int id )
|
||||
return "<world>";
|
||||
}
|
||||
|
||||
/*
|
||||
=========================
|
||||
Me stealing all of the layout code and making it work for nobuild, i know, im lazy, shutup.
|
||||
=========================
|
||||
*/
|
||||
|
||||
/*
|
||||
============
|
||||
G_NobuildSave
|
||||
|
||||
============
|
||||
*/
|
||||
void G_NobuildSave( void )
|
||||
{
|
||||
char map[ MAX_QPATH ];
|
||||
char fileName[ MAX_OSPATH ];
|
||||
fileHandle_t f;
|
||||
int len;
|
||||
int i;
|
||||
gentity_t *ent;
|
||||
char *s;
|
||||
|
||||
trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) );
|
||||
if( !map[ 0 ] )
|
||||
{
|
||||
G_Printf( "NobuildSave( ): no map is loaded\n" );
|
||||
return;
|
||||
}
|
||||
Com_sprintf( fileName, sizeof( fileName ), "nobuild/%s.dat", map );
|
||||
|
||||
len = trap_FS_FOpenFile( fileName, &f, FS_WRITE );
|
||||
if( len < 0 )
|
||||
{
|
||||
G_Printf( "nobuildsave: could not open %s\n", fileName );
|
||||
return;
|
||||
}
|
||||
|
||||
G_Printf("nobuildsave: saving nobuild to %s\n", fileName );
|
||||
|
||||
for( i = MAX_CLIENTS; i < level.num_entities; i++ )
|
||||
{
|
||||
ent = &level.gentities[ i ];
|
||||
if( ent->nobuilder != qtrue )
|
||||
continue;
|
||||
|
||||
s = va( "%f %f %f %f\n",
|
||||
ent->s.pos.trBase[ 0 ],
|
||||
ent->s.pos.trBase[ 1 ],
|
||||
ent->s.pos.trBase[ 2 ],
|
||||
ent->nobuildarea );
|
||||
trap_FS_Write( s, strlen( s ), f );
|
||||
}
|
||||
trap_FS_FCloseFile( f );
|
||||
}
|
||||
|
||||
int G_NobuildList( char *list, int len )
|
||||
{
|
||||
// up to 128 single character nobuild names could fit in nobuilds
|
||||
char fileList[ ( MAX_CVAR_VALUE_STRING / 2 ) * 5 ] = {""};
|
||||
char nobuild[ MAX_CVAR_VALUE_STRING ] = {""};
|
||||
int numFiles, i, fileLen = 0, listLen;
|
||||
int count = 0;
|
||||
char *filePtr;
|
||||
|
||||
numFiles = trap_FS_GetFileList( va( "nobuild" ), ".dat",
|
||||
fileList, sizeof( fileList ) );
|
||||
filePtr = fileList;
|
||||
for( i = 0; i < numFiles; i++, filePtr += fileLen + 1 )
|
||||
{
|
||||
fileLen = strlen( filePtr );
|
||||
listLen = strlen( nobuild );
|
||||
if( fileLen < 5 )
|
||||
continue;
|
||||
|
||||
// list is full, stop trying to add to it
|
||||
if( ( listLen + fileLen ) >= sizeof( nobuild ) )
|
||||
break;
|
||||
|
||||
Q_strcat( nobuild, sizeof( nobuild ), filePtr );
|
||||
listLen = strlen( nobuild );
|
||||
|
||||
// strip extension and add space delimiter
|
||||
nobuild[ listLen - 4 ] = ' ';
|
||||
nobuild[ listLen - 3 ] = '\0';
|
||||
count++;
|
||||
}
|
||||
if( count != numFiles )
|
||||
{
|
||||
G_Printf( S_COLOR_YELLOW "WARNING: nobuild list was truncated to %d "
|
||||
"nobuilds, but %d nobuild files exist in /nobuilds/.\n",
|
||||
count, numFiles );
|
||||
}
|
||||
Q_strncpyz( list, nobuild, len );
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
G_NobuildLoad
|
||||
|
||||
load the nobuild markers that were previously saved (if there are any).
|
||||
============
|
||||
*/
|
||||
void G_NobuildLoad( void )
|
||||
{
|
||||
fileHandle_t f;
|
||||
int len;
|
||||
char *nobuild;
|
||||
char map[ MAX_QPATH ];
|
||||
vec3_t origin = { 0.0f, 0.0f, 0.0f };
|
||||
char line[ MAX_STRING_CHARS ];
|
||||
int i = 0;
|
||||
gentity_t *nb;
|
||||
float units;
|
||||
|
||||
trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) );
|
||||
len = trap_FS_FOpenFile( va( "nobuild/%s.dat", map ),
|
||||
&f, FS_READ );
|
||||
if( len < 0 )
|
||||
{
|
||||
G_Printf( "ERROR: nobuild for %s could not be opened\n", map );
|
||||
return;
|
||||
}
|
||||
nobuild = G_Alloc( len + 1 );
|
||||
trap_FS_Read( nobuild, len, f );
|
||||
*( nobuild + len ) = '\0';
|
||||
trap_FS_FCloseFile( f );
|
||||
while( *nobuild )
|
||||
{
|
||||
if( i >= sizeof( line ) - 1 )
|
||||
{
|
||||
G_Printf( S_COLOR_RED "ERROR: line overflow in %s before \"%s\"\n",
|
||||
va( "nobuild/%s.dat", map ), line );
|
||||
return;
|
||||
}
|
||||
line[ i++ ] = *nobuild;
|
||||
line[ i ] = '\0';
|
||||
if( *nobuild == '\n' )
|
||||
{
|
||||
i = 0;
|
||||
sscanf( line, "%f %f %f %f\n",
|
||||
&origin[ 0 ], &origin[ 1 ], &origin[ 2 ], &units );
|
||||
|
||||
nb = G_Spawn( );
|
||||
nb->s.modelindex = 1337; //Coder humor is awesome isn't it?
|
||||
nb->think = NoThink;
|
||||
nb->nextthink = level.time;
|
||||
VectorCopy( origin, nb->s.pos.trBase );
|
||||
VectorCopy( origin, nb->r.currentOrigin );
|
||||
nb->nobuilder = qtrue;
|
||||
nb->nobuildarea = units;
|
||||
trap_LinkEntity( nb );
|
||||
|
||||
}
|
||||
nobuild++;
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,9 @@ struct gentity_s
|
||||
int bdnumb; // buildlog entry ID
|
||||
gentity_t *oldent;
|
||||
int livetime;
|
||||
|
||||
qboolean nobuilder;
|
||||
float nobuildarea;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
@@ -884,6 +887,9 @@ void G_LayoutSave( char *name );
|
||||
int G_LayoutList( const char *map, char *list, int len );
|
||||
void G_LayoutSelect( void );
|
||||
void G_LayoutLoad( void );
|
||||
void G_NobuildSave( void );
|
||||
int G_NobuildList( char *list, int len );
|
||||
void G_NobuildLoad( void );
|
||||
void G_BaseSelfDestruct( pTeam_t team );
|
||||
gentity_t *G_InstantBuild( buildable_t buildable, vec3_t origin, vec3_t angles, vec3_t origin2, vec3_t angles2 );
|
||||
void G_SpawnRevertedBuildable( buildHistory_t *bh, qboolean mark );
|
||||
|
||||
@@ -863,6 +863,9 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
|
||||
|
||||
// load up a custom building layout if there is one
|
||||
G_LayoutLoad( );
|
||||
|
||||
// load nobuilds, if there are any
|
||||
G_NobuildLoad( );
|
||||
|
||||
// the map might disable some things
|
||||
BG_InitAllowedGameElements( );
|
||||
|
||||
@@ -544,6 +544,33 @@ void Svcmd_LayoutLoad_f( void )
|
||||
level.restarted = qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Svcmd_NobuildSave_f
|
||||
|
||||
nobuildsave
|
||||
===================
|
||||
*/
|
||||
void Svcmd_NobuildSave_f( void )
|
||||
{
|
||||
G_NobuildSave();
|
||||
}
|
||||
|
||||
char *ConcatArgs( int start );
|
||||
|
||||
/*
|
||||
===================
|
||||
Svcmd_NobuildLoad_f
|
||||
|
||||
nobuildload
|
||||
|
||||
===================
|
||||
*/
|
||||
void Svcmd_NobuildLoad_f( void )
|
||||
{
|
||||
G_NobuildLoad();
|
||||
}
|
||||
|
||||
static void Svcmd_AdmitDefeat_f( void )
|
||||
{
|
||||
int team;
|
||||
@@ -688,6 +715,18 @@ qboolean ConsoleCommand( void )
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( cmd, "nobuildsave" ) )
|
||||
{
|
||||
Svcmd_NobuildSave_f( );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( cmd, "nobuildload" ) )
|
||||
{
|
||||
Svcmd_NobuildLoad_f( );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( cmd, "admitdefeat" ) )
|
||||
{
|
||||
Svcmd_AdmitDefeat_f( );
|
||||
|
||||
Reference in new issue
Block a user