0% found this document useful (0 votes)
13 views

f15213992

Uploaded by

l.feraboli95
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

f15213992

Uploaded by

l.feraboli95
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 18

CONTAINER_WEIGHT_CHECK = true -- true = enable / false = disable

CONTAINER_WEIGHT_MAX = 1000000 -- 1000000 = 10k = 10000.00 oz

local storeItemID = {
-- registered item ids here are not tradable with players
-- these items can be set to moveable at items.xml
-- 300000 charges exercise weapons
32384, -- exercise sword
32385, -- exercise axe
32386, -- exercise club
32387, -- exercise bow
32388, -- exercise rod
32389, -- exercise wand

-- 50 charges exercise weapons


32124, -- training sword
32125, -- training axe
32126, -- training club
32127, -- training bow
32128, -- training wand
32129, -- training club

-- magic gold and magic converter (activated/deactivated)


32109, -- magic gold converter
33299, -- magic gold converter
26378, -- gold converter
29020, -- gold converter

-- foods
35172, -- roasted wyvern wings
35173, -- carrot pie
35174, -- tropical marinated tiger
35175, -- delicatessen salad
35176, -- chilli con carniphila
35177, -- svargrond salmon filet
35178, -- carrion casserole
35179, -- consecrated beef
35180, -- overcooked noodles
}

-- Capacity imbuement store


local STORAGE_CAPACITY_IMBUEMENT = 42154

-- Players cannot throw items on teleports if set to true


local blockTeleportTrashing = true

local titles = {
{storageID = 14960, title = " Scout"},
{storageID = 14961, title = " Sentinel"},
{storageID = 14962, title = " Steward"},
{storageID = 14963, title = " Warden"},
{storageID = 14964, title = " Squire"},
{storageID = 14965, title = " Warrior"},
{storageID = 14966, title = " Keeper"},
{storageID = 14967, title = " Guardian"},
{storageID = 14968, title = " Sage"},
{storageID = 14969, title = " Tutor"},
{storageID = 14970, title = " Senior Tutor"},
{storageID = 14971, title = " King"},
}

local function getTitle(uid)


local player = Player(uid)
if not player then return false end

for i = #titles, 1, -1 do
if player:getStorageValue(titles[i].storageID) == 1 then
return titles[i].title
end
end

return false
end

function Player:onBrowseField(position)
return true
end

local function getHours(seconds)


return math.floor((seconds/60)/60)
end

local function getMinutes(seconds)


return math.floor(seconds/60)
end

local function getSeconds(seconds)


return seconds%60
end

local function getTime(seconds)


local hours, minutes = getHours(seconds), getMinutes(seconds)
if (minutes > 59) then
minutes = minutes-hours*60
end

if (minutes < 10) then


minutes = "0" ..minutes
end

return hours..":"..minutes.. "h"


end

local function getTimeinWords(secs)


local hours, minutes, seconds = getHours(secs), getMinutes(secs),
getSeconds(secs)
if (minutes > 59) then
minutes = minutes-hours*60
end

local timeStr = ''

if hours > 0 then


timeStr = timeStr .. ' hours '
end

timeStr = timeStr .. minutes .. ' minutes and '.. seconds .. ' seconds.'
return timeStr
end

function Player:onLook(thing, position, distance)


