Feature Perfect Autostacking Items 100,0% Stack All for 0.4 and 0.3.6pl1

sawex

Premium User
Premium User
Joined
Jan 31, 2009
Messages
43
Best answers
0
Reaction score
4
You don't need to change doPlayerAddItem function. There is a bug inside __queryDestination function, so it will always omit first items for INDEX_WHEREVER.
Here is a fixed version of player.cpp:

C++:
Cylinder* Player::__queryDestination(int32_t& index, const Thing* thing, Item** destItem,
    uint32_t& flags)
{
    if (index == 0 /*drop to capacity window*/ || index == INDEX_WHEREEVER)
    {
        *destItem = NULL;

        const Item* item = thing->getItem();
        if (item == NULL)
        {
            return this;
        }

        //find an appropiate slot
        std::list<Container*> containerList;
        for (int i = SLOT_FIRST; i < SLOT_LAST; ++i)
        {
            Item* inventoryItem = inventory[i];
            if (inventoryItem)
            {
                if (inventoryItem == tradeItem)
                {
                    continue;
                }

                //try find an already existing item to stack with
                if (inventoryItem != item && item->isStackable() && inventoryItem->getID() == item->getID() && inventoryItem->getItemCount() < 100)
                {
                    *destItem = inventoryItem;
                    index = i;
                    return this;
                }
                //check sub-containers
                else if (Container* subContainer = inventoryItem->getContainer())
                {
                    Cylinder* tmpCylinder = NULL;
                    int32_t tmpIndex = INDEX_WHEREEVER;
                    Item* tmpDestItem = NULL;

                    tmpCylinder = subContainer->__queryDestination(tmpIndex, item, &tmpDestItem, flags);
                    if (tmpCylinder && tmpCylinder->__queryAdd(tmpIndex, item, item->getItemCount(), flags) == RET_NOERROR)
                    {
                        index = tmpIndex;
                        *destItem = tmpDestItem;
                        return tmpCylinder;
                    }

                    containerList.push_back(subContainer);
                }
            }
            //empty slot
            else if (__queryAdd(i, item, item->getItemCount(), flags) == RET_NOERROR)
            {
                index = i;
                *destItem = NULL;
                return this;
            }
        }

        //check deeper in the containers
        for (std::list<Container*>::iterator it = containerList.begin(); it != containerList.end(); ++it)
        {
            for (ContainerIterator iit = (*it)->begin(); iit != (*it)->end(); ++iit)
            {
                if (Container* subContainer = (*iit)->getContainer())
                {

                    if (subContainer == tradeItem)
                    {
                        continue;
                    }

                    Cylinder* tmpCylinder = NULL;
                    int32_t tmpIndex = INDEX_WHEREEVER;
                    Item* tmpDestItem = NULL;

                    tmpCylinder = subContainer->__queryDestination(tmpIndex, item, &tmpDestItem, flags);
                    if (tmpCylinder && tmpCylinder->__queryAdd(tmpIndex, item, item->getItemCount(), flags) == RET_NOERROR)
                    {
                        index = tmpIndex;
                        *destItem = tmpDestItem;
                        return tmpCylinder;
                    }
                }
            }
        }
        return this;
    }

    Thing* destThing = __getThing(index);
    if (destThing)
        *destItem = destThing->getItem();

    Cylinder* subCylinder = dynamic_cast<Cylinder*>(destThing);

    if (subCylinder)
    {
        index = INDEX_WHEREEVER;
        *destItem = NULL;
        return subCylinder;
    }
    else
        return this;
}
 

abofoulla

Member
Joined
Apr 24, 2017
Messages
34
Best answers
1
Reaction score
0
Tested on TFS 0.4 and 0.3.6pl1

Retired from:
Autostacking Items - XTibia - A sua comunidade de Tibia e OTserv

Credits: Exedion
Find the functions and modify !

