/[james]/t2matchlog/t2matchlog
ViewVC logotype

Annotation of /t2matchlog/t2matchlog

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations) (download)
Sun Nov 30 13:41:03 2003 UTC (20 years, 5 months ago) by james
File size: 20058 byte(s)
Make the script work from any directory.

1 james 36 #!/bin/perl -W
2    
3 james 37 use strict;
4 james 36 use GD;
5    
6 james 38 die "Usage: perl $0 logfile outputdir" unless @ARGV == 2;
7 james 37 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 james 38 my $dir = $0;
11     $dir =~ s!(^|/)[^/]+$!$1!;
12     (system "cp ${dir}t2matchlog.css $outdir/") == 0 or die "Failed to copy stylesheet: $!";
13 james 37
14 james 36 $/ = "\r\n";
15 james 37 $| = 1;
16 james 36
17 james 37 my $near0 = 70;
18     my $near1 = 200;
19     my $thumbsize = 400;
20 james 36
21     # from damageTypes.cs
22 james 37 my @DamageTypeText;
23 james 36 $DamageTypeText[0] = 'default';
24     $DamageTypeText[1] = 'blaster';
25     $DamageTypeText[2] = 'plasma';
26     $DamageTypeText[3] = 'chaingun';
27     $DamageTypeText[4] = 'disc';
28     $DamageTypeText[5] = 'grenade';
29     $DamageTypeText[6] = 'laser';
30     $DamageTypeText[7] = 'ELF';
31     $DamageTypeText[8] = 'mortar';
32     $DamageTypeText[9] = 'missile';
33     $DamageTypeText[10] = 'shocklance';
34     $DamageTypeText[11] = 'mine';
35     $DamageTypeText[12] = 'explosion';
36     $DamageTypeText[13] = 'impact';
37     $DamageTypeText[14] = 'ground';
38     $DamageTypeText[15] = 'turret';
39     $DamageTypeText[16] = 'plasma turret';
40     $DamageTypeText[17] = 'AA turret';
41     $DamageTypeText[18] = 'ELF turret';
42     $DamageTypeText[19] = 'mortar turret';
43     $DamageTypeText[20] = 'missile turret';
44     $DamageTypeText[21] = 'clamp turret';
45     $DamageTypeText[22] = 'spike turret';
46     $DamageTypeText[23] = 'sentry turret';
47     $DamageTypeText[24] = 'out of bounds';
48     $DamageTypeText[25] = 'lava';
49     $DamageTypeText[26] = 'shrike blaster';
50     $DamageTypeText[27] = 'belly turret';
51     $DamageTypeText[28] = 'bomber bomb';
52     $DamageTypeText[29] = 'tank chaingun';
53     $DamageTypeText[30] = 'tank mortar';
54     $DamageTypeText[31] = 'satchel charge';
55     $DamageTypeText[32] = 'MPB missile';
56     $DamageTypeText[33] = 'lighting';
57     $DamageTypeText[35] = 'ForceField';
58     $DamageTypeText[36] = 'Crash';
59     $DamageTypeText[98] = 'nexus camping';
60     $DamageTypeText[99] = 'suicide';
61    
62 james 38 my $icon_player = load_image("${dir}icons/com_player_grey_24x.png");
63 james 37 my %icon;
64 james 38 $icon{'flag'} = load_image("${dir}icons/com_icon_flag_outside.png");
65     $icon{'gen'} = load_image("${dir}icons/com_icon_generator.png");
66     $icon{'turret'} = load_image("${dir}icons/com_icon_turretbase.png");
67     $icon{'inv'} = load_image("${dir}icons/com_icon_inventory.png");
68     $icon{'sensor'} = load_image("${dir}icons/com_icon_sensor.png");
69     $icon{'vpad'} = load_image("${dir}icons/com_icon_vehicle_inventory.png");
70     $icon{'solar'} = load_image("${dir}icons/com_icon_solar_gen.png");
71 james 36
72 james 37 my %colour = ('S' => 0xffff00, 'A' => 0xff8000, 'KK' => 0x00ff00, 'K' => 0xff0000,
73     'L' => 0xff8000, 'F+' => 0x00ffff, 'F-' => 0xff00ff, 'P' => 0xff8000,
74     'V' => 0xffff00, 'W' => 0xff0000, 'G' => 0x0080ff, 'J' => 0x00ff80,
75     'GG' => 0x0080ff, 'JJ' => 0x00ff80);
76     my $colour_me = 0xffffff;
77     my %desc = ('S' => 'spawned on team $team_name[$p1]',
78     'A' => '$p1 armour',
79     'KK' => 'killed $enemy using $DamageTypeText[$p2]',
80     'K' => 'killed by $DamageTypeText[$p2] $enemy',
81     'L' => 'left the game',
82     'F+' => 'took the $team_name[$p1] flag',
83     'F-' => 'dropped the $team_name[$p1] flag',
84     'P' => '$p1',
85     'V' => 'vehicle created',
86     'W' => 'vehicle destroyed',
87     'G' => 'entered " . vehicle_link($p1) . " as ${seat{$p2}}',
88     'J' => 'ejected from vehicle',
89     'GG' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> entered as ${seat{$p2}}',
90     'JJ' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> ejected');
91     my @teamcol = (0xffffff, 0x0000ff, 0xff00ff);
92     my %seat = ('' => 'a passenger', 'p' => 'pilot', 'w' => 'gunner');
93     my %veh_name = ('BomberFlyer' => 'Bomber',
94     'HAPCFlyer' => 'Havoc',
95     'MobileBaseVehicle' => 'MPB',
96     'ScoutFlyer' => 'Shrike',
97     'AssaultVehicle' => 'Tank',
98     'ScoutVehicle' => 'Wildcat');
99    
100     my ($mission, $mission_type, $mission_name, $mission_type_name, $x0, $y0, $width, $height);
101     my (@landmarks, @waypoints);
102    
103     print "reading data";
104     read_header();
105    
106     my @events = ();
107     my @coords = ();
108     my %score = ();
109     my %kills = ();
110     my %deaths = ();
111     my %player = ();
112     my %vehicle = ();
113     my %team = ();
114     my $end_time;
115     my (@final_score, @team_name);
116    
117     read_data();
118     print ".\n";
119    
120     my $imall = create_image();
121    
122     my $player;
123     foreach $player (keys %player) {
124     print "$player";
125     write_player_report($player);
126     print ".\n";
127 james 36 }
128 james 37 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 james 36
137 james 37 exit;
138 james 36
139 james 37 ####################################################################################################
140 james 36
141 james 37 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 james 36 }
170    
171 james 37 # sort by height for nicer plotting
172     @landmarks = sort { my ($az, $ra) = split / /, $a, 2; my ($bz, $rb) = split / /, $b, 2;
173     return $az <=> $bz; } @landmarks;
174     }
175 james 36
176 james 37 ####################################################################################################
177    
178     sub read_data {
179     my $time = 0;
180     my %name = ();
181     my @flag_carrier;
182     my %player_veh;
183    
184     while (<LOG>) {
185     chomp;
186     if ($_ eq '') {
187     $time++;
188     next;
189 james 36 }
190 james 37
191     my ($cmd, $params) = split / /, $_, 2;
192    
193     if ($cmd eq 'S') { # player spawned
194     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 james 36 }
212 james 37 # if (defined $player_veh{$name}) TODO
213     delete $name{$victim};
214    
215     } elsif ($cmd eq 'L') { # player left
216     my ($id, $score) = split / /, $params;
217     push @events, [$time, 'L', $name{$id}];
218     $score{$name{$id}} += $score;
219     delete $name{$id};
220    
221     } elsif ($cmd eq 'A') { # armour changed
222     my ($id, $armour) = split / /, $params;
223     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     }
231    
232     } elsif ($cmd eq 'D') { # player damaged
233     my ($victim, $attacker, $weapon) = split / /, $params;
234    
235     } elsif ($cmd eq 'V') { # new vehicle
236     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     } else { # player / vehicle position
274     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 james 36 }
296 james 37 }
297     $end_time = $time + 1;
298     }
299    
300     ####################################################################################################
301    
302     sub write_player_report {
303     my $player = shift;
304    
305     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 james 36 END
314    
315 james 37 # 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 james 36
321 james 37 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 james 36
335 james 37 save_html(safe_name($player) . '.html', $html);
336     }
337 james 36
338 james 37 ####################################################################################################
339 james 36
340 james 37 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 james 36 }
365    
366 james 37 my $enemy = '';
367     if (($ev eq 'K' or $ev eq 'KK') and defined $p1) {
368     my $sname_en = safe_name($p1);
369     $enemy = "<a href='$sname_en.html#t$time'>$p1</a>";
370 james 36 }
371 james 37 my $desc = eval '"' . $desc{$ev} . '"';
372     my $hexcol = sprintf "%.6lx", $colour{$ev};
373     $html .= "<td style='color: #$hexcol'>$desc</td></tr>\n";
374 james 36
375 james 37 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 james 36 }
382 james 37 $prev_time = $time;
383     }
384 james 36
385 james 37 $html .= "</table>\n";
386     save_image($im, $imname);
387 james 36
388 james 37 return $html;
389     }
390 james 36
391 james 37 ####################################################################################################
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 james 36 }
444     }
445     }
446    
447 james 37 ####################################################################################################
448    
449     sub write_vehicle_report {
450     my $name = shift;
451     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 james 36 }
474 james 37
475     save_html("${team}_$sname.html", $html);
476 james 36 }
477    
478 james 37 ####################################################################################################
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     ####################################################################################################
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 james 36 <div><a href="Overview.png"><img src="sOverview.png"
496     alt="" title="Overview map"></a></div>
497 james 37 <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 james 36 <table>
507     <tr><th>Player</th><th>Team</th><th>Score</th><th>Deaths</th><th>Kills</th></tr>
508     END
509 james 37
510     foreach $name (sort keys %player) {
511     my $sname = safe_name($name);
512     my $score = exists $score{$name} ? $score{$name} : 0;
513     my $deaths = exists $deaths{$name} ? $deaths{$name} : 0;
514     my $kills = exists $kills{$name} ? $kills{$name} : 0;
515     $html .= <<END;
516     <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>
517 james 36 END
518     }
519    
520 james 37 $html .= "</table>\n";
521 james 36
522 james 37 $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     $html .= "</table>\n";
531 james 36
532 james 37 save_html('index.html', $html);
533     save_image($imall, 'Overview.png');
534 james 36 }
535    
536 james 37 ####################################################################################################
537 james 36
538     sub create_image {
539     my $image = GD::Image->newTrueColor($width, $height);
540 james 37 my ($lm, $g);
541 james 36 foreach $lm (@landmarks) {
542     my ($z, $type, $team, $x, $y) = split / /, $lm;
543     icon($image, $icon{$type}, $x, $y);
544     }
545     foreach $g (@waypoints) {
546     my ($team, $x, $y, $z, $desc) = split / /, $g, 5;
547     text($image, $x, $y, $desc);
548     }
549     return $image;
550     }
551    
552     sub save_image {
553     my $image = shift;
554     my $file = shift;
555     my $png = $image->png;
556 james 37 open PNG, ">$outdir/$file" or die "failed to open $outdir/$file: $!";
557 james 36 binmode PNG;
558     print PNG $png;
559     close PNG;
560    
561     my $max = $width < $height ? $height : $width;
562     my $thumb = GD::Image->newTrueColor($thumbsize * $width / $max,
563     $thumbsize * $height / $max);
564     $thumb->copyResampled($image, 0, 0, 0, 0, $thumbsize * $width / $max,
565     $thumbsize * $height / $max, $width, $height);
566     $png = $thumb->png;
567 james 37 open PNG, ">$outdir/s$file" or die "failed to open $outdir/s$file: $!";
568 james 36 binmode PNG;
569     print PNG $png;
570     close PNG;
571     }
572    
573     sub square {
574     my $image = shift;
575     return unless defined $image;
576     my $x = shift;
577     my $y = shift;
578     my $s = shift;
579     my $colour = shift;
580     $image->filledRectangle($x - $s, $y - $s, $x + $s, $y + $s, $colour);
581     }
582    
583     sub line {
584     my $image = shift;
585     return unless defined $image;
586     my $x0 = shift;
587     my $y0 = shift;
588     my $x1 = shift;
589     my $y1 = shift;
590     my $colour = shift;
591     $image->line($x0, $y0, $x1, $y1, $colour);
592     }
593    
594     sub load_image {
595     my $file = shift;
596     open PNG, $file or die "failed to open $file: $!";
597     my $im = GD::Image->newFromPng(\*PNG) or die "PNG load of $file failed";
598     close PNG;
599     $im->transparent(0);
600     return $im;
601     }
602    
603     sub icon {
604     my $image = shift;
605     my $icon = shift;
606     my $x = shift;
607     my $y = shift;
608     $image->setBrush($icon);
609     $image->setPixel($x, $y, gdBrushed);
610     }
611    
612     sub text {
613     my $image = shift;
614     my $x = shift;
615     my $y = shift;
616     my $text = shift;
617 james 37 $image->string(gdSmallFont, $x, $y, $text, 0xffffff);
618 james 36 }
619    
620 james 37 ####################################################################################################
621    
622 james 36 sub create_html {
623     my $title = shift;
624     my $html = <<END;
625     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
626     "http://www.w3.org/TR/html4/strict.dtd">
627     <html>
628     <head>
629     <link rel="stylesheet" type="text/css" href="t2matchlog.css">
630     <title>$title ($mission_name / $mission_type_name)</title>
631     </head>
632    
633     <body>
634     <h1>$title <em class="mission">($mission_name / $mission_type_name)</em></h1>
635    
636     END
637     return $html;
638     }
639    
640     sub save_html {
641     my $file = shift;
642     my $html = shift;
643     $html .= "</body></html>\n";
644 james 37 open HTML, ">$outdir/$file" or die "failed to open $outdir/$file: $!";
645 james 36 print HTML $html;
646     close HTML;
647     }
648    
649 james 37 ####################################################################################################
650    
651 james 36 sub safe_name {
652     my $s = shift;
653     $s =~ tr/[a-zA-Z0-9]/_/cs;
654     return $s;
655     }
656    
657 james 37 sub nice_time {
658     my $time = shift;
659     my $secs = $time % 60;
660     return int($time / 60) . ':' . (($secs < 10) ? "0$secs" : $secs);
661 james 36 }
662    
663 james 37 sub distance {
664     return sqrt (($_[0] - $_[3]) ** 2 + ($_[1] - $_[4]) ** 2 + ($_[2] - $_[5]) ** 2);
665 james 36 }
666    
667 james 37 ####################################################################################################
668    

  ViewVC Help
Powered by ViewVC 1.1.26