• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Feature Autostacking stackable items in TFS 0.3.6pl1

Fresh

Quack!
Joined
Oct 21, 2009
Messages
1,838
Solutions
18
Reaction score
617
Location
Poland
Description:
When you put stackable item in your backpack anywhere, it stacks with another with the same id (item must be stackable).
This option is already in sources above 0.3.6pl1 (Tibia 8.6,8.7 etc.)
_________________________________________________​

Open container.cpp, change function `Cylinder* Container::__queryDestination(int32_t& index, const Thing* thing, Item** destItem, uint32_t&)` to:
PHP:
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;
}


Open container.cpp, change function `ReturnValue Container::__queryMaxCount(int32_t index, const Thing* thing, uint32_t count,` to:
PHP:
ReturnValue Container::__queryMaxCount(int32_t index, const Thing* thing, uint32_t count,
	uint32_t& maxQueryCount, uint32_t flags) const
{
	const Item* item = thing->getItem();
	if(!item)
	{
		maxQueryCount = 0;
		return RET_NOTPOSSIBLE;
	}

	if(((flags & FLAG_NOLIMIT) == FLAG_NOLIMIT))
	{
		maxQueryCount = std::max((uint32_t)1, count);
		return RET_NOERROR;
	}

	int32_t freeSlots = std::max((int32_t)(capacity() - size()), (int32_t)0);
	if(item->isStackable())
	{
		uint32_t n = 0;
		if(index != INDEX_WHEREEVER)
		{
			const Thing* destThing = __getThing(index);
			const Item* destItem = NULL;
			if(destThing)
				destItem = destThing->getItem();

			if(destItem && destItem->getID() == item->getID())
				n = 100 - destItem->getItemCount();
		}

		maxQueryCount = freeSlots * 100 + n;
		if(maxQueryCount < count)
			return RET_CONTAINERNOTENOUGHROOM;
	}
	else
	{
		maxQueryCount = freeSlots;
		if(maxQueryCount == 0)
			return RET_CONTAINERNOTENOUGHROOM;
	}

	return RET_NOERROR;
}

Open container.cpp, change function `ReturnValue Container::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const` to:
PHP:
ReturnValue Container::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const
{
	int32_t index = __getIndexOfThing(thing);
	if(index == -1)
		return RET_NOTPOSSIBLE;

	const Item* item = thing->getItem();
	if(item == NULL)
		return RET_NOTPOSSIBLE;

	if(count == 0 || (item->isStackable() && count > item->getItemCount()))
		return RET_NOTPOSSIBLE;

	if(item->isNotMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, flags))
		return RET_NOTMOVEABLE;

	return RET_NOERROR;
}

That's all, enjoy!
Don't forget to Like! and comment! ;)
 
Last edited:
tfs 0.3.6pl1, tibia 8.54 and error :
Code:
../container.cpp:350: error: `capacity' was not declared in this scope
../container.cpp:350: error: `size' was not declared in this scope

../container.cpp:351: error: expected unqualified-id before "if"
../container.cpp:369: error: expected unqualified-id before "else"
../container.cpp:376: error: expected unqualified-id before "return"
../container.cpp:377: error: expected declaration before '}' token

make.exe: *** [obj//container.o] Error 1

Execution terminated
My lines from error :
Code:
int32_t freeSlots = std::max((int32_t)(capacity() - size()), (int32_t)0);
	if(item->isStackable())
	{
		uint32_t n = 0;
		if(index != INDEX_WHEREEVER)
		{
			const Thing* destThing = __getThing(index);
			const Item* destItem = NULL;
			if(destThing)
				destItem = destThing->getItem();

			if(destItem && destItem->getID() == item->getID())
				n = 100 - destItem->getItemCount();
		}

		maxQueryCount = freeSlots * 100 + n;
		if(maxQueryCount < count)
			return RET_CONTAINERNOTENOUGHROOM;
	}
	else
	{
		maxQueryCount = freeSlots;
		if(maxQueryCount == 0)
			return RET_CONTAINERNOTENOUGHROOM;
	}

	return RET_NOERROR;
}
Please help me !!
 