local description = "You see "
if thing:isItem() then
if thing.actionid == 5640 then
description = description .. "a honeyflower patch."
elseif thing.actionid == 5641 then
description = description .. "a banana palm."
elseif thing.itemid >= ITEM_HEALTH_CASK_START and thing.itemid <=
ITEM_HEALTH_CASK_END
or thing.itemid >= ITEM_MANA_CASK_START and thing.itemid <=
ITEM_MANA_CASK_END
or thing.itemid >= ITEM_SPIRIT_CASK_START and thing.itemid <=
ITEM_SPIRIT_CASK_END
or thing.itemid >= ITEM_KEG_START and thing.itemid <= ITEM_KEG_END then
description = description .. thing:getDescription(distance)
local charges = thing:getCharges()
if charges then
description = string.format("%s\nIt has %d refillings
left.", description, charges)
end
else
description = description .. thing:getDescription(distance)
end

local itemType = thing:getType()


if (itemType and itemType:getImbuingSlots() > 0) then
local imbuingSlots = "Imbuements: ("
for slot = 0, itemType:getImbuingSlots() - 1 do
if slot > 0 then
imbuingSlots = string.format("%s, ", imbuingSlots)
end
local duration = thing:getImbuementDuration(slot)
if duration > 0 then
local imbue = thing:getImbuement(slot)
imbuingSlots = string.format("%s%s %s %s",
imbuingSlots, imbue:getBase().name,
imbue:getName(), getTime(duration))
else
imbuingSlots = string.format("%sEmpty Slot",
imbuingSlots)
end
end
imbuingSlots = string.format("%s).", imbuingSlots)
description = string.gsub(description, "It weighs",
imbuingSlots.. "\nIt weighs")
end
else
description = description .. thing:getDescription(distance)
if thing:isMonster() then
local master = thing:getMaster()
if master and
table.contains({'thundergiant','grovebeast','emberwing','skullfrost'},
thing:getName():lower()) then
description = description..' (Master: ' .. master:getName()
.. '). \z
It will disappear in ' ..
getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time())
end
end
end

if self:getGroup():getAccess() then
if thing:isItem() then
description = string.format("%s\nItem ID: %d", description,
thing:getId())

local actionId = thing:getActionId()


if actionId ~= 0 then
description = string.format("%s, Action ID: %d",
description, actionId)
end

local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID)


if uniqueId > 0 and uniqueId < 65536 then
description = string.format("%s, Unique ID: %d",
description, uniqueId)
end

if thing:isContainer() then
local quickLootCategories = {}
local container = Container(thing.uid)
for categoryId = LOOT_START, LOOT_END do
if container ~= nil then
if container:hasQuickLootCategory(categoryId)
then
table.insert(quickLootCategories,
categoryId)
end
end
end

description = string.format("%s, QuickLootCategory: (%s)",


description, table.concat(quickLootCategories, ", "))
end

local itemType = thing:getType()

local transformEquipId = itemType:getTransformEquipId()


