mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
Core: Add a function to allow worlds to easily allow self-locking items (#1383)
* implement function to allow self locking items for items accessibility * swap some lttp locations to use new functionality * lambda capture `item_name` and `location` * don't lambda capture location * Revert weird visual indent * make location.always_allow additive * fix always_allow rule for multiple items * don't need to lambda capture item_names * oop * move player assignment to the beginning * always_allow should only be for that player so prevent non_local_items * messenger got merged so have it use this * Core: fix doc string indentation for allow_self_locking_items * Core: fix doc string indentation for allow_self_locking_items, number two --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import collections
|
||||
import typing
|
||||
|
||||
from BaseClasses import LocationProgressType, MultiWorld
|
||||
from BaseClasses import LocationProgressType, MultiWorld, Location, Region, Entrance
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import BaseClasses
|
||||
@@ -143,14 +143,41 @@ def add_item_rule(location: "BaseClasses.Location", rule: ItemRule, combine: str
|
||||
def item_in_locations(state: "BaseClasses.CollectionState", item: str, player: int,
|
||||
locations: typing.Sequence["BaseClasses.Location"]) -> bool:
|
||||
for location in locations:
|
||||
if item_name(state, location[0], location[1]) == (item, player):
|
||||
if location_item_name(state, location[0], location[1]) == (item, player):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def item_name(state: "BaseClasses.CollectionState", location: str, player: int) -> \
|
||||
def location_item_name(state: "BaseClasses.CollectionState", location: str, player: int) -> \
|
||||
typing.Optional[typing.Tuple[str, int]]:
|
||||
location = state.multiworld.get_location(location, player)
|
||||
if location.item is None:
|
||||
return None
|
||||
return location.item.name, location.item.player
|
||||
|
||||
|
||||
def allow_self_locking_items(spot: typing.Union[Location, Region], *item_names: str) -> None:
|
||||
"""
|
||||
This function sets rules on the supplied spot, such that the supplied item_name(s) can possibly be placed there.
|
||||
|
||||
spot: Location or Region that the item(s) are allowed to be placed in
|
||||
item_names: item name or names that are allowed to be placed in the Location or Region
|
||||
"""
|
||||
player = spot.player
|
||||
|
||||
def add_allowed_rules(area: typing.Union[Location, Entrance], location: Location) -> None:
|
||||
def set_always_allow(location: Location, rule: typing.Callable) -> None:
|
||||
location.always_allow = rule
|
||||
|
||||
for item_name in item_names:
|
||||
add_rule(area, lambda state, item_name=item_name:
|
||||
location_item_name(state, location.name, player) == (item_name, player), "or")
|
||||
set_always_allow(location, lambda state, item:
|
||||
item.player == player and item.name in [item_name for item_name in item_names])
|
||||
|
||||
if isinstance(spot, Region):
|
||||
for entrance in spot.entrances:
|
||||
for location in spot.locations:
|
||||
add_allowed_rules(entrance, location)
|
||||
else:
|
||||
add_allowed_rules(spot, spot)
|
||||
|
||||
Reference in New Issue
Block a user