Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Witness: Shuffle Dog #3425

Merged
merged 15 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions worlds/witness/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ def create_regions(self) -> None:
event_locations.append(location_obj)

# Place other locked items
dog_puzzle_skip = self.create_item("Puzzle Skip")
self.get_location("Town Pet the Dog").place_locked_item(dog_puzzle_skip)

self.own_itempool.append(dog_puzzle_skip)
if self.options.shuffle_dog == "puzzle_skip":
dog_puzzle_skip = self.create_item("Puzzle Skip")
self.get_location("Town Pet the Dog").place_locked_item(dog_puzzle_skip)

self.items_placed_early.append("Puzzle Skip")
self.own_itempool.append(dog_puzzle_skip)
self.items_placed_early.append("Puzzle Skip")

if self.options.early_symbol_item:
# Pick an early item to place on the tutorial gate.
Expand All @@ -213,19 +214,22 @@ def create_regions(self) -> None:
self.own_itempool.append(gate_item)
self.items_placed_early.append(random_early_item)

# There are some really restrictive settings in The Witness.
# There are some really restrictive options in The Witness.
# They are rarely played, but when they are, we add some extra sphere 1 locations.
# This is done both to prevent generation failures, but also to make the early game less linear.
# Only sweeps for events because having this behavior be random based on Tutorial Gate would be strange.

state = CollectionState(self.multiworld)
state.sweep_for_events(locations=event_locations)

num_early_locs = sum(1 for loc in self.multiworld.get_reachable_locations(state, self.player) if loc.address)
num_early_locs = sum(
1 for loc in self.multiworld.get_reachable_locations(state, self.player)
if loc.address and not loc.item
)

# Adjust the needed size for sphere 1 based on how restrictive the settings are in terms of items
# Adjust the needed size for sphere 1 based on how restrictive the options are in terms of items

needed_size = 3
needed_size = 2
needed_size += self.options.puzzle_randomization == "sigma_expert"
needed_size += self.options.shuffle_symbols
needed_size += self.options.shuffle_doors > 0
Expand Down
2 changes: 2 additions & 0 deletions worlds/witness/data/static_locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
"Town RGB House Upstairs Right",
"Town RGB House Sound Room Right",

"Town Pet the Dog",

"Windmill Theater Entry Panel",
"Theater Exit Left Panel",
"Theater Exit Right Panel",
Expand Down
3 changes: 3 additions & 0 deletions worlds/witness/data/static_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ def read_logic_file(self, lines: List[str]) -> None:
elif "EP" in entity_name:
entity_type = "EP"
location_type = "EP"
elif "Pet the Dog" in entity_name:
entity_type = "Event"
location_type = "Good Boi"
elif entity_hex.startswith("0xFF"):
entity_type = "Event"
location_type = None
Expand Down
6 changes: 1 addition & 5 deletions worlds/witness/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class WitnessPlayerLocations:
def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic) -> None:
"""Defines locations AFTER logic changes due to options"""

self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"}
self.PANEL_TYPES_TO_SHUFFLE = {"General", "Good Boi"}
self.CHECK_LOCATIONS = static_witness_locations.GENERAL_LOCATIONS.copy()

if world.options.shuffle_discarded_panels:
Expand Down Expand Up @@ -53,10 +53,6 @@ def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic) -> N
if static_witness_logic.ENTITIES_BY_NAME[ch]["locationType"] in self.PANEL_TYPES_TO_SHUFFLE
}

dog_hex = static_witness_logic.ENTITIES_BY_NAME["Town Pet the Dog"]["entity_hex"]
dog_id = static_witness_locations.ALL_LOCATIONS_TO_ID["Town Pet the Dog"]
self.CHECK_PANELHEX_TO_ID[dog_hex] = dog_id

self.CHECK_PANELHEX_TO_ID = dict(
sorted(self.CHECK_PANELHEX_TO_ID.items(), key=lambda item: item[1])
)
Expand Down
14 changes: 12 additions & 2 deletions worlds/witness/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,18 @@ class ShuffleEnvironmentalPuzzles(Choice):
option_obelisk_sides = 2