local transformDeEquipId = itemType:getTransformDeEquipId()
if transformEquipId ~= 0 then
description = string.format("%s\nTransforms to: %d
(onEquip)", description, transformEquipId)
elseif transformDeEquipId ~= 0 then
description = string.format("%s\nTransforms to: %d
(onDeEquip)", description, transformDeEquipId)
end

local decayId = itemType:getDecayId()


if decayId ~= -1 then
description = string.format("%s\nDecays to: %d",
description, decayId)
end

local clientId = itemType:getClientId()


if clientId then
description = string.format("%s\nClient ID: %d",
description, clientId)
end

elseif thing:isCreature() then


local str = "%s\nHealth: %d / %d"
if thing:isPlayer() and thing:getMaxMana() > 0 then
str = string.format("%s, Mana: %d / %d", str,
thing:getMana(), thing:getMaxMana())
end
description = string.format(str, description, thing:getHealth(),
thing:getMaxHealth()) .. "."
end

description = string.format(
"%s\nPosition: %d, %d, %d",
description, position.x, position.y, position.z
)

if thing:isCreature() then
if thing:isPlayer() then
description = string.format("%s\nIP: %s.", description,
Game.convertIpToString(thing:getIp()))
end
end
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInBattleList(creature, distance)


local description = "You see " .. creature:getDescription(distance)
if creature:isMonster() then
local master = creature:getMaster()
local summons = {'thundergiant','grovebeast','emberwing','skullfrost'}
if master and table.contains(summons, creature:getName():lower()) then
description = description..' (Master: ' .. master:getName() ..
'). \z
It will disappear in ' ..
getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time())
end
end
if self:getGroup():getAccess() then
local str = "%s\nHealth: %d / %d"
if creature:isPlayer() and creature:getMaxMana() > 0 then
str = string.format("%s, Mana: %d / %d", str, creature:getMana(),
creature:getMaxMana())
end
description = string.format(str, description, creature:getHealth(),
creature:getMaxHealth()) .. "."

local position = creature:getPosition()


description = string.format(
"%s\nPosition: %d, %d, %d",
description, position.x, position.y, position.z

if creature:isPlayer() then
description = string.format("%s\nIP: %s", description,
Game.convertIpToString(creature:getIp()))
end
end
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInTrade(partner, item, distance)


self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " ..
item:getDescription(distance))
end

function Player:onLookInShop(itemType, count)


return true
end

local config = {
maxItemsPerSeconds = 1,
exhaustTime = 2000,
}

if not pushDelay then


pushDelay = { }
end

local function antiPush(self, item, count, fromPosition, toPosition, fromCylinder,


toCylinder)
if toPosition.x == CONTAINER_POSITION then
return true
end

local tile = Tile(toPosition)


if not tile then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end

local cid = self:getId()


if not pushDelay[cid] then
pushDelay[cid] = {items = 0, time = 0}
end

pushDelay[cid].items = pushDelay[cid].items + 1

local currentTime = os.mtime()


if pushDelay[cid].time == 0 then
pushDelay[cid].time = currentTime
elseif pushDelay[cid].time == currentTime then
pushDelay[cid].items = pushDelay[cid].items + 1
elseif currentTime > pushDelay[cid].time then
pushDelay[cid].time = 0
pushDelay[cid].items = 0
end

if pushDelay[cid].items > config.maxItemsPerSeconds then


pushDelay[cid].time = currentTime + config.exhaustTime
end

if pushDelay[cid].time > currentTime then


self:sendCancelMessage("You can't move that item so fast.")
return false
end

return true
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder,


toCylinder)

-- No move items with actionID = 100


if item:getActionId() == NOT_MOVEABLE_ACTION then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end

-- No move if item count > 20 items


local tile = Tile(toPosition)
if tile and tile:getItemCount() > 20 then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end

-- No move parcel very heavy


if CONTAINER_WEIGHT_CHECK and ItemType(item:getId()):isContainer()
and item:getWeight() > CONTAINER_WEIGHT_MAX then
self:sendCancelMessage("Your cannot move this item too heavy.")
return false
end

-- Loot Analyser
local t = Tile(fromCylinder:getPosition())
local corpse = t:getTopDownItem()
if corpse then
local itemType = corpse:getType()
if itemType:isCorpse() and toPosition.x == CONTAINER_POSITION then
self:sendLootStats(item)
end
end

-- Cults of Tibia begin


local frompos = Position(33023, 31904, 14) -- Checagem
local topos = Position(33052, 31932, 15) -- Checagem
if self:getPosition():isInRange(frompos, topos) and item:getId() == 26397
then
local tileBoss = Tile(toPosition)
if tileBoss and tileBoss:getTopCreature() and
tileBoss:getTopCreature():isMonster() then
if tileBoss:getTopCreature():getName():lower() == 'the
remorseless corruptor' then
tileBoss:getTopCreature():addHealth(-17000)
item:remove(1)
if tileBoss:getTopCreature():getHealth() <= 300 then
tileBoss:getTopCreature():remove()
local monster = Game.createMonster('the corruptor of
souls', toPosition)
monster:registerEvent('CheckTile')
if Game.getStorageValue('healthSoul') > 0 then
monster:addHealth(-(monster:getHealth() -
Game.getStorageValue('healthSoul')))
end
Game.setStorageValue('CheckTile', os.time()+30)
end
elseif tileBoss:getTopCreature():getName():lower() == 'the
corruptor of souls' then
Game.setStorageValue('CheckTile', os.time()+30)
item:remove(1)
end
end
end
-- Cults of Tibia end

-- SSA exhaust
local exhaust = { }
if toPosition.x == CONTAINER_POSITION and toPosition.y == CONST_SLOT_NECKLACE
and item:getId() == ITEM_STONE_SKIN_AMULET then
local pid = self:getId()
if exhaust[pid] then
self:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED)
return false
else
exhaust[pid] = true
addEvent(function() exhaust[pid] = false end, 2000, pid)
return true
end
end

