Hacking ROM Hack Pokemon Legends Z-A Cheat Database

  • Thread starter Thread starter OblivionReign
  • Start date Start date
  • Views Views 1,079,293
  • Replies Replies 7,134
  • Likes Likes 85
Is it possible to update these codes by TomSwitch for 1.0.2?

[R3 Mega Transform Toggle]
04000000 002E7798 BD01AA61
04000000 002E7798 14B37EAE
04000000 02FC7250 1C000061
04000000 02FC7254 BD01AA61
04000000 02FC7258 174C8151
04000000 02FC725C 42C80000
80000020
04000000 02FC725C 00000000
20000000
04000000 00245180 BD41AE60

if you turn the code off use this to set the game back to normal:
[Off enable]
04000000 0072ADDC B94042E1

Please and thank you :bow:
ok
 
Changing hunter to gengar don't effect the mission. The mission still there
Check flags to modify the Mable research
 

Attachments

  • Screenshot_2025-11-12-14-21-26-262_com.android.chrome.jpg
    Screenshot_2025-11-12-14-21-26-262_com.android.chrome.jpg
    141.4 KB · Views: 23
  • Like
Reactions: shinwg
Is it possible to update these codes by TomSwitch for 1.0.2?

[R3 Mega Transform Toggle]
04000000 002E7798 BD01AA61
04000000 002E7798 14B37EAE
04000000 02FC7250 1C000061
04000000 02FC7254 BD01AA61
04000000 02FC7258 174C8151
04000000 02FC725C 42C80000
80000020
04000000 02FC725C 00000000
20000000
04000000 00245180 BD41AE60

if you turn the code off use this to set the game back to normal:
[Off enable]
04000000 0072ADDC B94042E1

Please and thank you :bow:
[Press R3 to charge Mega Energy]
040E0000 002E52CC 1E204C21
80000020
040E0000 002E52CC D503201F
20000000
 
Next time you share my code, make sure to include it in full.

Without the Master Code, you're going to have issues with the HP code.

Doesn't work on emu. Both parties are stuck with full health on Eden and Citron. Ryubing it doesn't stop hp from decreasing at all. I have a modded switch, but when I try to update the title it knows I didn't get the update from Nintendo. lol
 
Hi i dont have Pkhex cause i play un macbook :'( can someone help me activate the diancie event?
Post automatically merged:

Hi i dont have pkehex cause i play in macbook :( can anyone help me activate the diancie event ?
A little late but you can run pkhex if you have something like boot camp or a virtual windows machine
Post automatically merged:

Not sure if you guys saw this mod, but a lot of people have asked for a forced Alpha code. This forces 100% Alpha rate so you can catch pokemon in their correct zones as Alphas. Credits to z923493402.

https://gamebanana.com/mods/633110
It isn’t yet updated for the new game update though
 
Wondering if anyone can help? I'm on 1.0.2 and was tinkering with things (new to pkhex) to enable to diancinite and mewtwo quests, but for some reason it's not triggering the events for me. I used the unlock all code and got the diancinite and mewtwo mega stones and put then on my first 3 pokemon in box 1, but that still didn't trigger the event. Also when i try to throw a pokeball, it has my character holding a EXP XL item insatead of options to use pokeballs. I might've messed something up somewhere and can't figure out how to fix it. Thank you in advance if anyone can help!
 

Attachments

Wondering if anyone can help? I'm on 1.0.2 and was tinkering with things (new to pkhex) to enable to diancinite and mewtwo quests, but for some reason it's not triggering the events for me. I used the unlock all code and got the diancinite and mewtwo mega stones and put then on my first 3 pokemon in box 1, but that still didn't trigger the event. Also when i try to throw a pokeball, it has my character holding a EXP XL item insatead of options to use pokeballs. I might've messed something up somewhere and can't figure out how to fix it. Thank you in advance if anyone can help!
ur event flags 180 and 182 is not activated....try this save file....and for stone, put on ur party pokemon, not ur box 1 pokemon...
 

Attachments

ur event flags 180 and 182 is not activated....try this save file....and for stone, put on ur party pokemon, not ur box 1 pokemon...
Tysm! That worked! Would you happen to know how to fix the glitch where i'm unable to throw pokeballs? It show's as EXP XL every time i try to throw a pokeball. When i sold all the EXP XL's, it says i have no pokeballs in my inventory.
 
A little late but you can run pkhex if you have something like boot camp or a virtual windows machine
Post automatically merged:


It isn’t yet updated for the new game update though
It's a new mod, it was created after the update came out; it was only released 1 day ago. Mods don't usually need updates like cheats do. It's a romfs mod, not a .txt cheat.
 
Tysm! That worked! Would you happen to know how to fix the glitch where i'm unable to throw pokeballs? It show's as EXP XL every time i try to throw a pokeball. When i sold all the EXP XL's, it says i have no pokeballs in my inventory.
just turn off all ur cheat code and do restore code...then try again after doing that...only using code that working only...
 
It's a new mod, it was created after the update came out; it was only released 1 day ago. Mods don't usually need updates like cheats do. It's a romfs mod, not a .txt cheat.
Yo, any idea if this thing even works with an emulator? Been messin’ around with Eden, but once I drop the folder in the right spot, the game just keeps loadin’ forever.
 
Yo, any idea if this thing even works with an emulator? Been messin’ around with Eden, but once I drop the folder in the right spot, the game just keeps loadin’ forever.
some mods are now based in cheat menu debug and this mode isnt compatible with yuzu-forks
 
  • Like
Reactions: bosanto
i fixed my script so if anyone wants to use it for updating or downgrading codes. this is for IDA 9.0+ but i am using 9.2
Python:
# This script was made by OblivionReign
import sys
sys.path.insert(1,'C:\Program Files\IDA Professional 9.2\scripts')
from importlib import reload
try:
    if 'cheatlib' in sys.modules:
        del sys.modules['cheatlib']
except NameError:
    pass

import cheatLib
cheatLib = reload(cheatLib)
from cheatLib import *
cls()
################################ START ######################################

Init('Pokemon Legends Z-A')

AddSection('Item/Misc')
AddCheat('Disable Autosave') # strb w8, [x20, #0xf0]
cheatAddr = AOB('88 C2 03 39 E1 03 13 AA')
Hack(cheatAddr, 'NOP')

AddCheat('Max/Inf Money') # str w8, [x0, #0x40]
cheatAddr1 = AOB('08 40 00 B9 00 01 80 52')
cheatAddr2 = AOB('08 40 00 B9 C0 03 5F D6 E0 CF 92 52')
Hack(cheatAddr1, 'str w9, [x0, #0x40]')
Hack(cheatAddr2, 'str w9, [x0, #0x40]')

AddCheat('Items dont decrease') # str x2, [x8]
cheatAddr = AOB('02 01 00 F9 03 09 00 B9')
Hack(cheatAddr, 'NOP')

AddCheat('50,000 Challenger Tickets') # add w8, w8, w22
cheatAddr = AOB('08 01 16 0B 69 2E 41 B9')
Hack(cheatAddr, 'mov w8, #0xc350')
EndSection('Item/Misc')

AddSection('Movement')
AddCheat('Movement Speed x8 Hold ZL') # fmov s0, #1.00000000
hack_addr = AOB('00 10 2E 1E 00 18 24 1E')
Hack(
    hack_addr,
    'fmov s0, #8.00000000',
    showRestoreCode=False,
    useButton='ZL',
    elseCode=Hack(
        hack_addr,
        'fmov s0, #1.00000000',
        showRestoreCode=False,
        returnCode=True
    )
)

AddCheat('Walk through Walls (Hold:Y)')
AddCheatCode('''580F0000 05F299A8
580F1000 000000C0
580F1000 00000000
580F1000 00000138
780F0000 00000143
610F0000 00000000 0000003C
80000008
610F0000 00000000 000000BF
20000000
''')

AddCheat('Moon Jump (Hold:B)')
AddCheatCode('''80000002
580F0000 05F299A8
580F1000 000000C0
580F1000 00000000
580F1000 00000138
780F0000 00000094
989EF000
580E1000 00000000
C4000000 00000000 00000002
94AEE100 40000000
20000000
A4EF0000
80000002
580F0000 05F299A8
580F1000 000000C0
580F1000 00000000
580F1000 00000138
780F0000 000000C4
640F0000 00000000 41200000
20000000
''')

AddCheat('Game Speed (L3+↑/↓ Speed Up/Down')
cheatAddr=AOB('56 A0 FC 01', searchStart=dataStart, searchEnd=dataEnd)
AddCheatCode('''80002020
18050000 %08X 00000000 03F940AB
040F0000 %08X 05F5E100
20000000
18050000 %08X 00000000 02FAF080
040F0000 %08X 03F940AB
20000000
18050000 %08X 00000000 01FCA056
040F0000 %08X 02FAF080
20000000
20000000
80008020
18050000 %08X 00000000 02FAF080
040F0000 %08X 01FCA056
20000000
18050000 %08X 00000000 03F940AB
040F0000 %08X 02FAF080
20000000
18050000 %08X 00000000 05F5E100
040F0000 %08X 03F940AB
20000000
20000000
'''%(cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr,cheatAddr))
EndSection('Movement')

AddSection('Spawn Modifiers')
AddCheat('Force Shiny') # ldr w1, [sp, #0x20], ldr w1, [sp, #0x28]
cheatAddr = AOB('E1 23 40 B9 ? ? ? ? 60 3A 40 F9')
cheatAddr1 = AOB('E1 2B 40 B9 ? ? ? ? 60 3A 40 F9')
Hack(cheatAddr, 'mov w1, #1')
Hack(cheatAddr1, 'mov w1, #1')

AddCheat('6IV On') # ldrb w1, [sp, #0x50]
cheatAddr1 = AOB('E1 43 41 39')
cheatAddr2 = AOB('E1 4B 41 39')
cheatAddr3 = AOB('E1 53 41 39')
cheatAddr4 = AOB('E1 5B 41 39')
cheatAddr5 = AOB('E1 63 41 39')
cheatAddr6 = AOB('E1 6B 41 39')
Hack(cheatAddr1, 'mov w1, #0x1f')
Hack(cheatAddr2, 'mov w1, #0x1f')
Hack(cheatAddr3, 'mov w1, #0x1f')
Hack(cheatAddr4, 'mov w1, #0x1f')
Hack(cheatAddr5, 'mov w1, #0x1f')
Hack(cheatAddr6, 'mov w1, #0x1f')

AddCheat('Always Encounter Pokedex')
cheatAddr1 = AOB('17 30 41 79')
cheatAddr2 = AOB('60 3A 40 F9 ? ? ? ? 60 3A 40 F9 E1 1B 40 B9')
cave_result = CodeCave(cheatAddr1,(
    'ldrh w23, [x0, #0x98]',
    'adrp x7, #0x2fa4000',
    'str w23, [x7, #0x8f0]',
    'B {back}',
),
    use_BL=False   
)
cave_result = CodeCave(cheatAddr2,(
    'adrp x7, #0x2fa4000',
    'ldr w1, [x7, #0x8f0]',
    'cbz w1, #0x8',
    'strh w1, [sp, #0x32]',
    'ldr x0, [x19, #0x70]',
    'B {back}',
),
    use_BL=False   
)

LEVEL_DATA_ADDR = RegCodeK(4)
ITEM_DATA_ADDR = RegCodeK(4)
FORM_DATA_ADDR = RegCodeK(4)
SPECIES_DATA_ADDR = RegCodeK(4)

AddCheat('Always Encounter Pokemon') # ldr x0, [x19, #0x70]
cheatAddr = AOB('60 3A 40 F9 ? ? ? ? 60 3A 40 F9 E1 1B 40 B9')
cave_result = CodeCave(cheatAddr,(
    'ldr w1, {end}-0x10',
    'cbz w1, #0x8',
    'strh w1, [sp, #0x32]',
    'ldr w1, {end}-0xC',
    'strh w1, [sp, #0x34]',
    'ldr w1, {end}-8',
    'strh w1, [sp, #0x36]',
    'ldr w1, {end}-4',
    'strb w1, [sp, #0x40]',
    'ldr x0, [x19, #0x70]',
    'B {back}',
    Value2DWord(1),
    Value2DWord(0),
    Value2DWord(0),
    Value2DWord(10)
    ),
    showRestoreCode=False,
    use_BL=False
)

AddCheat('Encounter Zygarde') # Dex #718 Hex #2CE
Hack(
    SPECIES_DATA_ADDR,
    0x2CE,
    False
)

AddCheat('Encounter Zygarde Level 100 10%') # Dex #718 Hex #2CE
Hack(
    SPECIES_DATA_ADDR,
    0x2CE,
    False
)
Hack(
    FORM_DATA_ADDR,
    0x2,
    False
)
Hack(
    LEVEL_DATA_ADDR,
    0x64,
    False
)

AddCheat('Encounter Item Masterball') # Item 1
Hack(
    ITEM_DATA_ADDR,
    0x1,
    False
)

AddCheat('Encounter Item Rare Candy') # Item 50
Hack(
    ITEM_DATA_ADDR,
    0x32,
    False
)

AddCheat('Always Level 100') # ldrb w2, [sp, #0x40]
cheatAddr = AOB('E2 03 41 39')
Hack(cheatAddr, 'mov w2, #0x64')

AddCheat('Always Level 50') # ldrb w2, [sp, #0x40]
cheatAddr = AOB('E2 03 41 39')
Hack(cheatAddr, 'mov w2, #50', showRestoreCode=False)

AddCheat('Always Level 5') # ldrb w2, [sp, #0x40]
cheatAddr = AOB('E2 03 41 39')
Hack(cheatAddr, 'mov w2, #0x5', showRestoreCode=False)

AddCheat('Always Level 1') # ldrb w2, [sp, #0x40]
cheatAddr = AOB('E2 03 41 39')
Hack(cheatAddr, 'mov w2, #0x1', showRestoreCode=False)

AddCheat('Always Male') # ldrb w1, [sp, #0x42]
cheatAddr = AOB('E1 0B 41 39')
Hack(cheatAddr, 'mov w1, #0')

AddCheat('Always Female') # ldrb w1, [sp, #0x42]
cheatAddr = AOB('E1 0B 41 39')
Hack(cheatAddr, 'mov w1, #1', showRestoreCode=False)

AddCheat('Always Genderless') # ldrb w1, [sp, #0x42]
cheatAddr = AOB('E1 0B 41 39')
Hack(cheatAddr, 'mov w1, #2', showRestoreCode=False)

AddCheat('(None Hardy)') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0')
Hack(cheatAddr2, 'mov w1, #0')

AddCheat('(+Atk, -Def) Lonely') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #1', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #1', showRestoreCode=False)

# [(+Atk, -Spd) Brave] - Value #2
AddCheat('(+Atk, -Spd) Brave') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #2', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #2', showRestoreCode=False)

# [(+Atk, -SAtk) Adamant] - Value #3
AddCheat('(+Atk, -SAtk) Adamant') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #3', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #3', showRestoreCode=False)

# [(+Atk, -SDef) Naughty] - Value #4
AddCheat('(+Atk, -SDef) Naughty') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #4', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #4', showRestoreCode=False)

# [(+Def, -Atk) Bold] - Value #5
AddCheat('(+Def, -Atk) Bold') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #5', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #5', showRestoreCode=False)

# [(None) Docile] - Value #6
AddCheat('(None) Docile') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #6', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #6', showRestoreCode=False)

# [(+Def, -Spd) Relaxed] - Value #7
AddCheat('(+Def, -Spd) Relaxed') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #7', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #7', showRestoreCode=False)

# [(+Def, -SAtk) Impish] - Value #8
AddCheat('(+Def, -SAtk) Impish') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #8', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #8', showRestoreCode=False)

# [(+Def, -SDef) Lax] - Value #9
AddCheat('(+Def, -SDef) Lax') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #9', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #9', showRestoreCode=False)

# [(+Spd, -Atk) Timid] - Value #0xA
AddCheat('(+Spd, -Atk) Timid') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xa', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xa', showRestoreCode=False)

