#!/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 ""; 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 ""; } } print ""; # sort units by name (Lots of other sorting methods are easy.) foreach $unit (sort { $a->{name} cmp $b->{name} } @units) { print ""; 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 ""; } } print "\n"; } print "
name$property
${$unit}{name}${$unit}{$property}
\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 ""; } 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 ""; } print "\n"; } print "
$columntitles{$property}
${$unit}{$property}
\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?