Skip to content

Instantly share code, notes, and snippets.

@Xymph
Last active February 16, 2022 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xymph/d32d9efde10c0ac0708505881aaa3f09 to your computer and use it in GitHub Desktop.
Save Xymph/d32d9efde10c0ac0708505881aaa3f09 to your computer and use it in GitHub Desktop.
Process an extracted TEXTMAP lump (from a Doom UDMF map) with regular expressions and some code to collect monster and equipment counts for single-player and cooperative modes, and lists those where the counts differ, for DoomWiki.org
#!/usr/bin/php
<?php
// TEXTMAP extra monsters & equipment script for DoomWiki.org, by Frans P. de Vries (Xymph)
$usage = "Usage: {$argv[0]} TEXTMAP-file\n";
// check input parameter
if ($argc != 2) {
echo $usage;
exit(1);
}
// load TEXTMAP file
if (($text = @file_get_contents($argv[1])) === false) {
echo $argv[1] . ": unable to read\n";
exit(1);
}
// define DOOM monsters
$monsters = array(
3004 => 'HUMAN',
9 => 'SERGEANT',
65 => 'COMMANDO',
3001 => 'IMP',
3006 => 'LOSTSOUL',
3002 => 'DEMON',
58 => 'SPECTRE',
892 => 'SPECTRE1PSX',
893 => 'SPECTRE2PSX',
890 => 'SPECTRE3PSX',
889 => 'SPECTRENMPSX',
66 => 'REVENANT',
3005 => 'CACODEMON',
894 => 'CACODEMONSPEC',
71 => 'PAINELEM',
69 => 'KNIGHT',
3003 => 'BARON',
68 => 'ARACHNO',
67 => 'MANCUBUS',
64 => 'ARCHVILE',
7 => 'SPIDERBOSS',
16 => 'CYBERDEMON',
84 => 'WOLF3DSS',
72 => 'KEEN',
9061 => 'ST_HUMAN',
9060 => 'ST_SERGEANT',
9054 => 'ST_COMMANDO',
9057 => 'ST_IMP',
9055 => 'ST_DEMON',
9059 => 'ST_REVENANT',
9053 => 'ST_CACODEMON',
9056 => 'ST_KNIGHT',
9052 => 'ST_BARON',
9050 => 'ST_ARACHNO',
9058 => 'ST_MANCUBUS',
9051 => 'ST_ARCHVILE',
888 => 'HELPERDOG',
9100 => 'SCRIPT_MARINE',
9101 => 'MARINE_FIST',
9102 => 'MARINE_BERSERK',
9103 => 'MARINE_CHNSAW',
9104 => 'MARINE_PISTOL',
9105 => 'MARINE_SHOTGUN',
9106 => 'MARINE_SUPERSG',
9107 => 'MARINE_CHNGUN',
9108 => 'MARINE_ROCKET',
9109 => 'MARINE_PLASMA',
9110 => 'MARINE_RAILGUN',
9111 => 'MARINE_BFG9000',
);
// define DOOM equipment
$equipment = array(
2005 => 'CHAINSAW',
2001 => 'SHOTGUN',
82 => 'COMBATGUN',
2002 => 'CHAINGUN',
2003 => 'LAUNCHER',
2004 => 'PLASMAGUN',
2006 => 'BFG9000',
2007 => 'AMMOCLIP',
2048 => 'AMMOBOX',
2008 => 'SHELLS',
2049 => 'SHELLBOX',
2010 => 'ROCKET',
2046 => 'ROCKETBOX',
2047 => 'ENERGYCELL',
17 => 'ENERGYPACK',
2011 => 'STIMPACK',
2012 => 'MEDIKIT',
2018 => 'GREENARMOR',
2019 => 'BLUEARMOR',
2015 => 'ARMBONUS1',
2014 => 'HLTBONUS1',
2013 => 'SOULSPHERE',
83 => 'MEGASPHERE',
8 => 'BACKPACK',
2023 => 'BERSERK',
2026 => 'COMPMAP',
2022 => 'INVULN',
2045 => 'LITEAMP',
2024 => 'BLURSPHERE',
2025 => 'RADSUIT',
);
// initialize stats
$stats = array(
'thing' => 0,
/*
'vertex' => 0,
'linedef' => 0,
'sidedef' => 0,
'sector' => 0,
*/
);
$tallymnst = array();
$tallyeqpm = array();
$nosing = array();
$nocoop = array();
// process all stats types
foreach ($stats as $type => $stat) {
$stats[$type] = preg_match_all("/^{$type}[^{=]+{[^}]+}/ms", $text, $matches);
if ($type == 'thing') {
// check all things for monsters & equipment
foreach ($matches[0] as $tnum => $thing) {
if (preg_match("/^type *= *(\d+)/ms", $thing, $type) == 1) {
if (array_key_exists($type[1], $monsters)) {
// check monster thing for SP/coop modes
if (!isset($tallymnst[$type[1]]))
$tallymnst[$type[1]] = array(0, 0);
if (preg_match("/^single *= *(true|false)/ms", $thing, $flag) == 1)
if ($flag[1] == 'true')
$tallymnst[$type[1]][0]++;
else
$nosing[] = $tnum;
else
$nosing[] = $tnum;
if (preg_match("/^coop *= *(true|false)/ms", $thing, $flag) == 1)
if ($flag[1] == 'true')
$tallymnst[$type[1]][1]++;
else
$nocoop[] = $tnum;
else
$nocoop[] = $tnum;
}
if (array_key_exists($type[1], $equipment)) {
// check equipment thing for SP/coop modes
if (!isset($tallyeqpm[$type[1]]))
$tallyeqpm[$type[1]] = array(0, 0);
if (preg_match("/^single *= *(true|false)/ms", $thing, $flag) == 1)
if ($flag[1] == 'true')
$tallyeqpm[$type[1]][0]++;
else
$nosing[] = $tnum;
else
$nosing[] = $tnum;
if (preg_match("/^coop *= *(true|false)/ms", $thing, $flag) == 1)
if ($flag[1] == 'true')
$tallyeqpm[$type[1]][1]++;
else
$nocoop[] = $tnum;
else
$nocoop[] = $tnum;
}
}
}
}
}
//print_r($tallymnst);
//print_r($tallyeqpm);
// show monster differences
foreach ($tallymnst as $tnum => $thing) {
if ($thing[0] != $thing[1])
echo "{$thing[0]}\t{$thing[1]}\t{$monsters[$tnum]}\n";
}
echo "\n";
// show equipment differences
foreach ($tallyeqpm as $tnum => $thing) {
if ($thing[0] != $thing[1])
echo "{$thing[0]}\t{$thing[1]}\t{$equipment[$tnum]}\n";
}
if (!empty($nosing)) {
echo "\nno Sing: "; print_r($nosing);
}
if (!empty($nocoop)) {
echo "\nno Coop: "; print_r($nocoop);
}
// vim:set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment