\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);
}
%last_pos = %pos;
%pos = ();
}
sub create_image {
my $image = GD::Image->newTrueColor($width, $height);
my $lm;
foreach $lm (@landmarks) {
my ($z, $type, $team, $x, $y) = split / /, $lm;
icon($image, $icon{$type}, $x, $y);
}
foreach $g (@waypoints) {
my ($team, $x, $y, $z, $desc) = split / /, $g, 5;
text($image, $x, $y, $desc);
}
return $image;
}
sub save_image {
my $image = shift;
my $file = shift;
my $png = $image->png;
open PNG, ">$file" or die "failed to open $file: $!";
binmode PNG;
print PNG $png;
close PNG;
my $max = $width < $height ? $height : $width;
my $thumb = GD::Image->newTrueColor($thumbsize * $width / $max,
$thumbsize * $height / $max);
$thumb->copyResampled($image, 0, 0, 0, 0, $thumbsize * $width / $max,
$thumbsize * $height / $max, $width, $height);
$png = $thumb->png;
open PNG, ">s$file" or die "failed to open s$file: $!";
binmode PNG;
print PNG $png;
close PNG;
}
sub square {
my $image = shift;
return unless defined $image;
my $x = shift;
my $y = shift;
my $s = shift;
my $colour = shift;
$image->filledRectangle($x - $s, $y - $s, $x + $s, $y + $s, $colour);
}
sub line {
my $image = shift;
return unless defined $image;
my $x0 = shift;
my $y0 = shift;
my $x1 = shift;
my $y1 = shift;
my $colour = shift;
$image->line($x0, $y0, $x1, $y1, $colour);
}
sub distance {
return sqrt (($_[0] - $_[3]) ** 2 + ($_[1] - $_[4]) ** 2 + ($_[2] - $_[5]) ** 2);
}
sub load_image {
my $file = shift;
open PNG, $file or die "failed to open $file: $!";
my $im = GD::Image->newFromPng(\*PNG) or die "PNG load of $file failed";
close PNG;
$im->transparent(0);
return $im;
}
sub icon {
my $image = shift;
my $icon = shift;
my $x = shift;
my $y = shift;
$image->setBrush($icon);
$image->setPixel($x, $y, gdBrushed);
}
sub text {
my $image = shift;
my $x = shift;
my $y = shift;
my $text = shift;
$image->string(gdSmallFont, $x, $y, $text, $white);
}
sub create_html {
my $title = shift;
my $html = <$title ($mission_name / $mission_type_name)
$title ($mission_name / $mission_type_name)
END
return $html;
}
sub save_html {
my $file = shift;
my $html = shift;
$html .= "\n";
open HTML, ">$file" or die "failed to open $file: $!";
print HTML $html;
close HTML;
}
sub safe_name {
my $s = shift;
$s =~ tr/[a-zA-Z0-9]/_/cs;
return $s;
}
sub event {
my $name = shift;
return unless exists $html{$name};
my $desc = shift;
my $colour = shift;
my $name2 = shift;
print "$nicetime\t$name $desc";
my $hexcol = sprintf "%.6lx", $colour;
my $line = "