+ Reply to Thread
Results 1 to 11 of 11

Thread: Pokemon B/W Lua scripts

  1. #1

    Pokemon B/W Lua scripts

    5th Gen RNG Suite



    it displays stuff for copypasting in the console window!
    Code:
    -- General Parameters for current game and setup (english)
    local game=0				-- 0 for white, 1 for black
    local rng=0x02216244-0x20*game		-- PRNG Seed Location
    local mtrng=0x02215374-0x20*game	-- Mersenne Twister Table Top
    local mac=0x123456			-- MAC Address of Emulator
    local pos_m=0x0224F92C-0x20*game	-- Map Position -> XYZ
    local storage=0x02000200
    local trackcgear=0 				-- 0 on, 1 off; disable for Standard Abuse, enable for Entralink Abuse
    local research=0 				-- 0 on, 1 off; only enable for dev features (unneeded)
    
    -- Setup Terminology abbreviations; from FractalFusion
    local bnd,br,bxr=bit.band,bit.bor,bit.bxor
    local rshift, lshift=bit.rshift, bit.lshift
    local mdword=memory.readdwordunsigned
    local mword=memory.readwordunsigned
    local mbyte=memory.readbyteunsigned
    local wdword=memory.writedword
    
    -- Setup initial variables, rest of script detection will take care of them
    local initl=0
    local inith=0
    local initm=0
    local adv=0
    local jump1=0
    local jump2=0
    local jump3=0
    local jump4=0
    local jump5=0
    local jump6=0
    local jump7=0
    local jump8=0
    local jump9=0
    local jump10=0
    local jump11=0
    local jump12=0
    local jump13=0
    local jump14=0
    local jump15=0
    local jump16=0
    local jump17=0
    local jump18=0
    local jump19=0
    local jump20=0
    local total=0
    local last=0
    local lastm=0
    local lmtp=0
    local steptable=0
    local mtf=0
    local mttrack=0
    local nextmt=0
    local second=0
    local minute=0
    local hour=0
    local cgearoff=0
    local cachevalue=0
    local notrestored=0
    local wasrestored=0
    
    -- S frame detection function; works off of seeing how many times the lower half was advanced
    -- Lua sucks and only allows 16 bit multiplication, so 32 bit multiplication can't be used
    -- The lower seed is advanced as follows, if observed as a standalone 32 bit number:
    -- SEED1 = (0x6C078965 * SEED1) + 0x00269EC3; from Kazo
    function next(s)
    local a=0x6C07*(s%65536)+rshift(s,16)*0x8965
    local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3
    local c=b%4294967296
    return c
    end
    
    -- To predict Mersenne advancement, it's a little harder. Copied and adapted pre-existing Lua
    -- http://code.google.com/p/gocha-tas/source/browse/trunk/Scripts/mt19937.lua?r=117
    -- Mersenne Twister: A random number generator
    -- ported to Lua by gocha, based on mt19937ar.c
    module("mt19937", package.seeall)
    
    require "bit"
    
    -- Period parameters
    local N = 624
    local M = 397
    local MATRIX_A = 0x9908b0df   -- constant vector a
    local UPPER_MASK = 0x80000000 -- most significant w-r bits
    local LOWER_MASK = 0x7fffffff -- least significant r bits
    
    local mt = {}     -- the array for the state vector
    local mti = N + 1 -- mti==N+1 means mt[N] is not initialized
    
    -- initializes mt[N] with a seed
    function randomseed(s)
        s = bit.band(s, 0xffffffff)
        mt[1] = s
        for i = 1, N - 1 do
            -- s = 1812433253 * (bit.bxor(s, bit.rshift(s, 30))) + i
            s = bit.bxor(s, bit.rshift(s, 30))
            local s_lo = bit.band(s, 0xffff)
            local s_hi = bit.rshift(s, 16)
            local s_lo2 = bit.band(1812433253 * s_lo, 0xffffffff)
            local s_hi2 = bit.band(1812433253 * s_hi, 0xffff)
            s = bit.bor(bit.lshift(bit.rshift(s_lo2, 16) + s_hi2, 16),
                bit.band(s_lo2, 0xffff))
            -- s = bit.band(s + i, 0xffffffff)
            local s_lim = -bit.tobit(s)
            -- assumes i<2^31
            if (s_lim > 0 and s_lim <= i) then
                s = i - s_lim
            else
                s = s + i
            end
            mt[i+1] = s
            -- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
            -- In the previous versions, MSBs of the seed affect
            -- only MSBs of the array mt[].
            -- 2002/01/09 modified by Makoto Matsumoto
        end
        mti = N
    end
    
    local mag01 = { 0, MATRIX_A }   -- mag01[x] = x * MATRIX_A  for x=0,1
    
    -- generates a random number on [0,0xffffffff]-interval
    function random_int32()
        local y
    
        if (mti >= N) then -- generate N words at one time
            local kk
    
            if (mti == N + 1) then -- if init_genrand() has not been called,
                mt19937.randomseed(5489) -- a default initial seed is used
            end
    
            for kk = 1, N - M do
                y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK))
                mt[kk] = bit.bxor(mt[kk+M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
            end
            for kk = N - M + 1, N - 1 do
                y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK))
                mt[kk] = bit.bxor(mt[kk+(M-N)], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
            end
            y = bit.bor(bit.band(mt[N], UPPER_MASK), bit.band(mt[1], LOWER_MASK))
            mt[N] = bit.bxor(mt[M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
    
            mti = 0
        end
    
        y = mt[mti+1]
        mti = mti + 1
    
    
    
        return y
    end
    
    function random(...)
        -- local r = mt19937.random_int32() * (1.0/4294967296.0)
        local rtemp = mt19937.random_int32()
        local r = (bit.band(rtemp, 0x7fffffff) * (1.0/4294967296.0)) + (bit.tobit(rtemp) < 0 and 0.5 or 0)
        local arg = {...}
        if #arg == 0 then
            return r
        elseif #arg == 1 then
            local u = math.floor(arg[1])
            if 1 <= u then
                return math.floor(r*u)+1
            else
                error("bad argument #1 to 'random' (internal is empty)")
            end
        elseif #arg == 2 then
            local l, u = math.floor(arg[1]), math.floor(arg[2])
            if l <= u then
                return math.floor((r*(u-l+1))+l)
            else
                error("bad argument #2 to 'random' (internal is empty)")
            end
        else
            error("wrong number of arguments")
        end
    end
    
    -- Lua script begin!
    while true do
    wdword(storage,1)
    -- setup every loop
    	seed2=mdword(rng+4)
    	seed1=mdword(rng)
    	adv=0
    	test=last
    	mtv=mdword(mtrng)
    	mtp=mdword(mtrng+0x9C0)
    	delay=mdword(0x02FFFC3C)
    	timehex=mdword(0x023FFDEC)
    	datehex=mdword(0x023FFDE8)
    	hour=string.format("%02X",(timehex%0x100)%0x40)				-- memory stores as decimal, but Lua reads as hex. Convert.
    	minute=string.format("%02X",(rshift(timehex%0x10000,8)))
    	second=string.format("%02X",(mbyte(0x02FFFDEE)))
    	year=string.format("%02X",(mbyte(0x02FFFDE8)))
    	month=string.format("%02X",(mbyte(0x02FFFDE9)))
    	day=string.format("%02X",(mbyte(0x02FFFDEA)))
    	
    -- display seeds every loop
    	gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1))
    	gui.text(1,180,string.format("Initial: %08X%08X",inith,initl))
    	gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", mword(pos_m), mword(pos_m+0x6), mword(pos_m+0xE), mword(pos_m+0xA)))
    
    	-- Check to see if the RNG advanced from the last value
    	while seed1~=0 and seed2~=0 and delay > 2 do
    		if adv>200 then -- RNG advanced a bunch, or the game/script was reset. Reset variables then stop loop.
    			steptable=0
    			adv  =0
    			jump1=0
    			jump2=0
    			jump3=0
    			jump4=0
    			jump5=0
    			jump6=0
    			jump7=0
    			jump8=0
    			jump9=0
    			jump10=0
    			jump11=0
    			jump12=0
    			jump13=0
    			jump14=0
    			jump15=0
    			jump16=0
    			jump17=0
    			jump18=0
    			jump19=0
    			jump20=0
    			if mdword(storage)==1 and delay>3 and mdword(storage+0x4*2)~=0 then
    				print(""..string.format("Restoring session. Please Wait..."))
    				steptable=mdword(storage+0x4*1)				-- restore mt
    				initm=mdword(storage+0x4*2)
    				lastm=mdword(storage+0x4*7)
    				randomseed(initm)
    				i=624*steptable+1
    				while i>0 do								-- restore internal mt frame
    						nextmt=math.floor(random_int32())
    						i=i-1	
    				end
    				
    				mttrack=1									-- turn on tracking
    				
    				inith=mdword(storage+0x4*4)					-- restore PRNG
    				initl=mdword(storage+0x4*3)
    
    				cacheseed=mdword(storage+0x4*5)
    				cachevalue=mdword(storage+0x4*6)
    				lastm=mtv
    				mtv=lastm
    				lmtp=mtp
    				
    				if initm==0 or inith==0 or initl==0 then 
    					print(""..string.format("Save state's session did not start with script.")) 
    					print(""..string.format("Either load a valid save state or resume with this one."))
    					initl=mdword(rng)						-- reset to session
    					inith=mdword(rng+4)
    					mttrack=0
    					emu.pause()
    					total=0
    					steptable=0
    					mtf=0
    					lmtp=mtp
    					steptable=0
    				else
    					print(""..string.format("PRNG: %08X%08X",inith,initl)) 
    					print(""..string.format("MTRNG: %08X", initm))
    					last=cacheseed
    					total=cachevalue							-- restored frame
    				end
    				cgearoff=mdword(storage+0x4*8)			-- remember if c-gear was turned on or not
    				notrestored=1
    				wasrestored=1
    			elseif initm==inith then
    				print(""..string.format("Game Reset. Re-initializing."))
    				total=0
    				steptable=0
    				mtf=0
    				lmtp=mtp
    				initl=mdword(rng)
    				inith=mdword(rng+4)
    				initm=mdword(mtrng)
    				if inith>0x7FFFFFFF then wdword(storage+0x4*4,inith-0x100000000) else wdword(storage+0x4*4,inith) end  -- dumb storage problems, have to make sure they are recognized as the right number type before storage
    				if initl>0x7FFFFFFF then wdword(storage+0x4*3,initl-0x100000000) else wdword(storage+0x4*3,initl) end
    				if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end
    				lastm=initm
    				randomseed(initm)
    				mttrack=1						-- enable mersenne tracking
    				nextmt=random_int32()			-- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone
    				cgearenoff=0
    				wasrestored=0
    					
    			print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) 
    			--print(""..string.format("Next: %08X", nextmt)) -- debug
    
    			-- see if initial seeding happened (high32=mtseed)
    				mttrack=1					-- enable tracking
    				print(""..string.format("Initial Seeding Detected. MTRNG Seed: %08X", initm))
    			else	
    				print(""..string.format("Foreign Save State Detected, or Restart didn't refresh. Reset again."))
    				total=0
    				steptable=0
    				mtf=0
    				lmtp=mtp
    				initl=mdword(rng)
    				inith=mdword(rng+4)
    				initm=mdword(mtrng)
    				if inith>0x7FFFFFFF then wdword(storage+0x4*4,inith-0x100000000) else wdword(storage+0x4*4,inith) end
    				if initl>0x7FFFFFFF then wdword(storage+0x4*3,initl-0x100000000) else wdword(storage+0x4*3,initl) end
    				if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end
    				lastm=initm
    				randomseed(initm)
    				mttrack=0						-- disable mersenne tracking
    				nextmt=random_int32()			-- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone
    				cgearenoff=0
    				wasrestored=0
    			end
    			print(""..string.format(""))	-- Visual Line to separate.
    			break 
    	
    		elseif test~=seed1 then 			-- RNG advanced at least once. Lets advance once and repeat the loop.
    			test=next(test)
    			adv=adv+1
    			
    		elseif test==seed1 then 
    			if adv > 0 then 				-- Refresh Frame Advancement Table if there's more than one advancement this frame.
    				jump20=jump19
    				jump19=jump18
    				jump18=jump17
    				jump17=jump16
    				jump16=jump15
    				jump15=jump14
    				jump14=jump13
    				jump13=jump12
    				jump12=jump11
    				jump11=jump10
    				jump10=jump9
    				jump9=jump8
    				jump8=jump7
    				jump7=jump6
    				jump6=jump5
    				jump5=jump4
    				jump4=jump3
    				jump3=jump2
    				jump2=jump1
    				jump1=adv 
    			end								
    			break 							-- last frame's advanced RNG value matches the current. Stop loop.
    		end
    	end
    
    
    	gui.text(180,10,string.format("%d/%d/%d",month,day,2000+year))					-- Display Date
    	gui.text(180,19,string.format("%02d:%02d:%02d",hour,minute,second,delay))		-- Display Time
    	
    -- Check to see if the MTRNG changed, only if tracking is enabled.
    	if mttrack==1 and notrestored == 0 then
    		if (lmtp>mtp and delay > 50 and notrestored==0) or (lmtp==mtp and lastm~=mtv) then
    				strmtv=string.format("%08X",mtv)		-- Mersenne Twister untempered is in one format while the memory is in another
    				strnmt=string.format("%08X",nextmt)		-- Convert to a string hex so that they can be equated when their decimal isn't
    			if strmtv~=strnmt  then 					-- New untempered table value isn't as predicted, so the c-gear was turned on!
    				mttrack=1 
    				-- print(strmtv,strnmt,string.format("%08X",lastm)) -- debug for bad initialize
    				if wasrestored==1 then print(""..string.format("Earlier restoration may have failed. Double Check.")) print(""..string.format("If C-Gear was just turned on this frame, ignore.")) print(""..string.format("")) wasrestored=0 end
    				-- mttrack=0
    				--else 
    				print(""..string.format("C-Gear turned on. Determining C-Gear Seed and restarting tracking.")) 
    				steptable=1
    				wdword(storage+0x4*1, steptable)
    				-- Finding the C-Gear seed you hit
    				-- Load Time Values
    					hour=string.format("%02X",(timehex%0x100)%0x40)				-- Memory stores as decimal, but Lua reads as hex. Convert.
    					minute=string.format("%02X",(rshift(timehex%0x10000,8)))
    					second=string.format("%02X",(mbyte(0x02FFFDEE)))
    					year=string.format("%02X",(mbyte(0x02FFFDE8)))
    					month=string.format("%02X",(mbyte(0x02FFFDE9)))
    					day=string.format("%02X",(mbyte(0x02FFFDEA)))
    							ab=(month*day+minute+second)%256
    							cd=hour
    							cgd=delay%65536-1									-- Delay from a frame before is used.
    							abcd=ab*0x100+cd
    							efgh=(year+cgd)%0x10000
    							tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000
    					randomseed(tempcgear)
    					trialseed=random_int32()
    					tempcgearuntemp=string.format("%08X",trialseed)
    					if strmtv~=tempcgearuntemp then
    						second=second-1					-- Subtract a second to check a different set.
    						if second < 0 then				-- Balaning minutes
    							second=59
    							minute=minute-1				
    							if minute<0 then			-- Balancing Hours
    								minute=59
    								hour=hour-1
    							end
    						end
    						ab=(month*day+minute+second)%256	-- Rebuild seed, try again.
    						cd=hour
    						abcd=ab*0x100+cd
    						efgh=(year+cgd)%0x10000
    						tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000
    						randomseed(tempcgear)
    						trialseed=random_int32()
    						tempcgearuntemp=string.format("%08X",trialseed)
    					end
    
    					initm=tempcgear
    					print(""..string.format("C-Gear Seed: %08X    Delay: %d",tempcgear,cgd))
    					print(""..string.format(""))				-- Visual Blank Line
    					cgearenabled=2
    					wdword(storage+0x4*8,cgearenabled)					
    					if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end
    					i=0
    					while i~=624 do								-- get the next untempered for the cgear
    						nextmt=math.floor(random_int32())
    						i=i+1
    					end --end
    			else												-- untempered is as predicted -> predict next one for when the time rolls around
    					
    				i=0
    				while i~=624 do									-- do 624 iterations to build the remaining 623 and the first of the next.
    					nextmt=math.floor(random_int32())
    					i=i+1
    				end
    			--print(""..string.format("Next: %08X", nextmt)) 	-- debug
    			
    				
    			
    				steptable=steptable+1 							-- mersenne twister has a new table as the counter is reset to 0; tables++
    				
    				wdword(storage+0x4*1, steptable)				-- save state storage of table refreshes
    			end
    		end
    	gui.text(1,160,string.format("MTRNG Seed: %08X",initm))
    	gui.text(1,150,string.format("Frame: %d",mtf))
    	-- gui.text(1,38,string.format("next mt: %08X", nextmt)) -- debug
    	end
    	
    
    -- Advancement Tracking for the PRNG and Mersenne Twister
    	total=adv+total										-- total advancements = advancements on this frame + total advancements from previous frames
    	if total-cachevalue>200 then						-- check to see if we should refresh the cached value
    		cachevalue=total
    	end
    	mtf=mtp+(steptable-1)*624							-- Mersenne Twister Frame = Pointer Value + (TableRefresh-1)*624 ; this accounts for the initial value of 0x270 which is actually zero
    
    	gui.text(1,19,string.format("Frame: %d", total))	-- Display PRNG Frame; total advancements since the initial seed
    
    -- If the user specifies they want to use the C-Gear
    	if trackcgear==0 then											-- C-Gear Seed Generation Loop
    		ab=(month*day+minute+second)%256							-- Build Seed
    		cd=hour
    		cgd=delay%65536+1
    		abcd=ab*0x100+cd
    		efgh=(year+cgd)%0x10000
    		betaseed=ab*0x1000000+cd*0x10000+efgh						-- Seed before MAC applied
    		cgearseed=betaseed+mac										-- Seed after MAC applied, return this value.
    	gui.text(1,130,string.format("Next C-Gear: %08X",cgearseed))	-- Display the C-Gear Seed of the next frame
    	gui.text(1,140,string.format("Delay: %d", delay))				-- Display Current Delay
    	elseif cgearenabled==2 then
    		gui.text(1,130,string.format(" C-GEAR WAS TURNED ON: SEE NEW MTRNG SEED"))
    	end
    
    -- If user specifies they want to see the frame advancement chart
    	if research==0 then									-- Display framebased advancement table
    	gui.text(1,37,string.format("%d", jump1)) gui.text(1,46,string.format("%d", jump2)) gui.text(1,55,string.format("%d", jump3)) gui.text(1,64,string.format("%d", jump4))
    	gui.text(1,73,string.format("%d", jump5)) gui.text(1,82,string.format("%d", jump6)) gui.text(1,91,string.format("%d", jump7)) gui.text(1,100,string.format("%d", jump8))
    	gui.text(1,109,string.format("%d", jump9)) gui.text(1,118,string.format("%d", jump10)) gui.text(20,37,string.format("%d", jump11)) gui.text(20,46,string.format("%d", jump12)) 
    	gui.text(20,55,string.format("%d", jump13)) gui.text(20,64,string.format("%d", jump14))	gui.text(20,73,string.format("%d", jump15))	gui.text(20,82,string.format("%d", jump16)) 
    	gui.text(20,91,string.format("%d", jump17)) gui.text(20,100,string.format("%d", jump18)) gui.text(20,109,string.format("%d", jump19)) gui.text(20,118,string.format("%d", jump20))
    	end
    	
    -- Set Up variables for next frame's pass
    	lmtp=mtp
    	last=seed1
    	lastm=mtv
    	if lastm>0x7FFFFFFF then wdword(storage+0x4*7,lastm-0x100000000) else wdword(storage+0x4*7,lastm) end
    		wdword(storage+0x4*6,total)
    				if seed1>0x7FFFFFFF then wdword(storage+0x4*5,seed1-0x100000000) else wdword(storage+0x4*5,seed1) end
    		
    	notrestored=0
    -- End Lua
    	emu.frameadvance() 
    end
    still may have some bugs to work out, however it's pretty much done

    edit: Added C-Gear detection and it will properly track the frames if you turn on the C-Gear. It also tells you what C-Gear seed you hit in addition to delay in the Console. The value that seeds the MTRNG is displayed on the HUD (changed from only displaying the initial seed from the start of the game).
    edit2: fixed bugs and allowed people to turn off the frame chart and C-Gear prediction. dubbed "research" and "trackcgear"

    different from image: frame advancement chart is displayed only by turning on research mode, and it's more collapsed than above (changed). c-gear tracking and research is by default off

    --

    edit3: added save state support

    old version without state support:
    Spoiler

    Code:
    -- General Parameters for current game and setup(currently English White)
    local rng=0x02216244			-- PRNG Seed Location
    local mtrng=0x02215374			-- Mersenne Twister Table Top
    local mac=0x123456				-- MAC Address of Emulator
    local pos_m=0x0224F92C			-- Map Position -> XYZ
    local trackcgear=1 			-- 0 on, 1 off; disable for Standard Abuse, enable for Entralink Abuse
    local research=1 				-- 0 on, 1 off; only enable for dev features (unneeded)
    
    -- Setup Terminology abbreviations; from FractalFusion
    local bnd,br,bxr=bit.band,bit.bor,bit.bxor
    local rshift, lshift=bit.rshift, bit.lshift
    local mdword=memory.readdwordunsigned
    local mword=memory.readwordunsigned
    local mbyte=memory.readbyteunsigned
    
    -- Setup initial variables, rest of script detection will take care of them
    local initl=0
    local inith=0
    local initm=0
    local adv=0
    local jump1=0
    local jump2=0
    local jump3=0
    local jump4=0
    local jump5=0
    local jump6=0
    local jump7=0
    local jump8=0
    local jump9=0
    local jump10=0
    local jump11=0
    local jump12=0
    local jump13=0
    local jump14=0
    local jump15=0
    local jump16=0
    local jump17=0
    local jump18=0
    local jump19=0
    local jump20=0
    local total=0
    local last=0
    local lastm=0
    local lmtp=0
    local steptable=0
    local mtf=0
    local mttrack=0
    local nextmt=0
    local second=0
    local minute=0
    local hour=0
    local cgearenabled=0
    
    -- S frame detection function; works off of seeing how many times the lower half was advanced
    -- Lua sucks and only allows 16 bit multiplication, so 32 bit multiplication can't be used
    -- The lower seed is advanced as follows, if observed as a standalone 32 bit number:
    -- SEED1 = (0x6C078965 * SEED1) + 0x00269EC3; from Kazo
    function next(s)
    local a=0x6C07*(s%65536)+rshift(s,16)*0x8965
    local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3
    local c=b%4294967296
    return c
    end
    
    -- To predict Mersenne advancement, it's a little harder. Copied and adapted pre-existing Lua
    -- http://code.google.com/p/gocha-tas/source/browse/trunk/Scripts/mt19937.lua?r=117
    -- Mersenne Twister: A random number generator
    -- ported to Lua by gocha, based on mt19937ar.c
    module("mt19937", package.seeall)
    
    require "bit"
    
    -- Period parameters
    local N = 624
    local M = 397
    local MATRIX_A = 0x9908b0df   -- constant vector a
    local UPPER_MASK = 0x80000000 -- most significant w-r bits
    local LOWER_MASK = 0x7fffffff -- least significant r bits
    
    local mt = {}     -- the array for the state vector
    local mti = N + 1 -- mti==N+1 means mt[N] is not initialized
    
    -- initializes mt[N] with a seed
    function randomseed(s)
        s = bit.band(s, 0xffffffff)
        mt[1] = s
        for i = 1, N - 1 do
            -- s = 1812433253 * (bit.bxor(s, bit.rshift(s, 30))) + i
            s = bit.bxor(s, bit.rshift(s, 30))
            local s_lo = bit.band(s, 0xffff)
            local s_hi = bit.rshift(s, 16)
            local s_lo2 = bit.band(1812433253 * s_lo, 0xffffffff)
            local s_hi2 = bit.band(1812433253 * s_hi, 0xffff)
            s = bit.bor(bit.lshift(bit.rshift(s_lo2, 16) + s_hi2, 16),
                bit.band(s_lo2, 0xffff))
            -- s = bit.band(s + i, 0xffffffff)
            local s_lim = -bit.tobit(s)
            -- assumes i<2^31
            if (s_lim > 0 and s_lim <= i) then
                s = i - s_lim
            else
                s = s + i
            end
            mt[i+1] = s
            -- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
            -- In the previous versions, MSBs of the seed affect
            -- only MSBs of the array mt[].
            -- 2002/01/09 modified by Makoto Matsumoto
        end
        mti = N
    end
    
    local mag01 = { 0, MATRIX_A }   -- mag01[x] = x * MATRIX_A  for x=0,1
    
    -- generates a random number on [0,0xffffffff]-interval
    function random_int32()
        local y
    
        if (mti >= N) then -- generate N words at one time
            local kk
    
            if (mti == N + 1) then -- if init_genrand() has not been called,
                mt19937.randomseed(5489) -- a default initial seed is used
            end
    
            for kk = 1, N - M do
                y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK))
                mt[kk] = bit.bxor(mt[kk+M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
            end
            for kk = N - M + 1, N - 1 do
                y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK))
                mt[kk] = bit.bxor(mt[kk+(M-N)], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
            end
            y = bit.bor(bit.band(mt[N], UPPER_MASK), bit.band(mt[1], LOWER_MASK))
            mt[N] = bit.bxor(mt[M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)])
    
            mti = 0
        end
    
        y = mt[mti+1]
        mti = mti + 1
    
    
    
        return y
    end
    
    function random(...)
        -- local r = mt19937.random_int32() * (1.0/4294967296.0)
        local rtemp = mt19937.random_int32()
        local r = (bit.band(rtemp, 0x7fffffff) * (1.0/4294967296.0)) + (bit.tobit(rtemp) < 0 and 0.5 or 0)
        local arg = {...}
        if #arg == 0 then
            return r
        elseif #arg == 1 then
            local u = math.floor(arg[1])
            if 1 <= u then
                return math.floor(r*u)+1
            else
                error("bad argument #1 to 'random' (internal is empty)")
            end
        elseif #arg == 2 then
            local l, u = math.floor(arg[1]), math.floor(arg[2])
            if l <= u then
                return math.floor((r*(u-l+1))+l)
            else
                error("bad argument #2 to 'random' (internal is empty)")
            end
        else
            error("wrong number of arguments")
        end
    end
    
    -- Lua script begin!
    while true do
    
    -- setup every loop
    	seed2=mdword(rng+4)
    	seed1=mdword(rng)
    	adv=0
    	test=last
    	mtv=mdword(mtrng)
    	mtp=mdword(mtrng+0x9C0)
    	delay=mdword(0x02FFFC3C)
    	timehex=mdword(0x023FFDEC)
    	datehex=mdword(0x023FFDE8)
    	hour=string.format("%02X",(timehex%0x100)%0x40)				-- memory stores as decimal, but Lua reads as hex. Convert.
    	minute=string.format("%02X",(rshift(timehex%0x10000,8)))
    	second=string.format("%02X",(mbyte(0x02FFFDEE)))
    	year=string.format("%02X",(mbyte(0x02FFFDE8)))
    	month=string.format("%02X",(mbyte(0x02FFFDE9)))
    	day=string.format("%02X",(mbyte(0x02FFFDEA)))
    	
    -- display seeds every loop
    	gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1))
    	gui.text(1,180,string.format("Initial: %08X%08X",inith,initl))
    	gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", mword(pos_m), mword(pos_m+0x6), mword(pos_m+0xE), mword(pos_m+0xA)))
    
    	-- Check to see if the RNG advanced from the last value
    	while seed1~=0 and seed2~=0 do
    		if adv>200 then -- RNG advanced a bunch, or the game/script was reset. Reset variables then stop loop.
    			print(""..string.format("Detected a reset or massive advancement. Re-initializing."))
    			adv  =0
    			total=0
    			jump1=0
    			jump2=0
    			jump3=0
    			jump4=0
    			jump5=0
    			jump6=0
    			jump7=0
    			jump8=0
    			jump9=0
    			jump10=0
    			jump11=0
    			jump12=0
    			jump13=0
    			jump14=0
    			jump15=0
    			jump16=0
    			jump17=0
    			jump18=0
    			jump19=0
    			jump20=0
    			steptable=0
    			mtf=0
    			lmtp=mtp
    			initl=mdword(rng)
    			inith=mdword(rng+4)
    			initm=mdword(mtrng)
    			lastm=initm
    			randomseed(initm)
    			mttrack=0						-- disable mersenne tracking
    			nextmt=random_int32()			-- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone
    			cgearenabled=0
    			
    			print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) 
    			--print(""..string.format("Next: %08X", nextmt)) -- debug
    
    			if initm==inith then			-- see if initial seeding happened (high32=mtseed)
    				mttrack=1					-- enable tracking
    				print(""..string.format("Initial Seeding Detected. MTRNG Seed: %08X", initm))
    			else	
    				print(""..string.format("Save State Detected. Unable to determine initial MTRNG"))
    			end
    			print(""..string.format(""))	-- Visual Line to separate.
    			break 
    	
    		elseif test~=seed1 then 			-- RNG advanced at least once. Lets advance once and repeat the loop.
    			test=next(test)
    			adv=adv+1
    			
    		elseif test==seed1 then 
    			if adv > 0 then 				-- Refresh Frame Advancement Table if there's more than one advancement this frame.
    				jump20=jump19
    				jump19=jump18
    				jump18=jump17
    				jump17=jump16
    				jump16=jump15
    				jump15=jump14
    				jump14=jump13
    				jump13=jump12
    				jump12=jump11
    				jump11=jump10
    				jump10=jump9
    				jump9=jump8
    				jump8=jump7
    				jump7=jump6
    				jump6=jump5
    				jump5=jump4
    				jump4=jump3
    				jump3=jump2
    				jump2=jump1
    				jump1=adv 
    			end								
    			break 							-- last frame's advanced RNG value matches the current. Stop loop.
    		end
    	end
    
    
    	gui.text(180,10,string.format("%d/%d/%d",month,day,2000+year))					-- Display Date
    	gui.text(180,19,string.format("%02d:%02d:%02d",hour,minute,second,delay))		-- Display Time
    	
    -- Check to see if the MTRNG changed, only if tracking is enabled.
    	if mttrack==1 then
    		if (lmtp>mtp and delay > 50) or (lmtp==mtp and lastm~=mtv) then
    				strmtv=string.format("%08X",mtv)		-- Mersenne Twister untempered is in one format while the memory is in another
    				strnmt=string.format("%08X",nextmt)		-- Convert to a string hex so that they can be equated when their decimal isn't
    			if strmtv~=strnmt  then 						-- New untempered table value isn't as predicted, so the c-gear was turned on!
    				mttrack=1 
    				print(""..string.format("C-Gear turned on. Determining C-Gear Seed and restarting tracking."))
    				steptable=1
    				-- Finding the C-Gear seed you hit
    				-- Load Time Values
    					hour=string.format("%02X",(timehex%0x100)%0x40)				-- Memory stores as decimal, but Lua reads as hex. Convert.
    					minute=string.format("%02X",(rshift(timehex%0x10000,8)))
    					second=string.format("%02X",(mbyte(0x02FFFDEE)))
    					year=string.format("%02X",(mbyte(0x02FFFDE8)))
    					month=string.format("%02X",(mbyte(0x02FFFDE9)))
    					day=string.format("%02X",(mbyte(0x02FFFDEA)))
    							ab=(month*day+minute+second)%256
    							cd=hour
    							cgd=delay%65536-1									-- Delay from a frame before is used.
    							abcd=ab*0x100+cd
    							efgh=(year+cgd)%0x10000
    							tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000
    					randomseed(tempcgear)
    					trialseed=random_int32()
    					tempcgearuntemp=string.format("%08X",trialseed)
    					if strmtv~=tempcgearuntemp then
    						second=second-1					-- Subtract a second to check a different set.
    						if second < 0 then				-- Balaning minutes
    							second=59
    							minute=minute-1				
    							if minute<0 then			-- Balancing Hours
    								minute=59
    								hour=hour-1
    							end
    						end
    						ab=(month*day+minute+second)%256	-- Rebuild seed, try again.
    						cd=hour
    						abcd=ab*0x100+cd
    						efgh=(year+cgd)%0x10000
    						tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000
    						randomseed(tempcgear)
    						trialseed=random_int32()
    						tempcgearuntemp=string.format("%08X",trialseed)
    					end
    
    					initm=tempcgear
    					print(""..string.format("C-Gear Seed: %08X    Delay: %d",tempcgear,cgd))
    					print(""..string.format(""))				-- Visual Blank Line
    					cgearenabled=1
    					i=0
    					while i~=624 do								-- get the next untempered for the cgear
    						nextmt=math.floor(random_int32())
    						i=i+1
    					end
    			else												-- untempered is as predicted -> predict next one for when the time rolls around
    					
    				i=0
    				while i~=624 do									-- do 624 iterations to build the remaining 623 and the first of the next.
    					nextmt=math.floor(random_int32())
    					i=i+1
    				end
    			--print(""..string.format("Next: %08X", nextmt)) 	-- debug
    			
    				steptable=steptable+1 							-- mersenne twister has a new table as the counter is reset to 0; tables++
    			end
    		end
    	gui.text(1,160,string.format("MTRNG Seed: %08X",initm))
    	gui.text(1,150,string.format("Frame: %d",mtf))
    	-- gui.text(1,38,string.format("next mt: %08X", nextmt)) -- debug
    	end
    	
    
    -- Advancement Tracking for the PRNG and Mersenne Twister
    	total=adv+total										-- total advancements = advancements on this frame + total advancements from previous frames
    	mtf=mtp+(steptable-1)*624							-- Mersenne Twister Frame = Pointer Value + (TableRefresh-1)*624 ; this accounts for the initial value of 0x270 which is actually zero
    
    	gui.text(1,19,string.format("Frame: %d", total))	-- Display PRNG Frame; total advancements since the initial seed
    
    -- If the user specifies they want to use the C-Gear
    	if trackcgear==0 then											-- C-Gear Seed Generation Loop
    		ab=(month*day+minute+second)%256							-- Build Seed
    		cd=hour
    		cgd=delay%65536+1
    		abcd=ab*0x100+cd
    		efgh=(year+cgd)%0x10000
    		betaseed=ab*0x1000000+cd*0x10000+efgh						-- Seed before MAC applied
    		cgearseed=betaseed+mac										-- Seed after MAC applied, return this value.
    	gui.text(1,130,string.format("Next C-Gear: %08X",cgearseed))	-- Display the C-Gear Seed of the next frame
    	gui.text(1,140,string.format("Delay: %d", delay))				-- Display Current Delay
    	elseif cgearenabled==1 then
    		gui.text(1,130,string.format(" C-GEAR WAS TURNED ON: SEE NEW MTRNG SEED"))
    	end
    
    -- If user specifies they want to see the frame advancement chart
    	if research==0 then									-- Display framebased advancement table
    	gui.text(1,37,string.format("%d", jump1)) gui.text(1,46,string.format("%d", jump2)) gui.text(1,55,string.format("%d", jump3)) gui.text(1,64,string.format("%d", jump4))
    	gui.text(1,73,string.format("%d", jump5)) gui.text(1,82,string.format("%d", jump6)) gui.text(1,91,string.format("%d", jump7)) gui.text(1,100,string.format("%d", jump8))
    	gui.text(1,109,string.format("%d", jump9)) gui.text(1,118,string.format("%d", jump10)) gui.text(20,37,string.format("%d", jump11)) gui.text(20,46,string.format("%d", jump12)) 
    	gui.text(20,55,string.format("%d", jump13)) gui.text(20,64,string.format("%d", jump14))	gui.text(20,73,string.format("%d", jump15))	gui.text(20,82,string.format("%d", jump16)) 
    	gui.text(20,91,string.format("%d", jump17)) gui.text(20,100,string.format("%d", jump18)) gui.text(20,109,string.format("%d", jump19)) gui.text(20,118,string.format("%d", jump20))
    	end
    	
    -- Set Up variables for next frame's pass
    	lmtp=mtp
    	last=seed1
    	lastm=mtv
    
    -- End Lua
    	emu.frameadvance() 
    end


    not adding the part that tracks battle RNG, for obvious reasons
    Last edited by Kaphotics; May 23rd, 2012 at 02:42 PM. Reason: typos, added black support

  2. #2
    Super Moderator Translation ContributorDeveloperGame Save ResearcherROM ResearcherRAM ResearcherIRC AOPSuper Moderator
    Join Date
    May 2010
    Age
    28
    Posts
    1,007

    Re: Pokemon White Map Coordinates LUA script

    i've been using this to watch the rng:

    Code:
    while true do
    	gui.text(1,185, string.format("%08X  %08X", memory.readdword(0x02216248), memory.readdword(0x02216244)))
    	emu.frameadvance()
    end
    lua is using windows' definition of a word when it runs, so you need to define a 32-bit value as a dword. also, for anyone who wants to try this out and isn't aware, the string.format method is really close to printf(), so you can use the variable definitins and other stuff for string.format(). for example, "%08X" is a capital letter hex value 8 digits large. "%08x" is the same thing but with lower case hex values, "%08u" is unsigned decimal, etc

  3. #3
    Learning to breathe IRC VOPDeveloperGame Save ResearcherModerator codemonkey85's Avatar
    Join Date
    Apr 2009
    Location
    http://goo.gl/Wd4id
    Age
    27
    Posts
    800

    Re: Pokemon White Map Coordinates LUA script

    Whoa... that is seriously cool.

    Man, if only we had this back in Gen IV!

  4. #4

    Re: Pokemon B/W Lua scripts

    I wonder... could the coordinate script maybe be used to create a world map of black and white? Something like: every time the coordinates change, save a new picture of the screen with the specified coordinates in the name? And then, by having some other script (maybe in LUA, or maybe in some completely other language) try to merge all these pictures together(i.e., grab the picture with the lowest X and Y, and then get the picture with the X and Y that are the second-lowest, and add that picture on top of the old one at X minus lowestX and Y minus lowestY, and so on.)

  5. #5

    Re: Pokemon B/W Lua scripts

    rng helper -- very old version. see first post for most up to date


    Code:
    -- RNG location for current game (English White)
    local rng=0x02216244
    
    -- setup terminology abbreviations
    local rshift=bit.rshift
    local mdword=memory.readdwordunsigned
    
    -- setup initial variables = 0, rest of script detection will take care of them
    local initl=0
    local inith=0
    local adv=0
    local total=0
    local last=0
    local jump1=0
    
    -- setup frame detection function
    function next(s)
    local a=0x6C07*(s%65536)+rshift(s,16)*0x8965
    local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3
    local c=b%4294967296
    return c
    end
    
    -- Lua script begin!
    while true do
    
    -- setup every loop
    	seed2=mdword(rng+4)
    	seed1=mdword(rng)
    	adv=0
    	test=last
    	
    -- display seeds every loop
    	gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1))
    	gui.text(1,180,string.format("Initial: %08X%08X",inith,initl))
    	gui.text(180,10,string.format("Delay: %d", mdword(0x023FFC3C)))
    	gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F92C), memory.readword(0x0224F932,2), memory.readword(0x0224F93A), memory.readword(0x0224F936))) -- copied from map coord Lua
    
    
    	-- check to see if the RNG advanced from the last value
    	while seed1~=0 and seed2~=0 do
    		if adv>200 then -- RNG advanced a bunch. Reset script then stop loop.
    			print(""..string.format("Detected a reset or massive advancement. Re-initializing."))
    			adv  =0
    			total=0
    			jump1=0
    			initl=mdword(rng)
    			inith=mdword(rng+4)	
    			print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) 
    			break 
    	
    		elseif test~=seed1 then -- RNG advanced at least once. Lets advance once and repeat the loop.
    			test=next(test)
    			adv=adv+1
    			jump1=adv
    			
    		elseif test==seed1 then break -- last frame's advanced RNG value matches the current. Stop loop.
    		end
    	end
    
    -- advancement tracking
    	total=adv+total
    	gui.text(1,19,string.format("Frame: %d", total))
    	gui.text(1,28,string.format("Jump: %d", jump1))
    	last=seed1
    
    	emu.frameadvance() 
    end

    main use is that it tracks RNG frames after keeping the seeds from the moment the script starts.
    it grabs the initial seed when the game is reset, or the first seed it can find and keeps it stored as long as the script runs.

    I may have it write the initial seeds it gets to somewhere so that upon loading a save state it can find and re-determine the frame (session preservation), but this was just for fun
    Last edited by Kaphotics; May 23rd, 2012 at 07:09 AM.

  6. #6

    Re: Pokemon B/W Lua scripts

    Map Coordinates

    Spoiler


    White
    Code:
    while true do
    	gui.text(1,184, string.format("Map: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F92C), memory.readword(0x0224F932,2), memory.readword(0x0224F93A), memory.readword(0x0224F936)))
    	emu.frameadvance()
    end
    Black
    Code:
    while true do
    	gui.text(1,184, string.format("Map: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F90C), memory.readword(0x0224F912,2), memory.readword(0x0224F91A), memory.readword(0x0224F916)))
    	emu.frameadvance()
    end
    Download Link (English White)
    Last edited by Kaphotics; May 23rd, 2012 at 05:43 AM. Reason: moved suite to top, map position to this post

  7. #7
    I like Belgian Chocolates Waitress_Tsubame's Avatar
    Join Date
    Jun 2012
    Posts
    12

    Re: Pokemon B/W Lua scripts

    Kinda weird why when I use the above lua script from the first post, the numbers stacked vertically in 2 columns remained zero in my Desmume.
    And also the frame value is still 0 :/

    BTW, kinda a bit unrelated, but is there a lua script for HGSS?

  8. #8

    Re: Pokemon B/W Lua scripts

    B2W2 Zonedata / Map Coordinates



    Notes:
    L toggles the raw zonedata display on/off. (default Q in DeSmuME)

    Spoiler
    Code:
    local rshift, lshift=bit.rshift, bit.lshift
    local md,mw,mb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned
    local gt,sf=gui.text,string.format
    local table={}
    local on,enbl,overprint,enblo=1,1,1,1
    
    if mb(0x023FFE09)==0x00 then		-- Not "2" ~ Not B2/W2
    	  pos_m=md(0x02000024)+0x3461C
    	    zds=md(0x02000024)+0x3DFAC
    	owstart=md(0x02000024)+0x34E04
    	game=1
    else
    	  pos_m=md(0x02000024)+0x36780
    	    zds=md(0x02000024)+0x41B2C
    	owstart=md(0x02000024)+0x36BE8
    	game=2
    end
    
    function main()
            table=joypad.get(1)
            if table.L then
                    gt(0,0, "Toggling Display")
                    enbl=0
            else
                    if enbl==0 then on=(on+1)%2 enbl=1 end
            end
    
            if table.R then
                    gt(0,0, "Printout")
                    enblo=0
            else
                    if enblo==0 then overprint=(overprint+1)%2 enblo=1 end
            end
    
            if on==0 then
    
    		
    		if game==2 then
    			bike=rshift(mw(zds+2*15),10)%2
    			 fly=rshift(mw(zds+2*15),13)%2
    		else 
    			bike=rshift(mb(zds+0x1F),2)%2
    			 fly=rshift(mb(zds+0x1F),5)%2
    	end
    
    
    
                    if bike==1 then
                            gt(159,110,sf("Bike - Enabled")) else
                            gt(159,110,sf("Bike - Disabled")) end
                    if fly==1 then
                            gt(159,120,sf("Fly  - Enabled")) else
                            gt(159,120,sf("Fly  - Disabled")) end
            
                    gt(1,50,sf("00-01: %04x",mw(zds+2*0)))        gt(80,50,sf("10-11: %04x",mw(zds+2*8)))       gt(159,50,sf("20-21: %04x",mw(zds+2*16)))
                    gt(1,60,sf("02-03: %04x",mw(zds+2*1)))        gt(80,60,sf("12-13: %04x",mw(zds+2*9)))       gt(159,60,sf("22-23: %04x",mw(zds+2*17)))
                    gt(1,70,sf("04-05: %04x",mw(zds+2*2)))        gt(80,70,sf("14-15: %04x",mw(zds+2*10)))      gt(159,70,sf("24-27: %08x",md(zds+2*18)))
                    gt(1,80,sf("06-07: %04x",mw(zds+2*3)))        gt(80,80,sf("16-17: %04x",mw(zds+2*11)))      gt(159,80,sf("28-2B: %08x",md(zds+2*20)))
                    gt(1,90,sf("08-09: %04x",mw(zds+2*4)))        gt(80,90,sf("18-19: %04x",mw(zds+2*12)))      gt(159,90,sf("2C-2F: %08x",md(zds+2*22)))
                    gt(1,100,sf("0A-0B: %04x",mw(zds+2*5)))       gt(80,100,sf("1A-1B: %04x",mw(zds+2*13)))
                    gt(1,110,sf("0C-0D: %04x",mw(zds+2*6)))       gt(80,110,sf("1C-1D: %04x",mw(zds+2*14)))
                    gt(1,120,sf("0E-0F: %04x",mw(zds+2*7)))       gt(80,120,sf("1E-1F: %04x",mw(zds+2*15)))    
            end
    
    	if overprint==0 then 
    		fcount=mb(0x4+owstart) ncount=mb(0x5+owstart) wcount=mb(0x6+owstart) tcount=mb(0x7+owstart)
    		furnstart=0x8
    		furnend=furnstart+0x14*fcount-1
    		 npcstart=0x08+mb(0x04+owstart)*0x14
    		 npcend= npcstart+0x24*ncount-1
    		warpstart=0x08+mb(0x04+owstart)*0x14+mb(0x05+owstart)*0x24
    		warpend=warpstart+0x14*wcount-1
    		trigstart=0x08+mb(0x04+owstart)*0x14+mb(0x05+owstart)*0x24+mb(0x06+owstart)*0x14
    		trigend=trigstart+0x16*tcount-1
    
    
    		print(sf("Overworld Data [%d] @ 0x%08X",mw(zds+2*11),owstart))
    		if fcount>0 then
    			print(sf("[%d] Furniture Range: 0x%04X-0x%04X",fcount,furnstart,furnend)) else print(sf("[%d] No Furniture",fcount))
    		end
    		if ncount>0 then
    			print(sf("[%d] NPC Range: 0x%04X-0x%04X",ncount,npcstart,npcend)) else print(sf("[%d] No NPCs",ncount))
    		end
    		if wcount>0 then
    			print(sf("[%d] Warp Range: 0x%04X-0x%04X",wcount,warpstart,warpend)) else print(sf("[%d] No Warps",wcount))
    		end
    		if tcount>0 then
    			print(sf("[%d] Trigger Range: 0x%04X-0x%04X",tcount,trigstart,trigend)) else print(sf("[%d] No Triggers",tcount))
    		end
    		if md(owstart)~=trigend-3 then print("Error in parsing, please be in game.") else print("Successful Parse!") end
    		print("") print("")
    	overprint=1
    	end
    	gt(160,145,sf("Overworld: %5d",mw(zds+2*11)))
        gt(160,155,sf("Script: %8d",mw(zds+2*3)))
    	gt(160,165,sf("Text: %10d",mw(zds+2*5)))
    	
    	flyx=md(zds+2*18)
    	flyy=md(zds+2*22)
    	flyz=md(zds+2*20)
    	if (flyx==5 and flyy==4 and flyz==0) or (flyx==13 and flyy==0 and flyz==5) then
    	gt(149,174,sf("Can't Fly to here.")) else
    	gt(185,174,sf("FlyTo (XYZ)"))
    	gt(185,184,sf("%d,%d,%d",flyx,flyy,flyz)) end
    
    	gt(1,145, sf("SubMap of Map: %3d",mw(zds+2*12)))
            if mw(zds+2*10)%256<255 then
                    gt(1,155,sf("Slot Location: %d",mw(zds+2*10)%256)) else gt(1,155,sf("No Encounters Here!")) end
     
            gt(1,165, sf("Current Position"))
            gt(2,175, sf("M: %3d, X: %3d", mw(pos_m), mw(pos_m+0x6)))
    	gt(2,184, sf("Y: %3d, Z: %3d", mw(pos_m+0xE), mw(pos_m+0xA)))
    end
     
    
    gui.register(main)
    Last edited by Kaphotics; Feb 16th, 2013 at 08:10 PM.

  9. #9

    Re: Pokemon B/W Lua scripts

    B2/W2 Script Parser

    Reads the memory of the game and translates the script language to meaningful instructions similar to XSE and other scripting programs.

    I primarily made the script to help me see how commands are used and help further our understanding of each command. No, it does not make the scripts, only interprets the hex.

    Spoiler
    I've made a ton of progress and the whole script is 90,000 characters! Too big to include in this post.

    http://dl.dropbox.com/u/12206225/ppo...r/scrparse.lua

    Old bare below.


    Code:
    local rshift, lshift=bit.rshift, bit.lshift
    local wd,ww,wb=memory.writedword,memory.writeword,memory.writebyte
    local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned
    
    mb=function(SRP)
    return rb(SRP) 
    end
    
    mw=function(SRP)
    return rb(SRP)+rb(SRP+1)*0x100 
    end
    
    md=function(SRP)
    return rb(SRP)+rb(SRP+1)*0x100+rb(SRP+2)*0x10000+rb(SRP+3)*0x1000000
    end
    
    local gt,sf=gui.text,string.format
    local table={}
    local start=md(0x02000024)+0x459A4
    local startscr=md(md(0x02000024)+0x459A4)+md(0x02000024)+0x0459A8
    local SRP=start
    local goscrp=0
    local iterhead=0
    local iterscr=0
    local scrt={}
    local scrnum=0
    local scrindex=mw(md(0x02000024)+0x41B32)
    local printiter=0
    local catcherror=1
    local itercatch=290
    
    
    
    function main()
    --Notify when analysis is starting:
    		if SRP==start then	
    			print(""..string.format("~Script File %d~",scrindex))
    		end
    
    	while goscrp==0 and mw(SRP)~=0xFD13 and iterhead<35 do 
    		readval=md(SRP)
    		scrt[scrnum] = readval
    		if rd(start) > 4000 then 
    			print(""..sf("~Error Catch, Start Read Error~",curscr))
    			goscrp=-1 end
    		SRP=SRP+4
    		scrnum=scrnum+1
    		print(""..sf("Script %d: %08X",scrnum,readval))
    		iterhead=iterhead+1
    	end
    
    if scrnum>0 then gt(1,00,sf("%08X",scrt[0])) end
    if scrnum>1 then gt(1,10,sf("%08X",scrt[1])) end
    if scrnum>2 then gt(1,20,sf("%08X",scrt[2])) end
    if scrnum>3 then gt(1,30,sf("%08X",scrt[3])) end
    if scrnum>4 then gt(1,40,sf("%08X",scrt[4])) end
    
    --Notify that Lua is ready to parse the script data
    	if mw(SRP)==0xFD13 and goscrp==0 then
    		---print(""..sf("Finished Offset Parse")) 
    		goscrp=1					--proceed to next phase
    		SRP=SRP+2
    		curscr=1
    		end
    
    --Begin 
    	while goscrp==1 and scrnum>=curscr and catcherror==1 and iterscr<300 do
    			printiter=printiter+1
    		if printiter>20 or iterscr>itercatch then 
    			print(""..sf("~Error Catch, Command Read Error~",curscr))
    			catcherror=0
    			break 
    		end
    
    		print(""..sf("~~~~~Script %d~~~~~~",curscr))
    			iterscr=1
    			done=0
    		while done==0 and md(SRP-2)~=0x0002 and (mw(SRP)~=0x5544 or mw(SRP)~=0x0000 or mw(SRP)~=0x4652) and iterscr<300 do
    		if printiter>20 or iterscr>itercatch then 
    			print(""..sf("~Error Catch, Command Read Error~",curscr))
    			catcherror=0
    			break 
    		end
    			cmd=mw(SRP)
    			SRP=SRP+2
    				if cmd==0x02 then 
    				print(""..sf("End (0x0002)"))
    				curscr=curscr+1
    				if scrnum>=curscr then print(""..sf("~~~~~Script %d~~~~~~",curscr)) 
    				else done=1
    				end
    
    			elseif cmd==0x04 then
    				rt=md(SRP) SRP=SRP+4
    				print(""..sf("CallRoutine (0x0004) 0x%08X",rt))
    
    			elseif cmd==0x05 then 
    				print(""..sf("End???[*TR] (0x0005)")) 
    
    			elseif cmd==0x08 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("Logic08 (0x0008)  %s%d",fa,u16a))
    
    			elseif cmd==0x09 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("Logic09 (0x0009)  %s%d",fa,u16a)) 
    
    			elseif cmd==0x0A then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("Logic0A (0x000A)  %s%02X",fa,u16a))  
    
    			elseif cmd==0x10 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("Readflag (0x0010)  %s%d",fa,u16a)) 
    
    			elseif cmd==0x11 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("Logic11 (0x0011)  %s%d",fa,u16a)) 
    
    			elseif cmd==0x19 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("CompareAtoB (0x0019) A=%s%d B=%s%d",fa,u16a,fb,u16b))
    
    
    			elseif cmd==0x1C then
    				std=mw(SRP) SRP=SRP+2
    				print(""..sf("CallStd (0x001C) 0x%04X",std))
    
    
    			elseif cmd==0x1D then
    				std=mw(SRP) SRP=SRP+2
    				print(""..sf("EndStdReturn[**] (0x001D)"))
    
    			elseif cmd==0x1E then
    				jump=md(SRP) SRP=SRP+4
    				print(""..sf("GoTo (0x001E) jump=0x%08X",jump))
    
    			elseif cmd==0x1F then
    				logic=mb(SRP) SRP=SRP+1
    				jump=md(SRP) SRP=SRP+4
    				print(""..sf("IfThenGoTo (0x001F) 0x%02X jump=0x%08X",logic,jump))
    
    			elseif cmd==0x23 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("SetFlag (0x0023)  %s%d",fa,u16a))  
    
    			elseif cmd==0x24 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("ClearFlag (0x0023)  %s%d",fa,u16a)) 
    
    			elseif cmd==0x26 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("SetVarEqCont (0x0028) %s%d %s%d",fa,u16a,fb,u16b)) 
    
    			elseif cmd==0x27 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("SetVar27 (0x0027) %s%d %s%d",fa,u16a,fb,u16b)) 
    
    
    			elseif cmd==0x28 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("SetVarEqVal (0x0028) %s%d %s%d",fa,u16a,fb,u16b)) 
    
    			elseif cmd==0x2A then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("SetVarEq28 (0x002A) %s%d %s%d",fa,u16a,fb,u16b)) 
    
    			elseif cmd==0x2E then 
    				print(""..sf("LockAll (0x002E)"))  
    
    			elseif cmd==0x2F then 
    				print(""..sf("UnlockAll (0x002F)"))
    
    			elseif cmd==0x30 then 
    				print(""..sf("WaitMoment (0x0030)"))
    		
    			elseif cmd==0x32 then 
    				print(""..sf("WaitKeyPress (0x0032)"))
    
    			elseif cmd==0x33 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("EventMessage (0x0033) id=%s%d",fa,u16a))
    
    			elseif cmd==0x34 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("GreyMessage (0x0034) id=%s%d view=%s%d",fa,u16a,fb,u16b))
    
    			elseif cmd==0x35 then 
    				print(""..sf("CloseEventMessage (0x0035)"))
    
    			elseif cmd==0x36 then 
    				print(""..sf("CloseGreyMessage (0x0036)"))
    
    
    
    			elseif cmd==0x38 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u8a=mw(SRP) SRP=SRP+1
    					if u8a/0x8000>=1 then fb="Var_" u8a=u8a%0x4000
    					elseif u8a/0x4000>=1 then fb="Cont_" u8a=u8a%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("BubbleMessage (0x0038) %s%d %s%d",fa,u16a,fb,u8a)) 
    
    			elseif cmd==0x39 then 
    				print(""..sf("CloseBubbleMessage (0x0039)"))
    
    			elseif cmd==0x3C then
    				u8a=mb(SRP) SRP=SRP+1
    				u8b=mb(SRP) SRP=SRP+1
    				mid=mw(SRP)  SRP=SRP+2
    					if mid/0x8000>=1 then fm="Var_" mid=mid%0x4000
    					elseif mid/0x4000>=1 then fm="Cont_" mid=mid%0x4000
    					else fm="Num_"
    					end
    				npc=mw(SRP) SRP=SRP+2
    				view=mw(SRP) SRP=SRP+2
    				type=mw(SRP) SRP=SRP+2
    				print(""..sf("Message1 (0x003C) MID=%s%X NPC=%d",fm,mid,npc))
    
    			elseif cmd==0x3D then
    				u8a=mb(SRP) SRP=SRP+1
    				u8b=mb(SRP) SRP=SRP+1
    				mid=mw(SRP)  SRP=SRP+2
    					if mid/0x8000>=1 then fm="Var_" mid=mid%0x4000
    					elseif mid/0x4000>=1 then fm="Cont_" mid=mid%0x4000
    					else fm="Num_"
    					end
    				view=mw(SRP) SRP=SRP+2
    				type=mw(SRP) SRP=SRP+2
    				print(""..sf("Message2 (0x003D) MID=%s%X",fm,mid))
    
    			elseif cmd==0x3E then 
    				print(""..sf("CloseMessage (0x003E)"))
    
    			elseif cmd==0x3F then 
    				print(""..sf("CloseMessage2[*] (0x003F)"))
    
    			elseif cmd==0x43 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("BorderMessage (0x0028) id=%s%d color=%s%d",fa,u16a,fb,u16b)) 
    
    			elseif cmd==0x44 then 
    				print(""..sf("CloseBorderMessage (0x0044)")) 
    
    			elseif cmd==0x47 then
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("PopYesNoVar (0x0047) 0x%04X",u16a))
    
    
    			elseif cmd==0x48 then 
    				u8a=mw(SRP) SRP=SRP+2
    					if 	u8a/0x8000>=1 then 	f1="Var_"  u8a=u8a%0x4000
    					elseif 	u8a/0x4000>=1 then 	f1="Cont_" u8a=u8a%0x4000
    					else 				f1="Num_"
    					end
    				u8b=mw(SRP) SRP=SRP+2
    					if 	u8b/0x8000>=1 then 	f2="Var_"  u8b=u8b%0x4000
    					elseif 	u8b/0x4000>=1 then 	f2="Cont_" u8b=u8b%0x4000
    					else 				f2="Num_"
    					end
    				u16a=mw(SRP) SRP=SRP+2
    					if 	u16a/0x8000>=1 then 	fa="Var_"  u16a=u16a%0x4000
    					elseif 	u16a/0x4000>=1 then 	fa="Cont_" u16a=u16a%0x4000
    					else 				fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if 	u16b/0x8000>=1 then 	fb="Var_"  u16b=u16b%0x4000
    					elseif 	u16b/0x4000>=1 then 	fb="Cont_" u16b=u16b%0x4000
    					else 				fb="Num_"
    					end
    				u16c=mw(SRP) SRP=SRP+2
    					if 	u16c/0x8000>=1 then 	fc="Var_"  u16c=u16c%0x4000
    					elseif 	u16c/0x4000>=1 then 	fc="Cont_" u16c=u16c%0x4000
    					else 				fc="Num_"
    					end
    				u16d=mw(SRP) SRP=SRP+2
    					if 	u16d/0x8000>=1 then 	fd="Var_"  u16d=u16d%0x4000
    					elseif 	u16d/0x4000>=1 then 	fd="Cont_" u16d=u16d%0x4000
    					else 				fd="Num_"
    					end
    				u16e=mw(SRP) SRP=SRP+2
    					if 	u16e/0x8000>=1 then 	fe="Var_"  u16e=u16e%0x4000
    					elseif 	u16e/0x4000>=1 then 	fe="Cont_" u16e=u16e%0x4000
    					else 				fe="Num_"
    					end
    				print(""..sf("Message3 (0x0048) %s%d %s%d %s%d %s%d %s%d %s%d %s%d",f1,u8a,f2,u8b,fa,u16a,fb,u16b,fc,u16c,fd,u16d,fe,u16e))
    
    
    			elseif cmd==0x4B then 
    				print(""..sf("CloseAngryMessage (0x004B)"))
    
    			elseif cmd==0x4C then 
    				u8a=mb(SRP) SRP=SRP+1
    				print(""..sf("???? (0x004C), 0x%02X",u8a))
    
    			elseif cmd==0x64 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u32a=md(SRP) SRP=SRP+4
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("Movement[***] (0x0064) A=%s%d color=%s%d",fa,u16a,fb,u32a)) 
    
    			elseif cmd==0x65 then 
    				print(""..sf("WaitMovement (0x0065)"))
    
    			elseif cmd==0x68 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("StoreHeroPosition (0x0068) A=%s%d B=%s%d",fa,u16a,fb,u16b))
    
    			elseif cmd==0x6C then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("???? (0x006C)  %s%d",fa,u16a)) 
    
    
    			elseif cmd==0x6D then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa=""
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb=""
    					end
    				u16c=mw(SRP) SRP=SRP+2
    					if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000
    					elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000
    					else fc=""
    					end
    				u16d=mw(SRP) SRP=SRP+2
    					if u16d/0x8000>=1 then fd="Var_" u16d=u16d%0x4000
    					elseif u16d/0x4000>=1 then fd="Cont_" u16d=u16d%0x4000
    					else fd=""
    					end
    				u16e=mw(SRP) SRP=SRP+2
    					if u16e/0x8000>=1 then fe="Var_" u16e=u16e%0x4000
    					elseif u16e/0x4000>=1 then fe="Cont_" u16e=u16e%0x4000
    					else fe=""
    					end
    				print(""..sf("SetOWPos (0x006D) npc=%s%d x=%s%d y=%s%d z=%s%d dir=%s%d",fa,u16a,fb,u16b,fc,u16c,fd,u16d,fe,u16e))  
    
    			elseif cmd==0x74 then
    				print(""..sf("FacePlayer"))
    			elseif cmd==0x85 then
    				u16a=mw(SRP) SRP=SRP+2
    					if 	u16a/0x8000>=1 then 	fa="Var_"  u16a=u16a%0x4000
    					elseif 	u16a/0x4000>=1 then 	fa="Cont_" u16a=u16a%0x4000
    					else 				fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if 	u16b/0x8000>=1 then 	fb="Var_"  u16b=u16b%0x4000
    					elseif 	u16b/0x4000>=1 then 	fb="Cont_" u16b=u16b%0x4000
    					else 				fb="Num_"
    					end
    				u16c=mw(SRP) SRP=SRP+2
    					if 	u16c/0x8000>=1 then 	fc="Var_"  u16c=u16c%0x4000
    					elseif 	u16c/0x4000>=1 then 	fc="Cont_" u16c=u16c%0x4000
    					else 				fc="Num_"
    					end
    				print(""..sf("TrBattle (0x0085) Opp1=%s%d Opp2=%s%d Logic=%s%d",fa,u16a,fb,u16b,fc,u16c))
    
    			elseif cmd==0x8C then 
    				print(""..sf("EndBattle (0x008C)")) 
    
    			elseif cmd==0x8D then
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("SetVarBattleResult (0x008D) %s%d",fa,u16a))
    
    			elseif cmd==0x8E then 
    				print(""..sf("DisableTrainer (0x008E)")) 
    
    			elseif cmd==0xA6 then
    				u16a=mw(SRP) SRP=SRP+2
    				print(""..sf("PlaySound (0x00A6) opp1=0x%X opp2=0x%X logic=%d",u16a,u16b,u16c))
    
    
    
    			elseif cmd==0xCB then
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    				print(""..sf("StoreRand (0x00CB) %s%d rand(0x%d)",fa,u16a,u16b)) 
    
    
    			elseif cmd==0xCC then
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("SetVarQualItem (0x00CC) %s%d",fa,u16a))
    
    			elseif cmd==0xCD then
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("SetVarQual???? (0x00CD) %s%d",fa,u16a))
    
    
    
    			elseif cmd==0x227 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("??? (0x0227) A=%s%d B=%s%d",fa,u16a,fb,u16b))
    
    			elseif cmd==0x24F then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa=""
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb=""
    					end
    				u16c=mw(SRP) SRP=SRP+2
    					if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000
    					elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000
    					else fc=""
    					end
    				u16d=mw(SRP) SRP=SRP+2
    					if u16d/0x8000>=1 then fd="Var_" u16d=u16d%0x4000
    					elseif u16d/0x4000>=1 then fd="Cont_" u16d=u16d%0x4000
    					else fd=""
    					end
    				print(""..sf("????? (0x024F) A=%s%d B=%s%d C=%s%d D=%s%d",fa,u16a,fb,u16b,fc,u16c,fd,u16d))  
    		
    			elseif cmd==0x276 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				u16b=mw(SRP) SRP=SRP+2
    					if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000
    					elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000
    					else fb="Num_"
    					end
    				print(""..sf("??? (0x0276) A=%s%d B=%s%d",fa,u16a,fb,u16b))
    
    			elseif cmd==0x2C5 then 
    				u16a=mw(SRP) SRP=SRP+2
    					if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000
    					elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000
    					else fa="Num_"
    					end
    				print(""..sf("??? (0x02C5) A=%s%d",fa,u16a))
    
    
    
    
    
     			
    			else
    			print(""..sf("0x%X",cmd))
    			iterscr=iterscr+1
    			end
    		end
    
    
    
    
    
    
    
    		
    	end
    	
    	if goscrp==1 and scrnum<curscr then 
    	print(""..sf("~~~~~~Finish~~~~~~")) 
    	goscrp=2 end
    
    
    gt(1,70,sf("Total Scripts: %d",scrnum))
    gt(1,80,sf("Attempts: %d",iterhead))
    
    gt(1,90,sf("SRP: %08X",SRP))
    if goscrp==2 then gt(1,100,sf("~~~~~Finish~~~~~")) end
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    end
    gui.register(main)


    Some examples of what it creates in the Console window:

    http://pastebin.com/raw.php?i=72nRf1aa
    http://pastebin.com/raw.php?i=fRBaRPkv
    http://pastebin.com/raw.php?i=gMRLPeuR
    http://pastebin.com/raw.php?i=TpgbtWnF

    To use it, the script file must be already loaded in game. Talk to an NPC that uses a script from the script file so that the game will have it loaded in the memory. Some locations don't work, I've only tested it indoors.

    I'll be updating it when I get time, school comes first Unknown/Un-programmed commands can throw off the parse so in general don't trust anything when it starts reporting hex.
    Last edited by Kaphotics; Dec 2nd, 2012 at 10:17 AM.

  10. #10

    Re: Pokemon B/W Lua scripts

    Overworld Editing for BW/B2W2



    Edits a single memory value of all overworlds of a certain type (say NPC->Overworld Sprite) to help the user position/assign overworlds properly. Pretty useful in finding out overworld sprite values. Enable (and keep on) before a fade2black map change, not a seamless route change. Even though the pic is B2W2, it works in BW. Current setup is to edit the sprite of all overworld NPCs.

    Spoiler
    Code:
    local rshift, lshift=bit.rshift, bit.lshift
    local wd,ww,wb=memory.writedword,memory.writeword,memory.writebyte
    local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned
    mb=function(x) return rb(x) 							end
    mw=function(x) return rb(x)+rb(x+1)*0x100 					end
    md=function(x) return rb(x)+rb(x+1)*0x100+rb(x+2)*0x10000+rb(x+3)*0x1000000 	end
    local gt,sf=gui.text,string.format
    
    if mb(0x023FFE09)==0x00 then		-- Not "2" ~ Not B2/W2
    	  pos_m=md(0x02000024)+0x3461C
    	    zds=md(0x02000024)+0x3DFAC
    	ows=md(0x02000024)+0x34E04
    	game=1
    else
    	  pos_m=md(0x02000024)+0x36780
    	    zds=md(0x02000024)+0x41B2C
    	ows=md(0x02000024)+0x36BE8
    	game=2
    end
    
    local useupper=true
    local L8=0x01
    local U8=0x00
    local edit="NPC"
    
    local mapexit=1
    local offset=0x02 --sprite. change to 0xA for script reassigning
    
    
    
    function main()
    --L8=math.random(500)
    --mapexit=math.random(6)
    
    if edit=="Furniture" then mode=1 
    	mult=0x14 
    	editat=0x08+ows
    elseif edit=="NPC" then 
    	mode=2
    	mult=0x24 
    	editat=0x08+mb(0x04+ows)*0x14+ows
    elseif edit=="Warp" then 
    	mode=3
    	mult=0x14 
    	editat=0x08+mb(0x04+ows)*0x14+mb(0x05+ows)*0x24+ows
    elseif edit=="Trigger" then 
    	mode=4 
    	mult=0x16 
    	editat=0x08+mb(0x04+ows)*0x14+mb(0x05+ows)*0x24+mb(0x06+ows)*0x14+ows end
    count=mb(ows+3+mode)
    
    --word editing mode
    	if useupper==true then
    	if mw(editat+offset)~=(L8+U8*0x100) then i=0
    	   gt(1,00,sf("Map is Switching!"))
    		while i<count do
    			insert=(L8+U8*0x100)
    			if mode==3 then ww(i*mult+offset+editat+4,mapexit) end
    			ww(i*mult+offset+editat,insert)
    			i=i+1
    		end
    	end end
    
    --byte editing mode
    	if useupper==false then 
    	if mb(editat+offset)~=(L8) then i=0
    	   gt(1,00,sf("Map is Switching!"))
    		while i<count do
    			insert=(L8)
    			if mode==3 then ww(i*mult+offset+editat+4,mapexit) end
    			wb(i*mult+offset+editat,insert)
    			i=i+1
    		end
    	end end
    
    --Debug
    gt(1,10,sf("OW Data Start: %08X",ows))
    gt(1,20,sf("Desired Count: %d",count))
    gt(1,30,sf("Start of Desired Data: %08X",editat))
    gt(1,40,sf("Mode: %s",edit))
    
    end
    gui.register(main)
    Event Script writer for BW & B2/W2



    Replaces the first script of the current map with a customized event script. Be sure the current event script file is loaded before enabling in order to write to the proper area.

    Allows a user to test an event script in real time, and change up instructions on the fly rather than tinker with the ROM. Be sure to buffer the event script file that is being edited with zeroes such that a long custom script won't overwrite other important memory locations. This is how I tested both of my Scripted Event videos on my YouTube channel.

    Spoiler
    Code:
    local wb,md,gt,sf=memory.writebyte,memory.readdwordunsigned,gui.text,string.format
    local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned
    mb=function(x) return rb(x) 							end
    mw=function(x) return rb(x)+rb(x+1)*0x100 					end
    md=function(x) return rb(x)+rb(x+1)*0x100+rb(x+2)*0x10000+rb(x+3)*0x1000000 	end
    local i,j,x,t=1,1,1,{}
    
    if mb(0x023FFE09)==0x00 then		-- Not "2" ~ Not B2/W2
    	  pos_m=md(0x02000024)+0x3461C
    	    zds=md(0x02000024)+0x3DFAC
    	ows=md(0x02000024)+0x34E04
    	scstart=md(md(0x02000024)+0x41834)+md(0x02000024)+0x41838
    	game=1
    else
    	  pos_m=md(0x02000024)+0x36780
    	    zds=md(0x02000024)+0x41B2C
    	ows=md(0x02000024)+0x36BE8
    	scstart=md(md(0x02000024)+0x459A4)+md(0x02000024)+0x0459A8
    	game=2
    end
    
    function main()
    
    --List all portions of or script
    s1="2E 00"
    s2=""
    s3=""
    s4="02 00"
    
    --Concatenate all strings in order
    s=s1..s2..s3..s4
    
    --Remove spaces from eventscript so that we can add the script in
    s = string.gsub (s, " ", "")
    
    --Break up eventscript string into a table
    while i<=string.len(s) do
    	t[j] ="0x"..string.sub(s,i,i+1)
    	j=j+1
    	i=i+2
    end
    
    --Write script per byte via values in the table.
    while x<j do
    	wb(scstart+x-1,t[x])
    	--Graphical display of text
    	gt((x-1)%10*15,math.floor((x-1)/0xA)*10,sf("%02X",t[x]))
    	x=x+1
    end
    
    x=1
    end
    gui.register(main)
    Last edited by Kaphotics; Feb 16th, 2013 at 07:47 PM.

  11. #11
    Member
    Join Date
    May 2013
    Location
    Italy
    Age
    23
    Posts
    2

    Re: Pokemon B/W Lua scripts

    Maybe I am dumb...but does the lua script for RNG frame work only on BW 1?
    Because I use a similar one but I was looking for one to use on BW2 USA.

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
PPN Top 50