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

RevScripts [REQUEST] Specific Tile with gaining experience, skill per minute

Xedoxo

Member
Joined
Oct 24, 2010
Messages
131
Reaction score
19
Hi everyone,

many people have already helped me a lot here, for which I am very grateful. Doesnt know what prefix should i choose
I wonder if there is any ready-made script that would ensure receiving XP/SKILL per minute for staying at specific tile (x/y/z pos).
Gaining SKILL on the basis of as if the character was training i.e. she was attacking e.g. monk all the time depends skill rate. Same with experience.
It is possible to do? If somebody ask - Nekiro TFS 1.5 8.0
 
Solution
F
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    local players = Game.getPlayers()
    for _, player in ipairs(players) do
        for _, pos in ipairs(positions) do...
LUA:
local pos = {x = 2918, y = 3120, z = 6} -- Coordinates where players need to be
local xp_per_minute = 1000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 10000000000000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    local players = Game.getPlayers()
    for _, player in ipairs(players) do
        if player:getPosition().x == pos.x and player:getPosition().y == pos.y and player:getPosition().z == pos.z then
            player:addExperience(xp_per_minute, true) -- Add experience to the player
            for _, skill_type in ipairs(skill_types) do
                player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
 
Last edited:
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    local players = Game.getPlayers()
    for _, player in ipairs(players) do
        for _, pos in ipairs(positions) do
            if player:getPosition().x == pos.x and player:getPosition().y == pos.y and player:getPosition().z == pos.z then
                player:addExperience(xp_per_minute, true) -- Add experience to the player
                for _, skill_type in ipairs(skill_types) do
                    player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                end
                break -- Exit the loop once a match is found
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
Here you can select more than one tile (x/y/z pos)
You must respond and explain if the script works well and report that it has been solved
 
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    local players = Game.getPlayers()
    for _, player in ipairs(players) do
        for _, pos in ipairs(positions) do
            if player:getPosition().x == pos.x and player:getPosition().y == pos.y and player:getPosition().z == pos.z then
                player:addExperience(xp_per_minute, true) -- Add experience to the player
                for _, skill_type in ipairs(skill_types) do
                    player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                end
                break -- Exit the loop once a match is found
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
Here you can select more than one tile (x/y/z pos)
You must respond and explain if the script works well and report that it has been solved
There is no need to loop through Game.getPlayers()... and the more players online, the more inefficient your script becomes.

Just loop through the positions, get the Tile and loop through tile:getCreatures() and then check if its a player, and add exp, skills.
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    for _, pos in ipairs(positions) do
        local tile = Tile(position)
        if tile then
            local creatures = tile:getCreatures()
            if creatures then
                for __, player in ipairs(creatures) do
                    if player:isPlayer() then
                        player:addExperience(xp_per_minute, true) -- Add experience to the player
                        for ___, skill_type in ipairs(skill_types) do
                            player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                        end
                    end
                end
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
 
Last edited by a moderator:
Solution
There is no need to loop through Game.getPlayers()... and the more players online, the more inefficient your script becomes.

Just loop through the positions, get the Tile and loop through tile:getCreatures() and then check if its a player, and add exp, skills.
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    for _, pos in ipairs(positions) do
        local tile = Tile(position)
        if tile then
            local creatures = tile:getCreatures()
            if creatures then
                for __, player in ipairs(creatures) do
                    if player:isPlayer() then
                        player:addExperience(xp_per_minute, true) -- Add experience to the player
                        for ___, skill_type in ipairs(skill_types) do
                            player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                        end
                    end
                end
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event

Ok i back and tested all of it. I swap to 1.2 TFS (idk it matter). Added and run this script in globalevents, but not works. Any idea?
 
In your TFS, there is no folder named data/scripts, which is RevScript. Therefore, you should add it directly to the folder data/globalevents/scripts .

remove those lines.
LUA:
local gainXpAndSkill = GlobalEvent("gainXpAndSkill")
LUA:
gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event

