Sie sind auf Seite 1von 16

#!

/usr/bin/perl
use Getopt::Std;
our($opt_f,$opt_o,$opt_h,$opt_x,$opt_y,$opt_s) = ();
getopts('hf:o:x:y:s:');
if ($opt_h) {
print <<EOF
$0 [-x x ] [-y y ] [-s squares/hexes-to-inch ]
[-f input (-)] [-o output (-) ] [-h]
-- Make SVG map from level description file
EOF
;
exit 0;
}
# Map constants
$sqtoinch = ($opt_s?$opt_s:4);
$xrange = ($opt_x?$opt_x:30);
$yrange = ($opt_y?$opt_y:$xrange);
$iqs = 1/$sqtoinch;
# M is a scaling factor because font sizes don't work well with
# fractional points
$m = 100;
# One-page template is 30x30
$gridsizex=$xrange * $m;
$gridsizey=$yrange * $m;
# Adjust so it looks nice, if this doesn't suit
$gridstroke = 0.008 * $m;
$wallstroke = 0.05 * $m;
$thickwallstroke = 0.15 * $m;
$thinstroke = 0.02 * $m;
# defaults for polygon
$maxdev = 0.3;
$minsize = 1.0; # in scaled grid units
$PI=3.14159265;
# Hex Constants
$SQRT3=sqrt(3);
# File that holds level data
unless ($opt_f) {
$opt_f = "-";
}
open (INPUT,"<$opt_f") or
die ("Could not open level data file $opt_f: $!\n");
if ($opt_o) {
open(OUTPUT,">$opt_o") or do {
close(INPUT);
die("Could not open output file $filename: $!\n");
};
select OUTPUT;
}
# For scaling the paper. One-page template is actually
# six-to-the-inch, five inches square. SVG looks better a bit bigger.
$height = $gridsizey * $iqs / $m;
$width = $gridsizex * $iqs / $m;
$strokecolor="#1EAED0"; # TSR Blue, as near as we can figure
# Print SVG header
print <<EOF
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/
<svg width="${width}in" height="${height}in" viewBox="0 0 $gridsizex $gridsizey" xmlns="htt
<desc>map grid</desc>
EOF
;
buildlib();
drawfeatures();
# Print SVG footer
print "</svg>\n";
if ($opt_o) {
close OUTPUT;
select STDOUT;
}
exit 0;
sub buildlib {
# Define hatching for pits
my $s = $m * .25;
my $w = $m * .015;
print <<EOF;
<defs>
<pattern id="hatch00" patternUnits="userSpaceOnUse"
x="0" y="0" width="$s" height="$s"
viewBox="0 0 $s $s">
<g style="fill:white; stroke: $strokecolor;
stroke-width:$w">
<path d="M0,0 $s,$s" />
</g>
</pattern>
</defs>
EOF
;
}

