pink_panther
Excellent OT User
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?
Combat
with no effects/damage and call it, to get target positions.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 someCombat
with no effects/damage and call it, to get target positions.
Like TFS does:
using:forgottenserver/data/spells/lib/spells.lua at master · otland/forgottenserver
A free and open-source MMORPG server emulator written in C++ - otland/forgottenservergithub.com
forgottenserver/data/lib/core/combat.lua at master · otland/forgottenserver
A free and open-source MMORPG server emulator written in C++ - otland/forgottenservergithub.com
Looks likecreature
parameter can benil
. You just need to create combat, set its area (ex.combat:setArea(AREA_CIRCLE3X3)
) and execute it withonTargetTile
callback.
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. xDWould 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()
--[[
-> 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
0
instead nil
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 try0
insteadnil
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
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()
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.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} }))
_AREA_CIRCLE3X3
or something xDsendAreaEffect(player:getPosition(), _AREA_CIRCLE3X3, 11)