mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-07-17 02:30:43 -07:00
f110a7efbc
* Update GauntletLegendsClient.py * Continuation of obelisk update * APPP Implementation Groundwork. * Continuation of APPP Implementation * Create Pain.asm * ROM verification modified since crc32 hash can no longer be calculated. * Initial upload of barrel/chest locations. * Finished adding and naming all chests/barrels. * Continued locations. * Added new yaml options * Work on mirror shards * Python 3.8 compatibility * Finalized location names. Fixed lambda bug. * v1.0 * Removed excess Docs and Changed item counts. * Update Archipelago Unittests.run.xml * Started working on Docs. * Updated item arrays for client * Fix client bugs * Flake8 fixes + Yaml fix * Update speed boots * v1.1 * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * v1.0.4 * Initial Ruff format * Formatting part-2 * More formatting + Doc changes * Updated Docs * Move client to root * Update Client Name * Make Imports Relative * Add new yaml options + rename obelisks * v1.1 Initial Upload * v1.1.0 + some additions * Client Update * Client Updates * pre-v1.1.1 * Update GauntletLegendsClient.py * pre-1.2 * 1.2.0 * v1.2.1 * Client fixes * v1.3.0 * v1.4.0 * v1.4.1 * Merged Changes * Experimental * pre-v1.5.0 * Changes * v1.5.0 * Update GauntletLegendsClient.py * Death Update * pre v1.5.1 * Obelisk rule changes * pre-v1.5.1 * Update GauntletLegendsClient.py * v1.5.1 * v1.5.1 * Update GauntletLegendsClient.py * Small fix * Update GauntletLegendsClient.py * v1.5.2 * pre-v1.6.0 * pre-v1.6.0 * v1.6.0 * Update * Update GauntletLegendsClient.py * Test * pre-v1.6.0 * Client Updtaes * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Update Rom.py * Update GauntletLegendsClient.py * Update Rom.py * Added Logging on stage enter * v1.6.2 * v1.6.2 * Update Rom.py * Update GauntletLegendsClient.py * v1.6.3 * Small Update * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Update GauntletLegendsClient.py * Changes ready for review * Update Rom.py * Remove root client * Update inno_setup.iss * Update client * Initial Review Refactor * Update Arrays.py * Review refactor * Update __init__.py * Small tweaks after test generations * Update GauntletLegendsClient.py * Implement new check_locations() function * Add name for Skorn to level_names Dict * Fix for #4671 * Update __init__.py * Adjust item frequency + Place 50% of filler as local * Oops I modified the itempool after create_items teehee * Update __init__.py * Check MD5 hash before patching ROM * Update __init__.py * Fix get_filler_item_name() * Update MD5 check to built in method in FilePath * Update Rom.py * Update worlds/gl/Rom.py Co-authored-by: qwint <qwint.42@gmail.com> * WIP Generation fixes * v1.7.1 * Update Archipelago Unittests.run.xml * 0.7.2 * Update GauntletLegendsClient.py * Review Edits * Update World description * Fuzz fixes * Update GauntletLegendsClient.py * Make static data immutable * Update option comparisons since no longer a Choice * Update worlds/gl/Rom.py Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com> * Update __init__.py * Initial Update commit * Progress * Remove un-used import + Add manifest * Add missing docstring for client command * Progress * pre-v2.0.0-BETA * Updates * Progress * Working Generations * Working IN-Game * v2.0.0-BETA * Create archipelago.json * v2.0.1 * v2.0.1 FINAL * pre v2.0.2 * Delete report.json * Cleanup * pre v2.0.2 * v2.0.2 * PR Ready * Update Items.py * Delete fuzz.py * Update Items.py * Update GauntletLegendsClient.py * Fix scouting disabled locations * Client Updates * v2.0.3 * Increment World Version * Docstring + slot_data updates * Option name update + Remove redundant option * Code Cleanup * Trenches is level 24 * Frequencies * More cleanup and removal of stale code. MISSING BASEPATCH * v2.1.0 * Minor enemy changes * Small fix * Update Rom.py * v2.1.1 * Small fixes * Update basepatch.bsdiff4 * Update GauntletLegendsClient.py * Socket error clarity * Delete settings.local.json * Update GauntletLegendsClient.py * v2.1.2 fixes * Boss portal fix * Small client fix + Item Frequencies * Update archipelago.json * Fix for games playing with max difficulty lower than 4 not sending locations * Update archipelago.json * v2.1.5 * Fix for Chimera's lair mirror shard * Update archipelago.json * Mod Re-Base + Queue limits + Item Receiving fixes * Options cleanup and newlines for some files * Include v2.x features in docs * Make sure players has at least 1 item * v2.1.6 * Update archipelago.json * Review Edits + Client Tweaks --------- Co-authored-by: qwint <qwint.42@gmail.com> Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com> Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com> Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
138 lines
7.5 KiB
Python
138 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 | None:
|
|
if world.options.portals.value:
|
|
return lambda state: state.has(item, world.player)
|
|
return None
|
|
|
|
|
|
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)
|