%s', $cat ne $_->{cat} ? ('h', $cat = $_->{cat}) : ('d', ' ')),
- '' . $_->{name},
- ' | ' . ($_->{min} || '0'),
+ return (
+ ' | ' . ($_->{min} // ''),
' | ' . ($_->{gas} || ''),
- sprintf(' | %s%.0f',
+ !defined $_->{build} ? ' | ' : sprintf(' | %s%.0f',
!!$_->{base} && '+',
$_->{build} || '0',
),
- sprintf(' | %s', $suitchar, ucfirst $suitchar),
- ' | ' . join('',
- $_->{unit} ? $_->{unit} == .5 ? '½' : $_->{unit} : ' ',
- defined $_->{organic} && sprintf(
- '%s',
- $_->{organic} ? 'o' : 'u',
- $_->{organic} ? 'organic' : 'mechanic',
- $_->{organic} ? 'o' : 'm',
- ),
+ !$suitchar ? ' | ' : sprintf(' | %s', $suitchar, ucfirst $suitchar),
+ ' | ' . (
+ defined $_->{unit} && $_->{unit} == .5 ? '½' : $_->{unit}
+ ),
+ ' | ' . join('', grep { $_ }
+ (defined $_->{organic} ? !$_->{organic} : $_->{attr}->{mech})
+ && 'm',
+ ($_->{organic} || $_->{attr}->{organic})
+ && 'o',
+ $_->{attr}->{psionic}
+ && 'Ï',
),
- ' | ' . $_->{hp},
- ' | ' . (
- $_->{shield} ? sprintf('%.0f%%', 100 * $_->{shield} / $_->{hp}) : ' '
+ ' | ' . join('', grep { $_ }
+ $_->{attr}->{armored}
+ && 'A',
+ $_->{attr}->{light}
+ && 'L',
),
- ' | ' . showrange($_, 'armor'),
+ ' | ' . $_->{hp} // '',
+ $_->{shield} ? sprintf(' | %.0f%% | {shield} / $_->{hp}
+ ) : ' | ' . showval($_, 'armor'),
showattack($_, 'ground'),
showattack($_, 'air'),
- ' | ' . showrange($_, 'attack', 'range'),
+ ' | ' . showval($_, 'attack', 'range'),
' | ' . sprintf(
$_->{detect} ? '%s' : '%s',
- showrange($_, 'sight')
+ showval($_, 'sight')
),
- ' | ' . showrange($_, 'speed'),
+ ' | ' . showval($_, 'speed'),
+ $_->{attr}->{massive}
+ && 'â',
' | ' . showmagic($_),
"\n"
);
+ }
- for my $alt (grep { $_->{alt} } @{ $_->{special} }) {
+ my $grouped = 1; # race headers
+ if (exists $get{order}) {
+ $grouped = 0;
+ $get{order} ||= '';
+ if ($get{order} eq 'size') {
+ $_->{order} = $_->{unit}*8 + $_->{suit} + $_->{hp}/512 + $_->{min}/8192 for @$units;
+ }
+ elsif ($get{order} eq 'cost') {
+ $_->{order} = $_->{gas}*1.5 + $_->{min} + $_->{unit}/8 + $_->{build}/256/8 for @$units;
+ }
+ else {
+ $units->[$_]->{order} = $_ for 0 .. $#$units;
+ }
+ }
+ my @rows = @{$units};
+ @rows = sort {$a->{order} <=> $b->{order}} @rows unless $grouped;
+
+ my ($race, $cat) = ('', '');
+ for (@rows) {
+ if ($grouped) {
+ printf ' | %s'."\n",
+ $race = $_->{race}, ucfirst $race
+ unless $race eq $_->{race};
+ }
+ else {
+ $_->{cat} = $_->{race};
+ }
+
+ print(
+ ' |
---|
',
+ '', $cat ne $_->{cat} && ($cat = $_->{cat}),
+ ' | ', $_->{name},
+ showunitcols($_),
+ );
+
+ for my $subrow (@{ $_->{special} }) {
+ $subrow->{alt} or next;
print(
- ' |
| ' . $alt->{alt},
- showattack($alt, 'ground'),
- showattack($alt, 'air'),
- ' | ' . showrange($alt, 'attack', 'range'),
- ' | ' . sprintf(
- $alt->{detect} ? '%s' : '%s',
- showrange($alt, 'sight')
- ),
- ' | ' . showrange($alt, 'speed'),
- ' | ',
- "\n",
+ ' |
| ', $subrow->{alt},
+ showunitcols($subrow),
);
}
}
@@ -339,11 +307,30 @@ sub showrange {
excludes construction of dependencies such as buildings
and +parent units
size
- affected by Small,
- Medium,
- or Large unit damage
+ <:
+if ($scver{major} > 1) {
+ :>transports can fit 8 Small,
+ 4 Medium,
+ 2 Large,
+ or a single Huge unit<:
+} else {
+ :>affected by Small,
+ Medium, or
+ Large unit damage<:
+} :>
number of command points taken per unit
- organic/mechanic unit
+ <:
+if ($scver{major} > 1) {
+ :>received damage depends on
+ organic,
+ mechanic,
+ Ï(ps)ionic,
+ Light, and
+ Armored
+ attributes<:
+} else {
+ :>organic/mechanic unit<:
+} :>
HP
total number of hitpoints (including shields)
shield
@@ -358,9 +345,9 @@ sub showrange {
ground/air
damage done per single attack against ground/air units
2nd column indicates relative amount of damage done in
- a certain
- amount of time
- splash damage+ hits nearby objects as well
+ 1 second of fastest game time
+ splash damage hits all objects nearby +
+ or in a straight line Ã.
explosive damage does only
50% damage to small units, 75% to medium, 100% to large
concussive/plasma damage does
@@ -373,7 +360,7 @@ sub showrange {
speed
relative speed of movement (when in full motion, startup speed ignored)
specials
- special abilities
+ special abilities are usually casted manually, but some are always active
parentheses () indicate that it needs to be researched first
hover for description
range is maximum range required to activate
|