container.cpp
Code:
Cylinder* Container::__queryDestination(int32_t& index, const Thing* thing, Item** destItem, uint32_t&)
{
        if(index == 254 /*move up*/)
        {
                index = INDEX_WHEREEVER;
                *destItem = NULL;
 
                Container* parentContainer = dynamic_cast<Container*>(getParent());
                if(parentContainer)
                        return parentContainer;
 
                return this;
        }
        else if(index == 255 /*add wherever*/){
                index = INDEX_WHEREEVER;
                *destItem = NULL;
        }
        else if(index >= (int32_t)capacity()){
                        /*
                        if you have a container, maximize it to show all 20 slots
                        then you open a bag that is inside the container you will have a bag with 8 slots
                        and a "grey" area where the other 12 slots where from the container
                        if you drop the item on that grey area
                        the client calculates the slot position as if the bag has 20 slots
                        */
                        index = INDEX_WHEREEVER;
                *destItem = NULL;
        }
 
        const Item* item = thing->getItem();
        if(item == NULL){
                return this;
        }
 
        if(item->isStackable()){
                if(item->getParent() != this){
                        //try find a suitable item to stack with
                        uint32_t n = 0;
                        for(ItemList::iterator cit = itemlist.begin(); cit != itemlist.end(); ++cit){
                                if((*cit) != item && (*cit)->getID() == item->getID() && (*cit)->getItemCount() < 100){
                                        *destItem = (*cit);
                                        index = n;
                                        return this;
                                }
 
                                ++n;
                        }
                }
        }
 
        if(index != INDEX_WHEREEVER){
                Thing* destThing = __getThing(index);
                if(destThing)
                        *destItem = destThing->getItem();
 
                Cylinder* subCylinder = dynamic_cast<Cylinder*>(*destItem);
 
                if(subCylinder){
                        index = INDEX_WHEREEVER;
                        *destItem = NULL;
                        return subCylinder;
                }
        }
 
        return this;
}
item.cpp
Code:
void Item::setDefaultSubtype()
{
        setItemCount(1);
        const ItemType& it = items[id];
        if(it.charges)
                setCharges(it.charges);
}
player.cpp
Code:
Cylinder* Player::__queryDestination(int32_t& index, const Thing* thing, Item** destItem,
        uint32_t& flags)
{
        if(index == 0 /*drop to capacity window*/ || index == INDEX_WHEREEVER){
                *destItem = NULL;
 
                const Item* item = thing->getItem();
                if(item == NULL){
                        return this;
                }
 
                //find an appropiate slot
                std::list<Container*> containerList;
                for(int i = SLOT_FIRST; i < SLOT_LAST; ++i){
                        Item* inventoryItem = inventory[i];
 
                        if(inventoryItem == tradeItem){
                                continue;
                        }
 
                        if(inventoryItem == tradeItem){
                                continue;
                        }
 
                                if(inventoryItem){
                                        //try find an already existing item to stack with
                                if(inventoryItem != item && item->isStackable() && inventoryItem->getID() == item->getID() && inventoryItem->getItemCount() < 100){
                                        *destItem = inventoryItem;
                                        index = i;
                                        return this;
                                }
                                //check sub-containers
                                else if(Container* subContainer = inventoryItem->getContainer()){
                                        Cylinder* tmpCylinder = NULL;
                                        int32_t tmpIndex = INDEX_WHEREEVER;
                                        Item* tmpDestItem = NULL;
 
                                        tmpCylinder = subContainer->__queryDestination(tmpIndex, item, &tmpDestItem, flags);
                                        if(tmpCylinder && tmpCylinder->__queryAdd(tmpIndex, item, item->getItemCount(), flags) == RET_NOERROR){
                                                index = tmpIndex;
                                                *destItem = tmpDestItem;
                                                return tmpCylinder;
                                        }
 
                                        containerList.push_back(subContainer);
                                }
                        }
                        //empty slot
                        else if(__queryAdd(i, item, item->getItemCount(), flags) == RET_NOERROR){
                                index = i;
                                *destItem = NULL;
                                return this;
                        }
                }
 
                //check deeper in the containers
                for(std::list<Container*>::iterator it = containerList.begin(); it != containerList.end(); ++it){
                        for(ContainerIterator iit = (*it)->begin(); iit != (*it)->end(); ++iit){
                                if(Container* subContainer = (*iit)->getContainer()){
 
                                        if(subContainer == tradeItem){
                                                continue;
                                        }
 
                                        Cylinder* tmpCylinder = NULL;
                                        int32_t tmpIndex = INDEX_WHEREEVER;
                                        Item* tmpDestItem = NULL;
 
                                        tmpCylinder = subContainer->__queryDestination(tmpIndex, item, &tmpDestItem, flags);
                                        if(tmpCylinder && tmpCylinder->__queryAdd(tmpIndex, item, item->getItemCount(), flags) == RET_NOERROR){
                                                index = tmpIndex;
                                                *destItem = tmpDestItem;
                                                return tmpCylinder;
                                        }
                                }
                        }
                }
                return this;
        }
 
        Thing* destThing = __getThing(index);
        if(destThing)
                *destItem = destThing->getItem();
 
        Cylinder* subCylinder = dynamic_cast<Cylinder*>(destThing);
 
        if(subCylinder){
                index = INDEX_WHEREEVER;
                *destItem = NULL;
                return subCylinder;
        }
        else
                return this;
}

Posted by Nubaza (Chavoz) in otland.net
Created by Exedion in xtibia.com/forum


Maybe this code ruins your firstitems, so i need the help of the forum to edit this code :S
Where can i find this container.cpp ,item.cpp and player.cpp in data
 

froy

Intermediate OT User
Joined
Sep 30, 2009
Messages
102
Best answers
0
Reaction score
18
@froy
Can help me to find it what i do
You will have to insert text from thread starter's first post, probably replace something. Im not sure.
Then you will need to compile the source.Use the search function for finding a guide to compile your distro.
 
Top