Last edited:
You have added bad the codes of Fresh.
I too use tfs 0.3.6pl1 8.5.4 and i not get errors..
 
where do i find that container.cpp? is it suppose to be in my server map somewhere or do i need to download something and put in there?
 
Bayue to open containter.cpp you need to download Dev c++ from here
http://otland.net/f479/compiling-forgotten-server-latest-source-code-last-update-02-12-2010-a-166/

make all the steps in the tutorial until you reach the .cpp

I downloaded this and I made all the changes but where do I extract everything? Since I already have a server crying damson 0.3.6 v8 I tried to put all the files dev files and such that came with it into my main server map I basically changed all the data, mods and so on with the ones I had before, but it didn't work. Is that the proper way to do it or how?
 
I already added this feature and it caused items fall on the floor. So i removed it.
 
I already added this feature and it caused items fall on the floor. So i removed it.

Okay I see, so If I want to have stackable items I will need to use a different distribution? Do you have any recommendation in that case, a 8.6 one. Thanks in advance!
 
if you want to use a new distrubtion use TFS v8.2 thats the one i am using
 
if you want to use a new distrubtion use TFS v8.2 thats the one i am using

And it works with stackable items and so on? including war shields? can you link it to me, can't seem to find it anywhere
 
Description:
When you put stackable item in your backpack anywhere, it stacks with another with the same id (item must be stackable).
This option is already in sources above 0.3.6pl1 (Tibia 8.6,8.7 etc.)
_________________________________________________​

Open container.cpp, change function `Cylinder* Container::__queryDestination(int32_t& index, const Thing* thing, Item** destItem, uint32_t&)` to:
PHP:
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;
}


Open container.cpp, change function `ReturnValue Container::__queryMaxCount(int32_t index, const Thing* thing, uint32_t count,` to:
PHP:
ReturnValue Container::__queryMaxCount(int32_t index, const Thing* thing, uint32_t count,
    uint32_t& maxQueryCount, uint32_t flags) const
{
    const Item* item = thing->getItem();
    if(!item)
    {
        maxQueryCount = 0;
        return RET_NOTPOSSIBLE;
    }

    if(((flags & FLAG_NOLIMIT) == FLAG_NOLIMIT))
    {
        maxQueryCount = std::max((uint32_t)1, count);
        return RET_NOERROR;
    }

    int32_t freeSlots = std::max((int32_t)(capacity() - size()), (int32_t)0);
    if(item->isStackable())
    {
        uint32_t n = 0;
        if(index != INDEX_WHEREEVER)
        {
            const Thing* destThing = __getThing(index);
            const Item* destItem = NULL;
            if(destThing)
                destItem = destThing->getItem();

            if(destItem && destItem->getID() == item->getID())
                n = 100 - destItem->getItemCount();
        }

        maxQueryCount = freeSlots * 100 + n;
        if(maxQueryCount < count)
            return RET_CONTAINERNOTENOUGHROOM;
    }
    else
    {
        maxQueryCount = freeSlots;
        if(maxQueryCount == 0)
            return RET_CONTAINERNOTENOUGHROOM;
    }

    return RET_NOERROR;
}

Open container.cpp, change function `ReturnValue Container::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const` to:
PHP:
ReturnValue Container::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const
{
    int32_t index = __getIndexOfThing(thing);
    if(index == -1)
        return RET_NOTPOSSIBLE;

    const Item* item = thing->getItem();
    if(item == NULL)
        return RET_NOTPOSSIBLE;

    if(count == 0 || (item->isStackable() && count > item->getItemCount()))
        return RET_NOTPOSSIBLE;

    if(item->isNotMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, flags))
        return RET_NOTMOVEABLE;

    return RET_NOERROR;
}

That's all, enjoy!
Don't forget to Like! and comment! ;)
Rep!! Works perfectly
 
Awesome! man, this is work 100% perfect, this code is Awesome :p, you helped me a lot, thanks very much, REP+++
 
Back
Top