• 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 TFS 1.2 Exp & Spawn Rate via TalkAction

PlaguedWithRain

New Member
Joined
May 15, 2024
Messages
5
Reaction score
0
Hi,

I'm wondering if it's possible to control the exp and spawn rate (which has been specified in the server config document) via a TalkAction in-game?

For example, if my config document specifies 5x exp rate and 1x spawn rate is it possible to alter both these figures either for x amount of time or until it is switched back manually?

If not via TalkAction then perhaps through some other in-game mechanic?


Thank you.
 
Been looking into this more and thinking it's probably possible to increase or decrease the experience rate using TalkActions but not the spawn rate.

Does this sounds right according to someone smarter than me?
 
I created a simple script by adapting functions from the !serverinfo command to the /setrates command in a straightforward and easy manner. Simply use the command /setrates followed by exp, loot, spawn, or skill, and the desired value. For example, /setrates exp 150 1 sets the experience rate to 150x for 1 minute.

talkaction
setrates.lua
Lua:
local originalExpRate, originalSpawnRate, originalSkillRate, originalMagicRate, originalLootRate

function onSay(player, words, param)
    if not player:getGroup():getAccess() then
        return true
    end

    param = param:lower():gsub(",", " "):gsub("%s+", " ")
    local setting, rate, duration = param:match("(%w+)%s+(%d+)%s*(%d*)")
    rate = tonumber(rate)
    duration = tonumber(duration)

    if not setting or not rate then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Invalid parameter.")
        return true
    end

    if not originalExpRate or not originalSpawnRate or not originalSkillRate or not originalMagicRate or not originalLootRate then
        originalExpRate = configManager.getNumber(configKeys.RATE_EXPERIENCE)
        originalSpawnRate = configManager.getNumber(configKeys.RATE_SPAWN)
        originalSkillRate = configManager.getNumber(configKeys.RATE_SKILL)
        originalMagicRate = configManager.getNumber(configKeys.RATE_MAGIC)
        originalLootRate = configManager.getNumber(configKeys.RATE_LOOT)
    end

    if not originalExpRate or not originalSpawnRate or not originalSkillRate or not originalMagicRate or not originalLootRate then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not read current rates from config.")
        return true
    end

    local configFilePath = "config.lua"
    local file = io.open(configFilePath, "r")
    if not file then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not open config.lua file.")
        return true
    end

    local content = file:read("*all")
    file:close()

    local settingsMap = {
        exp = {key = "rateExp", original = originalExpRate, message = "Experience"},
        spawn = {key = "rateSpawn", original = originalSpawnRate, message = "Spawn"},
        skill = {key = "rateSkill", original = originalSkillRate, message = "Skill"},
        magic = {key = "rateMagic", original = originalMagicRate, message = "Magic"},
        loot = {key = "rateLoot", original = originalLootRate, message = "Loot"}
    }

    local settingConfig = settingsMap[setting]
    if not settingConfig then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Invalid parameter.")
        return true
    end

    content = content:gsub(settingConfig.key .. " = %d+", settingConfig.key .. " = " .. rate)
    local broadcastMessage = os.date("%H:%M") .. " An event has begun! " .. settingConfig.message .. " rate is now set to " .. rate .. "x"
    if duration then
        broadcastMessage = broadcastMessage .. " for " .. duration .. " minutes. Enjoy!"
    else
        broadcastMessage = broadcastMessage .. ". Enjoy!"
    end
    Game.broadcastMessage(broadcastMessage, MESSAGE_STATUS_WARNING)

    file = io.open(configFilePath, "w")
    if not file then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not write to config.lua file.")
        return true
    end
    file:write(content)
    file:close()
    Game.reload("config")

    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Rates successfully changed. Configurations reloaded.")

    if duration and duration > 0 then
        addEvent(function()
            local restoreContent = content
            for key, config in pairs(settingsMap) do
                restoreContent = restoreContent:gsub(config.key .. " = %d+", config.key .. " = " .. config.original)
            end

            local restoreFile = io.open(configFilePath, "w")
            if not restoreFile then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not write to config.lua file for restoration.")
                return
            end
            restoreFile:write(restoreContent)
            restoreFile:close()
            Game.reload("config")
            Game.broadcastMessage("The event has ended! Rates have been restored to their original values. Thank you for participating!", MESSAGE_STATUS_WARNING)
        end, duration * 60 * 1000)
    end

    return true
