Wrote majority of overworld ladder rules

This commit is contained in:
Scipio Wright
2024-06-13 16:27:41 -04:00
parent 20e188ada2
commit a73bf37554
3 changed files with 116 additions and 63 deletions

View File

@@ -4,6 +4,7 @@ from .options import IceGrappling, LadderStorage
from .rules import (has_ability, has_sword, has_stick, has_ice_grapple_logic, has_lantern, has_mask, can_ladder_storage,
laurels_zip)
from .er_data import Portal
from .ladder_storage_data import ow_ladder_groups, region_ladders
from BaseClasses import Region, CollectionState
if TYPE_CHECKING:
@@ -999,6 +1000,61 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
world.options.hexagon_quest else
state.has_all({red_hexagon, green_hexagon, blue_hexagon, "Unseal the Heir"}, player)))
if options.ladder_storage:
def get_portal_info(portal_sd: str) -> Tuple[str, str]:
for portal1, portal2 in portal_pairs.items():
if portal1.scene_destination() == portal_sd:
return portal1.name, portal2.region
if portal2.scene_destination() == portal_sd:
return portal2.name, portal1.region
raise Exception("no matches found in get_paired_region")
def ls_connect(ladder_elev: str, portal_sdt: str) -> None:
p_name, paired_region_name = get_portal_info(portal_sdt)
ladder_regions[ladder_elev].connect(
regions[paired_region_name],
name=p_name + " (LS) " + ladder_elev)
# create the ls elevation regions
ladder_regions: Dict[str, Region] = {}
for name in ow_ladder_groups.keys():
ladder_regions[name] = Region(name, player, world.multiworld)
# connect the ls elevations to each other where applicable
if options.ladder_storage >= LadderStorage.option_medium:
for i in range(len(ow_ladder_groups) - 1):
ladder_regions[f"LS Elev {i}"].connect(ladder_regions[f"LS Elev {i + 1}"])
# connect the applicable overworld regions to the ls elevation regions
for origin_region, ladders in region_ladders.items():
for ladder_region, region_info in ow_ladder_groups.items():
common_ladders: Set[str] = ladders.intersection(region_info.ladders)
if common_ladders:
regions[origin_region].connect(ladder_regions[ladder_region],
rule=lambda state: state.has_any(common_ladders, player))
# connect ls elevation regions to the region on the other side of the portals
for ladder_region, region_info in ow_ladder_groups.items():
for portal_dest in region_info.portals:
ls_connect(ladder_region, "Overworld Redux, " + portal_dest)
# connect ls elevation regions to regions where you can get an enemy to knock you down
if options.ladder_storage >= LadderStorage.option_medium:
for ladder_region, region_info in ow_ladder_groups.items():
for dest_region in region_info.regions:
ladder_regions[ladder_region].connect(
connecting_region=regions[dest_region],
name=ladder_region + " (LS) " + dest_region)
# connect ls elevation regions to portals where you need to get behind the map to enter it
if options.ladder_storage >= LadderStorage.option_hard:
ls_connect("LS Elev 1", "Overworld Redux, EastFiligreeCache_")
ls_connect("LS Elev 2", "Overworld Redux, Town_FiligreeRoom_")
ls_connect("LS Elev 3", "Overworld Redux, Overworld Interiors_house")
ls_connect("LS Elev 5", "Overworld Redux, Temple_main")
# todo: add ls in other areas
# todo: add rules when er is off
# connecting the regions portals are in to other portals you can access via ladder storage
# using has_stick instead of can_ladder_storage since it's already checking the logic rules
if options.logic_rules == "unrestricted":

View File

