• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Upgrade script by Xikini.

OTcreator

Active Member
Joined
Feb 14, 2022
Messages
425
Solutions
1
Reaction score
44
Hi!
I use this script and it adds some bonus to the ring.
Everything works as expected, but I would like the bonus to work only if I put items in the ring slot.
At the moment, if I add something to the item and put it in place of the hand or arrow slot it still gets the bonus.

(Alternatively, what to do so that the item can be moved in backpacks and put only in the rig slot).

Lua:
local conditionSubId = 45083 -- must be a unique subId not used for other buffs in your server
local config = {
    ["statMain"] = {
        -- flat_bonus_stats
        {statType = "life increase"},
        {statType = "mana increase"},
        {statType = "magic"},
        {statType = "fist"},
        {statType = "melee"},
        {statType = "distance"},
        {statType = "shield"},
        {statType = "fishing"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 1000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 1000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = {
        {statType = "soul regen", ticks = 1000}
    },
 
    maxUpgradesPerItem = 5,
    upgradeItems = {
        [8302] = {statType = "reset item"},
        [8303] = {statType = "life increase", value = 100},
    },
    specialDisallowedItems = {} -- any items that shouldn't be upgradeable, add them here
}

-- Choose Flat or Percentage stats. Cannot use both.

-- Flat Stats
--[[
    ["statMain"] = {
        -- flat_bonus_stats
        {statType = "life increase"},
        {statType = "mana increase"},
        {statType = "magic"},
        {statType = "fist"},
        {statType = "melee"},
        {statType = "distance"},
        {statType = "shield"},
        {statType = "fishing"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 5000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 5000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = { -- you can remove entire categories
        {statType = "soul regen", ticks = 5000} -- or individual stats, if you don't want to use them
    },
]]--


-- Percent Stats
--[[
    ["statMain"] = {
        -- percent_bonus_stats
        {statType = "life increase percent"},
        {statType = "mana increase percent"},
        {statType = "magic percent"},
        {statType = "fist percent"},
        {statType = "melee percent"},
        {statType = "distance percent"},
        {statType = "shield percent"},
        {statType = "fishing percent"},
        {statType = "critical hit chance"},
        {statType = "critical hit damage"},
        {statType = "life leech chance"},
        {statType = "life leech amount"},
        {statType = "mana leech chance"},
        {statType = "mana leech amount"}
    },
    ["statSpeed"] = {
        {statType = "speed"}
    },
    ["statRegen"] = {
        {statType = "life regen", ticks = 5000}, -- ticks in milliseconds}
        {statType = "mana regen", ticks = 5000}  -- can't go lower then 1000
    },
    ["statSoulRegen"] = {
        {statType = "soul regen", ticks = 5000}
    },
]]--


-- END OF CONFIG

local choiceDictionary = {}

local conditions = {
    ["life increase"] = {CONDITION_PARAM_STAT_MAXHITPOINTS},
    ["mana increase"] = {CONDITION_PARAM_STAT_MAXMANAPOINTS},
    ["speed"] = {CONDITION_PARAM_SPEED},
    ["magic"] = {CONDITION_PARAM_STAT_MAGICPOINTS},
    ["melee"] = {CONDITION_PARAM_SKILL_MELEE},
    ["fist"] = {CONDITION_PARAM_SKILL_FIST},
    ["club"] = {CONDITION_PARAM_SKILL_CLUB},
    ["sword"] = {CONDITION_PARAM_SKILL_SWORD},
    ["axe"] = {CONDITION_PARAM_SKILL_AXE},
    ["distance"] = {CONDITION_PARAM_SKILL_DISTANCE},
    ["shield"] = {CONDITION_PARAM_SKILL_SHIELD},
    ["fishing"] = {CONDITION_PARAM_SKILL_FISHING},
    ["critical hit chance"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE},
    ["critical hit damage"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    ["life leech chance"] = {CONDITION_PARAM_SPECIALSKILL_LIFELEECHCHANCE},
    ["life leech amount"] = {CONDITION_PARAM_SPECIALSKILL_LIFELEECHAMOUNT},
    ["mana leech chance"] = {CONDITION_PARAM_SPECIALSKILL_MANALEECHCHANCE},
    ["mana leech amount"] = {CONDITION_PARAM_SPECIALSKILL_MANALEECHAMOUNT},
    ["life increase percent"] = {CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT},
    ["mana increase percent"] = {CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT},
    ["magic percent"] = {CONDITION_PARAM_STAT_MAGICPOINTSPERCENT},
    ["melee percent"] = {CONDITION_PARAM_SKILL_MELEEPERCENT},
    ["fist percent"] = {CONDITION_PARAM_SKILL_FISTPERCENT},
    ["club percent"] = {CONDITION_PARAM_SKILL_CLUBPERCENT},
    ["sword percent"] = {CONDITION_PARAM_SKILL_SWORDPERCENT},
    ["axe percent"] = {CONDITION_PARAM_SKILL_AXEPERCENT},
    ["distance percent"] = {CONDITION_PARAM_SKILL_DISTANCEPERCENT},
    ["shield percent"] = {CONDITION_PARAM_SKILL_SHIELDPERCENT},
    ["fishing percent"] = {CONDITION_PARAM_SKILL_FISHINGPERCENT},
    ["life regen"] = {CONDITION_PARAM_HEALTHGAIN, CONDITION_PARAM_HEALTHTICKS},
    ["mana regen"] = {CONDITION_PARAM_MANAGAIN, CONDITION_PARAM_MANATICKS},
    ["soul regen"] = {CONDITION_PARAM_SOULGAIN, CONDITION_PARAM_SOULTICKS}
}

local main_attributes = {CONDITION_ATTRIBUTES, CONDITION_HASTE, CONDITION_REGENERATION, CONDITION_SOUL}
local main_stats = {"statMain", "statSpeed", "statRegen", "statSoulRegen"}

local function updateStatBonus(playerId)
    local player = Player(playerId)
    if not player then
        return
    end
 
    -- remove all previous buffs
    for i = 1, 4 do
        if player:getCondition(main_attributes[i], conditionSubId) then
            player:removeCondition(main_attributes[i], conditionSubId)
        end
    end
 
    local equippedItems = {}
    for slot = 1, 10 do
        local slotItem = player:getSlotItem(slot)
        if slotItem then
            equippedItems[#equippedItems + 1] = slotItem
        end
    end
 
    -- add all buffs
    for i = 1, 4 do
        local statCategory = main_stats[i]
        if config[statCategory] then
            local condition = Condition(main_attributes[i], conditionSubId)
            condition:setParameter(CONDITION_PARAM_TICKS, -1)
            for _, stat in ipairs(config[statCategory]) do
                local statValue = 0
                for i = 1, #equippedItems do
                    local itemValue = equippedItems[i]:getCustomAttribute(stat.statType)
                    statValue = itemValue and itemValue + statValue or statValue
                end
                if statValue > 0 then
                    for conditionParam = 1, #conditions[stat.statType] do
                        condition:setParameter(conditions[stat.statType][conditionParam], statValue)
                    end
                    player:addCondition(condition)
                end
            end
        end
    end
    return true
end


local slotTypes = {
    48, -- weapon or shield
    49, -- helmet
    50, -- amulet
    52, -- backpack
    56, -- armor
    112, -- legs
    176, -- boots
    304, -- ring
    560, -- ammo
    2096 -- two handed
}

local function isItemUpgradeable(item)
    if not item:isItem() then
        return false
    end
    local itemType = ItemType(item:getId())
    if not table.contains(slotTypes, itemType:getSlotPosition()) then
        return false
    end
    if itemType:isStackable() then
        return false
    end
    if table.contains(config.specialDisallowedItems, item:getId()) then
        return false
    end
    return true
end



local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not isItemUpgradeable(target) then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Not a valid item to apply upgrades too.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF, player)
        return true
    end
 
    local itemIndex = config.upgradeItems[item:getId()]
    local itemUpgradeCount = target:getCustomAttribute("Upgrade Counter")
    itemUpgradeCount = itemUpgradeCount and itemUpgradeCount or 0
 
    if itemIndex.statType == "reset item" then
        if itemUpgradeCount == 0 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has no upgrades to reset.")
            target:getPosition():sendMagicEffect(CONST_ME_POFF, player)
            return true
        end
        for k, v in pairs(conditions) do
            target:removeCustomAttribute(k)
        end
        target:removeCustomAttribute("Upgrade Counter")
        target:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE, player)
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "All upgrades have been removed from this item.")
        item:remove(1)
        if toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 then
            addEvent(updateStatBonus, 0, player:getId())
        end
        return true
    end
 
    if itemUpgradeCount >= config.maxUpgradesPerItem then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has reached max upgrades.")
        target:getPosition():sendMagicEffect(CONST_ME_POFF, player)
        return true
    end
 
    local currentStatAmount = target:getCustomAttribute(itemIndex.statType)
    currentStatAmount = currentStatAmount and currentStatAmount or 0
    target:setCustomAttribute(itemIndex.statType, currentStatAmount + itemIndex.value)
    target:setCustomAttribute("Upgrade Counter", itemUpgradeCount + 1)
 
    target:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN, player)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Item has been upgraded.")
    item:remove(1)
 
    if toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 then
        addEvent(updateStatBonus, 0, player:getId())
    end
    return true
end

for itemId, _ in pairs(config.upgradeItems) do
    action:id(itemId)
end
action:register()


local creatureevent = CreatureEvent("onLogin_updateItemStatBonus")

function creatureevent.onLogin(player)
    updateStatBonus(player:getId())
    return true
end

creatureevent:register()


local ec = EventCallback

ec.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if not (toPosition.x == CONTAINER_POSITION and toPosition.y <= 10 or fromPosition.x == CONTAINER_POSITION and fromPosition.y <= 10) then
        return RETURNVALUE_NOERROR
    end
    addEvent(updateStatBonus, 0, self:getId())
    return RETURNVALUE_NOERROR
end

ec:register()
 
Lua:
local function updateStatBonus(playerId)
    local player = Player(playerId)
    if not player then
        return
    end

    -- remove all previous buffs
    for i = 1, 4 do
        if player:getCondition(main_attributes[i], conditionSubId) then
            player:removeCondition(main_attributes[i], conditionSubId)
        end
    end

    local equippedRing = player:getSlotItem(CONST_SLOT_RING)
    if not equippedRing then
        return
    end

    local equippedItems = {equippedRing}

    -- add all buffs
    for i = 1, 4 do
        local statCategory = main_stats[i]
        if config[statCategory] then
            local condition = Condition(main_attributes[i], conditionSubId)
            condition:setParameter(CONDITION_PARAM_TICKS, -1)
            for _, stat in ipairs(config[statCategory]) do
                local statValue = 0
                for i = 1, #equippedItems do
                    local itemValue = equippedItems[i]:getCustomAttribute(stat.statType)
                    statValue = itemValue and itemValue + statValue or statValue
                end
                if statValue > 0 then
                    for conditionParam = 1, #conditions[stat.statType] do
                        condition:setParameter(conditions[stat.statType][conditionParam], statValue)
                    end
                    player:addCondition(condition)
                end
            end
        end
    end
    return true
end

local function isItemUpgradeable(item)
    if not item:isItem() then
        return false
    end
    local itemType = ItemType(item:getId())
    if itemType:getSlotPosition() ~= SLOT_RING then
        return false
    end
    if itemType:isStackable() then
        return false
    end
    if table.contains(config.specialDisallowedItems, item:getId()) then
        return false
    end
    return true
end

local action = Action()
 
Last edited:
Lua:
local function updateStatBonus(playerId)
    local player = Player(playerId)
    if not player then
        return
    end

    -- remove all previous buffs
    for i = 1, 4 do
        if player:getCondition(main_attributes[i], conditionSubId) then
            player:removeCondition(main_attributes[i], conditionSubId)
        end
    end

    local equippedRing = player:getSlotItem(SLOT_RING)
    if not equippedRing then
        return
    end

    local equippedItems = {equippedRing}

    -- add all buffs
    for i = 1, 4 do
        local statCategory = main_stats[i]
        if config[statCategory] then
            local condition = Condition(main_attributes[i], conditionSubId)
            condition:setParameter(CONDITION_PARAM_TICKS, -1)
            for _, stat in ipairs(config[statCategory]) do
                local statValue = 0
                for i = 1, #equippedItems do
                    local itemValue = equippedItems[i]:getCustomAttribute(stat.statType)
                    statValue = itemValue and itemValue + statValue or statValue
                end
                if statValue > 0 then
                    for conditionParam = 1, #conditions[stat.statType] do
                        condition:setParameter(conditions[stat.statType][conditionParam], statValue)
                    end
                    player:addCondition(condition)
                end
            end
        end
    end
    return true
end

local function isItemUpgradeable(item)
    if not item:isItem() then
        return false
    end
    local itemType = ItemType(item:getId())
    if itemType:getSlotPosition() ~= SLOT_RING then
        return false
    end
    if itemType:isStackable() then
        return false
    end
    if table.contains(config.specialDisallowedItems, item:getId()) then
        return false
    end
    return true
end

local action = Action()

Thank you very much, I will check it as soon as possible.

And is there any other way to, for example, add a given bonus for a certain time ? (in the know, in the ring I can add a time after which it will remove the ring).
But it is more about some kind of storage, where during the established ring, it will subtract time for example from the storage, and as it comes more storage than given, it will remove for example from the slot 1 bonus.
Something like imbuing global?
 
Thank you very much, I will check it as soon as possible.

And is there any other way to, for example, add a given bonus for a certain time ? (in the know, in the ring I can add a time after which it will remove the ring).
But it is more about some kind of storage, where during the established ring, it will subtract time for example from the storage, and as it comes more storage than given, it will remove for example from the slot 1 bonus.
Something like imbuing global?
yes u can use for this
Lua:
os.time()
Lua:
item:getCustomAttribute(attribute name)
Lua:
item:setCustomAttribute(attribute name, value)

or just tables if you dont wanna keep the values when server is restarted
 
Back
Top