This line should change
LUA:
function gainXpAndSkill.onThink(interval, lastExecution)
for
LUA:
function onThink(interval, lastExecution)
keeping the rest of the script unchanged. It should work fine.
 
There is no need to loop through Game.getPlayers()... and the more players online, the more inefficient your script becomes.

Just loop through the positions, get the Tile and loop through tile:getCreatures() and then check if its a player, and add exp, skills.
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    for _, pos in ipairs(positions) do
        local tile = Tile(position)
        if tile then
            local creatures = tile:getCreatures()
            if creatures then
                for __, player in ipairs(creatures) do
                    if player:isPlayer() then
                        player:addExperience(xp_per_minute, true) -- Add experience to the player
                        for ___, skill_type in ipairs(skill_types) do
                            player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                        end
                    end
                end
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
if i have like 250x++ locations for this ? it wont give huge lag ?
 
if i have like 250x++ locations for this ? it wont give huge lag ?
Nah not really, take a few ms...
The amount of iterations would be equivalent to the amount of positions + any tiles that have multiple creatures (+ looping through skill tries)
i.e 250 positions would probably be between 250-500 iterations (+ skill tries iterations)

If you went with abdala ragab's suggestion:
The amount of iterations would be equivalent to the amount of players online * the amount of positions (+ looping through skill tries)
i.e 100 players online * 250 positions would be 25,000 iterations (+ skill tries iterations)
500 players online * 250 positions would be 125,000 iterations (+ skill tries iterations)

His script takes longer to execute with the more players online, and therefore less efficient.
 
Last edited by a moderator:
Nah not really, take a few ms...
The amount of iterations would be equivalent to the amount of positions + any tiles that have multiple creatures (+ looping through skill tries)
i.e 250 positions would probably be between 250-500 iterations (+ skill tries iterations)

If you went with abdala ragab's suggestion:
The amount of iterations would be equivalent to the amount of players online * the amount of positions (+ looping through skill tries)
i.e 100 players online * 250 positions would be 25,000 iterations (+ skill tries iterations)
500 players online * 250 positions would be 125,000 iterations (+ skill tries iterations)

His script takes longer to execute with the more players online, and therefore less efficient.
Thanks for your replys and help for all of us <3


i want to ask if you could make seperate version of this script

First of all could you like add a check that nonvocation cannot recieve exp/skills ?


ALso for seperate version, lets say i set 40min time for this bonus to give to player, but can make that it can be like obtained ? i mean like player doesnt must to be here standing to get it, every this 40min this Spot who will step(obtainn it) will get bonus and new timer will start ? i hope you got the idea.

and maybe like an effect on if its ready to be taken ?
 
For the first one, you can change:
LUA:
if player:isPlayer()
to:
LUA:
if player:isPlayer() and player:getVocation():getId() > 0 then

For the second one, do you mean like a shrine that people can step onto?
Would you want that just one player per 40 mins, or unlimited players (with their own individual timers)?
 
For the first one, you can change:
LUA:
if player:isPlayer()
to:
LUA:
if player:isPlayer() and player:getVocation():getId() > 0 then

For the second one, do you mean like a shrine that people can step onto?
Would you want that just one player per 40 mins, or unlimited players (with their own individual timers)?
thanks!

and yeah like if i set tons of location around explore land, and all can be collected be one or diff chars/people.
 
thanks!

and yeah like if i set tons of location around explore land, and all can be collected be one or diff chars/people.
Untested but should be good
LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    positions = {
        {
            position = Position(2918, 3120, 6),
            experience = 100000,
            skill_rate = 100000,
            skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST}
        },
        {
            position = Position(2917, 3120, 6),
            experience = 100000,
            skill_rate = 100000,
            skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST}
        },
    }
}

--dont edit below

local store = {}

