├── .gitignore
├── Gen 1
├── BizHawk
│ └── RBGY_Bot_BizHawk.lua
└── VBA
│ └── RBGY_Bot_VBA.lua
├── Gen 3
├── Dolphin
│ ├── Ageto_Celebi_RNG_Dolphin.lua
│ ├── Channel_RNG_Dolphin.lua
│ ├── Colo_Pikachu_RNG_Dolphin.lua
│ ├── Colosseum_Light_RNG_Dolphin.lua
│ ├── Colosseum_RNG_Dolphin.lua
│ └── XD_RNG_Dolphin.lua
└── mGBA
│ ├── E_RNG_mGBA.lua
│ ├── FRLG_RNG_mGBA.lua
│ ├── RS_RNG_Checksums_mGBA.lua
│ └── RS_RNG_mGBA.lua
├── Gen 4
├── BizHawk
│ ├── DP_RNG_BizHawk.lua
│ ├── HGSS_RNG_BizHawk.lua
│ └── Pt_RNG_BizHawk.lua
└── DeSmuMe
│ ├── DP_RNG_DeSmuMe.lua
│ ├── HGSS_RNG_DeSmuMe.lua
│ └── Pt_RNG_DeSmuMe.lua
├── Gen 5
├── BizHawk
│ ├── B2W2_RNG_BizHawk.lua
│ └── BW_RNG_BizHawk.lua
└── DeSmuMe
│ ├── B2W2_RNG_DeSmuMe.lua
│ └── BW_RNG_DeSmuMe.lua
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Lua sources
2 | luac.out
3 |
4 | # luarocks build files
5 | *.src.rock
6 | *.zip
7 | *.tar.gz
8 |
9 | # Object files
10 | *.o
11 | *.os
12 | *.ko
13 | *.obj
14 | *.elf
15 |
16 | # Precompiled Headers
17 | *.gch
18 | *.pch
19 |
20 | # Libraries
21 | *.lib
22 | *.a
23 | *.la
24 | *.lo
25 | *.def
26 | *.exp
27 |
28 | # Shared objects (inc. Windows DLLs)
29 | *.dll
30 | *.so
31 | *.so.*
32 | *.dylib
33 |
34 | # Executables
35 | *.exe
36 | *.out
37 | *.app
38 | *.i*86
39 | *.x86_64
40 | *.hex
41 |
42 | #Visual Studio folder
43 | .vscode
44 |
45 | #Save States file
46 | *.txt
47 |
--------------------------------------------------------------------------------
/Gen 1/BizHawk/RBGY_Bot_BizHawk.lua:
--------------------------------------------------------------------------------
1 | read16Bit = memory.read_u16_be
2 | read8Bit = memory.readbyte
3 | rshift = bit.rshift
4 | band = bit.band
5 |
6 | local speciesNamesList = {
7 | "Rhydon", "Kangaskhan", "Nidoran♂", "Clefairy", "Spearow", "Voltorb", "Nidoking", "Slowbro",
8 | "Ivysaur", "Exeggutor", "Lickitung", "Exeggcute", "Grimer", "Gengar", "Nidoran♀", "Nidoqueen",
9 | "Cubone", "Rhyhorn", "Lapras", "Arcanine", "Mew", "Gyarados", "Shellder", "Tentacool", "Gastly",
10 | "Scyther", "Staryu", "Blastoise", "Pinsir", "Tangela", "MissingNo.", "MissingNo.", "Growlithe",
11 | "Onix", "Fearow", "Pidgey", "Slowpoke", "Kadabra", "Graveler", "Chansey", "Machoke", "Mr. Mime",
12 | "Hitmonlee", "Hitmonchan", "Arbok", "Parasect", "Psyduck", "Drowzee", "Golem", "MissingNo.",
13 | "Magmar", "MissingNo.", "Electabuzz", "Magneton", "Koffing", "MissingNo.", "Mankey", "Seel",
14 | "Diglett", "Tauros", "MissingNo.", "MissingNo.", "MissingNo.", "Farfetch'd", "Venonat",
15 | "Dragonite", "MissingNo.", "MissingNo.", "MissingNo.", "Doduo", "Poliwag", "Jynx", "Moltres",
16 | "Articuno", "Zapdos", "Ditto", "Meowth", "Krabby", "MissingNo.", "MissingNo.", "MissingNo.",
17 | "Vulpix", "Ninetales", "Pikachu", "Raichu", "MissingNo.", "MissingNo.", "Dratini", "Dragonair",
18 | "Kabuto", "Kabutops", "Horsea", "Seadra", "MissingNo.", "MissingNo.", "Sandshrew", "Sandslash",
19 | "Omanyte", "Omastar", "Jigglypuff", "Wigglytuff", "Eevee", "Flareon", "Jolteon", "Vaporeon",
20 | "Machop", "Zubat", "Ekans", "Paras", "Poliwhirl", "Poliwrath", "Weedle", "Kakuna", "Beedrill",
21 | "MissingNo.", "Dodrio", "Primeape", "Dugtrio", "Venomoth", "Dewgong", "MissingNo.", "MissingNo.",
22 | "Caterpie", "Metapod", "Butterfree", "Machamp", "MissingNo.", "Golduck", "Hypno", "Golbat",
23 | "Mewtwo", "Snorlax", "Magikarp", "MissingNo.", "MissingNo.", "Muk", "MissingNo.", "Kingler",
24 | "Cloyster", "MissingNo.", "Electrode", "Clefable", "Weezing", "Persian", "Marowak", "MissingNo.",
25 | "Haunter", "Abra", "Alakazam", "Pidgeotto", "Pidgeot", "Starmie", "Bulbasaur", "Venusaur",
26 | "Tentacruel", "MissingNo.", "Goldeen", "Seaking", "MissingNo.", "MissingNo.", "MissingNo.",
27 | "MissingNo.", "Ponyta", "Rapidash", "Rattata", "Raticate", "Nidorino", "Nidorina", "Geodude",
28 | "Porygon", "Aerodactyl", "MissingNo.", "Magnemite", "MissingNo.", "MissingNo.", "Charmander",
29 | "Squirtle", "Charmeleon", "Wartortle", "Charizard", "MissingNo.", "MissingNo.", "MissingNo.",
30 | "MissingNo.", "Oddish", "Gloom", "Vileplume", "Bellsprout", "Weepinbell", "Victreebel"}
31 |
32 | local natureNamesList = {
33 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
34 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
35 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
36 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
37 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
38 |
39 | local versionAddr = read16Bit(0x13C)
40 | local version
41 | local languageAddr = read8Bit(0x14E)
42 | local language = ""
43 | local warning
44 |
45 | local emuWindow = {}
46 | local mode = {"None", "Gift Bot", "Stationary Bot", "Fishing Bot", "In-Game Trade Bot", "TID Bot", "Pokemon Info"}
47 | local index = 1
48 | local prevKey = {}
49 | local showInstructionsText = false
50 | local leftArrowColor
51 | local rightArrowColor
52 |
53 | local botOneTime = false
54 |
55 | local partyAddr
56 | local partySlotsCounterAddr
57 | local wildDVsAddr
58 | local shinyFound = {false, "None"}
59 |
60 | local botTargetFishingSpecies = 27 -- Input here the fishing bot target species index. You can find it in the link below
61 | -- https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_index_number_(Generation_I)
62 | local fishedSpeciesAddr
63 | local biteFlagAddr = 0xCD3D
64 |
65 | local tidAddr
66 | local TIDFound = false
67 | local botTargetTIDs = {0, 1, 1337, 8453, 8411, 11233, 11111, 22222, 33333} -- Input here the bot target TIDs
68 |
69 | if versionAddr == 0x414C then -- Check game version
70 | version = "Crystal"
71 | elseif versionAddr == 0x424C then
72 | version = "Blue"
73 | elseif versionAddr == 0x474C then
74 | version = "Gold"
75 | elseif versionAddr == 0x5245 then
76 | version = "Red"
77 | elseif versionAddr == 0x4752 then
78 | version = "Green"
79 | elseif versionAddr == 0x534C then
80 | version = "Silver"
81 | elseif versionAddr == 0x5945 then
82 | version = "Yellow"
83 | else
84 | version = "Unknown"
85 | end
86 |
87 | if languageAddr == 0x04 or languageAddr == 0x91 or languageAddr == 0x9D then -- Check game language and set addresses
88 | language = "USA"
89 |
90 | if version == "Blue" or version == "Red" then
91 | partyAddr = 0xD16B
92 | partySlotsCounterAddr = 0xD163
93 | wildDVsAddr = 0xCFF1
94 | fishedSpeciesAddr = 0xD059
95 | tidAddr = 0xD359
96 | elseif version == "Yellow" then
97 | partyAddr = 0xD16A
98 | partySlotsCounterAddr = 0xD162
99 | wildDVsAddr = 0xCFF0
100 | fishedSpeciesAddr = 0xD058
101 | tidAddr = 0xD358
102 | end
103 | elseif languageAddr == 0xB8 or languageAddr == 0xD9 or languageAddr == 0xDC or languageAddr == 0xF5 then
104 | language = "JPN"
105 | partyAddr = 0xD12B
106 | partySlotsCounterAddr = 0xD123
107 | wildDVsAddr = 0xCFD8
108 | fishedSpeciesAddr = 0xD036
109 | tidAddr = 0xD2D8
110 | else
111 | language = "EUR"
112 |
113 | if version == "Blue" or version == "Red" then
114 | partyAddr = 0xD170
115 | partySlotsCounterAddr = 0xD168
116 | wildDVsAddr = 0xCFF6
117 | fishedSpeciesAddr = 0xD05E
118 | tidAddr = 0xD35E
119 | elseif version == "Yellow" then
120 | partyAddr = 0xD16F
121 | partySlotsCounterAddr = 0xD167
122 | wildDVsAddr = 0xCFF5
123 | fishedSpeciesAddr = 0xD05D
124 | tidAddr = 0xD35D
125 | end
126 | end
127 |
128 | if version ~= "Blue" and version ~= "Red" and version ~= "Green" and version ~= "Yellow" then
129 | warning = " - Wrong game version! Use Blue/Red/Green/Yellow instead"
130 | else
131 | warning = ""
132 | end
133 |
134 | console.clear()
135 | print("Game Version: "..version..warning)
136 | print("Language: "..language)
137 | print("")
138 |
139 | function getScreenDimensions()
140 | emuWindow.height = client.screenheight()
141 | emuWindow.width = client.screenwidth()
142 | emuWindow.topPadding = client.borderheight()
143 | emuWindow.leftPadding = client.borderwidth()
144 | emuWindow.bottomPadding = emuWindow.height - emuWindow.topPadding - 18
145 | emuWindow.rightPadding = emuWindow.width - emuWindow.leftPadding - 18
146 | end
147 |
148 | function getInput()
149 | leftArrowColor = "gray"
150 | rightArrowColor = "gray"
151 |
152 | local key = input.get()
153 |
154 | if (key["Number1"] or key["Keypad1"]) and (not prevKey["Number1"] and not prevKey["Keypad1"]) then
155 | leftArrowColor = "orange"
156 | index = index - 1 < 1 and 7 or index - 1
157 | elseif (key["Number2"] or key["Keypad2"]) and (not prevKey["Number2"] and not prevKey["Keypad2"]) then
158 | rightArrowColor = "orange"
159 | index = index + 1 > 7 and 1 or index + 1
160 | end
161 |
162 | prevKey = key
163 | gui.text(emuWindow.leftPadding + 1, emuWindow.topPadding, "Mode: "..mode[index])
164 | drawArrowLeft(102, 0, leftArrowColor)
165 | gui.text((emuWindow.width / 2) + 100, emuWindow.topPadding, "1 - 2")
166 | drawArrowRight(140, 0, rightArrowColor)
167 | end
168 |
169 | function drawArrowLeft(a, b, c)
170 | gui.drawLine(a, b + 3, a + 2, b + 5, c)
171 | gui.drawLine(a, b + 3, a + 2, b + 1, c)
172 | gui.drawLine(a, b + 3, a + 6, b + 3, c)
173 | end
174 |
175 | function drawArrowRight(a, b, c)
176 | gui.drawLine(a, b + 3, a - 2, b + 5, c)
177 | gui.drawLine(a, b + 3, a - 2, b + 1, c)
178 | gui.drawLine(a, b + 3, a - 6, b + 3, c)
179 | end
180 |
181 | function getDVs(DVsAddr)
182 | local atkDefDVs = read8Bit(DVsAddr)
183 | local speSpcDVs = read8Bit(DVsAddr + 0x1)
184 | local atkDV = rshift(atkDefDVs, 4)
185 | local defDV = band(atkDefDVs, 0xF)
186 | local speDV = rshift(speSpcDVs, 4)
187 | local spcDV = band(speSpcDVs, 0xF)
188 |
189 | return atkDV, defDV, speDV, spcDV
190 | end
191 |
192 | function isShiny(atkDV, defDV, speDV, spcDV)
193 | return {defDV == 0xA and speDV == 0xA and spcDV == 0xA and
194 | (atkDV == 0x2 or atkDV == 0x3 or atkDV == 0x6 or atkDV == 0x7 or
195 | atkDV == 0xA or atkDV == 0xB or atkDV == 0xE or atkDV == 0xF), mode[index]}
196 | end
197 |
198 | function shinyBotLoop(pokemonDVsAddr)
199 | shinyFound = {false, "None"}
200 | botOneTime = false
201 |
202 | while not shinyFound[1] do
203 | savestate.save(0)
204 | joypad.set({A = true})
205 | local frameLimit
206 |
207 | if mode[index] == "Gift Bot" or mode[index] == "Stationary Bot" then
208 | frameLimit = 35
209 | elseif mode[index] == "Fishing Bot" then
210 | frameLimit = 55
211 | elseif mode[index] == "In-Game Trade Bot" then
212 | frameLimit = 2560
213 | end
214 |
215 | local atkDefDVs = read8Bit(pokemonDVsAddr)
216 | local speSpcDVs = read8Bit(pokemonDVsAddr + 1)
217 | local previousAtkDefDVs = atkDefDVs
218 | local previousSpeSpcDVs = speSpcDVs
219 |
220 | local i = 0
221 | while atkDefDVs == previousAtkDefDVs and speSpcDVs == previousSpeSpcDVs and i < frameLimit do
222 | atkDefDVs = read8Bit(pokemonDVsAddr)
223 | speSpcDVs = read8Bit(pokemonDVsAddr + 1)
224 | emu.frameadvance()
225 | i = i + 1
226 | end
227 |
228 | if atkDefDVs ~= previousAtkDefDVs or speSpcDVs ~= previousSpeSpcDVs then
229 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
230 | --print(atkDV.." "..defDV.." "..speDV.." "..spcDV)
231 | shinyFound = isShiny(atkDV, defDV, speDV, spcDV)
232 | end
233 |
234 | if not shinyFound[1] then
235 | savestate.load(0)
236 | emu.frameadvance()
237 | end
238 | end
239 | end
240 |
241 | function showFoundShiny(pokemonDVsAddr)
242 | if shinyFound[1] and shinyFound[2] == mode[index] then
243 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
244 | local hpDV = ((atkDV % 2) * 8) + ((defDV % 2) * 4) + ((speDV % 2) * 2) + (spcDV % 2)
245 |
246 | gui.text(emuWindow.leftPadding + 1, emuWindow.height / 2, "Shiny Found!")
247 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 18, string.format("Hp: %d", hpDV))
248 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 36, string.format("Atk: %d", atkDV))
249 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 54, string.format("Def: %d", defDV))
250 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 72, string.format("SpC: %d", spcDV))
251 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 90, string.format("Spe: %d", speDV))
252 |
253 | if not botOneTime then
254 | print("Shiny Found!")
255 | client.pause()
256 | botOneTime = true
257 | end
258 | end
259 | end
260 |
261 | function shinyBot(pokemonDVsAddr)
262 | local key = joypad.get()
263 |
264 | if key.Select then
265 | shinyBotLoop(pokemonDVsAddr)
266 | end
267 |
268 | showFoundShiny(pokemonDVsAddr)
269 | end
270 |
271 | function fishingBotBiteLoop()
272 | local biteFlag = false
273 |
274 | while not biteFlag do
275 | savestate.save(0)
276 | joypad.set({A = true})
277 |
278 | local i = 0
279 | while not biteFlag and i < 110 do
280 | biteFlag = read8Bit(biteFlagAddr) == 0x1
281 | emu.frameadvance()
282 | i = i + 1
283 | end
284 |
285 | if not biteFlag then
286 | savestate.load(0)
287 | emu.frameadvance()
288 | end
289 | end
290 | end
291 |
292 | function fishingBotLoop()
293 | local targetFishedSpeciesCheck = read8Bit(fishedSpeciesAddr) == botTargetFishingSpecies
294 |
295 | while not targetFishedSpeciesCheck do
296 | fishingBotBiteLoop()
297 | targetFishedSpeciesCheck = read8Bit(fishedSpeciesAddr) == botTargetFishingSpecies
298 |
299 | if not targetFishedSpeciesCheck then
300 | savestate.load(0)
301 | emu.frameadvance()
302 | end
303 | end
304 |
305 | for i = 1, 240 do
306 | emu.frameadvance()
307 | end
308 |
309 | shinyBotLoop(wildDVsAddr)
310 | end
311 |
312 | function fishingBot(pokemonDVsAddr)
313 | local key = joypad.get()
314 |
315 | if key.Select then
316 | fishingBotLoop()
317 | end
318 |
319 | showFoundShiny(pokemonDVsAddr)
320 | end
321 |
322 | function isTIDFound()
323 | local TID = read16Bit(tidAddr)
324 |
325 | for i = 1, table.getn(botTargetTIDs) do
326 | if TID == botTargetTIDs[i] then
327 | return true
328 | end
329 | end
330 |
331 | return false
332 | end
333 |
334 | function TIDBotLoop()
335 | TIDFound = false
336 | botOneTime = false
337 |
338 | while not TIDFound do
339 | savestate.save(0)
340 | joypad.set({A = true})
341 |
342 | local isTIDSet = read16Bit(tidAddr + 0x4) ~= 0
343 |
344 | local i = 0
345 | while not isTIDSet and i < 35 do
346 | isTIDSet = read16Bit(tidAddr + 0x4) ~= 0
347 | emu.frameadvance()
348 | i = i + 1
349 | end
350 |
351 | if isTIDSet then
352 | --print(read16Bit(tidAddr))
353 | TIDFound = isTIDFound()
354 | end
355 |
356 | if not TIDFound then
357 | savestate.load(0)
358 | emu.frameadvance()
359 | end
360 | end
361 | end
362 |
363 | function showFoundTID()
364 | if TIDFound then
365 | local TID = read16Bit(tidAddr)
366 |
367 | gui.text(emuWindow.leftPadding + 1, emuWindow.height / 2, "TID Found!")
368 | gui.text(emuWindow.leftPadding + 1, (emuWindow.height / 2) + 18, "TID: "..TID)
369 |
370 | if not botOneTime then
371 | print("TID Found!")
372 | client.pause()
373 | botOneTime = true
374 | end
375 | end
376 | end
377 |
378 | function TIDBot()
379 | local key = joypad.get()
380 |
381 | if key.Select then
382 | TIDBotLoop()
383 | end
384 |
385 | showFoundTID()
386 | end
387 |
388 | function shinyText(atkDV, defDV, speDV, spcDV)
389 | return isShiny(atkDV, defDV, speDV, spcDV)[1] and "\tShiny" or ""
390 | end
391 |
392 | function showPartyPokemonInfo()
393 | local partySlotsCounter = read8Bit(partySlotsCounterAddr) - 1
394 |
395 | gui.text(emuWindow.leftPadding + 1, 36, "Party natures:")
396 |
397 | for i = 0, partySlotsCounter do
398 | local pokemonSpeciesName = speciesNamesList[read8Bit(partyAddr + (i * 0x2C))]
399 | local pokemonEXPAddr = partyAddr + 0xE + (i * 0x2C)
400 | local pokemonDVsAddr = partyAddr + 0x1B + (i * 0x2C)
401 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
402 | local pokemonEXP = (0x10000 * read8Bit(pokemonEXPAddr)) + (0x100 * read8Bit(pokemonEXPAddr + 0x1)) + read8Bit(pokemonEXPAddr + 0x2)
403 | local pokemonNatureName = natureNamesList[(pokemonEXP % 25) + 1]
404 |
405 | if pokemonSpeciesName ~= nil then
406 | gui.text(emuWindow.leftPadding + 1, (i + 3) * 18, tostring(i + 1).." "..pokemonSpeciesName.."\t"..pokemonNatureName..shinyText(atkDV, defDV, speDV, spcDV))
407 | end
408 | end
409 | end
410 |
411 | while warning == "" do
412 | getScreenDimensions()
413 | getInput()
414 |
415 | if mode[index] == "Gift Bot" or mode[index] == "In-Game Trade Bot" then
416 | local partySlotsCounter = read8Bit(partySlotsCounterAddr) - 1
417 | local lastPartySlotDVsAddr = partyAddr + 0x1B + (partySlotsCounter * 0x2C)
418 | shinyBot(lastPartySlotDVsAddr)
419 | elseif mode[index] == "Stationary Bot" then
420 | shinyBot(wildDVsAddr)
421 | elseif mode[index] == "Fishing Bot" then
422 | fishingBot(wildDVsAddr)
423 | elseif mode[index] == "TID Bot" then
424 | TIDBot()
425 | elseif mode[index] == "Pokemon Info" then
426 | showPartyPokemonInfo()
427 | end
428 |
429 | emu.frameadvance()
430 | end
--------------------------------------------------------------------------------
/Gen 1/VBA/RBGY_Bot_VBA.lua:
--------------------------------------------------------------------------------
1 | read16Bit = memory.readwordunsigned
2 | read8Bit = memory.readbyte
3 | rshift = bit.rshift
4 | band = bit.band
5 |
6 | local speciesNamesList = {
7 | "Rhydon", "Kangaskhan", "Nidoran♂", "Clefairy", "Spearow", "Voltorb", "Nidoking", "Slowbro",
8 | "Ivysaur", "Exeggutor", "Lickitung", "Exeggcute", "Grimer", "Gengar", "Nidoran♀", "Nidoqueen",
9 | "Cubone", "Rhyhorn", "Lapras", "Arcanine", "Mew", "Gyarados", "Shellder", "Tentacool", "Gastly",
10 | "Scyther", "Staryu", "Blastoise", "Pinsir", "Tangela", "MissingNo.", "MissingNo.", "Growlithe",
11 | "Onix", "Fearow", "Pidgey", "Slowpoke", "Kadabra", "Graveler", "Chansey", "Machoke", "Mr. Mime",
12 | "Hitmonlee", "Hitmonchan", "Arbok", "Parasect", "Psyduck", "Drowzee", "Golem", "MissingNo.",
13 | "Magmar", "MissingNo.", "Electabuzz", "Magneton", "Koffing", "MissingNo.", "Mankey", "Seel",
14 | "Diglett", "Tauros", "MissingNo.", "MissingNo.", "MissingNo.", "Farfetch'd", "Venonat",
15 | "Dragonite", "MissingNo.", "MissingNo.", "MissingNo.", "Doduo", "Poliwag", "Jynx", "Moltres",
16 | "Articuno", "Zapdos", "Ditto", "Meowth", "Krabby", "MissingNo.", "MissingNo.", "MissingNo.",
17 | "Vulpix", "Ninetales", "Pikachu", "Raichu", "MissingNo.", "MissingNo.", "Dratini", "Dragonair",
18 | "Kabuto", "Kabutops", "Horsea", "Seadra", "MissingNo.", "MissingNo.", "Sandshrew", "Sandslash",
19 | "Omanyte", "Omastar", "Jigglypuff", "Wigglytuff", "Eevee", "Flareon", "Jolteon", "Vaporeon",
20 | "Machop", "Zubat", "Ekans", "Paras", "Poliwhirl", "Poliwrath", "Weedle", "Kakuna", "Beedrill",
21 | "MissingNo.", "Dodrio", "Primeape", "Dugtrio", "Venomoth", "Dewgong", "MissingNo.", "MissingNo.",
22 | "Caterpie", "Metapod", "Butterfree", "Machamp", "MissingNo.", "Golduck", "Hypno", "Golbat",
23 | "Mewtwo", "Snorlax", "Magikarp", "MissingNo.", "MissingNo.", "Muk", "MissingNo.", "Kingler",
24 | "Cloyster", "MissingNo.", "Electrode", "Clefable", "Weezing", "Persian", "Marowak", "MissingNo.",
25 | "Haunter", "Abra", "Alakazam", "Pidgeotto", "Pidgeot", "Starmie", "Bulbasaur", "Venusaur",
26 | "Tentacruel", "MissingNo.", "Goldeen", "Seaking", "MissingNo.", "MissingNo.", "MissingNo.",
27 | "MissingNo.", "Ponyta", "Rapidash", "Rattata", "Raticate", "Nidorino", "Nidorina", "Geodude",
28 | "Porygon", "Aerodactyl", "MissingNo.", "Magnemite", "MissingNo.", "MissingNo.", "Charmander",
29 | "Squirtle", "Charmeleon", "Wartortle", "Charizard", "MissingNo.", "MissingNo.", "MissingNo.",
30 | "MissingNo.", "Oddish", "Gloom", "Vileplume", "Bellsprout", "Weepinbell", "Victreebel"}
31 |
32 | local natureNamesList = {
33 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
34 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
35 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
36 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
37 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
38 |
39 | local versionAddr = read16Bit(0x13C)
40 | local version
41 | local languageAddr = read8Bit(0x14E)
42 | local language = ""
43 | local warning
44 |
45 | local mode = {"None", "Gift Bot", "Stationary Bot", "Fishing Bot", "In-Game Trade Bot", "TID Bot", "Pokemon Info"}
46 | local index = 1
47 | local prevKey = {}
48 | local showInstructionsText = false
49 | local leftArrowColor
50 | local rightArrowColor
51 |
52 | local botState = savestate.create()
53 | local botOneTime = false
54 |
55 | local partyAddr
56 | local partySlotsCounterAddr
57 | local wildDVsAddr
58 | local shinyFound = {false, "None"}
59 |
60 | local botTargetFishingSpecies = 27 -- Input here the fishing bot target species index. You can find it in the link below
61 | -- https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_index_number_(Generation_I)
62 | local fishedSpeciesAddr
63 | local biteFlagAddr = 0xCD3D
64 |
65 | local tidAddr
66 | local TIDFound = false
67 | local botTargetTIDs = {0, 1, 1337, 8453, 8411, 11233, 11111, 22222, 33333} -- Input here the bot target TIDs
68 |
69 | if versionAddr == 0x4C41 then -- Check game version
70 | version = "Crystal"
71 | elseif versionAddr == 0x4C42 then
72 | version = "Blue"
73 | elseif versionAddr == 0x4C47 then
74 | version = "Gold"
75 | elseif versionAddr == 0x4552 then
76 | version = "Red"
77 | elseif versionAddr == 0x5247 then
78 | version = "Green"
79 | elseif versionAddr == 0x4C53 then
80 | version = "Silver"
81 | elseif versionAddr == 0x4559 then
82 | version = "Yellow"
83 | else
84 | version = "Unknown"
85 | end
86 |
87 | if languageAddr == 0x04 or languageAddr == 0x91 or languageAddr == 0x9D then -- Check game language and set addresses
88 | language = "USA"
89 |
90 | if version == "Blue" or version == "Red" then
91 | partyAddr = 0xD16B
92 | partySlotsCounterAddr = 0xD163
93 | wildDVsAddr = 0xCFF1
94 | fishedSpeciesAddr = 0xD059
95 | tidAddr = 0xD359
96 | elseif version == "Yellow" then
97 | partyAddr = 0xD16A
98 | partySlotsCounterAddr = 0xD162
99 | wildDVsAddr = 0xCFF0
100 | fishedSpeciesAddr = 0xD058
101 | tidAddr = 0xD358
102 | end
103 | elseif languageAddr == 0xB8 or languageAddr == 0xD9 or languageAddr == 0xDC or languageAddr == 0xF5 then
104 | language = "JPN"
105 | partyAddr = 0xD12B
106 | partySlotsCounterAddr = 0xD123
107 | wildDVsAddr = 0xCFD8
108 | fishedSpeciesAddr = 0xD036
109 | tidAddr = 0xD2D8
110 | else
111 | language = "EUR"
112 |
113 | if version == "Blue" or version == "Red" then
114 | partyAddr = 0xD170
115 | partySlotsCounterAddr = 0xD168
116 | wildDVsAddr = 0xCFF6
117 | fishedSpeciesAddr = 0xD05E
118 | tidAddr = 0xD35E
119 | elseif version == "Yellow" then
120 | partyAddr = 0xD16F
121 | partySlotsCounterAddr = 0xD167
122 | wildDVsAddr = 0xCFF5
123 | fishedSpeciesAddr = 0xD05D
124 | tidAddr = 0xD35D
125 | end
126 | end
127 |
128 | if version ~= "Blue" and version ~= "Red" and version ~= "Green" and version ~= "Yellow" then
129 | warning = " - Wrong game version! Use Blue/Red/Green/Yellow instead"
130 | else
131 | warning = ""
132 | end
133 |
134 | print("Game Version: "..version..warning)
135 | print("Language: "..language)
136 | print()
137 |
138 | function getInput()
139 | leftArrowColor = "gray"
140 | rightArrowColor = "gray"
141 |
142 | local key = input.get()
143 |
144 | if (key["1"] or key["numpad1"]) and (not prevKey["1"] and not prevKey["numpad1"]) then
145 | leftArrowColor = "orange"
146 | index = index - 1 < 1 and 7 or index - 1
147 | elseif (key["2"] or key["numpad2"]) and (not prevKey["2"] and not prevKey["numpad2"]) then
148 | rightArrowColor = "orange"
149 | index = index + 1 > 7 and 1 or index + 1
150 | end
151 |
152 | prevKey = key
153 | gui.text(1, 1, "Mode: "..mode[index])
154 | drawArrowLeft(100, 1, leftArrowColor)
155 | gui.text(110, 1, "1 - 2")
156 | drawArrowRight(138, 1, rightArrowColor)
157 | end
158 |
159 | function drawArrowLeft(a, b, c)
160 | gui.line(a, b + 3, a + 2, b + 5, c)
161 | gui.line(a, b + 3, a + 2, b + 1, c)
162 | gui.line(a, b + 3, a + 6, b + 3, c)
163 | end
164 |
165 | function drawArrowRight(a, b, c)
166 | gui.line(a, b + 3, a - 2, b + 5, c)
167 | gui.line(a, b + 3, a - 2, b + 1, c)
168 | gui.line(a, b + 3, a - 6, b + 3, c)
169 | end
170 |
171 | function getDVs(DVsAddr)
172 | local atkDefDVs = read8Bit(DVsAddr)
173 | local speSpcDVs = read8Bit(DVsAddr + 0x1)
174 | local atkDV = rshift(atkDefDVs, 4)
175 | local defDV = band(atkDefDVs, 0xF)
176 | local speDV = rshift(speSpcDVs, 4)
177 | local spcDV = band(speSpcDVs, 0xF)
178 |
179 | return atkDV, defDV, speDV, spcDV
180 | end
181 |
182 | function isShiny(atkDV, defDV, speDV, spcDV)
183 | return {defDV == 0xA and speDV == 0xA and spcDV == 0xA and
184 | (atkDV == 0x2 or atkDV == 0x3 or atkDV == 0x6 or atkDV == 0x7 or
185 | atkDV == 0xA or atkDV == 0xB or atkDV == 0xE or atkDV == 0xF), mode[index]}
186 | end
187 |
188 | function shinyBotLoop(pokemonDVsAddr)
189 | shinyFound = {false, "None"}
190 | botOneTime = false
191 |
192 | while not shinyFound[1] do
193 | savestate.save(botState)
194 | joypad.set(1, {A = true})
195 | local frameLimit
196 |
197 | if mode[index] == "Gift Bot" or mode[index] == "Stationary Bot" then
198 | frameLimit = 35
199 | elseif mode[index] == "Fishing Bot" then
200 | frameLimit = 55
201 | elseif mode[index] == "In-Game Trade Bot" then
202 | frameLimit = 2560
203 | end
204 |
205 | local atkDefDVs = read8Bit(pokemonDVsAddr)
206 | local speSpcDVs = read8Bit(pokemonDVsAddr + 1)
207 | local previousAtkDefDVs = atkDefDVs
208 | local previousSpeSpcDVs = speSpcDVs
209 |
210 | local i = 0
211 | while atkDefDVs == previousAtkDefDVs and speSpcDVs == previousSpeSpcDVs and i < frameLimit do
212 | atkDefDVs = read8Bit(pokemonDVsAddr)
213 | speSpcDVs = read8Bit(pokemonDVsAddr + 1)
214 | emu.frameadvance()
215 | i = i + 1
216 | end
217 |
218 | if atkDefDVs ~= previousAtkDefDVs or speSpcDVs ~= previousSpeSpcDVs then
219 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
220 | --print(atkDV.." "..defDV.." "..speDV.." "..spcDV)
221 | shinyFound = isShiny(atkDV, defDV, speDV, spcDV)
222 | end
223 |
224 | if not shinyFound[1] then
225 | savestate.load(botState)
226 | emu.frameadvance()
227 | end
228 | end
229 | end
230 |
231 | function showFoundShiny(pokemonDVsAddr)
232 | if shinyFound[1] and shinyFound[2] == mode[index] then
233 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
234 | local hpDV = ((atkDV % 2) * 8) + ((defDV % 2) * 4) + ((speDV % 2) * 2) + (spcDV % 2)
235 |
236 | gui.text(1, 91, "Shiny Found!")
237 | gui.text(1, 100, string.format("Hp: %d", hpDV))
238 | gui.text(1, 109, string.format("Atk: %d", atkDV))
239 | gui.text(1, 118, string.format("Def: %d", defDV))
240 | gui.text(1, 127, string.format("SpC: %d", spcDV))
241 | gui.text(1, 136, string.format("Spe: %d", speDV))
242 |
243 | if not botOneTime then
244 | print("Shiny Found!")
245 | emu.pause()
246 | botOneTime = true
247 | end
248 | end
249 | end
250 |
251 | function shinyBot(pokemonDVsAddr)
252 | local key = joypad.get(1)
253 |
254 | if key.select then
255 | shinyBotLoop(pokemonDVsAddr)
256 | end
257 |
258 | showFoundShiny(pokemonDVsAddr)
259 | end
260 |
261 | function fishingBotBiteLoop()
262 | local biteFlag = false
263 |
264 | while not biteFlag do
265 | savestate.save(botState)
266 | joypad.set(1, {A = true})
267 |
268 | local i = 0
269 | while not biteFlag and i < 110 do
270 | biteFlag = read8Bit(biteFlagAddr) == 0x1
271 | emu.frameadvance()
272 | i = i + 1
273 | end
274 |
275 | if not biteFlag then
276 | savestate.load(botState)
277 | emu.frameadvance()
278 | end
279 | end
280 | end
281 |
282 | function fishingBotLoop()
283 | local targetFishedSpeciesCheck = read8Bit(fishedSpeciesAddr) == botTargetFishingSpecies
284 |
285 | while not targetFishedSpeciesCheck do
286 | fishingBotBiteLoop()
287 | targetFishedSpeciesCheck = read8Bit(fishedSpeciesAddr) == botTargetFishingSpecies
288 |
289 | if not targetFishedSpeciesCheck then
290 | savestate.load(botState)
291 | emu.frameadvance()
292 | end
293 | end
294 |
295 | for i = 1, 240 do
296 | emu.frameadvance()
297 | end
298 |
299 | shinyBotLoop(wildDVsAddr)
300 | end
301 |
302 | function fishingBot(pokemonDVsAddr)
303 | local key = joypad.get(1)
304 |
305 | if key.select then
306 | fishingBotLoop()
307 | end
308 |
309 | showFoundShiny(pokemonDVsAddr)
310 | end
311 |
312 | function reverseWord(word)
313 | return band(word, 0xFF) * 0x100 + rshift(word, 8)
314 | end
315 |
316 | function isTIDFound()
317 | local TID = reverseWord(read16Bit(tidAddr))
318 |
319 | for i = 1, table.getn(botTargetTIDs) do
320 | if TID == botTargetTIDs[i] then
321 | return true
322 | end
323 | end
324 |
325 | return false
326 | end
327 |
328 | function TIDBotLoop()
329 | TIDFound = false
330 | botOneTime = false
331 |
332 | while not TIDFound do
333 | savestate.save(botState)
334 | joypad.set(1, {A = true})
335 |
336 | local isTIDSet = read16Bit(tidAddr + 0x4) ~= 0
337 |
338 | local i = 0
339 | while not isTIDSet and i < 35 do
340 | isTIDSet = read16Bit(tidAddr + 0x4) ~= 0
341 | emu.frameadvance()
342 | i = i + 1
343 | end
344 |
345 | if isTIDSet then
346 | --print(reverseWord(read16Bit(tidAddr)))
347 | TIDFound = isTIDFound()
348 | end
349 |
350 | if not TIDFound then
351 | savestate.load(botState)
352 | emu.frameadvance()
353 | end
354 | end
355 | end
356 |
357 | function showFoundTID()
358 | if TIDFound then
359 | local TID = reverseWord(read16Bit(tidAddr))
360 |
361 | gui.text(1, 100, "TID Found!")
362 | gui.text(1, 109, "TID: "..TID)
363 |
364 | if not botOneTime then
365 | print("TID Found!")
366 | emu.pause()
367 | botOneTime = true
368 | end
369 | end
370 | end
371 |
372 | function TIDBot()
373 | local key = joypad.get(1)
374 |
375 | if key.select then
376 | TIDBotLoop()
377 | end
378 |
379 | showFoundTID()
380 | end
381 |
382 | function shinyText(atkDV, defDV, speDV, spcDV)
383 | return isShiny(atkDV, defDV, speDV, spcDV)[1] and "\tShiny" or ""
384 | end
385 |
386 | function showPartyPokemonInfo()
387 | local partySlotsCounter = read8Bit(partySlotsCounterAddr) - 1
388 |
389 | gui.text(1, 18, "Party natures:")
390 |
391 | for i = 0, partySlotsCounter do
392 | local pokemonSpeciesName = speciesNamesList[read8Bit(partyAddr + (i * 0x2C))]
393 | local pokemonEXPAddr = partyAddr + 0xE + (i * 0x2C)
394 | local pokemonDVsAddr = partyAddr + 0x1B + (i * 0x2C)
395 | local atkDV, defDV, speDV, spcDV = getDVs(pokemonDVsAddr)
396 | local pokemonEXP = (0x10000 * read8Bit(pokemonEXPAddr)) + (0x100 * read8Bit(pokemonEXPAddr + 0x1)) + read8Bit(pokemonEXPAddr + 0x2)
397 | local pokemonNatureName = natureNamesList[(pokemonEXP % 25) + 1]
398 |
399 | if pokemonSpeciesName ~= nil then
400 | gui.text(1, (i + 3) * 9, tostring(i + 1).." "..pokemonSpeciesName.."\t"..pokemonNatureName..shinyText(atkDV, defDV, speDV, spcDV))
401 | end
402 | end
403 | end
404 |
405 | while warning == "" do
406 | getInput()
407 |
408 | if mode[index] == "Gift Bot" or mode[index] == "In-Game Trade Bot" then
409 | local partySlotsCounter = read8Bit(partySlotsCounterAddr) - 1
410 | local lastPartySlotDVsAddr = partyAddr + 0x1B + (partySlotsCounter * 0x2C)
411 | shinyBot(lastPartySlotDVsAddr)
412 | elseif mode[index] == "Stationary Bot" then
413 | shinyBot(wildDVsAddr)
414 | elseif mode[index] == "Fishing Bot" then
415 | fishingBot(wildDVsAddr)
416 | elseif mode[index] == "TID Bot" then
417 | TIDBot()
418 | elseif mode[index] == "Pokemon Info" then
419 | showPartyPokemonInfo()
420 | end
421 |
422 | emu.frameadvance()
423 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/Ageto_Celebi_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read8Bit = ReadValue8
3 |
4 | local JUMP_DATA = {
5 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
6 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
7 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
8 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
9 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
10 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
11 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
12 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
13 |
14 | local natureNamesList = {
15 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
16 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
17 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
18 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
19 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
20 |
21 | local HPTypeNamesList = {
22 | "Fighting", "Flying", "Poison", "Ground",
23 | "Rock", "Bug", "Ghost", "Steel",
24 | "Fire", "Water", "Grass", "Electric",
25 | "Psychic", "Ice", "Dragon", "Dark"}
26 |
27 | local initialSeed, tempCurrentSeed, advances
28 |
29 | function setInitialSeed(seed)
30 | initialSeed = seed
31 | tempCurrentSeed = initialSeed
32 | advances = 0
33 | end
34 |
35 | local prevInitialSeed, initalSeedSetFlag
36 |
37 | function getInitialSeeding(seed)
38 | if initialSeed == 0 and prevInitialSeed ~= seed then
39 | initalSeedSetFlag = initalSeedSetFlag + 1
40 |
41 | if initalSeedSetFlag == 2 then
42 | setInitialSeed(seed)
43 | end
44 |
45 | prevInitialSeed = seed
46 | end
47 |
48 | return prevInitialSeed
49 | end
50 |
51 | function LCRNG(s, mul, sum)
52 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
53 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
54 |
55 | return b % 0x100000000
56 | end
57 |
58 | function LCRNGDistance(state0, state1)
59 | local mask = 1
60 | local dist = 0
61 |
62 | if state0 ~= state1 then
63 | for _, data in ipairs(JUMP_DATA) do
64 | local mult, add = table.unpack(data)
65 |
66 | if state0 == state1 then
67 | break
68 | end
69 |
70 | if ((state0 ~ state1) & mask) ~= 0 then
71 | state0 = LCRNG(state0, mult, add)
72 | dist = dist + mask
73 | end
74 |
75 | mask = mask << 1
76 | end
77 |
78 | tempCurrentSeed = state1
79 | end
80 |
81 | return dist > 1000000 and dist - 0x100000000 or dist
82 | end
83 |
84 | function getIVs(iv1, iv2)
85 | local ivs = {0, 0, 0, 0, 0, 0}
86 | ivs[1] = string.format("%02d", iv1 & 0x1F)
87 | ivs[2] = string.format("%02d", (iv1 >> 5) & 0x1F)
88 | ivs[3] = string.format("%02d", (iv1 >> 10) & 0x1F)
89 | ivs[4] = string.format("%02d", (iv2 >> 5) & 0x1F)
90 | ivs[5] = string.format("%02d", (iv2 >> 10) & 0x1F)
91 | ivs[6] = string.format("%02d", iv2 & 0x1F)
92 |
93 | return ivs
94 | end
95 |
96 | function getPID(seed)
97 | local trainerID = 31121
98 | local trainerSID = 0
99 |
100 | repeat -- Shiny lock reroll
101 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
102 | highPID = seed >> 16
103 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
104 | lowPID = seed >> 16
105 | until (trainerID ~ trainerSID ~ highPID ~ lowPID) > 8
106 |
107 | return (highPID << 16) + lowPID
108 | end
109 |
110 | function getHPTypeAndPower(hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
111 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
112 | + (32 * (spDefIV & 1))) * 15) // 63
113 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
114 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
115 |
116 | return string.format("HPower: %s %02d", HPTypeNamesList[hpType + 1], hpPower)
117 | end
118 |
119 | function getCelebiInfo(seed)
120 | seed = LCRNG(seed, 0x3C78F019, 0x7C93616E) -- 22 cycles
121 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
122 | local iv1 = seed >> 16
123 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
124 | local iv2 = seed >> 16
125 | local ivs = getIVs(iv1, iv2)
126 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
127 | local ability = (seed >> 16) & 1
128 | local pokemonPID = getPID(seed)
129 | local natureIndex = pokemonPID % 25
130 | local info = string.format("PID: %08X\nNature: %s\nIVs: %s", pokemonPID, natureNamesList[natureIndex + 1], table.concat(ivs, "/"))
131 | local hpTypeAndPower = getHPTypeAndPower(ivs[1], ivs[2], ivs[3], ivs[4], ivs[5], ivs[6])
132 | info = info.."\n"..hpTypeAndPower
133 |
134 | return info
135 | end
136 |
137 | function onScriptStart()
138 | initialSeed = 0
139 | prevInitialSeed = 0
140 | tempCurrentSeed = 0
141 | initalSeedSetFlag = 0
142 | advances = 0
143 | end
144 |
145 | function onScriptUpdate()
146 | local currentSeed = read32Bit(0x477098)
147 | getInitialSeeding(currentSeed)
148 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
149 | local celebiInfo = getCelebiInfo(currentSeed)
150 | local text = string.format("Visual Advances: %d\n\nInitial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d\n\nCelebi Info:\n%s",
151 | GetFrameCount(), initialSeed, currentSeed, advances, celebiInfo)
152 | SetScreenText(text)
153 | end
154 |
155 | function onScriptCancel()
156 | SetScreenText("")
157 | end
158 |
159 | function onStateLoaded()
160 | end
161 |
162 | function onStateSaved()
163 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/Channel_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read8Bit = ReadValue8
3 |
4 | local JUMP_DATA = {
5 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
6 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
7 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
8 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
9 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
10 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
11 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
12 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
13 |
14 | local natureNamesList = {
15 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
16 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
17 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
18 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
19 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
20 |
21 | local HPTypeNamesList = {
22 | "Fighting", "Flying", "Poison", "Ground",
23 | "Rock", "Bug", "Ghost", "Steel",
24 | "Fire", "Water", "Grass", "Electric",
25 | "Psychic", "Ice", "Dragon", "Dark"}
26 |
27 | function LCRNG(s, mul, sum)
28 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
29 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
30 |
31 | return b % 0x100000000
32 | end
33 |
34 | local tempCurrentSeed
35 |
36 | function LCRNGDistance(state0, state1)
37 | local mask = 1
38 | local dist = 0
39 |
40 | if state0 ~= state1 then
41 | for _, data in ipairs(JUMP_DATA) do
42 | local mult, add = table.unpack(data)
43 |
44 | if state0 == state1 then
45 | break
46 | end
47 |
48 | if ((state0 ~ state1) & mask) ~= 0 then
49 | state0 = LCRNG(state0, mult, add)
50 | dist = dist + mask
51 | end
52 |
53 | mask = mask << 1
54 | end
55 |
56 | tempCurrentSeed = state1
57 | end
58 |
59 | return dist > 1000000 and dist - 0x100000000 or dist
60 | end
61 |
62 | function getIVs(seed)
63 | local ivs = {0, 0, 0, 0, 0, 0}
64 | seed = LCRNG(seed, 0x45C82BE5, 0xD2F65B55) -- 3 cycle
65 |
66 | for i = 1, 6 do
67 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
68 | ivs[i == 4 and 6 or i == 5 and 4 or i == 6 and 5 or i] = string.format("%02d", (seed >> 16) >> 11)
69 | end
70 |
71 | return ivs
72 | end
73 |
74 | function shinyCheck(highPID, lowPID, trainerID, trainerSID)
75 | local shinyTypeValue = trainerID ~ trainerSID ~ highPID ~ lowPID
76 |
77 | if shinyTypeValue < 8 then
78 | return shinyTypeValue == 0 and " (Square Shiny)" or " (Star Shiny)"
79 | end
80 |
81 | return ""
82 | end
83 |
84 | function getHPTypeAndPower(hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
85 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
86 | + (32 * (spDefIV & 1))) * 15) // 63
87 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
88 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
89 |
90 | return string.format("HPower: %s %02d", HPTypeNamesList[hpType + 1], hpPower)
91 | end
92 |
93 | function getJirachiInfo(seed)
94 | local OTID = 40122
95 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
96 | local OTSID = seed >> 16
97 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
98 | local pokemonHighPID = seed >> 16
99 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
100 | local pokemonLowPID = seed >> 16
101 |
102 | if (pokemonLowPID < 8 and 1 or 0) ~= (pokemonHighPID ~ OTID ~ OTSID) then
103 | pokemonHighPID = pokemonHighPID ~ 0x8000
104 | end
105 |
106 | local ivs = getIVs(seed)
107 | local pokemonPID = (pokemonHighPID << 16) + pokemonLowPID
108 | local shinyType = shinyCheck(pokemonHighPID, pokemonLowPID, OTID, OTSID)
109 | local natureIndex = pokemonPID % 25
110 | local info = string.format("PID: %08X %s\nNature: %s\nIVs: %s", pokemonPID, shinyType, natureNamesList[natureIndex + 1], table.concat(ivs, "/"))
111 | local hpTypeAndPower = getHPTypeAndPower(ivs[1], ivs[2], ivs[3], ivs[4], ivs[5], ivs[6])
112 | info = info.."\n"..hpTypeAndPower
113 |
114 | return info
115 | end
116 |
117 | local currentSeedAddr, initialSeed, advances
118 |
119 | function onScriptStart()
120 | local gameLang = read8Bit(0x3)
121 |
122 | if gameLang == 0x45 then -- U
123 | currentSeedAddr = 0x3502C8
124 | elseif gameLang == 0x4A then -- J
125 | currentSeedAddr = read8Bit(0x0) == 0x47 and 0x387C18 or 0x387C38 -- Japan has two editions of the game
126 | elseif gameLang == 0x50 then -- E
127 | currentSeedAddr = 0x33D888
128 | else -- A
129 | currentSeedAddr = 0x337568
130 | end
131 |
132 | initialSeed = read32Bit(currentSeedAddr)
133 | tempCurrentSeed = initialSeed
134 | advances = 0
135 | end
136 |
137 | function onScriptUpdate()
138 | local currentSeed = read32Bit(currentSeedAddr)
139 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
140 | local jirachiInfo = getJirachiInfo(currentSeed)
141 | local text = string.format("Initial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d\n\nJirachi Info:\n%s",
142 | initialSeed, currentSeed, advances, jirachiInfo)
143 | SetScreenText(text)
144 | end
145 |
146 | function onScriptCancel()
147 | SetScreenText("")
148 | end
149 |
150 | function onStateLoaded()
151 | end
152 |
153 | function onStateSaved()
154 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/Colo_Pikachu_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read8Bit = ReadValue8
3 |
4 | local JUMP_DATA = {
5 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
6 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
7 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
8 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
9 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
10 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
11 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
12 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
13 |
14 | local natureNamesList = {
15 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
16 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
17 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
18 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
19 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
20 |
21 | local HPTypeNamesList = {
22 | "Fighting", "Flying", "Poison", "Ground",
23 | "Rock", "Bug", "Ghost", "Steel",
24 | "Fire", "Water", "Grass", "Electric",
25 | "Psychic", "Ice", "Dragon", "Dark"}
26 |
27 | local initialSeed, tempCurrentSeed, advances
28 |
29 | function setInitialSeed(seed)
30 | initialSeed = seed
31 | tempCurrentSeed = initialSeed
32 | advances = 0
33 | end
34 |
35 | local prevInitialSeed, initalSeedSetFlag
36 |
37 | function getInitialSeeding(seed)
38 | if initialSeed == 0 and prevInitialSeed ~= seed then
39 | initalSeedSetFlag = initalSeedSetFlag + 1
40 |
41 | if initalSeedSetFlag == 2 then
42 | setInitialSeed(seed)
43 | end
44 |
45 | prevInitialSeed = seed
46 | end
47 |
48 | return prevInitialSeed
49 | end
50 |
51 | function LCRNG(s, mul, sum)
52 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
53 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
54 |
55 | return b % 0x100000000
56 | end
57 |
58 | function LCRNGDistance(state0, state1)
59 | local mask = 1
60 | local dist = 0
61 |
62 | if state0 ~= state1 then
63 | for _, data in ipairs(JUMP_DATA) do
64 | local mult, add = table.unpack(data)
65 |
66 | if state0 == state1 then
67 | break
68 | end
69 |
70 | if ((state0 ~ state1) & mask) ~= 0 then
71 | state0 = LCRNG(state0, mult, add)
72 | dist = dist + mask
73 | end
74 |
75 | mask = mask << 1
76 | end
77 |
78 | tempCurrentSeed = state1
79 | end
80 |
81 | return dist > 1000000 and dist - 0x100000000 or dist
82 | end
83 |
84 | function getIVs(iv1, iv2)
85 | local ivs = {0, 0, 0, 0, 0, 0}
86 | ivs[1] = string.format("%02d", iv1 & 0x1F)
87 | ivs[2] = string.format("%02d", (iv1 >> 5) & 0x1F)
88 | ivs[3] = string.format("%02d", (iv1 >> 10) & 0x1F)
89 | ivs[4] = string.format("%02d", (iv2 >> 5) & 0x1F)
90 | ivs[5] = string.format("%02d", (iv2 >> 10) & 0x1F)
91 | ivs[6] = string.format("%02d", iv2 & 0x1F)
92 |
93 | return ivs
94 | end
95 |
96 | function getPID(seed)
97 | local trainerID = 31121
98 | local trainerSID = 0
99 |
100 | repeat -- Shiny lock reroll
101 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
102 | highPID = seed >> 16
103 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
104 | lowPID = seed >> 16
105 | until (trainerID ~ trainerSID ~ highPID ~ lowPID) > 8
106 |
107 | return (highPID << 16) + lowPID
108 | end
109 |
110 | function getHPTypeAndPower(hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
111 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
112 | + (32 * (spDefIV & 1))) * 15) // 63
113 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
114 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
115 |
116 | return string.format("HPower: %s %02d", HPTypeNamesList[hpType + 1], hpPower)
117 | end
118 |
119 | function getPikachuInfo(seed)
120 | seed = LCRNG(seed, 0xA9FC6809, 0x1E278E7A) -- 2 cycles
121 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
122 | local iv1 = seed >> 16
123 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
124 | local iv2 = seed >> 16
125 | local ivs = getIVs(iv1, iv2)
126 | seed = LCRNG(seed, 0x343FD, 0x269EC3)
127 | local ability = (seed >> 16) & 1
128 | local pokemonPID = getPID(seed)
129 | local natureIndex = pokemonPID % 25
130 | local info = string.format("PID: %08X\nNature: %s\nIVs: %s", pokemonPID, natureNamesList[natureIndex + 1], table.concat(ivs, "/"))
131 | local hpTypeAndPower = getHPTypeAndPower(ivs[1], ivs[2], ivs[3], ivs[4], ivs[5], ivs[6])
132 | info = info.."\n"..hpTypeAndPower
133 |
134 | return info
135 | end
136 |
137 | function onScriptStart()
138 | initialSeed = 0
139 | prevInitialSeed = 0
140 | tempCurrentSeed = 0
141 | initalSeedSetFlag = 0
142 | advances = 0
143 | end
144 |
145 | function onScriptUpdate()
146 | local currentSeed = read32Bit(0x477098)
147 | getInitialSeeding(currentSeed)
148 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
149 | local pikachuInfo = getPikachuInfo(currentSeed)
150 | local text = string.format("Visual Advances: %d\n\nInitial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d\n\nPikachu Info:\n%s",
151 | GetFrameCount(), initialSeed, currentSeed, advances, pikachuInfo)
152 | SetScreenText(text)
153 | end
154 |
155 | function onScriptCancel()
156 | SetScreenText("")
157 | end
158 |
159 | function onStateLoaded()
160 | end
161 |
162 | function onStateSaved()
163 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/Colosseum_Light_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read16Bit = ReadValue16
3 | read8Bit = ReadValue8
4 |
5 | local JUMP_DATA = {
6 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
7 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
8 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
9 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
10 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
11 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
12 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
13 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
14 |
15 | local natureNamesList = {
16 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
17 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
18 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
19 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
20 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
21 |
22 | local HPTypeNamesList = {
23 | "Fighting", "Flying", "Poison", "Ground",
24 | "Rock", "Bug", "Ghost", "Steel",
25 | "Fire", "Water", "Grass", "Electric",
26 | "Psychic", "Ice", "Dragon", "Dark"}
27 |
28 | local speciesNamesList = {
29 | -- Gen 1
30 | "NONE", "BULBASAUR", "IVYSAUR", "VENUSAUR", "CHARMANDER", "CHARMELEON", "CHARIZARD", "SQUIRTLE", "WARTORTLE", "BLASTOISE",
31 | "CATERPIE", "METAPOD", "BUTTERFREE", "WEEDLE", "KAKUNA", "BEEDRILL", "PIDGEY", "PIDGEOTTO", "PIDGEOT", "RATTATA", "RATICATE",
32 | "SPEAROW", "FEAROW", "EKANS", "ARBOK", "PIKACHU", "RAICHU", "SANDSHREW", "SANDSLASH", "NIDORAN♀", "NIDORINA", "NIDOQUEEN",
33 | "NIDORAN♂", "NIDORINO", "NIDOKING", "CLEFAIRY", "CLEFABLE", "VULPIX", "NINETALES", "JIGGLYPUFF", "WIGGLYTUFF", "ZUBAT", "GOLBAT",
34 | "ODDISH", "GLOOM", "VILEPLUME", "PARAS", "PARASECT", "VENONAT", "VENOMOTH", "DIGLETT", "DUGTRIO", "MEOWTH", "PERSIAN", "PSYDUCK",
35 | "GOLDUCK", "MANKEY", "PRIMEAPE", "GROWLITHE", "ARCANINE", "POLIWAG", "POLIWHIRL", "POLIWRATH", "ABRA", "KADABRA", "ALAKAZAM",
36 | "MACHOP", "MACHOKE", "MACHAMP", "BELLSPROUT", "WEEPINBELL", "VICTREEBEL", "TENTACOOL", "TENTACRUEL", "GEODUDE", "GRAVELER",
37 | "GOLEM", "PONYTA", "RAPIDASH", "SLOWPOKE", "SLOWBRO", "MAGNEMITE", "MAGNETON", "FARFETCH'D", "DODUO", "DODRIO", "SEEL", "DEWGONG",
38 | "GRIMER", "MUK", "SHELLDER", "CLOYSTER", "GASTLY", "HAUNTER", "GENGAR", "ONIX", "DROWZEE", "HYPNO", "KRABBY", "KINGLER", "VOLTORB",
39 | "ELECTRODE", "EXEGGCUTE", "EXEGGUTOR", "CUBONE", "MAROWAK", "HITMONLEE", "HITMONCHAN", "LICKITUNG", "KOFFING", "WEEZING", "RHYHORN",
40 | "RHYDON", "CHANSEY", "TANGELA", "KANGASKHAN", "HORSEA", "SEADRA", "GOLDEEN", "SEAKING", "STARYU", "STARMIE", "MR.MIME", "SCYTHER",
41 | "JYNX", "ELECTABUZZ", "MAGMAR", "PINSIR", "TAUROS", "MAGIKARP", "GYARADOS", "LAPRAS", "DITTO", "EEVEE", "VAPOREON", "JOLTEON",
42 | "FLAREON", "PORYGON", "OMANYTE", "OMASTAR", "KABUTO", "KABUTOPS", "AERODACTYL", "SNORLAX", "ARTICUNO", "ZAPDOS", "MOLTRES",
43 | "DRATINI", "DRAGONAIR", "DRAGONITE", "MEWTWO", "MEW",
44 | -- Gen 2
45 | "CHIKORITA", "BAYLEEF", "MEGANIUM", "CYNDAQUIL", "QUILAVA", "TYPHLOSION", "TOTODILE", "CROCONAW", "FERALIGATR", "SENTRET", "FURRET",
46 | "HOOTHOOT", "NOCTOWL", "LEDYBA", "LEDIAN", "SPINARAK", "ARIADOS", "CROBAT", "CHINCHOU", "LANTURN", "PICHU", "CLEFFA", "IGGLYBUFF",
47 | "TOGEPI", "TOGETIC", "NATU", "XATU", "MAREEP", "FLAAFFY", "AMPHAROS", "BELLOSSOM", "MARILL", "AZUMARILL", "SUDOWOODO", "POLITOED",
48 | "HOPPIP", "SKIPLOOM", "JUMPLUFF", "AIPOM", "SUNKERN", "SUNFLORA", "YANMA", "WOOPER", "QUAGSIRE", "ESPEON", "UMBREON", "MURKROW",
49 | "SLOWKING", "MISDREAVUS", "UNOWN", "WOBBUFFET", "GIRAFARIG", "PINECO", "FORRETRESS", "DUNSPARCE", "GLIGAR", "STEELIX", "SNUBBULL",
50 | "GRANBULL", "QWILFISH", "SCIZOR", "SHUCKLE", "HERACROSS", "SNEASEL", "TEDDIURSA", "URSARING", "SLUGMA", "MAGCARGO", "SWINUB",
51 | "PILOSWINE", "CORSOLA", "REMORAID", "OCTILLERY", "DELIBIRD", "MANTINE", "SKARMORY", "HOUNDOUR", "HOUNDOOM", "KINGDRA", "PHANPY",
52 | "DONPHAN", "PORYGON2", "STANTLER", "SMEARGLE", "TYROGUE", "HITMONTOP", "SMOOCHUM", "ELEKID", "MAGBY", "MILTANK", "BLISSEY", "RAIKOU",
53 | "ENTEI", "SUICUNE", "LARVITAR", "PUPITAR", "TYRANITAR", "LUGIA", "HO-OH", "CELEBI",
54 | -- Gen 3
55 | "TREECKO", "GROVYLE", "SCEPTILE", "TORCHIC", "COMBUSKEN", "BLAZIKEN", "MUDKIP", "MARSHTOMP", "SWAMPERT", "POOCHYENA", "MIGHTYENA",
56 | "ZIGZAGOON", "LINOONE", "WURMPLE", "SILCOON", "BEAUTIFLY", "CASCOON", "DUSTOX", "LOTAD", "LOMBRE", "LUDICOLO", "SEEDOT", "NUZLEAF",
57 | "SHIFTRY", "TAILLOW", "SWELLOW", "WINGULL", "PELIPPER", "RALTS", "KIRLIA", "GARDEVOIR", "SURSKIT", "MASQUERAIN", "SHROOMISH", "BRELOOM",
58 | "SLAKOTH", "VIGOROTH", "SLAKING", "NINCADA", "NINJASK", "SHEDINJA", "WHISMUR", "LOUDRED", "EXPLOUD", "MAKUHITA", "HARIYAMA", "AZURILL",
59 | "NOSEPASS", "SKITTY", "DELCATTY", "SABLEYE", "MAWILE", "ARON", "LAIRON", "AGGRON", "MEDITITE", "MEDICHAM", "ELECTRIKE", "MANECTRIC",
60 | "PLUSLE", "MINUN", "VOLBEAT", "ILLUMISE", "ROSELIA", "GULPIN", "SWALOT", "CARVANHA", "SHARPEDO", "WAILMER", "WAILORD", "NUMEL",
61 | "CAMERUPT", "TORKOAL", "SPOINK", "GRUMPIG", "SPINDA", "TRAPINCH", "VIBRAVA", "FLYGON", "CACNEA", "CACTURNE", "SWABLU", "ALTARIA",
62 | "ZANGOOSE", "SEVIPER", "LUNATONE", "SOLROCK", "BARBOACH", "WHISCASH", "CORPHISH", "CRAWDAUNT", "BALTOY", "CLAYDOL", "LILEEP", "CRADILY",
63 | "ANORITH", "ARMALDO", "FEEBAS", "MILOTIC", "CASTFORM", "KECLEON", "SHUPPET", "BANETTE", "DUSKULL", "DUSCLOPS", "TROPIUS", "CHIMECHO",
64 | "ABSOL", "WYNAUT", "SNORUNT", "GLALIE", "SPHEAL", "SEALEO", "WALREIN", "CLAMPERL", "HUNTAIL", "GOREBYSS", "RELICANTH", "LUVDISC", "BAGON",
65 | "SHELGON", "SALAMENCE", "BELDUM", "METANG", "METAGROSS", "REGIROCK", "REGICE", "REGISTEEL", "LATIAS", "LATIOS", "KYOGRE", "GROUDON",
66 | "RAYQUAZA", "JIRACHI", "DEOXYS"}
67 |
68 | local nationalDexList = {
69 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
70 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
71 | 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
72 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
73 | 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
74 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
75 | 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
76 | 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
77 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
78 | 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
79 | 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
80 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394,
81 | 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254,
82 | 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
83 | 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344,
84 | 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322,
85 | 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334,
86 | 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336,
87 | 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375,
88 | 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}
89 |
90 | local catchRatesList = {
91 | -- Gen 1
92 | 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 120, 90, 255, 120, 90, 255, 120,
93 | 45, 255, 127, 255, 90, 255, 90, 190, 75, 255, 90, 235, 120, 45, 235, 120,
94 | 45, 150, 25, 190, 75, 170, 50, 255, 90, 255, 120, 45, 190, 75, 190, 120,
95 | 255, 100, 255, 90, 190, 120, 190, 80, 190, 75, 255, 120, 90, 200, 100, 50,
96 | 180, 90, 45, 255, 120, 45, 190, 60, 255, 120, 45, 190, 110, 190, 75, 190,
97 | 110, 80, 190, 90, 190, 75, 190, 75, 190, 60, 190, 90, 45, 45, 190, 80, 225,
98 | 60, 190, 60, 90, 80, 190, 110, 90, 90, 90, 190, 60, 120, 100, 70, 90, 90,
99 | 225, 75, 225, 60, 225, 110, 90, 90, 45, 90, 90, 90, 80, 255, 45, 80, 35, 45,
100 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 70, 25, 25, 25, 45, 45, 45, 3, 45,
101 | -- Gen2
102 | 45, 180, 45, 45, 180, 45, 45, 180, 45, 255, 90, 255, 90, 255, 90, 255, 90,
103 | 90, 190, 75, 190, 150, 170, 190, 45, 190, 75, 235, 120, 45, 45, 190, 75, 65,
104 | 45, 255, 120, 45, 45, 235, 120, 75, 255, 90, 45, 45, 30, 70, 90, 225, 45, 60,
105 | 190, 75, 190, 60, 25, 190, 75, 45, 25, 190, 45, 60, 120, 60, 190, 120, 225,
106 | 75, 60, 190, 75, 45, 90, 15, 225, 45, 45, 120, 60, 45, 45, 45, 75, 45, 45, 45,
107 | 45, 45, 30, 15, 15, 15, 45, 45, 10, 3, 3, 45,
108 | -- Gen3
109 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 127, 255, 90, 255, 120, 45, 120, 45,
110 | 255, 120, 45, 255, 120, 45, 200, 90, 255, 45, 235, 120, 45, 200, 75, 255, 90,
111 | 255, 120, 45, 255, 120, 45, 190, 120, 45, 255, 200, 150, 255, 255, 120, 90, 120,
112 | 180, 90, 45, 180, 90, 120, 80, 200, 200, 150, 150, 150, 225, 75, 225, 60, 125,
113 | 60, 255, 150, 90, 255, 60, 255, 255, 120, 45, 190, 60, 255, 80, 90, 90, 100, 90,
114 | 190, 75, 205, 155, 255, 90, 45, 45, 45, 45, 255, 60, 45, 200, 225, 90, 190, 90,
115 | 45, 45, 30, 125, 190, 75, 255, 120, 45, 255, 60, 60, 25, 225, 45, 45, 80, 3, 3,
116 | 15, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3}
117 |
118 | function LCRNG(s, mul, sum)
119 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
120 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
121 |
122 | return b % 0x100000000
123 | end
124 |
125 | local tempCurrentSeed = 0
126 |
127 | function LCRNGDistance(state0, state1)
128 | local mask = 1
129 | local dist = 0
130 |
131 | if state0 ~= state1 then
132 | for _, data in ipairs(JUMP_DATA) do
133 | local mult, add = table.unpack(data)
134 |
135 | if state0 == state1 then
136 | break
137 | end
138 |
139 | if ((state0 ~ state1) & mask) ~= 0 then
140 | state0 = LCRNG(state0, mult, add)
141 | dist = dist + mask
142 | end
143 |
144 | mask = mask << 1
145 | end
146 |
147 | tempCurrentSeed = state1
148 | end
149 |
150 | return dist > 1000000 and dist - 0x100000000 or dist
151 | end
152 |
153 | local partySelectedSlotIndexAddr, boxSelectedPokemonAddr, enemyAddr, boxFlagAddr, currentSeedAddr, boxPointerAddr, pointerAddr, initialSeed, advances
154 |
155 | function onScriptStart()
156 | local gameLang = read8Bit(0x3)
157 |
158 | if gameLang == 0x45 then -- U
159 | partySelectedSlotIndexAddr = 0x3A1D46
160 | boxSelectedPokemonAddr = 0x3A95EC
161 | enemyAddr = 0x473070
162 | boxFlagAddr = 0x478B1A
163 | currentSeedAddr = 0x478C90
164 | boxPointerAddr = 0x47ADB8
165 | pointerAddr = 0x7EFDCC
166 | elseif gameLang == 0x4A then -- J
167 | partySelectedSlotIndexAddr = 0x38E4C6
168 | boxSelectedPokemonAddr = 0x395CBC
169 | enemyAddr = 0x45E750
170 | boxFlagAddr = 0x4641EA
171 | currentSeedAddr = 0x464360
172 | boxPointerAddr = 0x466468
173 | pointerAddr = 0x75E088
174 | else -- E
175 | partySelectedSlotIndexAddr = 0x3EF1C6
176 | boxSelectedPokemonAddr = 0x3F6A6C
177 | enemyAddr = 0x4C0508
178 | boxFlagAddr = 0x4C5FBA
179 | currentSeedAddr = 0x4C6130
180 | boxPointerAddr = 0x4C8268
181 | pointerAddr = 0x90C300
182 | end
183 |
184 | initialSeed = read32Bit(currentSeedAddr)
185 | tempCurrentSeed = initialSeed
186 | advances = 0
187 | end
188 |
189 | function getTrainerIDs(pointer)
190 | local trainerIDsAddr = pointer + 0x7FFE42E0
191 | local trainerIDs = read32Bit(trainerIDsAddr)
192 | local TID = trainerIDs & 0xFFFF
193 | local SID = trainerIDs >> 16
194 |
195 | return TID, SID
196 | end
197 |
198 | function calcCatchRate(HP, bonusBall, rate)
199 | if HP ~= 0 then
200 | local a = (HP * rate * bonusBall) // (3 * HP)
201 |
202 | return 1048560 // math.sqrt(math.sqrt(16711680 // a))
203 | end
204 |
205 | return 0
206 | end
207 |
208 | function getPokemonInfo(addr, trainerTID, trainerSID)
209 | trainerTID = trainerTID or nil
210 | trainerSID = trainerSID or nil
211 |
212 | local pokemonPID = read32Bit(addr)
213 | local speciesDexIndex = read16Bit(addr - 0x4)
214 | local OTSID = trainerSID and trainerSID or read16Bit(addr + 0x10)
215 | local OTID = trainerTID and trainerTID or read16Bit(addr + 0x12)
216 |
217 | local ivsAddr = addr + 0xA1
218 | local hpIV = read8Bit(ivsAddr)
219 | local atkIV = read8Bit(ivsAddr + 0x2)
220 | local defIV = read8Bit(ivsAddr + 0x4)
221 | local spAtkIV = read8Bit(ivsAddr + 0x6)
222 | local spDefIV = read8Bit(ivsAddr + 0x8)
223 | local spdIV = read8Bit(ivsAddr + 0xA)
224 |
225 | local shadowID = read8Bit(addr + 0xD5)
226 |
227 | local speciesDexNumber = nationalDexList[((speciesDexIndex > 411 or speciesDexIndex < 1) and 0 or speciesDexIndex) + 1] + 1
228 | local speciesName = speciesNamesList[speciesDexNumber]
229 | local natureName = natureNamesList[(pokemonPID % 25) + 1]
230 |
231 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
232 | + (32 * (spDefIV & 1))) * 15) // 63
233 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
234 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
235 |
236 | local catchRateValue = calcCatchRate(read16Bit(addr + 0x86), 1, catchRatesList[speciesDexNumber])
237 |
238 | return pokemonPID, OTSID, OTID, speciesName, natureName, hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV, hpType, hpPower, catchRateValue, shadowID
239 | end
240 |
241 | function isBoxOpened()
242 | return read16Bit(boxFlagAddr) == 0x391
243 | end
244 |
245 | function shinyCheck(PID, trainerID, trainerSID)
246 | local lowPID = PID & 0xFFFF
247 | local highPID = PID >> 16
248 | local shinyTypeValue = trainerID ~ trainerSID ~ lowPID ~ highPID
249 |
250 | if shinyTypeValue < 8 then
251 | return shinyTypeValue == 0 and " (Square) " or " (Star) "
252 | end
253 |
254 | return " "
255 | end
256 |
257 | function getFormattedText(pokemonPID, OTSID, OTID, speciesName, natureName, hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV, hpType, hpPower, catchRateValue)
258 | catchRateValue = catchRateValue or nil
259 |
260 | local speciesText = string.format("Species: %s", speciesName)
261 | local PIDText = string.format("\nPID: %08X%s", pokemonPID, shinyCheck(pokemonPID, OTID, OTSID))
262 | local natureText = string.format("\nNature: %s", natureName)
263 | local ivsText = string.format("\nIVs: %02d/%02d/%02d/%02d/%02d/%02d", hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
264 | local HPText = string.format("\nHPower: %s %02d", HPTypeNamesList[hpType + 1], hpPower)
265 | local catchRngText = catchRateValue and string.format("\nCatch Rate Value: %d", catchRateValue) or ""
266 |
267 | return speciesText..PIDText..natureText..ivsText..HPText..catchRngText
268 | end
269 |
270 | function getPokemonInfoText(pointer, trainerTID, trainerSID)
271 | local text = ""
272 |
273 | local enemyPID, enemyOTID, enemyOTSID, enemySpeciesName, enemyNatureName, enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV,
274 | enemySpdIV, enemyHpType, enemyHpPower, enemyCatchRateValue, enemyShadowID
275 |
276 | for i = 0, 5 do
277 | enemyPID, enemyOTID, enemyOTSID, enemySpeciesName, enemyNatureName, enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV,
278 | enemySpdIV, enemyHpType, enemyHpPower, enemyCatchRateValue, enemyShadowID = getPokemonInfo(enemyAddr + (0x138 * i), trainerTID, trainerSID)
279 |
280 | if enemyShadowID ~= 0 then
281 | break
282 | end
283 | end
284 |
285 | text = text.."\n\nOpponent\n\n"..getFormattedText(enemyPID, enemyOTID, enemyOTSID, enemySpeciesName, enemyNatureName, enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV,
286 | enemySpdIV, enemyHpType, enemyHpPower, enemyCatchRateValue)
287 |
288 | local partyAddr = pointer + 0x7FFE42E8
289 | local partySelectedSlotIndex = read8Bit(partySelectedSlotIndexAddr)
290 | local partyPID, partyOTID, partyOTSID, partySpeciesName, partyNatureName, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV,
291 | partySpdIV, partyHpType, partyHpPower, partyCatchRateValue, partyShadowID = getPokemonInfo(partyAddr + (0x138 *
292 | ((partySelectedSlotIndex >= 0 and partySelectedSlotIndex <= 5) and partySelectedSlotIndex or 0)))
293 |
294 | text = text.."\n\n\nParty\n\n"..getFormattedText(partyPID, partyOTID, partyOTSID, partySpeciesName, partyNatureName, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV,
295 | partySpdIV, partyHpType, partyHpPower)
296 |
297 | local boxPID, boxOTID, boxOTSID, boxSpeciesName, boxNatureName, boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV, boxHpType,
298 | boxHpPower, boxCatchRateValue, boxShadowID = getPokemonInfo(isBoxOpened() and boxSelectedPokemonAddr or read32Bit(boxPointerAddr) + 0xBA0) -- Current selected Pokémon or 1st slot of 1st box
299 |
300 | text = text.."\n\n\nBox\n\n"..getFormattedText(boxPID, boxOTID, boxOTSID, boxSpeciesName, boxNatureName, boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV, boxHpType, boxHpPower)
301 |
302 | return text
303 | end
304 |
305 | function onScriptUpdate()
306 | local currentSeed = read32Bit(currentSeedAddr)
307 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
308 | local pointer = read32Bit(pointerAddr)
309 | local trainerTID, trainerSID = 0, 0
310 |
311 | local RNGInfoText = string.format("Initial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d", initialSeed, currentSeed, advances)
312 | local infoText = ""
313 |
314 | if pointer ~= 0 then
315 | trainerTID, trainerSID = getTrainerIDs(pointer)
316 | infoText = getPokemonInfoText(pointer, trainerTID, trainerSID)
317 | end
318 |
319 | local IDsInfoText = string.format("\n\n\nTID: %05d\nSID: %05d", trainerTID, trainerSID)
320 |
321 | SetScreenText(RNGInfoText..infoText..IDsInfoText)
322 | end
323 |
324 | function onScriptCancel()
325 | SetScreenText("")
326 | end
327 |
328 | function onStateLoaded()
329 | end
330 |
331 | function onStateSaved()
332 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/Colosseum_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read16Bit = ReadValue16
3 | read8Bit = ReadValue8
4 |
5 | local JUMP_DATA = {
6 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
7 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
8 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
9 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
10 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
11 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
12 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
13 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
14 |
15 | local natureNamesList = {
16 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
17 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
18 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
19 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
20 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
21 |
22 | local HPTypeNamesList = {
23 | "Fighting", "Flying", "Poison", "Ground",
24 | "Rock", "Bug", "Ghost", "Steel",
25 | "Fire", "Water", "Grass", "Electric",
26 | "Psychic", "Ice", "Dragon", "Dark"}
27 |
28 | local speciesNamesList = {
29 | -- Gen 1
30 | "NONE", "BULBASAUR", "IVYSAUR", "VENUSAUR", "CHARMANDER", "CHARMELEON", "CHARIZARD", "SQUIRTLE", "WARTORTLE", "BLASTOISE",
31 | "CATERPIE", "METAPOD", "BUTTERFREE", "WEEDLE", "KAKUNA", "BEEDRILL", "PIDGEY", "PIDGEOTTO", "PIDGEOT", "RATTATA", "RATICATE",
32 | "SPEAROW", "FEAROW", "EKANS", "ARBOK", "PIKACHU", "RAICHU", "SANDSHREW", "SANDSLASH", "NIDORAN♀", "NIDORINA", "NIDOQUEEN",
33 | "NIDORAN♂", "NIDORINO", "NIDOKING", "CLEFAIRY", "CLEFABLE", "VULPIX", "NINETALES", "JIGGLYPUFF", "WIGGLYTUFF", "ZUBAT", "GOLBAT",
34 | "ODDISH", "GLOOM", "VILEPLUME", "PARAS", "PARASECT", "VENONAT", "VENOMOTH", "DIGLETT", "DUGTRIO", "MEOWTH", "PERSIAN", "PSYDUCK",
35 | "GOLDUCK", "MANKEY", "PRIMEAPE", "GROWLITHE", "ARCANINE", "POLIWAG", "POLIWHIRL", "POLIWRATH", "ABRA", "KADABRA", "ALAKAZAM",
36 | "MACHOP", "MACHOKE", "MACHAMP", "BELLSPROUT", "WEEPINBELL", "VICTREEBEL", "TENTACOOL", "TENTACRUEL", "GEODUDE", "GRAVELER",
37 | "GOLEM", "PONYTA", "RAPIDASH", "SLOWPOKE", "SLOWBRO", "MAGNEMITE", "MAGNETON", "FARFETCH'D", "DODUO", "DODRIO", "SEEL", "DEWGONG",
38 | "GRIMER", "MUK", "SHELLDER", "CLOYSTER", "GASTLY", "HAUNTER", "GENGAR", "ONIX", "DROWZEE", "HYPNO", "KRABBY", "KINGLER", "VOLTORB",
39 | "ELECTRODE", "EXEGGCUTE", "EXEGGUTOR", "CUBONE", "MAROWAK", "HITMONLEE", "HITMONCHAN", "LICKITUNG", "KOFFING", "WEEZING", "RHYHORN",
40 | "RHYDON", "CHANSEY", "TANGELA", "KANGASKHAN", "HORSEA", "SEADRA", "GOLDEEN", "SEAKING", "STARYU", "STARMIE", "MR.MIME", "SCYTHER",
41 | "JYNX", "ELECTABUZZ", "MAGMAR", "PINSIR", "TAUROS", "MAGIKARP", "GYARADOS", "LAPRAS", "DITTO", "EEVEE", "VAPOREON", "JOLTEON",
42 | "FLAREON", "PORYGON", "OMANYTE", "OMASTAR", "KABUTO", "KABUTOPS", "AERODACTYL", "SNORLAX", "ARTICUNO", "ZAPDOS", "MOLTRES",
43 | "DRATINI", "DRAGONAIR", "DRAGONITE", "MEWTWO", "MEW",
44 | -- Gen 2
45 | "CHIKORITA", "BAYLEEF", "MEGANIUM", "CYNDAQUIL", "QUILAVA", "TYPHLOSION", "TOTODILE", "CROCONAW", "FERALIGATR", "SENTRET", "FURRET",
46 | "HOOTHOOT", "NOCTOWL", "LEDYBA", "LEDIAN", "SPINARAK", "ARIADOS", "CROBAT", "CHINCHOU", "LANTURN", "PICHU", "CLEFFA", "IGGLYBUFF",
47 | "TOGEPI", "TOGETIC", "NATU", "XATU", "MAREEP", "FLAAFFY", "AMPHAROS", "BELLOSSOM", "MARILL", "AZUMARILL", "SUDOWOODO", "POLITOED",
48 | "HOPPIP", "SKIPLOOM", "JUMPLUFF", "AIPOM", "SUNKERN", "SUNFLORA", "YANMA", "WOOPER", "QUAGSIRE", "ESPEON", "UMBREON", "MURKROW",
49 | "SLOWKING", "MISDREAVUS", "UNOWN", "WOBBUFFET", "GIRAFARIG", "PINECO", "FORRETRESS", "DUNSPARCE", "GLIGAR", "STEELIX", "SNUBBULL",
50 | "GRANBULL", "QWILFISH", "SCIZOR", "SHUCKLE", "HERACROSS", "SNEASEL", "TEDDIURSA", "URSARING", "SLUGMA", "MAGCARGO", "SWINUB",
51 | "PILOSWINE", "CORSOLA", "REMORAID", "OCTILLERY", "DELIBIRD", "MANTINE", "SKARMORY", "HOUNDOUR", "HOUNDOOM", "KINGDRA", "PHANPY",
52 | "DONPHAN", "PORYGON2", "STANTLER", "SMEARGLE", "TYROGUE", "HITMONTOP", "SMOOCHUM", "ELEKID", "MAGBY", "MILTANK", "BLISSEY", "RAIKOU",
53 | "ENTEI", "SUICUNE", "LARVITAR", "PUPITAR", "TYRANITAR", "LUGIA", "HO-OH", "CELEBI",
54 | -- Gen 3
55 | "TREECKO", "GROVYLE", "SCEPTILE", "TORCHIC", "COMBUSKEN", "BLAZIKEN", "MUDKIP", "MARSHTOMP", "SWAMPERT", "POOCHYENA", "MIGHTYENA",
56 | "ZIGZAGOON", "LINOONE", "WURMPLE", "SILCOON", "BEAUTIFLY", "CASCOON", "DUSTOX", "LOTAD", "LOMBRE", "LUDICOLO", "SEEDOT", "NUZLEAF",
57 | "SHIFTRY", "TAILLOW", "SWELLOW", "WINGULL", "PELIPPER", "RALTS", "KIRLIA", "GARDEVOIR", "SURSKIT", "MASQUERAIN", "SHROOMISH", "BRELOOM",
58 | "SLAKOTH", "VIGOROTH", "SLAKING", "NINCADA", "NINJASK", "SHEDINJA", "WHISMUR", "LOUDRED", "EXPLOUD", "MAKUHITA", "HARIYAMA", "AZURILL",
59 | "NOSEPASS", "SKITTY", "DELCATTY", "SABLEYE", "MAWILE", "ARON", "LAIRON", "AGGRON", "MEDITITE", "MEDICHAM", "ELECTRIKE", "MANECTRIC",
60 | "PLUSLE", "MINUN", "VOLBEAT", "ILLUMISE", "ROSELIA", "GULPIN", "SWALOT", "CARVANHA", "SHARPEDO", "WAILMER", "WAILORD", "NUMEL",
61 | "CAMERUPT", "TORKOAL", "SPOINK", "GRUMPIG", "SPINDA", "TRAPINCH", "VIBRAVA", "FLYGON", "CACNEA", "CACTURNE", "SWABLU", "ALTARIA",
62 | "ZANGOOSE", "SEVIPER", "LUNATONE", "SOLROCK", "BARBOACH", "WHISCASH", "CORPHISH", "CRAWDAUNT", "BALTOY", "CLAYDOL", "LILEEP", "CRADILY",
63 | "ANORITH", "ARMALDO", "FEEBAS", "MILOTIC", "CASTFORM", "KECLEON", "SHUPPET", "BANETTE", "DUSKULL", "DUSCLOPS", "TROPIUS", "CHIMECHO",
64 | "ABSOL", "WYNAUT", "SNORUNT", "GLALIE", "SPHEAL", "SEALEO", "WALREIN", "CLAMPERL", "HUNTAIL", "GOREBYSS", "RELICANTH", "LUVDISC", "BAGON",
65 | "SHELGON", "SALAMENCE", "BELDUM", "METANG", "METAGROSS", "REGIROCK", "REGICE", "REGISTEEL", "LATIAS", "LATIOS", "KYOGRE", "GROUDON",
66 | "RAYQUAZA", "JIRACHI", "DEOXYS"}
67 |
68 | local nationalDexList = {
69 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
70 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
71 | 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
72 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
73 | 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
74 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
75 | 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
76 | 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
77 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
78 | 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
79 | 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
80 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394,
81 | 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254,
82 | 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
83 | 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344,
84 | 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322,
85 | 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334,
86 | 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336,
87 | 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375,
88 | 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}
89 |
90 | local catchRatesList = {
91 | -- Gen 1
92 | 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 120, 90, 255, 120, 90, 255, 120,
93 | 45, 255, 127, 255, 90, 255, 90, 190, 75, 255, 90, 235, 120, 45, 235, 120,
94 | 45, 150, 25, 190, 75, 170, 50, 255, 90, 255, 120, 45, 190, 75, 190, 120,
95 | 255, 100, 255, 90, 190, 120, 190, 80, 190, 75, 255, 120, 90, 200, 100, 50,
96 | 180, 90, 45, 255, 120, 45, 190, 60, 255, 120, 45, 190, 110, 190, 75, 190,
97 | 110, 80, 190, 90, 190, 75, 190, 75, 190, 60, 190, 90, 45, 45, 190, 80, 225,
98 | 60, 190, 60, 90, 80, 190, 110, 90, 90, 90, 190, 60, 120, 100, 70, 90, 90,
99 | 225, 75, 225, 60, 225, 110, 90, 90, 45, 90, 90, 90, 80, 255, 45, 80, 35, 45,
100 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 70, 25, 25, 25, 45, 45, 45, 3, 45,
101 | -- Gen2
102 | 45, 180, 45, 45, 180, 45, 45, 180, 45, 255, 90, 255, 90, 255, 90, 255, 90,
103 | 90, 190, 75, 190, 150, 170, 190, 45, 190, 75, 235, 120, 45, 45, 190, 75, 65,
104 | 45, 255, 120, 45, 45, 235, 120, 75, 255, 90, 45, 45, 30, 70, 90, 225, 45, 60,
105 | 190, 75, 190, 60, 25, 190, 75, 45, 25, 190, 45, 60, 120, 60, 190, 120, 225,
106 | 75, 60, 190, 75, 45, 90, 15, 225, 45, 45, 120, 60, 45, 45, 45, 75, 45, 45, 45,
107 | 45, 45, 30, 15, 15, 15, 45, 45, 10, 3, 3, 45,
108 | -- Gen3
109 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 127, 255, 90, 255, 120, 45, 120, 45,
110 | 255, 120, 45, 255, 120, 45, 200, 90, 255, 45, 235, 120, 45, 200, 75, 255, 90,
111 | 255, 120, 45, 255, 120, 45, 190, 120, 45, 255, 200, 150, 255, 255, 120, 90, 120,
112 | 180, 90, 45, 180, 90, 120, 80, 200, 200, 150, 150, 150, 225, 75, 225, 60, 125,
113 | 60, 255, 150, 90, 255, 60, 255, 255, 120, 45, 190, 60, 255, 80, 90, 90, 100, 90,
114 | 190, 75, 205, 155, 255, 90, 45, 45, 45, 45, 255, 60, 45, 200, 225, 90, 190, 90,
115 | 45, 45, 30, 125, 190, 75, 255, 120, 45, 255, 60, 60, 25, 225, 45, 45, 80, 3, 3,
116 | 15, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3}
117 |
118 | function LCRNG(s, mul, sum)
119 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
120 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
121 |
122 | return b % 0x100000000
123 | end
124 |
125 | local tempCurrentSeed = 0
126 |
127 | function LCRNGDistance(state0, state1)
128 | local mask = 1
129 | local dist = 0
130 |
131 | if state0 ~= state1 then
132 | for _, data in ipairs(JUMP_DATA) do
133 | local mult, add = table.unpack(data)
134 |
135 | if state0 == state1 then
136 | break
137 | end
138 |
139 | if ((state0 ~ state1) & mask) ~= 0 then
140 | state0 = LCRNG(state0, mult, add)
141 | dist = dist + mask
142 | end
143 |
144 | mask = mask << 1
145 | end
146 |
147 | tempCurrentSeed = state1
148 | end
149 |
150 | return dist > 1000000 and dist - 0x100000000 or dist
151 | end
152 |
153 | local boxSelectedPokemonAddr, enemyAddr, boxFlagAddr, currentSeedAddr, boxPointerAddr, pointerAddr, initialSeed, advances
154 |
155 | function onScriptStart()
156 | local gameLang = read8Bit(0x3)
157 |
158 | if gameLang == 0x45 then -- U
159 | boxSelectedPokemonAddr = 0x3A95EC
160 | enemyAddr = 0x473070
161 | boxFlagAddr = 0x478B1A
162 | currentSeedAddr = 0x478C90
163 | boxPointerAddr = 0x47ADB8
164 | pointerAddr = 0x7EFDCC
165 | elseif gameLang == 0x4A then -- J
166 | boxSelectedPokemonAddr = 0x395CBC
167 | enemyAddr = 0x45E750
168 | boxFlagAddr = 0x4641EA
169 | currentSeedAddr = 0x464360
170 | boxPointerAddr = 0x466468
171 | pointerAddr = 0x75E088
172 | else -- E
173 | boxSelectedPokemonAddr = 0x3F6A6C
174 | enemyAddr = 0x4C0508
175 | boxFlagAddr = 0x4C5FBA
176 | currentSeedAddr = 0x4C6130
177 | boxPointerAddr = 0x4C8268
178 | pointerAddr = 0x90C300
179 | end
180 |
181 | initialSeed = read32Bit(currentSeedAddr)
182 | tempCurrentSeed = initialSeed
183 | advances = 0
184 | end
185 |
186 | function getTrainerIDs(pointer)
187 | local trainerIDsAddr = pointer + 0x7FFE42E0
188 | local trainerIDs = read32Bit(trainerIDsAddr)
189 | local TID = trainerIDs & 0xFFFF
190 | local SID = trainerIDs >> 16
191 |
192 | return TID, SID
193 | end
194 |
195 | function setPadding(maxLength, goodSpacing, stringVar)
196 | local spaces = ""
197 | local stringVarLength = string.len(stringVar)
198 |
199 | if stringVarLength <= maxLength then
200 | local padding = maxLength - stringVarLength
201 |
202 | for i = 0, padding + goodSpacing do
203 | spaces = spaces.." "
204 | end
205 | end
206 |
207 | return spaces
208 | end
209 |
210 | function calcCatchRate(HP, bonusBall, rate)
211 | if HP ~= 0 then
212 | local a = (HP * rate * bonusBall) // (3 * HP)
213 |
214 | return 1048560 // math.sqrt(math.sqrt(16711680 // a))
215 | end
216 |
217 | return 0
218 | end
219 |
220 | function getPokemonInfo(addr, trainerTID, trainerSID)
221 | trainerTID = trainerTID or nil
222 | trainerSID = trainerSID or nil
223 |
224 | local pokemonPID = read32Bit(addr)
225 | local speciesDexIndex = read16Bit(addr - 0x4)
226 | local OTSID = trainerSID and trainerSID or read16Bit(addr + 0x10)
227 | local OTID = trainerTID and trainerTID or read16Bit(addr + 0x12)
228 |
229 | local ivsAddr = addr + 0xA1
230 | local hpIV = read8Bit(ivsAddr)
231 | local atkIV = read8Bit(ivsAddr + 0x2)
232 | local defIV = read8Bit(ivsAddr + 0x4)
233 | local spAtkIV = read8Bit(ivsAddr + 0x6)
234 | local spDefIV = read8Bit(ivsAddr + 0x8)
235 | local spdIV = read8Bit(ivsAddr + 0xA)
236 |
237 | local speciesDexNumber = nationalDexList[((speciesDexIndex > 411 or speciesDexIndex < 1) and 0 or speciesDexIndex) + 1] + 1
238 | local speciesName = speciesNamesList[speciesDexNumber]
239 | speciesName = speciesName..setPadding(10, 5, speciesName)
240 | local natureName = natureNamesList[(pokemonPID % 25) + 1]
241 | natureName = natureName..setPadding(7, 9, natureName)
242 |
243 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
244 | + (32 * (spDefIV & 1))) * 15) // 63
245 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
246 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
247 |
248 | local catchRateValue = calcCatchRate(read16Bit(addr + 0x86), 1, catchRatesList[speciesDexNumber])
249 |
250 | return pokemonPID, OTSID, OTID, speciesName, natureName, hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV, hpType, hpPower, catchRateValue
251 | end
252 |
253 | function isBoxOpened()
254 | return read16Bit(boxFlagAddr) == 0x391
255 | end
256 |
257 | function shinyCheck(PID, trainerID, trainerSID)
258 | local lowPID = PID & 0xFFFF
259 | local highPID = PID >> 16
260 | local shinyTypeValue = trainerID ~ trainerSID ~ lowPID ~ highPID
261 |
262 | if shinyTypeValue < 8 then
263 | return shinyTypeValue == 0 and " (Square) " or " (Star) "
264 | end
265 |
266 | return " "
267 | end
268 |
269 | function getPokemonInfoText(pointer, trainerTID, trainerSID)
270 | local text = ""
271 |
272 | local boxPID, boxOTID, boxOTSID, boxSpeciesName, boxNatureName, boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV, boxHpType,
273 | boxHpPower, boxCatchRateValue = getPokemonInfo(isBoxOpened() and boxSelectedPokemonAddr or read32Bit(boxPointerAddr) + 0xBA0) -- Current selected Pokémon or 1st slot of 1st box
274 |
275 | for i = 0, 5 do
276 | local enemyPID, enemyOTID, enemyOTSID, enemySpeciesName, enemyNatureName, enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV,
277 | enemySpdIV, enemyHpType, enemyHpPower, enemyCatchRateValue = getPokemonInfo(enemyAddr + (0x138 * i), trainerTID, trainerSID)
278 |
279 | local partyAddr = pointer + 0x7FFE42E8
280 | local partyPID, partyOTID, partyOTSID, partySpeciesName, partyNatureName, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV,
281 | partySpdIV, partyHpType, partyHpPower, partyCatchRateValue = getPokemonInfo(partyAddr + (0x138 * i))
282 |
283 | local speciesText = string.format("Species: %sSpecies: %s", enemySpeciesName, partySpeciesName)..(i == 0 and string.format("Species: %s", boxSpeciesName) or "")
284 | local PIDsText = string.format("\nPID: %08X%sPID: %08X%s", enemyPID, shinyCheck(enemyPID, enemyOTID, enemyOTSID), partyPID, shinyCheck(partyPID, partyOTID, partyOTSID))..
285 | (i == 0 and string.format("PID: %08X%s", boxPID, shinyCheck(boxPID, boxOTID, boxOTSID)) or "")
286 | local naturesText = string.format("\nNature: %sNature: %s", enemyNatureName, partyNatureName)..(i == 0 and string.format("Nature: %s", boxNatureName) or "")
287 | local ivsText = string.format("\nIVs: %02d/%02d/%02d/%02d/%02d/%02d IVs: %02d/%02d/%02d/%02d/%02d/%02d",
288 | enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV, enemySpdIV, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV, partySpdIV)..
289 | (i == 0 and string.format(" IVs: %02d/%02d/%02d/%02d/%02d/%02d", boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV) or "")
290 | local HPText = string.format("\nHPower: %s %02d", HPTypeNamesList[enemyHpType + 1], enemyHpPower)..setPadding(11, 5, string.format("%s %02d", HPTypeNamesList[enemyHpType + 1], enemyHpPower))..
291 | string.format("HPower: %s %02d", HPTypeNamesList[partyHpType + 1], partyHpPower)..
292 | (i == 0 and setPadding(11, 5, string.format("%s %02d", HPTypeNamesList[partyHpType + 1], partyHpPower))..
293 | string.format("HPower: %s %02d", HPTypeNamesList[boxHpType + 1], boxHpPower) or "")
294 | local catchRngText = string.format("\nCatch Rate Value: %d\n\n", enemyCatchRateValue)
295 |
296 | text = text..speciesText..PIDsText..naturesText..ivsText..HPText..catchRngText
297 | end
298 |
299 | return text
300 | end
301 |
302 | function onScriptUpdate()
303 | local currentSeed = read32Bit(currentSeedAddr)
304 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
305 | local pointer = read32Bit(pointerAddr)
306 | local trainerTID, trainerSID = 0, 0
307 |
308 | local RNGInfoText = string.format("Initial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d", initialSeed, currentSeed, advances)
309 | local infoText = "\n\n"
310 |
311 | if pointer ~= 0 then
312 | trainerTID, trainerSID = getTrainerIDs(pointer)
313 | infoText = string.format("\n\nOpponent Party Box\n\n")..getPokemonInfoText(pointer, trainerTID, trainerSID)
314 | end
315 |
316 | local IDsInfoText = string.format("\nTID: %05d\nSID: %05d", trainerTID, trainerSID)
317 |
318 | SetScreenText(RNGInfoText..infoText..IDsInfoText)
319 | end
320 |
321 | function onScriptCancel()
322 | SetScreenText("")
323 | end
324 |
325 | function onStateLoaded()
326 | end
327 |
328 | function onStateSaved()
329 | end
--------------------------------------------------------------------------------
/Gen 3/Dolphin/XD_RNG_Dolphin.lua:
--------------------------------------------------------------------------------
1 | read32Bit = ReadValue32
2 | read16Bit = ReadValue16
3 | read8Bit = ReadValue8
4 |
5 | local JUMP_DATA = {
6 | {0x343FD, 0x269EC3}, {0xA9FC6809, 0x1E278E7A}, {0xDDFF5051, 0x98520C4}, {0xF490B9A1, 0x7E1DBEC8},
7 | {0x43BA1741, 0x3E314290}, {0xD290BE81, 0x824E1920}, {0x82E3BD01, 0x844E8240}, {0xBF507A01, 0xFD864480},
8 | {0xF8C4F401, 0xDFB18900}, {0x7A19E801, 0xD9F71200}, {0x1673D001, 0x5E3E2400}, {0xB5E7A001, 0x65BC4800},
9 | {0x8FCF4001, 0x70789000}, {0xAF9E8001, 0x74F12000}, {0x9F3D0001, 0x39E24000}, {0x3E7A0001, 0xB3C48000},
10 | {0x7CF40001, 0x67890000}, {0xF9E80001, 0xCF120000}, {0xF3D00001, 0x9E240000}, {0xE7A00001, 0x3C480000},
11 | {0xCF400001, 0x78900000}, {0x9E800001, 0xF1200000}, {0x3D000001, 0xE2400000}, {0x7A000001, 0xC4800000},
12 | {0xF4000001, 0x89000000}, {0xE8000001, 0x12000000}, {0xD0000001, 0x24000000}, {0xA0000001, 0x48000000},
13 | {0x40000001, 0x90000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
14 |
15 | local natureNamesList = {
16 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
17 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
18 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
19 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
20 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
21 |
22 | local HPTypeNamesList = {
23 | "Fighting", "Flying", "Poison", "Ground",
24 | "Rock", "Bug", "Ghost", "Steel",
25 | "Fire", "Water", "Grass", "Electric",
26 | "Psychic", "Ice", "Dragon", "Dark"}
27 |
28 | local speciesNamesList = {
29 | -- Gen 1
30 | "NONE", "BULBASAUR", "IVYSAUR", "VENUSAUR", "CHARMANDER", "CHARMELEON", "CHARIZARD", "SQUIRTLE", "WARTORTLE", "BLASTOISE",
31 | "CATERPIE", "METAPOD", "BUTTERFREE", "WEEDLE", "KAKUNA", "BEEDRILL", "PIDGEY", "PIDGEOTTO", "PIDGEOT", "RATTATA", "RATICATE",
32 | "SPEAROW", "FEAROW", "EKANS", "ARBOK", "PIKACHU", "RAICHU", "SANDSHREW", "SANDSLASH", "NIDORAN♀", "NIDORINA", "NIDOQUEEN",
33 | "NIDORAN♂", "NIDORINO", "NIDOKING", "CLEFAIRY", "CLEFABLE", "VULPIX", "NINETALES", "JIGGLYPUFF", "WIGGLYTUFF", "ZUBAT", "GOLBAT",
34 | "ODDISH", "GLOOM", "VILEPLUME", "PARAS", "PARASECT", "VENONAT", "VENOMOTH", "DIGLETT", "DUGTRIO", "MEOWTH", "PERSIAN", "PSYDUCK",
35 | "GOLDUCK", "MANKEY", "PRIMEAPE", "GROWLITHE", "ARCANINE", "POLIWAG", "POLIWHIRL", "POLIWRATH", "ABRA", "KADABRA", "ALAKAZAM",
36 | "MACHOP", "MACHOKE", "MACHAMP", "BELLSPROUT", "WEEPINBELL", "VICTREEBEL", "TENTACOOL", "TENTACRUEL", "GEODUDE", "GRAVELER",
37 | "GOLEM", "PONYTA", "RAPIDASH", "SLOWPOKE", "SLOWBRO", "MAGNEMITE", "MAGNETON", "FARFETCH'D", "DODUO", "DODRIO", "SEEL", "DEWGONG",
38 | "GRIMER", "MUK", "SHELLDER", "CLOYSTER", "GASTLY", "HAUNTER", "GENGAR", "ONIX", "DROWZEE", "HYPNO", "KRABBY", "KINGLER", "VOLTORB",
39 | "ELECTRODE", "EXEGGCUTE", "EXEGGUTOR", "CUBONE", "MAROWAK", "HITMONLEE", "HITMONCHAN", "LICKITUNG", "KOFFING", "WEEZING", "RHYHORN",
40 | "RHYDON", "CHANSEY", "TANGELA", "KANGASKHAN", "HORSEA", "SEADRA", "GOLDEEN", "SEAKING", "STARYU", "STARMIE", "MR.MIME", "SCYTHER",
41 | "JYNX", "ELECTABUZZ", "MAGMAR", "PINSIR", "TAUROS", "MAGIKARP", "GYARADOS", "LAPRAS", "DITTO", "EEVEE", "VAPOREON", "JOLTEON",
42 | "FLAREON", "PORYGON", "OMANYTE", "OMASTAR", "KABUTO", "KABUTOPS", "AERODACTYL", "SNORLAX", "ARTICUNO", "ZAPDOS", "MOLTRES",
43 | "DRATINI", "DRAGONAIR", "DRAGONITE", "MEWTWO", "MEW",
44 | -- Gen 2
45 | "CHIKORITA", "BAYLEEF", "MEGANIUM", "CYNDAQUIL", "QUILAVA", "TYPHLOSION", "TOTODILE", "CROCONAW", "FERALIGATR", "SENTRET", "FURRET",
46 | "HOOTHOOT", "NOCTOWL", "LEDYBA", "LEDIAN", "SPINARAK", "ARIADOS", "CROBAT", "CHINCHOU", "LANTURN", "PICHU", "CLEFFA", "IGGLYBUFF",
47 | "TOGEPI", "TOGETIC", "NATU", "XATU", "MAREEP", "FLAAFFY", "AMPHAROS", "BELLOSSOM", "MARILL", "AZUMARILL", "SUDOWOODO", "POLITOED",
48 | "HOPPIP", "SKIPLOOM", "JUMPLUFF", "AIPOM", "SUNKERN", "SUNFLORA", "YANMA", "WOOPER", "QUAGSIRE", "ESPEON", "UMBREON", "MURKROW",
49 | "SLOWKING", "MISDREAVUS", "UNOWN", "WOBBUFFET", "GIRAFARIG", "PINECO", "FORRETRESS", "DUNSPARCE", "GLIGAR", "STEELIX", "SNUBBULL",
50 | "GRANBULL", "QWILFISH", "SCIZOR", "SHUCKLE", "HERACROSS", "SNEASEL", "TEDDIURSA", "URSARING", "SLUGMA", "MAGCARGO", "SWINUB",
51 | "PILOSWINE", "CORSOLA", "REMORAID", "OCTILLERY", "DELIBIRD", "MANTINE", "SKARMORY", "HOUNDOUR", "HOUNDOOM", "KINGDRA", "PHANPY",
52 | "DONPHAN", "PORYGON2", "STANTLER", "SMEARGLE", "TYROGUE", "HITMONTOP", "SMOOCHUM", "ELEKID", "MAGBY", "MILTANK", "BLISSEY", "RAIKOU",
53 | "ENTEI", "SUICUNE", "LARVITAR", "PUPITAR", "TYRANITAR", "LUGIA", "HO-OH", "CELEBI",
54 | -- Gen 3
55 | "TREECKO", "GROVYLE", "SCEPTILE", "TORCHIC", "COMBUSKEN", "BLAZIKEN", "MUDKIP", "MARSHTOMP", "SWAMPERT", "POOCHYENA", "MIGHTYENA",
56 | "ZIGZAGOON", "LINOONE", "WURMPLE", "SILCOON", "BEAUTIFLY", "CASCOON", "DUSTOX", "LOTAD", "LOMBRE", "LUDICOLO", "SEEDOT", "NUZLEAF",
57 | "SHIFTRY", "TAILLOW", "SWELLOW", "WINGULL", "PELIPPER", "RALTS", "KIRLIA", "GARDEVOIR", "SURSKIT", "MASQUERAIN", "SHROOMISH", "BRELOOM",
58 | "SLAKOTH", "VIGOROTH", "SLAKING", "NINCADA", "NINJASK", "SHEDINJA", "WHISMUR", "LOUDRED", "EXPLOUD", "MAKUHITA", "HARIYAMA", "AZURILL",
59 | "NOSEPASS", "SKITTY", "DELCATTY", "SABLEYE", "MAWILE", "ARON", "LAIRON", "AGGRON", "MEDITITE", "MEDICHAM", "ELECTRIKE", "MANECTRIC",
60 | "PLUSLE", "MINUN", "VOLBEAT", "ILLUMISE", "ROSELIA", "GULPIN", "SWALOT", "CARVANHA", "SHARPEDO", "WAILMER", "WAILORD", "NUMEL",
61 | "CAMERUPT", "TORKOAL", "SPOINK", "GRUMPIG", "SPINDA", "TRAPINCH", "VIBRAVA", "FLYGON", "CACNEA", "CACTURNE", "SWABLU", "ALTARIA",
62 | "ZANGOOSE", "SEVIPER", "LUNATONE", "SOLROCK", "BARBOACH", "WHISCASH", "CORPHISH", "CRAWDAUNT", "BALTOY", "CLAYDOL", "LILEEP", "CRADILY",
63 | "ANORITH", "ARMALDO", "FEEBAS", "MILOTIC", "CASTFORM", "KECLEON", "SHUPPET", "BANETTE", "DUSKULL", "DUSCLOPS", "TROPIUS", "CHIMECHO",
64 | "ABSOL", "WYNAUT", "SNORUNT", "GLALIE", "SPHEAL", "SEALEO", "WALREIN", "CLAMPERL", "HUNTAIL", "GOREBYSS", "RELICANTH", "LUVDISC", "BAGON",
65 | "SHELGON", "SALAMENCE", "BELDUM", "METANG", "METAGROSS", "REGIROCK", "REGICE", "REGISTEEL", "LATIAS", "LATIOS", "KYOGRE", "GROUDON",
66 | "RAYQUAZA", "JIRACHI", "DEOXYS"}
67 |
68 | local nationalDexList = {
69 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
70 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
71 | 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
72 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
73 | 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
74 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
75 | 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
76 | 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
77 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
78 | 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
79 | 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
80 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394,
81 | 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254,
82 | 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
83 | 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344,
84 | 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322,
85 | 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334,
86 | 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336,
87 | 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375,
88 | 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}
89 |
90 | local catchRatesList = {
91 | -- Gen 1
92 | 0, 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 120, 90, 255, 120, 90, 255, 120,
93 | 45, 255, 127, 255, 90, 255, 90, 190, 75, 255, 90, 235, 120, 45, 235, 120,
94 | 45, 150, 25, 190, 75, 170, 50, 255, 90, 255, 120, 45, 190, 75, 190, 120,
95 | 255, 100, 255, 90, 190, 120, 190, 80, 190, 75, 255, 120, 90, 200, 100, 50,
96 | 180, 90, 45, 255, 120, 45, 190, 60, 255, 120, 45, 190, 110, 190, 75, 190,
97 | 110, 80, 190, 90, 190, 75, 190, 75, 190, 60, 190, 90, 45, 45, 190, 80, 225,
98 | 60, 190, 60, 90, 80, 190, 110, 90, 90, 90, 190, 60, 120, 100, 70, 90, 90,
99 | 225, 75, 225, 60, 225, 110, 90, 90, 45, 90, 90, 90, 80, 255, 45, 80, 35, 45,
100 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 70, 25, 25, 25, 45, 45, 45, 3, 45,
101 | -- Gen2
102 | 45, 180, 45, 45, 180, 45, 45, 180, 45, 255, 90, 255, 90, 255, 90, 255, 90,
103 | 90, 190, 75, 190, 150, 170, 190, 45, 190, 75, 235, 120, 45, 45, 190, 75, 65,
104 | 45, 255, 120, 45, 45, 235, 120, 75, 255, 90, 45, 45, 30, 70, 90, 225, 45, 60,
105 | 190, 75, 190, 60, 25, 190, 75, 45, 25, 190, 45, 60, 120, 60, 190, 120, 225,
106 | 75, 60, 190, 75, 45, 90, 15, 225, 45, 45, 120, 60, 45, 45, 45, 75, 45, 45, 45,
107 | 45, 45, 30, 15, 15, 15, 45, 45, 10, 3, 3, 45,
108 | -- Gen3
109 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 127, 255, 90, 255, 120, 45, 120, 45,
110 | 255, 120, 45, 255, 120, 45, 200, 90, 255, 45, 235, 120, 45, 200, 75, 255, 90,
111 | 255, 120, 45, 255, 120, 45, 190, 120, 45, 255, 200, 150, 255, 255, 120, 90, 120,
112 | 180, 90, 45, 180, 90, 120, 80, 200, 200, 150, 150, 150, 225, 75, 225, 60, 125,
113 | 60, 255, 150, 90, 255, 60, 255, 255, 120, 45, 190, 60, 255, 80, 90, 90, 100, 90,
114 | 190, 75, 205, 155, 255, 90, 45, 45, 45, 45, 255, 60, 45, 200, 225, 90, 190, 90,
115 | 45, 45, 30, 125, 190, 75, 255, 120, 45, 255, 60, 60, 25, 225, 45, 45, 80, 3, 3,
116 | 15, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3}
117 |
118 | function LCRNG(s, mul, sum)
119 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
120 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
121 |
122 | return b % 0x100000000
123 | end
124 |
125 | local tempCurrentSeed = 0
126 |
127 | function LCRNGDistance(state0, state1)
128 | local mask = 1
129 | local dist = 0
130 |
131 | if state0 ~= state1 then
132 | for _, data in ipairs(JUMP_DATA) do
133 | local mult, add = table.unpack(data)
134 |
135 | if state0 == state1 then
136 | break
137 | end
138 |
139 | if ((state0 ~ state1) & mask) ~= 0 then
140 | state0 = LCRNG(state0, mult, add)
141 | dist = dist + mask
142 | end
143 |
144 | mask = mask << 1
145 | end
146 |
147 | tempCurrentSeed = state1
148 | end
149 |
150 | return dist > 1000000 and dist - 0x100000000 or dist
151 | end
152 |
153 | local offset = 0x10
154 | local boxSelectedSlotIndexAddr, enemyAddr, currentSeedAddr, currentBoxIndexAddr, pointerAddr, boxFlagAddr, initialSeed, advances
155 |
156 | function onScriptStart()
157 | local gameLang = read8Bit(0x3)
158 |
159 | if gameLang == 0x45 then -- U
160 | boxSelectedSlotIndexAddr = 0x4355FB
161 | enemyAddr = 0x4A86F4
162 | currentSeedAddr = 0x4E8610
163 | currentBoxIndexAddr = 0x4EB2E8
164 | pointerAddr = 0x4EB6F8
165 | boxFlagAddr = 0x80E6B6
166 | elseif gameLang == 0x4A then -- J
167 | offset = 0
168 | boxSelectedSlotIndexAddr = 0x412B4B
169 | enemyAddr = 0x485c14
170 | currentSeedAddr = 0x4C5B28
171 | currentBoxIndexAddr = 0x4C87D8
172 | pointerAddr = 0x4C8BE8
173 | boxFlagAddr = 0x7EBB16
174 | else -- E
175 | boxSelectedSlotIndexAddr = 0x46FBD3
176 | enemyAddr = 0x4E2CD4
177 | currentSeedAddr = 0x522BF0
178 | currentBoxIndexAddr = 0x5258D0
179 | pointerAddr = 0x525CE0
180 | boxFlagAddr = 0x866CB6
181 | end
182 |
183 | initialSeed = read32Bit(currentSeedAddr)
184 | tempCurrentSeed = initialSeed
185 | advances = 0
186 | end
187 |
188 | function getTrainerIDs(pointer)
189 | local trainerIDsAddr = pointer + 0x15C + offset
190 | local trainerIDs = read32Bit(trainerIDsAddr)
191 | local TID = trainerIDs & 0xFFFF
192 | local SID = trainerIDs >> 16
193 |
194 | return TID, SID
195 | end
196 |
197 | function isBoxOpened()
198 | return read16Bit(boxFlagAddr) == 0x391
199 | end
200 |
201 | function getBoxSelectedPokemonAddr(pointer, partyAddr)
202 | local boxAddr = pointer + 0xAFC + offset
203 |
204 | if isBoxOpened() then
205 | local boxSelectedSlotIndex = read8Bit(boxSelectedSlotIndexAddr)
206 |
207 | if boxSelectedSlotIndex < 4 then -- Index value is lower than 4 when you don't select a Pokémon slot
208 | return boxAddr
209 | elseif boxSelectedSlotIndex >= 4 and boxSelectedSlotIndex <= 9 then
210 | return partyAddr + (0xC4 * (boxSelectedSlotIndex - 4)) -- Box slot index value starts from 4 in party selection
211 | end
212 |
213 | local currentBoxIndex = read8Bit(currentBoxIndexAddr)
214 |
215 | return boxAddr + (0xC4 * (boxSelectedSlotIndex - 10)) + (0x14 * currentBoxIndex) + (0xC4 * currentBoxIndex * 0x1E) -- Box slot index value starts from 10 in box selection
216 | end
217 |
218 | return boxAddr
219 | end
220 |
221 | function setPadding(maxLength, goodSpacing, stringVar)
222 | local spaces = ""
223 | local stringVarLength = string.len(stringVar)
224 |
225 | if stringVarLength <= maxLength then
226 | local padding = maxLength - stringVarLength
227 |
228 | for i = 0, padding + goodSpacing do
229 | spaces = spaces.." "
230 | end
231 | end
232 |
233 | return spaces
234 | end
235 |
236 | function calcCatchRate(HP, bonusBall, rate)
237 | if HP ~= 0 then
238 | local a = (HP * rate * bonusBall) // (3 * HP)
239 |
240 | return 1048560 // math.sqrt(math.sqrt(16711680 // a))
241 | end
242 |
243 | return 0
244 | end
245 |
246 | function getPokemonInfo(addr, trainerTID, trainerSID)
247 | trainerTID = trainerTID or nil
248 | trainerSID = trainerSID or nil
249 |
250 | local pokemonPID = read32Bit(addr)
251 | local speciesDexIndex = read16Bit(addr - 0x28)
252 | local OTSID = trainerSID and trainerSID or read16Bit(addr - 0x2)
253 | local OTID = trainerTID and trainerTID or read16Bit(addr - 0x4)
254 |
255 | local ivsAddr = addr + 0x80
256 | local hpIV = read8Bit(ivsAddr)
257 | local atkIV = read8Bit(ivsAddr + 0x1)
258 | local defIV = read8Bit(ivsAddr + 0x2)
259 | local spAtkIV = read8Bit(ivsAddr + 0x3)
260 | local spDefIV = read8Bit(ivsAddr + 0x4)
261 | local spdIV = read8Bit(ivsAddr + 0x5)
262 |
263 | local speciesDexNumber = nationalDexList[((speciesDexIndex > 411 or speciesDexIndex < 1) and 0 or speciesDexIndex) + 1] + 1
264 | local speciesName = speciesNamesList[speciesDexNumber]
265 | speciesName = speciesName..setPadding(10, 5, speciesName)
266 | local natureName = natureNamesList[(pokemonPID % 25) + 1]
267 | natureName = natureName..setPadding(7, 9, natureName)
268 |
269 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
270 | + (32 * (spDefIV & 1))) * 15) // 63
271 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
272 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
273 |
274 | local catchRateValue = calcCatchRate(read16Bit(addr + 0x69), 1, catchRatesList[speciesDexNumber])
275 |
276 | return pokemonPID, OTSID, OTID, speciesName, natureName, hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV, hpType, hpPower, catchRateValue
277 | end
278 |
279 | function shinyCheck(PID, trainerID, trainerSID)
280 | local lowPID = PID & 0xFFFF
281 | local highPID = PID >> 16
282 | local shinyTypeValue = trainerID ~ trainerSID ~ lowPID ~ highPID
283 |
284 | if shinyTypeValue < 8 then
285 | return shinyTypeValue == 0 and " (Square) " or " (Star) "
286 | end
287 |
288 | return " "
289 | end
290 |
291 | function getPokemonInfoText(pointer, trainerTID, trainerSID)
292 | local text = ""
293 |
294 | local partyAddr = pointer + 0x188 + offset
295 | local boxSelectedPokemonAddr = getBoxSelectedPokemonAddr(pointer, partyAddr)
296 | local boxPID, boxOTID, boxOTSID, boxSpeciesName, boxNatureName, boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV, boxHpType,
297 | boxHpPower, boxCatchRateValue = getPokemonInfo(boxSelectedPokemonAddr) -- Current selected Pokémon or 1st slot of 1st box
298 |
299 | for i = 0, 5 do
300 | local enemyPID, enemyOTID, enemyOTSID, enemySpeciesName, enemyNatureName, enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV,
301 | enemySpdIV, enemyHpType, enemyHpPower, enemyCatchRateValue = getPokemonInfo(enemyAddr + (0xC4 * i), trainerTID, trainerSID)
302 |
303 | local partyPID, partyOTID, partyOTSID, partySpeciesName, partyNatureName, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV,
304 | partySpdIV, partyHpType, partyHpPower, partyCatchRateValue = getPokemonInfo(partyAddr + (0xC4 * i))
305 |
306 | local speciesText = string.format("Species: %sSpecies: %s", enemySpeciesName, partySpeciesName)..(i == 0 and string.format("Species: %s", boxSpeciesName) or "")
307 | local PIDsText = string.format("\nPID: %08X%sPID: %08X%s", enemyPID, shinyCheck(enemyPID, enemyOTID, enemyOTSID), partyPID, shinyCheck(partyPID, partyOTID, partyOTSID))..
308 | (i == 0 and string.format("PID: %08X%s", boxPID, shinyCheck(boxPID, boxOTID, boxOTSID)) or "")
309 | local naturesText = string.format("\nNature: %sNature: %s", enemyNatureName, partyNatureName)..(i == 0 and string.format("Nature: %s", boxNatureName) or "")
310 | local ivsText = string.format("\nIVs: %02d/%02d/%02d/%02d/%02d/%02d IVs: %02d/%02d/%02d/%02d/%02d/%02d",
311 | enemyHpIV, enemyAtkIV, enemyDefIV, enemySpAtkIV, enemySpDefIV, enemySpdIV, partyHpIV, partyAtkIV, partyDefIV, partySpAtkIV, partySpDefIV, partySpdIV)..
312 | (i == 0 and string.format(" IVs: %02d/%02d/%02d/%02d/%02d/%02d", boxHpIV, boxAtkIV, boxDefIV, boxSpAtkIV, boxSpDefIV, boxSpdIV) or "")
313 | local HPText = string.format("\nHPower: %s %02d", HPTypeNamesList[enemyHpType + 1], enemyHpPower)..setPadding(11, 5, string.format("%s %02d", HPTypeNamesList[enemyHpType + 1], enemyHpPower))..
314 | string.format("HPower: %s %02d", HPTypeNamesList[partyHpType + 1], partyHpPower)..
315 | (i == 0 and setPadding(11, 5, string.format("%s %02d", HPTypeNamesList[partyHpType + 1], partyHpPower))..
316 | string.format("HPower: %s %02d", HPTypeNamesList[boxHpType + 1], boxHpPower) or "")
317 | local catchRngText = string.format("\nCatch Rate Value: %d\n\n", enemyCatchRateValue)
318 |
319 | text = text..speciesText..PIDsText..naturesText..ivsText..HPText..catchRngText
320 | end
321 |
322 | return text
323 | end
324 |
325 | function onScriptUpdate()
326 | local currentSeed = read32Bit(currentSeedAddr)
327 | advances = advances + LCRNGDistance(tempCurrentSeed, currentSeed)
328 | local pointer = read32Bit(pointerAddr)
329 | local trainerTID, trainerSID = 0, 0
330 |
331 | local RNGInfoText = string.format("Initial Seed: %08X\nCurrent Seed: %08X\nAdvances: %d", initialSeed, currentSeed, advances)
332 | local infoText = "\n\n"
333 |
334 | if pointer ~= 0 then
335 | trainerTID, trainerSID = getTrainerIDs(pointer)
336 | infoText = string.format("\n\nOpponent Party Box\n\n")..getPokemonInfoText(pointer, trainerTID, trainerSID)
337 | end
338 |
339 | local IDsInfoText = string.format("\nTID: %05d\nSID: %05d", trainerTID, trainerSID)
340 |
341 | SetScreenText(RNGInfoText..infoText..IDsInfoText)
342 | end
343 |
344 | function onScriptCancel()
345 | SetScreenText("")
346 | end
347 |
348 | function onStateLoaded()
349 | end
350 |
351 | function onStateSaved()
352 | end
--------------------------------------------------------------------------------
/Gen 3/mGBA/RS_RNG_Checksums_mGBA.lua:
--------------------------------------------------------------------------------
1 | local targetSeed = 0xD517 -- Write here the target seed
2 | local targetHour = 0 -- Write here the target hours
3 | local targetMinute = 9 -- Write here the target minutes
4 | local targetSecond = 24 -- Write here the target seconds
5 | local targetSixtiethSecond = 22 -- Write here the target sixtieth seconds
6 | local savePath = "D:\\Desktop\\mGBA\\battery\\Pokemon - Ruby Version (USA, Europe) (Rev 2).sav" -- Write here the path of your Ruby/Sapphire save file
7 |
8 | local charMap = {
9 | " ", "À", "Á", "Â", "Ç", "È", "É", "Ê", "Ë", "Ì", "こ", "Î", "Ï", "Ò", "Ó", "Ô",
10 | "Œ", "Ù", "Ú", "Û", "Ñ", "ß", "à", "á", "ね", "ç", "è", "é", "ê", "ë", "ì", "ま",
11 | "î", "ï", "ò", "ó", "ô", "œ", "ù", "ú", "û", "ñ", "º", "ª", "�", "&", "+", "あ",
12 | "ぃ", "ぅ", "ぇ", "ぉ", "v", "=", "ょ", "が", "ぎ", "ぐ", "げ", "ご", "ざ", "じ", "ず", "ぜ",
13 | "ぞ", "だ", "ぢ", "づ", "で", "ど", "ば", "び", "ぶ", "べ", "ぼ", "ぱ", "ぴ", "ぷ", "ぺ", "ぽ",
14 | "っ", "¿", "¡", "P\u{200d}k", "M\u{200d}n", "P\u{200d}o", "K\u{200d}é", "�", "�", "�", "Í",
15 | "%", "(", ")", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "â", "ノ", "ハ", "ヒ",
16 | "フ", "ヘ", "ホ", "í", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "⬆", "⬇", "⬅",
17 | "➡", "ヲ", "ン", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ガ", "ギ", "グ", "ゲ", "ゴ",
18 | "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ",
19 | "ピ", "プ", "ペ", "ポ", "ッ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "!", "?", ".",
20 | "-", "・", "…", "“", "”", "‘", "’", "♂", "♀", "$", ",", "×", "/", "A", "B", "C", "D", "E",
21 | "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
22 | "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
23 | "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "▶",
24 | ":", "Ä", "Ö", "Ü", "ä", "ö", "ü", "⬆", "⬇", "⬅", "�", "�", "�", "�", "�", ""
25 | }
26 |
27 | local GameInfo, Jirachi, TENANNIV, TrainerInfo, Option, SaveInfo, Checksums
28 |
29 | function initializeBuffers()
30 | GameInfo = console:createBuffer("Game Info")
31 | GameInfo:setSize(100, 100)
32 | Jirachi = console:createBuffer("Jirachi")
33 | Jirachi:setSize(100, 100)
34 | TENANNIV = console:createBuffer("10ANNIV / Aura Mew")
35 | TENANNIV:setSize(100, 100)
36 | TrainerInfo = console:createBuffer("Trainer Info")
37 | TrainerInfo:setSize(100, 100)
38 | Option = console:createBuffer("Option")
39 | Option:setSize(100, 100)
40 | SaveInfo = console:createBuffer("Save Info")
41 | SaveInfo:setSize(100, 100)
42 | --Checksums = console:createBuffer("Checksums")
43 | --Checksums:setSize(100, 100)
44 | end
45 |
46 | local gameVersion, gameRegion = "", ""
47 | local wrongGameVersion, wrongGameRegion, currentSeedAddr
48 | local saveBlock2Addr = 0x2024EA4
49 | local saveBlock1Addr = 0x2025734
50 | local starterPokemonIndexAddr = 0x2026ABA
51 | local startingChecksumBlockAddr = 0xE000FF4
52 |
53 | function setGameVersion()
54 | local gameVersionCode = emu:read8(0x80000AE)
55 | local gameRegionCode = emu:read8(0x80000AF)
56 |
57 | if gameVersionCode == 0x45 then -- Check game version
58 | gameVersion = "Emerald"
59 | elseif gameVersionCode == 0x47 then
60 | gameVersion = "LeafGreen"
61 | elseif gameVersionCode == 0x50 then
62 | gameVersion = "Sapphire"
63 | elseif gameVersionCode == 0x52 then
64 | gameVersion = "FireRed"
65 | elseif gameVersionCode == 0x56 then
66 | gameVersion = "Ruby"
67 | end
68 |
69 | if gameRegionCode == 0x45 then -- Check game region and set addresses
70 | gameRegion = "USA"
71 | currentSeedAddr = 0x3004818
72 | elseif gameRegionCode == 0x4A then
73 | gameRegion = "JPN"
74 | elseif gameRegionCode == 0x44 or gameRegionCode == 0x46 or gameRegionCode == 0x49 or gameRegionCode == 0x53 then
75 | gameRegion = "EUR"
76 | currentSeedAddr = 0x3004828
77 | end
78 | end
79 |
80 | function printGameInfo()
81 | setGameVersion()
82 | wrongGameVersion = true
83 | wrongGameRegion = true
84 | GameInfo:clear()
85 |
86 | if gameVersion == "" then -- Print game info
87 | GameInfo:print("Version: Unknown game")
88 | elseif gameVersion ~= "Ruby" and gameVersion ~= "Sapphire" then
89 | GameInfo:print(string.format("Version: %s - Wrong game version! Use Ruby/Sapphire instead\n", gameVersion))
90 | elseif gameRegion == "JPN" then
91 | GameInfo:print(string.format("Region: %s - Wrong game region! Use USA/EUR instead\n", gameRegion))
92 | elseif gameRegion == "" then
93 | GameInfo:print("Version: "..gameVersion.."\n".."Region: Unknown region\n")
94 | else
95 | wrongGameVersion = false
96 | wrongGameRegion = false
97 | GameInfo:print("Version: "..gameVersion.."\n"..string.format("Region: %s\n", gameRegion))
98 | end
99 | end
100 |
101 | function calculateBaseTargetTime(textSpeedOptionIndex)
102 | local targetTotalSixtiethSeconds = (targetHour * 3600 * 60) + (targetMinute * 60 * 60) + (targetSecond * 60) + targetSixtiethSecond
103 | local delaySeconds = textSpeedOptionIndex == 0 and 3 or textSpeedOptionIndex == 1 and 1 or textSpeedOptionIndex == 2 and 0
104 | local delaySixtiethSeconds = textSpeedOptionIndex == 0 and 29 or textSpeedOptionIndex == 1 and 47 or textSpeedOptionIndex == 2 and 39
105 | local delayTotalSixtiethSeconds = (delaySeconds * 60) + delaySixtiethSeconds
106 | local resultSixtiethSeconds = targetTotalSixtiethSeconds - delayTotalSixtiethSeconds
107 |
108 | local resultHour = resultSixtiethSeconds // (3600 * 60)
109 | local resultMinute = (resultSixtiethSeconds % (3600 * 60)) // (60 * 60)
110 | local resultSecond = (resultSixtiethSeconds % (60 * 60)) // 60
111 |
112 | return resultHour, resultMinute, resultSecond, resultSixtiethSeconds % 60
113 | end
114 |
115 | function showCurrentTime(buffer)
116 | local hour = emu:read16(saveBlock2Addr + 0xE)
117 | local minute = emu:read8(saveBlock2Addr + 0x10)
118 | local second = emu:read8(saveBlock2Addr + 0x11)
119 | local sixtiethSecond = emu:read8(saveBlock2Addr + 0x12)
120 | buffer:print(string.format("Current Time: %02d:%02d:%02d:%02d\n", hour, minute, second, sixtiethSecond))
121 | end
122 |
123 | function getChecksumSeed()
124 | local startingCheckSumSegmentIndex = emu:read8(startingChecksumBlockAddr)
125 | local firstSegmentChecksumAddr = startingChecksumBlockAddr + ((0xE - startingCheckSumSegmentIndex) * 0x1000)
126 | local firstSegmentChecksumHigh = emu:read8(firstSegmentChecksumAddr + 0x3)
127 | local firstSegmentChecksumLow = emu:read8(firstSegmentChecksumAddr + 0x2)
128 |
129 | return (firstSegmentChecksumHigh << 8) + firstSegmentChecksumLow
130 | end
131 |
132 | function showTargetInfo(buffer, textSpeedOptionIndex, checksum)
133 | local targetBaseHour, targetBaseMinute, targetBaseSecond, targetBaseSixtiethSecond = calculateBaseTargetTime(textSpeedOptionIndex)
134 | buffer:clear()
135 | buffer:print(string.format("Target Checksum Seed: %04X\n", targetSeed))
136 | buffer:print(string.format("Target Final Time: %02d:%02d:%02d:%02d\n", targetHour, targetMinute, targetSecond, targetSixtiethSecond))
137 | buffer:print(string.format("Target Base Save Time: %02d:%02d:%02d:%02d\n\n", targetBaseHour, targetBaseMinute, targetBaseSecond, targetBaseSixtiethSecond))
138 | showCurrentTime(buffer)
139 | buffer:print(string.format("Segment 0 Checksum Seed: %04X\n", checksum))
140 | end
141 |
142 | function getChecksumsList()
143 | local saveFile = assert(io.open(savePath, "rb"))
144 | local bytes = saveFile:read(0x20000)
145 | local startingChecksumBlockSaveAddr = 0xFF7
146 | local checksumsList = {}
147 | saveFile:close()
148 |
149 | for i = 0, 0x1B do
150 | local segmentChecksumAddr = startingChecksumBlockSaveAddr + (i * 0x1000)
151 | local checksum = string.format("%02X%02X\n", bytes:byte(segmentChecksumAddr + 1), bytes:byte(segmentChecksumAddr))
152 | table.insert(checksumsList, checksum)
153 | end
154 |
155 | return checksumsList
156 | end
157 |
158 | function getCurrentXORChecksumSeed(checksumsList)
159 | local xorChecksumSeed = 0
160 |
161 | for _, checksum in ipairs(checksumsList) do
162 | xorChecksumSeed = xorChecksumSeed ~ tonumber(checksum, 16)
163 | end
164 |
165 | return xorChecksumSeed
166 | end
167 |
168 | function getTrainerIDs()
169 | local trainerIDsAddr = saveBlock2Addr + 0xA
170 | local TID = emu:read16(trainerIDsAddr)
171 | local SID = emu:read16(trainerIDsAddr + 0x2)
172 |
173 | return TID, SID
174 | end
175 |
176 | function getPlayerNameString(rawString)
177 | local string = ""
178 |
179 | for _, char in ipairs({rawString:byte(1, #rawString)}) do
180 | if char == 0xFF then -- Terminator character check
181 | break
182 | end
183 |
184 | string = string..charMap[char + 1]
185 | end
186 |
187 | return string
188 | end
189 |
190 | function showRNGInfo(buffer)
191 | local currentSeed = emu:read32(currentSeedAddr)
192 | buffer:print(string.format("Visual Frame: %d\n", emu:currentFrame() - 4))
193 | buffer:print(string.format("Current Seed: %08X", currentSeed))
194 | end
195 |
196 | function showTrainerInfo(buffer)
197 | local playerGenderSymbols = {"M", "F"}
198 | local playerGenderIndex = emu:read8(saveBlock2Addr + 0x8)
199 | local trainerTID, trainerSID = getTrainerIDs()
200 | local playerName = getPlayerNameString(emu:readRange(saveBlock2Addr, 8))
201 | buffer:clear()
202 | buffer:print(string.format("Gender: %s\n", playerGenderSymbols[playerGenderIndex + 1]))
203 | buffer:print(string.format("TID: %d\nSID: %d\n", trainerTID, trainerSID))
204 | buffer:print(string.format("Name: %s\n\n", playerName))
205 | showRNGInfo(buffer)
206 | end
207 |
208 | function showCurrentOptions(buffer, textSpeedOptionIndex)
209 | local speedTextOptions = {"Slow", "Mid", "Fast"}
210 | local battleSceneOptions = {"On", "Off"}
211 | local battleStyleOptions = {"Shift", "Set"}
212 | local soundOptions = {"Mono", "Stereo"}
213 | local buttonModeOptions = {"Normal", "LR", "L=A"}
214 | local buttonModeOptionIndex = emu:read8(saveBlock2Addr + 0x13)
215 | local optionsValue = emu:read32(saveBlock2Addr + 0x14)
216 | local frameTypeOptionIndex = (optionsValue >> 3) & 0x1F
217 | local soundOptionIndex = (optionsValue >> 8) & 0x1
218 | local battleStyleOptionIndex = (optionsValue >> 9) & 0x1
219 | local battleSceneOptionIndex = (optionsValue >> 10) & 0x1
220 | buffer:clear()
221 | buffer:print(string.format("Text Speed: %s\n", speedTextOptions[textSpeedOptionIndex + 1]))
222 | buffer:print(string.format("Battle Scene: %s\n", battleSceneOptions[battleSceneOptionIndex + 1]))
223 | buffer:print(string.format("Battle Style: %s\n", battleStyleOptions[battleStyleOptionIndex + 1]))
224 | buffer:print(string.format("Sound: %s\n", soundOptions[soundOptionIndex + 1]))
225 | buffer:print(string.format("Button Mode: %s\n", buttonModeOptions[buttonModeOptionIndex + 1]))
226 | buffer:print(string.format("Frame Style: %d", frameTypeOptionIndex + 1))
227 | end
228 |
229 | function getCurrentTextSpeedOptionIndex()
230 | return emu:read16(saveBlock2Addr + 0x14) & 0x7
231 | end
232 |
233 | function pokemonSeenFlag(speciesDexNumber)
234 | local dexIndex = (speciesDexNumber - 1) // 8
235 | local dexMask = 1 << (speciesDexNumber - 1) % 8
236 | local dexSeenFlag = emu:read8(saveBlock2Addr + 0x5C + dexIndex) & dexMask
237 | local dexSeen1Flag = emu:read8(saveBlock1Addr + 0x938 + dexIndex) & dexMask
238 | local dexSeen2Flag = emu:read8(saveBlock1Addr + 0x3A8C + dexIndex) & dexMask
239 |
240 | return dexSeenFlag ~= 0 and dexSeenFlag == dexSeen1Flag and dexSeenFlag == dexSeen2Flag
241 | end
242 |
243 | function showSaveInfo(buffer)
244 | local starterPokemonNames = {"Treecko", "Torchic", "Mudkip"}
245 | local currentClockHour = emu:read8(saveBlock2Addr + 0xA2)
246 | local currentClockMinute = emu:read8(saveBlock2Addr + 0xA3)
247 | local starterPokemonIndex = emu:read8(starterPokemonIndexAddr)
248 | buffer:clear()
249 | buffer:print(string.format("Clock: %02d:%02d (%s:%s)\n", currentClockHour, currentClockMinute, currentClockHour ~= 0 and "XX" or "00", currentClockMinute ~= 0 and "XX" or "00"))
250 | buffer:print(string.format("Starter: %s\n", starterPokemonNames[starterPokemonIndex + 1]))
251 | buffer:print(string.format("Zigzagoon seen? %s\n", pokemonSeenFlag(263) == true and "Yes" or "No"))
252 | buffer:print(string.format("Wurmple seen? %s\n", pokemonSeenFlag(265) == true and "Yes" or "No"))
253 | buffer:print(string.format("Wingull seen? %s\n", pokemonSeenFlag(278) == true and "Yes" or "No"))
254 | showCurrentTime(buffer)
255 | end
256 |
257 | function showAllChecksums(buffer, checksumsList)
258 | buffer:clear()
259 |
260 | for _, checksum in ipairs(checksumsList) do
261 | buffer:print(checksum)
262 | end
263 | end
264 |
265 | function updateJirachiBuffer(buffer, textSpeedIndex, checksumSeed)
266 | showTargetInfo(buffer, textSpeedIndex, checksumSeed)
267 | end
268 |
269 | function updateTENANNIVBuffer(buffer, textSpeedIndex, checksumSeed)
270 | showTargetInfo(buffer, textSpeedIndex, checksumSeed)
271 | local checksums = getChecksumsList()
272 | local currectXORChecksumSeed = getCurrentXORChecksumSeed(checksums)
273 | local segment0TargetSeed = currectXORChecksumSeed ~ checksumSeed ~ targetSeed
274 | buffer:print(string.format("Current Checksum Seed: %04X\n\n", currectXORChecksumSeed))
275 | buffer:print(string.format("Target Segment 0 Checksum Seed: %04X", segment0TargetSeed))
276 | end
277 |
278 | function updateTrainerInfoBuffer(buffer)
279 | showTrainerInfo(buffer)
280 | end
281 |
282 | function updateOptionBuffer(buffer, textSpeedIndex)
283 | showCurrentOptions(buffer, textSpeedIndex)
284 | end
285 |
286 | function updateSaveInfoBuffer(buffer)
287 | showSaveInfo(buffer)
288 | end
289 |
290 | function updateChecksumsBuffer(buffer)
291 | showAllChecksums(buffer, getChecksumsList())
292 | end
293 |
294 | function updateBuffers()
295 | if (not wrongGameVersion) then
296 | local textSpeedIndex = getCurrentTextSpeedOptionIndex()
297 | local checksumSeed = getChecksumSeed()
298 | updateJirachiBuffer(Jirachi, textSpeedIndex, checksumSeed)
299 | updateTENANNIVBuffer(TENANNIV, textSpeedIndex, checksumSeed)
300 | updateTrainerInfoBuffer(TrainerInfo)
301 | updateOptionBuffer(Option, textSpeedIndex)
302 | updateSaveInfoBuffer(SaveInfo)
303 | --updateChecksumsBuffer(Checksums)
304 | end
305 | end
306 |
307 | initializeBuffers()
308 | printGameInfo()
309 | callbacks:add("frame", updateBuffers)
310 | callbacks:add("reset", printGameInfo)
--------------------------------------------------------------------------------
/Gen 3/mGBA/RS_RNG_mGBA.lua:
--------------------------------------------------------------------------------
1 | local JUMP_DATA = {
2 | {0x41C64E6D, 0x6073}, {0xC2A29A69, 0xE97E7B6A}, {0xEE067F11, 0x31B0DDE4}, {0xCFDDDF21, 0x67DBB608},
3 | {0x5F748241, 0xCBA72510}, {0x8B2E1481, 0x1D29AE20}, {0x76006901, 0xBA84EC40}, {0x1711D201, 0x79F01880},
4 | {0xBE67A401, 0x8793100}, {0xDDDF4801, 0x6B566200}, {0x3FFE9001, 0x803CC400}, {0x90FD2001, 0xA6B98800},
5 | {0x65FA4001, 0xE6731000}, {0xDBF48001, 0x30E62000}, {0xF7E90001, 0xF1CC4000}, {0xEFD20001, 0x23988000},
6 | {0xDFA40001, 0x47310000}, {0xBF480001, 0x8E620000}, {0x7E900001, 0x1CC40000}, {0xFD200001, 0x39880000},
7 | {0xFA400001, 0x73100000}, {0xF4800001, 0xE6200000}, {0xE9000001, 0xCC400000}, {0xD2000001, 0x98800000},
8 | {0xA4000001, 0x31000000}, {0x48000001, 0x62000000}, {0x90000001, 0xC4000000}, {0x20000001, 0x88000000},
9 | {0x40000001, 0x10000000}, {0x80000001, 0x20000000}, {0x1, 0x40000000}, {0x1, 0x80000000}}
10 |
11 | local natureNamesList = {
12 | "Hardy", "Lonely", "Brave", "Adamant", "Naughty",
13 | "Bold", "Docile", "Relaxed", "Impish", "Lax",
14 | "Timid", "Hasty", "Serious", "Jolly", "Naive",
15 | "Modest", "Mild", "Quiet", "Bashful", "Rash",
16 | "Calm", "Gentle", "Sassy", "Careful", "Quirky"}
17 |
18 | local HPTypeNamesList = {
19 | "Fighting", "Flying", "Poison", "Ground",
20 | "Rock", "Bug", "Ghost", "Steel",
21 | "Fire", "Water", "Grass", "Electric",
22 | "Psychic", "Ice", "Dragon", "Dark"}
23 |
24 | local speciesNamesList = {
25 | -- Gen 1
26 | "Bulbasaur", "Ivysaur", "Venusaur", "Charmander", "Charmeleon", "Charizard", "Squirtle", "Wartortle", "Blastoise",
27 | "Caterpie", "Metapod", "Butterfree", "Weedle", "Kakuna", "Beedrill", "Pidgey", "Pidgeotto", "Pidgeot", "Rattata",
28 | "Raticate", "Spearow", "Fearow", "Ekans", "Arbok", "Pikachu", "Raichu", "Sandshrew", "Sandslash", "Nidoran♀",
29 | "Nidorina", "Nidoqueen", "Nidoran♂", "Nidorino", "Nidoking", "Clefairy", "Clefable", "Vulpix", "Ninetales",
30 | "Jigglypuff", "Wigglytuff", "Zubat", "Golbat", "Oddish", "Gloom", "Vileplume", "Paras", "Parasect", "Venonat",
31 | "Venomoth", "Diglett", "Dugtrio", "Meowth", "Persian", "Psyduck", "Golduck", "Mankey", "Primeape", "Growlithe",
32 | "Arcanine", "Poliwag", "Poliwhirl", "Poliwrath", "Abra", "Kadabra", "Alakazam", "Machop", "Machoke", "Machamp",
33 | "Bellsprout", "Weepinbell", "Victreebel", "Tentacool", "Tentacruel", "Geodude", "Graveler", "Golem", "Ponyta",
34 | "Rapidash", "Slowpoke", "Slowbro", "Magnemite", "Magneton", "Farfetch'd", "Doduo", "Dodrio", "Seel", "Dewgong",
35 | "Grimer", "Muk", "Shellder", "Cloyster", "Gastly", "Haunter", "Gengar", "Onix", "Drowzee", "Hypno", "Krabby",
36 | "Kingler", "Voltorb", "Electrode", "Exeggcute", "Exeggutor", "Cubone", "Marowak", "Hitmonlee", "Hitmonchan",
37 | "Lickitung", "Koffing", "Weezing", "Rhyhorn", "Rhydon", "Chansey", "Tangela", "Kangaskhan", "Horsea", "Seadra",
38 | "Goldeen", "Seaking", "Staryu", "Starmie", "Mr. Mime", "Scyther", "Jynx", "Electabuzz", "Magmar", "Pinsir",
39 | "Tauros", "Magikarp", "Gyarados", "Lapras", "Ditto", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Porygon",
40 | "Omanyte", "Omastar", "Kabuto", "Kabutops", "Aerodactyl", "Snorlax", "Articuno", "Zapdos", "Moltres", "Dratini",
41 | "Dragonair", "Dragonite", "Mewtwo", "Mew",
42 | -- Gen 2
43 | "Chikorita", "Bayleef", "Meganium", "Cyndaquil", "Quilava", "Typhlosion", "Totodile", "Croconaw", "Feraligatr",
44 | "Sentret", "Furret", "Hoothoot", "Noctowl", "Ledyba", "Ledian", "Spinarak", "Ariados", "Crobat", "Chinchou",
45 | "Lanturn", "Pichu", "Cleffa", "Igglybuff", "Togepi", "Togetic", "Natu", "Xatu", "Mareep", "Flaaffy", "Ampharos",
46 | "Bellossom", "Marill", "Azumarill", "Sudowoodo", "Politoed", "Hoppip", "Skiploom", "Jumpluff", "Aipom", "Sunkern",
47 | "Sunflora", "Yanma", "Wooper", "Quagsire", "Espeon", "Umbreon", "Murkrow", "Slowking", "Misdreavus", "Unown",
48 | "Wobbuffet", "Girafarig", "Pineco", "Forretress", "Dunsparce", "Gligar", "Steelix", "Snubbull", "Granbull",
49 | "Qwilfish", "Scizor", "Shuckle", "Heracross", "Sneasel", "Teddiursa", "Ursaring", "Slugma", "Magcargo", "Swinub",
50 | "Piloswine", "Corsola", "Remoraid", "Octillery", "Delibird", "Mantine", "Skarmory", "Houndour", "Houndoom",
51 | "Kingdra", "Phanpy", "Donphan", "Porygon2", "Stantler", "Smeargle", "Tyrogue", "Hitmontop", "Smoochum", "Elekid",
52 | "Magby", "Miltank", "Blissey", "Raikou", "Entei", "Suicune", "Larvitar", "Pupitar", "Tyranitar", "Lugia", "Ho-Oh",
53 | "Celebi",
54 | -- Gen 3
55 | "Treecko", "Grovyle", "Sceptile", "Torchic", "Combusken", "Blaziken", "Mudkip", "Marshtomp", "Swampert",
56 | "Poochyena", "Mightyena", "Zigzagoon", "Linoone", "Wurmple", "Silcoon", "Beautifly", "Cascoon", "Dustox", "Lotad",
57 | "Lombre", "Ludicolo", "Seedot", "Nuzleaf", "Shiftry", "Taillow", "Swellow", "Wingull", "Pelipper", "Ralts",
58 | "Kirlia", "Gardevoir", "Surskit", "Masquerain", "Shroomish", "Breloom", "Slakoth", "Vigoroth", "Slaking",
59 | "Nincada", "Ninjask", "Shedinja", "Whismur", "Loudred", "Exploud", "Makuhita", "Hariyama", "Azurill", "Nosepass",
60 | "Skitty", "Delcatty", "Sableye", "Mawile", "Aron", "Lairon", "Aggron", "Meditite", "Medicham", "Electrike",
61 | "Manectric", "Plusle", "Minun", "Volbeat", "Illumise", "Roselia", "Gulpin", "Swalot", "Carvanha", "Sharpedo",
62 | "Wailmer", "Wailord", "Numel", "Camerupt", "Torkoal", "Spoink", "Grumpig", "Spinda", "Trapinch", "Vibrava",
63 | "Flygon", "Cacnea", "Cacturne", "Swablu", "Altaria", "Zangoose", "Seviper", "Lunatone", "Solrock", "Barboach",
64 | "Whiscash", "Corphish", "Crawdaunt", "Baltoy", "Claydol", "Lileep", "Cradily", "Anorith", "Armaldo", "Feebas",
65 | "Milotic", "Castform", "Kecleon", "Shuppet", "Banette", "Duskull", "Dusclops", "Tropius", "Chimecho", "Absol",
66 | "Wynaut", "Snorunt", "Glalie", "Spheal", "Sealeo", "Walrein", "Clamperl", "Huntail", "Gorebyss", "Relicanth",
67 | "Luvdisc", "Bagon", "Shelgon", "Salamence", "Beldum", "Metang", "Metagross", "Regirock", "Regice", "Registeel",
68 | "Latias", "Latios", "Kyogre", "Groudon", "Rayquaza", "Jirachi", "Deoxys"}
69 |
70 | local abilityNamesList = {
71 | "Stench", "Drizzle", "Speed Boost", "Battle Armor", "Sturdy", "Damp", "Limber", "Sand Veil", "Static",
72 | "Volt Absorb", "Water Absorb", "Oblivious", "Cloud Nine", "Compound Eyes", "Insomnia", "Color Change", "Immunity",
73 | "Flash Fire", "Shield Dust", "Own Tempo", "Suction Cups", "Intimidate", "Shadow Tag", "Rough Skin", "Wonder Guard",
74 | "Levitate", "Effect Spore", "Synchronize", "Clear Body", "Natural Cure", "Lightning Rod", "Serene Grace",
75 | "Swift Swim", "Chlorophyll", "Illuminate", "Trace", "Huge Power", "Poison Point", "Inner Focus", "Magma Armor",
76 | "Water Veil", "Magnet Pull", "Soundproof", "Rain Dish", "Sand Stream", "Pressure", "Thick Fat", "Early Bird",
77 | "Flame Body", "Run Away", "Keen Eye", "Hyper Cutter", "Pickup", "Truant", "Hustle", "Cute Charm", "Plus", "Minus",
78 | "Forecast", "Sticky Hold", "Shed Skin", "Guts", "Marvel Scale", "Liquid Ooze", "Overgrow", "Blaze", "Torrent",
79 | "Swarm", "Rock Head", "Drought", "Arena Trap", "Vital Spirit", "White Smoke", "Pure Power", "Shell Armor",
80 | "Cacophony", "Air Lock"}
81 |
82 | local moveNamesList = {
83 | "--" , "Pound", "Karate Chop", "Double Slap", "Comet Punch", "Mega Punch", "Pay Day", "Fire Punch", "Ice Punch",
84 | "Thunder Punch", "Scratch", "Vice Grip", "Guillotine", "Razor Wind", "Swords Dance", "Cut", "Gust", "Wing Attack",
85 | "Whirlwind", "Fly", "Bind", "Slam", "Vine Whip", "Stomp", "Double Kick", "Mega Kick", "Jump Kick", "Rolling Kick",
86 | "Sand Attack", "Headbutt", "Horn Attack", "Fury Attack", "Horn Drill", "Tackle", "Body Slam", "Wrap", "Take Down",
87 | "Thrash", "Double-Edge", "Tail Whip", "Poison Sting", "Twineedle", "Pin Missile", "Leer", "Bite", "Growl", "Roar",
88 | "Sing", "Supersonic", "Sonic Boom", "Disable", "Acid", "Ember", "Flamethrower", "Mist", "Water Gun", "Hydro Pump",
89 | "Surf", "Ice Beam", "Blizzard", "Psybeam", "Bubble Beam", "Aurora Beam", "Hyper Beam", "Peck", "Drill Peck",
90 | "Submission", "Low Kick", "Counter", "Seismic Toss", "Strength", "Absorb", "Mega Drain", "Leech Seed", "Growth",
91 | "Razor Leaf", "Solar Beam", "Poison Powder", "Stun Spore", "Sleep Powder", "Petal Dance", "String Shot",
92 | "Dragon Rage", "Fire Spin", "Thunder Shock", "Thunderbolt", "Thunder Wave", "Thunder", "Rock Throw", "Earthquake",
93 | "Fissure", "Dig", "Toxic", "Confusion", "Psychic", "Hypnosis", "Meditate", "Agility", "Quick Attack", "Rage",
94 | "Teleport", "Night Shade", "Mimic", "Screech", "Double Team", "Recover", "Harden", "Minimize", "Smokescreen",
95 | "Confuse Ray", "Withdraw", "Defense Curl", "Barrier", "Light Screen", "Haze", "Reflect", "Focus Energy", "Bide",
96 | "Metronome", "Mirror Move", "Self-Destruct", "Egg Bomb", "Lick", "Smog", "Sludge", "Bone Club", "Fire Blast",
97 | "Waterfall", "Clamp", "Swift", "Skull Bash", "Spike Cannon", "Constrict", "Amnesia", "Kinesis", "Soft-Boiled",
98 | "High Jump Kick", "Glare", "Dream Eater", "Poison Gas", "Barrage", "Leech Life", "Lovely Kiss", "Sky Attack",
99 | "Transform", "Bubble", "Dizzy Punch", "Spore", "Flash", "Psywave", "Splash", "Acid Armor", "Crabhammer",
100 | "Explosion", "Fury Swipes", "Bonemerang", "Rest", "Rock Slide", "Hyper Fang", "Sharpen", "Conversion", "Tri Attack",
101 | "Super Fang", "Slash", "Substitute", "Struggle", "Sketch", "Triple Kick", "Thief", "Spider Web", "Mind Reader",
102 | "Nightmare", "Flame Wheel", "Snore", "Curse", "Flail", "Conversion 2", "Aeroblast", "Cotton Spore", "Reversal",
103 | "Spite", "Powder Snow", "Protect", "Mach Punch", "Scary Face", "Feint Attack", "Sweet Kiss", "Belly Drum",
104 | "Sludge Bomb", "Mud-Slap", "Octazooka", "Spikes", "Zap Cannon", "Foresight", "Destiny Bond", "Perish Song",
105 | "Icy Wind", "Detect", "Bone Rush", "Lock-On", "Outrage", "Sandstorm", "Giga Drain", "Endure", "Charm", "Rollout",
106 | "False Swipe", "Swagger", "Milk Drink", "Spark", "Fury Cutter", "Steel Wing", "Mean Look", "Attract", "Sleep Talk",
107 | "Heal Bell", "Return", "Present", "Frustration", "Safeguard", "Pain Split", "Sacred Fire", "Magnitude",
108 | "Dynamic Punch", "Megahorn", "Dragon Breath", "Baton Pass", "Encore", "Pursuit", "Rapid Spin", "Sweet Scent",
109 | "Iron Tail", "Metal Claw", "Vital Throw", "Morning Sun", "Synthesis", "Moonlight", "Hidden Power", "Cross Chop",
110 | "Twister", "Rain Dance", "Sunny Day", "Crunch", "Mirror Coat", "Psych Up", "Extreme Speed", "Ancient Power",
111 | "Shadow Ball", "Future Sight", "Rock Smash", "Whirlpool", "Beat Up", "Fake Out", "Uproar", "Stockpile", "Spit Up",
112 | "Swallow", "Heat Wave", "Hail", "Torment", "Flatter", "Will-O-Wisp", "Memento", "Facade", "Focus Punch",
113 | "Smelling Salts", "Follow Me", "Nature Power", "Charge", "Taunt", "Helping Hand", "Trick", "Role Play", "Wish",
114 | "Assist", "Ingrain", "Superpower", "Magic Coat", "Recycle", "Revenge", "Brick Break", "Yawn", "Knock Off", "Endeavor",
115 | "Eruption", "Skill Swap", "Imprison", "Refresh", "Grudge", "Snatch", "Secret Power", "Dive", "Arm Thrust", "Camouflage",
116 | "Tail Glow", "Luster Purge", "Mist Ball", "Feather Dance", "Teeter Dance", "Blaze Kick", "Mud Sport", "Ice Ball",
117 | "Needle Arm", "Slack Off", "Hyper Voice", "Poison Fang", "Crush Claw", "Blast Burn", "Hydro Cannon", "Meteor Mash",
118 | "Astonish", "Weather Ball", "Aromatherapy", "Fake Tears", "Air Cutter", "Overheat", "Odor Sleuth", "Rock Tomb",
119 | "Silver Wind", "Metal Sound", "Grass Whistle", "Tickle", "Cosmic Power", "Water Spout", "Signal Beam", "Shadow Punch",
120 | "Extrasensory", "Sky Uppercut", "Sand Tomb", "Sheer Cold", "Muddy Water", "Bullet Seed", "Aerial Ace", "Icicle Spear",
121 | "Iron Defense", "Block", "Howl", "Dragon Claw", "Frenzy Plant", "Bulk Up", "Bounce", "Mud Shot", "Poison Tail", "Covet",
122 | "Volt Tackle", "Magical Leaf", "Water Sport", "Calm Mind", "Leaf Blade", "Dragon Dance", "Rock Blast", "Shock Wave",
123 | "Water Pulse", "Doom Desire", "Psycho Boost"}
124 |
125 | local nationalDexList = {
126 | 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
127 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
128 | 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
129 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
130 | 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
131 | 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
132 | 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
133 | 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
134 | 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
135 | 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
136 | 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
137 | 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394,
138 | 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254,
139 | 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
140 | 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344,
141 | 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322,
142 | 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334,
143 | 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336,
144 | 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375,
145 | 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}
146 |
147 | local pokemonAbilities = {
148 | [001] = {65, 34}, [002] = {65, 34}, [003] = {65, 34}, [004] = {66}, [005] = {66}, [006] = {66}, [007] = {67, 44},
149 | [008] = {67, 44}, [009] = {67, 44}, [010] = {19, 50}, [011] = {61}, [012] = {14}, [013] = {19, 50}, [014] = {61},
150 | [015] = {68}, [016] = {51}, [017] = {51}, [018] = {51}, [019] = {50, 62, 55}, [020] = {50, 62, 55}, [021] = {51},
151 | [022] = {51}, [023] = {22, 61}, [024] = {22, 61}, [025] = {9, 31}, [026] = {9, 31}, [027] = {8}, [028] = {8},
152 | [029] = {38, 55}, [030] = {38, 55}, [031] = {38}, [032] = {38, 55}, [033] = {38, 55}, [034] = {38}, [035] = {56},
153 | [036] = {56}, [037] = {18, 70}, [038] = {18, 70}, [039] = {56}, [040] = {56}, [041] = {39}, [042] = {39},
154 | [043] = {34, 50}, [044] = {34, 1}, [045] = {34, 27}, [046] = {27, 6}, [047] = {27, 6}, [048] = {14, 50},
155 | [049] = {19}, [050] = {8, 71}, [051] = {8, 71}, [052] = {53}, [053] = {7}, [054] = {6, 13, 33},
156 | [055] = {6, 13, 33}, [056] = {72}, [057] = {72}, [058] = {22, 18}, [059] = {22, 18}, [060] = {11, 6, 33},
157 | [061] = {11, 6, 33}, [062] = {11, 6, 33}, [063] = {28, 39}, [064] = {28, 39}, [065] = {28, 39}, [066] = {62},
158 | [067] = {62}, [068] = {62}, [069] = {34}, [070] = {34}, [071] = {34}, [072] = {29, 64, 44}, [073] = {29, 64, 44},
159 | [074] = {69, 5, 8}, [075] = {69, 5, 8}, [076] = {69, 5, 8}, [077] = {50, 18, 49}, [078] = {50, 18, 49},
160 | [079] = {12, 20}, [080] = {12, 20}, [081] = {42, 5}, [082] = {42, 5}, [083] = {51, 39}, [084] = {50, 48},
161 | [085] = {50, 48}, [086] = {47}, [087] = {47}, [088] = {1, 60}, [089] = {1, 60}, [090] = {75}, [091] = {75},
162 | [092] = {26}, [093] = {26}, [094] = {26}, [095] = {69, 5}, [096] = {15, 39}, [097] = {15, 39}, [098] = {52, 75},
163 | [099] = {52, 75}, [100] = {43, 9}, [101] = {43, 9}, [102] = {34}, [103] = {34}, [104] = {69, 31, 4},
164 | [105] = {69, 31, 4}, [106] = {7}, [107] = {51, 39}, [108] = {20, 12, 13}, [109] = {26, 1}, [110] = {26, 1},
165 | [111] = {31, 69}, [112] = {31, 69}, [113] = {30, 32}, [114] = {34}, [115] = {48, 39}, [116] = {33, 6},
166 | [117] = {38, 6}, [230] = {33, 6}, [118] = {33, 41, 31}, [119] = {33, 41, 31}, [120] = {35, 30}, [121] = {35, 30},
167 | [122] = {43}, [123] = {68}, [212] = {68}, [238] = {12}, [124] = {12}, [239] = {9, 72}, [125] = {9, 72},
168 | [240] = {49, 72}, [126] = {49, 72}, [127] = {52}, [128] = {22}, [129] = {33}, [130] = {22}, [131] = {11, 75},
169 | [132] = {7}, [133] = {50}, [134] = {11}, [135] = {10}, [136] = {18, 62}, [196] = {28}, [197] = {28, 39},
170 | [137] = {36}, [233] = {36}, [138] = {33, 75}, [139] = {33, 75}, [140] = {33, 4}, [141] = {33, 4}, [142] = {69, 46},
171 | [143] = {17, 47}, [144] = {46}, [145] = {46, 9}, [146] = {46, 49}, [147] = {61, 63}, [148] = {61, 63}, [149] = {39},
172 | [150] = {46}, [151] = {28}, [152] = {65}, [153] = {65}, [154] = {65}, [155] = {66, 18}, [156] = {66, 18},
173 | [157] = {66, 18}, [158] = {67}, [159] = {67}, [160] = {67}, [161] = {50, 51}, [162] = {50, 51}, [163] = {15, 51},
174 | [164] = {15, 51}, [165] = {68, 48}, [166] = {68, 48}, [167] = {68, 15}, [168] = {68, 15}, [169] = {39},
175 | [170] = {10, 35, 11}, [171] = {10, 35, 11}, [172] = {9, 31}, [173] = {56}, [174] = {56}, [175] = {55, 32},
176 | [176] = {55, 32}, [177] = {28, 48}, [178] = {28, 48}, [179] = {9, 57}, [180] = {9, 57}, [181] = {9, 57}, [182] = {34},
177 | [183] = {47, 37}, [184] = {47, 37}, [185] = {5, 69}, [186] = {11, 6, 2}, [187] = {34}, [188] = {34}, [189] = {34},
178 | [190] = {50, 53}, [191] = {34, 48}, [192] = {34, 48}, [193] = {3, 14}, [194] = {6, 11}, [195] = {6, 11}, [198] = {15},
179 | [199] = {12, 20}, [200] = {26}, [201] = {26}, [202] = {23}, [203] = {39, 48}, [204] = {5}, [205] = {5},
180 | [206] = {32, 50}, [207] = {52, 8, 17}, [208] = {69, 5}, [209] = {22, 50}, [210] = {22}, [211] = {38, 33, 22},
181 | [213] = {5}, [214] = {68, 62}, [215] = {39, 51}, [216] = {53}, [217] = {62}, [218] = {40, 49}, [219] = {40, 49},
182 | [220] = {12, 47}, [221] = {12, 47}, [222] = {55, 30}, [223] = {55}, [224] = {21}, [225] = {72, 55, 15},
183 | [226] = {33, 11, 41}, [227] = {51, 5}, [228] = {48, 18}, [229] = {48, 18}, [231] = {53, 8}, [232] = {5, 8},
184 | [234] = {22}, [235] = {20}, [236] = {62, 72}, [237] = {22}, [241] = {47}, [242] = {30, 32}, [243] = {46, 39},
185 | [244] = {46, 39}, [245] = {46, 39}, [246] = {62, 8}, [247] = {61}, [248] = {45}, [249] = {46}, [250] = {46},
186 | [251] = {30}, [252] = {65}, [253] = {65}, [254] = {65}, [255] = {66, 3}, [256] = {66, 3}, [257] = {66, 3},
187 | [258] = {67, 6}, [259] = {67, 6}, [260] = {67, 6}, [261] = {50}, [262] = {22}, [263] = {53}, [264] = {53},
188 | [265] = {19, 50}, [266] = {61}, [267] = {68}, [268] = {61}, [269] = {19, 14}, [270] = {33, 44, 20}, [271] = {33, 44, 20},
189 | [272] = {33, 44, 20}, [273] = {34, 48}, [274] = {34, 48}, [275] = {34, 48}, [276] = {62}, [277] = {62}, [278] = {51, 44},
190 | [279] = {51, 2, 44}, [280] = {28, 36}, [281] = {28, 36}, [282] = {28, 36}, [283] = {33, 44}, [284] = {22}, [285] = {27},
191 | [286] = {27}, [287] = {54}, [288] = {72}, [289] = {54}, [290] = {14, 50}, [291] = {3}, [292] = {25}, [293] = {43},
192 | [294] = {43}, [295] = {43}, [296] = {47, 62}, [297] = {47, 62}, [298] = {47, 37}, [299] = {5, 42}, [300] = {56},
193 | [301] = {56}, [302] = {51}, [303] = {52, 22}, [304] = {5, 69}, [305] = {5, 69}, [306] = {5, 69}, [307] = {74},
194 | [308] = {74}, [309] = {9, 31, 58}, [310] = {9, 31, 58}, [311] = {57, 31}, [312] = {58, 10}, [313] = {35, 68},
195 | [314] = {12}, [315] = {30, 38}, [316] = {64, 60}, [317] = {64, 60}, [318] = {24, 3}, [319] = {24, 3},
196 | [320] = {41, 12, 46}, [321] = {41, 12, 46}, [322] = {12, 20}, [323] = {40}, [324] = {73, 70, 75}, [325] = {47, 20},
197 | [326] = {47, 20}, [327] = {20}, [328] = {52, 71}, [329] = {26}, [330] = {26}, [331] = {8, 11}, [332] = {8, 11},
198 | [333] = {30, 13}, [334] = {30, 13}, [335] = {17}, [336] = {61}, [337] = {26}, [338] = {26}, [339] = {12}, [340] = {12},
199 | [341] = {52, 75}, [342] = {52, 75}, [343] = {26}, [344] = {26}, [345] = {21}, [346] = {21}, [347] = {4, 33},
200 | [348] = {4, 33}, [349] = {33, 12}, [350] = {63, 56}, [351] = {59}, [352] = {16}, [353] = {15}, [354] = {15},
201 | [355] = {26}, [356] = {46}, [357] = {34}, [358] = {26}, [359] = {46}, [360] = {23}, [361] = {39}, [362] = {39},
202 | [363] = {47, 12}, [364] = {47, 12}, [365] = {47, 12}, [366] = {75}, [367] = {33, 41}, [368] = {33}, [369] = {33, 69, 5},
203 | [370] = {33}, [371] = {69}, [372] = {69}, [373] = {22}, [374] = {29}, [375] = {29}, [376] = {29}, [377] = {29, 5},
204 | [378] = {29}, [379] = {29}, [380] = {26}, [381] = {26}, [382] = {2}, [383] = {70}, [384] = {77}, [385] = {32}, [386] = {46}}
205 |
206 | local itemNamesList = {
207 | "None", "Master Ball", "Ultra Ball", "Great Ball", "Poke Ball", "Safari Ball", "Net Ball", "Dive Ball", "Nest Ball",
208 | "Repeat Ball", "Timer Ball", "Luxury Ball", "Premier Ball", "Potion", "Antidote", "Burn Heal", "Ice Heal", "Awakening",
209 | "Parlyz Heal", "Full Restore", "Max Potion", "Hyper Potion", "Super Potion", "Full Heal", "Revive", "Max Revive",
210 | "Fresh Water", "Soda Pop", "Lemonade", "Moomoo Milk", "EnergyPowder", "Energy Root", "Heal Powder", "Revival Herb",
211 | "Ether", "Max Ether", "Elixir", "Max Elixir", "Lava Cookie", "Blue Flute", "Yellow Flute", "Red Flute", "Black Flute",
212 | "White Flute", "Berry Juice", "Sacred Ash", "Shoal Salt", "Shoal Shell", "Red Shard", "Blue Shard", "Yellow Shard",
213 | "Green Shard", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown",
214 | "unknown", "unknown", "HP Up", "Protein", "Iron", "Carbos", "Calcium", "Rare Candy", "PP Up", "Zinc", "PP Max",
215 | "unknown", "Guard Spec.", "Dire Hit", "X Attack", "X Defend", "X Speed", "X Accuracy", "X Special", "Poke Doll",
216 | "Fluffy Tail", "unknown", "Super Repel", "Max Repel", "Escape Rope", "Repel", "unknown", "unknown", "unknown",
217 | "unknown", "unknown", "unknown", "Sun Stone", "Moon Stone", "Fire Stone", "Thunderstone", "Water Stone", "Leaf Stone",
218 | "unknown", "unknown", "unknown", "unknown", "TinyMushroom", "Big Mushroom", "unknown", "Pearl", "Big Pearl", "Stardust",
219 | "Star Piece", "Nugget", "Heart Scale", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown",
220 | "unknown", "unknown", "Orange Mail", "Harbor Mail", "Glitter Mail", "Mech Mail", "Wood Mail", "Wave Mail", "Bead Mail",
221 | "Shadow Mail", "Tropic Mail", "Dream Mail", "Fab Mail", "Retro Mail", "Cheri Berry", "Chesto Berry", "Pecha Berry",
222 | "Rawst Berry", "Aspear Berry", "Leppa Berry", "Oran Berry", "Persim Berry", "Lum Berry", "Sitrus Berry", "Figy Berry",
223 | "Wiki Berry", "Mago Berry", "Aguav Berry", "Iapapa Berry", "Razz Berry", "Bluk Berry", "Nanab Berry", "Wepear Berry",
224 | "Pinap Berry", "Pomeg Berry", "Kelpsy Berry", "Qualot Berry", "Hondew Berry", "Grepa Berry", "Tamato Berry",
225 | "Cornn Berry", "Magost Berry", "Rabuta Berry", "Nomel Berry", "Spelon Berry", "Pamtre Berry", "Watmel Berry",
226 | "Durin Berry", "Belue Berry", "Liechi Berry", "Ganlon Berry", "Salac Berry", "Petaya Berry", "Apicot Berry",
227 | "Lansat Berry", "Starf Berry", "Enigma Berry", "unknown", "unknown", "unknown", "BrightPowder", "White Herb",
228 | "Macho Brace", "Exp. Share", "Quick Claw", "Soothe Bell", "Mental Herb", "Choice Band", "King's Rock", "SilverPowder",
229 | "Amulet Coin", "Cleanse Tag", "Soul Dew", "DeepSeaTooth", "DeepSeaScale", "Smoke Ball", "Everstone", "Focus Band",
230 | "Lucky Egg", "Scope Lens", "Metal Coat", "Leftovers", "Dragon Scale", "Light Ball", "Soft Sand", "Hard Stone",
231 | "Miracle Seed", "BlackGlasses", "Black Belt", "Magnet", "Mystic Water", "Sharp Beak", "Poison Barb", "NeverMeltIce",
232 | "Spell Tag", "TwistedSpoon", "Charcoal", "Dragon Fang", "Silk Scarf", "Up-Grade", "Shell Bell", "Sea Incense",
233 | "Lax Incense", "Lucky Punch", "Metal Powder", "Thick Club", "Stick", "unknown", "unknown", "unknown", "unknown",
234 | "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown",
235 | "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown",
236 | "unknown", "unknown", "Red Scarf", "Blue Scarf", "Pink Scarf", "Green Scarf", "Yellow Scarf", "Mach Bike", "Coin Case",
237 | "Itemfinder", "Old Rod", "Good Rod", "Super Rod", "S.S. Ticket", "Contest Pass", "unknown", "Wailmer Pail", "Devon Goods",
238 | "Soot Sack", "Basement Key", "Acro Bike", "Pokeblock Case", "Letter", "Eon Ticket", "Red Orb", "Blue Orb", "Scanner",
239 | "Go-Goggles", "Meteorite", "Rm. 1 Key", "Rm. 2 Key", "Rm. 4 Key", "Rm. 6 Key", "Storage Key", "Root Fossil", "Claw Fossil",
240 | "Devon Scope", "TM 01", "TM 02", "TM 03", "TM 04", "TM 05", "TM 06", "TM 07", "TM 08", "TM 09", "TM 10", "TM 11", "TM 12",
241 | "TM 13", "TM 14", "TM 15", "TM 16", "TM 17", "TM 18", "TM 19", "TM 20", "TM 21", "TM 22", "TM 23", "TM 24", "TM 25",
242 | "TM 26", "TM 27", "TM 28", "TM 29", "TM 30", "TM 31", "TM 32", "TM 33", "TM 34", "TM 35", "TM 36", "TM 37", "TM 38", "TM 39",
243 | "TM 40", "TM 41", "TM 42", "TM 43", "TM 44", "TM 45", "TM 46", "TM 47", "TM 48", "TM 49", "TM 50", "HM 01", "HM 02", "HM 03",
244 | "HM 04", "HM 05", "HM 06", "HM 07", "HM 08", "unknown", "unknown", "Oak's Parcel", "Poke Flute", "Secret Key", "Bike Voucher",
245 | "Gold Teeth", "Old Amber", "Card Key", "Lift Key", "Helix Fossil", "Dome Fossil", "Silph Scope", "Bicycle", "Town Map",
246 | "VS Seeker", "Fame Checker", "TM Case", "Berry Pouch", "Teachy TV", "Tri-Pass", "Rainbow Pass", "Tea", "MysticTicket",
247 | "AuroraTicket", "Powder Jar", "Ruby", "Sapphire", "Magma Emblem", "Old Sea Map"}
248 |
249 | local catchRatesList = {
250 | -- Gen 1
251 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 120, 45, 255, 120, 45, 255, 120, 45, 255, 127, 255, 90, 255,
252 | 90, 190, 75, 255, 90, 235, 120, 45, 235, 120, 45, 150, 25, 190, 75, 170, 50, 255, 90, 255, 120, 45,
253 | 190, 75, 190, 75, 255, 50, 255, 90, 190, 75, 190, 75, 190, 75, 255, 120, 45, 200, 100, 50, 180, 90,
254 | 45, 255, 120, 45, 190, 60, 255, 120, 45, 190, 60, 190, 75, 190, 60, 45, 190, 45, 190, 75, 190, 75,
255 | 190, 60, 190, 90, 45, 45, 190, 75, 225, 60, 190, 60, 90, 45, 190, 75, 45, 45, 45, 190, 60, 120, 60,
256 | 30, 45, 45, 225, 75, 225, 60, 225, 60, 45, 45, 45, 45, 45, 45, 45, 255, 45, 45, 35, 45, 45, 45, 45,
257 | 45, 45, 45, 45, 45, 45, 25, 3, 3, 3, 45, 45, 45, 3, 45,
258 | -- Gen 2
259 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 90, 255, 90, 255, 90, 255, 90, 90, 190, 75, 190, 150, 170,
260 | 190, 75, 190, 75, 235, 120, 45, 45, 190, 75, 65, 45, 255, 120, 45, 45, 235, 120, 75, 255, 90, 45, 45,
261 | 30, 70, 45, 225, 45, 60, 190, 75, 190, 60, 25, 190, 75, 45, 25, 190, 45, 60, 120, 60, 190, 75, 225,
262 | 75, 60, 190, 75, 45, 25, 25, 120, 45, 45, 120, 60, 45, 45, 45, 75, 45, 45, 45, 45, 45, 30, 3, 3, 3, 45,
263 | 45, 45, 3, 3, 45,
264 | -- Gen 3
265 | 45, 45, 45, 45, 45, 45, 45, 45, 45, 255, 127, 255, 90, 255, 120, 45, 120, 45, 255, 120, 45, 255, 120,
266 | 45, 200, 45, 190, 45, 235, 120, 45, 200, 75, 255, 90, 255, 120, 45, 255, 120, 45, 190, 120, 45, 180,
267 | 200, 150, 255, 255, 60, 45, 45, 180, 90, 45, 180, 90, 120, 45, 200, 200, 150, 150, 150, 225, 75, 225,
268 | 60, 125, 60, 255, 150, 90, 255, 60, 255, 255, 120, 45, 190, 60, 255, 45, 90, 90, 45, 45, 190, 75, 205,
269 | 155, 255, 90, 45, 45, 45, 45, 255, 60, 45, 200, 225, 45, 190, 90, 200, 45, 30, 125, 190, 75, 255, 120,
270 | 45, 255, 60, 60, 25, 225, 45, 45, 45, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3}
271 |
272 | local locationNamesList = {
273 | "Petalburg City", "Slateport City", "Mauville City", "Rustboro City", "Fortree City", "Lilycove City",
274 | "Mossdeep City", "Sootopolis City", "Ever Grande City", "Littleroot Town", "Oldale Town", "Dewford Town",
275 | "Lavaridge Town", "Fallarbor Town", "Verdanturf Town", "Pacifidlog Town", "Route 101", "Route 102",
276 | "Route 103", "Route 104", "Route 105", "Route 106", "Route 107", "Route 108", "Route 109", "Route 110",
277 | "Route 111", "Route 112", "Route 113", "Route 114", "Route 115", "Route 116", "Route 117", "Route 118",
278 | "Route 119", "Route 120", "Route 121", "Route 122", "Route 123", "Route 124", "Route 125", "Route 126",
279 | "Route 127", "Route 128", "Route 129", "Route 130", "Route 131", "Route 132", "Route 133", "Route 134",
280 | "Underwater 1", "Underwater 2", "Underwater 3", "Underwater 4"}
281 |
282 | local statusConditionNamesList = {"None", "SLP", "PSN", "BRN", "FRZ", "PAR", "PSN"}
283 |
284 | local speciesDexIndexAddr, wildTypeAddr, saveBlock2Addr, saveBlock1Addr, eggLowPIDAddr, mapTypeAddr, currBoxIndexAddr, boxSelectedSlotIndexAddr,
285 | selectedItemAddr, safariZoneStepsCounterAddr, roamerMapGroupAndNumAddr, timerAddr, battleTurnsCounterAddr, partySlotsCounterAddr,
286 | partyAddr, enemyAddr, currentSeedAddr
287 |
288 | local GameInfo, CaptureInfo, RoamerInfo, BreedingInfo, PandoraInfo, PokemonInfo
289 |
290 | function initializeBuffers()
291 | GameInfo = console:createBuffer("Game Info")
292 | GameInfo:setSize(100, 100)
293 | CaptureInfo = console:createBuffer("Capture")
294 | CaptureInfo:setSize(100, 100)
295 | BreedingInfo = console:createBuffer("Breeding")
296 | BreedingInfo:setSize(100, 100)
297 | RoamerInfo = console:createBuffer("Roamer")
298 | RoamerInfo:setSize(100, 100)
299 | PandoraInfo = console:createBuffer("Pandora")
300 | PandoraInfo:setSize(100, 100)
301 | PokemonInfo = console:createBuffer("Pokemon Info")
302 | PokemonInfo:setSize(100, 100)
303 | end
304 |
305 | local gameVersion, gameLanguage = "", ""
306 | local wrongGameVersion
307 |
308 | function setGameVersion()
309 | local gameVersionCode = emu:read8(0x80000AE)
310 | local gameLanguageCode = emu:read8(0x80000AF)
311 |
312 | if gameVersionCode == 0x45 then -- Check game version
313 | gameVersion = "Emerald"
314 | elseif gameVersionCode == 0x47 then
315 | gameVersion = "LeafGreen"
316 | elseif gameVersionCode == 0x50 then
317 | gameVersion = "Sapphire"
318 | elseif gameVersionCode == 0x52 then
319 | gameVersion = "FireRed"
320 | elseif gameVersionCode == 0x56 then
321 | gameVersion = "Ruby"
322 | end
323 |
324 | if gameLanguageCode == 0x45 then -- Check game language and set addresses
325 | gameLanguage = "USA"
326 | speciesDexIndexAddr = 0x2024464
327 | wildTypeAddr = 0x2024AF9
328 | saveBlock2Addr = 0x2024EA4
329 | saveBlock1Addr = 0x2025734
330 | eggLowPIDAddr = 0x20287E8
331 | mapTypeAddr = 0x202E83F
332 | currBoxIndexAddr = 0x20300A0
333 | boxSelectedSlotIndexAddr = 0x20384E5
334 | selectedItemAddr = 0x203855E
335 | safariZoneStepsCounterAddr = 0x203880A
336 | roamerMapGroupAndNumAddr = 0x2039302
337 | timerAddr = 0x3001790
338 | battleTurnsCounterAddr = 0x30042F3
339 | partySlotsCounterAddr = 0x3004350
340 | partyAddr = 0x3004360
341 | enemyAddr = 0x30045C0
342 | currentSeedAddr = 0x3004818
343 | elseif gameLanguageCode == 0x4A then
344 | gameLanguage = "JPN"
345 | speciesDexIndexAddr = 0x20241C4
346 | wildTypeAddr = 0x2024859
347 | saveBlock2Addr = 0x2024C04
348 | saveBlock1Addr = 0x2025494
349 | eggLowPIDAddr = 0x2028548
350 | mapTypeAddr = 0x202E59F
351 | currBoxIndexAddr = 0x202FDBC
352 | boxSelectedSlotIndexAddr = 0x2038201
353 | selectedItemAddr = 0x203825C
354 | safariZoneStepsCounterAddr = 0x2038506
355 | roamerMapGroupAndNumAddr = 0x2038FFA
356 | timerAddr = 0x3001700
357 | battleTurnsCounterAddr = 0x3004223
358 | partySlotsCounterAddr = 0x3004280
359 | partyAddr = 0x3004290
360 | enemyAddr = 0x30044F0
361 | currentSeedAddr = 0x3004748
362 | elseif gameLanguageCode == 0x44 or gameLanguageCode == 0x46 or gameLanguageCode == 0x49 or gameLanguageCode == 0x53 then
363 | gameLanguage = "EUR"
364 | speciesDexIndexAddr = 0x2024464
365 | wildTypeAddr = 0x2024AF9
366 | saveBlock2Addr = 0x2024EA4
367 | saveBlock1Addr = 0x2025734
368 | eggLowPIDAddr = 0x20287E8
369 | mapTypeAddr = 0x202E83F
370 | currBoxIndexAddr = 0x20300A0
371 | boxSelectedSlotIndexAddr = 0x20384E5
372 | selectedItemAddr = 0x203855E
373 | safariZoneStepsCounterAddr = 0x203880A
374 | roamerMapGroupAndNumAddr = 0x2039302
375 | timerAddr = 0x3001790
376 | battleTurnsCounterAddr = 0x3004303
377 | partySlotsCounterAddr = 0x3004360
378 | partyAddr = 0x3004370
379 | enemyAddr = 0x30045D0
380 | currentSeedAddr = 0x3004828
381 | end
382 | end
383 |
384 | function printGameInfo()
385 | setGameVersion()
386 | wrongGameVersion = true
387 | GameInfo:clear()
388 |
389 | if gameVersion == "" then -- Print game info
390 | GameInfo:print("Version: Unknown game")
391 | elseif gameVersion ~= "Ruby" and gameVersion ~= "Sapphire" then
392 | GameInfo:print(string.format("Version: %s - Wrong game version! Use Ruby/Sapphire instead\n", gameVersion))
393 | elseif gameLanguage == "" then
394 | GameInfo:print("Version: "..gameVersion.."\n".."Language: Unknown language\n")
395 | else
396 | wrongGameVersion = false
397 | GameInfo:print("Version: "..gameVersion.."\n"..string.format("Language: %s\n", gameLanguage))
398 | end
399 | end
400 |
401 | function LCRNG(s, mul, sum)
402 | local a = (mul >> 16) * (s % 0x10000) + (s >> 16) * (mul % 0x10000)
403 | local b = (mul % 0x10000) * (s % 0x10000) + (a % 0x10000) * 0x10000 + sum
404 |
405 | return b % 0x100000000
406 | end
407 |
408 | local tempCurrentSeed = 0
409 |
410 | function LCRNGDistance(state0, state1)
411 | local mask = 1
412 | local dist = 0
413 |
414 | if state0 ~= state1 then
415 | for _, data in ipairs(JUMP_DATA) do
416 | local mult, add = table.unpack(data)
417 |
418 | if state0 == state1 then
419 | break
420 | end
421 |
422 | if ((state0 ~ state1) & mask) ~= 0 then
423 | state0 = LCRNG(state0, mult, add)
424 | dist = dist + mask
425 | end
426 |
427 | mask = mask << 1
428 | end
429 |
430 | tempCurrentSeed = state1
431 | end
432 |
433 | return dist > 999 and dist - 0x100000000 or dist
434 | end
435 |
436 | local initialSeed, advances = 0, 0
437 |
438 | function getRngInfo()
439 | local timer = emu:read16(timerAddr)
440 | local current = emu:read32(currentSeedAddr)
441 |
442 | if (timer == 0 and current <= 0xFFFF) or current == timer then
443 | initialSeed = current
444 | tempCurrentSeed = current
445 | end
446 |
447 | advances = initialSeed == current and 0 or advances + LCRNGDistance(tempCurrentSeed, current)
448 |
449 | return timer, current, advances
450 | end
451 |
452 | function showRngInfo(buffer)
453 | local paintingTimer, currentSeed, currentAdvances = getRngInfo()
454 | buffer:clear()
455 | buffer:print(string.format("Initial Seed: %04X\nPainting Timer: %04X\nCurrent Seed: %08X\nAdvances: %d\n\n\n", initialSeed, paintingTimer, currentSeed, currentAdvances))
456 | end
457 |
458 | function getPokemonIDs(addr)
459 | local pokemonIDs = emu:read32(addr + 0x4)
460 | local TID = pokemonIDs & 0xFFFF
461 | local SID = pokemonIDs >> 16
462 |
463 | return TID, SID
464 | end
465 |
466 | function getTrainerIDs()
467 | local trainerIDsAddr = saveBlock2Addr + 0xA
468 | local TID = emu:read16(trainerIDsAddr)
469 | local SID = emu:read16(trainerIDsAddr + 0x2)
470 |
471 | return TID, SID
472 | end
473 |
474 | function shinyCheck(PID, addr)
475 | addr = addr or nil
476 |
477 | local trainerTID, trainerSID
478 |
479 | if addr then
480 | trainerTID, trainerSID = getPokemonIDs(addr)
481 | else
482 | trainerTID, trainerSID = getTrainerIDs()
483 | end
484 |
485 | local lowPID = PID & 0xFFFF
486 | local highPID = PID >> 16
487 | local shinyTypeValue = (trainerSID ~ trainerTID) ~ (lowPID ~ highPID)
488 |
489 | if shinyTypeValue < 8 then
490 | return shinyTypeValue == 0 and " (Square)" or " (Star)"
491 | end
492 |
493 | return ""
494 | end
495 |
496 | function getOffset(offsetType, orderIndex)
497 | local offsets = {["growth"] = {0,0,0,0,0,0, 1,1,2,3,2,3, 1,1,2,3,2,3, 1,1,2,3,2,3},
498 | ["attack"] = {1,1,2,3,2,3, 0,0,0,0,0,0, 2,3,1,1,3,2, 2,3,1,1,3,2},
499 | ["misc"] = {3,2,3,2,1,1, 3,2,3,2,1,1, 3,2,3,2,1,1, 0,0,0,0,0,0}}
500 |
501 | return offsets[offsetType][orderIndex] * 12
502 | end
503 |
504 | function getIVs(ivsValue)
505 | local hpIV = ivsValue & 0x1F
506 | local atkIV = (ivsValue & (0x1F * 0x20)) / 0x20
507 | local defIV = (ivsValue & (0x1F * 0x400)) / 0x400
508 | local spAtkIV = (ivsValue & (0x1F * 0x100000)) / 0x100000
509 | local spDefIV = (ivsValue & (0x1F * 0x2000000)) / 0x2000000
510 | local spdIV = (ivsValue & (0x1F * 0x8000)) / 0x8000
511 |
512 | return hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV
513 | end
514 |
515 | function getHPTypeAndPower(hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
516 | local hpType = (((hpIV & 1) + (2 * (atkIV & 1)) + (4 * (defIV & 1)) + (8 * (spdIV & 1)) + (16 * (spAtkIV & 1))
517 | + (32 * (spDefIV & 1))) * 15) // 63
518 | local hpPower = (((((hpIV >> 1) & 1) + (2 * ((atkIV >> 1) & 1)) + (4 * ((defIV >> 1) & 1)) + (8 * ((spdIV >> 1) & 1))
519 | + (16 * ((spAtkIV >> 1) & 1)) + (32 * ((spDefIV >> 1) & 1))) * 40) // 63) + 30
520 |
521 | return hpType, hpPower
522 | end
523 |
524 | function showIVsAndHP(ivsValue, buffer)
525 | local hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV = getIVs(ivsValue)
526 | local hpType, hpPower = getHPTypeAndPower(hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV)
527 | buffer:print(string.format("IVs: %02d/%02d/%02d/%02d/%02d/%02d\nHPower: %s %d\n",
528 | hpIV, atkIV, defIV, spAtkIV, spDefIV, spdIV, HPTypeNamesList[hpType + 1], hpPower))
529 | end
530 |
531 | function getMoves(value1, value2)
532 | local move1 = value1 & 0xFFF
533 | local move2 = value1 >> 16
534 | local move3 = value2 & 0xFFF
535 | local move4 = value2 >> 16
536 |
537 | return move1, move2, move3, move4
538 | end
539 |
540 | function getPP(value)
541 | local PP1 = value & 0xFF
542 | local PP2 = (value >> 8) & 0xFF
543 | local PP3 = (value >> 16) & 0xFF
544 | local PP4 = value >> 24
545 |
546 | return PP1, PP2, PP3, PP4
547 | end
548 |
549 | function strPadding(moveStr, maxLength)
550 | local spaces = ""
551 | local moveStrLength = string.len(moveStr)
552 |
553 | if moveStrLength < maxLength then
554 | local padding = maxLength - moveStrLength
555 |
556 | for i = 0, padding do
557 | spaces = spaces.." "
558 | end
559 | end
560 |
561 | return moveStr..spaces
562 | end
563 |
564 | function showMovesAndPP(movesValue1, movesValue2, ppValue, buffer)
565 | local move1Index, move2Index, move3Index, move4Index = getMoves(movesValue1, movesValue2)
566 | local PPmove1, PPmove2, PPmove3, PPmove4 = getPP(ppValue)
567 | buffer:print(string.format("Move: %sPP: %d\n", strPadding(moveNamesList[move1Index <= 354 and move1Index + 1 or 1], 15), PPmove1))
568 | buffer:print(string.format("Move: %sPP: %d\n", strPadding(moveNamesList[move2Index <= 354 and move2Index + 1 or 1], 15), PPmove2))
569 | buffer:print(string.format("Move: %sPP: %d\n", strPadding(moveNamesList[move3Index <= 354 and move3Index + 1 or 1], 15), PPmove3))
570 | buffer:print(string.format("Move: %sPP: %d\n\n\n", strPadding(moveNamesList[move4Index <= 354 and move4Index + 1 or 1], 15), PPmove4))
571 | end
572 |
573 | function showInfo(pidAddr, buffer)
574 | local pokemonPID = emu:read32(pidAddr)
575 | local shinyType = shinyCheck(pokemonPID, pidAddr)
576 | local natureIndex = pokemonPID % 25
577 | local pokemonIDs = emu:read32(pidAddr + 0x4)
578 | local orderIndex = (pokemonPID % 24) + 1
579 | local decryptionKey = pokemonPID ~ pokemonIDs
580 | local growthOffset = getOffset("growth", orderIndex)
581 | local attacksOffset = getOffset("attack", orderIndex)
582 | local miscOffset = getOffset("misc", orderIndex)
583 |
584 | local ivsAndAbilityValue = emu:read32(pidAddr + 0x20 + miscOffset + 0x4) ~ decryptionKey
585 | local speciesAndItemValue = emu:read32(pidAddr + 0x20 + growthOffset) ~ decryptionKey
586 | local movesValue1 = emu:read32(pidAddr + 0x20 + attacksOffset) ~ decryptionKey
587 | local movesValue2 = emu:read32(pidAddr + 0x20 + attacksOffset + 0x4) ~ decryptionKey
588 | local PPValue = emu:read32(pidAddr + 0x20 + attacksOffset + 0x8) ~ decryptionKey
589 |
590 | local speciesDexIndex = speciesAndItemValue & 0xFFFF
591 | local speciesDexNumber = nationalDexList[speciesDexIndex + 1]
592 | local speciesName = speciesNamesList[speciesDexNumber]
593 |
594 | local itemIndex = speciesAndItemValue >> 16
595 | local itemName = itemNamesList[itemIndex + 1]
596 |
597 | local abilityNumber = (ivsAndAbilityValue >> 0x1F) + 1
598 | local abilityName = abilityNamesList[pokemonAbilities[(speciesDexNumber ~= nil and speciesDexNumber < 387) and speciesDexNumber or 1][abilityNumber]]
599 |
600 | buffer:print(string.format("Species: %s\n", speciesName ~= nil and speciesName or "--"))
601 | buffer:print(string.format("PID: %08X%s\n", pokemonPID, shinyType))
602 | buffer:print(string.format("Nature: %s\n", natureNamesList[natureIndex + 1]))
603 | buffer:print(string.format("Ability: %s (%d)\n", abilityName == nil and "--" or abilityName, abilityNumber))
604 | showIVsAndHP(ivsAndAbilityValue, buffer)
605 | buffer:print(string.format("Held item: %s\n\n", itemName ~= nil and itemName or "--"))
606 | showMovesAndPP(movesValue1, movesValue2, PPValue, buffer)
607 | end
608 |
609 | function showTrainerIDs(buffer)
610 | local trainerTID, trainerSID = getTrainerIDs()
611 | buffer:print(string.format("TID: %d\nSID: %d", trainerTID, trainerSID))
612 | end
613 |
614 | function getDayCareInfo()
615 | local eggStepsCounter = 255 - emu:read8(eggLowPIDAddr - 0x4)
616 | local eggFlagAddr = saveBlock1Addr + 0x1230
617 | local isEggReady = (emu:read8(eggFlagAddr) >> 6) & 0x1 == 1
618 |
619 | return isEggReady, eggStepsCounter
620 | end
621 |
622 | function showDayCareInfo(buffer)
623 | local isEggReady, eggStepsCounter = getDayCareInfo()
624 |
625 | if not isEggReady then
626 | buffer:print(string.format("Steps Counter: %d\nEgg is not ready\n", eggStepsCounter))
627 | end
628 |
629 | if isEggReady then
630 | local eggLowPid = emu:read16(eggLowPIDAddr)
631 | buffer:print(string.format("Egg generated, go get it!\nEgg lower PID: %04X\n\n\n", eggLowPid))
632 | elseif eggStepsCounter == 1 then
633 | buffer:print("Next step might generate an egg!\n\n\n")
634 | elseif eggStepsCounter == 0 then
635 | buffer:print("255th step taken\n\n\n")
636 | else
637 | buffer:print("Keep on steppin'\n\n\n")
638 | end
639 | end
640 |
641 | function isEgg(addr)
642 | return emu:read16(addr + 0x12) == 0x601
643 | end
644 |
645 | function showPartyEggInfo(buffer)
646 | local partySlotsCounter = emu:read8(partySlotsCounterAddr) - 1
647 | local lastPartySlotAddr = partyAddr + (partySlotsCounter * 0x64)
648 |
649 | if isEgg(lastPartySlotAddr) then
650 | showInfo(lastPartySlotAddr, buffer)
651 | end
652 | end
653 |
654 | function getRoamerInfo()
655 | local roamerAddr = saveBlock1Addr + 0x3144
656 | local roamerIVsValue = emu:read32(roamerAddr) & 0xFF -- Raomes IVs bug (RS/FRLG only)
657 | local roamerPID = emu:read32(roamerAddr + 0x4)
658 | local roamerShinyType = shinyCheck(roamerPID)
659 | local roamerNatureIndex = roamerPID % 25
660 | local roamerSpeciesIndex = emu:read16(roamerAddr + 0x8)
661 | local roamerDexIndex = nationalDexList[roamerSpeciesIndex + 1]
662 | local roamerSpeciesName = speciesNamesList[roamerDexIndex]
663 | local roamerHP = emu:read16(roamerAddr + 0xA)
664 | local roamerLevel = emu:read8(roamerAddr + 0xC)
665 | local roamerStatusIndex = emu:read8(roamerAddr + 0xD)
666 | local roamerStatus = statusConditionNamesList[1] -- No altered status condition
667 |
668 | local roamerMapGroupAndNum = emu:read16(roamerMapGroupAndNumAddr)
669 | local roamerMapIndex = roamerMapGroupAndNum >> 8
670 | local playerMapGroupAndNumAddr = saveBlock1Addr + 0x4
671 | local playerMapGroupAndNum = emu:read16(playerMapGroupAndNumAddr)
672 |
673 | if roamerStatusIndex > 0 and roamerStatusIndex < 0x8 then -- Sleep
674 | roamerStatus = statusConditionNamesList[2]
675 | elseif roamerStatusIndex == 0x8 then -- Poison
676 | roamerStatus = statusConditionNamesList[3]
677 | elseif roamerStatusIndex == 0x10 then -- Burn
678 | roamerStatus = statusConditionNamesList[4]
679 | elseif roamerStatusIndex == 0x20 then -- Freeze
680 | roamerStatus = statusConditionNamesList[5]
681 | elseif roamerStatusIndex == 0x40 then -- Paralysis
682 | roamerStatus = statusConditionNamesList[6]
683 | elseif roamerStatusIndex == 0x80 then -- Bad Poison
684 | roamerStatus = statusConditionNamesList[7]
685 | end
686 |
687 | local isRoamerActive = emu:read8(roamerAddr + 0x13) == 1
688 |
689 | return roamerSpeciesName, roamerPID, roamerShinyType, roamerNatureIndex, roamerIVsValue, isRoamerActive,
690 | roamerLevel, roamerHP, roamerStatus, roamerMapIndex, roamerMapGroupAndNum, playerMapGroupAndNum
691 | end
692 |
693 | function showRoamerInfo(buffer)
694 | local roamerSpeciesName, roamerPID, roamerShinyType, roamerNatureIndex, roamerIVsValue, isRoamerActive,
695 | roamerLevel, roamerHP, roamerStatus, roamerMapIndex, roamerMapGroupAndNum, playerMapGroupAndNum = getRoamerInfo()
696 |
697 | if isRoamerActive then
698 | buffer:print("Active Roamer? Yes\n")
699 | buffer:print(string.format("Species: %s\n", roamerSpeciesName))
700 | buffer:print(string.format("PID: %08X%s\n", roamerPID, roamerShinyType))
701 | buffer:print(string.format("Nature: %s\n", natureNamesList[roamerNatureIndex + 1]))
702 | showIVsAndHP(roamerIVsValue, buffer)
703 | buffer:print(string.format("Level: %d\n", roamerLevel))
704 | buffer:print(string.format("HP: %d\n", roamerHP))
705 | buffer:print(string.format("Status condition: %s\n", roamerStatus))
706 | buffer:print(string.format("Current position: %s%s\n\n\n", locationNamesList[roamerMapIndex + 1],
707 | roamerMapGroupAndNum == playerMapGroupAndNum and " (!!!)" or ""))
708 | else
709 | buffer:print("Active Roamer? No\n\n\n")
710 | end
711 | end
712 |
713 | local prevKeyInfo, infoIndex, infoMode = {}, 1, {"Gift", "Party", "Stats", "Box"}
714 |
715 | function getInfoInput(buffer)
716 | local key = emu:getKeys()
717 |
718 | if key == 0x120 and prevKeyInfo ~= key then
719 | infoIndex = infoIndex - 1 < 1 and 4 or infoIndex - 1
720 | elseif key == 0x110 and prevKeyInfo ~= key then
721 | infoIndex = infoIndex + 1 > 4 and 1 or infoIndex + 1
722 | end
723 |
724 | prevKeyInfo = key
725 | buffer:print(string.format("Mode: %s(Change mode pressing R+Right/R+Left)\n\n", strPadding(infoMode[infoIndex], 6)))
726 | end
727 |
728 | function showPokemonIDs(addr, buffer)
729 | local pokemonTID, pokemonSID = getPokemonIDs(addr)
730 | buffer:print(string.format("TID: %d\nSID: %d", pokemonTID, pokemonSID))
731 | end
732 |
733 | function showPokemonInfo(buffer)
734 | getInfoInput(buffer)
735 |
736 | if infoMode[infoIndex] == "Gift" then
737 | local partySlotsCounter = emu:read8(partySlotsCounterAddr) - 1
738 | local lastPartySlotAddr = partyAddr + (partySlotsCounter * 0x64)
739 |
740 | showInfo(lastPartySlotAddr, buffer)
741 | showPokemonIDs(lastPartySlotAddr, buffer)
742 | elseif infoMode[infoIndex] == "Party" then
743 | local partySlotsCounter = emu:read8(partySlotsCounterAddr) - 1
744 | local partySelectedSlotIndex = emu:read8(0x20200BA + (partySlotsCounter * 0x88))
745 | local partySelectedPokemonAddr = partyAddr + (partySelectedSlotIndex * 0x64)
746 |
747 | showInfo(partySelectedPokemonAddr, buffer)
748 | showPokemonIDs(partySelectedPokemonAddr, buffer)
749 | elseif infoMode[infoIndex] == "Box" then
750 | local currBoxIndex = emu:read8(currBoxIndexAddr)
751 | local boxAddr = currBoxIndexAddr + 0x4
752 | local boxSelectedSlotIndex = emu:read8(boxSelectedSlotIndexAddr)
753 | local boxSelectedPokemonAddr = boxAddr + (0x1E * currBoxIndex * 0x50) + (boxSelectedSlotIndex * 0x50)
754 |
755 | showInfo(boxSelectedPokemonAddr, buffer)
756 | showPokemonIDs(boxSelectedPokemonAddr, buffer)
757 | elseif infoMode[infoIndex] == "Stats" then
758 | local pokemonStatsScreenAddr = 0x2018010
759 | showInfo(pokemonStatsScreenAddr, buffer)
760 | showPokemonIDs(pokemonStatsScreenAddr, buffer)
761 | end
762 | end
763 |
764 | function updateCaptureBuffer()
765 | showRngInfo(CaptureInfo)
766 | showInfo(enemyAddr, CaptureInfo)
767 | showTrainerIDs(CaptureInfo)
768 | end
769 |
770 | function updateBreedingBuffer()
771 | showRngInfo(BreedingInfo)
772 | showDayCareInfo(BreedingInfo)
773 | showPartyEggInfo(BreedingInfo)
774 | showTrainerIDs(BreedingInfo)
775 | end
776 |
777 | function updateRoamerBuffer()
778 | showRngInfo(RoamerInfo)
779 | showRoamerInfo(RoamerInfo)
780 | showTrainerIDs(RoamerInfo)
781 | end
782 |
783 | function updatePandoraBuffer()
784 | showRngInfo(PandoraInfo)
785 | showTrainerIDs(PandoraInfo)
786 | end
787 |
788 | function updatePokemonInfoBuffer()
789 | showRngInfo(PokemonInfo)
790 | showPokemonInfo(PokemonInfo)
791 | end
792 |
793 | function createStateFile(statesFileName, stateSlot)
794 | os.execute("mkdir states")
795 | local statesFile = io.open(statesFileName, "w")
796 |
797 | if statesFile then -- Check if the state file has been created correctly
798 | for slotNumber = 1, 9 do
799 | if slotNumber == stateSlot then -- Write only in the line of the saved slot
800 | statesFile:write(string.format("%08X %08X %d\n", initialSeed, tempCurrentSeed, advances))
801 | else -- Fill with empty data the lines of not saved state
802 | statesFile:write("00000000 00000000 0\n")
803 | end
804 | end
805 |
806 | statesFile:close()
807 | end
808 | end
809 |
810 | function writeStateFile(statesFileName, stateSlot)
811 | local statesFile = io.open(statesFileName, "r")
812 | local line_num = 1
813 | local lines = ""
814 |
815 | for line in statesFile:lines() do
816 | if line_num == stateSlot then -- Overwrite only the line of the saved slot
817 | line = string.format("%08X %08X %d", initialSeed, tempCurrentSeed, advances)
818 | end
819 |
820 | lines = lines..line.."\n"
821 | line_num = line_num + 1
822 | end
823 |
824 | statesFile:close()
825 | statesFile = io.open(statesFileName, "w")
826 | statesFile:write(lines)
827 | statesFile:close()
828 | end
829 |
830 | function writeSaveStateValues(statesFileName, stateSlot)
831 | local statesFileCheck = io.open(statesFileName, "r")
832 |
833 | if not statesFileCheck then -- Check if the states file does not exist
834 | createStateFile(statesFileName, stateSlot)
835 | else -- States file already exists
836 | statesFileCheck:close()
837 | writeStateFile(statesFileName, stateSlot)
838 | end
839 | end
840 |
841 | function setSaveStateValues(statesFileName, stateSlot)
842 | local statesFile = io.open(statesFileName, "r")
843 |
844 | if statesFile then
845 | local line_num = 1
846 | local values = {}
847 |
848 | for line in statesFile:lines() do
849 | if line_num == stateSlot then -- Load values from the line of the loaded slot only
850 | for value in line:gmatch("%S+") do
851 | table.insert(values, value)
852 | end
853 |
854 | break
855 | end
856 |
857 | line_num = line_num + 1
858 | end
859 |
860 | statesFile:close()
861 | initialSeed = tonumber(values[1], 16)
862 | tempCurrentSeed = tonumber(values[2], 16)
863 | advances = tonumber(values[3])
864 | end
865 | end
866 |
867 | function getSaveStateInput()
868 | local slotNumber = nil
869 |
870 | if input:isKeyActive(49) or input:isKeyActive(33) then -- Check if (n) is being pressed
871 | slotNumber = 1
872 | elseif input:isKeyActive(50) or input:isKeyActive(34) then
873 | slotNumber = 2
874 | elseif input:isKeyActive(51) or input:isKeyActive(163) then
875 | slotNumber = 3
876 | elseif input:isKeyActive(52) or input:isKeyActive(36) then
877 | slotNumber = 4
878 | elseif input:isKeyActive(53) or input:isKeyActive(37) then
879 | slotNumber = 5
880 | elseif input:isKeyActive(54) or input:isKeyActive(38) then
881 | slotNumber = 6
882 | elseif input:isKeyActive(55) or input:isKeyActive(47) then
883 | slotNumber = 7
884 | elseif input:isKeyActive(56) or input:isKeyActive(40) then
885 | slotNumber = 8
886 | elseif input:isKeyActive(57) or input:isKeyActive(41) then
887 | slotNumber = 9
888 | end
889 |
890 | if slotNumber ~= nil then
891 | local savingStateFlag = input:isKeyActive(8388658) -- Check if Shift is being pressed
892 | local statesFileName = string.format("states/%s_%s_states_values.txt", gameVersion, string.gsub(gameLanguage, "/", "_"))
893 |
894 | if savingStateFlag then -- Saving a state
895 | emu:saveStateSlot(slotNumber)
896 | writeSaveStateValues(statesFileName, slotNumber)
897 | else -- Loading a state
898 | emu:loadStateSlot(slotNumber)
899 | setSaveStateValues(statesFileName, slotNumber)
900 | end
901 | end
902 | end
903 |
904 | function updateBuffers()
905 | if (not wrongGameVersion) then
906 | updateCaptureBuffer()
907 | updateBreedingBuffer()
908 | updateRoamerBuffer()
909 | updatePandoraBuffer()
910 | updatePokemonInfoBuffer()
911 | getSaveStateInput()
912 | end
913 | end
914 |
915 | emu:reset()
916 | initializeBuffers()
917 | printGameInfo()
918 | callbacks:add("frame", updateBuffers)
919 | callbacks:add("reset", printGameInfo)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PokeLua
2 | Useful lua scripts for RNG abusing in Pokémon games.
3 |
4 | Join [Pokemon RNG](https://www.pokemonrng.com) or [Devon Studios](https://devonstudios.it) discord servers to talk about RNG or for assistance!
5 |
6 | [](https://www.discord.gg/d8JuAvg)
7 | [](https://discord.gg/7gNVdkdBwA)
8 |
9 | ## Gen 1 features
10 | ### RBG/Y
11 | * Gift Bot
12 | * Stationary Bot
13 | * Fishing Bot
14 | * In-Game Trade Bot
15 | * TID Bot
16 | * Party Pokémon Info checking
17 |
18 | ## Gen 2 features - _soon_
19 | ### GS/C
20 |
21 | ## Gen 3 features
22 | ### RS/FRLG/E
23 | * Rng info checking
24 | * Wild Pokémon info checking
25 | * Breeding info checking
26 | * Roamer Pokémon info checking
27 | * Trainer info checking
28 | * Initial Seed Bot (FRLG only)
29 | * TID Bot (FRLG/E only)
30 | * Party Pokémon info checking
31 | * Box Pokémon info checking
32 | * Checksums info checking (USA/EUR RS only)
33 |
34 | ### C/XD
35 | * Rng info checking
36 | * Enemy Pokémon info checking
37 | * Party Pokémon info checking
38 | * Box Pokémon info checking
39 | * Trainer info checking
40 |
41 | ## Gen 4 features
42 | ### DP/Pt/HGSS
43 | * Rng info checking
44 | * Wild Pokémon info checking
45 | * Breeding info checking
46 | * Roamer Pokémon info checking
47 | * Trainer info checking
48 | * Party Pokémon info checking
49 | * Box Pokémon info checking
50 |
51 | ## Gen 5 features
52 | ### BW/B2W2
53 | * Rng info checking
54 | * Wild Pokémon info checking
55 | * Breeding info checking
56 | * Roamer Pokémon info checking (BW)
57 | * C-Gear Pokémon info checking
58 | * Trainer info checking
59 | * Party Pokémon info checking
60 | * Box Pokémon info checking
61 |
62 | ## Supported emulators
63 | ### mGBA
64 | Use latest development build: [link](https://mgba.io/downloads.html#desktop-os-1)
65 |
66 | ### Dolphin
67 | Use this build which supports lua core: [link](https://github.com/Real96/Dolphin-Lua-Core/releases)
68 |
69 | ### DeSmuMe
70 | Use version `0.9.11_x86_dev+`: [link](https://sourceforge.net/projects/desmume/files/desmume/0.9.11/desmume-0.9.11-win32-dev.zip/download)
71 |
72 | 1) Download the file [lua5.1.dll](https://sourceforge.net/projects/luabinaries/files/5.1.5/Windows%20Libraries/Dynamic/lua-5.1.5_Win32_dll17_lib.zip/download)
73 | 2) Move it in DeSmuMe folder
74 | 3) Rename it as `lua51.dll`
75 |
76 | #### Final folder:
77 | 
78 |
79 | ### BizHawk
80 | Use latest release: [link](https://github.com/TASEmulators/BizHawk/releases)
81 |
82 | ## Notes for mGBA scripts
83 | * Be sure to enlarge enough the lua window to avoid text flickering or emulation lagging
84 | * Every time you need to save or load a state, hold `Shift` + `(n)`/`(n)` (ex. `Shift` + `1` to save a state in slot 1 or `1` to load the state in slot 1) with game unpaused
85 |
86 | ## Notes for DeSmuMe scripts
87 | * Everytime you need to restart the game, press the button `Restart` in the lua window
88 | * Every time you need to save or load a state, pause the game and hold `Shift` + `F(n)`/`F(n)` (ex. `Shift` + `F1` to save a state in slot 1 or `F1` to load the state in slot 1) for some seconds, until you see the message `Saved State (n)`/`Loaded State (n)` appearing on the lower screen for less than a second
89 |
90 |
91 | ## Credits:
92 | * [Kaphotics](https://github.com/kwsch) for the research and for his [gen3](https://projectpokemon.org/home/forums/topic/15187-gen-3-lua-scripts) and [gen5](https://projectpokemon.org/home/forums/topic/15140-pokemon-bw-lua-scripts) scripts
93 | * [Admiral_Fish](https://github.com/Admiral-Fish), [bumba](https://github.com/pkmnbumba), and [EzPzStreamz](https://github.com/SteveCookTU) for the research and for their great app [PokeFinder](https://github.com/Admiral-Fish/PokeFinder) always up to date
94 | * [zep715](https://github.com/zep715) for his [gen1](https://github.com/zep715/rbylua) scripts
95 | * [wwwwwwzx](https://github.com/wwwwwwzx) for his [gen2](https://github.com/wwwwwwzx/gsclua) scripts
96 | * [zaksabeast](https://github.com/zaksabeast) for his Jirachi Wishmaker [script](https://www.reddit.com/r/pokemonrng/comments/5ny1el/scripts_and_guide_to_help_automate_rnging_a_shiny) and for his [wishmaker calculator](https://gist.github.com/zaksabeast/600fdd9579aaa4dde5b93f7207ea6550)
97 | * [SciresM](https://github.com/SciresM), Zari, [amab](https://github.com/AskMeAboutBirds), [OmegaDonut](https://github.com/OmegaDonut), [Bond697](https://github.com/Bond697), [Lincoln-LM](https://github.com/Lincoln-LM), [StarfBerry](https://github.com/StarfBerry), [Shao](https://github.com/c-poole) and all the other Pokémon researchers!
98 | * [MKDasher](https://github.com/mkdasher) for his [gen4/gen5](https://www.dropbox.com/s/qx2fo1zc44p1jr7/Pokemon%20Gen%204-5%20Lua%20script.rar) scripts
99 | * [BizHawk](https://github.com/TASEmulators/BizHawk), [DeSmuMe](https://github.com/TASEmulators/desmume), [mGBA](https://github.com/mgba-emu/mgba), [VBA-ReRecording](https://github.com/TASEmulators/vba-rerecording) devs
100 | * [SwareJonge](https://github.com/SwareJonge) for his [Dolphin version](https://github.com/SwareJonge/Dolphin-Lua-Core) with lua scripts support
101 |
--------------------------------------------------------------------------------