X-Git-Url: http://git.shiar.nl/sheet.git/blobdiff_plain/0083d6fee99e70519ff4770a4f76f02b6937537d..85cf1cbebe994484740a5471565f5859c49106c2:/sc.plp diff --git a/sc.plp b/sc.plp index 31d3555..5607a9a 100644 --- a/sc.plp +++ b/sc.plp @@ -1,5 +1,10 @@ <(common.inc.plp)><: +my $datafile = 'sc-units.inc.pl'; +if ($ENV{PATH_INFO} and $ENV{PATH_INFO} eq '/2') { + $datafile = 'sc2-units.inc.pl'; +} + Html({ title => 'starcraft unit cheat sheet', version => 'v1.0', @@ -13,6 +18,7 @@ Html({ reference software attributes properties '], stylesheet => [qw'light'], + data => [$datafile], }); :> @@ -28,6 +34,7 @@ Unit properties as seen or measured in Brood War border-collapse: separate; border-spacing: 0; margin: 0 auto; + white-space: nowrap; } .units th, .units td { border: 0; @@ -37,12 +44,12 @@ Unit properties as seen or measured in Brood War } tr.alt td { font-size: 70%; - border-top-style: dashed; + padding-left: 0.5em; } .units tr th:first-child { padding-left: 0; } - .units tr:hover:not(.race) { + .units tbody tr:hover:not(.race) { background: #EEE; } @@ -51,10 +58,6 @@ Unit properties as seen or measured in Brood War margin: 0; text-align: center; } - .units th.cat { - font-size: 70%; - text-transform: uppercase; - } .units thead th, .units tfoot th { font-size: 70%; font-weight: normal; @@ -62,13 +65,9 @@ Unit properties as seen or measured in Brood War .unit-o {color: #C08} /* organic */ .unit-u {color: #44C} /* mechanic */ - img.unit-o, img.unit-u { - margin-left: 0.2em; - vertical-align: middle; - } - .unit { - text-align: center; - white-space: nowrap; + .unit-composed { + color: #C88; + font-size: 70%; } .unit.unit-s {color: #770} .unit.unit-m {color: #C70} @@ -101,17 +100,18 @@ Unit properties as seen or measured in Brood War .unit-magic { padding-left: 0.5em; } + .magic-perma { + text-decoration: underline; + } .units .val { + white-space: nowrap; text-align: right; } - .legend dl { - text-align: left; - -moz-column-width: 20em; - -webkit-column-width: 20em; - } .legend dt { + float: none; + text-align: left; margin-top: 1ex; font-weight: bold; } @@ -120,10 +120,18 @@ Unit properties as seen or measured in Brood War } .legend dd { text-indent: -1em; - margin-left: 2em; - break-before: avoid; - break-inside: avoid; - -webkit-column-break-before: avoid; + margin-left: 1em; + } + + .legend { + display: table-cell; + min-width: 20em; + text-align: left; + } + .units { + float: left; + padding-bottom: 1em; + margin-right: 2em; } @@ -140,8 +148,8 @@ sub coltoggle { <:= coltoggle('name', '') :> - min - gas + min + gas <:= coltoggle(qw'build cost') :> <:= coltoggle(qw'size size') :> HP @@ -156,6 +164,12 @@ sub coltoggle { <: 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); @@ -179,40 +193,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; } @@ -220,26 +245,74 @@ 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}; + } + + sub showunitcols { + my ($row) = @_; + local $_ = $row; + $_->{hp} += $_->{shield} if $_->{shield}; + my $suitchar = ''; + if ($_->{suit}) { + $suitchar = [qw/? s m l/]->[$_->{suit}]; + } + + return ( + '' . ($_->{min} // ''), + '' . ($_->{gas} || ''), + !defined $_->{build} ? '' : sprintf('%s%.0f', + !!$_->{base} && '+', + $_->{build} || '0', + ), + !$suitchar ? '' : sprintf('%s', $suitchar, ucfirst $suitchar), + '' . join('', + defined $_->{unit} && $_->{unit} == .5 ? '½' : $_->{unit}, + defined $_->{organic} && sprintf( + '%s', + $_->{organic} ? 'o' : 'u', + $_->{organic} ? 'organic' : 'mechanic', + $_->{organic} ? 'o' : 'm', + ), + ), + '' . $_->{hp} // '', + '' . ( + $_->{shield} ? sprintf('%.0f%%', 100 * $_->{shield} / $_->{hp}) : ' ' + ), + '' . showval($_, 'armor'), + showattack($_, 'ground'), + showattack($_, 'air'), + '' . showval($_, 'attack', 'range'), + '' . sprintf( + $_->{detect} ? '%s' : '%s', + showval($_, 'sight') + ), + '' . showval($_, 'speed'), + '' . showmagic($_), + "\n" + ); } - my $units = do 'sc-units.inc.pl'; - die "Cannot open unit data: $_\n" for $! || $@ || (); - my $grouped = !exists $get{order}; + my $units = do $datafile; + die "Cannot open unit data: $_\n" for $@ || $! || (); + my $grouped = 1; # race headers if (exists $get{order}) { + $grouped = 0; $get{order} ||= ''; if ($get{order} eq 'size') { - $_->{order} = $_->{unit}*8 + $_->{size} + $_->{hp}/512 + $_->{min}/8192 for @$units; + $_->{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; @@ -248,60 +321,34 @@ sub showrange { $units->[$_]->{order} = $_ for 0 .. $#$units; } } - my @rows = $grouped ? @$units : sort {$a->{order} <=> $b->{order}} @$units; + my @rows = @{$units}; + @rows = sort {$a->{order} <=> $b->{order}} @rows unless $grouped; my ($race, $cat) = ('', ''); for (@rows) { - $race = $_->{race}, - printf '

%s

'."\n", $race, ucfirst $race - if $grouped and $race ne $_->{race}; - $_->{cat} = $_->{race} if not $grouped; - my $sizechar = [qw/? s m l/]->[$_->{size}]; + if ($grouped) { + printf '

%s

'."\n", + $race = $_->{race}, ucfirst $race + unless $race eq $_->{race}; + } + else { + $_->{cat} = $_->{race}; + } + print( '', - sprintf('%s', $cat ne $_->{cat} ? ('h', $cat = $_->{cat}) : ('d', ' ')), - '' . $_->{name}, - '' . ($_->{min} || '0'), - '' . ($_->{gas} || ''), - '' . sprintf('%.0f', $_->{build} || '0'), - sprintf('%s', $sizechar, ucfirst $sizechar), - '' . join('', - $_->{unit} ? $_->{unit} == .5 ? '½' : $_->{unit} : ' ', - defined $_->{organic} && sprintf( - '%s', - $_->{organic} ? 'o' : 'u', - $_->{race} . ($_->{organic} ? 'o' : ''), - $_->{organic} ? 'o' : 'm' - ), - ), - '' . $_->{hp}, - '' . ($_->{shield} ? $_->{shield}.'%' : ' '), - '' . showrange($_, 'armor'), - showattack($_, 'ground'), - showattack($_, 'air'), - '' . showrange($_, 'attack', 'range'), - '' . sprintf( - $_->{detect} ? '%s' : '%s', - showrange($_, 'sight') + sprintf('%s', + $cat ne $_->{cat} ? ('h', $cat = $_->{cat}) : ('d', ' ') ), - '' . showrange($_, 'speed'), - '' . showmagic($_), - "\n" + '' . $_->{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), ); } } @@ -314,14 +361,17 @@ sub showrange {
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, +
affected by Small, Medium, 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 @@ -332,12 +382,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 @@ -351,7 +400,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