Files
Grinch-AP/worlds/witness/regions.py
NewSoupVi 805f33c39e Witness: Bugfixes in response to beta tests (#1473)
* Make all Keep Pressure Plates logically required for the Laser Panel

* Added more Tutorial checks

* Added the remaining two Shipwreck Boat EPs to the exclude list for normal

* Improved itempool filling system, added warning if usefuls had to be eaten

* Moved creation of said warning string to utils

* Fixed logic bug causing broken seeds on Mountain Floor 2

* Hints system change

* Expert Logic Fix

* Fixed typo

* Better wording

* Added missing games to junk hints

* Made sure Entrance names are unique

* Fixed missing Obelisk Side

* Disable Non Randomized + EP Shuffle fix

* Fixed disable_non_randomized precompleted EPs being 'disabled' instead of 'precompleted'

* Fixed if/elif error

* Tutorial Gate Open local symbol item becomes local_early_item in expert instead

* Bump required client version. There is a beta client that sends 0.3.9.

* Removed print statement, oops

* Fixed itempool manipulation in pre_fill

* Replaced string concats with fstrings

* Improved make_warning_string function signature

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>

* Improved performance on removing multiple items from multiworld itempool

* Comment

* Fixed errors with the code

* Made removal from itempool not fail unit test for multiple references

* Moved all item creation to create_items, got rid of itempool modifying system

* Colored Squares is no longer a good item, that's outdated

* Removed double if

* React to from_pool: false by removing a junk item

* Fixed warning if only Fnc Brain was removed

* Make use of string truthiness instead

* Made reading of plandoed items safer

---------

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
2023-03-03 00:08:24 +01:00

114 lines
4.3 KiB
Python

"""
Defines Region for The Witness, assigns locations to them,
and connects them with the proper requirements
"""
from BaseClasses import MultiWorld, Entrance
from .static_logic import StaticWitnessLogic
from .Options import get_option_value
from .locations import WitnessPlayerLocations, StaticWitnessLocations
from .player_logic import WitnessPlayerLogic
class WitnessRegions:
"""Class that defines Witness Regions"""
locat = None
logic = None
def make_lambda(self, panel_hex_to_solve_set, world, player, player_logic):
"""
Lambdas are made in a for loop, so the values have to be captured
This function is for that purpose
"""
return lambda state: state._witness_can_solve_panels(
panel_hex_to_solve_set, world, player, player_logic, self.locat
)
def connect(self, world: MultiWorld, player: int, source: str, target: str, player_logic: WitnessPlayerLogic,
panel_hex_to_solve_set=frozenset({frozenset()}), backwards: bool = False):
"""
connect two regions and set the corresponding requirement
"""
source_region = world.get_region(source, player)
target_region = world.get_region(target, player)
backwards = " Backwards" if backwards else ""
connection = Entrance(
player,
source + " to " + target + backwards,
source_region
)
connection.access_rule = self.make_lambda(panel_hex_to_solve_set, world, player, player_logic)
source_region.exits.append(connection)
connection.connect(target_region)
def create_regions(self, world, player: int, player_logic: WitnessPlayerLogic):
"""
Creates all the regions for The Witness
"""
from . import create_region
world.regions += [
create_region(world, player, 'Menu', self.locat, None, ["The Splashscreen?"]),
]
difficulty = get_option_value(world, player, "puzzle_randomization")
if difficulty == 1:
reference_logic = StaticWitnessLogic.sigma_expert
elif difficulty == 0:
reference_logic = StaticWitnessLogic.sigma_normal
else:
reference_logic = StaticWitnessLogic.vanilla
all_locations = set()
for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items():
locations_for_this_region = [
reference_logic.CHECKS_BY_HEX[panel]["checkName"] for panel in region["panels"]
if reference_logic.CHECKS_BY_HEX[panel]["checkName"] in self.locat.CHECK_LOCATION_TABLE
]
locations_for_this_region += [
StaticWitnessLocations.get_event_name(panel) for panel in region["panels"]
if StaticWitnessLocations.get_event_name(panel) in self.locat.EVENT_LOCATION_TABLE
]
all_locations = all_locations | set(locations_for_this_region)
world.regions += [
create_region(world, player, region_name, self.locat, locations_for_this_region)
]
for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items():
for connection in player_logic.CONNECTIONS_BY_REGION_NAME[region_name]:
if connection[1] == frozenset({frozenset(["TrueOneWay"])}):
self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()}))
continue
backwards_connections = set()
for subset in connection[1]:
if all({panel in player_logic.DOOR_ITEMS_BY_ID for panel in subset}):
if all({reference_logic.CHECKS_BY_HEX[panel]["id"] is None for panel in subset}):
backwards_connections.add(subset)
if backwards_connections:
self.connect(
world, player, connection[0], region_name, player_logic,
frozenset(backwards_connections), True
)
self.connect(world, player, region_name, connection[0], player_logic, connection[1])
world.get_entrance("The Splashscreen?", player).connect(
world.get_region('First Hallway', player)
)
def __init__(self, locat: WitnessPlayerLocations):
self.locat = locat