From d7d9369b4d1bddef20d56636d7e7e85c507bb11a Mon Sep 17 00:00:00 2001 From: Shiar Date: Tue, 27 Nov 2007 20:18:02 +0100 Subject: [PATCH] Data::StarCraft::Map package taken out of scmap --- Data-StarCraft/lib/Data/StarCraft/Map.pm | 672 +++++++++++++++++++++++ scmap | 669 +--------------------- 2 files changed, 674 insertions(+), 667 deletions(-) create mode 100644 Data-StarCraft/lib/Data/StarCraft/Map.pm diff --git a/Data-StarCraft/lib/Data/StarCraft/Map.pm b/Data-StarCraft/lib/Data/StarCraft/Map.pm new file mode 100644 index 0000000..4b9953c --- /dev/null +++ b/Data-StarCraft/lib/Data/StarCraft/Map.pm @@ -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 e052c76..cd564d3 100755 --- 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", -- 2.30.0