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

Send Area Effect

pink_panther

Excellent OT User
Joined
Sep 10, 2016
Messages
1,171
Solutions
13
Reaction score
613
Location
Kazordoon
I know I can do position:sendMagicEffect(type), but is there an easy way to send a area magic effect (Like AREA_CIRCLE3X3 or AREA_BEAM5) without it being a combat damage?
 
Not with default functions, no.

You'd have to write some Lua functions, and make a similar table to the spells lib file.. then loop over it and send it to each position.

Make all of the 'graphs' in the north direction.

To rotate the spell..
South is just a mirror.. so use * -1 to turn it positive/negative.

For east/west, you need to swap x/y and make x or y negative.

---

rotate counter clockwise would be (-90 degree) (west)
x/y -> -y/x

rotate clockwise is (90 degree) (east)
x/y -> y/-x

rotate 180 (south)
x/y -> -x/-y

--

Hope that helps.
 
Yeah, I was thinking of doing that.. but thought surely there would be a way to send aoe effects that aren't coming from a creature/player.

Well, piss.
 
You can also write some Combat with no effects/damage and call it, to get target positions.
Like TFS does:
using:

Looks like creature parameter can be nil. You just need to create combat, set its area (ex. combat:setArea(AREA_CIRCLE3X3)) and execute it with onTargetTile callback.
 
You can also write some Combat with no effects/damage and call it, to get target positions.
Like TFS does:
using:

Looks like creature parameter can be nil. You just need to create combat, set its area (ex. combat:setArea(AREA_CIRCLE3X3)) and execute it with onTargetTile callback.

Would require some all back, or targeting an item to use somewhere? I was wanting to apply it at random, or a movement event or a non multi use action.

I also tried passing nil or 0 for the creature, but the function fails because the creature couldn't be found.

Lua:
local talkaction = TalkAction("!test")

local gfbArea = createCombatArea(AREA_CIRCLE5X5)
local eBeamArea = createCombatArea(AREA_BEAM5)

function talkaction.onSay(player, words, param)


    doAreaCombat(nil, COMBAT_FIREDAMAGE, itemPosition, gfbArea, 0, 0, CONST_ME_EXPLOSIONHIT)   
    
    return false
end

talkaction:register()
 
Would require some all back, or targeting an item to use somewhere? I was wanting to apply it at random, or a movement event or a non multi use action.

I also tried passing nil or 0 for the creature, but the function fails because the creature couldn't be found.

Lua:
local talkaction = TalkAction("!test")

local gfbArea = createCombatArea(AREA_CIRCLE5X5)
local eBeamArea = createCombatArea(AREA_BEAM5)

function talkaction.onSay(player, words, param)


    doAreaCombat(nil, COMBAT_FIREDAMAGE, itemPosition, gfbArea, 0, 0, CONST_ME_EXPLOSIONHIT)
 
    return false
end

talkaction:register()
Sorry, just replying back.. in case you wanted my solution. xD

I mostly just did it for some practice. 🤷‍♂️


Untested. Let me know if you try it out. :)
Lua:
--[[
    -> centrePosition = centre of area
        Example;
            Position(1000, 1000, 7)
            
    -> effectTable = determines area. Modular. Must be uniform rectangle
        Example;
            AREA_WAVE3 = {
                {1, 1, 1},
                {1, 1, 1},
                {0, 3, 0}
            }
            3 = centre + effect
            2 = centre
            1 = effect
            0 = no effect
            
    -> magicEffect = effect to use
        Example;
            CONST_ME_POFF
    
    -> direction = direction of spell (assumes effectTable is north) (rotates spell on x/y plane)
        Example;
            DIRECTION_NORTH or 0
            DIRECTION_EAST  or 1
            DIRECTION_SOUTH or 2
            DIRECTION_WEST  or 3
--]]

--[[
    Example Usage;
    
        local AREA_WAVE3 = {
            {1, 1, 1},
            {1, 1, 1},
            {0, 3, 0}
        }
        
        sendAreaEffect(Position(1000, 1000, 7), AREA_WAVE3, CONST_ME_POFF) -- direction omitted, defaults north
        sendAreaEffect(Position(1000, 1000, 7), AREA_WAVE3, CONST_ME_POFF, 1) -- south (mirror/rotate 180 degree)
        sendAreaEffect(Position(1000, 1000, 7), AREA_WAVE3, CONST_ME_POFF, DIRECTION_EAST) -- east (rotate 90 degree clockwise)
]]--