@@ -1,63 +0,0 @@
# for making rules for ladder storage in overworld
from typing import Dict, Set, NamedTuple
class LadderInfo(NamedTuple):
ladders: Set[str] # ladders where the top or bottom is at the same elevation
portals: Set[str] # portals at the same elevation
regions: Set[str] # regions where a melee enemy can hit you out of ladder storage
# groups for ladders at the same elevation, for use in determing whether you can ls to entrances in diff rulesets
overworld_ladder_groups: Dict[str, LadderInfo] = {
# lowest elevation
"Group 0": LadderInfo({"Ladders in Overworld Town", "Ladder to Ruined Atoll", "Ladder to Swamp"},
{"Swamp Redux 2_conduit", "Overworld Cave_", "Atoll Redux_lower", "Maze Room_",
"Town Basement_beach", "Archipelagos Redux_lowest"},
{"Overworld Beach"}),
"Group 1": LadderInfo({"Ladders near Weathervane", "Ladders in Overworld Town", "Ladder to Swamp"},
{"Furnace_gyro_lower", "Swamp Redux 2_wall"},
{"Overworld Tunnel Turret"}),
"Group 2": LadderInfo({"Ladders near Weathervane", "Ladders to West Bell"},
{"Archipelagos Redux_lower", "Ruins Passage_east", "Ruins Passage_west"},
{"After Ruined Passage"}),
"Group 3": LadderInfo({"Ladders near Weathervane", "Ladder to Quarry", "Ladders to West Bell",
"Ladders in Overworld Town"},
{"Overworld Interiors_house"},
{"Overworld after Envoy", "East Overworld"}),
# skip top of top ladder next to weathervane level, does not provide logical access to anything
"Group 4": LadderInfo({"Ladders near Dark Tomb", "Ladder to Quarry", "Ladders to West Bell",
"Ladders in Overworld Town", "Ladders in Well"},
{"Darkwoods Tunnel_"},
set()),
"Group 5": LadderInfo({"Ladders near Overworld Checkpoint", "Ladders near Patrol Cave"},
{"Temple_main", "PatrolCave_", "Forest Belltower_", "Fortress Courtyard_", "ShopSpecial_"},
{"East Overworld"}),
# skip top of belltower, middle of dark tomb ladders, and top of checkpoint, does not grant access to anything
"Group 6": LadderInfo({"Ladders near Patrol Cave", "Ladder near Temple Rafters"},
{"Temple_rafters"},
{"Overworld above Patrol Cave"}),
# in-line with the chest above dark tomb, gets you up the mountain stairs
"Group 7": LadderInfo({"Ladders near Patrol Cave", "Ladder near Temple Rafters", "Ladders near Dark Tomb"},
{"Mountain_"},
{"Upper Overworld"}),
}
# ladders accessible within different regions of overworld, only those that are relevant
# other scenes will just have them hardcoded since this type of structure is not necessary there
region_ladders: Dict[str, Set[str]] = {
"Overworld": {"Ladders near Weathervane", "Ladders near Overworld Checkpoint", "Ladders near Dark Tomb",
"Ladders in Overworld Town", "Ladder to Swamp", "Ladders in Well"},
"Overworld Beach": {"Ladder to Ruined Atoll"},
"Overworld at Patrol Cave": {"Ladders near Patrol Cave"},
"Overworld Quarry Entry": {"Ladder to Quarry"},
"Overworld Belltower": {"Ladders to West Bell"},
}
def ladder_and_lower(index: int) -> Set[str]:
ladder_set: Set[str] = set()
for i in range(index):
ladder_set.update(overworld_ladder_groups[f"Group {i}"].ladders)
return ladder_set

View File

@@ -0,0 +1,60 @@
# for making rules for ladder storage in overworld
from typing import Dict, List, Set, NamedTuple
class LadderInfo(NamedTuple):
ladders: Set[str] # ladders where the top or bottom is at the same elevation
portals: List[str] # portals at the same elevation, only those without doors
regions: List[str] # regions where a melee enemy can hit you out of ladder storage
# groups for ladders at the same elevation, for use in determing whether you can ls to entrances in diff rulesets
ow_ladder_groups: Dict[str, LadderInfo] = {
# lowest elevation
"LS Elev 0": LadderInfo({"Ladders in Overworld Town", "Ladder to Ruined Atoll", "Ladder to Swamp"},
["Swamp Redux 2_conduit", "Overworld Cave_", "Atoll Redux_lower", "Maze Room_",
"Town Basement_beach", "Archipelagos Redux_lowest"],
["Overworld Beach"]),
# also the east filigree room
"LS Elev 1": LadderInfo({"Ladders near Weathervane", "Ladders in Overworld Town", "Ladder to Swamp"},
["Furnace_gyro_lower", "Swamp Redux 2_wall"],
["Overworld Tunnel Turret"]),
# also the fountain filigree room and ruined passage door
"LS Elev 2": LadderInfo({"Ladders near Weathervane", "Ladders to West Bell"},
["Archipelagos Redux_lower", "Ruins Passage_east"],
["After Ruined Passage"]),
# also old house door
"LS Elev 3": LadderInfo({"Ladders near Weathervane", "Ladder to Quarry", "Ladders to West Bell",
"Ladders in Overworld Town"},
[],
["Overworld after Envoy", "East Overworld"]),
# skip top of top ladder next to weathervane level, does not provide logical access to anything
"LS Elev 4": LadderInfo({"Ladders near Dark Tomb", "Ladder to Quarry", "Ladders to West Bell", "Ladders in Well",
"Ladders in Overworld Town"},
["Darkwoods Tunnel_"],
[]),
"LS Elev 5": LadderInfo({"Ladders near Overworld Checkpoint", "Ladders near Patrol Cave"},
["PatrolCave_", "Forest Belltower_", "Fortress Courtyard_", "ShopSpecial_"],
["East Overworld"]),
# skip top of belltower, middle of dark tomb ladders, and top of checkpoint, does not grant access to anything
"LS Elev 6": LadderInfo({"Ladders near Patrol Cave", "Ladder near Temple Rafters"},
["Temple_rafters"],
["Overworld above Patrol Cave"]),
# in-line with the chest above dark tomb, gets you up the mountain stairs
"LS Elev 7": LadderInfo({"Ladders near Patrol Cave", "Ladder near Temple Rafters", "Ladders near Dark Tomb"},
["Mountain_"],
["Upper Overworld"]),
}
# ladders accessible within different regions of overworld, only those that are relevant
# other scenes will just have them hardcoded since this type of structure is not necessary there
region_ladders: Dict[str, Set[str]] = {
"Overworld": {"Ladders near Weathervane", "Ladders near Overworld Checkpoint", "Ladders near Dark Tomb",
"Ladders in Overworld Town", "Ladder to Swamp", "Ladders in Well"},
"Overworld Beach": {"Ladder to Ruined Atoll"},
"Overworld at Patrol Cave": {"Ladders near Patrol Cave"},
"Overworld Quarry Entry": {"Ladder to Quarry"},
"Overworld Belltower": {"Ladders to West Bell"},
"Overworld after Temple Rafters": {"Ladders near Temple Rafters"},
}