Ir para conteúdo

Featured Replies

Postado
  • Este é um post popular.

Olá pessoal, estive reparando que varias pessoas estão a procura de como adicionar Auto Stacking no TFS 0.3.6pl1, então estarei postando o método!

 

1 - No Arquivo Container.cpp procure por:

 

Cylinder* Container::__queryDestination(int32_t& index, const Thing* thing, Item** destItem, uint32_t&)

 

Troque toda a Function por essa:

 

 

Spoiler

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(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(*destItem);
 
                if(subCylinder){
                        index = INDEX_WHEREEVER;
                        *destItem = NULL;
                        return subCylinder;
                }
        }
 
        return this;
}

 

                                                    kQZmfen.gif

 

2 - novamente em Container.cpp procure por:

 

ReturnValue Container::__queryMaxCount(int32_t index, const Thing* thing, uint32_t count,

 

Troque toda a Function por essa:

 

 

Spoiler

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;
}

 

                                                    kQZmfen.gif

3 - novamente em Container.cpp procure por:

 

ReturnValue Container::__queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const

 

Troque toda a Function por essa:

 

 

Spoiler

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;
}

 

Prontinho Auto Stack Adicionado  :D

                                                    kQZmfen.gif

 

Perguntas

1- A Snix onde fica esse container.cpp?

R: nas sources do seu servidor.

 

2- A Snix qual versão do tibia funciona isso?

R: bom eu testei no tfs 0.3.6pl1 protocol 8.54 - 8.60 100% funcional.

 

3- A Snix o que esse system faz exatamente?

R: quando você puxa 1 item agrupável para sua bag se tiver o mesmo item na bag eles se agrupam automaticamente.

  • Respostas 20
  • Visualizações 6k
  • Created
  • Última resposta

Top Posters In This Topic

Most Popular Posts

  • Fir3element
    Fir3element

    vai bugar o doPlayerAddItem (e talvez doPlayerAddItemEx)   @fix  

  • Cylinder* subCylinder = dynamic_cast(*destItem); troca por Cylinder* subCylinder = dynamic_cast<Cylinder*>(*destItem); Container* parentContainer = dynamic_cast(getParent()); troca por Containe

  • So fazer o que disse acima.

Posted Images

Postado

vai bugar o doPlayerAddItem (e talvez doPlayerAddItemEx)

 

@fix

 

int32_t LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
{
    //doPlayerAddItem(cid, itemid[, count/subtype = 1[, canDropOnMap = true[, slot = 0]]])
    //doPlayerAddItem(cid, itemid[, count = 1[, canDropOnMap = true[, subtype = 1[, slot = 0]]]])
    int32_t params = lua_gettop(L), subType = 1, slot = SLOT_WHEREEVER;
    if(params > 5)
        slot = popNumber(L);

    if(params > 4)
    {
        if(params > 5)
            subType = popNumber(L);
        else
            slot = popNumber(L);
    }

    bool canDropOnMap = true;
    if(params > 3)
        canDropOnMap = popNumber(L);

    uint32_t count = 1;
    if(params > 2)
        count = popNumber(L);

    uint32_t itemId = popNumber(L);
    if(slot > SLOT_AMMO)
    {
        errorEx("Invalid slot.");
        lua_pushboolean(L, false);
        return 1;
    }

    ScriptEnviroment* env = getEnv();
    Player* player = env->getPlayerByUID((uint32_t)popNumber(L));
    if(!player)
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    const ItemType& it = Item::items[itemId];
    int32_t itemCount = 1;
    if(params > 4)
        itemCount = std::max((uint32_t)1, count);
    else if(it.hasSubType())
    {
        if(it.stackable)
            itemCount = (int32_t)std::ceil((float)count / 100);

        subType = count;
    }

    while(itemCount > 0)
    {
        int32_t stackCount = std::min(100, subType);
        Item* newItem = Item::CreateItem(itemId, stackCount);
        if(!newItem)
        {
            errorEx(getError(LUA_ERROR_ITEM_NOT_FOUND));
            lua_pushboolean(L, false);
            return 1;
        }

        if(it.stackable)
            subType -= stackCount;

        ReturnValue ret = g_game.internalPlayerAddItem(NULL, player, newItem, canDropOnMap, (slots_t)slot);
        if(ret != RET_NOERROR)
        {
            delete newItem;
            lua_pushboolean(L, false);
            return 1;
        }

        --itemCount;
        if(itemCount)
            continue;

        if(newItem->getParent())
            lua_pushnumber(L, env->addThing(newItem));
        else //stackable item stacked with existing object, newItem will be released
            lua_pushnil(L);

        return 1;
    }

    lua_pushnil(L);
    return 1;
}