end
XML:
        <talkaction words="/setrates" separator=" " script="setrates.lua" />
 
I created a simple script by adapting functions from the !serverinfo command to the /setrates command in a straightforward and easy manner. Simply use the command /setrates followed by exp, loot, spawn, or skill, and the desired value. For example, /setrates exp 150 1 sets the experience rate to 150x for 1 minute.


Very nice, thank you...


I'm wondering if you or somebody else would be able to rework this so that one command will change the experience rate and spawn rate to set (non-variable) values until another command changes it back to default.

For example:

"/setrates spawn event" sets the experience rate to 1x and the spawn rate to 5x.

"/setrates default" sets the experience rate to 2x and the spawn rate to 1x.

Of course people will able to edit those values to their own tastes.


I'll work on it too and if I get there first I'll post it up for other people but if someone else manages to get there first that'd be great as there's really no guarantee I'll be capable of making it myself as I'm still learning (slowly).


Thanks.
 
Of course, it's possible. Here it is, just the way you wanted. Simply use the command /setrates spawn event and it will automatically set with a message. If you want to revert to the default, use /setrates default. I left a configuration table where you can change whatever you want.


Lua:
local defaultExpRate = 2
local defaultSpawnRate = 1

function onSay(player, words, param)
    if not player:getGroup():getAccess() then
        return true
    end

    local command = param:lower()

    if command == "spawn event" then
        setRates(1, 5)
        Game.broadcastMessage("The experience rate has been set to 1x and the spawn rate to 5x!", MESSAGE_STATUS_WARNING)
    elseif command == "default" then
        setRates(defaultExpRate, defaultSpawnRate)
        Game.broadcastMessage("The rates have been restored to default: experience rate 2x and spawn rate 1x!", MESSAGE_STATUS_WARNING)
    else
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Invalid command.")
    end

    return true
end

function setRates(expRate, spawnRate)
    local configFilePath = "config.lua"
    local file = io.open(configFilePath, "r")
    if not file then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not open config.lua file.")
        return
    end

    local content = file:read("*all")
    file:close()

    content = content:gsub("rateExp = %d+", "rateExp = " .. expRate)
    content = content:gsub("rateSpawn = %d+", "rateSpawn = " .. spawnRate)

    file = io.open(configFilePath, "w")
    if not file then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Error: Could not write to config.lua file.")
        return
    end

    file:write(content)
    file:close()
    Game.reload("config")
end
 
Of course, it's possible. Here it is, just the way you wanted. Simply use the command /setrates spawn event and it will automatically set with a message. If you want to revert to the default, use /setrates default. I left a configuration table where you can change whatever you want.

Thanks for putting the time into this.

Been testing on TFS 1.2...

It turns out you can't have "Game.reload" as part of a TalkAction on TFS 1.2, this will only work on TFS 1.3 or higher. Your script will only work for a TFS 1.2 user if they remove line 46 entirely. You then have to separately type "/config reload" to reload the config (this command is only in sources for TFS 1.2 but not available as a TalkAction) . I guess we could edit your script to force the user to send those words to execute the config reload as a separate command/action. Which seems a fine workaround to me.

The other strange thing, which I haven't been able to solve, is that if your script is executed and config is then reloaded the exp rate will update correctly but the spawn time of monsters won't actually change until you shutdown and relaunch the server (even though the figure had been altered in the config.lua document and the config has been reloaded).
 
Back
Top