-- Store Inbox
local containerIdFrom = fromPosition.y - 64
local containerFrom = self:getContainerById(containerIdFrom)
if (containerFrom) then
if (containerFrom:getId() == ITEM_STORE_INBOX
and toPosition.y >= 1 and toPosition.y <= 11 and toPosition.y ~= 3)
then
self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)
return false
end
end

local containerTo = self:getContainerById(toPosition.y-64)


if (containerTo) then
if (containerTo:getId() == ITEM_STORE_INBOX) then
self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)
return false
end
-- Gold Pouch
if (containerTo:getId() == ITEM_GOLD_POUCH) then
if (not (item:getId() == ITEM_CRYSTAL_COIN or item:getId() ==
ITEM_PLATINUM_COIN
or item:getId() == ITEM_GOLD_COIN)) then
self:sendCancelMessage("You can move only money to this
container.")
return false
end
end
end

-- Bath tube
local toTile = Tile(toCylinder:getPosition())
local topDownItem = toTile:getTopDownItem()
if topDownItem and table.contains({ BATHTUB_EMPTY, BATHTUB_FILLED },
topDownItem:getId()) then
return false
end

-- Handle move items to the ground


if toPosition.x ~= CONTAINER_POSITION then
if item:isContainer() then
local container = Container(item.uid)
for categoryId = LOOT_START, LOOT_END do
if container:hasQuickLootCategory(categoryId) then
container:removeQuickLootCategory(categoryId)
self:setQuickLootBackpack(categoryId, nil)
end
end
end

return true
end

-- Check two-handed weapons


if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then
local itemType, moveItem = ItemType(item:getId())
if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and
toPosition.y == CONST_SLOT_LEFT then
moveItem = self:getSlotItem(CONST_SLOT_RIGHT)
elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y ==
CONST_SLOT_RIGHT then
moveItem = self:getSlotItem(CONST_SLOT_LEFT)
if moveItem and
bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then
return true
end
end

if moveItem then
local parent = item:getParent()
if parent:getSize() == parent:getCapacity() then
self:sendTextMessage(MESSAGE_STATUS_SMALL,
Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM))
return false
else
return moveItem:moveTo(parent)
end
end
end

-- Reward System
if toPosition.x == CONTAINER_POSITION then
local containerId = toPosition.y - 64
local container = self:getContainerById(containerId)
if not container then
return true
end

-- Do not let the player insert items into either the Reward Container
or the Reward Chest
local itemId = container:getId()
if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end

-- The player also shouldn't be able to insert items into the boss
corpse
local tileCorpse = Tile(container:getPosition())
for index, value in ipairs(tileCorpse:getItems() or { }) do
if value:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 and
value:getName() == container:getName() then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end
end
end

-- Do not let the player move the boss corpse.


if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
return false
end

-- Players cannot throw items on reward chest


local tileChest = Tile(toPosition)
if tileChest and tileChest:getItemById(ITEM_REWARD_CHEST) then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
self:getPosition():sendMagicEffect(CONST_ME_POFF)
return false
end

-- Players cannot throw items on teleports


if blockTeleportTrashing and toPosition.x ~= CONTAINER_POSITION then
local thing = Tile(toPosition):getItemByType(ITEM_TYPE_TELEPORT)
if thing then
self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
self:getPosition():sendMagicEffect(CONST_ME_POFF)
return false
end
end

if tile and tile:getItemById(370) then -- Trapdoor


