Skip to content

Commit 4e73b55

Browse files
Berserker66FlySniper
authored andcommitted
LttP: write fairy bottle fill to spoiler and prevent fart in a bottle (ArchipelagoMW#2424)
1 parent ac72bf1 commit 4e73b55

File tree

2 files changed

+49
-34
lines changed

2 files changed

+49
-34
lines changed

worlds/alttp/Rom.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ def get_nonnative_item_sprite(code: int) -> int:
783783

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

787788
# patch items
788789

@@ -1190,12 +1191,8 @@ def chunk(l, n):
11901191
])
11911192

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

12001197
# enable Fat Fairy Chests
12011198
rom.write_bytes(0x1FC16, [0xB1, 0xC6, 0xF9, 0xC9, 0xC6, 0xF9])

worlds/alttp/__init__.py

+46-28
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,17 @@ def enemizer_path(self) -> str:
249249
rom_name_available_event: threading.Event
250250
has_progressive_bows: bool
251251
dungeons: typing.Dict[str, Dungeon]
252+
waterfall_fairy_bottle_fill: str
253+
pyramid_fairy_bottle_fill: str
252254

253255
def __init__(self, *args, **kwargs):
254256
self.dungeon_local_item_names = set()
255257
self.dungeon_specific_item_names = set()
256258
self.rom_name_available_event = threading.Event()
257259
self.has_progressive_bows = False
258260
self.dungeons = {}
261+
self.waterfall_fairy_bottle_fill = "Bottle"
262+
self.pyramid_fairy_bottle_fill = "Bottle"
259263
super(ALTTPWorld, self).__init__(*args, **kwargs)
260264

261265
@classmethod
@@ -273,52 +277,62 @@ def stage_assert_generate(cls, multiworld: MultiWorld):
273277
def generate_early(self):
274278

275279
player = self.player
276-
world = self.multiworld
280+
multiworld = self.multiworld
277281

278-
if world.mode[player] == 'standard' \
279-
and world.smallkey_shuffle[player] \
280-
and world.smallkey_shuffle[player] != smallkey_shuffle.option_universal \
281-
and world.smallkey_shuffle[player] != smallkey_shuffle.option_own_dungeons \
282-
and world.smallkey_shuffle[player] != smallkey_shuffle.option_start_with:
282+
# fairy bottle fills
283+
bottle_options = [
284+
"Bottle (Red Potion)", "Bottle (Green Potion)", "Bottle (Blue Potion)",
285+
"Bottle (Bee)", "Bottle (Good Bee)"
286+
]
287+
if multiworld.difficulty[player] not in ["hard", "expert"]:
288+
bottle_options.append("Bottle (Fairy)")
289+
self.waterfall_fairy_bottle_fill = self.random.choice(bottle_options)
290+
self.pyramid_fairy_bottle_fill = self.random.choice(bottle_options)
291+
292+
if multiworld.mode[player] == 'standard' \
293+
and multiworld.smallkey_shuffle[player] \
294+
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_universal \
295+
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_own_dungeons \
296+
and multiworld.smallkey_shuffle[player] != smallkey_shuffle.option_start_with:
283297
self.multiworld.local_early_items[self.player]["Small Key (Hyrule Castle)"] = 1
284298

285299
# system for sharing ER layouts
286-
self.er_seed = str(world.random.randint(0, 2 ** 64))
300+
self.er_seed = str(multiworld.random.randint(0, 2 ** 64))
287301

288-
if "-" in world.shuffle[player]:
289-
shuffle, seed = world.shuffle[player].split("-", 1)
290-
world.shuffle[player] = shuffle
302+
if "-" in multiworld.shuffle[player]:
303+
shuffle, seed = multiworld.shuffle[player].split("-", 1)
304+
multiworld.shuffle[player] = shuffle
291305
if shuffle == "vanilla":
292306
self.er_seed = "vanilla"
293-
elif seed.startswith("group-") or world.is_race:
294-
self.er_seed = get_same_seed(world, (
295-
shuffle, seed, world.retro_caves[player], world.mode[player], world.logic[player]))
307+
elif seed.startswith("group-") or multiworld.is_race:
308+
self.er_seed = get_same_seed(multiworld, (
309+
shuffle, seed, multiworld.retro_caves[player], multiworld.mode[player], multiworld.logic[player]))
296310
else: # not a race or group seed, use set seed as is.
297311
self.er_seed = seed
298-
elif world.shuffle[player] == "vanilla":
312+
elif multiworld.shuffle[player] == "vanilla":
299313
self.er_seed = "vanilla"
300314
for dungeon_item in ["smallkey_shuffle", "bigkey_shuffle", "compass_shuffle", "map_shuffle"]:
301-
option = getattr(world, dungeon_item)[player]
315+
option = getattr(multiworld, dungeon_item)[player]
302316
if option == "own_world":
303-
world.local_items[player].value |= self.item_name_groups[option.item_name_group]
317+
multiworld.local_items[player].value |= self.item_name_groups[option.item_name_group]
304318
elif option == "different_world":
305-
world.non_local_items[player].value |= self.item_name_groups[option.item_name_group]
306-
if world.mode[player] == "standard":
307-
world.non_local_items[player].value -= {"Small Key (Hyrule Castle)"}
319+
multiworld.non_local_items[player].value |= self.item_name_groups[option.item_name_group]
320+
if multiworld.mode[player] == "standard":
321+
multiworld.non_local_items[player].value -= {"Small Key (Hyrule Castle)"}
308322
elif option.in_dungeon:
309323
self.dungeon_local_item_names |= self.item_name_groups[option.item_name_group]
310324
if option == "original_dungeon":
311325
self.dungeon_specific_item_names |= self.item_name_groups[option.item_name_group]
312326

313-
world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
327+
multiworld.difficulty_requirements[player] = difficulties[multiworld.difficulty[player]]
314328

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

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

323337
create_dungeons = create_dungeons
324338

@@ -364,7 +378,6 @@ def create_regions(self):
364378
world.register_indirect_condition(world.get_region(region_name, player),
365379
world.get_entrance(entrance_name, player))
366380

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

695708
def write_spoiler(self, spoiler_handle: typing.TextIO) -> None:
709+
player_name = self.multiworld.get_player_name(self.player)
696710
spoiler_handle.write("\n\nMedallions:\n")
697-
spoiler_handle.write(f"\nMisery Mire ({self.multiworld.get_player_name(self.player)}):"
711+
spoiler_handle.write(f"\nMisery Mire ({player_name}):"
698712
f" {self.multiworld.required_medallions[self.player][0]}")
699713
spoiler_handle.write(
700-
f"\nTurtle Rock ({self.multiworld.get_player_name(self.player)}):"
714+
f"\nTurtle Rock ({player_name}):"
701715
f" {self.multiworld.required_medallions[self.player][1]}")
702-
716+
spoiler_handle.write("\n\nFairy Fountain Bottle Fill:\n")
717+
spoiler_handle.write(f"\nPyramid Fairy ({player_name}):"
718+
f" {self.pyramid_fairy_bottle_fill}")
719+
spoiler_handle.write(f"\nWaterfall Fairy ({player_name}):"
720+
f" {self.waterfall_fairy_bottle_fill}")
703721
if self.multiworld.boss_shuffle[self.player] != "none":
704722
def create_boss_map() -> typing.Dict:
705723
boss_map = {

0 commit comments

Comments
 (0)