• 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+ Skill stages for each vocation

ralke

(҂ ͠❛ ෴ ͡❛)ᕤ
Joined
Dec 17, 2011
Messages
1,521
Solutions
27
Reaction score
870
Location
Santiago - Chile
GitHub
ralke23
Twitch
ralke23
Hi there! I've been using this wonderfull script make by @Xikini that allows to set experience stages to skills. But I encounter the issue that knights, for example, would benefit from the raised magic level stage (knights advance really slower in comparision to sorcerers or mages).

Lua:
local skillStages = {
    [SKILL_FIST] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_CLUB] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SWORD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_AXE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_DISTANCE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SHIELD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_FISHING] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_MAGLEVEL] = {
        [{  1,   60}] = {multiplier = 16},
        [{ 60, 100}] = {multiplier = 8},
        [{101}]      = {multiplier = 4}
    }
}


local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries)
    if not skillStages[skill] then
        return tries
    end
    local playerLevel = skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getSkillLevel(skill)
    for k, v in pairs(skillStages[skill]) do
        if playerLevel >= k[1] then
            if not k[2] or playerLevel <= k[2] then
                tries = tries * v.multiplier
            end
        end
    end 
    return tries
end

ec:register()
So, if I have:
Lua:
    [SKILL_MAGLEVEL] = {
        [{  1,   60}] = {multiplier = 16},
        [{ 60, 100}] = {multiplier = 8},
        [{101}]      = {multiplier = 4}
    }

The multiplier would be much easier for knights, from the other hand, I would like to have mages and druids to be able to progress really quick on their first magic level stages. So... How can I add vocation for each separated skill stage?. Thanks in advance!
 
Solution
Hi there! I've been using this wonderfull script make by @Xikini that allows to set experience stages to skills. But I encounter the issue that knights, for example, would benefit from the raised magic level stage (knights advance really slower in comparision to sorcerers or mages).

Lua:
local skillStages = {
    [SKILL_FIST] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_CLUB] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SWORD] = {
        [{  1...
Hi there! I've been using this wonderfull script make by @Xikini that allows to set experience stages to skills. But I encounter the issue that knights, for example, would benefit from the raised magic level stage (knights advance really slower in comparision to sorcerers or mages).

Lua:
local skillStages = {
    [SKILL_FIST] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_CLUB] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SWORD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_AXE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_DISTANCE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SHIELD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_FISHING] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_MAGLEVEL] = {
        [{  1,   60}] = {multiplier = 16},
        [{ 60, 100}] = {multiplier = 8},
        [{101}]      = {multiplier = 4}
    }
}


local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries)
    if not skillStages[skill] then
        return tries
    end
    local playerLevel = skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getSkillLevel(skill)
    for k, v in pairs(skillStages[skill]) do
        if playerLevel >= k[1] then
            if not k[2] or playerLevel <= k[2] then
                tries = tries * v.multiplier
            end
        end
    end
    return tries
end

ec:register()
So, if I have:
Lua:
    [SKILL_MAGLEVEL] = {
        [{  1,   60}] = {multiplier = 16},
        [{ 60, 100}] = {multiplier = 8},
        [{101}]      = {multiplier = 4}
    }

The multiplier would be much easier for knights, from the other hand, I would like to have mages and druids to be able to progress really quick on their first magic level stages. So... How can I add vocation for each separated skill stage?. Thanks in advance!
Should be ok but make sure you test it...
Lua:
local skillStages = {
    [SKILL_FIST] = { --{none, ms, ed, rp, ek}
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_CLUB] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16,16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_SWORD] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_AXE] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_DISTANCE] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_SHIELD] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_FISHING] = {
        [{1, 60}]    = {32, 32, 32, 32, 32},
        [{60, 100}]  = {16, 16, 16, 16, 16},
        [{101}]      = {8, 8, 8, 8, 8}
    },
    [SKILL_MAGLEVEL] = {
        [{1, 60}]    = {16, 16, 16, 16, 16},
        [{60, 100}]  = {8, 8, 8, 8, 8},
        [{101}]      = {4, 4, 4, 4, 4}
    }
}


local ec = EventCallback

ec.onGainSkillTries = function(self, skill, tries)
    if not skillStages[skill] then
        return tries
    end
   
    local playerLevel = skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getSkillLevel(skill)
    local vocationId = player:getVocation():getId() + 1
    local vocationIndex = vocationId > 5 and (vocationId - 4) or vocationId
    for range, multipliers in pairs(skillStages[skill]) do
        if playerLevel >= range[1] then
            if not range[2] or playerLevel <= range[2] then
                tries = tries * multipliers[vocationIndex]
                break
            end
        end
    end
    return tries
end

ec:register()
 