local function removeExhaust(playerId, positionKey)
    if store[playerId][positionKey] then
        store[playerId][positionKey] = nil
        return
    end
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
   
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
   
    local posData = nil
    for _, pos in ipairs(positions) do
        if pos == position then
            posData = pos
        end
    end
   
    if not posData then
        return false
    end
   
    local playerId = player:getGuid()
    local positionKey = ('%d:%d:%d'):format(position.x, position.y, position.z)
   
    --check for exhaust
    if store[playerId][positionKey] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
   
    --add exp and tries
    player:addExperience(posData.experience, true)
    for _, skill_type in ipairs(posData.skill_types) do
        player:addSkillTries(skill_type, posData.skill_rate)
    end
   
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, playerId, positionKey)
   
    --set the exhaust
    store[playerId][positionKey] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()
 
Untested but should be good
LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    positions = {
        {
            position = Position(2918, 3120, 6),
            experience = 100000,
            skill_rate = 100000,
            skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST}
        },
        {
            position = Position(2917, 3120, 6),
            experience = 100000,
            skill_rate = 100000,
            skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST}
        },
    }
}

--dont edit below

local store = {}

local function removeExhaust(playerId, positionKey)
    if store[playerId][positionKey] then
        store[playerId][positionKey] = nil
        return
    end
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
  
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
  
    local posData = nil
    for _, pos in ipairs(positions) do
        if pos == position then
            posData = pos
        end
    end
  
    if not posData then
        return false
    end
  
    local playerId = player:getGuid()
    local positionKey = ('%d:%d:%d'):format(position.x, position.y, position.z)
  
    --check for exhaust
    if store[playerId][positionKey] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
  
    --add exp and tries
    player:addExperience(posData.experience, true)
    for _, skill_type in ipairs(posData.skill_types) do
        player:addSkillTries(skill_type, posData.skill_rate)
    end
  
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, playerId, positionKey)
  
    --set the exhaust
    store[playerId][positionKey] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()
why is here actionid and position ? can explain please ?
 
why is here actionid and position ? can explain please ?
You register each position in RME with the same action ID, and make sure it matches tileActionID in the config.

Each "positions" in the config is a separate position with its own config. So one position can have different skills rates/exp etc to another.
Post automatically merged:

This is a more simplified version (again untested):
All you need to do is add actionID 9000 to any tile in RME.
LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    experience = 100000,
    skill_rate = 100000,
    skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST},
}

--dont edit below

local store = {}

local function removeExhaust(playerId, positionKey)
    if store[playerId][positionKey] then
        store[playerId][positionKey] = nil
        return
    end
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
    
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
    
    local playerId = player:getGuid()
    local positionKey = ('%d:%d:%d'):format(position.x, position.y, position.z)
    
    --check for exhaust
    if store[playerId][positionKey] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
    
    --add exp and tries
    player:addExperience(config.experience, true)
    for _, skill_type in ipairs(config.skill_types) do
        player:addSkillTries(skill_type, config.skill_rate)
    end
    
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, playerId, positionKey)
    
    --set the exhaust
    store[playerId][positionKey] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()

Use the previous script if you want more control over specific tiles (i.e different experience/skill rates on different tiles)
 
Last edited by a moderator:
You register each position in RME with the same action ID, and make sure it matches tileActionID in the config.

Each "positions" in the config is a separate position with its own config. So one position can have different skills rates/exp etc to another.
Post automatically merged:

This is a more simplified version (again untested):
All you need to do is add actionID 9000 to any tile in RME.
LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    experience = 100000,
    skill_rate = 100000,
    skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST},
}

--dont edit below

local store = {}

local function removeExhaust(playerId, positionKey)
    if store[playerId][positionKey] then
        store[playerId][positionKey] = nil
        return
    end
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
  
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
  
    local playerId = player:getGuid()
    local positionKey = ('%d:%d:%d'):format(position.x, position.y, position.z)
  
    --check for exhaust
    if store[playerId][positionKey] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
  
    --add exp and tries
    player:addExperience(config.experience, true)
    for _, skill_type in ipairs(config.skill_types) do
        player:addSkillTries(skill_type, config.skill_rate)
    end
  
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, playerId, positionKey)
  
    --set the exhaust
    store[playerId][positionKey] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()

