コード例 #1
0
ファイル: test_editor.py プロジェクト: randovania/randovania
def test_replace_node(game_editor):
    # Setup
    world_list = game_editor.game.world_list
    loc = AreaIdentifier("Temple Grounds", "Landing Site")
    loc2 = AreaIdentifier("Temple Grounds", "Service Access")

    landing_site = world_list.area_by_area_location(loc)
    source = landing_site.node_with_name("Save Station")
    door = landing_site.node_with_name("Door to Service Access")
    assert isinstance(door, DockNode)
    req = landing_site.connections[source][door]

    new_node = dataclasses.replace(
        door, identifier=door.identifier.renamed("FooBar"))

    # Run
    game_editor.replace_node(landing_site, door, new_node)

    # Assert
    assert world_list.area_by_area_location(
        loc).connections[source][new_node] is req
    dock_to_landing = world_list.area_by_area_location(loc2).node_with_name(
        "Door to Landing Site")
    assert isinstance(dock_to_landing, DockNode)
    assert dock_to_landing.default_connection.node_name == "FooBar"
コード例 #2
0
    def _starting_location_on_select_classic(self):
        classics = [
            AreaIdentifier("Mimiga Village", "Start Point"),
            AreaIdentifier("Mimiga Village", "Arthur's House"),
            AreaIdentifier("Labyrinth", "Camp")
        ]

        with self._editor as editor:
            editor.set_configuration_field(
                "starting_location",
                editor.configuration.starting_location.with_elements(
                    classics, self.game_enum))
コード例 #3
0
    def valid_targets(self) -> List[AreaIdentifier]:
        if self.mode == TeleporterShuffleMode.ONE_WAY_ANYTHING:
            return [
                location
                for location in self.excluded_targets.areas_list(self.game)
                if location not in self.excluded_targets.locations
            ]

        elif self.mode in {
                TeleporterShuffleMode.ONE_WAY_ELEVATOR,
                TeleporterShuffleMode.ONE_WAY_ELEVATOR_REPLACEMENT
        }:
            world_list = default_database.game_description_for(
                self.game).world_list
            result = []
            for identifier in self.editable_teleporters:
                node = world_list.node_by_identifier(identifier)
                if isinstance(node, TeleporterNode) and node.editable:
                    # Valid destinations must be valid starting areas
                    area = world_list.nodes_to_area(node)
                    if area.valid_starting_location:
                        result.append(identifier.area_identifier)
                    # Hack for Metroid Prime 1, where the scripting for Metroid Prime Lair is dependent on the previous room
                    elif area.name == "Metroid Prime Lair":
                        result.append(
                            AreaIdentifier.from_string(
                                "Impact Crater/Subchamber Five"))
            return result
        else:
            return []
コード例 #4
0
def test_create_message_for_hint_relative_area(echoes_game_patches,
                                               blank_pickup, players_config,
                                               echoes_hint_exporter, offset,
                                               distance_text):
    patches = echoes_game_patches.assign_new_pickups([
        (PickupIndex(5), PickupTarget(blank_pickup, 0)),
    ])

    hint = Hint(
        HintType.LOCATION,
        PrecisionPair(HintLocationPrecision.RELATIVE_TO_AREA,
                      HintItemPrecision.DETAILED,
                      include_owner=False,
                      relative=RelativeDataArea(
                          offset, AreaIdentifier("Torvus Bog", "Great Bridge"),
                          HintRelativeAreaName.NAME)), PickupIndex(5))

    namer = EchoesHintNamer({0: patches}, PlayersConfiguration(0, {0: "You"}))
    exporter = HintExporter(namer, random.Random(0), ["A Joke"])

    # Run
    result = exporter.create_message_for_hint(hint, {0: patches},
                                              players_config, True)

    # Assert
    assert result == (
        f'The &push;&main-color=#FF6705B3;Blank Pickup&pop; can be found '
        f'&push;&main-color=#FF3333;{distance_text} {10 + (offset or 0)} rooms&pop; away from '
        f'Torvus Bog - Great Bridge.')
