• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFS 1.X+ Spell not working HELP

Newani

New Member
Joined
Sep 11, 2024
Messages
20
Reaction score
2
LUA:
local repeatAmount = 2
 
 
local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
 
}
 
local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})
 
local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    deathFlames[k] = createCombatObject()
    setCombatParam(deathFlames[k], COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    setCombatParam(deathFlames[k], COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
 
    setCombatArea(deathFlames[k], area)
end
 
local bigFlames = createCombatObject()
setCombatParam(bigFlames, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(bigFlames, COMBAT_PARAM_EFFECT, 176)
 
setCombatArea(bigFlames, bigFlamesArea)
 
function onTargetTile(cid, pos)
    doSendDistanceShoot(getCreaturePosition(cid), pos, CONST_ANI_ETHEREALSPEAR)
end
setCombatCallback(bigFlames, CALLBACK_PARAM_TARGETTILE, "onTargetTile")

function onGetFormulaValues(player, level, maglevel, factor)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

setCombatCallback(#deathFlames, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
 
local function castSpellDelay(p)
    if(isCreature(p[1]) == TRUE) then
        doCombat(unpack(p))
    end
end
 
function onCastSpell(cid, var)
if getPlayerStorageValue(cid,23058) >= os.time() then
    doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end
    setPlayerStorageValue(cid, 23058, os.time() + 120) -- last number "120"  is the cooldown in seconds
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + #deathFlames * 150 * i + 700 * i, {cid, combat, var})
        end
        addEvent(castSpellDelay, (150 * #deathFlames) + #deathFlames * 150 * i + 700 * i, {cid, bigFlames, var})
    end

    return LUA_NO_ERROR
end
 
Could you possibly be more specific on whats not working so we know what to actually look for ^^?

i can see a potential risk of not working when it comes to this line specifically:
setCombatCallback(#deathFlames, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")


and why are you using: return LUA_NO_ERROR
instead of: return true
 
The problem is: not deal damage in the monsters. Yes the problem is in the line exactly "setcombatcallback" "ongetformula values"
 
Alright,

your bigFlamesArea doesnt have a damageformula either so what ive done is:

1. Added a new damageformula (copied the one you already set but gave it a new function name)
2. properly set the order of how the functions should be handled
3. changed: setCombatCallback(#deathFlames, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") since this would simply take the tables lenght and not the actual combat object

try this code and tell me if it works, i havent done this but i strongly recommend using return true at the end instead of return LUA_NO_ERROR


LUA:
local repeatAmount = 2

local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
}

local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})

function onGetFormulaValues(player, level, maglevel, factor)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

function onGetFormulaValuesBigFlames(player, level, maglevel, factor)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

function onTargetTile(cid, pos)
    doSendDistanceShoot(getCreaturePosition(cid), pos, CONST_ANI_ETHEREALSPEAR)
end

local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    deathFlames[k] = createCombatObject()
    setCombatParam(deathFlames[k], COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    setCombatParam(deathFlames[k], COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
    setCombatArea(deathFlames[k], area)
    setCombatCallback(deathFlames[k], CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
end

local bigFlames = createCombatObject()
setCombatParam(bigFlames, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(bigFlames, COMBAT_PARAM_EFFECT, 176)
setCombatArea(bigFlames, bigFlamesArea)
setCombatCallback(bigFlames, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValuesBigFlames")
setCombatCallback(bigFlames, CALLBACK_PARAM_TARGETTILE, "onTargetTile")

local function castSpellDelay(p)
    if(isCreature(p[1]) == TRUE) then
        doCombat(unpack(p))
    end
end

function onCastSpell(cid, var)
    if getPlayerStorageValue(cid, 23058) >= os.time() then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end
    setPlayerStorageValue(cid, 23058, os.time() + 120) -- last number "120" is the cooldown in seconds
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + #deathFlames * 150 * i + 700 * i, {cid, combat, var})
        end
        addEvent(castSpellDelay, (150 * #deathFlames) + #deathFlames * 150 * i + 700 * i, {cid, bigFlames, var})
    end

    return LUA_NO_ERROR
end
 
1763549478490.webp
Post automatically merged:

It's causing damage now, but it's throwing this error in the console that it didn't throw before. By the way, I'm using TFS 1.2.
 
hmm i dont think CALLBACK_PARAM_TARGETTILE exist in TFS 1.2 im not sure tho since i usually work on TFS 1.4.2 that could be the reason for the errors.

Question: are you seeing the distance effects at all?

try this code:
LUA:
local repeatAmount = 2

local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
}

local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})

function onGetFormulaValues(player, level, maglevel, factor)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

function onGetFormulaValuesBigFlames(player, level, maglevel, factor)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    deathFlames[k] = createCombatObject()
    setCombatParam(deathFlames[k], COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    setCombatParam(deathFlames[k], COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
    setCombatArea(deathFlames[k], area)
    setCombatCallback(deathFlames[k], CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
end

local bigFlames = createCombatObject()
setCombatParam(bigFlames, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(bigFlames, COMBAT_PARAM_EFFECT, 176)
setCombatArea(bigFlames, bigFlamesArea)
setCombatCallback(bigFlames, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValuesBigFlames")

local function castSpellDelay(p)
    if(isCreature(p[1]) == TRUE) then
        doCombat(unpack(p))
    end
end

function onCastSpell(cid, var)
    if getPlayerStorageValue(cid, 23058) >= os.time() then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end
    setPlayerStorageValue(cid, 23058, os.time() + 120) -- last number "120" is the cooldown in seconds
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + #deathFlames * 150 * i + 700 * i, {cid, combat, var})
        end
        addEvent(castSpellDelay, (150 * #deathFlames) + #deathFlames * 150 * i + 700 * i, {cid, bigFlames, var})
    end

    return true
end
 
Last edited:
1763551886975.webp
Post automatically merged:

Now not deal damage. And continue showing this in console. In this version of TFS 1.2 yes exist the "target tile".
I know this because I have several scripts, and I have another spell that uses "ontargettile" and works perfectly. This spell only has this problem, but if I use the old formula, it doesn't have any errors. However, the old method doesn't work for me because it doesn't increase damage per level and magic level correctly, which is why I need this formula.
 
1763552237401.webp
Post automatically merged:

Continue showing errors in the console. And now not have shoot distance effect of ethereal spear. :/
 
we could go into DMs on Discord so we dont spam the forum, you could also send a me working spell and ill be able to try to see if i can fix it!
 
LUA:
local repeatAmount = 2
 
 
local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
 
}
 
local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})
 
local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    deathFlames[k] = createCombatObject()
    setCombatParam(deathFlames[k], COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    setCombatParam(deathFlames[k], COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
    setCombatFormula(deathFlames[k], COMBAT_FORMULA_LEVELMAGIC, -2.493, -50, -2.829, -100)
 
    setCombatArea(deathFlames[k], area)
end
 
local bigFlames = createCombatObject()
setCombatParam(bigFlames, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(bigFlames, COMBAT_PARAM_EFFECT, 176)
setCombatFormula(bigFlames, COMBAT_FORMULA_LEVELMAGIC, -2.766, -50, -3.141, -100)
 
setCombatArea(bigFlames, bigFlamesArea)
 
function onTargetTile(cid, pos)
    doSendDistanceShoot(getCreaturePosition(cid), pos, CONST_ANI_ETHEREALSPEAR)
end
setCombatCallback(bigFlames, CALLBACK_PARAM_TARGETTILE, "onTargetTile")
 
local function castSpellDelay(p)
    if(isCreature(p[1]) == TRUE) then
        doCombat(unpack(p))
    end
end
 
function onCastSpell(cid, var)
if getPlayerStorageValue(cid,23058) >= os.time() then
    doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end
    setPlayerStorageValue(cid, 23058, os.time() + 120) -- last number "120"  is the cooldown in seconds
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + #deathFlames * 150 * i + 700 * i, {cid, combat, var})
        end
        addEvent(castSpellDelay, (150 * #deathFlames) + #deathFlames * 150 * i + 700 * i, {cid, bigFlames, var})
    end

    return LUA_NO_ERROR
end
Post automatically merged:

This is the script original based in the OLD FORMULA. I need with the new formula of magic level and level value.
This not have any error in the console and nothing of errors but i need with the new other formula.
 
aff im not getting this to work sadly, i dont have a tfs 1.2 version to try it out. Im sorry if i wasnt able to help you :/
 
Try this.

LUA:
local repeatAmount = 2

-- AREAS
local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
}

local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})

-- DAMAGE FORMULA
local function calculateDamage(cid)
    local level = getPlayerLevel(cid)
    local ml = getPlayerMagLevel(cid)

    local min = (level * 5) + (ml * 19)
    local max = (level * 5) + (ml * 20.2)

    return -min, -max
end

-- PROJECTILES
local function sendProjectiles(cid)
    if not isCreature(cid) then return end
    local pos = getCreaturePosition(cid)

    for x = -7, 7 do
        for y = -7, 7 do
            local to = {x = pos.x + x, y = pos.y + y, z = pos.z}
            doSendDistanceShoot(pos, to, CONST_ANI_ETHEREALSPEAR)
        end
    end
end

-- APPLY DAMAGE IN AREA
local function dealDamageArea(cid, area, effect, dtype)
    if not isCreature(cid) then return end
    local positions = {}

    local center = {x = 0, y = 0, z = 0}
    local pos = getCreaturePosition(cid)

    for aX = -10, 10 do
        for aY = -10, 10 do
            if area[(aY + 11)] and area[(aY + 11)][(aX + 11)] then
                if area[(aY + 11)][(aX + 11)] > 0 then
                    table.insert(positions, {x = pos.x + aX, y = pos.y + aY, z = pos.z})
                end
            end
        end
    end

    local min, max = calculateDamage(cid)

    for _, p in pairs(positions) do
        doAreaCombatHealth(cid, dtype, p, 0, min, max, effect)
    end
end

-- DELAY HANDLER
local function castDelayed(cid, area, effect, dtype)
    if not isCreature(cid) then return end
    sendProjectiles(cid)
    dealDamageArea(cid, area, effect, dtype)
end

-- MAIN SPELL
function onCastSpell(cid, var)
    if getPlayerStorageValue(cid, 23058) >= os.time() then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end

    setPlayerStorageValue(cid, 23058, os.time() + 120) -- cooldown

    for i = 0, repeatAmount - 1 do
        for k, area in ipairs(deathFlamesArea) do
            addEvent(castDelayed, (150 * k) + 700 * i, cid, area, CONST_ME_HOLYAREA, COMBAT_HOLYDAMAGE)
        end
        addEvent(castDelayed, (450) + 700 * i, cid, bigFlamesArea, 176, COMBAT_ENERGYDAMAGE)
    end

    return true
end
 
Since you're putting 0 effort into trying to resolve this yourself, here's a lazy copy-paste response from Grok. I'm not even going to bother trying it as you don't seem to bother doing anything yourself.

LUA:
local repeatAmount = 2

-- Original area matrices (before createCombatArea)
local deathFlamesMatrices = {
    {
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    },
    {
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    },
    {
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    }
}

local bigFlamesMatrix = {
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
}

-- Create actual combat areas
local deathFlamesArea = {}
for _, matrix in ipairs(deathFlamesMatrices) do
    table.insert(deathFlamesArea, createCombatArea(matrix))
end
local bigFlamesArea = createCombatArea(bigFlamesMatrix)

-- DAMAGE FORMULA
local function calculateDamage(cid)
    local level = getPlayerLevel(cid)
    local maglevel = getPlayerMagLevel(cid)
    local min = (level * 5) + (maglevel * 19)
    local max = (level * 5) + (maglevel * 20.2)
    return -min, -max
end

-- PROJECTILES
local function sendProjectiles(cid)
    if not isCreature(cid) then return end
    local pos = getCreaturePosition(cid)
    for x = -7, 7 do
        for y = -7, 7 do
            local toPos = {x = pos.x + x, y = pos.y + y, z = pos.z}
            if not (x == 0 and y == 0) then  -- optional: skip center
                doSendDistanceShoot(pos, toPos, CONST_ANI_ETHEREALSPEAR)
            end
        end
    end
end

-- APPLY DAMAGE
local function dealDamageArea(cid, area, effect, dtype)
    if not isCreature(cid) then return end
    local min, max = calculateDamage(cid)
    doAreaCombatHealth(cid, dtype, getCreaturePosition(cid), area, min, max, effect)
end

-- DELAYED CAST
local function castDelayed(cid, area, effect, dtype)
    if not isCreature(cid) then return end
    sendProjectiles(cid)
    dealDamageArea(cid, area, effect, dtype)
end

-- MAIN SPELL
function onCastSpell(cid, var)
    if getPlayerStorageValue(cid, 23058) >= os.time() then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You are exhausted for 120 seconds.")
        return false
    end

    setPlayerStorageValue(cid, 23058, os.time() + 120)

    for i = 0, repeatAmount - 1 do
        for k, area in ipairs(deathFlamesArea) do
            addEvent(castDelayed, (150 * k) + (700 * i), cid, area, CONST_ME_HOLYAREA, COMBAT_HOLYDAMAGE)
        end
        addEvent(castDelayed, 450 + (700 * i), cid, bigFlamesArea, 176, COMBAT_ENERGYDAMAGE)
    end

    return true
end
 
The error comes from the line using setCombatCallback with onGetFormulaValues.
This spell was written for TFS 0.x, and since you are using TFS 1.x, you must convert it to the updated API.
For example:

createCombatObject() → Combat()
setCombatParam() → combat:setParameter()
setCombatCallback() → combat:setCallback()
doSendDistanceShoot() → creature:getPosition():sendDistanceEffect()
onGetFormulaValues() → levelMagicCallback()

All of this is explained in the file:
data/lib/compat/compat.lua
Just study it and adapt the script before testing it’s really simple once you understand the differences.


LUA:
local repeatAmount = 2

local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
}

local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})

local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    local combat = Combat()
    combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
    combat:setArea(area)
    deathFlames[k] = combat
end

local bigFlames = Combat()
bigFlames:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
bigFlames:setParameter(COMBAT_PARAM_EFFECT, 176)
bigFlames:setArea(bigFlamesArea)

local function targetTileCallback(creature, position)
    creature:getPosition():sendDistanceEffect(position, CONST_ANI_ETHEREALSPEAR)
end
bigFlames:setCallback(CallBackParam.TARGETTILE, targetTileCallback)

local function levelMagicCallback(player, level, magicLevel)
    local min = (level * 5) + (magicLevel * 19)
    local max = (level * 5) + (magicLevel * 20.2)
    return -min, -max
end

for _, combat in ipairs(deathFlames) do
    combat:setCallback(CallBackParam.LEVELMAGICVALUE, levelMagicCallback)
end

local function castSpellDelay(actorKey, useGuid, combat, variant)
    local creature
    if useGuid then
        creature = Player(actorKey)
    else
        creature = Creature(actorKey)
    end
    if creature then
        combat:execute(creature, variant)
    end
end

function onCastSpell(creature, variant)
    local player = Player(creature)
    if player then
        local now = os.time()
        local exhausted = player:getStorageValue(23058)
        if type(exhausted) ~= "number" then
            exhausted = -1
        end
        if exhausted >= now then
            local remaining = exhausted - now
            if remaining < 0 then remaining = 0 end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "You are exhausted for " .. remaining .. " seconds.")
            return false
        end
        player:setStorageValue(23058, now + 120)
    end

    local useGuid = player ~= nil
    local actorKey = useGuid and player:getGuid() or creature:getId()
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + (700 * i), actorKey, useGuid, combat, variant)
        end
        addEvent(castSpellDelay, 450 + (700 * i), actorKey, useGuid, cid and bigFlames or bigFlames, variant)
    end
    return true
end
 
This error happens because OTX 3/TFS 1.2 does not have the global variable CallBackParam, so in line 56 the script tries to index something that doesn’t exist (nil).
I tested the same script on TFS 1.4.2 and it works fine without errors, because that version supports the callback.


try
LUA:
local repeatAmount = 2

local deathFlamesArea = {
    createCombatArea({
        {0, 1, 0},
        {1, 2, 1},
        {0, 1, 0}
    }),
    createCombatArea({
        {0, 1, 1, 1, 0},
        {1, 1, 0, 1, 1},
        {1, 0, 2, 0, 1},
        {1, 1, 0, 1, 1},
        {0, 1, 1, 1, 0}
    }),
    createCombatArea({
        {0, 0, 1, 1, 1, 0, 0},
        {0, 1, 0, 0, 0, 1, 0},
        {1, 0, 0, 0, 0, 0, 1},
        {1, 0, 0, 2, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 1},
        {0, 1, 0, 0, 0, 1, 0},
        {0, 0, 1, 1, 1, 0, 0}
    })
}

local bigFlamesArea = createCombatArea({
    {0, 0, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 2, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 0, 0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0, 0, 1, 1, 0},
    {0, 0, 1, 1, 1, 1, 1, 0, 0}
})

local deathFlames = {}
for k, area in ipairs(deathFlamesArea) do
    local combat = Combat()
    combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
    combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
    combat:setArea(area)
    combat:setCallback(CallBackParam.LEVELMAGICVALUE, levelMagicCallback)
    deathFlames[k] = combat
end

local bigFlames = Combat()
bigFlames:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
bigFlames:setParameter(COMBAT_PARAM_EFFECT, 176)
bigFlames:setArea(bigFlamesArea)
bigFlames:setCallback(CallBackParam.LEVELMAGICVALUE, levelMagicCallback)
bigFlames:setCallback(CallBackParam.TARGETTILE, targetTileCallback)

local function targetTileCallback(creature, position)
    creature:getPosition():sendDistanceEffect(position, CONST_ANI_ETHEREALSPEAR)
end

local function levelMagicCallback(player, level, magicLevel)
    local min = (level * 5) + (magicLevel * 19)
    local max = (level * 5) + (magicLevel * 20.2)
    return -min, -max
end

local function castSpellDelay(actorKey, useGuid, combat, variant)
    local creature = useGuid and Player(actorKey) or Creature(actorKey)
    if creature then
        combat:execute(creature, variant)
    end
end

function onCastSpell(creature, variant)
    local player = Player(creature)
    if player then
        local now = os.time()
        local exhausted = player:getStorageValue(23058)
        if type(exhausted) ~= "number" then
            exhausted = -1
        end
        if exhausted >= now then
            local remaining = exhausted - now
            if remaining < 0 then remaining = 0 end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "You are exhausted for " .. remaining .. " seconds.")
            return false
        end
        player:setStorageValue(23058, now + 120)
    end

    local useGuid = player ~= nil
    local actorKey = useGuid and player:getGuid() or creature:getId()
    for i = 0, repeatAmount - 1 do
        for k, combat in ipairs(deathFlames) do
            addEvent(castSpellDelay, (150 * k) + (700 * i), actorKey, useGuid, combat, variant)
        end
        addEvent(castSpellDelay, 450 + (700 * i), actorKey, useGuid, bigFlames, variant)
    end
    return true
end
 
Back
Top