royal kaito
New Member
- Joined
- Aug 15, 2011
- Messages
- 17
- Reaction score
- 2
Hi, im having problems with the Script that Gives the Reward Loot from bosses
like the "White Pale" or "The Pale count" , every boss give's me every item from his Loot list
i change the "Chance value" to 100 in some items and its still dropping it in the Reward container.
Im Using TFS 1.2
Ot vercion 10.96
here's some pics from my ot
here is the scripts
creaturescripts/scripts/others/Boss.lua
creaturescripts/scripts/others/Rewardloot
If I'm missing something just tell me, I'm not sure if the problem comes from that 2 scripts
Thanks in advance for any help you are able to provide.
bump
like the "White Pale" or "The Pale count" , every boss give's me every item from his Loot list
i change the "Chance value" to 100 in some items and its still dropping it in the Reward container.
Im Using TFS 1.2
Ot vercion 10.96
here's some pics from my ot
here is the scripts
creaturescripts/scripts/others/Boss.lua
Lua:
function onCreatureAppear(self, creature)
if self == creature then
if self:getType():isRewardBoss() then
self:setReward(true)
end
end
end
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 _, item in ipairs(itemList) do
bag:addItem(item[1], item[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
creaturescripts/scripts/others/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
If I'm missing something just tell me, I'm not sure if the problem comes from that 2 scripts
Thanks in advance for any help you are able to provide.
bump
Last edited: