Jump to content

Gen 3 Lua Scripts


Recommended Posts

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
Link to comment
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
Link to comment
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

Link to comment
Share on other sites

  • 3 weeks later...

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.

Link to comment
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
Link to comment
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!
Link to comment
Share on other sites

  • 6 months later...

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

Link to comment
Share on other sites

  • 1 month later...

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
  • Like 1
Link to comment
Share on other sites

  • 8 months later...

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?

Link to comment
Share on other sites

  • 5 months later...

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

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  • 3 months later...

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
×
×
  • Create New...