int32_t LuaScriptInterface::luaDoPlayerAddItemEx(lua_State* L)
{
    //doPlayerAddItemEx(cid, uid[, canDropOnMap = false[, slot = 0]])
    int32_t params = lua_gettop(L), slot = SLOT_WHEREEVER;
    if(params > 3)
        slot = popNumber(L);

    bool canDropOnMap = false;
    if(params > 2)
        canDropOnMap = popNumber(L);

    uint32_t uid = (uint32_t)popNumber(L);
    if(slot > SLOT_AMMO)
    {
        errorEx("Invalid slot.");
        lua_pushboolean(L, false);
        return 1;
    }

    ScriptEnviroment* env = getEnv();
    Player* player = env->getPlayerByUID(popNumber(L));
    if(!player)
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    Item* item = env->getItemByUID(uid);
    if(!item)
    {
        errorEx(getError(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    if(item->getParent() == VirtualCylinder::virtualCylinder)
        lua_pushnumber(L, g_game.internalPlayerAddItem(NULL, player, item, canDropOnMap, (slots_t)slot));
    else
        lua_pushboolean(L, false);

    return 1;
}

Editado por fireelement (veja o histórico de edições)

Postado
  • Autor

vai bugar o doPlayerAddItem (e talvez doPlayerAddItemEx)

 

@fix

 

int32_t LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
{
    //doPlayerAddItem(cid, itemid[, count/subtype = 1[, canDropOnMap = true[, slot = 0]]])
    //doPlayerAddItem(cid, itemid[, count = 1[, canDropOnMap = true[, subtype = 1[, slot = 0]]]])
    int32_t params = lua_gettop(L), subType = 1, slot = SLOT_WHEREEVER;
    if(params > 5)
        slot = popNumber(L);

    if(params > 4)
    {
        if(params > 5)
            subType = popNumber(L);
        else
            slot = popNumber(L);
    }

    bool canDropOnMap = true;
    if(params > 3)
        canDropOnMap = popNumber(L);

    uint32_t count = 1;
    if(params > 2)
        count = popNumber(L);

    uint32_t itemId = popNumber(L);
    if(slot > SLOT_AMMO)
    {
        errorEx("Invalid slot.");
        lua_pushboolean(L, false);
        return 1;
    }

    ScriptEnviroment* env = getEnv();
    Player* player = env->getPlayerByUID((uint32_t)popNumber(L));
    if(!player)
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    const ItemType& it = Item::items[itemId];
    int32_t itemCount = 1;
    if(params > 4)
        itemCount = std::max((uint32_t)1, count);
    else if(it.hasSubType())
    {
        if(it.stackable)
            itemCount = (int32_t)std::ceil((float)count / 100);

        subType = count;
    }

    while(itemCount > 0)
    {
        int32_t stackCount = std::min(100, subType);
        Item* newItem = Item::CreateItem(itemId, stackCount);
        if(!newItem)
        {
            errorEx(getError(LUA_ERROR_ITEM_NOT_FOUND));
            lua_pushboolean(L, false);
            return 1;
        }

        if(it.stackable)
            subType -= stackCount;

        ReturnValue ret = g_game.internalPlayerAddItem(NULL, player, newItem, canDropOnMap, (slots_t)slot);
        if(ret != RET_NOERROR)
        {
            delete newItem;
            lua_pushboolean(L, false);
            return 1;
        }

        --itemCount;
        if(itemCount)
            continue;

        if(newItem->getParent())
            lua_pushnumber(L, env->addThing(newItem));
        else //stackable item stacked with existing object, newItem will be released
            lua_pushnil(L);

        return 1;
    }

    lua_pushnil(L);
    return 1;
}

int32_t LuaScriptInterface::luaDoPlayerAddItemEx(lua_State* L)
{
    //doPlayerAddItemEx(cid, uid[, canDropOnMap = false[, slot = 0]])
    int32_t params = lua_gettop(L), slot = SLOT_WHEREEVER;
    if(params > 3)
        slot = popNumber(L);

    bool canDropOnMap = false;
    if(params > 2)
        canDropOnMap = popNumber(L);

    uint32_t uid = (uint32_t)popNumber(L);
    if(slot > SLOT_AMMO)
    {
        errorEx("Invalid slot.");
        lua_pushboolean(L, false);
        return 1;
    }

    ScriptEnviroment* env = getEnv();
    Player* player = env->getPlayerByUID(popNumber(L));
    if(!player)
    {
        errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    Item* item = env->getItemByUID(uid);
    if(!item)
    {
        errorEx(getError(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushboolean(L, false);
        return 1;
    }

    if(item->getParent() == VirtualCylinder::virtualCylinder)
        lua_pushnumber(L, g_game.internalPlayerAddItem(NULL, player, item, canDropOnMap, (slots_t)slot));
    else
        lua_pushboolean(L, false);

    return 1;
}

quando chegar em casa vou testar! caso o resultado seja positivo vou adicionar sua correção ao topico, obrigado.

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.6k

Informação Importante

Confirmação de Termo