Core: Rework accessibility (#1481)

* rename locations accessibility to "full" and make old locations accessibility debug only

* fix a bug in oot

* reorder lttp tests to not override its overrides

* changed the wrong word in the dict

* :forehead:

* update the manual lttp yaml

* use __debug__

* update pokemon and messenger

* fix conflicts from 993

* fix stardew presets

* add that locations may be inaccessible to description

* use reST format and make the items description one line so that it renders correctly on webhost

* forgot i renamed that

* add aliases for back compat

* some cleanup

* fix imports

* fix test failure

* only check "items" players when the item is progression

* Revert "only check "items" players when the item is progression"

This reverts commit ecbf986145e6194aa99a39c481d8ecd0736d5a4c.

* remove some unnecessary diffs

* CV64: Add ItemsAccessibility

* put items description at the bottom of the docstring since that's it's visual order

* :

* rename accessibility reference in pokemon rb dexsanity

* make the rendered tooltips look nicer
This commit is contained in:
Aaron Wagener 2024-07-31 05:13:14 -05:00 committed by GitHub
parent 83521e99d9
commit a05dbac55f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 75 additions and 57 deletions

View File

@ -64,7 +64,6 @@ class MultiWorld():
state: CollectionState state: CollectionState
plando_options: PlandoOptions plando_options: PlandoOptions
accessibility: Dict[int, Options.Accessibility]
early_items: Dict[int, Dict[str, int]] early_items: Dict[int, Dict[str, int]]
local_early_items: Dict[int, Dict[str, int]] local_early_items: Dict[int, Dict[str, int]]
local_items: Dict[int, Options.LocalItems] local_items: Dict[int, Options.LocalItems]
@ -602,26 +601,22 @@ class MultiWorld():
players: Dict[str, Set[int]] = { players: Dict[str, Set[int]] = {
"minimal": set(), "minimal": set(),
"items": set(), "items": set(),
"locations": set() "full": set()
} }
for player, access in self.accessibility.items(): for player, world in self.worlds.items():
players[access.current_key].add(player) players[world.options.accessibility.current_key].add(player)
beatable_fulfilled = False beatable_fulfilled = False
def location_condition(location: Location): def location_condition(location: Location) -> bool:
"""Determine if this location has to be accessible, location is already filtered by location_relevant""" """Determine if this location has to be accessible, location is already filtered by location_relevant"""
if location.player in players["locations"] or (location.item and location.item.player not in return location.player in players["full"] or \
players["minimal"]): (location.item and location.item.player not in players["minimal"])
return True
return False
def location_relevant(location: Location): def location_relevant(location: Location) -> bool:
"""Determine if this location is relevant to sweep.""" """Determine if this location is relevant to sweep."""
if location.progress_type != LocationProgressType.EXCLUDED \ return location.progress_type != LocationProgressType.EXCLUDED \
and (location.player in players["locations"] or location.advancement): and (location.player in players["full"] or location.advancement)
return True
return False
def all_done() -> bool: def all_done() -> bool:
"""Check if all access rules are fulfilled""" """Check if all access rules are fulfilled"""

View File

@ -1144,18 +1144,35 @@ class PlandoConnections(Option[typing.List[PlandoConnection]], metaclass=Connect
class Accessibility(Choice): class Accessibility(Choice):
"""Set rules for reachability of your items/locations. """
Set rules for reachability of your items/locations.
**Full:** ensure everything can be reached and acquired.
- **Locations:** ensure everything can be reached and acquired. **Minimal:** ensure what is needed to reach your goal can be acquired.
- **Items:** ensure all logically relevant items can be acquired.
- **Minimal:** ensure what is needed to reach your goal can be acquired.
""" """
display_name = "Accessibility" display_name = "Accessibility"
rich_text_doc = True rich_text_doc = True
option_locations = 0 option_full = 0
option_items = 1
option_minimal = 2 option_minimal = 2
alias_none = 2 alias_none = 2
alias_locations = 0
alias_items = 0
default = 0
class ItemsAccessibility(Accessibility):
"""
Set rules for reachability of your items/locations.
**Full:** ensure everything can be reached and acquired.
**Minimal:** ensure what is needed to reach your goal can be acquired.
**Items:** ensure all logically relevant items can be acquired. Some items, such as keys, may be self-locking, and
some locations may be inaccessible.
"""
option_items = 1
default = 1 default = 1

View File

@ -174,8 +174,8 @@ class TestFillRestrictive(unittest.TestCase):
player1 = generate_player_data(multiworld, 1, 3, 3) player1 = generate_player_data(multiworld, 1, 3, 3)
player2 = generate_player_data(multiworld, 2, 3, 3) player2 = generate_player_data(multiworld, 2, 3, 3)
multiworld.accessibility[player1.id].value = multiworld.accessibility[player1.id].option_minimal multiworld.worlds[player1.id].options.accessibility.value = Accessibility.option_minimal
multiworld.accessibility[player2.id].value = multiworld.accessibility[player2.id].option_locations multiworld.worlds[player2.id].options.accessibility.value = Accessibility.option_full
multiworld.completion_condition[player1.id] = lambda state: True multiworld.completion_condition[player1.id] = lambda state: True
multiworld.completion_condition[player2.id] = lambda state: state.has(player2.prog_items[2].name, player2.id) multiworld.completion_condition[player2.id] = lambda state: state.has(player2.prog_items[2].name, player2.id)

View File

@ -69,7 +69,7 @@ class TestTwoPlayerMulti(MultiworldTestBase):
for world in AutoWorldRegister.world_types.values(): for world in AutoWorldRegister.world_types.values():
self.multiworld = setup_multiworld([world, world], ()) self.multiworld = setup_multiworld([world, world], ())
for world in self.multiworld.worlds.values(): for world in self.multiworld.worlds.values():
world.options.accessibility.value = Accessibility.option_locations world.options.accessibility.value = Accessibility.option_full
self.assertSteps(gen_steps) self.assertSteps(gen_steps)
with self.subTest("filling multiworld", seed=self.multiworld.seed): with self.subTest("filling multiworld", seed=self.multiworld.seed):
distribute_items_restrictive(self.multiworld) distribute_items_restrictive(self.multiworld)

View File

@ -1,8 +1,8 @@
import typing import typing
from BaseClasses import MultiWorld from BaseClasses import MultiWorld
from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, \ from Options import Choice, Range, DeathLink, DefaultOnToggle, FreeText, ItemsAccessibility, Option, \
StartInventoryPool, PlandoBosses, PlandoConnections, PlandoTexts, FreeText, Removed PlandoBosses, PlandoConnections, PlandoTexts, Removed, StartInventoryPool, Toggle
from .EntranceShuffle import default_connections, default_dungeon_connections, \ from .EntranceShuffle import default_connections, default_dungeon_connections, \
inverted_default_connections, inverted_default_dungeon_connections inverted_default_connections, inverted_default_dungeon_connections
from .Text import TextTable from .Text import TextTable
@ -743,6 +743,7 @@ class ALttPPlandoTexts(PlandoTexts):
alttp_options: typing.Dict[str, type(Option)] = { alttp_options: typing.Dict[str, type(Option)] = {
"accessibility": ItemsAccessibility,
"plando_connections": ALttPPlandoConnections, "plando_connections": ALttPPlandoConnections,
"plando_texts": ALttPPlandoTexts, "plando_texts": ALttPPlandoTexts,
"start_inventory_from_pool": StartInventoryPool, "start_inventory_from_pool": StartInventoryPool,

View File

@ -2,6 +2,7 @@ import collections
import logging import logging
from typing import Iterator, Set from typing import Iterator, Set
from Options import ItemsAccessibility
from BaseClasses import Entrance, MultiWorld from BaseClasses import Entrance, MultiWorld
from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item, from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item,
item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items) item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items)
@ -39,7 +40,7 @@ def set_rules(world):
else: else:
# Set access rules according to max glitches for multiworld progression. # Set access rules according to max glitches for multiworld progression.
# Set accessibility to none, and shuffle assuming the no logic players can always win # 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 world.progression_balancing[player].value = 0
else: else:
@ -377,7 +378,7 @@ def global_rules(multiworld: MultiWorld, player: int):
or state.has("Cane of Somaria", player))) or state.has("Cane of Somaria", player)))
set_rule(multiworld.get_location('Tower of Hera - Big Chest', player), lambda state: state.has('Big Key (Tower of Hera)', player)) set_rule(multiworld.get_location('Tower of Hera - Big Chest', player), lambda state: state.has('Big Key (Tower of Hera)', player))
set_rule(multiworld.get_location('Tower of Hera - Big Key Chest', player), lambda state: has_fire_source(state, player)) set_rule(multiworld.get_location('Tower of Hera - Big Key Chest', player), lambda state: has_fire_source(state, player))
if multiworld.accessibility[player] != 'locations': if multiworld.accessibility[player] != 'full':
set_always_allow(multiworld.get_location('Tower of Hera - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Tower of Hera)' and item.player == player) set_always_allow(multiworld.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(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Flippers', player) and state.has('Open Floodgate', player)) set_rule(multiworld.get_entrance('Swamp Palace Moat', player), lambda state: state.has('Flippers', player) and state.has('Open Floodgate', player))
@ -393,7 +394,7 @@ def global_rules(multiworld: MultiWorld, player: int):
if state.has('Hookshot', player) if state.has('Hookshot', player)
else state._lttp_has_key('Small Key (Swamp Palace)', player, 4)) else state._lttp_has_key('Small Key (Swamp Palace)', player, 4))
set_rule(multiworld.get_location('Swamp Palace - Big Chest', player), lambda state: state.has('Big Key (Swamp Palace)', player)) set_rule(multiworld.get_location('Swamp Palace - Big Chest', player), lambda state: state.has('Big Key (Swamp Palace)', player))
if multiworld.accessibility[player] != 'locations': if multiworld.accessibility[player] != 'full':
allow_self_locking_items(multiworld.get_location('Swamp Palace - Big Chest', player), 'Big Key (Swamp Palace)') allow_self_locking_items(multiworld.get_location('Swamp Palace - Big Chest', player), 'Big Key (Swamp Palace)')
set_rule(multiworld.get_entrance('Swamp Palace (North)', player), lambda state: state.has('Hookshot', player) and state._lttp_has_key('Small Key (Swamp Palace)', player, 5)) set_rule(multiworld.get_entrance('Swamp Palace (North)', player), lambda state: state.has('Hookshot', player) and state._lttp_has_key('Small Key (Swamp Palace)', player, 5))
if not multiworld.small_key_shuffle[player] and multiworld.glitches_required[player] not in ['hybrid_major_glitches', 'no_logic']: if not multiworld.small_key_shuffle[player] and multiworld.glitches_required[player] not in ['hybrid_major_glitches', 'no_logic']:
@ -423,7 +424,7 @@ def global_rules(multiworld: MultiWorld, player: int):
set_rule(multiworld.get_entrance('Skull Woods First Section West Door', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) set_rule(multiworld.get_entrance('Skull Woods First Section West Door', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5))
set_rule(multiworld.get_entrance('Skull Woods First Section (Left) Door to Exit', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) set_rule(multiworld.get_entrance('Skull Woods First Section (Left) Door to Exit', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5))
set_rule(multiworld.get_location('Skull Woods - Big Chest', player), lambda state: state.has('Big Key (Skull Woods)', player) and can_use_bombs(state, player)) set_rule(multiworld.get_location('Skull Woods - Big Chest', player), lambda state: state.has('Big Key (Skull Woods)', player) and can_use_bombs(state, player))
if multiworld.accessibility[player] != 'locations': if multiworld.accessibility[player] != 'full':
allow_self_locking_items(multiworld.get_location('Skull Woods - Big Chest', player), 'Big Key (Skull Woods)') allow_self_locking_items(multiworld.get_location('Skull Woods - Big Chest', player), 'Big Key (Skull Woods)')
set_rule(multiworld.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 4) and state.has('Fire Rod', player) and has_sword(state, player)) # sword required for curtain set_rule(multiworld.get_entrance('Skull Woods Torch Room', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 4) and state.has('Fire Rod', player) and has_sword(state, player)) # sword required for curtain
add_rule(multiworld.get_location('Skull Woods - Prize', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5)) add_rule(multiworld.get_location('Skull Woods - Prize', player), lambda state: state._lttp_has_key('Small Key (Skull Woods)', player, 5))
@ -522,12 +523,12 @@ def global_rules(multiworld: MultiWorld, player: int):
set_rule(multiworld.get_entrance('Palace of Darkness Big Key Chest Staircase', player), lambda state: can_use_bombs(state, player) and (state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( set_rule(multiworld.get_entrance('Palace of Darkness Big Key Chest Staircase', player), lambda state: can_use_bombs(state, player) and (state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or (
location_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)))) location_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 multiworld.accessibility[player] != 'locations': if multiworld.accessibility[player] != 'full':
set_always_allow(multiworld.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_always_allow(multiworld.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(multiworld.get_entrance('Palace of Darkness Spike Statue Room Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or ( set_rule(multiworld.get_entrance('Palace of Darkness Spike Statue Room Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6) or (
location_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))) location_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 multiworld.accessibility[player] != 'locations': if multiworld.accessibility[player] != 'full':
set_always_allow(multiworld.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_always_allow(multiworld.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(multiworld.get_entrance('Palace of Darkness Maze Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6)) set_rule(multiworld.get_entrance('Palace of Darkness Maze Door', player), lambda state: state._lttp_has_key('Small Key (Palace of Darkness)', player, 6))
@ -1200,7 +1201,7 @@ def set_trock_key_rules(world, player):
# Must not go in the Chain Chomps chest - only 2 other chests available and 3+ keys required for all other chests # 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) forbid_item(world.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player)
forbid_item(world.get_location('Turtle Rock - Pokey 2 Key Drop', player), 'Big Key (Turtle Rock)', player) forbid_item(world.get_location('Turtle Rock - Pokey 2 Key Drop', player), 'Big Key (Turtle Rock)', player)
if world.accessibility[player] == 'locations': if world.accessibility[player] == 'full':
if world.big_key_shuffle[player] and can_reach_big_chest: if world.big_key_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 # 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', for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest',
@ -1214,7 +1215,7 @@ def set_trock_key_rules(world, player):
location.place_locked_item(item) location.place_locked_item(item)
toss_junk_item(world, player) 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 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))) and state.can_reach(state.multiworld.get_region('Turtle Rock (Second Section)', player)))

View File

@ -1,11 +1,11 @@
from worlds.alttp.Dungeons import create_dungeons, get_dungeon_item_pool from worlds.alttp.Dungeons import get_dungeon_item_pool
from worlds.alttp.EntranceShuffle import link_inverted_entrances from worlds.alttp.EntranceShuffle import link_inverted_entrances
from worlds.alttp.InvertedRegions import create_inverted_regions from worlds.alttp.InvertedRegions import create_inverted_regions
from worlds.alttp.ItemPool import difficulties from worlds.alttp.ItemPool import difficulties
from worlds.alttp.Items import item_factory from worlds.alttp.Items import item_factory
from worlds.alttp.Regions import mark_light_world_regions from worlds.alttp.Regions import mark_light_world_regions
from worlds.alttp.Shops import create_shops from worlds.alttp.Shops import create_shops
from test.TestBase import TestBase from test.bases import TestBase
from worlds.alttp.test import LTTPTestBase from worlds.alttp.test import LTTPTestBase

View File

@ -6,7 +6,7 @@ from worlds.alttp.Items import item_factory
from worlds.alttp.Options import GlitchesRequired from worlds.alttp.Options import GlitchesRequired
from worlds.alttp.Regions import mark_light_world_regions from worlds.alttp.Regions import mark_light_world_regions
from worlds.alttp.Shops import create_shops from worlds.alttp.Shops import create_shops
from test.TestBase import TestBase from test.bases import TestBase
from worlds.alttp.test import LTTPTestBase from worlds.alttp.test import LTTPTestBase

View File

@ -6,7 +6,7 @@ from worlds.alttp.Items import item_factory
from worlds.alttp.Options import GlitchesRequired from worlds.alttp.Options import GlitchesRequired
from worlds.alttp.Regions import mark_light_world_regions from worlds.alttp.Regions import mark_light_world_regions
from worlds.alttp.Shops import create_shops from worlds.alttp.Shops import create_shops
from test.TestBase import TestBase from test.bases import TestBase
from worlds.alttp.test import LTTPTestBase from worlds.alttp.test import LTTPTestBase

View File

@ -1,5 +1,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from Options import OptionGroup, Choice, DefaultOnToggle, Range, Toggle, PerGameCommonOptions, StartInventoryPool from Options import (OptionGroup, Choice, DefaultOnToggle, ItemsAccessibility, PerGameCommonOptions, Range, Toggle,
StartInventoryPool)
class CharacterStages(Choice): class CharacterStages(Choice):
@ -521,6 +522,7 @@ class DeathLink(Choice):
@dataclass @dataclass
class CV64Options(PerGameCommonOptions): class CV64Options(PerGameCommonOptions):
accessibility: ItemsAccessibility
start_inventory_from_pool: StartInventoryPool start_inventory_from_pool: StartInventoryPool
character_stages: CharacterStages character_stages: CharacterStages
stage_shuffle: StageShuffle stage_shuffle: StageShuffle

View File

@ -216,7 +216,7 @@ def stage_set_rules(multiworld):
multiworld.worlds[player].options.accessibility == "minimal"]) * 3): multiworld.worlds[player].options.accessibility == "minimal"]) * 3):
for player in no_enemies_players: for player in no_enemies_players:
for location in vendor_locations: for location in vendor_locations:
if multiworld.worlds[player].options.accessibility == "locations": if multiworld.worlds[player].options.accessibility == "full":
multiworld.get_location(location, player).progress_type = LocationProgressType.EXCLUDED multiworld.get_location(location, player).progress_type = LocationProgressType.EXCLUDED
else: else:
multiworld.get_location(location, player).access_rule = lambda state: False multiworld.get_location(location, player).access_rule = lambda state: False

