Example #1
0
    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()
Example #3
0
    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
Example #5
0
    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
Example #6
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.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
Example #8
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)))
Example #10
0
    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
Example #11
0
    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
Example #12
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
Example #13
0
    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
Example #14
0
    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))
Example #15
0
    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
Example #16
0
    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
Example #17
0
    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
Example #18
0
    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