• 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 Directional Spell & addEvent issue

Xikini

I whore myself out for likes
Senator
Premium User
Joined
Nov 17, 2010
Messages
6,798
Solutions
581
Reaction score
5,361
TFS 1.4.2

I want the direction of the spell to remain static. So if I'm facing south and cast, it will cast south 3 times, in the original casted spot.

So this works as expected, until I start moving my character around. xD

It seems like the direction of the character is checked everytime combat is called.. and there's no way to give the spell any information to get around that.

Is there something simple I'm missing?

bandicam2024-01-2808-06-14-375-ezgif.com-video-to-gif-converter.gif

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))


local function castDelayedSpell(creatureId, variant, combat)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, variant)
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    addEvent(castDelayedSpell, 0, creatureId, variant, combat1)
    addEvent(castDelayedSpell, 500, creatureId, variant, combat2)
    addEvent(castDelayedSpell, 1000, creatureId, variant, combat3)
    return 
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(false)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(true)
spell:register()
 
Solution
Nice.
This should work. Give me a few minutes to give it a try.
Lua:
local combat = Combat()
combat:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local effects = {CONST_ME_MAGIC_BLUE, CONST_ME_MAGIC_RED, CONST_ME_MAGIC_GREEN}
local disEffects = {CONST_ANI_ENERGY, CONST_ANI_FIRE, CONST_ANI_POISON}

local function callback(cid, creaturePos, toPos, positions, index)
    local caster = Creature(cid)
    if not caster then return end
    creaturePos:sendDistanceEffect(toPos, disEffects[index])
    for _, pos in ipairs(positions) do
        pos:sendMagicEffect(effects[index])
        local tile = Tile(pos)
        if tile then
            local creatures = tile:getCreatures()
            if creatures then...
TFS 1.4.2

I want the direction of the spell to remain static. So if I'm facing south and cast, it will cast south 3 times, in the original casted spot.

So this works as expected, until I start moving my character around. xD

It seems like the direction of the character is checked everytime combat is called.. and there's no way to give the spell any information to get around that.

Is there something simple I'm missing?

View attachment 81725

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))


local function castDelayedSpell(creatureId, variant, combat)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, variant)
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    addEvent(castDelayedSpell, 0, creatureId, variant, combat1)
    addEvent(castDelayedSpell, 500, creatureId, variant, combat2)
    addEvent(castDelayedSpell, 1000, creatureId, variant, combat3)
    return
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(false)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(true)
spell:register()


only this spell i know stays on same, static


Lua:
function spellCallback(cid, position, count)
    if Creature(cid) then
        if count > 0 or math.random(0, 1) == 1 then
            position:sendMagicEffect(243)
            doAreaCombatHealth(cid, COMBAT_ENERGYDAMAGE, position, 0, -50, -300, 243)
        end

        if count < 5 then
            count = count + 1
            addEvent(spellCallback, math.random(1000, 4000), cid, position, count)
        end
    end
end

function onTargetTile(creature, position)
    spellCallback(creature:getId(), position, 0)
end

local combat = Combat()
combat:setArea(createCombatArea(AREA_CIRCLE5X5))
combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile")

function onCastSpell(creature, variant, isHotkey)
    return combat:execute(creature, variant)
end

maybe it will be helpfull
 
only this spell i know stays on same, static


Lua:
function spellCallback(cid, position, count)
    if Creature(cid) then
        if count > 0 or math.random(0, 1) == 1 then
            position:sendMagicEffect(243)
            doAreaCombatHealth(cid, COMBAT_ENERGYDAMAGE, position, 0, -50, -300, 243)
        end

        if count < 5 then
            count = count + 1
            addEvent(spellCallback, math.random(1000, 4000), cid, position, count)
        end
    end
end

function onTargetTile(creature, position)
    spellCallback(creature:getId(), position, 0)
end

local combat = Combat()
combat:setArea(createCombatArea(AREA_CIRCLE5X5))
combat:setCallback(CALLBACK_PARAM_TARGETTILE, "onTargetTile")

function onCastSpell(creature, variant, isHotkey)
    return combat:execute(creature, variant)
end

maybe it will be helpfull

Yeah, not a directional spell unfortunately. lol
that spell is basically 'castOnSelf'
 