Use the previous script if you want more control over specific tiles (i.e different experience/skill rates on different tiles)
doesnt work for me,

Error:
Lua Script Error: [Scripts Interface]
/data/scripts/systems/housetile bonus.lua:callback
/data/scripts/systems/housetile bonus.lua:34: attempt to index a nil value
stack traceback:
[C]: in function '__index'
/data/scripts/systems/housetile bonus.lua:34: in function <
/data/scripts/systems/housetile bonus.lua:23>




also so if set for 100x diff location tiles with same acction id, they all work as seperate or 1 ?
 
Last edited:
doesnt work for me,

Error:
Lua Script Error: [Scripts Interface]
/data/scripts/systems/housetile bonus.lua:callback
/data/scripts/systems/housetile bonus.lua:34: attempt to index a nil value
stack traceback:
[C]: in function '__index'
/data/scripts/systems/housetile bonus.lua:34: in function <
/data/scripts/systems/housetile bonus.lua:23>




also so if set for 100x diff location tiles with same acction id, they all work as seperate or 1 ?

Whoops, yeah my bad it was untested.

Yes, if you put the actionID on 100 tiles, they are each separate.

LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    experience = 100000,
    skill_rate = 100000,
    skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST},
}

--dont edit below

local store = {}

local function removeExhaust(key)
    if store[key] then
        store[key] = nil
    end
    return
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
   
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
   
    local playerId = player:getGuid()
    local key = ('%d:%d:%d:%d'):format(playerId, position.x, position.y, position.z)
   
    --check for exhaust
    if store[key] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
   
    --add exp and tries
    player:addExperience(config.experience, true)
    for _, skill_type in ipairs(config.skill_types) do
        player:addSkillTries(skill_type, config.skill_rate)
    end
   
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, key)
   
    store[key] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()
 
Whoops, yeah my bad it was untested.

Yes, if you put the actionID on 100 tiles, they are each separate.

LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    omitNoneVoc = true    -- Set to true to omit the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    experience = 100000,
    skill_rate = 100000,
    skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST},
}

--dont edit below

local store = {}

local function removeExhaust(key)
    if store[key] then
        store[key] = nil
    end
    return
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
  
    --do basic checks
    if not player:isPlayer() or (omitNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
  
    local playerId = player:getGuid()
    local key = ('%d:%d:%d:%d'):format(playerId, position.x, position.y, position.z)
  
    --check for exhaust
    if store[key] then
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return false
    end
  
    --add exp and tries
    player:addExperience(config.experience, true)
    for _, skill_type in ipairs(config.skill_types) do
        player:addSkillTries(skill_type, config.skill_rate)
    end
  
    --schedule the exhaust removal for the future
    local exhaustTime = config.debugMode and (20 * 1000) or (config.exhaustTime * 60 * 1000)
    addEvent(removeExhaust, exhaustTime, key)
  
    store[key] = 1
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()
Thanks bro !!!


Works good!!!

Can we add some tunning ? like if its ready to be taken, can we give effect running every some seconds or something vissible always that is ready to be taken ?


also on stepping on taken bonuses, can give the cancel message with time left to take bonus ?

what about magic level skilling, can add it there to ? maybe different tryes or ? how it shoud work in balanced manner?
 
Thanks bro !!!


Works good!!!

Can we add some tunning ? like if its ready to be taken, can we give effect running every some seconds or something vissible always that is ready to be taken ?


also on stepping on taken bonuses, can give the cancel message with time left to take bonus ?

what about magic level skilling, can add it there to ? maybe different tryes or ? how it shoud work in balanced manner?
This will add magicspend and also send a message with the remaining time.
(Again untested, so let me know if there are any errors.)
LUA:
local config = {
    tileActionId = 9000,  -- Tile actionId in RME
    exhaustTime = 40,     -- Exhaust time in minutes.
    allowNoneVoc = false    -- Set to true to allow the None(0) vocation
    debugMode = true,     -- Sets exhaustTime to 20 seconds. Change to false in live environment.
    experience = 100000,
  
    addSkills = true,
    skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST},
    skill_tries = 100000,
  
    addMagic = true,
    magic_tries = 100000,
}