View File

@ -3,15 +3,15 @@ from typing import Dict
from schema import And, Optional, Or, Schema from schema import And, Optional, Or, Schema
from Options import Accessibility, Choice, DeathLinkMixin, DefaultOnToggle, OptionDict, PerGameCommonOptions, \ from Options import Choice, DeathLinkMixin, DefaultOnToggle, ItemsAccessibility, OptionDict, PerGameCommonOptions, \
PlandoConnections, Range, StartInventoryPool, Toggle, Visibility PlandoConnections, Range, StartInventoryPool, Toggle, Visibility
from .portals import CHECKPOINTS, PORTALS, SHOP_POINTS from .portals import CHECKPOINTS, PORTALS, SHOP_POINTS
class MessengerAccessibility(Accessibility): class MessengerAccessibility(ItemsAccessibility):
default = Accessibility.option_locations
# defaulting to locations accessibility since items makes certain items self-locking # defaulting to locations accessibility since items makes certain items self-locking
__doc__ = Accessibility.__doc__.replace(f"default {Accessibility.default}", f"default {default}") default = ItemsAccessibility.option_full
__doc__ = ItemsAccessibility.__doc__
class PortalPlando(PlandoConnections): class PortalPlando(PlandoConnections):

View File

@ -29,7 +29,7 @@ name: TuNombre
game: Minecraft game: Minecraft
# Opciones compartidas por todos los juegos: # Opciones compartidas por todos los juegos:
accessibility: locations accessibility: full
progression_balancing: 50 progression_balancing: 50
# Opciones Especficicas para Minecraft # Opciones Especficicas para Minecraft

View File

@ -79,7 +79,7 @@ description: Template Name
# Ditt spelnamn. Mellanslag kommer bli omplacerad med understräck och det är en 16-karaktärsgräns. # Ditt spelnamn. Mellanslag kommer bli omplacerad med understräck och det är en 16-karaktärsgräns.
name: YourName name: YourName
game: Minecraft game: Minecraft
accessibility: locations accessibility: full
progression_balancing: 0 progression_balancing: 0
advancement_goal: advancement_goal:
few: 0 few: 0

View File

@ -443,7 +443,7 @@ class PokemonRedBlueWorld(World):
self.multiworld.elite_four_pokedex_condition[self.player].total = \ self.multiworld.elite_four_pokedex_condition[self.player].total = \
int((len(reachable_mons) / 100) * self.multiworld.elite_four_pokedex_condition[self.player].value) int((len(reachable_mons) / 100) * self.multiworld.elite_four_pokedex_condition[self.player].value)
if self.multiworld.accessibility[self.player] == "locations": if self.multiworld.accessibility[self.player] == "full":
balls = [self.create_item(ball) for ball in ["Poke Ball", "Great Ball", "Ultra Ball"]] balls = [self.create_item(ball) for ball in ["Poke Ball", "Great Ball", "Ultra Ball"]]
traps = [self.create_item(trap) for trap in item_groups["Traps"]] traps = [self.create_item(trap) for trap in item_groups["Traps"]]
locations = [location for location in self.multiworld.get_locations(self.player) if "Pokedex - " in locations = [location for location in self.multiworld.get_locations(self.player) if "Pokedex - " in

View File

@ -1,4 +1,4 @@
from Options import Toggle, Choice, Range, NamedRange, TextChoice, DeathLink from Options import Toggle, Choice, Range, NamedRange, TextChoice, DeathLink, ItemsAccessibility
class GameVersion(Choice): class GameVersion(Choice):
@ -287,7 +287,7 @@ class AllPokemonSeen(Toggle):
class DexSanity(NamedRange): class DexSanity(NamedRange):
"""Adds location checks for Pokemon flagged "owned" on your Pokedex. You may specify a percentage of Pokemon to """Adds location checks for Pokemon flagged "owned" on your Pokedex. You may specify a percentage of Pokemon to
have checks added. If Accessibility is set to locations, this will be the percentage of all logically reachable have checks added. If Accessibility is set to full, this will be the percentage of all logically reachable
Pokemon that will get a location check added to it. With items or minimal Accessibility, it will be the percentage Pokemon that will get a location check added to it. With items or minimal Accessibility, it will be the percentage
of all 151 Pokemon. of all 151 Pokemon.
If Pokedex is required, the items for Pokemon acquired before acquiring the Pokedex can be found by talking to If Pokedex is required, the items for Pokemon acquired before acquiring the Pokedex can be found by talking to
@ -861,6 +861,7 @@ class RandomizePokemonPalettes(Choice):
pokemon_rb_options = { pokemon_rb_options = {
"accessibility": ItemsAccessibility,
"game_version": GameVersion, "game_version": GameVersion,
"trainer_name": TrainerName, "trainer_name": TrainerName,
"rival_name": RivalName, "rival_name": RivalName,

View File

@ -22,7 +22,7 @@ def set_rules(multiworld, player):
item_rules["Celadon Prize Corner - Item Prize 2"] = prize_rule item_rules["Celadon Prize Corner - Item Prize 2"] = prize_rule
item_rules["Celadon Prize Corner - Item Prize 3"] = prize_rule item_rules["Celadon Prize Corner - Item Prize 3"] = prize_rule
if multiworld.accessibility[player] != "locations": if multiworld.accessibility[player] != "full":
multiworld.get_location("Cerulean Bicycle Shop", player).always_allow = (lambda state, item: multiworld.get_location("Cerulean Bicycle Shop", player).always_allow = (lambda state, item:
item.name == "Bike Voucher" item.name == "Bike Voucher"
and item.player == player) and item.player == player)

View File

@ -1,5 +1,5 @@
import typing import typing
from Options import Choice, Option, Toggle, DefaultOnToggle, Range from Options import Choice, Option, Toggle, DefaultOnToggle, Range, ItemsAccessibility
class SMLogic(Choice): class SMLogic(Choice):
"""This option selects what kind of logic to use for item placement inside """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)] = { smz3_options: typing.Dict[str, type(Option)] = {
"accessibility": ItemsAccessibility,
"sm_logic": SMLogic, "sm_logic": SMLogic,
"sword_location": SwordLocation, "sword_location": SwordLocation,
"morph_location": MorphLocation, "morph_location": MorphLocation,

View File

@ -244,7 +244,7 @@ class SMZ3World(World):
set_rule(entrance, lambda state, region=region: region.CanEnter(state.smz3state[self.player])) set_rule(entrance, lambda state, region=region: region.CanEnter(state.smz3state[self.player]))
for loc in region.Locations: for loc in region.Locations:
l = self.locations[loc.Name] 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: \ l.always_allow = lambda state, item, loc=loc: \
item.game == "SMZ3" and \ item.game == "SMZ3" and \
loc.alwaysAllow(item.item, state.smz3state[self.player]) loc.alwaysAllow(item.item, state.smz3state[self.player])

View File

@ -58,7 +58,7 @@ all_random_settings = {
easy_settings = { easy_settings = {
"progression_balancing": ProgressionBalancing.default, "progression_balancing": ProgressionBalancing.default,
"accessibility": Accessibility.option_items, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.option_community_center, Goal.internal_name: Goal.option_community_center,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: "very rich", StartingMoney.internal_name: "very rich",
@ -104,7 +104,7 @@ easy_settings = {
medium_settings = { medium_settings = {
"progression_balancing": 25, "progression_balancing": 25,
"accessibility": Accessibility.option_locations, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.option_community_center, Goal.internal_name: Goal.option_community_center,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: "rich", StartingMoney.internal_name: "rich",
@ -150,7 +150,7 @@ medium_settings = {
hard_settings = { hard_settings = {
"progression_balancing": 0, "progression_balancing": 0,
"accessibility": Accessibility.option_locations, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.option_grandpa_evaluation, Goal.internal_name: Goal.option_grandpa_evaluation,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: "extra", StartingMoney.internal_name: "extra",
@ -196,7 +196,7 @@ hard_settings = {
nightmare_settings = { nightmare_settings = {
"progression_balancing": 0, "progression_balancing": 0,
"accessibility": Accessibility.option_locations, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.option_community_center, Goal.internal_name: Goal.option_community_center,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: "vanilla", StartingMoney.internal_name: "vanilla",
@ -242,7 +242,7 @@ nightmare_settings = {
short_settings = { short_settings = {
"progression_balancing": ProgressionBalancing.default, "progression_balancing": ProgressionBalancing.default,
"accessibility": Accessibility.option_items, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.option_bottom_of_the_mines, Goal.internal_name: Goal.option_bottom_of_the_mines,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: "filthy rich", StartingMoney.internal_name: "filthy rich",
@ -334,7 +334,7 @@ minsanity_settings = {
allsanity_settings = { allsanity_settings = {
"progression_balancing": ProgressionBalancing.default, "progression_balancing": ProgressionBalancing.default,
"accessibility": Accessibility.option_locations, "accessibility": Accessibility.option_full,
Goal.internal_name: Goal.default, Goal.internal_name: Goal.default,
FarmType.internal_name: "random", FarmType.internal_name: "random",
StartingMoney.internal_name: StartingMoney.default, StartingMoney.internal_name: StartingMoney.default,