class ShuffleDog(Toggle):
class ShuffleDog(Choice):
"""
Adds petting the Town dog into the location pool.
Adds petting the dog statue in Town into the location pool.
Alternatively, you can force it to be a Puzzle Skip.
"""
display_name = "Pet the Dog"

option_off = 0
option_puzzle_skip = 1
option_random_item = 2
default = 1


class EnvironmentalPuzzlesDifficulty(Choice):
"""
Expand Down Expand Up @@ -424,6 +430,7 @@ class TheWitnessOptions(PerGameCommonOptions):
laser_hints: LaserHints
death_link: DeathLink
death_link_amnesty: DeathLinkAmnesty
shuffle_dog: ShuffleDog


witness_option_groups = [
Expand Down Expand Up @@ -471,5 +478,8 @@ class TheWitnessOptions(PerGameCommonOptions):
ElevatorsComeToYou,
DeathLink,
DeathLinkAmnesty,
]),
OptionGroup("Silly Options", [
ShuffleDog,
])
]
2 changes: 1 addition & 1 deletion worlds/witness/player_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def get_progressive_item_ids_in_pool(self) -> Dict[int, List[int]]:
item = self.item_data[item_name]
if isinstance(item.definition, ProgressiveItemDefinition):
# Note: we need to reference the static table here rather than the player-specific one because the child
# items were removed from the pool when we pruned out all progression items not in the settings.
# items were removed from the pool when we pruned out all progression items not in the options.
output[cast(int, item.ap_code)] = [cast(int, static_witness_items.ITEM_DATA[child_item].ap_code)
for child_item in item.definition.child_item_names]
return output
Expand Down
5 changes: 4 additions & 1 deletion worlds/witness/player_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,9 @@ def make_options_adjustments(self, world: "WitnessWorld") -> None:
adjustment_linesets_in_order.append(get_complex_doors())
adjustment_linesets_in_order.append(get_complex_additional_panels())

if not world.options.shuffle_dog:
adjustment_linesets_in_order.append(["Disabled Locations:", "0xFFF80 (Town Pet the Dog)"])

if world.options.shuffle_boat:
adjustment_linesets_in_order.append(get_boat())

Expand Down Expand Up @@ -891,7 +894,7 @@ def is_disabled(self, entity_hex: str) -> bool:
)

def determine_unrequired_entities(self, world: "WitnessWorld") -> None:
"""Figure out which major items are actually useless in this world's settings"""
"""Figure out which major items are actually useless in this world's options"""

# Gather quick references to relevant options
eps_shuffled = world.options.shuffle_EPs
Expand Down
6 changes: 6 additions & 0 deletions worlds/witness/presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"laser_hints": LaserHints.default,
"death_link": DeathLink.default,
"death_link_amnesty": DeathLinkAmnesty.default,

"shuffle_dog": ShuffleDog.default,
},

# For relative beginners who want to move to the next step.
Expand Down Expand Up @@ -73,6 +75,8 @@
"laser_hints": LaserHints.default,
"death_link": DeathLink.default,
"death_link_amnesty": DeathLinkAmnesty.default,

"shuffle_dog": ShuffleDog.default,
},

# Allsanity but without the BS (no expert, no tedious EPs).
Expand Down Expand Up @@ -109,5 +113,7 @@
"laser_hints": LaserHints.default,
"death_link": DeathLink.default,
"death_link_amnesty": DeathLinkAmnesty.default,

"shuffle_dog": ShuffleDog.option_random_item,
},
}
3 changes: 3 additions & 0 deletions worlds/witness/test/test_roll_other_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class TestExpertNonRandomizedEPs(WitnessTestBase):
"victory_condition": "challenge",
"shuffle_discarded_panels": False,
"shuffle_boat": False,
"shuffle_dog": "off",
}


Expand All @@ -24,6 +25,7 @@ class TestVanillaAutoElevatorsPanels(WitnessTestBase):
"early_caves": True,
"shuffle_vault_boxes": True,
"mountain_lasers": 11,
"shuffle_dog": "puzzle_skip",
}


Expand All @@ -46,6 +48,7 @@ class TestMaxEntityShuffle(WitnessTestBase):
"obelisk_keys": True,
"shuffle_lasers": "anywhere",
"victory_condition": "mountain_box_long",
"shuffle_dog": "random_item",
}


Expand Down
Loading