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: Panel Hunt Plando #3549

Merged
merged 22 commits into from
Dec 12, 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
57 changes: 45 additions & 12 deletions worlds/witness/entity_hunt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import defaultdict
from logging import debug
from logging import debug, warning
from pprint import pformat
from typing import TYPE_CHECKING, Dict, List, Set, Tuple

Expand Down Expand Up @@ -48,6 +48,8 @@ def __init__(self, player_logic: "WitnessPlayerLogic", world: "WitnessWorld",
self.PRE_PICKED_HUNT_ENTITIES = pre_picked_entities.copy()
self.HUNT_ENTITIES: Set[str] = set()

self._add_plandoed_hunt_panels_to_pre_picked()

self.ALL_ELIGIBLE_ENTITIES, self.ELIGIBLE_ENTITIES_PER_AREA = self._get_eligible_panels()

def pick_panel_hunt_panels(self, total_amount: int) -> Set[str]:
Expand All @@ -69,24 +71,51 @@ def pick_panel_hunt_panels(self, total_amount: int) -> Set[str]:

return self.HUNT_ENTITIES

def _entity_is_eligible(self, panel_hex: str) -> bool:
def _entity_is_eligible(self, panel_hex: str, plando: bool = False) -> bool:
"""
Determine whether an entity is eligible for entity hunt based on player options.
"""
panel_obj = static_witness_logic.ENTITIES_BY_HEX[panel_hex]

return (
self.player_logic.solvability_guaranteed(panel_hex)
and panel_hex not in self.player_logic.EXCLUDED_ENTITIES
and not (
# Due to an edge case, Discards have to be on in disable_non_randomized even if Discard Shuffle is off.
# However, I don't think they should be hunt panels in this case.
self.player_options.disable_non_randomized_puzzles
and not self.player_options.shuffle_discarded_panels
and panel_obj["locationType"] == "Discard"
)
if not self.player_logic.solvability_guaranteed(panel_hex) or panel_hex in self.player_logic.EXCLUDED_ENTITIES:
if plando:
warning(f"Panel {panel_obj['checkName']} is disabled / excluded and thus not eligible for panel hunt.")
return False

return plando or not (
# Due to an edge case, Discards have to be on in disable_non_randomized even if Discard Shuffle is off.
# However, I don't think they should be hunt panels in this case.
self.player_options.disable_non_randomized_puzzles
and not self.player_options.shuffle_discarded_panels
and panel_obj["locationType"] == "Discard"
)

def _add_plandoed_hunt_panels_to_pre_picked(self) -> None:
"""
Add panels the player explicitly specified to be included in panel hunt to the pre picked hunt panels.
Output a warning if a panel could not be added for some reason.
"""

# Plandoed hunt panels should be in random order, but deterministic by seed, so we sort, then shuffle
panels_to_plando = sorted(self.player_options.panel_hunt_plando.value)
self.random.shuffle(panels_to_plando)

for location_name in panels_to_plando:
entity_hex = static_witness_logic.ENTITIES_BY_NAME[location_name]["entity_hex"]

if entity_hex in self.PRE_PICKED_HUNT_ENTITIES:
continue

if self._entity_is_eligible(entity_hex, plando=True):
if len(self.PRE_PICKED_HUNT_ENTITIES) == self.player_options.panel_hunt_total:
warning(
f"Panel {location_name} could not be plandoed as a hunt panel for {self.player_name}'s world, "
f"because it would exceed their panel hunt total."
)
continue

self.PRE_PICKED_HUNT_ENTITIES.add(entity_hex)

def _get_eligible_panels(self) -> Tuple[List[str], Dict[str, Set[str]]]:
"""
There are some entities that are not allowed for panel hunt for various technical of gameplay reasons.
Expand Down Expand Up @@ -215,6 +244,10 @@ def _replace_unfair_hunt_entities_with_good_hunt_entities(self) -> None:
if good_entity in self.HUNT_ENTITIES or good_entity not in self.ALL_ELIGIBLE_ENTITIES:
continue

# ... and it's not a forced pick that should stay the same ...
if bad_entitiy in self.PRE_PICKED_HUNT_ENTITIES:
continue

# ... replace the bad entity with the good entity.
self.HUNT_ENTITIES.remove(bad_entitiy)
self.HUNT_ENTITIES.add(good_entity)
Expand Down
14 changes: 14 additions & 0 deletions worlds/witness/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from Options import (
Choice,
DefaultOnToggle,
LocationSet,
OptionDict,
OptionError,
OptionGroup,
Expand All @@ -17,6 +18,7 @@

from .data import static_logic as static_witness_logic
from .data.item_definition_classes import ItemCategory, WeightedItemDefinition
from .entity_hunt import ALL_HUNTABLE_PANELS


class DisableNonRandomizedPuzzles(Toggle):
Expand Down Expand Up @@ -268,6 +270,16 @@ class PanelHuntDiscourageSameAreaFactor(Range):
default = 40


class PanelHuntPlando(LocationSet):
"""
Specify specific hunt panels you want for your panel hunt game.
"""

display_name = "Panel Hunt Plando"

valid_keys = [static_witness_logic.ENTITIES_BY_HEX[panel_hex]["checkName"] for panel_hex in ALL_HUNTABLE_PANELS]


class PuzzleRandomization(Choice):
"""
Puzzles in this randomizer are randomly generated. This option changes the difficulty/types of puzzles.
Expand Down Expand Up @@ -477,6 +489,7 @@ class TheWitnessOptions(PerGameCommonOptions):
panel_hunt_required_percentage: PanelHuntRequiredPercentage
panel_hunt_postgame: PanelHuntPostgame
panel_hunt_discourage_same_area_factor: PanelHuntDiscourageSameAreaFactor
panel_hunt_plando: PanelHuntPlando
early_caves: EarlyCaves
early_symbol_item: EarlySymbolItem
elevators_come_to_you: ElevatorsComeToYou
Expand Down Expand Up @@ -505,6 +518,7 @@ class TheWitnessOptions(PerGameCommonOptions):
PanelHuntTotal,
PanelHuntPostgame,
PanelHuntDiscourageSameAreaFactor,
PanelHuntPlando,
], start_collapsed=True),
OptionGroup("Locations", [
ShuffleDiscardedPanels,
Expand Down
Loading