• 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 Reset System TFS 1.2

Piifafa

Member
Joined
Apr 16, 2023
Messages
67
Reaction score
16
I would like to know how I can use this system on my server, as I use a Nostalrius database, and it's quite different from the typical OT servers. Even the NPCs are different, but I know it's TFS 1.2. I would like to have an NPC that can perform a player reset.

Lua:
local config = {
    backToLevel = 8,
    redskull = false, -- need to be without redskull to reset?
    battle = true, -- need to be without battle to reset?
    pz = false, -- need to be in protect zone to reset?
    stages = {
        {resets = 4, level = 350, premium = 330},
        {resets = 9, level = 355, premium = 340},
        {resets = 14, level = 360, premium = 355},
        {resets = 19, level = 365, premium = 360},
        {resets = 24, level = 380, premium = 370},
        {resets = 29, level = 390, premium = 380},
        {resets = 34, level = 410, premium = 400},
        {resets = 39, level = 430, premium = 420},
        {resets = 44, level = 450, premium = 440},
        {resets = 49, level = 480, premium = 470},
        {resets = 54, level = 510, premium = 500},
        {resets = 59, level = 550, premium = 540},
        {resets = 64, level = 590, premium = 580},
        {resets = 69, level = 630, premium = 620},
        {resets = 74, level = 680, premium = 670},
        {resets = 79, level = 730, premium = 720},
        {resets = 84, level = 780, premium = 770},
        {resets = 89, level = 860, premium = 840},
        {resets = 94, level = 930, premium = 910},
        {resets = 2^1024, level = 1010, premium = 990}
    }
}

function onSay(player, words, param)
    local function getExperienceForLevel(lv)
        lv = lv - 1
        return ((50 * lv * lv * lv) - (150 * lv * lv) + (400 * lv)) / 3
    end
    local function getPlayerResets()
        local resets = player:getStorageValue(500)
        return resets < 0 and 0 or resets
    end
 
    local function doPlayerAddResets(count)
        player:setStorageValue(500, getPlayerResets() + count)
    end
 
    if config.redskull and player:getSkull() == 4 then
        player:sendCancelMessage("You need to be without red skull to reset.")
        return false
    elseif config.pz and not getTilePzInfo(player:getPosition()) then
        player:sendCancelMessage("You need to be in protection zone to reset.")
        return false
    elseif config.battle and player:getCondition(CONDITION_INFIGHT) then
        player:sendCancelMessage("You need to be without battle to reset.")
        return false
    end
 
    local resetLevel = 0
    for x, y in ipairs(config.stages) do
        if getPlayerResets() <= y.resets then
            resetLevel = player:isPremium() and y.premium or y.level
            break
        end
    end
 
    if getPlayerLevel(player) < resetLevel then
        player:sendCancelMessage("You need level " .. resetLevel .. " or more to reset.")
        return false
    end
 
    doPlayerAddResets(1)
    local healthMax, manaMax, health, mana = player:getMaxHealth(), player:getMaxMana(), player:getHealth(), player:getMana()
    player:removeExperience(getExperienceForLevel(player:getLevel()) - getExperienceForLevel(config.backToLevel))
    player:setMaxHealth(healthMax)
    player:setMaxMana(manaMax)
    player:addHealth(health)
    player:addMana(mana)
    player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
    player:sendTextMessage(MESSAGE_INFO_DESCR, "Now you have " .. getPlayerResets() .. " " .. (getPlayerResets() == 1 and "reset" or "resets") .. ".")
    return false
end
 
I haven't tested it yet. I took my system and some functions you posted and adapted it for NPC. It is important to test to see if it works or not.


This NPC is used to reset the player's level, MP and HP in the database, and the percentages can be adjusted according to your preferences.

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end