# [(+Spd, -Def) Hasty] - Value #0xB
AddCheat('(+Spd, -Def) Hasty') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xb', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xb', showRestoreCode=False)

# [(None) Serious] - Value #0xC
AddCheat('(None) Serious') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xc', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xc', showRestoreCode=False)

# [(+Spd, -SAtk) Jolly] - Value #0xD
AddCheat('(+Spd, -SAtk) Jolly') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xd', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xd', showRestoreCode=False)

# [(+Spd, -SDef) Naive] - Value #0xE
AddCheat('(+Spd, -SDef) Naive') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xe', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xe', showRestoreCode=False)

# [(+SAtk, -Atk) Modest] - Value #0xF
AddCheat('(+SAtk, -Atk) Modest') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0xf', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0xf', showRestoreCode=False)

# [(+SAtk, -Def) Mild] - Value #0x10
AddCheat('(+SAtk, -Def) Mild') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x10', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x10', showRestoreCode=False)

# [(+SAtk, -Spd) Quiet] - Value #0x11
AddCheat('(+SAtk, -Spd) Quiet') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x11', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x11', showRestoreCode=False)

# [(None) Bashful] - Value #0x12
AddCheat('(None) Bashful') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x12', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x12', showRestoreCode=False)

# [(+SAtk, -SDef) Rash] - Value #0x13
AddCheat('(+SAtk, -SDef) Rash') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x13', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x13', showRestoreCode=False)

# [(+SDef, -Atk) Calm] - Value #0x14
AddCheat('(+SDef, -Atk) Calm') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x14', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x14', showRestoreCode=False)

# [(+SDef, -Def) Gentle] - Value #0x15
AddCheat('(+SDef, -Def) Gentle') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x15', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x15', showRestoreCode=False)

# [(+SDef, -Spd) Sassy] - Value #0x16
AddCheat('(+SDef, -Spd) Sassy') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x16', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x16', showRestoreCode=False)

# [(+SDef, -SAtk) Careful] - Value #0x17
AddCheat('(+SDef, -SAtk) Careful') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x17', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x17', showRestoreCode=False)

# [(None) Quirky] - Value #0x18
AddCheat('(None) Quirky') # ldrh w1, [sp, #0x44], ldrh w1, [sp, #0x46]
cheatAddr1 = AOB('E1 8B 40 79')
cheatAddr2 = AOB('E1 8F 40 79')
Hack(cheatAddr1, 'mov w1, #0x18', showRestoreCode=False)
Hack(cheatAddr2, 'mov w1, #0x18', showRestoreCode=False)
EndSection('Spawn Modifiers')

AddSection('Battle Codes')
AddCheat('Max/Infinite Mega Energy') # str s1, [x19, #0x1a8]
cheatAddr = AOB('61 AA 01 BD')
CodeCave(cheatAddr,(
    'ldr s1, {end}-4',
    'str s1, [x19, #0x1a8]',
    'B {back}',
    Float2DWord(100.0),
),
use_BL=False)

AddCheat('Exp Multiplier x4') # fmov s2, #2.0
cheatAddr = AOB('00 10 20 1E 60 10 00 1F')
Hack(cheatAddr, 'fmov s0, #4.0')

AddCheat('Exp Multiplier x17') # fmov s2, #2.0
cheatAddr = AOB('00 10 20 1E 60 10 00 1F')
Hack(cheatAddr, 'fmov s0, #17.0', showRestoreCode=False)

AddCheat('No Move cooldown') # fmaxnm v0.4s, v0.4s, v1.4s
cheatAddr = AOB('00 C4 21 4E')
Hack(cheatAddr, 'movi v0.2d, #0')

AddCheat('100% Catch Rate') # and w8, w0, #0xff
cheatAddr = AOB('08 1C 00 12 1F 05 00 71 21 01 00 54')
Hack(cheatAddr, 'mov w8, #1')

AddCheat('Player doesnt Blackout') # cbnz x0, #0x14
cheatAddr = AOB('A0 00 00 B5 94 22 00 91 9F 02 15 EB 41 FE FF 54 ? ? ? ? 57 00 00 B4')
Hack(cheatAddr, 'cbz x0, #0x14')
EndSection('Battle Codes')
################################# END #######################################

HackComplete()

These are the support scripts from Eiffel to use it modified since he dropped it years ago.
Python:
# This script was made by Eiffel2018, updated and modified for new ida and features by OblivionReign
import idc, ida_bytes, ida_search, struct, idautils, sys, ida_kernwin, ida_funcs, idaapi, ida_segment, math, os, ida_nalt, re
from idahelper import *
from keystone import *

SetDebug(True)
cheatCodes = masterCodes = restoreCodes = ''
english=''
is32bit=False
TID=BID=VER = RGN = None
TM='A'
TM2='F'

dataAddr = BADADDR if isGDB() else ida_segment.get_segm_by_name('.bss').end_ea
            
def SetAsmRegister(register):
    global TM
    TM = register
def SetPtrRegister(register):
    global TM2
    TM2 = register

def Addr2DWord(opAddr):
    return "{:08X}".format(opAddr & 0xFFFFFFFF)
def Value2DWord(value):
    if type(value) is str: value=int(value.replace(' ',''), 16)
    return "{:08X}".format(value & 0xFFFFFFFF)
