def test_assign_pickup_to_starting_items(empty_patches, state_game_data): # Setup starting = state.State({}, (), 99, None, empty_patches, None, state_game_data) resource_a = ItemResourceInfo(1, "A", "A", 10, None) resource_b = ItemResourceInfo(2, "B", "B", 10, None) p = PickupEntry( "A", 2, ItemCategory.SUIT, ItemCategory.LIFE_SUPPORT, progression=((resource_a, 5), ), extra_resources=((state_game_data.resource_database.item_percentage, 1), ), unlocks_resource=True, resource_lock=ResourceLock(resource_a, resource_a, resource_b), ) # Run final = starting.assign_pickup_to_starting_items(p) # Assert assert final.patches.starting_items == {resource_a: 5, resource_b: 0} assert final.resources == {resource_a: 5, resource_b: 0}
def create_resource_lock(self, resource_database: ResourceDatabase) -> Optional[ResourceLock]: if self.unlocked_by is not None: return ResourceLock( locked_by=resource_database.get_item(self.unlocked_by), item_to_lock=resource_database.get_item(self.items[0]), temporary_item=resource_database.get_item(self.temporary), ) return None
def test_create_seeker_launcher(ammo_quantity: int, ammo_requires_major_item: bool, echoes_item_database, echoes_resource_database, ): # Setup missile = echoes_resource_database.get_item(44) missile_launcher = echoes_resource_database.get_item(73) seeker_launcher = echoes_resource_database.get_item(26) temporary = echoes_resource_database.get_item(71) state = MajorItemState( include_copy_in_original_location=False, num_shuffled_pickups=0, num_included_in_starting_items=0, included_ammo=(ammo_quantity,), ) # Run result = randovania.generator.item_pool.pickup_creator.create_major_item( echoes_item_database.major_items["Seeker Launcher"], state, True, echoes_resource_database, echoes_item_database.ammo["Missile Expansion"], ammo_requires_major_item ) # Assert assert result == PickupEntry( name="Seeker Launcher", progression=( (seeker_launcher, 1), ), extra_resources=( (missile, ammo_quantity), (echoes_resource_database.item_percentage, 1), ), model=PickupModel(echoes_resource_database.game_enum, "SeekerLauncher"), item_category=ItemCategory.MISSILE, broad_category=ItemCategory.MISSILE_RELATED, respects_lock=ammo_requires_major_item, resource_lock=ResourceLock( locked_by=missile_launcher, temporary_item=temporary, item_to_lock=missile, ), )
def test_add_resource_gain_to_current_resources_convert(blank_pickup): # Setup resource_a = ItemResourceInfo("A", "A", 10, None) resource_b = ItemResourceInfo("B", "B", 10, None) pickup = dataclasses.replace( blank_pickup, progression=(), resource_lock=ResourceLock(resource_b, resource_b, resource_a), unlocks_resource=True, ) current_resources = {resource_a: 5} # Run add_resource_gain_to_current_resources( pickup.resource_gain(current_resources), current_resources) # Assert assert current_resources == {resource_a: 0, resource_b: 5}
def test_bit_pack_pickup_entry(has_convert: bool, echoes_resource_database, generic_item_category): # Setup name = "Some Random Name" if has_convert: resource_lock = ResourceLock( find_resource_info_with_long_name(echoes_resource_database.item, "Morph Ball"), find_resource_info_with_long_name(echoes_resource_database.item, "Item Percentage"), find_resource_info_with_long_name(echoes_resource_database.item, "Space Jump Boots"), ) else: resource_lock = None pickup = PickupEntry( name=name, model=PickupModel( game=RandovaniaGame.METROID_PRIME_CORRUPTION, name="HyperMissile", ), item_category=generic_item_category, broad_category=generic_item_category, progression=( (find_resource_info_with_long_name(echoes_resource_database.item, "Morph Ball"), 1), (find_resource_info_with_long_name(echoes_resource_database.item, "Grapple Beam"), 1), ), extra_resources=((find_resource_info_with_long_name( echoes_resource_database.item, "Item Percentage"), 5), ), resource_lock=resource_lock) # Run encoded = bitpacking.pack_value( BitPackPickupEntry(pickup, echoes_resource_database)) decoder = BitPackDecoder(encoded) decoded = BitPackPickupEntry.bit_pack_unpack(decoder, echoes_resource_database) # Assert assert pickup == decoded
def test_create_ammo_expansion(requires_major_item: bool, echoes_item_database, echoes_resource_database): # Setup primary_a = echoes_resource_database.get_item("MissileLauncher") ammo_a = echoes_resource_database.get_item("Missile") temporary_a = echoes_resource_database.get_item("Temporary1") ammo = Ammo( game=echoes_resource_database.game_enum, name="The Item", items=("Missile", ), broad_category=USELESS_ITEM_CATEGORY, unlocked_by="MissileLauncher", temporary="Temporary1", model_name="AmmoModel", ) ammo_count = (11, 150) # Run result = pickup_creator.create_ammo_expansion(ammo, ammo_count, requires_major_item, echoes_resource_database) # Assert assert result == PickupEntry( name="The Item", model=PickupModel(echoes_resource_database.game_enum, "AmmoModel"), progression=tuple(), extra_resources=( (ammo_a, ammo_count[0]), (echoes_resource_database.item_percentage, 1), ), item_category=AMMO_ITEM_CATEGORY, broad_category=USELESS_ITEM_CATEGORY, probability_offset=0, respects_lock=requires_major_item, resource_lock=ResourceLock( locked_by=primary_a, temporary_item=temporary_a, item_to_lock=ammo_a, ), )
def test_add_resource_gain_to_current_resources_convert(blank_resource_db, blank_pickup): # Setup resource_a = blank_resource_db.get_item("Ammo") resource_b = blank_resource_db.item[0] pickup = dataclasses.replace( blank_pickup, progression=(), resource_lock=ResourceLock(resource_b, resource_b, resource_a), unlocks_resource=True, ) current_resources = ResourceCollection() current_resources.add_resource_gain([(resource_a, 5)]) # Run current_resources.add_resource_gain(pickup.resource_gain(current_resources)) # Assert assert dict(current_resources.as_resource_gain()) == { resource_a: 0, resource_b: 5 }
def test_create_ammo_expansion(requires_major_item: bool, echoes_resource_database): # Setup primary_a = echoes_resource_database.get_item(73) ammo_a = echoes_resource_database.get_item(40) temporary_a = echoes_resource_database.get_item(71) ammo = Ammo( name="The Item", maximum=100, items=(40,), broad_category=ItemCategory.ETM, unlocked_by=73, temporary=71, model_name="AmmoModel", ) ammo_count = [75, 150] # Run result = randovania.generator.item_pool.pickup_creator.create_ammo_expansion( ammo, ammo_count, requires_major_item, echoes_resource_database) # Assert assert result == PickupEntry( name="The Item", model=PickupModel(echoes_resource_database.game_enum, "AmmoModel"), progression=tuple(), extra_resources=( (ammo_a, ammo_count[0]), (echoes_resource_database.item_percentage, 1), ), item_category=ItemCategory.EXPANSION, broad_category=ItemCategory.ETM, probability_offset=0, respects_lock=requires_major_item, resource_lock=ResourceLock( locked_by=primary_a, temporary_item=temporary_a, item_to_lock=ammo_a, ), )
def test_create_missile_launcher(ammo_quantity: int, echoes_item_database, echoes_resource_database): # Setup missile = echoes_resource_database.get_item("Missile") missile_launcher = echoes_resource_database.get_item("MissileLauncher") temporary = echoes_resource_database.get_item("Temporary1") state = MajorItemState( include_copy_in_original_location=False, num_shuffled_pickups=0, num_included_in_starting_items=0, included_ammo=(ammo_quantity, ), ) # Run result = pickup_creator.create_major_item( echoes_item_database.major_items["Missile Launcher"], state, True, echoes_resource_database, echoes_item_database.ammo["Missile Expansion"], True) # Assert assert result == PickupEntry( name="Missile Launcher", progression=((missile_launcher, 1), ), extra_resources=( (missile, ammo_quantity), (echoes_resource_database.item_percentage, 1), ), model=PickupModel(echoes_resource_database.game_enum, "MissileLauncher"), item_category=echoes_item_database.item_categories["missile"], broad_category=echoes_item_database.item_categories["missile_related"], resource_lock=ResourceLock( locked_by=missile_launcher, temporary_item=temporary, item_to_lock=missile, ), unlocks_resource=True, )
def test_assign_pickup_to_starting_items(empty_patches, state_game_data, generic_item_category): # Setup db = state_game_data.resource_database starting_node = state_game_data.world_list.resolve_teleporter_connection( empty_patches.game.starting_location) starting = state.State(ResourceCollection(), (), 99, starting_node, empty_patches, None, state_game_data) resource_a = db.get_item("Ammo") resource_b = db.item[0] p = PickupEntry( "A", 2, generic_item_category, generic_item_category, progression=((resource_a, 5), ), extra_resources=(), unlocks_resource=True, resource_lock=ResourceLock(resource_a, resource_a, resource_b), ) # Run final = starting.assign_pickup_to_starting_items(p) # Assert assert final.patches.starting_items == ResourceCollection.from_dict( db, { resource_a: 5, resource_b: 0 }) assert final.resources == ResourceCollection.from_dict( db, { resource_a: 5, resource_b: 0 })
def test_create_pickup_list(model_style: PickupModelStyle, empty_patches): # Setup has_scan_text = model_style in { PickupModelStyle.ALL_VISIBLE, PickupModelStyle.HIDE_MODEL } rng = Random(5000) model_0 = MagicMock(spec=PickupModel) model_1 = MagicMock(spec=PickupModel) model_2 = MagicMock(spec=PickupModel) useless_model = PickupModel( game=RandovaniaGame.PRIME2, name="EnergyTransferModule", ) useless_resource = ItemResourceInfo(0, "Useless", "Useless", 10, None) resource_a = ItemResourceInfo(1, "A", "A", 10, None) resource_b = ItemResourceInfo(2, "B", "B", 10, None) pickup_a = PickupEntry( "P-A", model_1, ItemCategory.TEMPLE_KEY, ItemCategory.KEY, progression=((resource_a, 1), ), ) pickup_b = PickupEntry( "P-B", model_2, ItemCategory.SUIT, ItemCategory.LIFE_SUPPORT, progression=((resource_b, 1), (resource_a, 5)), ) pickup_c = PickupEntry("P-C", model_2, ItemCategory.EXPANSION, ItemCategory.MISSILE_RELATED, progression=tuple(), extra_resources=((resource_b, 2), (resource_a, 1)), unlocks_resource=True, resource_lock=ResourceLock(resource_a, resource_a, useless_resource)) useless_pickup = PickupEntry("P-Useless", model_0, ItemCategory.ETM, ItemCategory.ETM, progression=((useless_resource, 1), )) patches = empty_patches.assign_pickup_assignment({ PickupIndex(0): PickupTarget(pickup_a, 0), PickupIndex(2): PickupTarget(pickup_b, 0), PickupIndex(3): PickupTarget(pickup_a, 0), PickupIndex(4): PickupTarget(pickup_c, 0), }) creator = pickup_exporter.PickupExporterSolo( pickup_exporter.GenericAcquiredMemo()) # Run result = pickup_exporter.export_all_indices( patches, PickupTarget(useless_pickup, 0), 5, rng, model_style, PickupModelDataSource.ETM, creator, pickup_creator.create_visual_etm(), ) # Assert assert len(result) == 5 assert result[0] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(0), scan_text="P-A" if has_scan_text else "Unknown item", hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ ConditionalResources("A", None, ((resource_a, 1), )) ], conversion=[], model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, ) assert result[1] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(1), scan_text="P-Useless" if has_scan_text else "Unknown item", hud_text=["Useless acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ ConditionalResources("Useless", None, ((useless_resource, 1), )) ], conversion=[], model=model_0 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, ) assert result[2] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(2), scan_text="P-B. Provides the following in order: B, A" if has_scan_text else "Unknown item", hud_text=["B acquired!", "A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!', 'Unknown item acquired!'], conditional_resources=[ ConditionalResources("B", None, ((resource_b, 1), )), ConditionalResources("A", resource_b, ((resource_a, 5), )), ], conversion=[], model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, ) assert result[3] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(3), scan_text="P-A" if has_scan_text else "Unknown item", hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ ConditionalResources("A", None, ((resource_a, 1), )) ], conversion=[], model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, ) assert result[4] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(4), scan_text="P-C. Provides 2 B and 1 A" if has_scan_text else "Unknown item", hud_text=["P-C acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ ConditionalResources("P-C", None, ( (resource_b, 2), (resource_a, 1), )) ], conversion=[ ResourceConversion(source=useless_resource, target=resource_a) ], model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, )
def decode_resource_lock(self, decoder: BitPackDecoder) -> ResourceLock: return ResourceLock( locked_by=self._decode_item(decoder), item_to_lock=self._decode_item(decoder), temporary_item=self._decode_item(decoder), )
def test_create_pickup_list(model_style: PickupModelStyle, empty_patches, generic_item_category, blank_resource_db): # Setup has_scan_text = model_style in {PickupModelStyle.ALL_VISIBLE, PickupModelStyle.HIDE_MODEL} rng = Random(5000) model_0 = MagicMock(spec=PickupModel) model_1 = MagicMock(spec=PickupModel) model_2 = MagicMock(spec=PickupModel) useless_model = PickupModel( game=RandovaniaGame.METROID_PRIME_ECHOES, name="EnergyTransferModule", ) useless_resource = ItemResourceInfo(0, "Useless", "Useless", 10) resource_a = ItemResourceInfo(1, "A", "A", 10) resource_b = ItemResourceInfo(2, "B", "B", 10) pickup_a = PickupEntry("P-A", model_1, generic_item_category, generic_item_category, progression=((resource_a, 1),), ) pickup_b = PickupEntry("P-B", model_2, generic_item_category, generic_item_category, progression=((resource_b, 1), (resource_a, 5)), ) pickup_c = PickupEntry("P-C", model_2, AMMO_ITEM_CATEGORY, generic_item_category, progression=tuple(), extra_resources=((resource_b, 2), (resource_a, 1)), unlocks_resource=True, resource_lock=ResourceLock(resource_a, resource_a, useless_resource)) useless_pickup = PickupEntry("P-Useless", model_0, USELESS_ITEM_CATEGORY, USELESS_ITEM_CATEGORY, progression=((useless_resource, 1),)) patches = empty_patches.assign_new_pickups([ (PickupIndex(0), PickupTarget(pickup_a, 0)), (PickupIndex(2), PickupTarget(pickup_b, 0)), (PickupIndex(3), PickupTarget(pickup_a, 0)), (PickupIndex(4), PickupTarget(pickup_c, 0)), ]) creator = pickup_exporter.PickupExporterSolo(pickup_exporter.GenericAcquiredMemo()) world_list = MagicMock() world_list.iterate_nodes.return_value = [ PickupNode(NodeIdentifier.create("World", "Area", f"Name {i}"), i, False, None, "", ("default",), {}, PickupIndex(i), False) for i in range(5) ] # Run result = pickup_exporter.export_all_indices( patches, PickupTarget(useless_pickup, 0), world_list, rng, model_style, PickupModelDataSource.ETM, creator, pickup_creator.create_visual_etm(), ) # Assert assert len(result) == 5 assert result[0] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(0), scan_text="P-A" if has_scan_text else "Unknown item", hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ConditionalResources("A", None, ((resource_a, 1),))], conversion=[], model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, other_player=False, original_pickup=pickup_a, ) assert result[1] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(1), scan_text="P-Useless" if has_scan_text else "Unknown item", hud_text=["Useless acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ConditionalResources("Useless", None, ((useless_resource, 1),))], conversion=[], model=model_0 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, other_player=False, original_pickup=useless_pickup, ) assert result[2] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(2), scan_text="P-B. Provides the following in order: B, A" if has_scan_text else "Unknown item", hud_text=["B acquired!", "A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else [ 'Unknown item acquired!', 'Unknown item acquired!'], conditional_resources=[ ConditionalResources("B", None, ((resource_b, 1),)), ConditionalResources("A", resource_b, ((resource_a, 5),)), ], conversion=[], model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, other_player=False, original_pickup=pickup_b, ) assert result[3] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(3), scan_text="P-A" if has_scan_text else "Unknown item", hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ConditionalResources("A", None, ((resource_a, 1),))], conversion=[], model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, other_player=False, original_pickup=pickup_a, ) assert result[4] == pickup_exporter.ExportedPickupDetails( index=PickupIndex(4), scan_text="P-C. Provides 2 B and 1 A" if has_scan_text else "Unknown item", hud_text=["P-C acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'], conditional_resources=[ConditionalResources("P-C", None, ( (resource_b, 2), (resource_a, 1), ))], conversion=[ResourceConversion(source=useless_resource, target=resource_a)], model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model, other_player=False, original_pickup=pickup_c, )