Boa, garoto!
Gostei bastante, sistema bem completo e com modificações no código-fonte que o deixam único. Parabéns. \o/
REP+
Por MatheusGlad, 11 de ago. de 2012 em NPCs, monsters e raids
Boa, garoto!
Gostei bastante, sistema bem completo e com modificações no código-fonte que o deixam único. Parabéns. \o/
REP+
info
Grupo: Conde
Registrado: 30/06/11
Posts: 631
Reputação: +371
Char no Tibia: Warrior of Mort

Muito bom, fiz esse mesmo sistema mais usando apenas "callbackOnBuy" e "callbackOnSell" para um item especifico mais achei muito precário. Assim ficou muito show, parabéns!
Rep+
info
Grupo: Lorde
Registrado: 17/01/09
Posts: 2.1k
Reputação: +395
Char no Tibia: Adra Sata

Opa.
Parabéns, ótimo ;D;
Script ficou ótimo, sem palavras para descreve-lo! rep+
info
Grupo: Conde
Registrado: 09/09/09
Posts: 528
Reputação: +424
Char no Tibia: Emekalo Makalo
Bem, eu fiz algumas alteraçoes no Npc System para que isso fosse possivel, tambem fiz alteraçoes na source, porem as modificaçoes da source nao sao obrigatorias, porem para um otserver serio seria bem legal implementa-las.
Video:
Download dos arquivos ja modificados:
Npc System Modified.rar
Ou entao modifique voce mesmo.
Entao vamos as alteraçoes:
Vá em data\npc\lib\npcsystem, todas as alteraçoes serao nos arquivos desta pasta entao nao vou ficar falando o destino.
npchandler.lua:
Procure por:
Em baixo adicione essa linha:
Procure por:
Substitua por:
Procure por:
Substitua por:
Agora Procure por:
Mude para:
Procure por:
Mude para:
modules.lua:
Procure por:
Embaixo bote:
Procure por:
Substitua Toda a funçao por:
function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, moneyId) local shopItem = nil if amount <= 0 or type(amount) ~= "number" then amount = 1 end for _, item in ipairs(self.npcHandler.shopItems) do if(item.id == itemid and item.subType == subType) then shopItem = item break end end if(shopItem == nil) then error("[shopModule.onBuy]", "Item not found on shopItems list") return false end if(shopItem.buy == -1) then error("[shopModule.onSell]", "Attempt to purchase an item which only sellable") return false end local backpack, totalCost = 1988, amount * shopItem.buy if(inBackpacks) then totalCost = not moneyId and (totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)) or totalCost end local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name, [TAG_MONEYNAME] = moneyId and getItemNameById(moneyId) or "gold" } if (not moneyId and getPlayerMoney(cid) < totalCost) or (moneyId and getPlayerItemCount(cid, moneyId) < totalCost) then local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY) doPlayerSendCancel(cid, self.npcHandler:parseMessage(msg, parseInfo)) return false end local subType = shopItem.subType or 1 local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack) if(a < amount) then local msgId = MESSAGE_NEEDMORESPACE if(a == 0) then msgId = MESSAGE_NEEDSPACE end local msg = self.npcHandler:getMessage(msgId) parseInfo[TAG_ITEMCOUNT] = a doPlayerSendCancel(cid, self.npcHandler:parseMessage(msg, parseInfo)) if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then self.npcHandler.talkStart[cid] = os.time() else self.npcHandler.talkStart = os.time() end if(a > 0) then if not moneyId then doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20))) else doPlayerRemoveItem(cid, moneyId, ((a * shopItem.buy) + (b * 20))) end return true end return false end local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, self.npcHandler:parseMessage(msg, parseInfo)) if not moneyId then doPlayerRemoveMoney(cid, totalCost) else doPlayerRemoveItem(cid, moneyId, totalCost) end if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then self.npcHandler.talkStart[cid] = os.time() else self.npcHandler.talkStart = os.time() end return true endAgora procure por:
Substitua toda a funçao por:
function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks, moneyId) local shopItem = nil for _, item in ipairs(self.npcHandler.shopItems) do if(item.id == itemid and item.subType == subType) then shopItem = item break end end if(shopItem == nil) then error("[shopModule.onBuy]", "Item not found on shopItems list") return false end if(shopItem.sell == -1) then error("[shopModule.onSell]", "Attempt to sell an item which is only buyable") return false end local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = amount * shopItem.sell, [TAG_ITEMNAME] = shopItem.name, [TAG_MONEYNAME] = moneyId and getItemNameById(moneyId) or "gold" } if(subType < 1 or getItemInfo(itemid).stackable) then subType = -1 end if(doPlayerRemoveItem(cid, itemid, amount, subType)) then local msg = self.npcHandler:getMessage(MESSAGE_SOLD) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, self.npcHandler:parseMessage(msg, parseInfo)) if not moneyId then doPlayerAddMoney(cid, amount * shopItem.sell) else doPlayerAddItem(cid, moneyId, amount * shopItem.sell) end if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then self.npcHandler.talkStart[cid] = os.time() else self.npcHandler.talkStart = os.time() end return true end local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM) doPlayerSendCancel(cid, self.npcHandler:parseMessage(msg, parseInfo)) if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then self.npcHandler.talkStart[cid] = os.time() else self.npcHandler.talkStart = os.time() end return false endnpcsystem.lua:
Procure por:
Embaixo bote:
Agora a parte em C++, lembrando nao é obrigatoria, é mais para uma questao de estetica:
protocolgame.cpp:
Obs: Isso soh ira funcionar com UMA MOEDA DIFERENTE! Voce pode editar para fazer funcionar com mais, porem tenha certeza que sabe o que esta fazendo.
Procure pela funçao:
Substitua toda ela por:
void ProtocolGame::sendGoods(const ShopInfoList& shop) { NetworkMessage_ptr msg = getOutputBuffer(); if(msg) { TRACK_MESSAGE(msg); msg->AddByte(0x7B); std::string value; player->getStorage(97113, value); if (atoi(value.c_str()) != 1) { msg->AddU32(g_game.getMoney(player)); } else { msg->AddU32(player->__getItemTypeCount(9971)); } std::map<uint32_t, uint32_t> goodsMap; if(shop.size() >= 5) { for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit) { if(sit->sellPrice < 0) continue; int8_t subType = -1; if(sit->subType) { const ItemType& it = Item::items[sit->itemId]; if(it.hasSubType() && !it.stackable) subType = sit->subType; } uint32_t count = player->__getItemTypeCount(sit->itemId, subType); if(count > 0) goodsMap[sit->itemId] = count; } } else { std::map<uint32_t, uint32_t> tmpMap; player->__getAllItemTypeCount(tmpMap); for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit) { if(sit->sellPrice < 0) continue; int8_t subType = -1; if(sit->subType) { const ItemType& it = Item::items[sit->itemId]; if(it.hasSubType() && !it.stackable) subType = sit->subType; } if(subType != -1) { uint32_t count = player->__getItemTypeCount(sit->itemId, subType); if(count > 0) goodsMap[sit->itemId] = count; } else goodsMap[sit->itemId] = tmpMap[sit->itemId]; } } msg->AddByte(std::min(goodsMap.size(), (size_t)255)); std::map<uint32_t, uint32_t>::const_iterator it = goodsMap.begin(); for(uint32_t i = 0; it != goodsMap.end() && i < 255; ++it, ++i) { msg->AddItemId(it->first); msg->AddByte(std::min(it->second, (uint32_t)255)); } } }E na linha msg->AddU32(player->__getItemTypeCount(9971)); aonde esta 9971 voce troca pelo id da sua moeda diferente!
player.cpp:
Procure por:
Voce achara 2 desses em ambos bote isso embaixo:
Pronto agora para que um npc use a moeda diferente ou nao voce bota isso no XML dele:
Flw
Editado Agosto 11 por MatheusMkalo