Data::StarCraft::Map package taken out of scmap
authorShiar <shiar@shiar.org>
Tue, 27 Nov 2007 19:18:02 +0000 (20:18 +0100)
committerShiar <shiar@shiar.org>
Tue, 27 Nov 2007 19:18:02 +0000 (20:18 +0100)
Data-StarCraft/lib/Data/StarCraft/Map.pm [new file with mode: 0644]
scmap

diff --git a/Data-StarCraft/lib/Data/StarCraft/Map.pm b/Data-StarCraft/lib/Data/StarCraft/Map.pm
new file mode 100644 (file)
index 0000000..4b9953c
--- /dev/null
@@ -0,0 +1,672 @@
+package Data::StarCraft::Map;
+
+use strict;
+use warnings;
+use Data::Dumper;
+
+our $VERSION = "0.10";
+our $DEBUG = 0;
+
+sub new {
+       my ($class) = @_;
+       bless {}, $class;
+}
+
+sub _read {
+       my $self = shift;
+       my ($fh, $size, $seek) = @_;
+       seek *$fh, $seek, 0 if $seek;
+       read(*$fh, my $in, $size) eq $size or return undef;
+       return $in;
+}
+
+sub open {
+       my $self = shift;
+       my ($file) = @_;
+
+       while (not eof $file) {
+               local $_ = $self->_read($file, 8)
+                       and my ($type, $size) = unpack "a4V", $_
+                       or die "Couldn't chunk header\n";
+               $type =~ s/ +$//;
+#printf STDERR "%s: %s\n", $type, $size;
+               defined $self->{$type} and warn "duplicate map chunk $type\n";
+               $self->{$type} = $self->_read($file, $size);
+       }
+       return $self;
+}
+
+sub version {
+       my $self = shift;
+       return 'v' . ord $self->{VER};
+}
+
+sub info {
+       my $self = shift;
+       my ($x, $y) = unpack "vv", $self->{DIM};
+       return {
+               x => $x,
+               y => $y,
+       };
+}
+
+sub width {
+       return $_[0]->info->{x};
+}
+
+sub tiles {
+       my $self = shift;
+       my @map = unpack 'v*', $self->{MTXM};
+       @map == $#map + 1 or warn(sprintf
+               "couldn't parse map: only %d tiles\n", scalar @map
+       ), return;
+       return \@map;
+}
+
+my @maptile = (
+       '!' => [  0.. 31],
+       'd' => [ 32.. 62,  63],      # dirt (verified)
+       'h' => [ 64.. 94],           # high dirt
+       "~" => [ 96..117, 118..127], # water
+       'j' => [128..159],           # jungle/crushed rock
+       'o' => [160..186, 187..191], # rocky/shale (verified)
+       'R' => [192..223],           # raised jungle
+       'l' => [224..252, 253..255], # lava/ruins (verified)/flagstones?
+       'b' => [256..287],           # basilica?
+       'x' => [288..319],           # high jungle
+#      'x' => [3745..3792],         # high jungle
+       'q' => [320..351],           # high ruins
+       ' ' => [352..383],
+       'a' => [384..415],           # high basilica
+       'm' => [416..447],           # mud
+       ' ' => [448..479],
+       ' ' => [480..511],
+
+       ' ' => [512..543],
+       ' ' => [544..575],
+       '/' => [576..607], # high dirt -> dirt (top left)
+       '/' => [608..639], # dirt -> high dirt
+       '\\' => [640..671], # high dirt -> dirt (top right)
+       '\\' => [672..703], # dirt -> high dirt (bottom left)
+       '\\' => [704..735], # high dirt -> dirt (bottom left)
+       '\\' => [736..767], # dirt -> high dirt (top right)
+       '/' => [768..863],
+       '=' => [864..1055], # some edge (tmp)
+       '=' => [1056..1183],
+       '=' => [1184..1727],
+       'D' => [1728..1780], # edge water
+       '/' => [1760..1791], # dirt -> water (top left)
+       '\\' => [1792..1823], # dirt -> water (top right)
+
+       'd' => [609..611],
+       'W' => [2048..2303],
+       '/' => [2304..2559],
+       'W' => [2560..2815],
+       'j' => [2816..3071],
+       'd' => [3072..3327],
+       'j' => [3328..3583],
+       'x' => [3648..3839],
+       'h' => [3840..4095],
+#      'x' => [4096..4351],
+       'h' => [4096..4351],
+#      'x' => [4352..4607],
+#      ' ' => [4608..4863],
+       'l' => [4864..5311],
+       'q' => [5312..5503],
+       'x' => [5504..5631],
+       'q' => [5632..5759],
+       'j' => [5760..5823],
+#      ' ' => [5824..5887],
+       '=' => [5888..6143], # raised jungle -> jungle
+#      ' ' => [6144..6655],
+       '/' => [6656..7167],
+       '/' => [7168..7359], # basilica -> crushed rock
+       '/' => [7360..7551],
+       'i' => [7552..7807], # high temple
+#      ' ' => [7808..8959],
+#      '=' => [8960..9087],
+#      'd' => [9088..9215],
+#      ' ' => [9216..9727],
+#      'm' => [9728..9983],
+#      #    >= 9984 unencountered
+#      ' ' => [19968..20480], # something here on twilight
+#      ' ' => [20544..20736], # center thing on twilight
+#      '~' => [20896..21023], # something in the water on twilight
+#      'x' => [23104..23231], # something on twilight (on X or H)
+#
+#      'm' => [9216..9776], # mud <-> dirt
+#      'r' => [5792..5875, 5888..5904], # raised jungle edge
+#
+#      'd' => [3042..3250], # dirt<->grass
+#      'P' => [4608..4977], # dirt<->shale (verified) [also seems to be rocks on mud]
+#      #'=' => [768..1731], # dirt<->lava ridge (verified)
+
+       'h' => [16389],
+       '1' => [16405, 16388],
+       '2' => [16421, 16404, 16387],
+       '3' => [16437, 16420, 16403, 16386],
+       '4' => [16453, 16436, 16419, 16402, 16385],
+       '5' => [              16435, 16418, 16401, 16384],
+       '6' => [                     16434, 16417, 16400],
+       '7' => [                            16433, 16416],
+       'd' => [16501,                             16432],
+       '7' => [16485, 16500],  # these ↕ aren't ramps in temple!!
+       '6' => [16469, 16484, 16499],
+       '5' => [16453, 16468, 16483, 16498],
+       '4' => [       16452, 16467, 16482, 16497],
+       '3' => [              16451, 16466, 16481, 16496],
+       '2' => [                     16450, 16465, 16480],
+       '1' => [                            16449, 16464],
+       'h' => [17248,                             16448],
+       '1' => [17264, 17249],
+       '1' => [17280, 17265, 17250],
+       '2' => [17296, 17281, 17266, 17251],
+       '3' => [17312, 17297, 17282, 17267, 17252],
+       '4' => [17328, 17313, 17298, 17283, 17268, 17253],
+       '5' => [       17329, 17314, 17299, 17284, 17269],
+       '6' => [              17330, 17315, 17300, 17285],
+       '7' => [                     17331, 17316, 17301],
+       '7' => [                            17332, 17317],
+       'd' => [17232,                             17333],
+       '7' => [17216, 17233],
+       '7' => [17200, 17217, 17234],
+       '6' => [17184, 17201, 17218, 17235],
+       '5' => [17168, 17185, 17202, 17219, 17236],
+       '4' => [17152, 17169, 17186, 17203, 17220, 17237],
+       '3' => [       17153, 17170, 17187, 17204, 17221],
+       '2' => [              17154, 17171, 17188, 17205],
+       '1' => [                     17155, 17172, 17189],
+       '1' => [                            17156, 17173],
+       'h' => [                                   17157],
+);
+
+my %eratile = (
+       4 => [
+               # Longinus (by KuKulZa, modified MBCgame/iCCup)
+               # SPRP: 6,0,1,0
+               # TYPE: 82,65,87,66
+               # VER: 205,0
+               # SIDE: 5,5,5,1,2,0,1,2,7,7,7,4
+               'd' => [
+                       19760..19761, 19792, 19793, 19680, 19681, 19712, 19713, 19664, 19665, 19728, 19729, # D→J
+                       19808,19809, 19776,19777, 19872,19873, 19920,19921,
+                       19744,19745, 19696,19697, 19632,19633, 19696,19697, 19952,19953,
+                       19568,19569, # below ridge
+                       3618,3634, 3586,3602, # D←J
+                       3601, # D→J(3585)
+               ],
+               'j' => [
+                       21968, 21969, 21984, 21985,
+                       21824,21825,21840,21841, 21856,21857,21872,21873, 21792,21793,
+                       21808,21809, 21888,21889,21904,21905,
+                       3616,3632,3584,3600,3616,3632, # J→D
+                       3585, # J→D(3601)
+               ],
+               'l' => [
+                       22608..22611, 22624..22627, 22640..22643,
+               ],
+               'o' => [
+                       24850, # besides ladder
+                       20832,20833,20848,20849, 20768,20769,20784,20785,
+                       20864,20865,20880,20881,
+                       20704,20705,20720,20721, # large rock
+                       4432,4433,4434,4448,4449,4464,4465,
+                       4545,4561,4577,4593, 4544,4560,4576,4592,
+               ],
+               'h' => [
+                       18000,18001, # H→X
+                       17952,17953, 17936,17937, 17920,17921, 17856,17857, 17888,17889, # H→X unsure
+                       17984,17985, 18160,18161, 18128,18129, 18048,18049,
+                       19648,19649,19616,19617, 18016,18017,
+                       17696,17697,17712,17713, # tree
+                       17872,17873,17904,17905, 18144,18145,
+                       18448,18449,18464,18465,18480,18481,
+               ],
+               'm' => [ # mud hole
+                       9219,9235,9539,9555,
+                       9218,9234,9795,9235,9811,9571,9587,
+                       9472,9488,9250,9266,9635,9651,9280,9296,
+                       9504,9520,9665,9681,9344,9360,9760,9776,9539,9555,
+                       9475,9491,9889,9905,9376,9392,9440,9456,9571,9587,
+                       9507,9523,9377,9393,
+
+                       9537,9553,
+                       9569,9585,9474,9490,9283,9299,9216,9232,9536,9552,
+                       9536,9552,9923,9939,9283,9299,9506,9522,9827,9843,9728,9744,9568,9584,
+                       9283,9299,9217,9233,9731,9747,9568,9584,9699,9715,9315,9331,9284,9300,9217,9233,9955,9971,
+                       9763,9779,9793,9809,9379,9395,9664,9680,9316,9332,9249,9265,9536,9552,
+                       9443,9459,9921,9937,9284,9300,9216,9232,9284,9300,9216,9232,9696,9712,9345,9361,9409,9425,9604,9620,9568,9584,
+                       9216,9232,9764,9780,9248,9264,9316,9332,9248,9264,9346,9362,9441,9457,9860,9876,9537,9553,
+                       9728,9744,9444,9460,9667,9683,9348,9364,9411,9427,9602,9618,9378,9394,9444,9460,9569,9585,
+                       9891,9907,9380,9396,9443,9459,9858,9874,9540,9556,
+                       9379,9395,9442,9458,9572,9588,
+               ],
+               '/' => [
+                       # Longinus (by KuKulZa, modified MBCgame/iCCup)
+                       9125, 9141, 9126, 9142, # D→~
+                       9120, 9136, # H→D
+                       9059,9075, 9189,9205, # D→~
+                       19824,19825, # D→~
+                       19200,19201,19216,19217, # object on D
+               ],
+               '/' => [
+                       17632,17633,17648,17649, # H rotating thing
+                       18208,18209, # H skull thing
+                       18224,18225,18240,18241, # H statuey thing
+               ],
+               'q' => [
+                       23872,23873,23874,23875,23888,23889,23890,23891,23904,23905,23906,23907, # Q crater
+                       23680,23681,23696,23697,23712,23713,
+               ],
+               'x' => [
+                       24336,24337,24352,24353, 24272,24273,24288,24289,
+                       24272,24273,24288,24289, 24368,24369,24384,24385,
+                       4353,4369, 4385,4401,4353,4369, 4386,4402, 4385,4401,
+                       4386,4402,4354,4370,4386,4402,
+               ],
+               '/' => [
+                       19856,19857,20144,20145, # D skeleton
+               ],
+               '/' => [21184], 'W' => [21185,21200,21201,21216,21217], # standing rock
+               '/' => [21232], 'W' => [21233,21248,21249,21264,21265], # standing rock
+               '7' => [25011, 25010], # M»H
+               '7' => [24699, 25143], 6 => [24716], # M»H
+               'W' => # island o' rocks
+                              [21120..21125, 21136..21141, 21152..21157, 21168..21173],
+                       '/' => [21121,21122,21136..21139,21152..21154],
+                       '~' => [21120,21124,21125,21141,21157,21171..21173],
+               '/' => [
+                       # D→~ coast
+                       8997,9013,8963,8979, 8996,9012,8963,8979,8993,9009, 8997,9013,
+                       8998,9014, 8993,9009, 9187,9203, 9121,9137, 9131,9147, 8992,9008,
+                       9190,9206, 9062,9078, 8996,9012, 9090,9106,9194,9210,
+                       9061,9077,9029,9045,9184,9200,8998,9014, 9024,9040,8997,9013,
+               ],
+
+               # Lost Temple (default?)
+               # SPRP: 4,0,5,0
+               # VER: 59,0
+               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
+               '/' => [
+                       9089,9105, # H←D
+                       9196,9212, # H←D→~
+                       8966,8982, 8962,8978, # H→~
+                       9088,9104, # D→D/~
+                       16832..16835,16848..16851,16864..16867,16880..16883, # H→D ridge (ramp elsewhere?)
+                       16384..16389, 16400..16405, 16416..16421, 16432..16437, # idem
+                       8961,8977,9155,9171, # H←D→~
+                       20160,20161,19984,19985,19986,19987,20000,20001,20002,20003, # D→H
+                       9124,9140, 9122,9138, 9002,9018, 8960,8976, 9168,9152, 8995,9011, # H→D→~
+                       9057,9073, # H→D→~ temple.6
+                       8968,8984, # D↔H
+               ],
+               'j' => [
+                       21952,21953,
+               ],
+               'x' => [
+                       4384,4400, 4352,4368, # X→H
+               ],
+               'h' => [
+                       18096,18097, 17968,17969, 18032,18033,18176,18177,
+               ],
+               'd' => [
+                       9347,9363,9953,9969,9473,9489,9251,9267,9633,9649,9505,9521,9410,9426,
+                       9347,9363, 19840,19841, 19888,19889, 20208,20209,20224,20225,
+                       20240,20241,20256,20257, 20272,20273,20288,20289, 19601,19600,
+                       20304,20305,20320,20321, # tree
+               ],
+               'o' => [
+                       4673,4689,4737,4753,4705,4721,4769,4785, # rocks on D
+                       4674,4690,4706,4722,4674,4690,4480,4496,4706,4722,4832,4848,4640,4656,
+                       4736,4752,4768,4784,
+                       4482,4498, 4834,4850, 4642,4658,
+               ], 'd' => [4498,4642],
+               'm' => [
+                       # M→D mud holes
+                       9281,9297,9313,9329, 9281,9297,9313,9329, 9538,9554,9570,9586,
+                       9282,9298,9282,9298,9220,9236,9476,9492,9314,9330,9729,9745,9412,9428,9476,9492,9314,9330,9538,9554,9476,9492,9252,9268,
+                       9508,9524,9668,9684,9600,9616,9508,9524,9666,9682,9601,9617,9570,9586,9508,9524,9408,9424,9700,9716,9632,9648,9698,9714,9282,9298,9314,9330,
+                       9312,9328, 9412,9428, 9636,9652, 9634,9650,
+                       9730,9746, 9761,9777,9762,9778, 9794,9810,
+                       9732,9748, # temple.5
+                       9603,9619, # temple.6
+               ],
+               'r' => [
+                       5859,5875, 5858,5874, # top edge
+               ],
+               'O' => # temple center ornament
+                       [
+                               22320,22321,22336,22337,22352,22353,
+                               22368,22369,22384,22385,22400,22401,
+                               22464..22467,22480..22483,22496..22499,
+                               22800,22801,22802,22803,22816,22817,22818,22819,22832,22833,22834,22835,
+                               22752,22753,22754,22755,22768,22769,22770,22771,22784,22785,22786,22787,
+                       ],
+                       'l' => [ # cut out shapes
+                               22464,22467,22496,22499, 22321,22353, 22368,22400,
+                               22800,22802,22803,22832,22835, 22819,
+                               22752,22753,22755,22787,22784, 22768,
+                       ],
+               'D' => # underwater cave
+                       [
+                               21440,21441,21442,21443, 21456,21457,21458,21459,
+                               21472,21473,21474,21475, 21488,21489,21490,21491,
+                       ],
+                       'W' => [21456, 21472,21473,21474,21475],
+                       'o' => [21442,21443],
+                       '~' => [21488,21489, 21490,21491],
+               'i' => [
+                       23632,23633,23648,23649,23664,23665, 23584,23585,23600,23601,23616,23617, # statue things on Q
+               ],
+               'D' => [1824..1839], 'W' => [1840..1855], # D→~ bright transition
+               'D' => [1856..1871], 'd' => [1872..1887], # D→~ bleft ridge
+               'W' => [1888..1903], 'D' => [1904..1919], # D→~ bleft transition
+               '~' => [1920..1935], 'W' => [1936..1951], # w→~ bleft transition
+               'd' => [1952..1967], 'D' => [1968..1983],
+               'D' => [1984..1999], 'W' => [2000..2015],
+               'W' => [2016..2031], '~' => [2032..2047],
+               'D' => [8965,8981, 8964,8980, 9174,9158, 9010,8994], # H→D→~
+               'd' => [19936,19937], # D→~
+               '/' => [19905], 'd' => [19904], # H→D
+               'r' => [
+                       5825,5841, 5857,5873, # J→R→map edge
+                       5826,5842, # J↔R
+               ],
+               'q' => [
+                       # gap
+                       23456,23457,23458,23459, 23472,23473,23474,23475,
+                       23488,23489,23490,23491, 23504,23505,23506,23507,
+                       # towery thing
+                       23824,23825,23826,23827, 23840,23841,23842,23843, 23856,23857,23858,23859,
+               ],
+
+               # Plains to Hill (v2.00 by Sir.Lupin)
+               # VER: 59,0
+               # SPRP: 1,0,2,0
+               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
+               # FORC: 0,0,0,0,1,1,1,1,31,0,30,0,29,0,28,0,1,11,0,0
+               '/' => [
+                       # H→D bottom left side (may be a ramp elsewhere)
+                       16768,16769,16770,16771, 16784,16785,16786,16787,
+                       16800,16801,16802,16803, 16816,16817,16818,16819,
+                       # idem bottom right side
+                       16960,16961,16962,16963, 16976,16977,16978,16979,
+                       16992,16993,16994,16995, 17008,17009,17010,17011,
+                       # idem
+                       17088,17089,17090,17091, 17104,17105,17106,17107,
+                       17120,17121,17122,17123, 17136,17137,17138,17139,
+               ],
+
+               # Python (v1.3 by Terrance, modified by Forgotten_/KeSPA)
+               # ERA: 100,0
+               # TYPE: 82,65,87,66
+               # VER: 205,0
+               # SPRP: 1,0,7,0
+               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
+               # FORC: 0,0,0,0,1,1,1,1,2,0,4,0,5,0,6,0,1,14,15,15
+               'x' => [
+                       24464,24465, 24448,24449
+               ],
+               'h' => [
+                       18064,18065,
+               ],
+               '/' => [
+                       9186,9202,
+                       18112,18113, # H→D
+                       9154,9170,9027,9043,9157,9173, # H↔D
+               ],
+               'O' =>
+                       [19504,19505,19520,19521, 18720,18721,18736,18737], # rock things
+                       'h' => [18737],
+               'O' => # hole
+                       [17488..17491,17504..17507,17520..17523,17536..17539],
+                       'h' => [17490,17491,17507,17523,17536..17539],
+               'o' => [
+                       4610, 4610,4626, 4481,4497,4513,4529, 4514,4530,
+                       4417,4608,4624,4418, 4512,4528, 4450,4466,
+                       4609,4625,4546,4562, 4833,4849, 4801,4817, 4800,4816,
+               ],
+               'd' => [
+                       4672,4688,4704,4720, # D↔O
+                       19584,19585,
+                       4416, # D→O
+                       4641,4657,4578,4594, 4802,4818, # O→D
+               ],
+               'm' => [
+                       9824,9840,9952,9968,9920,9936,9888,9904, 9796,9812,9924,9940,
+                       9697,9713, 9890,9906, 9922,9938, 9792,9808,9856,9872,9826,9842,
+               ],
+               'o' => [4738,4770], 'd' => [4754,4786],
+               '/' => [18256,18257,18272,18273], 'h' => [18288,18289], # obelisk
+               '/' => # sunken temple
+                       [21024..21029, 21040..21045, 21056..21061, 21072..21077, 21088..21093,21104..21109],
+                       '~' => [21024,21104,21109,21027,21059,21076,21072,21093,],
+                       'W' => [21029, 21060,21045,21073,21090,21106,21092,21107,21075,21108,21058, 21056,21088,21105,21077],
+               'O' => # ruins similar to 22464
+                       [22512..22515, 22528..22531, 22544..22547],
+                       'l' => [22512,22515, 22544,22547],
+               'Q' => [17664,17665,17680,17681], # rock thing
+               'Q' => [17728,17729,17744,17745], # tree
+               '/' => [17808,17824,17840], 'h' => [17809,17825,17841],
+               '6' => [25025], # D»H ramp (between D and 17328 = level 4)
+
+#},    2 => {
+               # Twilight Star (default)
+               # (all guessed from low res thumb)
+               'h' => [17584,17585], # H→D
+               'r' => [5827,5843, 5824,5840,5856,5872],
+               'W' => [
+                       # water objects
+                       20912,20913,20928,20929, 20896,20897, 20944,
+                       19440,19441,19456,19457, 20945,20960,20961,
+                       20816,20817,
+               ],
+               'h' => [17760,17761,17776,17777, 17600,17601],
+               'D' => [9093,9109],
+               'o' => [19472..19475, 19488..19491],
+               'o' => [
+                       21728,21729, 21744,21745, 21760,21761,
+                       21776,21777, 19536,19537, 19538,19539, 19552..19555,
+               ],
+               'j' => [3587,3603],
+               'O' => [19232..19235, 19248..19251], 'j' => [19218,19219],
+               'O' => [19938,19939,19954,19955],
+               'h' => [17792,17793],
+               'x' => [4356,4372],
+               'O' => [ # exotic/shiny things and other objects
+                       18656,18657,18672,18673, 18496,18497,18512,18513,
+                       18560..18563, 18576..18579, 18592..18595,
+                       18528,18529,18544,18545, 18864,18865,
+                       18608..18611,18624..18627,18640..18643,
+                       18912..18915,18928..18931,18944..18947,
+                       18816..18819,18832..18835,18848..18851,
+                       18960..18963,18976..18979,18992..18995,
+                       19008..19011,19024..19027,
+                       19040..19043,19056..19059,
+               ],
+               'A' => [ # X→A
+                       7811,7827,7873,7889,7809,7825,7875,7891,
+                       8707,8723,8737,8753,7874,7890,7808,7824,7872,7888,7904,
+                       8003,8019,8160,8176,7810,7826,
+               ],
+               'a' => [ # A←X
+                       7843,7859,7905,7921,7841,7857,7907,7923,
+                       8705,8721,7971,7987,8065,8081,8738,8754,7840,7856,
+                       7920,7906,7922,7938,7954,7969,7985,8066,8082,8035,8051,
+                       7970,7986,8032,8048,
+                       8034,8050,7936,7952,8033,8049,7937,7953,
+               ],
+               'R' => [6177,6193],
+               '/' => [18080,18081],
+               'a' => [8032..8047], 'a' => [8048..8063], # #3 bottom left
+               'A' => [7841..7843], 'a' => [7857..7859], # #2 top left
+               'A' => [8000..8003], 'x' => [8016..8019], # #1 bottom right
+               'A' => [8064..8067], 'a' => [8080..8083], # #2 bottom left
+               'A' => [8224..8227], 'x' => [8240..8243], # #1 top right
+               'A' => [8288..8291], 'x' => [8304..8307], # #1 bottom right
+               'a' => [8355], 'A' => [8371], # #2 top right
+               'a' => [8322], 'A' => [8338], # #2 top right
+               'A' => [8512], 'x' => [8528], # #1 top right
+               'x' => [7811], 'A' => [7827],
+               'x' => [8096..8099], 'A' => [8112..8115],
+               'x' => [8163], 'a' => [8179],
+               'x' => [8192..8195], 'A' => [8208..8211],
+               'x' => [8128..8131], 'A' => [8144..8147],
+               'A' => [8258,8274],
+               'a' => [7939,7955], # #3 bottom right
+               'a' => [7968..7971], 'A' => [7984..7987],
+               'A' => [8256,8272],
+               'A' => [8257,8273, 8259,8275, 8162,8178],
+
+               '!' => [],
+
+               # tau cross (v1.1 by Rose.Of.Dream/BW4eVeR)
+               # ERA: 6
+               # FORC: 0,0,0,1,1,1,1,1,7,0,6,0,5,0,4,0,1,15,15,15
+               # SIDE: 5,5,5,1,0,2,1,0,7,7,7,4
+               # SPRP: 1,0,2,0
+               # TYPE: 82,65,87,66
+               # VER: 205
+               '?' => [
+                       6176,6192, 20976,20977, 20592,20593, 21392,21393, 20800,20801,
+                       20608,20609, 20624,20625, 20640,20641, 20992,20993, 21008,21009,
+                       19922,19923,22070,22071, 19968..19971, 22230,
+                       22133,22137,22272,22157,22288,22313,
+                       20592,20593,21392,21393,20800,20801,20608,20609,20624,20625,20640,20641,20992,20993,21008,21009,19922,19923,
+                       22070,22071,19968,19969,19970,19971,22230,22272,22157,22288,22313,6147,6163,6178,6194,3589,3605,22147,22162,22163,22164,
+                       22180,22315,18400,18401,18336,18337,18192,18193,17730,17731,17826,17827,17746,17747,17842,17843,
+                       17762,17763,17794,17795,17778,17779,17810,17811,17616,17617,
+                       20688,20689,6145,6161,20736,20737,21408,21409,21410,21411,
+                       20752,20753,21424,21425,21426,21427,21376,21377,20656,20657,
+                       21312,21313,21314,21315,20672,20673,21328,21329,21330,21331,
+                       6146,6162,21344,21345,21346,21347,21360,21361,21362,21363,6144,
+                       6160,
+               ],
+               '2' => # bridges
+                       [
+                               22231..22235, 22246..22253, 22260..22269,
+                               22273..22285, 22289..22301, 22306..22312, 22324..22328,
+                       ],
+                       '4' => [22246..22253, 22273..22285, 22306..22312],
+                       '2' => [
+                               22084..22086, 22096..22103, 22112..22121, 22128..22139,
+                               22144..22156, 22165..22171, 22181..22199,
+                       ],
+                       '4' => [22084..22086, 22112..22121, 22144..22156, 22181..22199],
+               'r' => [22342,22343],
+
+               # Nostalgia (WGT13, v1.3 by Rose.of.Dream)
+               # ERA: 0,0
+               # FORC: 0,0,0,0,1,1,1,1,12,0,11,0,10,0,9,0,1,14,0,0
+               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
+               # SPRP: 1,0,4,0
+               # TYPE: 82,65,87,66
+               # VER: 205
+               '!' => [],
+       ], # jungle
+);
+
+our %tilechar;
+while (my ($char, $matches) = splice @maptile, 0, 2) {
+       $tilechar{$_} = $char for @$matches;
+}
+while (my ($char, $matches) = splice @{$eratile{4}}, 0, 2) {
+       $tilechar{$_} = $char for @$matches;
+}
+
+my @mapunit = ( # character => width, height, ids
+       '$' => [2,1, 176..178], # minerals
+       '*' => [2,1, 188], # gas
+       '@' => [2,2, 214], # start pos
+);
+
+our %unitchar;
+while (my ($char, $matches) = splice @mapunit, 0, 2) {
+       my @charinfo = ($char, splice @$matches, 0, 2);
+       $unitchar{$_} = \@charinfo for @$matches;
+}
+
+sub tiles_parsed {
+       my $self = shift;
+       my $map = $self->tiles or return;
+       if ($self->{DEBUG}) {
+               use Tie::IxHash;
+               tie my %unknown, 'Tie::IxHash';
+               defined $tilechar{$map->[$_]} or warn(sprintf
+                       "unknown tile %d at (%d,%d)\n",
+                       $map->[$_], $_ % $self->width, $_ / $self->width
+               ), $unknown{$map->[$_]} = $_ for 0 .. $#$map;
+               warn sprintf "unknown: %s\n", join ",", keys %unknown if keys %unknown;
+       }
+       $_ = defined $tilechar{$_} ? $tilechar{$_} : '?' for @$map;
+       for ($self->units) {
+               my ($chr, $width, $height) = defined $unitchar{$_->{id}} ?
+                       @{ $unitchar{$_->{id}} } : ('#', 1, 1);
+               for my $x ($_->{x} .. $_->{x} + $width - 1) {
+                       for my $y ($_->{y} .. $_->{y} + $height - 1) {
+                               $map->[$x + $y * $self->width] = $chr;
+                       }
+               }
+       }
+       return $map;
+}
+
+sub units {
+       my $self = shift;
+       my @units;
+       for (my $i = 0; $i < length $self->{UNIT}; $i += 36) {
+               # d1, d2, x*32, y*32, unitid, bytes1, playerid, bytes2, mineral, bytes3
+               my @pack = unpack "v5x6Cx3vx14", substr $self->{UNIT}, $i, 36;
+               push @units, {
+                       id => $pack[4],
+                       player => $pack[5],
+                       amount => $pack[6],
+                       x => $pack[2] >> 5,
+                       y => $pack[3] >> 5,
+#                      d1 => $pack[0],
+#                      d2 => $pack[1],
+               };
+       }
+       return @units;
+}
+
+sub units_parsed {
+       my $self = shift;
+       my @units;
+       for ($self->units) {
+               my ($chr, $width, $height) = defined $unitchar{$_->{id}} ?
+                       @{ $unitchar{delete $_->{id}} } : ('#', 1, 1);
+               $_->{chr} = $chr;
+               $_->{width} = $width;
+               push @units, $_;
+       }
+       return @units;
+}
+
+sub colors {
+       my $self = shift;
+       my @colormap = (
+               qw(
+                       FF0000 0000FF 209070 88409C E87824 5C2C14 FFFFFF DCDC3C
+                       0F930F FCFC8F EFCEBD 547CDC
+               ),
+               12 => "pale green", "gray", "pale yellow", "cyan",
+               17 => "black", "neon blue",
+               21 => "lavender", "black",
+               30 => "sky blue",
+               33 => "purple",
+       );
+       my @players;
+       for (unpack "C*", $self->{COLR}) {
+               push @players, $colormap[$_] || "? (#$_)";
+       }
+       return \@players;
+}
+
+sub era {
+       my $self = shift;
+       return unpack "v", $self->{ERA};
+}
+
+1;
+
diff --git a/scmap b/scmap
index e052c7645c6759048e13c8e550e244494a2750de..cd564d3280463b40483164248593cc37754729ce 100755 (executable)
--- a/scmap
+++ b/scmap
@@ -14,674 +14,9 @@ GetOptions(
        "color|c" => \$SHOWCOL,
 );
 
