• 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 0.X skill stages depending on vocation

sucibob

Member
Joined
Mar 28, 2017
Messages
128
Reaction score
13
I found this script:


But there is a big problem on that, the rates not change by vocation
So knights for example always have a high magic level rate

I tried to fix but with no success, is anyone more with more experience could help me to put to work?

SCRIPTS:

data\creaturescripts\scripts\stagesconfig.lua
Code:
-- Skill Stages Mages --
skillConfigM = {skill = getConfigValue('rateSkill'), magiclevel = getConfigValue('rateMagic')}
skillStagesM = {}
skillStagesM[SKILL_FIST] = {{0,0}}
skillStagesM[SKILL_CLUB] = {{0,0.5}}
skillStagesM[SKILL_SWORD] = {{0,0.5}}
skillStagesM[SKILL_AXE] = {{0,0.5}}
skillStagesM[SKILL_DISTANCE] = {{0,0.5}}
skillStagesM[SKILL_SHIELD] = {{0,3},{15,2},{25,1}}
--skillStagesM[SKILL_FISHING] = {{0,5},{60,4},{80,3},{100,2},{110,1}}
skillStagesM[SKILL__MAGLEVEL] = {{0,1.0},{20,2.0},{30,3.0},{40,1.5},{50,1},{60,0.5}}

-- Skill Stages Paladin --
skillConfigR = {skill = getConfigValue('rateSkill'), magiclevel = getConfigValue('rateMagic')}
skillStagesR = {}
skillStagesR[SKILL_FIST] = {{0,0}}
skillStagesR[SKILL_CLUB] = {{0,0.5}}
skillStagesR[SKILL_SWORD] = {{0,0.5}}
skillStagesR[SKILL_AXE] = {{0,0.5}}
skillStagesR[SKILL_DISTANCE] = {{0,3},{4,2},{9,1},{15,0.5}}
skillStagesR[SKILL_SHIELD] = {{0,3},{40,1},{60,0.5}}
--skillStagesR[SKILL_FISHING] = {{0,5},{60,4},{80,3},{100,2},{110,1}}
skillStagesR[SKILL__MAGLEVEL] = {{0,3},{4,2},{9,1},{15,0.5}}

-- Skill Stages Knight --
skillConfigW = {skill = getConfigValue('rateSkill'), magiclevel = getConfigValue('rateMagic')}
skillStagesW = {}
skillStagesW[SKILL_FIST] = {{0,0}}
skillStagesW[SKILL_CLUB] = {{0,3},{40,2},{60,1},{80,0.5}}
skillStagesW[SKILL_SWORD] = {{0,3},{40,2},{60,1},{80,0.5}}
skillStagesW[SKILL_AXE] = {{0,3},{40,2},{60,1},{80,0.5}}
skillStagesW[SKILL_DISTANCE] = {{0,0.5}}
skillStagesW[SKILL_SHIELD] = {{0,3},{40,2},{60,1},{80,0.5}}
--skillStagesW[SKILL_FISHING] = {{0,5},{60,4},{80,3},{100,2},{110,1}}
skillStagesW[SKILL__MAGLEVEL] = {{0,3},{4,2},{6,1},{9,0.5}}

-- Skill Stages Rooker (None) --
skillConfigN = {skill = getConfigValue('rateSkill'), magiclevel = getConfigValue('rateMagic')}
skillStagesN = {}
skillStagesN[SKILL_FIST] = {{0,0}}
skillStagesN[SKILL_CLUB] = {{0,5},{10,4},{15,3},{20,2},{25,1},{30,0.5}}
skillStagesN[SKILL_SWORD] = {{0,5},{10,4},{15,3},{20,2},{25,1},{30,0.5}}
skillStagesN[SKILL_AXE] = {{0,5},{10,4},{15,3},{20,2},{25,1},{30,0.5}}
skillStagesN[SKILL_DISTANCE] = {{0,5},{10,4},{15,3},{20,2},{25,1},{30,0.5}}
skillStagesN[SKILL_SHIELD] = {{0,5},{10,4},{15,3},{20,2},{25,1},{30,0.5}}
--skillStagesW[SKILL_FISHING] = {{0,5},{60,4},{80,3},{100,2},{110,1}}
skillStagesN[SKILL__MAGLEVEL] = {{0,0}}


showInfoOnAdvance = true -- send player message about skill rate change
showInfoOnLogin = true -- send player message about skill rates when he login
 
