Postado Fevereiro 19, 2018 7 anos Base: TFS 1.2 - OTX 3.0 Qual erro está surgindo/O que você procura? O sistema de reward system está funcionando, porém somente quem da mais dano no monster leva o loot os outros recebem: nothing Você tem o código disponível? Se tiver publique-o aqui: script base.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, 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 script boss.lua: local function pushSeparated(buffer, sep, ...) local argv = {...} local argc = #argv for k, v in ipairs(argv) do table.insert(buffer, v) if k < argc and sep then table.insert(buffer, sep) end end end local function insertItems(buffer, info, parent, items) local start = info.running for _, item in ipairs(items) do if _ ~= 1 or parent > 100 then table.insert(buffer, ",") end info.running = info.running + 1 table.insert(buffer, "(") pushSeparated(buffer, ",", info.playerGuid, parent, info.running, item:getId(), item:getSubType(), db.escapeBlob(item:serializeAttributes())) table.insert(buffer, ")") if item:isContainer() then local size = item:getSize() if size > 0 then local subItems = {} for i = 1, size do table.insert(subItems, item:getItem(i - 1)) end insertItems(buffer, info, info.running, subItems) end end end return info.running - start end local function insertRewardItems(playerGuid, timestamp, itemList) db.asyncStoreQuery('SELECT `pid`, `sid` FROM `player_rewards` WHERE player_id = ' .. playerGuid .. ' ORDER BY `sid` ASC;', function(query) local lastReward = 0 local lastStoreId if(query) then repeat local sid = result.getDataInt(query, 'sid') local pid = result.getDataInt(query, 'pid') if pid < 100 then lastReward = pid end lastStoreId = sid until not result.next(query) end local buffer = {'INSERT INTO `player_rewards` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES'} --reward bag local info = { playerGuid = playerGuid, running = lastStoreId or 100 } local bag = Game.createItem(ITEM_REWARD_CONTAINER) bag:setAttribute(ITEM_ATTRIBUTE_DATE, timestamp) if itemList then for _, p in ipairs(itemList) do bag:addItem(p[1], p[2]) end end local total = insertItems(buffer, info, lastReward + 1, {bag}) table.insert(buffer, ";") if total ~= 0 then db.query(table.concat(buffer)) end end ) end local function getPlayerStats(bossId, playerGuid, autocreate) local ret = globalBosses[bossId][playerGuid] if not ret and autocreate then ret = { bossId = bossId, damageIn = 0, -- damage taken from the boss healing = 0, -- healing (other players) done } globalBosses[bossId][playerGuid] = ret return ret end return ret end function onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified) local monsterType = creature:getType() if monsterType:isRewardBoss() then -- Make sure it is a boss local bossId = creature:getId() local timestamp = os.time() local totalDamageOut, totalDamageIn, totalHealing = 0.1, 0.1, 0.1 -- avoid dividing by zero local scores = {} local info = globalBosses[bossId] local damageMap = creature:getDamageMap() for guid, stats in pairs(info) do local player = Player(stats.playerId) local part = damageMap[stats.playerId] local damageOut, damageIn, healing = (stats.damageOut or 0) + (part and part.total or 0), stats.damageIn or 0, stats.healing or 0 totalDamageOut = totalDamageOut + damageOut totalDamageIn = totalDamageIn + damageIn totalHealing = totalHealing + healing table.insert(scores, { player = player, guid = guid, damageOut = damageOut, damageIn = damageIn, healing = healing, }) end local participants = 0 for _, con in ipairs(scores) do local score = (con.damageOut / totalDamageOut) + (con.damageIn / totalDamageIn) + (con.healing / totalHealing) con.score = score / 3 -- normalize to 0-1 if score ~= 0 then participants = participants + 1 end end table.sort(scores, function(a, b) return a.score > b.score end) local expectedScore = 1 / participants for _, con in ipairs(scores) do local reward, stamina -- ignoring stamina for now because I heard you receive rewards even when it's depleted if con.player then reward = con.player:getReward(timestamp, true) stamina = con.player:getStamina() else stamina = con.stamina or 0 end local playerLoot if --[[stamina > 840 and]] con.score ~= 0 then local lootFactor = 1 lootFactor = lootFactor / participants ^ (1 / 3) -- tone down the loot a notch if there are many participants lootFactor = lootFactor * (1 + lootFactor) ^ (con.score / expectedScore) -- increase the loot multiplicatively by how many times the player surpassed the expected score playerLoot = monsterType:getBossReward(lootFactor, _ == 1) if con.player then for _, p in ipairs(playerLoot) do reward:addItem(p[1], p[2]) end end end if con.player then local lootMessage = {"The following items are available in your reward chest: "} if --[[stamina > 840]]true then reward:getContentDescription(lootMessage) else table.insert(lootMessage, 'nothing (due to low stamina)') end table.insert(lootMessage, ".") con.player:sendTextMessage(MESSAGE_EVENT_ADVANCE, table.concat(lootMessage)) else insertRewardItems(con.guid, timestamp, playerLoot) end end globalBosses[bossId] = nil end return true end function onThink(creature, interval) local bossId = creature:getId() local info = globalBosses[bossId] -- Reset all players' status for _, player in pairs(info) do player.active = false end -- Set all players in boss' target list as active in the fight local targets = creature:getTargetList() for _, target in ipairs(targets) do if target:isPlayer() then local stats = getPlayerStats(bossId, target:getGuid(), true) stats.playerId = target:getId() -- Update player id stats.active = true end end end function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) if not next(globalBosses) then return primaryDamage, primaryType, secondaryDamage, secondaryType end if not creature or not attacker then return primaryDamage, primaryType, secondaryDamage, secondaryType end local stats = creature:inBossFight() if not stats then return primaryDamage, primaryType, secondaryDamage, secondaryType end local creatureId, attackerId = creature:getId(), attacker:getId() stats.playerId = creatureId -- Update player id -- Account for healing of others active in the boss fight if primaryType == COMBAT_HEALING and attacker:isPlayer() and attackerId ~= creatureId then local healerStats = getPlayerStats(stats.bossId, attacker:getGuid(), true) healerStats.active = true healerStats.playerId = attackerId -- Update player id healerStats.healing = healerStats.healing + primaryDamage elseif stats.bossId == attackerId then -- Account for damage taken from the boss stats.damageIn = stats.damageIn + primaryDamage end return primaryDamage, primaryType, secondaryDamage, secondaryType end query da database: CREATE TABLE `player_rewards` ( `player_id` int(11) NOT NULL, `sid` int(11) NOT NULL, `pid` int(11) NOT NULL DEFAULT '0', `itemtype` smallint(6) NOT NULL, `count` smallint(5) NOT NULL DEFAULT '0', `attributes` blob NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Por favor me ajudem!! é para o meu server já arrumei inúmeros bugs, mas esse não to conseguindo arrumar. Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. up up alguém? Editado Fevereiro 19, 2018 7 anos por vine96 (veja o histórico de edições)
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.