Last active
May 22, 2021 14:39
-
-
Save Xymph/5e2f5ce10a615e48d5d4c9a8aa5caaa0 to your computer and use it in GitHub Desktop.
Process an extracted TEXTMAP lump (from a Doom UDMF map) with regular expressions and a little code to generate statistics in Template:Mapdata format, along with formatted lists of secret sector numbers and deathmatch spawn points (if any), for DoomWiki.org
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
// TEXTMAP stats 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); | |
} | |
// initialize stats | |
$stats = array( | |
'thing' => 0, | |
'vertex' => 0, | |
'linedef' => 0, | |
'sidedef' => 0, | |
'sector' => 0, | |
); | |
$secrets = $secthgs = $dmstarts = $skills = 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 DM starts | |
$dmangle = -1; | |
foreach ($matches[0] as $tnum => $thing) { | |
if (preg_match("/^\s*angle\s*=\s*(\d+)/ms", $thing, $angle) == 1) | |
$dmangle = $angle[1] % 360; | |
if (preg_match("/^\s*type\s*=\s*(\d+)/ms", $thing, $thtype) == 1) { | |
if ($thtype[1] == 11) | |
$dmstarts[] = array($tnum, $dmangle); | |
} | |
if (preg_match("/^\s*countsecret\s*=\s*/ms", $thing) == 1) | |
$secthgs[] = array($tnum, $thtype[1]); | |
if (preg_match_all("/^\s*skill(\d+)\s*=\s*true/ms", $thing, $skill) >= 1) { | |
foreach ($skill[1] as $sk) { | |
if (!isset($skills[$sk])) | |
$skills[$sk] = 1; | |
else | |
$skills[$sk]++; | |
} | |
} | |
} | |
} else if ($type == 'sector') { | |
//print_r($matches[0]); | |
// check all sectors for secrets | |
foreach ($matches[0] as $snum => $sector) { | |
//echo $snum .': '.$sector."\n"; | |
if (preg_match("/^\s*special\s*=\s*(\d+)/ms", $sector, $special) == 1) { | |
//print_r($special); | |
if ($special[1] == 9 || ($special[1] & 1024) != 0) | |
$secrets[] = $snum; | |
} | |
if (preg_match("/^\s*secret\s*=\s*true/ms", $sector) == 1) { | |
$secrets[] = $snum; | |
} | |
} | |
} | |
} | |
//print_r($secrets); | |
//print_r($dmstarts); | |
//print_r($stats); | |
// format & output stats | |
echo "\n===Secrets===\n"; | |
if (!empty($secrets) || !empty($secthgs)) { | |
foreach ($secrets as $secret) | |
echo "# ('''sector $secret''')\n"; | |
foreach ($secthgs as $secret) | |
echo "# {$secret[1]} ('''thing {$secret[0]}''')\n"; | |
} else | |
echo "There are no official secrets on this map.\n"; | |
echo "\n===Player spawns===\n"; | |
if (!empty($dmstarts)) { | |
echo "This level contains ".count($dmstarts)." spawn points:\n"; | |
foreach ($dmstarts as $dmstart) { | |
echo "# facing "; | |
switch ($dmstart[1]) { | |
case 0: echo 'east'; break; | |
case 45: echo 'north-east'; break; | |
case 90: echo 'north'; break; | |
case 135: echo 'north-west'; break; | |
case 180: echo 'west'; break; | |
case 225: echo 'south-west'; break; | |
case 270: echo 'south'; break; | |
case 315: echo 'south-east'; break; | |
default : echo $dmstart[1]; break; | |
} | |
echo ". ('''thing {$dmstart[0]}''')\n"; | |
} | |
} | |
echo "\n===Map data===\n"; | |
echo "{{mapdata|\n"; | |
echo " things=".$stats['thing']."|\n"; | |
echo " vertexes=".$stats['vertex']."|\n"; | |
echo " linedefs=".$stats['linedef']."|\n"; | |
echo " sidedefs=".$stats['sidedef']."|\n"; | |
echo " sectors=".$stats['sector']."}}\n"; | |
echo "\n===Thing skills===\n"; | |
ksort($skills); | |
print_r($skills); | |
// 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