• 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!

Lua Spells and Animations

Aeronx

Intermediate OT User
Joined
Dec 17, 2015
Messages
746
Solutions
9
Reaction score
125
Hello everyone!

Im doing some testing and trying to learn a bit here, so maybe you can help me out, thank you in advance.

Here's the code:
Code:
 local function sendEffc(cid)
    local cid = Player(cid)
    r1 = cid:getPosition()
    a1 = Position(r1.x, r1.y - 3, r1.z)
    a2 = Position(r1.x + 1, r1.y - 3, r1.z)
    a3 = Position(r1.x + 2, r1.y - 2, r1.z)
    a4 = Position(r1.x + 3, r1.y - 1, r1.z)
    a5 = Position(r1.x + 3, r1.y, r1.z)
    a6 = Position(r1.x + 3, r1.y + 1, r1.z)
    a7 = Position(r1.x + 2, r1.y + 2, r1.z)
    a8 = Position(r1.x + 1, r1.y + 3, r1.z)
    a9 = Position(r1.x, r1.y + 3, r1.z)
    a10 = Position(r1.x - 1, r1.y + 3, r1.z)
    a11 = Position(r1.x - 2, r1.y + 2, r1.z)
    a12 = Position(r1.x - 3, r1.y + 1, r1.z)
    a13 = Position(r1.x - 3, r1.y, r1.z)
    a14 = Position(r1.x - 3, r1.y - 1, r1.z)
    a15 = Position(r1.x - 2, r1.y - 2, r1.z)
    a16 = Position(r1.x - 1, r1.y - 3, r1.z)

    a1:sendDistanceEffect(a2, CONST_ANI_FIRE)
    a2:sendDistanceEffect(a3, CONST_ANI_FIRE)
    a3:sendDistanceEffect(a4, CONST_ANI_FIRE)
    a4:sendDistanceEffect(a5, CONST_ANI_FIRE)
    a5:sendDistanceEffect(a6, CONST_ANI_FIRE)
    a6:sendDistanceEffect(a7, CONST_ANI_FIRE)
    a7:sendDistanceEffect(a8, CONST_ANI_FIRE)
    a8:sendDistanceEffect(a9, CONST_ANI_FIRE)
    a9:sendDistanceEffect(a10, CONST_ANI_FIRE)
    a10:sendDistanceEffect(a11, CONST_ANI_FIRE)
    a11:sendDistanceEffect(a12, CONST_ANI_FIRE)
    a12:sendDistanceEffect(a13, CONST_ANI_FIRE)
    a13:sendDistanceEffect(a14, CONST_ANI_FIRE)
    a14:sendDistanceEffect(a15, CONST_ANI_FIRE)
    a15:sendDistanceEffect(a16, CONST_ANI_FIRE)
    a16:sendDistanceEffect(a1, CONST_ANI_FIRE)

    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a1, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a2, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a3, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a4, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a5, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a6, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a7, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a8, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a9, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a10, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a11, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a12, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a13, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a14, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a15, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a16, {1}, 10, 20, CONST_ANI_FIRE)

end
local times = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
function onCastSpell(creature, variant)
    for i = 1, #times do
    addEvent(sendEffc, times[i] * 150, creature.uid)
    end
   return true
end

First of all this spell onCast creates a ring of fire and damages all creatures on it.

-How can i optimize the code? It looks waaay too repetitive.
-How can i add delay between sendDistanceEffects? and apply the same delay to damage?

Thank you for your time.
 
Solution
X
My bad! working perfectly! Thank you all!

Actually learned something today! Thanks for your time!


--Edit:

After doing some testing i got this:
(Because there was an obvious exploit, you could use it throgh walls!)

Trying to avoid this problem got this:
Code:
local positions = {
    {0, -3},
    {1, -3},
    {2, -2},
    {3, -1},
    {3,  0},
    {3,  1},
    {2,  2},
    {1,  3},
    {0,  3},
    {-1, 3},
    {-2, 2},
    {-3, 1},
    {-3, 0},
    {-3, -1},
    {-2, -2},
    {-1, -3}
}
local function sendEffc(cid, max_iterations, iterations)
    local x = (max_iterations - iterations) + 1
    if x > 16 then
        repeat
            x = x - 16
        until x <= 16
    end
    local y = x + 1
    if y > 16 then
        y = 1...
