Skip to content

Commit

Permalink
New Feature: Early Beth
Browse files Browse the repository at this point in the history
-Adds early beth option
-Cleans up rules.py a bit
  • Loading branch information
GodlFire committed Oct 24, 2023
1 parent be36a11 commit 54899a6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
7 changes: 6 additions & 1 deletion worlds/shivers/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ class ElevatorsStaySolved(DefaultOnToggle):
"""Adds elevators as checks and will remain open upon solving them."""
display_name = "Elevators Stay Solved"

class EarlyBeth(DefaultOnToggle):
"""Beth's body is open at the start of the game. This allows any pot piece to be placed in the slide and early checks on the second half of the final riddle."""
display_name = "Early Beth"

Shivers_options: Dict[str, Option] = {
"lobby_access": LobbyAccess,
"puzzle_hints_required": PuzzleHintsRequired,
"include_information_plaques": InformationPlaques,
"front_door_usable": FrontDoorUsable,
"elevators_stay_solved": ElevatorsStaySolved
"elevators_stay_solved": ElevatorsStaySolved,
"early_beth": EarlyBeth
}

def get_option_value(multiworld: MultiWorld, player: int, name: str) -> Union[int, FrozenSet]:
Expand Down
49 changes: 22 additions & 27 deletions worlds/shivers/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,85 +5,99 @@
from worlds.generic.Rules import forbid_item
from .Options import get_option_value


def water_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Lobby", "Region", player) or (state.can_reach("Janitor Closet", "Region", player) and cloth_capturable(state, player))) \
and state.has("Water Pot Bottom", player) \
and state.has("Water Pot Top", player) \
and state.has("Water Pot Bottom DUPE", player) \
and state.has("Water Pot Top DUPE", player)


def wax_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Library", "Region", player) or state.can_reach("Anansi", "Region", player)) \
and state.has("Wax Pot Bottom", player) \
and state.has("Wax Pot Top", player) \
and state.has("Wax Pot Bottom DUPE", player) \
and state.has("Wax Pot Top DUPE", player)


def ash_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Office", "Region", player) or state.can_reach("Burial", "Region", player)) \
and state.has("Ash Pot Bottom", player) \
and state.has("Ash Pot Top", player) \
and state.has("Ash Pot Bottom DUPE", player) \
and state.has("Ash Pot Top DUPE", player)


def oil_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Prehistoric", "Region", player) or state.can_reach("Tar River", "Region", player)) \
and state.has("Oil Pot Bottom", player) \
and state.has("Oil Pot Top", player) \
and state.has("Oil Pot Bottom DUPE", player) \
and state.has("Oil Pot Top DUPE", player)


def cloth_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Egypt", "Region", player) or state.can_reach("Burial", "Region", player) or state.can_reach("Janitor Closet", "Region", player)) \
and state.has("Cloth Pot Bottom", player) \
and state.has("Cloth Pot Top", player) \
and state.has("Cloth Pot Bottom DUPE", player) \
and state.has("Cloth Pot Top DUPE", player)


def wood_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Workshop", "Region", player) or state.can_reach("Blue Maze", "Region", player) or state.can_reach("Gods Room", "Region", player) or state.can_reach("Anansi", "Region", player)) \
and state.has("Wood Pot Bottom", player) \
and state.has("Wood Pot Top", player) \
and state.has("Wood Pot Bottom DUPE", player) \
and state.has("Wood Pot Top DUPE", player)


def crystal_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Lobby", "Region", player) or state.can_reach("Ocean", "Region", player)) \
and state.has("Crystal Pot Bottom", player) \
and state.has("Crystal Pot Top", player) \
and state.has("Crystal Pot Bottom DUPE", player) \
and state.has("Crystal Pot Top DUPE", player)


def sand_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Greenhouse", "Region", player) or state.can_reach("Ocean", "Region", player)) \
and state.has("Sand Pot Bottom", player) \
and state.has("Sand Pot Top", player) \
and state.has("Sand Pot Bottom DUPE", player) \
and state.has("Sand Pot Top DUPE", player)


def metal_capturable(state: CollectionState, player: int) -> bool:
return (state.can_reach("Projector Room", "Region", player) or state.can_reach("Prehistoric", "Region", player) or state.can_reach("Bedroom", "Region", player)) \
and state.has("Metal Pot Bottom", player) \
and state.has("Metal Pot Top", player) \
and state.has("Metal Pot Bottom DUPE", player) \
and state.has("Metal Pot Top DUPE", player)


def lightning_capturable(state: CollectionState, player: int) -> bool:
return beths_body_available(state, player) \
return first_nine_ixupi_capturable \
and state.can_reach("Generator", "Region", player) \
and state.has("Lightning Pot Bottom", player) \
and state.has("Lightning Pot Top", player) \
and state.has("Lightning Pot Bottom DUPE", player) \
and state.has("Lightning Pot Top DUPE", player)


