From 48090b1a3ec1f2e0e2cf06a64329366ea5d08db4 Mon Sep 17 00:00:00 2001 From: alwaysintreble Date: Fri, 24 Feb 2023 21:27:31 -0600 Subject: [PATCH] rename locations accessibility to "full" and make old locations accessibility debug only --- BaseClasses.py | 10 ++++++---- Options.py | 15 +++++++++++---- worlds/alttp/Options.py | 3 ++- worlds/alttp/Rules.py | 21 +++++++++++---------- worlds/minecraft/docs/minecraft_es.md | 2 +- worlds/minecraft/docs/minecraft_sv.md | 2 +- worlds/smz3/Options.py | 3 ++- worlds/smz3/__init__.py | 2 +- 8 files changed, 35 insertions(+), 23 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 75cd317a73..43057a956c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -6,6 +6,7 @@ import json import logging import random import secrets +import sys import typing # this can go away when Python 3.8 support is dropped from argparse import Namespace from collections import OrderedDict, Counter, deque @@ -569,7 +570,7 @@ class MultiWorld(): if not state: state = CollectionState(self) players: Dict[str, Set[int]] = { - "minimal": set(), + "full": set(), "items": set(), "locations": set() } @@ -586,9 +587,10 @@ class MultiWorld(): def location_relevant(location: Location): """Determine if this location is relevant to sweep.""" - if location.progress_type != LocationProgressType.EXCLUDED \ - and (location.player in players["locations"] or location.event - or (location.item and location.item.advancement)): + if getattr(sys, "gettrace", None) \ + and location.progress_type != LocationProgressType.EXCLUDED \ + and (location.player in players["locations"] or location.event + or (location.item and location.item.advancement)): return True return False diff --git a/Options.py b/Options.py index 10add11be6..17112644d6 100644 --- a/Options.py +++ b/Options.py @@ -835,14 +835,21 @@ local_objective = Toggle # local triforce pieces, local dungeon prizes etc. class Accessibility(Choice): """Set rules for reachability of your items/locations. - Locations: ensure everything can be reached and acquired. - Items: ensure all logically relevant items can be acquired. + Full: ensure everything can be reached and acquired. Minimal: ensure what is needed to reach your goal can be acquired.""" display_name = "Accessibility" - option_locations = 0 - option_items = 1 + option_full = 0 option_minimal = 2 alias_none = 2 + default = 0 + + +class ItemsAccessibility(Accessibility): + """Set rules for reachability of your items/locations. + Full: ensure everything can be reached and acquired. + Items: all logically relevant items can be acquired. Some items, such as keys, may be self-locking. + Minimal: ensure what is needed to reach your goal can be acquired.""" + option_items = 1 default = 1 diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index b1cfbc674e..90ae118771 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -1,7 +1,7 @@ import typing from BaseClasses import MultiWorld -from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, TextChoice, PlandoBosses +from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, PlandoBosses, ItemsAccessibility class Logic(Choice): @@ -402,6 +402,7 @@ class AllowCollect(Toggle): alttp_options: typing.Dict[str, type(Option)] = { + "accessibility": ItemsAccessibility, "crystals_needed_for_gt": CrystalsTower, "crystals_needed_for_ganon": CrystalsGanon, "open_pyramid": OpenPyramid, diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index a31641d679..7f863ec2a6 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -2,6 +2,7 @@ import collections import logging from typing import Iterator, Set +from Options import ItemsAccessibility from worlds.alttp import OverworldGlitchRules from BaseClasses import MultiWorld, Entrance from worlds.alttp.Items import ItemFactory, progression_items, item_name_groups, item_table @@ -33,7 +34,7 @@ def set_rules(world): else: # Set access rules according to max glitches for multiworld progression. # Set accessibility to none, and shuffle assuming the no logic players can always win - world.accessibility[player] = world.accessibility[player].from_text("minimal") + world.accessibility[player].value = ItemsAccessibility.option_minimal world.progression_balancing[player].value = 0 else: @@ -265,14 +266,14 @@ def global_rules(world, player): set_rule(world.get_entrance('Tower of Hera Big Key Door', player), lambda state: state.has('Big Key (Tower of Hera)', player)) set_rule(world.get_location('Tower of Hera - Big Chest', player), lambda state: state.has('Big Key (Tower of Hera)', player)) set_rule(world.get_location('Tower of Hera - Big Key Chest', player), lambda state: state.has_fire_source(player)) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Tower of Hera - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Tower of Hera)' and item.player == player) set_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Flippers', player) and state.has('Open Floodgate', player)) set_rule(world.get_entrance('Swamp Palace Small Key Door', player), lambda state: state._lttp_has_key('Small Key (Swamp Palace)', player)) set_rule(world.get_entrance('Swamp Palace (Center)', player), lambda state: state.has('Hammer', player)) set_rule(world.get_location('Swamp Palace - Big Chest', player), lambda state: state.has('Big Key (Swamp Palace)', player) or item_name(state, 'Swamp Palace - Big Chest', player) == ('Big Key (Swamp Palace)', player)) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Swamp Palace - Big Chest', player), lambda state, item: item.name == 'Big Key (Swamp Palace)' and item.player == player) set_rule(world.get_entrance('Swamp Palace (North)', player), lambda state: state.has('Hookshot', player)) if not world.smallkey_shuffle[player] and world.logic[player] not in ['hybridglitches', 'nologic']: @@ -281,7 +282,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Thieves Town Big Key Door', player), lambda state: state.has('Big Key (Thieves Town)', player)) set_rule(world.get_entrance('Blind Fight', player), lambda state: state._lttp_has_key('Small Key (Thieves Town)', player)) set_rule(world.get_location('Thieves\' Town - Big Chest', player), lambda state: (state._lttp_has_key('Small Key (Thieves Town)', player) or item_name(state, 'Thieves\' Town - Big Chest', player) == ('Small Key (Thieves Town)', player)) and state.has('Hammer', player)) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Thieves\' Town - Big Chest', player), lambda state, item: item.name == 'Small Key (Thieves Town)' and item.player == player and state.has('Hammer', player)) set_rule(world.get_location('Thieves\' Town - Attic', player), lambda state: state._lttp_has_key('Small Key (Thieves Town)', player)) @@ -290,7 +291,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Skull Woods First Section West Door', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 2)) # ideally would only be one key, but we may have spent thst key already on escaping the right section set_rule(world.get_entrance('Skull Woods First Section (Left) Door to Exit', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 2)) set_rule(world.get_location('Skull Woods - Big Chest', player), lambda state: state.has('Big Key (Skull Woods)', player) or item_name(state, 'Skull Woods - Big Chest', player) == ('Big Key (Skull Woods)', player)) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Skull Woods - Big Chest', player), lambda state, item: item.name == 'Big Key (Skull Woods)' and item.player == player) set_rule(world.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 3) and state.has('Fire Rod', player) and state.has_sword(player)) # sword required for curtain @@ -344,12 +345,12 @@ def global_rules(world, player): set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( item_name(state, 'Palace of Darkness - Big Key Chest', player) in [('Small Key (Palace of Darkness)', player)] and state._lttp_has_key('Small Key (Palace of Darkness)', player, 3))) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Palace of Darkness - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Palace of Darkness)' and item.player == player and state._lttp_has_key('Small Key (Palace of Darkness)', player, 5)) set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( item_name(state, 'Palace of Darkness - Harmless Hellway', player) in [('Small Key (Palace of Darkness)', player)] and state._lttp_has_key('Small Key (Palace of Darkness)', player, 4))) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Palace of Darkness - Harmless Hellway', player), lambda state, item: item.name == 'Small Key (Palace of Darkness)' and item.player == player and state._lttp_has_key('Small Key (Palace of Darkness)', player, 5)) set_rule(world.get_entrance('Palace of Darkness Maze Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6)) @@ -363,7 +364,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hammer', player) and (state.has('Hookshot', player) or state.has('Pegasus Boots', player))) set_rule(world.get_entrance('Ganons Tower (Map Room)', player), lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 4) or ( item_name(state, 'Ganons Tower - Map Chest', player) in [('Big Key (Ganons Tower)', player), ('Small Key (Ganons Tower)', player)] and state._lttp_has_key('Small Key (Ganons Tower)', player, 3))) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Ganons Tower - Map Chest', player), lambda state, item: item.name == 'Small Key (Ganons Tower)' and item.player == player and state._lttp_has_key('Small Key (Ganons Tower)', player, 3) and state.can_reach('Ganons Tower (Hookshot Room)', 'region', player)) # It is possible to need more than 2 keys to get through this entrance if you spend keys elsewhere. We reflect this in the chest requirements. @@ -938,7 +939,7 @@ def set_trock_key_rules(world, player): if not can_reach_big_chest: # Must not go in the Chain Chomps chest - only 2 other chests available and 3+ keys required for all other chests forbid_item(world.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player) - if world.accessibility[player] == 'locations' and world.goal[player] != 'icerodhunt': + if world.accessibility[player] == 'full' and world.goal[player] != 'icerodhunt': if world.bigkey_shuffle[player] and can_reach_big_chest: # Must not go in the dungeon - all 3 available chests (Chomps, Big Chest, Crystaroller) must be keys to access laser bridge, and the big key is required first for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest', @@ -952,7 +953,7 @@ def set_trock_key_rules(world, player): location.event = True toss_junk_item(world, player) - if world.accessibility[player] != 'locations': + if world.accessibility[player] != 'full': set_always_allow(world.get_location('Turtle Rock - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Turtle Rock)' and item.player == player and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player))) diff --git a/worlds/minecraft/docs/minecraft_es.md b/worlds/minecraft/docs/minecraft_es.md index 3f2df6e7ba..4f48992122 100644 --- a/worlds/minecraft/docs/minecraft_es.md +++ b/worlds/minecraft/docs/minecraft_es.md @@ -29,7 +29,7 @@ name: TuNombre game: Minecraft # Opciones compartidas por todos los juegos: -accessibility: locations +accessibility: full progression_balancing: 50 # Opciones Especficicas para Minecraft diff --git a/worlds/minecraft/docs/minecraft_sv.md b/worlds/minecraft/docs/minecraft_sv.md index e86d293939..f2dc84cfa2 100644 --- a/worlds/minecraft/docs/minecraft_sv.md +++ b/worlds/minecraft/docs/minecraft_sv.md @@ -79,7 +79,7 @@ description: Template Name # Ditt spelnamn. Mellanslag kommer bli omplacerad med understräck och det är en 16-karaktärsgräns. name: YourName game: Minecraft -accessibility: locations +accessibility: full progression_balancing: 0 advancement_goal: few: 0 diff --git a/worlds/smz3/Options.py b/worlds/smz3/Options.py index e3d8b8dd10..7ac98cb439 100644 --- a/worlds/smz3/Options.py +++ b/worlds/smz3/Options.py @@ -1,5 +1,5 @@ import typing -from Options import Choice, Option, Toggle, DefaultOnToggle, Range +from Options import Choice, Option, Toggle, DefaultOnToggle, Range, ItemsAccessibility class SMLogic(Choice): """This option selects what kind of logic to use for item placement inside @@ -128,6 +128,7 @@ class EnergyBeep(DefaultOnToggle): smz3_options: typing.Dict[str, type(Option)] = { + "accessibility": ItemsAccessibility, "sm_logic": SMLogic, "sword_location": SwordLocation, "morph_location": MorphLocation, diff --git a/worlds/smz3/__init__.py b/worlds/smz3/__init__.py index 93ac7fbddf..c14cbe35d2 100644 --- a/worlds/smz3/__init__.py +++ b/worlds/smz3/__init__.py @@ -241,7 +241,7 @@ class SMZ3World(World): set_rule(entrance, lambda state, region=region: region.CanEnter(state.smz3state[self.player])) for loc in region.Locations: l = self.locations[loc.Name] - if self.multiworld.accessibility[self.player] != 'locations': + if self.multiworld.accessibility[self.player] != 'full': l.always_allow = lambda state, item, loc=loc: \ item.game == "SMZ3" and \ loc.alwaysAllow(item.item, state.smz3state[self.player])