├── .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 | [![PokemonRNG](https://discordapp.com/assets/07dca80a102d4149e9736d4b162cff6f.ico)](https://www.discord.gg/d8JuAvg) 7 | [![Devon Studios](https://discordapp.com/assets/07dca80a102d4149e9736d4b162cff6f.ico)](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 | ![image](https://github.com/Real96/PokeLua/assets/20956021/e6a21f63-ba96-4cc6-82fa-e9fba93537c6) 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 | --------------------------------------------------------------------------------