Skip to content

Commit

Permalink
LttP: write fairy bottle fill to spoiler and prevent fart in a bottle
Browse files Browse the repository at this point in the history
  • Loading branch information
Berserker66 committed Nov 4, 2023
1 parent d2e9bfb commit ac030cb
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 34 deletions.
9 changes: 3 additions & 6 deletions worlds/alttp/Rom.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ def get_nonnative_item_sprite(code: int) -> int:

def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool):
local_random = world.per_slot_randoms[player]
local_world = world.worlds[player]

# patch items

Expand Down Expand Up @@ -1190,12 +1191,8 @@ def chunk(l, n):
])

# set Fountain bottle exchange items
if world.difficulty[player] in ['hard', 'expert']:
rom.write_byte(0x348FF, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x48][local_random.randint(0, 5)])
rom.write_byte(0x3493B, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x48][local_random.randint(0, 5)])
else:
rom.write_byte(0x348FF, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x3D, 0x48][local_random.randint(0, 6)])
rom.write_byte(0x3493B, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x3D, 0x48][local_random.randint(0, 6)])
rom.write_byte(0x348FF, item_table[local_world.waterfall_fairy_bottle_fill].item_code)
rom.write_byte(0x3493B, item_table[local_world.pyramid_fairy_bottle_fill].item_code)

# enable Fat Fairy Chests
rom.write_bytes(0x1FC16, [0xB1, 0xC6, 0xF9, 0xC9, 0xC6, 0xF9])
Expand Down
74 changes: 46 additions & 28 deletions worlds/alttp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,17 @@ def enemizer_path(self) -> str:
rom_name_available_event: threading.Event
has_progressive_bows: bool
dungeons: typing.Dict[str, Dungeon]
waterfall_fairy_bottle_fill: str
pyramid_fairy_bottle_fill: str

def __init__(self, *args, **kwargs):
self.dungeon_local_item_names = set()
self.dungeon_specific_item_names = set()
self.rom_name_available_event = threading.Event()
self.has_progressive_bows = False
self.dungeons = {}
self.waterfall_fairy_bottle_fill = "Bottle"
self.pyramid_fairy_bottle_fill = "Bottle"
super(ALTTPWorld, self).__init__(*args, **kwargs)

@classmethod
Expand All @@ -273,52 +277,62 @@ def stage_assert_generate(cls, multiworld: MultiWorld):
def generate_early(self):

player = self.player
world = self.multiworld
multiworld = self.multiworld

if world.mode[player] == 'standard' \
and world.smallkey_shuffle[player] \
and world.smallkey_shuffle[player] != smallkey_shuffle.option_universal \
and world.smallkey_shuffle[player] != smallkey_shuffle.option_own_dungeons \
and world.smallkey_shuffle[player] != smallkey_shuffle.option_start_with:
# fairy bottle fills
bottle_options = [
"Bottle (Red Potion)", "Bottle (Green Potion)", "Bottle (Blue Potion)",
"Bottle (Bee)", "Bottle (Good Bee)"
]
if multiworld.difficulty[player] not in ["hard", "expert"]:
bottle_options.append("Bottle (Fairy)")
self.waterfall_fairy_bottle_fill = self.random.choice(bottle_options)
self.pyramid_fairy_bottle_fill = self.random.choice(bottle_options)

if multiworld.mode[player] == 'standard' \
and multiworld.smallkey_shuffle[player] \
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_universal \
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_own_dungeons \
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_start_with:
self.multiworld.local_early_items[self.player]["Small Key (Hyrule Castle)"] = 1

# system for sharing ER layouts
self.er_seed = str(world.random.randint(0, 2 ** 64))
self.er_seed = str(multiworld.random.randint(0, 2 ** 64))

