Kaphotics

Gen 3 Lua Scripts

27 posts in this topic

FractalFusion did some great work in regards to gen 3 TAS, and I stumbled upon some of his Lua scripts and wanted to improve upon them for RNG abuse.

The following scripts work for R/S, you have to change the memory offset in the script if you are on FRLG/E

Party PKM #1 PID/IV Display

party1gen3.png

-- http://tasvideos.org/forum/viewtopic.php?t=4101
-- http://tasvideos.org/forum/viewtopic.php?t=4101&postdays=0&postorder=asc&start=100 my post
-- http://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_data_structure_in_Generation_III
-- ruby/sapphire 0x03004360
-- emerald 0x02024190 J 0x020244EC U
-- firered 0x02024284
-- leafgreen 0x020241e4

-- 64
-- 4360 43C4 4428 448C 44F0 4554
-- 45C0 4624

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}

local start=0x03004360
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5


gui.text(0,0,"HP IV="..hpiv, "yellow")
gui.text(0,10,"Atk IV="..atkiv, "red")
gui.text(50,10,"Def IV="..defiv, "orange")
gui.text(50,0,"Spd IV="..spdiv, "green")
gui.text(0,20,"SpAtk IV="..spatkiv, "red")
gui.text(50,20,"SpDef IV="..spdefiv, "orange")

gui.text(0,30,"Species "..species)
gui.text(0,40,"Nature: "..naturename[nature+1])
gui.text(0,50,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(0,60,"PID: "..string.format("%08X", personality))


emu.frameadvance()

end

vvvvvvvvvvvvvvvvvvv

Edited by Kaphotics

Share this post


Link to post
Share on other sites

-- 64
-- 4360 43C4 4428 448C 44F0 4554
-- 45C0 4624

64 between each pkm in RAM

RS Party Pokemon Offsets

RS Enemy Pokemon offsets (single / double)

Edited by Kaphotics

Share this post


Link to post
Share on other sites

You have to change the offsets to the memory locations for the version you want.

Share this post


Link to post
Share on other sites

the offsets:

ruby/sapphire 0x03004360

emerald 0x02024190 J 0x020244EC U

firered 0x02024284

leafgreen 0x020241e4

are the same for Wild Pokemon?

Share this post


Link to post
Share on other sites

No those are for party Pokemon, not for the wild Pokemon. Someone would have to find those locations for the other games.

=0x030045C0 is for R/S.

see below, I found the offsets and edited the lua to make each one work on all english games.

Edited by Kaphotics

Share this post


Link to post
Share on other sites

R/S RNG Suite:

rsbattle.png

Download

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x030045C0
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03004818)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,vba.framecount()) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
print("Seed: "..string.format("%8X", seed))

emu.frameadvance()

end

FRLG RNG Suite:

frlgbattle.png

Download

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x0202402C
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03005000)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,vba.framecount()) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
print("Seed: "..string.format("%8X", seed))

emu.frameadvance()

end

Emerald RNG Suite:

emeraldbattle.png

Download

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x02024744
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03005D80)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,vba.framecount()) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
print("Seed: "..string.format("%8X", seed))

emu.frameadvance()

end

Share this post


Link to post
Share on other sites

I believe this works on Emerald (J):

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x020243E8
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03005AE0)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,vba.framecount()) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
print(""..string.format("%8X", seed))

emu.frameadvance()

end

The seed memory location is correct for sure but I'm not 100% sure on the enemy pokemon location. It seems to have worked so far though.

Edit: Too lazy to upload the file atm. Copy and paste it into a .txt file and change the extension to .lua.

Share this post


Link to post
Share on other sites

The Seed is correct, but the start is wrong, although I used an other one..

Share this post


Link to post
Share on other sites

Well the start memory location seems to be correct to me as it matched exactly when I looked at a pokemon in Enciclopedia Pokemon. If the address I have is wrong why don't you share yours?

Share this post


Link to post
Share on other sites

