• 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 TFS 1.3, downgrade level on player command

Joriku

Working in the mines, need something?
Joined
Jul 16, 2016
Messages
1,085
Solutions
15
Reaction score
379
Location
Sweden
YouTube
Joriku
Hello,
Would It be possible to create a script that has a usage of /downgrade playername and it sets the player to level 8 with 10 on each skill?
 
Hmm for level

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

Lua:
    -- Set Level 100
    player:addExperience(getExpForLevel(100) - player:getExperience(), false)

    -- Set Level 8
    player:removeExperience(player:getExperience() - getExpForLevel(8), false)

For remove skills i think you need modify the sources for new functions or ex query but player neet to logout
 
Last edited:
Hmm for level

Lua:
    -- Set Level 100
    player:addExperience(getExpForLevel(100) - player:getExperience(), false)

    -- Set Level 8
    player:removeExperience(player:getExperience() - getExpForLevel(8), false)

For remove skills i think you need modify the sources for new functions or ex query but player neet to logout
Not Possible to make it able to be at login aswell?
 
Not Possible to make it able to be at login aswell?

Yeah, just add that to your login script.

Lua:
db.asyncQuery("UPDATE `players` SET `skill_sword` = 10, `skill_fist` = 10, `skill_club` = 10, `skill_sword` = 10, `skill_axe` = 10, `skill_dist` = 10, `skill_shielding` = 10, `skill_fishing` = 10, `skill_fist_tries` = 0, `skill_club_tries` = 0, `skill_sword_tries` = 0, `skill_axe_tries` = 0, `skill_dist_tries` = 0, `skill_fishing_tries` = 0, `skill_shielding_tries` = 0, `level` = 8, `experience` = 4200 WHERE `id` = " .. player:getId())

Wont work if they're online though
 
If you know how modify the sources try this...

in src/player.cpp add this:
C++:
void Player::setMagiclevel(uint64_t newMagicLevel)
{
    magLevel = newMagicLevel;
    manaSpent = 0;

    uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);

    if (nextReqMana > vocation->getReqMana(magLevel)) {
        magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana);
    } else {
        magLevelPercent = 0;
    }

    sendStats();
}

void Player::setSkillLevel(uint64_t skillType, uint64_t newSkillLevel) {
    skills[skillType].level = newSkillLevel;
    skills[skillType].tries = 0;
    skills[skillType].percent = Player::getPercentLevel(skills[skillType].tries, vocation->getReqSkillTries(skillType, skills[skillType].level));

    sendSkills();
}

in src/player.h add this:
C++:
void setMagiclevel(uint64_t newMagicLevel);
void setSkillLevel(uint64_t skillType, uint64_t newSkillLevel);

in src/luascript.cpp add this:
C++:
registerMethod("Player", "setMagiclevel", LuaScriptInterface::luaPlayerSetMagiclevel);
registerMethod("Player", "setSkillLevel", LuaScriptInterface::luaPlayerSetSkillLevel);

C++:
int LuaScriptInterface::luaPlayerSetMagiclevel(lua_State* L)
{
    // player:setMagiclevel()
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        int64_t newMagicLevel = getNumber<int64_t>(L, 2);
        player->setMagiclevel(newMagicLevel);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaPlayerSetSkillLevel(lua_State* L)
{
    // player:setSkillLevel()
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        int64_t skillType = getNumber<int64_t>(L, 2);
        int64_t newSkillLevel = getNumber<int64_t>(L, 3);
        player->setSkillLevel(skillType, newSkillLevel);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

in src/luascript.h add this:
C++:
static int luaPlayerSetMagiclevel(lua_State* L);
static int luaPlayerSetSkillLevel(lua_State* L);

Now in lua youcan use this functions for example:

Lua:
local ml = 8
local swordSkill = 30
local shieldSkill = 20

player:setMagiclevel(ml)
player:setSkillLevel(SKILL_SWORD, swordSkill)
player:setSkillLevel(SKILL_SHIELD, shieldSkill)
 
Yeah, just add that to your login script.

Lua:
db.asyncQuery("UPDATE `players` SET `skill_sword` = 10, `skill_fist` = 10, `skill_club` = 10, `skill_sword` = 10, `skill_axe` = 10, `skill_dist` = 10, `skill_shielding` = 10, `skill_fishing` = 10, `skill_fist_tries` = 0, `skill_club_tries` = 0, `skill_sword_tries` = 0, `skill_axe_tries` = 0, `skill_dist_tries` = 0, `skill_fishing_tries` = 0, `skill_shielding_tries` = 0, `level` = 8, `experience` = 4200 WHERE `id` = " .. player:getId())

Wont work if they're online though
Would It be possible to make it for a demotion once talkaction is thru. I mean, once they're online. If they're offline than the command Is useless
If you know how modify the sources try this...

in src/player.cpp add this:
C++:
void Player::setMagiclevel(uint64_t newMagicLevel)
{
    magLevel = newMagicLevel;
    manaSpent = 0;

    uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);

    if (nextReqMana > vocation->getReqMana(magLevel)) {
        magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana);
    } else {
        magLevelPercent = 0;
    }

    sendStats();
}

void Player::setSkillLevel(uint64_t skillType, uint64_t newSkillLevel) {
    skills[skillType].level = newSkillLevel;
    skills[skillType].tries = 0;
    skills[skillType].percent = Player::getPercentLevel(skills[skillType].tries, vocation->getReqSkillTries(skillType, skills[skillType].level));

    sendSkills();
}

in src/player.h add this:
C++:
void setMagiclevel(uint64_t newMagicLevel);
void setSkillLevel(uint64_t skillType, uint64_t newSkillLevel);