Hello everyone!

Im doing some testing and trying to learn a bit here, so maybe you can help me out, thank you in advance.

Here's the code:
Code:
 local function sendEffc(cid)
    local cid = Player(cid)
    r1 = cid:getPosition()
    a1 = Position(r1.x, r1.y - 3, r1.z)
    a2 = Position(r1.x + 1, r1.y - 3, r1.z)
    a3 = Position(r1.x + 2, r1.y - 2, r1.z)
    a4 = Position(r1.x + 3, r1.y - 1, r1.z)
    a5 = Position(r1.x + 3, r1.y, r1.z)
    a6 = Position(r1.x + 3, r1.y + 1, r1.z)
    a7 = Position(r1.x + 2, r1.y + 2, r1.z)
    a8 = Position(r1.x + 1, r1.y + 3, r1.z)
    a9 = Position(r1.x, r1.y + 3, r1.z)
    a10 = Position(r1.x - 1, r1.y + 3, r1.z)
    a11 = Position(r1.x - 2, r1.y + 2, r1.z)
    a12 = Position(r1.x - 3, r1.y + 1, r1.z)
    a13 = Position(r1.x - 3, r1.y, r1.z)
    a14 = Position(r1.x - 3, r1.y - 1, r1.z)
    a15 = Position(r1.x - 2, r1.y - 2, r1.z)
    a16 = Position(r1.x - 1, r1.y - 3, r1.z)

    a1:sendDistanceEffect(a2, CONST_ANI_FIRE)
    a2:sendDistanceEffect(a3, CONST_ANI_FIRE)
    a3:sendDistanceEffect(a4, CONST_ANI_FIRE)
    a4:sendDistanceEffect(a5, CONST_ANI_FIRE)
    a5:sendDistanceEffect(a6, CONST_ANI_FIRE)
    a6:sendDistanceEffect(a7, CONST_ANI_FIRE)
    a7:sendDistanceEffect(a8, CONST_ANI_FIRE)
    a8:sendDistanceEffect(a9, CONST_ANI_FIRE)
    a9:sendDistanceEffect(a10, CONST_ANI_FIRE)
    a10:sendDistanceEffect(a11, CONST_ANI_FIRE)
    a11:sendDistanceEffect(a12, CONST_ANI_FIRE)
    a12:sendDistanceEffect(a13, CONST_ANI_FIRE)
    a13:sendDistanceEffect(a14, CONST_ANI_FIRE)
    a14:sendDistanceEffect(a15, CONST_ANI_FIRE)
    a15:sendDistanceEffect(a16, CONST_ANI_FIRE)
    a16:sendDistanceEffect(a1, CONST_ANI_FIRE)

    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a1, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a2, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a3, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a4, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a5, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a6, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a7, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a8, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a9, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a10, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a11, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a12, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a13, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a14, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a15, {1}, 10, 20, CONST_ANI_FIRE)
    doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, a16, {1}, 10, 20, CONST_ANI_FIRE)

end
local times = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
function onCastSpell(creature, variant)
    for i = 1, #times do
    addEvent(sendEffc, times[i] * 150, creature.uid)
    end
   return true
end

First of all this spell onCast creates a ring of fire and damages all creatures on it.

-How can i optimize the code? It looks waaay too repetitive.
-How can i add delay between sendDistanceEffects? and apply the same delay to damage?

Thank you for your time.
Try this.
LUA:
local function sendEffc(cid, position, position2)
   local cid = Player(cid)
   position:sendDistanceEffect(position2, CONST_ANI_FIRE)
   doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, position, {1}, 10, 20, CONST_ANI_FIRE)
end

function onCastSpell(creature, variant)
   local cid = Player(creature.uid)
   pos = cid:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
   for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i], positions[1])
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i], positions[i + 1])
       end
   end
   return true
end
 
Last edited by a moderator:
Can you try this too?
Just curious if it will work.

