User File #58692469321661997

Upload All User Files

#58692469321661997 - RNG script

pokemonGen3RNG.lua
1767 downloads
Uploaded 10/18/2019 5:09 AM by FractalFusion (see all 87)
A Lua script to analyze RNG in Gen 3 Pokemon
local game=5 --see below
local startvalue=0x153 --insert the first value of RNG

-- These are all the possible key names: [keys]
-- backspace, tab, enter, shift, control, alt, pause, capslock, escape,
-- space, pageup, pagedown, end, home, left, up, right, down, insert, delete,
-- 0 .. 9, A .. Z, numpad0 .. numpad9, numpad*, numpad+, numpad-, numpad., numpad/,
-- F1 .. F24, numlock, scrolllock, semicolon, plus, comma, minus, period, slash, tilde,
-- leftbracket, backslash, rightbracket, quote.
-- [/keys]
-- Key names must be in quotes.
-- Key names are case sensitive.
local key={"9", "8", "7"}

-- It is not necessary to change anything beyond this point.

--for different display modes
local status=2
local substatus={1,1,1}

local tabl={}
local prev={}

local xfix=0 --x position of display handle
local yfix=100 --y position of display handle

local xfix2=300 --x position of 2nd handle
local yfix2=0 --y position of 2nd handle

local k 


--for different game versions
--1: Ruby/Sapphire U
--2: Emerald U
--3: FireRed/LeafGreen U
--4: Ruby/Sapphire J
--5: Emerald J (TODO)
--6: FireRed/LeafGreen J (1360)

local gamename={"Ruby/Sapphire U", "Emerald U", "FireRed/LeafGreen U", "Ruby/Sapphire J", "Emerald J", "FireRed/LeafGreen J (1360)"}

--game dependent

local pstats={0x3004360, 0x20244EC, 0x2024284, 0x3004290, 0x2024190, 0x20241E4}
local estats={0x30045C0, 0x2024744, 0x202402C, 0x30044F0, 0x20243E8, 0x2023F8C}
local rng   ={0x3004818, 0x3005D80, 0x3005000, 0x3004748, 0x3005AE0, 0x3005040} --0X3004FA0
local rng2  ={0x0000000, 0x0000000, 0x20386D0, 0x0000000, 0x0000000, 0x203861C}

local enemynum=0x2023d14

--HP, Atk, Def, Spd, SpAtk, SpDef
local statcolor = {"yellow", "red", "blue", "green", "magenta", "cyan"}

local multspa={
 0x41C64E6D, 0xC2A29A69, 0xEE067F11, 0xCFDDDF21,
 0x5F748241, 0x8B2E1481, 0x76006901, 0x1711D201,
 0xBE67A401, 0xDDDF4801, 0x3FFE9001, 0x90FD2001,
 0x65FA4001, 0xDBF48001, 0xF7E90001, 0xEFD20001,
 0xDFA40001, 0xBF480001, 0x7E900001, 0xFD200001,
 0xFA400001, 0xF4800001, 0xE9000001, 0xD2000001,
 0xA4000001, 0x48000001, 0x90000001, 0x20000001,
 0x40000001, 0x80000001, 0x00000001, 0x00000001}

local multspb={
 0x00006073, 0xE97E7B6A, 0x31B0DDE4, 0x67DBB608,
 0xCBA72510, 0x1D29AE20, 0xBA84EC40, 0x79F01880,
 0x08793100, 0x6B566200, 0x803CC400, 0xA6B98800,
 0xE6731000, 0x30E62000, 0xF1CC4000, 0x23988000,
 0x47310000, 0x8E620000, 0x1CC40000, 0x39880000,
 0x73100000, 0xE6200000, 0xCC400000, 0x98800000,
 0x31000000, 0x62000000, 0xC4000000, 0x88000000,
 0x10000000, 0x20000000, 0x40000000, 0x80000000}

dofile "tables.lua"

local flag=0
local last=0
local cur=0
local counter=0

local bnd,br,bxr=bit.band,bit.bor,bit.bxor
local rshift, lshift=bit.rshift, bit.lshift

memory.usememorydomain("System Bus")
local mdword=memory.read_u32_le
local mword=memory.read_u16_le
local mbyte=memory.read_u8

--a 32-bit, b bit position bottom, d size
function getbits(a,b,d)
 return rshift(a,b)%lshift(1,d)
end

--for RNG purposes
function gettop(a)
 return(rshift(a,16))
end

--does 32-bit multiplication
--necessary because Lua does not allow 32-bit integer definitions
--so one cannot do 32-bit arithmetic
--furthermore, precision loss occurs at around 10^10
--so numbers must be broken into parts
--may be improved using bitop library exclusively
function mult32(a,b)
 local c=rshift(a,16)
 local d=a%0x10000
 local e=rshift(b,16)
 local f=b%0x10000
 local g=(c*f+d*e)%0x10000
 local h=d*f
 local i=(g*0x10000+h)%0x100000000
 return i
end

--checksum stuff; add halves
function ah(a)
 b=getbits(a,0,16)
 c=getbits(a,16,16)
 return b+c
end



function update()
   last=mdword(rng[game])
end



event.onloadstate(update, "update")

--a press is when input is registered on one frame but not on the previous
--that's why the previous input is used as well

update()
function fn()
--*********
 
    i=0
    cur=mdword(rng[game])
    test=last
    while cur~=test and i<=100 do
     test=(mult32(test,0x41C64E6D) + 0x6073)%0x100000000
	 gui.text(16+48*(math.floor(i/10)),48+16*(i%10),bizstring.hex(math.floor(test/65536)))
     i=i+1

	 

	 
    end
    gui.text(16,0,"Cur: "..bizstring.hex(cur))
	gui.text(180,0,"Last: "..bizstring.hex(last))
	last=cur
    if i<=100 then
     gui.text(16,16,"CycDiff: "..i)
    else
     gui.text(16,16,"CycDiff: >100")
    end
    

    
    
    --math
    indexfind=startvalue
    index=0
    for j=0,31,1 do
     if getbits(cur,j,1)~=getbits(indexfind,j,1) then
      indexfind=mult32(indexfind,multspa[j+1])+multspb[j+1]
      index=index+bit.lshift(1,j)
      if j==31 then
       index=index+0x100000000
      end
     end
    end
    gui.text(180,16,"Cycle#: "..index)
	


    --start=pstats[game]
    start=estats[game]+100*(0)
	xfix=200

    personality=mdword(start)
    trainerid=mdword(start+4)
    magicword=bxr(personality, trainerid)
	
    i=personality%24
	

	miscoffset=(misctbl[i+1]-1)*12

    misc1=bxr(mdword(start+32+miscoffset),magicword)
	misc2=bxr(mdword(start+32+miscoffset+4),magicword)


    ivs=misc2
	
	
	gui.text(16,240,"PID: "..bizstring.hex(personality))
	gui.text(16,256,"IVs: "..bizstring.hex(ivs))
	gui.text(16,272,"Misc1: "..bizstring.hex(misc1))

   
    
--*********
end

while true do
fn()
emu.frameadvance()
end

--event.onframeend(fn)