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

Lua Add melee skill to skill point system

Icaraii

Well-Known Member
Joined
Jan 5, 2020
Messages
469
Solutions
1
Reaction score
58
Hi guys,

I'm trying to add melee skill to skill points system that @zbizu created, but I'm failing hard at that, can somebody help?

Here is the original script:

That's what I've tried:
Lua:
-- config
--promoted vocations included in function
local gainVoc = {
    [0] = {health = 10, mana = 10, magic = 1, skill = 1, cap = 10},
    [1] = {health = 10, mana = 10, magic = 1, skill = 1, cap = 10},
    [2] = {health = 10, mana = 10, magic = 1, skill = 1, cap = 10},
    [3] = {health = 10, mana = 10, magic = 1, skill = 1, cap = 10},
    [4] = {health = 10, mana = 10, magic = 1, skill = 1, cap = 10}
}

local skillStorage = 62490
local modalId = 4869
local TextModalId = 4870 -- so player may return to skill window
local skillPointsPerLevel = 3 -- points per level
local skillPointsAdvanceStorage = 62491 -- storage to avoid giving points twice for same level
local skillPointsTalkaction = "!points" -- so player knows command when he gets level up

local skills = {
-- name, get value, set value
    [1] = {'Health', function(player) return player:getMaxHealth() end, function(player) local gain = gainVoc[player:getBaseVocId()].health player:setMaxHealth(player:getMaxHealth() + gain) return gain end, 1},
    [2] = {'Mana', function(player) return player:getMaxMana() end, function(player) local gain = gainVoc[player:getBaseVocId()].mana player:setMaxMana(player:getMaxMana() + gain) return gain end, 1},
    [3] = {'Capacity', function(player) return player:getCapacity() / 100 end, function(player) local gain = gainVoc[player:getBaseVocId()].cap player:setCapacity(player:getCapacity() + (gain * 100)) return gain end, 1},
    [4] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 1},
    [5] = {'Fist', function(player) return player:getSkillLevel(SKILL_FIST) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FIST, gain) return gain end, 1},
    [6] = {'Club', function(player) return player:getSkillLevel(SKILL_CLUB) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_CLUB, gain) return gain end, 1},
    [7] = {'Sword', function(player) return player:getSkillLevel(SKILL_SWORD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SWORD, gain) return gain end, 1},
    [8] = {'Axe', function(player) return player:getSkillLevel(SKILL_AXE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_AXE, gain) return gain end, 1},
    [9] = {'Distance', function(player) return player:getSkillLevel(SKILL_DISTANCE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_DISTANCE, gain) return gain end, 1},
    [10] = {'Shielding', function(player) return player:getSkillLevel(SKILL_SHIELD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SHIELD, gain) return gain end, 1},
    [11] = {'Fishing', function(player) return player:getSkillLevel(SKILL_FISHING) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FISHING, gain) return gain end, 1},
    [12] = {'Melee', function(player) return player:getSkillLevel(SKILL_MELEE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_MELEE, gain) return gain end, 1}
}

local skillForVoc = {
    [0] = {1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12}, -- crusader
    [1] = {1, 2, 3, 4, 10, 11}, -- druid
    [2] = {1, 2, 3, 4, 10, 11}, -- druid
    [3] = {1, 2, 3, 4, 9, 10, 11}, -- paladin
    [4] = {1, 2, 3, 5, 6, 7, 8, 10, 11}, -- knight
}

function Player:getBaseVocId()
    local basevoc = self:getVocation():getDemotion()
    if basevoc then
        return basevoc:getId()
    end
    return self:getVocation():getId()
end

function getExpForLevel(level)
    level = level - 1
    return ((50 * level * level * level) - (150 * level * level) + (400 * level)) / 3
end

function Player:addSkillLevels(skill, count)
    count = math.max(1, count or 1)
 
    if isInArray({SKILL_FIST, SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FISHING, SKILL_MELEE}, skill) then
        for i = 1, count do
            local xp = math.ceil(self:getVocation():getRequiredSkillTries(skill, self:getSkillLevel(skill) + 1) / configManager.getNumber(configKeys.RATE_SKILL))
            self:addSkillTries(skill, xp)
        end
        return true
    end

    if skill == SKILL_MAGLEVEL then
        for i = 1, count do
            local xp = math.ceil(self:getVocation():getRequiredManaSpent(self:getBaseMagicLevel() + 1) / configManager.getNumber(configKeys.RATE_MAGIC))
            self:addManaSpent(xp)
        end
        return true
    end

    if skill == SKILL_LEVEL then
        for i = 1, count do
            local lv = self:getLevel()
            local xp = getExpForLevel(lv + 1) - getExpForLevel(lv)
            self:addExperience(xp, false)
        end
        return true
    end
    return false
end

