Add 'listentities' command.

This rather sophisticated command prints all entities of one or more
given classes and their coordinates. Possible classes are:

* ammo
* items
* keys
* monsters
* weapons

Classes can be combined into one command, e.g. `listentities ammo keys'
would print all ammunition and all keys. The special class `all` prints
all entities, regardless of their class.

The command is protected by `cheats 1`.

This is part of issue yquake2/yquake2#430.
This commit is contained in:
Yamagi Burmeister 2019-09-05 17:47:10 +02:00
parent 532ae678de
commit f64f112aa0

View file

@ -1305,6 +1305,124 @@ Cmd_Teleport_f(edict_t *ent)
gi.linkentity(ent); gi.linkentity(ent);
} }
void
Cmd_ListEntities_f(edict_t *ent)
{
if ((deathmatch->value || coop->value) && !sv_cheats->value)
{
gi.cprintf(ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
return;
}
if (gi.argc() < 2)
{
gi.cprintf(ent, PRINT_HIGH, "Usage: listentities <all|ammo|items|keys|monsters|weapons>\n");
return;
}
/* What to print? */
qboolean all = false;
qboolean ammo = false;
qboolean items = false;
qboolean keys = false;
qboolean monsters = false;
qboolean weapons = false;
for (int i = 1; i < gi.argc(); i++)
{
const char *arg = gi.argv(i);
if (Q_stricmp(arg, "all") == 0)
{
all = true;
}
else if (Q_stricmp(arg, "ammo") == 0)
{
ammo = true;
}
else if (Q_stricmp(arg, "items") == 0)
{
items = true;
}
else if (Q_stricmp(arg, "keys") == 0)
{
keys = true;
}
else if (Q_stricmp(arg, "monsters") == 0)
{
monsters = true;
}
else if (Q_stricmp(arg, "weapons") == 0)
{
weapons = true;
}
else
{
gi.cprintf(ent, PRINT_HIGH, "Usage: listentities <all|ammo|items|keys|monsters|weapons>\n");
}
}
/* Print what's requested. */
for (int i = 0; i < globals.num_edicts; i++)
{
edict_t *cur = &g_edicts[i];
qboolean print = false;
if (all)
{
print = true;
}
else
{
if (ammo)
{
if (strncmp(cur->classname, "ammo_", 5) == 0)
{
print = true;
}
}
if (items)
{
if (strncmp(cur->classname, "item_", 5) == 0)
{
print = true;
}
}
if (keys)
{
if (strncmp(cur->classname, "key_", 4) == 0)
{
print = true;
}
}
if (monsters)
{
if (strncmp(cur->classname, "monster_", 8) == 0)
{
print = true;
}
}
if (weapons)
{
if (strncmp(cur->classname, "weapon_", 7) == 0)
{
print = true;
}
}
}
if (print)
{
/* We use dprintf() because cprintf() may flood the server... */
gi.dprintf("%s: %f %f %f\n", cur->classname, cur->s.origin[0], cur->s.origin[1], cur->s.origin[2]);
}
}
}
void void
ClientCommand(edict_t *ent) ClientCommand(edict_t *ent)
{ {
@ -1449,6 +1567,10 @@ ClientCommand(edict_t *ent)
{ {
Cmd_Teleport_f(ent); Cmd_Teleport_f(ent);
} }
else if (Q_stricmp(cmd, "listentities") == 0)
{
Cmd_ListEntities_f(ent);
}
else /* anything that doesn't match a command will be a chat */ else /* anything that doesn't match a command will be a chat */
{ {
Cmd_Say_f(ent, false, true); Cmd_Say_f(ent, false, true);