示例#1
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,
    )
示例#2
0
 def from_json(cls, value: dict) -> "NodeIdentifier":
     return cls(AreaIdentifier.from_json(value), value["node_name"])
示例#3
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}")
示例#4
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