• 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!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

TFS 1.X+ addEvent spells monster

Kahras

Member
Joined
Aug 6, 2012
Messages
97
Reaction score
7
Location
Warsaw
Hello
I have such a script for a spell and I have a problem with addEvent:

Lua:
Position.directionOffset = {
    [DIRECTION_NORTH] = {x = 0, y = -1},
    [DIRECTION_EAST] = {x = 1, y = 0},
    [DIRECTION_SOUTH] = {x = 0, y = 1},
    [DIRECTION_WEST] = {x = -1, y = 0},
    [DIRECTION_SOUTHWEST] = {x = -1, y = 1},
    [DIRECTION_SOUTHEAST] = {x = 1, y = 1},
    [DIRECTION_NORTHWEST] = {x = -1, y = -1},
    [DIRECTION_NORTHEAST] = {x = 1, y = -1}
}

function Position:setDirectionOffset(dir)
    local tmp = Position.directionOffset[dir]
    if not tmp then
        return self
    end
    return Position(self.x + tmp.x, self.y + tmp.y, self.z)
end

--[[#######################################################################################]]--
function doAreaCombatDamage(cid, attacker, combatType, position, min, max, effect)
   --// Incase the creature disappears within 120-250ms time window
   local creature = Creature(cid)
   if not creature then
       return
   end
   doAreaCombatHealth(attacker, combatType, position, 0, min, max, effect)
end

local running = {}

local function runSpell(cid, i, j, delay, radius, damage, damageType, areaEffect, distanceEffect)
   local player = Creature(cid)
   --// Player doesn't exist anymore
   if not player or Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) and bit.band(player:getGroup():getFlags(), PlayerFlag_IgnoreProtectionZone) == 0 then
       stopEvent(running[cid])
       running[cid] = nil
       return
   end
   --// Maximum rounds complete
   if i > j then
       stopEvent(running[cid])
       running[cid] = nil
       return
   end
   local center = player:getPosition()
   local specs = Game.getSpectators(center, false, false, radius.x, radius.x, radius.y, radius.y)
   --// Send effects and damage creatures within radius
   local args = {nil, cid, damageType, nil, damage.min, damage.max, areaEffect}
   for i = 1, #specs do
       if specs[i]:isPlayer() then
           local specPos = specs[i]:getPosition()
           args[1] = specs[i]:getId()
           args[4] = specPos
           center:sendDistanceEffect(specPos, distanceEffect)
           addEvent(doAreaCombatDamage, 120 + (center:getDistance(specPos) * 7), unpack(args))
       end
   end
   addEvent(runSpell, delay, cid, i+1, j, delay, radius, damage, damageType, areaEffect, distanceEffect)
end

local offsets = {DIRECTION_WEST, DIRECTION_NORTH, DIRECTION_EAST, DIRECTION_SOUTH}

local function sendEffects(cid, delay, areaEffect, distanceEffect)
   local player = Monster(cid)
   if not player or Tile(player:getPosition()):hasFlag(TILESTATE_PROTECTIONZONE) and bit.band(player:getGroup():getFlags(), PlayerFlag_IgnoreProtectionZone) == 0 then
       stopEvent(running[cid])
       running[cid] = nil
       return
   end
   local pos = player:getPosition()
   --// Send distance effects (N/E/S/W) & area effect on player
   for i = 1, #offsets do
       local fromPos = pos:setDirectionOffset(offsets[i])
       local toPos = pos:setDirectionOffset(offsets[i+1] or offsets[1])
       fromPos:sendDistanceEffect(toPos, distanceEffect)
   end
   pos:sendMagicEffect(areaEffect)
   running[cid] = addEvent(sendEffects, delay, cid, delay, areaEffect, distanceEffect)
end
--[[#######################################################################################]]--
local config = {
   damage = {min = -100, max = -100},
   rounds = 40, -- number of times the spell loops (effects & damage)
   delay = 250, -- ms
   radius = {x = 4, y = 4}, -- sqm radius
   damageType = COMBAT_DEATHDAMAGE,
   areaEffect = CONST_ME_MORTAREA,
   distanceEffect = CONST_ANI_SUDDENDEATH,
}

function onCastSpell(creature, variant)
   local player = Creature(cid)
   sendEffects(creature, config.delay, config.areaEffect, config.distanceEffect)
   runSpell(creature, 0, config.rounds, config.delay, config.radius, config.damage, config.damageType, config.areaEffect, config.distanceEffect)
   return true
end

LuaScriptInterface::luaAddEvent(). Argument #3 is unsafe
stack traceback:
[C]: in function 'addEvent'
data/spells/scripts/monster/boss/ue.lua:79: in function <data/spells/scripts/monster/boss/ue.lua:64>

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
LuaScriptInterface::luaAddEvent(). Argument #4 is unsafe
stack traceback:
[C]: in function 'addEvent'
data/spells/scripts/monster/boss/ue.lua:56: in function <data/spells/scripts/monster/boss/ue.lua:32>

The spell is meant to be used by the monster.
ps. I'll remove those unnecessary conditions later (player:getPosition()):hasFlag(TILESTATE_PROT...
 

Roddet

Boo!
Premium User
Support Team
Joined
May 1, 2013
Messages
726
Solutions
84
Reaction score
479
Location
Mex
You are passing userdata instead creatureId as argument on addEvents, which eventually will crash your server
Just change creature to creature:getId() inside onCastSpell

More info:
 
OP
OP
K

Kahras

Member
Joined
Aug 6, 2012
Messages
97
Reaction score
7
Location
Warsaw
You are passing userdata instead creatureId as argument on addEvents, which eventually will crash your server
Just change creature to creature:getId() inside onCastSpell

More info:
thx ;) very good!
 
Top