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

Lua Spell problem TIBIA 860 Distro Crying Damson

FilipeJF

New Member
Joined
Jan 9, 2012
Messages
124
Reaction score
4
First of all, I would like to thank Printer for the spell he posted in the post below:
https://otland.net/threads/ninja-vocation-spells.223635/

So, that's the script:

Lua:
function isWalkable(cid, pos)
    local tile = Tile(pos)
    if not tile then
        return false
    end
    if tile:queryAdd(cid) == 1 and not tile:hasFlag(TILESTATE_PROTECTIONZONE) then
        return true
    end
    return false
end
local function jumpBehindTarget(cid, target)
    local player = Player(cid)
    local target = Creature(target)
    local targetPos = target:getPosition()
    local targetPositions = {
        north = Position(targetPos.x, targetPos.y-1, targetPos.z),
        east = Position(targetPos.x+1, targetPos.y, targetPos.z),
        west = Position(targetPos.x-1, targetPos.y, targetPos.z),
        south = Position(targetPos.x, targetPos.y+1, targetPos.z)
    }
    local targetDir = target:getDirection()
    if targetDir == NORTH then
        dir = targetPositions.south
    elseif targetDir == EAST then
        dir = targetPositions.west
    elseif targetDir == WEST then
        dir = targetPositions.east
    elseif targetDir == SOUTH then
        dir = targetPositions.north
    end
    return dir
end
local function oldPos(cid, oldPos)
    local player = Player(cid)
    if not player then
        return
    end
    player:teleportTo(oldPos)
end
local function checkHasTarget(cid, count, oldPos)
    local player = Player(cid)
    if not player then
        return
    end
    if count < 1 then
        player:setGhostMode(false)
        return
    end

    local target = player:getTarget()
    if target then
        local behindTarget = jumpBehindTarget(cid, target:getId())
        if isWalkable(cid, behindTarget) then
            player:teleportTo(behindTarget)
        else
            player:teleportTo(target:getPosition())
            addEvent(backOldPos, 100, cid, oldPos)
        end
        player:setDirection(target:getDirection())
        player:setGhostMode(false)
        doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -20, -100, CONST_ME_FIREATTACK)
        return true
    end
    addEvent(checkHasTarget, 1 * 100, cid, count - 1)
end
function onCastSpell(creature, var)
    local playerPos = creature:getPosition()
    creature:setGhostMode(true)
    playerPos:sendMagicEffect(CONST_ME_POFF)
    addEvent(checkHasTarget, 1 * 250, creature:getId(), 50, playerPos)
    return false
end

And that's the error that I've been receiving:

Code:
[Error - Spell Interface]
data/spells/scripts/attack/ninja.lua:onCastSpell
Description:
data/spells/scripts/attack/ninja.lua:75: attempt to index local 'creature' (a number value)
stack traceback:
        data/spells/scripts/attack/ninja.lua:75: in function <data/spells/scripts/attack/ninja.lua:74>

I suppose this spell system is outdated, but since I'm a rookie on this department I don't know what to change to make it functionable. I don't even know if it's possible to make it functionable.
 
Solution
A few of parts of the code needed to be rewritten

quick explanation on how addEvent works:
addEvent(functionName, time in ms b4 execution, parameters)

example:
doCreatureSay(cid, "Hello World")
to do the above with 2 seconds delay
addEvent(doCreatureSay, 2000, cid, "Hello World")

Lua:
local condition = createConditionObject(CONDITION_INVISIBLE)
setConditionParam(condition, CONDITION_PARAM_TICKS, 5000)

local function isWalkable(cid, pos)
    pos.stackpos = 253
    if doTileQueryAdd(cid, pos) == 1 then -- checks if we can add cid to a position of choice
        return true
    end
    return false
end

