X-Git-Url: http://git.shiar.net/perl/schtarr.git/blobdiff_plain/cc84763f9e53b6620ccd437a434bfd90d6d761c2..5e197a36431a61974bd5d0a158d2d9855aac1baf:/screp diff --git a/screp b/screp index 4b1f033..910f3d2 100755 --- a/screp +++ b/screp @@ -10,6 +10,8 @@ GetOptions( "verbose|v!" => \$SHOWWARN, ); +use constant { APM_FIRSTFRAME => 80 / .042 }; + { package Data::StarCraft::Replay; @@ -310,6 +312,7 @@ my %cmdread = ( 0x18 => ["cancel"], 0x19 => ["cancel hatch"], 0x1A => ["stop", 1], +# 0x1B => ["move-thing??"], # tim: after hotkey (unit, reaver??) select; soon after reselected and moved 0x1E => ["return cargo", 1], 0x1F => ["train", 2, \%unit], 0x20 => ["cancel train", 2], # == 254 @@ -411,6 +414,8 @@ sub open { } +my @race = (qw(Z T P), (undef) x 3, '-'); + sub showtime { my $time = shift() * .042; my $minutes = int($time / 60); @@ -426,7 +431,7 @@ sub unpackhash { } local $_ = Data::StarCraft::Replay::_read(undef, \*STDIN, 633) - and my ($head, @headdata) = unpackhash("CVa3Va12Z28v2Z16Z24Ca26a38a*", $_, qw( + and my ($head, @headdata) = unpackhash("CVa3Va12Z28v2Z16Z24CZ26a38a*", $_, qw( engine frames mag1 time mag2 name width height unknown1 creator unknown2 map unknown3 )) @@ -442,14 +447,32 @@ $_ eq "\10"x8 . "\0"x4 or warn sprintf( ) for $head->{mag2}; delete $head->{$_} for qw(mag1 mag2 unknown1 unknown2); -my @playdata = unpack "a36"x12 . "V8C8", $headdata[0] +my @playdata = unpack "Va32"x12 . "V8C8", $headdata[0] or die "Couldn't parse player data in replay header\n"; -my @player; -push @player, unpackhash("x11Z25", shift @playdata, qw/name/) for 0 .. 11; +my (@player, @slot); +for (0 .. 11) { + my $number = shift @playdata; + defined $player[$number] and warn "Player #$number redefined"; + my ($data) = unpackhash("VcccZ25", shift @playdata, qw( + slot type race unknown name + )); + defined $race[$_] ? ($data->{race} = $race[$_]) : + warn "Unknown race #$_ for player $number" + for $data->{race}; + $slot[$data->{slot}] = $number if $data->{slot} < 16; + $player[$number] = $data; +} $player[$_]->{color} = shift @playdata for 0 .. 7; $player[$_]->{index} = shift @playdata for 0 .. 7; +sub showplayer { + my $id = shift; + my $playdata = $player[$slot[$id]]; + return defined $playdata ? + sprintf '%s (%s)', $playdata->{name}, $playdata->{race} : "#$id"; +} + printf "%s: %s\n", $_, $head->{$_} for qw(name creator); use Date::Format; printf "created: %s\n", time2str('%Y-%m-%d %X', $_) for $head->{time}; @@ -486,7 +509,7 @@ my %cmdmacro = map {$_ => 1} ( my %stats; # player => count for (@$map) { $stats{$_->[1]}{actions}++; - $stats{$_->[1]}{gameactions}++ if $_->[0] > 80 / .042; + $stats{$_->[1]}{gameactions}++ if $_->[0] >= APM_FIRSTFRAME; $stats{$_->[1]}{last} = $_->[0] if $_->[2] eq "part"; $stats{$_->[1]}{$cmdmacro{$_->[2]} ? "macro" : "micro"}++; $stats{$_->[1]}{count}{$_->[2]}++; @@ -495,14 +518,14 @@ for (@$map) { for my $player (sort keys %stats) { my $row = $stats{$player}; $row->{last} ||= $map->[-1][0]; -# printf("%d:%6d actions (%3d micro,%4d macro);%4d APM\n", - printf("%d:%6d actions in%7d frames (%s) = %d APM\n", - $player, $row->{actions}, $row->{last}, +# printf("%-16s%6d actions (%3d micro,%4d macro);%4d APM\n", + my $name = showplayer($player); + printf("%-16s%6d actions in%7d frames (%s) = %d APM\n", + $name, $row->{actions}, $row->{last}, showtime($row->{last}), # $row->{micro} / $row->{last} * 60 / .042 * 1.05, # $row->{macro} / $row->{last} * 60 / .042 * 1.05, - $row->{gameactions} / $row->{last} * 60 / .042 * 1.042, - # $row->{gameactions} / $map->[-1][0] * 60 / .042, + $row->{gameactions} / ($row->{last} - APM_FIRSTFRAME) * 60 / .042, ); if (0) {