function Player:sendSkillPointsWindow()
    local pts = self:getStorageValue(skillStorage)
    if pts < 0 then
        self:setStorageValue(skillStorage, 0)
        pts = 0
    end

    local window = ModalWindow(modalId, "Character Mastery", "Available points: [" .. pts .. "]")
    window:addButton(1, "Assign")
    window:addButton(2, "Exit")

    for i = 1, #skills do
        if isInArray(skillForVoc[self:getBaseVocId()], i) then
            window:addChoice(i, skills[i][1] .. ": [" .. skills[i][2](self) .. "][cost: " .. skills[i][4] .. "]")
        end
    end
 
    window:setDefaultEnterButton(1)
    window:setDefaultEscapeButton(2)
    window:sendToPlayer(self)
    return true
end

function Player:skillWindowChoice(windowId, buttonId, choiceId)
    if windowId == modalId then
        if buttonId == 1 then
            if not skills[choiceId] then
                local textWindow = ModalWindow(TextModalId, "Error", "No skill selected.")
                textWindow:addButton(1, "Ok")
                textWindow:setDefaultEnterButton(1)
                textWindow:setDefaultEscapeButton(1)
                textWindow:sendToPlayer(self)
                return true
            end
            local pts = self:getStorageValue(skillStorage)
            if pts < 0 then
                self:setStorageValue(skillStorage, 0)
                pts = 0
            end
         
            if pts - skills[choiceId][4] >= 0 then
                local textWindow = ModalWindow(TextModalId, "Point assigned.", skills[choiceId][1] .. " +" .. skills[choiceId][3](self))
                textWindow:addButton(1, "Ok")
                textWindow:setDefaultEnterButton(1)
                textWindow:setDefaultEscapeButton(1)
                textWindow:sendToPlayer(self)
                self:setStorageValue(skillStorage, pts - skills[choiceId][4])
                return true
            end

            local textWindow = ModalWindow(TextModalId, "Error", "Not enough points")
            textWindow:addButton(1, "Ok")
            textWindow:setDefaultEnterButton(1)
            textWindow:setDefaultEscapeButton(1)
            textWindow:sendToPlayer(self)
            return true
        end
        return false
    end
 
    if not (windowId == TextModalId) then
        return false
    end
     
    self:sendSkillPointsWindow()
    return false
end

function Player:addSkillPoints(count)
    count = math.max(1, count or 1)
 
    local pts = self:getStorageValue(skillStorage)
    if pts < 0 then
        self:setStorageValue(skillStorage, 0)
        pts = 0
    end
 
    return self:setStorageValue(skillStorage, pts + count)
end

function Player:skillPointsAdvance(nlevel)
    if self:getStorageValue(skillPointsAdvanceStorage) < nlevel then
        self:addSkillPoints(skillPointsPerLevel)
        self:setStorageValue(skillPointsAdvanceStorage, nlevel)
        self:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "New skill points available. Type " .. skillPointsTalkaction .. " to open character mastery window.")
    end
    return true
end


It would be even better if the player could choose skill and receive 1 sword, axe, club, first, magic level and distance skill, is that possible?
 
Last edited:
C++ code needed to be edited and compiled anew
I'm sorry if I couldn't be that clear, but what I would like is to edit the script above to add the option for the player to choose melee skill when he levels up. In the original script, there is no option for the player to choose melee skill:
Lua:
local skills = {
-- name, get value, set value
    [1] = {'Health', function(player) return player:getMaxHealth() end, function(player) local gain = gainVoc[player:getBaseVocId()].health player:setMaxHealth(player:getMaxHealth() + gain) return gain end, 10},
    [2] = {'Mana', function(player) return player:getMaxMana() end, function(player) local gain = gainVoc[player:getBaseVocId()].mana player:setMaxMana(player:getMaxMana() + gain) return gain end, 10},
    [3] = {'Capacity', function(player) return player:getCapacity() / 100 end, function(player) local gain = gainVoc[player:getBaseVocId()].cap player:setCapacity(player:getCapacity() + (gain * 100)) return gain end, 10},
    [4] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 10},
    [5] = {'Fist', function(player) return player:getSkillLevel(SKILL_FIST) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FIST, gain) return gain end, 10},
    [6] = {'Club', function(player) return player:getSkillLevel(SKILL_CLUB) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_CLUB, gain) return gain end, 10},
    [7] = {'Sword', function(player) return player:getSkillLevel(SKILL_SWORD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SWORD, gain) return gain end, 10},
    [8] = {'Axe', function(player) return player:getSkillLevel(SKILL_AXE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_AXE, gain) return gain end, 10},
    [9] = {'Distance', function(player) return player:getSkillLevel(SKILL_DISTANCE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_DISTANCE, gain) return gain end, 10},
    [10] = {'Shielding', function(player) return player:getSkillLevel(SKILL_SHIELD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SHIELD, gain) return gain end, 10},
    [11] = {'Fishing', function(player) return player:getSkillLevel(SKILL_FISHING) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FISHING, gain) return gain end, 10}
}
I tried to put:
Code:
local skills = {
-- name, get value, set value
    [1] = {'Health', function(player) return player:getMaxHealth() end, function(player) local gain = gainVoc[player:getBaseVocId()].health player:setMaxHealth(player:getMaxHealth() + gain) return gain end, 1},
    [2] = {'Mana', function(player) return player:getMaxMana() end, function(player) local gain = gainVoc[player:getBaseVocId()].mana player:setMaxMana(player:getMaxMana() + gain) return gain end, 1},
    [3] = {'Capacity', function(player) return player:getCapacity() / 100 end, function(player) local gain = gainVoc[player:getBaseVocId()].cap player:setCapacity(player:getCapacity() + (gain * 100)) return gain end, 1},
    [4] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 1},
    [5] = {'Fist', function(player) return player:getSkillLevel(SKILL_FIST) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FIST, gain) return gain end, 1},
    [6] = {'Club', function(player) return player:getSkillLevel(SKILL_CLUB) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_CLUB, gain) return gain end, 1},
    [7] = {'Sword', function(player) return player:getSkillLevel(SKILL_SWORD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SWORD, gain) return gain end, 1},
    [8] = {'Axe', function(player) return player:getSkillLevel(SKILL_AXE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_AXE, gain) return gain end, 1},
    [9] = {'Distance', function(player) return player:getSkillLevel(SKILL_DISTANCE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_DISTANCE, gain) return gain end, 1},
    [10] = {'Shielding', function(player) return player:getSkillLevel(SKILL_SHIELD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SHIELD, gain) return gain end, 1},
    [11] = {'Fishing', function(player) return player:getSkillLevel(SKILL_FISHING) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FISHING, gain) return gain end, 1},
    [12] = {'Melee', function(player) return player:getSkillLevel(SKILL_MELEE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_MELEE, gain) return gain end, 1}
}

