X-Git-Url: http://git.shiar.nl/sheet.git/blobdiff_plain/ca987f558f793b296a159060a2fbe3f8f164eb67..e487749bf1899655bb0c7b7fe9c2d4cbff3b8021:/sc.plp diff --git a/sc.plp b/sc.plp index 7ae2805..cf2155f 100644 --- a/sc.plp +++ b/sc.plp @@ -1,119 +1,53 @@ <(common.inc.plp)><: +my %scver = ( + id => 'bw', + name => 'Brood War', + title => 'starcraft', + game => 'StarCraft', + major => 1, +); + +if ($ENV{PATH_INFO} and $ENV{PATH_INFO} eq '/2') { + %scver = ( + id => 'hots', + name => 'Heart of the Swarm', + title => 'starcraft2', + game => 'StarCraft II', + major => 2, + ); +} +my $datafile = "sc-units-$scver{id}.inc.pl"; + Html({ - title => 'starcraft unit cheat sheets', - version => 'v1.0', + title => "$scver{title} unit cheat sheet", + version => 'v1.1', description => [ - 'Reference of StarCraft unit properties,' - . ' comparing various statistics of all the units in Brood War' + "Reference of $scver{game} unit properties," + . " comparing various statistics of all the units in $scver{name}" . ' including costs, damage, defense, speed, ranges, and abilities.', ], - keywords => [qw' + keywords => [ + qw' starcraft game unit statistics stats comparison table sheet cheat reference software attributes properties - '], + ', + $scver{major} < 2 ? qw' bw broodwar brood war ' : qw' starcraft2 hots ', + ], stylesheet => [qw'light'], + raw => '', + data => [$datafile], }); -:> -

StarCraft unit cheat sheet

- -

-Unit properties as seen or measured in Brood War -version≥1.08. -

- - +print "

Unit properties as seen or measured in $scver{name}\n$patch.\n

\n\n"; -<: sub coltoggle { my ($name, $id) = @_; return sprintf( @@ -126,8 +60,8 @@ sub coltoggle { <:= coltoggle('name', '') :> - min - gas + min + gas <:= coltoggle(qw'build cost') :> <:= coltoggle(qw'size size') :> HP @@ -140,9 +74,14 @@ sub coltoggle { speed specials - <: sub showrange { + my ($min, $max) = @_; + $_ = int($_ + .5) for $min, $max; # round halves up + return $min == $max ? $min : "$min-$max"; +} + +sub showval { my ($row, @elements) = @_; my ($min, $max); @@ -166,40 +105,51 @@ sub showrange { } } - if ($elements[0] eq 'attack' and $elements[1] ne 'range' and $elements[2] eq 'cmp') {{ - my $type = $row->{$elements[0]}->{$elements[1]}->{type} or next; + if ($elements[0] eq 'attack' and $elements[1] ne 'range' and $elements[2] eq 'dps') {{ + my $attack = $row->{ $elements[0] }->{ $elements[1] }; + ref $attack or $attack = $row->{ $elements[0] }->{$attack}; # follow + my $type = $attack->{type} or next; if ($type eq 'explosive') { $min /= 2; } elsif ($type eq 'implosive') { $min /= 4; } - $min = int($min + .5); # round halves up }} - - return $min == $max ? $min : "$min-$max"; + return showrange($min, $max); } sub showattack { my ($row, $area) = @_; - local $_ = $row->{attack}->{$area}; + my $attack = $row->{attack}->{$area}; + if (not ref $attack) { + # reference to another area + $area = $attack; + $attack = $row->{attack}->{$area}; + } - return '' unless $_; + return '' unless $attack; my $tagbase = ''; - my $out = showrange($row, 'attack', $area, 'damage'); - $out .= '+' if $_->{splash}; - $out .= '' . showrange($row, 'attack', $area, 'cmp'); + my $out = showval($row, 'attack', $area, 'damage'); + $out .= '+' if $attack->{splash}; + $attack->{dps} = $attack->{cooldown} && [ + map { 24 * $_ / $attack->{cooldown} * ($attack->{count} // 1) } + map { ref $_ ? @{$_} : $_ } + $attack->{damage} + #TODO: upgrade (zergling) + ]; + $out .= '' . showval($row, 'attack', $area, 'dps'); return $tagbase . $out; } @@ -207,108 +157,143 @@ sub showrange { my ($row) = @_; my $specials = $row->{special} or return ''; return join ' ', map { - sprintf '%s', + sprintf '%s', + $_->{duration} < 0 && ' class="magic-perma"', join('', $_->{name}, $_->{desc} ? ": $_->{desc}" : '', - $_->{range} ? sprintf(' (%s)', join ', ', - "range $_->{range}", -# "cost $_->{cost}", + $_->{range} || $_->{cost} ? sprintf(' (%s)', join ', ', + $_->{range} ? "range $_->{range}" : (), + $_->{cost} ? sprintf('cost %.0f%%', + 100 * $_->{cost} / $row->{energy} + ) : (), ) : '', ), - $_->{abbr}, - } @$specials; + sprintf($_->{build} ? '(%s)' : '%s', $_->{abbr}), + } grep { defined $_->{abbr} } @{$specials}; } - my $units = do 'sc-units.inc.pl'; - die "Cannot open unit data: $_\n" for $! || $@ || (); - my $grouped = !exists $get{order}; - if (exists $get{order}) { - $get{order} ||= ''; - if ($get{order} eq 'size') { - $_->{order} = $_->{unit}*8 + $_->{size} + $_->{hp}/512 + $_->{min}/8192 for @$units; + sub showunitcols { + my ($row) = @_; + local $_ = $row; + $_->{hp} += $_->{shield} if $_->{shield}; + my $suitchar = ''; + if ($_->{cargo} > 0) { + $suitchar = [qw/? s m l l h h h h/]->[abs $_->{cargo}]; } - elsif ($get{order} eq 'cost') { - $_->{order} = $_->{gas}*1.5 + $_->{min} + $_->{unit}/8 + $_->{build}/256/8 for @$units; + elsif ($_->{size}) { + $suitchar = [qw/s m l h h h/]->[$_->{size}]; } - else { - $units->[$_]->{order} = $_ for 0 .. $#$units; + elsif ($_->{suit}) { + $suitchar = [qw/? s m l/]->[$_->{suit}]; } - } - my @rows = $grouped ? @$units : sort {$a->{order} <=> $b->{order}} @$units; - my ($race, $cat) = ('', ''); - for (@rows) { - $race = $_->{race}, - printf '

