zerghel
Tsuni
- Joined
- Jul 1, 2008
- Messages
- 299
- Reaction score
- 9
Hello dear otlanders
i was wondering if someone can give me a hand on this error in console
here's my player.lua
and droploot.lua
plus blessings.lua
distro is OTX 3.10
i was wondering if someone can give me a hand on this error in console
Lua:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/others/droploot.lua:onDeath
data/lib/core/player.lua:162: attempt to call method 'hasFlag' (a nil value)
stack traceback:
[C]: in function 'hasFlag'
data/lib/core/player.lua:162: in function 'hasFlag'
data/creaturescripts/scripts/others/droploot.lua:3: in function <data/creaturescripts/scripts/others/droploot.lua:2>
here's my player.lua
Code:
function Player.allowMovement(self, allow)
return self:setStorageValue(STORAGE.blockMovementStorage, allow and -1 or 1)
end
function Player.checkGnomeRank(self)
local points = self:getStorageValue(Storage.BigfootBurden.Rank)
local questProgress = self:getStorageValue(Storage.BigfootBurden.QuestLine)
if points >= 30 and points < 120 then
if questProgress <= 25 then
self:setStorageValue(Storage.BigfootBurden.QuestLine, 26)
self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
self:addAchievement('Gnome Little Helper')
end
elseif points >= 120 and points < 480 then
if questProgress <= 26 then
self:setStorageValue(Storage.BigfootBurden.QuestLine, 27)
self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
self:addAchievement('Gnome Little Helper')
self:addAchievement('Gnome Friend')
end
elseif points >= 480 and points < 1440 then
if questProgress <= 27 then
self:setStorageValue(Storage.BigfootBurden.QuestLine, 28)
self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
self:addAchievement('Gnome Little Helper')
self:addAchievement('Gnome Friend')
self:addAchievement('Gnomelike')
end
elseif points >= 1440 then
if questProgress <= 29 then
self:setStorageValue(Storage.BigfootBurden.QuestLine, 30)
self:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
self:addAchievement('Gnome Little Helper')
self:addAchievement('Gnome Friend')
self:addAchievement('Gnomelike')
self:addAchievement('Honorary Gnome')
end
end
return true
end
function Player.addFamePoint(self)
local points = self:getStorageValue(SPIKE_FAME_POINTS)
local current = math.max(0, points)
self:setStorageValue(SPIKE_FAME_POINTS, current + 1)
self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have received a fame point.")
end
function Player.getFamePoints(self)
local points = self:getStorageValue(SPIKE_FAME_POINTS)
return math.max(0, points)
end
function Player.removeFamePoints(self, amount)
local points = self:getStorageValue(SPIKE_FAME_POINTS)
local current = math.max(0, points)
self:setStorageValue(SPIKE_FAME_POINTS, current - amount)
end
function Player.depositMoney(self, amount)
if not self:removeMoney(amount) then
return false
end
self:setBankBalance(self:getBankBalance() + amount)
return true
end
local foodCondition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
function Player.feed(self, food)
local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
if condition then
condition:setTicks(condition:getTicks() + (food * 1000))
else
local vocation = self:getVocation()
if not vocation then
return nil
end
foodCondition:setTicks(food * 1000)
foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN, vocation:getHealthGainAmount())
foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS, vocation:getHealthGainTicks() * 1000)
foodCondition:setParameter(CONDITION_PARAM_MANAGAIN, vocation:getManaGainAmount())
foodCondition:setParameter(CONDITION_PARAM_MANATICKS, vocation:getManaGainTicks() * 1000)
self:addCondition(foodCondition)
end
return true
end
function Player.getBlessings(self)
local blessings = 0
for i = 1, 5 do
if self:hasBlessing(i) then
blessings = blessings + 1
end
end
return blessings
end
function Player.getClosestFreePosition(self, position, extended)
if self:getAccountType() >= ACCOUNT_TYPE_GOD then
return position
end
return Creature.getClosestFreePosition(self, position, extended)
end
function Player.getCookiesDelivered(self)
local storage, amount = {
STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.SIMONTHEBEGGAR, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.MARKWIN, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.ARIELLA,
STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.HAIRYCLES, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.DJINN, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.AVARTAR,
STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.ORCKING, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.LORBAS, STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.WYDA,
STORAGE.WHATAFOOLISHQUEST.COOKIEDELIVERY.HJAERN
}, 0
for i = 1, #storage do
if self:getStorageValue(storage[i]) == 1 then
amount = amount + 1
end
end
return amount
end
function Player.getDepotItems(self, depotId)
return self:getDepotChest(depotId, true):getItemHoldingCount()
end
function Player.hasAllowMovement(self)
return self:getStorageValue(STORAGE.blockMovementStorage) ~= 1
end
function Player.hasRookgaardShield(self)
-- Wooden Shield, Studded Shield, Brass Shield, Plate Shield, Copper Shield
return self:getItemCount(2512) > 0
or self:getItemCount(2526) > 0
or self:getItemCount(2511) > 0
or self:getItemCount(2510) > 0
or self:getItemCount(2530) > 0
end
function Player.isDruid(self)
return isInArray({2, 6}, self:getVocation():getId())
end
function Player.isKnight(self)
return isInArray({4, 8}, self:getVocation():getId())
end
function Player.isPaladin(self)
return isInArray({3, 7}, self:getVocation():getId())
end
function Player.isMage(self)
return isInArray({1, 2, 5, 6}, self:getVocation():getId())
end
function Player.isSorcerer(self)
return isInArray({1, 5}, self:getVocation():getId())
end
function Player.hasFlag(self, flag)
return self:getGroup():hasFlag(flag)
end
function Player.isPremium(self)
return self:getPremiumDays() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM)
end
function Player.isPromoted(self)
local vocation = self:getVocation()
local promotedVocation = vocation:getPromotion()
promotedVocation = promotedVocation and promotedVocation:getId() or 0
return promotedVocation == 0 and vocation:getId() ~= promotedVocation
end
function Player.isUsingOtClient(self)
return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX
end
function Player.sendCancelMessage(self, message)
if type(message) == "number" then
message = Game.getReturnMessage(message)
end
return self:sendTextMessage(MESSAGE_STATUS_SMALL, message)
end
function Player.sendExtendedOpcode(self, opcode, buffer)
if not self:isUsingOtClient() then
return false
end
local networkMessage = NetworkMessage()
networkMessage:addByte(0x32)
networkMessage:addByte(opcode)
networkMessage:addString(buffer)
networkMessage:sendToPlayer(self)
networkMessage:delete()
return true
end
function Player.transferMoneyTo(self, target, amount)
local balance = self:getBankBalance()
if amount > balance then
return false
end
local targetPlayer = Player(target)
if targetPlayer then
targetPlayer:setBankBalance(targetPlayer:getBankBalance() + amount)
else
if not playerExists(target) then
return false
end
db.query("UPDATE `players` SET `balance` = `balance` + '" .. amount .. "' WHERE `name` = " .. db.escapeString(target))
end
self:setBankBalance(self:getBankBalance() - amount)
return true
end
function Player.withdrawMoney(self, amount)
local balance = self:getBankBalance()
if amount > balance or not self:addMoney(amount) then
return false
end
self:setBankBalance(balance - amount)
return true
end
APPLY_SKILL_MULTIPLIER = true
local addSkillTriesFunc = Player.addSkillTries
function Player.addSkillTries(...)
APPLY_SKILL_MULTIPLIER = false
local ret = addSkillTriesFunc(...)
APPLY_SKILL_MULTIPLIER = true
return ret
end
local addManaSpentFunc = Player.addManaSpent
function Player.addManaSpent(...)
APPLY_SKILL_MULTIPLIER = false
local ret = addManaSpentFunc(...)
APPLY_SKILL_MULTIPLIER = true
return ret
end
--jlcvp - impact analyser
function Player.sendHealingImpact(self, healAmmount)
local msg = NetworkMessage()
msg:addByte(0xCC) -- DEC: 204
msg:addByte(0) -- 0 = healing / 1 = damage (boolean)
msg:addU32(healAmmount) -- unsigned int
msg:sendToPlayer(self)
end
function Player.sendDamageImpact(self, damage)
local msg = NetworkMessage()
msg:addByte(0xCC) -- DEC: 204
msg:addByte(1) -- 0 = healing / 1 = damage (boolean)
msg:addU32(damage) -- unsigned int
msg:sendToPlayer(self)
end
-- Loot Analyser
function Player.sendLootStats(self, item)
local msg = NetworkMessage()
msg:addByte(0xCF) -- loot analyser bit
msg:addItem(item, self) -- item userdata
msg:addString(getItemName(item:getId()))
msg:sendToPlayer(self)
end
-- Supply Analyser
function Player.sendWaste(self, item)
local msg = NetworkMessage()
msg:addByte(0xCE) -- waste bit
msg:addItemId(item) -- itemId
msg:sendToPlayer(self)
end
Code:
dofile('data/modules/scripts/blessings/blessings.lua')
function onDeath(player, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
if player:hasFlag(PlayerFlag_NotGenerateLoot) then
return true
end
Blessings.DebugPrint("onDeath DROPLOOT EVENT DropLoot")
return Blessings.PlayerDeath(player, corpse, killer)
end
Code:
Blessings = {}
Blessings.Credits = {
Developer = "Charles (Cjaker), DudZ",
Version = "2.0",
lastUpdate = "08/04/2020",
todo = {
"Insert & Select query in blessings_history",
"Add unfair fight reductio (convert the get killer is pvp fight with getDamageMap of dead player)",
"Gamestore buy blessing",
"Test ank print text",
"Test all functions",
"Test henricus prices/blessings",
"Add data \\movements\\scripts\\quests\\cults of tibia\\icedeath.lua blessing information",
"WotE data\\movements\\scripts\\quests\\wrath of the emperor\\realmTeleport.lua has line checking if player has bless 1??? wtf",
"add blessings module support npc\\lib\\npcsystem\\modules.lua",
"Fix store buying bless",
"Check if store is inside lua or source..."
}
}
Blessings.Config = {
AdventurerBlessingLevel = 20, -- Free full bless until level
HasToF = false, -- Enables/disables twist of fate
InquisitonBlessPriceMultiplier = 1.1, -- Bless price multiplied by henricus
SkulledDeathLoseStoreItem = true, -- Destroy all items on store when dying with red/blackskull
InventoryGlowOnFiveBless = true, -- Glow in yellow inventory items when the player has 5 or more bless,
Debug = false -- Prin debug messages in console if enabled
}
dofile('data/modules/scripts/blessings/assets.lua')
--[=====[
--
-- Table structure `blessings_history`
--
CREATE TABLE IF NOT EXISTS `blessings_history` (
`id` int(11) NOT NULL,
`player_id` int(11) NOT NULL,
`blessing` tinyint(4) NOT NULL,
`loss` tinyint(1) NOT NULL,
`timestamp` int(11) NOT NULL,
CONSTRAINT `blessings_history_pk` PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--]=====]
Blessings.DebugPrint = function(content,pre,pos)
if not Blessings.Config.Debug then
return
end
if pre == nil then
pre = ""
else
pre = pre.. " "
end
if pos == nil then
pos = ""
else
pos = " " .. pos
end
if type(content) == "boolean" then
print("[Blessings] START BOOL - "..pre)
print(content)
print("[Blessings] END BOOL - "..pos)
else
print("[Blessings] "..pre .. content..pos)
end
end
Blessings.C_Packet = {
OpenWindow = 0xCF
}
Blessings.S_Packet = {
BlessDialog = 0x9B,
BlessStatus = 0x9C
}
function onRecvbyte(player, msg, byte)
if (byte == Blessings.C_Packet.OpenWindow) then
if (player:getClient().os ~= CLIENTOS_NEW_WINDOWS and player:getClient().os ~= CLIENTOS_FLASH) then
player:sendCancelMessage("Only work with Flash Client & 11.0")
return false
end
Blessings.sendBlessDialog(player)
end
end
Blessings.sendBlessStatus = function(player, curBless)
local msg = NetworkMessage()
msg:addByte(Blessings.S_Packet.BlessStatus)
callback = function(k) return true end
if curBless == nil then
curBless = player:getBlessings(callback) -- ex: {1, 2, 5, 7}
end
Blessings.DebugPrint(#curBless, "sendBlessStatus curBless")
if player:getClient().version >= 1120 then
local bitWiseCurrentBless = 0
local blessCount = 0
for i = 1, #curBless do
if curBless[i].losscount then
blessCount = blessCount + 1
end
if (not curBless[i].losscount and Blessings.Config.HasToF) or curBless[i].losscount then
bitWiseCurrentBless = bit.bor(bitWiseCurrentBless, Blessings.BitWiseTable[curBless[i].id])
end
end
if blessCount > 5 and Blessings.Config.InventoryGlowOnFiveBless then
bitWiseCurrentBless = bit.bor(bitWiseCurrentBless, 1)
end
msg:addU16(bitWiseCurrentBless)
dlgBtnColour = 1
if blessCount >= 7 then
dlgBtnColour = 3
elseif blessCount > 0 then
dlgBtnColour = 2
end
msg:addByte(dlgBtnColour) -- Bless dialog button colour 1 = Disabled | 2 = normal | 3 = green
elseif #curBless >= 5 then
msg:addU16(1) -- TODO ?
else
msg:addU16(0)
end
msg:sendToPlayer(player)
end
Blessings.sendBlessDialog = function(player)
local msg = NetworkMessage()
msg:addByte(Blessings.S_Packet.BlessDialog)
callback = function(k) return true end
local curBless = player:getBlessings()
msg:addByte(Blessings.Config.HasToF and #Blessings.All or (#Blessings.All - 1)) -- total blessings
for k = 1, #Blessings.All do
v = Blessings.All[k]
if v.type ~= Blessings.Types.PvP or Blessings.Config.HasToF then
msg:addU16(Blessings.BitWiseTable[v.id])
msg:addByte(player:getBlessingCount(v.id))
end
end
local promotion = (player:isPremium() and player:isPromoted()) and 30 or 0
local PvPminXPLoss = Blessings.LossPercent[#curBless].skill + promotion
local PvPmaxXPLoss = PvPminXPLoss
if Blessings.Config.HasToF then
PvPmaxXPLoss = math.floor(PvPminXPLoss * 1.15)
end
local PvEXPLoss = PvPminXPLoss
local playerAmulet = player:getSlotItem(CONST_SLOT_NECKLACE)
local haveSkull = player:getSkull() >= 4
hasAol = (playerAmulet and playerAmulet:getId() == ITEM_AMULETOFLOSS)
equipLoss = Blessings.LossPercent[#curBless].item
if haveSkull then
equipLoss = 100
elseif hasAol then
equipLoss = 0
end
msg:addByte(2) -- BYTE PREMIUM (only work with premium days)
msg:addByte(promotion) -- XP Loss Lower POR SER PREMIUM
msg:addByte(PvPminXPLoss) -- XP/Skill loss min pvp death
msg:addByte(PvPmaxXPLoss) -- XP/Skill loss max pvp death
msg:addByte(PvEXPLoss) -- XP/Skill pve death
msg:addByte(equipLoss) -- Equip container lose pvp death
msg:addByte(equipLoss) -- Equip container pve death
msg:addByte(haveSkull and 1 or 0) -- is red/black skull
msg:addByte(hasAol and 1 or 0)
-- History
local historyAmount = 1
msg:addByte(historyAmount) -- History log count
for i = 1, historyAmount do
msg:addU32(os.time()) -- timestamp
msg:addByte(0) -- Color message (1 - Red | 0 = White loss)
msg:addString("Blessing Purchased") -- History message
end
msg:sendToPlayer(player)
end
Blessings.getBlessingsCost = function(level)
if level <= 30 then
return 2000
elseif level >= 120 then
return 20000
else
return (level - 20) * 200
end
end
Blessings.getPvpBlessingCost = function(level)
if level <= 30 then
return 2000
elseif level >= 270 then
return 50000
else
return (level - 20) * 200
end
end
Blessings.useCharm = function(player, item)
local useItem = Blessings.Charms[item.itemid]
if not useItem then
return true
end
if player:hasBlessing(useItem.blessId) then
player:say('You already possess this blessing.', TALKTYPE_MONSTER_SAY)
return true
end
player:addBlessing(useItem.blessId, 1)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, useItem.text .. ' protects you.')
player:getPosition():sendMagicEffect(CONST_ME_LOSEENERGY)
item:remove(1)
return true
end
Blessings.checkBless = function(player)
local result, bless = 'Received blessings:'
for k, v in pairs(Blessings.All) do
result = player:hasBlessing(k) and result .. '\\n' .. v.name or result
end
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 20 > result:len() and 'No blessings received.' or result)
return true
end
Blessings.doAdventurerBlessing = function(player)
if player:getLevel() > Blessings.Config.AdventurerBlessingLevel then
return true
end
player:addMissingBless(true, true)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE,'You received adventurers blessings for you being level lower than ' .. Blessings.Config.AdventurerBlessingLevel .. '!')
player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE)
return true
end
Blessings.getInquisitionPrice = function(player)
-- Find how many missing bless we have and give out the price
inquifilter = function(b) return b.inquisition end
donthavefilter = function(p, b) return not p:hasBlessing(b) end
local missing = #player:getBlessings(filter, donthavefilter)
local totalBlessPrice = Blessings.getBlessingsCost(player:getLevel()) * missing * Blessings.Config.InquisitonBlessPriceMultiplier
return missing, totalBlessPrice
end
Blessings.DropLoot = function(player, corpse, chance, skulled)
local multiplier = 100 -- Improve the loot randomness spectrum
math.randomseed(os.time()) -- Improve the loot randomness spectrum
chance = chance * multiplier
Blessings.DebugPrint(chance, "DropLoot chance")
for i = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
local item = player:getSlotItem(i)
if item then
local thisChance = chance
local thisRandom = math.random(100*multiplier)
if not item:isContainer() then
thisChance = chance/10
end
Blessings.DebugPrint(thisChance/multiplier .. "%" .. " | thisRandom "..thisRandom/multiplier.."%", "DropLoot item "..item:getName() .. " |")
if skulled or thisRandom <= thisChance then
Blessings.DebugPrint("Dropped "..item:getName())
item:moveTo(corpse)
end
end
end
if skulled and Blessings.Config.SkulledDeathLoseStoreItem then
local inbox = self:getSlotItem(CONST_SLOT_STORE_INBOX)
local inboxsize = inbox:getSize() - 1
for i = 0, inboxsize do
inbox:getItem(i):destroy()
end
end
end
Blessings.ClearBless = function(player, killer, currentBless)
Blessings.DebugPrint(#currentBless, "ClearBless #currentBless")
local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or false
if hasToF and killer (killer:isPlayer() or (killer:getMaster() and killer:getMaster():isPlayer())) then -- TODO add better check if its pvp or pve
player:removeBlessing(1)
return
end
for i = 1, #currentBless do
Blessings.DebugPrint(i, "ClearBless curBless i", " | "..currentBless[i].name)
player:removeBlessing(currentBless[i].id, 1)
end
end
Blessings.BuyAllBlesses = function(player)
if not Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) and (player:isPzLocked() or player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT)) then
player:sendCancelMessage("You can't buy bless while in battle.")
player:getPosition():sendMagicEffect(CONST_ME_POFF)
return
end
local blessCost = Blessings.getBlessingsCost(player:getLevel())
local PvPBlessCost = Blessings.getPvpBlessingCost(player:getLevel())
local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or true
donthavefilter = function(p, b) return not p:hasBlessing(b) end
local missingBless = player:getBlessings(nil,donthavefilter)
local missingBlessAmt = #missingBless + (hasToF and 0 or 1)
local totalCost = blessCost * #missingBless
if missingBlessAmt == 0 then
player:sendCancelMessage("You are already blessed.")
player:getPosition():sendMagicEffect(CONST_ME_POFF)
return
end
if not hasToF then
totalCost = totalCost + PvPBlessCost
end
if player:removeMoneyNpc(totalCost) then
for i, v in ipairs(missingBless) do
player:addBlessing(v.id, 1)
end
player:sendCancelMessage("You received the remaining " .. missingBlessAmt .. " blesses for a total of " .. totalCost .." gold.")
player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
else
player:sendCancelMessage("You don't have enough money. You need " .. totalCost .. " to buy all blesses.", cid)
player:getPosition():sendMagicEffect(CONST_ME_POFF)
end
end
Blessings.PlayerDeath = function(player, corpse, killer)
local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or false
local hasAol = (player:getSlotItem(CONST_SLOT_NECKLACE) and player:getSlotItem(CONST_SLOT_NECKLACE):getId() == ITEM_AMULETOFLOSS)
local haveSkull = isInArray({SKULL_RED, SKULL_BLACK}, player:getSkull())
local curBless = player:getBlessings()
if haveSkull then -- lose all bless + drop all items
Blessings.DropLoot(player, corpse, 100, true)
elseif #curBless < 5 and not hasAol then -- lose all items
local equipLoss = Blessings.LossPercent[#curBless].item
Blessings.DropLoot(player, corpse, equipLoss)
elseif #curBless < 5 and hasAol and not hasToF then
player:removeItem(ITEM_AMULETOFLOSS, 1, -1, false)
end
--Blessings.ClearBless(player, killer, curBless) IMPLEMENTED IN SOURCE BECAUSE THIS WAS HAPPENING BEFORE SKILL/EXP CALCULATIONS
if not player:getSlotItem(CONST_SLOT_BACKPACK) then
player:addItem(ITEM_BAG, 1, false, CONST_SLOT_BACKPACK)
end
return true
end
function Player.getBlessings(self, filter, hasblessingFilter)
local blessings = {}
if filter == nil then
filter = function(b) return b.losscount end
end
if hasblessingFilter == nil then
hasblessingFilter = function(p, b) return p:hasBlessing(b) end
end
for k, v in pairs(Blessings.All) do
if filter(v) and hasblessingFilter(self, k) then
table.insert(blessings, v)
end
end
return blessings
end
function Player.addMissingBless(self, all, tof)
if all == nil then
all = true
end
if tof == nil then
tof = false
elseif tof then
tof = tof and Blessings.Config.HasToF
end
for k, v in pairs(Blessings.All) do
if all or (v.type == Blessings.Types.REGULAR) or (tof and v.type == Blessings.Types.PvP) then
if not self:hasBlessing(k) then
self:addBlessing(k, 1)
end
end
end
Blessings.sendBlessStatus(self)
end