The Witness 0.3.4 features (#780)
New options:
Shuffle Doors: Many doors in the game will open on their own upon receiving an item ("key").
Variant - Shuffle Door/Control Panels: Many panels in the game that open doors or control devices in the world will be off until receiving their respective item ("key").
Shuffle Lasers: Lasers no longer activate by solving the laser panel, instead you will get an item that activates the laser.
Shuffle Symbols: Now that there is something else to shuffle (doors / door panels), you can turn off Symbol Rando.
Shuffle Postgame (replaces "Shuffle Hard"): The randomizer will now determine by your settings which panels are in the "postgame" - Meaning they can only be accessed after you can complete your win condition anyway.
This commit is contained in:
@@ -22,6 +22,21 @@ class WitnessLogic(LogicMixin):
|
||||
def _witness_has_lasers(self, world, player: int, amount: int) -> bool:
|
||||
lasers = 0
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_lasers"):
|
||||
lasers += int(self.has("Symmetry Laser", player))
|
||||
lasers += int(self.has("Desert Laser", player)
|
||||
and self.has("Desert Laser Redirection", player))
|
||||
lasers += int(self.has("Town Laser", player))
|
||||
lasers += int(self.has("Monastery Laser", player))
|
||||
lasers += int(self.has("Keep Laser", player))
|
||||
lasers += int(self.has("Quarry Laser", player))
|
||||
lasers += int(self.has("Treehouse Laser", player))
|
||||
lasers += int(self.has("Jungle Laser", player))
|
||||
lasers += int(self.has("Bunker Laser", player))
|
||||
lasers += int(self.has("Swamp Laser", player))
|
||||
lasers += int(self.has("Shadows Laser", player))
|
||||
return lasers >= amount
|
||||
|
||||
lasers += int(self.has("Symmetry Laser Activation", player))
|
||||
lasers += int(self.has("Desert Laser Activation", player)
|
||||
and self.has("Desert Laser Redirection", player))
|
||||
@@ -48,11 +63,8 @@ class WitnessLogic(LogicMixin):
|
||||
if (check_name + " Solved" in locat.EVENT_LOCATION_TABLE
|
||||
and not self.has(player_logic.EVENT_ITEM_PAIRS[check_name + " Solved"], player)):
|
||||
return False
|
||||
if panel not in player_logic.ORIGINAL_EVENT_PANELS and not self.can_reach(check_name, "Location", player):
|
||||
return False
|
||||
if (panel in player_logic.ORIGINAL_EVENT_PANELS
|
||||
and check_name + " Solved" not in locat.EVENT_LOCATION_TABLE
|
||||
and not self._witness_safe_manual_panel_check(panel, world, player, player_logic, locat)):
|
||||
if (check_name + " Solved" not in locat.EVENT_LOCATION_TABLE
|
||||
and not self._witness_meets_item_requirements(panel, world, player, player_logic, locat)):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -79,8 +91,10 @@ class WitnessLogic(LogicMixin):
|
||||
if not self._witness_has_lasers(world, player, get_option_value(world, player, "challenge_lasers")):
|
||||
valid_option = False
|
||||
break
|
||||
elif item in player_logic.ORIGINAL_EVENT_PANELS:
|
||||
valid_option = self._witness_can_solve_panel(item, world, player, player_logic, locat)
|
||||
elif item in player_logic.EVENT_PANELS:
|
||||
if not self._witness_can_solve_panel(item, world, player, player_logic, locat):
|
||||
valid_option = False
|
||||
break
|
||||
elif not self.has(item, player):
|
||||
valid_option = False
|
||||
break
|
||||
@@ -90,24 +104,6 @@ class WitnessLogic(LogicMixin):
|
||||
|
||||
return False
|
||||
|
||||
def _witness_safe_manual_panel_check(self, panel, world, player, player_logic: WitnessPlayerLogic, locat):
|
||||
"""
|
||||
nested can_reach can cause problems, but only if the region being
|
||||
checked is neither of the two original regions from the first
|
||||
can_reach.
|
||||
A nested can_reach is okay here because the only panels this
|
||||
function is called on are panels that exist on either side of all
|
||||
connections they are required for.
|
||||
The spoiler log looks so much nicer this way,
|
||||
it gets rid of a bunch of event items, only leaving a couple. :)
|
||||
"""
|
||||
region = StaticWitnessLogic.CHECKS_BY_HEX[panel]["region"]["name"]
|
||||
|
||||
return (
|
||||
self._witness_meets_item_requirements(panel, world, player, player_logic, locat)
|
||||
and self.can_reach(region, "Region", player)
|
||||
)
|
||||
|
||||
def _witness_can_solve_panels(self, panel_hex_to_solve_set, world, player, player_logic: WitnessPlayerLogic, locat):
|
||||
"""
|
||||
Checks whether a set of panels can be solved.
|
||||
@@ -120,7 +116,12 @@ class WitnessLogic(LogicMixin):
|
||||
valid_option = True
|
||||
|
||||
for panel in option:
|
||||
if not self._witness_can_solve_panel(panel, world, player, player_logic, locat):
|
||||
if panel in player_logic.DOOR_ITEMS_BY_ID:
|
||||
if all({not self.has(item, player) for item in player_logic.DOOR_ITEMS_BY_ID[panel]}):
|
||||
valid_option = False
|
||||
break
|
||||
|
||||
elif not self._witness_can_solve_panel(panel, world, player, player_logic, locat):
|
||||
valid_option = False
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user