• 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 0.X Raid System - Crashing Server

potinho

Intermediate OT User
Joined
Oct 11, 2009
Messages
1,397
Solutions
17
Reaction score
148
Location
Brazil
Hello everyone, everything good?

I would like to ask you for help:

I implemented a MOD that performs a task on predefined days and times, but when the task runs, the CPU consumption of the VPS increases a lot, sometimes even making it impossible to login to the machine. Could you help me fix and improve the script?

XML:
<?xml version="1.0" encoding="UTF-8"?>
<mod name="Automatic Raids" version="1.0" author="Vodkart And xotservx" contact="tibiaking.com" enabled="yes">
<config name="raids_func">



<![CDATA[
days = {
    -- Segunda
    ["Monday"] = {
        ["17:00"] = {nome = "Ferumbras", pos = {fromPosition = {x=118, y=227, z=8},toPosition = {x=127, y=232, z=8}},m = {"1 Ferumbras"}, Time = 20},
        ["22:00"] = {nome = "Dragon", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}},m = {"100 Dragon"}, Time = 20}
    },
    -- Terça
    ["Tuesday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Quarta
    ["Wednesday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Quinta
    ["Tursday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Sexta
    ["Friday"] = {
        ["12:00"] = {nome = "Ancient Gargoyle", pos = {fromPosition = {x=693, y=139, z=7},toPosition = {x=737, y=170, z=7}}, m = {"15 Ancient Gargoyle"}, Time = 20},
        ["17:00"] = {nome = "Djins", pos = {fromPosition = {x=224, y=77, z=7},toPosition = {x=256, y=107, z=7}}, m = {"15 Marid", "15 Efreet"}, Time = 20},
        ["21:00"] = {nome = "Ferumbras", pos = {fromPosition = {x=282, y=305, z=8},toPosition = {x=289, y=307, z=8}}, m = {"1 Ferumbras"}, Time = 15}
    },
    -- Sábado
    ["Saturday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Domingo
    ["Sunday"] = {
        ["20:33"] = {nome = "renegados", pos = {fromPosition = {x=1019, y=916, z=7},toPosition = {x=1033, y=922, z=7}}, m = {"1 Renegade", "1 Bandit", "1 Shinobi Archer"}, Time = 1},
        ["20:30"] = {nome = "Ferumbras", pos = {fromPosition = {x=359, y=192, z=5},toPosition = {x=364, y=195, z=5}}, m = {"1 Ferumbras"}, Time = 30}
    }
}
]]></config>
<globalevent name="AutomaticRaids" interval="60000" event="script"><![CDATA[
domodlib('raids_func')
function onThink(interval, lastExecution) 
    function isWalkable(pos) -- by Nord / editado por Omega
        if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then
            return false
        elseif isCreature(getTopCreature(pos).uid) then
            return false
        elseif getTileInfo(pos).protection then
            return false
        elseif hasProperty(getThingFromPos(pos).uid, 3) or hasProperty(getThingFromPos(pos).uid, 7) then
            return false
        end
        return true
    end
 
    if days[os.date("%A")] then
        hours = tostring(os.date("%X")):sub(1, 5)
        tb = days[os.date("%A")][hours]
        if tb then
            function removeCreature(tb)
                for x = ((tb.pos.fromPosition.x)-20), ((tb.pos.toPosition.x)+20) do
                    for y = ((tb.pos.fromPosition.y)-20), ((tb.pos.toPosition.y)+20) do
                        local m = getTopCreature({x=x, y=y, z= tb.pos.fromPosition.z}).uid
                        if m ~= 0 and isMonster(m) then
                            doSendMagicEffect(getCreaturePosition(m), CONST_ME_MORTAREA)
                            doRemoveCreature(m)
                        end
                    end
                end
            end
            doBroadcastMessage("Uma orda de " .. tb.nome .. " esta invadindo a cidade ajude a defende-la") -- Mensagem que vai aparecer para todos do servidor quando a invasão iniciar
            for _ , x in pairs(tb.m) do
                local c = tonumber(x:match("%d+"))
                if c > 0 then
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0
                end
            end
            addEvent(removeCreature, tb.Time*60000*1000, tb)
            addEvent(doBroadcastMessage, tb.Time*60*1000, "A invasão de " .. tb.nome .. " acabou, os sobreviventes fugiram") -- Mensagem que vai aparecer para todos do servidor quando a invasão iniciar
        end
    end
    return true
end
]]></globalevent>
</mod>
 
Solution
Replace:
Lua:
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1...
Hello everyone, everything good?

I would like to ask you for help:

I implemented a MOD that performs a task on predefined days and times, but when the task runs, the CPU consumption of the VPS increases a lot, sometimes even making it impossible to login to the machine. Could you help me fix and improve the script?

XML:
<?xml version="1.0" encoding="UTF-8"?>
<mod name="Automatic Raids" version="1.0" author="Vodkart And xotservx" contact="tibiaking.com" enabled="yes">
<config name="raids_func">



<![CDATA[
days = {
    -- Segunda
    ["Monday"] = {
        ["17:00"] = {nome = "Ferumbras", pos = {fromPosition = {x=118, y=227, z=8},toPosition = {x=127, y=232, z=8}},m = {"1 Ferumbras"}, Time = 20},
        ["22:00"] = {nome = "Dragon", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}},m = {"100 Dragon"}, Time = 20}
    },
    -- Terça
    ["Tuesday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Quarta
    ["Wednesday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Quinta
    ["Tursday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Sexta
    ["Friday"] = {
        ["12:00"] = {nome = "Ancient Gargoyle", pos = {fromPosition = {x=693, y=139, z=7},toPosition = {x=737, y=170, z=7}}, m = {"15 Ancient Gargoyle"}, Time = 20},
        ["17:00"] = {nome = "Djins", pos = {fromPosition = {x=224, y=77, z=7},toPosition = {x=256, y=107, z=7}}, m = {"15 Marid", "15 Efreet"}, Time = 20},
        ["21:00"] = {nome = "Ferumbras", pos = {fromPosition = {x=282, y=305, z=8},toPosition = {x=289, y=307, z=8}}, m = {"1 Ferumbras"}, Time = 15}
    },
    -- Sábado
    ["Saturday"] = {
        ["17:00"] = {nome = "Demon", pos = {fromPosition = {x=202, y=11, z=7},toPosition = {x=204, y=12, z=7}}, m = {"1 Demon"}, Time = 15},
        ["22:00"] = {nome = "Hydra", pos = {fromPosition = {x=197, y=57, z=7},toPosition = {x=203, y=60, z=7}}, m = {"7 Hydra", "4 Cyclops"}, Time = 20}
    },
    -- Domingo
    ["Sunday"] = {
        ["20:33"] = {nome = "renegados", pos = {fromPosition = {x=1019, y=916, z=7},toPosition = {x=1033, y=922, z=7}}, m = {"1 Renegade", "1 Bandit", "1 Shinobi Archer"}, Time = 1},
        ["20:30"] = {nome = "Ferumbras", pos = {fromPosition = {x=359, y=192, z=5},toPosition = {x=364, y=195, z=5}}, m = {"1 Ferumbras"}, Time = 30}
    }
}
]]></config>
<globalevent name="AutomaticRaids" interval="60000" event="script"><![CDATA[
domodlib('raids_func')
function onThink(interval, lastExecution)
    function isWalkable(pos) -- by Nord / editado por Omega
        if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then
            return false
        elseif isCreature(getTopCreature(pos).uid) then
            return false
        elseif getTileInfo(pos).protection then
            return false
        elseif hasProperty(getThingFromPos(pos).uid, 3) or hasProperty(getThingFromPos(pos).uid, 7) then
            return false
        end
        return true
    end
 
    if days[os.date("%A")] then
        hours = tostring(os.date("%X")):sub(1, 5)
        tb = days[os.date("%A")][hours]
        if tb then
            function removeCreature(tb)
                for x = ((tb.pos.fromPosition.x)-20), ((tb.pos.toPosition.x)+20) do
                    for y = ((tb.pos.fromPosition.y)-20), ((tb.pos.toPosition.y)+20) do
                        local m = getTopCreature({x=x, y=y, z= tb.pos.fromPosition.z}).uid
                        if m ~= 0 and isMonster(m) then
                            doSendMagicEffect(getCreaturePosition(m), CONST_ME_MORTAREA)
                            doRemoveCreature(m)
                        end
                    end
                end
            end
            doBroadcastMessage("Uma orda de " .. tb.nome .. " esta invadindo a cidade ajude a defende-la") -- Mensagem que vai aparecer para todos do servidor quando a invasão iniciar
            for _ , x in pairs(tb.m) do
                local c = tonumber(x:match("%d+"))
                if c > 0 then
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0
                end
            end
            addEvent(removeCreature, tb.Time*60000*1000, tb)
            addEvent(doBroadcastMessage, tb.Time*60*1000, "A invasão de " .. tb.nome .. " acabou, os sobreviventes fugiram") -- Mensagem que vai aparecer para todos do servidor quando a invasão iniciar
        end
    end
    return true
end
]]></globalevent>
</mod>
It is probably some position that is wrongly configured and is blocking the respawn, so the mod runs and does not stop. The positions should be in a position where it is not so easy to block (protected area, walls, non-movable items) the respawn.

I have tested this system and it works correctly

Screenshot-from-2021-10-06-12-28-01.png
 
It is probably some position that is wrongly configured and is blocking the respawn, so the mod runs and does not stop. The positions should be in a position where it is not so easy to block (protected area, walls, non-movable items) the respawn.

I have tested this system and it works correctly

Screenshot-from-2021-10-06-12-28-01.png
Thanks for reply @Alberto Cabrera . There is a way to remove this check? I want to put a raid on a forest (too many trees and blocking areas), to simplify script, or dont validate the area and stop summon.
 
Last edited:
Another problem:

when time for raid is finished, a message appear saying its over, but not removing the raid monster.
 
In some cases it might never find a valid position and just loop forever.

Get rid of the repeat loot and just replace it with a 1,3 loop so it tries a max of 3 times instead of getting stuck almost indefinitely looking for a place it can place the monster.

At the very least, change until c == 0 to until c <= 0 incase it's already 0 and starts at -1 and loops forever.
 
In some cases it might never find a valid position and just loop forever.

Get rid of the repeat loot and just replace it with a 1,3 loop so it tries a max of 3 times instead of getting stuck almost indefinitely looking for a place it can place the monster.

At the very least, change until c == 0 to until c <= 0 incase it's already 0 and starts at -1 and loops forever.
Can u help me to rewrite in correct way?
 
Replace:
Lua:
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0
with:
Lua:
                    local tries = 1000
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        tries = tries - 1
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0 or tries == 0
It will try to find random empty position 1000 times and if it fails, it will stop.
 
Solution
Replace:
Lua:
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0
with:
Lua:
                    local tries = 1000
                    repeat
                        local pos = {x = math.random(tb.pos.fromPosition.x, tb.pos.toPosition.x), y = math.random(tb.pos.fromPosition.y, tb.pos.toPosition.y), z = tb.pos.fromPosition.z}
                        tries = tries - 1
                        if isWalkable(pos) then
                            doCreateMonster(x:match("%s(.+)"), pos)
                            doSendDistanceShoot({x = pos.x - math.random(4, 6), y = pos.y - 5, z = pos.z}, pos, CONST_ANI_FIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_HITBYFIRE)
                            addEvent(doSendMagicEffect, 150, pos, CONST_ME_FIREAREA)
                            doSendMagicEffect(pos, CONST_ME_MORTAREA)
                            c = c-1
                        end
                    until c == 0 or tries == 0
It will try to find random empty position 1000 times and if it fails, it will stop.
Thanks Gesior!
 
Back
Top