def test_calculate_dangerous_resources(danger_a, danger_b, expected_result): set_a: Requirement = MagicMock() set_b: Requirement = MagicMock() set_a.as_set.return_value.dangerous_resources = danger_a set_b.as_set.return_value.dangerous_resources = danger_b n1 = MagicMock() n1.node_index = 0 n2 = MagicMock() n2.node_index = 1 n3 = MagicMock() n3.node_index = 2 n4 = MagicMock() n4.node_index = 3 area_a = Area("area_a", 0, True, [n1, n2], {n1: {n2: set_a}, n2: {}}, {}) area_b = Area("area_b", 0, True, [n3, n4], {n3: {}, n4: {n3: set_b}}, {}) world = World("W", [area_a, area_b], {}) wl = WorldList([world]) # Run result = game_description._calculate_dangerous_resources_in_areas(wl, None) # Assert assert set(result) == set(expected_result)
def test_connections_from_dock_blast_shield(empty_patches): # Setup trivial = Requirement.trivial() req_1 = ResourceRequirement.simple( SimpleResourceInfo(0, "Ev1", "Ev1", ResourceType.EVENT)) req_2 = ResourceRequirement.simple( SimpleResourceInfo(1, "Ev2", "Ev2", ResourceType.EVENT)) dock_type = DockType("Type", "Type", frozendict()) weak_1 = DockWeakness(0, "Weak 1", frozendict(), req_1, None) weak_2 = DockWeakness(1, "Weak 2", frozendict(), trivial, DockLock(DockLockType.FRONT_BLAST_BACK_BLAST, req_2)) node_1_identifier = NodeIdentifier.create("W", "Area 1", "Node 1") node_2_identifier = NodeIdentifier.create("W", "Area 2", "Node 2") node_1 = DockNode(node_1_identifier, 0, False, None, "", ("default", ), {}, dock_type, node_2_identifier, weak_1, None, None) node_1_lock = DockLockNode.create_from_dock(node_1, 1) node_2 = DockNode(node_2_identifier, 2, False, None, "", ("default", ), {}, dock_type, node_1_identifier, weak_2, None, None) node_2_lock = DockLockNode.create_from_dock(node_2, 3) area_1 = Area("Area 1", None, True, [node_1, node_1_lock], {}, {}) area_2 = Area("Area 2", None, True, [node_2, node_2_lock], {}, {}) world = World("W", [area_1, area_2], {}) world_list = WorldList([world]) world_list.ensure_has_node_cache() game_mock = MagicMock() game_mock.world_list = world_list patches = dataclasses.replace(empty_patches, game=game_mock) context = NodeContext( patches=patches, current_resources=ResourceCollection(), database=patches.game.resource_database, node_provider=world_list, ) # Run result_1 = list(node_1.connections_from(context)) result_2 = list(node_2.connections_from(context)) # Assert simple = ResourceRequirement.simple assert result_1 == [ (node_2, RequirementAnd( [req_1, simple(NodeResourceInfo.from_node(node_2, context))])), (node_1_lock, RequirementAnd([trivial, req_2])), ] assert result_2 == [ (node_1, simple(NodeResourceInfo.from_node(node_2, context))), (node_2_lock, req_2), ]
def test_basic_search_with_translator_gate(has_translator: bool, echoes_resource_database, echoes_game_patches): # Setup scan_visor = echoes_resource_database.get_item("DarkVisor") nc = functools.partial(NodeIdentifier.create, "Test World", "Test Area A") node_a = GenericNode(nc("Node A"), True, None, "", ("default",), {}) node_b = GenericNode(nc("Node B"), True, None, "", ("default",), {}) node_c = GenericNode(nc("Node C"), True, None, "", ("default",), {}) translator_node = ConfigurableNode(translator_identif := nc("Translator Gate"), True, None, "", ("default",), {}) world_list = WorldList([ World("Test World", [ Area("Test Area A", None, 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 = GameDescription(RandovaniaGame.METROID_PRIME_ECHOES, DockWeaknessDatabase([], {}, (None, None)), echoes_resource_database, ("default",), Requirement.impossible(), None, {}, None, world_list) patches = echoes_game_patches.assign_node_configuration({ translator_identif: ResourceRequirement(scan_visor, 1, False) }) initial_state = State({scan_visor: 1 if has_translator else 0}, (), 99, node_a, patches, None, StateGameData(echoes_resource_database, game.world_list, 100, 99)) # Run reach = reach_lib.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_connections_from_dock_blast_shield(empty_patches): # Setup trivial = Requirement.trivial() req_1 = ResourceRequirement( SimpleResourceInfo("Ev1", "Ev1", ResourceType.EVENT), 1, False) req_2 = ResourceRequirement( SimpleResourceInfo("Ev2", "Ev2", ResourceType.EVENT), 1, False) dock_type = DockType("Type", "Type", frozendict()) weak_1 = DockWeakness("Weak 1", frozendict(), req_1, None) weak_2 = DockWeakness("Weak 2", frozendict(), trivial, DockLock(DockLockType.FRONT_BLAST_BACK_BLAST, req_2)) node_1_identifier = NodeIdentifier.create("W", "Area 1", "Node 1") node_2_identifier = NodeIdentifier.create("W", "Area 2", "Node 2") node_1 = DockNode(node_1_identifier, False, None, "", ("default", ), {}, dock_type, node_2_identifier, weak_1, None, None) node_1_lock = DockLockNode.create_from_dock(node_1) node_2 = DockNode(node_2_identifier, False, None, "", ("default", ), {}, dock_type, node_1_identifier, weak_2, None, None) node_2_lock = DockLockNode.create_from_dock(node_2) area_1 = Area("Area 1", None, True, [node_1, node_1_lock], {}, {}) area_2 = Area("Area 2", None, True, [node_2, node_2_lock], {}, {}) world = World("W", [area_1, area_2], {}) world_list = WorldList([world]) context = NodeContext( patches=empty_patches, current_resources={}, database=None, node_provider=world_list, ) # Run result_1 = list(node_1.connections_from(context)) result_2 = list(node_2.connections_from(context)) # Assert assert result_1 == [ (node_2, RequirementAnd([req_1, ResourceRequirement.simple(node_2_identifier)])), (node_1_lock, RequirementAnd([trivial, req_2])), ] assert result_2 == [ (node_1, ResourceRequirement.simple(node_2_identifier)), (node_2_lock, req_2), ]
def get_mutable(self) -> "GameDescription": if self.mutable: return self else: result = GameDescription( game=self.game, resource_database=self.resource_database, layers=self.layers, dock_weakness_database=self.dock_weakness_database, world_list=WorldList( [world.duplicate() for world in self.world_list.worlds]), victory_condition=self.victory_condition, starting_location=self.starting_location, initial_states=copy.copy(self.initial_states), minimal_logic=self.minimal_logic, ) result.mutable = True return result
def _create_world_list(asset_id: int, pickup_index: PickupIndex): nc = NodeIdentifier.create logbook_node = LogbookNode(nc("World", "Area", "Logbook A"), True, None, "", ("default", ), {}, asset_id, None, None, None, None) pickup_node = PickupNode(nc("World", "Area", "Pickup Node"), True, None, "", ("default", ), {}, pickup_index, True) world_list = WorldList([ World("World", [ Area("Area", 0, True, [logbook_node, pickup_node], {}, {}), Area("Other Area", 0, True, [ PickupNode(nc("World", "Other Area", f"Pickup {i}"), True, None, "", ("default", ), {}, PickupIndex(i), True) for i in range(pickup_index.index) ], {}, {}), ], {}), ]) return logbook_node, pickup_node, world_list
def read_world_list(self, data: List[Dict]) -> WorldList: return WorldList(read_array(data, self.read_world))
for connection in connections.values(): connection.pop(node, None) if area.default_node == node.name: has_default_node = False areas.append( Area( name=area.name, default_node=area.default_node if has_default_node else None, valid_starting_location=area.valid_starting_location, nodes=nodes, connections=connections, extra=area.extra, )) worlds.append(dataclasses.replace(world, areas=areas)) return GameDescription( game=game.game, resource_database=game.resource_database, layers=game.layers, dock_weakness_database=game.dock_weakness_database, world_list=WorldList(worlds), victory_condition=game.victory_condition, starting_location=game.starting_location, initial_states=game.initial_states, minimal_logic=game.minimal_logic, )