Lua:
local function castDelayedSpell(creatureId, combat)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, Variant(creature:getPosition()))
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    addEvent(castDelayedSpell, 0, creatureId, combat1)
    addEvent(castDelayedSpell, 500, creatureId, combat2)
    addEvent(castDelayedSpell, 1000, creatureId, combat3)
    return 
end
 
Lua:
local function castDelayedSpell(creatureId, combat)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, Variant(creature:getPosition()))
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    addEvent(castDelayedSpell, 0, creatureId, combat1)
    addEvent(castDelayedSpell, 500, creatureId, combat2)
    addEvent(castDelayedSpell, 1000, creatureId, combat3)
    return
end
This is close, but not quite.
The directional spell always casts south, and it follows the player instead of being stationary.
and of course, changing it to cast in front of the player, but that's trivial.

So the first gif is what it's currently doing, and the second gif is what I want it to do.

bandicam2024-01-2814-42-07-656-ezgif.com-video-to-gif-converter.giftriple effect spell.gif

(and yes, I can simulate the combat system via Lua functions to achieve what I want.. but if it's possible with the default combat system, I'd prefer to do that)
 
Just for the record -- the variant position must be based on creature's direction (x1 offset) to create the area/direction properly.

North = position.y - 1
South = position.y + 1
West = position.x - 1
East = position.x + 1
 
The variant position must be based on creature's direction (x1 offset) to create the area/direction accordingly.

North = position.y - 1
South = position.y + 1
West = position.x - 1
East = position.x + 1
Alright, that fixes the direction issue.
Now how do we make it stop following the player and remain stationary from where it was cast?

bandicam2024-01-2815-35-08-525-ezgif.com-video-to-gif-converter.gif

Lua:
local function castDelayedSpell(creatureId, combat, lookDir)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    local position = creature:getPosition()
    local offset = Position.directionOffset[lookDir]
    local positionInFrontOfCaster = Position(position.x + offset.x, position.y + offset.y, position.z)
    combat:execute(creature, Variant(positionInFrontOfCaster))
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local originalDirection = creature:getDirection()
    addEvent(castDelayedSpell, 0, creatureId, combat1, originalDirection)
    addEvent(castDelayedSpell, 500, creatureId, combat2, originalDirection)
    addEvent(castDelayedSpell, 1000, creatureId, combat3, originalDirection)
    return
end
 
TFS 1.4.2

I want the direction of the spell to remain static. So if I'm facing south and cast, it will cast south 3 times, in the original casted spot.

So this works as expected, until I start moving my character around. xD

It seems like the direction of the character is checked everytime combat is called.. and there's no way to give the spell any information to get around that.

Is there something simple I'm missing?

View attachment 81725

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))


local function castDelayedSpell(creatureId, variant, combat)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, variant)
end

local spell = Spell("instant")

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    addEvent(castDelayedSpell, 0, creatureId, variant, combat1)
    addEvent(castDelayedSpell, 500, creatureId, variant, combat2)
    addEvent(castDelayedSpell, 1000, creatureId, variant, combat3)
    return
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(false)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(true)
spell:register()

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))



function castDelayedSpell(creatureId, combat, initialPosition)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, Variant(initialPosition))
end

function onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local initialPosition = creature:getPosition()

    addEvent(castDelayedSpell, 0, creatureId, combat1, initialPosition)
    addEvent(castDelayedSpell, 500, creatureId, combat2, initialPosition)
    addEvent(castDelayedSpell, 1000, creatureId, combat3, initialPosition)
end
 
Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))



function castDelayedSpell(creatureId, combat, initialPosition)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    combat:execute(creature, Variant(initialPosition))
end

function onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local initialPosition = creature:getPosition()

    addEvent(castDelayedSpell, 0, creatureId, combat1, initialPosition)
    addEvent(castDelayedSpell, 500, creatureId, combat2, initialPosition)
    addEvent(castDelayedSpell, 1000, creatureId, combat3, initialPosition)
end
Yep, I thought this as well, but it just simulates the same behaviour as the original spell.
(of course we can fix the direction issue, but the point stands)

bandicam2024-01-2815-50-10-412-ezgif.com-video-to-gif-converter.gif
 
