mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00
LTTP: Rip Lttp specific entrance code out of core and use Region helpers (#1960)
This commit is contained in:
@@ -1022,9 +1022,6 @@ class Entrance:
|
|||||||
connected_region: Optional[Region] = None
|
connected_region: Optional[Region] = None
|
||||||
randomization_group: int
|
randomization_group: int
|
||||||
randomization_type: EntranceType
|
randomization_type: EntranceType
|
||||||
# LttP specific, TODO: should make a LttPEntrance
|
|
||||||
addresses = None
|
|
||||||
target = None
|
|
||||||
|
|
||||||
def __init__(self, player: int, name: str = "", parent: Optional[Region] = None,
|
def __init__(self, player: int, name: str = "", parent: Optional[Region] = None,
|
||||||
randomization_group: int = 0, randomization_type: EntranceType = EntranceType.ONE_WAY) -> None:
|
randomization_group: int = 0, randomization_type: EntranceType = EntranceType.ONE_WAY) -> None:
|
||||||
@@ -1043,10 +1040,8 @@ class Entrance:
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def connect(self, region: Region, addresses: Any = None, target: Any = None) -> None:
|
def connect(self, region: Region) -> None:
|
||||||
self.connected_region = region
|
self.connected_region = region
|
||||||
self.target = target
|
|
||||||
self.addresses = addresses
|
|
||||||
region.entrances.append(self)
|
region.entrances.append(self)
|
||||||
|
|
||||||
def is_valid_source_transition(self, er_state: "ERPlacementState") -> bool:
|
def is_valid_source_transition(self, er_state: "ERPlacementState") -> bool:
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
Helper functions to deliver entrance/exit/region sets to OWG rules.
|
Helper functions to deliver entrance/exit/region sets to OWG rules.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from BaseClasses import Entrance
|
|
||||||
|
|
||||||
from .StateHelpers import can_lift_heavy_rocks, can_boots_clip_lw, can_boots_clip_dw, can_get_glitched_speed_dw
|
from .StateHelpers import can_lift_heavy_rocks, can_boots_clip_lw, can_boots_clip_dw, can_get_glitched_speed_dw
|
||||||
|
|
||||||
|
|
||||||
@@ -279,18 +277,14 @@ def create_no_logic_connections(player, world, connections):
|
|||||||
for entrance, parent_region, target_region, *rule_override in connections:
|
for entrance, parent_region, target_region, *rule_override in connections:
|
||||||
parent = world.get_region(parent_region, player)
|
parent = world.get_region(parent_region, player)
|
||||||
target = world.get_region(target_region, player)
|
target = world.get_region(target_region, player)
|
||||||
connection = Entrance(player, entrance, parent)
|
parent.connect(target, entrance)
|
||||||
parent.exits.append(connection)
|
|
||||||
connection.connect(target)
|
|
||||||
|
|
||||||
|
|
||||||
def create_owg_connections(player, world, connections):
|
def create_owg_connections(player, world, connections):
|
||||||
for entrance, parent_region, target_region, *rule_override in connections:
|
for entrance, parent_region, target_region, *rule_override in connections:
|
||||||
parent = world.get_region(parent_region, player)
|
parent = world.get_region(parent_region, player)
|
||||||
target = world.get_region(target_region, player)
|
target = world.get_region(target_region, player)
|
||||||
connection = Entrance(player, entrance, parent)
|
parent.connect(target, entrance)
|
||||||
parent.exits.append(connection)
|
|
||||||
connection.connect(target)
|
|
||||||
|
|
||||||
|
|
||||||
def set_owg_connection_rules(player, world, connections, default_rule):
|
def set_owg_connection_rules(player, world, connections, default_rule):
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import collections
|
import collections
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from BaseClasses import Entrance, MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from .SubClasses import LTTPRegion, LTTPRegionType
|
from .SubClasses import LTTPEntrance, LTTPRegion, LTTPRegionType
|
||||||
|
|
||||||
|
|
||||||
def is_main_entrance(entrance: Entrance) -> bool:
|
def is_main_entrance(entrance: LTTPEntrance) -> bool:
|
||||||
return entrance.parent_region.type in {LTTPRegionType.DarkWorld, LTTPRegionType.LightWorld} if entrance.parent_region.type else True
|
return entrance.parent_region.type in {LTTPRegionType.DarkWorld, LTTPRegionType.LightWorld} if entrance.parent_region.type else True
|
||||||
|
|
||||||
|
|
||||||
@@ -410,7 +410,7 @@ def _create_region(world: MultiWorld, player: int, name: str, type: LTTPRegionTy
|
|||||||
ret = LTTPRegion(name, type, hint, player, world)
|
ret = LTTPRegion(name, type, hint, player, world)
|
||||||
if exits:
|
if exits:
|
||||||
for exit in exits:
|
for exit in exits:
|
||||||
ret.exits.append(Entrance(player, exit, ret))
|
ret.create_exit(exit)
|
||||||
if locations:
|
if locations:
|
||||||
for location in locations:
|
for location in locations:
|
||||||
if location in key_drop_data:
|
if location in key_drop_data:
|
||||||
|
@@ -3,7 +3,7 @@ import logging
|
|||||||
from typing import Iterator, Set
|
from typing import Iterator, Set
|
||||||
|
|
||||||
from Options import ItemsAccessibility
|
from Options import ItemsAccessibility
|
||||||
from BaseClasses import Entrance, MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item,
|
from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item,
|
||||||
item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items)
|
item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items)
|
||||||
|
|
||||||
@@ -1071,9 +1071,8 @@ def swordless_rules(world, player):
|
|||||||
def add_connection(parent_name, target_name, entrance_name, world, player):
|
def add_connection(parent_name, target_name, entrance_name, world, player):
|
||||||
parent = world.get_region(parent_name, player)
|
parent = world.get_region(parent_name, player)
|
||||||
target = world.get_region(target_name, player)
|
target = world.get_region(target_name, player)
|
||||||
connection = Entrance(player, entrance_name, parent)
|
parent.connect(target, entrance_name)
|
||||||
parent.exits.append(connection)
|
|
||||||
connection.connect(target)
|
|
||||||
|
|
||||||
|
|
||||||
def standard_rules(world, player):
|
def standard_rules(world, player):
|
||||||
@@ -1108,6 +1107,7 @@ def standard_rules(world, player):
|
|||||||
set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player),
|
set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player),
|
||||||
lambda state: state.has('Big Key (Hyrule Castle)', player))
|
lambda state: state.has('Big Key (Hyrule Castle)', player))
|
||||||
|
|
||||||
|
|
||||||
def toss_junk_item(world, player):
|
def toss_junk_item(world, player):
|
||||||
items = ['Rupees (20)', 'Bombs (3)', 'Arrows (10)', 'Rupees (5)', 'Rupee (1)', 'Bombs (10)',
|
items = ['Rupees (20)', 'Bombs (3)', 'Arrows (10)', 'Rupees (5)', 'Rupee (1)', 'Bombs (10)',
|
||||||
'Single Arrow', 'Rupees (50)', 'Rupees (100)', 'Single Bomb', 'Bee', 'Bee Trap',
|
'Single Arrow', 'Rupees (50)', 'Rupees (100)', 'Single Bomb', 'Bee', 'Bee Trap',
|
||||||
|
@@ -2,11 +2,10 @@
|
|||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
from BaseClasses import Location, Item, ItemClassification, Region, MultiWorld
|
from BaseClasses import Entrance, Location, Item, ItemClassification, Region, MultiWorld
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .Dungeons import Dungeon
|
from .Dungeons import Dungeon
|
||||||
from .Regions import LTTPRegion
|
|
||||||
|
|
||||||
|
|
||||||
class ALttPLocation(Location):
|
class ALttPLocation(Location):
|
||||||
@@ -77,6 +76,19 @@ class ALttPItem(Item):
|
|||||||
return self.type
|
return self.type
|
||||||
|
|
||||||
|
|
||||||
|
Addresses = int | list[int] | tuple[int, int, int, int, int, int, int, int, int, int, int, int, int]
|
||||||
|
|
||||||
|
|
||||||
|
class LTTPEntrance(Entrance):
|
||||||
|
addresses: Addresses | None = None
|
||||||
|
target: int | None = None
|
||||||
|
|
||||||
|
def connect(self, region: Region, addresses: Addresses | None = None, target: int | None = None) -> None:
|
||||||
|
super().connect(region)
|
||||||
|
self.addresses = addresses
|
||||||
|
self.target = target
|
||||||
|
|
||||||
|
|
||||||
class LTTPRegionType(IntEnum):
|
class LTTPRegionType(IntEnum):
|
||||||
LightWorld = 1
|
LightWorld = 1
|
||||||
DarkWorld = 2
|
DarkWorld = 2
|
||||||
@@ -90,6 +102,7 @@ class LTTPRegionType(IntEnum):
|
|||||||
|
|
||||||
|
|
||||||
class LTTPRegion(Region):
|
class LTTPRegion(Region):
|
||||||
|
entrance_type = LTTPEntrance
|
||||||
type: LTTPRegionType
|
type: LTTPRegionType
|
||||||
|
|
||||||
# will be set after making connections.
|
# will be set after making connections.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
from BaseClasses import Entrance
|
|
||||||
from worlds.generic.Rules import set_rule, add_rule
|
from worlds.generic.Rules import set_rule, add_rule
|
||||||
from .StateHelpers import can_bomb_clip, has_sword, has_beam_sword, has_fire_source, can_melt_things, has_misery_mire_medallion
|
from .StateHelpers import can_bomb_clip, has_sword, has_beam_sword, has_fire_source, can_melt_things, has_misery_mire_medallion
|
||||||
|
from .SubClasses import LTTPEntrance
|
||||||
|
|
||||||
|
|
||||||
# We actually need the logic to properly "mark" these regions as Light or Dark world.
|
# We actually need the logic to properly "mark" these regions as Light or Dark world.
|
||||||
@@ -9,17 +9,15 @@ def underworld_glitch_connections(world, player):
|
|||||||
specrock = world.get_region('Spectacle Rock Cave (Bottom)', player)
|
specrock = world.get_region('Spectacle Rock Cave (Bottom)', player)
|
||||||
mire = world.get_region('Misery Mire (West)', player)
|
mire = world.get_region('Misery Mire (West)', player)
|
||||||
|
|
||||||
kikiskip = Entrance(player, 'Kiki Skip', specrock)
|
kikiskip = specrock.create_exit('Kiki Skip')
|
||||||
mire_to_hera = Entrance(player, 'Mire to Hera Clip', mire)
|
mire_to_hera = mire.create_exit('Mire to Hera Clip')
|
||||||
mire_to_swamp = Entrance(player, 'Hera to Swamp Clip', mire)
|
mire_to_swamp = mire.create_exit('Hera to Swamp Clip')
|
||||||
specrock.exits.append(kikiskip)
|
|
||||||
mire.exits.extend([mire_to_hera, mire_to_swamp])
|
|
||||||
|
|
||||||
if world.worlds[player].fix_fake_world:
|
if world.worlds[player].fix_fake_world:
|
||||||
kikiskip.connect(world.get_entrance('Palace of Darkness Exit', player).connected_region)
|
kikiskip.connect(world.get_entrance('Palace of Darkness Exit', player).connected_region)
|
||||||
mire_to_hera.connect(world.get_entrance('Tower of Hera Exit', player).connected_region)
|
mire_to_hera.connect(world.get_entrance('Tower of Hera Exit', player).connected_region)
|
||||||
mire_to_swamp.connect(world.get_entrance('Swamp Palace Exit', player).connected_region)
|
mire_to_swamp.connect(world.get_entrance('Swamp Palace Exit', player).connected_region)
|
||||||
else:
|
else:
|
||||||
kikiskip.connect(world.get_region('Palace of Darkness (Entrance)', player))
|
kikiskip.connect(world.get_region('Palace of Darkness (Entrance)', player))
|
||||||
mire_to_hera.connect(world.get_region('Tower of Hera (Bottom)', player))
|
mire_to_hera.connect(world.get_region('Tower of Hera (Bottom)', player))
|
||||||
mire_to_swamp.connect(world.get_region('Swamp Palace (Entrance)', player))
|
mire_to_swamp.connect(world.get_region('Swamp Palace (Entrance)', player))
|
||||||
@@ -37,7 +35,7 @@ def fake_pearl_state(state, player):
|
|||||||
|
|
||||||
# Sets the rules on where we can actually go using this clip.
|
# Sets the rules on where we can actually go using this clip.
|
||||||
# Behavior differs based on what type of ER shuffle we're playing.
|
# Behavior differs based on what type of ER shuffle we're playing.
|
||||||
def dungeon_reentry_rules(world, player, clip: Entrance, dungeon_region: str, dungeon_exit: str):
|
def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str, dungeon_exit: str):
|
||||||
fix_dungeon_exits = world.worlds[player].fix_palaceofdarkness_exit
|
fix_dungeon_exits = world.worlds[player].fix_palaceofdarkness_exit
|
||||||
fix_fake_worlds = world.worlds[player].fix_fake_world
|
fix_fake_worlds = world.worlds[player].fix_fake_world
|
||||||
|
|
||||||
|
@@ -2640,9 +2640,13 @@ class PokemonRBWarp(Entrance):
|
|||||||
self.warp_id = warp_id
|
self.warp_id = warp_id
|
||||||
self.address = address
|
self.address = address
|
||||||
self.flags = flags
|
self.flags = flags
|
||||||
|
self.addresses = None
|
||||||
|
self.target = None
|
||||||
|
|
||||||
def connect(self, entrance):
|
def connect(self, entrance):
|
||||||
super().connect(entrance.parent_region, None, target=entrance.warp_id)
|
super().connect(entrance.parent_region)
|
||||||
|
self.addresses = None
|
||||||
|
self.target = entrance.warp_id
|
||||||
|
|
||||||
def access_rule(self, state):
|
def access_rule(self, state):
|
||||||
if self.connected_region is None:
|
if self.connected_region is None:
|
||||||
|
Reference in New Issue
Block a user