local config = {
    price = 10000,
    newlevel = 8,
    priceByReset = 0,
    percent = 10,
    maxresets = 50,
    levelbyreset = 0,
    redskull = false, -- need to be without redskull to reset?
    battle = true, -- need to be without battle to reset?
    pz = false, -- need to be in protect zone to reset?
    stages = {
        {resets = 4, level = 350, premium = 330},
        {resets = 9, level = 355, premium = 340},
        {resets = 14, level = 360, premium = 355},
        {resets = 19, level = 365, premium = 360},
        {resets = 24, level = 380, premium = 370},
        {resets = 29, level = 390, premium = 380},
        {resets = 34, level = 410, premium = 400},
        {resets = 39, level = 430, premium = 420},
        {resets = 44, level = 450, premium = 440},
        {resets = 49, level = 480, premium = 470},
        {resets = 54, level = 510, premium = 500},
        {resets = 59, level = 550, premium = 540},
        {resets = 64, level = 590, premium = 580},
        {resets = 69, level = 630, premium = 620},
        {resets = 74, level = 680, premium = 670},
        {resets = 79, level = 730, premium = 720},
        {resets = 84, level = 780, premium = 770},
        {resets = 89, level = 860, premium = 840},
        {resets = 94, level = 930, premium = 910},
        {resets = 2^1024, level = 1010, premium = 990}
    }
}

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

local function getResets(uid)
    local player = Player(uid)
    local resets = 0
    if player then
        resets = math.max(0, player:getStorageValue(500))
    end
    return resets
end

local function addReset(uid)
    local player = Player(uid)
    if player then
        local resets = getResets(uid)
        local hp = player:getMaxHealth()
        local resethp = hp * (config.percent / 100)
        player:setMaxHealth(resethp)
        local mana = player:getMaxMana()
        local resetmana = mana * (config.percent / 100)
        player:setMaxMana(resetmana)
        local playerid = player:getGuid()
        player:remove()
        db.query("UPDATE `players` SET `resets`=" .. resets + 1 .. ",`experience`= 0 WHERE `players`.`id`= " .. playerid .. "")
        db.query("UPDATE `players` SET `level`=" .. config.newlevel .. ",`experience`= 0 WHERE `players`.`id`= " .. playerid .. "")
    end
    return true
end

