• 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+ TFS 1.2 Add timer on spell

Lopaskurwa

Active Member
Joined
Oct 6, 2017
Messages
873
Solutions
2
Reaction score
49
Is it possible to add timer on this spell so it would count when it will be casted. Basically this spell is not created in spells lua but direcetly in monster file, but basically what it does it casts wave spell that one shots everyone

<attacks>
<attack name="lifedrain" interval="2000" chance="85" length="15" spread="0" min="-3000000" max="-5000000">
<attribute key="areaEffect" value="purpleenergy"/>
</attack>
 
Probably several ways of doing it, i have not done custom spells for monsters yet, but you can create a monster script that kills all people on a given situation.

I think this should do(not tested):


Lua:
function onCreatureAppear(cid)
    local think = createConditionObject(CONDITION_ATTRIBUTES) -- conditions are the only way to force a monster to "think", even if there are no players nearby
    setConditionParam(think, CONDITION_PARAM_TICKS, -1) -- set condition to be indefinite in duration
    cid:addCondition(think) -- give condition to monster

end
function onCreatureDisappear(cid)                    end
function onCreatureSay(cid, type, msg)                end
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

end

local function killAll(monster)
    local monsterPos = monster:getPosition()
    local area = Game.getSpectators(monsterPos,false,true,3,3,3,3) -- Check for players 3 sqm from monster in all ranges
    for _,playerID in pairs(area) do
        local player = Player(playerID)
        if player then
        local maxHealth = player:getMaxHealth()
            monsterPos:sendDistanceEffect(player:getPosition(), CONST_ANI_ENERGYBALL)
            doTargetCombat(0, player, COMBAT_ENERGYDAMAGE, -maxHealth, -maxHealth, CONST_ME_PURPLEENERGY, true, false, false)
        end
    end
return true
end

function onThink(monster)
local rand = math.random(1,100)
    if rand <= 2 then
        killAll(monster)
    end
end



EDIT: With timer(Again not tested)

Lua:
local function killAll(monsterID)
    local monster = Monster(monsterID)
    local monsterPos = monster:getPosition()
    local area = Game.getSpectators(monsterPos,false,true,3,3,3,3) -- Check for players 3 sqm from monster in all ranges
    for _,playerID in pairs(area) do
        local player = Player(playerID)
        if player then
            local maxHealth = player:getMaxHealth()
            monsterPos:sendDistanceEffect(player:getPosition(), CONST_ANI_ENERGYBALL)
            doTargetCombat(0, player, COMBAT_ENERGYDAMAGE, -maxHealth, -maxHealth, CONST_ME_PURPLEENERGY, true, false, false)
        end
    end
    return true
end

local function countdownTimer(creatureID, count)
    local creature = Monster(creatureID)
    if not creature then
        return false
    end
   
    if count > 0 then
        creature:say(count, TALKTYPE_MONSTER_SAY, nil, nil, creature:getPosition())
        addEvent(countdownTimer, 1000, creature.uid, count - 1)
    else
        killAll(creature.uid)
    end
end




local timeToKill = 100 --seconds
function onCreatureAppear(creature)

creature:say("You have "..timeToKill.." seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY, nil, nil, creature:getPosition())
addEvent(countdownTimer, 3000, creature, timeToKill)
end




function onCreatureDisappear(cid)                    end
function onCreatureSay(cid, type, msg)                end
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin) end

function onThink(monster) end
 
Last edited:
Gives error on monster spell call because it doesnt have onCastSpell
Post automatically merged:

Fixed the error but monster doesnt cast that spell
Post automatically merged:

Okay so i wrote this but now spell became target idk how to make it wave for some reason it ignores my local arr and directions
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN) -- Use COMBAT_LIFEDRAIN for a powerful one-shot kill
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) -- Set a visual effect

local arr = {
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 3, 0},
}

local area = createCombatArea(arr)
setCombatArea(combat, area)

local timeToKill = 5 -- seconds (adjust this value to your desired countdown duration)

function doCreatureDamage(target, damage)
    if target then
        target:setHealth(0) -- Set the target's health to 0 to simulate their death
    end
end

function onCastSpell(cid, var)
    local creature = Creature(cid)
    if creature then
        creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                local target = creature:getTarget()
                if target then
                    local damage = target:getMaxHealth() -- Set the damage to the target's max health (one-shot kill)
                    doCreatureDamage(target, damage)
                end
            end
        end

        countdown() -- Start the countdown
    end
end
 
Last edited:
Gives error on monster spell call because it doesnt have onCastSpell
Post automatically merged:

Fixed the error but monster doesnt cast that spell
Post automatically merged:

Okay so i wrote this but now spell became target idk how to make it wave for some reason it ignores my local arr and directions
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN) -- Use COMBAT_LIFEDRAIN for a powerful one-shot kill
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) -- Set a visual effect

local arr = {
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 1, 0},
    {0, 3, 0},
}

local area = createCombatArea(arr)
setCombatArea(combat, area)

local timeToKill = 5 -- seconds (adjust this value to your desired countdown duration)

function doCreatureDamage(target, damage)
    if target then
        target:setHealth(0) -- Set the target's health to 0 to simulate their death
    end
end

function onCastSpell(cid, var)
    local creature = Creature(cid)
    if creature then
        creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                local target = creature:getTarget()
                if target then
                    local damage = target:getMaxHealth() -- Set the damage to the target's max health (one-shot kill)
                    doCreatureDamage(target, damage)
                end
            end
        end

        countdown() -- Start the countdown
    end
end

First of all, your countdown function. You should pass the counter as an argument back. How else will it know how much time is left? Don't change the timer i posted.

Also, your trying to create an area spell with target. that means the player has to be in the direction of the monster to hit him.
The code i made was not ment as a spell, but with monster interaction, also without area damage but target.

I'm not very experienced with coding spells.
 
Last edited:
First of all, your countdown function will not work. You have to pass the counter as an argument back. How else will it know how much time is left? Don't change the timer i posted.

Also, your trying to create an area spell with target. that means the player has to be in the direction of the monster to hit him.
The code i made was not ment as a spell, but with monster interaction, also without area damage but target.

I'm not very experienced with coding spells.
I mean my timer works perfectly fine but your doesnt i just tested it the only issue it has now it became target spell not wave, it ignore local arr = { parameter
 
First of all, don't define a local function inside another function, move it outside the scope of and above the onCastSpell function.

Secondly, once the timer hits 0, you can just call combat:execute(cid, var), and just setFormula for COMBAT_FORMULA_DAMAGE, and make it a large value to make sure everyone dies.

You could even use a custom callback using CALLBACK_PARAM_TARGETTILE, if you want to do something specific.
 
GIF 14-10-2023 11-00-14.gif

I had to correct some, I tested it and it is working perfectly. :)

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)


local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

function onCastSpell(cid, var)
    local timeToKill = 5
    local creature = Creature(cid)

    local function doCreatureDamage(target, damage)
        if target then
            target:addHealth(-damage)
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                local target = creature:getTarget()
                if target then
                    local damage = target:getMaxHealth()
                    doCreatureDamage(target, damage)
                end

                combat:execute(creature, var)
            end
        end

        countdown()
    end

    startCombat()
end
Post automatically merged:

What I posted in the first post was just a target. So I decided to fix it so that all targets work well. If you want, you can adjust only the damage with 'local damage = 1000000'.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

function onCastSpell(cid, var)
    local creature = Creature(cid)
    local targets = {}
    local damage = 1000000
    local radius = 5
    local timeToKill = 5

    local function doCreatureDamage(target)
        if target and target ~= creature then
            target:addHealth(-damage)
        end
    end

    local function getTargetsInArea(centerPosition)
        for x = centerPosition.x - radius, centerPosition.x + radius do
            for y = centerPosition.y - radius, centerPosition.y + radius do
                local tile = Tile(Position(x, y, centerPosition.z))
                if tile then
                    local creature = tile:getTopCreature()
                    if creature and creature:isCreature() then
                        table.insert(targets, creature)
                    end
                end
            end
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)

    getTargetsInArea(creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                for _, target in ipairs(targets) do
                    doCreatureDamage(target)
                end

                combat:execute(creature, var)
            end
        end
        countdown()
    end

    startCombat()

    return true
end
 
Last edited:
View attachment 79248

I had to correct some, I tested it and it is working perfectly. :)

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)