LUA:
local function sendEffc(cid)
    if cid then
        local cid = Player(cid)
        r1 = cid:getPosition()
       
        local nextPos;
        local myPositions ={}
        for xInc = 1, 3 do
            for yInc = 1,3 do
                table.insert(myPositions, Position(r.x+xInc, r.y+yInc, r.z))
            end
        end

        for i = 1, #myPositions do
            if i == #myPositions then
                nextPos = myPositions[1]
            else
                nextPos = myPositions[i]+1
            end
            myPositions[i] = sendDistanceEffect(nextPos, CONST_ANI_FIRE)
            doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, myPositions[i], {1}, 10, 20, CONST_ANI_FIRE)
        end
    end
end

function onCastSpell(creature, variant)
    for i = 1, 34 do
        addEvent(sendEffc, i * 150, creature.uid)
    end
   return true
end
 
Try this.
LUA:
local function sendEffc(cid, position, position2)
   local cid = Player(cid)
   position:sendDistanceEffect(position2, CONST_ANI_FIRE)
   doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, position, {1}, 10, 20, CONST_ANI_FIRE)
end

function onCastSpell(creature, variant)
   local cid = Player(creature.uid)
   pos = cid:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
   for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i], positions[1])
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i], positions[i + 1])
       end
   end
   return true
end

@Xikini 's gives this error:
Code:
data/spells/scripts/fourth/Energytornado.lua:3: attempt to call method 'sendDistanceEffect' (a nil value)

Can you try this too?
Just curious if it will work.

LUA:
local function sendEffc(cid)
    if cid then
        local cid = Player(cid)
        r1 = cid:getPosition()
    
        local nextPos;
        local myPositions ={}
        for xInc = 1, 3 do
            for yInc = 1,3 do
                table.insert(myPositions, Position(r.x+xInc, r.y+yInc, r.z))
            end
        end

        for i = 1, #myPositions do
            if i == #myPositions then
                nextPos = myPositions[1]
            else
                nextPos = myPositions[i]+1
            end
            myPositions[i] = sendDistanceEffect(nextPos, CONST_ANI_FIRE)
            doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, myPositions[i], {1}, 10, 20, CONST_ANI_FIRE)
        end
    end
end

function onCastSpell(creature, variant)
    for i = 1, 34 do
        addEvent(sendEffc, i * 150, creature.uid)
    end
   return true
end
@Shadowsong 's error:
Code:
data/spells/scripts/fourth/Energytornado.lua:10: attempt to index global 'r' (a nil value)
after fixing shadowsong's problem r1 instead of r this error:
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
attempt to index a number value
stack traceback:
        [C]: at 0x7ff6eb224d30
        [C]: in function '__add'
        data/spells/scripts/fourth/Energytornado.lua:18: in function <data/spells/scripts/fourth/Energytornado.lua:1>
 
Last edited:
Okay try this
LUA:
local function sendEffc(cid)
    if cid then
        local player = Player(cid)
        local r = player:getPosition()
 
        local nextPos;
        local myPositions = {}
        for xInc = 1, 3 do
            for yInc = 1,3 do
                table.insert(myPositions, Position(r.x+xInc, r.y+yInc, r.z))
            end
        end
        for i = 1, #myPositions do
            if i == #myPositions then
                nextPos = myPositions[1]
            else
                nextPos = myPositions[i]+1
            end
            myPositions[i] = sendDistanceEffect(nextPos, CONST_ANI_FIRE)
            doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, myPositions[i], {1}, 10, 20, CONST_ANI_FIRE)
        end
    end
end
function onCastSpell(creature, variant)
    for i = 1, 34 do
        addEvent(sendEffc, i * 150, creature.uid)
    end
   return true
end

Also, was your code working properly when you posted it? (except from it being unoptimized)
 
Xikin's gives this error:
Code:
data/spells/scripts/fourth/Energytornado.lua:3: attempt to call method 'sendDistanceEffect' (a nil value)
Unless the table positions aren't being called.. idk what could be wrong. xP
try this I guess
LUA:
local function sendEffc(cid, position, position2)
   local cid = Player(cid)
   position:sendDistanceEffect(position2, CONST_ANI_FIRE)
   doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, position, {1}, 10, 20, CONST_ANI_FIRE)
end

function onCastSpell(creature, variant)
   local cid = Player(creature.uid)
   pos = cid:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
   for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[1][1])
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[i + 1][1])
       end
   end
   return true
end
 