self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
self:getPosition():sendMagicEffect(CONST_ME_POFF)
return false
end

if not antiPush(self, item, count, fromPosition, toPosition, fromCylinder,


toCylinder) then
return false
end

return true
end

function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder,


toCylinder)
end
function Player:onMoveCreature(creature, fromPosition, toPosition)
return true
end

local function hasPendingReport(name, targetName, reportType)


local f = io.open(string.format("data/reports/players/%s-%s-%d.txt", name,
targetName, reportType), "r")
if f then
io.close(f)
return true
else
return false
end
end

function Player:onReportRuleViolation(targetName, reportType, reportReason,


comment, translation)
local name = self:getName()
if hasPendingReport(name, targetName, reportType) then
self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your report is being
processed.")
return
end

local file = io.open(string.format("data/reports/players/%s-%s-%d.txt", name,


targetName, reportType), "a")
if not file then
self:sendTextMessage(MESSAGE_EVENT_ADVANCE,
"There was an error when processing your report, please contact a
gamemaster.")
return
end

io.output(file)
io.write("------------------------------\n")
io.write("Reported by: " .. name .. "\n")
io.write("Target: " .. targetName .. "\n")
io.write("Type: " .. reportType .. "\n")
io.write("Reason: " .. reportReason .. "\n")
io.write("Comment: " .. comment .. "\n")
if reportType ~= REPORT_TYPE_BOT then
io.write("Translation: " .. translation .. "\n")
end
io.write("------------------------------\n")
io.close(file)
self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Thank you for
reporting %s. Your report \z
will be processed by %s team as soon as possible.", targetName,
configManager.getString(configKeys.SERVER_NAME)))
return
end

function Player:onReportBug(message, position, category)


if self:getAccountType() == ACCOUNT_TYPE_NORMAL then
return false
end

local name = self:getName()


local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a")

if not file then


self:sendTextMessage(MESSAGE_EVENT_DEFAULT,
"There was an error when processing your report, please contact a
gamemaster.")
return true
end

io.output(file)
io.write("------------------------------\n")
io.write("Name: " .. name)
if category == BUG_CATEGORY_MAP then
io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", "
.. position.z .. "]")
end
local playerPosition = self:getPosition()
io.write(" [Player Position: " .. playerPosition.x .. ", " ..
playerPosition.y .. ", " .. playerPosition.z .. "]\n")
io.write("Comment: " .. message .. "\n")
io.close(file)

self:sendTextMessage(MESSAGE_EVENT_DEFAULT,
"Your report has been sent to " ..
configManager.getString(configKeys.SERVER_NAME) .. ".")
return true
end

function Player:onTurn(direction)
if self:getGroup():getAccess() and self:getDirection() == direction then
local nextPosition = self:getPosition()
nextPosition:getNextPosition(direction)

self:teleportTo(nextPosition, true)
end

return true
end

function Player:onTradeRequest(target, item)


-- No trade items with actionID = 100
if item:getActionId() == NOT_MOVEABLE_ACTION then
return false
end

if isInArray(storeItemID,item.itemid) then
return false
end
return true
end

function Player:onTradeAccept(target, item, targetItem)


self:closeImbuementWindow()
target:closeImbuementWindow()
return true
end

local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)


soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)

local function useStamina(player)


local staminaMinutes = player:getStamina()
if staminaMinutes == 0 then
return
end

local playerId = player:getId()


local currentTime = os.time()
local timePassed = currentTime - nextUseStaminaTime[playerId]
if timePassed <= 0 then
return
end

if timePassed > 60 then


if staminaMinutes > 2 then
staminaMinutes = staminaMinutes - 2
else
staminaMinutes = 0
end
nextUseStaminaTime[playerId] = currentTime + 120
else
staminaMinutes = staminaMinutes - 1
nextUseStaminaTime[playerId] = currentTime + 60
end
player:setStamina(staminaMinutes)
end

local function useStaminaXp(player)