local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

function onCastSpell(cid, var)
    local timeToKill = 5
    local creature = Creature(cid)

    local function doCreatureDamage(target, damage)
        if target then
            target:addHealth(-damage)
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                local target = creature:getTarget()
                if target then
                    local damage = target:getMaxHealth()
                    doCreatureDamage(target, damage)
                end

                combat:execute(creature, var)
            end
        end

        countdown()
    end

    startCombat()
end
Post automatically merged:

What I posted in the first post was just a target. So I decided to fix it so that all targets work well. If you want, you can adjust only the damage with 'local damage = 1000000'.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

function onCastSpell(cid, var)
    local creature = Creature(cid)
    local targets = {}
    local damage = 1000000
    local radius = 5
    local timeToKill = 5

    local function doCreatureDamage(target)
        if target and target ~= creature then
            target:addHealth(-damage)
        end
    end

    local function getTargetsInArea(centerPosition)
        for x = centerPosition.x - radius, centerPosition.x + radius do
            for y = centerPosition.y - radius, centerPosition.y + radius do
                local tile = Tile(Position(x, y, centerPosition.z))
                if tile then
                    local creature = tile:getTopCreature()
                    if creature and creature:isCreature() then
                        table.insert(targets, creature)
                    end
                end
            end
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)

    getTargetsInArea(creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                for _, target in ipairs(targets) do
                    doCreatureDamage(target)
                end

                combat:execute(creature, var)
            end
        end
        countdown()
    end

    startCombat()

    return true
end

You shouldn't be re-defining each local function on each spell cast, it's very inefficient.

The combat and its parameter's are already defined.... so a simple addEvent to call combat:execute is all that is needed. And if you really want to, you can just use a attach a CALLBACK_PARAM_TARGETTILE callback to combat, and do it that way.
 
You shouldn't be re-defining each local function on each spell cast, it's very inefficient.

The combat and its parameter's are already defined.... so a simple addEvent to call combat:execute is all that is needed. And if you really want to, you can just use a attach a CALLBACK_PARAM_TARGETTILE callback to combat, and do it that way.
I shortened the code, as you said it was too long. So I formatted it to make it better and easier to read.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

local damage = 1000000
local radius = 5
local timeToKill = 5

function onCastSpell(cid, var)
    local creature = Creature(cid)
    local targets = {}
    
    local function doCreatureDamage(target)
        if target and target ~= creature then
            target:addHealth(-damage)
        end
    end

    local function getTargetsInArea(centerPosition)
        for x = centerPosition.x - radius, centerPosition.x + radius do
            for y = centerPosition.y - radius, centerPosition.y + radius do
                local tile = Tile(Position(x, y, centerPosition.z))
                if tile then
                    local creature = tile:getTopCreature()
                    if creature and creature:isCreature() then
                        table.insert(targets, creature)
                    end
                end
            end
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)
    getTargetsInArea(creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                for _, target in ipairs(targets) do
                    doCreatureDamage(target)
                end

                combat:execute(creature, var)
            end
        end
        countdown()
    end

    startCombat()

    return true
end
 
I shortened the code, as you said it was too long. So I formatted it to make it better and easier to read.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

local damage = 1000000
local radius = 5
local timeToKill = 5

function onCastSpell(cid, var)
    local creature = Creature(cid)
    local targets = {}
 
    local function doCreatureDamage(target)
        if target and target ~= creature then
            target:addHealth(-damage)
        end
    end

    local function getTargetsInArea(centerPosition)
        for x = centerPosition.x - radius, centerPosition.x + radius do
            for y = centerPosition.y - radius, centerPosition.y + radius do
                local tile = Tile(Position(x, y, centerPosition.z))
                if tile then
                    local creature = tile:getTopCreature()
                    if creature and creature:isCreature() then
                        table.insert(targets, creature)
                    end
                end
            end
        end
    end

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)
    getTargetsInArea(creature:getPosition())

    local function startCombat()
        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                for _, target in ipairs(targets) do
                    doCreatureDamage(target)
                end

                combat:execute(creature, var)
            end
        end
        countdown()
    end

    startCombat()

    return true
