• 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.5] Counter based on a monster.

Sarah Wesker

ƐƖєgαηт Sуηтαx ❤
Staff member
TFS Developer
Support Team
Joined
Mar 16, 2017
Messages
1,422
Solutions
155
Reaction score
1,986
Location
London
GitHub
MillhioreBT
Twitch
millhiorebt
I have created a couple of functions that help create a monster that represents a countdown timer with its name changing every second to reflect the countdown. On each tick, an onThink function is executed if it exists, or an onEnd function is executed if it exists. This function accepts some parameters such as position, seconds, prefix, suffix, outfit or lookType, with the only required parameters being position and seconds. The function is called Game.createMonsterCounter(props).

In summary, this function creates a dynamic countdown timer that can be customized with various parameters. The countdown is represented by a monster whose name changes every second, and the function allows for the execution of custom functions on each tick and on the countdown's completion. This function can be useful for creating time-based events or challenges in games.

to install this function you just have to add a lua file to your scripts.
data/scripts/counter.lua
Lua:
--[[
    Monster Counter
    By: 𝓜𝓲𝓵𝓵𝓱𝓲𝓸𝓻𝓮 𝓑𝓣
    version: 1.0
]]--

local function timeFormat(seconds)
    local hours = math.floor(seconds / 3600)
    local minutes = math.floor((seconds - (hours * 3600)) / 60)
    local seconds = seconds - (hours * 3600) - (minutes * 60)
    local time = {}
    if hours > 0 then time[#time + 1] = hours .. "h " end
    if minutes > 0 then time[#time + 1] = minutes .. "m " end
    if seconds > 0 then time[#time + 1] = seconds .. "s " end
    return table.concat(time)
end

local Counter = Creature
local function getSeconds(counter) return counter:getStorageValue("MonsterCounter") end
local function setSeconds(counter, seconds) return counter:setStorageValue("MonsterCounter", seconds) end
local function decreaseSeconds(counter) return setSeconds(counter, getSeconds(counter) - 1) end
local function updateHealth(counter, initialSeconds) return counter:setHealth(math.ceil(counter:getMaxHealth() / 100 * math.ceil((getSeconds(counter) * 100) / initialSeconds))) end
local function updateName(counter, props)
    local name = {}
    if type(props.prefix) == "string" then
        name[#name + 1] = props.prefix
    end

    name[#name + 1] = timeFormat(getSeconds(counter))

    if type(props.suffix) == "string" then
        name[#name + 1] = props.suffix
    end

    return counter:rename(table.concat(name))
end

local function onThink(props)
    local counter = Counter(props.counterId)
    if not counter then
        error("Could not find counter.")
    end

    local seconds = getSeconds(counter)
    if seconds <= 0 then
        if props.onEnd then
            props.onEnd(counter:getPosition())
        end
        return counter:remove()
    end

    updateName(counter, props)
    decreaseSeconds(counter)
    updateHealth(counter, props.initialSeconds)
    if props.onThink then
        props.onThink(getSeconds(counter), counter:getPosition())
    end

    if not counter:isRemoved() then
        addEvent(onThink, 1000, props)
    end
    return true
end

function Game.createMonsterCounter(props)
    if type(props) ~= "table" then
        error("Invalid props table.")
    end

    if getmetatable(props.position) ~= Position then
        error("Invalid position.")
    end

    if type(props.seconds) ~= "number" then
        error("Invalid seconds.")
    end

    local counter = Game.createMonster("Monster Counter", props.position, true, true)
    if not counter then
        error("Could not create counter.")
    end

    if type(props.outfit) == "table" then
        counter:setOutfit(props.outfit)
    elseif type(props.lookType) == "number" then
        local outfit = counter:getOutfit()
        outfit.lookType = props.lookType
        counter:setOutfit(outfit)
    end

    updateName(counter, props)
    setSeconds(counter, props.seconds)
    props.initialSeconds = props.seconds
    props.counterId = counter:getId()
    addEvent(onThink, 1000, props)
    return true
end

-- Model
local mType = Game.createMonsterType("Monster Counter")
local monster = {}
monster.description = "an monster counter"
monster.experience = 0
monster.outfit = { lookType = 0 }
monster.health = 10000000
monster.maxHealth = monster.health
monster.race = "blood"
monster.corpse = 0
monster.speed = 0
monster.changeTarget = { interval = 0, chance = 0 }
monster.flags = {
    summonable = false,
    attackable = false,
    hostile = false,
    challengeable = false,
    convinceable = false,
    ignoreSpawnBlock = false,
    illusionable = false,
    canPushItems = true,
    canPushCreatures = true,
    targetDistance = 1,
    staticAttackChance = 0
}

mType:register(monster)

Example of how it could be used:
Lua:
local talkAction = TalkAction("/counter")

function talkAction.onSay(player, words, param, type)
    Game.createMonsterCounter({
        position = player:getPosition(),
        seconds = 10,
        prefix = "Counter: ",
        suffix = "seconds",
        onEnd = function(position)
            Game.createMonster("Demon", position, true, true)
        end,
        onThink = function(seconds, position)
            position:sendMagicEffect(232)
            if seconds == 5 then
                Game.createMonster("Rotworm", position, true, true)
            end
        end
    })
    return false
end

talkAction:register()
asdfr.gif
It's worth mentioning that this is just a very simple example, and the possibilities are endless.

Notes:
The inspiration for this function was taken from the thread of Noveria.
 
Nice release!! I'll be using your release on my server, and I can't wait to see how it enhances my server. Thank you once again for all that you do, and I look forward to seeing what other amazing creations you come up with in the future! 😍😍
 
Just write bug report on mehah github then :)
Worth a try making a new blank looktype (should have animations too btw) in object builder that wouldn't have any graphic and then in the script switching it's id there: monster.outfit = { lookType = 0 }
Maybe mehah has some check for looktype 0 and might recognize it as a non existent.
 
Back
Top