def test_create_translator_gates_field(): # Setup gate_assignment = { TranslatorGate(1): SimpleResourceInfo(10, "LongA", "A", ResourceType.ITEM), TranslatorGate(3): SimpleResourceInfo(50, "LongB", "B", ResourceType.ITEM), TranslatorGate(4): SimpleResourceInfo(10, "LongA", "A", ResourceType.ITEM), } # Run result = claris_patcher_file._create_translator_gates_field( gate_assignment) # Assert assert result == [ { "gate_index": 1, "translator_index": 10 }, { "gate_index": 3, "translator_index": 50 }, { "gate_index": 4, "translator_index": 10 }, ]
def test_gate_assignment_for_configuration_all_random( echoes_resource_database): # Setup violet = find_resource_info_with_long_name(echoes_resource_database.item, "Violet Translator") emerald = find_resource_info_with_long_name(echoes_resource_database.item, "Emerald Translator") configuration = MagicMock() configuration.translator_configuration.translator_requirement = { TranslatorGate(index): LayoutTranslatorRequirement.RANDOM for index in [1, 15, 23] } rng = MagicMock() rng.choice.side_effect = [ LayoutTranslatorRequirement.EMERALD, LayoutTranslatorRequirement.VIOLET, LayoutTranslatorRequirement.EMERALD, ] # Run results = base_patches_factory.gate_assignment_for_configuration( configuration, echoes_resource_database, rng) # Assert assert results == { TranslatorGate(1): emerald, TranslatorGate(15): violet, TranslatorGate(23): emerald, }
def test_basic_search_with_translator_gate(has_translator: bool, echoes_resource_database): # Setup scan_visor = echoes_resource_database.get_item(10) node_a = GenericNode("Node A", True, None, 0) node_b = GenericNode("Node B", True, None, 1) node_c = GenericNode("Node C", True, None, 2) translator_node = TranslatorGateNode("Translator Gate", True, None, 3, TranslatorGate(1), scan_visor) world_list = WorldList([ World("Test World", "Test Dark World", 1, [ Area( "Test Area A", False, 10, 0, True, [node_a, node_b, node_c, translator_node], { node_a: { node_b: Requirement.trivial(), translator_node: Requirement.trivial(), }, node_b: { node_a: Requirement.trivial(), }, node_c: { translator_node: Requirement.trivial(), }, translator_node: { node_a: Requirement.trivial(), node_c: Requirement.trivial(), }, }) ]) ]) game_specific = EchoesGameSpecific(energy_per_tank=100, safe_zone_heal_per_second=1, beam_configurations=(), dangerous_energy_tank=False) game = GameDescription(RandovaniaGame.PRIME2, DockWeaknessDatabase([], [], [], []), echoes_resource_database, game_specific, Requirement.impossible(), None, {}, world_list) patches = game.create_game_patches() patches = patches.assign_gate_assignment({TranslatorGate(1): scan_visor}) initial_state = State({scan_visor: 1 if has_translator else 0}, (), 99, node_a, patches, None, echoes_resource_database, game.world_list) # Run reach = reach_with_all_safe_resources(game, initial_state) # Assert if has_translator: assert set( reach.safe_nodes) == {node_a, node_b, translator_node, node_c} else: assert set(reach.safe_nodes) == {node_a, node_b}
def test_basic_search_with_translator_gate(has_translator: bool, echoes_resource_database): # Setup scan_visor = echoes_resource_database.get_by_type_and_index( ResourceType.ITEM, 10) node_a = GenericNode("Node A", True, 0) node_b = GenericNode("Node B", True, 1) node_c = GenericNode("Node C", True, 2) translator_node = TranslatorGateNode("Translator Gate", True, 3, TranslatorGate(1), scan_visor) world_list = WorldList([ World("Test World", 1, [ Area( "Test Area A", False, 10, 0, [node_a, node_b, node_c, translator_node], { node_a: { node_b: RequirementSet.trivial(), translator_node: RequirementSet.trivial(), }, node_b: { node_a: RequirementSet.trivial(), }, node_c: { translator_node: RequirementSet.trivial(), }, translator_node: { node_a: RequirementSet.trivial(), node_c: RequirementSet.trivial(), }, }) ]) ]) game = GameDescription(0, "", DockWeaknessDatabase([], [], [], []), echoes_resource_database, RequirementSet.impossible(), None, {}, world_list) patches = GamePatches.with_game(game) patches = patches.assign_gate_assignment({TranslatorGate(1): scan_visor}) initial_state = State({scan_visor: 1 if has_translator else 0}, (), 99, node_a, patches, None, echoes_resource_database) # Run reach = reach_with_all_safe_resources(game, initial_state) # Assert if has_translator: assert set( reach.safe_nodes) == {node_a, node_b, translator_node, node_c} else: assert set(reach.safe_nodes) == {node_a, node_b}
def __init__(self, editor: PresetEditor): super().__init__() self.setupUi(self) self._editor = editor randomizer_data = default_data.decode_randomizer_data() self.translators_layout.setAlignment(QtCore.Qt.AlignTop) self.translator_randomize_all_button.clicked.connect( self._on_randomize_all_gates_pressed) self.translator_vanilla_actual_button.clicked.connect( self._on_vanilla_actual_gates_pressed) self.translator_vanilla_colors_button.clicked.connect( self._on_vanilla_colors_gates_pressed) self._combo_for_gate = {} for i, gate in enumerate(randomizer_data["TranslatorLocationData"]): label = QtWidgets.QLabel(self.translators_scroll_contents) label.setText(gate["Name"]) self.translators_layout.addWidget(label, 3 + i, 0, 1, 1) combo = QComboBox(self.translators_scroll_contents) combo.gate = TranslatorGate(gate["Index"]) for item in iterate_enum(LayoutTranslatorRequirement): combo.addItem(item.long_name, item) combo.currentIndexChanged.connect( functools.partial(self._on_gate_combo_box_changed, combo)) self.translators_layout.addWidget(combo, 3 + i, 1, 1, 2) self._combo_for_gate[combo.gate] = combo
def setup_translators_elements(self): randomizer_data = default_data.decode_randomizer_data() self.always_up_gfmc_compound_check.stateChanged.connect( functools.partial(self._on_always_up_check_changed, "fixed_gfmc_compound")) self.always_up_torvus_temple_check.stateChanged.connect( functools.partial(self._on_always_up_check_changed, "fixed_torvus_temple")) self.always_up_great_temple_check.stateChanged.connect( functools.partial(self._on_always_up_check_changed, "fixed_great_temple")) self.translator_randomize_all_button.clicked.connect(self._on_randomize_all_gates_pressed) self.translator_vanilla_actual_button.clicked.connect(self._on_vanilla_actual_gates_pressed) self.translator_vanilla_colors_button.clicked.connect(self._on_vanilla_colors_gates_pressed) self._combo_for_gate = {} for i, gate in enumerate(randomizer_data["TranslatorLocationData"]): label = QLabel(self.translators_scroll_contents) label.setText(gate["Name"]) self.translators_layout.addWidget(label, 3 + i, 0, 1, 1) combo = QComboBox(self.translators_scroll_contents) combo.gate = TranslatorGate(gate["Index"]) for item in LayoutTranslatorRequirement: combo.addItem(item.long_name, item) combo.currentIndexChanged.connect(functools.partial(self._on_gate_combo_box_changed, combo)) self.translators_layout.addWidget(combo, 3 + i, 1, 1, 2) self._combo_for_gate[combo.gate] = combo
def _find_gate_with_name(gate_name: str) -> TranslatorGate: from randovania.games.patchers import claris_patcher for items in claris_patcher.decode_randomizer_data( )["TranslatorLocationData"]: if items["Name"] == gate_name: return TranslatorGate(items["Index"]) raise ValueError("Unknown gate name: {}".format(gate_name))
def from_json(cls, value: dict) -> "TranslatorConfiguration": default = cls.default() params = copy.copy(value) translator_requirement = copy.copy(default.translator_requirement) for key, item in params.pop("translator_requirement").items(): translator_requirement[TranslatorGate( int(key))] = LayoutTranslatorRequirement(item) return cls(translator_requirement, **params)
def test_gate_assignment_for_configuration_all_emerald( echoes_resource_database): # Setup emerald = find_resource_info_with_long_name(echoes_resource_database.item, "Emerald Translator") indices = [1, 15, 23] configuration = MagicMock() configuration.translator_configuration.translator_requirement = { TranslatorGate(index): LayoutTranslatorRequirement.EMERALD for index in indices } rng = MagicMock() # Run results = base_patches_factory.gate_assignment_for_configuration( configuration, echoes_resource_database, rng) # Assert assert results == {TranslatorGate(index): emerald for index in indices}
def _find_gate_with_name(gate_name: str) -> TranslatorGate: for items in default_data.decode_randomizer_data( )["TranslatorLocationData"]: if items["Name"] == gate_name: return TranslatorGate(items["Index"]) raise ValueError("Unknown gate name: {}".format(gate_name))
def create_new_node(self) -> Node: node_type = self.node_type_combo.currentData() 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()) index = self.node.index if node_type == GenericNode: return GenericNode(name, heal, location, index) elif node_type == DockNode: return DockNode( name, heal, location, index, self.dock_index_spin.value(), DockConnection( self.dock_connection_area_combo.currentData( ).area_asset_id, self.dock_connection_node_combo.currentData()), self.dock_weakness_combo.currentData(), ) elif node_type == PickupNode: return PickupNode( name, heal, location, index, PickupIndex(self.pickup_index_spin.value()), self.major_location_check.isChecked(), ) elif node_type == TeleporterNode: instance_id = self.teleporter_instance_id_edit.text() scan_asset_id = self.teleporter_scan_asset_id_edit.text() return TeleporterNode( name, heal, location, index, int(instance_id, 0) if instance_id != "" else None, AreaLocation( self.teleporter_destination_world_combo.currentData( ).world_asset_id, self.teleporter_destination_area_combo.currentData(). area_asset_id), int(scan_asset_id, 0) if scan_asset_id != "" else None, 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( name, heal, location, index, event, ) elif node_type == TranslatorGateNode: return TranslatorGateNode( name, heal, location, index, TranslatorGate(self.translator_gate_spin.value()), self._get_scan_visor()) elif node_type == LogbookNode: lore_type: LoreType = self.lore_type_combo.currentData() if lore_type == LoreType.LUMINOTH_LORE: 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.LUMINOTH_WARRIOR: hint_index = self.logbook_extra_combo.currentData() else: hint_index = None return LogbookNode( name, heal, location, index, 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(name, heal, location, index, self._unlocked_by_requirement, self._get_command_visor()) else: raise RuntimeError(f"Unknown node type: {node_type}")
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.layout_configuration.starting_location.locations) > 1 resource_db = self.game_description.resource_database translator_gates = {} 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.all_nodes[index] for index in previous_state["actions"] ] if needs_starting_location: starting_location = AreaLocation.from_json( previous_state["starting_location"]) elevators: Dict[Teleporter, Optional[AreaLocation]] = { Teleporter.from_json(item["teleporter"]): AreaLocation.from_json(item["data"]) if item["data"] is not None else None for item in previous_state["elevators"] } if self.layout_configuration.game == RandovaniaGame.PRIME2: translator_gates = { TranslatorGate(int(gate)): (resource_db.get_item(item) if item is not None else self._undefined_item) for gate, item in previous_state["translator_gates"].items() } except KeyError: return False self.setup_starting_location(starting_location) for teleporter, area_location in elevators.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 gate, item in translator_gates.items(): combo = self._translator_gate_to_combo[gate] for i in range(combo.count()): if item == combo.itemData(i): combo.setCurrentIndex(i) break self.bulk_change_quantity(quantity_to_change) self._add_new_actions(previous_actions) return True
def read_node(self, data: Dict) -> Node: name: str = data["name"] heal: bool = data["heal"] node_type: int = data["node_type"] self.generic_index += 1 if node_type == 0: return GenericNode(name, heal, self.generic_index) elif node_type == 1: return DockNode( name, heal, self.generic_index, data["dock_index"], DockConnection(data["connected_area_asset_id"], data["connected_dock_index"]), self.dock_weakness_database.get_by_type_and_index( DockType(data["dock_type"]), data["dock_weakness_index"])) elif node_type == 2: return PickupNode(name, heal, self.generic_index, PickupIndex(data["pickup_index"]), data["major_location"]) elif node_type == 3: instance_id = data["teleporter_instance_id"] destination_world_asset_id = data["destination_world_asset_id"] destination_area_asset_id = data["destination_area_asset_id"] return TeleporterNode( name, heal, self.generic_index, instance_id, AreaLocation(destination_world_asset_id, destination_area_asset_id), data["keep_name_when_vanilla"], data["editable"], ) elif node_type == 4: return EventNode( name, heal, self.generic_index, self.resource_database.get_by_type_and_index( ResourceType.EVENT, data["event_index"])) elif node_type == 5: return TranslatorGateNode( name, heal, self.generic_index, TranslatorGate(data["gate_index"]), find_resource_info_with_long_name(self.resource_database.item, "Scan Visor")) elif node_type == 6: lore_type = list(LoreType)[data["lore_type"]] if lore_type == LoreType.LUMINOTH_LORE: required_translator = self.resource_database.get_item( data["extra"]) else: required_translator = None if lore_type in { LoreType.LUMINOTH_WARRIOR, LoreType.SKY_TEMPLE_KEY_HINT }: hint_index = data["extra"] else: hint_index = None return LogbookNode( name, heal, self.generic_index, data["string_asset_id"], find_resource_info_with_long_name(self.resource_database.item, "Scan Visor"), lore_type, required_translator, hint_index) else: raise Exception("Unknown node type: {}".format(node_type))
def _patches_with_data(request, echoes_game_data, echoes_item_database): game = data_reader.decode_data(echoes_game_data) data = { "starting_location": "Temple Grounds/Landing Site", "starting_items": {}, "elevators": { "Temple Grounds/Temple Transport C": "Great Temple/Temple Transport C", "Temple Grounds/Transport to Agon Wastes": "Agon Wastes/Transport to Temple Grounds", "Temple Grounds/Transport to Torvus Bog": "Torvus Bog/Transport to Temple Grounds", "Temple Grounds/Temple Transport B": "Great Temple/Temple Transport B", "Temple Grounds/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Temple Grounds", "Temple Grounds/Temple Transport A": "Great Temple/Temple Transport A", "Great Temple/Temple Transport A": "Temple Grounds/Temple Transport A", "Great Temple/Temple Transport C": "Temple Grounds/Temple Transport C", "Great Temple/Temple Transport B": "Temple Grounds/Temple Transport B", "Sky Temple Grounds/Sky Temple Gateway": "Sky Temple/Sky Temple Energy Controller", "Sky Temple/Sky Temple Energy Controller": "Sky Temple Grounds/Sky Temple Gateway", "Agon Wastes/Transport to Temple Grounds": "Temple Grounds/Transport to Agon Wastes", "Agon Wastes/Transport to Torvus Bog": "Torvus Bog/Transport to Agon Wastes", "Agon Wastes/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Agon Wastes", "Torvus Bog/Transport to Temple Grounds": "Temple Grounds/Transport to Torvus Bog", "Torvus Bog/Transport to Agon Wastes": "Agon Wastes/Transport to Torvus Bog", "Torvus Bog/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Torvus Bog", "Sanctuary Fortress/Transport to Temple Grounds": "Temple Grounds/Transport to Sanctuary Fortress", "Sanctuary Fortress/Transport to Agon Wastes": "Agon Wastes/Transport to Sanctuary Fortress", "Sanctuary Fortress/Transport to Torvus Bog": "Torvus Bog/Transport to Sanctuary Fortress", "Sanctuary Fortress/Aerie": "Sanctuary Fortress/Aerie Transport Station", "Sanctuary Fortress/Aerie Transport Station": "Sanctuary Fortress/Aerie", }, "translators": {}, "locations": {}, "hints": {}, "_locations_internal": "", } patches = game.create_game_patches() locations = collections.defaultdict(dict) for world, area, node in game.world_list.all_worlds_areas_nodes: if node.is_resource_node and isinstance(node, PickupNode): world_name = world.dark_name if area.in_dark_aether else world.name locations[world_name][game.world_list.node_name(node)] = game_patches_serializer._ETM_NAME data["locations"] = { world: { area: item for area, item in sorted(locations[world].items()) } for world in sorted(locations.keys()) } if request.param.get("starting_item"): item_name = request.param.get("starting_item") patches = patches.assign_extra_initial_items({ find_resource_info_with_long_name(game.resource_database.item, item_name): 1, }) data["starting_items"][item_name] = 1 if request.param.get("elevator"): elevator_id, elevator_source = request.param.get("elevator") elevator_connection = copy.copy(patches.elevator_connection) elevator_connection[elevator_id] = game.starting_location patches = dataclasses.replace(patches, elevator_connection=elevator_connection) data["elevators"][elevator_source] = "Temple Grounds/Landing Site" if request.param.get("translator"): gates = {} for index, gate_name, translator in request.param.get("translator"): gates[TranslatorGate(index)] = find_resource_info_with_long_name(game.resource_database.item, translator) data["translators"][gate_name] = translator patches = patches.assign_gate_assignment(gates) if request.param.get("pickup"): data["_locations_internal"], pickup_name = request.param.get("pickup") pickup = pickup_creator.create_major_item(echoes_item_database.major_items[pickup_name], MajorItemState(), True, game.resource_database, None, False) patches = patches.assign_new_pickups([(PickupIndex(5), pickup)]) data["locations"]["Temple Grounds"]['Transport to Agon Wastes/Pickup (Missile)'] = pickup_name if request.param.get("hint"): asset, hint = request.param.get("hint") patches = patches.assign_hint(LogbookAsset(asset), Hint.from_json(hint)) data["hints"][str(asset)] = hint return data, patches
def read_node(self, data: Dict) -> Node: name: str = data["name"] self.generic_index += 1 try: heal: bool = data["heal"] node_type: int = data["node_type"] location = None if data["coordinates"] is not None: location = location_from_json(data["coordinates"]) if node_type == "generic": return GenericNode(name, heal, location, self.generic_index) elif node_type == "dock": return DockNode( name, heal, location, self.generic_index, data["dock_index"], DockConnection(data["connected_area_asset_id"], data["connected_dock_index"]), self.dock_weakness_database.get_by_type_and_index( DockType(data["dock_type"]), data["dock_weakness_index"])) elif node_type == "pickup": return PickupNode(name, heal, location, self.generic_index, PickupIndex(data["pickup_index"]), data["major_location"]) elif node_type == "teleporter": instance_id = data["teleporter_instance_id"] destination_world_asset_id = data["destination_world_asset_id"] destination_area_asset_id = data["destination_area_asset_id"] return TeleporterNode( name, heal, location, self.generic_index, instance_id, AreaLocation(destination_world_asset_id, destination_area_asset_id), data["scan_asset_id"], data["keep_name_when_vanilla"], data["editable"], ) elif node_type == "event": return EventNode( name, heal, location, self.generic_index, self.resource_database.get_by_type_and_index( ResourceType.EVENT, data["event_index"])) elif node_type == "translator_gate": return TranslatorGateNode(name, heal, location, self.generic_index, TranslatorGate(data["gate_index"]), self._get_scan_visor()) elif node_type == "logbook": lore_type = LoreType(data["lore_type"]) if lore_type == LoreType.LUMINOTH_LORE: required_translator = self.resource_database.get_item( data["extra"]) else: required_translator = None if lore_type in { LoreType.LUMINOTH_WARRIOR, LoreType.SKY_TEMPLE_KEY_HINT }: hint_index = data["extra"] else: hint_index = None return LogbookNode(name, heal, location, self.generic_index, data["string_asset_id"], self._get_scan_visor(), lore_type, required_translator, hint_index) else: raise Exception(f"Unknown type: {node_type}") except Exception as e: raise Exception(f"In node {name}, got error: {e}")
def _raw_translator_configurations( data: dict) -> Dict[TranslatorGate, LayoutTranslatorRequirement]: return { TranslatorGate(int(key)): LayoutTranslatorRequirement(item) for key, item in data["translator_requirement"].items() }
def _patches_with_data(request, echoes_game_data, echoes_item_database): game = data_reader.decode_data(echoes_game_data) data = { "starting_location": "Temple Grounds/Landing Site", "starting_items": {}, "elevators": { "Temple Grounds/Temple Transport C": "Great Temple/Temple Transport C", "Temple Grounds/Transport to Agon Wastes": "Agon Wastes/Transport to Temple Grounds", "Temple Grounds/Transport to Torvus Bog": "Torvus Bog/Transport to Temple Grounds", "Temple Grounds/Temple Transport B": "Great Temple/Temple Transport B", "Temple Grounds/Sky Temple Gateway": "Great Temple/Sky Temple Energy Controller", "Temple Grounds/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Temple Grounds", "Temple Grounds/Temple Transport A": "Great Temple/Temple Transport A", "Great Temple/Temple Transport A": "Temple Grounds/Temple Transport A", "Great Temple/Temple Transport C": "Temple Grounds/Temple Transport C", "Great Temple/Temple Transport B": "Temple Grounds/Temple Transport B", "Great Temple/Sky Temple Energy Controller": "Temple Grounds/Sky Temple Gateway", "Agon Wastes/Transport to Temple Grounds": "Temple Grounds/Transport to Agon Wastes", "Agon Wastes/Transport to Torvus Bog": "Torvus Bog/Transport to Agon Wastes", "Agon Wastes/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Agon Wastes", "Torvus Bog/Transport to Temple Grounds": "Temple Grounds/Transport to Torvus Bog", "Torvus Bog/Transport to Agon Wastes": "Agon Wastes/Transport to Torvus Bog", "Torvus Bog/Transport to Sanctuary Fortress": "Sanctuary Fortress/Transport to Torvus Bog", "Sanctuary Fortress/Transport to Temple Grounds": "Temple Grounds/Transport to Sanctuary Fortress", "Sanctuary Fortress/Transport to Agon Wastes": "Agon Wastes/Transport to Sanctuary Fortress", "Sanctuary Fortress/Transport to Torvus Bog": "Torvus Bog/Transport to Sanctuary Fortress" }, "translators": {}, "locations": { world.name: { game.world_list.node_name(node): "Nothing" for node in world.all_nodes if node.is_resource_node and isinstance(node, PickupNode) } for world in sorted(game.world_list.worlds, key=lambda w: w.name) }, "hints": {}, "_locations_internal": "", } patches = GamePatches.with_game(game) if request.param.get("starting_item"): item_name = request.param.get("starting_item") patches = patches.assign_extra_initial_items({ find_resource_info_with_long_name(game.resource_database.item, item_name): 1, }) data["starting_items"][item_name] = 1 if request.param.get("elevator"): elevator_id, elevator_source = request.param.get("elevator") elevator_connection = copy.copy(patches.elevator_connection) elevator_connection[elevator_id] = game.starting_location patches = dataclasses.replace(patches, elevator_connection=elevator_connection) data["elevators"][elevator_source] = "Temple Grounds/Landing Site" if request.param.get("translator"): gates = {} for index, gate_name, translator in request.param.get("translator"): gates[TranslatorGate(index)] = find_resource_info_with_long_name( game.resource_database.item, translator) data["translators"][gate_name] = translator patches = patches.assign_gate_assignment(gates) if request.param.get("pickup"): data["_locations_internal"], pickup_name = request.param.get("pickup") pickup = pickup_creator.create_major_item( echoes_item_database.major_items[pickup_name], MajorItemState(), True, game.resource_database, None, False) patches = patches.assign_new_pickups([(PickupIndex(5), pickup)]) data["locations"]["Temple Grounds"][ 'Transport to Agon Wastes/Pickup (Missile)'] = pickup_name if request.param.get("hint"): asset, hint = request.param.get("hint") patches = patches.assign_hint(LogbookAsset(asset), Hint.from_json(hint)) data["hints"][str(asset)] = hint return data, patches