There's multiple places it can be.

If you don't find the right location you will probably find one that is DMA shifted.

Share this post


Link to post
Share on other sites

And here's JP Sapphire (and presumably JP Ruby)

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x030044F0
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03004748)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,vba.framecount()) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
print("Seed: "..string.format("%8X", seed))

emu.frameadvance()

end

Edit: I apologize for being short with you. It's just that a lot of people have been secretive about 3rd gen things for who knows how long while they only know what they know because of other people's work (ie. the guys who figured out the RNG mechanics in the first place).

Edited by Hozu

Share this post


Link to post
Share on other sites
Well the start memory location seems to be correct to me as it matched exactly when I looked at a pokemon in Enciclopedia Pokemon. If the address I have is wrong why don't you share yours?
I didn't want to offend you, sorry.
There's multiple places it can be.

If you don't find the right location you will probably find one that is DMA shifted.

Thanks Kaphotics!

Share this post


Link to post
Share on other sites

This is pretty cool.

I was thinking about something like this for 4th gen along time ago but never got around to doing it and then ended up forgetting about it completely. :(

Share this post


Link to post
Share on other sites

Bond697 made this fix a while ago for the Emerald script but it wasn't posted here so... This uses the game's RNG advancement counter rather than the video frame for Emerald (NA version) for consistency.

local natureorder={"Atk","Def","Spd","SpAtk","SpDef"}
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}
local typeorder={
"Fighting","Flying","Poison","Ground",
"Rock","Bug","Ghost","Steel",
"Fire","Water","Grass","Electric",
"Psychic","Ice","Dragon","Dark"}

local start=0x02024744
local personality
local trainerid
local magicword
local growthoffset
local miscoffset
local i
local rngframe=0x020249C0

local species
local ivs
local hpiv
local atkiv
local defiv
local spdiv
local spatkiv
local spdefiv
local nature
local natinc
local natdec
local hidpowbase
local hidpowtype

while true do

personality=memory.readdwordunsigned(start)
trainerid=memory.readdwordunsigned(start+4)
magicword=bit.bxor(personality, trainerid)
seed=memory.readdwordunsigned(0x03005D80)

i=personality%24

if i<=5 then
 growthoffset=0
elseif i%6<=1 then
 growthoffset=12
elseif i%2==0 then
 growthoffset=24
else
 growthoffset=36
end

if i>=18 then
 miscoffset=0
elseif i%6>=4 then
 miscoffset=12
elseif i%2==1 then
 miscoffset=24
else
 miscoffset=36
end

species=bit.band(bit.bxor(memory.readdwordunsigned(start+32+growthoffset),magicword),0xFFF)

ivs=bit.bxor(memory.readdwordunsigned(start+32+miscoffset+4),magicword)

hpiv=bit.band(ivs,0x1F)
atkiv=bit.band(ivs,0x1F*0x20)/0x20
defiv=bit.band(ivs,0x1F*0x400)/0x400
spdiv=bit.band(ivs,0x1F*0x8000)/0x8000
spatkiv=bit.band(ivs,0x1F*0x100000)/0x100000
spdefiv=bit.band(ivs,0x1F*0x2000000)/0x2000000

nature=personality%25
natinc=math.floor(nature/5)
natdec=nature%5

hidpowtype=math.floor(((hpiv%2 + 2*(atkiv%2) + 4*(defiv%2) + 8*(spdiv%2) + 16*(spatkiv%2) + 32*(spdefiv%2))*15)/63)
hidpowbase=math.floor(((bit.band(hpiv,2)/2 + bit.band(atkiv,2) + 2*bit.band(defiv,2) + 4*bit.band(spdiv,2) + 8*bit.band(spatkiv,2) + 16*bit.band(spdefiv,2))*40)/63 + 30)

