Fixed various Flute logic issues and improved logic efficiency

This commit is contained in:
codemann8
2023-04-01 07:59:13 -05:00
parent d216cb337b
commit 3eeeda363b
5 changed files with 27 additions and 8 deletions

View File

@@ -1299,11 +1299,7 @@ class CollectionState(object):
def can_flute(self, player): def can_flute(self, player):
if self.world.mode[player] == 'standard' and not self.has('Zelda Delivered', player): if self.world.mode[player] == 'standard' and not self.has('Zelda Delivered', player):
return False # can't flute in rain state return False # can't flute in rain state
if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], self.world.precollected_items)): return self.has('Ocarina (Activated)', player)
return True
lw = self.world.get_region('Kakariko Area', player)
return self.has('Ocarina (Activated)', player) or (self.has('Ocarina', player) and lw.can_reach(self)
and self.is_not_bunny(lw, player))
def can_melt_things(self, player): def can_melt_things(self, player):
return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player)) return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player))

View File

@@ -212,6 +212,20 @@ def generate_itempool(world, player):
loc.locked = True loc.locked = True
loc.forced_item = loc.item loc.forced_item = loc.item
if not world.is_tile_swapped(0x18, player):
region = world.get_region('Kakariko Area',player)
loc = Location(player, "Flute Activation", parent=region)
region.locations.append(loc)
world.dynamic_locations.append(loc)
world.clear_location_cache()
world.push_item(loc, ItemFactory('Ocarina (Activated)', player), False)
loc.event = True
loc.locked = True
loc.forced_item = loc.item
world.get_location('Ganon', player).event = True world.get_location('Ganon', player).event = True
world.get_location('Ganon', player).locked = True world.get_location('Ganon', player).locked = True
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False) world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
@@ -1433,6 +1447,9 @@ def make_customizer_pool(world, player):
place_item('Master Sword Pedestal', 'Triforce') place_item('Master Sword Pedestal', 'Triforce')
guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl'] guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl']
if world.is_tile_swapped(0x18, player) or world.flute_mode[player] == 'active':
guaranteed_items.remove('Ocarina')
guaranteed_items.append('Ocarina (Activated)')
missing_items = [] missing_items = []
if world.shopsanity[player]: if world.shopsanity[player]:
guaranteed_items.extend(['Blue Potion', 'Green Potion', 'Red Potion']) guaranteed_items.extend(['Blue Potion', 'Green Potion', 'Red Potion'])

View File

@@ -1092,7 +1092,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
region = base_world.get_region(region_name, player) region = base_world.get_region(region_name, player)
for exit in region.exits: for exit in region.exits:
if exit.connected_region is not None: if exit.connected_region is not None:
if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], base_world.precollected_items)) and exit.spot_type == 'Flute': if any(map(lambda i: i.name == 'Ocarina (Activated)', base_world.precollected_items)) and exit.spot_type == 'Flute':
fluteregion = exit.connected_region fluteregion = exit.connected_region
for flutespot in fluteregion.exits: for flutespot in fluteregion.exits:
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions: if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:

3
Rom.py
View File

@@ -2308,10 +2308,9 @@ def write_strings(rom, world, player, team):
# of how many exist. This supports many settings well. # of how many exist. This supports many settings well.
items_to_hint = RelevantItems.copy() items_to_hint = RelevantItems.copy()
flute_item = 'Ocarina' flute_item = 'Ocarina'
if world.is_tile_swapped(0x18, player): if world.is_tile_swapped(0x18, player) or world.flute_mode[player] == 'active':
items_to_hint.remove(flute_item) items_to_hint.remove(flute_item)
flute_item = 'Ocarina (Activated)' flute_item = 'Ocarina (Activated)'
items_to_hint.append(flute_item)
if world.owShuffle[player] != 'vanilla' or world.owMixed[player]: if world.owShuffle[player] != 'vanilla' or world.owMixed[player]:
# Adding a guaranteed hint for the Flute in overworld shuffle. # Adding a guaranteed hint for the Flute in overworld shuffle.
this_location = world.find_items_not_key_only(flute_item, player) this_location = world.find_items_not_key_only(flute_item, player)

View File

@@ -70,6 +70,13 @@ def set_rules(world, player):
elif world.goal[player] == 'completionist': elif world.goal[player] == 'completionist':
add_rule(world.get_location('Ganon', player), lambda state: state.everything(player)) add_rule(world.get_location('Ganon', player), lambda state: state.everything(player))
if not world.is_tile_swapped(0x18, player):
if not world.is_copied_world:
# Commented out below, this would be needed for rando implementations where Inverted requires flute activation in bunny territory
# kak_region = self.world.get_region('Kakariko Area', player)
# add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player) and state.is_not_bunny(kak_region, player))
add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player))
# if swamp and dam have not been moved we require mirror for swamp palace # if swamp and dam have not been moved we require mirror for swamp palace
if not world.swamp_patch_required[player]: if not world.swamp_patch_required[player]:
add_rule(world.get_entrance('Swamp Lobby Moat', player), lambda state: state.has_Mirror(player)) add_rule(world.get_entrance('Swamp Lobby Moat', player), lambda state: state.has_Mirror(player))