diff --git a/Dolphin scripts/Entrance Randomizer/__main__.py b/Dolphin scripts/Entrance Randomizer/__main__.py index 2d97bd9..80237f3 100644 --- a/Dolphin scripts/Entrance Randomizer/__main__.py +++ b/Dolphin scripts/Entrance Randomizer/__main__.py @@ -20,10 +20,10 @@ from lib.constants import * # noqa: F403 from lib.constants import __version__ from lib.entrance_rando import ( + DISABLED_TRANSITIONS, highjack_transition_rando, set_transitions_map, starting_area, - temp_disabled_exits, transitions_map, ) from lib.graph_creation import create_graphml @@ -50,7 +50,7 @@ # Dump spoiler logs and graph dump_spoiler_logs(starting_area_name, transitions_map, seed_string) -create_graphml(transitions_map, temp_disabled_exits, seed_string, starting_area) +create_graphml(transitions_map, DISABLED_TRANSITIONS, seed_string, starting_area) async def main_loop(): diff --git a/Dolphin scripts/Entrance Randomizer/lib/constants.py b/Dolphin scripts/Entrance Randomizer/lib/constants.py index fa8bcb4..28e7d21 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/constants.py +++ b/Dolphin scripts/Entrance Randomizer/lib/constants.py @@ -8,7 +8,7 @@ import CONFIGS from dolphin import memory # pyright: ignore[reportMissingModuleSource] -from lib.transition_infos import transition_infos +from lib.transition_infos import Transition, transition_infos __version = "0.4.0" """See CHANGELOG.md for version semantics.""" @@ -256,3 +256,15 @@ class LevelCRC(IntEnum): } """Entrances that can softlock by infinitely running into a door. Value is the minimum height boost needed to regain control.""" + + +ONE_WAY_TRANSITIONS = ( + # the White Valley geyser + Transition(LevelCRC.WHITE_VALLEY, LevelCRC.MOUNTAIN_SLED_RUN), + # the Apu Illapu Shrine geyser + Transition(LevelCRC.APU_ILLAPU_SHRINE, LevelCRC.WHITE_VALLEY), + # the Apu Illapu Shrine one-way door + Transition(LevelCRC.MOUNTAIN_SLED_RUN, LevelCRC.APU_ILLAPU_SHRINE), + # the Jungle Canyon waterfall + Transition(LevelCRC.CAVERN_LAKE, LevelCRC.JUNGLE_CANYON), +) diff --git a/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py b/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py index 836c7d2..6ed7f19 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py +++ b/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py @@ -3,9 +3,8 @@ import random from collections.abc import Iterable, MutableMapping, MutableSequence, Sequence, Sized from copy import copy -from enum import IntEnum +from enum import IntEnum, auto from itertools import starmap -from typing import NamedTuple import CONFIGS from lib.constants import * # noqa: F403 @@ -13,32 +12,10 @@ from lib.utils import follow_pointer_path, state -class Transition(NamedTuple): - from_: int - to: int - - class Choice(IntEnum): - CONNECT = 1 - INBETWEEN = 2 - - -temples = ( - LevelCRC.MONKEY_TEMPLE, - LevelCRC.SCORPION_TEMPLE, - LevelCRC.PENGUIN_TEMPLE, -) + CONNECT = auto() + INBETWEEN = auto() -one_way_exits = ( - # the White Valley geyser - Transition(LevelCRC.WHITE_VALLEY, LevelCRC.MOUNTAIN_SLED_RUN), - # the Apu Illapu Shrine geyser - Transition(LevelCRC.APU_ILLAPU_SHRINE, LevelCRC.WHITE_VALLEY), - # the Apu Illapu Shrine one-way door - Transition(LevelCRC.MOUNTAIN_SLED_RUN, LevelCRC.APU_ILLAPU_SHRINE), - # the Jungle Canyon waterfall - Transition(LevelCRC.CAVERN_LAKE, LevelCRC.JUNGLE_CANYON), -) _possible_starting_areas = [ area for area in ALL_TRANSITION_AREAS @@ -75,7 +52,7 @@ class Choice(IntEnum): } ] -temp_disabled_exits = [ +SHOWN_DISABLED_TRANSITIONS = ( # Mouth of Inti has 2 connections with Altar of Huitaca, which causes problems, # basically it's very easy to get softlocked by the spider web when entering Altar of Huitaca # So for now just don't randomize it. That way runs don't just end out of nowhere @@ -87,10 +64,11 @@ class Choice(IntEnum): # So for now just don't randomize it. That way we won't have to worry about that yet (LevelCRC.TWIN_OUTPOSTS, LevelCRC.TWIN_OUTPOSTS_UNDERWATER), (LevelCRC.TWIN_OUTPOSTS_UNDERWATER, LevelCRC.TWIN_OUTPOSTS), -] +) +"""These disabled exits are to be shown on the graph.""" -disabled_exits = ( - *temp_disabled_exits, +DISABLED_TRANSITIONS = ( + *SHOWN_DISABLED_TRANSITIONS, # The 3 Spirit Fights are not randomized, # because that will cause issues with the transformation cutscene trigger. # Plus it wouldn't really improve anything, given that the Temples are randomized anyway. @@ -207,7 +185,7 @@ def remove_disabled_exits(): for area in TRANSITION_INFOS_DICT.values(): for ex in area.exits: current = (area.area_id, ex.area_id) - if current in one_way_exits or current in disabled_exits: + if current in ONE_WAY_TRANSITIONS or current in DISABLED_TRANSITIONS: TRANSITION_INFOS_DICT_RANDO[area.area_id] = Area( area.area_id, area.name, @@ -221,7 +199,7 @@ def remove_disabled_exits(): # remove exits from ALL_POSSIBLE_TRANSITIONS_RANDO global ALL_POSSIBLE_TRANSITIONS_RANDO for trans in ALL_POSSIBLE_TRANSITIONS: - if trans in one_way_exits or trans in disabled_exits: + if trans in ONE_WAY_TRANSITIONS or trans in DISABLED_TRANSITIONS: ALL_POSSIBLE_TRANSITIONS_RANDO = [ # pyright: ignore[reportConstantRedefinition] x for x in ALL_POSSIBLE_TRANSITIONS_RANDO if x != trans ] @@ -415,9 +393,9 @@ def set_transitions_map(): # noqa: PLR0915 # TODO: Break up in smaller function _possible_redirections_bucket, ) - one_way_redirects = list(one_way_exits) + one_way_redirects = list(ONE_WAY_TRANSITIONS) random.shuffle(one_way_redirects) - for original in one_way_exits: + for original in ONE_WAY_TRANSITIONS: if one_way_redirects[0].to == original.from_: transitions_map[original] = one_way_redirects.pop(1) else: @@ -425,7 +403,7 @@ def set_transitions_map(): # noqa: PLR0915 # TODO: Break up in smaller function else: # Ground rules: # 1. you can't make a transition from a level to itself - _possible_redirections_bucket.extend(one_way_exits) + _possible_redirections_bucket.extend(ONE_WAY_TRANSITIONS) for area in TRANSITION_INFOS_DICT_RANDO.values(): for to_og in (exit_.area_id for exit_ in area.exits): original = Transition(from_=area.area_id, to=to_og) @@ -433,7 +411,7 @@ def set_transitions_map(): # noqa: PLR0915 # TODO: Break up in smaller function if redirect is not None: transitions_map[original] = redirect _possible_redirections_bucket.remove(redirect) - for original in one_way_exits: + for original in ONE_WAY_TRANSITIONS: redirect = get_random_redirection(original, _possible_redirections_bucket) if redirect is not None: transitions_map[original] = redirect diff --git a/Dolphin scripts/Entrance Randomizer/lib/graph_creation.py b/Dolphin scripts/Entrance Randomizer/lib/graph_creation.py index edc9e9e..81b96fa 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/graph_creation.py +++ b/Dolphin scripts/Entrance Randomizer/lib/graph_creation.py @@ -124,11 +124,11 @@ def create_edges(transitions_map: Mapping[tuple[int, int], tuple[int, int]]): def create_graphml( transitions_map: Mapping[tuple[int, int], tuple[int, int]], - temp_disabled_exits: Sequence[tuple[int, int]], + shown_disabled_transitions: Sequence[tuple[int, int]], seed_string: SeedType, starting_area: int, ): - all_transitions = dict(transitions_map) | {item: item for item in temp_disabled_exits} + all_transitions = dict(transitions_map) | {item: item for item in shown_disabled_transitions} graphml_text = ( '' diff --git a/Dolphin scripts/Entrance Randomizer/lib/transition_infos.py b/Dolphin scripts/Entrance Randomizer/lib/transition_infos.py index 991d6fb..1cdcfa5 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/transition_infos.py +++ b/Dolphin scripts/Entrance Randomizer/lib/transition_infos.py @@ -1,3 +1,9 @@ +""" +Expose `transition_infos.json` with static Python classes. + +No other information should be found here other than the imported data and helper classes. +""" + from __future__ import annotations import json @@ -6,6 +12,11 @@ from typing import Literal, NamedTuple, TypeAlias, TypedDict +class Transition(NamedTuple): + from_: int + to: int + + class ExitJSON(TypedDict): area_id: str area_name: str