Files
dockipelago/worlds/gauntletlegends/Regions.py
Jonathan Tinney 7971961166
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
add schedule I, sonic 1/frontiers/heroes, spirit island
2026-04-02 23:46:36 -07:00

136 lines
7.5 KiB
Python

import typing
from typing import Optional, Callable
from BaseClasses import Region
from .Data import excluded_levels
from .Locations import GLLocation, LocationData, get_locations_by_tags
if typing.TYPE_CHECKING:
from . import GauntletLegendsWorld
def create_regions(world: "GauntletLegendsWorld"):
world.multiworld.regions.append(Region("Menu", world.player, world.multiworld))
regions_dict = get_regions_dict()
for name, locations in regions_dict.items():
if name not in [level for region, levels in excluded_levels.items() if region in world.excluded_regions for level in levels]:
create_region(world, name, locations)
else:
world.disabled_locations.update([loc.name for loc in locations if loc.name not in world.disabled_locations])
def get_regions_dict() -> dict[str, list[LocationData]]:
"""
Returns a dictionary mapping region names to their corresponding location data lists.
"""
return {
"Valley of Fire": get_locations_by_tags("valley_of_fire"),
"Dagger Peak": get_locations_by_tags("dagger_peak"),
"Cliffs of Desolation": get_locations_by_tags("cliffs_of_desolation"),
"Lost Cave": get_locations_by_tags("lost_cave"),
"Volcanic Caverns": get_locations_by_tags("volcanic_cavern"),
"Dragon's Lair": get_locations_by_tags("dragons_lair"),
"Castle Courtyard": get_locations_by_tags("castle_courtyard"),
"Dungeon of Torment": get_locations_by_tags("dungeon_of_torment"),
"Tower Armory": get_locations_by_tags("tower_armory"),
"Castle Treasury": get_locations_by_tags("castle_treasury"),
"Chimera's Keep": get_locations_by_tags("chimeras_keep"),
"Poisoned Fields": get_locations_by_tags("poisoned_fields"),
"Haunted Cemetery": get_locations_by_tags("haunted_cemetery"),
"Venomous Spire": get_locations_by_tags("venomous_spire"),
"Toxic Air Ship": get_locations_by_tags("toxic_air_ship"),
"Vat of the Plague Fiend": get_locations_by_tags("plague_fiend"),
"Arctic Docks": get_locations_by_tags("arctic_docks"),
"Frozen Camp": get_locations_by_tags("frozen_camp"),
"Crystal Mine": get_locations_by_tags("crystal_mine"),
"Erupting Fissure": get_locations_by_tags("erupting_fissure"),
"Yeti's Cavern": get_locations_by_tags("yeti"),
"Desecrated Temple": get_locations_by_tags("desecrated_temple"),
"Altar of Skorne": get_locations_by_tags("altar_of_skorne"),
"Battle Trenches": get_locations_by_tags("battle_trenches"),
"Fortified Towers": get_locations_by_tags("fortified_towers"),
"Infernal Fortress": get_locations_by_tags("infernal_fortress"),
"Gates of the Underworld": get_locations_by_tags("gates_of_the_underworld")
}
def connect_regions(world: "GauntletLegendsWorld"):
names: dict[str, int] = {}
connect(world, names, "Menu", "Valley of Fire")
connect(world, names, "Menu", "Dagger Peak", _portal_helper("Portal to Dagger Peak", world))
connect(world, names, "Menu", "Cliffs of Desolation", _portal_helper("Portal to Cliffs of Desolation", world))
connect(world, names, "Menu", "Lost Cave", _portal_helper("Portal to Lost Cave", world))
connect(world, names, "Menu", "Volcanic Caverns", _portal_helper("Portal to Volcanic Caverns", world))
connect(world, names, "Menu", "Dragon's Lair", _portal_helper("Portal to Dragon's Lair", world))
connect(world, names, "Menu", "Castle Courtyard",
lambda state: state.has("Valley of Fire Obelisk", world.player)
and state.has("Dagger Peak Obelisk", world.player)
and state.has("Cliffs of Desolation Obelisk", world.player)
)
connect(world, names, "Castle Courtyard", "Dungeon of Torment", _portal_helper("Portal to Dungeon of Torment", world))
connect(world, names, "Castle Courtyard", "Tower Armory", _portal_helper("Portal to Tower Armory", world))
connect(world, names, "Castle Courtyard", "Castle Treasury", _portal_helper("Portal to Castle Treasury", world))
connect(world, names, "Castle Courtyard", "Chimera's Keep", _portal_helper("Portal to Chimera's Keep", world))
connect(world, names, "Menu", "Poisoned Fields",
lambda state: state.has("Castle Courtyard Obelisk", world.player)
and state.has("Dungeon of Torment Obelisk", world.player)
)
connect(world, names, "Poisoned Fields", "Haunted Cemetery", _portal_helper("Portal to Haunted Cemetery", world))
connect(world, names, "Poisoned Fields", "Venomous Spire", _portal_helper("Portal to Venomous Spire", world))
connect(world, names, "Poisoned Fields", "Toxic Air Ship", _portal_helper("Portal to Toxic Air Ship", world))
connect(world, names, "Toxic Air Ship", "Vat of the Plague Fiend", _portal_helper("Portal to Vat of the Plague Fiend", world))
connect(world, names, "Menu", "Arctic Docks",
lambda state: state.has("Poisoned Fields Obelisk", world.player)
and state.has("Haunted Cemetery Obelisk", world.player)
)
connect(world, names, "Arctic Docks", "Frozen Camp", _portal_helper("Portal to Frozen Camp", world))
connect(world, names, "Arctic Docks", "Crystal Mine", _portal_helper("Portal to Crystal Mine", world))
connect(world, names, "Arctic Docks", "Erupting Fissure", _portal_helper("Portal to Erupting Fissure", world))
connect(world, names, "Erupting Fissure", "Yeti's Cavern", _portal_helper("Portal to Yeti's Cavern", world))
connect(world, names, "Menu", "Desecrated Temple",
lambda state: state.has("Dragon Mirror Shard", world.player)
and state.has("Chimera Mirror Shard", world.player)
and state.has("Plague Fiend Mirror Shard", world.player)
and state.has("Yeti Mirror Shard", world.player)
)
connect(world, names, "Desecrated Temple", "Altar of Skorne")
connect(world, names, "Desecrated Temple", "Battle Trenches")
connect(world, names, "Desecrated Temple", "Fortified Towers", _portal_helper("Portal to Fortified Towers", world))
connect(world, names, "Desecrated Temple", "Infernal Fortress", _portal_helper("Portal to Infernal Fortress", world))
connect(world, names, "Menu", "Gates of the Underworld",
lambda state: state.has("stones", world.player, 13)
)
def _portal_helper(item: str, world: "GauntletLegendsWorld") -> Callable:
return lambda state, portals=bool(world.options.portals.value): (state.has(item, world.player) if portals else True)
def create_region(world: "GauntletLegendsWorld", name: str, locations: list[LocationData]):
reg = Region(name, world.player, world.multiworld)
reg.add_locations({loc.name: loc.id for loc in locations if loc.name not in world.disabled_locations}, GLLocation)
world.multiworld.regions.append(reg)
def connect(world: "GauntletLegendsWorld",
used_names: dict[str, int],
source: str,
target: str,
rule: Optional[Callable] = None,
):
excluded_levels_ = [level for region, levels in excluded_levels.items() if region in world.excluded_regions for level in levels]
if source in excluded_levels_ or target in excluded_levels_:
return
source_region = world.multiworld.get_region(source, world.player)
target_region = world.multiworld.get_region(target, world.player)
if target not in used_names:
used_names[target] = 1
name = target
else:
used_names[target] += 1
name = target + (" " * used_names[target])
source_region.connect(target_region, name, rule)