v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Difference between revisions of "User:Quietust/parsebody.php"

From Dwarf Fortress Wiki
Jump to navigation Jump to search
(upload my "parsebody" script)
 
m
 
(5 intermediate revisions by the same user not shown)
Line 56: Line 56:
 
}
 
}
  
function readBodies ($file)
+
function readBodies (&$bodies, $in)
 
{
 
{
$bodies = array();
 
 
$in = @fopen($file, "r");
 
if (!$in)
 
error("unable to open body definitions from $file - please run this from the game's root folder (or from a region folder)");
 
$token = readToken($in);
 
if (!$token || ($token[0] != 'OBJECT') || ($token[1] != 'BODY'))
 
error("file $file does not contain BODY objects");
 
 
 
$partname = $partdata = 0;
 
$partname = $partdata = 0;
 
$bodyname = $bodydata = 0;
 
$bodyname = $bodydata = 0;
Line 127: Line 118:
 
}
 
}
 
}
 
}
fclose($in);
 
return $bodies;
 
 
}
 
}
  
Line 135: Line 124:
 
if (isset($part['UPPERBODY']))
 
if (isset($part['UPPERBODY']))
 
{
 
{
verbose("-");
+
verbose("The $part[name] bone IS the upper body - all done");
 
return TRUE;
 
return TRUE;
 
}
 
}
 
$types = 0;
 
$types = 0;
$found = FALSE;
 
 
$numcon = $numcat = $numtype = 0;
 
$numcon = $numcat = $numtype = 0;
 
if (isset($part['CON']))
 
if (isset($part['CON']))
Line 157: Line 145:
 
{
 
{
 
$types++;
 
$types++;
 +
$found = FALSE;
 
foreach ($body as $bp)
 
foreach ($body as $bp)
 
{
 
{
Line 163: Line 152:
 
if ($part['CON_CAT'] == $bp['CATEGORY'])
 
if ($part['CON_CAT'] == $bp['CATEGORY'])
 
{
 
{
 +
$found = TRUE;
 
if ($numcat)
 
if ($numcat)
 
verbose("...and the $part[name] bone's connected to the $bp[name] bone");
 
verbose("...and the $part[name] bone's connected to the $bp[name] bone");
Line 171: Line 161:
 
}
 
}
 
}
 
}
if (!$numcat)
+
if (!$found)
 
warning("Body part $part[id] could not find [CATEGORY:$part[CON_CAT]] body part to connect to!");
 
warning("Body part $part[id] could not find [CATEGORY:$part[CON_CAT]] body part to connect to!");
 
}
 
}
Line 177: Line 167:
 
{
 
{
 
$types++;
 
$types++;
 +
$found = FALSE;
 
foreach ($body as $bp)
 
foreach ($body as $bp)
 
{
 
{
 
if (isset($bp[$part['CONTYPE']]))
 
if (isset($bp[$part['CONTYPE']]))
 
{
 
{
 +
$found = TRUE;
 
if ($numtype)
 
if ($numtype)
 
verbose("...and the $part[name] bone's connected to the $bp[name] bone");
 
verbose("...and the $part[name] bone's connected to the $bp[name] bone");
Line 188: Line 180:
 
}
 
}
 
}
 
}
if (!$numtype)
+
if (!$found)
 
warning("Body part $part[id] could not find [$part[CONTYPE]] body part to connect to!");
 
warning("Body part $part[id] could not find [$part[CONTYPE]] body part to connect to!");
 
}
 
}
Line 247: Line 239:
 
}
 
}
  
//$bodies = readBodies("raw/objects/body_rcp.txt");
+
$bodies = array();
$bodies = readBodies("raw/objects/body_default.txt");
+
foreach (glob("raw/objects/*.txt") as $filename)
 +
{
 +
$in = fopen($filename, "r");
 +
if (!$in)
 +
continue;
 +
$token = readToken($in);
 +
if (($token) && ($token[0] == 'OBJECT') && ($token[1] == 'BODY'))
 +
readBodies($bodies, $in);
 +
fclose($in);
 +
}
 +
 
 +
if (!count($bodies))
 +
