• 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!

RevScripts addSpecialSkill (permanent)

muriloclv

New Member
Joined
Apr 28, 2010
Messages
7
Reaction score
0
  • TFS 1.5 Downgrade by: Nekiro
  • Lua / C++
LUA:
local config = {
    gemId = 11208, -- ID do item
    storageKey = 31085, -- Chave de armazenamento para verificar o uso
    effects = {
        maxHpPercent = 2, -- Aumento percentual na vida máxima
        maxManaPercent = 2, -- Aumento percentual na mana máxima
        criticalAmount = 2, -- Bônus de dano crítico
        criticalChance = 1 -- Bônus de chance crítica
    },
    effect = CONST_ME_MAGIC_RED -- Efeito visual ao usar o item
}

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local storageValue = player:getStorageValue(config.storageKey)
    
    -- Verifica se o jogador já usou o item
    if storageValue > 0 then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você já usou este item.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    -- Obter os valores atuais de CriticalHit
    local currentCriticalAmount = player:getSpecialSkill(SPECIALSKILL_CRITICALHITAMOUNT)
    local currentCriticalChance = player:getSpecialSkill(SPECIALSKILL_CRITICALHITCHANCE)

    -- Aplica os efeitos permanentemente
    player:setMaxHealth(math.floor(player:getMaxHealth() * (1 + config.effects.maxHpPercent / 100)))
    player:setMaxMana(math.floor(player:getMaxMana() * (1 + config.effects.maxManaPercent / 100)))

    -- Atualiza as habilidades especiais de CriticalHit
    player:addSpecialSkill(SPECIALSKILL_CRITICALHITAMOUNT, currentCriticalAmount + config.effects.criticalAmount)
    player:addSpecialSkill(SPECIALSKILL_CRITICALHITCHANCE, currentCriticalChance + config.effects.criticalChance)

    -- Armazena os valores no storage
    local storageString = string.format("%d;%d;%d;%d", config.effects.maxHpPercent, config.effects.maxManaPercent, config.effects.criticalAmount, config.effects.criticalChance)
    player:setStorageValue(config.storageKey, storageString)

    -- Mensagem de sucesso e efeito visual
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você recebeu os bônus do item permanentemente!")
    player:getPosition():sendMagicEffect(config.effect)

    -- Remove o item do jogador
    item:remove(1)
    return true
end

action:id(config.gemId)
action:register()

Im trying to make a Buff that when Player use (ITEM ID), he take a permanent buff. The problem is when player leave and login again on the server, SpecialSkill buff dont "keep" on the player, just Health and Mana buff.

Example:

On first use

1000 HP > 1020 HP
1000 MP > 1020 MP
Critical Chance > 1
Critical Amount > 2

Player relog:
1000 HP > 1020 HP
1000 MP > 1020 MP
Critical Chance > 0
Critical Amount > 0
 
Solution
I made the script as you wanted. So, I removed the 'onMoveItem' function, applying it only to items/objects and not to the player. Therefore, it is correct to use 'onLogin' when logging in to maintain the permanent bonus.

LUA:
local conditionSubId = 45083

local config = {
    gemId = 11208,
    storageKey = 31085,
    maxTier = 10,
    effects = {
        maxHpPercent = 2, -- Percentage increase in max health per tier
        maxManaPercent = 2, -- Percentage increase in max mana per tier
        criticalAmount = 2, -- Bonus critical damage per tier
        criticalChance = 1  -- Bonus critical chance per tier
    },
    effectOnUse = CONST_ME_MAGIC_RED
}