function getPlayerSkillRatesText(cid)
 local skillInfo = getPlayerRates(cid)
 if isMage(cid) then
     return "YOUR RATES: [ Magic Level: " .. skillInfo[SKILL__MAGLEVEL] * skillConfigM.magiclevel .. "x || Fist: " .. skillInfo[SKILL_FIST] * skillConfigM.skill .. "x | Club: " .. skillInfo[SKILL_CLUB] * skillConfigM.skill .. "x |  Sword: " .. skillInfo[SKILL_SWORD] * skillConfigM.skill .. "x | Axe: " .. skillInfo[SKILL_AXE] * skillConfigM.skill .. "x |  Distance: " .. skillInfo[SKILL_DISTANCE] * skillConfigM.skill .. " | Shielding: " .. skillInfo[SKILL_SHIELD] * skillConfigM.skill .. "x | Fishing: " .. skillInfo[SKILL_FISHING] * skillConfigM.skill .. "x ]"
 elseif isRanger(cid) then
     return "YOUR RATES: [ Magic Level: " .. skillInfo[SKILL__MAGLEVEL] * skillConfigR.magiclevel .. "x || Fist: " .. skillInfo[SKILL_FIST] * skillConfigR.skill .. "x | Club: " .. skillInfo[SKILL_CLUB] * skillConfigR.skill .. "x |  Sword: " .. skillInfo[SKILL_SWORD] * skillConfigR.skill .. "x | Axe: " .. skillInfo[SKILL_AXE] * skillConfigR.skill .. "x |  Distance: " .. skillInfo[SKILL_DISTANCE] * skillConfigR.skill .. " | Shielding: " .. skillInfo[SKILL_SHIELD] * skillConfigR.skill .. "x | Fishing: " .. skillInfo[SKILL_FISHING] * skillConfigR.skill .. "x ]"
 elseif isWarrior(cid) then
     return "YOUR RATES: [ Magic Level: " .. skillInfo[SKILL__MAGLEVEL] * skillConfigW.magiclevel .. "x || Fist: " .. skillInfo[SKILL_FIST] * skillConfigW.skill .. "x | Club: " .. skillInfo[SKILL_CLUB] * skillConfigW.skill .. "x |  Sword: " .. skillInfo[SKILL_SWORD] * skillConfigW.skill .. "x | Axe: " .. skillInfo[SKILL_AXE] * skillConfigW.skill .. "x |  Distance: " .. skillInfo[SKILL_DISTANCE] * skillConfigW.skill .. " | Shielding: " .. skillInfo[SKILL_SHIELD] * skillConfigW.skill .. "x | Fishing: " .. skillInfo[SKILL_FISHING] * skillConfigW.skill .. "x ]"
 elseif isRooker(cid) then
     return "YOUR RATES: [ Magic Level: " .. skillInfo[SKILL__MAGLEVEL] * skillConfigN.magiclevel .. "x || Fist: " .. skillInfo[SKILL_FIST] * skillConfigN.skill .. "x | Club: " .. skillInfo[SKILL_CLUB] * skillConfigN.skill .. "x |  Sword: " .. skillInfo[SKILL_SWORD] * skillConfigN.skill .. "x | Axe: " .. skillInfo[SKILL_AXE] * skillConfigN.skill .. "x |  Distance: " .. skillInfo[SKILL_DISTANCE] * skillConfigN.skill .. " | Shielding: " .. skillInfo[SKILL_SHIELD] * skillConfigN.skill .. "x | Fishing: " .. skillInfo[SKILL_FISHING] * skillConfigN.skill .. "x ]"
 end
end

data\creaturescripts\scripts\skillstageslogin.lua
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local voc = getPlayerVocation(cid)
    -- Mage --
    if isMage(cid) then
        for skill, skillStageM in pairs(skillStagesM) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoM in pairs(skillStageM) do
            if(nowSkill >= skillRateInfoM[1]) then
                skillRateM = skillRateInfoM[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateM)
    -- Paladin --
    elseif isRanger(cid) then
        for skill, skillStageP in pairs(skillStagesR) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoP in pairs(skillStageP) do
            if(nowSkill >= skillRateInfoP[1]) then
                skillRateP = skillRateInfoP[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateP)
    -- Knight --
    elseif isKnight(cid) then
        for skill, skillStageK in pairs(skillStagesW) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoK in pairs(skillStageK) do
            if(nowSkill >= skillRateInfoK[1]) then
                skillRateK = skillRateInfoK[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateK)
    elseif isRooker(cid) then
        for skill, skillStageN in pairs(skillStageN) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoW in pairs(skillStageN) do
            if(nowSkill >= skillRateInfoW[1]) then
                skillRateW = skillRateInfoW[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateW)
    end


    if(showInfoOnLogin) then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return TRUE
end