コード例 #5
0
def test_create_spawn_point_field(echoes_game_description, empty_patches):
    # Setup
    resource_db = echoes_game_description.resource_database

    loc = AreaIdentifier("Temple Grounds", "Hive Chamber B")
    patches = empty_patches.assign_starting_location(loc).assign_extra_initial_items({
        resource_db.get_by_type_and_index(ResourceType.ITEM, "MorphBall"): 3,
    })

    capacities = [
        {'amount': 3 if item.short_name == "MorphBall" else 0, 'index': item.extra["item_id"]}
        for item in resource_db.item
    ]

    # Run
    result = patch_data_factory._create_spawn_point_field(patches, echoes_game_description)

    # Assert
    assert result == {
        "location": {
            "world_asset_id": 1006255871,
            "area_asset_id": 494654382,
        },
        "amount": capacities,
        "capacity": capacities,
    }
コード例 #6
0
ファイル: test_editor.py プロジェクト: randovania/randovania
def test_rename_area(game_editor):
    # Setup
    world_list = game_editor.game.world_list
    loc_1 = AreaIdentifier("Temple Grounds", "Transport to Agon Wastes")
    loc_2 = AreaIdentifier("Agon Wastes", "Transport to Temple Grounds")
    final = AreaIdentifier("Temple Grounds", "Foo Bar Transportation")

    # Run
    game_editor.rename_area(world_list.area_by_area_location(loc_1),
                            "Foo Bar Transportation")

    # Assert
    assert world_list.area_by_area_location(final) is not None
    area_2 = world_list.area_by_area_location(loc_2)
    assert area_2.node_with_name(
        "Elevator to Temple Grounds - Foo Bar Transportation") is not None
コード例 #7
0
def decode_data_with_world_reader(
        data: Dict) -> Tuple[WorldReader, GameDescription]:
    data = game_migration.migrate_to_current(copy.deepcopy(data))

    game = RandovaniaGame(data["game"])

    resource_database = read_resource_database(game, data["resource_database"])
    dock_weakness_database = read_dock_weakness_database(
        data["dock_weakness_database"], resource_database)

    layers = frozen_lib.wrap(data["layers"])
    world_reader = WorldReader(resource_database, dock_weakness_database)
    world_list = world_reader.read_world_list(data["worlds"])

    victory_condition = read_requirement(data["victory_condition"],
                                         resource_database)
    starting_location = AreaIdentifier.from_json(data["starting_location"])
    initial_states = read_initial_states(data["initial_states"],
                                         resource_database)
    minimal_logic = read_minimal_logic_db(data["minimal_logic"])

    return world_reader, GameDescription(
        game=game,
        resource_database=resource_database,
        layers=layers,
        dock_weakness_database=dock_weakness_database,
        world_list=world_list,
        victory_condition=victory_condition,
        starting_location=starting_location,
        initial_states=initial_states,
        minimal_logic=minimal_logic,
    )
コード例 #8
0
def test_add_elevator_connections_to_patches_vanilla(echoes_game_description,
                                                     skip_final_bosses: bool,
                                                     default_echoes_configuration,
                                                     echoes_game_patches):
    # Setup
    patches_factory = echoes_game_description.game.generator.base_patches_factory
    expected = dataclasses.replace(echoes_game_patches,
                                   elevator_connection=echoes_game_description.get_default_elevator_connection())
    if skip_final_bosses:
        node_ident = NodeIdentifier.create("Temple Grounds", "Sky Temple Gateway",
                                           "Teleport to Great Temple - Sky Temple Energy Controller")
        expected.elevator_connection[node_ident] = AreaIdentifier("Temple Grounds", "Credits")

    config = default_echoes_configuration
    config = dataclasses.replace(config,
                                 elevators=dataclasses.replace(config.elevators,
                                                               skip_final_bosses=skip_final_bosses))

    # Run
    result = patches_factory.add_elevator_connections_to_patches(
        config,
        Random(0),
        echoes_game_patches)

    # Assert
    assert result == expected
