diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 998068a07..8eef23ede 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -57,6 +57,7 @@ #include "k_respawn.h" #include "k_grandprix.h" #include "doomstat.h" +#include "deh_tables.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR @@ -167,6 +168,7 @@ static void Command_LeaveParty_f(void); static void Command_Addfile(void); static void Command_ListWADS_f(void); +static void Command_ListDoomednums_f(void); static void Command_RunSOC(void); static void Command_Pause(void); static void Command_Respawn(void); @@ -642,6 +644,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("addfile", Command_Addfile); COM_AddCommand("listwad", Command_ListWADS_f); + COM_AddCommand("listmapthings", Command_ListDoomednums_f); COM_AddCommand("runsoc", Command_RunSOC); COM_AddCommand("pause", Command_Pause); @@ -4107,6 +4110,111 @@ static void Command_ListWADS_f(void) } } +#define MAXDOOMEDNUM 4095 + +static void Command_ListDoomednums_f(void) +{ + INT16 i, j, k = 0, l = 0; + INT32 argc = COM_Argc(); + INT16 table[MAXDOOMEDNUM]; + + switch (argc) + { + case 1: + l = MAXDOOMEDNUM; + break; + case 3: + l = atoi(COM_Argv(2)); + if (l < 1 || l > MAXDOOMEDNUM) + { + CONS_Printf("arg 2: doomednum \x82""%d \x85out of range (1-4095)\n", k); + return; + } + //FALLTHRU + case 2: + k = atoi(COM_Argv(1)); + if (k < 1 || k > MAXDOOMEDNUM) + { + CONS_Printf("arg 1: doomednum \x82""%d \x85out of range (1-4095)\n", k); + return; + } + if (!l) + l = k; + else if (l < k) // silently and helpfully swap. + { + j = k; + k = l; + l = j; + } + break; + default: + CONS_Printf("listmapthings: \x86too many arguments!\n"); + return; + } + + // see P_SpawnNonMobjMapThing + memset(table, 0, sizeof(table)); + for (i = 1; i <= MAXPLAYERS; i++) + table[i-1] = MT_PLAYER; // playerstarts + table[33-1] = table[34-1] = table[35-1] = MT_PLAYER; // battle/team starts + table[750-1] = table[777-1] = table[778-1] = MT_UNKNOWN; // slopes + for (i = 600; i <= 609; i++) + table[i-1] = MT_RING; // placement patterns + table[1705-1] = table[1713-1] = MT_HOOP; // types of hoop + + CONS_Printf("\x82""Checking for double defines...\n"); + for (i = 1; i < MT_FIRSTFREESLOT+NUMMOBJFREESLOTS; i++) + { + j = mobjinfo[i].doomednum; + if (j < (k ? k : 1) || j > (l ? l : MAXDOOMEDNUM)) + continue; + if (table[j-1]) + { + CONS_Printf(" doomednum \x82""%d""\x80 is \x85""double-defined\x80 by ", j); + if (i < MT_FIRSTFREESLOT) + { + CONS_Printf("\x87""hardcode %s <-- MAJOR ERROR\n", MOBJTYPE_LIST[i]); + continue; + } + CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[i-MT_FIRSTFREESLOT]); + continue; + } + table[j-1] = i; + } + CONS_Printf("\x82Printing doomednum usage...\n"); + if (!k) + { + i = 35; // skip MT_PLAYER spam + CONS_Printf(" doomednums \x82""1-35""\x80 are used by ""\x87""hardcode MT_PLAYER\n"); + } + else + i = k-1; + + for (; i < l; i++) + { + if (!table[i]) + { + if (k) + { + CONS_Printf(" doomednum \x82""%d""\x80 is \x83""free!", i+1); + if (i < 99) // above the humble crawla? how dare you + CONS_Printf(" (Don't freeslot this low...)"); + CONS_Printf("\n"); + } + continue; + } + CONS_Printf(" doomednum \x82""%d""\x80 is used by ", i+1); + if (table[i] < MT_FIRSTFREESLOT) + { + CONS_Printf("\x87""hardcode %s\n", MOBJTYPE_LIST[table[i]]); + continue; + } + CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[table[i]-MT_FIRSTFREESLOT]); + } +} + +#undef MAXDOOMEDNUM + // ========================================================================= // MISC. COMMANDS // =========================================================================