#!/usr/bin/perl -w

# Copyright by Bernhard Oemer 1998

# This programm can be freely distributed, as long 
# as this note is left in place

sub conv { ucfirst(lc $_[0]); };
#sub conv { $_[0]; };

while (<>) {

  m/^Sending heartbeat to/ and next;

  if( m{^FindFile: \./\w+/maps/(\w+)\.bsp} ) {
    $map=lc($1);
    $maps{lc($1)}++;
    next;
  }

  if( m/^(\w+) entered the game/ ) { 
    $games{conv($1)}++; 
    $cseq{conv($1)}=0;
    next;
  }


  if(
    m/^(\w+) mows down a teammate/ or
    m/^(\w+) checks his glasses/ or
    m/^(\w+) gets a frag for the other team/ or
    m/^(\w+) loses another friend/
  ) {
    $pl=conv($1);
    $suic{$pl}++;
    $team{$pl}++;
    $kills{"$pl $pl"}++;
    $mdeaths{"$pl $map"}++;
    $cseq{$pl}=0;
    next;
  }
  

  if(
    m/^(\w+) discharges into the water/ or
    m/^(\w+) tries to put the pin back in/ or
    m/^(\w+) becomes bored with life/ or
    m/^(\w+) checks if his weapon is loaded/ or
    m/^(\w+) sleeps with the fishes/ or
    m/^(\w+) sucks it down/ or
    m/^(\w+) gulped a load of slime/ or
    m/^(\w+) can't exist on slime alone/ or
    m/^(\w+) burst into flames/ or
    m/^(\w+) turned into hot slag/ or
    m/^(\w+) visits the Volcano God/ or
    m/^(\w+) was squished/ or
    m/^(\w+) fell to his death/ or
    m/^(\w+) was spiked/ or
    m/^(\w+) was squished/ or
    m/^(\w+) fell to his death/ or
    m/^(\w+) ate a lavaball/ 
  ) {
    $pl=conv($1);
    $suic{$pl}++;
    $kills{"$pl $pl"}++;
    $mdeaths{"$pl $map"}++;
    $cseq{$pl}=0;
    next;
  }
  
  s/^(\w+) rips (\w+) a new one/$2 rips $1 a new one/;
  if(
    m/^(\w+) was ax-murdered by (\w+)$/ or
    m/^(\w+) chewed on (\w+)'s boomstick/ or
    m/^(\w+) ate 2 loads of (\w+)'s buckshot/ or
    m/^(\w+) was \w+ed by (\w+)'s/ or
    m/^(\w+) was \w+ed by (\w+)$/ or
    m/^(\w+) rips (\w+) a new one/ or 
    m/^(\w+) \w+s (\w+)'s/ 
  ) { 
    $p1=conv($1);
    $p2=conv($2);
    $deaths{$p1}++;
    $frags{$p2}++;
    $mdeaths{"$p1 $map"}++;
    $mfrags{"$p2 $map"}++;
    $cseq{$p1}=0;
    $cseq{$p2}++;
    $kills{"$p2 $p1"}++;
    if(!$seq{$p2} || $cseq{$p2} > $seq{$p2}) { $seq{$p2}=$cseq{$p2}; }
    $k=$p2;
    if(m/ax-murdered/) { $ax{$k}++; }
    next;
  }
#  print
}

(keys %frags) or exit 1; #die "No players found";

#exit;

format STDOUT_TOP =
Player    Games Frags Deaths Suic Team Ratio  best map   % worst map  % Sq Ax
-----------------------------------------------------------------------------
.

format STDOUT =  
@<<<<<<<<<<@>>> @>>>>  @>>>> @>>> @>>> @>>>%  @<<<<<<<@>>> @<<<<<<<@>>>@>>@>>
$p, $games{$p}, $frags{$p}, $deaths{$p}, ($suic{$p}||0)-($team{$p}||0),($team{$p}||0),int(100*$ratio{$p}),$mapmax{$p},int(100*$mmax{$p}),$mapmin{$p},int(100*$mmin{$p}),$seq{$p} || 0,$ax{$p} || 0
.