data\creaturescripts\scripts\skillstagesadvance.lua
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onAdvance(cid, skill, oldLevel, newLevel)
    -- Mage --
    if isMage(cid) then
        if(skillStagesM[skill] ~= nil) then
        local skillRateM = 1
        local oldRatesM = getPlayerRates(cid)
        for i, skillRateInfoM in pairs(skillStagesM[skill]) do
            if(newLevel >= skillRateInfoM[1]) then
                skillRateM = skillRateInfoM[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateM)
        if(showInfoOnAdvance and skillRateM ~= oldRatesM[skill]) then
            if(skill >= 0 and skill <= 6) then
                configRateM = skillConfigM.skill
            else
                configRateM = skillConfigM.magiclevel
            end
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, getPlayerNewSkillRatesText(cid))
        end
    -- Paladin --
    elseif isRanger(cid) then
        if(skillStagesR[skill] ~= nil) then
            local skillRateP = 1
            local oldRatesP = getPlayerRates(cid)
            for i, skillRateInfoP in pairs(skillStagesR[skill]) do
                if(newLevel >= skillRateInfoP[1]) then
                    skillRateP = skillRateInfoP[2]
                else
                    break
                end
            end
        end
        doPlayerSetRate(cid, skill, skillRateP)
        if(showInfoOnAdvance and skillRateP ~= oldRatesP[skill]) then
        if(skill >= 0 and skill <= 6) then
            configRateP = skillConfigR.skill
        else
            configRateP = skillConfigR.magiclevel
        end
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, getPlayerNewSkillRatesText(cid))
    -- Knight --
    elseif isWarrior(cid) then
        if(skillStagesW[skill] ~= nil) then
            local skillRateW = 1
            local oldRatesK = getPlayerRates(cid)
            for i, skillRateInfoW in pairs(skillStagesW[skill]) do
                if(newLevel >= skillRateInfoW[1]) then
                skillRateW = skillRateInfoW[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateW)
        if(showInfoOnAdvance and skillRateW ~= oldRatesK[skill]) then
            if(skill >= 0 and skill <= 6) then
                configRateK = skillConfigW.skill
            else
                configRateK = skillConfigW.magiclevel
            end
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, getPlayerNewSkillRatesText(cid))
        end
    end
    -- ROOKERS --
    elseif isRooker(cid) then
        if(skillStagesN[skill] ~= nil) then
            local skillRateW = 1
            local oldRatesK = getPlayerRates(cid)
            for i, skillRateInfoW in pairs(skillStagesN[skill]) do
                if(newLevel >= skillRateInfoW[1]) then
                skillRateW = skillRateInfoW[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateW)
        if(showInfoOnAdvance and skillRateW ~= oldRatesK[skill]) then
            if(skill >= 0 and skill <= 6) then
                configRateK = skillConfigN.skill
            else
                configRateK = skillConfigN.magiclevel
            end
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, getPlayerNewSkillRatesText(cid))
        end
    end
    return true
end

ERRORS:

when i try to login with a rooker (vocation 0):
Code:
[18:48:23.749] Mical has logged in.

[18:48:23.749] [Error - CreatureScript Interface] 
[18:48:23.749] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[18:48:23.749] Description: 
[18:48:23.749] data/creaturescripts/scripts/skillstageslogin.lua:57: bad argument #1 to 'pairs' (table expected, got nil)
[18:48:23.749] stack traceback:
[18:48:23.749]     [C]: in function 'pairs'
[18:48:23.749]     data/creaturescripts/scripts/skillstageslogin.lua:57: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>
[18:48:23.815] Mical has logged out.
 
Solution
For anyone coming into to this thread later and wants to use this functionality in their 0.X server
I've turned this into a mod available here:


You should not use the code below as-is because the config is very strange.

--- CAUTION: STRANGE CODE BELOW ---


I have refactored this for you. Updated: Should be complete now.

Your terrible code duplication and variable name fails aside, your biggest issue was you destroyed onLogin function by moving the doPlayerSetRate outside the outer loop. It could no longer do it's job because of this.

Lua:
function...
You delcare skillStagesN:
Lua:
skillStagesN = {}

But call skillStageN in the loop (the one in pairs bracket):
Lua:
for skill, skillStageN in pairs(skillStageN) do

skillStageN wouldn't exist as an array that would be the object/item in the array.
add the S
 
You delcare skillStagesN:
Lua:
skillStagesN = {}

But call skillStageN in the loop (the one in pairs bracket):
Lua:
for skill, skillStageN in pairs(skillStageN) do

skillStageN wouldn't exist as an array that would be the object/item in the array.
add the S

Oh fuck, sorry im too dumb on this
I've tried to change data\creaturescripts\scripts\skillstageslogin.lua to

Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local voc = getPlayerVocation(cid)
    -- Mage --
    if isMage(cid) then
        for skill, skillStagesM in pairs(skillStagesM) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoM in pairs(skillStagesM) do
            if(nowSkill >= skillRateInfoM[1]) then
                skillRateM = skillRateInfoM[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateM)
    -- Paladin --
    elseif isRanger(cid) then
        for skill, skillStagesP in pairs(skillStagesR) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoP in pairs(skillStagesP) do
            if(nowSkill >= skillRateInfoP[1]) then
                skillRateP = skillRateInfoP[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateP)
    -- Knight --
    elseif isKnight(cid) then
        for skill, skillStagesK in pairs(skillStagesW) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoK in pairs(skillStagesK) do
            if(nowSkill >= skillRateInfoK[1]) then
                skillRateK = skillRateInfoK[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateK)
    elseif isRooker(cid) then
        for skill, skillStagesN in pairs(skillStagesN) do
            if(skill >= 0 and skill <= 6) then
                nowSkill = getPlayerSkillLevel(cid, skill)
            else
                nowSkill = getPlayerMagLevel(cid, true)
            end
        end
        for i, skillRateInfoW in pairs(skillStagesN) do
            if(nowSkill >= skillRateInfoW[1]) then
                skillRateW = skillRateInfoW[2]
            else
                break
            end
        end
        doPlayerSetRate(cid, skill, skillRateW)
    end


    if(showInfoOnLogin) then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return TRUE
