Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- LOTO ROUTER
- -- warning: overwrites savestate 5 ("searchsave" below).
- --
- -- this program finds crit routes for axe knight battles in Dragon Warrior.
- --
- -- loads a prepared save state ("startsave") and then buffers "Command?"
- -- prompts using B some number of times until attacking gives useful crits. it
- -- assumes the battle is set up so that you get to attack first. the tactic is
- -- to crit high, tank a hit, and then crit again, because buffering "sleep"
- -- is too hard and would require L7 which is harder to manipulate.
- -- startsave is a savestate on the swamp tile left of the axe knight.
- -- for the battle to sync consistently, the savestate should either have the
- -- hero moving right onto the axe knight tile, or be in the 16-frame
- -- "hesitation" window after releasing right.
- startsave = savestate.object(4) -- save slot 4
- -- searchsave is a scratch save slot used to search for the next crit buffer.
- searchsave = savestate.object(5) -- save slot 5
- -- the maximum crit for whatever level you are attempting this insanity at.
- -- this is set for level 6 with a broad sword. (no, really, level 6.)
- maxcrit = 36
- -- joypad state to set before waiting
- jp = {}
- -- wait for n frames while pushing some buttons
- function waitframes(n)
- for i=1,n do
- joypad.set(1, jp)
- emu.frameadvance()
- end
- end
- -- detects a critical hit.
- crit = false
- function detectcrit()
- crit = true
- end
- memory.registerexecute(0xe628, detectcrit)
- -- ok, here we go.
- savestate.load(startsave)
- emu.speedmode("turbo")
- -- walk right onto battle tile
- jp.right = true
- waitframes(32)
- jp.right = false
- -- wait for battle menu to load and poll joypad
- jp.B = true
- while emu.lagged() do
- waitframes(1)
- end
- emu.print(string.format("in battle. [%d hp]", memory.readbyte(0xe2)))
- -- set to true if the battle is won.
- won = false
- -- count of how many times you've buffered in the current turn.
- buffers = 0
- -- the overall buffer route.
- route = {}
- while true do
- -- figure out what to do this turn.
- repeat
- -- savestate and then attack.
- savestate.save(searchsave)
- emu.print(string.format("attack after %d", buffers))
- jp.A = true
- waitframes(16)
- -- wait and see how it went.
- crit = false
- waitframes(200)
- if memory.readbyte(0xc5) == 0 then
- -- thou art dead.
- emu.print("... cod")
- elseif memory.readbytesigned(0xe2) <= 0 then
- -- we got him!
- emu.print("... rekt!")
- table.insert(route, buffers)
- won = true
- do break end
- elseif memory.readbyte(0xdf) >= 0x80 then
- -- thou art asleep.
- emu.print("... zzz")
- elseif crit == true then
- -- we got a crit, awesome.
- if memory.readbyte(0xe2) <= maxcrit then
- -- the axe knight has less hp left than our max crit, so we can kill it
- -- next turn. let's keep this one.
- emu.print(string.format("good crit@%d. [%d hp]", buffers, memory.readbyte(0xe2)))
- table.insert(route, buffers)
- buffers = 0
- -- rewind to the point of the savestate and commit it.
- savestate.load(searchsave)
- jp.A = true
- waitframes(16)
- -- loop until the menu starts polling again.
- jp.A = false
- jp.B = true
- while emu.lagged() do
- waitframes(1)
- end
- -- next turn.
- do break end
- else
- -- assume this crit is not going to cut it.
- emu.print(string.format("weak crit@%d. [%d hp]", buffers, memory.readbyte(0xe2)))
- end
- else
- -- either this was a miss or a weak hit.
- emu.print("... meh")
- end
- -- not a good attack. buffer another "command" window.
- savestate.load(searchsave)
- jp.A = false
- jp.B = true
- waitframes(16)
- while emu.lagged() do
- waitframes(1)
- end
- buffers = buffers + 1
- until true
- -- lua is totally awesome.
- if won then break end
- end
- -- print out the route
- emu.print("courage and wit have served thee well")
- for i,v in ipairs(route) do
- emu.print(string.format("- turn %d: buffer %d", i, v))
- end
- emu.speedmode("normal")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement