MatheusGlad 424 Postado Dezembro 3, 2015 Share Postado Dezembro 3, 2015 (editado) Creditos:Baseado no code do cbrm:https://otland.net/threads/reward-chest-boss-reward-tfs-1-2.233397/Instruções::src/const.h:Embaixo de... ITEM_MARKET = 14405, ...Adicione: ITEM_REWARD_BAG = 21518, ITEM_REWARD_CHEST = 21584, REWARD_CHEST_DEPOTID = 99, src/depotchest.h:Embaixo de... explicit DepotChest(uint16_t _type); ...Adicione: uint32_t getDepotId() const { return depotId; } void setDepotId(uint32_t id) { depotId = id; } Embaixo de... uint32_t maxDepotItems; ...Adicione: uint32_t depotId; src/depotchest.cpp:Embaixo de... maxDepotItems = 1500; ...Adicione: depotId = 0; Em cima de... return Container::queryAdd(index, thing, count, flags, actor); ...Adicione: if (actor != nullptr && getDepotId() == REWARD_CHEST_DEPOTID) { return RETURNVALUE_NOTPOSSIBLE; } src/depotlocker.h:Em cima de... //cylinder implementations ...Adicione: void setMaxLockerItems(uint32_t maxitems) { maxSize = maxitems; } src/player.h:Embaixo de... DepotLocker* getDepotLocker(uint32_t depotId); ...Adicione: DepotChest* getRewardBag(uint32_t depotId, bool autoCreate); DepotLocker* getRewardChest(uint16_t itemId); src/player.cpp:Em cima de... void Player::sendCancelMessage(ReturnValue message) const ...Adicione: DepotChest* Player::getRewardBag(uint32_t depotId, bool autoCreate) { auto it = depotChests.find(depotId); if (it != depotChests.end()) { return it->second; } if (!autoCreate) { return nullptr; } DepotChest* bagReward = new DepotChest(ITEM_REWARD_BAG); bagReward->setDepotId(depotId); bagReward->incrementReferenceCounter(); bagReward->setMaxDepotItems(getMaxDepotItems()); depotChests[depotId] = bagReward; return bagReward; } DepotLocker* Player::getRewardChest(uint16_t itemId) { auto it = depotLockerMap.find(REWARD_CHEST_DEPOTID); if (it != depotLockerMap.end()) { it->second->setID(itemId); return it->second; } DepotLocker* rewardChest = new DepotLocker(ITEM_REWARD_CHEST); rewardChest->setID(itemId); rewardChest->setDepotId(REWARD_CHEST_DEPOTID); rewardChest->setMaxLockerItems(1); rewardChest->internalAddThing(getRewardBag(REWARD_CHEST_DEPOTID, true)); depotLockerMap[REWARD_CHEST_DEPOTID] = rewardChest; return rewardChest; } Em player.cpp, container.cpp, inbox.cpp:Mude: if (!item->isPickupable()) { Por: if (item->getID() != 21518 && !item->isPickupable()) { src/actions.cpp:Mude: //depot container if (DepotLocker* depot = container->getDepotLocker()) { DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); } else { openContainer = container; } Por: //reward chest and depot container if (item->getActionId() == ITEM_REWARD_CHEST || item->getID() == ITEM_REWARD_CHEST) { DepotLocker* myRewardChest = player->getRewardChest(item->getID()); myRewardChest->setParent(item->getTile()); openContainer = myRewardChest; player->setLastDepotId(REWARD_CHEST_DEPOTID); } else if (DepotLocker* depot = container->getDepotLocker()) { DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); } else { openContainer = container; } src/game.cpp:Em cima de... if (!item->isPushable() || item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) { ...Adicione: if (item->getID() == ITEM_REWARD_BAG || item->getActionId() == ITEM_REWARD_CHEST) { player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); return; } src/monsters.h:Embaixo de... int32_t subType; int32_t actionId; std::string text; ...Adicione: bool uniquedrop; Embaixo de... actionId = -1; ...Adicione: uniquedrop = false; Embaixo de... bool hiddenHealth; ...Adicione: bool rewardChest; src/monsters.cpp:Embaixo de... healthMax = 100; ...Adicione: rewardChest = false; Embaixo de... } else if (strcasecmp(attrName, "hidehealth") == 0) { mType->hiddenHealth = attr.as_bool(); ...Adicione: } else if (strcasecmp(attrName, "rewardchest") == 0) { mType->rewardChest = attr.as_bool(); Em cima de... if ((attr = node.attribute("actionId"))) { ...Adicione: if ((attr = node.attribute("uniquedrop"))) { lootBlock.uniquedrop = attr.as_bool(); } src/iologindata.cpp:Embaixo de... //load depot items ...Adicione: player->getRewardChest(ITEM_REWARD_CHEST); Mude: if (pid >= 0 && pid < 100) { DepotChest* depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); } Por: if (pid >= 0 && pid < 100) { if (pid == REWARD_CHEST_DEPOTID) { DepotChest* depotChest = player->getRewardBag(pid, true); if (depotChest) { depotChest->internalAddThing(item); } } else { DepotChest* depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); } } src/luascript.h:Em cima de... // Combat ...Adicione: // Reward static int luaItemGetNameDescription(lua_State* L); static int luaMonsterTypeUseRewardChest(lua_State* L); src/luascript.cpp:Em cima de... // Party registerClass("Party", "", nullptr); ...Adicione: // Reward registerMethod("MonsterType", "useRewardChest", LuaScriptInterface::luaMonsterTypeUseRewardChest); registerMethod("Item", "getNameDescription", LuaScriptInterface::luaItemGetNameDescription); Em cima de... // Combat int LuaScriptInterface::luaCombatCreate(lua_State* L) ...Adicione: int LuaScriptInterface::luaItemGetNameDescription(lua_State* L) { // item:getNameDescription() const Item* item = getUserdata<const Item>(L, 1); int32_t subType; bool addArticle = true; if (item) { subType = item->getSubType(); const ItemType& it = Item::items[item->getID()]; std::ostringstream s; const std::string& name = (item ? item->getName() : it.name); if (!name.empty()) { if (it.stackable && subType > 1) { if (it.showCount) { s << subType << ' '; } s << (item ? item->getPluralName() : it.getPluralName()); } else { if (addArticle) { const std::string& article = (item ? item->getArticle() : it.article); if (!article.empty()) { s << article << ' '; } } s << name; } } else { s << "an item of type " << it.id; } pushString(L, s.str()); } else { lua_pushnil(L); } return 1; } int LuaScriptInterface::luaMonsterTypeUseRewardChest(lua_State* L) { // monsterType:useRewardChest() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (monsterType) { pushBoolean(L, monsterType->rewardChest); } else { lua_pushnil(L); } return 1; } Mude: int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L) { // monsterType:getLoot() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (!monsterType) { lua_pushnil(L); return 1; } static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) { lua_createtable(L, lootList.size(), 0); int index = 0; for (const auto& lootBlock : lootList) { lua_createtable(L, 0, 7); setField(L, "itemId", lootBlock.id); setField(L, "chance", lootBlock.chance); setField(L, "subType", lootBlock.subType); setField(L, "maxCount", lootBlock.countmax); setField(L, "actionId", lootBlock.actionId); setField(L, "text", lootBlock.text); parseLoot(lootBlock.childLoot); lua_setfield(L, -2, "childLoot"); lua_rawseti(L, -2, ++index); } }; parseLoot(monsterType->lootItems); return 1; } Por: int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L) { // monsterType:getLoot() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (!monsterType) { lua_pushnil(L); return 1; } static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) { lua_createtable(L, lootList.size(), 0); int index = 0; for (const auto& lootBlock : lootList) { lua_createtable(L, 0, 8); setField(L, "itemId", lootBlock.id); setField(L, "chance", lootBlock.chance); setField(L, "subType", lootBlock.subType); setField(L, "maxCount", lootBlock.countmax); setField(L, "actionId", lootBlock.actionId); setField(L, "text", lootBlock.text); pushBoolean(L, lootBlock.uniquedrop); lua_setfield(L, -2, "uniquedrop"); parseLoot(lootBlock.childLoot); lua_setfield(L, -2, "childLoot"); lua_rawseti(L, -2, ++index); } }; parseLoot(monsterType->lootItems); return 1; } Pronto, a parte de C++ acabou agora o resto: Adicione @ data/items/items/xml <item id="21518" article="a" name="reward container"> <attribute key="weight" value="1800" /> <attribute key="containersize" value="100" /> <attribute key="slotType" value="backpack" /> </item> <item id="21584" article="a" name="reward chest"> <attribute key="type" value="depot" /> <attribute key="containerSize" value="1" /> <attribute key="description" value="This chest contains your rewards earned in battles." /> </item> Adicione @ data/creaturescripts/creaturescripts.xml <event type="kill" name="RewardLoot" script="rewardloot.lua"/> Registre @ data/creaturescripts/scripts/login.lua player:registerEvent("RewardLoot") Crie data/creaturescripts/scripts/rewardloot.lua: function sort_descending(t) local tmp = {} for k, v in pairs(t) do table.insert(tmp, {k, v}) end table.sort(tmp, function(a, b) return a[2] > b[2] end) return tmp end function table.find(t, v) for i,x in pairs(t) do if x == v then return true end end end function Player:addItemRewardBag(itemid, count) local rewardbag = self:getDepotChest(99) return rewardbag:addItem(itemid, count) end function MonsterType:getBossReward(chance, unique) local ret = {} local function randomItem(lootBlock, chance) local randvalue = math.random(0, 100000) / (getConfigInfo("rateLoot") * chance) if randvalue < lootBlock.chance then if (ItemType(lootBlock.itemId):isStackable()) then return (randvalue%lootBlock.maxCount) + 1 else return 1 end end end local lootBlockList = self:getLoot() for _, loot in pairs(lootBlockList) do local rd = randomItem(loot, chance) if rd then if loot.uniquedrop then if unique then table.insert(ret, {loot, rd}) end else table.insert(ret, {loot, rd}) end end end return ret end BossLoot = {} BossUids = {} function BossLoot:new(boss) if not table.find(BossUids, boss:getId()) then table.insert(BossUids, boss:getId()) return setmetatable({creature=boss}, {__index = BossLoot}) end end function BossLoot:updateDamage() if self.creature then local tmp = {} local totaldmg = 0 for killer, damage in pairs(self.creature:getDamageMap()) do totaldmg = totaldmg+damage.total tmp[killer] = damage.total end self.players = sort_descending(tmp) self.totaldmg = totaldmg else error("Creature not found.") end end function BossLoot:setRewards() if self.totaldmg and self.creature then if getConfigInfo("rateLoot") > 0 then local mt = MonsterType(self.creature:getName()) for i, playertab in ipairs(self.players) do local loot if i == 1 then loot = mt:getBossReward(playertab[2] / self.totaldmg, true) else loot = mt:getBossReward(playertab[2] / self.totaldmg, false) end table.insert(self.players[i], loot) end end else error("Error") end end function BossLoot:addRewards() if self.players and self.players[1] and self.players[1][3] then for i, playertab in ipairs(self.players) do local player = Player(playertab[1]) if player then local str = "The following items are available in your reward chest: " for i, lootTable in ipairs(playertab[3]) do local item = player:addItemRewardBag(lootTable[1].itemId, math.ceil(lootTable[2])) if item then str = str .. item:getNameDescription() .. ", " end end str = str:sub(1, #str-2) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, str) end end else error("Error") end end function onKill(creature, target) if (Monster(target) ~= nil) then local mt = MonsterType(target:getName()) if mt:useRewardChest() then local loot = BossLoot:new(target) if loot then local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition())) corpse:decay() target:setDropLoot(false) loot:updateDamage() loot:setRewards() loot:addRewards() corpse:setAttribute('aid', 21584) end end end end COMO USAR !!Simplesmente adicione essa flag no monstro: <flag rewardchest="1" /> Você tambem pode fazer um drop ser unique, assim somente a pessoa que fez a maior parte do dano vai pegar esse item. <item id="5903" chance="100000" uniquedrop="1" /><!-- ferumbras' hat --> Editado Dezembro 3, 2015 por MatheusMkalo Link para o comentário Compartilhar em outros sites More sharing options...
Deadpool 862 Postado Dezembro 6, 2015 Share Postado Dezembro 6, 2015 Boa garoto! haha, eu não tfs 1.0+.. porem é um codigo bacana.. vou tentar fazer um pra tfs 0.3.6 até 10.10 Link para o comentário Compartilhar em outros sites More sharing options...
GustavaoTibia 0 Postado Dezembro 11, 2015 Share Postado Dezembro 11, 2015 (editado) [Creditos:Baseado no code do cbrm:https://otland.net/threads/reward-chest-boss-reward-tfs-1-2.233397/Instruções::src/const.h:Embaixo de... ITEM_MARKET = 14405, ...Adicione: ITEM_REWARD_BAG = 21518, ITEM_REWARD_CHEST = 21584, REWARD_CHEST_DEPOTID = 99, src/depotchest.h:Embaixo de... explicit DepotChest(uint16_t _type); ...Adicione: uint32_t getDepotId() const { return depotId; } void setDepotId(uint32_t id) { depotId = id; } Embaixo de... uint32_t maxDepotItems; ...Adicione: uint32_t depotId; src/depotchest.cpp:Embaixo de... maxDepotItems = 1500; ...Adicione: depotId = 0; Em cima de... return Container::queryAdd(index, thing, count, flags, actor); ...Adicione: if (actor != nullptr && getDepotId() == REWARD_CHEST_DEPOTID) { return RETURNVALUE_NOTPOSSIBLE; } src/depotlocker.h:Em cima de... //cylinder implementations ...Adicione: void setMaxLockerItems(uint32_t maxitems) { maxSize = maxitems; } src/player.h:Embaixo de... DepotLocker* getDepotLocker(uint32_t depotId); ...Adicione: DepotChest* getRewardBag(uint32_t depotId, bool autoCreate); DepotLocker* getRewardChest(uint16_t itemId); src/player.cpp:Em cima de... void Player::sendCancelMessage(ReturnValue message) const ...Adicione: DepotChest* Player::getRewardBag(uint32_t depotId, bool autoCreate) { auto it = depotChests.find(depotId); if (it != depotChests.end()) { return it->second; } if (!autoCreate) { return nullptr; } DepotChest* bagReward = new DepotChest(ITEM_REWARD_BAG); bagReward->setDepotId(depotId); bagReward->incrementReferenceCounter(); bagReward->setMaxDepotItems(getMaxDepotItems()); depotChests[depotId] = bagReward; return bagReward; } DepotLocker* Player::getRewardChest(uint16_t itemId) { auto it = depotLockerMap.find(REWARD_CHEST_DEPOTID); if (it != depotLockerMap.end()) { it->second->setID(itemId); return it->second; } DepotLocker* rewardChest = new DepotLocker(ITEM_REWARD_CHEST); rewardChest->setID(itemId); rewardChest->setDepotId(REWARD_CHEST_DEPOTID); rewardChest->setMaxLockerItems(1); rewardChest->internalAddThing(getRewardBag(REWARD_CHEST_DEPOTID, true)); depotLockerMap[REWARD_CHEST_DEPOTID] = rewardChest; return rewardChest; } Em player.cpp, container.cpp, inbox.cpp:Mude: if (!item->isPickupable()) { Por: if (item->getID() != 21518 && !item->isPickupable()) { src/actions.cpp:Mude: //depot container if (DepotLocker* depot = container->getDepotLocker()) { DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); } else { openContainer = container; } Por: //reward chest and depot container if (item->getActionId() == ITEM_REWARD_CHEST || item->getID() == ITEM_REWARD_CHEST) { DepotLocker* myRewardChest = player->getRewardChest(item->getID()); myRewardChest->setParent(item->getTile()); openContainer = myRewardChest; player->setLastDepotId(REWARD_CHEST_DEPOTID); } else if (DepotLocker* depot = container->getDepotLocker()) { DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); } else { openContainer = container; } src/game.cpp:Em cima de... if (!item->isPushable() || item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) { ...Adicione: if (item->getID() == ITEM_REWARD_BAG || item->getActionId() == ITEM_REWARD_CHEST) { player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); return; } src/monsters.h:Embaixo de... int32_t subType; int32_t actionId; std::string text; ...Adicione: bool uniquedrop; Embaixo de... actionId = -1; ...Adicione: uniquedrop = false; Embaixo de... bool hiddenHealth; ...Adicione: bool rewardChest; src/monsters.cpp:Embaixo de... healthMax = 100; ...Adicione: rewardChest = false; Embaixo de... } else if (strcasecmp(attrName, "hidehealth") == 0) { mType->hiddenHealth = attr.as_bool(); ...Adicione: } else if (strcasecmp(attrName, "rewardchest") == 0) { mType->rewardChest = attr.as_bool(); Em cima de... if ((attr = node.attribute("actionId"))) { ...Adicione: if ((attr = node.attribute("uniquedrop"))) { lootBlock.uniquedrop = attr.as_bool(); } src/iologindata.cpp:Embaixo de... //load depot items ...Adicione: player->getRewardChest(ITEM_REWARD_CHEST); Mude: if (pid >= 0 && pid < 100) { DepotChest* depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); } Por: if (pid >= 0 && pid < 100) { if (pid == REWARD_CHEST_DEPOTID) { DepotChest* depotChest = player->getRewardBag(pid, true); if (depotChest) { depotChest->internalAddThing(item); } } else { DepotChest* depotChest = player->getDepotChest(pid, true); if (depotChest) { depotChest->internalAddThing(item); } } src/luascript.h:Em cima de... // Combat ...Adicione: // Reward static int luaItemGetNameDescription(lua_State* L); static int luaMonsterTypeUseRewardChest(lua_State* L); src/luascript.cpp:Em cima de... // Party registerClass("Party", "", nullptr); ...Adicione: // Reward registerMethod("MonsterType", "useRewardChest", LuaScriptInterface::luaMonsterTypeUseRewardChest); registerMethod("Item", "getNameDescription", LuaScriptInterface::luaItemGetNameDescription); Em cima de... // Combat int LuaScriptInterface::luaCombatCreate(lua_State* L) ...Adicione: int LuaScriptInterface::luaItemGetNameDescription(lua_State* L) { // item:getNameDescription() const Item* item = getUserdata<const Item>(L, 1); int32_t subType; bool addArticle = true; if (item) { subType = item->getSubType(); const ItemType& it = Item::items[item->getID()]; std::ostringstream s; const std::string& name = (item ? item->getName() : it.name); if (!name.empty()) { if (it.stackable && subType > 1) { if (it.showCount) { s << subType << ' '; } s << (item ? item->getPluralName() : it.getPluralName()); } else { if (addArticle) { const std::string& article = (item ? item->getArticle() : it.article); if (!article.empty()) { s << article << ' '; } } s << name; } } else { s << "an item of type " << it.id; } pushString(L, s.str()); } else { lua_pushnil(L); } return 1; } int LuaScriptInterface::luaMonsterTypeUseRewardChest(lua_State* L) { // monsterType:useRewardChest() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (monsterType) { pushBoolean(L, monsterType->rewardChest); } else { lua_pushnil(L); } return 1; } Mude: int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L) { // monsterType:getLoot() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (!monsterType) { lua_pushnil(L); return 1; } static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) { lua_createtable(L, lootList.size(), 0); int index = 0; for (const auto& lootBlock : lootList) { lua_createtable(L, 0, 7); setField(L, "itemId", lootBlock.id); setField(L, "chance", lootBlock.chance); setField(L, "subType", lootBlock.subType); setField(L, "maxCount", lootBlock.countmax); setField(L, "actionId", lootBlock.actionId); setField(L, "text", lootBlock.text); parseLoot(lootBlock.childLoot); lua_setfield(L, -2, "childLoot"); lua_rawseti(L, -2, ++index); } }; parseLoot(monsterType->lootItems); return 1; } Por: int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L) { // monsterType:getLoot() MonsterType* monsterType = getUserdata<MonsterType>(L, 1); if (!monsterType) { lua_pushnil(L); return 1; } static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) { lua_createtable(L, lootList.size(), 0); int index = 0; for (const auto& lootBlock : lootList) { lua_createtable(L, 0, 8); setField(L, "itemId", lootBlock.id); setField(L, "chance", lootBlock.chance); setField(L, "subType", lootBlock.subType); setField(L, "maxCount", lootBlock.countmax); setField(L, "actionId", lootBlock.actionId); setField(L, "text", lootBlock.text); pushBoolean(L, lootBlock.uniquedrop); lua_setfield(L, -2, "uniquedrop"); parseLoot(lootBlock.childLoot); lua_setfield(L, -2, "childLoot"); lua_rawseti(L, -2, ++index); } }; parseLoot(monsterType->lootItems); return 1; } Pronto, a parte de C++ acabou agora o resto:Adicione @ data/items/items/xml <item id="21518" article="a" name="reward container"> <attribute key="weight" value="1800" /> <attribute key="containersize" value="100" /> <attribute key="slotType" value="backpack" /> </item> <item id="21584" article="a" name="reward chest"> <attribute key="type" value="depot" /> <attribute key="containerSize" value="1" /> <attribute key="description" value="This chest contains your rewards earned in battles." /> </item> Adicione @ data/creaturescripts/creaturescripts.xml <event type="kill" name="RewardLoot" script="rewardloot.lua"/> Registre @ data/creaturescripts/scripts/login.lua player:registerEvent("RewardLoot") Crie data/creaturescripts/scripts/rewardloot.lua: function sort_descending(t) local tmp = {} for k, v in pairs(t) do table.insert(tmp, {k, v}) end table.sort(tmp, function(a, b) return a[2] > b[2] end) return tmp end function table.find(t, v) for i,x in pairs(t) do if x == v then return true end end end function Player:addItemRewardBag(itemid, count) local rewardbag = self:getDepotChest(99) return rewardbag:addItem(itemid, count) end function MonsterType:getBossReward(chance, unique) local ret = {} local function randomItem(lootBlock, chance) local randvalue = math.random(0, 100000) / (getConfigInfo("rateLoot") * chance) if randvalue < lootBlock.chance then if (ItemType(lootBlock.itemId):isStackable()) then return (randvalue%lootBlock.maxCount) + 1 else return 1 end end end local lootBlockList = self:getLoot() for _, loot in pairs(lootBlockList) do local rd = randomItem(loot, chance) if rd then if loot.uniquedrop then if unique then table.insert(ret, {loot, rd}) end else table.insert(ret, {loot, rd}) end end end return ret end BossLoot = {} BossUids = {} function BossLoot:new(boss) if not table.find(BossUids, boss:getId()) then table.insert(BossUids, boss:getId()) return setmetatable({creature=boss}, {__index = BossLoot}) end end function BossLoot:updateDamage() if self.creature then local tmp = {} local totaldmg = 0 for killer, damage in pairs(self.creature:getDamageMap()) do totaldmg = totaldmg+damage.total tmp[killer] = damage.total end self.players = sort_descending(tmp) self.totaldmg = totaldmg else error("Creature not found.") end end function BossLoot:setRewards() if self.totaldmg and self.creature then if getConfigInfo("rateLoot") > 0 then local mt = MonsterType(self.creature:getName()) for i, playertab in ipairs(self.players) do local loot if i == 1 then loot = mt:getBossReward(playertab[2] / self.totaldmg, true) else loot = mt:getBossReward(playertab[2] / self.totaldmg, false) end table.insert(self.players[i], loot) end end else error("Error") end end function BossLoot:addRewards() if self.players and self.players[1] and self.players[1][3] then for i, playertab in ipairs(self.players) do local player = Player(playertab[1]) if player then local str = "The following items are available in your reward chest: " for i, lootTable in ipairs(playertab[3]) do local item = player:addItemRewardBag(lootTable[1].itemId, math.ceil(lootTable[2])) if item then str = str .. item:getNameDescription() .. ", " end end str = str:sub(1, #str-2) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, str) end end else error("Error") end end function onKill(creature, target) if (Monster(target) ~= nil) then local mt = MonsterType(target:getName()) if mt:useRewardChest() then local loot = BossLoot:new(target) if loot then local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition())) corpse:decay() target:setDropLoot(false) loot:updateDamage() loot:setRewards() loot:addRewards() corpse:setAttribute('aid', 21584) end end end end COMO USAR !!Simplesmente adicione essa flag no monstro: <flag rewardchest="1" /> Você tambem pode fazer um drop ser unique, assim somente a pessoa que fez a maior parte do dano vai pegar esse item. <item id="5903" chance="100000" uniquedrop="1" /><!-- ferumbras' hat --> Foi você que fez esse sistema ou pegou na net? Eu consegui fazer funcionar no TFS 1.0 porem as vezes quando mata o boss e vai abrir o loot "reward" da debug e o servidor cai, as vezes nem da debug já cai direto assim quando mata o boss. Estou tentando resolver mais se alguém quiser ajudar por favor ajuda ai. Editado Dezembro 11, 2015 por GustavaoTibia Link para o comentário Compartilhar em outros sites More sharing options...
MatheusGlad 424 Postado Dezembro 11, 2015 Autor Share Postado Dezembro 11, 2015 (editado) Foi você que fez esse sistema ou pegou na net? Eu consegui fazer funcionar no TFS 1.0 porem as vezes quando mata o boss e vai abrir o loot "reward" da debug e o servidor cai, as vezes nem da debug já cai direto assim quando mata o boss. Estou tentando resolver mais se alguém quiser ajudar por favor ajuda ai. O que acontece quando voce abre o reward chest em vez do corpo do boss? Ve se crasha ou se da debug. Tenta mudar a function onKill no arquivo rewardloot.lua por: function onKill(creature, target) target = Monster(target) if (target ~= nil) then local mt = MonsterType(target:getName()) if mt:useRewardChest() then local loot = BossLoot:new(target) if loot then local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition())) corpse:decay() target:setDropLoot(false) loot:updateDamage() loot:setRewards() loot:addRewards() corpse:setAttribute('aid', 21584) end end end end Se continuar crashando, não posso te ajudar porque eu fiz o sistema para TFS 1.2. Editado Dezembro 11, 2015 por MatheusMkalo Link para o comentário Compartilhar em outros sites More sharing options...
GustavaoTibia 0 Postado Dezembro 11, 2015 Share Postado Dezembro 11, 2015 O que acontece quando voce abre o reward chest em vez do corpo do boss? Ve se crasha ou se da debug. Tenta mudar a function onKill no arquivo rewardloot.lua por: function onKill(creature, target) target = Monster(target) if (target ~= nil) then local mt = MonsterType(target:getName()) if mt:useRewardChest() then local loot = BossLoot:new(target) if loot then local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition())) corpse:decay() target:setDropLoot(false) loot:updateDamage() loot:setRewards() loot:addRewards() corpse:setAttribute('aid', 21584) end end end end Se continuar crashando, não posso te ajudar porque eu fiz o sistema para TFS 1.2. Ja tenho esse onkill. Tanto faz eu abrir o loot ou o reward chest tem vez que debuga e as vezes nem debuga já cai direto ou quando matar o boss dar um "/save" se não cair é porque da pra abrir normal o loot ou o reward chest agora se der um "/save" e cair o server é porque ta dando debug na hora de abrir o loot ou reward chest. Mesmo dando debug da pra entrar no jogo, ou seja, quando debugar o cliente eu vou la e entro de novo o char continua on só não vou poder abrir o loot ou o reward porque vai debugar de novo logico, mais dai quando o server for salvar tanto no save normal ou no "/save" vai cair :\ Link para o comentário Compartilhar em outros sites More sharing options...
Taiger 286 Postado Janeiro 5, 2016 Share Postado Janeiro 5, 2016 Ja tenho esse onkill. Tanto faz eu abrir o loot ou o reward chest tem vez que debuga e as vezes nem debuga já cai direto ou quando matar o boss dar um "/save" se não cair é porque da pra abrir normal o loot ou o reward chest agora se der um "/save" e cair o server é porque ta dando debug na hora de abrir o loot ou reward chest. Mesmo dando debug da pra entrar no jogo, ou seja, quando debugar o cliente eu vou la e entro de novo o char continua on só não vou poder abrir o loot ou o reward porque vai debugar de novo logico, mais dai quando o server for salvar tanto no save normal ou no "/save" vai cair :\ Ta usando qual versao do TFS? Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados