Postado Abril 1, 2015 10 anos 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; } 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; } 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 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.
Postado Abril 1, 2015 10 anos Muito obrigado por compartilhar amigo, Realmente, eu notei que conteúdos assim estão em falta! Tópico movido para seção correta e reputação entregue.
Postado Abril 1, 2015 10 anos Bom, agora os novos servidores terão esse sistema. #MaisSistemasAssim <3, Alias, gostei muito, ganhou meu Rep
Postado Abril 1, 2015 10 anos 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 Abril 1, 2015 10 anos por fireelement (veja o histórico de edições)
Postado Abril 1, 2015 10 anos 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.