コード例 #9
0
def test_create_new_dock(skip_qtbot, tmp_path, blank_game_data):
    db_path = Path(tmp_path.joinpath("test-game", "game"))
    game_data = default_data.read_json_then_binary(RandovaniaGame.BLANK)[1]

    window = DataEditorWindow(game_data, db_path, True, True)
    window.set_warning_dialogs_disabled(True)
    skip_qtbot.addWidget(window)

    window.focus_on_area_by_name("Back-Only Lock Room")
    current_area = window.current_area
    target_area = window.game_description.world_list.area_by_area_location(
        AreaIdentifier("Intro", "Explosive Depot"))

    assert current_area.node_with_name("Dock to Explosive Depot") is None
    assert target_area.node_with_name("Dock to Back-Only Lock Room") is None

    # Run
    window._create_new_dock(NodeLocation(0, 0, 0), target_area)

    # Assert
    new_node = current_area.node_with_name("Dock to Explosive Depot")
    assert new_node is not None
    assert window.current_node is new_node

    assert target_area.node_with_name(
        "Dock to Back-Only Lock Room") is not None
コード例 #10
0
ファイル: test_editor.py プロジェクト: randovania/randovania
def test_replace_node_unknown_node(game_editor):
    # Setup
    world_list = game_editor.game.world_list
    loc = AreaIdentifier("Temple Grounds", "Landing Site")
    loc2 = AreaIdentifier("Temple Grounds", "Service Access")

    landing_site = world_list.area_by_area_location(loc)
    dock = world_list.area_by_area_location(loc2).node_with_name(
        "Door to Landing Site")

    # Run
    with pytest.raises(
            ValueError,
            match=
            "Given Door to Landing Site does does not belong to Landing Site."
    ):
        game_editor.replace_node(landing_site, dock, dock)
コード例 #11
0
def _area_name_to_area_location(world_list: WorldList,
                                area_name: str) -> AreaIdentifier:
    world_name, area_name = re.match("([^/]+)/([^/]+)", area_name).group(1, 2)

    # Filter out dark world names
    world_name = world_list.world_with_name(world_name).name

    return AreaIdentifier(world_name, area_name)
コード例 #12
0
def test_one_way_elevator_connections(echoes_game_description, replacement,
                                      expected):
    # Setup
    rng = random.Random(5000)
    target_locations = [AreaIdentifier(f"w{i}", f"a{i}") for i in range(6)]
    elevators = [
        ElevatorHelper(NodeIdentifier.create(f"w{i}", f"a{i}", f"n{i}"),
                       AreaIdentifier(f"w{i}", f"a{i}")) for i in range(6)
    ]
    database = tuple(elevators)

    # Run
    result = elevator_distributor.one_way_elevator_connections(
        rng, database, target_locations, replacement)

    # Assert
    assert result == expected
コード例 #13
0
    def static_teleporters(self) -> Dict[NodeIdentifier, AreaIdentifier]:
        static = {}
        if self.skip_final_bosses:
            if self.game == RandovaniaGame.METROID_PRIME:
                crater = NodeIdentifier.create(
                    "Tallon Overworld", "Artifact Temple",
                    "Teleport to Impact Crater - Crater Impact Point")
                static[crater] = AreaIdentifier("End of Game", "Credits")
            elif self.game == RandovaniaGame.METROID_PRIME_ECHOES:
                gateway = NodeIdentifier.create(
                    "Temple Grounds", "Sky Temple Gateway",
                    "Teleport to Great Temple - Sky Temple Energy Controller")
                static[gateway] = AreaIdentifier("Temple Grounds", "Credits")
            else:
                raise ValueError(
                    f"Unsupported skip_final_bosses and {self.game}")

        return static
