#!/usr/bin/perl -n
#
# parse_fbi - parse one or more .fbi files (from TA: Kingdoms)
#
# usage: parse_fbi foo.fbi bar.fbi ...
# cat foo.fbi bar.fbi ... | parse_fbi
#
# 19990630 mike@ossmann.com Created.
# 19990701 mike@ossmann.com Bug fixes. List of useful properties.
#
# Hopefully this framework can be used for some cool things. This code
# is free in every sense of the word. I would appreciate it if you
# would let me know if you do anything really groovy with it. Feel free
# to send me improvements.
#
# -Mike Ossmann (Trouvere on Boneyards)
BEGIN {
@units = ( {} ); # an array of hashes of name/value pairs
# Each element in the array is one unit.
$i = -1; # array index
@prefix = (); # the prefix(es) of each property name
$header = ""; # the header we are under in the .fbi file
}
if (/\[(\S+)\]/) {
# section header
$header = $1;
if ($header eq "UNITINFO") {
# this is a new unit listing
$i++;
@prefix = ();
$header = "";
} else {
$header .= "::";
}
} elsif (/{/) {
# left bracket
push (@prefix, "$header");
} elsif (/\}/) {
# right bracket
pop (@prefix);
} elsif (/(\S+)\s+\=\s+(\S+.*)\;/) {
# name/value pair
$propertyname = $1;
$value = $2;
$fullpropertyname = join ("", @prefix) . $propertyname;
$units[$i]{$fullpropertyname} = $value;
}
# Some output examples
#
# Uncomment what you want to see.
END {
#&print_all_units("name");
#&print_all_units("WEAPON1::name");
#&print_property_names;
#&print_basic_output;
#&print_giant_html_table;
&print_customized_html_table;
}
# print out a single field (such as "name") from every unit
sub print_all_units {
$field = shift;
foreach $unit (@units) {
print ${$unit}{$field}, "\n";
}
}
# print a list of all property names in all units (There are 352!)
sub print_property_names {
# find all the property names (and their frequency, in case we want it)
foreach $unit (@units) {
foreach $property (keys %{$unit}) {
$fieldfrequency{$property}++;
}
}
foreach $property (sort keys %fieldfrequency) {
print $property, "\n";
}
}
# print a simple, sorted output similar to the .fbi files themselves
sub print_basic_output {
# sort units by name
foreach $unit (sort { $a->{name} cmp $b->{name} } @units) {
print ${$unit}{name}, "\n";
foreach $property (sort keys %{$unit}) {
print " ", $property, " = ", ${$unit}{$property}, "\n";
}
}
}
# print a giant html table with every unit and almost all properties
#
# This will crash some browsers! It doesn't look very good anyway.
sub print_giant_html_table {
print "
\n";
# find all the property names (and their frequency, in case we want it)
foreach $unit (@units) {
foreach $property (keys %{$unit}) {
$fieldfrequency{$property}++;
}
}
@fieldlist = keys %fieldfrequency;
# First row is the key
print "name | ";
foreach $property (sort @fieldlist) {
# some filtering is done to attampt to make this readable:
if ( ($property ne 'name')
&& ($property ne 'yardmap')
&& ($property ne 'copyright')
) {
print "$property | ";
}
}
print "
";
# sort units by name (Lots of other sorting methods are easy.)
foreach $unit (sort { $a->{name} cmp $b->{name} } @units) {
print "${$unit}{name} | ";
foreach $property (sort @fieldlist) {
# some filtering is done to attampt to make this readable:
if ( ($property ne 'name')
&& ($property ne 'yardmap')
&& ($property ne 'copyright')
) {
print "${$unit}{$property} | ";
}
}
print "
\n";
}
print "
\n";
}
# print a custom html table
#
# I've attempted to put something together which would be useful to
# players but not too huge. Thanks to hansolo@tauniverse.com for
# reference information. This could certainly be improved upon.
sub print_customized_html_table {
print "\n";
@usefulfields = (
'name',
'tedclass',
'buildcost',
'buildtime',
'workertime',
'bodytype',
'maxdamage',
'maxmana',
'experiencepoints',
'maxvelocity',
'acceleration',
'sightdistance',
'cruisealt',
'radardistance',
'WEAPON1::type',
'WEAPON1::DAMAGE::default',
'WEAPON1::range',
'WEAPON1::minrange',
'WEAPON1::reloadtime',
'WEAPON1::areaofeffect',
'WEAPON1::manapershot',
'WEAPON2::type',
'WEAPON2::DAMAGE::default',
'WEAPON2::range',
'WEAPON2::minrange',
'WEAPON2::reloadtime',
'WEAPON2::areaofeffect',
'WEAPON2::manapershot',
'WEAPON3::type',
'WEAPON3::DAMAGE::default',
'WEAPON3::range',
'WEAPON3::minrange',
'WEAPON3::reloadtime',
'WEAPON3::areaofeffect',
'WEAPON3::manapershot',
);
# These data structures are redundant, but, hey, it's 5:00 am and
# Perl hashes aren't strictly ordered like lists. . .
%columntitles = (
'name' => 'Name',
'tedclass' => 'Race',
'buildcost' => 'Cost',
'buildtime' => 'Build Time',
'workertime' => 'Build Rate',
'bodytype' => 'Body Type',
'maxdamage' => 'Hit Points',
'maxmana' => 'Mana',
'experiencepoints' => 'Exp. Points',
'maxvelocity' => 'Vel.',
'acceleration' => 'Accel.',
'sightdistance' => 'Sight Range',
'cruisealt' => 'Altitude',
'radardistance' => 'Radar Range',
'WEAPON1::type' => 'Weapon Type',
'WEAPON1::DAMAGE::default' => 'Damage',
'WEAPON1::range' => 'Range',
'WEAPON1::minrange' => 'Min Range',
'WEAPON1::reloadtime' => 'Reload Time',
'WEAPON1::areaofeffect' => 'Area of Effect',
'WEAPON1::manapershot' => 'Shot Cost',
'WEAPON2::type' => 'Weapon Type',
'WEAPON2::DAMAGE::default' => 'Damage',
'WEAPON2::range' => 'Range',
'WEAPON2::minrange' => 'Min Range',
'WEAPON2::reloadtime' => 'Reload Time',
'WEAPON2::areaofeffect' => 'Area of Effect',
'WEAPON2::manapershot' => 'Shot Cost',
'WEAPON3::type' => 'Weapon Type',
'WEAPON3::DAMAGE::default' => 'Damage',
'WEAPON3::range' => 'Range',
'WEAPON3::minrange' => 'Min Range',
'WEAPON3::reloadtime' => 'Reload Time',
'WEAPON3::areaofeffect' => 'Area of Effect',
'WEAPON3::manapershot' => 'Shot Cost',
);
# First row is the key
print "";
foreach $property (@usefulfields) {
print "$columntitles{$property} | ";
}
print "
";
# sort units by name (Lots of other sorting methods are easy.)
foreach $unit (sort { $a->{name} cmp $b->{name} } @units) {
print "";
foreach $property (@usefulfields) {
print "${$unit}{$property} | ";
}
print "
\n";
}
print "
\n";
}
# Additional useful fields?
#
#category
#attractsgods
#brakerate
#cancloak
#cloakcost
#cloakmoving
#canfly
#canhover
#floater
#movementclass
#builddistance
#damagecatagory
#mogriumincome
#mogriumstorage
#manarechargerate
#roadmultiplier
#watermultiplier
#turninplacerate
#totalallowed
#transportcapacity
#transportdistance
#transportsize
#transportsizecapacity
#fireatwillrandom
#economybonus
#notargetcategory
#standingunitorder
#WEAPON*::weaponvelocity
#WEAPON*::aimtolerance
#WEAPON*::DAMAGE::*
#WEAPON*::noairweapon
#WEAPON*::builduptime
#
# remove weapon fields?
# typos found in .fbi files
#
#WEAPON1::aimtolerance?
#WEAPON1::edgeeffectivness
#WEAPON1::wapongaf?
#roadmultplier
#watermultipliser
#
#zongod/vergod no totalallowed?