damian00912
Member
- Joined
- Sep 11, 2009
- Messages
- 90
- Reaction score
- 6
Hallo, i have problem, sometime, not every time, but sometime show me this error in logs. Someone know why?
script:
One more problem is with extra loot, also ont every drop only sometime show me this in log.
here is code:
And last problem is with potions, also only one time on maybe 1k use show this error
Script potions:
Thanks for help!
Lua:
Lua Script Error: [Main Interface]
(Unknown scriptfile)
...ata/scripts/creaturescripts/others/boss_reward_chest.lua:21: attempt to call global 'serializeAttributes' (a nil value)
stack traceback:
[C]: in function 'serializeAttributes'
...ata/scripts/creaturescripts/others/boss_reward_chest.lua:21: in function 'insertItems'
...ata/scripts/creaturescripts/others/boss_reward_chest.lua:73: in function <...ata/scripts/creaturescripts/others/boss_reward_chest.lua:42>
script:
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 item ~= nil then
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.escapeString(serializeAttributes(item)))
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
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
local function resetAndSetTargetList(creature)
if not creature then
return
end
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
local bossDeath = CreatureEvent("BossDeath")
function bossDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
-- player
if not creature or creature:isPlayer() then
return true
end
-- Deny summons
if creature:getMaster() then
return true
end
-- boss
local monsterType = creature:getType()
if monsterType and monsterType:isRewardBoss() then -- Make sure it is a boss
local bossId = creature:getId()
local timestamp = os.time()
resetAndSetTargetList(creature)
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 get 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 and con.score ~= 0 then
local lootMessage = ("The following items dropped by %s are available in your reward chest: %s"):format(creature:getName(), reward:getContentDescription())
if stamina > 840 then
reward:getContentDescription(lootMessage)
end
con.player:sendTextMessage(MESSAGE_LOOT, lootMessage)
elseif con.score ~= 0 then
insertRewardItems(con.guid, timestamp, playerLoot)
end
end
globalBosses[bossId] = nil
end
return true
end
bossDeath:register()
local bossThink = CreatureEvent("BossThink")
function bossThink.onThink(creature, interval)
resetAndSetTargetList(creature)
end
bossThink:register()
local bossParticipation = CreatureEvent("BossParticipation")
function bossParticipation.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
bossParticipation:register()
local loginBossPlayer = CreatureEvent("LoginBossPlayer")
function loginBossPlayer.onLogin(player)
player:registerEvent("BossDeath")
return true
end
loginBossPlayer:register()
One more problem is with extra loot, also ont every drop only sometime show me this in log.
Lua:
Lua Script Error: [Scripts Interface]
/home/abcd/data/scripts/creaturescripts/others/extraloot.lua:callback
...data/scripts/creaturescripts/others/extraloot.lua:49: attempt to call method 'getType' (a nil value)
stack traceback:
[C]: in function 'getType'
...data/scripts/creaturescripts/others/extraloot.lua:49: in function <...data/scripts/creaturescripts/others/extraloot.lua:39>
here is code:
Lua:
math.randomseed(os.time())
local extra_loot = {
{items = {
{id = 40407, chance = 6000}
}}
}
local extra_loot_d = CreatureEvent("extra_loot_d")
function Container:addExtraLoot(c, t)
if t.hasName then
local cn = c:getName():lower()
local cm = t.hasName:lower()
if not cn:match(cm) then
return true
end
end
for i = 1, #t.items do
local count = 1
if t.items[i].count then
if t.items[i].countMax then
count = math.random(t.items[i].count, t.items[i].countMax)
else
count = t.items[i].count
end
else
if t.items[i].countMax then
count = math.random(1, t.items[i].countMax)
end
end
if math.random(0, 100000) <= t.items[i].chance then
self:addItem(t.items[i].id, count)
end
end
end
function extra_loot_d.onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
if not creature:isMonster() then
return true
end
if creature:getMaster() then
return true
end
if corpse then
local itemType = corpse:getType()
if itemType:isCorpse() and itemType:isContainer() then
for i = 1, #extra_loot do
corpse:addExtraLoot(creature, extra_loot[i])
end
end
return true
end
end
extra_loot_d:register()
And last problem is with potions, also only one time on maybe 1k use show this error
Code:
Lua Script Error: [Scripts Interface]
/home/otxnowy/data/scripts/actions/other/potions.lua:callback
luaDoTargetCombatMana(). Creature not found
stack traceback:
[C]: in function 'doTargetCombatMana'
/home/otxnowy/data/scripts/actions/other/potions.lua:255: in function </home/otxnowy/data/scripts/actions/other/potions.lua:224>
Lua Script Error: [Scripts Interface]
/home/otxnowy/data/scripts/actions/other/potions.lua:callback
/home/otxnowy/data/scripts/actions/other/potions.lua:263: attempt to call method 'say' (a nil value)
stack traceback:
[C]: in function 'say'
/home/otxnowy/data/scripts/actions/other/potions.lua:263: in function </home/otxnowy/data/scripts/actions/other/potions.lua:224>
Script potions:
Lua:
local berserk = Condition(CONDITION_ATTRIBUTES)
berserk:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000)
berserk:setParameter(CONDITION_PARAM_SKILL_MELEE, 5)
berserk:setParameter(CONDITION_PARAM_SKILL_SHIELD, -10)
berserk:setParameter(CONDITION_PARAM_BUFF_SPELL, true)
local mastermind = Condition(CONDITION_ATTRIBUTES)
mastermind:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000)
mastermind:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, 3)
mastermind:setParameter(CONDITION_PARAM_BUFF_SPELL, true)
local bullseye = Condition(CONDITION_ATTRIBUTES)
bullseye:setParameter(CONDITION_PARAM_TICKS, 10 * 60 * 1000)
bullseye:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 5)
bullseye:setParameter(CONDITION_PARAM_SKILL_SHIELD, -10)
bullseye:setParameter(CONDITION_PARAM_BUFF_SPELL, true)
local antidote = Combat()
antidote:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
antidote:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
antidote:setParameter(COMBAT_PARAM_DISPEL, CONDITION_POISON)
antidote:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
antidote:setParameter(COMBAT_PARAM_TARGETCASTERORTOPMOST, true)
local exhaust = Condition(CONDITION_EXHAUST_HEAL)
exhaust:setParameter(CONDITION_PARAM_TICKS, (configManager.getNumber(configKeys.EX_ACTIONS_DELAY_INTERVAL) - 1000))
-- 1000 - 100 due to exact condition timing. -100 doesn't hurt us, and players don't have reminding ~50ms exhaustion.
local function magicshield(player)
local condition = Condition(CONDITION_MANASHIELD)
condition:setParameter(CONDITION_PARAM_TICKS, 60000)
condition:setParameter(CONDITION_PARAM_MANASHIELD, math.min(player:getMaxMana(), 300 + 7.6 * player:getLevel() + 7 * player:getMagicLevel()))
player:addCondition(condition)
end
local potions = {
[6558] = {
transform = {
id = {7588, 7589}
},
effect = CONST_ME_DRAWBLOOD
},
[7439] = {
vocations = {
VOCATION.CLIENT_ID.KNIGHT
},
condition = berserk,
effect = CONST_ME_MAGIC_RED,
description = "Only knights may drink this potion.",
text = "You feel stronger."
},
[7440] = {
vocations = {
VOCATION.CLIENT_ID.SORCERER,
VOCATION.CLIENT_ID.DRUID
},
condition = mastermind,
effect = CONST_ME_MAGIC_BLUE,
description = "Only sorcerers and druids may drink this potion.",
text = "You feel smarter."
},
[7443] = {
vocations = {
VOCATION.CLIENT_ID.PALADIN
},
condition = bullseye,
effect = CONST_ME_MAGIC_GREEN,
description = "Only paladins may drink this potion.",
text = "You feel more accurate."
},
[40398] = {
vocations = {
VOCATION.CLIENT_ID.SORCERER,
VOCATION.CLIENT_ID.DRUID
},
level = 14,
func = magicshield,
effect = CONST_ME_ENERGYAREA,
description = "Only sorcerers and druids of level 14 or above may drink this potion.",
},
[7588] = {
health = {
250,
350
},
vocations = {
VOCATION.CLIENT_ID.PALADIN,
VOCATION.CLIENT_ID.KNIGHT
},
level = 50,
flask = 7634,
description = "Only knights and paladins of level 50 or above may drink this fluid."
},
[7589] = {
mana = {
115,
185
},
level = 50,
flask = 7634,
description = "Only players of level 50 or above may drink this fluid."
},
[7590] = {
mana = {
150,
250
},
vocations = {
VOCATION.CLIENT_ID.SORCERER,
VOCATION.CLIENT_ID.DRUID,
VOCATION.CLIENT_ID.PALADIN
},
level = 80,
flask = 7635,
description = "Only sorcerers, druids and paladins of level 80 or above may drink this fluid."
},
[7591] = {
health = {
425,
575
},
vocations = {
VOCATION.CLIENT_ID.KNIGHT
},
level = 80,
flask = 7635,
description = "Only knights of level 80 or above may drink this fluid."
},
[7618] = {
health = {
125,
175
},
flask = 7636
},
[7620] = {
mana = {
75,
125
},
flask = 7636
},
[8472] = {
health = {
250,
350
},
mana = {
100,
200
},
vocations = {
VOCATION.CLIENT_ID.PALADIN
},
level = 80,
flask = 7635,
description = "Only paladins of level 80 or above may drink this fluid."
},
[8473] = {
health = {650, 850},
vocations = {
VOCATION.CLIENT_ID.KNIGHT
},
level = 130,
flask = 7635,
description = "Only knights of level 130 or above may drink this fluid."
},
[8474] = {
combat = antidote,
flask = 7636
},
[8704] = {
health = {
60,
90
},
flask = 7636
},
[26029] = {
mana = {
425,
575
},
vocations = {
VOCATION.CLIENT_ID.SORCERER,
VOCATION.CLIENT_ID.DRUID
},
level = 130,
flask = 7635,
description = "Only druids and sorcerers of level 130 or above may drink this fluid."
},
[26030] = {
health = {
420,
580
},
mana = {
250,
350
},
vocations = {
VOCATION.CLIENT_ID.PALADIN
},
level = 130,
flask = 7635,
description = "Only paladins of level 130 or above may drink this fluid."
},
[26031] = {
health = {
875,
1125
},
vocations = {
VOCATION.CLIENT_ID.KNIGHT
},
level = 200,
flask = 7635,
description = "Only knights of level 200 or above may drink this fluid."
}
}
local flaskPotion = Action()
function flaskPotion.onUse(player, item, fromPosition, target, toPosition, isHotkey)
if type(target) == "userdata" and not target:isPlayer() then
return false
end
-- Delay potion
if not playerDelayPotion[player:getId()] then
playerDelayPotion[player:getId()] = 0
end
if playerDelayPotion[player:getId()] > os.mtime() then
player:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_YOUAREEXHAUSTED))
return true
end
local potion = potions[item:getId()]
if potion.level and player:getLevel() < potion.level or potion.vocations and not table.contains(potion.vocations, player:getVocation():getClientId()) and not (player:getGroup():getId() >= 2) then
player:say(potion.description, MESSAGE_POTION)
return true
end
if player:getCondition(CONDITION_EXHAUST_HEAL) then
player:sendTextMessage(MESSAGE_FAILURE, Game.getReturnMessage(RETURNVALUE_YOUAREEXHAUSTED))
return true
end
if potion.health or potion.mana or potion.combat then
if potion.health then
doTargetCombatHealth(0, target, COMBAT_HEALING, potion.health[1], potion.health[2], CONST_ME_MAGIC_BLUE)
end
if potion.mana then
doTargetCombatMana(0, target, potion.mana[1], potion.mana[2], CONST_ME_MAGIC_BLUE)
end
if potion.combat then
potion.combat:execute(target, Variant(target:getId()))
end
player:addAchievementProgress('Potion Addict', 100000)
target:say("Aaaah...", MESSAGE_POTION)
player:addCondition(exhaust)
player:setStorageValue(38412, player:getStorageValue(38412)+1)
end
-- Delay potion
playerDelayPotion[player:getId()] = os.mtime() + 500
if potion.func then
potion.func(player)
if potion.text then
player:say(potion.text, MESSAGE_POTION)
end
player:getPosition():sendMagicEffect(potion.effect)
end
if potion.condition then
player:addCondition(potion.condition)
player:say(potion.text, MESSAGE_POTION)
player:getPosition():sendMagicEffect(potion.effect)
end
if potion.transform then
if item:getCount() >= 1 then
item:remove(1)
player:addItem(potion.transform.id[math.random(#potion.transform.id)], 1)
item:getPosition():sendMagicEffect(potion.effect)
return true
end
end
if not configManager.getBoolean(configKeys.REMOVE_POTION_CHARGES) then
return true
end
player:updateSupplyTracker(item)
item:remove(1)
return true
end
for index, value in pairs(potions) do
flaskPotion:id(index)
end
flaskPotion:register()