コード例 #14
0
def _location_with_data(request, mocker, echoes_game_description):
    world_list = echoes_game_description.world_list
    areas = list(itertools.islice(
        (AreaIdentifier(world.name, area.name)
         for world in world_list.worlds
         for area in world.areas
         if area.valid_starting_location), 15))

    mocker.patch("randovania.layout.lib.location_list.LocationList.areas_list",
                 return_value=list(sorted(areas)))
    return request.param["encoded"], LocationList.from_json(request.param["json"], RandovaniaGame.METROID_PRIME_ECHOES)
コード例 #15
0
def area_locations_with_filter(
        game: RandovaniaGame,
        condition: Callable[[Area], bool]) -> list[AreaIdentifier]:
    world_list = default_database.game_description_for(game).world_list
    identifiers = [
        AreaIdentifier(
            world_name=world.name,
            area_name=area.name,
        ) for world in world_list.worlds for area in world.areas
        if condition(area)
    ]
    return _sorted_area_identifiers(identifiers)
コード例 #16
0
ファイル: test_editor.py プロジェクト: randovania/randovania
def test_edit_connections(game_editor):
    # Setup
    landing_site = game_editor.game.world_list.area_by_area_location(
        AreaIdentifier("Temple Grounds", "Landing Site"))
    source = landing_site.node_with_name("Save Station")
    target = landing_site.node_with_name("Door to Service Access")
    assert landing_site.connections[source][target] != Requirement.trivial()

    # Run
    game_editor.edit_connections(landing_site, source, target,
                                 Requirement.trivial())

    # Assert
    assert landing_site.connections[source][target] == Requirement.trivial()
コード例 #17
0
ファイル: test_runner.py プロジェクト: randovania/randovania
def test_add_relative_hint(echoes_game_description, echoes_game_patches,
                           precise_distance, location_precision,
                           echoes_item_database):
    # Setup
    rng = Random(5000)
    target_precision = MagicMock(spec=HintItemPrecision)
    precision = MagicMock(spec=HintItemPrecision)
    patches = echoes_game_patches.assign_new_pickups([
        (PickupIndex(8),
         PickupTarget(
             _make_pickup(echoes_item_database.item_categories["movement"]),
             0)),
    ])
    hint_distributor = EchoesHintDistributor()

    if location_precision == HintLocationPrecision.RELATIVE_TO_AREA:
        max_distance = 8
        data = RelativeDataArea(
            None if precise_distance else 3,
            # Was Industrial Site
            AreaIdentifier("Temple Grounds", "Hive Chamber A"),
            precision,
        )
    else:
        max_distance = 20
        data = RelativeDataItem(
            None if precise_distance else 11,
            PickupIndex(8),
            precision,
        )

    # Run
    result = hint_distributor.add_relative_hint(
        echoes_game_description.world_list,
        patches,
        rng,
        PickupIndex(1),
        target_precision,
        location_precision,
        precise_distance,
        precision,
        max_distance=max_distance,
    )

    # Assert
    pair = PrecisionPair(location_precision,
                         target_precision,
                         include_owner=False,
                         relative=data)
    assert result == Hint(HintType.LOCATION, pair, PickupIndex(1))
コード例 #18
0
def test_quick_fill_cs_classic(skip_qtbot, preset_manager):
    # Setup
    base = preset_manager.default_preset_for_game(
        RandovaniaGame.CAVE_STORY).get_preset()
    preset = dataclasses.replace(
        base,
        uuid=uuid.UUID('b41fde84-1f57-4b79-8cd6-3e5a78077fa6'),
        base_preset_uuid=base.uuid)
    editor = PresetEditor(preset)
    window = PresetCSStartingArea(
        editor, default_database.game_description_for(preset.game))
    skip_qtbot.addWidget(window)

    # Run
    skip_qtbot.mouseClick(window.starting_area_quick_fill_classic,
                          QtCore.Qt.LeftButton)

    # Assert
    expected = {
        AreaIdentifier("Mimiga Village", "Start Point"),
        AreaIdentifier("Mimiga Village", "Arthur's House"),
        AreaIdentifier("Labyrinth", "Camp")
    }
    assert set(editor.configuration.starting_location.locations) == expected
