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

Solved Movements.xml stepIn trap, nil value, creature not found.

  • Thread starter Thread starter Xikini
  • Start date Start date
X

Xikini

Guest
The Forgotten Server, version 0.3.7_SVN (Crying Damson)
Trying to make a wall trap that gives an animation, and then attempts to 'follow the area' of the projectile.
Picture for reference.
iQJVEtI.png

I know it takes about 100/200 milliseconds to travel the width of the area, and I can fiddle with that later.

Current problem is I don't seem to be doing something correctly.

When I step on the tile I get 4 instances of this error,
Code:
[13:30:47.007] [Error - MoveEvents Interface]
[13:30:47.007] In a timer event called from:
[13:30:47.007] data/movements/scripts/trapthrowingstar.lua:onStepIn
[13:30:47.008] Description:
[13:30:47.008] attempt to index a nil value
[13:30:47.008] stack traceback:
[13:30:47.008]  [C]: in function 'getTopCreature'
[13:30:47.009]  data/movements/scripts/trapthrowingstar.lua:14: in function <data/movements/scripts/trapthrowingstar.lua:13>
Which makes sense, seeing as it has no idea where 'i' is.
I don't really care if the loop doesn't work, I just need it to 'work'. :p

Here's my current script.
Code:
local config = {
   [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
   [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
   mindmg = -40,
   maxdmg = -200
}
local hitArea = {
   [1] = {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
   [2] = {x = 1411, y = 1423, z = 7},
   [3] = {x = 1411, y = 1424, z = 7},
   [4] = {x = 1411, y = 1425, z = 7}
}
function hitTarget()
   doTargetCombatHealth(0, getTopCreature(hitArea[i]), COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
end
function onStepIn(cid, item, fromPos, item2, toPos)
   doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
   for i = 1, #hitArea do
     addEvent(hitTarget, i * 25)
   end
   return true
end
How can I modify it to get the desired results?
Thanks,

Xikini
 
Last edited by a moderator:
Code:
local config = {
   [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
   [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
   mindmg = -40,
   maxdmg = -200
}
local hitArea = {
   {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
   {x = 1411, y = 1423, z = 7},
   {x = 1411, y = 1424, z = 7},
   {x = 1411, y = 1425, z = 7}
}
function onStepIn(cid, item, fromPos, item2, toPos)
  function hitTarget(uid)
    print(uid)
    doTargetCombatHealth(0, uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
   for _, pos in pairs(hitArea) do
     if isPlayer(getTopCreature(pos).uid) then
       addEvent(hitTarget, getTopCreature(pos).uid, i * 25)
     end
   end
   return true
end
Code:
[15:10:51.637] [Error - MoveEvents Interface]
[15:10:51.637] data/movements/scripts/trapthrowingstar.lua:onStepIn
[15:10:51.638] Description:
[15:10:51.638] data/movements/scripts/trapthrowingstar.lua:21: attempt to perform arithmetic on global 'i' (a nil value)
[15:10:51.638] stack traceback:
[15:10:51.638]  data/movements/scripts/trapthrowingstar.lua:21: in function <data/movements/scripts/trapthrowingstar.lua:13>
 
Code:
[15:10:51.637] [Error - MoveEvents Interface]
[15:10:51.637] data/movements/scripts/trapthrowingstar.lua:onStepIn
[15:10:51.638] Description:
[15:10:51.638] data/movements/scripts/trapthrowingstar.lua:21: attempt to perform arithmetic on global 'i' (a nil value)
[15:10:51.638] stack traceback:
[15:10:51.638]  data/movements/scripts/trapthrowingstar.lua:21: in function <data/movements/scripts/trapthrowingstar.lua:13>
well change
for _, pos in pairs(hitArea) do
to
for i, pos in pairs(hitArea) do
 
well change
for _, pos in pairs(hitArea) do
to
for i, pos in pairs(hitArea) do
No error's, no damage.
Code:
local config = {
  [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
  [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
  mindmg = -40,
  maxdmg = -200
}
local hitArea = {
  {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
  {x = 1411, y = 1423, z = 7},
  {x = 1411, y = 1424, z = 7},
  {x = 1411, y = 1425, z = 7}
}
function onStepIn(cid, item, fromPos, item2, toPos)
  function hitTarget(uid)
  print(uid)
  doTargetCombatHealth(0, uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
  for i, pos in pairs(hitArea) do
  if isPlayer(getTopCreature(pos).uid) then
  addEvent(hitTarget, getTopCreature(pos).uid, i * 25)
  end
  end
  return true
end
 
well use this
Code:
local config = {
   [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
   [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
   mindmg = -40,
   maxdmg = -200
}
local hitArea = {
   {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
   {x = 1411, y = 1423, z = 7},
   {x = 1411, y = 1424, z = 7},
   {x = 1411, y = 1425, z = 7}
}
function onStepIn(cid, item, fromPos, item2, toPos)
  function hitTarget(uid)
    print(uid)
    doTargetCombatHealth(0, uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
   for _, pos in pairs(hitArea) do
     if isPlayer(getTopCreature(pos).uid) then
       addEvent(hitTarget, getTopCreature(pos).uid, 1 * 25)
     end
   end
   return true
end
 
well use this
Code:
local config = {
   [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
   [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
   mindmg = -40,
   maxdmg = -200
}
local hitArea = {
   {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
   {x = 1411, y = 1423, z = 7},
   {x = 1411, y = 1424, z = 7},
   {x = 1411, y = 1425, z = 7}
}
function onStepIn(cid, item, fromPos, item2, toPos)
  function hitTarget(uid)
    print(uid)
    doTargetCombatHealth(0, uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
   for _, pos in pairs(hitArea) do
     if isPlayer(getTopCreature(pos).uid) then
       addEvent(hitTarget, getTopCreature(pos).uid, 1 * 25)
     end
   end
   return true
end
No error's, no print.
I really appreciate the time your taking. :P
 
Code:
addEvent(callback, delay, ...)

addEvent(hitTarget, getTopCreature(pos).uid, 1 * 25) -> addEvent(hitTarget, 1 * 25, getTopCreature(pos).uid)

Code:
local function hitTarget(cid)
    if not isPlayer(cid) then
        return
    end

    doTargetCombatHealth(0, cid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
end

function onStepIn(cid, item, fromPos, item2, toPos)
    doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)

    local creatureId
    for i = 1, #hitArea do
        creatureId = getTopCreature(hitArea[i]).uid
        if creatureId ~= 0 then
            addEvent(hitTarget, i * 25, creatureId)
        end
    end
    return true
end
 
Code:
addEvent(callback, delay, ...)

addEvent(hitTarget, getTopCreature(pos).uid, 1 * 25) -> addEvent(hitTarget, 1 * 25, getTopCreature(pos).uid)

Code:
local function hitTarget(cid)
    if not isPlayer(cid) then
        return
    end

    doTargetCombatHealth(0, cid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
end

function onStepIn(cid, item, fromPos, item2, toPos)
    doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)

    local creatureId
    for i = 1, #hitArea do
        creatureId = getTopCreature(hitArea[i]).uid
        if creatureId ~= 0 then
            addEvent(hitTarget, i * 25, creatureId)
        end
    end
    return true
end
It works mostly.
Streamside took into into private with me, and this is what we came up with, before ending for the day. :P

Code:
local config = {
  [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
  [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
  mindmg = -40,
  maxdmg = -200
}
local hitArea = {
  {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
  {x = 1411, y = 1423, z = 7},
  {x = 1411, y = 1424, z = 7},
  {x = 1411, y = 1425, z = 7}
}
function onStepIn(cid, item, fromPos, item2, toPos)
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
  for _, pos in pairs(hitArea) do
   print (getTopCreature(pos).uid)
   if isPlayer(getTopCreature(pos).uid) then
     addEvent(function(cid)
     doTargetCombatHealth(0, cid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
     end, 25, getTopCreature(pos).uid)
   end
  end
  return true
end

Problem is that it's checking each square for the player, then sending the damage after the timer expires.

What it needs to be changed to.. is check the square After the timer, then send the damage instantly if player is found.
kjqWCuK.png


This is so players can effectively dodge the trap if they are on the far side of it.
Although I'm unsure how to even do that now. :P
 
I'm very bad with old TFS revisions but I only re-arranged the code you had. It should hit any player standing on the area when the timer ends.
I would probably put the distance effect in the addEvent function too so the animation is also delayed the same amount as the damage, but that's up to you.
Code:
local config = {
  [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
  [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
  mindmg = -40,
  maxdmg = -200
}
local hitArea = {
  {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
  {x = 1411, y = 1423, z = 7},
  {x = 1411, y = 1424, z = 7},
  {x = 1411, y = 1425, z = 7}
}

local function hitTargets()
  for _, pos in pairs(hitArea) do
    print (getTopCreature(pos).uid)
    if isPlayer(getTopCreature(pos).uid) then
      doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
    end
  end
end

function onStepIn(cid, item, fromPos, item2, toPos)
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
  addEvent(hitTargets, 25)
  return true
end
 
I'm very bad with old TFS revisions but I only re-arranged the code you had. It should hit any player standing on the area when the timer ends.
I would probably put the distance effect in the addEvent function too so the animation is also delayed the same amount as the damage, but that's up to you.
Code:
local config = {
  [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
  [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
  mindmg = -40,
  maxdmg = -200
}
local hitArea = {
  {x = 1411, y = 1422, z = 7}, -- hit area for damage between walls
  {x = 1411, y = 1423, z = 7},
  {x = 1411, y = 1424, z = 7},
  {x = 1411, y = 1425, z = 7}
}

local function hitTargets()
  for _, pos in pairs(hitArea) do
    print (getTopCreature(pos).uid)
    if isPlayer(getTopCreature(pos).uid) then
      doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
    end
  end
end

function onStepIn(cid, item, fromPos, item2, toPos)
  doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
  addEvent(hitTargets, 25)
  return true
end
This is probably very clunky, but it works the way I want it to. :p
If anyone wants to shorten it into some sort of loop, I'd be happy to see how that happens. :oops:
Code:
local config = {
  [1] = {x = 1411, y = 1421, z = 7}, -- top wall for animation
  [2] = {x = 1411, y = 1426, z = 7}, -- bottom wall for animation
  mindmg = -40,
  maxdmg = -200
}
local hitArea1 = {
{x = 1411, y = 1422, z = 7}
}
local hitArea2 = {
{x = 1411, y = 1423, z = 7}
}
local hitArea3 = {
{x = 1411, y = 1424, z = 7}
}
local hitArea4 = {
{x = 1411, y = 1425, z = 7}
}

   local function hitTargets1()
  for _, pos in pairs(hitArea1) do
  if isPlayer(getTopCreature(pos).uid) then
  doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  end
end

   local function hitTargets2()
  for _, pos in pairs(hitArea2) do
  if isPlayer(getTopCreature(pos).uid) then
  doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  end
end

   local function hitTargets3()
  for _, pos in pairs(hitArea3) do
  if isPlayer(getTopCreature(pos).uid) then
  doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  end
end

   local function hitTargets4()
  for _, pos in pairs(hitArea4) do
  if isPlayer(getTopCreature(pos).uid) then
  doTargetCombatHealth(0, getTopCreature(pos).uid, COMBAT_PHYSICALDAMAGE, config.mindmg, config.maxdmg, CONST_ME_NONE)
  end
  end
end

local function Animation()
   doSendDistanceShoot(config[1], config[2], CONST_ANI_THROWINGSTAR)
end

function onStepIn(cid, item, fromPos, item2, toPos)
   addEvent(Animation, 30)
   addEvent(hitTargets1, 60)
   addEvent(hitTargets2, 90)
   addEvent(hitTargets3, 130)
   addEvent(hitTargets4, 190)
  return true
end

Thank you,
@forgee @Ninja @StreamSide @Codinablack
:p :oops: :rolleyes: :oops: :p
Xikini
 
Last edited by a moderator:
Back
Top