@Shadowsong 's new error:
Same as before
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
attempt to index a number value
stack traceback:
        [C]: at 0x7ff6eb224d30
        [C]: in function '__add'
        data/spells/scripts/fourth/Energytornado.lua:17: in function <data/spells/scripts/fourth/Energytornado.lua:1>

@Xikini 's working perfectly now! ^^

I can keep testing things if you want guys, learning tons here!
 
Last edited:
Sure, I'm mainly interested in becoming a bit more knowledgeable with the new TFS scripting style. As far as I can tell on the surface level, the new one is making use of object oriented styled code as opposed to old TFS.
It bums me out that this error doesn't show a line number and I'm not really good with metatables, so I find it hard to decypher what it means, but it's possibly because i used
"if cid then" to check if cid is valid, try to swap that with

Code:
isCreature(cid)
or
Code:
isPlayer(cid)
if you have such functions in there.

EDIT: Also, even if that ends up fixing the script, it won't work as your original one, I made a miscalculation in the position inserting loop, i'll calculate a new one in a moment.
 
Last edited:
@Shadowsong Tested with both, isCreature(cid) and isPlayer(cid) same error here:
Code:
nextPos = myPositions[i]+1
@Xikini -Question: Xikini yours now works but it only does the whole circle once. What if i wanted to add X times to happen this circle?
 
@Shadowsong Tested with both, isCreature(cid) and isPlayer(cid) same error here:
Code:
nextPos = myPositions[i]+1
@Xikini -Question: Xikini yours now works but it only does the whole circle once. What if i wanted to add X times to happen this circle?
I rescripted it anyway.
You shouldn't be triggering that many addEvents at once.
Try looking at this instead.
It only triggers 1 addEvent per cast instead of 32.
LUA:
local positions = {
    {0, -3},
    {1, -3},
    {2, -2},
    {3, -1},
    {3,  0},
    {3,  1},
    {2,  2},
    {1,  3},
    {0,  3},
    {-1, 3},
    {-2, 2},
    {-3, 1},
    {-3, 0},
    {-3, 1},
    {-2, 2},
    {-1, 3}
}

local function sendEffc(cid, cid_p, count)
    local x = count
    if count > 16 then
        x = count - 16
    end
    local y = x + 1
    if count == 17 or count == 1 then
        y = 1
    end   
    local pid = Player(cid)
    local pos = Position(cid_p.x + positions[x][1], cid_p.y + positions[y][2], cid_p.z)
    local pos2 = Position(cid_p.x + positions[x][1], cid_p.y + positions[y][2], cid_p.z)
    pos:sendDistanceEffect(pos2, CONST_ANI_FIRE)
    doAreaCombatHealth(pid, COMBAT_FIREDAMAGE, pos, {1}, 10, 20, CONST_ANI_FIRE)
    count = count - 1
    if count > 0 then
        addEvent(sendEffc, 150, cid, cid_p, count)
    end
end

function onCastSpell(creature, variant)
    local cid = Player(creature.uid)
    local cid_p = cid:getPosition()
    addEvent(sendEffc, 150, creature.uid, cid_p, 32)
    return true
end
 
@Shadowsong Tested with both, isCreature(cid) and isPlayer(cid) same error here:
Code:
nextPos = myPositions[i]+1
@Xikini -Question: Xikini yours now works but it only does the whole circle once. What if i wanted to add X times to happen this circle?
My bad, that +1 should be inside the brackets.
But yeah, will need to change this

LUA:
        for xInc = 1, 3 do
            for yInc = 1,3 do
                table.insert(myPositions, Position(r.x+xInc, r.y+yInc, r.z))
            end
        end

because this will do the effect on all the following offsets of the player position:
LUA:
x = 1, y= 1
x = 1, y = 2
x = 1, y = 3
x = 2, y = 1
x = 2, y = 2
x = 2, y = 3
x = 3, y = 1
x = 3, y = 2
x = 3, y = 3
And after reading your first post thoroughly, i realized you want another shape :p
 
I was trying something like this before you answered @Xikini LoL but again fcking repetitive >.<

Code:
local function sendEffc(cid, position, position2)
   local cid = Player(cid)
   position:sendDistanceEffect(position2, CONST_ANI_FIRE)
   doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, position, {1}, 10, 20, CONST_ANI_FIRE)