gui.text(0,0,"Stats")
gui.text(30,0,"HP  "..memory.readwordunsigned(start+86))
gui.text(65,0,"Atk "..memory.readwordunsigned(start+90))
gui.text(99,0,"Def "..memory.readwordunsigned(start+92))
gui.text(133,0,"SpA "..memory.readwordunsigned(start+96))
gui.text(167,0,"SpD "..memory.readwordunsigned(start+98))
gui.text(201,0,"Spe "..memory.readwordunsigned(start+94))

gui.text(0,8,"IVs")
gui.text(30,8,"HP  "..hpiv)
gui.text(65,8,"Atk "..atkiv)
gui.text(99,8,"Def "..defiv)
gui.text(133,8,"SpA "..spatkiv)
gui.text(167,8,"SpD "..spdefiv)
gui.text(201,8,"Spe "..spdiv)

gui.text(0,40,"PID:  "..string.format("%08X", personality))
gui.text(60,40,"IVs: "..string.format("%08X", ivs))
gui.text(0,50,"Nature: "..naturename[nature+1])
gui.text(0,60,natureorder[natinc+1].."+ "..natureorder[natdec+1].."-")
gui.text(167,15,"HP "..typeorder[hidpowtype+1].." "..hidpowbase)
gui.text(0,95,"Frame "..memory.readdwordunsigned(rngframe)) 
gui.text(0,105,"Seed: "..string.format("%8X", seed))
--print("Seed: "..string.format("%8X", seed))

emu.frameadvance()

end

Share this post


Link to post
Share on other sites

Pokemon Emerald (U)

Emerald Egg Tracking RNG Suite

rL1a7.png

local rng
local timer
local offset 
local pidpointer=0x0203BC78
local pidoffset
local pid
local iter=0
local base=0
local a
local timerseed=0
local stepcounter
local nature
local ids
local tid
local sid
local lpid
local hpid
local shiny
local naturename={
"Hardy","Lonely","Brave","Adamant","Naughty",
"Bold","Docile","Relaxed","Impish","Lax",
"Timid","Hasty","Serious","Jolly","Naive",
"Modest","Mild","Quiet","Bashful","Rash",
"Calm","Gentle","Sassy","Careful","Quirky"}

while true do 	

a=memory.readdwordunsigned(0x03005D84)
rng = memory.readwordunsigned(0x020249C0)
timer = memory.readwordunsigned(0x030022E4)
offset = math.floor(rng - timer)
pidoffset = math.floor(memory.readdwordunsigned(pidpointer) + 0x988)
pid = memory.readdwordunsigned(pidoffset)
nature = math.floor(pid % 0x19)
stepcounter = memory.readbyteunsigned(math.floor(pidoffset - 0x4,2))
ids = memory.readdwordunsigned(0x020244F0)
sid = math.floor(ids / 65536)
tid = ids % 0x10000
hpid = math.floor(pid / 65536)
lpid = pid % 0x10000
shiny = bit.bxor(bit.bxor(sid,tid),bit.bxor(lpid,hpid))

gui.text(199,140, string.format("TID: %d", tid))
gui.text(199,150,string.format("SID: %d", sid))
gui.text(1,1, string.format("RNG Information:"))
gui.text(1, 10, string.format("RNG Frame   -  %d", memory.readword(0x020249C0))) 
gui.text(1, 19, string.format("Timer Value -  %d", memory.readword(0x030022E4)))
gui.text(1, 28, string.format("Difference  -  %d", offset))
gui.text(1, 46, string.format("tRNG %08X", memory.readdwordunsigned(0x03005D84)))
gui.text(1, 55, string.format("pRNG %08X", memory.readdwordunsigned(0x03005D80)))

if a == 0 then 
	base = offset
	iter = 0 
elseif a > 0 then 
	if base == base and iter < 1 then
		iter = math.floor(offset - base - 5) 
	else 
		base = offset
	end
end

if a == 0 then
	if pid == 0 then
		gui.text(1, 73, string.format("No Egg."))
	else
		gui.text(1, 73, string.format("PID %08X", pid))
		gui.text(1, 82,"Nature: "..naturename[nature+1])
	end