local conditions = {
    ["criticalAmount"] =...
This system, created by Xiniki, works like this: just click the item to gain permanent attributes, which remain even after logging out and back in. You can try it here—just click, pick it up, and add it to your TFS to test.


LUA:
 ["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"}
 
This system, created by Xiniki, works like this: just click the item to gain permanent attributes, which remain even after logging out and back in. You can try it here—just click, pick it up, and add it to your TFS to test.


LUA:
 ["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"}
i think that i wont be clearly about item or i dont understood the Xiniki's script. Let me try explain xD

I want a Item (Ex: stuffed toad) that when i use it, i gain permanent buff on character, dont need use in another item or something like this, just use Stuffed Toad, item will disappear and i take permanent buffs (hp, mp, crit chance and amount). I think its simple than Xakini's script, or im wrong? Im confused xDD
 
I sent you the link just to give you an example. I know you want to consume the item on the character, not directly the item itself. I took Xinili's script and adapted it to what you wanted – just consume the item, and after logging out and back in, it still remains. Enjoy!

LUA:
local conditionSubId = 45083

local config = {
    gemId = 18408,
    storageKey = 31088,
    effects = {
        maxHpPercent = 2,
        maxManaPercent = 2,
        criticalAmount = 2,
        criticalChance = 1
    },
    effectOnUse = CONST_ME_MAGIC_RED
}

local conditions = {
    ["criticalAmount"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    ["criticalChance"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE}
}

local function hasUsedItem(player)
    return player:getStorageValue(config.storageKey) > 0
end

local function applyCriticalBonuses(player)
    player:removeCondition(CONDITION_ATTRIBUTES, conditionSubId)

    local condition = Condition(CONDITION_ATTRIBUTES, conditionSubId)
    condition:setParameter(CONDITION_PARAM_TICKS, -1)

    for stat, value in pairs(config.effects) do
        if conditions[stat] then
            for _, param in ipairs(conditions[stat]) do
                condition:setParameter(param, value)
            end
        end
    end
    player:addCondition(condition)
end

local action = Action()
function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if hasUsedItem(player) then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você já consumiu este item antes.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    player:setMaxHealth(math.floor(player:getMaxHealth() * (1 + config.effects.maxHpPercent / 100)))
    player:setMaxMana(math.floor(player:getMaxMana() * (1 + config.effects.maxManaPercent / 100)))
    
    applyCriticalBonuses(player)
    
    player:setStorageValue(config.storageKey, 1)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você recebeu os bônus do item permanentemente!")
    player:getPosition():sendMagicEffect(config.effectOnUse)
    item:remove(1)
    return true
end
action:id(config.gemId)
action:register()

local creatureevent = CreatureEvent("onLogin_updateItemStatBonus")
function creatureevent.onLogin(player)
    if hasUsedItem(player) then
        applyCriticalBonuses(player)
    end
    return true
end
creatureevent:register()

local ecMoveItem = EventCallback
ecMoveItem.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
    if hasUsedItem(self) then
        applyCriticalBonuses(self)
    end
    return RETURNVALUE_NOERROR
end
ecMoveItem:register()
 
Last edited:
I sent you the link just to give you an example. I know you want to consume the item on the character, not directly the item itself. I took Xinili's script and adapted it to what you wanted – just consume the item, and after logging out and back in, it still remains. Enjoy!

LUA:
local conditionSubId = 45083

local config = {
    gemId = 11208,
    storageKey = 31085,
    effects = {
        maxHpPercent = 2,
        maxManaPercent = 2,
        criticalAmount = 2,
        criticalChance = 1
    },
    effectOnUse = CONST_ME_MAGIC_RED
}

local conditions = {
    ["maxHpPercent"] = {CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT},
    ["maxManaPercent"] = {CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT},
    ["criticalAmount"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    ["criticalChance"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE}
}

local function hasUsedItem(player)
    return player:getStorageValue(config.storageKey) > 0
end

local function applyBonuses(player)
    player:removeCondition(CONDITION_ATTRIBUTES, conditionSubId)

    local condition = Condition(CONDITION_ATTRIBUTES, conditionSubId)
    condition:setParameter(CONDITION_PARAM_TICKS, -1)

    for stat, value in pairs(config.effects) do
        if conditions[stat] then
            for _, param in ipairs(conditions[stat]) do
                condition:setParameter(param, value)
            end
        end
    end

    player:addCondition(condition)
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Seus bônus foram aplicados com sucesso!")
end

local action = Action()
function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if hasUsedItem(player) then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você já consumiu este item antes.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    applyBonuses(player)
    player:setStorageValue(config.storageKey, 1)
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Você recebeu os bônus do item permanentemente!")
    player:getPosition():sendMagicEffect(config.effectOnUse)
    item:remove(1)
    return true
end
action:id(config.gemId)
action:register()

local creatureevent = CreatureEvent("onLogin_updateItemStatBonus")
function creatureevent.onLogin(player)
    if hasUsedItem(player) then
        applyBonuses(player)
    end
    return true
end
creatureevent:register()

local ecMoveItem = EventCallback
ecMoveItem.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
    if hasUsedItem(self) then
        applyBonuses(self)
    end
    return RETURNVALUE_NOERROR
end
ecMoveItem:register()
I needed make some changes on Script cuz the bonus % not correctly, in:

LUA:
    effects = {
        maxHpPercent = 102,
        maxManaPercent = 102,
        criticalAmount = 2,
        criticalChance = 1
    },

But in tests, when player dies, he dont comeback with full HP. Example:

Player has: 1.020.000/1.020.000 with buff
When he dies, back with: 1.000.000/1.020.000

And in DB, the player maxhp still 1.000.000, i think is it, have way to change this and solve?
 
Post edited: The script has been updated.
Yesterday, I took the script and adapted it without testing. I posted it here and went to sleep. When I woke up, you mentioned there was a problem. I made a small edit and tested it. It seems to be working fine... Can you take a look?
 
Post edited: The script has been updated.
Yesterday, I took the script and adapted it without testing. I posted it here and went to sleep. When I woke up, you mentioned there was a problem. I made a small edit and tested it. It seems to be working fine... Can you take a look?
I had a problem in the script friend. I Have 10 items to buff, in scale, 1% chance 1% amount tier 1, 2/2% in tier 2, until tier 10. The first buff is ok, saved when use, logout and login, but the rest no. Example: If I used Tier 1 + Tier 2 = 3% of Chance and 3% of Amount, but if I relog, I take only 1% from Tier 1.
I made few tests about and I discovery that when I throw the item on ground, relog, take the item and open BP, all buffs activated again, can u understand ma problem? Hahahaha I don't know how to explain it better than now to facility.
I removed last part from script and this bug don't occurs, but the buff Tier 1 is the only permanent on the player, same as before.
 
I made the script as you wanted. So, I removed the 'onMoveItem' function, applying it only to items/objects and not to the player. Therefore, it is correct to use 'onLogin' when logging in to maintain the permanent bonus.

LUA:
local conditionSubId = 45083

local config = {
    gemId = 11208,
    storageKey = 31085,
    maxTier = 10,
    effects = {
        maxHpPercent = 2, -- Percentage increase in max health per tier
        maxManaPercent = 2, -- Percentage increase in max mana per tier
        criticalAmount = 2, -- Bonus critical damage per tier
        criticalChance = 1  -- Bonus critical chance per tier
    },
    effectOnUse = CONST_ME_MAGIC_RED
}

local conditions = {
    ["criticalAmount"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITAMOUNT},
    ["criticalChance"] = {CONDITION_PARAM_SPECIALSKILL_CRITICALHITCHANCE}
}

local function getCurrentTier(player)
    local currentTier = player:getStorageValue(config.storageKey)
    return currentTier > 0 and currentTier or 0
end

local function applyCriticalBonuses(player)
    player:removeCondition(CONDITION_ATTRIBUTES, conditionSubId)

    local currentTier = getCurrentTier(player)
    if currentTier <= 0 then
        return
    end

    local condition = Condition(CONDITION_ATTRIBUTES, conditionSubId)
    condition:setParameter(CONDITION_PARAM_TICKS, -1)

    local criticalAmount = config.effects.criticalAmount * currentTier
    local criticalChance = config.effects.criticalChance * currentTier
    local hpBonus = config.effects.maxHpPercent * currentTier
    local manaBonus = config.effects.maxManaPercent * currentTier

    if conditions["criticalAmount"] then
        for _, param in ipairs(conditions["criticalAmount"]) do
            condition:setParameter(param, criticalAmount)
        end
    end
   
    if conditions["criticalChance"] then
        for _, param in ipairs(conditions["criticalChance"]) do
            condition:setParameter(param, criticalChance)
        end
    end

    player:addCondition(condition)

    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE,
        string.format("Your current buff bonuses: Tier %d - HP: +%d%%, MP: +%d%%, Critical Chance: +%d%%, Critical Amount: +%d%%",
        currentTier, hpBonus, manaBonus, criticalChance, criticalAmount))
end

local action = Action()
function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local _player = Player(item:getTopParent())
    if not _player or _player:getId() ~= player:getId() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot consume this buff from the ground. Move it to your inventory.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local currentTier = getCurrentTier(player)

    if currentTier >= config.maxTier then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You have already reached the maximum buff level.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local newTier = currentTier + 1
   
    local hpBonus = config.effects.maxHpPercent * newTier
    local manaBonus = config.effects.maxManaPercent * newTier
   
    player:setMaxHealth(math.floor(player:getMaxHealth() * (1 + hpBonus / 100)))
    player:setMaxMana(math.floor(player:getMaxMana() * (1 + manaBonus / 100)))
   
    player:setStorageValue(config.storageKey, newTier)
    applyCriticalBonuses(player)

    player:sendTextMessage(MESSAGE_STATUS_SMALL,
        string.format("You have successfully used the stone! Buff Tier %d activated. Remaining until max: %d.",
        newTier, config.maxTier - newTier))
    player:getPosition():sendMagicEffect(config.effectOnUse)
    item:remove(1)

    return true
end
action:id(config.gemId)
action:register()

local creatureevent = CreatureEvent("onLogin_updateItemStatBonus")
function creatureevent.onLogin(player)
    applyCriticalBonuses(player)
    return true
end
creatureevent:register()
 
Last edited:
Solution
Back
Top