end
local function wait (cid)
local creature = Creature(cid)
pos = creature:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[1][1])
          
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[i + 1][1])
          
       end
      
   end
end
function onCastSpell(creature, variant)
   local cid = Player(creature.uid)
   pos = cid:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
   for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[1][1])
           addEvent(wait, 600, creature.uid)
           addEvent(wait, 1200, creature.uid)
           addEvent(wait, 1800, creature.uid)
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[i + 1][1])
           addEvent(wait, 600, creature.uid)
           addEvent(wait, 1200, creature.uid)
           addEvent(wait, 1800, creature.uid)
       end
      
   end
   return true
end

On your new script this error shows up:
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/spells/scripts/fourth/Energytornado.lua:30: attempt to index a nil value
stack traceback:
        [C]: in function '__index'
        data/spells/scripts/fourth/Energytornado.lua:30: in function <data/spells/scripts/fourth/Energytornado.lua:20>
 
I rescripted it anyway.
You shouldn't be triggering that many addEvents at once.
Try looking at this instead.
It only triggers 1 addEvent per cast instead of 32.
LUA:
local positions = {
    {0, -3},
    {1, -3},
    {2, -2},
    {3, -1},
    {3,  0},
    {3,  1},
    {2,  2},
    {1,  3},
    {0,  3},
    {-1, 3},
    {-2, 2},
    {-3, 1},
    {-3, 0},
    {-3, 1},
    {-2, 2},
    {-1, 3}
}

local function sendEffc(cid, cid_p, count)
    local x = count
    if count > 16 then
        x = count - 16
    end
    local y = x + 1
    if count == 17 or count == 1 then
        y = 1
    end  
    local pid = Player(cid)
    local pos = Position(cid_p.x + positions[x][1], cid_p.y + positions[y][2], cid_p.z)
    local pos2 = Position(cid_p.x + positions[x][1], cid_p.y + positions[y][2], cid_p.z)
    pos:sendDistanceEffect(pos2, CONST_ANI_FIRE)
    doAreaCombatHealth(pid, COMBAT_FIREDAMAGE, pos, {1}, 10, 20, CONST_ANI_FIRE)
    count = count - 1
    if count > 0 then
        addEvent(sendEffc, 150, cid, cid_p, count)
    end
end

function onCastSpell(creature, variant)
    local cid = Player(creature.uid)
    local cid_p = cid:getPosition()
    addEvent(sendEffc, 150, creature.uid, cid_p, 32)
    return true
end

Yeah that's better. @Aeronx go with this script anyway, disregard what I wrote. I was just experimenting a bit :P I need to download myself a distro of this new TFS so I can test stuff before posting it to people for sure.

Also Xikini, as far as performance goes, does it make much difference that yours is called recursively as opposed to within a for loop?
I mean, given that the performance of the code above the recursive call is unobstructed by errors, they should be called and executed within relatively same interval, the only difference being that it will take some miniscule time period to execute the code above your addEvent before calling it again.

Don't get me wrong, it's certainly is better that way of course, because in my case, even if the creature didn't exist, those events would still be scheduled to execute, where as yours won't schedule another one if the code above screws up.
I'm just curious.
 
I was trying something like this before you answered @Xikini LoL but again fcking repetitive >.<

Code:
local function sendEffc(cid, position, position2)
   local cid = Player(cid)
   position:sendDistanceEffect(position2, CONST_ANI_FIRE)
   doAreaCombatHealth(cid, COMBAT_FIREDAMAGE, position, {1}, 10, 20, CONST_ANI_FIRE)
end
local function wait (cid)
local creature = Creature(cid)
pos = creature:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[1][1])
    
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[i + 1][1])
    
       end
 
   end
