--------------------------
-- Creaditos: [Adm] SevuOT de tibiaface.com
-- Nota: este sistema fue creado con la intension de regalarles algo en navidad! feliz navidad!
-- Version: 1.0
-- RECOMENDACIONES: > Si no sabe de lua o scripts, mejor no tocar mucho el script, es delicado a cambios brutos <
-- Objetos con el cual podras añadirle slots a otros objeos
-- Tambien puedes añadir esta funcionalidad a mas de un objeto, solo añadiendo una coma y seguido de la nueva ID
-- Ejemplo: local addSlotItems = { 2160, 2452 }
local addSlotItems = { 42028 }
local slotAction = Action()
local creatureEvent = CreatureEvent()
-- Libreria para la funcionalidad del sistema
local Attr = {}
Attr.__index = Attr
Attr.init = function(slot)
local attr = {}
setmetatable(attr, Attr)
attr.name = slot.name
attr.value = slot.value
attr.percent = slot.percent
return attr
end
setmetatable(Attr, {
__call = function(_, ...) return Attr.init(...) end,
__eq = function(a, b) return a.name == b.name and a.value == b.value and a.percent == b.percent end
})
local slotLib = {}
slotLib.maxSlots = 3 -- max 10, more get a errors
slotLib.baseSubids = 90
slotLib.cache = {}
slotLib.attributes = {
{ name = "Club", values = { 1, 2 }, percent = false },
{ name = "Sword", values = { 1, 2 }, percent = false },
{ name = "Axe", values = { 1, 2 }, percent = false },
{ name = "Distance", values = { 1, 2 }, percent = false },
{ name = "Shield", values = { 1, 2 }, percent = false },
{ name = "Fishing", values = { 1, 2 }, percent = false },
{ name = "MagicLevel", values = { 1, 2 }, percent = false },
{ name = "CriticalChance", values = { 1, 2 }, percent = false },
{ name = "CriticalAmount", values = { 1, 2 }, percent = false },
{ name = "LifeLeechChance", values = { 1, 2 }, percent = false },
{ name = "LifeLeechAmount", values = { 1, 2 }, percent = false },
{ name = "ManaLeechChance", values = { 1, 2 }, percent = false },
{ name = "ManaLeechAmount", values = { 1, 2 }, percent = false },
{ name = "Speed", values = { 1, 2 }, percent = false },
{ name = "HealthGain", values = { 1, 2 }, percent = false },
{ name = "ManaGain", values = { 1, 2 }, percent = false }
}
slotLib.conditions = {
["Club"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_CLUB },
["Sword"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_SWORD },
["Axe"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_AXE },
["Distance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_DISTANCE },
["Shield"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_SHIELD },
["Fishing"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_FISHING },
["MagicLevel"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_STAT_MAGICPOINTS },
["CriticalChance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_CRITICAL_HIT_CHANCE },
["CriticalAmount"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_CRITICAL_HIT_DAMAGE },
["LifeLeechChance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_LIFE_LEECH_CHANCE },
["LifeLeechAmount"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_LIFE_LEECH_AMOUNT },
["ManaLeechChance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_MANA_LEECH_CHANCE },
["ManaLeechAmount"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_MANA_LEECH_AMOUNT },
["Speed"] = { Type = CONDITION_SPEED, Attr = CONDITION_PARAM_SPEED },
["HealthGain"] = { Type = CONDITION_REGENERATION, Attr = CONDITION_PARAM_HEALTHGAIN },
["ManaGain"] = { Type = CONDITION_REGENERATION, Attr = CONDITION_PARAM_MANAGAIN }
}
slotLib.addItemSlot = function(item)
local slots = slotLib.getItemSlots(item)
local replace = #slots >= slotLib.maxSlots
local slot = slotLib.attributes[math.random(1, #slotLib.attributes)]
if slot then
local slotIndex = not replace and #slots + 1 or math.random(1, slotLib.maxSlots)
local newvalue = slot.values[math.random(1, #slot.values)]
local oldvalue = replace and slots[slotIndex].value or newvalue
slots[slotIndex] = {
name = slot.name,
value = not slot.percent and newvalue,
valuePercent = slot.percent and newvalue
}
slotLib.setItemSlots(item, slots)
return newvalue >= oldvalue
end
end
slotLib.getItemSlots = function(item)
local slots = {}
for slot in string.gmatch(Item.getDescription(item), "(%[.-%])") do
local name = string.match(slot, "%[(%a+)%p")
local value = tonumber(string.match(slot, "%p(%d+)%]"))
local valuePercent = tonumber(string.match(slot, "%p(%d+)%%+%]"))
slots[#slots + 1] = {
name = name,
value = value,
valuePercent = valuePercent
}
end
return slots
end
slotLib.setItemSlots = function(item, slots)
local description = ItemType.getDescription(ItemType(Item.getId(item))) or ""
for _, slot in pairs(slots) do
description = string.format("%s[%s+%u%s]%s", description, slot.name, slot.value or slot.valuePercent, slot.valuePercent and "%" or "", _ == #slots and "" or "\n")
end
return Item.setAttribute(item, ITEM_ATTRIBUTE_DESCRIPTION, description)
end
slotLib.autoDetection = function(playerId)
local player = Player(playerId)
if player then
if not slotLib.cache[playerId] then
slotLib.cache[playerId] = {}
end
for slot = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
local item = player:getSlotItem(slot)
if item then
local slots = slotLib.getItemSlots(item)
slotLib.onSlotEquip(player, slots, slot)
if #slots < slotLib.maxSlots then
for index = #slots+1, slotLib.maxSlots do
local subid = slotLib.baseSubids + slot + (CONST_SLOT_AMMO * index)
player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_SPEED, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
end
end
else
for index = 1, slotLib.maxSlots do
local subid = slotLib.baseSubids + slot + (CONST_SLOT_AMMO * index)
player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_SPEED, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
end
end
end
addEvent(slotLib.autoDetection, 100, playerId)
else
slotLib.cache[playerId] = nil
end
end
slotLib.onSlotEquip = function(player, slots, slotIndex)
for index, slot in pairs(slots) do
local attr = Attr(slot)
local subid = slotLib.baseSubids + slotIndex + (CONST_SLOT_AMMO * index)
if not slotLib.cache[player.uid][subid] or slotLib.cache[player.uid][subid] ~= attr then
if slotLib.cache[player.uid][subid] and slotLib.cache[player.uid][subid] ~= attr then
player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_SPEED, CONDITIONID_DEFAULT, subid, true)
player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
end
local info = slotLib.conditions[attr.name]
if info then
local condition = Condition(info.Type, CONDITIONID_DEFAULT)
if condition then
condition:setParameter(info.Attr, attr.value)
condition:setParameter(CONDITION_PARAM_TICKS, -1)
condition:setParameter(CONDITION_PARAM_SUBID, subid)
player:addCondition(condition)
slotLib.cache[player.uid][subid] = attr
end
end
end
end
end
slotLib.isUpgradeable = function(item)
local it = ItemType(item.itemid)
return it:getArmor() >= 1 or it:getDefense() >= 1 or it:getAttack() >= 1 or it:getExtraDefense() >= 1 or it:getShootRange() >= 1 or it:getWeaponType() >= 1
end
function slotAction.onUse(player, item, fromPos, target, toPos, isHotkey)
if not target or not target:isItem() then
return player:sendCancelMessage("Sorry not possible, only work on items.")
end
if not slotLib.isUpgradeable(target) then
return player:sendCancelMessage("Sorry not possible, this item cannot update slots.")
end
local greatz = slotLib.addItemSlot(target)
target:getPosition():sendMagicEffect(greatz and CONST_ME_FIREWORK_RED or CONST_ME_FIREWORK_BLUE)
player:say(greatz and "Perfect!" or "Bad!")
return true
end
slotAction:id(addSlotItems[1])
slotAction:register()
function creatureEvent.onLogin(player)
slotLib.autoDetection(player.uid)
return true
end
creatureEvent:register()