User File #21477503642485906

Upload All User Files

#21477503642485906 - GBA - Dungeons & Dragons: Eye of the Beholder - Dice roll prediction script

EotB_RNG_v1.lua
694 downloads
Uploaded 3/17/2015 5:27 AM by FatRatKnight (see all 245)
For BizHawk. Geez, those forms work slow. I recommend pausing the script when you want to use turbo mode.
Currently predicts d4, d6, d8, d10, d12, and d20 rolls. It gives some pride that I can't detect errors with its predictions, but on the other hand, this could also mean my error detection might need work. Regardless, I think I know all the dice rolls in the future!
It spawns a single window with a list of numbers. Each column reports dice of different sides, with the top numbers being the immediate next result. Anyone here fluent in object properties and can tell me how to right-justify the labels?
--Time to fabricate the most complex script ever!
--(If you don't count the more complex ones...)

local R1u= memory.read_u8
local R2u= memory.read_u16_le
local R4u= memory.read_u32_le
memory.usememorydomain("BUS")

local R1, R2= 0, 0
local c1, c2= 0, 0

--*****************************************************************************
local function Roll1(R) --0x0000LLLL * 0x00004650 + 0x0000HHHH
--*****************************************************************************
    return bit.band(R,0xFFFF)*0x4650 + bit.rshift(R,16)
end
--*****************************************************************************
local function Roll2(R) --0x0000LLLL * 0x000078B7 + 0x0000HHHH
--*****************************************************************************
    return bit.band(R,0xFFFF)*0x78B7 + bit.rshift(R,16)
end

--*****************************************************************************
local function ResetRNG()
--*****************************************************************************
    R1,R2,c1,c2= R4u(0x03004D5C),R4u(0x03004D60),0,0
end
--ResetRNG()

--*****************************************************************************
local function Dice(count,sides,r1,r2)
--*****************************************************************************
-- Useful for knowing, say... 3d6 or something.

    local v= count
    for i= 1, count do
        r1,r2= Roll1(r1),Roll2(r2)
        v= v+(bit.band(0xFFFF,r1)*16+bit.band(0xFFFF,r2))%sides
    end
    return v
end

--*****************************************************************************
local function DiceOneRoll(sides,r1,r2)
--*****************************************************************************
--Unlike Dice(1,sides,r1,r2), uses the immediate RNG instead of the next RNG.
--Keep this in mind, yo!

    return 1 + (                -- Example standard dice go 1~20, not 0~19
       bit.band(0xFFFF,r1)*16   -- First RNG is shifted 4 bits for some reason
      +bit.band(0xFFFF,r2)      -- As such, d4 and d8 only uses this one.
     )%sides                    -- Crop to within dice range, of course.
end

local Sides= {4,6,8,10,12,20}
local ListLength= 30

--Generate form
-------------------------------------------------------------------------------
local RNGForm= forms.newform(20+#Sides*30,54+ListLength*16,"RNG Table")
-------------------------------------------------------------------------------
local DiceTable= {}
for c= 1, ListLength do
    DiceTable[c]= {}
    for s= 1, #Sides do
        DiceTable[c][s]= forms.label(RNGForm,tostring(Sides[s]),(s-1)*30,(c-1)*16,29,15)
    end
end

--*****************************************************************************
local function UpdateRNGForm()
--*****************************************************************************
--This function is SLOW! I blame the forms coding.
--Ensures that form always has the latest in RNG information.
--Returns immediately if the script-storage matches the game's RNG state.

    local r1,r2= R4u(0x03004D5C),R4u(0x03004D60)
    if (r1 == R1) and (r2 == R2) then return end
    R1,R2= r1,r2

    for c= 1, #DiceTable do
        r1,r2= Roll1(r1),Roll2(r2)
        for s= 1, #Sides do
            forms.settext(DiceTable[c][s],tostring(DiceOneRoll(Sides[s],r1,r2)))
        end
    end
end

--forms.destroyall()

--[[
local StatusForm= forms.newform(800,600,"Party Status")

local AbilityScores= {}
for i= 0, 5 do
    AbilityScores[i]= forms.textbox(StatusForm,"n",50,20,nil,10,25*i)
end
]]--

--[[
03004D5C,4x - RNG1
03004D60,4x - RNG2

0x0000LLLL * 0x00004650 + 0x0000HHHH = New RNG1
0x0000LLLL * 0x000078B7 + 0x0000HHHH = New RNG2
]]--


--*****************************************************************************
local function CountRNG()
--*****************************************************************************
    local pass= false
    local r= R4u(0x03004D5C)
    for i= 0, 2000 do
        if R1 == r then  c1= c1+i;  pass= true;  break  end
        R1= Roll1(R1)
    end
    if not pass then R1= r; c1= 0 end

    pass= false
    r= R4u(0x03004D60)
    for i= 0, 2000 do
        if R2 == r then  c2= c2+i;  pass=true;  break  end
        R2= Roll2(R2)
    end
    if not pass then R2= r; c2= 0 end

    gui.drawBox(0,50,63,120,0xFF000000,0xFF000000)
    gui.drawText(0, 50,string.format("%8X",R1))
    gui.drawText(0, 60,string.format("%8X",Roll1(R1)))
    gui.drawText(0, 70,string.format("%8d",c1))
    gui.drawText(0, 85,string.format("%8X",R2))
    gui.drawText(0, 95,string.format("%8X",Roll2(R2)))
    gui.drawText(0,105,string.format("%8d",c2))
end
--event.onframeend(Fn)

--*****************************************************************************
while true do
--*****************************************************************************
--    gui.drawText(5, 5, "Rather lovely long text.",0xFF000000,12)
--    gui.text(50, 50, "Rather lovely long text.")
--    gui.drawBox(15,15,80,80)
--    Fn()
    UpdateRNGForm()
    emu.frameadvance()
end

--forms.textbox(
--  formHandle,
--  caption,
--  width,
--  height,
--  boxtype, (?)
--  x,
--  y,
--  multiline,
--  fixedWidth
--)