/[james]/t2matchlog/t2matchlog
ViewVC logotype

Diff of /t2matchlog/t2matchlog

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 36 by james, Mon Nov 24 23:57:14 2003 UTC revision 38 by james, Sun Nov 30 13:41:03 2003 UTC
# Line 1  Line 1 
1  #!/bin/perl -W  #!/bin/perl -W
2    
3    use strict;
4  use GD;  use GD;
5    
6    die "Usage: perl $0 logfile outputdir" unless @ARGV == 2;
7    open LOG, $ARGV[0] or die "Failed to open $ARGV[0]: $!";
8    my $outdir = $ARGV[1];
9    mkdir $outdir or die "Failed to create output directory $outdir: $!";
10    my $dir = $0;
11    $dir =~ s!(^|/)[^/]+$!$1!;
12    (system "cp ${dir}t2matchlog.css $outdir/") == 0 or die "Failed to copy stylesheet: $!";
13    
14  $/ = "\r\n";  $/ = "\r\n";
15    $| = 1;
16    
17  $near0 = 70;  my $near0 = 70;
18  $near1 = 200;  my $near1 = 200;
19  $thumbsize = 400;  my $thumbsize = 400;
   
 $black = 0x000000;  
 $white = 0xffffff;  
 $red   = 0xff0000;  
 $green = 0x00ff00;  
 $blue  = 0x0000ff;  
 $magenta = 0xff00ff;  
 $yellow = 0xffff00;  
 $orange = 0xff8000;  
 $grey  = 0x404040;  
 $teamcol[1] = $blue;  
 $teamcol[2] = $magenta;  