%1$s

'."\n", $race - if $grouped and $race ne $_->{race}; - $_->{cat} = $_->{race} if not $grouped; - my $sizechar = [qw/? s m l/]->[$_->{size}]; - print( - '', - sprintf('%s', $cat ne $_->{cat} ? ('h', $cat = $_->{cat}) : ('d', ' ')), - '' . $_->{name}, - '' . ($_->{min} || '0'), + return ( + '' . ($_->{min} // ''), '' . ($_->{gas} || ''), - '' . sprintf('%.0f', $_->{build} || '0'), - sprintf('%s', $sizechar, ucfirst $sizechar), + !defined $_->{build} ? '' : sprintf('%s%.0f', + !!$_->{base} && '+', + $_->{build} || '0', + ), + !$suitchar ? '' : sprintf('%s', $suitchar, ucfirst $suitchar), '' . join('', - $_->{unit} ? $_->{unit} == .5 ? '½' : $_->{unit} : ' ', + defined $_->{unit} && $_->{unit} == .5 ? '½' : $_->{unit}, defined $_->{organic} && sprintf( - '%s', + '%s', $_->{organic} ? 'o' : 'u', - $_->{race} . ($_->{organic} ? 'o' : ''), - $_->{organic} ? 'o' : 'm' + $_->{organic} ? 'organic' : 'mechanic', + $_->{organic} ? 'o' : 'm', ), ), - '' . $_->{hp}, - '' . ($_->{shield} ? $_->{shield}.'%' : ' '), - '' . showrange($_, 'armor'), + '' . $_->{hp} // '', + '' . ( + $_->{shield} ? sprintf('%.0f%%', 100 * $_->{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'), '' . showmagic($_), "\n" ); + } + + 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 $alt (grep { $_->{alt} } @{ $_->{special} }) { + 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), ); } } :> - +

Legend

-
+
cost
minerals+gas required to create one unit +
includes total expenses if based on existing units
build
relative time needed to create at least one unit +
excludes construction of dependencies such as buildings + and +parent units
size -
Small, +
<: +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 + or Large unit damage<: +} :>
number of command points taken per unit -
organic/mechanic unit +
organic/mechanic unit
HP
total number of hitpoints (including shields)
shield @@ -319,12 +304,11 @@ sub showrange {
base unit armor
can be increased by upto 3 at various facilities
each point decreases damage per hit by one, upto a minimum of ½ -
reduction applies to initial damage, before size penalties (so a large plasma hit of 12 to 4 armor deals 2 damage, not ½) +
reduction applies to initial damage, before size penalties (so a plasma hit of 12 to 4 armor large deals 2 damage, not ½)
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 + 1 second of fastest game time
splash damage+ hits nearby objects as well
explosive damage does only 50% damage to small units, 75% to medium, 100% to large @@ -338,8 +322,8 @@ sub showrange {
speed
relative speed of movement (when in full motion, startup speed ignored)
specials -
special abilities -
parentheses () indicated that it needs to be researched first +
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
cost is percentage of total energy lost @@ -350,28 +334,5 @@ When two values are given (1-2), second value indicates attribute after all possible upgrades.

-<: exit :> -

Magic

- -
    <: -for (@$units) { - print '
  • ', $_->{name}; - print '
    '; -# my $units = {qw/protoss W zerg B terran R/}->{$_->{race}} x int($_->{unit} + .5); -# my $cost = int(($_->{min} + $_->{gas}) / 50 - $_->{unit}) || ''; - my $units = {qw/protoss W zerg B terran R/}->{$_->{race}} x int($_->{gas} / 50) || ''; - my $cost = int($_->{min} / 50) || 0; - my @desc; - push @desc, "Flying" if $_->{flying}; - push @desc, "Cloaking" if $_->{cloak}; - push @desc, "First Strike" if $_->{range} and $_->{range} >= 4; - my $att = $_->{attack}->{ground}; - push @desc, "Trample" if $att and $att->{splash}; - $att = $att->{damage} if $att; - $att = $att->[0] if ref $att eq "ARRAY"; - $att = int($att / 5); - my $def = int($_->{hp} / 45); - printf "%s
    %s
    %s/%s", $cost . $units, join(",", @desc), $att, $def; -} -:>
+