Not sure if I understand fully what you need then.
If you initially cast the spell in South direction and start moving, it should be casting South as well but from your current (after moving) position? So the spell direction stays, its position follows you?
If so then
Lua:
function castDelayedSpell(creatureId, combat, direction)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    local position = creature:getPosition()
    position:getNextPosition(direction)
    combat:execute(creature, Variant(position))
end

function onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local direction = creature:getDirection()

    addEvent(castDelayedSpell, 0, creatureId, combat1, direction)
    addEvent(castDelayedSpell, 500, creatureId, combat2, direction)
    addEvent(castDelayedSpell, 1000, creatureId, combat3, direction)
end
 
Not sure if I understand fully what you need then.
If you initially cast the spell in South direction and start moving, it should be casting South as well but from your current (after moving) position? So the spell direction stays, its position follows you?
If so then
Lua:
function castDelayedSpell(creatureId, combat, direction)
    local creature = Creature(creatureId)
    if not creature then
        return
    end
    local position = creature:getPosition()
    position:getNextPosition(direction)
    combat:execute(creature, Variant(position))
end

function onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local direction = creature:getDirection()

    addEvent(castDelayedSpell, 0, creatureId, combat1, direction)
    addEvent(castDelayedSpell, 500, creatureId, combat2, direction)
    addEvent(castDelayedSpell, 1000, creatureId, combat3, direction)
end

With the latest code you provided.

bandicam2024-01-2816-38-49-482-ezgif.com-video-to-gif-converter.gif
 
You can do it like this, but you'll have to make do with an onCombatTile event, to provide the custom damage.

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local function castDelayedSpell(p, c)
    c:execute(nil, Variant(p))
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    local position = creature:getPosition()
    addEvent(castDelayedSpell, 0, position, combat1)
    addEvent(castDelayedSpell, 500, position, combat2)
    addEvent(castDelayedSpell, 1000, position, combat3)
    return true
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(true)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(false)
spell:register()
Post automatically merged:

You may also need to provide some predefined areas to calculate the address manually.
 
You can do it like this, but you'll have to make do with an onCombatTile event, to provide the custom damage.

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local function castDelayedSpell(p, c)
    c:execute(nil, Variant(p))
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    local position = creature:getPosition()
    addEvent(castDelayedSpell, 0, position, combat1)
    addEvent(castDelayedSpell, 500, position, combat2)
    addEvent(castDelayedSpell, 1000, position, combat3)
    return true
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(true)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(false)
spell:register()
Post automatically merged:

You may also need to provide some predefined areas to calculate the address manually.
This works, but doesn't shoot in any direction other then south.

bandicam2024-01-2817-37-31-467-ezgif.com-video-to-gif-converter(1).gif
 
Here I will leave you an example with two addresses, if you can finish the other addresses do so, if not let me know:

Lua:
-- LuaFormatter off
local AR_S = createCombatArea{
    {1, 1, 1},
    {1, 1, 1},
    {1, 1, 1},
    {0, 1, 0},
    {0, 3, 0}
}

local AR_N = createCombatArea{
    {0, 3, 0},
    {0, 1, 0},
    {1, 1, 1},
    {1, 1, 1},
    {1, 1, 1}
}
-- LuaFormatter on

local c_n = Combat()
c_n:setArea(AR_N)

local c_s = Combat()
c_s:setArea(AR_S)

local effects = {CONST_ME_MAGIC_BLUE, CONST_ME_MAGIC_RED, CONST_ME_MAGIC_GREEN}
local disEffects = {CONST_ANI_ENERGY, CONST_ANI_FIRE, CONST_ANI_POISON}

--[[
local tempCid = nil

local function callback(unUse, position)
    local creature = Creature(tempCid)
    if not creature then return end
    print("callback", unUse, position.x, position.y, position.z)
end

c_n:setCallback(CallBackParam.TARGETTILE, callback)
c_s:setCallback(CallBackParam.TARGETTILE, callback)
]]--

local function castDelayedSpell(cid, p, c)
    --tempCid = cid
    c:execute(nil, Variant(p))
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local position = creature:getPosition()
    local direction = creature:getDirection()
    local c = c_s
    if direction == DIRECTION_NORTH then
        c = c_n
    end

    for i = 1, 3 do
        c:setParameter(COMBAT_PARAM_EFFECT, effects[i])
        c:setParameter(COMBAT_PARAM_DISTANCEEFFECT, disEffects[i])
        addEvent(castDelayedSpell, (500 * (i - 1)), creatureId, position, c)
    end
    return true
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(false)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(true)
spell:register()
 
