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

Different starting level, health, mana, and townID based on player vocation

X X X

Newb
Joined
Jul 26, 2015
Messages
148
Reaction score
13
Hello,
I am using TFS 1.2 and I am wondering how I can add a script that can start players at level one but have them spawn in different areas based on their chosen vocation. I also want to scale health, mana and cap per vocation separately and want each vocation to start with different amounts of health/mana/cap. How can I do this?

Thanks!
 
Solution
Code:
function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

Thank you. I'm guessing I would add something after LastLoginSaved() <= 0 that gets players vocations and from there sets their max health/mana/townID/cap.

Could...
Hello,
I am using TFS 1.2 and I am wondering how I can add a script that can start players at level one but have them spawn in different areas based on their chosen vocation. I also want to scale health, mana and cap per vocation separately and want each vocation to start with different amounts of health/mana/cap. How can I do this?

Thanks!
All of this can be done in onLogin. Vocations.xml handles values they gain as they level but in onLogin you can set the starting position, temple, max hp/mana & maybe even cap for each vocation. You'll find login.lua inside of creaturescripts/scripts

That script will give you an idea on how to tackle these concepts. You don't need to write everything in that script you can create a separate onLogin script and then register the creature event in login.lua and placing an entry in creaturescripts.xml
 
Last edited:
All of this can be done in onLogin. Vocations.xml handles values they gain as they level but in onLogin you can set the starting position, temple, max hp/mana & maybe even cap for each vocation. You'll find login.lua inside of creaturescripts/scripts

That script will give you an idea on how to tackle these concepts. You don't need to write everything in that script you can create a separate onLogin script and then register the creature event in login.lua and placing an entry in creaturescripts.xml

Code:
function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

Thank you. I'm guessing I would add something after LastLoginSaved() <= 0 that gets players vocations and from there sets their max health/mana/townID/cap.

Could someone show me an example of what one vocation would look like so I can do the rest? Something like ifVocationID = 1, setmaxhealth=X, setmaxmana=X, settownID=X, setmaxcap=X.

Thank you so much for your guys help!
 
Code:
function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

Thank you. I'm guessing I would add something after LastLoginSaved() <= 0 that gets players vocations and from there sets their max health/mana/townID/cap.

Could someone show me an example of what one vocation would look like so I can do the rest? Something like ifVocationID = 1, setmaxhealth=X, setmaxmana=X, settownID=X, setmaxcap=X.

Thank you so much for your guys help!
Here's the login script, you can adjust the vocations table to fit what you need for each vocation.
Lua:
local vocations = {
    [1] = {town_id = 1, max_health = 100, max_mana = 100, max_cap = 100},  -- Sorcerer
    [2] = {town_id = 2, max_health = 100, max_mana = 100, max_cap = 100},  -- Druid
    [3] = {town_id = 3, max_health = 100, max_mana = 100, max_cap = 100},  -- Paladin
    [4] = {town_id = 4, max_health = 100, max_mana = 100, max_cap = 100}   -- Knight
}

function onLogin(player)
    if player:getLastLoginSaved() > 0 or player:getLevel() > 1 then
        return true
    end

    local vocation_id = player:getVocation():getId()
    if not vocations[vocation_id] then
        return true
    end

    player:setMaxHealth(vocations[vocation_id].max_health)
    player:setMaxMana(vocations[vocation_id].max_mana)
    player:setCapacity(vocations[vocation_id].max_cap)

    local town = Town(vocations[vocation_id].town_id)
    local temple_pos = town:getTemplePosition()
    player:setTown(town)
    player:teleportTo(temple_pos)
    temple_pos:sendMagicEffect(CONST_ME_TELEPORT)
    return true
end
If the player is starting at level 8 and you want it to set back to one, then this is best done within your website files or wherever is creating the character. However if you cannot figure it out, you can do this:

Change:
player:getLevel() > 1
To this, or whatever level your players are starting at before adjustment:
player:getLevel() > 8
Add before setMaxHealth:
player:addExperience(-player:getExperience())

Everything else for scaling as they level up is handled within vocations.xml.
Example:
XML:
gaincap="10" gainhp="5" gainmana="30"
 
Last edited:
Solution
Here's the login script, you can adjust the vocations table to fit what you need for each vocation.

If the player is starting at level 8 and you want it to set back to one, then this is best done within your website files or wherever is creating the character. However if you cannot figure it out, you can do this:

Change:
player:getLevel() > 1
To this, or whatever level your players are starting at before adjustment:
player:getLevel() > 8
Add before setMaxHealth:
player:addExperience(-player:getExperience())

Everything else for scaling as they level up is handled within vocations.xml.
Example:
XML:
gaincap="10" gainhp="5" gainmana="30"

