• 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 Experience Functions for TFS 1.1

Lava Titan

Developer
Joined
Jul 25, 2009
Messages
1,529
Solutions
1
Reaction score
85
Location
Portugal
Hello I've been searching in all functions of TFS 1.1 for experience rate functions and I only found:

Code:
Game.getExperienceStage()

I'm trying to make a double exp onUse item but I can't find the suitable functions like

Code:
player:SetExperienceStage()
player:GetExperienceStage()

Can anyone tell me what function should I use to set player x2 exp?
 
Hello I've been searching in all functions of TFS 1.1 for experience rate functions and I only found:

Code:
Game.getExperienceStage()

I'm trying to make a double exp onUse item but I can't find the suitable functions like

Code:
player:SetExperienceStage()
player:GetExperienceStage()

Can anyone tell me what function should I use to set player x2 exp?
There is no extra exp for players in TFS 1.0 (as it was in 0.4).
You can try to make it some sick-LUA way (in onKill event store exp in some variable, when player execute next onKill event, get 'current exp' - 'exp from variable' [how much he gained since last kill] and add player exp by 'player:addExperience').

EDIT:
Events way looks better :p
https://github.com/otland/forgottenserver/blob/master/data/events/scripts/player.lua#L139
 
I found this code down:

Code:
if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end
    return exp
    end

And added it to events like this:

Code:
function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        return exp
    end

    -- Double Exp
    if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end

    -- Soul regeneration
    local vocation = self:getVocation()
    if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
        soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
        self:addCondition(soulCondition)
    end

    -- Apply experience stage multiplier
    exp = exp * Game.getExperienceStage(self:getLevel())

    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        end
    end

    return exp
end

going to test now, ill post results in few time

EDIT:

Worked fine, the function for double exp is:

Code:
if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end
 
Last edited:
I found this code down:

Code:
if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end
    return exp
    end

And added it to events like this:

Code:
function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        return exp
    end

    -- Double Exp
    if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end

    -- Soul regeneration
    local vocation = self:getVocation()
    if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
        soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
        self:addCondition(soulCondition)
    end

    -- Apply experience stage multiplier
    exp = exp * Game.getExperienceStage(self:getLevel())

    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        end
    end

    return exp
end

going to test now, ill post results in few time

EDIT:

Worked fine, the function for double exp is:

Code:
if self:getStorageValue("doubleExp") >= os.time() then
        exp = exp * 2
    end
I'm not sure, if that getStorageValue("doubleExp") is just an example, but as storage of TFS 1.2 is 'number' value with 'number' key, it means that your "doubleExp" is saved in database as key 0 and every other string used in any script as key for storage will also store as 0.

It can result in serious problem that can be hard to detect without checking in engine that storage 'key' must be an number!

If you got 5 minutes please check in database table 'player_storage' what is key of your double exp. It's interesting (maybe somewhere TFS changes that 'doubleExp' to some random value instead of 0).
 
@Gesior.pl You're right it does change value to 0

7DiICMH.png


Btw shouldnt the storage value be decreasing each second or minute? even if player offline?
 
@Gesior.pl You're right it does change value to 0

7DiICMH.png


Btw shouldnt the storage value be decreasing each second or minute? even if player offline?
You tried to set key 'doubleExp' - it changed it to 0.
Value you set is 'os.time()', which is number (of seconds since 1 january 1970). It did not change it - it's stored with right value 1440719314. Which is 08/27/2015 @ 11:48pm (UTC) [ http://www.unixtimestamp.com/index.php ].

Should it decrease? I don't know.
Current version of code 'decrease' [not really - it does not need to calculate it all time] double exp time even when player is offline. It just store 'end of double exp date' in storage. If you set there 'now + 4 hours', it will end after 4 hours no matter, if player is online or not.

To give someone 4 hours of 'double exp' you must use:
PHP:
player:setStorageValue(STORAGE_DOUBLE_EXP, os.time() + (4 * 3600))

but first you need in some 'lib' define variable with real storage (number! :) ):
PHP:
STORAGE_DOUBLE_EXP = 54354
 
The range for storage values is from –2,147,483,648 to 2,147,483,647 and from 0 to 4,294,967,295 for keys
 
I'm trying to check for storage value with query but I can't find how to execute the query correctly...

I tried db.query but print in console says "true" instead of saying the result of the query...

Code:
SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";

Code:
print(db.query("SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";"))

Do I have any error in the query that it's not returning correct value or am I not executing it correctly?
 
I'm trying to check for storage value with query but I can't find how to execute the query correctly...

I tried db.query but print in console says "true" instead of saying the result of the query...

Code:
SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";

Code:
print(db.query("SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";"))

Do I have any error in the query that it's not returning correct value or am I not executing it correctly?
Here you got example how to use SQL in TFS 1.x:
https://github.com/otland/forgottenserver/blob/master/data/talkactions/scripts/deathlist.lua

PHP:
local resultId = db.storeQuery("SELECT `id`, `name` FROM `players` WHERE `name` = " .. db.escapeString(param))
if resultId ~= false then
local targetGUID = result.getDataInt(resultId, "id")
local targetName = result.getDataString(resultId, "name")
result.free(resultId)

db.query - for UPDATE/DELETE/INSERT statements
db.queryStore [query that return some data] - for SELECT/SHOW statements

[in PHP you got one universal 'query']

TFS 1.2 SQL functions (db.XXX):
PHP:
query
storeQuery
asyncQuery -- for tests only, crash server sometimes
asyncStoreQuery-- for tests only, crash server sometimes
escapeString -- escape string to format safe for MySQL
escapeBlob -- escape binary data for MySQL
lastInsertId -- after 'INSERT' query you can use it to get 'primary key' set for last 'row' you added
tableExists -- for auto-database-update

TFS 'result' functions (result.XXX):
PHP:
getString -- 'getDataString' is alias for that function
getNumber -- 'getDataInt' and 'getDataLong' are aliases for that function
getBoolean
 
Last edited:
I'm trying to check for storage value with query but I can't find how to execute the query correctly...

I tried db.query but print in console says "true" instead of saying the result of the query...

Code:
SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";

Code:
print(db.query("SELECT `value` FROM `player_storage` WHERE `player_id` = ".. player:getId() .." AND `key` = ".. DOUBLE_EXP_USED_STORAGE ..";"))

Do I have any error in the query that it's not returning correct value or am I not executing it correctly?
Why are you acessing the database directly anyway? Use player:getStorageValue() and player:setStorageValue() instead.
 
@Damc I totally forgot I could do something like

Code:
player:setStorageValue(12345, player:getStorageValue(12345) + 1)

So I was trying to get the value from the database '-' my bad XD
 
Back
Top