function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end

    local player = Player(cid)
    if not player then
        return false
    end

    local newPrice = config.price + (getResets(cid) * config.priceByReset)

    if config.redskull and player:getSkull() == SKULL_RED then
        player:sendCancelMessage("You need to be without red skull to reset.")
        return true
    elseif config.pz and not getTilePzInfo(player:getPosition()) then
        player:sendCancelMessage("You need to be in a protection zone to reset.")
        return true
    elseif config.battle and player:getCondition(CONDITION_INFIGHT) then
        player:sendCancelMessage("You need to be without battle to reset.")
        return true
    end

    local resetLevel = 0
    for x, y in ipairs(config.stages) do
        if getResets(cid) <= y.resets then
            resetLevel = player:isPremium() and y.premium or y.level
            break
        end
    end

    if getPlayerLevel(player) < resetLevel then
        player:sendCancelMessage("You need level " .. resetLevel .. " or more to reset.")
        return true
    end

    local newminlevel = resetLevel + (getResets(cid) * config.levelbyreset)

    if msgcontains(msg, 'reset') then
        if getResets(cid) < config.maxresets then
            npcHandler:say('You want to reset your character? It will cost ' .. newPrice .. ' gp\'s!', cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say('You already reached the maximum reset level!', cid)
        end
        return true
    elseif msgcontains(msg, 'yes') and npcHandler.topic[cid] == 1 then
        if player:getLevel() > newminlevel then
            if player:removeMoney(newPrice) then
                addEvent(function()
                    if isPlayer(cid) then
                        addReset(cid)
                    end
                end, 3000)
                local number = getResets(cid) + 1
                local msg = "---[Reset: " .. number .. "]-- You have reseted! You'll be disconnected in 3 seconds."
                player:popupFYI(msg)
                npcHandler.topic[cid] = 0
                npcHandler:releaseFocus(cid)
            else
                npcHandler:say('It\'s necessary to have at least ' .. newPrice .. ' gp\'s for resetting!', cid)
            end
        else
            npcHandler:say('The minimum level for resetting is ' .. newminlevel .. '!', cid)
        end
        return true
    elseif msgcontains(msg, 'no') and isInArray({1}, npcHandler.topic[cid]) then
        npcHandler.topic[cid] = 0
        npcHandler:releaseFocus(cid)
        npcHandler:say('Ok.', cid)
        return true
    elseif msgcontains(msg, 'quantity') then
        npcHandler:say('You have a total of ' .. getResets(cid) .. ' reset(s).', cid)
        npcHandler.topic[cid] = 0
        return true
    end
end


npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
thanks for trying to help me but my npc's are different from these, they are like that.

Lua:
# GIMUD - Graphical Interface Multi User Dungeon
# xodet.npc: Datenbank für den Magieladen-Besitzer Xodet

Name = "Dark Rodo"
Outfit = (128,78-71-82-114)
Home = [0,0,0]
Radius = 0

Behaviour = {
ADDRESS,"hello$",! -> "Oh, please come in, %N. What do you need?"
ADDRESS,"hi$",!    -> *
ADDRESS,!          -> Idle
BUSY,"hello$",!    -> "Sorry %N, I am already talking to a customer. Wait a minute, please.", Queue
BUSY,"hi$",!       -> *
BUSY,!             -> NOP
VANISH,!           -> "Good bye."

"bye"      -> "Good bye and come again.", Idle
"farewell" -> *
"job"      -> "I'm sorcerer and trade with all kinds of magic items."
"sorcerer" -> "There is a sorcerer guild in Thais. Just go in the east of the town, it is easly to find."

"offer"           -> "I'm selling life and mana fluids, runes, wands, rods and spellbooks."
"goods"           -> *
"do","you","sell" -> *
"do","you","have" -> *

"rune"         -> "I sell spell runes."
"life","fluid" -> Type=5224, Amount=1, Price=55, "Do you want to buy life fluid for %P gold?", Topic=2
"mana","fluid" -> Type=5225, Amount=1, Price=100, "Do you want to buy mana fluid for %P gold?", Topic=2
"spellbook"    -> Type=3059, Amount=1, Price=150, "Do you want to buy a spellbook for %P gold?", Topic=1

%1,1<%1,"life","fluid"  -> Type=5224, Amount=%1, Price=55*%1, "Do you want to buy %A potions of life fluid for %P gold?", Topic=2
%1,1<%1,"mana","fluid"  -> Type=5225, Amount=%1, Price=100*%1, "Do you want to buy %A potions of mana fluid for %P gold?", Topic=2
%1,1<%1,"spellbook"    -> Type=3059, Amount=%1, Price=150*%1, "Do you want to buy %A spellbooks for %P gold?", Topic=1

"deposit"                   -> "I will pay you 5 gold for every empty vial. Ok?", Data=0, Topic=3
"vial"                      -> *
"flask"                     -> *

Topic=1,"yes",CountMoney>=Price -> "Here you are.", DeleteMoney, Create(Type)
Topic=1,"yes"                   -> "Come back, when you have enough money."
Topic=1                         -> "Hmm, but next time."

Topic=2,"yes",CountMoney>=Price -> "Here you are. There is a deposit of 5 gold on the vial.", DeleteMoney, Create(Type)
Topic=2,"yes"                   -> "Come back, when you have enough money."
Topic=2                         -> "Hmm, but next time."

Topic=3,"yes",Count(5226)>0 -> Amount=Count(5226), Price=Amount*5, "Here you are ... %P gold.", Delete(5226), CreateMoney
Topic=3,"yes"               -> "You don't have any empty vials."
Topic=3                     -> "Hmm, but please keep Tibia litter free."

@"gen-t-runes-free-s.ndb"
@"gen-t-wands-free-s.ndb"
@"gen-t-wands-prem-s.ndb"

}
 
I thought it was the same as TFS 1.2, but I realized that it is based on Nostalrius. When I saw his NPCs, I realized that he is quite different. Actually, I'm not familiar with this Nostalrius base. I tried to adapt the script for the NPC, but I know it won't work. Hope someone with experience on that server can help. Sorry for the confusion!

The script is just an example...
Code:
Name = "Master Reset"
Outfit = (128,78-71-82-114)
Home = [0,0,0]
Radius = 0

local config = {
    price = 10000,
    newlevel = 8,
    priceByReset = 0,
    percent = 10,
    maxresets = 50,
    levelbyreset = 0,
    stages = {
        {resets = 4, level = 350, premium = 330},
        {resets = 9, level = 355, premium = 340},
        {resets = 14, level = 360, premium = 355},
       -- Define more reset steps here
    }
}

Behaviour = {
    ADDRESS,"hello$",! -> "Greetings, %N. How can I assist you?"
    ADDRESS,"hi$",!    -> *
    ADDRESS,!          -> Idle
    BUSY,"hello$",!    -> "Apologies %N, I am currently engaged with another customer. Please wait a moment.", Queue
    BUSY,"hi$",!       -> *
    BUSY,!             -> NOP
    VANISH,!           -> "Farewell."

    "bye"      -> "Farewell, and may your journey be prosperous.", Idle
    "farewell" -> *
    "job"      -> "I oversee the path of renewal through reset. Are you interested in a fresh start?"
    
    "reset"     -> "Are you certain you wish to embark on a new journey through reset?", Topic=4

    Topic=4,"yes" ->
        local resets = getResets(uid)
        local playerLevel = player:getLevel()

        if playerLevel >= config.stages[resets + 1].level then
            local resetStage = config.stages[resets + 1]
            local hp = player:getMaxHealth() * (config.percent / 100)
            local mana = player:getMaxMana() * (config.percent / 100)

            player:setMaxHealth(hp)
            player:setMaxMana(mana)
            player:setLevel(resetStage.level)
            player:setResets(resets + 1)
            player:setExperience(0)

            db.query("UPDATE `players` SET `resets`=" .. (resets + 1) .. ",`experience`=0 WHERE `id`= " .. uid)
            return "Congratulations! You have been reset to level " .. resetStage.level .. ". May your journey be renewed and filled with new challenges."
        else
            return "You do not meet the requirements for this reset."
        end
    end
}
 
it's actually not easy.
Post automatically merged:

I'm trying to create a double exp item, which stays activated for a few days or hours despite using I don't know what's missing for it to work, it's really difficult on that basis.
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local player = Player(cid)
    if player:getStorageValue(9234) >= os.time() then
        player:say('You already have double exp!', TALKTYPE_MONSTER_SAY)
        return true
    end

    player:setStorageValue(9234, os.time() + 86400)
    Item(item.uid):remove(1)
    player:say('Your 24 hours of double XP has started!', TALKTYPE_MONSTER_SAY)
    return true
end

function Player:onGainExperience(source, exp, rawExp)
    if self:getStorageValue(9234) >= os.time() then
        exp = exp * 2
    end
    return exp
end
 
Last edited:
it's actually not easy.
Post automatically merged:

I'm trying to create a double exp item, which stays activated for a few days or hours despite using I don't know what's missing for it to work, it's really difficult on that basis.
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local player = Player(cid)
    if player:getStorageValue(9234) >= os.time() then
        player:say('You already have double exp!', TALKTYPE_MONSTER_SAY)
        return true
    end

    player:setStorageValue(9234, os.time() + 86400)
    Item(item.uid):remove(1)
    player:say('Your 24 hours of double XP has started!', TALKTYPE_MONSTER_SAY)
    return true
end

function Player:onGainExperience(source, exp, rawExp)
    if self:getStorageValue(9234) >= os.time() then
        exp = exp * 2
    end
    return exp
end
u need go to nnplayr.lua on events and put the same 9234 storage there
 
Back
Top