Post subject: Beat this TAS or Script!
Skilled player (1638)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
To inspire others, I am attempting to do more open TASing. Each map entity is 0x9C, or 156 bytes large. I've found only what a portion of those bytes mean. The blocks start at 0x11EBF8, and count down, not up. (i.e. subtract 0x9C to get the next block, instead of adding. I need to find where the size of the entity is (if that is even in the blocks - it might be hardcoded by ID?) My script draws everything off the map, and will tell you the owner, HP, type, etc. Here is my current script: Download WC2.lua
Language: lua

--Offsets Ms = 6; -- Map size. (could be double ? Maps seem to grow by 16s, not 8s.) Player = 5; -- Which number of owner the player is, to avoid drawing on the map. OffsetLoc = 0x11E7B4+7*0x9c; Sz = 0x9C; -- Bytes found -- -- X - 0 (2 bytes) -- Y - 2 (2 bytes) -- 6 is alive. (2 or 0) --8 current action - 2 - stopped, 3 walking, 4 attacking/harvesting -- 23 - 32 if selected, other wise 0 -- 32 Visible - 1 covered with fog of war, 0 visible -- 36 Owner 0 - player, 15 - resource/animal -- 138 Resources left resources = false; Ofs = {0x00, 0x02, 0x19, 29, 32, 138, 6, 8, 27}; F=4; CamX = 0x01616D8; CamY = 0x01616DC; keys = {}; last_keys = {}; function press(button) if keys[button] and not last_keys[button] then return true end return false end while true do CX = memory.readwordsigned(CamX); CY = memory.readwordsigned(CamY); gui.text(100,20,string.format("Of: %d",F)); --gui.text(230,10,string.format("%d, %d",CX+memory.readword(0x00160BFC), CY+memory.readword(0x00160C00))); keys = input.get(); emu.frameadvance(); clickhappen = false; for i = -150,0,1 do --gui.text(10,100+i*10, string.format("%d,%d - %d (%d %d)", memory.readword(OffsetLoc+Sz*i), memory.readword(2+OffsetLoc+Sz*i), memory.readword(0x1A+OffsetLoc+Sz*i), memory.readbyte(F+OffsetLoc+Sz*i), memory.readword(F+OffsetLoc+Sz*i))); X = memory.readword(OffsetLoc+Sz*i); Y = memory.readword(OffsetLoc+Sz*i+2); if(memory.readbyte(OffsetLoc+Sz*i+36) ~= Player) and (memory.readbyte(OffsetLoc+Sz*i+36) < 15) then gui.drawbox(17+X/(8*Ms),33+Y/(8*Ms),17+X/(8*Ms)+1,33+Y/(8*Ms)+1, 'red') end; if resources and (memory.readbyte(OffsetLoc+Sz*i+36) == 15) then gui.drawbox(17+X/(8*Ms),33+Y/(8*Ms),17+X/(8*Ms)+1,33+Y/(8*Ms)+1, 'yellow') end --gui.text(10,100+i*10, string.format("%d,%d - %d", X-CX, Y-CY,memory.readbyte(6+OffsetLoc+Sz*i))); if (X >= CX) and (X < (CX+600)) and (Y >= CY) and (Y < (CY+600)) and (memory.readbyte(8+OffsetLoc+Sz*i)>0) then --and (memory.readbyte(6+OffsetLoc+Sz*i)==32) then X2 = (X-CX)/2; Y2 = (Y-CY)/2; --gui.text(X2+1,Y2+1,-1*i); --gui.text(X2+1,Y2+10,memory.readbyte(OffsetLoc+F+Sz*i)); --gui.text(X2+1,Y2+20,memory.readword(OffsetLoc+F+Sz*i)); Type = memory.readbyte(29+OffsetLoc+Sz*i) if Type < 20 then size = 15; elseif Type < 60 then size = 30; elseif Type < 75 then size = 45; else size = 60; end; gui.drawbox(X2,Y2,X2+size,Y2+size); if keys['leftclick'] and clickhappen == false then if keys.xmouse > X2 and keys.xmouse < X2+size and keys.ymouse > Y2 and keys.ymouse < Y2+size then clickhappen = true; item = i; end; end; end; end; if clickhappen == true then gui.drawbox(200,0,320,120,'black','white'); gui.text(203, 2, string.format("Item #%d", -1*item)); gui.text(203, 12, string.format("Type %d", memory.readbyte(29+OffsetLoc+Sz*item))); gui.text(203, 22, string.format("Owner %d", memory.readbyte(36+OffsetLoc+Sz*item))); gui.text(203, 32, string.format("HP %d", memory.readword(26+OffsetLoc+Sz*item))); end; if press('I') then F = F + 1; end; if press('U') then F = F - 1; end; last_keys = keys; end;
http://dehacked.2y.net/microstorage.php/info/401483148/Warcraft2.pjm
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Active player (456)
Joined: 11/12/2010
Posts: 183
Location: Sweden
Would anyone happen to know what settings I should use to run this game as I can't get it to start on either pcsx or psxjin myself? Might Windows 7 be the issue?
"An artist who can’t take constructive critique on their work is only hurting themselves and their potential. Conversely, and artist that can’t communicate a critique in a constructive way isn’t helping anybody."
Skilled player (1535)
Joined: 7/25/2007
Posts: 299
Location: UK
I've started TASing this game now, and have saved a whopping 1 second on the first level so far. However, I'm still puzzled/annoyed as to why it's not more than that, considering the small improvements should add up. But of course, due to the annoying nature of this game, starting one thing earlier just means you'll be waiting longer to start the next thing.
Post subject: Work progressing on Warcraft II? Awesome!
Moderator, Senior Ambassador, Experienced player (898)
Joined: 9/14/2008
Posts: 1007
Flip, I'm very excited to see some progress on a Warcraft II run. I'm assuming you're working on the PSX version instead of the DOS / jpc-rr version. Is there any particular strategy you're working from? When do you hope to have a WIP up? Just curious and thanks for tackling this, A.C. ******
I was laid off in May 2023 and could use support via Patreon or onetime donations as I work on TASBot Re: and TASBot HD. I'm dwangoAC, part of the senior staff of TASVideos as the Senior Ambassador and BDFL of the TASBot community; I post TAS content on YouTube.com/dwangoAC based on livestreams from Twitch.tv/dwangoAC.
Skilled player (1535)
Joined: 7/25/2007
Posts: 299
Location: UK
OK, WIP of first 3 levels, 13 seconds ahead of previous run. http://dehacked.2y.net/microstorage.php/info/399454605/Warcraft%20II-The%20Dark%20Saga.pjm For future levels, I'll be basing my strats off youtube videos, although I have no idea if they're the records or not.
Post subject: Challenge Accepted
Skilled player (1535)
Joined: 7/25/2007
Posts: 299
Location: UK
So here's an improved version of the previous script. This one fixes the oversized minimap projection, properly locates all of the units on the map, successfully identifying which are your own, gives units their proper clan colour, draws proper sized boxes around them, gives a tidier information box, and has far more decoded info. Download War2.Lua
Language: Lua

