• 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 Vocation based skillpoint system!

calveron

Bravemansworld
Joined
Feb 5, 2008
Messages
165
Reaction score
13
Location
Sweden
Hey, so Im using zbizu's modal skillpoint system and Im trying to change it so that depending on your vocation, you can only increase certain skills. Here's the full script
Code:
-- config
--promoted vocations included in function
local gainVoc = {
    [0] = {health = 0, mana = 0, magic = 0, skill = 0, cap = 0},
    [1] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
    [2] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
    [3] = {health = 6, mana = 6, magic = 0, skill = 1, cap = 5},
    [4] = {health = 10, mana = 0, magic = 0, skill = 1, cap = 10}
}

local skillStorage = 62490
local modalId = 4869
local TextModalId = 4870 -- so player may return to skill window
local skillPointsPerLevel = 1 -- points per level
local skillPointsAdvanceStorage = 62491 -- storage to avoid giving points twice for same level
local skillPointsTalkaction = "skillbook" -- 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] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 2},
    [4] = {'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, 2},
    [5] = {'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, 2},
    [6] = {'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, 2},
    [7] = {'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, 2},
    [8] = {'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, 2}
    }

function Player.getBaseVocId(self)
    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(self, 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) 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(self)
    local pts = self:getStorageValue(skillStorage)
    if pts < 0 then
        self:setStorageValue(skillStorage, 0)
        pts = 0
    end

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

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

function Player.skillWindowChoice(self, windowId, buttonId, choiceId)
    if windowId == modalId then
        if buttonId == 1 then
            local pts = self:getStorageValue(skillStorage)
            if pts < 0 then
                self:setStorageValue(skillStorage, pts - skills[i][4])
                pts = 0
            end
           
            if pts - skills[choiceId][4] >= 0 then
                local textWindow = ModalWindow(TextModalId, "skill 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(self, 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(self, nlevel)
    if self:getStorageValue(skillPointsAdvanceStorage) < nlevel then
        self:addSkillPoints(skillPointsPerLevel)
        self:setStorageValue(skillPointsAdvanceStorage, nlevel)
        self:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "New skill points available. Open your" .. skillPointsTalkaction .. " to asign your new skill point.")
    end
    return true
end

Zbizu was kind enough to show what functions to add but I honestly dont have any clue where to put them, I tried some stuff but nope :p.
Find this:
Code:
    for i = 1, #skills do
        window:addChoice(i, skills[i][1] .. ": [" .. skills[i][2](self) .. "]")
    end

Above addChoice put if isIArray(table, i) then
-- addChoice
end

Funcions you will need:
isInArray(table[voc], i)
player:getVocation():getId()
table = {
[vocid] = {statid1, statid2}
}

If any kind soul out there would help with this I would be extremely glad!
 
Try this..
I green texted the parts I changed.. and I can only hope it works.
I'm not a great scripter. :p

Code:
-- config
--promoted vocations included in function
local gainVoc = {
  [0] = {health = 0, mana = 0, magic = 0, skill = 0, cap = 0},
  [1] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
  [2] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
  [3] = {health = 6, mana = 6, magic = 0, skill = 1, cap = 5},
  [4] = {health = 10, mana = 0, magic = 0, skill = 1, cap = 10}
}

local skillStorage = 62490
local modalId = 4869
local TextModalId = 4870 -- so player may return to skill window
local skillPointsPerLevel = 1 -- points per level
local skillPointsAdvanceStorage = 62491 -- storage to avoid giving points twice for same level
local skillPointsTalkaction = "skillbook" -- 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] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 2},
  [4] = {'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, 2},
  [5] = {'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, 2},
  [6] = {'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, 2},
  [7] = {'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, 2},
  [8] = {'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, 2}
  }
  
   -- edited this part v
function isInArray(table[voc], i)
   player:getVocation():getId()
   table = {
     [0] = {1, 2}, -- 1 = health, 2 = mana, 3 = magic, et cetera. it's all above.
     [1] = {1, 2, 4, 5, 6, 8}, -- knight?
     [2] = {1, 2, 3, 7, 8}, -- paladin?
     [3] = {1, 2, 3, 8}, -- sorcerer?
     [4] = {1, 2, 3, 8} -- druid?
   }
end
   -- edited this part ^

function Player.getBaseVocId(self)
  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(self, 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) 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(self)
  local pts = self:getStorageValue(skillStorage)
  if pts < 0 then
  self:setStorageValue(skillStorage, 0)
  pts = 0
  end

  local window = ModalWindow(modalId, "Skillbook", "Available skillpoints: [" .. pts .. "]")
  window:addButton(1, "Assign")
  window:addButton(2, "Exit")
  
   -- edited this part v
   if isInArray(table, i) then
     for i = 1, #skills do
       window:addChoice(i, skills[i][1] .. ": [" .. skills[i][2](self) .. "]")
     end
   end
   -- edited this part ^
  
  window:setDefaultEnterButton(1)
  window:setDefaultEscapeButton(2)
  window:sendToPlayer(self)
  return true
end

function Player.skillWindowChoice(self, windowId, buttonId, choiceId)
  if windowId == modalId then
  if buttonId == 1 then
  local pts = self:getStorageValue(skillStorage)
  if pts < 0 then
  self:setStorageValue(skillStorage, pts - skills[i][4])
  pts = 0
  end
  
  if pts - skills[choiceId][4] >= 0 then
  local textWindow = ModalWindow(TextModalId, "skill 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(self, 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(self, nlevel)
  if self:getStorageValue(skillPointsAdvanceStorage) < nlevel then
  self:addSkillPoints(skillPointsPerLevel)
  self:setStorageValue(skillPointsAdvanceStorage, nlevel)
  self:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "New skill points available. Open your" .. skillPointsTalkaction .. " to asign your new skill point.")
  end
  return true
end

Unsure of the vocation id's, so take care when editing.
 
Hm, small error:
data/sp.lua:31: ') expected near '['

It would appear to be because voc is undefined. I would try to replace on that line voc with player:getBaseVocId() and see if that works... Here I did it for you, see if that works.


Code:
-- config
--promoted vocations included in function
local gainVoc = {
  [0] = {health = 0, mana = 0, magic = 0, skill = 0, cap = 0},
  [1] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
  [2] = {health = 0, mana = 10, magic = 1, skill = 0, cap = 0},
  [3] = {health = 6, mana = 6, magic = 0, skill = 1, cap = 5},
  [4] = {health = 10, mana = 0, magic = 0, skill = 1, cap = 10}
}

local skillStorage = 62490
local modalId = 4869
local TextModalId = 4870 -- so player may return to skill window
local skillPointsPerLevel = 1 -- points per level
local skillPointsAdvanceStorage = 62491 -- storage to avoid giving points twice for same level
local skillPointsTalkaction = "skillbook" -- 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] = {'Magic', function(player) return player:getBaseMagicLevel() end, function(player) local gain = gainVoc[player:getBaseVocId()].magic player:addSkillLevels(SKILL_MAGLEVEL, gain) return gain end, 2},
  [4] = {'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, 2},
  [5] = {'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, 2},
  [6] = {'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, 2},
  [7] = {'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, 2},
  [8] = {'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, 2}
  }
 
   -- edited this part v
function isInArray(table[player:getBaseVocId()], i)
   player:getVocation():getId()
   table = {
     [0] = {1, 2}, -- 1 = health, 2 = mana, 3 = magic, et cetera. it's all above.
     [1] = {1, 2, 4, 5, 6, 8}, -- knight?
     [2] = {1, 2, 3, 7, 8}, -- paladin?
     [3] = {1, 2, 3, 8}, -- sorcerer?
     [4] = {1, 2, 3, 8} -- druid?
   }
end
   -- edited this part ^

function Player.getBaseVocId(self)
  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(self, 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) 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(self)
  local pts = self:getStorageValue(skillStorage)
  if pts < 0 then
  self:setStorageValue(skillStorage, 0)
  pts = 0
  end

  local window = ModalWindow(modalId, "Skillbook", "Available skillpoints: [" .. pts .. "]")
  window:addButton(1, "Assign")
  window:addButton(2, "Exit")
 
   -- edited this part v
   if isInArray(table, i) then
     for i = 1, #skills do
       window:addChoice(i, skills[i][1] .. ": [" .. skills[i][2](self) .. "]")
     end
   end
   -- edited this part ^
 
  window:setDefaultEnterButton(1)
  window:setDefaultEscapeButton(2)
  window:sendToPlayer(self)
  return true
end

function Player.skillWindowChoice(self, windowId, buttonId, choiceId)
  if windowId == modalId then
  if buttonId == 1 then
  local pts = self:getStorageValue(skillStorage)
  if pts < 0 then
  self:setStorageValue(skillStorage, pts - skills[i][4])
  pts = 0
  end
 
  if pts - skills[choiceId][4] >= 0 then
  local textWindow = ModalWindow(TextModalId, "skill 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(self, 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(self, nlevel)
  if self:getStorageValue(skillPointsAdvanceStorage) < nlevel then
  self:addSkillPoints(skillPointsPerLevel)
  self:setStorageValue(skillPointsAdvanceStorage, nlevel)
  self:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "New skill points available. Open your" .. skillPointsTalkaction .. " to asign your new skill point.")
  end
  return true
end
 
error.png

same thing :eek:
 
Sorry man I'm at school, got crap for text editor, probably a open ( somewhere before that line... idk, but I am also skeptical if his edit would work, because he overwrites a premade function, but I don't see it return anything, and I'm not sure if it will still return or not when you overwrite a premade function that does have a return... Not really sure...
 
Back
Top