Last edited:
You can do it like this, but you'll have to make do with an onCombatTile event, to provide the custom damage.

Lua:
local combat1 = Combat()
combat1:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat1:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
combat1:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat2 = Combat()
combat2:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED)
combat2:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
combat2:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local combat3 = Combat()
combat3:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_GREEN)
combat3:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISON)
combat3:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local function castDelayedSpell(p, c)
    c:execute(nil, Variant(p))
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    local position = creature:getPosition()
    addEvent(castDelayedSpell, 0, position, combat1)
    addEvent(castDelayedSpell, 500, position, combat2)
    addEvent(castDelayedSpell, 1000, position, combat3)
    return true
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(true)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(false)
spell:register()
Post automatically merged:

You may also need to provide some predefined areas to calculate the address manually.
Create combat that will do the effects. Then hook up onTargetCombat callback to it. Inside that callback you can execute combat that will actually do damage (caster can be passed there now).
 
Now how do we make it stop following the player and remain stationary from where it was cast?
You can generate the positions first and then do a 3x loop (with addEvents) and using doTargetCombat (you'd also need to parse the tile for the creatures to apply the damage)

Lua:
local combat = Combat()
combat:setArea(createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))

local spell = Spell("instant")
function spell.onCastSpell(creature, variant)

    local positions = combat:getPositions(creature, variant) -- # array
    -- # your code
 
    return
end
 
Here I will leave you an example with two addresses, if you can finish the other addresses do so, if not let me know:

Lua:
-- LuaFormatter off
local AR_S = createCombatArea{
    {1, 1, 1},
    {1, 1, 1},
    {1, 1, 1},
    {0, 1, 0},
    {0, 3, 0}
}

local AR_N = createCombatArea{
    {0, 3, 0},
    {0, 1, 0},
    {1, 1, 1},
    {1, 1, 1},
    {1, 1, 1}
}
-- LuaFormatter on

local c_n = Combat()
c_n:setArea(AR_N)

local c_s = Combat()
c_s:setArea(AR_S)

local effects = {CONST_ME_MAGIC_BLUE, CONST_ME_MAGIC_RED, CONST_ME_MAGIC_GREEN}
local disEffects = {CONST_ANI_ENERGY, CONST_ANI_FIRE, CONST_ANI_POISON}

--[[
local tempCid = nil

local function callback(unUse, position)
    local creature = Creature(tempCid)
    if not creature then return end
    print("callback", unUse, position.x, position.y, position.z)
end

c_n:setCallback(CallBackParam.TARGETTILE, callback)
c_s:setCallback(CallBackParam.TARGETTILE, callback)
]]--

local function castDelayedSpell(cid, p, c)
    --tempCid = cid
    c:execute(nil, Variant(p))
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    local creatureId = creature:getId()
    local position = creature:getPosition()
    local direction = creature:getDirection()
    local c = c_s
    if direction == DIRECTION_NORTH then
        c = c_n
    end

    for i = 0, 2 do
        c:setParameter(COMBAT_PARAM_EFFECT, effects[i])
        c:setParameter(COMBAT_PARAM_DISTANCEEFFECT, disEffects[i])
        addEvent(castDelayedSpell, (500 * i), creatureId, position, c)
    end
    return true
end

spell:name("triple effect spell")
spell:words("triple effect spell")
spell:group("attack")
spell:id(179)
spell:cooldown(1000)
spell:groupCooldown(1000)
spell:level(1)
spell:mana(10)
spell:isSelfTarget(false)
spell:isPremium(true)
spell:needLearn(false)
spell:needDirection(true)
spell:register()

This technically works but side-steps the initial problem, by turning every spell into a 'cast on self' spell, instead of a directional spell.
 
This technically works but side-steps the initial problem, by turning every spell into a 'cast on self' spell, instead of a directional spell.
Yes, well it is a fairly simple example, but it is better to use predefined areas than to build the areas with functions in real time
You can use the direction of attack with the objective and calculate the areas.

I don't do it, because I'm going out, and I won't be back home for a while.

Basically it's all about not executing the combat with a caster, since if you do, the sources will auto-calculate the area, and will use the current position of the caster no matter what.

1706483590096.png
 
Back
Top