sc: compare attack order by dps
[sheet.git] / sc.plp
diff --git a/sc.plp b/sc.plp
index b5d81ecd47684c90a7bdd64932ebd355e6e4fef9..a721035d215ad2c3ec9a93744b3aa66548efb6dc 100644 (file)
--- a/sc.plp
+++ b/sc.plp
@@ -43,14 +43,14 @@ Html({
 say "<h1>$scver{game} units</h1>\n";
 
 my $units = do $datafile;
-die "Cannot open unit data: $_\n" for $@ || $! || ();
+Abort("Cannot open unit data", 501, $_) for $@ || $! || ();
 my $patch = shift @{$units}
-       or die "Cannot open unit data: metadata not found\n";
+       or Abort("Cannot open unit data: metadata not found", 501);
 
 say "<p>Unit properties as seen or measured in $scver{name}\n$patch.";
 say "Also see the $_ table." for join(', ',
-       ('<a href="/sc/2">StarCraft 2: HotS</a>')    x ($scver{major} < 2),
-       ('<a href="/sc">original SC: Brood War</a>') x ($scver{major} > 1),
+       (showlink('StarCraft 2: HotS', '/sc/2'))    x ($scver{major} < 2),
+       (showlink('original SC: Brood War', '/sc')) x ($scver{major} > 1),
 );
 say "</p>\n";
 
@@ -85,16 +85,14 @@ for my $unit (@{$units}) {
 
 sub coltoggle {
        my ($name, $id, $nolink) = @_;
-       return sprintf(
-               (defined $get{order} ? $get{order} eq $id : !$id) ? '%2$s ▼'
-                       : $nolink ? '%2$s' : '<a href="?%s">%s</a>',
-               $id && "order=$id", $name
-       );
+       return "$name ▼" if defined $get{order} ? $get{order} eq $id : !$id;
+       return $name if $nolink;
+       return showlink($name, '?'.($id && "order=$id"));
 }
 :><table class="units">
 <thead><tr>
-       <th></th>
-       <th><:= coltoggle('name', '') :></th>
+       <th><:= coltoggle(exists $get{order} ? 'race' : 'source' => '') :></th>
+       <th><:= coltoggle(name => 'name') :></th>
        <th class="val min" title=minerals>cost</th>
        <th class="val gas">gas</th>
        <th class="val time"><:= coltoggle(qw'build cost') :></th>
@@ -103,8 +101,8 @@ sub coltoggle {
        <th class="val unit-hp">HP</th>
        <th class="val unit-shield">shield</th>
        <th class="val unit-armor" title="armor">⛨</th>
-       <th class="val hurt">attack</th>
-       <th class="hurt hurtrel"><:= coltoggle(qw'dps attack 1') :></th>
+       <th class="val hurt"><:= coltoggle(attack => 'attack') :></th>
+       <th class="hurt hurtrel">dps</th>
        <th class="val unit-range" colspan=3>range</th>
        <th class="val unit-sight">sight</th>
        <th class="val unit-speed">speed</th>
@@ -340,38 +338,40 @@ sub showrangeint {
                );
        }
 
+       my @rows = @{$units};
        my $grouped = 1;  # race headers
        if (exists $get{order}) {
                $grouped = 0;
                $get{order} ||= '';
-               if ($get{order} eq 'size') {
-                       $_->{order} = (
-                               $_->{pop}*16 + ($_->{size} // $_->{suit}) + $_->{cargo}/8
-                               + $_->{hp}/512 + $_->{min}/8192
-                       ) for @$units;
+               if ($get{order} eq 'name') {
+                       @rows = sort {$a->{name} cmp $b->{name}} @rows;
                }
                elsif ($get{order} eq 'cost') {
                        $_->{order} = (
                                $_->{gas}*1.5 + $_->{min} + $_->{pop}/8 + $_->{build}/256/8
-                       ) for @$units;
+                       ) for @rows;
+               }
+               elsif ($get{order} eq 'size') {
+                       $_->{order} = (
+                               $_->{pop}*16 + ($_->{size} // $_->{suit}) + $_->{cargo}/8
+                               + $_->{hp}/512 + $_->{min}/8192
+                       ) for @rows;
                }
                elsif ($get{order} eq 'attack') {
                        $_->{order} = $_->{hp} / 1024 + $_->{shield} / 1008 + max(
                                map {
-                                       ($_->{damage} + $_->{upgrade} * 3)
-                                       * ($_->{count} // 1) / ($_->{cooldown} // 1)
+                                       ($_->{dps} ? $_->{dps}->[-1] :
+                                               ($_->{damage} + $_->{upgrade} * 3)
+                                               * ($_->{count} // 1) / ($_->{cooldown} // 1)
+                                       )
                                        * ($_->{splash} ? 1.01 : 1)
                                        * ($_->{type} eq 'implosive' ? .96 : 1)
                                        * ($_->{type} eq 'explosive' ? .98 : 1)
                                } @{ $_->{attack} }
-                       ) for @$units;
-               }
-               else {
-                       $units->[$_]->{order} = $_ for 0 .. $#$units;
+                       ) for @rows;
                }
+               @rows = sort {$a->{order} <=> $b->{order}} @rows if exists $rows[0]->{order};
        }
-       my @rows = @{$units};
-       @rows = sort {$a->{order} <=> $b->{order}} @rows unless $grouped;
 
        my ($race, $cat) = ('', '');
        for (@rows) {