#!perl # # mapmaker v1.1 # reads a file with lines of format: # nnnn A000000-0 NSG # or # Jd aaaa bbbb cccc xxxx # or # RZ nnnn # AZ nnnn # where nnnn is a hex map coordinate (0101 through 0810), A000000-0 is a UPP, # NSG indicates Naval Scout or Gas Giant (omit or replace with . if none) # and d is a single digit followed by a list of hex coordinates. # # It then draws a TAS form 6 with systems plotted and decorated with # X-boat paths drawn. # # Revision 1.0 07-09-2007 bjm Initial release # Revision 1.1 08-09-2007 bjm Adds listings, better option handling, help # Revision 1.2 08-09-2007 bjm System, sector, subsector names use strict; use warnings; use Getopt::Long; Getopt::Long::Configure ("bundling"); # set this to get colour zones and listings our $COLOUR = 0; our $LISTINGS = 0; our $HELP = 0; our $side = 40; my $rv = GetOptions ("colour|color|c" => \$COLOUR, "listing|l" => \$LISTINGS, "help|h" => \$HELP, "side|s=i" => \$side, ); if ($HELP) { print STDERR "Usage: mapmaker [-l] [-c] [-s n] [-h]\n"; print STDERR " -l --listing List system stats\n"; print STDERR " -c --colour Use colour for zones and listing bars\n"; print STDERR " -s integer Set hex side length to integer\n"; print STDERR " -h --help Print this message\n"; exit; } #set these to control size our $factor = 1.732; #calc size of map our $total_width = $side * 12.5; our $total_height = $side * $factor * 10.5; #calc hex info our $sheight = $side * $factor / 2; our $swidth = $side/2; our $width = $side; #jump dashes our @jumpdash = ( "none", "none", "1%,1%", "3%,1%", "3%,1%,1%,3%" ); # names our $sector; our $subsector; printmap(); sub printmap { print header(); print frame(); for (0..9) { print tophalf($_); print bottomhalf($_); } print tophalf(10); print number(); my @drawstuff; my @worldlist; while (<>) { chomp; s/^\s+//; next if /^\s+$/; next if /^#/; /^\d/ && do { push @drawstuff, world($_); push @worldlist, $_; }; /^J/ && unshift @drawstuff, jump($_); /^(R|A)Z/ && unshift @drawstuff, zone($_); /^Sector/i && do { (undef,$sector) = split ' '; }; /^Subsector/i && do { (undef,$subsector) = split ' ';}; } print "\n"; for (@drawstuff) { print; } print "\n"; if ($LISTINGS) { print "\n"; print listworlds(@worldlist); print "\n"; } print footer(); } sub listworlds { my @w = @_; my $margin = $total_width + $side; my $topmargin = $side; my $line=0; my $fsz = $side/4; my $lsz = $side/3; my $list; my $subsecfontcolor; my $secfontcolor; if ($sector) { $secfontcolor = 'black'; } else { $secfontcolor = '#dddddd'; $sector = "Uknown"; } if ($subsector) { $subsecfontcolor = 'black'; } else { $subsecfontcolor = '#dddddd'; $subsector = "Unknown"; } $list .= '' . $sector . ' sector' . "\n"; $topmargin+= $fsz*2; $list .= '' . $subsector . ' subsector' . "\n"; $topmargin+= $fsz*3; $list .= '' . "\n"; for (@w) { if ($line % 2) { $list .= ''; $list .= "$loc"; $list .= '' . "\n"; $list .= ''; $list .= "$upp"; $list .= '' . "\n"; my $nsgsp=0; for (@nsg) { unless ($_ eq '.') { $list .= ''; $list .= "$_"; $list .= '' . "\n"; } $nsgsp++; } if ($rest) { $list .= ''; $list .= $rest; $list .= '' . "\n"; } else { $list .= ''; $list .= "system name"; $list .= '' . "\n"; } $line++; } $list .= '' . "\n"; return $list; } sub center_of { my $coord = shift; my $c = substr($coord,0,2) + 0; my $r = substr($coord,2,2) + 0; my $x = $side + (($c-1) * $side * 1.5); my $y = ($c % 2) ? ($r-1) * $side * $factor + ($side * $factor /2): ($r-1) * $side * $factor + ($side * $factor); return ($x,$y); } sub zone { my $data = shift; my ($z, $loc) = split ' ', $data; my $zone = substr($z,0,1); my %c = ('R' => 'red', 'A' => '#bbbb00'); my %zd = ('R' => "none", 'A' => "3%,1%"); my ($x, $y) = center_of($loc); my $f; if ($COLOUR) { $f = $c{$zone}; } else { $f = 'white'; } return '' . "\n"; } sub jump { my $data = shift; my ($j, @jumps) = split ' ', $data; my $jt = substr($j,1,1) + 0; my $s = $side/20; my $out = '' . "\n"; } else { $output .= ''; for (0..6) { $output .= '' . "\n"; } $output .= '' . "\n"; } # sp $output .= '' . $sp . '' . "\n"; # decorations if ($dec =~ /N/i) { my $nx = $x - ($side/3); my $ny = $y - ($side/3); $output .= star($nx,$ny); }; if ($dec =~ /S/i) { my $nx = $x + ($side/3); my $ny = $y - ($side/3); $output .= triangle($nx, $ny); }; if ($dec =~ /G/i) { my $nx = $x - ($side/3); my $ny = $y + ($side/3); $output .= ' ' . "\n"; }; return $output; } sub triangle { my ($x,$y) = @_; my $triangle = '[0]; my $py = $y + $_->[1]; $star .= "$px,$py "; } $star .= '" />' . "\n"; return $star; } sub star_coords { my $r1 = shift; my $r2 = shift; my $points = shift; my $pi = 3.14159; my $pangle = 2*$pi/$points; my $sangle = $pi/$points; my $oangle = $pi/-2; my @coords; for (0..($points-1)) { push @coords, [$r1 * cos($pangle * $_ + $oangle), $r1 * sin($pangle * $_ + $oangle)]; if ($r2) { push @coords, [$r2 * cos(($pangle * $_) + $sangle + $oangle), $r2 * sin(($pangle * $_) + $sangle + $oangle)]}; } return @coords; } sub number { my $t; my $f = $side/5; for my $c (1..8) { for my $r (1..10) { my $n = sprintf("%02d%02d",$c,$r); my $x = $side + (($c-1) * $side * 1.5); my $y = ($c % 2) ? ($r-1) * $side * $factor + (0.2 * $side) : ($r-1) * $side * $factor + $sheight + (0.2 * $side); $t .= '' . $n . '' . "\n"; } } return $t; } sub frame { my $h = $total_height; my $w = $total_width; return '' . "\n"; } sub half { my ($row, $top) = @_; my $ly = ($row * 2 * $sheight ) + $sheight; my $line = ''; return $line; } sub tophalf { return half(shift,1); } sub bottomhalf { return half(shift,0); } sub header { my $h = $total_height+5; my $w; if ($LISTINGS) { $w = $total_width*2; } else { $w = $total_width+5; } return ' Subsector Map Grid' . "\n"; } sub footer { return '' . "\n"; } #### #!perl # # subsector v1.0 # generates a random subsector in mapmaker format. Default occurence # is 4+ but can be set on the command line. Can be piped to mapmaker # or to a file for modification, storage, and addition of X-boat paths. # # Revision 1.1 08-09-2007 bjm Fixed law level trouble use strict; use warnings; our $occ = shift || 4; # stars occur on a 4+ on 1d6 our @spt = qw(A A A B B C C D E E X); our @nbt = qw(. . . . . . N N N N N); our @sbt = qw(. . . . . S S S S S S); our @ggt = qw(G G G G G G G G . . .); our %sptl = ('A' => 6, 'B' => 4, 'C' => 2, 'D' => 0, 'E' => 0, 'X' => -4); our @sztl = (2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0); our @attl = (1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1); our @hytl = (0,0,0,0,0,0,0,0,0,1,2); our @potl = (0,1,1,1,1,1,0,0,0,2,4); our @gvtl = (1,0,0,0,0,1,0,0,0,0,0,0,0,-2,0,0,0,0,0,0); for my $c (1..8) { for my $r (1..10) { if (d6()+1 >= $occ) { my $loc = sprintf("%02d%02d", $c, $r); my $sp = $spt[d6()+d6()]; # starport lookup my $sz = d6() + d6(); # size my $at = d6() + d6() - 5 + $sz; # atmosphere if ($at < 0) { $at = 0; } my $hy = d6() + d6() - 5 + $at; # hydrographics if ($sz == 0) { $hy = 0; } elsif ($at < 2 || $at > 9) { $hy -= 4; } if ($hy < 0) { $hy = 0; } if ($hy > 10) { $hy = 10; } my $po = d6() + d6(); # population my $gv = d6() + d6() - 5 + $po; # government if ($gv < 0) { $gv = 0; } my $ll = d6() + d6() - 5 + $gv; # law level if ($ll < 0) { $ll = 0; } my $tl = d6() + 1 # tech level + $sptl{$sp} + $sztl[$sz] + $attl[$at] + $hytl[$hy] + $potl[$po] + $gvtl[$gv]; my $upp = $sp # generate UPP . phex($sz) . phex($at) . phex($hy) . phex($po) . phex($gv) . phex ($ll) . '-' . phex($tl); my $nsg; # naval base? if ($sp eq 'A' || $sp eq 'B') { $nsg = $nbt[d6() + d6()]; } else { $nsg = '.'; } my $sbv = d6() + d6(); # scout base? if ($sp eq 'E' || $sp eq 'X') { $sbv = 0; } elsif ($sp eq 'A') { $sbv += -3; } elsif ($sp eq 'B') { $sbv += -2; } elsif ($sp eq 'C') { $sbv += -1; } if ($sbv < 0) { $sbv = 0; } $nsg .= $sbt[$sbv]; $nsg .= $ggt[d6() + d6()]; print "$loc $upp $nsg\n"; } } } sub phex { my $n = shift; return 0 if ($n < 0); return $n if ($n < 10); return chr($n + ord('A') - 10); } sub d6 { return int(rand(6)); }