But that didn't work.

no i think he mean that when a player picks 'melee' it levels up all 3 of the melee skills in a one go
or instead if players pick 'skill' it levels all skills in a one go
That is what I need. I have a custom server where there's a single vocarion and player can use up to 9 different weapon types, so the problem with that is that player would have to lvl up sword skill, axe, skill, club skill all together or the solution I came up with is to put all close combat into fist skill and all ranged combat into distance skill, and that solved my problema. I set up all the close combat weapons to use fist skill and all the ranged combat weapons to use distance skill.
 
Lua:
local skills = {
-- name, get value, set value
    [1] = {'Health', function(player) return player:getMaxHealth() end, function(player) local gain = gainVoc[player:getBaseVocId()].health player:setMaxHealth(player:getMaxHealth() + gain) return gain end, 1},
    [2] = {'Mana', function(player) return player:getMaxMana() end, function(player) local gain = gainVoc[player:getBaseVocId()].mana player:setMaxMana(player:getMaxMana() + gain) return gain end, 1},
    [3] = {'Capacity', function(player) return player:getCapacity() / 100 end, function(player) local gain = gainVoc[player:getBaseVocId()].cap player:setCapacity(player:getCapacity() + (gain * 100)) return gain end, 1},
    [4] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 1},
    [5] = {'Fist', function(player) return player:getSkillLevel(SKILL_FIST) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FIST, gain) return gain end, 1},
    [6] = {'Club', function(player) return player:getSkillLevel(SKILL_CLUB) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_CLUB, gain) return gain end, 1},
    [7] = {'Sword', function(player) return player:getSkillLevel(SKILL_SWORD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SWORD, gain) return gain end, 1},
    [8] = {'Axe', function(player) return player:getSkillLevel(SKILL_AXE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_AXE, gain) return gain end, 1},
    [9] = {'Distance', function(player) return player:getSkillLevel(SKILL_DISTANCE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_DISTANCE, gain) return gain end, 1},
    [10] = {'Shielding', function(player) return player:getSkillLevel(SKILL_SHIELD) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_SHIELD, gain) return gain end, 1},
    [11] = {'Fishing', function(player) return player:getSkillLevel(SKILL_FISHING) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_FISHING, gain) return gain end, 1},
    [12] = {'Melee', function(player) return player:getSkillLevel(SKILL_MELEE) end, function(player) local gain = gainVoc[player:getBaseVocId()].skill player:addSkillLevels(SKILL_MELEE, gain) return gain end, 1},
}

find:
Code:
if isInArray({SKILL_FIST, SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FISHING}, skill) then
replace with:
Code:
if isInArray({SKILL_FIST, SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FISHING, SKILL_MELEE}, skill) then
 
if isInArray({SKILL_FIST, SKILL_CLUB, SKILL_SWORD, SKILL_AXE, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FISHING, SKILL_MELEE}, skill) then
I've done that before I post it here and doesn't work, and I have no idea why. The new skill (melee skill) appears on the model window, but when I spend point into melee skill it just take my points and doesn't give any skill level.
 
I've done that before I post it here and doesn't work, and I have no idea why. The new skill (melee skill) appears on the model window, but when I spend point into melee skill it just take my points and doesn't give any skill level.
maybe you can make club/axe/sword into swords in items.xml then

renaming them to show as melee

so players can pick melee, magic or distance
 
I've done that before I post it here and doesn't work, and I have no idea why. The new skill (melee skill) appears on the model window, but when I spend point into melee skill it just take my points and doesn't give any skill level.
Make sure you have registered SKILL_MELEE in luascripts, in general i would check at ur place SKILL_MELEE condition - to make sure its not a server issue
 
Back
Top