20    
21  # from damageTypes.cs  # from damageTypes.cs
22    my @DamageTypeText;
23  $DamageTypeText[0] = 'default';  $DamageTypeText[0] = 'default';
24  $DamageTypeText[1] = 'blaster';  $DamageTypeText[1] = 'blaster';
25  $DamageTypeText[2] = 'plasma';  $DamageTypeText[2] = 'plasma';
# Line 60  $DamageTypeText[36] = 'Crash'; Line 59  $DamageTypeText[36] = 'Crash';
59  $DamageTypeText[98] = 'nexus camping';  $DamageTypeText[98] = 'nexus camping';
60  $DamageTypeText[99] = 'suicide';  $DamageTypeText[99] = 'suicide';
61    
62  $icon_player = load_image("icons/com_player_grey_24x.png");  my $icon_player = load_image("${dir}icons/com_player_grey_24x.png");
63  $icon{'flag'} = load_image("icons/com_icon_flag_outside.png");  my %icon;
64  $icon{'gen'} = load_image("icons/com_icon_generator.png");  $icon{'flag'} = load_image("${dir}icons/com_icon_flag_outside.png");
65  $icon{'turret'} = load_image("icons/com_icon_turretbase.png");  $icon{'gen'} = load_image("${dir}icons/com_icon_generator.png");
66  $icon{'inv'} = load_image("icons/com_icon_inventory.png");  $icon{'turret'} = load_image("${dir}icons/com_icon_turretbase.png");
67  $icon{'sensor'} = load_image("icons/com_icon_sensor.png");  $icon{'inv'} = load_image("${dir}icons/com_icon_inventory.png");
68  $icon{'vpad'} = load_image("icons/com_icon_vehicle_inventory.png");  $icon{'sensor'} = load_image("${dir}icons/com_icon_sensor.png");
69    $icon{'vpad'} = load_image("${dir}icons/com_icon_vehicle_inventory.png");
70  # read header  $icon{'solar'} = load_image("${dir}icons/com_icon_solar_gen.png");
71  $mission = <>; chomp $mission;  
72  $mission_type = <>; chomp $mission_type;  my %colour = ('S' => 0xffff00, 'A' => 0xff8000, 'KK' => 0x00ff00, 'K' => 0xff0000,
73  $mission_name = <>; chomp $mission_name;                  'L' => 0xff8000, 'F+' => 0x00ffff, 'F-' => 0xff00ff, 'P' => 0xff8000,
74  $mission_type_name = <>; chomp $mission_type_name;                  'V' => 0xffff00, 'W' => 0xff0000, 'G' => 0x0080ff, 'J' => 0x00ff80,
75  $area = <>; chomp $area; ($x0, $y0, $width, $height) = split / /, $area;                  'GG' => 0x0080ff, 'JJ' => 0x00ff80);
76  while (($_ = <>) ne $/) {  my $colour_me = 0xffffff;
77          chomp;  my %desc = ('S' => 'spawned on team $team_name[$p1]',
78          ($team, $type, $block, $name, $x, $y, $z, $desc) = split / /, $_, 8;                  'A' => '$p1 armour',
79          $x -= $x0; $y = $height - $y + $y0;                  'KK' => 'killed $enemy using $DamageTypeText[$p2]',
80          if ($type eq 'StaticShape' and $block eq 'GeneratorLarge') {                  'K' => 'killed by $DamageTypeText[$p2] $enemy',
81                  push @landmarks, "$z gen $team $x $y";                  'L' => 'left the game',
82          } elsif ($type eq 'Turret' and $block eq 'TurretBaseLarge') {                  'F+' => 'took the $team_name[$p1] flag',
83                  push @landmarks, "$z turret $team $x $y";                  'F-' => 'dropped the $team_name[$p1] flag',
84          } elsif ($type eq 'StaticShape' and $block eq 'ExteriorFlagStand') {                  'P' => '$p1',
85                  push @landmarks, "$z flag $team $x $y";                  'V' => 'vehicle created',
86          } elsif ($type eq 'StaticShape' and $block eq 'StationVehicle') {                  'W' => 'vehicle destroyed',
87                  push @landmarks, "$z vpad $team $x $y";                  'G' => 'entered " . vehicle_link($p1) . " as ${seat{$p2}}',
88          } elsif ($type eq 'StaticShape' and $block eq 'StationInventory') {                  'J' => 'ejected from vehicle',
89                  push @landmarks, "$z inv $team $x $y";                  'GG' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> entered as ${seat{$p2}}',
90          } elsif ($type eq 'StaticShape' and $block eq 'SensorLargePulse') {                  'JJ' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> ejected');
91                  push @landmarks, "$z sensor $team $x $y";  my @teamcol = (0xffffff, 0x0000ff, 0xff00ff);
92          } elsif ($type eq 'WayPoint' and $block eq 'WayPointMarker') {  my %seat = ('' => 'a passenger', 'p' => 'pilot', 'w' => 'gunner');
93                  push @waypoints, "$team $x $y $z $desc";  my %veh_name = ('BomberFlyer' => 'Bomber',
94          }                  'HAPCFlyer' => 'Havoc',
95  }                  'MobileBaseVehicle' => 'MPB',
96  @landmarks = sort { my ($az, $ra) = split / /, $a, 2; my ($bz, $rb) = split / /, $b, 2;                  'ScoutFlyer' => 'Shrike',
97                  return $az <=> $bz; } @landmarks;                  'AssaultVehicle' => 'Tank',
98                    'ScoutVehicle' => 'Wildcat');
99  $html_index = create_html('Match Summary');  
100    my ($mission, $mission_type, $mission_name, $mission_type_name, $x0, $y0, $width, $height);
101  $time = 0;  my (@landmarks, @waypoints);
102  $nicetime = "0:00";  
103  $imall = create_image();  print "reading data";
104  %alive = ();  read_header();
105  @allevents = ();  
106    my @events = ();
107  while (<>) {  my @coords = ();
108          chomp;  my %score = ();
109          if ($_ eq '') {  my %kills = ();
110                  plot_frame();  my %deaths = ();
111                  $time++;  my %player = ();
112                  $secs = $time % 60;  my %vehicle = ();
113                  $nicetime = int($time / 60) . ':' . (($secs < 10) ? "0$secs" : $secs);  my %team = ();
114                  next;  my $end_time;
115          }  my (@final_score, @team_name);
116    
117          ($cmd, $params) = split / /, $_, 2;  read_data();
118    print ".\n";
119          if ($cmd eq 'S' or $cmd eq 'V') {       # player spawned / new vehicle  
120                  ($id, $team, $name) = split / /, $params, 3;  my $imall = create_image();
121                  if ($cmd eq 'V') {  
122                          $vname{$id} = $name;  my $player;
123                          $name = $id;  foreach $player (keys %player) {
124            print "$player";
125            write_player_report($player);
126            print ".\n";
127    }
128    my $vehicle;
129    foreach $vehicle (keys %vehicle) {
130            my ($team, $name) = split / /, $vehicle, 2;
131            print "$team_name[$team] $veh_name{$name}s";
132            write_vehicle_report($name, $team);
133            print ".\n";
134    }
135    write_summary_report();
136    
137    exit;
138    
139    ####################################################################################################
140    
141    sub read_header {
142            $mission = <LOG>; chomp $mission;
143            $mission_type = <LOG>; chomp $mission_type;
144            $mission_name = <LOG>; chomp $mission_name;
145            $mission_type_name = <LOG>; chomp $mission_type_name;
146            my $area = <LOG>; chomp $area; ($x0, $y0, $width, $height) = split / /, $area;
147    
148            while (($_ = <LOG>) ne $/) {
149                    chomp;
150                    my ($team, $type, $block, $name, $x, $y, $z, $desc) = split / /, $_, 8;
151                    $x -= $x0; $y = $height - $y + $y0;
152                    if ($type eq 'StaticShape' and $block eq 'GeneratorLarge') {
153                            push @landmarks, "$z gen $team $x $y";
154                    } elsif ($type eq 'Turret' and $block eq 'TurretBaseLarge') {
155                            push @landmarks, "$z turret $team $x $y";
156                    } elsif ($type eq 'StaticShape' and $block eq 'ExteriorFlagStand') {
157                            push @landmarks, "$z flag $team $x $y";
158                    } elsif ($type eq 'StaticShape' and $block eq 'StationVehicle') {
159                            push @landmarks, "$z vpad $team $x $y";
160                    } elsif ($type eq 'StaticShape' and $block eq 'StationInventory') {
161                            push @landmarks, "$z inv $team $x $y";
162                    } elsif ($type eq 'StaticShape' and $block eq 'SensorLargePulse') {
163                            push @landmarks, "$z sensor $team $x $y";
164                    } elsif ($type eq 'StaticShape' and $block eq 'SolarPanel') {
165                            push @landmarks, "$z solar $team $x $y";
166                    } elsif ($type eq 'WayPoint' and $block eq 'WayPointMarker') {
167                            push @waypoints, "$team $x $y $z $desc";
168                  }                  }
169                  $name{$id} = $name;          }
170                  $life{$name}++;  
171                  $type{$name} = $cmd eq 'S' ? 'player' : 'vehicle';          # sort by height for nicer plotting
172                  $team{$name} = $team;          @landmarks = sort { my ($az, $ra) = split / /, $a, 2; my ($bz, $rb) = split / /, $b, 2;
173                  $im{$name} = create_image();                          return $az <=> $bz; } @landmarks;
174                  delete $last_pos{$name};  }
175                  delete $pos{$name};  
176                  $alive{$name} = 1;  ####################################################################################################
177                  $near{$name} = {};  
178                  $events{$name} = [];  sub read_data {
179                  if (!exists $html{$name}) {          my $time = 0;
180                          $html{$name} = create_html($name);          my %name = ();
181                          unless ($type{$name} eq 'vehicle') {          my @flag_carrier;
182                                  $html{$name} .= <<END;          my %player_veh;
183  <p>Total score FINALSCORE, deaths FINALDEATHS, kills FINALKILLS.</p>  
184  END          while (<LOG>) {
185                          }                  chomp;
186                          $score{$name} = 0;                  if ($_ eq '') {
187                          $deaths{$name} = 0;                          $time++;
188                          $kills{$name} = 0;                          next;
                 } else {  
                         $html{$name} .= "</table></div>\n";  
189                  }                  }
                 $sname = safe_name($name);  
                 $html{$name} .= <<END;  
 <div><h2 id="life$life{$name}">Life $life{$name} ($nicetime - ENDTIME)</h2>  
 <div><a href="${sname}_$life{$name}.png"><img src="s${sname}_$life{$name}.png"  
 alt="" title="Map of life $life{$name}"></a></div>  
 <table>  
 END  
                 event($name, "spawned on team $team", $yellow);  
190    
191          } elsif ($cmd eq 'F') {         # flag position                  my ($cmd, $params) = split / /, $_, 2;
192    
193          } elsif ($cmd eq 'D') {         # player damaged                  if ($cmd eq 'S') {              # player spawned
194                  ($victim, $attacker, $weapon) = split / /, $params;                          my ($id, $team, $name) = split / /, $params, 3;
195                            $name{$id} = $name;
196                            push @events, [$time, 'S', $name, $team];
197                            $player{$name} = 1;
198                            $team{$name} = $team;
199                            $player_veh{$name} = 0;
200    
201                    } elsif ($cmd eq 'K') {         # player killed
202                            my ($victim, $killer, $weapon) = split / /, $params;
203                            $deaths{$name{$victim}}++;
204                            $kills{$name{$killer}}++ if exists $name{$killer};
205                            push @events, [$time, 'K', $name{$victim}, $name{$killer}, $weapon];
206                            push @events, [$time, 'KK', $name{$killer}, $name{$victim}, $weapon]
207                                            if exists $name{$killer};
208                            if (exists $name{$killer} and $player_veh{$name{$killer}}) {
209                                    push @events, [$time, 'KK', $name{$player_veh{$name{$killer}}},
210                                                    $name{$victim}, $weapon];
211                            }
212                            # if (defined $player_veh{$name})  TODO
213                            delete $name{$victim};
214    
215          } elsif ($cmd eq 'K' or $cmd eq 'L' or $cmd eq 'W') {   # player killed / left / vehicle destroyed                  } elsif ($cmd eq 'L') {         # player left
216                  if ($cmd eq 'K') {                          my ($id, $score) = split / /, $params;
217                          ($victim, $killer, $weapon) = split / /, $params;                          push @events, [$time, 'L', $name{$id}];
218                          $victim = $name{$victim};                          $score{$name{$id}} += $score;
219                          $killer = $name{$killer};                          delete $name{$id};
220                          event($victim, "killed by $DamageTypeText[$weapon]", $red, $killer);  
221                          if (defined $killer) {                  } elsif ($cmd eq 'A') {         # armour changed
222                                  event($killer, "killed ($DamageTypeText[$weapon])", $green, $victim);                          my ($id, $armour) = split / /, $params;
223                                  $kills{$killer}++;                          push @events, [$time, 'A', $name{$id}, $armour];
224    
225                    } elsif ($cmd eq 'I') {         # inventory changed
226                            my ($id, $item, $count) = split / /, $params;
227                            if ($item =~ m/(Pack|SatchelCharge)$/ and $count == 1) {
228                                    $item =~ s/Pack$/ pack/;
229                                    push @events, [$time, 'P', $name{$id}, $item];
230                          }                          }
                         $deaths{$victim}++;  
231    
232                  } elsif ($cmd eq 'L') {                  } elsif ($cmd eq 'D') {         # player damaged
233                          ($victim, $score) = split / /, $params;                          my ($victim, $attacker, $weapon) = split / /, $params;
                         $victim = $name{$victim};  
                         undef $killer;  
                         event($victim, "left the game, score $score", $red);  
                         $score{$victim} += $score;  
234    
235                  } elsif ($cmd eq 'W') {                  } elsif ($cmd eq 'V') {         # new vehicle
236                          $victim = $name{$params};                          my ($id, $team, $name) = split / /, $params, 3;
237                  }                          $vehicle{"$team $name"}++;
238                            $name{$id} = "$team $name " . $vehicle{"$team $name"};
239                            $team{$name{$id}} = $team;
240                            push @events, [$time, 'V', $name{$id}];
241    
242                    } elsif ($cmd eq 'W') {         # vehicle destroyed
243                            my $id = $params;
244                            push @events, [$time, 'W', $name{$id}];
245                            #delete $name{$id};
246    
247                    } elsif ($cmd eq 'Z') {         # final score
248                            my ($team, $score, $team_name) = split / /, $params, 3;
249                            $final_score[$team] = $score;
250                            $team_name[$team] = $team_name;
251    
252                    } elsif ($cmd eq 'F') {         # flag position
253                            my ($team, @data) = split / /, $params;
254                            my $carrier;
255                            $flag_carrier[$team] = 0 unless defined $flag_carrier[$team];
256                            if (@data == 3) {
257                                    my ($x, $y, $z) = @data;
258                                    $x -= $x0; $y = $height - $y + $y0;
259                                    $carrier = 0;
260                            } else {
261                                    $carrier = $name{$data[0]};
262                            }
263                            if ($carrier ne $flag_carrier[$team]) {
264                                    if ($flag_carrier[$team]) {
265                                            push @events, [$time, 'F-', $flag_carrier[$team], $team];
266                                    }
267                                    if ($carrier) {
268                                            push @events, [$time, 'F+', $carrier, $team];
269                                    }
270                                    $flag_carrier[$team] = $carrier;
271                            }
272    
273                  foreach $name (keys %near) {                  } else {                        # player / vehicle position
274                          delete ${$near{$name}}{$victim} if exists ${$near{$name}}{$victim};                          my $id = $cmd;
275                            next unless exists $name{$id};
276                            my $name = $name{$id};
277                            my ($x, $y, $z, $vehicle, $seat) = split / /, $params;
278                            $x -= $x0; $y = $height - $y + $y0;
279                            ${$coords[$time]}{$name} = "$x $y $z";
280                            next unless defined $player{$name};
281                            if ($player_veh{$name} != $vehicle) {
282                                    if ($player_veh{$name}) {
283                                            push @events, [$time, 'J', $name];
284                                            push @events, [$time, 'JJ',
285                                                            $name{$player_veh{$name}}, $name];
286                                    }
287                                    if ($vehicle != 0) {
288                                            push @events, [$time, 'G', $name,
289                                                            $name{$vehicle}, $seat];
290                                            push @events, [$time, 'GG', $name{$vehicle},
291                                                            $name, $seat];
292                                    }
293                                    $player_veh{$name} = $vehicle;
294                            }
295                  }                  }
296            }
297            $end_time = $time + 1;
298    }
299    
300    ####################################################################################################
301    
302                  if ($im{$victim}) {  sub write_player_report {
303                          plot_events($victim);          my $player = shift;
304                          $sname = safe_name($victim);  
305                          save_image($im{$victim}, "${sname}_$life{$victim}.png");          my $score = exists $score{$player} ? $score{$player} : 0;
306            my $deaths = exists $deaths{$player} ? $deaths{$player} : 0;
307            my $kills = exists $kills{$player} ? $kills{$player} : 0;
308            my $sname = safe_name($player);
309            my $html = create_html($player);
310    
311            $html .= <<END;
312    <p>Total score $score, deaths $deaths, kills $kills. <a href="./">Match summary.</a></p>
313    END
314    
315            # find spawn / death times
316            my @spawn = map $$_[0], (grep {$$_[2] eq $player and $$_[1] eq 'S'} @events);
317            my @death = map $$_[0], (grep {$$_[2] eq $player and
318                            ($$_[1] eq 'K' or $$_[1] eq 'L')} @events);
319            push @spawn, $end_time;
320    
321            for (my $life = 0; $life != @spawn - 1; $life++) {
322                    my $nicetime = nice_time($spawn[$life]);
323                    my $nicedtime = nice_time($death[$life]);
324                    my $life1 = $life + 1;
325                    $html .= <<END;
326    <div><h2 id="life$life1">Life $life1 ($nicetime - $nicedtime)</h2>
327    <div><a href="${sname}_$life1.png"><img src="s${sname}_$life1.png"
328    alt="" title="Map of life $life1"></a></div>
329    END
330                    $html .= player_life($player, "${sname}_$life1.png",
331                                    $spawn[$life], $spawn[$life1] - 1);
332                    $html .= '</div>';
333            }
334    
335            save_html(safe_name($player) . '.html', $html);
336    }
337    
338    ####################################################################################################
339    
340    sub player_life {
341            my $player = shift;
342            my $imname = shift;
343            my $time0 = shift;
344            my $time1 = shift;
345    
346            my $prev_time = -1;
347    
348            my $html = "<table>\n";
349    
350            my $im = create_image();
351            plot_route($im, $player, $time0, $time1);
352    
353            my @evs = grep {$$_[2] eq $player and $time0 <= $$_[0] and $$_[0] <= $time1} @events;
354    
355            my $event;
356            foreach $event (@evs) {
357                    my ($time, $ev, $me, $p1, $p2) = @$event;
358    
359                    my $nicetime = nice_time($time);
360                    if ($time == $prev_time) {
361                            $html .= '<tr><td></td>';
362                    } else {
363                            $html .= "<tr id='t$time'><td class='time'>$nicetime</td>";
364                  }                  }
                 delete $alive{$victim};  
                 $html{$victim} =~ s/ENDTIME/$nicetime/;  
365    
366          } elsif ($cmd eq 'A') {         # armour changed                  my $enemy = '';
367                  ($id, $armour) = split / /, $params;                  if (($ev eq 'K' or $ev eq 'KK') and defined $p1) {
368                  $name = $name{$id};                          my $sname_en = safe_name($p1);
369                  $armour{$name} = $armour;                          $enemy = "<a href='$sname_en.html#t$time'>$p1</a>";
                 event($name, "$armour armour", $orange);  
   
         } elsif ($cmd eq 'Z') {         # final score  
   
         } else {                        # player / vehicle position  
                 $id = $cmd;  
                 $name = $name{$id};  
                 next unless (exists $name{$id} and exists $im{$name});  
                 ($x, $y, $z, $vehicle, $seat) = split / /, $params;  
                 $x -= $x0; $y = $height - $y + $y0;  
                 $pos{$name} = "$x $y $z";  
                 if (exists $pending{$name}) {  
                         push @{$events{$name}}, "$x $y $z $pending{$name}";  
                         delete $pending{$name};  
370                  }                  }
371                    my $desc = eval '"' . $desc{$ev} . '"';
372                    my $hexcol = sprintf "%.6lx", $colour{$ev};
373                    $html .= "<td style='color: #$hexcol'>$desc</td></tr>\n";
374    
375                    if (exists ${$coords[$time]}{$player}) {
376                            my ($x, $y, $z) = split / /, ${$coords[$time]}{$player};
377                            square($im, $x, $y, 8, $colour{$ev});
378                    } elsif (exists ${$coords[$time - 1]}{$player}) {
379                            my ($x, $y, $z) = split / /, ${$coords[$time - 1]}{$player};
380                            square($im, $x, $y, 8, $colour{$ev});
381                    }
382                    $prev_time = $time;
383            }
384    
385            $html .= "</table>\n";
386            save_image($im, $imname);
387    
388            return $html;
389    }
390    
391    ####################################################################################################
392    
393    sub plot_route {
394            my $image = shift;
395            my $name = shift;
396            my $t0 = shift;
397            my $t1 = shift;
398            my %near = ();
399            for (my $t = $t0; $t != $t1; $t++) {
400                    my $s = ($t % 10) == 0 ? 2 : 1;
401                    if (exists ${$coords[$t]}{$name}) {
402                            my ($x0, $y0, $z0) = split / /, ${$coords[$t]}{$name};
403                            my $near;
404                            foreach $near (keys %near) {
405                                    if (exists ${$coords[$t]}{$near}) {
406                                            my ($xn, $yn, $zn) = split / /, ${$coords[$t]}{$near};
407                                            delete $near{$near} if $near1 < distance($x0, $y0, $z0,
408                                                            $xn, $yn, $zn);
409                                    } else {
410                                            delete $near{$near};
411                                    }
412                            }
413                            foreach $near (keys %player) {
414                                    next if $near eq $name;
415                                    next if exists $near{$near};
416                                    if (exists ${$coords[$t]}{$near}) {
417                                            my ($xn, $yn, $zn) = split / /, ${$coords[$t]}{$near};
418                                            if (distance($x0, $y0, $z0, $xn, $yn, $zn) < $near0) {
419                                                    $near{$near} = 1;
420                                                    line($image, $x0, $y0, $xn, $yn, 0x444444);
421                                                    text($image, $xn, $yn, $near);
422                                            }
423                                    }
424                            }
425                            foreach $near (keys %near) {
426                                    my ($xn0, $yn0, $zn0) = split / /, ${$coords[$t]}{$near};
427                                    my $colour = $team{$name} == $team{$near} ? 0x00ff00 : 0xff0000;
428                                    line($image, $x0, $y0, $xn0, $yn0, 0x444444) if $s == 2;
429                                    if (exists ${$coords[$t + 1]}{$near}) {
430                                            my ($xn1, $yn1, $zn1) = split / /,
431                                                            ${$coords[$t + 1]}{$near};
432                                            line($image, $xn0, $yn0, $xn1, $yn1, $colour);
433                                    }
434                                    square($image, $xn0, $yn0, $s, $colour);
435                            }
436                            if (exists ${$coords[$t + 1]}{$name}) {
437                                    my ($x1, $y1, $z1) = split / /, ${$coords[$t + 1]}{$name};
438                                    line($image, $x0, $y0, $x1, $y1, $colour_me);
439                                    line($imall, $x0, $y0, $x1, $y1, $teamcol[$team{$name}]);
440                            }
441                            square($image, $x0, $y0, $s, $colour_me);
442                            text($image, $x0, $y0, nice_time($t)) if $s == 2;
443                    }
444          }          }
445  }  }
446    
447  foreach $victim (keys %alive) {  ####################################################################################################
448          if ($im{$victim}) {  
449                  plot_events($victim);  sub write_vehicle_report {
450                  $sname = safe_name($victim);          my $name = shift;
451                  save_image($im{$victim}, "${sname}_$life{$victim}.png");          my $team = shift;
452    
453            my $sname = safe_name($name);
454            my $html = create_html($team_name[$team] . ' ' . $veh_name{$name} . 's');
455            $html .= '<p><a href="./">Match summary.</a></p>';
456    
457            my $run;
458            for ($run = 1; $run != $vehicle{"$team $name"} + 1; $run++) {
459                    my @ev = grep {$$_[2] eq "$team $name $run"} @events;
460                    my $time0 = ${$ev[0]}[0];
461                    my $time1 = ${$ev[-1]}[1] eq 'W' ? ${$ev[-1]}[0] : $end_time;
462                    my $nicetime = nice_time($time0);
463                    my $nicedtime = nice_time($time1);
464    
465                    $html .= <<END;
466    <div><h2 id="life$run">$veh_name{$name} $run ($nicetime - $nicedtime)</h2>
467    <div><a href="${team}_${sname}_$run.png"><img src="s${team}_${sname}_$run.png"
468    alt="" title="Map of $veh_name{$name} $run"></a></div>
469    END
470                    $html .= player_life("$team $name $run", "${team}_${sname}_$run.png",
471                                    $time0, $time1);
472                    $html .= '</div>';
473          }          }
474    
475            save_html("${team}_$sname.html", $html);
476    }
477    
478    ####################################################################################################
479    
480    sub vehicle_link {
481            my $s = shift;
482            my ($team, $name, $run) = split / /, $s;
483            return "<a href='${team}_$name.html#life$run'>$team_name[$team] $veh_name{$name} $run</a>";
484  }  }
485    
486  $html_index .= <<END;  ####################################################################################################
487    
488    sub write_summary_report {
489            my $html = create_html("Match Summary");
490            my $name;
491            my $nicetime = nice_time($end_time);
492            my $i;
493    
494            $html .= <<END;
495  <div><a href="Overview.png"><img src="sOverview.png"  <div><a href="Overview.png"><img src="sOverview.png"
496  alt="" title="Overview map"></a></div>  alt="" title="Overview map"></a></div>
497  <p>Playing time: $nicetime</p>  <p>Playing time $nicetime</p>
498    <table><tr><th>Final scores</th></tr>
499    END
500            for ($i = 1; $i != @team_name; $i++) {
501                    $html .= "<tr><td>${team_name[$i]}</td><td>${final_score[$i]}</td></tr>\n";
502            }
503    
504            $html .= <<END;
505    </table>
506  <table>  <table>
507  <tr><th>Player</th><th>Team</th><th>Score</th><th>Deaths</th><th>Kills</th></tr>  <tr><th>Player</th><th>Team</th><th>Score</th><th>Deaths</th><th>Kills</th></tr>
508  END  END
509  while (($name, $html) = each %html) {  
510          $html .= "</table></div>\n";          foreach $name (sort keys %player) {
511          $html =~ s/FINALSCORE/$score{$name}/;                  my $sname = safe_name($name);
512          $html =~ s/FINALDEATHS/$deaths{$name}/;                  my $score = exists $score{$name} ? $score{$name} : 0;
513          $html =~ s/FINALKILLS/$kills{$name}/;                  my $deaths = exists $deaths{$name} ? $deaths{$name} : 0;
514          $sname = safe_name($name);                  my $kills = exists $kills{$name} ? $kills{$name} : 0;
515          save_html("$sname.html", $html);                  $html .= <<END;
516          if ($type{$name} eq 'player') {  <tr><td><a href="$sname.html">$name</a></td><td>$team_name[$team{$name}]</td><td>$score</td><td>$deaths</td><td>$kills</td></tr>
                 $html_index .= <<END;  
 <tr><td><a href="$sname.html">$name</a></td><td>$team{$name}</td><td>$score{$name}</td><td>$deaths{$name}</td><td>$kills{$name}</td></tr>  
517  END  END
518          }          }
 }  
   
 $html_index .= "</table>\n";  
   
519    
520  #$html_index .= "<h2>Timeline<h2>\n<table class='timeline'>\n";          $html .= "</table>\n";
 $header = "<tr><td></td>";  
 foreach $n (keys %type) {  
         $header .= "<th>$n</th>";  
 }  
 $header .= "</tr>\n";  
 #$html_index .= $header;  
 $time = 0;  
 %event = ();  
 foreach $e (@allevents) {  
         ($t, $colour, $name) = split / /, $e, 3;  
         while ($time < $t) {  
                 $secs = $time % 60;  
                 $nicetime = int($time / 60) . ':' . (($secs < 10) ? "0$secs" : $secs);  
 #               $html_index .= "<tr><td>$nicetime</td>";  
                 foreach $n (keys %type) {  
                         if (exists $event{$n}) {  
                                 $hexcol = sprintf "%.6lx", $event{$n};  
 #                               $html_index .= "<td style='background-color: #$hexcol'>&nbsp;</td>";  
                         } else {  
 #                               $html_index .= "<td>&nbsp;</td>";  
                         }  
                 }  
                 %event = ();  
 #               $html_index .= "</tr>\n";  
                 $time++;  
 #               $html_index .= $header if (($time % 30) == 0);  
         }  
         $event{$name} = $colour;  
 }  
   
 save_image($imall, "Overview.png");  
 #$html_index .= "</table>\n";  
 save_html("index.html", $html_index);  
   
   
 sub plot_frame {  
         $s = 1;  
         $s = 2 if ($time % 10) == 0;  
         foreach $name (keys %alive) {  
                 next unless exists $pos{$name};  
                 ($x, $y, $z) = split / /, $pos{$name};  
                 %near0 = %{$near{$name}};  
                 foreach $name1 (keys %alive) {  
                         next if $name1 eq $name;  
                         ($x1, $y1, $z1) = split / /, $pos{$name1};  
                         my $dist = distance($x, $y, $z, $x1, $y1, $z1);  
                         if (exists ${$near{$name}}{$name1}) {  
                                 delete ${$near{$name}}{$name1} if $near1 < $dist;  
                         } elsif ($dist < $near0) {  
                                 ($x1, $y1, $z1) = split / /, $pos{$name1};  
                                 text($im{$name}, $x1 + 4, $y1, $name1);  
                                 ${$near{$name}}{$name1} = 1;  
                         }  
                 }  
                 foreach $name1 (keys %{$near{$name}}) {  
                         ($x1, $y1, $z1) = split / /, $pos{$name1};  
                         my $colour = $team{$name1} == $team{$name} ? $green : $red;  
                         if ($last_pos{$name1}) {  
                                 ($xp, $yp, $zp) = split / /, $last_pos{$name1};  
                                 line($im{$name}, $xp, $yp, $x1, $y1, $colour);  
                         }  
                         square($im{$name}, $x1, $y1, $s, $colour);  
                         line($im{$name}, $x, $y, $x1, $y1, $grey) if $s == 2;  
                 }  
                 text($im{$name}, $x, $y, $nicetime) if $s == 2;  
                 if (exists $last_pos{$name}) {  
                         ($xp, $yp, $zp) = split / /, $last_pos{$name};  
                         line($im{$name}, $xp, $yp, $x, $y, $white);  
                         line($imall, $xp, $yp, $x, $y, $teamcol[$team{$name}]);  
                 }  
                 square($im{$name}, $x, $y, $s, $white);  
521    
522            $html .= "<table><tr><th>Vehicles</th><th>Total used</th></tr>\n";
523            foreach $vehicle (sort keys %vehicle) {
524                    my ($team, $name) = split / /, $vehicle, 2;
525                    my $sname = safe_name($name);
526                    $html .= <<END;
527    <tr><td><a href="${team}_$sname.html">$team_name[$team] $veh_name{$name}s</a></td><td>${vehicle{"$team $name"}}</td></tr>
528    END
529          }          }
530          %last_pos = %pos;          $html .= "</table>\n";
531          %pos = ();  
532            save_html('index.html', $html);
533            save_image($imall, 'Overview.png');
534  }  }
535    
536    ####################################################################################################
537    
538  sub create_image {  sub create_image {
539          my $image = GD::Image->newTrueColor($width, $height);          my $image = GD::Image->newTrueColor($width, $height);
540          my $lm;          my ($lm, $g);
541          foreach $lm (@landmarks) {          foreach $lm (@landmarks) {
542                  my ($z, $type, $team, $x, $y) = split / /, $lm;                  my ($z, $type, $team, $x, $y) = split / /, $lm;
543                  icon($image, $icon{$type}, $x, $y);                  icon($image, $icon{$type}, $x, $y);
# Line 346  sub save_image { Line 553  sub save_image {
553          my $image = shift;          my $image = shift;
554          my $file = shift;          my $file = shift;
555          my $png = $image->png;          my $png = $image->png;
556          open PNG, ">$file" or die "failed to open $file: $!";          open PNG, ">$outdir/$file" or die "failed to open $outdir/$file: $!";
557          binmode PNG;          binmode PNG;
558          print PNG $png;          print PNG $png;
559          close PNG;          close PNG;
# Line 357  sub save_image { Line 564  sub save_image {
564          $thumb->copyResampled($image, 0, 0, 0, 0, $thumbsize * $width / $max,          $thumb->copyResampled($image, 0, 0, 0, 0, $thumbsize * $width / $max,
565                          $thumbsize * $height / $max, $width, $height);                          $thumbsize * $height / $max, $width, $height);
566          $png = $thumb->png;          $png = $thumb->png;
567          open PNG, ">s$file" or die "failed to open s$file: $!";          open PNG, ">$outdir/s$file" or die "failed to open $outdir/s$file: $!";
568          binmode PNG;          binmode PNG;
569          print PNG $png;          print PNG $png;
570          close PNG;          close PNG;
# Line 384  sub line { Line 591  sub line {
591          $image->line($x0, $y0, $x1, $y1, $colour);          $image->line($x0, $y0, $x1, $y1, $colour);
592  }  }
593    
 sub distance {  
         return sqrt (($_[0] - $_[3]) ** 2 + ($_[1] - $_[4]) ** 2 + ($_[2] - $_[5]) ** 2);  
 }  
   
594  sub load_image {  sub load_image {
595          my $file = shift;          my $file = shift;
596          open PNG, $file or die "failed to open $file: $!";          open PNG, $file or die "failed to open $file: $!";
# Line 411  sub text { Line 614  sub text {
614          my $x = shift;          my $x = shift;
615          my $y = shift;          my $y = shift;
616          my $text = shift;          my $text = shift;
617          $image->string(gdSmallFont, $x, $y, $text, $white);          $image->string(gdSmallFont, $x, $y, $text, 0xffffff);
618  }  }
619    
620    ####################################################################################################
621    
622  sub create_html {  sub create_html {
623          my $title = shift;          my $title = shift;
624          my $html = <<END;          my $html = <<END;
# Line 436  sub save_html { Line 641  sub save_html {
641          my $file = shift;          my $file = shift;
642          my $html = shift;          my $html = shift;
643          $html .= "</body></html>\n";          $html .= "</body></html>\n";
644          open HTML, ">$file" or die "failed to open $file: $!";          open HTML, ">$outdir/$file" or die "failed to open $outdir/$file: $!";
645          print HTML $html;          print HTML $html;
646          close HTML;          close HTML;
647  }  }
648    
649    ####################################################################################################
650    
651  sub safe_name {  sub safe_name {
652          my $s = shift;          my $s = shift;
653          $s =~ tr/[a-zA-Z0-9]/_/cs;          $s =~ tr/[a-zA-Z0-9]/_/cs;
654          return $s;          return $s;
655  }  }
656    
657  sub event {  sub nice_time {
658          my $name = shift;          my $time = shift;
659          return unless exists $html{$name};          my $secs = $time % 60;
660          my $desc = shift;          return int($time / 60) . ':' . (($secs < 10) ? "0$secs" : $secs);
         my $colour = shift;  
         my $name2 = shift;  
         print "$nicetime\t$name $desc";  
         my $hexcol = sprintf "%.6lx", $colour;  
         my $line = "<tr id='t$time'><td class='time'>$nicetime</td><td style='color: #$hexcol'>$desc";  
         if (defined $name2 and exists $html{$name2}) {  
                 print " $name2";  
                 $sname = safe_name($name2);  
                 $line .= " <a href='$sname.html#t$time'>$name2</a>";  
         }  
         print "\n";  
         $line .= "</td></tr>\n";  
         $html{$name} .= $line;  
         if (exists $last_pos{$name}) {  
                 push @{$events{$name}}, "$last_pos{$name} $colour $desc";  
         } else {  
                 $pending{$name} = "$colour $desc";  
         }  
         push @allevents, "$time $colour $name";  
661  }  }
662    
663  sub plot_events {  sub distance {
664          my $name = shift;          return sqrt (($_[0] - $_[3]) ** 2 + ($_[1] - $_[4]) ** 2 + ($_[2] - $_[5]) ** 2);
         foreach $e (@{$events{$name}}) {  
                 my ($x, $y, $z, $colour, $desc) = split / /, $e, 5;  
                 square($im{$name}, $x, $y, 8, $colour);  
         }  
665  }  }
666    
667    ####################################################################################################
668    

Legend:
Removed from v.36  
changed lines
  Added in v.38

  ViewVC Help
Powered by ViewVC 1.1.26