in src/luascript.cpp add this:
C++:
registerMethod("Player", "setMagiclevel", LuaScriptInterface::luaPlayerSetMagiclevel);
registerMethod("Player", "setSkillLevel", LuaScriptInterface::luaPlayerSetSkillLevel);

C++:
int LuaScriptInterface::luaPlayerSetMagiclevel(lua_State* L)
{
    // player:setMagiclevel()
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        int64_t newMagicLevel = getNumber<int64_t>(L, 2);
        player->setMagiclevel(newMagicLevel);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaPlayerSetSkillLevel(lua_State* L)
{
    // player:setSkillLevel()
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        int64_t skillType = getNumber<int64_t>(L, 2);
        int64_t newSkillLevel = getNumber<int64_t>(L, 3);
        player->setSkillLevel(skillType, newSkillLevel);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

in src/luascript.h add this:
C++:
static int luaPlayerSetMagiclevel(lua_State* L);
static int luaPlayerSetSkillLevel(lua_State* L);

Now in lua youcan use this functions for example:

Lua:
local ml = 8
local swordSkill = 30
local shieldSkill = 20

player:setMagiclevel(ml)
player:setSkillLevel(SKILL_SWORD, swordSkill)
player:setSkillLevel(SKILL_SHIELD, shieldSkill)
Will try this, got any talkaction example?
Lua:
local ml = 8
local swordSkill = 10
local axeSkill = 10
local clubSkill = 10
local shieldSkill = 10
local distanceSkill = 10

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

local removeSkill = TalkAction("/demote")

function removeSkill.onSay(player, words, param)
    if not player:getGroup():getAccess() or player:getAccountType() < ACCOUNT_TYPE_GOD then
        return true
    end

    if param == "" then
        player:sendCancelMessage("Command param required.")
        return false
    end

    local split = param:split(",")
    if not split[2] then
        player:sendCancelMessage("Insufficient parameters.")
        return false
    end

    local target = Player(split[1])
    if not target then
        player:sendCancelMessage("A player with that name is not online.")
        return false
    end

    function onSay(cid, words, param, channel)
    t = string.explode(param, ",", 2)
    pid = getPlayerByName(t[1])
    level = tonumber(t[2])
     player:removeExperience(player:getExperience() - getExpForLevel(8), false)
    return true
end

removeSkill:separator(" ")
removeSkill:register()


Compile went thru and builded, but cannot start the server.
04dde3efcf1673f3a3f5f5c8a5e7d2f7.png
 
Last edited:
for this example i use die.lua in actions (Make backup file for your die function).

in actions.xml i have:
Lua:
<action fromid="5792" toid="5797" script="other/die.lua" />

now in my scripts/other/die.lua i add:
Lua:
local function getExpForLevel(level)
    level = level - 1
    return ((50 * level * level * level) - (150 * level * level) + (400 * level)) / 3
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    -- SKILL_FIST = 0,
    -- SKILL_CLUB = 1,
    -- SKILL_SWORD = 2,
    -- SKILL_AXE = 3,
    -- SKILL_DISTANCE = 4,
    -- SKILL_SHIELD = 5,
    -- SKILL_FISHING = 6,
    
    local random = math.random(1, 6)
    local sendAdvanceMsg = true
    local pLevel = player:getLevel()
    local pExp = player:getExperience()
    local pSkill = player:getSkillLevel(random)
    local pML = player:getMagicLevel()

    
    if random > 3 then
        player:addExperience(getExpForLevel(pLevel + 1) - pExp, sendAdvanceMsg)
        player:setMagiclevel(pML + 1)
        player:setSkillLevel(random, pSkill + 1)
    else
        player:removeExperience(pExp - getExpForLevel(pLevel - 1), sendAdvanceMsg)
        player:setMagiclevel(pML - 1)
        player:setSkillLevel(random, pSkill - 1)
    end

    player:setSkillLevel(SKILL_FIST, player:getSkillLevel(SKILL_FIST) + 1)

    item:transform(5791 + random)
    return true
end

only for testing purposes
 
for this example i use die.lua in actions (Make backup file for your die function).

in actions.xml i have:
Lua:
<action fromid="5792" toid="5797" script="other/die.lua" />

now in my scripts/other/die.lua i add:
Lua:
local function getExpForLevel(level)
    level = level - 1
    return ((50 * level * level * level) - (150 * level * level) + (400 * level)) / 3
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    -- SKILL_FIST = 0,
    -- SKILL_CLUB = 1,
    -- SKILL_SWORD = 2,
    -- SKILL_AXE = 3,
    -- SKILL_DISTANCE = 4,
    -- SKILL_SHIELD = 5,
    -- SKILL_FISHING = 6,
   
    local random = math.random(1, 6)
    local sendAdvanceMsg = true
    local pLevel = player:getLevel()
    local pExp = player:getExperience()
    local pSkill = player:getSkillLevel(random)
    local pML = player:getMagicLevel()

   
    if random > 3 then
        player:addExperience(getExpForLevel(pLevel + 1) - pExp, sendAdvanceMsg)
        player:setMagiclevel(pML + 1)
        player:setSkillLevel(random, pSkill + 1)
    else
        player:removeExperience(pExp - getExpForLevel(pLevel - 1), sendAdvanceMsg)
        player:setMagiclevel(pML - 1)
        player:setSkillLevel(random, pSkill - 1)
    end

    player:setSkillLevel(SKILL_FIST, player:getSkillLevel(SKILL_FIST) + 1)

    item:transform(5791 + random)
    return true
end

only for testing purposes
This Is sort of the opposit of what I want tho, I want a talkaction that demotes the named player to level 8. Not when he dies.
 
Back
Top