from .itemInfo import ItemInfo from .constants import * from ..assembler import ASM from ..utils import formatText class BoomerangGuy(ItemInfo): OPTIONS = [BOOMERANG, HOOKSHOT, MAGIC_ROD, PEGASUS_BOOTS, FEATHER, SHOVEL] def __init__(self): super().__init__(0x1F5) self.setting = 'trade' def configure(self, options): self.MULTIWORLD = False self.setting = options.boomerang if self.setting == 'gift': self.MULTIWORLD = True # Cannot trade: # SWORD, BOMB, SHIELD, POWER_BRACELET, OCARINA, MAGIC_POWDER, BOW # Checks for these are at $46A2, and potentially we could remove those. # But SHIELD, BOMB and MAGIC_POWDER would most likely break things. # SWORD and POWER_BRACELET would most likely introduce the lv0 shield/bracelet issue def patch(self, rom, option, *, multiworld=None): # Always have the boomerang trade guy enabled (normally you need the magnifier) rom.patch(0x19, 0x05EC, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # show the guy rom.patch(0x00, 0x3199, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # load the proper room layout rom.patch(0x19, 0x05F4, ASM("ld a, [wTradeSequenceItem2]\nand a"), ASM("xor a"), fill_nop=True) if self.setting == 'trade': inv = INVENTORY_MAP[option] # Patch the check if you traded back the boomerang (so traded twice) rom.patch(0x19, 0x063F, ASM("cp $0D"), ASM("cp $%s" % (inv))) # Item to give by "default" (aka, boomerang) rom.patch(0x19, 0x06C1, ASM("ld a, $0D"), ASM("ld a, $%s" % (inv))) # Check if inventory slot is boomerang to give back item in this slot rom.patch(0x19, 0x06FC, ASM("cp $0D"), ASM("cp $%s" % (inv))) # Put the boomerang ID in the inventory of the boomerang guy (aka, traded back) rom.patch(0x19, 0x0710, ASM("ld a, $0D"), ASM("ld a, $%s" % (inv))) rom.texts[0x222] = formatText("Okay, let's do it!") rom.texts[0x224] = formatText("You got the {%s} in exchange for the item you had." % (option)) rom.texts[0x225] = formatText("Give me back my {%s}, I beg you! I'll return the item you gave me" % (option), ask="Okay Not Now") rom.texts[0x226] = formatText("The item came back to you. You returned the other item.") else: # Patch the inventory trade to give an specific item instead rom.texts[0x221] = formatText("I found a good item washed up on the beach... Want to have it?", ask="Okay No") rom.patch(0x19, 0x069C, 0x06C6, ASM(""" ; Mark trade as done ld a, $06 ld [$DB7D], a ld a, [$472B] ldh [$F1], a ld a, $06 rst 8 ld a, $0D """), fill_nop=True) # Show the right item above link rom.patch(0x19, 0x0786, 0x0793, ASM(""" ld a, [$472B] ldh [$F1], a ld a, $01 rst 8 """), fill_nop=True) # Give the proper message for this item rom.patch(0x19, 0x075A, 0x076A, ASM(""" ld a, [$472B] ldh [$F1], a ld a, $0A rst 8 """), fill_nop=True) rom.patch(0x19, 0x072B, "00", "%02X" % (CHEST_ITEMS[option])) # Ignore the trade back. rom.texts[0x225] = formatText("It's a secret to everybody.") rom.patch(0x19, 0x0668, ASM("ld a, [$DB7D]"), ASM("ret"), fill_nop=True) if multiworld is not None: rom.banks[0x3E][0x3300 + self.room] = multiworld def read(self, rom): if rom.banks[0x19][0x06C5] == 0x00: for k, v in CHEST_ITEMS.items(): if v == rom.banks[0x19][0x072B]: return k else: for k, v in INVENTORY_MAP.items(): if int(v, 16) == rom.banks[0x19][0x0640]: return k raise ValueError()