8000 mint-arena: Add argument auto completion for Game VM commands · Turtle-Arena/turtle-arena-code@ca5bd9f · GitHub
[go: up one dir, main page]

Skip to content

Commit ca5bd9f

Browse files
committed
mint-arena: Add argument auto completion for Game VM commands
Add argument auto completion for addbot, forceTeam, teleport, and tell (new for dedicated server only, cgame already handles tell).
1 parent 993bea4 commit ca5bd9f

File tree

6 files changed

+171
-54
lines changed

6 files changed

+171
-54
lines changed

code/cgame/cg_consolecmds.c

+12-48
Original file line numberDiff line numberDiff line change
@@ -303,42 +303,6 @@ void CG_SetTeamHeadmodel_f( int localPlayerNum ) {
303303
}
304304
}
305305

306-
/*
307-
=============
308-
CG_AddStringToList
309-
=============
310-
*/
311-
static void CG_AddStringToList( char *list, size_t listSize, int *listLength, char *name ) {
312-
size_t namelen;
313-
int val;
314-
char *listptr;
315-
316-
namelen = strlen( name );
317-
318-
if ( *listLength + namelen + 1 >= listSize ) {
319-
return;
320-
}
321-
322-
for ( listptr = list; *listptr; listptr += strlen( listptr ) + 1 ) {
323-
val = Q_stricmp( name, listptr );
324-
if ( val == 0 ) {
325-
return;
326-
}
327-
// insert into list
328-
else if ( val < 0 ) {
329-
int moveBytes = *listLength - (int)( listptr - list ) + 1;
330-
331-
memmove( listptr + namelen + 1, listptr, moveBytes );
332-
strncpy( listptr, name, namelen + 1 );
333-
*listLength += namelen + 1;
334-
return;
335-
}
336-
}
337-
338-
strncpy( listptr, name, namelen + 1 );
339-
*listLength += namelen + 1;
340-
}
341-
342306
/*
343307
==================
344308
CG_Field_CompletePlayerModel
@@ -399,7 +363,7 @@ static void CG_Field_CompletePlayerModel( int argNum, qboolean lookingForHead, c
399363
skinTeamSuffix = ( lookingForTeam == TEAM_BLUE ) ? "_blue" : "_red";
400364
skinTeamSuffixLength = ( lookingForTeam == TEAM_BLUE ) ? 5 : 6;
401365

402-
// ZTM: FIXME: have to clear whole list because CG_AddStringToList doesn't properly terminate list
366+
// ZTM: FIXME: have to clear whole list because BG_AddStringToList doesn't properly terminate list
403367
memset( list, 0, sizeof( list ) );
404368
listTotalLength = 0;
405369

@@ -449,7 +413,7 @@ static void CG_Field_CompletePlayerModel( int argNum, qboolean lookingForHead, c
449413
// models/players/example/upper_default.skin
450414
// add default skin as just the model name
451415
// for team models this is red or blue
452-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, dirptr );
416+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, dirptr );
453417
} else if ( lookingForTeam != TEAM_FREE ) {
454418
// models/players/example/upper_lily_red.skin
455419
// for team model add lily_red skin as lily
@@ -459,12 +423,12 @@ static void CG_Field_CompletePlayerModel( int argNum, qboolean lookingForHead, c
459423
&& COM_CompareExtension( skinname, skinTeamSuffix ) ) {
460424
// remove _red
461425
skinname[skinnameLength - 1 - skinTeamSuffixLength] = '\0';
462-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "%s/%s", dirptr, skinname ) );
426+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "%s/%s", dirptr, skinname ) );
463427
}
464428
} else {
465429
// models/players/example/upper_lily.skin
466430
// misc ffa skins
467-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "%s/%s", dirptr, skinname ) );
431+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "%s/%s", dirptr, skinname ) );
468432
}
469433
}
470434
}
@@ -517,7 +481,7 @@ static void CG_Field_CompletePlayerModel( int argNum, qboolean lookingForHead, c
517481
// models/players/heads/example/head_default.skin
518482
// add default skin as just the model name
519483
// for team models this is red or blue
520-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s", dirptr ) );
484+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s", dirptr ) );
521485
} else if ( lookingForTeam != TEAM_FREE ) {
522486
// models/players/heads/example/head_lily_red.skin
523487
// for team model add lily_red skin as lily
@@ -527,12 +491,12 @@ static void CG_Field_CompletePlayerModel( int argNum, qboolean lookingForHead, c
527491
&& COM_CompareExtension( skinname, skinTeamSuffix ) ) {
528492
// remove _red
529493
skinname[skinnameLength - 1 - skinTeamSuffixLength] = '\0';
530-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s/%s", dirptr, skinname ) );
494+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s/%s", dirptr, skinname ) );
531495
}
532496
} else {
533497
// models/players/heads/example/head_lily.skin
534498
// misc ffa skins
535-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s/%s", dirptr, skinname ) );
499+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "*%s/%s", dirptr, skinname ) );
536500
}
537501
}
538502
}
@@ -1328,7 +1292,7 @@ static void CG_Field_CompletePlayerName( int team, qboolean excludeTeam, qboolea
13281292
return;
13291293
}
13301294

1331-
// ZTM: FIXME: have to clear whole list because CG_AddStringToList doesn't properly terminate list
1295+
// ZTM: FIXME: have to clear whole list because BG_AddStringToList doesn't properly terminate list
13321296
memset( list, 0, sizeof( list ) );
13331297
listTotalLength = 0;
13341298

@@ -1351,9 +1315,9 @@ static void CG_Field_CompletePlayerName( int team, qboolean excludeTeam, qboolea
13511315

13521316
// Use quotes if there is a space in the name
13531317
if ( strchr( name, ' ' ) != NULL ) {
1354-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "\"%s\"", name ) );
1318+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "\"%s\"", name ) );
13551319
} else {
1356-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, name );
1320+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, name );
13571321
}
13581322
}
13591323

@@ -1459,7 +1423,7 @@ static void CG_GiveComplete( int localPlayerNum, char *args, int argNum ) {
14591423
int i, j, listTotalLength, typedNameLength;
14601424
gitem_t *item;
14611425

1462-
// ZTM: FIXME: have to clear whole list because CG_AddStringToList doesn't properly terminate list
1426+
// ZTM: FIXME: have to clear whole list because BG_AddStringToList doesn't properly terminate list
14631427
memset( list, 0, sizeof( list ) );
14641428
listTotalLength = 0;
14651429

@@ -1499,7 +1463,7 @@ static void CG_GiveComplete( int localPlayerNum, char *args, int argNum ) {
14991463
}
15001464

15011465
if ( name && *name ) {
1502-
CG_AddStringToList( list, sizeof( list ), &listTotalLength, name );
1466+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, name );
15031467
}
15041468
}
15051469

code/game/bg_misc.c

+42-1
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,42 @@ void BG_DecomposeUserCmdValue( int value, int *weapon ) {
18851885
BG_DecomposeBits( value, &bitsUsed, weapon, WEAPONNUM_BITS );
18861886
}
18871887

1888+
/*
1889+
=============
1890+
BG_AddStringToList
1891+
=============
1892+
*/
1893+
void BG_AddStringToList( char *list, size_t listSize, int *listLength, char *name ) {
1894+
size_t namelen;
1895+
int val;
1896+
char *listptr;
1897+
1898+
namelen = strlen( name );
1899+
1900+
if ( *listLength + namelen + 1 >= listSize ) {
1901+
return;
1902+
}
1903+
1904+
for ( listptr = list; *listptr; listptr += strlen( listptr ) + 1 ) {
1905+
val = Q_stricmp( name, listptr );
1906+
if ( val == 0 ) {
1907+
return;
1908+
}
1909+
// insert into list
1910+
else if ( val < 0 ) {
1911+
int moveBytes = *listLength - (int)( listptr - list ) + 1;
1912+
1913+
memmove( listptr + namelen + 1, listptr, moveBytes );
1914+
strncpy( listptr, name, namelen + 1 );
1915+
*listLength += namelen + 1;
1916+
return;
1917+
}
1918+
}
1919+
1920+
strncpy( listptr, name, namelen + 1 );
1921+
*listLength += namelen + 1;
1922+
}
1923+
18881924
/*
18891925
======================
18901926
SnapVectorTowards
@@ -1907,8 +1943,13 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) {
19071943
}
19081944
}
19091945

1946+
/*
1947+
=============
1948+
cmdcmp
1949+
=============
1950+
*/
19101951
int cmdcmp( const void *a, const void *b ) {
1911-
return Q_stricmp( (const char *)a, ((dummyCmd_t *)b)->name );
1952+
return Q_stricmp( (const char *)a, ((dummyCmd_t *)b)->name 10000 );
19121953
}
19131954