end

but now i got this error:
Code:
[3:12:50.346] Micha has logged in.

[3:12:50.348] [Error - CreatureScript Interface] 
[3:12:50.348] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[3:12:50.348] Description: 
[3:12:50.348] data/creaturescripts/scripts/skillstageslogin.lua:65: attempt to compare table with number
[3:12:50.348] stack traceback:
[3:12:50.348]     data/creaturescripts/scripts/skillstageslogin.lua:65: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>
[3:12:50.430] Micha has logged out.
 
For anyone coming into to this thread later and wants to use this functionality in their 0.X server
I've turned this into a mod available here:


You should not use the code below as-is because the config is very strange.

--- CAUTION: STRANGE CODE BELOW ---


I have refactored this for you. Updated: Should be complete now.

Your terrible code duplication and variable name fails aside, your biggest issue was you destroyed onLogin function by moving the doPlayerSetRate outside the outer loop. It could no longer do it's job because of this.

Lua:
function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    if(config.infoOnLogin) then
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end



new style of config with the values you provided.
notice: I believe using these values will cause problems, because you are using zero multipliers in this.
I believe you should probably not be using any values less than 0.25. I will adjust the script to account for this.

Lua:
config = {
    infoOnAdvance = true, -- send player message about skill rate change
    infoOnLogin   = true, -- send player message about skill rates when he login
    loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
    advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}

SERVER_RATE_SR = getConfigValue('rateSkill')
SERVER_RATE_ML = getConfigValue('rateMagic')

CUSTOM_RATE_STAGES = {
    -- Skill Stages Rooker (None) --
    ROOK = {
        [SKILL_FIST]      = {{ 0, 1 }},
        [SKILL_CLUB]      = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_AXE]       = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 0 }},
    },
    -- Skill Stages Mage --
    MAGE = {
        [SKILL_FIST]      = {{ 0, 1.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 15, 2.0 },{ 25, 1.0 }},
        [SKILL__MAGLEVEL] = {{ 0, 1.0 },{ 20, 2.0 },{ 30, 3.0 },{ 40, 1.5}, { 50, 1 },{ 60, 0.5 }},
    },
    -- Skill Stages Paladin --
    PALADIN = {
        [SKILL_FIST]      = {{ 0, 1.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 1 },{ 60, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
    },
    -- Skill Stages Knight --
    KNIGHT = {
        [SKILL_FIST]      = {{ 0, 1.0 }},
        [SKILL_CLUB]      = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_AXE]       = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  6, 1 },{  9, 0.5 }},
    },
    --SKILL_FISHING = {{0,5},{60,4},{80,3},{100,2},{110,1}}
}



I believe this should work, and looks cleaner.
Lua:
function getPlayerSkillRatesText(cid)
    local skillInfo = getPlayerRates(cid)
    local packed = {
        skillInfo[SKILL__MAGLEVEL] * SERVER_RATE_ML,
        skillInfo[SKILL_FIST]      * SERVER_RATE_SR,
        skillInfo[SKILL_CLUB]      * SERVER_RATE_SR,
        skillInfo[SKILL_SWORD]     * SERVER_RATE_SR,
        skillInfo[SKILL_AXE]       * SERVER_RATE_SR,
        skillInfo[SKILL_DISTANCE]  * SERVER_RATE_SR,
        skillInfo[SKILL_SHIELD]    * SERVER_RATE_SR,
        skillInfo[SKILL_FISHING]   * SERVER_RATE_SR
    }
    local message = string.format("YOUR RATES: [ Magic Level: %sx || Fist: %sx | Club: %sx |  Sword: %sx | Axe: %sx |  Distance: %s | Shielding: %sx | Fishing: %sx ]", unpack(packed))

    return message
end