--dont edit below

local store = {}

local function removeExhaust(key)
    if store[key] then
        store[key] = nil
    end
    return
end

local gainXpAndSkills = MoveEvent()
function gainXpAndSkills.onStepIn(player, item, position, fromPosition)
 
    --do basic checks
    if not player:isPlayer() or (not config.allowNoneVoc and player:getVocation():getId() == 0) then
        return false
    end
  
    local now = os.time()
    local playerId = player:getGuid()
    local key = ('%d:%d:%d:%d'):format(playerId, position.x, position.y, position.z)
 
    --check for exhaust
    if store[key] then
        player:teleportTo(fromPosition)
        position:sendMagicEffect(CONST_ME_POFF)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
      
        local remainder = store[key] - now
        local hours = floor(remainder / 3600)
        local minutes = floor((remainder % 3600) / 60)
        local seconds = remainder % 60
        local remainderString = ("%02dh:%02dm:%02ds"):format(hours, minutes, seconds)
      
        player:sendTextMessage(MESSAGE_STATUS_SMALL , ('You can use this again in %s'):format(remainderString))
        return true
    end
 
    --add exp
    player:addExperience(config.experience, true)
  
    --add skill tries
    if config.addSkills then
        for _, skill_type in ipairs(config.skill_types) do
            player:addSkillTries(skill_type, config.skill_tries)
        end
    end
  
    --add mana tries
    if config.addMagic then
        player:addManaSpent(config.magic_tries)
    end
 
    --schedule the exhaust removal for the future
    local _exhaustTime = config.debugMode and 20 or (config.exhaustTime * 60)
    addEvent(removeExhaust, _exhaustTime * 1000, key)
 
    store[key] = now + _exhaustTime
    return true
end
gainXpAndSkills:aid(config.tileActionId)
gainXpAndSkills:register()

Showing an effect only visible to a specific player can be very inefficient. There is no "good" way to do it. It would involve checking getSpectators around every position, and then checking that the player doesn't have an exhaust for that position. Only then would you send effect/text message to the tile for only that one spectator(player) to see it. If you are doing this with 100+ positions every 5 seconds, it becomes a waste for such a gimmick...
 
LUA:
local positions = {
    {x = 2918, y = 3120, z = 6},
    {x = 2917, y = 3120, z = 6},
    {x = 2919, y = 3120, z = 6} -- Add more positions as needed
}

local xp_per_minute = 100000 -- Replace with the amount of XP you want to give per minute
local skill_types = {SKILL_AXE, SKILL_SWORD, SKILL_CLUB, SKILL_DISTANCE, SKILL_SHIELD, SKILL_FIST} -- Types of skills you want to increase
local skill_rate = 100000 -- Rate at which to increase the skills
local interval = 60 -- Interval in seconds (1 minute)

local gainXpAndSkill = GlobalEvent("gainXpAndSkill")

function gainXpAndSkill.onThink(interval, lastExecution)
    local players = Game.getPlayers()
    for _, player in ipairs(players) do
        for _, pos in ipairs(positions) do
            if player:getPosition().x == pos.x and player:getPosition().y == pos.y and player:getPosition().z == pos.z then
                player:addExperience(xp_per_minute, true) -- Add experience to the player
                for _, skill_type in ipairs(skill_types) do
                    player:addSkillTries(skill_type, skill_rate) -- Increase the player's skill for each skill type
                end
                break -- Exit the loop once a match is found
            end
        end
    end
    return true
end

gainXpAndSkill:interval(interval * 1000) -- Convert seconds to milliseconds
gainXpAndSkill:register() -- Register the global event
Here you can select more than one tile (x/y/z pos)
You must respond and explain if the script works well and report that it has been solved
how add magic skill?
 
how add magic skill?
Friday The 13Th GIF by Digg
 
Back
Top