コード例 #19
0
ファイル: test_editor.py プロジェクト: randovania/randovania
def test_remove_node(game_editor):
    # Setup
    world_list = game_editor.game.world_list
    loc = AreaIdentifier("Temple Grounds", "Landing Site")

    landing_site = world_list.area_by_area_location(loc)
    node = landing_site.node_with_name("Door to Service Access")
    assert node is not None

    # Run
    game_editor.remove_node(landing_site, node)

    # Assert
    assert world_list.area_by_area_location(loc).node_with_name(
        "Door to Service Access") is None
コード例 #20
0
def test_two_way_elevator_connections_unchecked():
    # Setup
    rng = random.Random(5000)
    elevators = [
        ElevatorHelper(NodeIdentifier.create(f"w{i}", f"a{i}", f"n{i}"),
                       AreaIdentifier(f"w{i}", f"a{i}")) for i in range(6)
    ]
    database = tuple(elevators)

    # Run
    result = elevator_distributor.two_way_elevator_connections(
        rng, database, False)

    # Assert
    assert result == {
        NodeIdentifier.create("w0", "a0", "n0"): AreaIdentifier("w4", "a4"),
        NodeIdentifier.create("w1", "a1", "n1"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w2", "a2", "n2"): AreaIdentifier("w1", "a1"),
        NodeIdentifier.create("w3", "a3", "n3"): AreaIdentifier("w5", "a5"),
        NodeIdentifier.create("w4", "a4", "n4"): AreaIdentifier("w0", "a0"),
        NodeIdentifier.create("w5", "a5", "n5"): AreaIdentifier("w3", "a3"),
    }
コード例 #21
0
    def read_node(self, name: str, data: Dict) -> Node:
        try:
            location = None
            if data["coordinates"] is not None:
                location = location_from_json(data["coordinates"])

            generic_args = {
                "identifier":
                NodeIdentifier.create(self.current_world_name,
                                      self.current_area_name, name),
                "heal":
                data["heal"],
                "location":
                location,
                "description":
                data["description"],
                "layers":
                tuple(data["layers"]),
                "extra":
                frozen_lib.wrap(data["extra"]),
            }
            node_type: int = data["node_type"]

            if node_type == "generic":
                return GenericNode(**generic_args)

            elif node_type == "dock":
                return DockNode(
                    **generic_args,
                    dock_type=self.dock_weakness_database.find_type(
                        data["dock_type"]),
                    default_connection=NodeIdentifier.from_json(
                        data["default_connection"]),
                    default_dock_weakness=self.dock_weakness_database.
                    get_by_weakness(
                        data["dock_type"],
                        data["default_dock_weakness"],
                    ),
                    override_default_open_requirement=read_optional_requirement(
                        data["override_default_open_requirement"],
                        self.resource_database),
                    override_default_lock_requirement=read_optional_requirement(
                        data["override_default_lock_requirement"],
                        self.resource_database),
                )

            elif node_type == "pickup":
                return PickupNode(
                    **generic_args,
                    pickup_index=PickupIndex(data["pickup_index"]),
                    major_location=data["major_location"],
                )

            elif node_type == "teleporter":
                return TeleporterNode(
                    **generic_args,
                    default_connection=AreaIdentifier.from_json(
                        data["destination"]),
                    keep_name_when_vanilla=data["keep_name_when_vanilla"],
                    editable=data["editable"],
                )

            elif node_type == "event":
                return EventNode(
                    **generic_args,
                    event=self.resource_database.get_by_type_and_index(
                        ResourceType.EVENT, data["event_name"]))

            elif node_type == "configurable_node":
                return ConfigurableNode(**generic_args, )

            elif node_type == "logbook":
                lore_type = LoreType(data["lore_type"])

                if lore_type == LoreType.REQUIRES_ITEM:
                    required_translator = self.resource_database.get_item(
                        data["extra"]["translator"])
                else:
                    required_translator = None

                if lore_type in {
                        LoreType.SPECIFIC_PICKUP, LoreType.SKY_TEMPLE_KEY_HINT
                }:
                    hint_index = data["extra"]["hint_index"]
                else:
                    hint_index = None

                return LogbookNode(
                    **generic_args,
                    string_asset_id=data["string_asset_id"],
                    scan_visor=self._get_scan_visor(),
                    lore_type=lore_type,
                    required_translator=required_translator,
                    hint_index=hint_index,
                )

            elif node_type == "player_ship":
                return PlayerShipNode(
                    **generic_args,
                    is_unlocked=read_requirement(data["is_unlocked"],
                                                 self.resource_database),
                    item_to_summon=self._get_command_visor(),
                )

            else:
                raise Exception(f"Unknown type: {node_type}")

        except Exception as e:
            raise Exception(f"In node {name}, got error: {e}")
コード例 #22
0
 def from_json(cls, value: dict) -> "NodeIdentifier":
     return cls(AreaIdentifier.from_json(value), value["node_name"])
コード例 #23
0
 def create(cls, world_name: str, area_name: str, node_name: str) -> "NodeIdentifier":
     return cls(AreaIdentifier(world_name, area_name), node_name)
コード例 #24
0
 def identifier_for_area(self, area: Area) -> AreaIdentifier:
     world = self.world_with_area(area)
     return AreaIdentifier(world_name=world.name, area_name=area.name)
コード例 #25
0
    def setup_elevators(self):
        self._elevator_id_to_combo = {}

        if not hasattr(self.game_configuration, "elevators"):
            return

        elevators_config: TeleporterConfiguration = getattr(
            self.game_configuration, "elevators")

        world_list = self.game_description.world_list
        nodes_by_world: Dict[
            str, List[TeleporterNode]] = collections.defaultdict(list)

        areas_to_not_change = {
            "Sky Temple Gateway",
            "Sky Temple Energy Controller",
            "Aerie Transport Station",
            "Aerie",
        }
        targets = {}
        for world, area, node in world_list.all_worlds_areas_nodes:
            if isinstance(
                    node, TeleporterNode
            ) and node.editable and area.name not in areas_to_not_change:
                name = world.correct_name(area.in_dark_aether)
                nodes_by_world[name].append(node)

                location = AreaIdentifier(world.name, area.name)
                targets[elevators.get_short_elevator_or_area_name(
                    self.game_configuration.game, world_list, location,
                    True)] = location

        if elevators_config.mode == TeleporterShuffleMode.ONE_WAY_ANYTHING:
            targets = {}
            for world in world_list.worlds:
                for area in world.areas:
                    name = world.correct_name(area.in_dark_aether)
                    targets[f"{name} - {area.name}"] = AreaIdentifier(
                        world.name, area.name)

        combo_targets = sorted(targets.items(), key=lambda it: it[0])

        for world_name in sorted(nodes_by_world.keys()):
            nodes = nodes_by_world[world_name]
            nodes_locations = [
                world_list.identifier_for_node(node).area_location
                for node in nodes
            ]
            nodes_names = [
                elevators.get_short_elevator_or_area_name(
                    self.game_configuration.game, world_list, location, False)
                for location in nodes_locations
            ]

            group = QtWidgets.QGroupBox(self.elevators_scroll_contents)
            group.setTitle(world_name)
            self.elevators_scroll_layout.addWidget(group)
            layout = QtWidgets.QGridLayout(group)

            for i, (node, location, name) in enumerate(
                    sorted(zip(nodes, nodes_locations, nodes_names),
                           key=lambda it: it[2])):
                node_name = QtWidgets.QLabel(group)
                node_name.setText(name)
                node_name.setWordWrap(True)
                node_name.setMinimumWidth(75)
                layout.addWidget(node_name, i, 0)

                combo = QtWidgets.QComboBox(group)
                if elevators_config.is_vanilla:
                    combo.addItem("Vanilla", node.default_connection)
                    combo.setEnabled(False)
                else:
                    combo.addItem("Undefined", None)
                    for target_name, connection in combo_targets:
                        combo.addItem(target_name, connection)

                combo.setMinimumContentsLength(11)
                combo.currentIndexChanged.connect(
                    self.update_locations_tree_for_reachable_nodes)
                self._elevator_id_to_combo[world_list.identifier_for_node(
                    node)] = combo
                layout.addWidget(combo, i, 1)
コード例 #26
0
    def apply_previous_state(self, previous_state: Optional[dict]) -> bool:
        if previous_state is None:
            return False

        starting_location = None
        needs_starting_location = len(
            self.game_configuration.starting_location.locations) > 1
        configurable_nodes = {}

        try:
            pickup_name_to_pickup = {
                pickup.name: pickup
                for pickup in self._collected_pickups.keys()
            }
            quantity_to_change = {
                pickup_name_to_pickup[pickup_name]: quantity
                for pickup_name, quantity in
                previous_state["collected_pickups"].items()
            }
            previous_actions = [
                self.game_description.world_list.node_by_identifier(
                    NodeIdentifier.from_string(identifier))
                for identifier in previous_state["actions"]
            ]
            if needs_starting_location:
                starting_location = AreaIdentifier.from_json(
                    previous_state["starting_location"])

            teleporters: Dict[NodeIdentifier, Optional[AreaIdentifier]] = {
                NodeIdentifier.from_json(item["teleporter"]):
                (AreaIdentifier.from_json(item["data"])
                 if item["data"] is not None else None)
                for item in previous_state["elevators"]
            }
            if self.game_configuration.game == RandovaniaGame.METROID_PRIME_ECHOES:
                configurable_nodes = {
                    NodeIdentifier.from_string(identifier):
                    (LayoutTranslatorRequirement(item)
                     if item is not None else None)
                    for identifier, item in
                    previous_state["configurable_nodes"].items()
                }
        except (KeyError, AttributeError):
            return False

        self.setup_starting_location(starting_location)

        for teleporter, area_location in teleporters.items():
            combo = self._elevator_id_to_combo[teleporter]
            if area_location is None:
                combo.setCurrentIndex(0)
                continue
            for i in range(combo.count()):
                if area_location == combo.itemData(i):
                    combo.setCurrentIndex(i)
                    break

        for identifier, requirement in configurable_nodes.items():
            combo = self._translator_gate_to_combo[identifier]
            for i in range(combo.count()):
                if requirement == combo.itemData(i):
                    combo.setCurrentIndex(i)
                    break

        self.bulk_change_quantity(quantity_to_change)
        self._add_new_actions(previous_actions)

        world_list = self.game_description.world_list
        state = self.state_for_current_configuration()
        self.focus_on_world(world_list.nodes_to_world(state.node))
        self.focus_on_area(world_list.nodes_to_area(state.node))

        return True
コード例 #27
0
    def create_new_node(self) -> Node:
        node_type = self.node_type_combo.currentData()
        identifier = dataclasses.replace(self.node.identifier, node_name=self.name_edit.text())
        heal = self.heals_check.isChecked()
        location = None
        if self.location_group.isChecked():
            location = NodeLocation(self.location_x_spin.value(),
                                    self.location_y_spin.value(),
                                    self.location_z_spin.value())
        description = self.description_edit.toMarkdown()
        extra = json.loads(self.extra_edit.toPlainText())
        layers = (self.layers_combo.currentText(),)

        if node_type == GenericNode:
            return GenericNode(identifier, heal, location, description, layers, extra)

        elif node_type == DockNode:
            connection_node: Node = self.dock_connection_node_combo.currentData()

            return DockNode(
                identifier, heal, location, description, layers, extra,
                self.dock_type_combo.currentData(),
                self.game.world_list.identifier_for_node(connection_node),
                self.dock_weakness_combo.currentData(),
                None, None,
            )

        elif node_type == PickupNode:
            return PickupNode(
                identifier, heal, location, description, layers, extra,
                PickupIndex(self.pickup_index_spin.value()),
                self.major_location_check.isChecked(),
            )

        elif node_type == TeleporterNode:
            dest_world: World = self.teleporter_destination_world_combo.currentData()
            dest_area: Area = self.teleporter_destination_area_combo.currentData()

            return TeleporterNode(
                identifier, heal, location, description, layers, extra,
                AreaIdentifier(
                    world_name=dest_world.name,
                    area_name=dest_area.name,
                ),
                self.teleporter_vanilla_name_edit.isChecked(),
                self.teleporter_editable_check.isChecked(),
            )

        elif node_type == EventNode:
            event = self.event_resource_combo.currentData()
            if event is None:
                raise ValueError("There are no events in the database, unable to create EventNode.")
            return EventNode(
                identifier, heal, location, description, layers, extra,
                event,
            )

        elif node_type == ConfigurableNode:
            return ConfigurableNode(
                identifier, heal, location, description, layers, extra,
            )

        elif node_type == LogbookNode:
            lore_type: LoreType = self.lore_type_combo.currentData()
            if lore_type == LoreType.REQUIRES_ITEM:
                required_translator = self.logbook_extra_combo.currentData()
                if required_translator is None:
                    raise ValueError("Missing required translator.")
            else:
                required_translator = None

            if lore_type == LoreType.SPECIFIC_PICKUP:
                hint_index = self.logbook_extra_combo.currentData()
            else:
                hint_index = None

            return LogbookNode(
                identifier, heal, location, description, layers, extra,
                int(self.logbook_string_asset_id_edit.text(), 0),
                self._get_scan_visor(),
                lore_type,
                required_translator,
                hint_index
            )

        elif node_type == PlayerShipNode:
            return PlayerShipNode(
                identifier, heal, location, description, layers, extra,
                self._unlocked_by_requirement,
                self._get_command_visor()
            )

        else:
            raise RuntimeError(f"Unknown node type: {node_type}")
コード例 #28
0
            default_echoes_configuration.major_items_configuration,
            minimum_random_starting_items=2,
        ),
        sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
    )

    # Run
    result = pool_creator.calculate_pool_item_count(layout_configuration)

    # Assert
    assert result == (118, 121)


