Finally, if you wish to play 2 player mode against this script, now you can.
-- D-Pad Hero 2 game play lua bot
-- created by CaitSith2.
--
-- Created to assist in making a 100% TAS of Expert D-Pad hero 2, which requires playing every song twice.
-- (once to hit all pow blocks, and once to skip all pow blocks.)
-- Push up on second controller to enable pow block collection
-- Push down on second controller to disable pow block collection.
-- Regardless of whether pow blocks are being collected or not,
-- 7 out of 8 challenges will be completed.
-- Stars and Slow down clocks are always skipped. :)
local function bubbleSort(table,table2)
--check to make sure the table has some items in it
if #table < 2 then
print("Table does not have enough data in it")
return
end
for i = 0, #table do --> array start to end
for j = 1, #table do
if table[j] < table[j-1] then -->switch
temp = table[j-1]
table[j-1] = table[j]
table[j] = temp
temp = table2[j-1]
table2[j-1] = table2[j]
table2[j] = temp
end
end
end
return
end
local h2 = {[0]= 0,0,0,0,0,0,0,0 }
local h3 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
local h4 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
local h5 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
local h6 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
local h7 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
local frames = 0
local seconds = 0
local minutes = 0
local hours = 0
local function displayer(skippow)
y = {[0]= 0x51C, 0x522, 0x528, 0x52E, 0x534, 0x53A, 0x540, 0x546, 0x54C, 0x552, 0x558, 0x55E, 0x564, 0x56A, 0x570, 0x576, 0x57C, 0x582, 0x588, 0x58E, 0x594, 0x59A, 0x5A0, 0x5A6, 0x5AC, 0x5B2, 0x5B8, 0x5BE}
t = {[0]= 0x51B, 0x521, 0x527, 0x52D, 0x533, 0x539, 0x53F, 0x545, 0x54B, 0x551, 0x557, 0x55D, 0x563, 0x569, 0x56F, 0x575, 0x57B, 0x581, 0x587, 0x58D, 0x593, 0x599, 0x59F, 0x5A5, 0x5AB, 0x5B1, 0x5B7, 0x5BD}
q = {[0]= "<", ">", "s", "B", "A","","","" }
r = {[0]= "points","skull","pow block","star","clock","letter","fake skull","","","","","","","",""}
s = {[0]= true, false, false, false, false, true, true, false, false, false, false, false, false}
if skippow == 0 then
s[2] = true
s[5] = false
s[6] = false
else
s[2] = false
s[5] = true
s[6] = true
end
h = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
h1 = {[0]= 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
local hyperspeed = memory.readbyte(0x0302)
minhs = { [0]= 204,203,201,200,200,199,199,198 }
maxhs = { [0]= 204,204,202,202,202,202,202,202 }
for i=0,27,1 do
h[i] = memory.readbyte(y[i])
h1[i] = memory.readbyte(t[i])
if ( h1[i] > 0x3F ) then h[i] = 255 end
if ( h[i] == 0 ) then h[i] = 255 end
if ( h[i] > 214 ) then h[i] = 255 end
--if memory.readbyte(y[i])==174 then v[i]=1 r=i end
end
bubbleSort(h,h1)
local l=0
local m=0
local n= { }
n.A = nil
n.B = nil
n.select = nil
n.right = nil
n.left = nil
for i=0,27,1 do
l = (h1[i]-(h1[i]%8))/8
m = h1[i]%8
if (h[i] >= minhs[hyperspeed]) and (h[i] <= maxhs[hyperspeed]) then
if ( l ~= 1 ) and ( l ~= 3 ) and ( l ~= 4 ) and ( ( ( skippow == 1 ) and ( l ~= 2 ) ) or (( skippow == 0 ) and ( l ~= 5 ) and ( l ~= 6 )) ) then
h2[m] = h2[m] + 1
if m == 0 then n.left = 1
elseif m == 1 then n.right = 1
elseif m == 2 then n.select = 1
elseif m == 3 then n.B = 1
else n.A = 1 end
-- Detect a 2 player mode, and control the first player in its own lanes.
if memory.readbyte(0x00B2) == 3 then n.left = nil end
if memory.readbyte(0x00B3) == 3 then n.right = nil end
if memory.readbyte(0x00B4) == 3 then n.select = nil end
if memory.readbyte(0x00B5) == 3 then n.B = nil end
if memory.readbyte(0x00B6) == 3 then n.A = nil end
end
if m == 0 then h3[l] = h3[l] + 1
elseif m == 1 then h4[l] = h4[l] + 1
elseif m == 2 then h5[l] = h5[l] + 1
elseif m == 3 then h6[l] = h6[l] + 1
else h7[l] = h7[l] + 1 end
end
end
FCEU.frameadvance()
frames = frames + 1
if frames == 60 then
frames = 0
seconds = seconds + 1
if seconds == 60 then
seconds = 0
minutes = minutes + 1
if minutes == 60 then
minutes = 0
hours = hours + 1
end
end
end
joypad.set(1, n)
gui.text(10,10+8*1,"Endured the unbeatable computer for: " .. hours .. ":" .. minutes .. ":" .. seconds .. "." .. frames)
--gui.text(10,10+8*1,hours .. ":" .. minutes .. ":" .. seconds .. "." .. frames)
if false then
for k=0,4,1 do
gui.text(10,10+8*k,q[k] .. ": " .. h2[k])
end
end
if false then
for k=0,6,1 do
if s[k] then
gui.text(10,10+8*(k+1),"HIT: " .. r[k] .. ": " .. h3[k] .. ", " .. h4[k] .. ", " .. h5[k] .. ", " .. h6[k] .. ", " .. h7[k])
else
gui.text(10,10+8*(k+1),"MISS: " .. r[k] .. ": " .. h3[k] .. ", " .. h4[k] .. ", " .. h5[k] .. ", " .. h6[k] .. ", " .. h7[k])
end
end
end
if false then
for k=0,27,1 do
if h[k] > 240 then
gui.text(10,10+8*k,"") break
else
gui.text(10,10+8*k,h[k] .. ": " .. r[(h1[k]-(h1[k]%8))/8] .. " on " .. q[h1[k]%8])
end
end
end
end
local buttons = { }
local temp = savestate.create(5)
local temp2 = savestate.create(7)
local clockavoid = savestate.create(6)
local endofsong = savestate.create(2)
savestate.save(temp)
local health=0
local lasthealth=0
local loop=0
local anythingtohit=0
local lastanything=0
local powerhit=0
local powerhitzero=0
local lastpowerhit=0
local powblockhit=0
local rendertext=0
local zerotolerance=1
local maxtolerance=0x0B
while true do
FCEU.speedmode("normal")
-- Loop while game play highway is NOT active. Allow normal user input.
while (memory.readbyte(0x0318) == 0) or (memory.readbyte(0x0319) == 0) do
FCEU.frameadvance()
if rendertext > 0 then
rendertext = rendertext - 1
if rendertext == 0 then gui.text(16,16,"") end
end
if(joypad.read(2).up) then
zerotolerance = 0
gui.text(16,16,"Pow blocks will be hit");
rendertext=60
end
if(joypad.read(2).down) then
zerotolerance = 1
gui.text(16,16,"Pow blocks will be skipped");
rendertext=60
end
end
for i=0,6,1 do
h2[i] = 0
h3[i] = 0
h4[i] = 0
h5[i] = 0
h6[i] = 0
h7[i] = 0
end
frames=0
seconds=0
minutes=0
hours=0
--End of no highway loop.
--Set speed to maximum. Loop while the highway is in view, and song has not
--yet ended.
--FCEU.speedmode("nothrottle")
while (memory.readbyte(0x0318) > 0) and (memory.readbyte(0x0319) > 0) do
displayer(zerotolerance)
--FCEU.frameadvance()
end
if (memory.readbyte(0x0318) == 0) then
gui.text(10,10+8*1,"Computer player died. How did that happen?")
end
--End of song.
-- And wait for a new song to start, accepting normal input again.
end
-- We should never reach here. :)
I did at least implement a timer to show how long you lasted against the computer in hours:minutes:seconds.frames format.)
EDIT: Scripted computer is now truely unbeatable. hyperspeed has been figured out, and computer no longer messes up, when hyperspeed gets a bit too fast.