• 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.X+ Extending script to multiple usage (TFS 1.4)

BBQ Fanatic

New Member
Joined
Jul 10, 2022
Messages
13
Reaction score
3
Hi :)

I'm trying to create a feature, which gives player experience when he arrives at specific location for the first time.
So far, I've made something like that (I'm not good at lua (yet :p), so code review would be appreciated)

movements.xml
Code:
<movevent event="StepIn" actionid="6661" script="discover.lua"/>

discover.lua
Code:
function onStepIn(cid, item, pos)
local discover = 7670

    if isPlayer(cid) then
        if getPlayerStorageValue(cid,discover) < 0 then
            setPlayerStorageValue(cid, discover, 1)
            doSendMagicEffect(getCreaturePosition(cid), 13)
            doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You discovered new place. \n You gained 1750 experience points.")
            doPlayerAddExp(cid, 1750)
        end
    end
end

In RME:

example.png

And, whats surprising to me, it works.
But I'd like to have multiple places like this.
Theoretically I can copy-paste that X times. But I imagine it can be done somehow using arrays. But I don't know how to do it. The only thing that came up to my head was starting with array like this:
Code:
local places = {
    { aid = 6661, storage = 7670, name = 'Cave', expgain = 500 },  --"name" appears here, because message will be showing discovered place's name
    { aid = 6662, storage = 7671, name = 'Other Place', expgain = 1000 }, -- exp will be various depending on the location level
}

And on that I stuck. Have no idea how modify that code to work with array, dunno if i gotta use for loop or whatever.
And, how link that in movements.xml since it has actionId parameter, which will be different for each place.
 
Last edited:
Solution
Hi :)

I'm trying to create a feature, which gives player experience when he arrives at specific location for the first time.
So far, I've made something like that (I'm not good at lua (yet :p), so code review would be appreciated)

movements.xml
Code:
<movevent event="StepIn" actionid="6661" script="discover.lua"/>

discover.lua
Code:
function onStepIn(cid, item, pos)
local discover = 7670

    if isPlayer(cid) then
        if getPlayerStorageValue(cid,discover) < 0 then
            setPlayerStorageValue(cid, discover, 1)
            doSendMagicEffect(getCreaturePosition(cid), 13)
            doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You discovered new place. \n You gained 1750 experience points.")...
Hi :)

I'm trying to create a feature, which gives player experience when he arrives at specific location for the first time.
So far, I've made something like that (I'm not good at lua (yet :p), so code review would be appreciated)

movements.xml
Code:
<movevent event="StepIn" actionid="6661" script="discover.lua"/>

discover.lua
Code:
function onStepIn(cid, item, pos)
local discover = 7670

    if isPlayer(cid) then
        if getPlayerStorageValue(cid,discover) < 0 then
            setPlayerStorageValue(cid, discover, 1)
            doSendMagicEffect(getCreaturePosition(cid), 13)
            doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You discovered new place. \n You gained 1750 experience points.")
            doPlayerAddExp(cid, 1750)
        end
    end
end

In RME:

View attachment 69174

And, whats surprising to me, it works.
But I'd like to have multiple places like this.
Theoretically I can copy-paste that X times. But I imagine it can be done somehow using arrays. But I don't know how to do it. The only thing that came up to my head was starting with array like this:
Code:
local places = {
    { aid = 6661, storage = 7670, name = 'Cave', expgain = 500 },  --"name" appears here, because message will be showing discovered place's name
    { aid = 6662, storage = 7671, name = 'Other Place', expgain = 1000 }, -- exp will be various depending on the location level
}

And on that I stuck. Have no idea how modify that code to work with array, dunno if i gotta use for loop or whatever.
And, how link that in movements.xml since it has actionId parameter, which will be different for each place.

First off, fantastic first post.
It made it really easy to help you. :)

Try this.

Put it into data/scripts as a .lua file. Name it whatever you want.
Each new place will have it's own actionId and storage value.
Put it on the map, just like you've been doing.
Lua:
local places = {
    [6661] = { storage = 7670, expgain = 500, effect = CONST_ME_POFF, name = "Cave"}, -- [actionId] = {}
    [6662] = { storage = 7671, expgain = 1000, effect = 13, name = "Other Place"},
}