error("unable to locate any body part definitions - please run this from the game's root folder (or from a region folder)");
  
foreach (glob("raw/objects/creature_*.txt") as $filename)
+
foreach (glob("raw/objects/*.txt") as $filename)
 
{
 
{
 
$in = fopen($filename, "r");
 
$in = fopen($filename, "r");
Line 258: Line 262:
 
if (($token) && ($token[0] == 'OBJECT') && ($token[1] == 'CREATURE'))
 
if (($token) && ($token[0] == 'OBJECT') && ($token[1] == 'CREATURE'))
 
{
 
{
$creature = 0;
+
$creature = '';
 
while (1)
 
while (1)
 
{
 
{
Line 266: Line 270:
 
if ($token[0] == 'CREATURE')
 
if ($token[0] == 'CREATURE')
 
$creature = $token[1];
 
$creature = $token[1];
if ($token[0] == 'BODY')
+
if (($creature != '') && ($token[0] == 'BODY'))
 
{
 
{
 
if (in_array($filter, array($creature, 'all')))
 
if (in_array($filter, array($creature, 'all')))

Latest revision as of 22:47, 29 November 2023

<?
$verbose = 0;
$filter = 'all';
array_shift($argv);
while (count($argv) > 0)
{
	$arg = array_shift($argv);
	if ($arg == '-verbose')
		$verbose = 1;
	else	$filter = $arg;
}

function verbose ($text)
{
	global $verbose;
	if ($verbose)
		echo "$text\n";
}
function notice ($text)
{
	echo "$text\n";
}
function warning ($text)
{
	echo "WARNING - $text\n";
}
function error ($text)
{
	echo "ERROR - $text\n";
	exit;
}

function readToken ($file)
{
	$token = '';
	while (1)
	{
		$c = fgetc($file);
		if (feof($file))
			return 0;
		if ($c == '[')
			break;
	}
	while (1)
	{
		$c = fgetc($file);
		if (feof($file))
			return 0;
		if ($c == '[')
			warning("Unterminated token '$token' found!");
		if ($c == ']')
			break;
		$token .= $c;
	}
	return explode(':', $token);
}

function readBodies (&$bodies, $in)
{
	$partname = $partdata = 0;
	$bodyname = $bodydata = 0;
	while (1)
	{
		$token = readToken($in);
		if (!$token)
		{
			if ($partname)
			{
				$bodydata[$partname] = $partdata;
				$partname = $partdata = 0;
			}
			if ($bodyname)
			{
				$bodies[$bodyname] = $bodydata;
				$bodyname = $bodydata = 0;
			}
			break;
		}
		switch ($token[0])
		{
		case 'BODY':
			if ($partname)
			{
				$bodydata[$partname] = $partdata;
				$partname = $partdata = 0;
			}
			if ($bodyname)
			{
				$bodies[$bodyname] = $bodydata;
				$bodyname = $bodydata = 0;
			}
			$bodyname = $token[1];
			$bodydata = array();
			break;
		case 'BP':
			if ($partname)
			{
				$bodydata[$partname] = $partdata;
				$partname = $partdata = 0;
			}
			$partname = $token[1];
			$partdata = array('id' => $partname, 'name' => $token[2]);
			break;
		case 'UPPERBODY':
		case 'LOWERBODY':
		case 'HEAD':
		case 'GRASP':
		case 'STANCE':
			$partdata[$token[0]] = 1;
			break;
		case 'CON':
		case 'CON_CAT':
		case 'CATEGORY':
		case 'CONTYPE':
			$partdata[$token[0]] = $token[1];
			break;
		// ignore other tokens
		}
	}
}

function tracePart ($body, $part)
{
	if (isset($part['UPPERBODY']))
	{
		verbose("The $part[name] bone IS the upper body - all done");
		return TRUE;
	}
	$types = 0;
	$numcon = $numcat = $numtype = 0;
	if (isset($part['CON']))
	{
		$types++;
		if (!isset($body[$part['CON']]))
		{
			warning("Body part $part[id] connects to nonexistent part $part[CON]!");
			return FALSE;
		}
		$bp = $body[$part['CON']];
		verbose("The $part[name] bone's connected to the $bp[name] bone");
		if (tracePart($body, $bp))
			$numcon++;
	}
	if (isset($part['CON_CAT']))
	{
		$types++;
		$found = FALSE;
		foreach ($body as $bp)
		{
			if (isset($bp['CATEGORY']))
			{
				if ($part['CON_CAT'] == $bp['CATEGORY'])
				{
					$found = TRUE;
					if ($numcat)
						verbose("...and the $part[name] bone's connected to the $bp[name] bone");
					else	verbose("The $part[name] bone's connected to the $bp[name] bone");
					if (tracePart($body, $bp))
						$numcat++;
				}
			}
		}
		if (!$found)
			warning("Body part $part[id] could not find [CATEGORY:$part[CON_CAT]] body part to connect to!");
	}
	if (isset($part['CONTYPE']))
	{
		$types++;
		$found = FALSE;
		foreach ($body as $bp)
		{
			if (isset($bp[$part['CONTYPE']]))
			{
				$found = TRUE;
				if ($numtype)
					verbose("...and the $part[name] bone's connected to the $bp[name] bone");
				else	verbose("The $part[name] bone's connected to the $bp[name] bone");
				if (tracePart($body, $bp))
					$numtype++;
			}
		}
		if (!$found)
			warning("Body part $part[id] could not find [$part[CONTYPE]] body part to connect to!");
	}
	if ($types > 1)
		warning("Body part $part[id] has multiple connections?");
	return ($numcon + $numcat + $numtype) > 0;
}

function parseBody ($name, $body)
{
	global $bodies;
	verbose("Parsing body of creature $name");
	array_shift($body);
	$parts = array();
	foreach ($body as $b)
	{
		if (!isset($bodies[$b]))
		{
			warning("Creature $name attempting to add nonexistent body $b!");
			continue;
		}
		verbose("Creature $name uses the BODY group '$b'");
		foreach ($bodies[$b] as $part)
		{
			verbose("That includes the '$part[name]' ($part[id])");
			if (isset($parts[$part['id']]))
			{
				$dup = $parts[$part['id']];
				verbose("...but that's got the same ID as the $dup[name]!");
				warning("Creature $name includes multiple instances of body part $part[id]!");
			}
		}
		$parts = array_merge($parts, $bodies[$b]);
	}
	$upper = array();
	foreach ($parts as $id => $part)
	{
		if (isset($part['UPPERBODY']))
			$upper[] = $id;
	}
	if (count($upper) == 0)
	{
		notice("Creature $name has no upper body, skipping.");
		return;
	}
	if (count($upper) > 1)
	{
		notice("Creature $name has more than one upper body, skipping.");
		return;
	}
	verbose("Creature $name has ". count($parts) ." body parts, starting at $upper[0].");
	foreach ($parts as $id => $part)
	{
		if (!tracePart($parts, $part))
			notice("Creature $name body part '$part[name]' is unconnected!");
	}
	verbose('');
}

$bodies = array();
foreach (glob("raw/objects/*.txt") as $filename)
{
	$in = fopen($filename, "r");
	if (!$in)
		continue;
	$token = readToken($in);
	if (($token) && ($token[0] == 'OBJECT') && ($token[1] == 'BODY'))
		readBodies($bodies, $in);
	fclose($in);
}

if (!count($bodies))
	error("unable to locate any body part definitions - please run this from the game's root folder (or from a region folder)");

foreach (glob("raw/objects/*.txt") as $filename)
{
	$in = fopen($filename, "r");
	if (!$in)
		continue;
	$token = readToken($in);
	if (($token) && ($token[0] == 'OBJECT') && ($token[1] == 'CREATURE'))
	{
		$creature = '';
		while (1)
		{
			$token = readToken($in);
			if (!$token)
				break;
			if ($token[0] == 'CREATURE')
				$creature = $token[1];
			if (($creature != '') && ($token[0] == 'BODY'))
			{
				if (in_array($filter, array($creature, 'all')))
					parseBody($creature, $token);
			}
		}
	}
	fclose($in);
}
?>