local staminaMinutes = player:getExpBoostStamina() / 60
if staminaMinutes == 0 then
return
end

local playerId = player:getId()


local currentTime = os.time()
local timePassed = currentTime - nextUseXpStamina[playerId]
if timePassed <= 0 then
return
end

if timePassed > 60 then


if staminaMinutes > 2 then
staminaMinutes = staminaMinutes - 2
else
staminaMinutes = 0
end
nextUseXpStamina[playerId] = currentTime + 120
else
staminaMinutes = staminaMinutes - 1
nextUseXpStamina[playerId] = currentTime + 60
end
player:setExpBoostStamina(staminaMinutes * 60)
end

function Player:onGainExperience(source, exp, rawExp)


if not source or source:isPlayer() then
return exp
end

-- Soul regeneration
local vocation = self:getVocation()
if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
soulCondition:setParameter(CONDITION_PARAM_SOULTICKS,
vocation:getSoulGainTicks() * 1000)
self:addCondition(soulCondition)
end

-- Experience Stage Multiplier


local expStage = getRateFromTable(experienceStages, self:getLevel(),
configManager.getNumber(configKeys.RATE_EXP))
exp = exp * expStage
baseExp = rawExp * expStage
if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then
displayRate = expStage
else
displayRate = 1
end

-- Prey Bonus
for slot = CONST_PREY_SLOT_FIRST, CONST_PREY_SLOT_THIRD do
if (self:getPreyCurrentMonster(slot) == source:getName()
and self:getPreyBonusType(slot) == CONST_BONUS_XP_BONUS) then
exp = exp + math.floor(exp * (self:getPreyBonusValue(slot) /
100))
break
end
if (self:getPreyTimeLeft(slot) / 60) > 0 then
preyTimeLeft(self, slot) -- slot consumption, outside of the
mosnter check
end
end

-- Store Bonus
useStaminaXp(self) -- Use store boost stamina

local Boost = self:getExpBoostStamina()


local stillHasBoost = Boost > 0
local storeXpBoostAmount = stillHasBoost and self:getStoreXpBoost() or 0

self:setStoreXpBoost(storeXpBoostAmount)

if (storeXpBoostAmount > 0) then


exp = exp + (baseExp * (storeXpBoostAmount/100)) -- Exp Boost
end

-- Stamina Bonus
if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
useStamina(self)
local staminaMinutes = self:getStamina()
if staminaMinutes > 2400 and self:isPremium() then
exp = exp * 1.5
self:setStaminaXpBoost(150)
elseif staminaMinutes <= 840 then
exp = exp * 0.5 --TODO destroy loot of people with 840- stamina
self:setStaminaXpBoost(50)
else
self:setStaminaXpBoost(100)
end
end

self:setBaseXpGain(displayRate * 100)
return exp
end

function Player:onLoseExperience(exp)
return exp
end

function Player:onGainSkillTries(skill, tries)


if APPLY_SKILL_MULTIPLIER == false then
return tries
end

if skill == SKILL_MAGLEVEL then


return tries * configManager.getNumber(configKeys.RATE_MAGIC)
end
return tries * configManager.getNumber(configKeys.RATE_SKILL)
end

function Player:onRemoveCount(item)
self:sendWaste(item:getId())
end

function Player:onRequestQuestLog()
self:sendQuestLog()
end

function Player:onRequestQuestLine(questId)
self:sendQuestLine(questId)
end

function Player:onStorageUpdate(key, value, oldValue, currentFrameTime)


self:updateStorage(key, value, oldValue, currentFrameTime)
end

function Player:canBeAppliedImbuement(imbuement, item)


local categories = {}
local slots = ItemType(item:getId()):getImbuingSlots()
if slots > 0 then
for slot = 0, slots - 1 do
local duration = item:getImbuementDuration(slot)
if duration > 0 then
local imbue = item:getImbuement(slot)
local catid = imbue:getCategory().id
table.insert(categories, catid)
end
end
end