--[[Each Map entity takes up 0x9C=156 blocks, and count DOWN from the Offset Location. Here are decoded values: -00 X Coord, each square treated as 32x32. -02 Y Coord, same as X. -04 increases by +5 +4 Mod 54, don't know why. -06 Existence? 0=yes, 16=In training? 32=no, 48=Dead, or skeleton? Seems to keep changing to 32 while alive though, weird. -08 Animation: 2=stop, 3=move, 4=attack. -09 Animation frame -10 Direction, 0=N, 1=NE, 2=E, ...., 7=NW. -12 Graphic displacement (Y), used for sea/air units, which bob up and down periodically thus alternating 0, 1. -13 Graphic Displacement (Y) Timer. Controls when to bob. -16 X Coord, each square being 1x1 -18 Y Coord. -20 Movement type. 0=Land, 6=Flying, 8=Transport on Coast, 10=Ship. Dictates where/how unit travels. IE Flying creatures move 2 squares at a time. Also affects their shadow on ground. -22 Possible to select. 128=Yes, 136=No. -23 Selected: 0=No, 1=Building<50%, 32=Yes, 64=issued command, 128=selected by enemy. These values get added to each other. -26 HP -28 Countdowns from 200 when attacking/attacked. Possible RNG? -29 Unit Type. See values below, this merely controls actions available to it. -30 Mana. Also functions as construction/upgrade progress (0-256). Also, summoned units use Mana as duration countdown. -31 Unit Stats. Uses same values as Unit Type, but this changes Unit's Portrait Icon/stats etc. -32 Visiblity: 0=Yes, 1=Inside another Unit, 2=No -35 Unit Graphic. Uses same values as Unit Type, but a few extra values for 'peon with lumber' etc. -36 Owner. Players 0-7, 15 if just critter/GM etc -37 Clan Colour. 0-7. IE a player may control another clan -38 Current Action. See below tables -39 Next upcoming Action. -40 Route Plan. 40-59 shows the upcoming path a unit takes, using values 0-7 to desribe the direction to travel after taking each step. Directions will be -1 if unused, and if path is more than 20 steps these values will update themselves, according to Step Counter below. -59 End of Route Plan. -60 Invisibility Timer -62 Unholy Armour Timer -64 Bloodlust Timer -66 Slow/Haste Timer. Haste starts positive value, Slow starts negative, both countdown to 0. -70 Flame Shield Timer -72 Targetted by somebody? 0=No 7=Yes. Doesn't reset at all? -73 Attack countdown? 0 by default, quickly decreases from 31 after somebody targets attack? -76-80 Change to bloody weird values when under attack. No clue why. -100 Next Patrol X. Previous location to patrol back to. -102 Next Patrol Y. Updates after each journey. Also functions as Tower Upgrade progress. -104 Start of Personal Info. See data below -115 End of Personal info -134 Step Counter. 20 by default, keeps counting down to 0, on when to update Route Plan. -138 Gold inside GM. -142 Destination X Coord. Not subsquare values, each square treated as 1x1. -144 Destination Y Coord. -Unit Types. Also shares same values for graphic/stats. -0 Footman -1 Grunt -2 Peasant -3 Peon -4 Ballista -5 Catapult -6 Knight -7 Ogre -8 High Elven Archer -9 Axe Thrower -10 Mage -11 DK -12 Paladin -13 Ogre-Mage -14 Dwarf Demolishen Squad -15 Sappers -16 Alterac Traitors -17 Useless Peons (Horde equiv of traitors?) -18 High Ranger -19 Beserker -20 Alleria -21 Teron Gorefiend -22 Kurdran And Sky'ree -23 Dentarg -24 Khadgar -25 Grom Hellscream -26 Oil Tanker -27 Oil Tanker -28 Transport -29 Transport -30 Elven Destroyer -31 Troll Destroyer -32 Battleship -33 Juggernaut -35 Deathwing -38 Gnomish Submarine -39 Giant Turtle -40 Flying Machine -41 Zeppelin -42 Gryphon Rider -43 Dragon -44 Turalyon -45 Eye of Killrog -46 Danath -47 Korgath Bladefist -49 Cho'gall -50 Lord Lothar -51 Gul'Dan -52 Uther Lightbringer -53 Zul'jin -55 skeleton -56 Daemon -57 Critter -58 Farm -59 Pig Farm -60 Barracks -61 Barracks -62 Church -63 Altar of Storms -64 Watch Tower -65 Watch Tower -66 Stables -67 Ogre Mound -68 Gnomish Inventor -69 Goblin Alchemist -70 Gryphon Aviary -71 Dragon Roost -72 Shipyard -73 Shipyard -74 Town Hall -75 Great Hall -76 Elven Lumber Mill -77 Troll Lumber Mill -78 Foundry -79 Foundry -80 Mage Tower -81 Temple of the Damned -82 Blacksmith -83 Blacksmith -84 Oil Refinery -85 Oil Refinery -86 Oil Platform -87 Oil Platform -89 Keep -89 Stronghold -90 Castle -91 Fortress -92 Gold Mine -93 Oil Patch -96 Guard Tower (IE non upgraded, was like this originally) -97 Guard Tower (IE was already upgraded at start) -98 Cannon Tower -99 Cannon Tower -100 Circle of Power -101 Dark Portal -102 Runestone -103 Wall -104 Wall -105 Corpse -106 Flame -107 2x2 Rubble -108 3x3 Rubble -109 3x3 Rubble -110 Peasant with Lumber -111 Peon with Lumber -112 Peasant with Gold -113 Peon with Gold -114 Full Oil Tanker (A) -115 Full Oil Tanker (H) -116 Construction site part 1+2 -117 Construction site/Upgrading or Researching Building -118 Contruction (H) -Further values used for progressive construction graphics, but cba finding all. -Current Actions: 0=Not Existing, 1=dieing, 2=stop, 3=move, 4=Flying 5=patrol, 6=Catching up to follow 7=follow, 9=attack 12=Attacking during patrol, 13=stand ground, 14=Idle Tower, 17=Attack Ground 20=Demolish, 22=In construction, 23=harvest, 24=return goods, 27=repair, 28=going to build 30=Moving to coast, 32=Waiting on coast, 33=Idle building, 34=Going into Transport, 36=In transport, 37=Upgrading/Researching/Training, 38=Holy Vision, 39=Heal 41=Exorcism 42=Fire Shield, 43=Fireball, 44=Slow, 45=Invis, 46=Polymorph, 47=Blizzard, 48=Eye of Kilrog, 49=Bloodlust 50=Raise Dead, 51=Death Coil, 52=Whirlwind, 53=Haste, 54=Unholy Armour, 55=Runes, 56=DnD -Personal Info. 104-115. -Transport units: Six pairs of 2 bytes, for type/size? of unit. First byte: 87-Item number Second byte: -1=Empty, 1=1x1 unit, 2=2x2 unit? Repeat 6 times. -Mana Units: 105 functions as Mana Regenation timer -Peasants: 104-107 Go weird inside GM. 108 Chop Count for peasants/peons 109 88=Returning LM inside building, 90=Chopping, 120=with Lumber, lots of weird values. -Towers: 105 Upgrade Status 106 -Obviously more for other units, but don't care.]]-- while true do Start=0x011EBF8 Sz=0x9C MpSz=memory.readbyte(0x01031E) --Map size, each square treated as 1x1 XCa=memory.readwordsigned(0x1616D8) YCa=memory.readwordsigned(0x1616DC) Player=memory.readbyte(0x010328) keys = {} last_keys = {} clickhappen = false keys = input.get() emu.frameadvance() for i= 0,400,1 do XC=memory.readword(Start-i*Sz) YC=memory.readword(Start-i*Sz+2) Ex=memory.readbyte(Start-i*Sz+6) HP=memory.readbyte(Start-i*Sz+26) Ty=memory.readbyte(Start-i*Sz+29) Pl=memory.readbyte(Start-i*Sz+36) CC=memory.readbyte(Start-i*Sz+37) Xd=memory.readword(Start-i*Sz+140)*32 Yd=memory.readword(Start-i*Sz+142)*32 An=memory.readbyte(Start-i*Sz+38) Cx=XC-XCa Cy=YC-YCa Cxd=Xd-XCa Cyd=Yd-YCa Xm=XC/(MpSz*32)*63 --X minimap. Divide by total Map Size, then stretch to size of minimap, 63x63. Ym=YC/(MpSz*32)*63 --Y minimap. if Pl == 0 then PlC = 'red' --Player colours. elseif Pl == 1 then PlC = 'blue' elseif Pl == 2 then PlC = 'cyan' elseif Pl == 3 then PlC = 'purple' elseif Pl == 4 then PlC = 'orange' elseif Pl == 5 then PlC = 'red' --Player 5 is Black, but draw Red on map instead. elseif Pl == 6 then PlC = 'white' elseif Pl == 7 then PlC = 'orange' else PlC ='white' end if Ty < 4 then size = 15 --Trying to draw appropriate size boxes around stuff. elseif Ty < 6 then size = 31 --But their graphic size, and space occupancy on map don't neccesarily match. elseif Ty < 8 then size = 21 --EG Ogres classed as 1x1, yet graphic is nearly 2x2, so script elseif Ty == 8 then size = 17 --also needs some displacement on box for certain units. elseif Ty == 9 then size = 18 elseif Ty == 10 then size = 17 elseif Ty == 11 then size = 19 elseif Ty < 14 then size = 21 elseif Ty == 14 then size = 16 elseif Ty == 15 then size = 19 elseif Ty < 18 then size = 15 elseif Ty == 18 then size = 17 elseif Ty == 19 then size = 18 elseif Ty == 20 then size = 17 elseif Ty == 21 then size = 19 elseif Ty == 22 then size = 31 elseif Ty == 23 then size = 21 elseif Ty == 24 then size = 17 elseif Ty == 25 then size = 15 elseif Ty < 32 then size = 31 elseif Ty < 36 then size = 35 elseif Ty < 43 then size = 31 elseif Ty == 43 then size = 35 elseif Ty == 44 then size = 21 elseif Ty < 48 then size = 15 elseif Ty < 49 then size = 22 elseif Ty < 51 then size = 21 elseif Ty == 51 then size = 17 elseif Ty == 52 then size = 21 elseif Ty == 53 then size = 18 elseif Ty < 58 then size = 15 elseif Ty < 60 then size = 31 elseif Ty < 64 then size = 47 elseif Ty < 66 then size = 31 elseif Ty < 74 then size = 47 elseif Ty < 76 then size = 63 elseif Ty < 88 then size = 47 elseif Ty < 92 then size = 63 elseif Ty < 94 then size = 47 elseif Ty < 101 then size = 31 elseif Ty == 101 then size = 63 elseif Ty == 102 then size = 31 else size = 47 end if Ty < 4 then DV = 0 --Displacement Values, since not every graphic elseif Ty < 6 then DV = 8 --appears on the top left corner of the square. elseif Ty < 8 then DV = 3 --so need to shift it along a bit. elseif Ty == 8 then DV = 1 elseif Ty == 9 then DV = 2 elseif Ty == 10 then DV = 1 elseif Ty == 11 then DV = 2 elseif Ty < 14 then DV = 3 elseif Ty == 14 then DV = 1 elseif Ty == 15 then DV = 2 elseif Ty < 18 then DV = 0 elseif Ty == 18 then DV = 1 elseif Ty == 19 then DV = 2 elseif Ty == 20 then DV = 1 elseif Ty == 21 then DV = 2 elseif Ty == 22 then DV = 8 elseif Ty == 23 then DV = 3 elseif Ty == 24 then DV = 1 elseif Ty == 25 then DV = 0 elseif Ty < 32 then DV = 8 elseif Ty < 36 then DV = 10 elseif Ty < 42 then DV = 8 elseif Ty == 42 then DV = 8 elseif Ty == 43 then DV = 10 elseif Ty == 44 then DV = 3 elseif Ty < 48 then DV = 0 elseif Ty < 51 then DV = 3 elseif Ty == 51 then DV = 1 elseif Ty == 52 then DV = 3 elseif Ty == 53 then DV = 2 else DV = 0 end if (Pl ~= Player) and (An ~=0) then --Reveal non-player stuff only, and those which actually exist... gui.drawbox(Cx/2-DV, Cy/2-DV, Cx/2-DV+size, Cy/2-DV+size,white,PlC) --Lua equivalent size box is 16x16, thus need /2, then translate along by DV. gui.drawbox(17+Xm, 33+Ym, 18+Xm, 34+Ym, PlC) end if clickhappen == true then --Hmmm, have to do all calculations a 2nd time? Can't just reference previous ones? Stupid Lua stuff. gui.drawbox(230,20,275,65,'black','white') gui.text(233, 22, "Item: "..item,'white') gui.text(233, 32, "Type: "..memory.readbyte(Start-item*Sz+29) ,'white'); gui.text(233, 42, "HP: "..memory.readword(Start-item*Sz+26) ,'white'); gui.text(233, 52, "Action: "..memory.readbyte(Start-item*Sz+38) ,'white'); end if keys['leftclick'] and clickhappen == false then if keys.xmouse > Cx/2-DV and keys.ymouse > Cy/2-DV and keys.xmouse < Cx/2-DV+size and keys.ymouse < Cy/2-DV+size then clickhappen = true item = i end end last_keys = keys end end
But if you really want to know where stuff is on the map, just use the built in cheat 'nscrn', makes it a lot easier.