-{
-
-package Data::StarCraft::Map;
-
-sub new {
-       my ($class) = @_;
-       bless {}, $class;
-}
-
-sub _read {
-       my $self = shift;
-       my ($fh, $size, $seek) = @_;
-       seek *$fh, $seek, 0 if $seek;
-       read(*$fh, my $in, $size) eq $size or return undef;
-       return $in;
-}
-
-sub open {
-       my $self = shift;
-       my ($file) = @_;
-
-       while (not eof $file) {
-               local $_ = $self->_read($file, 8)
-                       and my ($type, $size) = unpack "a4V", $_
-                       or die "Couldn't chunk header\n";
-               $type =~ s/ +$//;
-#printf STDERR "%s: %s\n", $type, $size;
-               defined $self->{$type} and warn "duplicate map chunk $type\n";
-               $self->{$type} = $self->_read($file, $size);
-       }
-       return $self;
-}
-
-sub version {
-       my $self = shift;
-       return 'v' . ord $self->{VER};
-}
-
-sub info {
-       my $self = shift;
-       my ($x, $y) = unpack "vv", $self->{DIM};
-       return {
-               x => $x,
-               y => $y,
-       };
-}
-
-sub width {
-       return $_[0]->info->{x};
-}
-
-sub tiles {
-       my $self = shift;
-       my @map = unpack 'v*', $self->{MTXM};
-       @map == $#map + 1 or warn(sprintf
-               "couldn't parse map: only %d tiles\n", scalar @map
-       ), return;
-       return \@map;
-}
-
-my @maptile = (
-       '!' => [  0.. 31],
-       'd' => [ 32.. 62,  63],      # dirt (verified)
-       'h' => [ 64.. 94],           # high dirt
-       "~" => [ 96..117, 118..127], # water
-       'j' => [128..159],           # jungle/crushed rock
-       'o' => [160..186, 187..191], # rocky/shale (verified)
-       'R' => [192..223],           # raised jungle
-       'l' => [224..252, 253..255], # lava/ruins (verified)/flagstones?
-       'b' => [256..287],           # basilica?
-       'x' => [288..319],           # high jungle
-#      'x' => [3745..3792],         # high jungle
-       'q' => [320..351],           # high ruins
-       ' ' => [352..383],
-       'a' => [384..415],           # high basilica
-       'm' => [416..447],           # mud
-       ' ' => [448..479],
-       ' ' => [480..511],
-
-       ' ' => [512..543],
-       ' ' => [544..575],
-       '/' => [576..607], # high dirt -> dirt (top left)
-       '/' => [608..639], # dirt -> high dirt
-       '\\' => [640..671], # high dirt -> dirt (top right)
-       '\\' => [672..703], # dirt -> high dirt (bottom left)
-       '\\' => [704..735], # high dirt -> dirt (bottom left)
-       '\\' => [736..767], # dirt -> high dirt (top right)
-       '/' => [768..863],
-       '=' => [864..1055], # some edge (tmp)
-       '=' => [1056..1183],
-       '=' => [1184..1727],
-       'D' => [1728..1780], # edge water
-       '/' => [1760..1791], # dirt -> water (top left)
-       '\\' => [1792..1823], # dirt -> water (top right)
-
-       'd' => [609..611],
-       'W' => [2048..2303],
-       '/' => [2304..2559],
-       'W' => [2560..2815],
-       'j' => [2816..3071],
-       'd' => [3072..3327],
-       'j' => [3328..3583],
-       'x' => [3648..3839],
-       'h' => [3840..4095],
-#      'x' => [4096..4351],
-       'h' => [4096..4351],
-#      'x' => [4352..4607],
-#      ' ' => [4608..4863],
-       'l' => [4864..5311],
-       'q' => [5312..5503],
-       'x' => [5504..5631],
-       'q' => [5632..5759],
-       'j' => [5760..5823],
-#      ' ' => [5824..5887],
-       '=' => [5888..6143], # raised jungle -> jungle
-#      ' ' => [6144..6655],
-       '/' => [6656..7167],
-       '/' => [7168..7359], # basilica -> crushed rock
-       '/' => [7360..7551],
-       'i' => [7552..7807], # high temple
-#      ' ' => [7808..8959],
-#      '=' => [8960..9087],
-#      'd' => [9088..9215],
-#      ' ' => [9216..9727],
-#      'm' => [9728..9983],
-#      #    >= 9984 unencountered
-#      ' ' => [19968..20480], # something here on twilight
-#      ' ' => [20544..20736], # center thing on twilight
-#      '~' => [20896..21023], # something in the water on twilight
-#      'x' => [23104..23231], # something on twilight (on X or H)
-#
-#      'm' => [9216..9776], # mud <-> dirt
-#      'r' => [5792..5875, 5888..5904], # raised jungle edge
-#
-#      'd' => [3042..3250], # dirt<->grass
-#      'P' => [4608..4977], # dirt<->shale (verified) [also seems to be rocks on mud]
-#      #'=' => [768..1731], # dirt<->lava ridge (verified)
-
-       'h' => [16389],
-       '1' => [16405, 16388],
-       '2' => [16421, 16404, 16387],
-       '3' => [16437, 16420, 16403, 16386],
-       '4' => [16453, 16436, 16419, 16402, 16385],
-       '5' => [              16435, 16418, 16401, 16384],
-       '6' => [                     16434, 16417, 16400],
-       '7' => [                            16433, 16416],
-       'd' => [16501,                             16432],
-       '7' => [16485, 16500],  # these ↕ aren't ramps in temple!!
-       '6' => [16469, 16484, 16499],
-       '5' => [16453, 16468, 16483, 16498],
-       '4' => [       16452, 16467, 16482, 16497],
-       '3' => [              16451, 16466, 16481, 16496],
-       '2' => [                     16450, 16465, 16480],
-       '1' => [                            16449, 16464],
-       'h' => [17248,                             16448],
-       '1' => [17264, 17249],
-       '1' => [17280, 17265, 17250],
-       '2' => [17296, 17281, 17266, 17251],
-       '3' => [17312, 17297, 17282, 17267, 17252],
-       '4' => [17328, 17313, 17298, 17283, 17268, 17253],
-       '5' => [       17329, 17314, 17299, 17284, 17269],
-       '6' => [              17330, 17315, 17300, 17285],
-       '7' => [                     17331, 17316, 17301],
-       '7' => [                            17332, 17317],
-       'd' => [17232,                             17333],
-       '7' => [17216, 17233],
-       '7' => [17200, 17217, 17234],
-       '6' => [17184, 17201, 17218, 17235],
-       '5' => [17168, 17185, 17202, 17219, 17236],
-       '4' => [17152, 17169, 17186, 17203, 17220, 17237],
-       '3' => [       17153, 17170, 17187, 17204, 17221],
-       '2' => [              17154, 17171, 17188, 17205],
-       '1' => [                     17155, 17172, 17189],
-       '1' => [                            17156, 17173],
-       'h' => [                                   17157],
-);
-
-my %eratile = (
-       4 => [
-               # Longinus (by KuKulZa, modified MBCgame/iCCup)
-               # SPRP: 6,0,1,0
-               # TYPE: 82,65,87,66
-               # VER: 205,0
-               # SIDE: 5,5,5,1,2,0,1,2,7,7,7,4
-               'd' => [
-                       19760..19761, 19792, 19793, 19680, 19681, 19712, 19713, 19664, 19665, 19728, 19729, # D→J
-                       19808,19809, 19776,19777, 19872,19873, 19920,19921,
-                       19744,19745, 19696,19697, 19632,19633, 19696,19697, 19952,19953,
-                       19568,19569, # below ridge
-                       3618,3634, 3586,3602, # D←J
-                       3601, # D→J(3585)
-               ],
-               'j' => [
-                       21968, 21969, 21984, 21985,
-                       21824,21825,21840,21841, 21856,21857,21872,21873, 21792,21793,
-                       21808,21809, 21888,21889,21904,21905,
-                       3616,3632,3584,3600,3616,3632, # J→D
-                       3585, # J→D(3601)
-               ],
-               'l' => [
-                       22608..22611, 22624..22627, 22640..22643,
-               ],
-               'o' => [
-                       24850, # besides ladder
-                       20832,20833,20848,20849, 20768,20769,20784,20785,
-                       20864,20865,20880,20881,
-                       20704,20705,20720,20721, # large rock
-                       4432,4433,4434,4448,4449,4464,4465,
-                       4545,4561,4577,4593, 4544,4560,4576,4592,
-               ],
-               'h' => [
-                       18000,18001, # H→X
-                       17952,17953, 17936,17937, 17920,17921, 17856,17857, 17888,17889, # H→X unsure
-                       17984,17985, 18160,18161, 18128,18129, 18048,18049,
-                       19648,19649,19616,19617, 18016,18017,
-                       17696,17697,17712,17713, # tree
-                       17872,17873,17904,17905, 18144,18145,
-                       18448,18449,18464,18465,18480,18481,
-               ],
-               'm' => [ # mud hole
-                       9219,9235,9539,9555,
-                       9218,9234,9795,9235,9811,9571,9587,
-                       9472,9488,9250,9266,9635,9651,9280,9296,
-                       9504,9520,9665,9681,9344,9360,9760,9776,9539,9555,
-                       9475,9491,9889,9905,9376,9392,9440,9456,9571,9587,
-                       9507,9523,9377,9393,
-
-                       9537,9553,
-                       9569,9585,9474,9490,9283,9299,9216,9232,9536,9552,
-                       9536,9552,9923,9939,9283,9299,9506,9522,9827,9843,9728,9744,9568,9584,
-                       9283,9299,9217,9233,9731,9747,9568,9584,9699,9715,9315,9331,9284,9300,9217,9233,9955,9971,
-                       9763,9779,9793,9809,9379,9395,9664,9680,9316,9332,9249,9265,9536,9552,
-                       9443,9459,9921,9937,9284,9300,9216,9232,9284,9300,9216,9232,9696,9712,9345,9361,9409,9425,9604,9620,9568,9584,
-                       9216,9232,9764,9780,9248,9264,9316,9332,9248,9264,9346,9362,9441,9457,9860,9876,9537,9553,
-                       9728,9744,9444,9460,9667,9683,9348,9364,9411,9427,9602,9618,9378,9394,9444,9460,9569,9585,
-                       9891,9907,9380,9396,9443,9459,9858,9874,9540,9556,
-                       9379,9395,9442,9458,9572,9588,
-               ],
-               '/' => [
-                       # Longinus (by KuKulZa, modified MBCgame/iCCup)
-                       9125, 9141, 9126, 9142, # D→~
-                       9120, 9136, # H→D
-                       9059,9075, 9189,9205, # D→~
-                       19824,19825, # D→~
-                       19200,19201,19216,19217, # object on D
-               ],
-               '/' => [
-                       17632,17633,17648,17649, # H rotating thing
-                       18208,18209, # H skull thing
-                       18224,18225,18240,18241, # H statuey thing
-               ],
-               'q' => [
-                       23872,23873,23874,23875,23888,23889,23890,23891,23904,23905,23906,23907, # Q crater
-                       23680,23681,23696,23697,23712,23713,
-               ],
-               'x' => [
-                       24336,24337,24352,24353, 24272,24273,24288,24289,
-                       24272,24273,24288,24289, 24368,24369,24384,24385,
-                       4353,4369, 4385,4401,4353,4369, 4386,4402, 4385,4401,
-                       4386,4402,4354,4370,4386,4402,
-               ],
-               '/' => [
-                       19856,19857,20144,20145, # D skeleton
-               ],
-               '/' => [21184], 'W' => [21185,21200,21201,21216,21217], # standing rock
-               '/' => [21232], 'W' => [21233,21248,21249,21264,21265], # standing rock
-               '7' => [25011, 25010], # M»H
-               '7' => [24699, 25143], 6 => [24716], # M»H
-               'W' => # island o' rocks
-                              [21120..21125, 21136..21141, 21152..21157, 21168..21173],
-                       '/' => [21121,21122,21136..21139,21152..21154],
-                       '~' => [21120,21124,21125,21141,21157,21171..21173],
-               '/' => [
-                       # D→~ coast
-                       8997,9013,8963,8979, 8996,9012,8963,8979,8993,9009, 8997,9013,
-                       8998,9014, 8993,9009, 9187,9203, 9121,9137, 9131,9147, 8992,9008,
-                       9190,9206, 9062,9078, 8996,9012, 9090,9106,9194,9210,
-                       9061,9077,9029,9045,9184,9200,8998,9014, 9024,9040,8997,9013,
-               ],
-
-               # Lost Temple (default?)
-               # SPRP: 4,0,5,0
-               # VER: 59,0
-               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
-               '/' => [
-                       9089,9105, # H←D
-                       9196,9212, # H←D→~
-                       8966,8982, 8962,8978, # H→~
-                       9088,9104, # D→D/~
-                       16832..16835,16848..16851,16864..16867,16880..16883, # H→D ridge (ramp elsewhere?)
-                       16384..16389, 16400..16405, 16416..16421, 16432..16437, # idem
-                       8961,8977,9155,9171, # H←D→~
-                       20160,20161,19984,19985,19986,19987,20000,20001,20002,20003, # D→H
-                       9124,9140, 9122,9138, 9002,9018, 8960,8976, 9168,9152, 8995,9011, # H→D→~
-                       9057,9073, # H→D→~ temple.6
-                       8968,8984, # D↔H
-               ],
-               'j' => [
-                       21952,21953,
-               ],
-               'x' => [
-                       4384,4400, 4352,4368, # X→H
-               ],
-               'h' => [
-                       18096,18097, 17968,17969, 18032,18033,18176,18177,
-               ],
-               'd' => [
-                       9347,9363,9953,9969,9473,9489,9251,9267,9633,9649,9505,9521,9410,9426,
-                       9347,9363, 19840,19841, 19888,19889, 20208,20209,20224,20225,
-                       20240,20241,20256,20257, 20272,20273,20288,20289, 19601,19600,
-                       20304,20305,20320,20321, # tree
-               ],
-               'o' => [
-                       4673,4689,4737,4753,4705,4721,4769,4785, # rocks on D
-                       4674,4690,4706,4722,4674,4690,4480,4496,4706,4722,4832,4848,4640,4656,
-                       4736,4752,4768,4784,
-                       4482,4498, 4834,4850, 4642,4658,
-               ], 'd' => [4498,4642],
-               'm' => [
-                       # M→D mud holes
-                       9281,9297,9313,9329, 9281,9297,9313,9329, 9538,9554,9570,9586,
-                       9282,9298,9282,9298,9220,9236,9476,9492,9314,9330,9729,9745,9412,9428,9476,9492,9314,9330,9538,9554,9476,9492,9252,9268,
-                       9508,9524,9668,9684,9600,9616,9508,9524,9666,9682,9601,9617,9570,9586,9508,9524,9408,9424,9700,9716,9632,9648,9698,9714,9282,9298,9314,9330,
-                       9312,9328, 9412,9428, 9636,9652, 9634,9650,
-                       9730,9746, 9761,9777,9762,9778, 9794,9810,
-                       9732,9748, # temple.5
-                       9603,9619, # temple.6
-               ],
-               'r' => [
-                       5859,5875, 5858,5874, # top edge
-               ],
-               'O' => # temple center ornament
-                       [
-                               22320,22321,22336,22337,22352,22353,
-                               22368,22369,22384,22385,22400,22401,
-                               22464..22467,22480..22483,22496..22499,
-                               22800,22801,22802,22803,22816,22817,22818,22819,22832,22833,22834,22835,
-                               22752,22753,22754,22755,22768,22769,22770,22771,22784,22785,22786,22787,
-                       ],
-                       'l' => [ # cut out shapes
-                               22464,22467,22496,22499, 22321,22353, 22368,22400,
-                               22800,22802,22803,22832,22835, 22819,
-                               22752,22753,22755,22787,22784, 22768,
-                       ],
-               'D' => # underwater cave
-                       [
-                               21440,21441,21442,21443, 21456,21457,21458,21459,
-                               21472,21473,21474,21475, 21488,21489,21490,21491,
-                       ],
-                       'W' => [21456, 21472,21473,21474,21475],
-                       'o' => [21442,21443],
-                       '~' => [21488,21489, 21490,21491],
-               'i' => [
-                       23632,23633,23648,23649,23664,23665, 23584,23585,23600,23601,23616,23617, # statue things on Q
-               ],
-               'D' => [1824..1839], 'W' => [1840..1855], # D→~ bright transition
-               'D' => [1856..1871], 'd' => [1872..1887], # D→~ bleft ridge
-               'W' => [1888..1903], 'D' => [1904..1919], # D→~ bleft transition
-               '~' => [1920..1935], 'W' => [1936..1951], # w→~ bleft transition
-               'd' => [1952..1967], 'D' => [1968..1983],
-               'D' => [1984..1999], 'W' => [2000..2015],
-               'W' => [2016..2031], '~' => [2032..2047],
-               'D' => [8965,8981, 8964,8980, 9174,9158, 9010,8994], # H→D→~
-               'd' => [19936,19937], # D→~
-               '/' => [19905], 'd' => [19904], # H→D
-               'r' => [
-                       5825,5841, 5857,5873, # J→R→map edge
-                       5826,5842, # J↔R
-               ],
-               'q' => [
-                       # gap
-                       23456,23457,23458,23459, 23472,23473,23474,23475,
-                       23488,23489,23490,23491, 23504,23505,23506,23507,
-                       # towery thing
-                       23824,23825,23826,23827, 23840,23841,23842,23843, 23856,23857,23858,23859,
-               ],
-
-               # Plains to Hill (v2.00 by Sir.Lupin)
-               # VER: 59,0
-               # SPRP: 1,0,2,0
-               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
-               # FORC: 0,0,0,0,1,1,1,1,31,0,30,0,29,0,28,0,1,11,0,0
-               '/' => [
-                       # H→D bottom left side (may be a ramp elsewhere)
-                       16768,16769,16770,16771, 16784,16785,16786,16787,
-                       16800,16801,16802,16803, 16816,16817,16818,16819,
-                       # idem bottom right side
-                       16960,16961,16962,16963, 16976,16977,16978,16979,
-                       16992,16993,16994,16995, 17008,17009,17010,17011,
-                       # idem
-                       17088,17089,17090,17091, 17104,17105,17106,17107,
-                       17120,17121,17122,17123, 17136,17137,17138,17139,
-               ],
-
-               # Python (v1.3 by Terrance, modified by Forgotten_/KeSPA)
-               # ERA: 100,0
-               # TYPE: 82,65,87,66
-               # VER: 205,0
-               # SPRP: 1,0,7,0
-               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
-               # FORC: 0,0,0,0,1,1,1,1,2,0,4,0,5,0,6,0,1,14,15,15
-               'x' => [
-                       24464,24465, 24448,24449
-               ],
-               'h' => [
-                       18064,18065,
-               ],
-               '/' => [
-                       9186,9202,
-                       18112,18113, # H→D
-                       9154,9170,9027,9043,9157,9173, # H↔D
-               ],
-               'O' =>
-                       [19504,19505,19520,19521, 18720,18721,18736,18737], # rock things
-                       'h' => [18737],
-               'O' => # hole
-                       [17488..17491,17504..17507,17520..17523,17536..17539],
-                       'h' => [17490,17491,17507,17523,17536..17539],
-               'o' => [
-                       4610, 4610,4626, 4481,4497,4513,4529, 4514,4530,
-                       4417,4608,4624,4418, 4512,4528, 4450,4466,
-                       4609,4625,4546,4562, 4833,4849, 4801,4817, 4800,4816,
-               ],
-               'd' => [
-                       4672,4688,4704,4720, # D↔O
-                       19584,19585,
-                       4416, # D→O
-                       4641,4657,4578,4594, 4802,4818, # O→D
-               ],
-               'm' => [
-                       9824,9840,9952,9968,9920,9936,9888,9904, 9796,9812,9924,9940,
-                       9697,9713, 9890,9906, 9922,9938, 9792,9808,9856,9872,9826,9842,
-               ],
-               'o' => [4738,4770], 'd' => [4754,4786],
-               '/' => [18256,18257,18272,18273], 'h' => [18288,18289], # obelisk
-               '/' => # sunken temple
-                       [21024..21029, 21040..21045, 21056..21061, 21072..21077, 21088..21093,21104..21109],
-                       '~' => [21024,21104,21109,21027,21059,21076,21072,21093,],
-                       'W' => [21029, 21060,21045,21073,21090,21106,21092,21107,21075,21108,21058, 21056,21088,21105,21077],
-               'O' => # ruins similar to 22464
-                       [22512..22515, 22528..22531, 22544..22547],
-                       'l' => [22512,22515, 22544,22547],
-               'Q' => [17664,17665,17680,17681], # rock thing
-               'Q' => [17728,17729,17744,17745], # tree
-               '/' => [17808,17824,17840], 'h' => [17809,17825,17841],
-               '6' => [25025], # D»H ramp (between D and 17328 = level 4)
-
-#},    2 => {
-               # Twilight Star (default)
-               # (all guessed from low res thumb)
-               'h' => [17584,17585], # H→D
-               'r' => [5827,5843, 5824,5840,5856,5872],
-               'W' => [
-                       # water objects
-                       20912,20913,20928,20929, 20896,20897, 20944,
-                       19440,19441,19456,19457, 20945,20960,20961,
-                       20816,20817,
-               ],
-               'h' => [17760,17761,17776,17777, 17600,17601],
-               'D' => [9093,9109],
-               'o' => [19472..19475, 19488..19491],
-               'o' => [
-                       21728,21729, 21744,21745, 21760,21761,
-                       21776,21777, 19536,19537, 19538,19539, 19552..19555,
-               ],
-               'j' => [3587,3603],
-               'O' => [19232..19235, 19248..19251], 'j' => [19218,19219],
-               'O' => [19938,19939,19954,19955],
-               'h' => [17792,17793],
-               'x' => [4356,4372],
-               'O' => [ # exotic/shiny things and other objects
-                       18656,18657,18672,18673, 18496,18497,18512,18513,
-                       18560..18563, 18576..18579, 18592..18595,
-                       18528,18529,18544,18545, 18864,18865,
-                       18608..18611,18624..18627,18640..18643,
-                       18912..18915,18928..18931,18944..18947,
-                       18816..18819,18832..18835,18848..18851,
-                       18960..18963,18976..18979,18992..18995,
-                       19008..19011,19024..19027,
-                       19040..19043,19056..19059,
-               ],
-               'A' => [ # X→A
-                       7811,7827,7873,7889,7809,7825,7875,7891,
-                       8707,8723,8737,8753,7874,7890,7808,7824,7872,7888,7904,
-                       8003,8019,8160,8176,7810,7826,
-               ],
-               'a' => [ # A←X
-                       7843,7859,7905,7921,7841,7857,7907,7923,
-                       8705,8721,7971,7987,8065,8081,8738,8754,7840,7856,
-                       7920,7906,7922,7938,7954,7969,7985,8066,8082,8035,8051,
-                       7970,7986,8032,8048,
-                       8034,8050,7936,7952,8033,8049,7937,7953,
-               ],
-               'R' => [6177,6193],
-               '/' => [18080,18081],
-               'a' => [8032..8047], 'a' => [8048..8063], # #3 bottom left
-               'A' => [7841..7843], 'a' => [7857..7859], # #2 top left
-               'A' => [8000..8003], 'x' => [8016..8019], # #1 bottom right
-               'A' => [8064..8067], 'a' => [8080..8083], # #2 bottom left
-               'A' => [8224..8227], 'x' => [8240..8243], # #1 top right
-               'A' => [8288..8291], 'x' => [8304..8307], # #1 bottom right
-               'a' => [8355], 'A' => [8371], # #2 top right
-               'a' => [8322], 'A' => [8338], # #2 top right
-               'A' => [8512], 'x' => [8528], # #1 top right
-               'x' => [7811], 'A' => [7827],
-               'x' => [8096..8099], 'A' => [8112..8115],
-               'x' => [8163], 'a' => [8179],
-               'x' => [8192..8195], 'A' => [8208..8211],
-               'x' => [8128..8131], 'A' => [8144..8147],
-               'A' => [8258,8274],
-               'a' => [7939,7955], # #3 bottom right
-               'a' => [7968..7971], 'A' => [7984..7987],
-               'A' => [8256,8272],
-               'A' => [8257,8273, 8259,8275, 8162,8178],
-
-               '!' => [],
-
-               # tau cross (v1.1 by Rose.Of.Dream/BW4eVeR)
-               # ERA: 6
-               # FORC: 0,0,0,1,1,1,1,1,7,0,6,0,5,0,4,0,1,15,15,15
-               # SIDE: 5,5,5,1,0,2,1,0,7,7,7,4
-               # SPRP: 1,0,2,0
-               # TYPE: 82,65,87,66
-               # VER: 205
-               '?' => [
-                       6176,6192, 20976,20977, 20592,20593, 21392,21393, 20800,20801,
-                       20608,20609, 20624,20625, 20640,20641, 20992,20993, 21008,21009,
-                       19922,19923,22070,22071, 19968..19971, 22230,
-                       22133,22137,22272,22157,22288,22313,
-                       20592,20593,21392,21393,20800,20801,20608,20609,20624,20625,20640,20641,20992,20993,21008,21009,19922,19923,
-                       22070,22071,19968,19969,19970,19971,22230,22272,22157,22288,22313,6147,6163,6178,6194,3589,3605,22147,22162,22163,22164,
-                       22180,22315,18400,18401,18336,18337,18192,18193,17730,17731,17826,17827,17746,17747,17842,17843,
-                       17762,17763,17794,17795,17778,17779,17810,17811,17616,17617,
-                       20688,20689,6145,6161,20736,20737,21408,21409,21410,21411,
-                       20752,20753,21424,21425,21426,21427,21376,21377,20656,20657,
-                       21312,21313,21314,21315,20672,20673,21328,21329,21330,21331,
-                       6146,6162,21344,21345,21346,21347,21360,21361,21362,21363,6144,
-                       6160,
-               ],
-               '2' => # bridges
-                       [
-                               22231..22235, 22246..22253, 22260..22269,
-                               22273..22285, 22289..22301, 22306..22312, 22324..22328,
-                       ],
-                       '4' => [22246..22253, 22273..22285, 22306..22312],
-                       '2' => [
-                               22084..22086, 22096..22103, 22112..22121, 22128..22139,
-                               22144..22156, 22165..22171, 22181..22199,
-                       ],
-                       '4' => [22084..22086, 22112..22121, 22144..22156, 22181..22199],
-               'r' => [22342,22343],
-
-               # Nostalgia (WGT13, v1.3 by Rose.of.Dream)
-               # ERA: 0,0
-               # FORC: 0,0,0,0,1,1,1,1,12,0,11,0,10,0,9,0,1,14,0,0
-               # SIDE: 5,5,5,5,0,2,1,0,7,7,7,4
-               # SPRP: 1,0,4,0
-               # TYPE: 82,65,87,66
-               # VER: 205
-               '!' => [],
-       ], # jungle
-);
-
-our %tilechar;
-while (my ($char, $matches) = splice @maptile, 0, 2) {
-       $tilechar{$_} = $char for @$matches;
-}
-while (my ($char, $matches) = splice @{$eratile{4}}, 0, 2) {
-       $tilechar{$_} = $char for @$matches;
-}
-
-my @mapunit = ( # character => width, height, ids
-       '$' => [2,1, 176..178], # minerals
-       '*' => [2,1, 188], # gas
-       '@' => [2,2, 214], # start pos
-);
-
-our %unitchar;
-while (my ($char, $matches) = splice @mapunit, 0, 2) {
-       my @charinfo = ($char, splice @$matches, 0, 2);
-       $unitchar{$_} = \@charinfo for @$matches;
-}
-
-sub tiles_parsed {
-       my $self = shift;
-       my $map = $self->tiles or return;
-       if ($SHOWWARN) {
-               use Tie::IxHash;
-               tie my %unknown, 'Tie::IxHash';
-               defined $tilechar{$map->[$_]} or warn(sprintf
-                       "unknown tile %d at (%d,%d)\n",
-                       $map->[$_], $_ % $self->width, $_ / $self->width
-               ), $unknown{$map->[$_]} = $_ for 0 .. $#$map;
-               warn sprintf "unknown: %s\n", join ",", keys %unknown if keys %unknown;
-       }
-       $_ = defined $tilechar{$_} ? $tilechar{$_} : '?' for @$map;
-       for ($self->units) {
-               my ($chr, $width, $height) = defined $unitchar{$_->{id}} ?
-                       @{ $unitchar{$_->{id}} } : ('#', 1, 1);
-               for my $x ($_->{x} .. $_->{x} + $width - 1) {
-                       for my $y ($_->{y} .. $_->{y} + $height - 1) {
-                               $map->[$x + $y * $self->width] = $chr;
-                       }
-               }
-       }
-       return $map;
-}
-
-sub units {
-       my $self = shift;
-       my @units;
-       for (my $i = 0; $i < length $self->{UNIT}; $i += 36) {
-               # d1, d2, x*32, y*32, unitid, bytes1, playerid, bytes2, mineral, bytes3
-               my @pack = unpack "v5x6Cx3vx14", substr $self->{UNIT}, $i, 36;
-               push @units, {
-                       id => $pack[4],
-                       player => $pack[5],
-                       amount => $pack[6],
-                       x => $pack[2] >> 5,
-                       y => $pack[3] >> 5,
-#                      d1 => $pack[0],
-#                      d2 => $pack[1],
-               };
-       }
-       return @units;
-}
-
-sub units_parsed {
-       my $self = shift;
-       my @units;
-       for ($self->units) {
-               my ($chr, $width, $height) = defined $unitchar{$_->{id}} ?
-                       @{ $unitchar{delete $_->{id}} } : ('#', 1, 1);
-               $_->{chr} = $chr;
-               $_->{width} = $width;
-               push @units, $_;
-       }
-       return @units;
-}
-
-sub colors {
-       my $self = shift;
-       my @colormap = (
-               qw(
-                       FF0000 0000FF 209070 88409C E87824 5C2C14 FFFFFF DCDC3C
-                       0F930F FCFC8F EFCEBD 547CDC
-               ),
-               12 => "pale green", "gray", "pale yellow", "cyan",
-               17 => "black", "neon blue",
-               21 => "lavender", "black",
-               30 => "sky blue",
-               33 => "purple",
-       );
-       my @players;
-       for (unpack "C*", $self->{COLR}) {
-               push @players, $colormap[$_] || "? (#$_)";
-       }
-       return \@players;
-}
-
-sub era {
-       my $self = shift;
-       return unpack "v", $self->{ERA};
-}
-
-}
-
+use Data::StarCraft::Map;
 my $map = Data::StarCraft::Map->new->open(\*STDIN);
+$map->{DEBUG} = 1 if $SHOWWARN;
 
 if ($SHOWMAP ne "ppm") {
        printf("%s size %dx%d, %d player\n",