Alight, here is the final piece. And I've updated the others to be consistent with more refactors.
Lua:
function onAdvance(cid, skill, oldLevel, newLevel)
    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    local function doAdvance(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        local skillRate = 1
        local oldRates = getPlayerRates(cid)

        -- gotta check cuz some are empty in the defaults like fishing
        if(classStages[skill] ~= nil) then
            for i, skillStage in pairs(classStages[skill]) do
                if(newLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            doPlayerSetRate(cid, skill, skillRate)
            if(config.infoOnAdvance and skillRate ~= oldRates[skill]) then
                local configRate = 1
                if(skill >= 0 and skill <= 6) then
                    configRate = SERVER_RATE_SR
                else
                    configRate = SERVER_RATE_ML
                end

                local message = string.format("%s rate changed from %sx to %sx. %s",
                    SKILL_NAMES[skill], oldRates[skill] * configRate, skillRate * configRate, getPlayerSkillRatesText(cid))

                doPlayerSendTextMessage(cid, config.advanceColor, message)
                -- getPlayerNewSkillRatesText(cid) ???
            end
        end
    end

    doAdvance(getClass(cid))
    return true
end

~
 
Last edited:
Solution
I have refactored this for you. Updated: Should be complete now.


Your terrible code duplication and variable name fails aside, your biggest issue was you destroyed onLogin function by moving the doPlayerSetRate outside the outer loop. It could no longer do it's job because of this.

Lua:
function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    if(config.infoOnLogin) then
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end



new style of config with the values you provided.
notice: I believe using these values will cause problems, because you are using zero multipliers in this.
I believe you should probably not be using any values less than 0.25. I will adjust the script to account for this.

Lua:
local config = {
    infoOnAdvance = true, -- send player message about skill rate change
    infoOnLogin   = true, -- send player message about skill rates when he login
    loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
    advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}

local SERVER_RATE_SR = getConfigValue('rateSkill')
local SERVER_RATE_ML = getConfigValue('rateMagic')

CUSTOM_RATE_STAGES = {
    -- Skill Stages Mage --
    MAGE = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 15, 2.0 },{ 25, 1.0 }},
        [SKILL__MAGLEVEL] = {{ 0, 1.0 },{ 20, 2.0 },{ 30, 3.0 },{ 40, 1.5}, { 50, 1 },{ 60, 0.5 }},
    },
    -- Skill Stages Paladin --
    PALADIN = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 1 },{ 60, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
    },
    -- Skill Stages Knight --
    KNIGHT = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_AXE]       = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  6, 1 },{  9, 0.5 }},
    },
    -- Skill Stages Rooker (None) --
    ROOK = {
        [SKILL_FIST]      = {{ 0, 0 }},
        [SKILL_CLUB]      = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_AXE]       = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 0 }},
    },
    --SKILL_FISHING = {{0,5},{60,4},{80,3},{100,2},{110,1}}
}



I believe this should work, and looks cleaner.
Lua:
function getPlayerSkillRatesText(cid)
    local skillInfo = getPlayerRates(cid)
    local packed = {
        skillInfo[SKILL__MAGLEVEL] * SERVER_RATE_ML,
        skillInfo[SKILL_FIST]      * SERVER_RATE_SR,
        skillInfo[SKILL_CLUB]      * SERVER_RATE_SR,
        skillInfo[SKILL_SWORD]     * SERVER_RATE_SR,
        skillInfo[SKILL_AXE]       * SERVER_RATE_SR,
        skillInfo[SKILL_DISTANCE]  * SERVER_RATE_SR,
        skillInfo[SKILL_SHIELD]    * SERVER_RATE_SR,
        skillInfo[SKILL_FISHING]   * SERVER_RATE_SR
    }
    local message = string.format("YOUR RATES: [ Magic Level: %sx || Fist: %sx | Club: %sx |  Sword: %sx | Axe: %sx |  Distance: %s | Shielding: %sx | Fishing: %sx ]", unpack(packed))

    return message
end



Alight, here is the final piece. And I've updated the others to be consistent with more refactors.
Lua:
function onAdvance(cid, skill, oldLevel, newLevel)
    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    local function doAdvance(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        local skillRate = 1
        local oldRates = getPlayerRates(cid)

        -- gotta check cuz some are empty in the defaults like fishing
        if(classStages[skill] ~= nil) then
            for i, skillStage in pairs(classStages[skill]) do
                if(newLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
            if(config.infoOnAdvance and skillRate ~= oldRates[skill]) then
                local configRate = 1
                if(skill >= 0 and skill <= 6) then
                    configRate = SERVER_RATE_SR
                else
                    configRate = SERVER_RATE_ML
                end

                local message = string.format("%s rate changed from %sx to %sx. %s",
                    SKILL_NAMES[skill], oldRates[skill] * configRate, skillRate * configRate, getPlayerSkillRatesText(cid))

                doPlayerSendTextMessage(cid, config.advanceColor, message)
                -- getPlayerNewSkillRatesText(cid) ???
            end
        end
    end

    doAdvance(getClass(cid))
    return true
end

~

LOL thank you
looks so much better

But its not work:
Code:
[19:25:09.430] Lone Druid has logged in.
[19:25:09.431] [Error - CreatureScript Interface] 
[19:25:09.431] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[19:25:09.431] Description: 
[19:25:09.431] data/creaturescripts/scripts/skillstageslogin.lua:36: Using skill stage rate multiplier less than 0.25
[19:25:09.431] stack traceback:
[19:25:09.431]     [C]: in function 'assert'
[19:25:09.431]     data/creaturescripts/scripts/skillstageslogin.lua:36: in function 'doRatings'
[19:25:09.432]     data/creaturescripts/scripts/skillstageslogin.lua:48: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>
[19:25:09.537] Lone Druid has logged out.

i had to add
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)

Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onAdvance(cid, skill, oldLevel, newLevel)

what is this:
Code:
    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

my server is a little custom, there are a lot of vocations
for example:
/lib/vocations
Code:
function isMage(cid)
    local voc = getPlayerVocation(cid)
    if voc == 3 or voc == 11 or voc == 12 or voc == 13 or voc == 14 or voc == 15 or voc == 16 or voc == 17 then
        return true
    else
        return false
    end
end
 
But its not work:
[19:25:09.431] data/creaturescripts/scripts/skillstageslogin.lua:36: Using skill stage rate multiplier less than 0.25

It told you why. Fix your configuration values. The code intentionally threw an error here.
if you use a multiplier of zero the character can no longer gain any experience in that skill


script
if isMage(cid) then return 'MAGE' end
your server
function isMage(cid) if voc == 3 or voc == 11 or voc == 12 or voc == 13 or voc == 14 or voc == 15 or voc == 16 or voc == 17 then
You can clearly see my provided code makes no assumptions about what constitutes a mage, and uses your servers customized facility. Same for the others. You shouldn't that part if you don't understand table member access methods.
 
It told you why. Fix your configuration values. The code intentionally threw an error here.
if you use a multiplier of zero the character can no longer gain any experience in that skill



You can clearly see my provided code makes no assumptions about what constitutes a mage, and uses your servers customized facility. Same for the others. You shouldn't that part if you don't understand table member access methods.

but my rates are all one on config.lua
Code:
    experienceStages = true
    rateExperience = 1.0
    rateExperienceFromPlayers = 1
    rateSkill = 1.0
    rateMagic = 1.0
    rateLoot = 1.0
    rateSpawn = 1

u was saying about this:
{{ 0, 1.0 },{ 20, 2.0 },{ 30, 3.0 },{ 40, 1.5}, { 50, 1 },{ 60, 0.5 }},
???

i would like to use 0.5 :(
 
You can use 0.5

You had some set at 0

Lua:
    MAGE = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
    },
    -- Skill Stages Paladin --
    PALADIN = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
    },
    -- Skill Stages Knight --
    KNIGHT = {
        [SKILL_FIST]      = {{ 0, 0.0 }},
    },
    -- Skill Stages Rooker (None) --
    ROOK = {
        [SKILL_FIST]      = {{ 0, 0 }},
    },

