def load_items(self): # Add backpack self.containers[InventorySlots.SLOT_INBACKPACK] = ContainerManager( is_backpack=True, owner=self.owner.guid) character_inventory = RealmDatabaseManager.character_get_inventory( self.owner.guid) # First load bags for item_instance in character_inventory: item_template = WorldDatabaseManager.item_template_get_by_entry( item_instance.item_template) if item_template and item_template.inventory_type == InventoryTypes.BAG: container_mgr = ContainerManager(owner=self.owner.guid, item_template=item_template, item_instance=item_instance) if self.is_bag_pos(container_mgr.current_slot): self.containers[item_instance.bag].sorted_slots[ container_mgr.current_slot] = container_mgr self.containers[container_mgr.current_slot] = container_mgr # Then load items for item_instance in character_inventory: item_template = WorldDatabaseManager.item_template_get_by_entry( item_instance.item_template) if item_template: item_mgr = ItemManager(item_template=item_template, item_instance=item_instance) if item_mgr.is_container() and self.is_bag_pos( item_mgr.current_slot): continue if item_instance.bag in self.containers: self.containers[item_instance.bag].sorted_slots[ item_mgr.current_slot] = item_mgr
def load_items(self): # Add backpack self.containers[InventorySlots.SLOT_INBACKPACK] = ContainerManager( is_backpack=True, owner=self.owner.guid) character_inventory = RealmDatabaseManager.character_get_inventory( self.owner.guid) # First load bags for item_instance in character_inventory: item_template = WorldDatabaseManager.item_template_get_by_entry( item_instance.item_template) if item_template and item_template.inventory_type == InventoryTypes.BAG: container_mgr = ContainerManager(owner=self.owner.guid, item_template=item_template, item_instance=item_instance) if self.is_bag_pos(container_mgr.current_slot): self.containers[item_instance.bag].sorted_slots[ container_mgr.current_slot] = container_mgr self.containers[container_mgr.current_slot] = container_mgr # Then load items for item_instance in character_inventory: item_template = WorldDatabaseManager.item_template_get_by_entry( item_instance.item_template) if item_template: if item_template.display_id > MAX_3368_ITEM_DISPLAY_ID and \ self.is_equipment_pos(item_instance.bag, item_instance.slot): Logger.error( 'Character %s has an equipped item (%u - %s) with out of bounds display_id (%u), ' 'deleting in order to prevent crashes.' % (self.owner.player.name, item_template.entry, item_template.name, item_template.display_id)) RealmDatabaseManager.character_inventory_delete( item_instance) continue if item_template.inventory_type == InventoryTypes.BAG: if self.is_bag_pos(item_instance.slot): continue item_mgr = ContainerManager(owner=self.owner.guid, item_template=item_template, item_instance=item_instance) else: item_mgr = ItemManager(item_template=item_template, item_instance=item_instance) if item_instance.bag in self.containers: self.containers[item_instance.bag].sorted_slots[ item_mgr.current_slot] = item_mgr self.set_base_attack_time()
def set_virtual_item(self, slot, item_entry): if item_entry == 0: self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, 0) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, 0) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, 0) return item_template = WorldDatabaseManager.item_template_get_by_entry( item_entry) if item_template: self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, item_template.display_id) virtual_item_info = unpack( '<I', pack('<4B', item_template.class_, item_template.subclass, item_template.material, item_template.inventory_type))[0] self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, virtual_item_info) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, item_template.sheath) if slot == 1: self.has_offhand_weapon = (item_template.inventory_type == InventoryTypes.WEAPON or item_template.inventory_type == InventoryTypes.WEAPONOFFHAND)
def generate_item_from_entry(entry): item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if item_template: item_mgr = ItemManager(item_template=item_template) return item_mgr return None
def add_item(self, entry=0, item_template=None, count=1, handle_error=True, from_npc=True, send_message=True, show_item_get=True): if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry( entry) amount_left = count target_bag_slot = -1 # Highest bag slot items were added to if item_template: if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return False # Add to any existing stacks for slot, container in self.containers.items(): if not container or not container.can_contain_item( item_template): continue amount_left = container.add_item_to_existing_stacks( item_template, amount_left) if amount_left <= 0: break if amount_left > 0: for slot, container in self.containers.items(): if not container or not container.can_contain_item( item_template): continue prev_left = amount_left amount_left = container.add_item(item_template, amount_left, False) if slot != InventorySlots.SLOT_INBACKPACK and prev_left > amount_left and slot > target_bag_slot: target_bag_slot = slot if amount_left <= 0: break items_added = (amount_left != count) if items_added: if show_item_get: # Default to backpack so we can prefer highest slot ID to receive message (backpack ID is highest) if target_bag_slot == -1: target_bag_slot = InventorySlots.SLOT_INBACKPACK self.send_item_receive_message(self.owner.guid, item_template.entry, target_bag_slot, from_npc, send_message) self.owner.send_update_self() self.owner.reset_fields() return items_added
def add_item(self, entry, count=1): item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if item_template: if not self.can_store_item(item_template, count): self.owner.send_equip_error( InventoryError.EQUIP_ERR_CANT_CARRY_MORE_OF_THIS) if count <= item_template.stackable: pass # TODO: Finish return None
def handle(world_session, socket, reader): if len(reader.data) >= 4: # Avoid handling empty item query packet entry = unpack('<I', reader.data[:4])[0] if entry > 0: item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if item_template: item_mgr = ItemManager( item_template=item_template ) socket.sendall(item_mgr.query_details()) return 0
def generate_starting_item(owner, entry, last_bag_slot): item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if item_template: slot = ItemManager.get_inv_slot_by_type(item_template.inventory_type) if slot >= InventorySlots.SLOT_INBACKPACK: slot = last_bag_slot bag = InventorySlots.SLOT_INBACKPACK.value count = 1 if item_template.inventory_type == 0 and item_template.class_ == 0: count = 2 if item_template.spellid_1 == 430 else 4 elif item_template.inventory_type == 24: count = 200 return ItemManager.generate_item(item_template, owner, bag, slot, count=count) return None
def generate_loot(self): # TODO: Implement loot group handling money = randint(self.world_obj.creature_template.gold_min, self.world_obj.creature_template.gold_max) self.current_money = money for loot_item in self.loot_template: chance = float(round(uniform(0.0, 1.0), 2) * 100) item_template = WorldDatabaseManager.item_template_get_by_entry(loot_item.item) if item_template: item_chance = loot_item.ChanceOrQuestChance item_chance = item_chance if item_chance > 0 else item_chance * -1 if item_chance >= 100 or chance - item_chance < 0: item = ItemManager.generate_item_from_entry(item_template.entry) if item: self.current_loot.append(LootHolder(item, randint(loot_item.mincountOrRef, loot_item.maxcount)))
def get_char_packet(world_session, character): name_bytes = PacketWriter.string_to_bytes(character.name) char_fmt = '<Q%usBBBBBBBBBIIfffIIII' % len(name_bytes) char_packet = pack( char_fmt, character.guid, name_bytes, character.race, character.class_, character.gender, character.skin, character.face, character.hairstyle, character.haircolour, character.facialhair, character.level, character.zone, character.map, character.position_x, character.position_y, character.position_z, 0, # TODO: Handle Guild GUID, 0, # TODO: Handle PetDisplayInfo 0, # TODO: Handle PetLevel 0 # TODO: Handle PetFamily ) for slot in range(0, 19): item = RealmDatabaseManager.character_get_item_by_slot(character.guid, slot) display_id = 0 inventory_type = 0 if item: item_template = WorldDatabaseManager.item_template_get_by_entry(item.item_template) if item_template: display_id = item_template.display_id inventory_type = item_template.inventory_type else: display_id = 0 inventory_type = 0 char_packet += pack('<IB', display_id, inventory_type) char_packet += pack('<IB', 0, 0) # First bag data return char_packet
def set_virtual_item(self, slot, item_entry): if item_entry == 0: self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, 0) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, 0) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, 0) return item_template = WorldDatabaseManager.item_template_get_by_entry( item_entry) if item_template: self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, item_template.display_id) virtual_item_info = unpack( '<I', pack('<4B', item_template.class_, item_template.subclass, item_template.material, item_template.inventory_type))[0] self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, virtual_item_info) self.set_uint32(UnitFields.UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, item_template.sheath) # Main hand if slot == 0: # This is a TOTAL guess, I have no idea about real weapon reach values. # The weapon reach unit field was removed in patch 0.10. if item_template.inventory_type == InventoryTypes.TWOHANDEDWEAPON: self.weapon_reach = 1.5 elif item_template.subclass == ItemSubClasses.ITEM_SUBCLASS_DAGGER: self.weapon_reach = 0.5 elif item_template.subclass != ItemSubClasses.ITEM_SUBCLASS_FIST_WEAPON: self.weapon_reach = 1.0 # Offhand if slot == 1: self.has_offhand_weapon = (item_template.inventory_type == InventoryTypes.WEAPON or item_template.inventory_type == InventoryTypes.WEAPONOFFHAND) elif slot == 0: self.weapon_reach = 0.0
def add_item(self, entry, count=1): item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if item_template: if not self.can_store_item(item_template, count): self.send_equip_error( InventoryError.EQUIP_ERR_CANT_CARRY_MORE_OF_THIS) if count <= item_template.stackable: for slot, container in self.containers.items(): if not container.is_full(): item_mgr = container.add_item(item_template) if item_mgr: self.owner.session.request.sendall( PacketWriter.get_packet( OpCode.SMSG_UPDATE_OBJECT, self.owner.get_update_packet( update_type=UpdateTypes.UPDATE_FULL, is_self=True))) return item_mgr return None
def add_item(self, entry=0, item_template=None, count=1, handle_error=True): if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry( entry) if item_template: if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return None if count <= item_template.stackable: for slot, container in self.containers.items(): if not container.is_full(): item_mgr = container.add_item(item_template) if item_mgr: self.owner.send_update_self() return item_mgr return None
def send_quest_giver_quest_details(self, quest, quest_giver_guid, activate_accept): # Quest information quest_title = PacketWriter.string_to_bytes(quest.Title) quest_details = PacketWriter.string_to_bytes(quest.Details) quest_objectives = PacketWriter.string_to_bytes(quest.Objectives) data = pack( '<QL%us%us%usL' %(len(quest_title), len(quest_details), len(quest_objectives)), quest_giver_guid, quest.entry, quest_title, quest_details, quest_objectives, 1 if activate_accept else 0 ) # Reward choices rew_choice_item_list = self.generate_rew_choice_item_list(quest) rew_choice_count_list = self.generate_rew_choice_count_list(quest) data += pack('<L', len(rew_choice_item_list)) for index, item in enumerate(rew_choice_item_list): item_template = WorldDatabaseManager.item_template_get_by_entry(item) data += pack( '<3L', item, rew_choice_count_list[index], item_template.display_id ) # Reward items rew_item_list = self.generate_rew_item_list(quest) rew_count_list = self.generate_rew_count_list(quest) data += pack('<L', len(rew_item_list)) for index, item in enumerate(rew_item_list): # TODO: Query item check item_template = WorldDatabaseManager.item_template_get_by_entry(item) data += pack( '<3L', item, rew_count_list[index], item_template.display_id if item_template.display_id else 0 ) # Reward money data += pack('<L', quest.RewOrReqMoney) # Required items req_item_list = self.generate_req_item_list(quest) req_count_list = self.generate_req_count_list(quest) data += pack('<L', len(req_item_list)) for index, item in enumerate(req_item_list): # TODO: Query item check data += pack( '<2L', item, req_count_list[index], ) # Required kill/item count req_creature_or_go_list = self.generate_req_creature_or_go_list(quest) req_creature_or_go_count_list = self.generate_req_creature_or_go_count_list(quest) data += pack('<L', len(req_creature_or_go_list)) for index, creature_or_go in enumerate(req_creature_or_go_list): data += pack( '<2L', creature_or_go if creature_or_go >= 0 else creature_or_go * -1 or 0x80000000, req_creature_or_go_count_list[index] ) self.player_mgr.session.request.sendall(PacketWriter.get_packet(OpCode.SMSG_QUESTGIVER_QUEST_DETAILS, data))
def add_item_to_slot(self, dest_bag_slot, dest_slot, entry=0, item_template=None, count=1, handle_error=True): if not self.containers[dest_bag_slot]: if handle_error: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry( entry) if not item_template: if handle_error: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return dest_container = self.containers[dest_bag_slot] dest_item = dest_container.get_item(dest_slot) # Bag family check if self.is_inventory_pos(dest_bag_slot, dest_slot) and \ not dest_container.can_contain_item(item_template): self.send_equip_error(InventoryError.BAG_ITEM_CLASS_MISMATCH, None, dest_item) return if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return if not self.owner.is_alive: if handle_error: self.send_equip_error(InventoryError.BAG_NOT_WHILE_DEAD, None, dest_item) return # Destination slot checks if dest_container.is_backpack: template_equip_slot = ItemManager.get_inv_slot_by_type( item_template.inventory_type) if self.is_equipment_pos(dest_bag_slot, dest_slot) and dest_slot != template_equip_slot or \ self.is_bag_pos(dest_slot) and item_template.inventory_type != InventoryTypes.BAG or \ dest_slot == 255: # slot 255 is the backpack slot if handle_error: self.send_equip_error(InventoryError.BAG_SLOT_MISMATCH, None, dest_item) return # Check backpack / paperdoll placement if item_template.required_level > self.owner.level and \ self.is_equipment_pos(dest_bag_slot, dest_slot): # Not enough level if handle_error: self.send_equip_error(InventoryError.BAG_LEVEL_MISMATCH, None, dest_item, item_template.required_level) return # Stack handling if dest_item: if self.is_inventory_pos(dest_bag_slot, dest_slot): if item_template.entry == dest_item.item_template.entry: diff = dest_item.item_template.stackable - dest_item.item_instance.stackcount if diff >= count: dest_item.item_instance.stackcount += count else: # Update stack values # Case where an item is dragged to stack but there's no space. # Test on later version shows that the items will go to another stack if there's space dest_item.item_instance.stackcount += diff self.add_item(item_template=item_template, count=count - diff, handle_error=False) self.owner.send_update_self() RealmDatabaseManager.character_inventory_update_item( dest_item.item_instance) return True else: if handle_error: self.send_equip_error(InventoryError.BAG_CANT_STACK, None, dest_item) return else: if handle_error: self.send_equip_error(InventoryError.BAG_NOT_EQUIPPABLE, None, dest_item) return generated_item = dest_container.set_item(item_template, dest_slot, count) # Add to containers if a bag was dragged to bag slots if self.is_bag_pos(dest_slot): if item_template.inventory_type == InventoryTypes.BAG: self.add_bag(dest_slot, generated_item) else: if handle_error: self.send_equip_error(InventoryError.BAG_SLOT_MISMATCH, None, dest_item) return # Update attack time if dest_slot == InventorySlots.SLOT_MAINHAND: self.set_base_attack_time() if self.is_equipment_pos(dest_bag_slot, dest_slot): self.owner.flagged_for_update = True else: self.owner.send_update_self() return True
def add_item(self, entry=0, item_template=None, count=1, handle_error=True, from_npc=True, send_message=True): if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry( entry) items_added = False target_bag_slot = -1 # Highest bag slot items were added to if item_template: if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return False # First, add to any pre-existing stacks amount_left = count for slot, container in list(self.containers.items()): if not container or not container.can_contain_item( item_template): continue for x in range(container.start_slot, container.max_slot): if self.is_bank_slot(slot, x): continue if x not in container.sorted_slots: continue # Skip any reserved slots item_mgr = container.sorted_slots[x] if item_mgr.item_template.entry == item_template.entry \ and item_mgr.item_instance.stackcount < item_mgr.item_template.stackable: stack_missing = item_template.stackable - item_mgr.item_instance.stackcount items_added = True if slot > target_bag_slot and slot != InventorySlots.SLOT_INBACKPACK: target_bag_slot = slot if stack_missing >= amount_left: item_mgr.item_instance.stackcount += amount_left amount_left = 0 RealmDatabaseManager.character_inventory_update_item( item_mgr.item_instance) break else: item_mgr.item_instance.stackcount += stack_missing amount_left -= stack_missing RealmDatabaseManager.character_inventory_update_item( item_mgr.item_instance) # Add the remaining stack(s) to empty slots. if amount_left > 0: for slot, container in list(self.containers.items()): if not container or not container.can_contain_item( item_template): continue items_added = True if slot > target_bag_slot and slot != InventorySlots.SLOT_INBACKPACK: target_bag_slot = slot if not container.is_full(): if amount_left > item_template.stackable: container.add_item(item_template, count=item_template.stackable) amount_left -= item_template.stackable else: container.add_item(item_template, count=amount_left) break if items_added: # Default to backpack so we can prefer highest slot ID to receive message (backpack ID is highest) if target_bag_slot == -1: target_bag_slot = InventorySlots.SLOT_INBACKPACK self.send_item_receive_message(self.owner.guid, item_template.entry, target_bag_slot, from_npc, send_message) self.owner.send_update_self() return items_added
def add_item_to_slot(self, dest_bag_slot, dest_slot, entry=0, item=None, item_template=None, count=1, handle_error=True): if not self.containers[dest_bag_slot]: if handle_error: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry(entry) if not item_template: if handle_error: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return dest_container = self.containers[dest_bag_slot] dest_item = dest_container.get_item(dest_slot) # Bag family check if self.is_inventory_pos(dest_bag_slot, dest_slot) and \ not dest_container.can_contain_item(item_template): self.send_equip_error(InventoryError.BAG_ITEM_CLASS_MISMATCH, item, dest_item) return if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return if not self.owner.is_alive: if handle_error: self.send_equip_error(InventoryError.BAG_NOT_WHILE_DEAD, item, dest_item) return # Destination slot checks if dest_container.is_backpack: # Set equip slot as offhand if trying to equip a one handed weapon in the offhand slot if dest_slot == InventorySlots.SLOT_OFFHAND and item_template.inventory_type == InventoryTypes.WEAPON: template_equip_slot = InventorySlots.SLOT_OFFHAND.value else: template_equip_slot = ItemManager.get_inv_slot_by_type(item_template.inventory_type) if self.is_equipment_pos(dest_bag_slot, dest_slot) and dest_slot != template_equip_slot or \ self.is_bag_pos(dest_slot) and item_template.inventory_type != InventoryTypes.BAG: if handle_error: self.send_equip_error(InventoryError.BAG_SLOT_MISMATCH, item, dest_item) return if dest_slot == 0xFF: # Dragging an item to bag bar. Acts like adding item but with container priority if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL, item, dest_item) return dest_slot = dest_container.next_available_slot() remaining = count if dest_slot == -1: dest_slot, dest_container = self.get_next_available_inventory_slot() if not dest_slot == -1: # If the target container has a slot open remaining = dest_container.add_item(item_template, count) # Add items to target container if remaining > 0: self.add_item(item_template=item_template, count=remaining) # Overflow to inventory else: # Update if container is modified self.add_item isn't called self.owner.send_update_self(force_inventory_update=True) return # Check backpack / paperdoll placement if item_template.required_level > self.owner.level and \ self.is_equipment_pos(dest_bag_slot, dest_slot): # Not enough level if handle_error: self.send_equip_error(InventoryError.BAG_LEVEL_MISMATCH, item, dest_item, item_template.required_level) return # Stack handling if dest_item: if self.is_inventory_pos(dest_bag_slot, dest_slot): if item_template.entry == dest_item.item_template.entry: diff = dest_item.item_template.stackable - dest_item.item_instance.stackcount if diff >= count: dest_item.item_instance.stackcount += count else: # Update stack values # Case where an item is dragged to stack but there's no space. # Test on later version shows that the items will go to another stack if there's space dest_item.item_instance.stackcount += diff self.add_item(item_template=item_template, count=count-diff, handle_error=False) self.owner.send_update_self(force_inventory_update=True) RealmDatabaseManager.character_inventory_update_item(dest_item.item_instance) return True else: if handle_error: self.send_equip_error(InventoryError.BAG_CANT_STACK, item, dest_item) return else: if handle_error: self.send_equip_error(InventoryError.BAG_NOT_EQUIPPABLE, item, dest_item) return generated_item = dest_container.set_item(item_template, dest_slot, count) # Add to containers if a bag was dragged to bag slots if self.is_bag_pos(dest_slot): if item_template.inventory_type == InventoryTypes.BAG: self.add_bag(dest_slot, generated_item) else: if handle_error: self.send_equip_error(InventoryError.BAG_SLOT_MISMATCH, item, dest_item) return if self.is_equipment_pos(dest_bag_slot, dest_slot): self.owner.stat_manager.apply_bonuses() self.owner.set_dirty(dirty_inventory=True) else: self.owner.send_update_self(force_inventory_update=True) return True
def add_item_to_slot(self, dest_bag_slot, dest_slot, entry=0, item=None, item_template=None, count=1, handle_error=True): if entry != 0 and not item_template: item_template = WorldDatabaseManager.item_template_get_by_entry( entry) if not item_template: if handle_error: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return dest_container = self.get_container(dest_bag_slot) if not dest_container: self.send_equip_error(InventoryError.BAG_ITEM_NOT_FOUND) return False dest_item = dest_container.get_item(dest_slot) if not self.can_store_item(item_template, count): if handle_error: self.send_equip_error(InventoryError.BAG_INV_FULL) return is_valid_target_slot = self.item_can_be_moved_to_slot( item_template, dest_slot, dest_bag_slot, item) if not is_valid_target_slot: return if dest_slot == 0xFF: # Dragging an item to bag bar. Acts like adding item but with container priority dest_slot = dest_container.next_available_slot() remaining = count if not dest_slot == -1: # If the target container has a slot open remaining = dest_container.add_item( item_template, count) # Add items to target container if remaining > 0: self.add_item(item_template=item_template, count=remaining) # Overflow to inventory else: # Update if container is modified self.add_item isn't called self.owner.send_update_self(force_inventory_update=True) return True # Stack handling if dest_item: if self.is_inventory_pos(dest_bag_slot, dest_slot): if item_template.entry == dest_item.item_template.entry: diff = dest_item.item_template.stackable - dest_item.item_instance.stackcount if diff >= count: dest_item.item_instance.stackcount += count else: dest_item.item_instance.stackcount += diff self.add_item(item_template=item_template, count=count - diff, handle_error=False) self.owner.send_update_self(force_inventory_update=True) RealmDatabaseManager.character_inventory_update_item( dest_item.item_instance) return True else: if handle_error: self.send_equip_error(InventoryError.BAG_CANT_STACK, item, dest_item) return else: if handle_error: self.send_equip_error(InventoryError.BAG_NOT_EQUIPPABLE, item, dest_item) return generated_item = dest_container.set_item(item_template, dest_slot, count) # Add to containers if a bag was dragged to bag slots if dest_container.is_backpack and self.is_bag_pos(dest_slot): self.add_bag(dest_slot, generated_item) if dest_container.is_backpack and \ (self.is_equipment_pos(dest_bag_slot, dest_slot) or self.is_bag_pos(dest_slot)): # Added equipment or bag self.handle_equipment_change(generated_item) RealmDatabaseManager.character_inventory_update_item( generated_item.item_instance) else: self.owner.send_update_self(force_inventory_update=True) return True