if isInArray(categories, imbuement:getCategory().id) then


return false
end

if imbuement:isPremium() and self:getPremiumDays() < 1 then


return false
end

if self:getStorageValue(Storage.ForgottenKnowledge.Tomes) > 0 then


imbuable = true
else
return false
end

if not self:canImbueItem(imbuement, item) then


return false
end

return true
end

function Player:onApplyImbuement(imbuement, item, slot, protectionCharm)


for _, pid in pairs(imbuement:getItems()) do
if self:getItemCount(pid.itemid) < pid.count then
self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED,
"You don't have all necessary items.")
return false
end
end

if item:getImbuementDuration(slot) > 0 then


self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ERROR, "An error
ocurred, please reopen imbuement window.")
return false
end
local base = imbuement:getBase()
local price = base.price + (protectionCharm and base.protection or 0)

local chance = protectionCharm and 100 or base.percent


if math.random(100) > chance then -- failed attempt
self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "Oh no!\
n\nThe imbuement has failed. You have lost the astral sources and gold you needed
for the imbuement.\n\nNext time use a protection charm to better your chances.")
-- Removing items
for _, pid in pairs(imbuement:getItems()) do
self:removeItem(pid.itemid, pid.count)
end
-- Removing money
self:removeMoneyNpc(price)
-- Refreshing shrine window
local nitem = Item(item.uid)
self:sendImbuementPanel(nitem)
return false
end

-- Removing items
for _, pid in pairs(imbuement:getItems()) do
if not self:removeItem(pid.itemid, pid.count) then
self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED,
"You don't have all necessary items.")
return false
end
end

if not self:removeMoneyNpc(price) then


self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "You
don't have enough money " ..price.. " gps.")
return false
end

if not item:addImbuement(slot, imbuement:getId()) then


self:sendImbuementResult(MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED, "Item
failed to apply imbuement.")
return false
end

-- Update item
local nitem = Item(item.uid)
self:sendImbuementPanel(nitem)
return true
end

function Player:clearImbuement(item, slot)


local slots = ItemType(item:getId()):getImbuingSlots()
if slots < slot then
self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR, "Sorry,
not possible.")
return false
end

if item:getTopParent() ~= self or item:getParent() == self then


self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR,
"An error occurred while applying the clearing charm to the
item.")
return false
end

-- slot is not used


local info = item:getImbuementDuration(slot)
if info == 0 then
self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR,
"An error occurred while applying the clearing charm to the
item.")
return false
end

local imbuement = item:getImbuement(slot)


if not self:removeMoneyNpc(imbuement:getBase().removecust) then
self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR,
"You don't have enough money " ..imbuement:getBase().removecust..
" gps.")
return false
end

if not item:cleanImbuement(slot) then


self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_ERROR,
"An error occurred while applying the clearing charm to the
item.")
return false
end

-- Update item
local nitem = Item(item.uid)
self:sendImbuementResult(MESSAGEDIALOG_CLEARING_CHARM_SUCCESS,
"Congratulations! You have successfully applied the clearing charm to
your item.");
self:sendImbuementPanel(nitem)

return true
end

function Player:onCombat(target, item, primaryDamage, primaryType, secondaryDamage,


secondaryType)
if not item or not target then
return primaryDamage, primaryType, secondaryDamage, secondaryType
end

local slots = ItemType(item:getId()):getImbuingSlots()


if slots > 0 then
for i = 0, slots - 1 do
local imbuement = item:getImbuement(i)
if imbuement then
local percent = imbuement:getElementDamage()
local totalDmg = primaryDamage --store it for damage
adjustment
if percent and percent > 0 then
if primaryDamage ~= 0 then
local factor = percent / 100
secondaryType = imbuement:getCombatType()
primaryDamage = totalDmg * (1 - factor)
secondaryDamage = totalDmg * (factor)
end
end
end
end
end

return primaryDamage, primaryType, secondaryDamage, secondaryType


end

You might also like