Solution
local skillStages = { [SKILL_FIST] = { --{none, ms, ed, rp, ek} [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_CLUB] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16,16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_SWORD] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_AXE] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_DISTANCE] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_SHIELD] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_FISHING] = { [{1, 60}] = {32, 32, 32, 32, 32}, [{60, 100}] = {16, 16, 16, 16, 16}, [{101}] = {8, 8, 8, 8, 8} }, [SKILL_MAGLEVEL] = { [{1, 60}] = {16, 16, 16, 16, 16}, [{60, 100}] = {8, 8, 8, 8, 8}, [{101}] = {4, 4, 4, 4, 4} } } local ec = EventCallback ec.onGainSkillTries = function(self, skill, tries) if not skillStages[skill] then return tries end local playerLevel = skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getSkillLevel(skill) local vocationId = player:getVocation():getId() + 1 local vocationIndex = vocationId > 5 and (vocationId - 4) or vocationId for range, multipliers in pairs(skillStages[skill]) do if playerLevel >= range[1] then if not range[2] or playerLevel <= range[2] then tries = tries * multipliers[vocationIndex] break end end end return tries end ec:register()

Thanks a lot, really appreciate the outcome! There's a chance that you could help me with the following talkaction too? I'm on way to test it but I want to get ensure that it triggers the correct stage.

Lua:
local skillStages = {
    [SKILL_FIST] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_CLUB] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SWORD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_AXE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_DISTANCE] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_SHIELD] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    },
    [SKILL_MAGLEVEL] = {
        [{  1,   60}] = {multiplier = 32},
        [{ 60, 100}] = {multiplier = 16},
        [{101}]      = {multiplier = 8}
    }
}

local lootRateConfigKey = configKeys.RATE_LOOT

function getRateText(player, skillStages)
    local skillRates = {}
 
    -- Get the player's skill levels
    local skills = {
        SKILL_FIST, SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE, SKILL_SHIELD
    }

    for _, skill in ipairs(skills) do
        local skillLevel = player:getSkillLevel(skill)
        local stages = skillStages[skill]

        for k, v in pairs(stages) do
            if skillLevel >= k[1] then
                if not k[2] or skillLevel <= k[2] then
                    -- Append the level range to the skill rate message
                    local range = k[2] and string.format("from level %d to %d", k[1], k[2]) or string.format("from level %d to infinite", k[1])
                    skillRates[skill] = string.format("%dx (%s)", v.multiplier, range)
                    break
                end
            end
        end

        -- If skill rate not found, set to "Unknown"
        skillRates[skill] = skillRates[skill] or "Unknown"
    end
 
    -- Get the player's magic level
    local magicLevel = player:getMagicLevel()
    local magicStages = skillStages[SKILL_MAGLEVEL]
    local magicRate = getRateForMagicLevel(magicLevel, magicStages)

    -- Append the level range for magic skill
    local magicRange = ""
    for k, v in pairs(magicStages) do
        if magicLevel >= k[1] then
            if not k[2] or magicLevel <= k[2] then
                magicRange = k[2] and string.format("from level %d to %d", k[1], k[2]) or string.format("from level %d to infinite", k[1])
                break
            end
        end
    end

    -- If magic rate not found, set to "Unknown"
    magicRate = magicRate or "Unknown"

    return skillRates, magicRate, magicRange
end

function getRateForMagicLevel(magicLevel, magicStages)
    for k, v in pairs(magicStages) do
        if magicLevel >= k[1] then
            if not k[2] or magicLevel <= k[2] then
                return string.format("%dx", v.multiplier)
            end
        end
    end
    return "Unknown"
end

function onSay(player, words, param)
    local message = "Server Info:\n"
 
    -- Append exp rate to the message
    local expRate = string.format("%.1f", Game.getExperienceStage(player:getLevel())) -- Format to one decimal point for low xp stages
    message = message .. string.format("Exp rate: %sx\n", expRate)

    -- Get the skill rates for each skill and the magic rate
    local skillRates, magicRate, magicRange = getRateText(player, skillStages)

    -- Append skill rates for each skill to the message
    for skill, rate in pairs(skillRates) do
        local skillName = getSkillName(skill):gsub("^%l", string.upper)
        skillName = skillName:gsub(" fighting$", "") -- Remove " fighting" suffix if present
        message = message .. string.format("%s rate: %s\n", skillName, rate)
    end

    -- Append magic rate and range to the message
    message = message .. string.format("Magic rate: %s (%s)\n", magicRate, magicRange)

    -- Append loot rate to the message
    local lootRate = configManager.getNumber(lootRateConfigKey)
    message = message .. string.format("Loot rate: %dx", lootRate)

    -- Send the message to the player
    player:sendTextMessage(MESSAGE_INFO_DESCR, message)
    return false
end
 
Back
Top