@pytest.mark.parametrize("puppies", [False, True])
@pytest.mark.parametrize("starting_area", [
    AreaIdentifier("Mimiga Village", "Start Point"),
    AreaIdentifier("Labyrinth", "Camp")
])
def test_cs_item_pool_creator(default_cs_configuration: CSConfiguration,
                              puppies, starting_area):
    game_description = default_database.game_description_for(
        default_cs_configuration.game)
    default_cs_configuration = dataclasses.replace(default_cs_configuration,
                                                   puppies_anywhere=puppies)
    tricks = default_cs_configuration.trick_level.set_level_for_trick(
        game_description.resource_database.get_by_type_and_index(
            ResourceType.TRICK, "SNBubbler"), LayoutTrickLevel.HYPERMODE)
    tricks = tricks.set_level_for_trick(
        game_description.resource_database.get_by_type_and_index(
            ResourceType.TRICK, "SNMissiles"), LayoutTrickLevel.HYPERMODE)
    default_cs_configuration = dataclasses.replace(default_cs_configuration,
コード例 #29
0
 def node_to_area_location(self, node: Node) -> AreaIdentifier:
     return AreaIdentifier(
         world_name=self.nodes_to_world(node).name,
         area_name=self.nodes_to_area(node).name,
     )
コード例 #30
0
 def ni(w: str, a: str, n: str, tw: str, ta: str):
     elevator_connection[NodeIdentifier.create(w, a, n)] = AreaIdentifier(tw, ta)