local function jumpBehindTarget(cid, target)

    local tPos = getCreaturePosition(target)
    local tPositions = {
        north = {x...
The problem is that you are trying to use a script made for TFS 1.2+ while you are using TFS 0.3.6.
They don't use the same Lua functions, 1.2 uses meta ex. player:getName() while 0.3.6 uses getPlayerName(cid).
 
Can I ask why they did change it? Why didnt they just keep it same? whats the reason that its now "player:getName instead of getPlayerName ?

Alot of reasons, imo it's cleaner, easier to remember, all "getName" functions are the same, it isen't getItemName, getMonsterName etc etc
We also now use userdata values that I think.. makes it use less resources.

But one major thing is that the old script system was just a big mess, now it's clean and by that easier to work with.
 
The problem is that you are trying to use a script made for TFS 1.2+ while you are using TFS 0.3.6.
They don't use the same Lua functions, 1.2 uses meta ex. player:getName() while 0.3.6 uses getPlayerName(cid).


I've never worked with functions in this version. Is it possible to make this script work on TFS 0.36? Could someone give me more detailed help?

Well yes, you can use this file; forgottenserver/compat.lua at master · otland/forgottenserver · GitHub
To serach for the functions and find out what the old function was.



Okay, I'll spend some time studying this. Any result i put her; Thanks
 
Last edited by a moderator:
I'm a very slow person, so I'm not getting this to work. Tried to do the same as the Misterious guy, but not being any successfull. Can anybody help me replace the new funtions? Please!
 
I'm a very slow person, so I'm not getting this to work. Tried to do the same as the Misterious guy, but not being any successfull. Can anybody help me replace the new funtions? Please!
Bump !


I did not get anywhere! Can someone make it compatible?

Just checked the scripts and it looks like 0.3/0.4 dosn't have a "setGhostMode" function, but this might be good enough?
Otherwise you have to add that function to Lua in your sources.

This should work, not tested tho :p
Lua:
function isWalkable(cid, position)
    if not getTilePzInfo(position) then
        return true
    end

    return false
end

local function jumpBehindTarget(cid, target)
    local targetPos = getCreaturePosition(target)
    local targetPositions = {
        north = {x = targetPos.x, y = targetPos.y - 1, z = targetPos.z},
        east = {x = targetPos.x + 1, y = targetPos.y, z = targetPos.z},
        west = {x = targetPos.x - 1, y = targetPos.y, z = targetPos.z},
        south = {x = targetPos.x, y = targetPos.y + 1, z = targetPos.z}
    }

    local targetDir = getPlayerLookDir(target)
    if targetDir == NORTH then
        dir = targetPositions.south
    elseif targetDir == EAST then
        dir = targetPositions.west
    elseif targetDir == WEST then
        dir = targetPositions.east
    elseif targetDir == SOUTH then
        dir = targetPositions.north
    end

    return dir
end

local function backOldPos(cid, oldPos)
    if not isPlayer(cid) then
        return
    end

    doTeleportThing(cid, oldPos)
end

local function checkHasTarget(cid, count, oldPos)
    if not isPlayer(cid) then
        return
    end

    local target = getCreatureTarget(cid)
    if target then
        local behindTarget = jumpBehindTarget(cid, target:getId())
        if isWalkable(cid, behindTarget) then
            doTeleportThing(cid, behindTarget)
        else
            doTeleportThing(cid, getCreaturePosition(target))
            addEvent(backOldPos, 100, cid, oldPos)
        end

        doCreatureSetLookDir(cid, getPlayerLookDir(target))
        doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -20, -100, CONST_ME_FIREATTACK)
        return true
    end

    addEvent(checkHasTarget, 1 * 100, cid, count - 1)
end

function onCastSpell(cid, var)
    local playerPos = getCreaturePosition(cid)
    doSendMagicEffect(playerPos, CONST_ME_POFF)
    addEvent(checkHasTarget, 1 * 250, getCreatureId(cid), 50, playerPos)
    return false
end
 
Just checked the scripts and it looks like 0.3/0.4 dosn't have a "setGhostMode" function, but this might be good enough?
Otherwise you have to add that function to Lua in your sources.

This should work, not tested tho :p
Lua:
function isWalkable(cid, position)
    if not getTilePzInfo(position) then
        return true
    end

    return false
end

local function jumpBehindTarget(cid, target)
    local targetPos = getCreaturePosition(target)
    local targetPositions = {
        north = {x = targetPos.x, y = targetPos.y - 1, z = targetPos.z},
        east = {x = targetPos.x + 1, y = targetPos.y, z = targetPos.z},
        west = {x = targetPos.x - 1, y = targetPos.y, z = targetPos.z},
        south = {x = targetPos.x, y = targetPos.y + 1, z = targetPos.z}
    }

    local targetDir = getPlayerLookDir(target)
    if targetDir == NORTH then
        dir = targetPositions.south
    elseif targetDir == EAST then
        dir = targetPositions.west
    elseif targetDir == WEST then
        dir = targetPositions.east
    elseif targetDir == SOUTH then
        dir = targetPositions.north
    end

    return dir
end

local function backOldPos(cid, oldPos)
    if not isPlayer(cid) then
        return
    end

    doTeleportThing(cid, oldPos)
end

local function checkHasTarget(cid, count, oldPos)
    if not isPlayer(cid) then
        return
    end

    local target = getCreatureTarget(cid)
    if target then
        local behindTarget = jumpBehindTarget(cid, target:getId())
        if isWalkable(cid, behindTarget) then
            doTeleportThing(cid, behindTarget)
        else
            doTeleportThing(cid, getCreaturePosition(target))
            addEvent(backOldPos, 100, cid, oldPos)
        end

        doCreatureSetLookDir(cid, getPlayerLookDir(target))
        doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -20, -100, CONST_ME_FIREATTACK)
        return true
    end

    addEvent(checkHasTarget, 1 * 100, cid, count - 1)
end

function onCastSpell(cid, var)
    local playerPos = getCreaturePosition(cid)
    doSendMagicEffect(playerPos, CONST_ME_POFF)
    addEvent(checkHasTarget, 1 * 250, getCreatureId(cid), 50, playerPos)
    return false
end

Hello! First of all, thank you for taking your time for helping me. But as I tried to use a spell, an error appeared:

Lua:
[Error - Spell Interface]
data/spells/scripts/attack/ninja.lua:onCastSpell
Description:
data/spells/scripts/attack/ninja.lua:66: attempt to call global 'getCreatureId' (a nil value)
stack traceback:
        data/spells/scripts/attack/ninja.lua:66: in function <data/spells/scripts/attack/ninja.lua:63>

What could it mean?
 
Hello! First of all, thank you for taking your time for helping me. But as I tried to use a spell, an error appeared:

Lua:
[Error - Spell Interface]
data/spells/scripts/attack/ninja.lua:onCastSpell
Description:
data/spells/scripts/attack/ninja.lua:66: attempt to call global 'getCreatureId' (a nil value)
stack traceback:
        data/spells/scripts/attack/ninja.lua:66: in function <data/spells/scripts/attack/ninja.lua:63>

What could it mean?

Jesus 0.x is just a cluster f..k
Ehm try getPlayerId insted of getCreatureId then xD
 
So, I think that this function is not avaible in my server. I've checked the entire list of functions, and GetPlayerId isn't avaible also. Is there any other function that could work with this?

KABUUUUUUUUUMP
 
Last edited by a moderator:
Now i get this

Lua:
[Error - Spell Interface]
In a timer event called from:
data/spells/scripts/attack/ninja.lua:onCastSpell
Description:
data/spells/scripts/attack/ninja.lua:47: attempt to index local 'target' (a number value)
stack traceback:
        data/spells/scripts/attack/ninja.lua:47: in function <data/spells/scripts/attack/ninja.lua:40>

bump!
 
Last edited by a moderator:
change target:getId() to target (remove :getId())
I changed to this in line 47:
Lua:
        local behindTarget = jumpBehindTarget(cid, target (remove :getId()))

And i got this error:

Lua:
[Error - Spell Interface]
In a timer event called from:
data/spells/scripts/attack/ninja.lua:onCastSpell
Description:
data/spells/scripts/attack/ninja.lua:47: attempt to index global 'remove' (a nil value)
stack traceback:
        data/spells/scripts/attack/ninja.lua:47: in function <data/spells/scripts/attack/ninja.lua:40>

Any ideas boss?
 
A few of parts of the code needed to be rewritten

quick explanation on how addEvent works:
addEvent(functionName, time in ms b4 execution, parameters)

example:
doCreatureSay(cid, "Hello World")
to do the above with 2 seconds delay
addEvent(doCreatureSay, 2000, cid, "Hello World")

Lua:
local condition = createConditionObject(CONDITION_INVISIBLE)
setConditionParam(condition, CONDITION_PARAM_TICKS, 5000)

local function isWalkable(cid, pos)
    pos.stackpos = 253
    if doTileQueryAdd(cid, pos) == 1 then -- checks if we can add cid to a position of choice
        return true
    end
    return false
end

local function jumpBehindTarget(cid, target)

    local tPos = getCreaturePosition(target)
    local tPositions = {
        north = {x = tPos.x, y = tPos.y - 1, z = tPos.z},
        east = {x = tPos.x + 1, y = tPos.y, z = tPos.z},
        west = {x = tPos.x - 1, y = tPos.y, z = tPos.z},
        south = {x = tPos.x, y = tPos.y + 1, z = tPos.z}
    }
    local tDir = getPlayerLookDir(target)

    if tDir == NORTH then
        dir = tPositions.south
    elseif tDir == EAST then
        dir = tPositions.west
    elseif tDir == WEST then
        dir = tPositions.east
    elseif tDir == SOUTH then
        dir = tPositions.north
    end

    return dir
end

local function checkHasTarget(cid, count, oldPos)

    local target = getCreatureTarget(cid)

    if target ~= 0 then
        local behindTarget = jumpBehindTarget(cid, target)

        if isWalkable(cid, behindTarget) then
            doTeleportThing(cid, behindTarget)
            --addEvent(doTeleportThing, 100, cid, oldPos)
        else
            doTeleportThing(cid, getCreaturePosition(target))
            --addEvent(doTeleportThing, 100, cid, oldPos)
        end

        doCreatureSetLookDir(cid, getPlayerLookDir(target))
        doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -20, -100, CONST_ME_FIREATTACK)
        doRemoveCondition(cid, CONDITION_INVISIBLE)
        return true
    end

    addEvent(checkHasTarget, 100, cid, count - 1, getCreaturePosition(cid))
end

function onCastSpell(cid, var)
    local pPos = getCreaturePosition(cid)
    doSendMagicEffect(pPos, CONST_ME_POFF)
    doAddCondition(cid, condition)
    addEvent(checkHasTarget, 50, cid, 50, pPos)
    return true
end
 
Last edited:
Solution
no
the isWalkable function was faulty and so was getPlayerLookDir it returns numbers not NORTH EAST etc
also in several parts it was checking if cid is a player for no reason.
With the player checks, if a monster casted the spell nothing would happen, so why even add the spell to a monster?
 
Back
Top