local function sendAreaEffect(centrePosition, effectTable, magicEffect, direction)

    local centre = 0
    local length = #effectTable   -- north/south (amount of arrays in main array)
    local width = #effectTable[1] --  west/east (amount of items in each array)
    
    for _length = 1, length do
        if centre ~= 0 then
            break
        end
        for _width = 1, do
            if effectTable[_length][_width] > 1 then
                centre = {length = _length, width = _width}
                break
            end
        end
    end
    
    if centre == 0 then
        print("Lua Error: no centre found for effectTable. (3 = centre + effect | 2 = centre | 1 = effect | 0 = no effect)")
        return
    end
    
    local x_offset = length - centre.length -- 0
    local y_offset = width - centre.width -- 1
    
    if not Position(centrePosition) then -- Idk if this works or not. Would have to test lol
        print("Lua Error: a valid position was not used.")
        return
    end
    
    for _length = 1, length do
        for _width = 1, width do
            if effectTable[_length][_width] == 1 or effectTable[_length][_width] == 3 then
                local effectPosition = Position(centrePosition.x + ((_width - width) + x_offset), centrePosition.y + ((_length - length) + y_offset), centrePosition.z)
                if direction then
                    if direction == DIRECTION_NORTH then
                        -- do nothing
                    elseif direction == DIRECTION_SOUTH then
                        effectPosition = Position(effectPosition.x * -1, effectPosition.y * -1, effectPosition.z)
                    elseif direction == DIRECTION_EAST then
                        effectPosition = Position(effectPosition.y, effectPosition.x * -1, effectPosition.z)
                    elseif direction == DIRECTION_WEST then
                        effectPosition = Position(effectPosition.y * -1, effectPosition.x, effectPosition.z)
                    else
                        print("Lua Error: not a valid direction. use 0,1,2,3 or DIRECTION_SOUTH / WEST / EAST / NORTH")
                        return
                    end
                end
                effectPosition:sendMagicEffect(magicEffect)
            end
        end
    end
    
end
 
@pink_panther try 0 instead nil

or Gesior's suggestion
Lua:
local combat = Combat()
combat:setArea(createCombatArea(AREA_CIRCLE5X5))

local positions = combat:getPositions(0, {
    type = 2, -- # VARIANT_POSITION
    pos = position
})

for i = 1, #positions do
    positions[i]:sendMagicEffect(effect)
end
 
@pink_panther try 0 instead nil

or Gesior's suggestion
Lua:
local combat = Combat()
combat:setArea(createCombatArea(AREA_CIRCLE5X5))

local positions = combat:getPositions(0, {
    type = 2, -- # VARIANT_POSITION
    pos = position
})

for i = 1, #positions do
    positions[i]:sendMagicEffect(effect)
end

Yeah, looks like this method works alright. Thanks guys.

Here's an example I slapped into a talk action if anyone else is trying to do this.

Lua:
local talkaction = TalkAction("!test")


local gfbEffect = Combat()
gfbEffect:setArea(createCombatArea(AREA_CIRCLE3X3))


function talkaction.onSay(player, words, param)

    local positions = gfbEffect:getPositions(0, {
        type = 2, -- # VARIANT_POSITION
        pos = player:getPosition()
    })
    
    for i = 1, #positions do
        positions[i]:sendMagicEffect(11)
    end
    
    return false
end

talkaction:register()

1674189762340.png
Post automatically merged:

I'm now having a different issue... Strangely enough when the server starts, its failing to create these combat variables, throwing some error about the area.

If I do /reload all again once the server has finished starting up, it reloads the scripts just fine and it works as expected.... Can see in the server console too that it loads the libs, then the scripts, so I don't understand what I've done now.

Edit: Seems the area variables like AREA_CIRCLE3X3 are all defined in areas.lua, which is part of spells not libs, so it doesn't know what they are. Can be fixed by manually setting the area in the script, like this

Lua:
local gfbEffect = Combat()
gfbEffect:setArea(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}
}))
 
Last edited:
Yeah, looks like this method works alright. Thanks guys.

Here's an example I slapped into a talk action if anyone else is trying to do this.

Lua:
local talkaction = TalkAction("!test")


local gfbEffect = Combat()
gfbEffect:setArea(createCombatArea(AREA_CIRCLE3X3))


function talkaction.onSay(player, words, param)

    local positions = gfbEffect:getPositions(0, {
        type = 2, -- # VARIANT_POSITION
        pos = player:getPosition()
    })
   
    for i = 1, #positions do
        positions[i]:sendMagicEffect(11)
    end
   
    return false
end

talkaction:register()

View attachment 72898
Post automatically merged:

I'm now having a different issue... Strangely enough when the server starts, its failing to create these combat variables, throwing some error about the area.

If I do /reload all again once the server has finished starting up, it reloads the scripts just fine and it works as expected.... Can see in the server console too that it loads the libs, then the scripts, so I don't understand what I've done now.

Edit: Seems the area variables like AREA_CIRCLE3X3 are all defined in areas.lua, which is part of spells not libs, so it doesn't know what they are. Can be fixed by manually setting the area in the script, like this

Lua:
local gfbEffect = Combat()
gfbEffect:setArea(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}
}))
Could make your own lib for the area's.
Just copy paste the spell lib, and rename it to _AREA_CIRCLE3X3 or something xD

Usage would be simple then.
Lua:
sendAreaEffect(player:getPosition(), _AREA_CIRCLE3X3, 11)
 
Back
Top