def Value2QWord(value):
    if type(value) is str: value=int(value.replace(' ',''), 16)
    return "{:08X} {:08X}".format(value // 0x100000000, value & 0xFFFFFFFF)
def Double2QWord(d):
    return Value2QWord(struct.unpack('<Q', struct.pack('<d', d))[0])
def Float2DWord(f):
    return Value2DWord(struct.unpack('<I', struct.pack('<f', f))[0])
def Char2DwordList(s):
    i=0
    result=[]
    while i<len(s):
        result.append(int(''.join('%02X'%ord(x) for x in reversed(s[i:i+4])),16))
        i+=4
    return result
def Char2QwordList(s):
    i=0
    result=[]
    while i<len(s):
        result.append(int(''.join('%02X'%ord(x) for x in reversed(s[i:i+8])),16))
        i+=8
    return result
def CheatCode(length,opAddr,value):
    if opAddr>base and base>0x10000000: opAddr-=base
    if type(value) not in (list,tuple):
        if type(value) is str and re.match(r"^[0-9a-fA-F]{8}$", value[0:8]) is None: value=ASM(value)
        # if type(value) is int and length==4: value=Value2DWord(value)
        return '0{}0A0000 {} {}\n'.format(length,Addr2DWord(opAddr),Value2DWord(value) if length<=4 else Value2QWord(value))
    lastInstruction = ResultCode = ''
    for instruction in value:
        if type(instruction) is str: instruction=instruction.replace('{there}',OperandAddr(opAddr)).replace('{here}',hex(opAddr))
        if type(instruction) is str and re.match(r"^[0-9a-fA-F]{8}$", instruction[0:8]) is None: instruction=ASM(instruction)
        if type(instruction) is int: instruction=Value2DWord(instruction)
        if lastInstruction=='':
            lastInstruction = instruction
        else:
            ResultCode += CheatCode(8,opAddr-4,instruction+lastInstruction)
            lastInstruction = ''
        opAddr+=4
    if (lastInstruction != ''): ResultCode += CheatCode(4,opAddr-4,lastInstruction)
    return ResultCode
def RestoreCode(length,opAddr):
    if isGDB(): return ''
    if length>=8: return CheatCode(length,opAddr,[ 0 if (opAddr+i>=GetCodeK() and opAddr+i<codeEnd) else (ida_bytes.get_dword(opAddr+i)) for i in range(0,length,4) ]) # IDA 9.2 Update
    return CheatCode(length,opAddr,0 if (opAddr>=GetCodeK() and opAddr<codeEnd) else (GetBytes(length,opAddr) if length<=4 else GetQword(opAddr)))
    
def PointerCodeHeader(offsets,register=None,length=8): # offsets use tuples/list with at least 2 element
    if isGDB(): return ''
    if register == None: register = TM2
    if type(offsets) not in (tuple, list): offsets=[offsets]
    code = '5{}0{}0000 {:08X}\n'.format(length,register,offsets[0])
    if len(offsets)>1: code += PointerCodeAddOffset(offsets[1:],register)
    return code
def PointerCodeReadOffset(offset,register=None,length=8):
    return PointerCodeAddOffset(offset,register,length)
def PointerCodeAddOffset(offsets,register=None,length=8):
    if isGDB(): return ''
    if register == None: register = TM2
    if type(offsets) not in (tuple, list): offsets=[offsets]
    if len(offsets)<1: return ''
    code=''
    if len(offsets)>1:
        for offset in offsets[:-1]:
            code += '5{}0{}1000 {:08X}\n'.format(8,register,offset)
    code += '5{}0{}1000 {:08X}\n'.format(length,register,offsets[-1])
    return code
def PointerCodeAddRegister(offset,register=None):
    if isGDB(): return ''
    return '780{}0000 {:08X}\n'.format(register,offset) if offset>=0 else '780{}1000 {:08X}\n'.format(register,-offset)
def PointerCodeSetValue(value,register='D',length=8):
    if isGDB(): return ''
    return '4{}0{}0000 {}\n'.format(length,register,Value2QWord(value))
def PointerCodeWrite(length, value, value2=None, register=None, use_D=True, increase=False):
    if use_D==True: use_D='D'
    if isGDB(): return ''
    if register == None: register = TM2
    if value2!=None and length==8:
        code = '6{}0{}{}{}0 {} {}\n'.format(length, register,'1' if increase else '0','1'+use_D if use_D!=False else '00',Value2DWord(value2), Value2DWord(value))
    else:
        code = '6{}0{}{}{}0 {}\n'.format(length, register,'1' if increase else '0', '1'+use_D if use_D!=False else '00', Value2QWord(value))
    return code
def PointerCodeBody(offset, length, value, value2=None, register=None):
    if isGDB(): return ''
    if register == None: register = TM2
    return PointerCodeSetValue(offset) + PointerCodeWrite(length, value, value2, register)
def PointerCodeArithmetic(operater,r0=None,r1=None,r2=None,length=8): # Code Type 0x9
    if isGDB(): return ''
    if r0 == None: r0 = TM2
    if r1 == None: r1 = TM2
    operations = {'+':'0', '-':'1', '*':'2', '<<':'3', '>>':'4', 'and':'5', 'or':'6', 'not':'7', 'xor':'8', 'mov':'9'}
    if r2==None or type(r2) is str: # 9TCRS0s0
        if r2==None: r2='0'
        result = '9{}{}{}{}0{}0\n'.format(length,operations[operater.lower()],r0,r1,r2)
    else: # 9TCRS100 VVVVVVVV
        result = '9{}{}{}{}100 {}\n'.format(length,operations[operater.lower()],r0,r1, Value2DWord(r2) if length<8 else Value2QWord(r2))
    return result
def PointerCodeStoreRegisterValueToRegisterAddress(valueRegister='D', addrRegister=None, length=4, offset=0, increase=False): # Code Type 0xA  A4SR1000
    if isGDB(): return ''
    if addrRegister == None: addrRegister = TM2
    if offset==0:
        return 'A{}{}{}{}000\n'.format(length,valueRegister, addrRegister, 1 if increase else 0)
    elif type(offset) is str:
        return 'A{}{}{}{}1{}0\n'.format(length,valueRegister, addrRegister, 1 if increase else 0, offset)
    else:
        return 'A{}{}{}{}200 {}\n'.format(length,valueRegister, addrRegister, 1 if increase else 0, Value2DWord(offset)) # seem buggy
def PointerCodeStoreRegisterValueToMemoryAddress(valueRegister=None, addr='B', length=4, offset=None, increase=False): # Code Type 0xA
    if isGDB(): return ''
    if valueRegister == None: valueRegister = TM2
    if type(addr) is str and offset==None:
        return 'A{}{}{}{}300\n'.format(length, valueRegister, addr, 1 if increase else 0)
    elif type(addr) is not str:
        return 'A{}{}0{}400 {:08X}\n'.format(length, valueRegister, 1 if increase else 0, addr)
    else:
        return 'A{}{}{}{}500 {:08X}\n'.format(length, valueRegister, addr, 1 if increase else 0, offset)
def PointerCodeCopyRegister(dest, source):
    if isGDB(): return ''
    return PointerCodeArithmetic('mov', dest, source)
def PointerCodeCondition(register,condition,value,length=4):
    if isGDB(): return ''
    Conditions={'>':'1', '>=':'2', '<':'3', '<=':'4', '==':'5', '=':'5', '!=':'6'}
    if type(value) is str and len(value)==1:
        return 'C0{}{}{}5{}0\n'.format(length,Conditions[condition],register,value)
    else:
        return 'C0{}{}{}400 {}\n'.format(length,Conditions[condition],register,Value2DWord(value) if length<8 else Value2QWord(value))
def PointerCodeEndBlock():
    if isGDB(): return ''
    return '20000000\n'
def PointerCodeElseBlock():
    if isGDB(): return ''
    return '21000000\n'
def PointerCodeStartLoop(size,register='C'):
    if isGDB(): return ''
    return '300{}0000 {:08X}\n'.format(register,size)
def PointerCodeEndLoop(register='C'):
    if isGDB(): return ''
    return '310{}0000\n'.format(register)
def PointerHack(offsets,values,length=4,useButton=None,default=None,appendCodes=None):
    if isGDB(): return ''
    codes=PointerCodeHeader(offsets[:-1])
    if offsets[-1]>0: codes+=PointerCodeAddRegister(offsets[-1])
    if type(values) not in (tuple, list): values=[values]
    finalCode=''
    useCombine=length==4 and len(values)>=2
    if useCombine:
        idx=0
        while idx+1<len(values):
            finalCode+=PointerCodeWrite(8,values[idx],values[idx+1],use_D=False,increase=True)
            idx+=2
        if idx<len(values):
            finalCode+=PointerCodeWrite(4,values[idx],use_D=False,increase=True)
    else:
        for value in values:
            finalCode+=PointerCodeWrite(length,value,use_D=False,increase=True)
    if appendCodes!=None: finalCode+=appendCodes
    defaultCode = '' if default==None else PointerCodeWrite(length,default,use_D=False)
    if useButton != None: finalCode= defaultCode + ButtonCode(useButton,finalCode)
    AddCheatCode(codes+finalCode)
def PointerCopyValue(dest,source,length=4):
    common = []
    for idx in range(len(source)):
        if source[idx]!=dest[idx]: break
        common.append(source[idx])
    if len(common)==0:
        codes = PointerCodeHeader(source[:-1],'F')
        codes += PointerCodeHeader(dest[:-1],'A')
    else:
        codes = PointerCodeHeader(common,'F')
        codes += PointerCodeCopyRegister('A','F')
        codes += PointerCodeAddOffset(source[len(common):-1],'F')
        codes += PointerCodeAddOffset(dest[len(common):-1],'A')
    if length<=8:
        codes += PointerCodeReadOffset(source[-1],'F',length)
        codes += PointerCodeStoreRegisterValueToRegisterAddress('F', 'A', length, dest[-1])
    else:
        codes += PointerCodeCopyRegister('B','F')
        sourceoffset=source[-1]
        while length>0:
            codes += PointerCodeReadOffset(sourceoffset,'F',length if length<8 else 8)
            codes += PointerCodeStoreRegisterValueToRegisterAddress('F', 'A', length if length<8 else 8, dest[-1], increase=True)
            sourceoffset+=8
            length-=8
            if length>0: codes += PointerCodeCopyRegister('F','B')
    AddCheatCode(codes)
def PointerFillRange(basePointer, maxSize, value, length=4, condition=None, conditionValue=None):
    codes = PointerCodeHeader(basePointer[:-1],'F')
    if basePointer[-1]!=0: codes += PointerCodeAddRegister(basePointer[-1],'F')
    codes += PointerCodeStartLoop(maxSize)
    if condition!=None and conditionValue!=None:
        codes += PointerCodeCopyRegister('B','F')
        codes += PointerCodeReadOffset(0,'B',length)
        codes += PointerCodeCondition('B',condition,conditionValue,length)
    codes += PointerCodeWrite(length, value, None, 'F', use_D=False, increase=True)
    if condition!=None and conditionValue!=None:
        codes += PointerCodeElseBlock()
        codes += PointerCodeAddRegister(0x8,'F')
        codes += PointerCodeEndBlock()
    codes += PointerCodeEndLoop()
    AddCheatCode(codes)
def PointerFillArray(basePointer, maxSize, finalOffset, value, length=4, check=False, condition=None, conditionValue=None):
    codes = PointerCodeHeader(basePointer,'F')
    codes += PointerCodeAddRegister(0x18,'F')
    codes += PointerCodeSetValue(finalOffset,'D')
    if check:
        codes += PointerCodeCopyRegister('A','F')
        codes += PointerCodeReadOffset(0,'A',2)
    codes += PointerCodeStartLoop(maxSize)
    codes += PointerCodeAddRegister(0x8,'F')
    if check:
        codes += PointerCodeCondition('A','>',0,2)
        codes += PointerCodeArithmetic('-','A','A',1,2)
    if condition!=None and conditionValue!=None:
        codes += PointerCodeCopyRegister('B','F')
        codes += PointerCodeReadOffset(finalOffset,'B',length)
        codes += PointerCodeCondition('B',condition,conditionValue,length)
    codes += PointerCodeCopyRegister('B','F')
    codes += PointerCodeAddOffset([0],'B')
    codes += PointerCodeWrite(length, value, None, 'B')
    if condition!=None and conditionValue!=None:
        codes += PointerCodeEndBlock()
    if check:
        codes += PointerCodeEndBlock()
    codes += PointerCodeEndLoop()
    AddCheatCode(codes)
def ButtonCode(key,code=None,elseCode=None): # note: the ElseCode is not supported by Yuzu currently
    if isGDB(): return ''
    if type(key) in (tuple, list): key=MixButtons(key)
    keymap={'a':0x1,'b':0x2,'x':0x4,'y':0x8,'l3':0x10,'r3':0x20,'l':0x40,'r':0x80,'zl':0x100,'zr':0x200,'+':0x400,'-':0x800,'left':0x1000,'up':0x2000,'right':0x4000,'down':0x8000,'l3left':0x10000,'l3up':0x20000,'l3right':0x40000,'l3down':0x80000,'r3left':0x100000,'r3up':0x200000,'r3right':0x400000,'r3down':0x800000,'sl':0x1000000,'sr':0x2000000}
    if isinstance(key, str) and key.lower() in keymap: key=keymap[key.lower()]
    key=key & 0xFFFFFFF
    return '8{:07X}\n{}\n{}20000000\n'.format(key,code.strip('\n '),'' if elseCode==None else '21000000\n%s\n'%(elseCode.strip('\n '))) if code != None else '8%07X\n'%key
def MixButtons(keys):
    if isGDB(): return ''
    result=0
    for key in keys:
        result=result|int(ButtonCode(key),16)
    return result
def ConditionCode(length,opAddr,value,commands,otherwise=None):
    if isGDB(): return ''
    if type(value) is str and re.match(r"^[0-9a-fA-F]{8}$", value[0:8]) is None: value=ASM(value)
    result = '1%d050000 %s %s\n%s'%(length,Addr2DWord(opAddr),Value2DWord(value) if length<=4 else Value2QWord(value),commands)
    if otherwise != None: result += '21000000\n%s'%(otherwise)
    result += '20000000\n'
    return result
def ToggleCode(button,length,opAddr,code1,code2=None):
    if isGDB(): return ''
    if code2==None: code2=RestoreCode(length,opAddr)
    return ButtonCode(button,ConditionCode(length,opAddr,code2,CheatCode(length,opAddr,code1),CheatCode(length,opAddr,code2)))
def ASM(asm_code):
    # IDA 9.2 Update: Corrected Keystone mode parameter
    ks = Ks(KS_ARCH_ARM if is32bit else KS_ARCH_ARM64, KS_MODE_ARM if is32bit else KS_MODE_LITTLE_ENDIAN)
    try:
        bytecode, cnt = ks.asm(asm_code, as_bytes=True)
    except:
        idaapi.warning("Error in code: %s"%asm_code)
        bytecode=b'FFFFFFFF'
    if bytecode is None:
        idaapi.warning("Error in code: %s"%asm_code);
        return '????????'
    return ''.join(map('{:02X}'.format, reversed(bytecode)))
def isEMU():
    return isEMU;
def OperandAddr(addr):  # return something like "B.NE 0x12345678" become "B 0x12345678"
    if not isCode(addr): return '__ERROR__'
    # IDA 9.2 Update
    import ida_ua
    cmd = ida_ua.insn_t()
    if ida_ua.decode_insn(cmd, addr) == 0:
        return '__ERROR__'
    mnem = ida_ua.print_insn_mnem(addr).upper()
    
    operand_index = 1
    if mnem in ('B', 'BL', 'B.CC', 'B.HI', 'B.GE', 'B.LE', 'B.EQ', 'B.NE', 'CBNZ', 'CBZ'):
        operand_index = 0
    elif mnem in ('TBZ', 'TBNZ'):
        operand_index = 2
    target_addr = idc.get_operand_value(addr, operand_index)
    return hex(target_addr - addr)
def Hack(pattern,codes,showRestoreCode=True,useButton=None,elseCode=None,returnCode=False,searchStart=codeStart,searchEnd=codeEnd):
    if isGDB(): return
    global cheatCodes, restoreCodes, masterCodes
    output=''
    cheatAddr=AOB(pattern,searchStart,searchEnd) if type(pattern) is str else pattern
    if notFound(cheatAddr):
        idaapi.warning(cheatName+': AOB broken!\n%s'%(pattern if type(pattern) is str else hex(pattern)))
    else:
        if type(codes) is str and re.match(r"^[0-9a-fA-F]{8} $", codes[0:9]) is not None: codes=list(reversed(codes.split(' ')))
        if type(codes) is str or type(codes) is int: codes=[codes]
        length = len(codes)*4
        if showRestoreCode=='masterCodes':
            masterCodes += RestoreCode(length,cheatAddr)
        elif showRestoreCode and useButton==None:
            restoreCodes += RestoreCode(length,cheatAddr)
        output += CheatCode(length, cheatAddr, codes)
        if useButton != None:
            output=(RestoreCode(length,cheatAddr) if showRestoreCode and showRestoreCode!='masterCodes' else '') + ButtonCode(useButton,output,elseCode)
        if not returnCode: cheatCodes += output
    return output
def HackAll(pattern,codes,offset=0,showRestoreCode=True,useButton=None,elseCode=None,searchStart=codeStart,searchEnd=codeEnd,returnCode=False):
    if isGDB(): return
    global cheatCodes
    output=''
    cheatAddrs=AllOccur(pattern,offset,searchStart,searchEnd)
    if len(cheatAddrs)<1:
        idaapi.warning(cheatName+': AOB broken!')
    else:
        if useButton != None and showRestoreCode and elseCode == None:
            for cheatAddr in cheatAddrs: output += RestoreCode(len(codes)*4,cheatAddr)
        if useButton != None: output += ButtonCode(useButton) # Note: EMU cheat-vm does not support button activator on ASM codes
        for cheatAddr in cheatAddrs: output += Hack(cheatAddr, codes, useButton == None and showRestoreCode and elseCode == None, None, returnCode=True)
        if useButton != None and elseCode!=None: output += '21000000\n%s\n'%(elseCode.strip('\n '))
        if useButton != None: output += '20000000\n'
        if not returnCode: cheatCodes += output
    return output
def CodeFunc(codes,retAddr=None,targetAddr=None):
    global codeK
    if isGDB(): return
    ResultCode=lastInstruction=''
    end=GetCodeK()
    if type(codes) is str: idaapi.warning("Cannot be type of string: %s"%codes); return
    for instruction in reversed(codes):
        if type(instruction) is str: instruction = instruction.strip()
        if not instruction: continue
        codeK-=4
        if type(instruction) is int: instruction='%08X'%instruction
        
        instruction=instruction.replace('{here}',hex(codeK)).replace('{end}',hex(end-codeK)).replace('{start}',hex(end-len(codes)*4-codeK))
        
        if retAddr!=None: instruction=instruction.replace('{back}',hex(retAddr-codeK))
            
        if targetAddr!=None: instruction=instruction.replace('{there}',hex(targetAddr-codeK))
        
        if re.match(r"^[0-9a-fA-F]{8}$", instruction[0:8]) is None: instruction=ASM(instruction)
        
        if lastInstruction=='':
            lastInstruction = instruction
        else:
            ResultCode += CheatCode(8,codeK,(lastInstruction)+(instruction))
            lastInstruction = ''
            
    if (lastInstruction != ''): ResultCode += CheatCode(4,codeK,(lastInstruction))
    return ResultCode
def CodeCave(cheatAddr, codes, showRestoreCode=True, use_BL=True, returnCode=False, data_size=0):
    if isGDB(): return ''
    global cheatCodes, masterCodes, restoreCodes, codeK
    output = CodeFunc(codes, cheatAddr + 4, idc.get_operand_value(cheatAddr, 0)) or ''
    asm_start_addr = GetCodeK() # GetCodeK() now holds the start of the instructions
    
    if not output:
        idaapi.warning(cheatName+': CodeCave assembly failed!')
        return ''
        
    if showRestoreCode=="masterCodes":
        masterCodes += RestoreCode(4,cheatAddr)
    elif showRestoreCode:
        restoreCodes += RestoreCode(4,cheatAddr)
        
    hook_jump = ('BL ' if use_BL else 'B ') + hex(asm_start_addr - cheatAddr)
    output += Hack(cheatAddr, hook_jump, False, None, returnCode=True)

    if not returnCode: cheatCodes += output
    return output
def GetCodeK():
    if isGDB(): return BADADDR
    return codeK
def SetCodeK(addr):
    if isGDB(): return
    global codeK
    codeK=addr
def RegCodeK(size=4):
    if isGDB(): return BADADDR
    global codeK
    codeK-=size
    return codeK
def RegData(assignValue,size=4): # Reverted to simple data registration
    if isGDB(): return ''
    if type(assignValue) in (tuple, list): size=size*len(assignValue)
    return CheatCode(size,RegCodeK(size),assignValue)

def DefineWriteableAddress(size=4):
    if isGDB(): return BADADDR
    global dataAddr
    dataAddr-=size
    return dataAddr
def Either(aob1,aob2):
    if isGDB(): return
    if type(aob1) is str: aob1=AOB(aob1)
    if type(aob2) is str: aob2=AOB(aob2)
    return aob1 if isFound(aob1) else aob2
def GetADRP(addr):
    if notFound(addr): return BADADDR
    # IDA 9.2 Update
    register = idc.get_op_text(addr,1)[1:4].replace(',','')
    baseAddr = SearchPrevASM(addr,'ADRP',register)
    return idc.get_operand_value(baseAddr,1)+idc.get_operand_value(addr,1)
def WriteFile(filepath,content):
    folder = os.path.dirname(filepath)
    if not os.path.exists(folder): os.makedirs(folder)
    with open(filepath, "w", encoding='utf-8') as out:
        out.write(content)

def GetTID():
    global TID
    if isGDB(): return None
    if TID is None:
        TIDs = re.findall(r"[0-9a-fA-F]{16}", os.path.basename(idc.get_idb_path()).replace('800 ','000 ').replace('800]','000]'))
        TID = TIDs[0] if len(TIDs)>0 else None
    return TID
def GetBID(length=8):
    global BID
    if isGDB(): return None
    if BID is None:
        gnu=AOB("00 00 00 47 4E 55 00",dataStart,dataEnd)
        # IDA 9.2 Update
        BID = ''.join('%02X'%ida_bytes.get_byte(gnu+7+i) for i in range(length)) if isFound(gnu) else None
    return BID
def SetBID(bid):
    global BID
    BID = bid
def SetTID(tid):
    global TID
    TID = tid
def SetVersion(ver):
    global VER
    VER = ver
def GetVersion():
    global VER
    if VER == None:
        try:
            VERs = re.findall('v\d[\d\.a-z]*',os.path.basename(idc.get_idb_path()))
            VER=VERs[0] if len(VERs)>0 else None
        except IndexError:
            VER = None
    return VER
    
def GetRegion():
    global RGN
    if RGN == None:
        try:
            RGNs = re.findall('[\[\(](US|GB|JP|AU|HK|PL|CN|TW|FR|KR|NL|NO|NZ|PE|PT|RU|SE|ZA|CZ|DE|DK|ES|FI|GR|HU|IT|MX|AR|AT|BE|CA|CL|CO)[\]\)]',os.path.basename(idc.get_idb_path()))
            RGN = RGNs[0] if len(RGNs)>0 else None
        except IndexError:
            RGN = None
    return RGN

def AddMasterCode(codes):
    if isGDB(): return
    global masterCodes
    masterCodes+=codes
def AddCheatCode(codes):
    if isGDB(): return
    global cheatCodes
    cheatCodes+=codes
def InsertCheatCode(line,codes):
    if isGDB(): return
    global cheatCodes
    cheatlines=cheatCodes.split('\n')
    cheatlines.insert(-line-1,codes[0:-1])
    cheatCodes='\n'.join(cheatlines)
def AddRestoreCode(codes):
    if isGDB(): return
    global restoreCodes
    restoreCodes+=codes
def AddCheat(nameEN,nameZH=None,newOption=0,isSuggest=False,showOption=True): # newOption=0(不是)/1(新)/2(接上)
    if isGDB(): return
    global cheatCnt, idx, cheatCodes, cheatName
    cheatName=nameEN if english or nameZH==None else nameZH
    if newOption<2:
        cheatCnt+=1
        idx=ord('a')
    else:
        idx+=1
    title = '№%2d. %s'%(cheatCnt,cheatName) if newOption==0 else '№%2d%s %s'%(cheatCnt,chr(idx) if showOption else '',cheatName)
    if isSuggest: title+=' ★'
    Show(title)
    cheatCodes += '\n[%s]\n'%title
    
def AddSection(nameEN,nameZH=None):
    if isGDB(): return
    global cheatCnt, idx, cheatCodes, cheatName
    cheatName=nameEN if english or nameZH==None else nameZH
    title = '--SectionStart:%s--'%(cheatName)
    Show(title)
    cheatCodes += '\n[%s]\n20000000\n'%title
    return
    
def EndSection(nameEN,nameZH=None):
    if isGDB(): return
    global cheatCnt, idx, cheatCodes, cheatName
    cheatName=nameEN if english or nameZH==None else nameZH
    title = '--SectionEnd:%s--'%(cheatName)
    Show(title)
    cheatCodes += '\n[%s]\n20000001\n'%title
    return 

def HackComplete():
    if isGDB(): return
    header = ("[%s %s TID=%s BID=%s]\n"%(gameName,VER,TID,BID))
    footer = ('[This set of cheats is created by All Credited, enjoy!]' if english else '[此套金手指由 OblivionReign 制作, 免費提供, 歡迎轉載, 敬請註明來源出處]')
    if isEMU:
        cheats=cheatCodes.replace('\r','').split('\n\n')
        if masterCodes!='':
            cheatfilename="# Master Code (include share functions)"
            cheat = '{%s}\n%s'%(cheatfilename,masterCodes.strip('\n '))
            cheats= [cheat]+cheats
        for i in range(len(cheats)):
            cheat=cheats[i]=cheats[i].strip('\n ')
            if cheat=='': continue
            cheatfilename=(cheat.split('\n'))[0].strip('{}[] ')
            path='%s\\%s for Yuzu\\%s\\cheats\\%s.txt'%(os.path.dirname(idc.get_idb_path()),TID,cheatfilename,BID)
            content = '%s\n'%cheat
            if codeK<ida_segment.get_segm_by_name('.bss').end_ea: WriteFile(path,content) # skip Yuzu if using sdk code cave
        path='%s\\%s for Ryujinx\\%s %s\\cheats\\%s.txt'%(os.path.dirname(idc.get_idb_path()),TID,gameName,VER,BID)
        content = '%s\n'%('\n\n'.join(cheats))
        WriteFile(path,content)
    else:
        if masterCodes != '':
            header += (('\n{%s}\n'%('Master Code (includes share functions)' if english else '關鍵碼 (含共用函式)'))+masterCodes)
        restoreCode = '' if restoreCodes=='' else '\n[%s]\n%s'%('Restore Code (Use after unchecking any cheats below)' if english else '還原碼 (當取消以下金手指時使用)', restoreCodes)
            
        path='%s\\%s\\%s\\cheats\\%s.txt'%(os.path.dirname(idc.get_idb_path()),gameName,TID,BID)
        content = '%s%s%s\n%s\n'%(header,restoreCode,cheatCodes,footer)
        WriteFile(path,content)
    cls()
    print('ApplyPatch(\'\'\'\n'+header+cheatCodes+'\'\'\')')

def MarkLabel(name,type='Class'):
    if isGDB():
        addr=ptr(eval(name),returnResult=True)
        if type=='Address':
            MarkOffset(addr)
        elif type=='Class':
            MarkOffset(addr)
            ApplyStruct(GetQword(addr), 'ObjHeader') # Ungine only
        elif type=='Float':
            MarkFloat(addr,4)
        elif type=='Long':
            MarkBytes(addr,8)
        elif type=='DWord':
            MarkBytes(addr,4)
        elif type=='Word':
            MarkBytes(addr,2)
        elif type=='Byte':
            MarkBytes(addr,1)
        elif type=='Bits':
            MarkBytes(addr,1)
        Patch(GetQword(addr) if type in ('Class','Address') else addr,name)
            
def Init(enName,zhName=None,EMU=None, is64bit=True):
    if isGDB(): return
    cls()
    global isEMU, english, TID, BID, VER, RGN, gameName, cheatCnt, cheatCodes, masterCodes, restoreCodes, is32bit

    isNRO = '.nro.' in os.path.basename(idc.get_idb_path())

    TID = GetTID()
    if TID==None and not isNRO: TID=ida_kernwin.ask_str('', 11, "Please enter TID")
    
    BID = GetBID()
    if BID==None and not isNRO: BID=ida_kernwin.ask_str('', 11, "Please enter BID")

    VER = GetVersion()
    if VER==None and not isNRO: VER = ida_kernwin.ask_str('v0', 12, "Please enter VER")
    
    RGN = GetRegion()
    # if RGN==None: RGN = ida_kernwin.ask_str('US', 13, "Please enter Region")

    isEMU = ida_kernwin.ask_yn(False, 'HIDECANCEL\nUse RyujinX / Yuzu?') if EMU == None else EMU
    
    english = True if isEMU or zhName==None else ida_kernwin.ask_yn(True, 'HIDECANCEL\nUse english?')

    gameName= (enName if english else zhName) + ('' if RGN==None else ' (%s)'%RGN)

    cheatCnt=0
    cheatCodes = masterCodes = restoreCodes = ''
    SetCodeK(GetCodeEnd())
    is32bit = not is64bit
    
def FpsCode(methods,SDK_FPS_Addr=None):
    if type(methods) not in (tuple, list): methods=[methods]
    cheatAddr1 = cheatAddr1b = cheatAddr1c = cheatAddr2 = cheatAddr3 = cheatAddr4 = cheatAddr5 = cheatAddr6 = cheatAddr7 = cheatAddr8 = BADADDR
    if 1 in methods:
        cheatAddr1=AOB('? ? ? 97 F4 00 00 34 68 3A 42 B9')
        cheatAddr1b=Either('00 01 62 1E C8 09 E8 D2','00 03 62 1E 01 01 67 9E')
        cheatAddr1c=Either('00 D8 61 5E 0A 18 61 1E','20 01 62 1E C9 09 E8 D2 21 01 67 9E 0A 18 61 1E')
    if 2 in methods and SDK_FPS_Addr != None:
        nnmusl_init_dso=AOB('? ? ? 94 80 ? ? B9 88 ? ? B9') #i.e. ida_segment.get_segm_by_name('.got.plt').start_ea + 0x18
        cheatAddr2=GetADRP(idc.get_operand_value(nnmusl_init_dso,0)+4) if isFound(nnmusl_init_dso) else ida_segment.get_segm_by_name('.got.plt').start_ea + 0x18
        # SDK_FPS_Addr = 0x7a66c # find in sdk: p( AOB("AB 26 4F B9") - get_name_ea(0,'__nnmusl_init_dso') )
    if 3 in methods:
        targetAddrs = AllOccur('88 01 00 34 ? ? ? 94 ? ? ? 94 ? ? ? ? 08 ? ? F9 08 01 40 B9 1F 01 00 6B E8 07 9F 1A 60 7A 68 BC ? ? ? ? ? ? ? ? C0 03 5F D6 E8 03 1F AA 60 7A 68 BC ? ? ? ? ? ? ? ? C0 03 5F D6')
        cheatAddr3= GetADRP(SearchPrevASM(targetAddrs[1], 'LDR', 'X19', limit=0x40)) if len(targetAddrs)==2 else BADADDR
    if 4 in methods:
        temp=AOB('08 ? ? F9 01 01 40 F9 ? ? ? ? 08 ? ? F9 08 01 40 F9 A0 23 03 D1 00 01 3F D6 ? ? ? ? ? 02 40 B9 A0 23 03 D1 08 ? ? F9 08 01 40 F9 00 01 3F D6')  # unity
        if isFound(temp):
            cheatAddr4=[GetQword(GetADRP(temp))]
        else:
            # temp=AOB('08 ? ? F9 01 01 40 F9 ? ? ? ? 08 ? ? F9 08 01 40 F9 A0 ? ? D1 00 01 3F D6 ? ? ? ? ? 02 40 B9  08 ? ? F9 08 01 40 F9 A0 ? ? D1 00 01 3F D6 ? ? ? ? 81 02 40 B9 08 ? ? F9 08 01 40 F9 A0 ? ? D1 00 01 3F D6')  # old version unity
            temp=AOB('08 ? ? F9 01 01 40 F9 ? ? ? ? 08 ? ? F9 08 01 40 F9 A0 ? ? D1 00 01 3F D6 ? ? ? ? ? 02 40 B9 A0 ? ? D1 08 ? ? F9 08 01 40 F9 00 01 3F D6')  # old version unity
            if isFound(temp): cheatAddr4=[GetQword(GetADRP(temp))]
    if 5 in methods:
        temp=AOB('1A ? ? F9 28 03 40 39')
        if isFound(temp):
            cheatAddr5=GetADRP(temp)
    if 8 in methods:
        temp=AOB('? ? ? ? ? ? ? 91 09 09 80 B9 C9 02 00 34 08 01 40 F9 0A 05 80 52')
        if isFound(temp):
            cheatAddr8=GetADRL(temp)
    if 6 in methods: # search sysFps::m_flipSync
        cheatAddr6=AOB('F3 03 00 2A ? ? ? 97 ? ? ? ? 08 ? ? F9')
    if 7 in methods and SDK_FPS_Addr != None:
        cheatAddr7=SDK_FPS_Addr

    AddCheat('60 FPS',None,1)
    if isFound(cheatAddr1):
        Hack(cheatAddr1,'MOV W0, #1', False)
        Hack(cheatAddr1b,'FMOV D0, #1.0', False)
        Hack(cheatAddr1c,'FMOV D0, #1.0', False)
    if isFound(cheatAddr2):
        AddCheatCode(PointerCodeHeader((cheatAddr2)))
        AddCheatCode(PointerCodeAddRegister(SDK_FPS_Addr))
        AddCheatCode(PointerCodeWrite(4,ASM('MOV W11, #1'),use_D=False))
    if isFound(cheatAddr3):
        AddCheatCode(PointerCodeHeader((cheatAddr3)))
        AddCheatCode(PointerCodeWrite(8,Float2DWord(60),Float2DWord(60),use_D=False))
    if isFound(cheatAddr4):
        AddCheatCode(PointerCodeHeader(cheatAddr4))
        AddCheatCode(PointerCodeAddRegister(0xF14))
        AddCheatCode(PointerCodeWrite(4,1,use_D=False))
    if isFound(cheatAddr5):
        AddCheatCode(PointerCodeHeader((cheatAddr5)))
        AddCheatCode(PointerCodeWrite(8, 1, 1, use_D=False))
    if isFound(cheatAddr8):
        AddCheatCode(PointerCodeHeader((cheatAddr8)))
        AddCheatCode(PointerCodeAddRegister(0x1F24))
        AddCheatCode(PointerCodeWrite(4, 1, use_D=False))
    if isFound(cheatAddr6):
        Hack('62 6A 68 B8 08 26 86 52', 'MOV W2, #1', False)
        Hack(cheatAddr6, 'MOV W0, #1', False)
        Hack(GetQword(GetADRP(cheatAddr6+12)), 1, False)
    if isFound(cheatAddr7):
        Hack(SDK_FPS_Addr,'MOV W11, #1', False)
        
    AddCheat('30 FPS',None,2)
    if isFound(cheatAddr1):
        Hack(cheatAddr1,'MOV W0, #2', False)
        Hack(cheatAddr1b,'FMOV D0, #2.0', False)
        Hack(cheatAddr1c,'FMOV D0, #2.0', False)
    if isFound(cheatAddr2):
        AddCheatCode(PointerCodeHeader((cheatAddr2)))
        AddCheatCode(PointerCodeAddRegister(SDK_FPS_Addr))
        AddCheatCode(PointerCodeWrite(4,ASM('MOV W11, #2'),use_D=False))
    if isFound(cheatAddr3):
        AddCheatCode(PointerCodeHeader((cheatAddr3)))
        AddCheatCode(PointerCodeWrite(8,Float2DWord(30),Float2DWord(30),use_D=False))
        # FPS method 3 if fail
        # search 60 D2 4B BD  check something like LDR S0, [X21,X8,LSL#2] or LDR S8, [X21,X8,LSL#2]
    if isFound(cheatAddr4):
        AddCheatCode(PointerCodeHeader(cheatAddr4))
        AddCheatCode(PointerCodeAddRegister(0xF14))
        AddCheatCode(PointerCodeWrite(4,2,use_D=False))
    if isFound(cheatAddr5):
        AddCheatCode(PointerCodeHeader((cheatAddr5)))
        AddCheatCode(PointerCodeWrite(8, 2, 2, use_D=False))
    if isFound(cheatAddr8):
        AddCheatCode(PointerCodeHeader((cheatAddr8)))
        AddCheatCode(PointerCodeAddRegister(0x1F24))
        AddCheatCode(PointerCodeWrite(4, 2, use_D=False))
    if isFound(cheatAddr6):
        Hack('62 6A 68 B8 08 26 86 52', 'MOV W2, #2', False)
        Hack(cheatAddr6, 'MOV W0, #2', False)
        Hack(GetQword(GetADRP(cheatAddr6+12)), 2, False)
    if isFound(cheatAddr7):
        Hack(cheatAddr7,'MOV W11, #2', False)

Python:
# This script was made by Eiffel2018, updated and modified for new ida and features by OblivionReign
from ida_idaapi import BADADDR
import idc, ida_kernwin, ida_bytes, ida_search, idautils, ida_funcs, ida_offset, ida_segment, ida_auto, os, sys, ida_nalt, ida_lines, idaapi, re, typing, ida_range

def ClearCache(lib='idahelper'):
    loaded_package_modules = [key for key, value in sys.modules.items() if lib in str(value)]
    for key in loaded_package_modules: del sys.modules[key]

def isGDB():
    return os.path.dirname(ida_nalt.get_input_file_path()) == ''

if isGDB() and ida_kernwin.ask_yn(False, 'HIDECANCEL\nMark Regions?'):
    ClearCache('markRegions')
    from markRegions64 import markRegions


base=main= ida_segment.get_segm_by_name('main').start_ea if isGDB() else ida_segment.get_segm_by_name('.text').start_ea
codeStart = base+0x30
codeEnd = ida_segment.get_segm_by_name('main').end_ea if isGDB() else ida_segment.get_segm_by_name('.rodata').start_ea
dataStart = ida_segment.get_segm_by_name('main_data').start_ea if isGDB() else ida_segment.get_segm_by_name('.rodata').start_ea
dataEnd = ida_segment.get_segm_by_name('main_data').end_ea if isGDB() else ida_segment.get_segm_by_name('.bss').start_ea
mainEnd = ida_segment.get_segm_by_name('main_data').end_ea if isGDB() else ida_segment.get_segm_by_name('.bss').end_ea
def GetBase(): return base
def GetCodeStart(): return codeStart
def GetCodeEnd(): return codeEnd
def GetDataStart(): return dataStart
def GetDataEnd(): return dataEnd
def GetMainEnd(): return mainEnd

_UTF16start = _AsciiSTRstart = dataStart
_UTF16end = _AsciiSTRend = dataEnd

# --- API UPDATE: Use ida_kernwin.get_screen_ea() instead of the deprecated idc.ScreenEA() ---
s=ida_kernwin.get_screen_ea
j=ida_kernwin.jumpto

def g(name):
    ida_kernwin.jumpto(idc.get_name_ea(codeStart,name))

def p(x,returnResult=False):
    if x is None: return
    if type(x) in (tuple, list):
        result='[%s]'%(', '.join(map(lambda y:p(y,returnResult=True),x)))
    else:
        result='0:%X'%x if isinstance(x, int) else x
    if returnResult: return result
    print(result)

def a(): # print current address as [main+??????] used for GBD environment
    if not isGDB(): return
    heap=ida_segment.get_segm_by_name('heap').start_ea
    current_ea = s()
    if current_ea>heap and heap>base or current_ea<base:
        print('heap+%X'%(current_ea-heap))
    else:
        print('main+%X'%(current_ea-base))

def cls():
    ida_kernwin.activate_widget(ida_kernwin.find_widget("Output window"), True);
    ida_kernwin.process_ui_action("msglist:Clear");

def show(lines): print ("['"+ "', '".join( ' '.join(idc.GetDisasm(addr).split()) for addr in range(s(), s()+lines*4,4) ) + "']")

def r():
    MakeFunc(s())

def halt(msg):
    raise ImportError(msg)
def Debug(msg):
    if isDebug: print(msg)
def SetDebug(bool):
    global isDebug
    isDebug=bool
def Show(msg):
    if not isDebug: print(msg)
    ida_kernwin.replace_wait_box(msg)
    # time.sleep(0.00000001)
def isCode(targetAddr):
    targetAddr=targetAddr//4 * 4
    if not inCodeRange(targetAddr): return False
    if not ida_bytes.is_code(ida_bytes.get_full_flags(targetAddr)): ida_auto.auto_make_code(targetAddr); ida_auto.auto_wait_range(targetAddr,targetAddr+4)
    # return ida_bytes.is_code(ida_bytes.get_full_flags(targetAddr))
    return ida_bytes.is_code(ida_bytes.get_full_flags(targetAddr)) or ida_bytes.is_code(ida_bytes.get_full_flags(targetAddr-4))
def inCodeRange(targetAddr):
    return codeStart<=targetAddr<codeEnd
def inDataRange(targetAddr):
    return dataStart<=targetAddr<dataEnd
def inWriteableMemory(targetAddr):
    if isGDB(): return inDataRange(targetAddr)
    # return ida_segment.get_segm_by_name('.bss').start_ea <= targetAddr < ida_segment.get_segm_by_name('.bss').end_ea
    return ida_segment.get_segm_by_name('.bss').start_ea <= targetAddr < 0x80000000
def inHeapRange(targetAddr):
    if not isGDB(): return BADADDR
    return ida_segment.get_segm_by_name('heap').start_ea <= targetAddr < ida_segment.get_segm_by_name('heap').end_ea
def inAliasRange(targetAddr):
    if not isGDB(): return BADADDR
    return ida_segment.get_segm_by_name('alias').start_ea <= targetAddr < ida_segment.get_segm_by_name('alias').end_ea
def inStackRange(targetAddr):
    if not isGDB(): return BADADDR
    return ida_segment.get_segm_by_name('stack').start_ea <= targetAddr < ida_segment.get_segm_by_name('stack').end_ea
def isAddress(targetAddr):
    addr=GetQword(targetAddr)
    return addr%8==0 and 0x1000000000<addr<0xFF00000000 and (inAliasRange(addr) or inHeapRange(addr) or inCodeRange(addr) or inDataRange(addr) or inWriteableMemory(addr))
def SetUTFRange(a,b):
    global _UTF16start,_UTF16end
    (_UTF16start,_UTF16end) = (a,b)
def SetAsciiRange(a,b):
    global _AsciiSTRstart,_AsciiSTRend
    (_AsciiSTRstart,_AsciiSTRend) = (a,b)

def SearchUTF16(name):
    pattern='00 00 '+' '.join('{:02X}'.format(x) for x in name.encode('utf-16le'))+' 00 00'
    # API FIX: Use ida_bytes.find_bytes for high-level pattern searching.
    result = ida_bytes.find_bytes(_UTF16start, _UTF16end - _UTF16start, pattern, None, ida_bytes.BIN_SEARCH_FORWARD)
    return result+2 if isFound(result) else BADADDR

def SearchAscii(name):
    pattern='00 '+' '.join('{:02X}'.format(x) for x in name.encode('utf-8'))+' 00'
    # API FIX: Use ida_bytes.find_bytes for high-level pattern searching.
    result = ida_bytes.find_bytes(_AsciiSTRstart, _AsciiSTRend - _AsciiSTRstart, pattern, None, ida_bytes.BIN_SEARCH_FORWARD)
    return result+1 if isFound(result) else BADADDR

def SearchDataRef(targetAddr):
    dataSeg=ida_segment.get_segm_by_name('.data')
    pattern = '%X'%targetAddr
    # API FIX: Use ida_bytes.find_bytes for high-level pattern searching.
    return ida_bytes.find_bytes(dataSeg.start_ea, dataSeg.end_ea - dataSeg.start_ea, pattern, None, ida_bytes.BIN_SEARCH_FORWARD)

def inUTF16Range(targetAddr):
    return _UTF16start<=targetAddr<_UTF16end
def inASCIIRange(targetAddr):
    return _AsciiSTRstart<=targetAddr<_AsciiSTRend
def isPointer(targetAddr):
    if not inDataRange(targetAddr) or targetAddr is None: return False
    if ida_segment.get_segm_by_name('.bss').start_ea <= targetAddr < ida_segment.get_segm_by_name('.bss').end_ea: return True
    return codeStart<GetQword(targetAddr)<dataEnd
def isFound(targetAddr):
    if targetAddr==BADADDR or targetAddr is None: return False
    if type(targetAddr) in (tuple, list): return True
    return codeStart<=targetAddr<dataEnd or ((inHeapRange(targetAddr) or inAliasRange(targetAddr)) if isGDB() else inWriteableMemory(targetAddr))
def notFound(targetAddr):
    return not isFound(targetAddr)
def GetQword(targetAddr):
    return ida_bytes.get_qword(targetAddr) if isFound(targetAddr) and targetAddr!=None else BADADDR
def GetDword(targetAddr):
    # CORRECTED: Using ida_bytes.get_dword instead of get_wide_dword for standard 32-bit read
    return ida_bytes.get_dword(targetAddr) if isFound(targetAddr) and targetAddr!=None else BADADDR
def GetADRP(addr):
    if notFound(addr): return BADADDR
    register = idc.print_operand(addr,1)[1:4].replace(',','')
    baseAddr = SearchPrevASM(addr,'ADRP',register)
    return idc.get_operand_value(baseAddr,1)+idc.get_operand_value(addr,1)
def GetADRL(addr):
    if notFound(addr): return BADADDR
    if idc.print_insn_mnem(addr)=='ADRL': return idc.get_operand_value(addr,1)
    register = idc.print_operand(addr,1)[1:4].replace(',','')
    baseAddr = SearchPrevASM(addr,'ADRL',register)
    return idc.get_operand_value(baseAddr,1)+idc.get_operand_value(addr,1)
def isString(targetAddr):
    return ida_bytes.is_strlit(ida_bytes.get_full_flags(targetAddr))
def isFunc(addr):
    # API CHECK: Use ida_funcs.get_func(addr) and check start_ea/end_ea instead of deprecated idc.is_func
    f = ida_funcs.get_func(addr)
    return f and f.start_ea == addr

def inFunc(addr):
    return ida_funcs.get_fchunk(addr)!=None
def isFuncTail(addr):
    f = ida_funcs.get_func(addr)
    return f and ida_funcs.is_func_tail(f)

def iter_all_funcs():
    for func_ea in idautils.Functions():
        yield ida_funcs.get_func(func_ea)
        
def RemoveAllFuncTail():
    for func_t in iter_all_funcs():
        if func_t.tailqty > 0:
            RemoveFuncTail(func_t.start_ea)
            
def RemoveFuncTail(addr):
    f = ida_funcs.get_func(addr)
    chunk = ida_funcs.get_fchunk(addr)
    if f and chunk:
        ida_funcs.remove_func_tail(f, chunk.start_ea)

def RemakeFunc(addr):
    if isFuncTail(addr): RemoveFuncTail(addr)
    if isFunc(addr): ida_funcs.del_func(addr)
    AddFunc(addr)
    
def MakeFunc(addr): # find the prev function end, and add new function there
    if ida_bytes.get_item_size(addr)>4: ida_bytes.del_items(addr)
    if not(codeEnd>addr>codeStart): return
    addr=addr//4*4
    if isFuncTail(addr): RemoveFuncTail(addr)
    if inFunc(addr): return
    
    prevFunc=ida_funcs.get_prev_func(addr)
    while prevFunc and prevFunc.end_ea>addr and prevFunc.tailqty>0:
        chunk = ida_funcs.get_fchunk(prevFunc.end_ea)
        if chunk:
            AddFunc(chunk.start_ea)
        prevFunc=ida_funcs.get_prev_func(addr)
    
    # Get the end address of the previous function chunk
    prev_head = idc.prev_head(addr)
    prev_func = ida_funcs.get_func(prev_head)
    funcStart = prev_func.end_ea if prev_func else addr
    
    while GetDword(funcStart) in (0,0xD503201F,0xE7FFDEFE) and funcStart<codeEnd: funcStart+=4
    while not inFunc(addr) and funcStart<=addr<codeEnd:
        if funcStart==addr and not isFuncEnd(addr-4):
            CombineFunc(addr)
            break
        AddFunc(funcStart)
        
        # Re-calculate funcStart based on the new function created
        prev_head = idc.prev_head(addr)
        prev_func = ida_funcs.get_func(prev_head)
        funcStart = prev_func.end_ea if prev_func else addr
        
        while GetDword(funcStart) in (0,0xD503201F,0xE7FFDEFE) and funcStart<codeEnd: funcStart+=4
        
def AddFunc(funcStart): # force Add function here
    if isGDB() and funcStart<0x8000000: funcStart+=base
    if not inCodeRange(funcStart): return
    if ida_bytes.get_item_size(funcStart)>4: ida_bytes.del_items(funcStart)
    if isFuncTail(funcStart): RemoveFuncTail(funcStart)
    if isFunc(funcStart): return
    Debug('%X: Making Function at %X'%(funcStart,funcStart))
    ida_funcs.del_func(funcStart)
    ida_auto.auto_make_proc(funcStart)
    ida_auto.auto_wait_range(funcStart,funcStart+0x8)
    if not isFunc(funcStart):
        funcEnd=idc.find_func_end(funcStart)
        if notFound(funcEnd) or funcEnd<funcStart:
            funcEnd=funcStart+4
            while not isFuncEnd(funcEnd) and funcEnd<codeEnd: funcEnd+=4
            if idc.print_insn_mnem(funcEnd) in ('RET','B','BR'): funcEnd+=4
        ida_funcs.add_func(funcStart,funcEnd)
        ida_auto.auto_wait_range(funcStart,funcEnd)
        
def isFuncEnd(funcEnd):
    return idc.print_insn_mnem(funcEnd) in ('RET','B','BR','NOP') or GetDword(funcEnd) in (0,0xE7FFDEFE)

def CombineFunc(ea):
    # ea=GetFuncStart(ea)
    prevFunc=ida_funcs.get_prev_func(ea)
    if not prevFunc or prevFunc.end_ea!=ea or isFuncEnd(ea-4): return # Added 'not prevFunc or' check
    ida_funcs.del_func(ea)
    RemakeFunc(prevFunc.start_ea)
    
def GetFuncStart(targetAddr):
    if not inCodeRange(targetAddr): halt('Error in GetFuncStart at %X'%targetAddr) 
    if isFunc(targetAddr): CombineFunc(targetAddr)
    if isFuncTail(targetAddr): RemoveFuncTail(targetAddr)
    while not inFunc(targetAddr): MakeFunc(targetAddr)
    f = ida_funcs.get_func(targetAddr)
    return f.start_ea if f else BADADDR

def GetFuncEnd(targetAddr):
    if not inCodeRange(targetAddr): halt('Error in GetFuncEnd at %X'%targetAddr) 
    if isFuncTail(targetAddr): RemoveFuncTail(targetAddr)
    while not inFunc(targetAddr): MakeFunc(targetAddr)
    f = ida_funcs.get_func(targetAddr)
    return f.end_ea if f else BADADDR

def AOB(pattern,searchStart=codeStart,searchEnd=codeEnd):
    return ida_bytes.find_bytes(pattern, searchStart, searchEnd - searchStart)

def AOB2(pattern,offset=0,pattern2=None,searchStart=codeStart,searchEnd=codeEnd): # funcion inside
    opAddr=AOB(pattern,searchStart,searchEnd) if type(pattern) is str else pattern
    if notFound(opAddr): return BADADDR
    return idc.get_operand_value(opAddr+offset,0) if pattern2 is None else AOB(pattern2,idc.get_operand_value(opAddr+offset,0))

def AOB3(pattern,pattern2,searchStart=codeStart,searchEnd=codeEnd):
    opAddr=AOB(pattern,searchStart,searchEnd) if type(pattern) is str else pattern
    if notFound(opAddr): return BADADDR
    return AOB(pattern2,opAddr) if type(pattern2) is str else opAddr+pattern2

def uAOB(pattern,searchStart=codeStart,searchEnd=codeEnd):
    if type(searchStart) is str:
        searchStart = idc.get_name_ea(BADADDR, searchStart)
        if searchEnd == BADADDR:
            halt("ERROR %s", pattern)
        searchEnd = GetFuncEnd(searchStart)
        if searchEnd == BADADDR:
            halt("ERROR %s", pattern)

    # API FIX: CORRECTED parameter order: (pattern, start_ea, range_size)
    return ida_bytes.find_bytes(pattern, searchStart, searchEnd - searchStart)


def AllOccur(pattern,offset=0,searchStart=codeStart,searchEnd=codeEnd):
    result=[]
    # API FIX: Use ida_bytes.find_bytes with correct arguments. Use range_end for clarity in this loop.
    ea = ida_bytes.find_bytes(pattern, searchStart, range_end=searchEnd, flags=ida_bytes.BIN_SEARCH_FORWARD)
    while ea != BADADDR:
        result.append(ea + offset)
        # For the next search, start from ea+1 to find the next occurrence within the original end boundary
        ea = ida_bytes.find_bytes(pattern, ea + 1, range_end=searchEnd, flags=ida_bytes.BIN_SEARCH_FORWARD)
    return result

def checkUnique(pattern):
    cheatAddr=AOB(pattern)
    # API FIX: Corrected arguments. Search from cheatAddr+1 to the end.
    if not isFound(cheatAddr):
        return None
    next_occurrence = ida_bytes.find_bytes(pattern, cheatAddr + 1, codeEnd - (cheatAddr + 1))
    return notFound(next_occurrence)

def GetBytesPattern(opAddr):
    return ' '.join('{:02X}'.format(x) for x in ida_bytes.get_bytes(opAddr, 4))
    
def anaysis(opAddr):
    cmd=idc.print_insn_mnem(opAddr)
    if cmd == 'BL' or cmd == 'B':
        return '? ? ? ?'           # return '? ? ? {:02X}'.format(ida_bytes.get_original_byte(opAddr+3))
    elif cmd == 'ADRP' or cmd == 'ADRL':
        return '? ? ? ?'
    elif cmd == '' and idc.print_insn_mnem(opAddr-4)=='ADRL':
        return "? ? ? {:02X}".format(ida_bytes.get_original_byte(opAddr+3))
    elif 'PAGEOFF' in idc.print_operand(opAddr,1):
        return "{:02X} ? ? {:02X}".format(ida_bytes.get_original_byte(opAddr),ida_bytes.get_original_byte(opAddr+3))
    else:
        return GetBytesPattern(opAddr)

def GetAOB(opAddr=BADADDR):
    if notFound(opAddr): opAddr=s()
    pattern=space=''
    result=False
    funcEnd=GetFuncEnd(opAddr)
    while opAddr<funcEnd and result==False:
        pattern+=space+anaysis(opAddr)
        space=' '
        opAddr+=4
        result=checkUnique(pattern)
    print(pattern)
    if result==None: Warning('Pattern not Unqiue!')
    
def SearchNextASM(addr,command,operand0=None,operand1=None, operand2=None, limit=0):
    if notFound(addr): halt('invalid start searching address '+hex(addr))
    if not inFunc(addr): MakeFunc(addr)
    while GetDword(addr) in (0,0xD503201F,0xE7FFDEFE): addr+=4
    limitAddr=GetFuncEnd(addr) if limit==0 else addr+limit
    addr+=4
    while addr<limitAddr:
        if command in ('LDR','LDRB','STR','STRB'):
            if (idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0) and \
               (operand1==None or idc.print_operand(addr,1)==operand1 or idc.print_operand(addr,1)[1:len(operand1)+1]==operand1) and \
               (operand2==None or idc.get_operand_value(addr,1)==operand2): break
        elif command in ('LDP','STP'):
            if(idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0) and \
               (operand1==None or idc.print_operand(addr,1)==operand1) and \
               (operand2==None or (isinstance(operand2, str) and idc.print_operand(addr,2)[1:len(operand2)+1]==operand2) or (isinstance(operand2, int) and idc.get_operand_value(addr,2)==operand2)): break
        else:
            if (idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0 or (isinstance(operand0, int) and idc.get_operand_value(addr,0)==operand0)) and \
               (operand1==None or idc.print_operand(addr,1)==operand1 or (isinstance(operand1, int) and idc.get_operand_value(addr,1)==operand1)) and \
               (operand2==None or idc.print_operand(addr,2)==operand2 or (isinstance(operand2, int) and idc.get_operand_value(addr,2)==operand2)): break
        addr+=4
    return addr if addr<limitAddr else BADADDR
    
def SearchPrevASM(addr,command,operand0=None,operand1=None,operand2=None,limit=0):
    if notFound(addr): halt('invalid start searching address '+hex(addr))
    # if limit==0 and not inFunc(addr): MakeFunc(addr)
    if limit==0 and not inFunc(addr): limit=0x3000
    addr-=4
    while GetDword(addr) in (0,0xD503201F,0xE7FFDEFE): addr-=4
    # p(addr)
    limitAddr = GetFuncStart(addr) if limit==0 else addr-limit
    while addr>=limitAddr:
        # if not isCode(addr): ida_auto.auto_make_code(addr)
        if not isCode(addr): MakeFunc(addr)
        if command in ('LDR','LDRB','STR','STRB'):
            if (idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0) and \
               (operand1==None or idc.print_operand(addr,1)==operand1 or idc.print_operand(addr,1)[1:len(operand1)+1]==operand1) and \
               (operand2==None or idc.get_operand_value(addr,1)==operand2): break
        elif command in ('LDP','STP'):
            if(idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0) and \
               (operand1==None or idc.print_operand(addr,1)==operand1) and \
               (operand2==None or (isinstance(operand2, str) and idc.print_operand(addr,2)[1:len(operand2)+1]==operand2) or (isinstance(operand2, int) and idc.get_operand_value(addr,2)==operand2)): break
        else:
            if (idc.print_insn_mnem(addr)==command) and \
               (operand0==None or idc.print_operand(addr,0)==operand0 or (isinstance(operand0, int) and idc.get_operand_value(addr,0)==operand0)) and \
               (operand1==None or idc.print_operand(addr,1)==operand1 or (isinstance(operand1, int) and idc.get_operand_value(addr,1)==operand1)) and \
               (operand2==None or idc.print_operand(addr,2)==operand2 or (isinstance(operand2, int) and idc.get_operand_value(addr,2)==operand2)): break
        addr-=4
    return addr if addr>=limitAddr else BADADDR

def SearchXrefASM(funcAddr,command,operand0=None,operand1=None,listAll=False):
    addr=BADADDR
    results=[]
    for xref in idautils.XrefsTo(funcAddr,0):
        if (idc.print_insn_mnem(xref.frm)==command) and \
           (operand0==None or (idc.print_operand(xref.frm,0)!=operand0[1:] if operand0[0]=='!' else idc.print_operand(xref.frm,0)==operand0) or (isinstance(operand0, int) and idc.get_operand_value(xref.frm,0)==operand0)) and \
           (operand1==None or idc.get_operand_value(xref.frm,1)==operand1):
            addr=xref.frm;
            results.append(addr)
            if not listAll: break
    return results if listAll else addr
    
def ApplyComment(targetAddr,comment):
    idc.set_cmt(targetAddr,comment,1)
def AddEmptyLines(targetAddr):
    ida_lines.del_extra_cmt(targetAddr,ida_lines.E_NEXT)
    ida_lines.del_extra_cmt(targetAddr,ida_lines.E_NEXT+1)
    ida_lines.add_extra_line(targetAddr,False,'\n\n')
def ReplacePriorComment(targetAddr,comment):
    ida_lines.delete_extra_cmts(targetAddr,ida_lines.E_PREV)
    ida_lines.add_extra_line(targetAddr,True,comment)
def AddPriorComment(targetAddr,comment):
    lines=ida_lines.get_extra_cmt(targetAddr, ida_lines.E_PREV)
    if lines != None:
        for l in lines.replace('; ','').split('\n'):
            if comment==l: return
    ida_lines.add_extra_cmt(targetAddr,True,comment)         

def GetParameterHelper(funcAddr,regName,memType=None):
    x=SearchPrevASM(funcAddr,'ADRL',regName,limit=0x60)
    r=SearchPrevASM(funcAddr,'MOV',regName,limit=0x60)
    a=SearchPrevASM(funcAddr,'ADD',regName,limit=0x60)
    l1=SearchPrevASM(funcAddr,'LDR',regName,limit=0x60)
    l2=SearchPrevASM(funcAddr,'LDUR',regName,limit=0x60)
    l = max(l1,l2) if isFound(l1) and isFound(l2) else (l1 if isFound(l1) else l2)
    if isFound(r) and (notFound(x) or r>x):
        x=SearchPrevASM(r,'ADRL',idc.print_operand(r,1))
        if memType=='Code':
            while not inCodeRange(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
        elif memType=='UTF':
            while not inUTF16Range(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
        elif memType=='ASC':
            while not inASCIIRange(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
        elif memType=='Pointer':
            while not isPointer(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
        elif memType=='Writeable':
            while not inWriteableMemory(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
        if notFound(x): # far function call
            # xref=list(idautils.CodeRefsTo(GetFuncStart(r),1))
            # if len(xref)==1:
                # caller=next(xref)
                # return GetParameterHelper(caller,idc.print_operand(r,1),memType)
            b=SearchPrevASM(r,'B')
            if isFound(b) and b>GetFuncStart(r):
                # Using next(idautils.CodeRefsTo) might raise StopIteration if empty, better to check list length
                xrefs = list(idautils.CodeRefsTo(b+4,1))
                caller = xrefs[0] if len(xrefs)==1 else BADADDR
            else:
                xref=list(idautils.CodeRefsTo(GetFuncStart(r),1))
                caller=xref[0] if len(xref)==1 else BADADDR
            if isFound(caller) and inCodeRange(caller):
                # print('GetParameterHelper(0x%X,"%s","%s")'%(caller,idc.print_operand(r,1),memType))
                return GetParameterHelper(caller,idc.print_operand(r,1),memType)
                
    elif isFound(l) and (notFound(r) or l>r) and (notFound(x) or l>x) and (notFound(a) or l>a):
        if idc.print_operand(l,1)[1:4] not in ('SP,','X29'):
            return GetADRP(l)
        else:
            r1=SearchPrevASM(l,'STR',None,idc.print_operand(l,1))
            r2=SearchPrevASM(l,'STUR',None,idc.print_operand(l,1))
            r=max(r1,r2) if isFound(r1) and isFound(r2) else (r1 if isFound(r1) else r2)
            x=SearchPrevASM(r,'ADRL',idc.print_operand(r,0))
            if notFound(x): # far function call
                xref=list(idautils.CodeRefsTo(GetFuncStart(r),1))
                if len(xref)==1 and inCodeRange(xref[0]):
                    return GetParameterHelper(xref[0],idc.print_operand(r,0),memType)
    elif isFound(a) and (notFound(x) or a>x): 
        b=SearchPrevASM(a,'ADRP',idc.get_operand_value(a,1))
        if isFound(b): return idc.get_operand_value(b,1) + idc.get_operand_value(a,2)
    if notFound(x): return BADADDR
    if memType=='Code':
        while not inCodeRange(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
    elif memType=='UTF':
        while not inUTF16Range(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
    elif memType=='ASC':
        while not inASCIIRange(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
    elif memType=='Pointer':
        while not isPointer(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
    elif memType=='Writeable':
        while not inWriteableMemory(idc.get_operand_value(x,1)) and isFound(x): x=SearchPrevASM(x,'ADRL',idc.print_operand(r,1))
    return idc.get_operand_value(x,1) if isFound(x) else BADADDR
    
def ApplyPatch(code):# use 3 """ to quote the multiline codes
    lines=code.split('\n')
    for line in lines:
        if len(line)<26 or line[0]!='0': continue
        type,addr,value=(int(x.replace(' ',''),16) for x in line.split(' ',2))
        size=(type&0x0F000000)//0x1000000
        PatchBytes(size,base+addr,value)
        ida_bytes.del_items(addr+base)
        idc.create_insn(addr+base)
        
def PatchBytes(length,opAddr,value):
    if type(value) is str: value=int(value.replace(' ',''), 16)
    if (length==1):
        ida_bytes.patch_byte(opAddr,value)
    elif (length==2):
        ida_bytes.patch_word(opAddr,value)
    elif (length==4):
        ida_bytes.patch_dword(opAddr,value)
    elif (length==8):
        ida_bytes.patch_qword(opAddr,value)
    else:
        print('Error in PatchBytes(%X,%X,%X)'%(length,opAddr,value))

def ptr(offsets,length=0,returnResult=False): # return the address/value of pointer expression, e.g. [[main+123456]+1234]+32 , type ptr((123456,0x1234,0x32)) or ptr((123456,0x1234,0x32),4)
    if type(offsets) not in (tuple, list): return 'Error with NOEXES expression'
    addr=base if offsets[0]<0x10000000 else 0
    for offset in offsets[:-1]:
        addr = GetQword(addr+offset)
    addr += offsets[-1]
    result = addr if length==0 else GetBytes(length,addr)
    if returnResult:
        return result
    else:
        p(result)

def GetBytes(length,opAddr):
    if length not in (1,2,4,8): halt('Bytes length must be 1, 2, 4 or 8')
    return {1:ida_bytes.get_original_byte(opAddr), 2:ida_bytes.get_original_word(opAddr), 4:ida_bytes.get_original_dword(opAddr), 8:ida_bytes.get_original_qword(opAddr)}[length]

def GetUTFstr(addr,maxLen=0x1000):
    if not(isGDB()) and not inUTF16Range(addr): halt(hex(addr));return 'unknown'
    # API FIX: Use ida_bytes.find_bytes with correct arguments.
    pattern = '00 00 00 00'
    end = ida_bytes.find_bytes(pattern, addr, 0x100)
    if end == BADADDR:
        return 'unknown' # or handle error

    length=min(maxLen,end-addr+3)
    result=idc.get_strlit_contents(addr,length,ida_nalt.STRTYPE_C_16).decode()
    if not isString(addr) or idaapi.get_item_head(addr+length-1)!=addr or idaapi.get_item_head(addr)!=addr:
        ida_bytes.del_items(addr,0,length)
        ida_bytes.create_strlit(addr, length, ida_nalt.STRTYPE_C_16)
    idc.set_name(addr,'utf_'+result,0x39A1)
    return result
    
def GetASCstr(addr):
    if not isGDB() and not inASCIIRange(addr): return ''
    if notFound(addr): return ''
    # API FIX: Use ida_bytes.find_bytes with correct arguments.
    pattern = '00'
    end = ida_bytes.find_bytes(pattern, addr, 0x100)
    if end == BADADDR:
        return ''

    length=end-addr+1
    string=idc.get_strlit_contents(addr,length,ida_nalt.STRTYPE_C)
    if string is None: return ''
    result=string.decode()
    if len(result)<2 or not bool(re.match(r'[a-zA-Z\_\.\<]+$', result[0])): return ''
    if not isString(addr) or idaapi.get_item_head(addr+length-1)!=addr or idaapi.get_item_head(addr)!=addr:
        ida_bytes.del_items(addr,0,length)
        ida_bytes.create_strlit(addr, length, ida_nalt.STRTYPE_C)
    idc.set_name(addr,'str_'+result,0x39A1)
    return '' if result is None else result
    
def Patch(targetAddr,newName,ref=BADADDR, force=False):
    if isGDB() and targetAddr<0x10000000: targetAddr+=base
    if not isGDB() and inCodeRange(targetAddr):
        AddFunc(targetAddr)
    if isFound(ref):
        Debug('Patch(0x%X, \'%s\', 0x%X)' % (targetAddr,newName,ref))
    else:
        Debug('Patch(0x%X, \'%s\')' % (targetAddr-base if isGDB() and inCodeRange(targetAddr) else targetAddr,newName))
    tempAddr=idc.get_name_ea(codeStart,newName)
    if force and isFound(tempAddr) and tempAddr != targetAddr:
        idc.set_name(tempAddr,'')
        idc.set_name(targetAddr, newName, (0x3921 if inCodeRange(targetAddr) else 0x39A1))
        idc.set_name(tempAddr, newName, (0x3921 if inCodeRange(targetAddr) else 0x39A1))
    else:
        idc.set_name(targetAddr, '')
        idc.set_name(targetAddr, newName, (0x3921 if inCodeRange(targetAddr) else 0x39A1))
        
def ApplyStruct(targetAddr,name):
    # if inCodeRange(targetAddr) and targetAddr>base and base>0: targetAddr-=base
    sid=ida_struct.get_struc_id(name)
    size=ida_struct.get_struc_size(sid)
    # ida_bytes.create_struct(targetAddr+base, size, ida_struct.get_struc_id(name),True)
    ida_bytes.create_struct(targetAddr, size, ida_struct.get_struc_id(name),True)
    
def MarkOffset(addr):
    ida_bytes.create_qword(addr,8)
    ida_offset.op_plain_offset(addr,0,0)

def MarkBytes(addr,length=4):
    ida_bytes.create_byte(addr,length)

def MarkFloat(addr,length=4):
    ida_bytes.create_float(addr,length)
 
For those who obtained the lab key in wrong order causing to get stuck at Lysandre Labs B3F
i figured it out!!
I used someones save file that hasn't obtain keys and compared the save file before after they obtained
output:
=====
updated.Blocks.Event:
=====
DD09A5AF5869E155 changed from False to True

=====
updated.Blocks.FieldItems:
=====
FF919BF7529EB09C changed from False to True
FF919DF7529EB402 changed from False to True
FF919AF7529EAEE9 changed from False to True
FF919EF7529EB5B5 changed from False to True
---

Basically you need to modify ur save file with pkhex:

After openig ur save file go to SAV > Items > Key icon
1. Remove key items (Lab Key Card A, B, C, Elevator key) - set to value '0' and uncheck anything related
View attachment 538099

go to 'Event Flags'
2. uncheck 1 value under 'Event' tab - DD09A5AF5869E155
View attachment 538100

3. uncheck 4 values under 'Field Items' tab
FF919BF7529EB09C - Lab Key Card A
FF919DF7529EB402 - Lab Key Card B
FF919AF7529EAEE9 - Lab Key Card C
FF919EF7529EB5B5 - Elevator Key
View attachment 538101

then save and obtain in order! you can use go thru walls with cheat but make sure u obtain in order to trigger the event and you should be good to go!!
Post automatically merged:

@Xjackio thank u for guiding me i appriciate it!!!
I want to make again the side mission 21 to get one more time the spewpa who evolve into blue vivillon, i deleted these spewpa before knowing that evolve into blue vivillon... the flags that you mentioned there worked for these mission? you know exacly wich flag is for that side mission?
 

Site & Scene News

Popular threads in this forum