sub drawgrid {
my $i, $j = 0;
for ($i=0; $i < $gridsizey; $i += $m) {
for ($j=0; $j < $gridsizex; $j += $m) {
print (" <rect height=\"" . $m . "\" width=\"" . $m .
"\" stroke=\"" . $strokecolor . "\" y=\"" . $i .
"\" x=\"". $j . "\" stroke-width=\"" .
$gridstroke . "\" fill=\"none\"/>\n");
}
}
}
sub drawhexgrid {
# Because of the bounding rectangle, this is actually
# smaller than the dimensions specified...
my $t = shift;
my $i, $j = 0;
my $xmax = $xrange - 1;
my $ymax = int($yrange / ( (4/3) * ($SQRT3 / 2 ) ));
for ($i = 1; $i <= $ymax; $i++) {
for ($j = 1; $j <= $xmax; $j++) {
drawhex($j,$i,$t,0);
}
}
}
sub drawhex {
my ($x,$y,$t,$c) = @_;
my $color="none";
$color = $strokecolor if (defined($c) && $c);
# return if (($y == $yrange) && ($x == $xrange) && ($x % 2 == 0));
# my $cx = ((($x - 1) * 0.75) + 0.5) * $m;
my $cx = (($x - 1) + (2/3)) * $m;
my $cy = ((($SQRT3 / 2) * ($y)) - ($SQRT3 * ($x % 2) / 4)) * (4/3) * $m;
print(" <polygon fill=\"" . $color . "\" stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $gridstroke . "\" points=\"" .
($cx - ((2/3) * $m)) . "," . $cy . " " .
($cx - ((1/3) * $m)) . "," . ($cy - ($SQRT3 / 3) * $m ) . " " .
($cx + ((1/3) * $m)) . "," . ($cy - ($SQRT3 / 3) * $m ) . " " .
($cx + ((2/3) * $m)) . "," . $cy . " " .
($cx + ((1/3) * $m)) . "," . ($cy + ($SQRT3 / 3) * $m ) . " " .
($cx - ((1/3) * $m)) . "," . ($cy + ($SQRT3 / 3) * $m ) . " " .
($cx - ((2/3) * $m)) . "," . $cy .
"\"\/>\n");
drawhexnum($x,$y,$t);
}
sub drawhexfeature {
my ($x,$y,$t,$k) = @_;
my $cx = (($x - 1) + (2/3)) * $m;
my $cy = ((($SQRT3 / 2) * ($y)) - ($SQRT3 * ($x % 2) / 4)) * (4/3) * $m;
if ($t == 0) {
# Solid hex with/without numbers
drawhex($x,$y,-$k,1);
} elsif ($t == 1) {
# Triangular mountain
my $color="#FFFFFF"; # White
$color = $strokecolor if $k; # Or map-colored
print (" <polygon fill=\"" . $color .
"\" stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $wallstroke . "\" points=\"" .
$cx . "," . ($cy - ($SQRT3 * 3/16) * $m ) . " " .
($cx + ((3/8) * $m)) . "," . ($cy + ($SQRT3 / 6) * $m ) . " " .
($cx - ((3/8) * $m)) . "," . ($cy + ($SQRT3 / 6) * $m ) . " " .
"\"\/>\n");
} elsif ($t == 2) {
# Hills
for my $angle ( 0, 120, 240) {
my $xo = cos($PI*$angle/180);
my $yo = sin($PI*$angle/180);
my $fr = $SQRT3/8;
my $hw = 0.25;
my $s = " <path stroke=\"" . $strokecolor;
$s .= "\" stroke-width=\"" . $thinstroke;
$s .= "\" fill=\"none";
$s .= "\" d=\"M";
$s .= $cx + ($xo * $fr + $hw) *$m . ",";
$s .= $cy + (($yo * $fr) + $SQRT3/12) * $m . " A";
$s .= $fr * $m . ",";
$s .= $fr * $m * 0.5 . ",0,0,0,";
$s .= $cx + ($xo * $fr - $hw) *$m . ",";
$s .= $cy + (($yo * $fr ) + $SQRT3/12) * $m . "\"/>\n";
print $s;
}
if (defined($k) && $k) {
my $s = " <circle r=\"";
$s .= 0.05 * $m;
$s .= "\" fill=\"";
$s .= $strokecolor;
$s .= "\" cx=\"";
$s .= $cx - 0.08 * $m ;
$s .= "\" cy=\"";
$s .= $cy - 0.07 * $m;
$s .= "\"/>\n";
print $s;
}
} elsif ($t == 3) {
# Radiation
print(" <circle r=\"". (($SQRT3/18) * $m) . "\" fill=\""
. $strokecolor . "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
my $ir = $SQRT3 / 12;
my $or = $SQRT3 / 4;
if (defined($k) && ($k == 1)) {
# White background
print(" <circle r=\"". $or . "\" fill=\""
. "#FFFFFF" . "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
}
for my $angle (60 , 180, 300) {
my $scalex1 = cos($PI*$angle/180);
my $scaley1 = sin($PI*$angle/180);
my $scalex2 = cos($PI*($angle + 60)/180);
my $scaley2 = sin($PI*($angle + 60)/180);
my $s = " <path fill=\"";
$s .= $strokecolor . "\" stroke=\"";
$s .= $strokecolor . "\" stroke-width=\"";
$s .= $thinstroke . "\" d=\"M";
$s .= $cx + ($scalex1 * $m * $or) . ",";
$s .= $cy + ($scaley1 * $m * $or) . " A";
$s .= ($or * $m) . "," . ($or * $m) . "," . "0,0,1,";
$s .= $cx + ($scalex2 * $m * $or) . ",";
$s .= $cy + ($scaley2 * $m * $or) . " L";
$s .= $cx + ($scalex2 * $m * $ir) . ",";
$s .= $cy + ($scaley2 * $m * $ir) . " A";
$s .= ($ir * $m) . "," . ($ir * $m) . "," . "0,0,0,";
$s .= $cx + ($scalex1 * $m * $ir) . ",";
$s .= $cy + ($scaley1 * $m * $ir) . " Z\" />";
print "$s\n";
}
} elsif ($t==4) {
# swamp
my @xoff = (-0.2,.1,-0.35,-0.1,-0.2);
my @yoff = (-0.1,0,0.1,0.2,0.3);
for my $i ( 0 .. 4) {
# horizontal water lines
my $s = " <line x1=\"";
$s .= $cx + $xoff[$i]*$m ;
$s .= "\" y1=\"";
my $cury = $cy + $yoff[$i] * $m;
$s .= $cury;
$s .= "\" x2=\"";
$s .= $cx + (.4 + $xoff[$i])*$m ;
$s .= "\" y2=\"";
$s .= $cury;
$s .= "\" style=\"stroke: ";
$s .= $strokecolor;
$s .= "; stroke-width: ";
$s .= $thinstroke;
$s .= "; stroke-dasharray: 9 2 3 2;\"";
$s .= "/>\n";
print $s;
}
my @xr = map { $m * $_ } ( 0.2, 0.3, 0.4);
my @yr = map { 0.5 + $m * $_} ( 0.2, 0.3, 0.4);
my @xe = map { cos($PI * $_ / 180) * $m * 0.3 + $cx } ( 190, 230, 290);
my @ye = map { sin($PI * $_ / 180) * $m * 0.5 * cos($PI * $_ / 180) + $cy - 0.1 * $
for my $i ( 0 .. 2) {
my $s = " <path d=\"M";
$s .= $cx;
$s .= ",";
$s .= $cy + 0.25 * $m;
$s .= " A";
$s .= $xr[$i];
$s .= ",";
$s .= $yr[$i];
$s .= ",";
$s .= (-40 + 25*$i);
$s .= ",0,0,";
$s .= $xe[$i];
$s .= ",";
$s .= $ye[$i];
$s .= "\" style=\"stroke: ";
$s .= $strokecolor;
$s .= "; stroke-width: ";
$s .= $thinstroke;
$s .= "\" fill=\"none\"/>\n";
print $s;
}
} elsif ($t == 5) {
# Pine Forest
my $scale = 0.12;
my $s = " <rect style=\"fill:none";
$s .= ";stroke:";
$s .= $strokecolor;
$s .= ";stroke-width:";
$s .= $thinstroke;
$s .= "\" x=\"";
$s .= $cx - ($m*$scale/3);
$s .= "\" y=\"";
$s .= $cy;
$s .= "\" width=\"";
$s .= $m * 2 * $scale / 3;
$s .= "\" height=\"";
$s .= $m * 4 * $scale;
$s .= "\" />\n";
print $s;
for my $i ( 0 .. 2 ) {
my $s = " <polygon style=\"fill:";
$s .= $strokecolor;
$s .= ";stroke:";
$s .= $strokecolor;
$s .= ";stroke-width:";
$s .= $wallstroke;
$s .= "\" points=\"";
my $top = $cy - ($scale * $i *$m);
$s .= $cx;
$s .= ",";
$s .= $top;
$s .= " ";
$s .= $cx - ($scale * $m);
$s .= ",";
$bot = $top + (2 * $scale * $m);
$s .= $bot;
$s .= " ";
$s .= $cx + ($scale * $m);
$s .= ",";
$s .= $bot;
$s .= "\" />\n";
print $s;
}
} elsif ($t == 6) {
# ruins
seedrand(0.3,1,0);
my $s = " <polygon style=\"fill:";
$s .= "none";
$s .= ";stroke:";
$s .= $strokecolor;
$s .= ";stroke-width:";
$s .= $thinstroke;
$s .= "\" points=\"";
print $s;
print $cx - 0.3 * $m;
print ",";
print $cy - 0.1 * $m;
print " ";
print $cx - 0.3 * $m;
print ",";
print $cy + 0.3 * $m;
print " ";
my $x1 = $cx + 0.3 * $m;
print $x1;
print ",";
print $cy + 0.3 * $m;
my $y1 = $cy - 0.1 * $m;
print " ";
my $x2 = $x1 - 0.1 * $m;
my $y2 = $y1 + 0.2 * $m;
crinkle($x1,$y1,$x2,$y2);
$y1 = $y2 + 0.1 * $m;
print "\n ";
print $x2;
print ",";
print $y1;
$x1 = $x2 - 0.2 * $m;
$x2 = $x1 - 0.1 * $m;
crinkle($x1,$y1,$x2,$y2);
$x1 = $x2 - 0.1 * $m;
$y1 = $y2 - 0.2 * $m;
print "\n ";
print $x1;
print ",";
print $y2;
print " ";
$y2 = $y1;
$x2 = $x1 - 0.1 * $m;
crinkle($x1,$y1,$x2,$y2);
print "\n ";
print "\" />\n";
my $s = " <polygon style=\"fill:";
$s .= "none";
$s .= ";stroke:";
$s .= $strokecolor;
$s .= ";stroke-width:";
$s .= $thinstroke;
$s .= "\" points=\"";
print $s;
$x2 = $cx - 0.3 * $m;
print $x2;
print ",";
$y1 = $cy + 0.3 * $m;
print $y1;
print " ";
$x1 = $x2 - 0.1 * $m;
$y2 = $y1 - 0.2 * $m;
crinkle ($x1,$y1,$x2,$y2);
print "\" />\n";
} elsif ($t == 7) {
# Settlements
if ($k == 0) {
# Hamlet
print(" <circle r=\"" .( 0.1 * $m) . "\" fill=\"none\""
. " stroke-width=\"" . $thinstroke
. "\" stroke=\"" . $strokecolor
. "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
} elsif ($k == 1) {
print(" <circle r=\"" .( 0.1 * $m) . "\" fill=\"none\""
. " stroke-width=\"" . $wallstroke
. "\" stroke=\"" . $strokecolor
. "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
} elsif (($k == 2) or ($k == 3)) {
if ($k == 3) {
# City
print(" <circle r=\"" .( 0.22 * $m) . "\" fill=\"none\""
. " stroke-width=\"" . $wallstroke
. "\" stroke=\"" . $strokecolor
. "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
}
# Town
print(" <circle r=\"" .( 0.15 * $m) . "\" fill=\""
. $strokecolor . "\" cx=\"" . $cx . "\" cy=\""
. $cy . "\"/>\n");
}
}
}
sub drawhexnum {
my ($x,$y,$t) = @_;
return unless ($t);
my $color = $strokecolor;
if ($t == -1) {
$color = "#FFFFFF";
}
# return if (($y == $yrange) && ($x % 2 == 0) && ($y % 2 == 0));
my $xmax = $xrange - 1;
my $ymax = int($yrange / ( (4/3) * ($SQRT3 / 2 ) ));
my $lx = length($xmax);
my $ly = length($ymax);
my $cx = (($x - 1) + (2/3)) * $m;
my $cy = ((($SQRT3 / 2) * ($y)) - ($SQRT3 * ($x % 2) / 4)) * (4/3) * $m;
my $hexnum = sprintf("%0${lx}d%0${ly}d",$x,$y);
# my $font="HelveticaNeue-CondensedBold";
my $font="HelveticaNeue-UltraLight";
# my $font="ArialNarrow";
my $len = $lx + $ly;
my $size = 0.2 * (6/($len+2)) * $m;
my $x1 = $cx - ( 4 * $m / $size );
my $y1 = $cy - (($SQRT3 / 3 ) * $m) + $size;
my $ffamily = "sans-serif";
print " <text x=\"" . $x1 . "\" y=\"" . $y1 .
"\" style=\"font-family: " . $font . ","
. $ffamily .";" .
"stroke: " . $color . "; " .
"font-size: " . $size . "; " .
"stroke-width: " . $thinstroke . "; " .
"fill: " . $color . ";\">" . $hexnum .
"</text>\n";
}
sub seedrand {
my ($x,$y,$seed) = @_;
$maxdev = $x;
$minsize = $y;
if ($maxdev < 0) {
$maxdev = 0; # That would be straight lines....
# 0.2 is nice for streams/laminar flow
# 0.3 gives something pretty close to classic module caves,
# 0.4 is highly fractal
# > 0.5 is not guaranteed to converge
# > 0.9 probably WON'T converge in a reasonable time
}
if ($maxdev >= 1.0) {
$maxdev = 0.9; # Otherwise it will probably never converge
}
if ($minsize < 0.1) {
$minsize = 0.1; # This is scaled, so that's REALLY tiny
# Leaving this at 1.0 is usually fine
}
if ($seed) {
srand($seed);
}
}
sub drawfeatures {
my $inproc = 0;
my $savex = 0;
my $savey = 0;
my $saver = 0;
my $saves = 0;
while (<INPUT>) {
if ($inproc == 20) {
unless (/^\s*20,/) {
print;
next;
}
}
chomp;
s/^\s+//;
s/\s+$//;
# Discard comments and blank lines
next if (/^$/);
next if (/^#/);
my ($kind,$startx,$starty,$endx,$endy,$type) = split(',');
my $x1 = $startx * $m;
my $y1 = $starty * $m;
my $x2 = 0;
my $y2 = 0;
unless (($kind == 9) or ($kind==10)) {
# Text doesn't use the second coordinates, and doing math on
# a string is a bad idea
# And for the cave-wall-randomized, it's completely different.
$x2 = $endx * $m;
$y2 = $endy * $m;
}
if ($kind == 1) {
# Wall
my $sw = $wallstroke;
if (($type == 2) or ($type == 4)) {
# Thick or dotted
$sw=$thickwallstroke;
}
if ($type == 5) {
# Thin (used for furniture)
$sw = $thinstroke;
}
# Draw a wall
print " <line x1=\"" . $x1 . "\" y1=\"" . $y1 .
"\" x2=\"" . $x2 . "\" y2 =\"" . $y2 . "\" " .
"stroke = \"" . $strokecolor . "\" stroke-width=\"" . $sw .
"\" ";
if ($type == 3 ) { # Dashed
print "stroke-dasharray=\"" . (0.2 * $m) . " " .
(0.2 * $m) . "\"";
} elsif ($type == 4) { # Dotted
print "stroke-dasharray=\"" . (0.10 * $m) . " " .
(0.15 * $m) . "\"";
}
print "/>\n";
} elsif ($kind == 2) {
# Circular Arc
$inproc=2;
$savex=$x1;
$savey=$y1;
$saver=$x2;
my $sw = $wallstroke;
if (($type == 2) or ($type == 4)) {
# Thick or dotted
$sw=$thickwallstroke;
}
if ($type == 5) {
# Thin (used for furniture)
$sw = $thinstroke;
}
print " <path style=\"stroke:" . $strokecolor . ";";
print "stroke-width:" . $sw ;
if ($type == 3 ) { # Dashed
print ";stroke-dasharray:" . (0.2 * $m) . "," .
(0.2 * $m);
} elsif ($type == 4) { # Dotted
print ";stroke-dasharray:" . (0.10 * $m) . "," .
(0.15 * $m);
}
print ";fill:none\" ";
} elsif (($kind == 99) && ($type==99) && ($inproc==2)) {
my $start=$startx % 360.0;
my $end=$starty % 360.0;
if ($start > $end) {
$end += 360;
}
my $large=0;
my $sweepflag=1;
if (($end-$start) > 180) {
$large=1;
}
my $sx = $savex + (sin($start * $PI / 180) * $saver);
my $sy = $savey - (cos($start * $PI / 180) * $saver);
my $ex = $savex + (sin($end * $PI / 180) * $saver) - $sx;
my $ey = $savey - (cos($end * $PI / 180) * $saver) - $sy;
print "d=\"M" . $sx . "," . $sy;
print " a" . $saver . "," . $saver . " 0 " . $large . ",";
print $sweepflag . " " . $ex . "," . $ey . "\"/>\n";
$inproc = 0;
$savex = 0;
$savey = 0;
$saver = 0;
} elsif ($kind == 3) { # Door
my $sw = $wallstroke;
my $h = 0.4 * $m ;
my $w = 0.2 * $m ;
my $x = $x1 - (0.1 * $m);
my $y = $y1 + (0.3 * $m);
if ($type == 2) { # Horizontal Door
$h = (0.2 * $m);
$w = (0.4 * $m);
$x = $x1 + (0.3 * $m);
$y = $y1 - (0.1 * $m);
} elsif ($type == 3) { # Vertical Double Door
$h = (0.3 * $m);
$y = $y1 + (0.2 * $m);
} elsif ($type == 4) { # Horizontal Double Door
$h = 0.2 * $m;
$w = 0.3 * $m;
$x = $x1 + (0.2 * $m);
$y = $y1 - (0.1 * $m);
}
print (" <rect height=\"" . $h . "\" width=\"" . $w .
"\" stroke=\"" . $strokecolor . "\" y=\"" . $y .
"\" x=\"". $x . "\" stroke-width=\"" .
$sw . "\" fill=\"white\"/>\n");
if (($type == 3) or ($type == 4)) {
if ($type == 3) {
$y = $y + (0.3 * $m);
} elsif ($type == 4) {
$x = $x + ( 0.3 * $m);
}
print (" <rect height=\"" . $h . "\" width=\"" . $w .
"\" stroke=\"" . $strokecolor . "\" y=\"" . $y .
"\" x=\"". $x . "\" stroke-width=\"" .
$sw . "\" fill=\"white\"/>\n");
}
} elsif ($kind == 4) { # Crinkled wall
my $sw = $wallstroke;
if (($type == 2) or ($type == 4)) {
# Thick or dotted
$sw=$thickwallstroke;
}
if ($type > 4) {
# Thin (used for furniture)
$sw = $thinstroke;
$type = $type - 4;
}
# Draw a crinkled wall
print " <path fill=\"none\" stroke = \"" . $strokecolor .
"\" stroke-width=\"" . $sw . "\" ";
if ($type == 3 ) { # Dashed
print "stroke-dasharray=\"" . (0.2 * $m) . " " .
(0.2 * $m) . "\" ";
} elsif ($type == 4) { # Dotted
print "stroke-dasharray=\"" . (0.10 * $m) . " " .
(0.15 * $m) . "\" ";
}
print "d=\"M ". $x1 . " " . $y1 . " L" ;
crinkle($x1,$y1,$x2,$y2);
print "\"/>\n";
} elsif ($kind == 5) {
# Cave -- which is polygon with possibly crinkly edges
my $sw=$wallstroke;
my $sc=$strokecolor;
if ($type > 8) {
$sw=$thinstroke;
$sc="white";
$type = $type -4;
}
if ($type > 4) {
$sw=$thinstroke;
$type = $type - 4;
}
if ($type == 1) {
$fill = $strokecolor;
} elsif ($type == 2) {
$fill = "white";
} elsif ($type == 3) {
$fill = "url(#hatch00)";
}
# Start a polygon
$inproc=5;
print " <polygon fill=\"" . $fill .
"\" stroke=\"" . $sc . "\" stroke-width=\"" .
$sw . "\" ";
if ($type == 3) {
print " stroke-dasharray=\"" . (0.08 * $m) . " " .
(0.08 * $m) . "\" ";
}
print "\n points = \"" ;
# First one will always be straight, so for a crinkle cave,
# just have the second point in the same place
print $x1 . "," . $y1 . " " . $x2 . "," . $y2 ;
} elsif ((($kind == 98) or ($kind == 99)) and ($inproc == 5)) {
if ($kind == 98) {
# Continue a crinkled polygon
crinkle($x1,$y1,$x2,$y2);
} else {
# Straight line to x2,y2
print " " . $x2 . "," . $y2;
}
if ($type == 99) {
$inproc = 0;
# Close path
print "\" />\n";
}
} elsif ($kind == 6) { # Filled ellipse
my $cx=$x1;
my $cx=$y1;
my $rx=$x2;
my $ry=$y2;
my $sw=$wallstroke;
if ($type > 4) {
$sw = $thinstroke;
$type = $type - 4;
}
if ($type == 1) {
$fill = $strokecolor;
} elsif ($type == 2) {
$fill = "white";
} elsif ($type == 3) {
$fill = "url(#hatch00)";
}
print " <ellipse fill=\"" . $fill .
"\" stroke=\"" . $strokecolor . "\" stroke-width=\"" .
$sw . "\" cx=\"" .
$x1 . "\" cy=\"" . $y1 . "\" rx=\"". $x2 . "\" ry=\"" . $y2 .
"\" />\n";
} elsif ($kind == 7) { # Spiral Stairs
my $z=(sqrt(2)/4) * $m; # For diagonals
$sw = (($wallstroke + $thinstroke) / 2);
print " <circle fill=\"white\" stroke=\"" .
$strokecolor ."\" stroke-width=\"" . $sw .
"\" cx=\"" . $x1 . "\" cy=\"" . $y1 . "\" r=\"".
.5 * $m . "\" />\n";
print " <line stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $sw . "\" y1=\"" .
($y1 + 0.5 * $m) .
"\" x1=\"" . $x1 . "\" y2=\"" .
($y1 - 0.5 * $m) .
"\" x2=\"" . $x1 . "\" />\n";
print " <line stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $wallstroke . "\" x1=\"" .
($x1 + 0.5 * $m) .
"\" y1=\"" . $y1 . "\" x2=\"" .
($x1 - 0.5 * $m) .
"\" y2=\"" . $y1 . "\" />\n";
print " <line stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $wallstroke . "\" x1=\"" . ($x1 + $z) .
"\" y1=\"" . ($y1 - $z) . "\" x2=\"" . ($x1 - $z) .
"\" y2=\"" . ($y1 + $z) . "\" />\n";
print " <line stroke=\"" . $strokecolor .
"\" stroke-width=\"" . $wallstroke . "\" x1=\"" . ($x1 + $z) .
"\" y1=\"" . ($y1 + $z) . "\" x2=\"" . ($x1 - $z) .
"\" y2=\"" . ($y1 - $z) . "\" />\n";
} elsif ($kind == 8) { # Toilets. Hey, they're a common feature
my $cx=$x1;
my $cy=$y1;
my $sw=$thinstroke;
my $rx=0.15 * $m;
my $ry=0.2 * $m;
my $drainsize = 0.03 * $m;
$fill = "white";
if ($kind == 2) {
$rx=0.2 * $m;
$ry=0.15 * $m;
}
print " <ellipse fill=\"" . $fill .
"\" stroke=\"" . $strokecolor . "\" stroke-width=\"" .
$sw . "\" cx=\"" .
$cx . "\" cy=\"" . $cy . "\" rx=\"". $rx . "\" ry=\"" . $ry .
"\" />\n";
if ($kind == 1) {
$cy = $cy - (0.05 * $m);
} elsif ($kind == 2) {
$cx = $cx - (0.05 * $m);
}
print " <circle fill=\"" . $strokecolor . "\" stroke=\"" .
$strokecolor . "\" stroke-width=\"" . $thinstroke .
"\" cx=\"" . $cx . "\" cy=\"" . $cy . "\" r=\"" .
$drainsize . "\" />\n";
} elsif ($kind == 9) { # Text
my $text=$endx;
my $tstyle=$endy;
my $size=$type * $m;
my $font="HelveticaNeue-CondensedBold";
# Close to fonts used in Classic AD&D V1: S1-3, G1-3, A1-4, etc.
my $ffamily = "sans-serif";
if ($tstyle eq "s") {
$font="Soutane"; # Close to X3-X4 font
$ffamily = "serif";
}
print " <text x=\"" . $x1 . "\" y=\"" . $y1 .
"\" style=\"font-family: " . $font . ","
. $ffamily .";" .
"stroke: " . $strokecolor . "; " .
"font-size: " . $size . "; " .
"stroke-width: " . $thinstroke . "; " .
"fill: " . $strokecolor . ";\">" . $text .
"</text>\n";
} elsif ($kind == 10) { # Seed values for polygon
seedrand($startx,$starty,$endx);
} elsif ($kind==11) { # Draw the grid
# Parameterized so that you can draw a solid background, then
# dig out rooms, then lay down the grid....
drawgrid();
} elsif ($kind==12) { # Radial line
$savex=$x1;
$savey=$y1;
$saver=$x2;
$saves=$y2;
$inproc=12;
my $sw=$wallstroke;
if (($type == 2) or ($type == 4)) {
# Thick or dotted
$sw=$thickwallstroke;
}
if ($type == 5) {
# Thin (used for furniture)
$sw = $thinstroke;
}
print " <line ".
"stroke = \"" . $strokecolor . "\" stroke-width=\"" . $sw .
"\" ";
if ($type == 3 ) { # Dashed
print "stroke-dasharray=\"" . (0.2 * $m) . " " .
(0.2 * $m) . "\"";
} elsif ($type == 4) { # Dotted
print "stroke-dasharray=\"" . (0.10 * $m) . " " .
(0.15 * $m) . "\"";
}
} elsif (($kind==99) and ($type==99) and ($inproc==12)) {
$x1 = $savex + sin($PI * $startx / 180) * $saver;
$x2 = $savex + sin($PI * $startx / 180) * $saves;
$y1 = $savey - cos($PI * $startx / 180) * $saver;
$y2 = $savey - cos($PI * $startx / 180) * $saves;
print " x1=\"" . $x1 . "\" y1=\"" . $y1 .
"\" x2=\"" . $x2 . "\" y2 =\"" . $y2 . "\" />\n";
$savex = $savey = $saver = $saves = $inproc = 0;
} elsif ($kind == 20) {
if ($inproc == 20) {
$inproc = 0;
} else {
$inproc = 20;
}
} elsif ($kind == 21) {
drawhexgrid($type);
} elsif ($kind == 22) {
drawhexfeature($startx,$starty,$type,$endy);
} else {
# Unknown feature
}
}
close(INPUT);
}
sub crinkle {
my ($x1,$y1,$x2,$y2) = @_;
my $linelength = sqrt((($x2 - $x1) ** 2) + (($y2 - $y1) ** 2));
my $maxdeviation = $linelength * $maxdev;
my $deviation = rand($maxdeviation);
if ($deviation <= $minsize) {
print "\n " . $x1 . "," . $y1 . " " . $x2 . "," . $y2;
} else {
my $theta = rand(2 * $PI);
my $deviationx = $deviation * cos($theta);
my $deviationy = $deviation * sin($theta);
my $halfwayx = (($x1 + $x2)/2) + $deviationx;
my $halfwayy = (($y1 + $y2)/2) + $deviationy;
crinkle($x1,$y1,$halfwayx,$halfwayy);
crinkle($halfwayx,$halfwayy,$x2,$y2);
}
}
__END
# Level description file:
# Each line has six fields: kind, startx, starty, endx, endy, type
# is a comment line
# kind: 1 = straight wall
# 2 = Circular arc
# 3 = door (startx,starty are left/top of door)
# 4 = crinkly wall
# 5 = filled block
# 6 = filled ellipse (endx/endy are rx/ry)
# 7 = spiral stairs (startx/starty are center)
# 8 = toilet (hey, there are a lot)
# 9 = text (endx is text to print, endy is "b" for bold, type is size)
# 10 = seed randomness for polygon (x = fraction of line length
# for max deviation, y = minimum feature size, endx = srand()
# seed, 0 to leave it up to the terp)
# 11 = draw grid
# 12 = radial line
# 20 = embedded SVG: just print input file until next 20
# 21 = draw hex grid
# 22 = draw hex feature
# 98 = continuation of previous block with crinkly sides
# 99 = continuation of previous block with straight sides
# or second line of arc/radial line
# Type for lines
# type: 1 = normal
# 2 = thick
# 3 = dashed
# 4 = dotted
# 5 = thin
# Type for arc
# endx is radius; endy is not used
# Type is as for line
# Arc line two: kind=99
# line two: startx is start of arc (degrees), starty is end, endx, endy
# are unused, type is 99
# Arcs always go clockwise, 0 degrees is towards the top of the page
# Type for fill
# type: 1 = solid
# 2 = white
# 3 = hatched
# 4+n = Thin outline
# 99 = end of polygon
# Type for door
# type: 1 = vertical
# 2 = horizontal
# 3 = vertical double
# 4 = horizontal double
# Type for toilet
# type: 1 = vertical
# type: 2 = horizontal
# For text
# endx: Text to use (Can't contain commas)
# endy: "s" means use Soutane font (serif)
# Type for hexgrid
# type: 0 = no hex numbers
# type: 1 = numbered hexes
# Type for hex feature
# type: 0 = solid hex
# endy: 0 = no numbers
# 1 = white numbers
# type: 1 = mountain
# endy: 0 = white
# 1 = filled
# type: 2 = hills
# endy: 0 = plain
# 1 = caves
# type: 3 = radiation
# type: 4 = swamp
# type: 5 = pine forest
# type: 6 = ruins
# type: 7 = settlement
# endy: 0 = hamlet
# endy: 1 = village
# endy: 2 = town
# endy: 3 = city

Das könnte Ihnen auch gefallen