19141955
/*

code/game/bg_public.h

+2
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,8 @@ qboolean BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTim
11231123
int BG_ComposeUserCmdValue( int weapon );
11241124
void BG_DecomposeUserCmdValue( int value, int *weapon );
11251125

1126+
void BG_AddStringToList( char *list, size_t listSize, int *listLength, char *name );
1127+
11261128
void SnapVectorTowards( vec3_t v, vec3_t to );
11271129

11281130
#define ARENAS_PER_TIER 4

code/game/g_bot.c

+37
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,43 @@ void Svcmd_AddBot_f( void ) {
845845
}
846846
}
847847

848+
/*
849+
===============
850+
Svcmd_AddBotComplete
851+
===============
852+
*/
853+
void Svcmd_AddBotComplete( char *args, int argNum ) {
854+
if ( argNum == 2 ) {
855+
int i;
856+
char name[MAX_NAME_LENGTH];
857+
char list[32000]; // [MAX_BOTS * MAX_NAME_LENGTH] is too big to fit in QVM locals (max 32k)
858+
int listTotalLength;
859+
860+
// ZTM: FIXME: have to clear whole list because BG_AddStringToList doesn't properly terminate list
861+
memset( list, 0, sizeof( list ) );
862+
listTotalLength = 0;
863+
864+
for (i = 0; i < g_numBots; i++) {
865+
Q_strncpyz( name, Info_ValueForKey( g_botInfos[i], "name" ), sizeof ( name ) );
866+
Q_CleanStr( name );
867+
868+
// Use quotes if there is a space in the name
869+
if ( strchr( name, ' ' ) != NULL ) {
870+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "\"%s\"", name ) );
871+
} else {
872+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, name );
873+
}
874+
}
875+
876+
if ( listTotalLength > 0 ) {
877+
list[listTotalLength++] = 0;
878+
trap_Field_CompleteList( list );
879+
}
880+
} else if ( argNum == 4 ) {
881+
trap_Field_CompleteList( "blue\0follow1\0follow2\0free\0red\0scoreboard\0spectator\0" );
882+
}
883+
}
884+
848885
/*
849886
===============
850887
Svcmd_BotList_f

code/game/g_local.h

+1
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ void G_CheckBotSpawn( void );
724724
void G_RemoveQueuedBotBegin( int playerNum );
725725
qboolean G_BotConnect( int playerNum, qboolean restart );
726726
void Svcmd_AddBot_f( void );
727+
void Svcmd_AddBotComplete( char *args, int argNum );
727728
void Svcmd_BotList_f( void );
728729
void BotInterbreedEndMatch( void );
729730

code/game/g_svcmds.c

+77-5
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ void Svcmd_EntityList_f (void) {
389389
int PlayerForString( const char *s ) {
390390
gplayer_t *cl;
391391
int idnum;
392-
char cleanName[MAX_STRING_CHARS];
392+
char cleanName[MAX_NETNAME];
393393

394394
// numeric values could be slot numbers
395395
if ( StringIsInteger( s ) ) {
@@ -419,6 +419,43 @@ int PlayerForString( const char *s ) {
419419
return -1;
420420
}
421421

422+
/*
423+
===================
424+
G_Field_CompletePlayerName
425+
===================
426+
*/
427+
void G_Field_CompletePlayerName( void ) {
428+
gplayer_t *cl;
429+
int idnum;
430+
char cleanName[MAX_NETNAME];
431+
char list[MAX_CLIENTS * MAX_NETNAME];
432+
int listTotalLength;
433+
434+
// ZTM: FIXME: have to clear whole list because BG_AddStringToList doesn't properly terminate list
435+
memset( list, 0, sizeof( list ) );
436+
listTotalLength = 0;
437+
438+
for ( idnum=0,cl=level.players ; idnum < level.maxplayers ; idnum++,cl++ ) {
439+
if ( cl->pers.connected != CON_CONNECTED ) {
440+
continue;
441+
}
442+
Q_strncpyz(cleanName, cl->pers.netname, sizeof(cleanName));
443+
Q_CleanStr(cleanName);
444+
445+
// Use quotes if there is a space in the name
446+
if ( strchr( cleanName, ' ' ) != NULL ) {
447+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, va( "\"%s\"", cleanName ) );
448+
} else {
449+
BG_AddStringToList( list, sizeof( list ), &listTotalLength, cleanName );
450+
}
451+
}
452+
453+
if ( listTotalLength > 0 ) {
454+
list[listTotalLength++] = 0;
455+
trap_Field_CompleteList( list );
456+
}
457+
}
458+
422459
/*
423460
===================
424461
Svcmd_ForceTeam_f
@@ -447,6 +484,19 @@ void Svcmd_ForceTeam_f( void ) {
447484
SetTeam( &g_entities[playerNum], str );
448485
}
449486

487+
/*
488+
===================
489+
Svcmd_ForceTeamComplete
490+
===================
491+
*/
492+
void Svcmd_ForceTeamComplete( char *args, int argNum ) {
493+
if ( argNum == 2 ) {
494+
G_Field_CompletePlayerName();
495+
} else if ( argNum == 3 ) {
496+
trap_Field_CompleteList( "blue\0follow1\0follow2\0free\0red\0scoreboard\0spectator\0" );
497+
}
498+
}
499+
450500
/*
451501
===================
452502
Svcmd_Teleport_f
@@ -498,6 +548,17 @@ void Svcmd_Teleport_f( void ) {
498548
TeleportPlayer( ent, position, angles );
499549
}
500550

551+
/*
552+
===================
553+
Svcmd_TeleportComplete
554+
===================
555+
*/
556+
void Svcmd_TeleportComplete( char *args, int argNum ) {
557+
if ( argNum == 2 ) {
558+
G_Field_CompletePlayerName();
559+
}
560+
}
561+
501562
/*
502563
===================
503564
Svcmd_ListIPs_f
@@ -556,6 +617,17 @@ void Svcmd_Tell_f( void ) {
556617
G_Say( NULL, target, SAY_TELL, p );
557618
}
558619

620+
/*
621+
===================
622+
Svcmd_TellComplete
623+
===================
624+
*/
625+
void Svcmd_TellComplete( char *args, int argNum ) {
626+
if ( argNum == 2 ) {
627+
G_Field_CompletePlayerName();
628+
}
629+
}
630+
559631
struct svcmd
560632
{
561633
char *cmd;
@@ -564,17 +636,17 @@ struct svcmd
564636
void ( *complete )( char *, int );
565637
} svcmds[ ] = {
566638
{ "abort_podium", qfalse, Svcmd_AbortPodium_f },
567-
{ "addbot", qfalse, Svcmd_AddBot_f },
639+
{ "addbot", qfalse, Svcmd_AddBot_f, Svcmd_AddBotComplete },
568640
{ "addip", qfalse, Svcmd_AddIP_f },
569641
{ "botlist", qfalse, Svcmd_BotList_f },
570642
{ "botreport", qfalse, Svcmd_BotTeamplayReport_f },
571643
{ "entityList", qfalse, Svcmd_EntityList_f },
572-
{ "forceTeam", qfalse, Svcmd_ForceTeam_f },
644+
{ "forceTeam", qfalse, Svcmd_ForceTeam_f, Svcmd_ForceTeamComplete },
573645
{ "listip", qfalse, Svcmd_ListIPs_f },
574646
{ "removeip", qfalse, Svcmd_RemoveIP_f },
575647
{ "say", qtrue, Svcmd_Say_f },
576-
{ "teleport", qfalse, Svcmd_Teleport_f },
577-
{ "tell", qtrue, Svcmd_Tell_f },
648+
{ "teleport", qfalse, Svcmd_Teleport_f, Svcmd_TeleportComplete },
649+
{ "tell", qtrue, Svcmd_Tell_f, Svcmd_TellComplete },
578650
};
579651

580652
const size_t numSvCmds = ARRAY_LEN(svcmds);

0 commit comments

Comments
 (0)
0