Raw model (for completeness)
{
"meta": {
"id": "04e1b6d8-0566-4542-b933-a0140d5660df",
"sha1": "dcb5c5fdcc1488b3f001321539c5c9c826c4a46d",
"sha256": "597f12e050257f0e85d2dfada56bff51da2861d865ad024ade85251c643f51d1",
"filenames": [
"doom2_the_master_levels.pk3"
],
"additional": {
"engines": [],
"iwad": [],
"filename": null,
"added": "2020-10-21 16:40:06",
"locked": false,
"canDownload": true,
"adult": false,
"hidden": false,
"name": null,
"description": null,
"maps": null,
"graphicOverrides": null,
"screenshots": {
"MAP01": "MAP01.png",
"MAP03": "MAP03.png",
"MAP05": "MAP05.png",
"MAP07": "MAP07.png",
"MAP08": "MAP08.png",
"MAP09": "MAP09.png",
"MAP25": "MAP25.png",
"MAP31": "MAP31.png",
"MAP32": "MAP32.png",
"MENU": "MENU.png",
"TITLEMAP": "TITLEMAP.png"
},
"palettes": null,
"categories": null
},
"flags": {
"locked": false,
"canDownload": true,
"adult": false,
"hidden": false
},
"added": "2020-10-21 16:40:06",
"file": {
"type": "PK3",
"size": 3734753,
"url": "https://wadarchive2.nyc3.digitaloceanspaces.com/dcb5c5fdcc1488b3f001321539c5c9c826c4a46d/dcb5c5fdcc1488b3f001321539c5c9c826c4a46d.pk3.gz",
"corrupt": false
},
"content": {
"maps": [
"ATTACK",
"BLACKTWR",
"BLOODSEA",
"CANYON",
"CATWALK",
"COMBINE",
"FISTULA",
"GARRISON",
"GERYON",
"MANOR",
"MEPHISTO",
"MINOS",
"MENU",
"NESSUS",
"PARADOX",
"SUBSPACE",
"SUBTERRA",
"TEETH",
"TEETH2",
"TITLEMAP",
"TTRAP",
"VESPERAS",
"VIRGIL"
],
"counts": {
"endoom": 0,
"graphics": 1,
"lumps": 75,
"maps": 23,
"palettes": 0
}
},
"text_files": [
{
"source": "pk3",
"name": "ANIMDEFS.txt",
"contents": "WARP TEXTURE FIRWARP"
},
{
"source": "pk3",
"name": "credits.txt",
"contents": "Master Levels Menu interface Mod Editor\n\tby Zippy\nMaster Levels Maps Mod Editor\n by DenisNinja release date Junuary 06th 2019\n\nDesigned to work with ZDoom 2.5.0, GZDoom, Zandronum equivalent,\nor above. Special thanks to Randy, Graf Zahl, and\nall contributing programmers for their respective work.\nZDoom\t- http://zdoom.org\nGZDoom\t- http://grafzahl.drdteam.org\nZandronum - https://zandronum.com\n\nSpecial thanks to id Software for Doom II.\nhttp://www.idsoftware.com/\n\nMaster Levels Menu scripting by Zippy.\n\nMaster Levels Menu... uh... \"graphics\"... by Zippy.\n\nIn-menu screenshots of the levels were taken from\nZDoom on the actual Master Levels, made by their\nrespective authors (consult the documentation that\ncame with the Master Levels for further info.)\n\nFixedSys font by whoever... Microsoft, I suppose.\nVisitation font found on http://www.1001freefonts.com.\nFonts created with bagheadspidey's doomcrap tools.\n\nLogo and M_DOOM replacement by Kaze. Thanks.\n\nHigh res skull flesh texture provided courtesy of\nJohn Romero (specifically his Formspring account.)\nhttp://planetromero.com/\n\nTitlemap and Menu music:\n D00M2(Game oveR)\n by moonwalker\n http://modarchive.org/index.php?request=view_by_moduleid&query=145832"
},
{
"source": "pk3",
"name": "LOADACS.txt",
"contents": "MSTRLVLL"
},
{
"source": "pk3",
"name": "MAPINFO.txt",
"contents": "map TITLEMAP \"Title Screen\"\n{\n\tlevelnum = 98\n\tmusic = \"D2_GMOVR\"\n}\n\nclearepisodes\nepisode MENU\n{\n\tname = \"Master Levels for Doom II\"\n\t//noskillmenu\n}\n\nmap MENU \"Menu\"\n{\n\tlevelnum = 99\n\tmusic = \"D2_GMOVR\"\n}\n\nmap ATTACK \"Attack\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 1\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 105\n\tmusic = \"D_RUNNIN\"\n}\n\nmap BLACKTWR \"Black Tower\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 2\n\tsky1 = \"RSKY3\", 0.0\n\tpar = 345\n\tmusic = \"D_ADRIAN\"\n}\n\nmap BLOODSEA \"Bloodsea Keep\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 3\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 240\n\tmusic = \"D_SHAWN\"\n\tmap07special\n}\n\nmap CANYON \"Canyon\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 4\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 105\n\tmusic = \"D_RUNNIN\"\n}\n\nmap CATWALK \"The Catwalk\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 5\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 150\n\tmusic = \"D_RUNNIN\"\n}\n\nmap COMBINE \"The Combine\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 6\n\tsky1 = \"COMBISKY\", 0.0\n\tpar = 135\n\tmusic = \"D_RUNNIN\"\n}\n\nmap FISTULA \"The Fistula\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 7\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 120\n\tmusic = \"D_RUNNIN\"\n}\n\nmap GARRISON \"The Garrison\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 8\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 165\n\tmusic = \"D_RUNNIN\"\n}\n\nmap GERYON \"Geryon: 6th Canto of INFERNO\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 9\n\tsky1 = \"GERYOSKY\", 0.0\n\tpar = 120\n\tmusic = \"D_DDTBLU\"\n}\n\nmap MANOR \"Titan Manor\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 10\n\tsky1 = \"MANORSKY\", 0.0\n\tpar = 210\n\tmusic = \"D_RUNNIN\"\n}\n\nmap MEPHISTO \"Mephisto's Maosoleum\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 11\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 210\n\tmusic = \"D_SHAWN\"\n\tmap07special\n}\n\nmap MINOS \"Minos' Judgement: 4th Canto of INFERNO\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 12\n\tsky1 = \"MINOSSKY\", 0.0\n\tpar = 120\n\tmusic = \"D_DOOM\"\n}\n\nmap NESSUS \"Nessus: 5th Canto of INFERNO\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 13\n\tsky1 = \"NESSUSKY\", 0.0\n\tpar = 45\n\tmusic = \"D_SHAWN\"\n\tmap07special\n}\n\nmap PARADOX \"Paradox\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 14\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 120\n\tmusic = \"D_RUNNIN\"\n}\n\nmap SUBSPACE \"SUBSPACE\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 15\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 105\n\tmusic = \"D_RUNNIN\"\n}\n\nmap SUBTERRA \"SUBTERRA\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 16\n\tsky1 = \"ORSKY1\", 0.0\n\tpar = 150\n\tmusic = \"D_RUNNIN\"\n}\n\nmap TEETH \"The Express Elevator to Hell\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 17\n\tsecretnext = \"TEETH2\"\n\tsky1 = \"RSKY3\", 0.0\n\tpar = 360\n\tmusic = \"D_EVIL\"\n}\n\nmap TEETH2 \"Bad Dream\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 21\n\tsky1 = \"RSKY3\", 0.0\n\tpar = 45\n\tmusic = \"D_ULTIMA\"\n}\n\nmap TTRAP \"Trapped on Titan\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 18\n\tsky1 = \"TTRAPSKY\", 0.0\n\tpar = 225\n\tmusic = \"D_RUNNIN\"\n}\n\nmap VESPERAS \"Vesperas: 7th Canto of INFERNO\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 19\n\tsky1 = \"VESPESKY\", 0.0\n\tpar = 150\n\tmusic = \"D_IN_CIT\"\n}\n\nmap VIRGIL \"Virgil's Lead: 3rd Canto of INFERNO\"\n{\n\tnext = \"MENU\"\n\tlevelnum = 20\n\tsky1 = \"VIRGISKY\", 0.0\n\tpar = 105\n\tmusic = \"D_COUNTD\"\n}"
},
{
"source": "pk3",
"name": "MasterLevelsLibrary.txt",
"contents": "#library \"MSTRLVLL\"\n#include \"zcommon.acs\"\n\n//\n// THESE LIBRARIES SCRIPTS ARE PURELY FOR MANAGING PLAY RESULT RECORDINGS AND\n// DON'T HAVE ANYTHING TO DO WITH GETPLAYERINPUT. IF YOU ARE INTERESTING IN\n// THE DEMONSTRATION OF GETPLAYERINPUT, SEE MenuLevelScripts.txt OR LOOK AT THE\n// SCRIPTS FOR MENULEVL IN Menu.wad (THEY ARE IDENTICAL).\n//\n\n// See the copy of the map scripts for definitions of the global variables\nglobal int 51:returningToMenu;\nglobal int 52:option_music;\nglobal int 53:option_inv;\n\nglobal int 54:recentPlayResults[];\n\nglobal int 55:playResults[]; // 0 if not beaten yet, 1 for beaten before\nglobal int 56:killsResults[];\nglobal int 57:killsMaxResults[];\nglobal int 58:itemsResults[];\nglobal int 59:itemsMaxResults[];\nglobal int 60:secretsResults[];\nglobal int 61:secretsMaxResults[];\nglobal int 62:timeResults[]; // int tics\nglobal int 63:timeParResults[]; // in seconds\n\n// recentPlayResults format\n// levelnum, kills, killmax, items, itemmax, secrets, secretmax, time, par\n\n#DEFINE R_LEVELNUM\t0\n#DEFINE R_KILLS\t\t1\n#DEFINE R_KILLS_MAX\t2\n#DEFINE R_ITEMS\t\t3\n#DEFINE R_ITEMS_MAX\t4\n#DEFINE R_SECRETS\t5\n#DEFINE R_SECRETS_MAX\t6\n#DEFINE R_TIME\t\t7\t// in tics\n#DEFINE R_TIME_PAR\t8\t// in seconds\n\n#DEFINE MAP_BADDREAM 21\n#DEFINE MAP_TITLEMAP 98\n#DEFINE MAP_MENU 99\n\n// When using the \"Varied music\" option, play these songs for the levels\nint newMusic[21] = {\t // Map - Default music\n\t\t\"D_RUNNIN\", // Attack - D_RUNNIN\n\t\t\"D_ADRIAN\", // Black Tower - D_ADRIAN\n\t\t\"D_SHAWN\", // Bloodsea - D_SHAWN\n\t\t\"D_THE_DA\", // Canyon - D_RUNNIN\n\t\t\"D_BETWEE\", // Catwalk - D_RUNNIN\n\t\t\"D_STALKS\", // Combine - D_RUNNIN\n\t\t\"D_AMPIE\", // Fistula - D_RUNNIN\n\t\t\"D_MESSAG\", // Garrison - D_RUNNIN\n\t\t\"D_DDTBLU\", // Geryon - D_DDTBLU\n\t\t\"D_DEAD\", // Titan Manor - D_RUNNIN\n\t\t\"D_ROMERO\", // Mephisto - D_SHAWN\n\t\t\"D_DOOM\", // Minos - D_DOOM\n\t\t\"D_SHAWN2\", // Nessus - D_SHAWN\n\t\t\"D_THEDA2\", // Paradox - D_RUNNIN\n\t\t\"D_COUNT2\", // Subspace - D_RUNNIN\n\t\t\"D_TENSE\", // Subterra - D_RUNNIN\n\t\t\"D_EVIL\", // TEETH - D_EVIL\n\t\t\"D_DDTBL2\", // Trapped - D_RUNNIN\n\t\t\"D_IN_CIT\", // Vesperas - D_IN_CIT\n\t\t\"D_COUNTD\", // Virgil - D_COUNTD\n\t\t\"D_ULTIMA\", // TEETH2 - D_ULTIMA\n\t};\n\n// Music level start script\nscript 100 OPEN\n{\n\tint levelnum = GetLevelInfo(LEVELINFO_LEVELNUM);\n\n\t// Safety check. Make sure the level is inside the array\n\t// range, to prevent the script from bombing if the user\n\t// goes to a different level. This also prevents the script\n\t// from changing music on the menu level\n\tif( levelnum > 21 )\n\t{\n\t\tterminate;\n\t}\n\n\tif( option_music )\n\t{\n\t\tSetMusic( newMusic[levelnum - 1] );\n\t}\n}\n\n// Beat a level\nscript 102 UNLOADING\n{\n\t// Special behavior: Leaving Menu level, titlemap, or \"Bad Dream\"\n\t// means don't do anything. Not worth the special coding to record\n\t// the results for \"Bad Dream\". Plus, it's a joke level, I mean come on.\n\tint levelnum = GetLevelInfo(LEVELINFO_LEVELNUM);\n\tif( levelnum == MAP_MENU || levelnum == MAP_BADDREAM )\n\t{\n\t\tterminate;\n\t}\n\n\treturningToMenu = 1;\n\n\t// Store the results of this map session\n\trecentPlayResults[R_LEVELNUM]\t = levelnum;\n\trecentPlayResults[R_KILLS]\t = GetLevelInfo(LEVELINFO_KILLED_MONSTERS);\n\trecentPlayResults[R_KILLS_MAX]\t = GetLevelInfo(LEVELINFO_TOTAL_MONSTERS);\n\trecentPlayResults[R_ITEMS]\t = GetLevelInfo(LEVELINFO_FOUND_ITEMS);\n\trecentPlayResults[R_ITEMS_MAX]\t = GetLevelInfo(LEVELINFO_TOTAL_ITEMS);\n\trecentPlayResults[R_SECRETS]\t = GetLevelInfo(LEVELINFO_FOUND_SECRETS);\n\trecentPlayResults[R_SECRETS_MAX] = GetLevelInfo(LEVELINFO_TOTAL_SECRETS);\n\trecentPlayResults[R_TIME]\t = Timer();\n\trecentPlayResults[R_TIME_PAR]\t = GetLevelInfo(LEVELINFO_PAR_TIME);\n}"
},
{
"source": "pk3",
"name": "MenuLevelScripts.txt",
"contents": "/*\n * This is a copy of the SCRIPTS lump for the menu level.\n * For easier reading.\n *\n */\n\n#include \"zcommon.acs\"\n\n// Global variables\nglobal int 51:returningToMenu; // When 1, player is returning to the menu from a map\nglobal int 52:option_music; // The \"varied music\" option\nglobal int 53:option_inv; // The \"keep inventory\" option\n\nglobal int 54:recentPlayResults[]; // Stores the kills, secrets, etc. of the last map played\nglobal int 55:playResults[]; // Which maps are beaten: 0 if not, 1 for beaten before\nglobal int 56:killsResults[]; // Stores how many kills on each map\nglobal int 57:killsMaxResults[]; // Stores the max kills of each map\nglobal int 58:itemsResults[]; // items\nglobal int 59:itemsMaxResults[]; // max items\nglobal int 60:secretsResults[]; // bleh\nglobal int 61:secretsMaxResults[]; // blah\nglobal int 62:timeResults[]; // Stores the time, in tics, played on each map\nglobal int 63:timeParResults[]; // Stores the par time, in seconds\n\n// CONSTANTS FOR THE recentPlayResults ARRAY.\n// This is what is stored at each index\n#define R_LEVELNUM\t\t0\n#define R_KILLS\t\t\t1\n#define R_KILLS_MAX\t\t2\n#define R_ITEMS\t\t\t3\n#define R_ITEMS_MAX\t\t4\n#define R_SECRETS\t\t5\n#define R_SECRETS_MAX\t6\n#define R_TIME\t\t\t7\n#define R_TIME_PAR\t\t8\n\n// CONSTANTS FOR THE wad information\n#define NUMBER_OF_WADS 20\n#define NUMBER_OF_WAD_FIELDS 4\n#define WAD_LUMPNAME 0\n#define WAD_TITLE 1\n#define WAD_AUTHOR 2\n#define WAD_IMAGELUMP 3\n// This is the data for each wad entry in the wad list\nint wadList[NUMBER_OF_WADS][NUMBER_OF_WAD_FIELDS]\n\t= {\t{ \"ATTACK\", \"Attack\", \"Tim Willits\", \"ATTKSCRN\" },\n\t\t{ \"BLACKTWR\", \"Black Tower\", \"Sverre Andre Kvernmo AKA Cranium\", \"BLTWSCRN\" },\n\t\t{ \"BLOODSEA\", \"Bloodsea Keep\", \"Sverre Andre Kvernmo AKA Cranium\", \"BDSESCRN\" },\n\t\t{ \"CANYON\", \"Canyon\", \"Tim Willits\", \"CANYSCRN\" },\n\t\t{ \"CATWALK\", \"The Catwalk\", \"Christen David Klie\", \"CATWSCRN\" },\n\t\t{ \"COMBINE\", \"The Combine\", \"Christen David Klie\", \"COMBSCRN\" },\n\t\t{ \"FISTULA\", \"The Fistula\", \"Christen David Klie\", \"FISTSCRN\" },\n\t\t{ \"GARRISON\", \"The Garrison\", \"Christen David Klie\", \"GARRSCRN\" },\n\t\t{ \"GERYON\", \"Geryon: 6th Canto of INFERNO\", \"John W. Anderson AKA Dr. Sleep\", \"GERYSCRN\" },\n\t\t{ \"MANOR\", \"Titan Manor\", \"Jim Flynn\", \"MANRSCRN\" },\n\t\t{ \"MEPHISTO\", \"Mephisto's Maosoleum\", \"Sverre Andre Kvernmo AKA Cranium\", \"MEPHSCRN\" },\n\t\t{ \"MINOS\", \"Minos' Judgement: 4th Canto of INFERNO\", \"John W. Anderson AKA Dr. Sleep\", \"MINOSCRN\" },\n\t\t{ \"NESSUS\", \"Nessus: 5th Canto of INFERNO\", \"John W. Anderson AKA Dr. Sleep\", \"NESSSCRN\" },\n\t\t{ \"PARADOX\", \"Paradox\", \"Tom Mustaine\", \"PARASCRN\"},\n\t\t{ \"SUBSPACE\" , \"SUBSPACE\", \"Christen David Klie\", \"SUBSSCRN\" },\n\t\t{ \"SUBTERRA\" , \"SUBTERRA\", \"Christen David Klie\", \"SUBTSCRN\" },\n\t\t{ \"TEETH\", \"The Express Elevator to Hell\", \"Sverre Andre Kvernmo AKA Cranium\", \"TETHSCRN\"},\n\t\t{ \"TTRAP\", \"Trapped on Titan\", \"Jim Flynn\", \"TTRPSCRN\"},\n\t\t{ \"VESPERAS\", \"Vesperas: 7th Canto of INFERNO\", \"John W. Anderson AKA Dr. Sleep\", \"VESPSCRN\" },\n\t\t{ \"VIRGIL\", \"Virgil's Lead: 3rd Canto of INFERNO\", \"John W. Anderson AKA Dr. Sleep\", \"VIRGSCRN\" }\n\t };\nint selectedIndex = 0; // Currently selected menu index\n\n// CONSTANTS FOR THE menu tabs\n#define NUMBER_OF_TABS 3\n#define TAB_WADDETAILS 0\n#define TAB_PLAYRESULTS 1\n#define TAB_OPTIONS 2\n#define LAST_HUDMSG_ID 74\nint currentTab = TAB_WADDETAILS; // The currently highlighted tab\n\n// CONSTANTS FOR THE options menu\n#define NUMBER_OF_OPTIONS 3\n#define OPT_DIFFICULTY 0\n#define OPT_MUSIC 1\n#define OPT_INVENTORY 2\nint currentOpt = OPT_DIFFICULTY; // The currently selected option\nint currentSkill; // Records the current skill level\nbool musicOpt; // The state of the MENU music option (as opposed to the global setting)\nbool invOpt; // The state of the MENU inventory option (yadda yadda)\n\n//\n// FOR THE PURPOSES OF THIS WAD SERVING AS A BASIC GETPLAYERINPUT EXAMPLE, I'M\n// GOING TO TRY TO KEEP THE GETPLAYERINPUT FUNCTIONALITY SEPERATE FROM THE\n// MASTER LEVELS RELATED THINGS (E.G. RECORDING PLAY RESULTS, ETC.).\n//\n// SO, IF YOU ARE ONLY INTERESTED IN THE GETPLAYERINPUT MENU FUNCTIONALITY, THEN\n// SCRIPT 2 IS THE ONLY THING YOU NEED CONCERN YOURSELF WITH.\n//\n\n//\n// GetPlayerInput Menu Script\n// This script is the player input loop. It's ENTER so it runs for all players,\n// but aborts shortly after player setup for all players EXCEPT player 1, who\n// will control the menu.\nscript 2 ENTER\n{\n\t// Freeze the player\n\tSetPlayerProperty(0,ON,PROP_TOTALLYFROZEN);\n\n\t// Draw the menu background\n\tSetHudSize(150,480,1);\n\tSetFont(\"WIDEBACK\"); // Widescreen background covers\n\tHudMessage(s:\"A\"; HUDMSG_PLAIN, 1001, CR_UNTRANSLATED, 0.2, 0.1, 0);\n\tHudMessage(s:\"A\"; HUDMSG_PLAIN, 1002, CR_UNTRANSLATED, 150.1, 0.1, 0);\n\tSetHudSize(640,480,1);\n\tSetFont(\"MENUBACK\");\n\tHudMessage(s:\"A\"; HUDMSG_PLAIN, 1000, CR_UNTRANSLATED, 0.1, 0.1, 0);\n\n\t// If you're not the first player, then you're done here.\n\tif( PlayerNumber() != 0 )\n\t{\n\t\tterminate;\n\t}\n\n\t// Draw all the dynamic menu elements. The wad list, the contents of the currently\n\t// viewed tab, etc.\n\tSetFont(\"FIXEDSYS\");\n\tdrawSelections();\n\n\tdelay(1); // Give a brief moment before reading player input\n\n\tint butIn; // This is the currently read player input\n\tint butOld; // This is the old player input\n\tbool held = FALSE; // Records if the player is holding a DIRECTION key down\n\tint waitTime = 0; // Generic variable used to count how many tics we wait after a press\n\n\tdelay(12); // Don't take input for a little bit just to prevent\n // accidental selection with USE on map load\n\n\t// This is the main menu loop, and it runs FOREVER. Basically, it is a loop\n\t// which checks the player's input every tic to see what keys the player has\n\t// hit/released, and determines if it should take any action based on this.\n\t//\n\t// All the actions are handled in outside functions to keep the menu loop\n\t// from being too cluttered.\n\twhile( TRUE )\n\t{\n\t\t// With this menu, the important keys are\n\t\t// LEFT, RIGHT, UP, DOWN, and USE.\n\t\t// GetPlayerInput checks what player commands are being input, not what\n\t\t// what physical buttons are being held. So, we must instead pick the\n\t\t// player inputs that will be associated with each \"key\".\n\t\t// LEFT = Strafe left OR turn left\n\t\t// RIGHT = Strafe right OR turn right\n\t\t// UP = Move forward\n\t\t// DOWN = Move backwards\n\t\t// USE = Attack 1 (primary fire) OR use\n\t\t//\n\t\t// LEFT, RIGHT, UP, and DOWN will control the player's menu selection and\n\t\t// USE will be the action button. This makes for a nice, simplistic\n\t\t// menu model:\n\t\t//\t\t1) Get player input\n\t\t//\t\t2) Check LEFT RIGHT UP DOWN and if needed move the player's cursor\n\t\t// 3) Check USE and if needed perform an action based on selection\n\t\t//\n\t\t// Checking the direction is the most difficult part of this, especially\n\t\t// if you want to support something like holding direction == fast\n\t\t// scrolling. But that's exactly what I do here.\n\t\t//\n\t\t// This implementation doesn't have complex handling of multiple inputs\n\t\t// (e.g. holding left and up at the same time) but it is robust enough\n\t\t// that it shouldn't break. Getting complex handling in wouldn't be\n\t\t// too difficult though: give the inputs each a priority and the take\n\t\t// the highest priority action in the case of input conflicts.\n\t\t//\n\t\t// Here we go.\n\n\t\t// Get the player's input\n\t\tbutIn = GetPlayerInput(0,INPUT_BUTTONS);\n\t\tbutOld = GetPlayerInput(0,INPUT_OLDBUTTONS);\n\n\t\t//==\n\t\t// This entire section manages recording if direction buttons are being held\n\t\t// and engaging FAST SCROLLING behavior if the same button is held down for\n\t\t// long enough.\n\t\t//==\n\n\t\t// If no DIRECTION key is being held...\n\t\tif( !held )\n\t\t{\n\t\t\t// Check for a DIRECTION key press.\n\t\t\tif((butIn & BT_FORWARD) ||\n\t\t\t (butIn & BT_BACK) ||\n\t\t\t (butIn & (BT_LEFT | BT_MOVELEFT)) ||\n\t\t\t (butIn & (BT_RIGHT | BT_MOVERIGHT)) )\n\t\t\t{\n\t\t\t\t// Because HELD was FALSE and DIRECTION press was positive, it\n\t\t\t\t// means the player has JUST pressed a direction\n\t\t\t\theld = TRUE; // Remember that the player has a key down\n\t\t\t\twaitTime = 14; // Wait 14 tics until we start fast scrolling\n\t\t\t}\n\t\t}\n\t\telse // DIRECTION key WAS being held...\n\t\t{\n\t\t\t// Check for a DIRECTION button release by seeing if the player's OLD\n\t\t\t// input DOES NOT MATCH their NEW input\n\t\t\tif(((butIn & BT_FORWARD) != (butOld & BT_FORWARD)) ||\n\t\t\t ((butIn & BT_BACK) != (butOld & BT_BACK)) ||\n\t\t\t ((butIn & (BT_LEFT | BT_MOVELEFT)) != (butOld & (BT_LEFT | BT_MOVELEFT))) ||\n\t\t\t ((butIn & (BT_RIGHT | BT_MOVERIGHT)) != (butOld & (BT_RIGHT | BT_MOVERIGHT))) )\n\t\t\t{\n\t\t\t // Because HELD was TRUE and there was a mismatch between the DIRECTION\n\t\t\t // key state last tic to this tic, the player has JUST released a\n\t\t\t // a direction\n\t\t\t \theld = FALSE; // The player is no longer holding down the same direction key\n\t\t\t \twaitTime = 0; // Reset the wait time to 0\n\t\t\t}\n\n\t\t\t// Button is being held, check if we still have waiting time left\n\t\t\tif( waitTime != 0 )\n\t\t\t{\n\t\t\t\t// Still waiting, decrement the waiting time and restart the loop\n\t\t\t\twaitTime--;\n\t\t\t\tdelay(1);\n\t\t\t\tcontinue; // Jump back to the top of the loop\n\t\t\t}\n\t\t\telse if (held)\n\t\t\t{ // waitTime is 0 and the button is still being held...\n\t\t\t\twaitTime = 3; // ENGAGE FAST SCROLL - wait 3 tics between selection changes\n\t\t\t}\n\t\t}\n\n\t\t//==\n\t\t// This section performs actions based on the buttons being pressed.\n\t\t//==\n\n\t\t// UP\n\t\tif( butIn & BT_FORWARD )\n\t\t{\n\t\t\tif( currentTab != TAB_OPTIONS )\n\t\t\t{\n\t\t\t\t// Outside of the options tab, hitting UP will move the currently\n\t\t\t\t// selected wad index up by 1.\n\t\t\t\tif( selectedIndex > 0 )\n\t\t\t\t{\n\t\t\t\t\tselectedIndex--;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Hit the top, loop around to the bottom\n\t\t\t\t\tselectedIndex = NUMBER_OF_WADS - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Inside the options tab, hitting UP will move the currently\n\t\t\t\t// selected option index up by 1\n\t\t\t\tif( currentOpt > 0 )\n\t\t\t\t{\n\t\t\t\t\tcurrentOpt--;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Hit the top, loop around to the bottom\n\t\t\t\t\tcurrentOpt = NUMBER_OF_OPTIONS - 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update the menu screen because something has changed\n\t\t\tdrawSelections();\n\t\t}\n\n\t\t// DOWN\n\t\tif( butIn & BT_BACK )\n\t\t{\n\t\t\tif( currentTab != TAB_OPTIONS )\n\t\t\t{\n\t\t\t\t// Outside of the options tab, hitting DOWN will move the currently\n\t\t\t\t// selected wad index down by 1.\n\t\t\t\tif( selectedIndex < NUMBER_OF_WADS-1 )\n\t\t\t\t{\n\t\t\t\t\tselectedIndex++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Hit the bottom, loop around to the top\n\t\t\t\t\tselectedIndex = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Inside the options tab, hitting DOWN will move the currently\n\t\t\t\t// selected option index down by 1\n\t\t\t\tif( currentOpt < NUMBER_OF_OPTIONS-1 )\n\t\t\t\t{\n\t\t\t\t\tcurrentOpt++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Hit the bottom, loop around to the top\n\t\t\t\t\tcurrentOpt = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update the menu screen because something has changed\n\t\t\tdrawSelections();\n\t\t}\n\n\t\t// USE\n\t\tif( butIn & (BT_ATTACK | BT_USE) )\n\t\t{\n\t\t\t// The effect of USE is going to depend on the player's selection.\n\t\t\t// OPTIONS TAB\n\t\t\t// Toggle the selected option\n\t\t\t// ANYWHERE ELSE\n\t\t\t// Change level to the currently selected wad\n\t\t\tif( currentTab != TAB_OPTIONS )\n\t\t\t{\n\t\t\t\tSetPlayerProperty(1,OFF,PROP_TOTALLYFROZEN);\n\t\t\t\tint clFlags = CHANGELEVEL_NOINTERMISSION;\n\t\t\t\tif( !option_inv )\n\t\t\t\t{\n\t\t\t\t\tclFlags = clFlags | CHANGELEVEL_RESETINVENTORY | CHANGELEVEL_RESETHEALTH;\n\t\t\t\t}\n\n\t\t\t\tChangeLevel(wadList[selectedIndex], 0, clFlags, currentSkill);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Toggle the selected option\n\t\t\t\tswitch( currentOpt )\n\t\t\t\t{\n\t\t\t\t\tcase OPT_DIFFICULTY:\n\t\t\t\t\t\t// Difficulty toggles by going up one every time it\n\t\t\t\t\t\t// is \"used\". When it hits the top, it cycles around\n\t\t\t\t\t\t// to the bottom\n\t\t\t\t\t\tif( currentSkill == SKILL_VERY_HARD )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurrentSkill = SKILL_VERY_EASY;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurrentSkill++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OPT_MUSIC:\n\t\t\t\t\t\tmusicOpt = !musicOpt; // This is the local menu option\n\t\t\t\t\t\toption_music = musicOpt; // Save it to the global variable\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OPT_INVENTORY:\n\t\t\t\t\t\tinvOpt = !invOpt; // This is the local menu option\n\t\t\t\t\t\toption_inv = invOpt; // Save it to the global variable\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Something has changed so update the menu screen\n\t\t\t\tdrawSelections();\n\n\t\t\t\t// After the player has pressed USE, force a 4 tic delay before\n\t\t\t\t// we do anymore input checks. This avoids effects like the player\n\t\t\t\t// taps USE but the input loop cycles twice and thinks the player\n\t\t\t\t// has hit it twice.\n\t\t\t\t//\n\t\t\t\t// If you need more complex handling, you will have to record when\n\t\t\t\t// the player presses and releases the USE key, like done above\n\t\t\t\t// with the DIRECTION keys.\n\t\t\t\tdelay(4);\n\t\t\t}\n\t\t}\n\n\t\t// LEFT\n\t\tif( butIn & (BT_LEFT | BT_MOVELEFT) )\n\t\t{\n\t\t\t// LEFT will always cycle the tab left by 1\n\t\t\tif( currentTab > 0 )\n\t\t\t{\n\t\t\t\tcurrentTab--;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Hit the left edge, loop around to the right\n\t\t\t\tcurrentTab = NUMBER_OF_TABS - 1;\n\t\t\t}\n\n\t\t\t// Update the menu screen because something has changed\n\t\t\tdrawSelections();\n\t\t}\n\n\t\t// RIGHT\n\t\tif( butIn & (BT_RIGHT | BT_MOVERIGHT) )\n\t\t{\n\t\t\t// RIGHT will always cycle the tab right by 1\n\t\t\tif( currentTab < NUMBER_OF_TABS-1 )\n\t\t\t{\n\t\t\t\tcurrentTab++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Hit the right edge, loop around to the left\n\t\t\t\tcurrentTab = 0;\n\t\t\t}\n\n\t\t\t// Update the menu screen because something has changed\n\t\t\tdrawSelections();\n\t\t}\n\n\t\t// Delay required to prevent runaway script and give everything a chance\n\t\t// to draw, not to mention to give an opportunity for the player's input\n\t\t// to update.\n\t\tdelay(1);\n\t}\n}\n\n//\n// FROM THIS POINT ON, GETPLAYERINPUT IS NO LONGER USED. THE REST OF THE\n// SCRIPTS ARE FOR THE SPECIFICALLY HANDLING OF DRAWING THE MENU, ETC.\n//\n\n// OPEN setup script.\n// Setup some menu variables and if the players have just returned from\n// playing a map, display their play results to them.\nscript 1 OPEN\n{\n\tcurrentSkill = GameSkill();\n\n\t// When returning to the menu from a level playthrough, record our play results\n\tif( returningToMenu )\n\t{\n\t\t// Go to play results tab and make sure the last played map is selected\n\t\tselectedIndex = recentPlayResults[R_LEVELNUM] - 1;\n\t\tcurrentTab = TAB_PLAYRESULTS;\n\n\t\t// Calculate percentage scores. If there were 0 maximum it counts as\n\t\t// 100% instead of... divide by zero error%.\n\t\tint killPer = 100;\n\t\tint itemPer = 100;\n\t\tint secrPer = 100;\n\t\tif( recentPlayResults[R_KILLS_MAX] > 0 )\n\t\t{\n\t\t\tkillPer = 100 * recentPlayResults[R_KILLS] / recentPlayResults[R_KILLS_MAX];\n\t\t}\n\t\tif( recentPlayResults[R_ITEMS_MAX] > 0 )\n\t\t{\n\t\t\titemPer = 100 * recentPlayResults[R_ITEMS] / recentPlayResults[R_ITEMS_MAX];\n\t\t}\n\t\tif( recentPlayResults[R_SECRETS_MAX] > 0 )\n\t\t{\n\t\t\tsecrPer = 100 * recentPlayResults[R_SECRETS] / recentPlayResults[R_SECRETS_MAX];\n\t\t}\n\n\t\t// Calculate the level and par time as hours, minutes, seconds\n\t\tint timeInSec = recentPlayResults[R_TIME] / 35;\n\t\tint timeH = timeInSec / 3600;\n\t\tint timeM = (timeInSec / 60) - (60 * timeH);\n\t\tint timeS = timeInSec - (3600 * timeH) - (60 * timeM);\n\t\tint temp = recentPlayResults[R_TIME_PAR];\n\t\tint ptimeH = temp / 3600;\n\t\tint ptimeM = (temp / 60) - (60 * ptimeH);\n\t\tint ptimeS = temp - (3600 * ptimeH) - (60 * ptimeM);\n\n\t\t// Print out the results from this playthrough (the normal Play Results\n\t\t// tab drawing will take care of drawing the Best results)\n\t\tSetHudSize(640,480,1);\n\t\tSetFont(\"FIXEDSYS\");\n\n\t\t// General layout\n\t\tHudMessageBold(s:\"Kills : / %\\n\",\n\t\t\t\t s:\"Items : / %\\n\",\n\t\t\t\t s:\"Secrets: / %\\n\",\n\t\t\t\t s:\"Time : Par:\";\n\t\t\tHUDMSG_PLAIN, 63, CR_WHITE, 205.1, 170.1, 0);\n\n\t\t// Numerical player results\n\t\tHudMessageBold(d:recentPlayResults[R_KILLS];\n\t\t\tHUDMSG_PLAIN, 64, CR_WHITE, 309.2, 170.1, 0);\n\t\tHudMessageBold(d:recentPlayResults[R_ITEMS];\n\t\t\tHUDMSG_PLAIN, 65, CR_WHITE, 309.2, 185.1, 0);\n\t\tHudMessageBold(d:recentPlayResults[R_SECRETS];\n\t\t\tHUDMSG_PLAIN, 66, CR_WHITE, 309.2, 200.1, 0);\n\n\t\t// Numerical level maximums\n\t\tHudMessageBold(d:recentPlayResults[R_KILLS_MAX];\n\t\t\tHUDMSG_PLAIN, 67, CR_WHITE, 365.2, 170.1, 0);\n\t\tHudMessageBold(d:recentPlayResults[R_ITEMS_MAX];\n\t\t\tHUDMSG_PLAIN, 68, CR_WHITE, 365.2, 185.1, 0);\n\t\tHudMessageBold(d:recentPlayResults[R_SECRETS_MAX];\n\t\t\tHUDMSG_PLAIN, 69, CR_WHITE, 365.2, 200.1, 0);\n\n\t\t// Percentages\n\t\tHudMessageBold(d:killPer;\n\t\t\tHUDMSG_PLAIN, 70, CR_WHITE, 413.2, 170.1, 0);\n\t\tHudMessageBold(d:itemPer;\n\t\t\tHUDMSG_PLAIN, 71, CR_WHITE, 413.2, 185.1, 0);\n\t\tHudMessageBold(d:secrPer;\n\t\t\tHUDMSG_PLAIN, 72, CR_WHITE, 413.2, 200.1, 0);\n\n\t\t// Time and Par\n\t\tHudMessageBold(d:timeH, s:\"h:\", d:timeM, s:\"m:\", d:timeS, s:\"s\";\n\t\t\tHUDMSG_PLAIN, 73, CR_WHITE, 365.2, 215.1, 0);\n\t\tHudMessageBold(d:ptimeH, s:\"h:\", d:ptimeM, s:\"m:\", d:ptimeS, s:\"s\";\n\t\t\tHUDMSG_PLAIN, 74, CR_WHITE, 517.2, 215.1, 0);\n\n\t\t// Obligitory delay to let the rest of the drawing occur, including\n\t\t// displaying the old BEST result\n\t\tdelay(1);\n\n\t\t// Store these play results if they are better than\n\t\t// the best previous playthrough or if this is the first playthrough.\n\t\t// We aren't counting time, only percentages.\n\t\t// So a playthrough's \"score\" is just the sum of the percentages.\n\t\tbool save = TRUE;\n\t\tif( playResults[selectedIndex] != 0 )\n\t\t{\n\t\t\tint oldKill = 100;\n\t\t\tint oldItem = 100;\n\t\t\tint oldSecr = 100;\n\t\t\tif( killsMaxResults[selectedIndex] > 0 )\n\t\t\t{\n\t\t\t\toldKill = 100 * killsResults[selectedIndex] / killsMaxResults[selectedIndex];\n\t\t\t}\n\t\t\tif( itemsMaxResults[selectedIndex] > 0 )\n\t\t\t{\n\t\t\t\toldItem = 100 * itemsResults[selectedIndex] / itemsMaxResults[selectedIndex];\n\t\t\t}\n\t\t\tif( secretsMaxResults[selectedIndex] > 0 )\n\t\t\t{\n\t\t\t\toldSecr = 100 * secretsResults[selectedIndex] / secretsMaxResults[selectedIndex];\n\t\t\t}\n\n\t\t\t// Did you do worse?\n\t\t\tif( killPer + itemPer + secrPer < oldKill + oldItem + oldSecr )\n\t\t\t{\n\t\t\t\tsave = FALSE;\n\n\t\t\t\t// YOU FAIL IT!\n\t\t\t\tHudMessageBold(s:\"Better luck next time!\";\n\t\t\t\t\tHUDMSG_PLAIN, 54, CR_WHITE, 173.1, 260.1, 0);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Record that we have beaten this map\n\t\t\tplayResults[selectedIndex] = 1;\n\n\t\t\t// Draw the beaten marker (necessary because we are past the delay()\n\t\t\t// statement, so main drawing is already done\n\t\t\tHudMessageBold(s:\"*\"; HUDMSG_PLAIN, 0, CR_GREEN, 21.1, 35.1 + ((15*selectedIndex)<<16), 0);\n\t\t}\n\n\t\tif (save)\n\t\t{\n\t\t\tkillsResults[selectedIndex] = recentPlayResults[R_KILLS];\n\t\t\tkillsMaxResults[selectedIndex] = recentPlayResults[R_KILLS_MAX];\n\t\t\titemsResults[selectedIndex] = recentPlayResults[R_ITEMS];\n\t\t\titemsMaxResults[selectedIndex] = recentPlayResults[R_ITEMS_MAX];\n\t\t\tsecretsResults[selectedIndex] = recentPlayResults[R_SECRETS];\n\t\t\tsecretsMaxResults[selectedIndex] = recentPlayResults[R_SECRETS_MAX];\n\t\t\ttimeResults[selectedIndex] = recentPlayResults[R_TIME];\n\t\t\ttimeParResults[selectedIndex] = recentPlayResults[R_TIME_PAR];\n\t\t\tHudMessageBold(s:\"New record! Nice work!\";\n\t\t\t\tHUDMSG_PLAIN, 54, CR_WHITE, 173.1, 260.1, 0);\n\t\t}\n\n\t\t// End play results\n\t\treturningToMenu = 0;\n\t}\n\telse\n\t{\n\t\t// This is the FIRST time loading the level menu, e.g. just starting\n\t\t// a new game. Set the DEFAULT OPTIONS.\n\t\toption_music = TRUE;\n\t\toption_inv = FALSE;\n\t}\n\n\t// Set options on map load\n\tmusicOpt = option_music;\n\tinvOpt = option_inv;\n}\n\n//\n// THESE NAMED FUNCTIONS ARE USED AT VARIOUS POINTS TO DO THE DRAWING OF THE MENU.\n// THE MAIN FUNCTION IS drawSelections, WHICH WILL BASICALLY DRAW THE ENTIRE MENU\n// FOREGROUND, INCLUDING TABS.\n//\n\n// Draw everything\nfunction int drawSelections(void)\n{\n\t// Draw the wad selection list on the left\n\tint y = 35.1;\n\tfor( int i = 0; i < NUMBER_OF_WADS; i++ )\n\t{\n\t\tHudMessageBold(s:wadList[i][WAD_LUMPNAME], s:\".WAD\";\n\t\t\tHUDMSG_PLAIN, i+1, CR_WHITE, 127.2, y, 0);\n\t\tif( playResults[i] == 1 )\n\t\t{\n\t\t\tHudMessageBold(s:\"*\"; HUDMSG_PLAIN, 0, CR_GREEN, 21.1, y, 0);\n\t\t}\n\t\tif( i == selectedIndex )\n\t\t{\n\t\t\tSetFont(\"SELETION\");\n\t\t\tHudMessageBold(s:\"A\";\n\t\t\t\tHUDMSG_PLAIN, 999, CR_UNTRANSLATED, 31.1, y+2.0, 0);\n\t\t\tSetFont(\"FIXEDSYS\");\n\t\t}\n\t\ty += 15.0;\n\t}\n\n\t// Draw the tab headers\n\tHudMessageBold(s:\"WAD DETAILS\"; HUDMSG_PLAIN, 100,\n\t\tgetTabNameColor(TAB_WADDETAILS), 141.1, 21.1, 0);\n\tHudMessageBold(s:\"PLAY RESULTS\"; HUDMSG_PLAIN, 101,\n\t\tgetTabNameColor(TAB_PLAYRESULTS), 239.1, 21.1, 0);\n\tHudMessageBold(s:\"OPTIONS\"; HUDMSG_PLAIN, 102,\n\t\tgetTabNameColor(TAB_OPTIONS), 345.1, 21.1, 0);\n\n\t// Draw the difficulty indicator\n\tswitch( currentSkill )\n\t{\n\tcase SKILL_VERY_EASY:\n\t\tHudMessageBold(s:\"ITYTD\"; HUDMSG_PLAIN, 200, CR_DARKGREEN,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\tcase SKILL_EASY:\n\t\tHudMessageBold(s:\"HNTR\"; HUDMSG_PLAIN, 200, CR_BLUE,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\tcase SKILL_NORMAL:\n\t\tHudMessageBold(s:\"HMP\"; HUDMSG_PLAIN, 200, CR_YELLOW,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\tcase SKILL_HARD:\n\t\tHudMessageBold(s:\"UV\"; HUDMSG_PLAIN, 200, CR_ORANGE,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\tcase SKILL_VERY_HARD:\n\t\tHudMessageBold(s:\"NM\"; HUDMSG_PLAIN, 200, CR_RED,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\tdefault:\n\t\t// This should NEVER happen\n\t\tHudMessageBold(s:\"???\"; HUDMSG_PLAIN, 200, CR_BROWN,\n\t\t\t586.1, 454.1, 0);\n\t\tbreak;\n\t}\n\n\t// Draw the current tab details.\n\t// In order to avoid bloating this function, these details will be\n\t// exported to other functions.\n\tif( currentTab == TAB_WADDETAILS )\n\t{\n\t\tdrawWadDetails();\n\t}\n\telse if ( currentTab == TAB_PLAYRESULTS )\n\t{\n\t\tdrawWadPlayResults();\n\t}\n\telse\n\t{ // TAB_OPTIONS\n\t\tdrawOptions();\n\t}\n\n\treturn 0;\n}\n\n// Checks the given tab (by index) and returns the color that tab name should\n// be drawn in.\n// Used by drawSelections().\nfunction int getTabNameColor(int tab)\n{\n\tif( tab == currentTab )\n\t{\n\t\treturn CR_WHITE;\n\t}\n\n\treturn CR_BLACK;\n}\n\n// Draws the contents of the drawWadDetails tab, based upon the currently\n// selected wad (selectedIndex)\nfunction int drawWadDetails(void)\n{\n\tHudMessageBold(s:\"File : \", s:wadList[selectedIndex][WAD_LUMPNAME], s:\".WAD\\n\",\n\t\t\t s:\"Title : \", s:wadList[selectedIndex][WAD_TITLE], s:\"\\n\",\n\t\t\t s:\"Author: \", s:wadList[selectedIndex][WAD_AUTHOR];\n\t\tHUDMSG_PLAIN, 50, CR_WHITE, 141.1, 35.1, 0);\n\tSetHudSize(1280,960,1);\n\tSetFont(wadList[selectedIndex][WAD_IMAGELUMP]);\n\tHudMessageBold(s:\"A\";\n\t\tHUDMSG_PLAIN, 51, CR_UNTRANSLATED, 900.1, 625.1, 0);\n\tSetFont(\"SCRNBACK\");\n\tHudMessageBold(s:\"A\";\n\t\tHUDMSG_PLAIN, 53, CR_UNTRANSLATED, 896.1, 621.1, 0);\n\tSetFont(\"FixedSys\");\n\tSetHudSize(640,480,1);\n\n\tswitch( selectedIndex )\n\t{\n\t\tcase 1: // Black Tower\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"You were once the biggest and baddest Cyber-demon to rule\\n\",\n\t\t\t\t\t s:\"Hell. Betrayed by your council, \\\"The Cabal\\\", you find\\n\",\n\t\t\t\t\t s:\"yourself victim to the utmost humilation: morphed into a\\n\",\n\t\t\t\t\t s:\"human! Of course you're out for revenge on \\\"The Cabal\\\".\\n\\n\",\n\t\t\t\t\t s:\"You're nearing the end of your journey. Chagrin, the ruler\\n\",\n\t\t\t\t\t s:\"of the Black Tower, was the closest thing you had to a\\n\",\n\t\t\t\t\t s:\"friend as a demon. \\\"Oil runs thicker than blood\\\" the two of\\n\",\n\t\t\t\t\t s:\"you used to say. Well, now your buddy rules the hordes of\\n\",\n\t\t\t\t\t s:\"Hell previously under your command and has left you for\\n\",\n\t\t\t\t\t s:\"dead. The task is simple: ascend the Black Tower and slay\\n\",\n\t\t\t\t\t s:\"Chagrin. Then there is problem of getting back out...\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 2: // Bloodsea\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"You were once the biggest and baddest Cyber-demon to rule\\n\",\n\t\t\t\t\t s:\"Hell. Betrayed by your council, \\\"The Cabal\\\", you find\\n\",\n\t\t\t\t\t s:\"yourself victim to the utmost humilation: morphed into a\\n\",\n\t\t\t\t\t s:\"human! Of course you're out for revenge on \\\"The Cabal\\\".\\n\\n\",\n\t\t\t\t\t s:\"\\\"Bloodsea Keep\\\" is the home of your past advisor,\\n\",\n\t\t\t\t\t s:\"Veavitdpoh. After being dumped into the \\\"Sea of Blood\\\"\\n\",\n\t\t\t\t\t s:\"following your humiliating transformation into a human, you\\n\",\n\t\t\t\t\t s:\"swim until you come to the keep pier. All who enter\\n\",\n\t\t\t\t\t s:\"\\\"Bloodsea Keep\\\" fall victim to your former advisor's\\n\",\n\t\t\t\t\t s:\"favorite pastime: torture.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 8: // Geryon\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"GERYON is the 6th Canto in Dr. Sleep's INFERNO series.\\n\\n\",\n\t\t\t\t\t s:\"This level is a little more spread out than previous\\n\",\n\t\t\t\t\t s:\"efforts, but it provides for a nice and leisurely jaunt\\n\",\n\t\t\t\t\t s:\"through Hell.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 9: // Titan Manor\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"A strange and enigmatic building on a moon of Saturn\\n\",\n\t\t\t\t\t s:\"contains the latest in alien weapons technology. If you\\n\",\n\t\t\t\t\t s:\"can survive the guards and solve the puzzles, the\\n\",\n\t\t\t\t\t s:\"Federation will leapfrog in technology. It's all up to\\n\",\n\t\t\t\t\t s:\"you.\\n\\nOh, and watch those windows!\";\n\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 10: // Mephisto\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"You were once the biggest and baddest Cyber-demon to rule\\n\",\n\t\t\t\t\t s:\"Hell. Betrayed by your council, \\\"The Cabal\\\", you find\\n\",\n\t\t\t\t\t s:\"yourself victim to the utmost humilation: morphed into a\\n\",\n\t\t\t\t\t s:\"human! Of course you're out for revenge on \\\"The Cabal\\\".\\n\\n\",\n\t\t\t\t\t s:\"You have reached the grave of an old friend and mentor:\\n\",\n\t\t\t\t\t s:\"Mephisto. In the past there was an incident with an\\n\",\n\t\t\t\t\t s:\"earthling marine that lost him a lot of credit in Hell.\\n\",\n\t\t\t\t\t s:\"So, you had him kicked off the throne. His immortal soul\\n\",\n\t\t\t\t\t s:\"was kept as a member of \\\"The Cabal\\\" though, and so he was\\n\",\n\t\t\t\t\t s:\"in on your betrayal. Time to enter his tomb and lay the\\n\",\n\t\t\t\t\t s:\"old man down to rest for good.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 11: // Minos\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"MINOS'S JUDGEMENT is the 4th Canto in Dr. Sleep's INFERNO\\n\",\n\t\t\t\t\t s:\"series.\\n\\n\",\n\t\t\t\t\t s:\"In your search for Beatrice, your guide, Virgil (the\\n\",\n\t\t\t\t\t s:\"beatnik space-poet) has just successfully lead you through\\n\",\n\t\t\t\t\t s:\"the First Circle of Hades -- only to bring you to the court\\n\",\n\t\t\t\t\t s:\"of Minos, the Judge of Hell. \\\"Well,\\\" you say, \\\"this is\\n\",\n\t\t\t\t\t s:\"another fine mess you've gotten us into. Now what?\\\"\\n\",\n\t\t\t\t\t s:\"Virgil, with his usual loquacity, replies, \\\"Heh heh.\\\"\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 12: // Nessus\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"NESSUS is the 5th Canto in Dr. Sleep's INFERNO series.\\n\\n\",\n\t\t\t\t\t s:\"Minos decided to grant you leniency and not kill you until\\n\",\n\t\t\t\t\t s:\"next week. In the meantime, you and Virgil come to a\\n\",\n\t\t\t\t\t s:\"precipice overlooking the river Phlegethon. You grab\\n\",\n\t\t\t\t\t s:\"Virgil and climb down some boulders to the foot of the\\n\",\n\t\t\t\t\t s:\"cliff where Chiron, the chief Centaur, offers to have\\n\",\n\t\t\t\t\t s:\"Nessus carry you across the river on his shoulders. \\\"Why,\\n\",\n\t\t\t\t\t s:\"that's mighty white of ya,\\\" says Virgil. \\\"No problem,\\n\",\n\t\t\t\t\t s:\"sailor,\\\" says Nessus. \\\"Hop on.\\\"\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 13: // Paradox\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"Extreme planning went into the play flow on this level.\\n\",\n\t\t\t\t\t s:\"The archeticture is designed around a large castle with\\n\",\n\t\t\t\t\t s:\"guard towers that hold each access key. The level is\\n\",\n\t\t\t\t\t s:\"extremtly non-linear to allow for the player to choose a\\n\",\n\t\t\t\t\t s:\"varied path each time. Ammo and health is placed in key\\n\",\n\t\t\t\t\t s:\"positions, not enough to be wasteful, but more than enough\\n\",\n\t\t\t\t\t s:\"to finish the level from a pistol start.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 16: // TEETH\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"You were once the biggest and baddest Cyber-demon to rule\\n\",\n\t\t\t\t\t s:\"Hell. Betrayed by your council, \\\"The Cabal\\\", you find\\n\",\n\t\t\t\t\t s:\"yourself victim to the utmost humilation: morphed into a\\n\",\n\t\t\t\t\t s:\"human! Of course you're out for revenge on \\\"The Cabal\\\".\\n\\n\",\n\t\t\t\t\t s:\"When the \\\"Express Elevator to Hell\\\" starts descending \\\"The\\n\",\n\t\t\t\t\t s:\"Cabal\\\" has begun to realize you might be a threat to them,\\n\",\n\t\t\t\t\t s:\"human or not. Half way down the shaft that should have\\n\",\n\t\t\t\t\t s:\"taken you to the deepest pits\tof Hell, the lift first slows\\n\",\n\t\t\t\t\t s:\"down before it jerks to a halt. It's an ambush! Survive\\n\",\n\t\t\t\t\t s:\"the initial onslaught and find a gateway out of the now\\n\",\n\t\t\t\t\t s:\"sealed elevator. Tough,\tbut that's the way you like it.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 17: // Trapped\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"Every step you take may be your last. If it looks too\\n\",\n\t\t\t\t\t s:\"easy, it probably isn't. Good luck - you'll need it.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 18: // Vesperas\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"VESPERAS is the 7th Canto in Dr. Sleep's INFERNO series.\\n\\n\",\n\t\t\t\t\t s:\"\\\"Vesperas\\\" (or \\\"vespers\\\"): an evening ceremony. \\\"Now it's\\n\",\n\t\t\t\t\t s:\"dark.\\\"\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tcase 19: // Virgil\n\t\t\tHudMessageBold(\n\t\t\t\t\t s:\"VIRGIL'S LEAD is the 3th Canto in Dr. Sleep's INFERNO\\n\",\n\t\t\t\t\t s:\"series.\\n\\n\",\n\t\t\t\t\t s:\"In your search for Beatrice, you lost your guide Virgil\\n\",\n\t\t\t\t\t s:\"(the beatnik space-poet) while crossing Acheron. But you've\\n\",\n\t\t\t\t\t s:\"caught up with him again, and he's agreed to lead you\\n\",\n\t\t\t\t\t s:\"through the current way-station. \\\"You can get a lot\\n\",\n\t\t\t\t\t s:\"further with a kind word and a gun then you can with a kind\\n\",\n\t\t\t\t\t s:\"word,\\\" you tell Virgil. \\\"You belong to the NRA, don't\\n\",\n\t\t\t\t\t s:\"you?\\\" Virgil asks. \\\"No, I'm just a pessimistic pacifist.\\\"\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Every other map that came with the Master Levels wasn't given any kind\n\t\t\t// of detailed description, so we'll fall back to that for all the other maps.\n\t\t\tHudMessageBold(s:\"No extra details given.\";\n\t\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 141.1, 95.1, 0);\n\t\t\tbreak;\n\t}\n\n\t// Clean up unused HudMessages\n\thmCleanUp(54);\n\n\treturn 0;\n}\n\n// Draws the contents of the Play Results tab. This WON'T draw the recent\n// play results when coming back from a map (that is done in the OPEN script).\nfunction int drawWadPlayResults(void)\n{\n\tHudMessageBold(s:wadList[selectedIndex][WAD_LUMPNAME], s:\".WAD : \",\n\t\t\t s:wadList[selectedIndex][WAD_TITLE], s:\"\\n\\n\",\n\t\t\t s:\" Best Play Results:\";\n\t\tHUDMSG_PLAIN, 50, CR_WHITE, 141.1, 35.1, 0);\n\n\t// If this map has been beaten (and therefore must have play results)...\n\tif( playResults[selectedIndex] == 1 )\n\t{\n\t\t// Calculate percentage scores. If there were 0 maximum it counts as\n\t\t// 100% instead of... divide by zero error%.\n\t\tint killPer = 100;\n\t\tint itemPer = 100;\n\t\tint secrPer = 100;\n\t\tif( killsMaxResults[selectedIndex] > 0 )\n\t\t{\n\t\t\tkillPer = 100 * killsResults[selectedIndex] / killsMaxResults[selectedIndex];\n\t\t}\n\t\tif( itemsMaxResults[selectedIndex] > 0 )\n\t\t{\n\t\t\titemPer = 100 * itemsResults[selectedIndex] / itemsMaxResults[selectedIndex];\n\t\t}\n\t\tif( secretsMaxResults[selectedIndex] > 0 )\n\t\t{\n\t\t\tsecrPer = 100 * secretsResults[selectedIndex] / secretsMaxResults[selectedIndex];\n\t\t}\n\n\t\t// Calculate the level and par time as hours, minutes, seconds\n\t\tint timeInSec = timeResults[selectedIndex] / 35;\n\t\tint timeH = timeInSec / 3600;\n\t\tint timeM = (timeInSec / 60) - (60 * timeH);\n\t\tint timeS = timeInSec - (3600 * timeH) - (60 * timeM);\n\t\tint temp = timeParResults[selectedIndex];\n\t\tint ptimeH = temp / 3600;\n\t\tint ptimeM = (temp / 60) - (60 * ptimeH);\n\t\tint ptimeS = temp - (3600 * ptimeH) - (60 * ptimeM);\n\n\t\t// General layout\n\t\tHudMessageBold(s:\"Kills : / %\\n\",\n\t\t\t\t s:\"Items : / %\\n\",\n\t\t\t\t s:\"Secrets: / %\\n\",\n\t\t\t\t s:\"Time : Par:\";\n\t\t\tHUDMSG_PLAIN, 51, CR_WHITE, 205.1, 80.1, 0);\n\n\t\t// Numerical player results\n\t\tHudMessageBold(d:killsResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 52, CR_WHITE, 309.2, 80.1, 0);\n\t\tHudMessageBold(d:itemsResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 53, CR_WHITE, 309.2, 95.1, 0);\n\t\tHudMessageBold(d:secretsResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 54, CR_WHITE, 309.2, 110.1, 0);\n\n\t\t// Numerical level maximums\n\t\tHudMessageBold(d:killsMaxResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 55, CR_WHITE, 365.2, 80.1, 0);\n\t\tHudMessageBold(d:itemsMaxResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 56, CR_WHITE, 365.2, 95.1, 0);\n\t\tHudMessageBold(d:secretsMaxResults[selectedIndex];\n\t\t\tHUDMSG_PLAIN, 57, CR_WHITE, 365.2, 110.1, 0);\n\n\t\t// Percentages\n\t\tHudMessageBold(d:killPer;\n\t\t\tHUDMSG_PLAIN, 58, CR_WHITE, 413.2, 80.1, 0);\n\t\tHudMessageBold(d:itemPer;\n\t\t\tHUDMSG_PLAIN, 59, CR_WHITE, 413.2, 95.1, 0);\n\t\tHudMessageBold(d:secrPer;\n\t\t\tHUDMSG_PLAIN, 60, CR_WHITE, 413.2, 110.1, 0);\n\n\t\t// Time and Par\n\t\tHudMessageBold(d:timeH, s:\"h:\", d:timeM, s:\"m:\", d:timeS, s:\"s\";\n\t\t\tHUDMSG_PLAIN, 61, CR_WHITE, 365.2, 125.1, 0);\n\t\tHudMessageBold(d:ptimeH, s:\"h:\", d:ptimeM, s:\"m:\", d:ptimeS, s:\"s\";\n\t\t\tHUDMSG_PLAIN, 62, CR_WHITE, 517.2, 125.1, 0);\n\n\t\t// If the player has 300% total, display \"Rock, rock on!\"\n\t\t// ....... nah.......\n\t}\n\telse\n\t{\n\t\t// Players have not beaten this map yet\n\t\tHudMessageBold(s:\"NO RESULTS TO DISPLAY\";\n\t\t HUDMSG_PLAIN, 51, CR_WHITE, 205.1, 80.1, 0);\n\n\t\t// Only clean up HudMessages if we aren't just coming back from a level\n\t\tif( !returningToMenu )\n\t\t{\n\t\t\thmCleanUp(52);\n\t\t}\n\t}\n\n\t// If you haven't just come back from a level, clean up the extraneous hudmessages.\n\tif( !returningToMenu )\n\t{\n\t\thmCleanup(63);\n\t}\n\n\treturn 0;\n}\n\n// Draws the contents of the options tab\nfunction int drawOptions(void)\n{\n\t// Draw the static text and the little *'s that show the current value of\n\t// each option\n\tHudMessageBold(\n\t\t\t s:\"-- DIFFICULTY --\\n\",\n\t\t\t s:\" [ ] I'm too young to die\\n\",\n\t\t\t s:\" [ ] Hey, not too rough\\n\",\n\t\t\t s:\" [ ] Hurt me plenty\\n\",\n\t\t\t s:\" [ ] Ultra-violence\\n\",\n\t\t\t s:\" [ ] NIGHTMARE!\\n\";\n\t\tHUDMSG_PLAIN, 50, CR_WHITE, 165.1, 35.1, 0);\n\tHudMessageBold(s:\"*\";\n\t\tHUDMSG_PLAIN, 51, CR_RED, 205.1, 50.1 + ((currentSkill*15)<<16), 0);\n\tHudMessageBold(s:\"-- VARIED MUSIC --\\n\",\n\t\t\t s:\" [ ] On [ ] Off\";\n\t\tHUDMSG_PLAIN, 52, CR_WHITE, 165.1, 140.1, 0);\n\tHudMessageBold(s:\"*\";\n\t\tHUDMSG_PLAIN, 53, CR_RED, 285.1 - ((musicOpt*80)<<16), 155.1, 0);\n\tHudMessageBold(s:\"-- KEEP INVENTORY --\\n\",\n\t\t\t s:\" [ ] On [ ] Off\";\n\t\tHUDMSG_PLAIN, 54, CR_WHITE, 165.1, 185.1, 0);\n\tHudMessageBold(s:\"*\";\n\t\tHUDMSG_PLAIN, 55, CR_RED, 285.1 - ((invOpt*80)<<16), 200.1, 0);\n\n\t// Draw selected option arrow\n\tint yOff = 35.1;\n\tif( currentOpt == OPT_MUSIC ) { yOff = 140.1; }\n\tif( currentOpt == OPT_INVENTORY ) { yOff = 185.1; }\n\n\tHudMessage(s:\"->\";\n\t\t\tHUDMSG_PLAIN, 56, CR_GREEN, 141.1, yOff, 0);\n\n\t// Clean up any unused HudMessages\n\thmCleanUp(57);\n\n\treturn 0;\n}\n\n// Cleans up unused HudMessages, starting at the given on and going to the maximum\n// foreground HudMessage. This is useful when drawing tabs. If the player changes\n// tabs it will make sure the screen is clear of details from tab to tab.\nfunction int hmCleanUp(int startId)\n{\n\tfor( int i = startId; i <= LAST_HUDMSG_ID; i++ )\n\t{\n\t\tHudMessageBold(s:\"\";\n\t\t\tHUDMSG_PLAIN, i, CR_WHITE, 0.0, 0.0, 0);\n\t}\n\n\treturn 0;\n}"
},
{
"source": "pk3",
"name": "TEXTURES.txt",
"contents": "graphic M_DOOM, 740, 127\n{\n\tXScale 3.3\n\tYScale 2.7\n\tOffset 143, -24\n\tPatch M_TITLE, 0, 0\n}\n\ntexture TTLBACK, 1024, 512\n{\n\tXScale 4.0\n\tYScale 4.0\n\tOffset 0, 0\n\tPatch TTLBCKHI, 0, 0\n}\n\ntexture FIRWARP, 256, 256\n{\n\tXScale 2.0\n\tYScale 2.0\n\tOffset 0, 0\n\tPatch W65B_1, 0, 0\n\tPatch W65B_1, 128, 0\n\tPatch W65B_1, 0, 128\n\tPatch W65B_1, 128, 128\n}"
}
]
},
"maps": [
{
"map": "MAP01",
"title": "MAP01",
"format": "doom",
"stats": {
"things": 478,
"linedefs": 1720,
"sidedefs": 2541,
"vertices": 1819,
"sectors": 326,
"segs": 2983,
"ssectors": 1153,
"nodes": 1152,
"textures": {
"FLOOR6_1": 1,
"WOOD6": 5,
"SW1ROCK": 2,
"SPCDOOR4": 1,
"BSTONE1": 213,
"SW1WOOD": 3,
"ZIMMER3": 22,
"FLOOR4_6": 1,
"GRAY2": 4,
"CEMENT8": 6,
"STONE6": 79,
"FLOOR0_2": 9,
"SPCDOOR2": 2,
"CEIL4_2": 6,
"MARBLE3": 35,
"LITE3": 8,
"GRNROCK": 136,
"METAL2": 31,
"GRAY1": 11,
"MFLR8_2": 24,
"ROCK2": 244,
"FLAT1_1": 4,
"FLOOR0_3": 1,
"BIGBRIK1": 5,
"PANCASE1": 1,
"BRICK11": 35,
"GRASS2": 1,
"FLOOR7_1": 11,
"TEKGREN4": 13,
"FLAT19": 21,
"PANBORD1": 26,
"RROCK03": 4,
"TEKBRON2": 6,
"WOODGARG": 1,
"STEP2": 2,
"WOOD5": 4,
"FLAT23": 34,
"STONE5": 1,
"CEIL3_3": 26,
"FWATER1": 3,
"STEP5": 2,
"SUPPORT3": 140,
"TEKLITE": 18,
"WOOD1": 185,
"PANBORD2": 8,
"ceil4_3": 1,
"ZIMMER2": 56,
"SW1MET2": 1,
"TEKGREN5": 11,
"COMPBLUE": 3,
"DOORRED2": 2,
"SUPPORT2": 37,
"SW1ZIM": 1,
"DEM1_5": 38,
"FLAT1_2": 1,
"MARBLE1": 48,
"TEKBRON1": 1,
"RROCK11": 6,
"BLAKWAL1": 13,
"STUCCO1": 40,
"SPACEW2": 2,
"WOODMET1": 32,
"SW1GRAY": 1,
"FLAT1": 24,
"METAL7": 8,
"METAL6": 8,
"PANBOOK": 5,
"GRNLITE1": 15,
"METAL4": 4,
"SW1MARB": 5,
"FLAT5_4": 30,
"WOOD12": 39,
"SW1EXIT": 1,
"TEKGREN3": 2,
"EXITSIGN": 2,
"DOORSTOP": 8,
"TEKGREN2": 114,
"TEKWALL1": 73,
"CEMENT2": 4,
"F_SKY1": 59,
"PANCASE2": 59,
"DEM1_6": 1,
"TANROCK2": 81,
"GRAY7": 47,
"TANROCK5": 55,
"FLAT5_1": 1,
"ZIMMER4": 4,
"DOORYEL2": 4,
"FLAT20": 1,
"DOORBLU2": 3,
"ZIMMER1": 2,
"CEMENT1": 4,
"GRAY5": 3,
"TEKWALL4": 3,
"GRAYBIG": 125,
"GRASS1": 3,
"SHAWN2": 191,
"SPACEW3": 5,
"DOORTRAK": 30,
"STONE": 12,
"BRICK7": 156,
"FLOOR1_6": 24,
"GATE4": 1,
"FLAT18": 36,
"SPCDOOR3": 1,
"TANROCK3": 8,
"SPCDOOR1": 13,
"MARBGRAY": 46,
"TEKGREN1": 28,
"WOODMET2": 1,
"SILVER1": 9,
"FLAT5_2": 127,
"SP_HOT1": 7
}
},
"monsters": {
"total": 273,
"by_type": {
"arachnotron": 7,
"archvile": 2,
"baron": 12,
"cacodemon": 24,
"chaingun_guy": 35,
"cyberdemon": 1,
"demon": 9,
"hell_knight": 15,
"imp": 49,
"lost_soul": 15,
"mancubus": 18,
"pain_elemental": 9,
"revenant": 33,
"shotgun_guy": 39,
"spectre": 4,
"spider_mastermind": 1
},
"by_category": {
"boss": 2,
"hitscanner": 74,
"melee": 13,
"projectile": 184
}
},
"items": {
"total": 152,
"by_type": {
"ammo_box": 27,
"backpack": 2,
"berserk": 5,
"blue_armor": 3,
"cell": 1,
"cell_pack": 8,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 3,
"health_bonus": 1,
"invisibility": 2,
"light_amp_goggles": 1,
"medikit": 20,
"megasphere": 4,
"plasma_rifle": 1,
"rocket_box": 46,
"rocket_launcher": 1,
"shell_box": 20,
"shotgun": 1,
"soulsphere": 2,
"super_shotgun": 2
},
"ammo_by_category": {
"bullets": 27,
"cells": 9,
"rockets": 46,
"shells": 20
},
"weapons_present": [
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue_skull",
"red_skull",
"yellow_skull"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 250,
"hmp_monsters": 195,
"htr_monsters": 127,
"uv_items": 152,
"hmp_items": 152,
"htr_items": 152
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP03",
"title": "MAP03",
"format": "doom",
"stats": {
"things": 199,
"linedefs": 1128,
"sidedefs": 1680,
"vertices": 1023,
"sectors": 236,
"segs": 1810,
"ssectors": 665,
"nodes": 664,
"textures": {
"STEP6": 80,
"METAL3": 5,
"RROCK12": 28,
"BRONZE2": 2,
"FLOOR7_2": 17,
"MARBFAC3": 2,
"RROCK03": 22,
"SW1MET2": 3,
"ZIMMER1": 7,
"ZIMMER3": 16,
"FLOOR6_2": 10,
"ASHWALL6": 56,
"BRONZE3": 30,
"BRICK9": 12,
"FLOOR4_6": 6,
"FLOOR7_1": 5,
"METAL": 109,
"METAL2": 6,
"MARBLE1": 3,
"DEM1_6": 81,
"WOOD12": 26,
"BIGBRIK1": 57,
"CEIL5_2": 54,
"FLAT1_1": 8,
"METAL4": 3,
"DOORTRAK": 34,
"GSTFONT2": 2,
"BROWNHUG": 18,
"MARBLE2": 87,
"PANBORD2": 2,
"MARBFACE": 5,
"SW1PANEL": 1,
"SW1ZIM": 2,
"WOODMET1": 22,
"BRONZE1": 18,
"SW1SATYR": 1,
"BIGDOOR7": 2,
"MARBGRAY": 383,
"CEIL1_3": 1,
"SW1LION": 2,
"RROCK10": 90,
"SUPPORT3": 36,
"GSTLION": 2,
"TLITE6_6": 6,
"MARBFAC4": 4,
"RROCK11": 26,
"SW1MARB": 1,
"METAL6": 1,
"MARBFAC2": 1,
"TANROCK4": 28,
"DEM1_5": 28,
"LITE5": 8,
"GATE3": 2,
"SW1GARG": 13,
"BLOOD1": 1,
"WOODMET2": 11,
"BIGBRIK3": 28,
"METAL7": 5,
"GSTONE1": 93,
"SPCDOOR1": 4,
"STEP1": 2,
"STONE7": 1,
"BIGDOOR4": 8,
"BIGBRIK2": 2,
"F_SKY1": 59,
"MARBLE3": 24,
"MIDBARS3": 10,
"BRICK7": 140,
"TEKLITE": 4,
"FLAT5_2": 7,
"GATE4": 1,
"RROCK14": 18,
"STONE6": 39,
"BRICK6": 21
}
},
"monsters": {
"total": 74,
"by_type": {
"archvile": 1,
"baron": 2,
"cacodemon": 3,
"chaingun_guy": 4,
"demon": 4,
"hell_knight": 6,
"imp": 21,
"lost_soul": 3,
"mancubus": 2,
"pain_elemental": 2,
"revenant": 3,
"shotgun_guy": 13,
"spectre": 4,
"zombieman": 6
},
"by_category": {
"boss": 0,
"hitscanner": 23,
"melee": 8,
"projectile": 43
}
},
"items": {
"total": 73,
"by_type": {
"ammo_box": 2,
"ammo_clip": 1,
"armor_bonus": 8,
"backpack": 1,
"berserk": 1,
"bfg9000": 1,
"blue_armor": 1,
"cell": 4,
"chaingun": 1,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 2,
"health_bonus": 8,
"invisibility": 3,
"medikit": 5,
"megasphere": 1,
"plasma_rifle": 1,
"rocket": 2,
"rocket_box": 2,
"rocket_launcher": 1,
"shell_box": 5,
"shells": 12,
"shotgun": 4,
"soulsphere": 1,
"stimpack": 2,
"super_shotgun": 2
},
"ammo_by_category": {
"bullets": 3,
"cells": 4,
"rockets": 4,
"shells": 17
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue_skull",
"red_skull",
"yellow_skull"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 72,
"hmp_monsters": 72,
"htr_monsters": 50,
"uv_items": 73,
"hmp_items": 73,
"htr_items": 69
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP05",
"title": "MAP05",
"format": "doom",
"stats": {
"things": 400,
"linedefs": 2537,
"sidedefs": 3701,
"vertices": 2351,
"sectors": 544,
"segs": 4030,
"ssectors": 1350,
"nodes": 1349,
"textures": {
"BRICK6": 88,
"DOORTRAK": 78,
"FLAT23": 6,
"GATE2": 10,
"PANCASE2": 8,
"STEP2": 4,
"PLAT1": 10,
"GATE1": 6,
"MFLR8_2": 12,
"CRATOP1": 4,
"GRAY1": 37,
"RROCK09": 7,
"BRONZE3": 125,
"CEIL5_1": 33,
"FLAT1": 5,
"FLAT5_1": 15,
"SFALL1": 2,
"SP_DUDE7": 3,
"SUPPORT3": 677,
"GRAY2": 5,
"BRONZE1": 48,
"CRATELIT": 4,
"MARBLE3": 2,
"METAL3": 10,
"CEIL5_2": 225,
"FLOOR7_2": 4,
"FLOOR7_1": 42,
"F_SKY1": 68,
"GRAY5": 15,
"MIDBARS3": 7,
"SLIME15": 2,
"SW1GRAY1": 4,
"SW1MET2": 1,
"SW1WOOD": 1,
"TLITE6_6": 48,
"WOOD1": 53,
"WOOD3": 3,
"RROCK10": 97,
"CEMENT9": 8,
"METAL2": 28,
"STEP4": 23,
"BRICK7": 176,
"GRAYPOIS": 1,
"GRAYVINE": 8,
"DEM1_5": 13,
"NUKAGE1": 73,
"CRATINY": 8,
"MARBFACE": 4,
"GRAYTALL": 2,
"CEIL1_3": 1,
"LITE5": 28,
"METAL4": 14,
"SLIME14": 7,
"DEM1_6": 24,
"GATE3": 6,
"BIGDOOR4": 4,
"FLOOR4_6": 40,
"MARBLE2": 47,
"DOORYEL": 24,
"MODWALL4": 16,
"DOOR1": 12,
"SW1DIRT": 1,
"WOOD12": 46,
"WOODGARG": 1,
"BRICK9": 19,
"MARBFAC4": 4,
"WOOD6": 1,
"MIDBRONZ": 4,
"TLITE6_1": 3,
"SW1LION": 21,
"MODWALL3": 9,
"GRASS2": 7,
"PIPEWAL1": 40,
"BRICK8": 56,
"BIGDOOR7": 2,
"FLAT5_2": 18,
"BROWN144": 36,
"WOOD5": 5,
"BRONZE4": 32,
"PIPEWAL2": 43,
"SHAWN2": 5,
"TLITE6_5": 23,
"WOODMET1": 28,
"CRATE2": 4,
"BLAKWAL2": 8,
"LITEBLU4": 8,
"WOODMET2": 16,
"METAL": 394,
"BROWNHUG": 105,
"FLAT5_4": 33,
"RROCK03": 8,
"SP_DUDE8": 2,
"BROWN96": 64,
"FLOOR5_4": 108,
"GATE4": 1,
"ICKWALL3": 6,
"METAL7": 8,
"MARBGRAY": 96,
"BRONZE2": 23,
"BLAKWAL1": 4,
"RROCK11": 90,
"RROCK12": 44,
"STEP1": 1,
"STEP6": 90,
"SW1GARG": 2,
"METAL5": 6,
"SW1SATYR": 4
}
},
"monsters": {
"total": 196,
"by_type": {
"archvile": 1,
"baron": 2,
"cacodemon": 3,
"chaingun_guy": 10,
"demon": 3,
"hell_knight": 5,
"imp": 96,
"lost_soul": 2,
"mancubus": 3,
"revenant": 5,
"shotgun_guy": 49,
"spectre": 13,
"zombieman": 4
},
"by_category": {
"boss": 0,
"hitscanner": 63,
"melee": 16,
"projectile": 117
}
},
"items": {
"total": 114,
"by_type": {
"ammo_box": 3,
"armor_bonus": 12,
"backpack": 1,
"berserk": 1,
"bfg9000": 1,
"blue_armor": 1,
"cell": 4,
"chaingun": 2,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 2,
"health_bonus": 22,
"medikit": 5,
"megasphere": 1,
"plasma_rifle": 1,
"radiation_suit": 5,
"rocket": 2,
"rocket_box": 5,
"rocket_launcher": 1,
"shell_box": 8,
"shells": 9,
"shotgun": 7,
"soulsphere": 1,
"stimpack": 16,
"super_shotgun": 2
},
"ammo_by_category": {
"bullets": 3,
"cells": 4,
"rockets": 7,
"shells": 17
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue",
"red",
"yellow"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 191,
"hmp_monsters": 166,
"htr_monsters": 127,
"uv_items": 114,
"hmp_items": 109,
"htr_items": 107
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP07",
"title": "MAP07",
"format": "doom",
"stats": {
"things": 158,
"linedefs": 1110,
"sidedefs": 1555,
"vertices": 951,
"sectors": 229,
"segs": 1633,
"ssectors": 512,
"nodes": 511,
"textures": {
"BRICK6": 32,
"BIGDOOR6": 4,
"CEIL5_1": 46,
"METAL3": 6,
"SW1SATYR": 8,
"RROCK09": 52,
"WOODMET2": 4,
"BRICK7": 165,
"SW1MET2": 2,
"BRONZE1": 7,
"GATE2": 2,
"STEP6": 68,
"DOORTRAK": 30,
"METAL": 159,
"RROCK16": 3,
"MFLR8_2": 1,
"SW1LION": 12,
"BRONZE4": 17,
"LITE5": 24,
"TLITE6_1": 5,
"FLOOR7_1": 1,
"BRONZE2": 4,
"GATE3": 2,
"GATE1": 4,
"BIGDOOR7": 2,
"FLOOR5_4": 70,
"STONE6": 15,
"STEP1": 2,
"CEIL5_2": 56,
"CRATOP1": 1,
"SW1GARG": 3,
"RROCK11": 29,
"EXITSIGN": 4,
"SHAWN2": 1,
"GRASS1": 6,
"SUPPORT3": 373,
"METAL2": 12,
"BRONZE3": 138,
"F_SKY1": 4,
"RROCK10": 152,
"MIDBARS3": 8,
"BROWN96": 80,
"STONE7": 5,
"TLITE6_6": 19,
"RROCK03": 3,
"WOOD12": 20
}
},
"monsters": {
"total": 74,
"by_type": {
"archvile": 1,
"baron": 2,
"cacodemon": 2,
"chaingun_guy": 4,
"demon": 3,
"hell_knight": 2,
"imp": 28,
"mancubus": 2,
"revenant": 3,
"shotgun_guy": 18,
"spectre": 3,
"zombieman": 6
},
"by_category": {
"boss": 0,
"hitscanner": 28,
"melee": 6,
"projectile": 40
}
},
"items": {
"total": 59,
"by_type": {
"ammo_box": 1,
"ammo_clip": 3,
"armor_bonus": 3,
"backpack": 1,
"berserk": 1,
"bfg9000": 1,
"blue_armor": 2,
"cell": 3,
"cell_pack": 2,
"chaingun": 3,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 1,
"health_bonus": 3,
"invisibility": 3,
"medikit": 3,
"megasphere": 1,
"plasma_rifle": 1,
"rocket": 3,
"rocket_box": 4,
"rocket_launcher": 1,
"shell_box": 4,
"shells": 5,
"shotgun": 3,
"soulsphere": 2,
"stimpack": 2,
"super_shotgun": 1
},
"ammo_by_category": {
"bullets": 4,
"cells": 5,
"rockets": 7,
"shells": 9
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 73,
"hmp_monsters": 66,
"htr_monsters": 50,
"uv_items": 57,
"hmp_items": 54,
"htr_items": 51
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP08",
"title": "MAP08",
"format": "doom",
"stats": {
"things": 341,
"linedefs": 1430,
"sidedefs": 2082,
"vertices": 1444,
"sectors": 295,
"segs": 2373,
"ssectors": 825,
"nodes": 824,
"textures": {
"BRICK6": 87,
"BIGDOOR6": 2,
"ROCK3": 6,
"STEP6": 21,
"SUPPORT3": 331,
"FLAT19": 7,
"SW1STON1": 1,
"STEPTOP": 1,
"STONE4": 55,
"BIGDOOR5": 2,
"BRONZE3": 39,
"CEMENT9": 10,
"STONE2": 41,
"SW1WOOD": 4,
"BRICK9": 17,
"CEIL5_2": 89,
"F_SKY1": 67,
"GRASS2": 1,
"SLIME01": 2,
"WOOD5": 77,
"CEIL4_3": 1,
"METAL": 200,
"SW1DIRT": 1,
"MFLR8_2": 17,
"TLITE6_5": 2,
"WOODMET1": 29,
"FLAT5_4": 14,
"BRICK1": 9,
"BFALL1": 1,
"SW1STON6": 2,
"ZIMMER3": 121,
"FLAT5_2": 5,
"DOORTRAK": 42,
"WOOD1": 16,
"MARBLE1": 11,
"SW1WDMET": 1,
"RROCK12": 4,
"STONE7": 2,
"GRAY1": 71,
"BIGDOOR7": 6,
"FLOOR7_1": 16,
"ICKWALL2": 12,
"METAL2": 51,
"METAL5": 1,
"CEIL5_1": 38,
"DEM1_2": 1,
"DOORBLU": 2,
"SW1MET2": 1,
"METAL6": 4,
"WOODMET4": 7,
"STEP1": 3,
"DEM1_4": 1,
"BRONZE2": 2,
"FLOOR5_4": 31,
"FLOOR7_2": 12,
"MIDGRATE": 10,
"FLAT5_1": 13,
"BLOOD1": 6,
"EXITSIGN": 3,
"GATE4": 6,
"GRAY4": 6,
"GSTONE1": 16,
"SLIME14": 48,
"SLIME15": 32,
"DEM1_3": 1,
"GRAYVINE": 28,
"MARBLE2": 4,
"MODWALL3": 1,
"BRICK7": 12,
"DEM1_1": 1,
"LITE5": 23,
"STEP2": 2,
"STONE6": 49,
"SW1GRAY1": 1,
"WOODMET2": 6,
"FLAT5_8": 6,
"FLOOR6_2": 2,
"NUKAGE1": 3,
"BRICK8": 2,
"BROWN96": 30,
"RROCK03": 11,
"BRONZE1": 38,
"GATE3": 8,
"MARBFACE": 2,
"RROCK13": 3,
"GRAY5": 55,
"MARBFAC4": 9,
"METAL4": 7,
"SW1LION": 4,
"SW1SATYR": 3,
"METAL3": 3,
"BIGBRIK1": 22,
"MARBGRAY": 70,
"DEM1_5": 4,
"METAL7": 3,
"RROCK09": 22,
"TLITE6_6": 8,
"FLOOR0_3": 28,
"RROCK10": 75
}
},
"monsters": {
"total": 135,
"by_type": {
"arachnotron": 2,
"archvile": 1,
"baron": 2,
"cacodemon": 4,
"chaingun_guy": 6,
"demon": 3,
"hell_knight": 1,
"imp": 38,
"lost_soul": 6,
"mancubus": 4,
"revenant": 5,
"shotgun_guy": 27,
"spectre": 7,
"zombieman": 29
},
"by_category": {
"boss": 0,
"hitscanner": 62,
"melee": 10,
"projectile": 63
}
},
"items": {
"total": 126,
"by_type": {
"ammo_box": 2,
"ammo_clip": 6,
"armor_bonus": 12,
"backpack": 1,
"berserk": 1,
"bfg9000": 1,
"blue_armor": 1,
"cell": 3,
"cell_pack": 4,
"chaingun": 2,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 1,
"health_bonus": 16,
"invisibility": 2,
"medikit": 9,
"megasphere": 2,
"plasma_rifle": 3,
"radiation_suit": 1,
"rocket": 8,
"rocket_box": 6,
"rocket_launcher": 3,
"shell_box": 6,
"shells": 11,
"shotgun": 9,
"soulsphere": 1,
"stimpack": 10,
"super_shotgun": 3
},
"ammo_by_category": {
"bullets": 8,
"cells": 7,
"rockets": 14,
"shells": 17
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 133,
"hmp_monsters": 120,
"htr_monsters": 102,
"uv_items": 125,
"hmp_items": 121,
"htr_items": 119
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP09",
"title": "MAP09",
"format": "doom",
"stats": {
"things": 290,
"linedefs": 1678,
"sidedefs": 2353,
"vertices": 1599,
"sectors": 353,
"segs": 2592,
"ssectors": 924,
"nodes": 923,
"textures": {
"SFALL1": 1,
"LITE5": 32,
"TLITE6_6": 17,
"FLAT19": 3,
"TLITE6_5": 3,
"DOORYEL": 20,
"BROWN96": 132,
"DOORTRAK": 32,
"BRICK9": 1,
"STEP1": 10,
"CEIL5_2": 202,
"STEP2": 4,
"BRONZE3": 14,
"FLOOR5_4": 172,
"MIDBARS1": 6,
"BRICK6": 264,
"GATE1": 8,
"SW1LION": 22,
"WOODMET1": 12,
"BRICK8": 25,
"STEP6": 58,
"LITEBLU4": 2,
"GATE2": 1,
"SLIME14": 36,
"SUPPORT3": 768,
"WOOD12": 45,
"RROCK11": 48,
"CEIL5_1": 41,
"GSTONE2": 16,
"BLOOD1": 15,
"FLOOR7_1": 2,
"WOODMET2": 6,
"MARBFACE": 2,
"LITE3": 2,
"SW1GARG": 2,
"SW1SATYR": 11,
"METAL": 428,
"MIDBARS3": 6,
"RROCK03": 17,
"TANROCK5": 4,
"BRICK7": 13,
"BROWNHUG": 2,
"SHAWN2": 8,
"SW1MET2": 1,
"F_SKY1": 34,
"SKINSYMB": 9,
"TLITE6_4": 2,
"EXITSIGN": 2,
"GATE3": 4,
"SP_DUDE8": 1,
"SFALL2": 1,
"GATE4": 2,
"MARBGRAY": 28,
"NUKAGE1": 5,
"RROCK10": 78,
"CEIL1_2": 2,
"SP_DUDE7": 1
}
},
"monsters": {
"total": 145,
"by_type": {
"archvile": 1,
"baron": 8,
"cacodemon": 15,
"chaingun_guy": 11,
"cyberdemon": 1,
"demon": 12,
"hell_knight": 6,
"imp": 51,
"mancubus": 1,
"pain_elemental": 1,
"revenant": 5,
"shotgun_guy": 25,
"spectre": 7,
"zombieman": 1
},
"by_category": {
"boss": 1,
"hitscanner": 37,
"melee": 19,
"projectile": 88
}
},
"items": {
"total": 107,
"by_type": {
"ammo_box": 1,
"ammo_clip": 2,
"armor_bonus": 13,
"backpack": 1,
"berserk": 2,
"bfg9000": 1,
"blue_armor": 1,
"cell": 6,
"cell_pack": 1,
"chaingun": 1,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 1,
"health_bonus": 14,
"invisibility": 4,
"invulnerability": 1,
"medikit": 3,
"megasphere": 1,
"plasma_rifle": 1,
"radiation_suit": 1,
"rocket": 1,
"rocket_box": 15,
"rocket_launcher": 2,
"shell_box": 6,
"shells": 10,
"shotgun": 6,
"soulsphere": 2,
"stimpack": 6,
"super_shotgun": 2
},
"ammo_by_category": {
"bullets": 3,
"cells": 7,
"rockets": 16,
"shells": 16
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue",
"red",
"yellow"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 137,
"hmp_monsters": 131,
"htr_monsters": 98,
"uv_items": 106,
"hmp_items": 103,
"htr_items": 71
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP25",
"title": "MAP25",
"format": "doom",
"stats": {
"things": 889,
"linedefs": 1490,
"sidedefs": 2131,
"vertices": 1622,
"sectors": 256,
"segs": 2547,
"ssectors": 958,
"nodes": 957,
"textures": {
"MARBLOD1": 16,
"SP_DUDE8": 1,
"ZIMMER5": 16,
"gray1": 108,
"MARBFAC2": 3,
"RROCK12": 1,
"BRICK7": 1,
"SP_DUDE7": 3,
"WOODMET3": 1,
"GSTGARG": 2,
"BSTONE2": 17,
"BLAKWAL1": 183,
"FLOOR7_1": 14,
"SP_DUDE4": 1,
"GSTVINE2": 18,
"DOORBLU2": 6,
"EXITSTON": 4,
"GATE4": 2,
"LAVA1": 4,
"ASHWALL3": 54,
"MARBLE3": 38,
"BSTONE3": 7,
"GSTONE2": 12,
"GSTLION": 2,
"SP_DUDE5": 4,
"FIREBLU1": 33,
"GSTONE1": 300,
"WOOD7": 1,
"FIRELAV3": 3,
"FLOOR6_1": 4,
"ZIMMER7": 4,
"BRICK9": 69,
"BRICK8": 17,
"MIDBARS1": 1,
"SLIME09": 1,
"RROCK17": 1,
"MARBFAC4": 12,
"MARBFAC3": 23,
"SLADWALL": 16,
"SLIME13": 1,
"F_SKY1": 51,
"SFLR6_4": 1,
"MFLR8_1": 6,
"SLADPOIS": 2,
"DOORYEL2": 6,
"ZIMMER2": 10,
"SW1HOT": 1,
"SW1ROCK": 3,
"NUKEPOIS": 1,
"STONE2": 13,
"ROCKRED3": 4,
"FLAT5_5": 7,
"SW1GSTON": 4,
"SW1STON1": 2,
"WOODMET1": 17,
"MARBLE1": 64,
"BRICK6": 8,
"WOOD9": 17,
"FLOOR1_6": 1,
"SW1BLUE": 8,
"RROCK10": 3,
"SP_HOT1": 9,
"MIDGRATE": 2,
"SW1BRCOM": 2,
"BLOOD1": 10,
"FWATER1": 10,
"MFLR8_4": 2,
"MODWALL2": 8,
"SW1GARG": 4,
"ZIMMER8": 1,
"rrock13": 2,
"NUKEDGE1": 7,
"RROCK13": 1,
"DEM1_5": 36,
"RROCK03": 1,
"STONE6": 12,
"ROCK3": 12,
"SLIME05": 3,
"rrock03": 11,
"STONE7": 4,
"grass1": 23,
"SW1LION": 3,
"BFALL1": 4,
"SUPPORT3": 73,
"RROCK18": 18,
"GSTVINE1": 30,
"SW1SATYR": 10,
"GSTFONT1": 3,
"MARBFACE": 29,
"rock3": 6,
"BRICKLIT": 7,
"RROCK19": 11,
"SW1DIRT": 1,
"ceil5_2": 25,
"WOODMET2": 8,
"SW1MARB": 2,
"SP_DUDE1": 1,
"MARBLE2": 116,
"CEIL5_2": 12,
"SW1STON6": 1,
"ROCKRED1": 25,
"GSTSATYR": 18,
"ROCK2": 2,
"ROCK1": 6,
"BLAKWAL2": 2,
"SW1WDMET": 1,
"FLAT1_2": 4,
"STONE3": 54,
"DEM1_6": 97,
"MFLR8_2": 2,
"WOODVERT": 18,
"MIDBARS3": 6,
"FLOOR7_2": 120,
"FLAT1_1": 27,
"FIREWALA": 6
}
},
"monsters": {
"total": 394,
"by_type": {
"arachnotron": 10,
"archvile": 4,
"baron": 15,
"cacodemon": 39,
"chaingun_guy": 30,
"cyberdemon": 1,
"demon": 49,
"hell_knight": 3,
"imp": 77,
"lost_soul": 13,
"mancubus": 6,
"pain_elemental": 8,
"revenant": 12,
"shotgun_guy": 47,
"spectre": 43,
"zombieman": 37
},
"by_category": {
"boss": 1,
"hitscanner": 114,
"melee": 92,
"projectile": 187
}
},
"items": {
"total": 325,
"by_type": {
"ammo_box": 14,
"ammo_clip": 10,
"armor_bonus": 4,
"backpack": 7,
"berserk": 2,
"bfg9000": 1,
"blue_armor": 3,
"cell": 22,
"cell_pack": 7,
"chaingun": 1,
"chainsaw": 1,
"computer_area_map": 1,
"green_armor": 6,
"health_bonus": 89,
"invisibility": 1,
"invulnerability": 1,
"light_amp_goggles": 1,
"medikit": 25,
"megasphere": 2,
"plasma_rifle": 3,
"radiation_suit": 1,
"rocket": 12,
"rocket_box": 17,
"rocket_launcher": 1,
"shell_box": 27,
"shells": 20,
"shotgun": 8,
"soulsphere": 4,
"stimpack": 31,
"super_shotgun": 3
},
"ammo_by_category": {
"bullets": 24,
"cells": 29,
"rockets": 29,
"shells": 47
},
"weapons_present": [
"bfg9000",
"chaingun",
"chainsaw",
"plasma_rifle",
"rocket_launcher",
"shotgun",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue_skull",
"red_skull",
"yellow_skull"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 380,
"hmp_monsters": 294,
"htr_monsters": 202,
"uv_items": 325,
"hmp_items": 324,
"htr_items": 324
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP31",
"title": "MAP31",
"format": "doom",
"stats": {
"things": 417,
"linedefs": 1385,
"sidedefs": 2110,
"vertices": 1415,
"sectors": 290,
"segs": 2398,
"ssectors": 860,
"nodes": 859,
"textures": {
"METAL1": 19,
"METAL5": 3,
"DOORYEL": 2,
"FLAT3": 9,
"PIPEWAL1": 50,
"FLAT5_3": 1,
"MARBLOD1": 8,
"BLOOD2": 1,
"DOOR3": 20,
"BROWNGRN": 82,
"SLIME16": 17,
"SW1MET2": 4,
"METAL7": 25,
"FLAT5": 5,
"FLAT5_4": 2,
"MFLR8_4": 14,
"TEKGREN2": 69,
"CEIL5_1": 4,
"DOORTRAK": 141,
"FLAT1": 11,
"ICKWALL1": 3,
"STEP2": 2,
"SW1STON6": 2,
"FLAT9": 18,
"FLOOR0_1": 2,
"GATE2": 1,
"SUPPORT3": 12,
"AASHITTY": 1,
"FIREBLU2": 5,
"ZZZFACE6": 1,
"TEKGREN4": 2,
"LITE5": 18,
"METAL6": 4,
"SPACEW4": 1,
"MIDSPACE": 9,
"SW1TEK": 3,
"TEKWALL4": 24,
"GATE3": 4,
"CEMENT8": 7,
"FLOOR1_6": 2,
"MIDBARS1": 40,
"TEKGREN1": 14,
"FLOOR0_7": 6,
"SILVER1": 265,
"FLOOR4_1": 4,
"SW1BRNGN": 2,
"CEMENT7": 39,
"FLOOR5_2": 1,
"SW2SKULL": 1,
"METAL4": 16,
"FLAT18": 11,
"CEMENT9": 148,
"REDWALL": 4,
"SPACEW3": 2,
"FLAT10": 13,
"FLOOR3_3": 2,
"GRAY1": 16,
"GRAY2": 232,
"STEP4": 10,
"FLOOR1_1": 3,
"EXITDOOR": 3,
"TEKWALL1": 48,
"DOORRED": 2,
"FLOOR5_1": 14,
"BLOOD1": 3,
"MIDBRN1": 2,
"GRAY4": 7,
"MIDGRATE": 16,
"SPCDOOR4": 4,
"FLAT20": 102,
"FLOOR0_2": 3,
"SW1CMT": 3,
"MARBLE1": 137,
"MFLR8_2": 9,
"SW2BRNGN": 1,
"FLOOR0_3": 43,
"SHAWN2": 4,
"ICKWALL2": 3,
"TEKLITE": 81,
"BROWN144": 25,
"DOORSTOP": 28,
"FLOOR7_2": 97,
"FLOOR4_5": 1,
"EXITSIGN": 1,
"STARTAN3": 9,
"TEKLITE2": 71,
"CEIL4_2": 3,
"SLIME15": 2,
"TEKBRON2": 4,
"CEMENT1": 16,
"CEIL5_2": 15,
"BFALL1": 3,
"SUPPORT2": 70,
"SLADWALL": 6,
"METAL2": 37,
"rock3": 13,
"METAL": 71,
"ASHWALL2": 13,
"CEMENT4": 2,
"METAL3": 12,
"SW1SLAD": 1,
"BLAKWAL2": 17,
"FLAT23": 58,
"PIPEWAL2": 110,
"FLAT2": 1,
"CEIL1_2": 7,
"FLAT19": 64,
"GATE4": 4,
"DOORBLU": 2,
"SW1EXIT": 1,
"SLIME14": 15,
"TEKBRON1": 2,
"FLOOR7_1": 2,
"CEMENT6": 1,
"CEIL3_5": 4,
"BLAKWAL1": 19
}
},
"monsters": {
"total": 172,
"by_type": {
"arachnotron": 2,
"archvile": 3,
"baron": 8,
"chaingun_guy": 38,
"demon": 4,
"hell_knight": 9,
"imp": 19,
"mancubus": 7,
"pain_elemental": 3,
"revenant": 13,
"shotgun_guy": 45,
"spectre": 6,
"zombieman": 15
},
"by_category": {
"boss": 0,
"hitscanner": 98,
"melee": 10,
"projectile": 64
}
},
"items": {
"total": 212,
"by_type": {
"ammo_clip": 19,
"armor_bonus": 49,
"berserk": 1,
"bfg9000": 1,
"blue_armor": 1,
"cell": 8,
"cell_pack": 1,
"computer_area_map": 1,
"green_armor": 3,
"health_bonus": 57,
"invisibility": 2,
"invulnerability": 1,
"medikit": 11,
"megasphere": 1,
"plasma_rifle": 2,
"rocket": 18,
"rocket_box": 3,
"rocket_launcher": 1,
"shell_box": 14,
"shells": 6,
"soulsphere": 4,
"stimpack": 7,
"super_shotgun": 1
},
"ammo_by_category": {
"bullets": 19,
"cells": 9,
"rockets": 21,
"shells": 20
},
"weapons_present": [
"bfg9000",
"plasma_rifle",
"rocket_launcher",
"super_shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue",
"red",
"yellow"
],
"secret_exit": true
},
"difficulty": {
"uv_monsters": 129,
"hmp_monsters": 96,
"htr_monsters": 78,
"uv_items": 212,
"hmp_items": 211,
"htr_items": 211
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
},
{
"map": "MAP32",
"title": "MAP32",
"format": "doom",
"stats": {
"things": 59,
"linedefs": 83,
"sidedefs": 103,
"vertices": 74,
"sectors": 14,
"segs": 106,
"ssectors": 21,
"nodes": 20,
"textures": {
"FLOOR7_1": 10,
"BROWN96": 14,
"DOORRED2": 2,
"COMPBLUE": 2,
"FLAT5": 10,
"DOOR3": 2,
"BLAKWAL1": 16,
"REDWALL": 2,
"FLAT5_3": 2,
"FLAT8": 1,
"ZIMMER5": 10,
"DOORBLU2": 2,
"FLAT14": 1,
"FLAT1_2": 2,
"CEIL5_1": 1,
"FLOOR5_1": 1,
"STUCCO1": 34,
"SUPPORT3": 10,
"ZIMMER3": 1,
"BRICK4": 2,
"SW1BLUE": 1,
"DOORYEL2": 2,
"SW1BRN1": 1
}
},
"monsters": {
"total": 40,
"by_type": {
"baron": 1,
"cyberdemon": 34,
"hell_knight": 1,
"pain_elemental": 1,
"revenant": 1,
"spider_mastermind": 1,
"zombieman": 1
},
"by_category": {
"boss": 35,
"hitscanner": 1,
"melee": 0,
"projectile": 4
}
},
"items": {
"total": 7,
"by_type": {
"bfg9000": 1,
"chainsaw": 1,
"computer_area_map": 1,
"invulnerability": 1,
"megasphere": 1,
"rocket_launcher": 1,
"shotgun": 1
},
"ammo_by_category": {
"bullets": 0,
"cells": 0,
"rockets": 0,
"shells": 0
},
"weapons_present": [
"bfg9000",
"chainsaw",
"rocket_launcher",
"shotgun"
]
},
"mechanics": {
"teleports": true,
"keys": [
"blue_skull",
"red_skull",
"yellow_skull"
],
"secret_exit": false
},
"difficulty": {
"uv_monsters": 40,
"hmp_monsters": 32,
"htr_monsters": 26,
"uv_items": 7,
"hmp_items": 7,
"htr_items": 7
},
"compatibility": "vanilla_or_boom",
"metadata": {
"title": null,
"music": null,
"source": "marker"
}
}
]
}