def beths_body_available(state: CollectionState, player: int) -> bool:
return water_capturable(state, player) and wax_capturable(state, player) \
return (first_nine_ixupi_capturable(state, player) or get_option_value(state.multiworld, player, "early_beth")) \
and state.can_reach("Generator", "Region", player)

def first_nine_ixupi_capturable(state: CollectionState, player: int) -> bool:
return (water_capturable(state, player) and wax_capturable(state, player) \
and ash_capturable(state, player) and oil_capturable(state, player) \
and cloth_capturable(state, player) and wood_capturable(state, player) \
and crystal_capturable(state, player) and sand_capturable(state, player) \
and metal_capturable(state, player) and state.can_reach("Generator", "Region", player)
and metal_capturable(state, player))



def get_rules_lookup(player: int):
rules_lookup: typing.Dict[str, typing.List[Callable[[CollectionState], bool]]] = {
Expand Down Expand Up @@ -131,8 +145,8 @@ def get_rules_lookup(player: int):
"To Burial From Egypt": lambda state: state.can_reach("Egypt", "Region", player),
"To Gods Room From Anansi": lambda state: state.can_reach("Gods Room", "Region", player),
"To Slide Room": lambda state: (
state.can_reach("Prehistoric", "Region", player) and state.can_reach("Tar River", "Region",player) and
state.can_reach("Egypt", "Region", player) and state.can_reach("Burial", "Region", player) and
state.can_reach("Prehistoric", "Region", player) and state.can_reach("Tar River", "Region",player) and
state.can_reach("Egypt", "Region", player) and state.can_reach("Burial", "Region", player) and
state.can_reach("Gods Room", "Region", player) and state.can_reach("Werewolf", "Region", player)),
"To Lobby From Slide Room": lambda state: (beths_body_available(state, player))
},
Expand All @@ -141,6 +155,7 @@ def get_rules_lookup(player: int):
"Accessible: Storage: Janitor Closet": lambda state: cloth_capturable(state, player),
"Accessible: Storage: Tar River": lambda state: oil_capturable(state, player),
"Accessible: Storage: Theater": lambda state: state.can_reach("Projector Room", "Region", player),
"Accessible: Storage: Slide": lambda state: beths_body_available(state, player) and state.can_reach("Slide Room", "Region", player),
"Ixupi Captured Water": lambda state: water_capturable(state, player),
"Ixupi Captured Wax": lambda state: wax_capturable(state, player),
"Ixupi Captured Ash": lambda state: ash_capturable(state, player),
Expand Down Expand Up @@ -203,26 +218,6 @@ def set_rules(Shivers: World) -> None:
forbid_item(multiworld.get_location("Accessible: Storage: Tar River", player), "Oil Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Tar River", player), "Oil Pot Top DUPE", player)

#forbid all but lightning in slide
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Water Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Wax Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Ash Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Oil Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Cloth Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Wood Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Crystal Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Sand Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Metal Pot Bottom DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Water Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Wax Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Ash Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Oil Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Cloth Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Wood Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Crystal Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Sand Pot Top DUPE", player)
forbid_item(multiworld.get_location("Accessible: Storage: Slide", player), "Metal Pot Top DUPE", player)

#Filler Item Forbids
forbid_item(multiworld.get_location("Puzzle Solved Lyre", player), "Easier Lyre", player)
forbid_item(multiworld.get_location("Ixupi Captured Water", player), "Water Always Available in Lobby", player)
Expand All @@ -248,4 +243,4 @@ def set_rules(Shivers: World) -> None:




6 changes: 4 additions & 2 deletions worlds/shivers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,16 @@ def pre_fill(self) -> None:
set_rules = set_rules

def generate_basic(self):
self.multiworld.completion_condition[self.player] = lambda state: Rules.lightning_capturable(state, self.player)
self.multiworld.completion_condition[self.player] = lambda state: (Rules.first_nine_ixupi_capturable(state, self.player)
and Rules.lightning_capturable(state, self.player))


def _get_slot_data(self):
return {
'storageplacements': self.storage_placements,
'excludedlocations': {str(excluded_location).replace('ExcludeLocations(', '').replace(')', '') for excluded_location in self.multiworld.exclude_locations.values()},
'elevatorsstaysolved': {self.multiworld.elevators_stay_solved[self.player].value}
'elevatorsstaysolved': {self.multiworld.elevators_stay_solved[self.player].value},
'earlybeth': {self.multiworld.early_beth[self.player].value}
}

def fill_slot_data(self) -> dict:
Expand Down

0 comments on commit 54899a6

Please sign in to comment.