The Witness: Panel Hunt Mode (#3265)
* Add panel hunt options * Make sure all panels are either solvable or disabled in panel hunt * Pick huntable panels * Discards in disable non randomized * Set up panel hunt requirement * Panel hunt functional * Make it so an event can have multiple names * Panel hunt with events * Add hunt entities to slot data * ruff * add to hint data, no client sneding yet * encode panel hunt amount in compact hint data * Remove print statement * my b * consistent * meh * additions for lcient * Nah * Victory panels ineligible for panel hunt * Panel Hunt Postgame option * cleanup * Add data generation file * pull out set * always disable gate ep in panel hunt * Disallow certain challenge panels from being panel hunt panels * Make panelhuntpostgame its own function, so it can be called even if normal postgame is enabled * disallow PP resets from panel hunt * Disable challenge timer and elevetor start respectively in disable hunt postgame * Fix panelhunt postgame * lol * When you test that the bug is fixed but not that the non-bug is not unfixed * Prevent Obelisks from being panel hunt panels * Make picking panels for panel hunt a bit more sophisticated, if less random * Better function maybe ig * Ok maybe that was a bit too much * Give advanced players some control over panel hunt * lint * correct the logic for amount to pick * decided the jingle thing was dumb, I'll figure sth out client side. Same area discouragement is now a configurable factor, and the logic has been significantly rewritten * comment * Make the option visible * Safety * Change assert slightly * We do a little logging * number tweak & we do a lil logging * we do a little more logging * Ruff * Panel Hunt Option Group * Idk how that got here * Update worlds/witness/options.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/witness/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * remove merge error * Update worlds/witness/player_logic.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * True * Don't have underwater sliding bridge when you have above water sliding bridge * These are not actually connected lol * get rid of unnecessary variable * Refactor compact hint function again * lint * Pull out Entity Hunt Picking into its own class, split it into many functions. Kept a lot of the comments tho * forgot to actually add the new file * some more refactoring & docstrings * consistent naming * flip elif change * Comment about naming * Make static eligible panels a constant I can refer back to * slight formatting change * pull out options-based eligibility into its own function * better text and stuff * lint * this is not necessary * capitalisation * Fix same area discouragement 0 * Simplify data file generation * Simplify data file generation * prevent div 0 * Add Vault Boxes -> Vault Panels to replacements * Update options.py * Update worlds/witness/entity_hunt.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update entity_hunt.py * Fix some events not working * assert * remove now unused function * lint * Lasers Activate, Lasers don't Solve * lint * oops * mypy * lint * Add simple panel hunt unit test * Add Panel Hunt Tests * Add more Panel Hunt Tests * Disallow Box Short for normal panel hunt --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
@@ -15,7 +15,7 @@ from .data import static_locations as static_witness_locations
|
||||
from .data import static_logic as static_witness_logic
|
||||
from .data.item_definition_classes import DoorItemDefinition, ItemData
|
||||
from .data.utils import get_audio_logs
|
||||
from .hints import CompactItemData, create_all_hints, make_compact_hint_data, make_laser_hints
|
||||
from .hints import CompactHintData, create_all_hints, make_compact_hint_data, make_laser_hints
|
||||
from .locations import WitnessPlayerLocations
|
||||
from .options import TheWitnessOptions, witness_option_groups
|
||||
from .player_items import WitnessItem, WitnessPlayerItems
|
||||
@@ -68,12 +68,14 @@ class WitnessWorld(World):
|
||||
player_items: WitnessPlayerItems
|
||||
player_regions: WitnessPlayerRegions
|
||||
|
||||
log_ids_to_hints: Dict[int, CompactItemData]
|
||||
laser_ids_to_hints: Dict[int, CompactItemData]
|
||||
log_ids_to_hints: Dict[int, CompactHintData]
|
||||
laser_ids_to_hints: Dict[int, CompactHintData]
|
||||
|
||||
items_placed_early: List[str]
|
||||
own_itempool: List[WitnessItem]
|
||||
|
||||
panel_hunt_required_count: int
|
||||
|
||||
def _get_slot_data(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"seed": self.random.randrange(0, 1000000),
|
||||
@@ -83,12 +85,14 @@ class WitnessWorld(World):
|
||||
"door_hexes_in_the_pool": self.player_items.get_door_ids_in_pool(),
|
||||
"symbols_not_in_the_game": self.player_items.get_symbol_ids_not_in_pool(),
|
||||
"disabled_entities": [int(h, 16) for h in self.player_logic.COMPLETELY_DISABLED_ENTITIES],
|
||||
"hunt_entities": [int(h, 16) for h in self.player_logic.HUNT_ENTITIES],
|
||||
"log_ids_to_hints": self.log_ids_to_hints,
|
||||
"laser_ids_to_hints": self.laser_ids_to_hints,
|
||||
"progressive_item_lists": self.player_items.get_progressive_item_ids_in_pool(),
|
||||
"obelisk_side_id_to_EPs": static_witness_logic.OBELISK_SIDE_ID_TO_EP_HEXES,
|
||||
"precompleted_puzzles": [int(h, 16) for h in self.player_logic.EXCLUDED_LOCATIONS],
|
||||
"entity_to_name": static_witness_logic.ENTITY_ID_TO_NAME,
|
||||
"panel_hunt_required_absolute": self.panel_hunt_required_count
|
||||
}
|
||||
|
||||
def determine_sufficient_progression(self) -> None:
|
||||
@@ -151,6 +155,13 @@ class WitnessWorld(World):
|
||||
if self.options.shuffle_lasers == "local":
|
||||
self.options.local_items.value |= self.item_name_groups["Lasers"]
|
||||
|
||||
if self.options.victory_condition == "panel_hunt":
|
||||
total_panels = self.options.panel_hunt_total
|
||||
required_percentage = self.options.panel_hunt_required_percentage
|
||||
self.panel_hunt_required_count = round(total_panels * required_percentage / 100)
|
||||
else:
|
||||
self.panel_hunt_required_count = 0
|
||||
|
||||
def create_regions(self) -> None:
|
||||
self.player_regions.create_regions(self, self.player_logic)
|
||||
|
||||
@@ -169,7 +180,7 @@ class WitnessWorld(World):
|
||||
|
||||
for event_location in self.player_locations.EVENT_LOCATION_TABLE:
|
||||
item_obj = self.create_item(
|
||||
self.player_logic.EVENT_ITEM_PAIRS[event_location]
|
||||
self.player_logic.EVENT_ITEM_PAIRS[event_location][0]
|
||||
)
|
||||
location_obj = self.get_location(event_location)
|
||||
location_obj.place_locked_item(item_obj)
|
||||
@@ -192,7 +203,7 @@ class WitnessWorld(World):
|
||||
]
|
||||
if early_items:
|
||||
random_early_item = self.random.choice(early_items)
|
||||
if self.options.puzzle_randomization == "sigma_expert":
|
||||
if self.options.puzzle_randomization == "sigma_expert" or self.options.victory_condition == "panel_hunt":
|
||||
# In Expert, only tag the item as early, rather than forcing it onto the gate.
|
||||
self.multiworld.local_early_items[self.player][random_early_item] = 1
|
||||
else:
|
||||
@@ -305,8 +316,8 @@ class WitnessWorld(World):
|
||||
self.options.local_items.value.add(item_name)
|
||||
|
||||
def fill_slot_data(self) -> Dict[str, Any]:
|
||||
self.log_ids_to_hints: Dict[int, CompactItemData] = {}
|
||||
self.laser_ids_to_hints: Dict[int, CompactItemData] = {}
|
||||
self.log_ids_to_hints: Dict[int, CompactHintData] = {}
|
||||
self.laser_ids_to_hints: Dict[int, CompactHintData] = {}
|
||||
|
||||
already_hinted_locations = set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user