Пример #1
0
    def get_next_available_slot_for_inv_type(self, inventory_type):
        if inventory_type == InventoryTypes.BAG:
            for container_slot, container in list(self.containers.items()):
                if not container:
                    return container_slot.value

        # Inventory types that can target multiple slots (bags handled separately)

        if inventory_type == InventoryTypes.FINGER:
            target_slots = (InventorySlots.SLOT_FINGERL.value,
                            InventorySlots.SLOT_FINGERR.value)
        elif inventory_type == InventoryTypes.TRINKET:
            target_slots = (InventorySlots.SLOT_TRINKETL.value,
                            InventorySlots.SLOT_TRINKETR.value)
        elif inventory_type == InventoryTypes.WEAPON and \
                self.owner.skill_manager.can_dual_wield() and not self.has_two_handed_weapon():
            target_slots = (
                InventorySlots.SLOT_MAINHAND.value,
                InventorySlots.SLOT_OFFHAND.value
            )  # Offhand option is only valid when player can dual wield and doesn't have a 2H weapon (autoequip 1H weapon should replace 2H)
        else:
            target_slots = (ItemManager.get_inv_slot_by_type(inventory_type), )

        for slot in target_slots:
            if not self.get_backpack().get_item(slot):
                return slot

        return -1
Пример #2
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
Пример #3
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