Skip to content

Instantly share code, notes, and snippets.

@Xymph
Last active May 22, 2021 14:39
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/5e2f5ce10a615e48d5d4c9a8aa5caaa0 to your computer and use it in GitHub Desktop.
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
#!/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