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

Action Moving Boat

Im using this system and it works great on 1.1 tfs
I was wondering if you could show script with only 1 boat that only goes 1 way
Again a great system
Thanks in advance for any help
 
Im using this system and it works great on 1.1 tfs
I was wondering if you could show script with only 1 boat that only goes 1 way
Again a great system
Thanks in advance for any help

Limos made a function for that. All you need to do is make a movement script that returns the function where you get off the boat.

Thanks for the comments.

There were some people who mentioned possible issues incase people want to use the boat script for places where players can only go with the boat (when they die/logout, the boat won't return).
So for people who want that, you can use a function like this and add it in a login, logout and preparedeath script.
Code:
function returnBoat(cid)

local config = {
storage = 42956,
removeBoat = {x = 61, y = 86, z = 7}, -- middle part of the boat
firstBoat = {
{pos = {x = 69, y = 122, z = 7}, id = 3592},
{pos = {x = 70, y = 122, z = 7}, id = 3594},
{pos = {x = 71, y = 122, z = 7}, id = 3596}
}
}

if(getPlayerStorageValue(cid, config.storage) == 1) then
local p = config.removeBoat
for x = p.x - 1, p.x + 1 do
for y = p.y - 1, p.y + 1 do
pos = {x = x, y = y, z = p.z}
for id = 3587, 3596 do
if(getTileItemById(pos, id).uid > 0) then
doRemoveItem(getTileItemById(pos, id).uid, 1)
end
end
end
end
for b = 1, #config.firstBoat do
if(getTileItemById(config.firstBoat[b].pos, config.firstBoat[b].id).uid < 1) then
boat = doCreateItem(config.firstBoat[b].id, 1, config.firstBoat[b].pos)
if(b == 2) then
doSetItemActionId(boat, 6901)
end
end
end
end
return true
end
You can add it in a lib file and then use the function like this.
Code:
returnBoat(cid)
Then set the storage to 1 and -1 when using the boat.
Code:
setPlayerStorageValue(cid, 42956, getPlayerStorageValue(cid, 42956) == -1 and 1 or -1)
Then in a login script (under the function)
Code:
if(getPlayerStorageValue(cid, 42956) == 1) then
doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
setPlayerStorageValue(cid, 42956, -1)
end

extremely simple movement script I made for my 0.4 project(shouldn't be too difficult to remake it to 1.x)

Code:
function onStepIn(cid, item, pos)
    if(getPlayerStorageValue(cid, 42956) == 1) then
        returnBoat(cid)
        doPlayerSetStorageValue(cid, 42956, -1)
    end
    return true
end
 
Does it work on TFS 1.2?
I'm trying to add this system but I can't get in the boat, seems like the borders beneath the boat are blocking the player to move up.
So I tried placing a normal grass tile under the center of the boat, and even tried to replace the border for just water id 4820, but when I did that and got on the boat, nothing happened, no error, nothing.

Some assistence would be highly appreciated.
Thank you.

EDIT: Feel stupid, the character is supposed to "onUse" the boat, and not walk over it. Got it working now...
 
Last edited:
Got this error:

Lua Script Error: [Action Interface]
data/actions/scripts/other/movingboat.lua:eek:nUse
LuaScriptInterface::luaAddEvent(). Argument #3 is unsafe
stack traceback:
[C]: in function 'doTravel'
data/actions/scripts/other/movingboat.lua:107: in function <data/actions
/scripts/other/movingboat.lua:100>
 
Maybe it would cut down the problems and need for storages, ect. If you set up an NPC that is on the boat like a fairymen. Then make 2 boats which have paths next to eachother but never on the same tiles. That way you won't have to worry about a boat not being there ect. Right now, only one person can go to the area. That seems kind of un-fair in a sense. As the player could use a anti-logout script and sit in there forever.
 
Hey, i im new here/ and i don't know if im breaking any rules, but im trying to put this system on my project and everything was doing great, like the beginning i used the boat and all, but when the boat arrives in the end of the route, idk the boat goes up on the ground instead of stopping at the endborders/ pleasee help me!!

 
sorry bro i got this error -- my ot tibia 8.1 i use <?xml version="1.0"?>

Lua Script Error: [Action Interface]
data/actions/scripts/movingboat.lua:eek:nUse

data/actions/scripts/movingboat.lua:103: attempt to call global 'getCreatureCondition' (a nil value)
 
I don't code with Lua very much but someone asked for a modification to get the boat to go down a waterfall (facing south) and i kind of hacked it together to make it work. This code is as is, so if you can't get it working i'm sorry.

Lua:
-- Moving Boat by Limos

local config = {
   endborders = {4644, 4646},
   speed = 300,
   ignorefirstborders = 1

}

local fight = createConditionObject(CONDITION_INFIGHT)
setConditionParam(fight, CONDITION_PARAM_TICKS, -1)

local function comparePos(poss, pos)
     return pos.x == poss.x and pos.y == poss.y
end

local n, s = 0, 0

local function getRightPos(poss, last)

     ps = {
         {x = poss.x, y = poss.y - 1, z = poss.z},
         {x = poss.x + 1, y = poss.y, z = poss.z},
         {x = poss.x, y = poss.y + 1, z = poss.z},
         {x = poss.x - 1, y = poss.y, z = poss.z}
     }

     for _, pos in pairs(ps) do
         if getTileItemById(pos, 4820).uid > 0 then
             if not comparePos(last, pos) then
                 p = pos
                 return p
             end
         else
             if getTileItemById(pos, 3571).uid > 0 then
                print("I see the waterfall")
                p = {x = poss.x, y = poss.y + 1, z = poss.z + 1}
                return p
             end

             for b = 1, #config.endborders do
                 if getTileItemById(pos, config.endborders[b]).uid > 0 and s > config.ignorefirstborders then
                     n = n + 1
                     p = pos
                     return p
                 end
             end
         end
     end
end

local function doTravel(cid, poss, last)
     getRightPos(poss, last)

     if p.z > poss.z then
        print(p.z .. " :: " .. poss.z)
     end

     travel = p.x > poss.x and "east" or (p.y < poss.y and "north" or (p.y > poss.y and "south" or (p.x < poss.x and "west" or "false")))

     if n > 1 then
        print("N = " .. n)
         p = poss
     end

     if travel == "false" then
        if getCreatureCondition(cid, CONDITION_INFIGHT) then
             doRemoveCondition(cid, CONDITION_INFIGHT)
         end
         n = 0
         s = 0

         print("Travel was false")
         return false
     else
        if p.z > poss.z then
            print("Travel :" .. travel)
        end
     end

     local des = {
         ["north"] = {cPos = {{x = p.x, y = p.y - 1, z = p.z}, p, {x = p.x, y = p.y + 1, z = p.z}}, dir = 0, boat = {3587, 3589, 3591}},
         ["east"] = {cPos = {{x = p.x + 1, y = p.y, z = p.z}, p, {x = p.x - 1, y = p.y, z = p.z}}, dir = 1, boat = {3596, 3594, 3592}},
         ["south"] = {cPos = {{x = p.x, y = p.y + 1, z = p.z}, p, {x = p.x, y = p.y - 1, z = p.z}}, dir = 2, boat = {3591, 3589, 3587}},
         ["west"] = {cPos = {{x = p.x - 1, y = p.y, z = p.z}, p, {x = p.x + 1, y = p.y, z = p.z}}, dir = 3, boat = {3592, 3594, 3596}}
     }

     local x = des[travel]

     if not x then
        print("X not set.")
     end

     if p.z > poss.z and (travel == "south") then
        print("Going down the waterfall!")

        --x = last
        for x = p.x - 2, p.x + 2 do
             for y = p.y - 2, p.y + 2 do
                 pos = {x = x, y = y, z = p.z - 1}
                 for id = 3587, 3596 do
                     if getTileItemById(pos, id).uid > 0 then
                         print("Removing item id " .. id .. " in :" .. pos.x .. "," .. pos.y .. "," .. pos.z)
                         doRemoveItem(getTileItemById(pos, id).uid, 1)
                     else
                        --print("Item " .. id .. " not found in :" .. pos.x .. "," .. pos.y .. "," .. pos.z)
                     end
                 end
             end
         end

        newLocation = {
            cPos = {
                {x = x.cPos[1].x, y = x.cPos[1].y + 2, z = x.cPos[1].z },
                {x = x.cPos[2].x, y = x.cPos[2].y + 2, z = x.cPos[2].z },
                {x = x.cPos[3].x, y = x.cPos[3].y + 2, z = x.cPos[3].z }
            },
            dir = 2,
            boat = {3591, 3589, 3587}
        }
        doTeleportThing(cid, newLocation.cPos[2], false)
        doCreatureSetLookDir(newLocation.dir)
        doCreateItem(newLocation.boat[1], 1, newLocation.cPos[1])
        its = doCreateItem(newLocation.boat[2], 1, newLocation.cPos[2])
        if n > 0 then
            doSetItemActionId(its, 6901)
        end
        doCreateItem(newLocation.boat[3], 1, newLocation.cPos[3])

        return addEvent(doTravel, config.speed, cid, p, poss)
     else
        print("Moving")
     end

     if x then
         for x = p.x - 2, p.x + 2 do
             for y = p.y - 2, p.y + 2 do
                 pos = {x = x, y = y, z = p.z}
                 for id = 3587, 3596 do
                     if getTileItemById(pos, id).uid > 0 then
                         doRemoveItem(getTileItemById(pos, id).uid, 1)
                     end
                 end
             end
         end
         for c = 1, #x.boat do
             its = doCreateItem(x.boat[c], 1, x.cPos[c])
             if n > 0 and c == 2 then
                 doSetItemActionId(its, 6901)
             end
         end
         doTeleportThing(cid, x.cPos[2], false)
         doCreatureSetLookDir(cid, x.dir)
         if n > 1 then
             if getCreatureCondition(cid, CONDITION_INFIGHT) then
                 doRemoveCondition(cid, CONDITION_INFIGHT)
             end
             n = 0
             s = 0
             return false
         end
         s = s + 1
     end
     return addEvent(doTravel, config.speed, cid, p, poss)
end

function onUse(cid, item, fromPosition, itemEx, toPosition)

     if getCreatureCondition(cid, CONDITION_INFIGHT) then
         return doPlayerSendCancel(cid, "You can't travel when you're in a fight.")
     end
     doTeleportThing(cid, toPosition)
     doAddCondition(cid, fight)
     doTravel(cid, getPlayerPosition(cid), getPlayerPosition(cid))
     return true
end
 
I get this error, udinh TFS 1.2

Lua Script Error: [Action Interface]
data/actions/scripts/other/movingboat.lua:eek:nUse
LuaScriptInterface::luaAddEvent(). Argument #3 is unsafe
stack traceback:
[C]: in function 'doTravel'
data/actions/scripts/other/movingboat.lua:174: in function <data/actions/scripts/other/movingboat.lua:167>

Have been trying to fix it without success.. Would be very thankfull for help with it.
 
For anybody having trouble 1.2+

Lua:
local config = {
    waterid = 4820,
    endborders = {4644, 4646, 4647},
    speed = 300, -- ms per tile
    ignorefirstborders = 3
}

local fight = createConditionObject(CONDITION_INFIGHT)
setConditionParam(fight, CONDITION_PARAM_TICKS, -1)

local function comparePos(poss, pos)
     return pos.x == poss.x and pos.y == poss.y
end

local n, s = 0, 0
local function getRightPos(poss, last)
    ps = {
        {x = poss.x, y = poss.y - 1, z = poss.z},
        {x = poss.x + 1, y = poss.y, z = poss.z},
        {x = poss.x, y = poss.y + 1, z = poss.z},
        {x = poss.x - 1, y = poss.y, z = poss.z}
    }

    for _, pos in pairs(ps) do
        if Tile(pos):getItemById(config.waterid) ~= nil and Tile(pos):getItemById(config.waterid):getUniqueId() > 0 then
            if not comparePos(last, pos) then
                p = pos
                return p
            end
        else
            for b = 1,#config.endborders do
                if Tile(pos):getItemById(config.endborders[b]) ~= nil and Tile(pos):getItemById(config.endborders[b]):getUniqueId() > 0 and s > config.ignorefirstborders then
                    n = n + 1
                    p = pos
                    return p
                end
            end
        end
    end
end

local function doTravel(cid, poss, last)
     local player = Player(cid)
    getRightPos(poss, last)
    travel = p.x > poss.x and "east" or (p.y < poss.y and "north" or (p.y > poss.y and "south" or (p.x < poss.x and "west" or "false")))
 
    if n > 1 then
        p = poss
    end
 
    if travel == "false" then
        if getCreatureCondition(cid, CONDITION_INFIGHT) then
            doRemoveCondition(cid, CONDITION_INFIGHT)
        end
        n = 0
        s = 0
        return false
    end

    local des = {
        ["north"] = {cPos = {{x = p.x, y = p.y - 1, z = p.z}, p, {x = p.x, y = p.y + 1, z = p.z}}, dir = 0, boat = {3587, 3589, 3591}},
        ["east"] = {cPos = {{x = p.x + 1, y = p.y, z = p.z}, p, {x = p.x - 1, y = p.y, z = p.z}}, dir = 1, boat = {3596, 3594, 3592}},
        ["south"] = {cPos = {{x = p.x, y = p.y + 1, z = p.z}, p, {x = p.x, y = p.y - 1, z = p.z}}, dir = 2, boat = {3591, 3589, 3587}},
        ["west"] = {cPos = {{x = p.x - 1, y = p.y, z = p.z}, p, {x = p.x + 1, y = p.y, z = p.z}}, dir = 3, boat = {3592, 3594, 3596}}
    }

    local x = des[travel]
    if x then
        for x = p.x - 2, p.x + 2 do
            for y = p.y - 2, p.y + 2 do
                pos = {x = x, y = y, z = p.z}
                for id = 3587,3596 do
                    local item = Tile(pos):getItemById(id)
                    if item ~= nil then
                        if item:getUniqueId() > 0 then
                            item:remove()
                        end
                    end
                end
            end
        end
        for c = 1, #x.boat do
            its = Game.createItem(x.boat[c], 1, x.cPos[c])
            if n > 0 and c == 2 then
                its:setActionId(6901)
            end
        end
        player:teleportTo(x.cPos[2])
        player:setDirection(x.dir)
        if n > 1 then
            if getCreatureCondition(cid, CONDITION_INFIGHT) then
                doRemoveCondition(cid, CONDITION_INFIGHT)
            end
            n = 0
            s = 0
            return false
        end
        s = s + 1
    end
    return addEvent(doTravel, config.speed, cid, p, poss)
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local cid = player:getId()
    if getCreatureCondition(cid, CONDITION_INFIGHT) then
        return doPlayerSendCancel(cid, "You can't travel when you're in a fight.")
    end
    player:teleportTo(toPosition)
    doAddCondition(cid, fight)
    doTravel(cid, player:getPosition(), player:getPosition())
    return true
end
 
Back
Top