elseif a < 65536 then
	gui.text(1, 73, string.format("Egg Generating... please advance another frame!"))
	gui.text(1, 82, string.format("tRNG seeded, no temporary PID testing yet..."))

elseif math.floor(memory.readdwordunsigned(0x03007D98)/65536) == math.floor(a/65536) then
	gui.text(1, 73, string.format("Egg Generating... please advance another frame!"))
	gui.text(1, 82, string.format("TempPID %08X", memory.readdwordunsigned(0x03007D98)))

else
	gui.text(1, 73, string.format("PID %08X", pid))
--		gui.text(1, 91, string.format("loc %08X", pidoffset))

		gui.text(1, 82,"Nature: "..naturename[nature+1])
	if shiny < 8 then
		gui.text(1, 64, string.format("SHINY!!!"))
	end 

	if iter > 1 then
		gui.text(1, 110, string.format("stone worked!"))
		gui.text(1, 100, string.format("approx iter: %d", iter))
	else
		gui.text(1, 110, string.format("stone failed?"))
		gui.text(1, 100, string.format("first egg PID result"))
	end
end

	gui.text(1,130,string.format("Step Counter: %02X", stepcounter))
if pid > 0 then
	gui.text(1,140,string.format("Egg Generated, go get it!"))
elseif stepcounter == 254 then
	gui.text(1,140,string.format("Next Step might generate an egg!"))
elseif stepcounter == 255 then
	gui.text(1,140,string.format("255th Step Taken."))
else
	gui.text(1,140,string.format("Keep on steppin'"))
end

emu.frameadvance() 
end

fixed shiny check, fixed walking outside preservation

Edited by Kaphotics

Share this post


Link to post
Share on other sites

Does anyong here have the memory address of the ID/SID in PKMN FR English version? I was able to use the Emerald script's part on Sapphire but with the Sapphire address for the ID/SID to display those attributes, now I would like to do the same for Fire Red. Or if possible coud one upload a script with the ability to see the ID/SID in Fire Red please?

Share this post


Link to post
Share on other sites

Pretty sure it's DMA shifted every time, but after 3 times I found it at 02024288.

Anyways you can just use a save editor to find your ID/SID.

Share this post


Link to post
Share on other sites

Thanks Kaphotics. I just needed this because I had been RNG'ing ID/SID in Fire Red and it was frustrating having to save state and collect a starter each time to identfy if it had worked.

Share this post


Link to post
Share on other sites

PID Frame Check for Emerald

5j4hD.jpg

local pid=0xPUT THE ENTIRE HEX PID HERE
local mf,sf,pr=math.floor,string.format,print
local ts,f,d,cp=0,0,0,0

function rand(s)
return (0x4e6d*(s%65536)+((0x41C6*(s%65536)+0x4e6d*mf(s/65536))%65536)*65536+0x6073)%(4294967296)
end

function main()
  while cp ~= pid do
ts=rand(ts)+0
cp=mf(rand(ts)/65536)*0x10000+mf(ts/65536)
f=f+1
  end

  if d==0 then
pr("PID: "..sf("%5XXXX", mf(pid/4096)))
pr("RNG Frame: "..sf("%d", f))
pr("Seconds: "..sf("%.2f", f/60))
if f<10000 then pr("Seems like a soft reset!") end
d=1 
  end
end

gui.register(main)

checks the earliest frame that a PID can occur for emerald... just a small script to easily see if an upload is a plausible soft reset

Share this post


Link to post
Share on other sites

The script to view your Pokemon's IV stats (the one in your party) didn't work for FR/LG (yes, I swapped the offsets).

Share this post


Link to post
Share on other sites

here is the deal.. the download for the emerald lua script is down and when i try to copy/paste the code into notepad and change the .txt to .lua and then load it into the lua script in VBA, it doesnt load into the output. what am i doing wrong..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now