If you don't need fist, change it to 1.0 or just add -- before the [ to comment out the line.
 
what are u mean? why 0=0.5?
and where i want to set 0?

Like:

[SKILL__MAGLEVEL] = {{ 0, 0 }},

Code:
    ROOK = {
        [SKILL_FIST]      = {{ 0, 0 }},
        [SKILL_CLUB]      = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_SWORD]     = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_AXE]       = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_DISTANCE]  = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_SHIELD]    = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL__MAGLEVEL] = {{ 0, 0 }},
    },


why cant i use 0?
 
what are u mean? why 0=0.5?
and where i want to set 0?

Like:

[SKILL__MAGLEVEL] = {{ 0, 0 }},

Code:
    ROOK = {
        [SKILL_FIST]      = {{ 0, 0 }},
        [SKILL_CLUB]      = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_SWORD]     = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_AXE]       = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_DISTANCE]  = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL_SHIELD]    = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 }},
        [SKILL__MAGLEVEL] = {{ 0, 0 }},
    },

SKILL_FIST is zero.
 
SKILL_FIST is zero.

i know, but why cant i use 0?
i want to block players to get this skill

and why when i login don't shows the message on default about skills info
even with:
Code:
local config = {
    infoOnAdvance = true, -- send player message about skill rate change
    infoOnLogin   = true, -- send player message about skill rates when he login
    loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
    advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}
 
i know, but why cant i use 0? i want to block players to get this skill

🤐 nani the fuck?
If your setting of zero is actually intentional... just remove these assert lines.
assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")

I just can't presume anyone that comes along to this thread later and takes this code and just uses your bizarre configuration values would also do something so unusual and a corner case, so I work to prevent them shooting themselves in the foot.

when i login don't shows the message

That's actually a bug... You just replaced the function right? The login script still actually loads the config file? I thought it was clear I was providing the parts that changed, not drop-in replacements.
 
🤐 nani the fuck?
If your setting of zero is actually intentional... just remove these assert lines.
assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")

I just can't presume anyone that comes along to this thread later and takes this code and just uses your bizarre configuration values would also do something so unusual and a corner case, so I work to prevent them shooting themselves in the foot.

Nice! Good idea!

That's actually a bug... You just replaced the function right? The login script still actually loads the config file? I thought it was clear I was providing the parts that changed, not drop-in replacements.


I did

skillstageslogin.lua
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    if(config.infoOnLogin) then
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end

