async def _patches_for_pickup(self, provider_name: str, pickup: PickupEntry): inventory_resources: CurrentResources = { item: inv_item.capacity for item, inv_item in self._inventory.items() } conditional = pickup.conditional_for_resources(inventory_resources) if conditional.name is not None: item_name = conditional.name else: item_name = pickup.name resources_to_give = {} add_resource_gain_to_current_resources(conditional.resources, inventory_resources) add_resource_gain_to_current_resources(conditional.resources, resources_to_give) add_resource_gain_to_current_resources(pickup.conversion_resource_gain(inventory_resources), resources_to_give) # Ignore item% for received items resources_to_give.pop(self.game.resource_database.item_percentage, None) patches = [ all_prime_dol_patches.adjust_item_amount_and_capacity_patch(self.patches.powerup_functions, item.index, delta) for item, delta in resources_to_give.items() ] return patches, f"Received {item_name} from {provider_name}."
async def _update_magic_item(self): multiworld_magic_item = self.game.resource_database.multiworld_magic_item patches = [] magic_inv = self._inventory[multiworld_magic_item] magic_capacity = magic_inv.capacity if magic_inv.amount > 0: self.logger.info(f"magic item was at {magic_inv.amount}/{magic_capacity}") magic_capacity -= magic_inv.amount await self._emit_location_collected(magic_inv.amount - 1) patches.append(all_prime_dol_patches.adjust_item_amount_and_capacity_patch(self.patches.powerup_functions, multiworld_magic_item.index, -magic_inv.amount)) # Only attempt to give the next item if outside cooldown message = None if self.message_cooldown <= 0 and magic_capacity < len(self._permanent_pickups): item_patches, message = await self._patches_for_pickup(*self._permanent_pickups[magic_capacity]) self.logger.info(f"{len(self._permanent_pickups)} permanent pickups, magic {magic_capacity}. " f"Next pickup: {message}") patches.extend(item_patches) patches.append(all_prime_dol_patches.increment_item_capacity_patch(self.patches.powerup_functions, multiworld_magic_item.index)) if patches: await self._execute_remote_patches(patches, message)
def test_give_item_patch( powerup_address: all_prime_dol_patches.PowerupFunctionsAddresses): # Run patch = all_prime_dol_patches.adjust_item_amount_and_capacity_patch( powerup_address, 10, 5) data = bytes(assembler.assemble_instructions(0x80008020, patch)) # Assert assert data == ( b"\x80\x7f\x15\x0c\x38\x80\x00\x0a\x38\xa0\x00\x05\x48\x06\xd8\xc5\x80\x7f\x15\x0c" b"\x38\x80\x00\x0a\x38\xa0\x00\x05\x48\x06\xd7\x25")
def test_create_remote_execution_body( string_display: all_prime_dol_patches.StringDisplayPatchAddresses, powerup_address: all_prime_dol_patches.PowerupFunctionsAddresses): # Run patch_address, patch_bytes = all_prime_dol_patches.create_remote_execution_body( string_display, [ *all_prime_dol_patches.call_display_hud_patch(string_display), *all_prime_dol_patches.adjust_item_amount_and_capacity_patch( powerup_address, 3, 12), ]) # Assert assert patch_address == string_display.update_hint_state + 0x60 assert patch_bytes == ( b'\x3c\xa0\x41\x00\x38\xc0\x00\x00\x38\xe0\x00\x01\x39\x20\x00\x09\x90\xa1\x00\x10' b'\x98\xe1\x00\x14\x98\xc1\x00\x15\x98\xc1\x00\x16\x98\xe1\x00\x17\x91\x21\x00\x18' b'\x38\x61\x00\x1c\x3c\x80\x00\x00\x60\x84\x90\x00\x48\x2c\x73\x29\x38\x81\x00\x10' b'\x48\x03\x33\x0d\x80\x7f\x15\x0c\x38\x80\x00\x03\x38\xa0\x00\x0c\x48\x03\xd8\x25' b'\x80\x7f\x15\x0c\x38\x80\x00\x03\x38\xa0\x00\x0c\x48\x03\xd6\x85\xbb\xc1\x00\x2c' b'\x80\x01\x00\x38\x7c\x08\x03\xa6\x38\x21\x00\x34\x4e\x80\x00\x20')