local discover = MoveEvent()
discover:type("stepin")

function discover.onStepIn(creature, item, position, fromPosition)
    if not creature:isPlayer() then
        return true
    end
  
    local player = creature

    local index = places[item:getActionId()]
    if player:getStorageValue(index.storage) > 0 then
        return true
    end
  
    item:getPosition():sendMagicEffect(index.effect)
    player:setStorageValue(index.storage, 1)
    player:addExperience(index.expgain)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You discovered " .. index.name .. ".\nYou gained " .. index.expgain .. " experience points.")
    return true
end

for actionId, config in pairs(places) do
    discover:aid(actionId)
end
discover:register()
 
Last edited:
Solution
First off, fantastic first post.
What you mean? :)

Try this.
I'm confused now. It does not work, but no errors in console. I checked if storage was applied, but not. Tried to find any typos, like "stepin" -> "StepIn" or deleting comma in array's last row, but didn't help. Do I need to register this script in other file, or something?
Just for case: I deleted link from movements.xml, since it is in data/scripts now.
 
@Xikini
Code:
local discover = MoveEvent()
discover:type("stepin")
How does it bind event to action ids?

I think that you must add this at end of script:
Lua:
for actionId, config in pairs(places) do
    discover:aid(actionId)
end
discover:register()
 
@Xikini
Code:
local discover = MoveEvent()
discover:type("stepin")
How does it bind event to action ids?

I think that you must add this at end of script:
Lua:
for actionId, config in pairs(places) do
    discover:aid(actionId)
end
discover:register()
Yup, you're right. I copy paste failed

Edited my above post.
 
Okay, now it's ###ing works! I'm as happy as sad, because now this code is not readable as mine was (for lua noob which i am) what means I would never figure it out by myself.

Let me drain your skills a bit more. Just right now a thought came to my mind. What if I would want to SOME (not each) discovered places also give an achievement? Or others additional functions like giving item etc.? What I would do right now is creating another script (by my way from 1st post) that triggers at the same time.
 
Okay, now it's ###ing works! I'm as happy as sad, because now this code is not readable as mine was (for lua noob which i am) what means I would never figure it out by myself.

Let me drain your skills a bit more. Just right now a thought came to my mind. What if I would want to SOME (not each) discovered places also give an achievement? Or others additional functions like giving item etc.? What I would do right now is creating another script (by my way from 1st post) that triggers at the same time.

data/lib/core/achievements.lua to find the achievement names. (or add your own)

I'd do something like this.

Lua:
local places = {
    [6661] = {
        storage = 7670, -- storage and name required. Everything else is optional.
        name = "Cave",
        
        effect = CONST_ME_POFF, -- remove any of these from the table to disable them.        
        expgain = 500, 
        achievement = "Blessed!",
        rewardItem = {itemId = 1111, amount = 1}
    },
    [6662] = { -- example of discovered place, with no rewards or effects.
        storage = 7671,
        name = "Other Place",
    },
}

local discover = MoveEvent()
discover:type("stepin")

function discover.onStepIn(creature, item, position, fromPosition)
    if not creature:isPlayer() then
        return true
    end
  
    local player = creature
    local index = places[item:getActionId()]
    
    if player:getStorageValue(index.storage) > 0 then
        return true
    end
    player:setStorageValue(index.storage, 1)
  
    if index.effect then
        item:getPosition():sendMagicEffect(index.effect)
    end
    
    if index.achievement then
        player:addAchievement(index.achievement)
    end
    
    local text = "You discovered " .. index.name .. "."
    
    if index.expgain then
        player:addExperience(index.expgain)
        text = text .. "\nYou've gained " .. index.expgain .. " experience points."
    end
    
    if index.rewardItem then
        player:addItem(index.rewardItem.itemId, index.rewardItem.amount, true)
        text = text .. "\nYou've received " .. index.rewardItem.amount .. " " .. ItemType(index.rewardItem.itemId):getName() .. "."
    end
    
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, text)
    return true
end

for actionId, config in pairs(places) do
    discover:aid(actionId)
end
discover:register()
 
Back
Top