skillstagesadvace.lua
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onAdvance(cid, skill, oldLevel, newLevel)
    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    local function doAdvance(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        local skillRate = 1
        local oldRates = getPlayerRates(cid)

        -- gotta check cuz some are empty in the defaults like fishing
        if(classStages[skill] ~= nil) then
            for i, skillStage in pairs(classStages[skill]) do
                if(newLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
            if(config.infoOnAdvance and skillRate ~= oldRates[skill]) then
                local configRate = 1
                if(skill >= 0 and skill <= 6) then
                    configRate = SERVER_RATE_SR
                else
                    configRate = SERVER_RATE_ML
                end

                local message = string.format("%s rate changed from %sx to %sx. %s",
                    SKILL_NAMES[skill], oldRates[skill] * configRate, skillRate * configRate, getPlayerSkillRatesText(cid))

                doPlayerSendTextMessage(cid, config.advanceColor, message)
                -- getPlayerNewSkillRatesText(cid) ???
            end
        end
    end

    doAdvance(getClass(cid))
    return true
end

stagesconfig.lua
Code:
local config = {
    infoOnAdvance = true, -- send player message about skill rate change
    infoOnLogin   = true, -- send player message about skill rates when he login
    loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
    advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}

local SERVER_RATE_SR = getConfigValue('rateSkill')
local SERVER_RATE_ML = getConfigValue('rateMagic')

CUSTOM_RATE_STAGES = {
    -- Skill Stages Mage --
    MAGE = {
        --[SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 15, 2.0 },{ 25, 1.0 }},
        [SKILL__MAGLEVEL] = {{ 0, 1.0 },{ 20, 2.0 },{ 30, 3.0 },{ 40, 1.5}, { 50, 1 },{ 60, 0.5 }},
    },
    -- Skill Stages Paladin --
    PALADIN = {
        --[SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 0.5 }},
        [SKILL_AXE]       = {{ 0, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 1 },{ 60, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  9, 1.0 },{ 15, 0.5 }},
    },
    -- Skill Stages Knight --
    KNIGHT = {
        --[SKILL_FIST]      = {{ 0, 0.0 }},
        [SKILL_CLUB]      = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_AXE]       = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 3.0 },{ 40, 2 },{ 60, 1 },{ 80, 0.5 }},
        [SKILL__MAGLEVEL] = {{ 0, 3.0 },{  4, 2 },{  6, 1 },{  9, 0.5 }},
    },
    -- Skill Stages Rooker (None) --
    ROOK = {
        --[SKILL_FIST]      = {{ 0, 0 }},
        [SKILL_CLUB]      = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SWORD]     = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_AXE]       = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_DISTANCE]  = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        [SKILL_SHIELD]    = {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }},
        --[SKILL__MAGLEVEL] = {{ 0, 0 }},
    },
    --SKILL_FISHING = {{0,5},{60,4},{80,3},{100,2},{110,1}}
}
 
Alright, this is getting complex so changes will be in a DIFF format now. Please be smart enough to know the + and - used in diffs aren't part of the script, but indicators of how things change.

Can you add these debugging lines to your login script? See what it spits out?
Diff:
     doRatings(getClass(cid))

+    print("DEBUG: Script should have executed this far")
+    print("DEBUG: Should show info now:" .. config.infoOnLogin)

     if(config.infoOnLogin) then

+        print("DEBUG: Sending info message!")
+        print("DEBUG: text should be:" .. getPlayerSkillRatesText(cid))
         doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
     end

2-second diff tutorial:
Diff:
+    these lines are getting added!
+    these lines are getting added!
+    these lines are getting added!

     this line was already here

+        add me!
-        remove me!
         this line was also already here!
         me too!
-        remove me too!
     yep, been here

-    these lines are getting removed!
-    these lines are getting removed!
-    these lines are getting removed!

end result:
Code:
    these lines got added!
    these lines got added!
    these lines got added!

     this line was already here

         you added me!
         this line is still here!
         me too!

     yep, still here
 
Last edited:
Code:
DEBUG: Script should have executed this far

[3:38:25.199] [Error - CreatureScript Interface] 
[3:38:25.199] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[3:38:25.199] Description: 
[3:38:25.199] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to perform arithmetic on a string value
[3:38:25.199] stack traceback:
[3:38:25.199]     data/creaturescripts/scripts/skillstageslogin.lua:51: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>

Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    print("DEBUG: Script should have executed this far")
    print("DEBUG: Should show info now:" + config.infoOnLogin)

    if(config.infoOnLogin) then
        print("DEBUG: Sending info message!")
        print("DEBUG: text should be:" .. getPlayerSkillRatesText(cid))
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end
Post automatically merged:

by commenting that line of error
Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    print("DEBUG: Script should have executed this far")
    --print("DEBUG: Should show info now:" + config.infoOnLogin)

    if(config.infoOnLogin) then
        print("DEBUG: Sending info message!")
        print("DEBUG: text should be:" .. getPlayerSkillRatesText(cid))
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end

Code:
[3:40:04.236] Elite Knight has logged in.
DEBUG: Script should have executed this far
 
Oh, that one was my bad. I'm used to ducky typing from NodeJS being my daily driver. Replace the addition operator with two fullstops.
+ with ..
Then uncomment the line.

However we can clearly tell that if(config.infoOnLogin) then conditional is not executing.
 
Last edited:
Oh, that one was my bad. I'm used to ducky typing from NodeJS being my daily driver. Replace the addition operator with two fullstops.
+ with ..

It was bugging even without that

Code:
[3:52:45.789] Elite Knight has logged in.
DEBUG: Script should have executed this far