if "-" in world.shuffle[player]:
shuffle, seed = world.shuffle[player].split("-", 1)
world.shuffle[player] = shuffle
if "-" in multiworld.shuffle[player]:
shuffle, seed = multiworld.shuffle[player].split("-", 1)
multiworld.shuffle[player] = shuffle
if shuffle == "vanilla":
self.er_seed = "vanilla"
elif seed.startswith("group-") or world.is_race:
self.er_seed = get_same_seed(world, (
shuffle, seed, world.retro_caves[player], world.mode[player], world.logic[player]))
elif seed.startswith("group-") or multiworld.is_race:
self.er_seed = get_same_seed(multiworld, (
shuffle, seed, multiworld.retro_caves[player], multiworld.mode[player], multiworld.logic[player]))
else: # not a race or group seed, use set seed as is.
self.er_seed = seed
elif world.shuffle[player] == "vanilla":
elif multiworld.shuffle[player] == "vanilla":
self.er_seed = "vanilla"
for dungeon_item in ["smallkey_shuffle", "bigkey_shuffle", "compass_shuffle", "map_shuffle"]:
option = getattr(world, dungeon_item)[player]
option = getattr(multiworld, dungeon_item)[player]
if option == "own_world":
world.local_items[player].value |= self.item_name_groups[option.item_name_group]
multiworld.local_items[player].value |= self.item_name_groups[option.item_name_group]
elif option == "different_world":
world.non_local_items[player].value |= self.item_name_groups[option.item_name_group]
if world.mode[player] == "standard":
world.non_local_items[player].value -= {"Small Key (Hyrule Castle)"}
multiworld.non_local_items[player].value |= self.item_name_groups[option.item_name_group]
if multiworld.mode[player] == "standard":
multiworld.non_local_items[player].value -= {"Small Key (Hyrule Castle)"}
elif option.in_dungeon:
self.dungeon_local_item_names |= self.item_name_groups[option.item_name_group]
if option == "original_dungeon":
self.dungeon_specific_item_names |= self.item_name_groups[option.item_name_group]

world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
multiworld.difficulty_requirements[player] = difficulties[multiworld.difficulty[player]]

# enforce pre-defined local items.
if world.goal[player] in ["localtriforcehunt", "localganontriforcehunt"]:
world.local_items[player].value.add('Triforce Piece')
if multiworld.goal[player] in ["localtriforcehunt", "localganontriforcehunt"]:
multiworld.local_items[player].value.add('Triforce Piece')

# Not possible to place crystals outside boss prizes yet (might as well make it consistent with pendants too).
world.non_local_items[player].value -= item_name_groups['Pendants']
world.non_local_items[player].value -= item_name_groups['Crystals']
multiworld.non_local_items[player].value -= item_name_groups['Pendants']
multiworld.non_local_items[player].value -= item_name_groups['Crystals']

create_dungeons = create_dungeons

Expand Down Expand Up @@ -364,7 +378,6 @@ def create_regions(self):
world.register_indirect_condition(world.get_region(region_name, player),
world.get_entrance(entrance_name, player))


def collect_item(self, state: CollectionState, item: Item, remove=False):
item_name = item.name
if item_name.startswith('Progressive '):
Expand Down Expand Up @@ -693,13 +706,18 @@ def bool_to_text(variable: typing.Union[bool, str]) -> str:
spoiler_handle.write('Prize shuffle %s\n' % self.multiworld.shuffle_prizes[self.player])

def write_spoiler(self, spoiler_handle: typing.TextIO) -> None:
player_name = self.multiworld.get_player_name(self.player)
spoiler_handle.write("\n\nMedallions:\n")
spoiler_handle.write(f"\nMisery Mire ({self.multiworld.get_player_name(self.player)}):"
spoiler_handle.write(f"\nMisery Mire ({player_name}):"
f" {self.multiworld.required_medallions[self.player][0]}")
spoiler_handle.write(
f"\nTurtle Rock ({self.multiworld.get_player_name(self.player)}):"
f"\nTurtle Rock ({player_name}):"
f" {self.multiworld.required_medallions[self.player][1]}")

spoiler_handle.write("\n\nFairy Fountain Bottle Fill:\n")
spoiler_handle.write(f"\nPyramid Fairy ({player_name}):"
f" {self.pyramid_fairy_bottle_fill}")
spoiler_handle.write(f"\nWaterfall Fairy ({player_name}):"
f" {self.waterfall_fairy_bottle_fill}")
if self.multiworld.boss_shuffle[self.player] != "none":
def create_boss_map() -> typing.Dict:
boss_map = {
Expand Down

0 comments on commit ac030cb

Please sign in to comment.