Revision (current)
Last Updated by feos on 7/30/2016 6:36 PM
!! Positioning
Y subpixels roll "randomly" every frame, like in Duck Tales and Chip'n'Dale.
!! Randomness
Addresses {{$E4-$E7}} get RORed every gameplay frame, and sometimes additional small manipulations are done with either {{$E4-$E5}} or {{$E6-$E7}} whenever random even is about to occur (item drops from dying enemies, bosses actions).
End values can be affected by killing enemies at different frames, by spawning enemies that roll RNG at different frames.
!! Bosses
Each boss has his own randomness (if any) and can't be manipulated during the fight. But they roll their RNG routines at fixed time relatively to boss room start, so by entering it at different frames one should be able to manipulate the pattern the boss will take during the whole fight.
! The Liquidator
He moves around the screen, then whenever he reaches position 0x40, 0x80, or 0xC0, he rolls RNGs 3 and 4, puts to Y register, reads from {{$9F6F}} + Y register what he should do: show up or resume swimming.
! QuackerJack
Runs around a platform until you step on it, the next frame jumps up or down from it. If he is at the top, he will jump down, if at the bottom, he will jump up, but if he is in the middle, he rolls RNGs 1 and 2, puts to Y register, then reads from {{$9969}} + Y register for whether he should jump up or down.
! Wolfduck
Is vulnerable only when the Moon is covered with a cloud, which travels by the rule: when the room fades in, the cloud is covering the Moon, and the timer ticks from 78 to 0 every frame, then the cloud starts moving left around the screen. When it reaches the Moon again, it counts down from 0xB4 to 0 and starts moving again.
! Megavolt
Jumps on a middle platform, rolls RNGs 3 and 4, puts result to Y register, reads from {{$AA69}} + Y register for whether he should jump up or stay on the platform. Then shoots from the platform he's on and walks off to cross the screen and jump on the other middle platform, to roll RNG once again.
! Moliarty
Starts fixing whichever machine gets broken. Walks around the platform until you touch it, then he throws a hammer in you and jumps away. His behavior doesn't really matter, since even with default gun he dies in one cycle.
! Bushroot
At certain moments, while jumping, {{$049F}} decrements from 7 to 0. If Bushroot is jumping when that address is 6, 4, or 2, he will roll RNGs 1 and 2, write the result to Y register, then read from {{$A83F}} for what he should do next.
! Steelbeak
His behavior also doesn't matter, since bullets can reach him from the back after going through him.
!! Script
function getb(i,offset)
return memory.readbyte(i+offset)
end
function getw(i,offset)
return memory.readword(i+offset,i+offset+0x10)
end
function object(slot)
a = 0x400 + slot
facing = getb(a,0x000)
timer1 = getb(a,0x010)
state = getb(a,0x020)
timer2 = getb(a,0x030)
yScr = getb(a,0x040)
xScr = getb(a,0x050)
ySub = getb(a,0x060)
xSub = getb(a,0x070)
timer3 = getb(a,0x080)
action = getb(a,0x0d0)
xPos = getw(a,0x0f0)
yPos = getw(a,0x110)
xVelSub = getb(a,0x130)
xVel = getb(a,0x140)
yVelSub = getb(a,0x150)/256
yVel = memory.readbytesigned(a+0x160)
id = getb(a,0x170)
if yVel >= 0
then ySpd = yVel + yVelSub
else ySpd = yVel - yVelSub
end
if action > 0 then
--gui.text(xScr,yScr,string.format("%X",state'''')'''''''')''''
gui.text( 1,1,string.format(
"X: %04d.%d\nY: %04d.%03d\nS: %.3f",
xPos,xSub/25.6,yPos,ySub,ySpd'''')'''''''')''''
end
end
function rng()
rng1 = memory.readbyte(0xe4)
rng2 = memory.readbyte(0xe5)
rng3 = memory.readbyte(0xe6)
rng4 = memory.readbyte(0xe7)
gui.text(10,10,string.format("%02X:%02X:%02X:%02X",rng1,rng2,rng3,rng4'''')'''''''')''''
end
function stuff()
xCam = memory.readword(0xfc)
yCam = memory.readword(0xfa)
bossInv = memory.readbyte(0xed)
bossHP = memory.readbyte(0xee)
bossSlot = memory.readbyte(0xef)
bossX = memory.readbyte(0x450+bossSlot)
bossY = memory.readbyte(0x440+bossSlot)
if bossHP > 0 then
gui.text(bossX,bossY,string.format("%d\n%d",16-bossHP,bossInv'''')'''''''')''''
end
--rng()
object(0)
gui.text(xScr,yScr,memory.readbyte(0x50'''')'''''''')''''
end
emu.registerafter(stuff)