[3:52:45.790] [Error - CreatureScript Interface] 
[3:52:45.791] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[3:52:45.791] Description: 
[3:52:45.791] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to concatenate field 'infoOnLogin' (a nil value)
[3:52:45.791] stack traceback:
[3:52:45.791]     data/creaturescripts/scripts/skillstageslogin.lua:51: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>
[3:52:45.839] Elite Knight has logged out.

Code:
dofile(getDataDir() .. "creaturescripts/scripts/stagesconfig.lua")

function onLogin(cid)
    local function doRatings(class)
        local classStages = CUSTOM_RATE_STAGES[class]
        --[[
            first for loop cycles through skills
            ie: SKILL_FIST - SKILL__MAGLEVEL

            second loop cycles through the line
            ie: {{ 0, 5 },{ 10, 4 },{ 15, 3 },{ 20, 2 },{ 25, 1 },{ 30, 0.5 }}
        ]]
        for skill, stages in pairs(classStages) do
            --[[
                first loop this
                skill:  "SKILL_FIST"
                stages: {{ 0, 0.0 }}
            ]]
            local skillLevel = 0
            if(skill >= 0 and skill <= 6) then
                skillLevel = getPlayerSkillLevel(cid, skill)
            else
                -- if out of range, presume magic
                skillLevel = getPlayerMagLevel(cid, true)
            end

            -- {{0,1},{3,2},{7,4}} -> on 3rd round -> i=3; skillRateInfo = {7,4}
            local skillRate = 1
            for i, skillStage in pairs(stages) do
                if(skillLevel >= skillStage[1]) then
                    skillRate = skillStage[2]
                else
                    break
                end
            end
            assert(skillRate > 0.25, "Using skill stage rate multiplier less than 0.25")
            doPlayerSetRate(cid, skill, skillRate)
        end
    end

    local function getClass(cid)
        if isMage(cid)    then return 'MAGE'    end
        if isRanger(cid)  then return 'PALADIN' end
        if isWarrior(cid) then return 'KNIGHT'  end
        if isRooker(cid)  then return 'ROOK'    end
    end

    doRatings(getClass(cid))

    print("DEBUG: Script should have executed this far")
    print("DEBUG: Should show info now:" .. config.infoOnLogin)

    if(config.infoOnLogin) then
        print("DEBUG: Sending info message!")
        print("DEBUG: text should be:" .. getPlayerSkillRatesText(cid))
        doPlayerSendTextMessage(cid, config.loginColor, getPlayerSkillRatesText(cid))
    end
    registerCreatureEvent(cid, "SkillStagesAdvance")
    return true
end
 
Yes, that was what we actually wanted
[3:52:45.791] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to concatenate field 'infoOnLogin' (a nil value)

That part of the config wasn't making it. And that's what we needed to know.

(Only needed the error, not the whole script again man. 🤫 The whole point of diffs is to eliminate posting the same huge block of code repeatedly)

Lua has lexical scoping.
Make this change to your config
Diff:
-local config = {
+config = {
     infoOnAdvance = true, -- send player message about skill rate change
     infoOnLogin   = true, -- send player message about skill rates when he login
     loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
     advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}

-local SERVER_RATE_SR = getConfigValue('rateSkill')
-local SERVER_RATE_ML = getConfigValue('rateMagic')
+SERVER_RATE_SR = getConfigValue('rateSkill')
+SERVER_RATE_ML = getConfigValue('rateMagic')
 
Last edited:
Yes, that was what we actually wanted
[3:52:45.791] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to concatenate field 'infoOnLogin' (a nil value)

That part of the config wasn't making it. And that's what we needed to know.

(Only needed the error, not the whole script again man. 🤫 The whole point of diffs is to eliminate posting the same huge block of code repeatedly)

Lua has lexical scoping.
Make this change to your config
Diff:
-local config = {
+config = {
     infoOnAdvance = true, -- send player message about skill rate change
     infoOnLogin   = true, -- send player message about skill rates when he login
     loginColor    = MESSAGE_STATUS_CONSOLE_ORANGE,
     advanceColor  = MESSAGE_STATUS_CONSOLE_BLUE
}

-local SERVER_RATE_SR = getConfigValue('rateSkill')
-local SERVER_RATE_ML = getConfigValue('rateMagic')
+SERVER_RATE_SR = getConfigValue('rateSkill')
+SERVER_RATE_ML = getConfigValue('rateMagic')

Code:
DEBUG: Script should have executed this far

[15:30:35.232] [Error - CreatureScript Interface] 
[15:30:35.232] data/creaturescripts/scripts/skillstageslogin.lua:onLogin
[15:30:35.232] Description: 
[15:30:35.232] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to concatenate field 'infoOnLogin' (a boolean value)
[15:30:35.232] stack traceback:
[15:30:35.232]     data/creaturescripts/scripts/skillstageslogin.lua:51: in function <data/creaturescripts/scripts/skillstageslogin.lua:3>
 
[15:30:35.232] data/creaturescripts/scripts/skillstageslogin.lua:51: attempt to concatenate field 'infoOnLogin' (a boolean value)
a boolean value

That means config is getting through. Drop the debug lines and everything should be working.
 
Back
Top