Thank you for this. However, I think I'm still getting interference from the config.php part of my website, and it automatically start players with the stats in there.
Code:
    $config['player'] = array(
        'base' => array(
            'level' => 1,
            'health' => 155,
            'mana' =35> ,
            'cap' => 415,
            'soul' => 100
        ),
I tried deleting the lines, but it still starts characters with whatever was in there last, regardless of vocation.

How can I make it prioritize my login.lua? Here is my login.lua, I added exactly what you gave me:

Code:
local vocations = {
    [1] = {town_id = 1, max_health = 45, max_mana = 5, max_cap = 425},  -- Sorcerer
    [2] = {town_id = 2, max_health = 100, max_mana = 100, max_cap = 100},  -- Druid
    [3] = {town_id = 3, max_health = 100, max_mana = 100, max_cap = 100},  -- Paladin
    [4] = {town_id = 4, max_health = 100, max_mana = 100, max_cap = 100}   -- Knight
}

function onLogin(player)
    if player:getLastLoginSaved() > 0 or player:getLevel() > 1 then
        return true
    end

    local vocation_id = player:getVocation():getBase():getId()
    if not vocations[vocation_id] then
        return true
    end

    player:setMaxHealth(vocations[vocation_id].max_health)
    player:setMaxMana(vocations[vocation_id].max_mana)
    player:setCapacity(vocations[vocation_id].max_cap)

    local town = Town(vocations[vocation_id].town_id)
    local temple_pos = town:getTemplePosition()
    player:setTown(town)
    player:teleportTo(temple_pos)
    temple_pos:sendMagicEffect(CONST_ME_TELEPORT)
    return true
end

function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

    -- Stamina
    nextUseStaminaTime[player.uid] = 0

    -- Promotion
    local vocation = player:getVocation()
    local promotion = vocation:getPromotion()
    if player:isPremium() then
        local value = player:getStorageValue(STORAGEVALUE_PROMOTION)
        if not promotion and value ~= 1 then
            player:setStorageValue(STORAGEVALUE_PROMOTION, 1)
        elseif value == 1 then
            player:setVocation(promotion)
        end
    elseif not promotion then
        player:setVocation(vocation:getDemotion())
    end

    -- Events
    player:registerEvent("PlayerDeath")
    player:registerEvent("DropLoot")
    return true
end
 
Thank you for this. However, I think I'm still getting interference from the config.php part of my website, and it automatically start players with the stats in there.
Code:
    $config['player'] = array(
        'base' => array(
            'level' => 1,
            'health' => 155,
            'mana' =35> ,
            'cap' => 415,
            'soul' => 100
        ),
I tried deleting the lines, but it still starts characters with whatever was in there last, regardless of vocation.

How can I make it prioritize my login.lua? Here is my login.lua, I added exactly what you gave me:

Code:
local vocations = {
    [1] = {town_id = 1, max_health = 45, max_mana = 5, max_cap = 425},  -- Sorcerer
    [2] = {town_id = 2, max_health = 100, max_mana = 100, max_cap = 100},  -- Druid
    [3] = {town_id = 3, max_health = 100, max_mana = 100, max_cap = 100},  -- Paladin
    [4] = {town_id = 4, max_health = 100, max_mana = 100, max_cap = 100}   -- Knight
}

function onLogin(player)
    if player:getLastLoginSaved() > 0 or player:getLevel() > 1 then
        return true
    end

    local vocation_id = player:getVocation():getBase():getId()
    if not vocations[vocation_id] then
        return true
    end

    player:setMaxHealth(vocations[vocation_id].max_health)
    player:setMaxMana(vocations[vocation_id].max_mana)
    player:setCapacity(vocations[vocation_id].max_cap)

    local town = Town(vocations[vocation_id].town_id)
    local temple_pos = town:getTemplePosition()
    player:setTown(town)
    player:teleportTo(temple_pos)
    temple_pos:sendMagicEffect(CONST_ME_TELEPORT)
    return true
end

function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

    -- Stamina
    nextUseStaminaTime[player.uid] = 0

    -- Promotion
    local vocation = player:getVocation()
    local promotion = vocation:getPromotion()
    if player:isPremium() then
        local value = player:getStorageValue(STORAGEVALUE_PROMOTION)
        if not promotion and value ~= 1 then
            player:setStorageValue(STORAGEVALUE_PROMOTION, 1)
        elseif value == 1 then
            player:setVocation(promotion)
        end
    elseif not promotion then
        player:setVocation(vocation:getDemotion())
    end

    -- Events
    player:registerEvent("PlayerDeath")
    player:registerEvent("DropLoot")
    return true
end
This new one needs to be in a separate script than the original onLogin, you can have multiple onLogin creaturescripts as long as you link to each of them separately in creaturescripts.xml.
 
When I first tried this I got this error on line 13:
Code:
    local vocation_id = player:getVocation():getBase():getId()
With getBase() as a NULL value. So I just removed the getBase() part and it appears to be working! Thank you so much for the help, I appreciate it so much :)
 
Back
Top