The Witness: Panel Hunt Plando (#3549)

* Add panel hunt plando option

* Keys are strs

* oops

* better message

* ,

* this doesn ot need to be here

* don't replace pre picked panels

* Update options.py

* rebase error

* rebase error

* oops

* Mypy

* ruff

* another rebase error

* actually this is a stupid change too

* bring over that change™️

* Update entity_hunt.py

* Update entity_hunt.py

* Update entity_hunt.py
This commit is contained in:
NewSoupVi 2024-12-12 19:42:14 +01:00 committed by GitHub
parent f5e3677ef1
commit d7736950cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 12 deletions

View File

@ -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
@ -48,6 +48,8 @@ class EntityHuntPicker:
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]:
@ -69,24 +71,51 @@ class EntityHuntPicker:
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.
@ -215,6 +244,10 @@ class EntityHuntPicker:
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)

View File

@ -5,6 +5,7 @@ from schema import And, Schema
from Options import (
Choice,
DefaultOnToggle,
LocationSet,
OptionDict,
OptionError,
OptionGroup,
@ -17,6 +18,7 @@ from Options import (
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):
@ -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.
@ -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
@ -505,6 +518,7 @@ witness_option_groups = [
PanelHuntTotal,
PanelHuntPostgame,
PanelHuntDiscourageSameAreaFactor,
PanelHuntPlando,
], start_collapsed=True),
OptionGroup("Locations", [
ShuffleDiscardedPanels,