1 package Data::StarCraft::Replay;
31 0x09 => "Science Vessel",
34 0x0C => "Battlecruiser",
56 0x32 => "Infested Terran",
61 0x3D => "Dark Templar",
67 0x43 => "High Templar",
80 0x6A => "Command Center",
82 0x6C => "Nuclear Silo",
83 0x6D => "Supply Depot",
84 0x6E => "Refinery", # refinery?
86 0x70 => "Academy", # Academy?
89 0x73 => "Control Tower",
90 0x74 => "Science Facility",
92 0x76 => "Physics Lab",
94 0x78 => "Machine Shop",
96 0x7A => "Engineering Bay",
98 0x7C => "Missile Turret",
101 0x82 => "Infested CC",
105 0x86 => "Nydus Canal",
106 0x87 => "Hydralisk Den",
107 0x88 => "Defiler Mound",
108 0x89 => "Greater Spire",
109 0x8A => "Queens Nest",
110 0x8B => "Evolution Chamber",
111 0x8C => "Ultralisk Cavern",
113 0x8E => "Spawning Pool",
114 0x8F => "Creep Colony",
115 0x90 => "Spore Colony",
117 0x92 => "Sunken Colony",
123 0x9B => "Robotics Facility",
125 0x9D => "Assimilator",
127 0x9F => "Observatory",
130 0xA2 => "Photon Cannon",
131 0xA3 => "Citadel of Adun",
132 0xA4 => "Cybernetics Core",
133 0xA5 => "Templar Archives",
137 0xA9 => "Fleet Beacon",
138 0xAA => "Arbiter Tribunal",
139 0xAB => "Robotics Support Bay",
140 0xAC => "Shield Battery",
144 0xC2 => "Dark Archon",
147 0xC5 => "Interceptor",
148 0xC6 => "Interceptor/Scarab",
151 "Terran Infantry Armor",
152 "Terran Vehicle Plating",
153 "Terran Ship Plating",
155 "Zerg Flyer Carapace",
156 "Protoss Ground Armor",
158 "Terran Infantry Weapons",
159 "Terran Vehicle Weapons",
160 "Terran Ship Weapons",
161 "Zerg Melee Attacks",
162 "Zerg Missile Attacks",
163 "Zerg Flyer Attacks",
164 "Protoss Ground Weapons",
165 "Protoss Air Weapons",
166 "Protoss Plasma Shields",
168 "U-238 Shells (Marine Range)",
169 "Ion Thrusters (Vulture Speed)",
171 "Titan Reactor (Science Vessel Energy)",
172 "Ocular Implants (Ghost Sight)",
173 "Moebius Reactor (Ghost Energy)",
174 "Apollo Reactor (Wraith Energy)",
175 "Colossus Reactor (Battle Cruiser Energy)",
176 "Ventral Sacs (Overlord Transport)",
177 "Antennae (Overlord Sight)",
178 "Pneumatized Carapace (Overlord Speed)",
179 "Metabolic Boost (Zergling Speed)",
180 "Adrenal Glands (Zergling Attack)",
181 "Muscular Augments (Hydralisk Speed)",
182 "Grooved Spines (Hydralisk Range)",
183 "Gamete Meiosis (Queen Energy)",
186 "Singularity Charge (Dragoon Range)",
187 "Leg Enhancement (Zealot Speed)",
190 "Gravitic Drive (Shuttle Speed)",
191 "Sensor Array (Observer Sight)",
192 "Gravitic Booster (Observer Speed)",
193 "Khaydarin Amulet (Templar Energy)",
194 "Apial Sensors (Scout Sight)",
195 "Gravitic Thrusters (Scout Speed)",
197 "Khaydarin Core (Arbiter Energy)",
200 "Argus Jewel (Corsair Energy)",
203 "Argus Talisman (Dark Archon Energy)",
204 "Caduceus Reactor (Medic Energy)",
205 "Chitinous Plating (Ultralisk Armor)",
206 "Anabolic Synthesis (Ultralisk Speed)",
207 "Charon Boosters (Goliath Range)",
219 "Cloaking Field (wraith)",
220 "Personal Cloaking (ghost)",
248 0x02 => "Unallowed Move?",
249 0x06 => "Force move",
252 0x0E => "Attack Move",
253 0x13 => "Failed Casting (?)",
257 0x27 => "Clear Rally",
264 0x77 => "Dark Swarm",
266 0x79 => "Spawn Broodling",
268 0x7E => "Launch Nuke",
270 0x8B => "ComSat Scan",
271 0x8D => "Defense Matrix",
272 0x8E => "Psionic Storm",
278 0x94 => "Hallucination",
282 0xB5 => "Disruption Web",
283 0xB6 => "Mind Control",
285 0xB9 => "Optic Flare",
291 0x09 => ["select", 1, 2 | CMD_REPEAT],
292 0x0A => ["add", 1, 2 | CMD_REPEAT],
293 0x0B => ["deselect", 1, 2 | CMD_REPEAT],
294 0x0C => ["build", 1, \%build, 2, 2, 2, \%unit],
295 0x0D => ["vision", 2],
296 0x0E => ["ally", 2, 2],
297 0x13 => ["hotkey", 1, [qw"assign select"], 1],
298 0x14 => ["move", 2, 2, 2, 2, 1], # 1 = queued?
299 0x15 => ["action", 2, 2, 2, 2, 1, \%action, 1, [qw"normal queued"]],
301 0x19 => ["cancel hatch"],
303 # 0x1B => ["move-thing??"], # tim: after hotkey (unit, reaver??) select; soon after reselected and moved
304 0x1E => ["return cargo", 1],
305 0x1F => ["train", 2, \%unit],
306 0x20 => ["cancel train", 2], # == 254
307 0x21 => ["cloak", 1],
308 0x22 => ["decloak", 1],
309 0x23 => ["hatch", 2, \%unit],
310 0x25 => ["unsiege", 1],
311 0x26 => ["siege", 1],
312 0x27 => ["arm", 0], # scarab/interceptor
313 0x28 => ["unload all", 1],
314 0x29 => ["unload", 2],
315 0x2A => ["merge archon", 0],
316 0x2B => ["hold position", 1],
317 0x2C => ["burrow", 1],
318 0x2D => ["unburrow", 1],
319 0x2E => ["cancel nuke", 0],
320 0x2F => ["lift", 2, 2],
321 0x30 => ["research", 1, \@research],
322 0x31 => ["cancel research", 0],
323 0x32 => ["upgrade", 1, \@upgrade],
324 # 0x33 => ["forge-thing??"], # right after forge select: probably unpowered, iirc cancel research
325 0x35 => ["morph", 2, \%unit],
327 0x57 => ["part", 1, {qw"1 quit 6 drop"}],
328 0x5A => ["merge dark archon", 0],
338 my ($fh, $size, $seek) = @_;
339 seek *$fh, $seek, 0 if $seek;
340 read(*$fh, my $in, $size) eq $size or return undef;
348 while (not eof $file) {
349 local $_ = $self->_read($file, 5)
350 and my ($time, $size) = unpack "VC", $_
351 or die "Couldn't read time block head\n";
352 local $_ = $self->_read($file, $size)
353 and my @block = unpack "C*", $_
354 or die "Couldn't read time block data\n";
356 my $player = shift @block;
357 my $cmd = shift @block;
358 if (not defined $cmdread{$cmd}) {
359 warn sprintf "command #%X not defined: %d bytes ignored\n",
361 push @$self, [$time, $player, "??? $cmd"] if $::SHOWWARN;
366 my ($data, $byte) = @_;
367 my $out = shift @$data;
368 if (($byte & 3) == 2) {
369 @$data ? ($out += shift(@$data) << 8)
370 : warn "high byte not present\n";
375 my @format = @{ $cmdread{$cmd} };
376 my $desc = shift @format;
378 for my $bit (@format) {
380 if (ref $bit eq "ARRAY") {
381 $data[-1] = defined $bit->[$data[-1]] ? $bit->[$data[-1]]
384 $data[-1] = defined $bit->{$data[-1]} ? $bit->{$data[-1]}
390 if ($bit & CMD_REPEAT) {
391 push @data, readbyte(\@block, $bit) for 1 .. shift @data;
393 push @data, readbyte(\@block, $bit);
396 $desc eq "move" and $data[2] == 0 and $desc = "rally";
397 push @$self, [$time, $player, $desc, @data];