end
function onCastSpell(creature, variant)
   local cid = Player(creature.uid)
   pos = cid:getPosition()
   local positions = {
       {Position(pos.x, pos.y - 3, pos.z)},
       {Position(pos.x + 1, pos.y - 3, pos.z)},
       {Position(pos.x + 2, pos.y - 2, pos.z)},
       {Position(pos.x + 3, pos.y - 1, pos.z)},
       {Position(pos.x + 3, pos.y, pos.z)},
       {Position(pos.x + 3, pos.y + 1, pos.z)},
       {Position(pos.x + 2, pos.y + 2, pos.z)},
       {Position(pos.x + 1, pos.y + 3, pos.z)},
       {Position(pos.x, pos.y + 3, pos.z)},
       {Position(pos.x - 1, pos.y + 3, pos.z)},
       {Position(pos.x - 2, pos.y + 2, pos.z)},
       {Position(pos.x - 3, pos.y + 1, pos.z)},
       {Position(pos.x - 3, pos.y, pos.z)},
       {Position(pos.x - 3, pos.y - 1, pos.z)},
       {Position(pos.x - 2, pos.y - 2, pos.z)},
       {Position(pos.x - 1, pos.y - 3, pos.z)}
   }
   for i = 1, 32 do
       if i > 16 then
           i = i - 16
       end
       if i == 16 then
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[1][1])
           addEvent(wait, 600, creature.uid)
           addEvent(wait, 1200, creature.uid)
           addEvent(wait, 1800, creature.uid)
       else
           addEvent(sendEffc, i * 150, creature.uid, positions[i][1], positions[i + 1][1])
           addEvent(wait, 600, creature.uid)
           addEvent(wait, 1200, creature.uid)
           addEvent(wait, 1800, creature.uid)
       end
 
   end
   return true
end

On your new script this error shows up:
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/spells/scripts/fourth/Energytornado.lua:30: attempt to index a nil value
stack traceback:
        [C]: in function '__index'
        data/spells/scripts/fourth/Energytornado.lua:30: in function <data/spells/scripts/fourth/Energytornado.lua:20>
I added in the functionality you wanted, and I think fixed the error.. hopefully
LUA:
local positions = {
   {0, -3},
   {1, -3},
   {2, -2},
   {3, -1},
   {3,  0},
   {3,  1},
   {2,  2},
   {1,  3},
   {0,  3},
   {-1, 3},
   {-2, 2},
   {-3, 1},
   {-3, 0},
   {-3, 1},
   {-2, 2},
   {-1, 3}
}

local function sendEffc(cid, cid_x, cid_y, cid_z, count)
   local x = count
   if x > 16 then
       repeat
           x = x - 16
       until x <= 16
   end
   local y = x + 1
   if y > 16 then
       y = 1
   end
   local pid = Player(cid)
   local pos = Position(cid_x + positions[x][1], cid_y + positions[x][2], cid_z)
   local pos2 = Position(cid_x + positions[y][1], cid_y + positions[y][2], cid_z)
   pos:sendDistanceEffect(pos2, CONST_ANI_FIRE)
   doAreaCombatHealth(pid, COMBAT_FIREDAMAGE, pos, {1}, 10, 20, CONST_ANI_FIRE)
   count = count - 1
   if count > 0 then
       addEvent(sendEffc, 150, cid, cid_x, cid_y, cid_z, count)
   end
end

function onCastSpell(creature, variant)
   local times_to_run = 2
   local cid = Player(creature.uid)
   local cid_p = cid:getPosition()
   addEvent(sendEffc, 150, creature.uid, cid_p.x, cid_p.y, cid_p.z, times_to_run * 16)
   return true
end
Yeah that's better. @Aeronx go with this script anyway, disregard what I wrote. I was just experimenting a bit :p I need to download myself a distro of this new TFS so I can test stuff before posting it to people for sure.

Also Xikini, as far as performance goes, does it make much difference that yours is called recursively as opposed to within a for loop?
I mean, given that the performance of the code above the recursive call is unobstructed by errors, they should be called and executed within relatively same interval, the only difference being that it will take some miniscule time period to execute the code above your addEvent before calling it again.

Don't get me wrong, it's certainly is better that way of course, because in my case, even if the creature didn't exist, those events would still be scheduled to execute, where as yours won't schedule another one if the code above screws up.
I'm just curious.
Well the main reason for the looping function is just so your not lagging down the server with endless addEvents.

Imagine 10 people casting the spell.

With it looping through the same function = 10 addEvents running simultaneously
with addEvent in a for loop = 320 addEvents running simultaneously

and if you have multiple spells doing this, and more players online, the problem just aggravates itself.






-- edit
fixed a super small error
 
Last edited by a moderator:
Back
Top