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

TFS 1.3 BUY PASS TO TRAINER

Latorre01

New Member
Joined
Aug 14, 2019
Messages
22
Reaction score
2
I want to know if there is anyway to buy a pass or to pay a NPC in order to enter the training room and stay there for, lets say... 1hour every pass and when the pass is timed out the player would be automatically kicked from the room.
 
Solution
This is a NPC Script that sells "Timestamps" at trainers.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local TRAINING_STORAGE = 1414224 -- Storage value for the training...
Yes you can achieve this with an NPC that sells a ”pass” (timed storageid) that lets you train for a certain time, then either use a movement script on the tile that checks for correct storage or actionscript if the room has a door.

A globalevent that checks the time left and then kick the player (teleport) to a certain location.
 
This is a NPC Script that sells "Timestamps" at trainers.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
    local player = Player(cid)
    -- TRAINER TICKET
    if(msgcontains(msg, "ticket")) then
        if player:getStorageValue(TRAINING_STORAGE) < os.time() then
            npcHandler:say("Do you want to purchase a hourly ticket for trainers? With it you can train as much as you want for one hour. 1000 gold only. Deal?", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("Your hourly ticket is still valid. Would be a waste of money to purchase a second one", cid)
            npcHandler.topic[cid] = 0
        end
    elseif(msgcontains(msg, "yes")) then
        if(npcHandler.topic[cid] == 1) then
            if player:getMoney() >= 1000 then
                player:removeMoney(1000)
                player:setStorageValue(TRAINING_STORAGE, os.time() + 60 * 60)
                npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one hour from now.", cid)
            else
                npcHandler:say("You don't have enough money.", cid)
            end
            npcHandler.topic[cid] = 0
        end
    elseif(npcHandler.topic[cid] == 1) then
        if(msgcontains(msg, "no")) then
            npcHandler:say("No then.", cid)
            npcHandler.topic[cid] = 0
        end
    -- TRAINER TICKET
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you want a hourly {ticket} for the trainers?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.")
npcHandler:addModule(FocusModule:new())

This is a globalevent that checks the "Training area" if they still have time left on the stamp, and if not kicks them out. name it trainercheck.lua
Lua:
local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
local KICK_AREA = Position(32344, 32220, 7) -- Where they will be kicked when the ticket runs out
local TRAINING_FLOOR_CENTRE = Position(32532, 32385, 7) -- The center of the training room, works in 15 by 15 square
local area = {
topos = {x = 32516, y = 32369, z = 7},
frompos = {x = 32548, y = 32401, z = 7}}
function onThink(interval)
local specs, spec = Game.getSpectators(TRAINING_FLOOR_CENTRE, false, false, 15, 15, 15, 15)
        for i = 1, #specs do
            spec = specs [i]
            if spec:isPlayer() then
                local ppos = spec:getPosition()
                if area.frompos.x >= ppos.x and area.topos.x <= ppos.x then
                    if area.frompos.y >= ppos.y and area.topos.y <= ppos.y then
                        if area.frompos.z == ppos.z and area.topos.z == ppos.z then
                                if spec:getStorageValue(TRAINING_STORAGE) < os.time() then
                                    spec:teleportTo(KICK_AREA)
                                    spec:sendTextMessage(MESSAGE_INFO_DESCR, "You've used up your training ticket!.")
                                    spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                                return true
                                end
                        end
                    end
                end
            end
        end
        return true
end
then add this line to globalevents
XML:
<globalevent name="TrainingCheck" interval="5000" script="trainercheck.lua"/>

Dont know if it works properly, havent tested it, but you can try it, and get back to me

EDIT: Did some changes and tested it, seems to be working!
 
Last edited:
Solution
This is a NPC Script that sells "Timestamps" at trainers.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
    local player = Player(cid)
    -- TRAINER TICKET
    if(msgcontains(msg, "ticket")) then
        if player:getStorageValue(TRAINING_STORAGE) < os.time() then
            npcHandler:say("Do you want to purchase a hourly ticket for trainers? With it you can train as much as you want for one hour. 1000 gold only. Deal?", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("Your hourly ticket is still valid. Would be a waste of money to purchase a second one", cid)
            npcHandler.topic[cid] = 0
        end
    elseif(msgcontains(msg, "yes")) then
        if(npcHandler.topic[cid] == 1) then
            if player:getMoney() + player:getBankBalance() >= 1000 then
                player:removeMoneyNpc(1000)
                player:setStorageValue(TRAINING_STORAGE, os.time() + 60 * 60)
                npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one hour from now.", cid)
            else
                npcHandler:say("You don't have enough money.", cid)
            end
            npcHandler.topic[cid] = 0
        end
    elseif(npcHandler.topic[cid] == 1) then
        if(msgcontains(msg, "no")) then
            npcHandler:say("No then.", cid)
            npcHandler.topic[cid] = 0
        end
    -- TRAINER TICKET
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you want a hourly {ticket} for the trainers?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.")
npcHandler:addModule(FocusModule:new())

This is a globalevent that checks the "Training area" if they still have time left on the stamp, and if not kicks them out. name it trainercheck.lua
Lua:
local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
local KICK_AREA = Position(1111, 1111, 7) -- Where they will be kicked when the ticket runs out
local TRAINING_FLOOR_CENTRE = Position(1111, 1111, 7) -- The center of the training room, works in 15 by 15 square
local player = Player(cid)
local specstators = Game.getSpectators(TRAINING_FLOOR_CENTRE, false, false, 15, 15, 15, 15)

function onThink(interval, lastExecution)

            for _, pid in ipairs(spectators) do
                if player and player:getStorageValue(TRAINING_STORAGE) < os.time() then
                    player:teleportTo(KICK_AREA)
                    player:sendTextMessage(MESSAGE_INFO_DESCR, "You've used up your training ticket!.")
                    player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                end
            end
end
then add this line to globalevents
XML:
<globalevent name="TrainingCheck" interval="5000" script="trainercheck.lua"/>

Dont know if it works properly, havent tested it, but you can try it, and get back to me
on trainercheck.lua line 5 you named the variable "specstators" and then on line 9 referenced "spectators" so probably a mistype
 
This is a NPC Script that sells "Timestamps" at trainers.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
    local player = Player(cid)
    -- TRAINER TICKET
    if(msgcontains(msg, "ticket")) then
        if player:getStorageValue(TRAINING_STORAGE) < os.time() then
            npcHandler:say("Do you want to purchase a hourly ticket for trainers? With it you can train as much as you want for one hour. 1000 gold only. Deal?", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("Your hourly ticket is still valid. Would be a waste of money to purchase a second one", cid)
            npcHandler.topic[cid] = 0
        end
    elseif(msgcontains(msg, "yes")) then
        if(npcHandler.topic[cid] == 1) then
            if player:getMoney() + player:getBankBalance() >= 1000 then
                player:removeMoneyNpc(1000)
                player:setStorageValue(TRAINING_STORAGE, os.time() + 60 * 60)
                npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one hour from now.", cid)
            else
                npcHandler:say("You don't have enough money.", cid)
            end
            npcHandler.topic[cid] = 0
        end
    elseif(npcHandler.topic[cid] == 1) then
        if(msgcontains(msg, "no")) then
            npcHandler:say("No then.", cid)
            npcHandler.topic[cid] = 0
        end
    -- TRAINER TICKET
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you want a hourly {ticket} for the trainers?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.")
npcHandler:addModule(FocusModule:new())

This is a globalevent that checks the "Training area" if they still have time left on the stamp, and if not kicks them out. name it trainercheck.lua
Lua:
local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
local KICK_AREA = Position(32344, 32220, 7) -- Where they will be kicked when the ticket runs out
local TRAINING_FLOOR_CENTRE = Position(32532, 32385, 7) -- The center of the training room, works in 15 by 15 square
local player = Player(cid)
local specs, spec = Game.getSpectators(TRAINING_FLOOR_CENTRE, false, false, 15, 17, 15, 19)
local area = {
topos = {x = 32516, y = 32369, z = 7},
frompos = {x = 32548, y = 32401, z = 7}}
function onThink(interval)

        for i = 1, #specs do
            spec = specs [i]
            if spec:isPlayer() then
                local ppos = spec:getPosition()
                if area.frompos.x >= ppos.x and area.topos.x <= ppos.x then
                    if area.frompos.y >= ppos.y and area.topos.y <= ppos.y then
                        if area.frompos.z == ppos.z and area.topos.z == ppos.z then
                                if spec:getStorageValue(TRAINING_STORAGE) < os.time() then
                                    spec:teleportTo(KICK_AREA)
                                    spec:sendTextMessage(MESSAGE_INFO_DESCR, "You've used up your training ticket!.")
                                    spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                                return true
                                end
                        end
                    end
                end
            end
        end
        return true
end
then add this line to globalevents
XML:
<globalevent name="TrainingCheck" interval="5000" script="trainercheck.lua"/>

Dont know if it works properly, havent tested it, but you can try it, and get back to me

EDIT: Did some changes and tested it, seems to be working!
The spectator variable needs to be assigned inside of the onThink function, otherwise it will always check the same creatures. You're only getting spectators once when the script loads, instead of every time the script executes.
 
This is a NPC Script that sells "Timestamps" at trainers.

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 function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
    local player = Player(cid)
    -- TRAINER TICKET
    if(msgcontains(msg, "ticket")) then
        if player:getStorageValue(TRAINING_STORAGE) < os.time() then
            npcHandler:say("Do you want to purchase a hourly ticket for trainers? With it you can train as much as you want for one hour. 1000 gold only. Deal?", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("Your hourly ticket is still valid. Would be a waste of money to purchase a second one", cid)
            npcHandler.topic[cid] = 0
        end
    elseif(msgcontains(msg, "yes")) then
        if(npcHandler.topic[cid] == 1) then
            if player:getMoney() + player:getBankBalance() >= 1000 then
                player:removeMoneyNpc(1000)
                player:setStorageValue(TRAINING_STORAGE, os.time() + 60 * 60)
                npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one hour from now.", cid)
            else
                npcHandler:say("You don't have enough money.", cid)
            end
            npcHandler.topic[cid] = 0
        end
    elseif(npcHandler.topic[cid] == 1) then
        if(msgcontains(msg, "no")) then
            npcHandler:say("No then.", cid)
            npcHandler.topic[cid] = 0
        end
    -- TRAINER TICKET
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you want a hourly {ticket} for the trainers?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.")
npcHandler:addModule(FocusModule:new())

This is a globalevent that checks the "Training area" if they still have time left on the stamp, and if not kicks them out. name it trainercheck.lua
Lua:
local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket
local KICK_AREA = Position(32344, 32220, 7) -- Where they will be kicked when the ticket runs out
local TRAINING_FLOOR_CENTRE = Position(32532, 32385, 7) -- The center of the training room, works in 15 by 15 square
local player = Player(cid)
local area = {
topos = {x = 32516, y = 32369, z = 7},
frompos = {x = 32548, y = 32401, z = 7}}
function onThink(interval)
local specs, spec = Game.getSpectators(TRAINING_FLOOR_CENTRE, false, false, 15, 17, 15, 19)
        for i = 1, #specs do
            spec = specs [i]
            if spec:isPlayer() then
                local ppos = spec:getPosition()
                if area.frompos.x >= ppos.x and area.topos.x <= ppos.x then
                    if area.frompos.y >= ppos.y and area.topos.y <= ppos.y then
                        if area.frompos.z == ppos.z and area.topos.z == ppos.z then
                                if spec:getStorageValue(TRAINING_STORAGE) < os.time() then
                                    spec:teleportTo(KICK_AREA)
                                    spec:sendTextMessage(MESSAGE_INFO_DESCR, "You've used up your training ticket!.")
                                    spec:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                                return true
                                end
                        end
                    end
                end
            end
        end
        return true
end
then add this line to globalevents
XML:
<globalevent name="TrainingCheck" interval="5000" script="trainercheck.lua"/>

Dont know if it works properly, havent tested it, but you can try it, and get back to me

EDIT: Did some changes and tested it, seems to be working!
Wasn't sure what this is about local player = Player(cid) (cid is undefined) but then noticed it's unused variable anyway.
 
Heyho Sparkles.
A little bit late but I wanna thank you for creating and sharing this with us!
I like the idea to have this on my fresh TFS 1.4 Server (10.98) and wanna try to implemnt it.
But what do I have to fill in here? Sorry for this, maybe dumb, question but I'm not that into lua..
Lua:
local area = {
topos = {x = 32516, y = 32369, z = 7},
frompos = {x = 32548, y = 32401, z = 7}}
-> trainercheck.lua
 
Heyho Sparkles.
A little bit late but I wanna thank you for creating and sharing this with us!
I like the idea to have this on my fresh TFS 1.4 Server (10.98) and wanna try to implemnt it.
But what do I have to fill in here? Sorry for this, maybe dumb, question but I'm not that into lua..
Lua:
local area = {
topos = {x = 32516, y = 32369, z = 7},
frompos = {x = 32548, y = 32401, z = 7}}
-> trainercheck.lua
Its the corners of the area, "top left" and "bottom right"
 
@Sparkles Hey again. Something came up my mind and maybe it's a lot more easy to realize for u as it's for me as an non-lua-coder.. :3
Do you have an idea how to let the price inflate by let's say 200gp each time you buy the training-pass at your NPC?
 
@Sparkles Hey again. Something came up my mind and maybe it's a lot more easy to realize for u as it's for me as an non-lua-coder.. :3
Do you have an idea how to let the price inflate by let's say 200gp each time you buy the training-pass at your NPC?
Using storages.
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 startingPrice = 1000
local priceIncrease = 200
local priceIncreaseStorage = 1414223
local TRAINING_STORAGE = 1414224 -- Storage value for the training ticket

local function calculateCost(player)
    local cost
    local priceIncreaseAmount = player:getStorageValue(priceIncreaseStorage)
    priceIncreaseAmount = priceIncreaseAmount > 1 and priceIncreaseAmount or 1
    cost = (priceIncrease * priceIncreaseAmount) + startingPrice
    return cost
end

local function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
  
    local player = Player(cid)
  
    -- TRAINER TICKET
    if msgcontains(msg, "ticket") then
        if player:getStorageValue(TRAINING_STORAGE) < os.time() then
            npcHandler:say("Do you want to purchase a hourly ticket for trainers? With it you can train as much as you want for one hour. " .. calculateCost(player) .. " gold only. Deal?", cid)
            npcHandler.topic[cid] = 1
        else
            npcHandler:say("Your hourly ticket is still valid. Would be a waste of money to purchase a second one", cid)
            npcHandler.topic[cid] = 0
        end
    elseif msgcontains(msg, "yes") then
        if npcHandler.topic[cid] == 1 then
            local cost = calculateCost(player)
            if player:getMoney() >= cost then
                player:removeMoney(cost)
                local priceIncreaseAmount = player:getStorageValue(priceIncreaseStorage)
                player:setStorageValue(priceIncreaseStorage, priceIncreaseAmount < 2 and 2 or priceIncreaseAmount + 1)
                player:setStorageValue(TRAINING_STORAGE, os.time() + (60 * 60))
                npcHandler:say("Here is your stamp. It can't be transferred to another person and will last one hour from now.", cid)
            else
                npcHandler:say("You don't have enough money.", cid)
            end
            npcHandler.topic[cid] = 0
        end
    elseif npcHandler.topic[cid] == 1 then
        if msgcontains(msg, "no") then
            npcHandler:say("No then.", cid)
            npcHandler.topic[cid] = 0
        end
    -- TRAINER TICKET
    end
  
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! Do you want a hourly {ticket} for the trainers?")
npcHandler:setMessage(MESSAGE_FAREWELL, "Hope to see you again.")
npcHandler:addModule(FocusModule:new())
 
Back
Top