end
You haven't read what I previously said.

You are still declaring functions inside functions, which means they are being declared every time the spell is cast, rather than just once.

There are also several things wrong with the logic. You are getting targets on spell cast, and not at the time of the combat:execute(), which means if a creature was standing in the area with 5 seconds to go, and then it moves out of the way, they are still going to be hit.
 
You haven't read what I previously said.

You are still declaring functions inside functions, which means they are being declared every time the spell is cast, rather than just once.

There are also several things wrong with the logic. You are getting targets on spell cast, and not at the time of the combat:execute(), which means if a creature was standing in the area with 5 seconds to go, and then it moves out of the way, they are still going to be hit.
Like this?
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local area = createCombatArea({
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
})

combat:setArea(area)

local damage = 1000000
local radius = 5
local timeToKill = 5

-- Function to apply damage to a target
local function doCreatureDamage(target)
    if target and target:isCreature() then
        target:addHealth(-damage)
    end
end

-- Function to get targets in the combat area
local function getTargetsInArea(centerPosition)
    local targets = {}
    for x = centerPosition.x - radius, centerPosition.x + radius do
        for y = centerPosition.y - radius, centerPosition.y + radius do
            local tile = Tile(Position(x, y, centerPosition.z))
            if tile then
                local creature = tile:getTopCreature()
                if creature and creature:isCreature() then
                    table.insert(targets, creature)
                end
            end
        end
    end
    return targets
end

function onCastSpell(cid, var)
    local creature = Creature(cid)

    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)
    
    local function startCombat()
        local targets = getTargetsInArea(creature:getPosition())

        local function countdown()
            if timeToKill > 0 then
                creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
                timeToKill = timeToKill - 1
                addEvent(countdown, 1000)
            else
                creature:say("Warning!", TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())

                for _, target in ipairs(targets) do
                    doCreatureDamage(target)
                end

                combat:execute(creature, var)
            end
        end
        countdown()
    end
    startCombat()
    return true
end
 
You haven't read what I previously said.

You are still declaring functions inside functions, which means they are being declared every time the spell is cast, rather than just once.

There are also several things wrong with the logic. You are getting targets on spell cast, and not at the time of the combat:execute(), which means if a creature was standing in the area with 5 seconds to go, and then it moves out of the way, they are still going to be hit.
So please fix this script. I'm looking forward to seeing how it turns out. I am waiting.
 
So please fix this script. I'm looking forward to seeing how it turns out. I am waiting.

Hes talking about something like this as example


Lua:
local area = {
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
}

local combatArea = createCombatArea(area)

local combat = Combat()

combat:setArea(combatArea)
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local timeToKill = 5

local function countdown(cid, var, timeToKill)
    local creature = Creature(cid)
    if not creature then
        return true
    end

    if timeToKill > 0 then
        creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
        timeToKill = timeToKill - 1
        addEvent(countdown, 1000, creature, var, timeToKill)
    else
        combat:execute(creature, var)
    end
end

function onCastSpell(creature, var)
    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)
    countdown(creature:getId(), var, timeToKill)
    return false
end
 
Last edited:
Hes talking about something like this as example


Lua:
local area = {
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
}

local combatArea = createCombatArea(area)

local combat = Combat()

combat:setArea(combatArea)
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)

local timeToKill = 5

local function countdown(cid, var, timeToKill)
    local creature = Creature(cid)
    if not creature then
        return true
    end

    if timeToKill > 0 then
        creature:say(timeToKill, TALKTYPE_MONSTER_SAY, false, nil, creature:getPosition())
        timeToKill = timeToKill - 1
        addEvent(countdown, 1000, creature, var, timeToKill)
    else
        combat:execute(creature, var)
    end
end

function onCastSpell(creature, var)
    creature:say("You have " .. timeToKill .. " seconds to kill me, mohaha!", TALKTYPE_MONSTER_SAY)
    countdown(creature:getId(), var, timeToKill)
    return false
end
hmmm... cool then.
 
Back
Top