$nmaps=scalar (keys %maps);
foreach $p (keys %games) {
  $frags{$p} or $frags{$p}=0;
  $deaths{$p} or $deaths{$p}=0;
  $suic{$p} or $suic{$p}=0;
  $d=$deaths{$p}+$suic{$p};
  $k=$frags{$p};
  $ratio{$p} = $d ? $k/$d : $k;
  $mmax{$p}=0;
  $mmin{$p}=9999;
  $mapmax{$p}=$mapmin{$p}="";
  $kmin=$k/$nmaps;
  $dmin=$d/$nmaps;
  foreach $m (keys %maps) {
    $k=$mfrags{"$p $m"} || 0;
    $d=$mdeaths{"$p $m"} || 1;
    if($mmax{$p} < $k/$d && $k > $kmin) { $mmax{$p}=$k/$d; $mapmax{$p}=$m; }
    if($mmin{$p} > $k/$d && $d > $dmin) { $mmin{$p}=$k/$d; $mapmin{$p}=$m; }
    #printf "%9s %8s: %3d / %3d = %d %%\n",$p,$m,$k,$d,100*$k/$d;
  }
  $mapmax{$p} eq $mapmin{$p} and $mapmax{$p}=$mapmin{$p}="";
  $mapmin{$p} or $mmin{$p}=0;
  $mapmax{$p} or $mmax{$p}=0;
}

$max=30;
foreach $p (sort { $ratio{$a} < $ratio{$b} } (keys %games)) {
 $frags{$p} or $deaths{$p} or next;
 write;
  --$max or last;
}

print <<EOF;

legend: ratio = frags/(deaths+suic+team), sq = max. frags w/o getting killed, 
        ax = ax assaults, best/worst map rqs. frags/deaths > player avg.
EOF

@l=sort { $frags{$a}+$deaths{$a} < $frags{$b}+$deaths{$b} } (keys %games);
@o=splice @l,9;

foreach $k (@o) {
  foreach $v (@l) {
    $kills{"others $v"}+= $kills{"$k $v"} || 0; 
    $kills{"$v others"}+= $kills{"$v $k"} || 0; 
  }
  foreach $v (@o) { 
    $kills{"others others"}+= $kills{"$k $v"} || 0; 
  }
}

@ll = @o ? (@l,"others") : @l;

printf "\nScores ";
foreach $v (@ll) { printf " %6s",lc substr($v,0,6); }
print "\n" . "-" x (7+7*@ll);

foreach $k (@ll) {
  printf "\n%-6s:", substr($k, 0, 6);
  foreach $v (@ll) { print $kills{"$k $v"} ? sprintf " %6d",$kills{"$k $v"} : " " x 6 . "-"; }
}

print "\n";

@mm=sort { $maps{$a} < $maps{$b} } (keys %maps);

printf "\nMaps     Games";
foreach $v (@l) { printf " %6s",lc substr($v,0,6); }
print "\n" . "-" x (14+7*@l);

$max=10;
foreach $m (@mm) {
  printf "\n%-8s: %4d",$m,$maps{$m}/2;
  %lr=();
  $s=0;
  foreach $p (@l) { 
    $k=$mfrags{"$p $m"} || 0;
    $d=$mdeaths{"$p $m"} || 1;
    $s+=$k+$d;
  }
  foreach $p (@l) { 
    $k=$mfrags{"$p $m"} || 0;
    $d=$mdeaths{"$p $m"} || 1;
    if($k+$d > ($frags{$p}+$deaths{$p}+$suic{$p})/($nmaps) or
    $k+$d > $s/(2*@l)) { $lr{$p}=$k/$d; } 
  }
  @slr=sort { $lr{$a} < $lr{$b} } (keys %lr);
  foreach $p (@l) {
    $c=" ";
    $p eq $slr[-1] and $c="\~";
    $p eq $slr[0] and $c="\"";
    @slr > 1 and $p eq $slr[1] and $c="\'";
    print $lr{$p} ? sprintf "%5d%s%%",int(100*$lr{$p}),$c : "   --  ";
  }
  --$max or last;
}

print <<EOF;


legend: " ... best player, ' ... 2nd best, ~ ... loser

EOF

