Lingo: Remove unnecessary player_logic parameters (#3054)

A world's player_logic is accessible from the LingoWorld object, so it's not necessary to also pass the LingoPlayerLogic object through every function that uses both.
This commit is contained in:
Star Rauchenberger 2024-04-13 17:20:31 -05:00 committed by GitHub
parent 7e660dbd23
commit 11073dfdac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 50 deletions

View File

@ -63,7 +63,7 @@ class LingoWorld(World):
self.player_logic = LingoPlayerLogic(self) self.player_logic = LingoPlayerLogic(self)
def create_regions(self): def create_regions(self):
create_regions(self, self.player_logic) create_regions(self)
def create_items(self): def create_items(self):
pool = [self.create_item(name) for name in self.player_logic.real_items] pool = [self.create_item(name) for name in self.player_logic.real_items]

View File

@ -4,7 +4,6 @@ from BaseClasses import Entrance, ItemClassification, Region
from .datatypes import Room, RoomAndDoor from .datatypes import Room, RoomAndDoor
from .items import LingoItem from .items import LingoItem
from .locations import LingoLocation from .locations import LingoLocation
from .player_logic import LingoPlayerLogic
from .rules import lingo_can_use_entrance, make_location_lambda from .rules import lingo_can_use_entrance, make_location_lambda
from .static_logic import ALL_ROOMS, PAINTINGS from .static_logic import ALL_ROOMS, PAINTINGS
@ -12,14 +11,14 @@ if TYPE_CHECKING:
from . import LingoWorld from . import LingoWorld
def create_region(room: Room, world: "LingoWorld", player_logic: LingoPlayerLogic) -> Region: def create_region(room: Room, world: "LingoWorld") -> Region:
new_region = Region(room.name, world.player, world.multiworld) new_region = Region(room.name, world.player, world.multiworld)
for location in player_logic.locations_by_room.get(room.name, {}): for location in world.player_logic.locations_by_room.get(room.name, {}):
new_location = LingoLocation(world.player, location.name, location.code, new_region) new_location = LingoLocation(world.player, location.name, location.code, new_region)
new_location.access_rule = make_location_lambda(location, world, player_logic) new_location.access_rule = make_location_lambda(location, world)
new_region.locations.append(new_location) new_region.locations.append(new_location)
if location.name in player_logic.event_loc_to_item: if location.name in world.player_logic.event_loc_to_item:
event_name = player_logic.event_loc_to_item[location.name] event_name = world.player_logic.event_loc_to_item[location.name]
event_item = LingoItem(event_name, ItemClassification.progression, None, world.player) event_item = LingoItem(event_name, ItemClassification.progression, None, world.player)
new_location.place_locked_item(event_item) new_location.place_locked_item(event_item)
@ -27,22 +26,21 @@ def create_region(room: Room, world: "LingoWorld", player_logic: LingoPlayerLogi
def connect_entrance(regions: Dict[str, Region], source_region: Region, target_region: Region, description: str, def connect_entrance(regions: Dict[str, Region], source_region: Region, target_region: Region, description: str,
door: Optional[RoomAndDoor], world: "LingoWorld", player_logic: LingoPlayerLogic): door: Optional[RoomAndDoor], world: "LingoWorld"):
connection = Entrance(world.player, description, source_region) connection = Entrance(world.player, description, source_region)
connection.access_rule = lambda state: lingo_can_use_entrance(state, target_region.name, door, world, player_logic) connection.access_rule = lambda state: lingo_can_use_entrance(state, target_region.name, door, world)
source_region.exits.append(connection) source_region.exits.append(connection)
connection.connect(target_region) connection.connect(target_region)
if door is not None: if door is not None:
effective_room = target_region.name if door.room is None else door.room effective_room = target_region.name if door.room is None else door.room
if door.door not in player_logic.item_by_door.get(effective_room, {}): if door.door not in world.player_logic.item_by_door.get(effective_room, {}):
for region in player_logic.calculate_door_requirements(effective_room, door.door, world).rooms: for region in world.player_logic.calculate_door_requirements(effective_room, door.door, world).rooms:
world.multiworld.register_indirect_condition(regions[region], connection) world.multiworld.register_indirect_condition(regions[region], connection)
def connect_painting(regions: Dict[str, Region], warp_enter: str, warp_exit: str, world: "LingoWorld", def connect_painting(regions: Dict[str, Region], warp_enter: str, warp_exit: str, world: "LingoWorld") -> None:
player_logic: LingoPlayerLogic) -> None:
source_painting = PAINTINGS[warp_enter] source_painting = PAINTINGS[warp_enter]
target_painting = PAINTINGS[warp_exit] target_painting = PAINTINGS[warp_exit]
@ -50,11 +48,10 @@ def connect_painting(regions: Dict[str, Region], warp_enter: str, warp_exit: str
source_region = regions[source_painting.room] source_region = regions[source_painting.room]
entrance_name = f"{source_painting.room} to {target_painting.room} ({source_painting.id} Painting)" entrance_name = f"{source_painting.room} to {target_painting.room} ({source_painting.id} Painting)"
connect_entrance(regions, source_region, target_region, entrance_name, source_painting.required_door, world, connect_entrance(regions, source_region, target_region, entrance_name, source_painting.required_door, world)
player_logic)
def create_regions(world: "LingoWorld", player_logic: LingoPlayerLogic) -> None: def create_regions(world: "LingoWorld") -> None:
regions = { regions = {
"Menu": Region("Menu", world.player, world.multiworld) "Menu": Region("Menu", world.player, world.multiworld)
} }
@ -64,7 +61,7 @@ def create_regions(world: "LingoWorld", player_logic: LingoPlayerLogic) -> None:
# Instantiate all rooms as regions with their locations first. # Instantiate all rooms as regions with their locations first.
for room in ALL_ROOMS: for room in ALL_ROOMS:
regions[room.name] = create_region(room, world, player_logic) regions[room.name] = create_region(room, world)
# Connect all created regions now that they exist. # Connect all created regions now that they exist.
for room in ALL_ROOMS: for room in ALL_ROOMS:
@ -80,18 +77,17 @@ def create_regions(world: "LingoWorld", player_logic: LingoPlayerLogic) -> None:
else: else:
entrance_name += f" (through {room.name} - {entrance.door.door})" entrance_name += f" (through {room.name} - {entrance.door.door})"
connect_entrance(regions, regions[entrance.room], regions[room.name], entrance_name, entrance.door, world, connect_entrance(regions, regions[entrance.room], regions[room.name], entrance_name, entrance.door, world)
player_logic)
# Add the fake pilgrimage. # Add the fake pilgrimage.
connect_entrance(regions, regions["Outside The Agreeable"], regions["Pilgrim Antechamber"], "Pilgrimage", connect_entrance(regions, regions["Outside The Agreeable"], regions["Pilgrim Antechamber"], "Pilgrimage",
RoomAndDoor("Pilgrim Antechamber", "Pilgrimage"), world, player_logic) RoomAndDoor("Pilgrim Antechamber", "Pilgrimage"), world)
if early_color_hallways: if early_color_hallways:
regions["Starting Room"].connect(regions["Outside The Undeterred"], "Early Color Hallways") regions["Starting Room"].connect(regions["Outside The Undeterred"], "Early Color Hallways")
if painting_shuffle: if painting_shuffle:
for warp_enter, warp_exit in player_logic.painting_mapping.items(): for warp_enter, warp_exit in world.player_logic.painting_mapping.items():
connect_painting(regions, warp_enter, warp_exit, world, player_logic) connect_painting(regions, warp_enter, warp_exit, world)
world.multiworld.regions += regions.values() world.multiworld.regions += regions.values()

View File

@ -2,61 +2,58 @@ from typing import TYPE_CHECKING
from BaseClasses import CollectionState from BaseClasses import CollectionState
from .datatypes import RoomAndDoor from .datatypes import RoomAndDoor
from .player_logic import AccessRequirements, LingoPlayerLogic, PlayerLocation from .player_logic import AccessRequirements, PlayerLocation
from .static_logic import PROGRESSION_BY_ROOM, PROGRESSIVE_ITEMS from .static_logic import PROGRESSION_BY_ROOM, PROGRESSIVE_ITEMS
if TYPE_CHECKING: if TYPE_CHECKING:
from . import LingoWorld from . import LingoWorld
def lingo_can_use_entrance(state: CollectionState, room: str, door: RoomAndDoor, world: "LingoWorld", def lingo_can_use_entrance(state: CollectionState, room: str, door: RoomAndDoor, world: "LingoWorld"):
player_logic: LingoPlayerLogic):
if door is None: if door is None:
return True return True
effective_room = room if door.room is None else door.room effective_room = room if door.room is None else door.room
return _lingo_can_open_door(state, effective_room, door.door, world, player_logic) return _lingo_can_open_door(state, effective_room, door.door, world)
def lingo_can_use_location(state: CollectionState, location: PlayerLocation, world: "LingoWorld", def lingo_can_use_location(state: CollectionState, location: PlayerLocation, world: "LingoWorld"):
player_logic: LingoPlayerLogic): return _lingo_can_satisfy_requirements(state, location.access, world)
return _lingo_can_satisfy_requirements(state, location.access, world, player_logic)
def lingo_can_use_mastery_location(state: CollectionState, world: "LingoWorld", player_logic: LingoPlayerLogic): def lingo_can_use_mastery_location(state: CollectionState, world: "LingoWorld"):
satisfied_count = 0 satisfied_count = 0
for access_req in player_logic.mastery_reqs: for access_req in world.player_logic.mastery_reqs:
if _lingo_can_satisfy_requirements(state, access_req, world, player_logic): if _lingo_can_satisfy_requirements(state, access_req, world):
satisfied_count += 1 satisfied_count += 1
return satisfied_count >= world.options.mastery_achievements.value return satisfied_count >= world.options.mastery_achievements.value
def lingo_can_use_level_2_location(state: CollectionState, world: "LingoWorld", player_logic: LingoPlayerLogic): def lingo_can_use_level_2_location(state: CollectionState, world: "LingoWorld"):
counted_panels = 0 counted_panels = 0
state.update_reachable_regions(world.player) state.update_reachable_regions(world.player)
for region in state.reachable_regions[world.player]: for region in state.reachable_regions[world.player]:
for access_req, panel_count in player_logic.counting_panel_reqs.get(region.name, []): for access_req, panel_count in world.player_logic.counting_panel_reqs.get(region.name, []):
if _lingo_can_satisfy_requirements(state, access_req, world, player_logic): if _lingo_can_satisfy_requirements(state, access_req, world):
counted_panels += panel_count counted_panels += panel_count
if counted_panels >= world.options.level_2_requirement.value - 1: if counted_panels >= world.options.level_2_requirement.value - 1:
return True return True
# THE MASTER has to be handled separately, because it has special access rules. # THE MASTER has to be handled separately, because it has special access rules.
if state.can_reach("Orange Tower Seventh Floor", "Region", world.player)\ if state.can_reach("Orange Tower Seventh Floor", "Region", world.player)\
and lingo_can_use_mastery_location(state, world, player_logic): and lingo_can_use_mastery_location(state, world):
counted_panels += 1 counted_panels += 1
if counted_panels >= world.options.level_2_requirement.value - 1: if counted_panels >= world.options.level_2_requirement.value - 1:
return True return True
return False return False
def _lingo_can_satisfy_requirements(state: CollectionState, access: AccessRequirements, world: "LingoWorld", def _lingo_can_satisfy_requirements(state: CollectionState, access: AccessRequirements, world: "LingoWorld"):
player_logic: LingoPlayerLogic):
for req_room in access.rooms: for req_room in access.rooms:
if not state.can_reach(req_room, "Region", world.player): if not state.can_reach(req_room, "Region", world.player):
return False return False
for req_door in access.doors: for req_door in access.doors:
if not _lingo_can_open_door(state, req_door.room, req_door.door, world, player_logic): if not _lingo_can_open_door(state, req_door.room, req_door.door, world):
return False return False
if len(access.colors) > 0 and world.options.shuffle_colors: if len(access.colors) > 0 and world.options.shuffle_colors:
@ -67,15 +64,14 @@ def _lingo_can_satisfy_requirements(state: CollectionState, access: AccessRequir
return True return True
def _lingo_can_open_door(state: CollectionState, room: str, door: str, world: "LingoWorld", def _lingo_can_open_door(state: CollectionState, room: str, door: str, world: "LingoWorld"):
player_logic: LingoPlayerLogic):
""" """
Determines whether a door can be opened Determines whether a door can be opened
""" """
if door not in player_logic.item_by_door.get(room, {}): if door not in world.player_logic.item_by_door.get(room, {}):
return _lingo_can_satisfy_requirements(state, player_logic.door_reqs[room][door], world, player_logic) return _lingo_can_satisfy_requirements(state, world.player_logic.door_reqs[room][door], world)
item_name = player_logic.item_by_door[room][door] item_name = world.player_logic.item_by_door[room][door]
if item_name in PROGRESSIVE_ITEMS: if item_name in PROGRESSIVE_ITEMS:
progression = PROGRESSION_BY_ROOM[room][door] progression = PROGRESSION_BY_ROOM[room][door]
return state.has(item_name, world.player, progression.index) return state.has(item_name, world.player, progression.index)
@ -83,12 +79,12 @@ def _lingo_can_open_door(state: CollectionState, room: str, door: str, world: "L
return state.has(item_name, world.player) return state.has(item_name, world.player)
def make_location_lambda(location: PlayerLocation, world: "LingoWorld", player_logic: LingoPlayerLogic): def make_location_lambda(location: PlayerLocation, world: "LingoWorld"):
if location.name == player_logic.mastery_location: if location.name == world.player_logic.mastery_location:
return lambda state: lingo_can_use_mastery_location(state, world, player_logic) return lambda state: lingo_can_use_mastery_location(state, world)
if world.options.level_2_requirement > 1\ if world.options.level_2_requirement > 1\
and (location.name == "Second Room - ANOTHER TRY" or location.name == player_logic.level_2_location): and (location.name == "Second Room - ANOTHER TRY" or location.name == world.player_logic.level_2_location):
return lambda state: lingo_can_use_level_2_location(state, world, player_logic) return lambda state: lingo_can_use_level_2_location(state, world)
return lambda state: lingo_can_use_location(state, location, world, player_logic) return lambda state: lingo_can_use_location(state, location, world)