• 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

PHP:
[Error - Action Interface]
data/actions/scripts/other/movingboat.lua:onUse
Description:
(luaDoRemoveItem) Item not found
Picture :
153acu0.jpg

bug? plase help : ) nice script
Which server do you use and how did you added it in the map?
Which script do you use? The one on the first post or the version with 2 boats?
Why is there a second boat there? If you used the version with 2 boats, did you added the positions correct?
 
Tested with TFS 0.3.6 and TFS 0.2.14
Should work on almost every server.

I was making this script for someone, but since I couldn't find a script on otland that works the same way I decided to release it here and maybe it will be useful to other people aswell.

ieqwn7evTflfc.gif


How does it work:
Add actionid 6901 to the middle part of the boat.
Where the boat should go, add water with itemid 4820.
The borders the boat will go on when it goes on land, should be the ones in the config endborders.
The border next to it should have the same itemid (so atleast 2 straight borders next to eachother), because this is what makes the boat turn.
ZZwopm.png



actions.xml
TFS 0.3/0.4
Code:
<action actionid="6901" event="script" value="other/movingboat.lua"/>

TFS 0.2/1.0
Code:
<action actionid="6901" script="other/movingboat.lua"/>

movingboat.lua
Code:
-- Moving Boat by Limos

local config = {
   endborders = {4644, 4646},
   speed = 300,
   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(getTileItemById(pos, 4820).uid > 0) then
             if(not comparePos(last, pos)) then
                 p = pos
                 return p
             end
         else
             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 and n
                 end
             end
         end
     end
end

local function doTravel(cid, poss, last)

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

Movement script (to prevent people stepping out of the boat on the walkable water when the boat stands still)

movements.xml
TFS 0.3/0.4
Code:
<movevent type="StepIn" itemid="4820" event="script" value="water.lua"/>
TFS 0.2/1.0
Code:
<movevent event="StepIn" itemid="4820" script="water.lua"/>

water.lua
Code:
local boatids = {3589, 3594}

function onStepIn(cid, item, position, fromPosition)

   for _, id in pairs(boatids) do
     if(getTileItemById(fromPosition, id).uid > 0) then
       return doTeleportThing(cid, fromPosition)
     end
   end
   return true
end


If you use TFS 0.3/0.4, add this in 050-function.lua (if it's not already there).
Code:
function doSetItemActionId(uid, actionid)
   return doItemSetAttribute(uid, "aid", actionid)
end



Questions or bugs? Let me know.
very good i liked it but i need you to add something, i need this boat to back at same place after period of time like every 10 mints back again to begin
 
It works the same as the picture on the first post, but then with 2 boats, 1 at each side, so you have to place 2 boats in the map and add the positions in the script.
 
It works the same as the picture on the first post, but then with 2 boats, 1 at each side, so you have to place 2 boats in the map and add the positions in the script.

Im using 2 boats and getting this: (TFS 1.0)

Lua Script Error - [Action Interface]
[08/01/2015 14:34:23] data/actions/scripts/other/movingboat.lua:eek:nUse
[08/01/2015 14:34:24] Description:
[08/01/2015 14:34:25] data/actions/scripts/other/movingboat.lua:61: attempt to index global 'config' (a nil value)
[08/01/2015 14:34:25] stack traceback:
[C] in function '__index'
[08/01/2015 14:34:26] data/actions/scripts/other/movingboat.lua:61: in function 'getRightPos'
[08/01/2015 14:34:26] data/actions/scripts/other/movingboat.lua:73: in function 'doTravel'
[08/01/2015 14:34:26] data/actions/scripts/other/movingboat.lua:138: in function data/actions/scripts/other/movingboat.lua:125 >
 
Did you copy the whole script?

That's the movingboat script with 2 boats (the script with 1 boat worked perfectly):

Code:
local boatpositions = {
     boat1 = {
         {id = 3592, pos = {x = 31871, y = 32283, z = 6}},
         {id = 3594, pos = {x = 31872, y = 32283, z = 6}},
         {id = 3596, pos = {x = 31873, y = 32283, z = 6}}
     },
     boat2 = {
         {id = 3587, pos = {x = 31892, y = 32278, z = 6}},
         {id = 3589, pos = {x = 31892, y = 32279, z = 6}},
         {id = 3591, pos = {x = 31892, y = 32280, z = 6}}
     }
}

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

local function doRelocateBoat(boat, remove)
     if remove then
         for x = 1, #boatpositions.boat1 do
             if boat == 1 then
                 doRemoveItem(getTileItemById(boatpositions.boat2[x].pos, boatpositions.boat2[x].id).uid, 1)
             else
                 doRemoveItem(getTileItemById(boatpositions.boat1[x].pos, boatpositions.boat1[x].id).uid, 1)
             end
         end
     else
         for c = 1, #boatpositions.boat1 do
             if boat == 1 then
                 b = doCreateItem(boatpositions.boat1[c].id, 1, boatpositions.boat1[c].pos)
             else
                 b = doCreateItem(boatpositions.boat2[c].id, 1, boatpositions.boat2[c].pos)
             end
             if c == 2 then
                 doSetItemActionId(b, 6901)
             end
         end
     end
     return true
end

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
             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 and n
                 end
             end
         end
     end
end

local function doTravel(cid, poss, last, boat)
     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
         doRelocateBoat(boat, false)
         doRemoveCondition(cid, CONDITION_INFIGHT)
         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
                     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
             doRelocateBoat(boat, false)
             doRemoveCondition(cid, CONDITION_INFIGHT)
             n = 0
             s = 0
             return false
         end
         s = s + 1
     end
     return addEvent(doTravel, config.speed, cid, p, poss, boat)
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

     local boat = 1
     if comparePos(toPosition, boatpositions.boat2[2].pos) then
         boat = 2
     end
     doRelocateBoat(boat, true)
     doTeleportThing(cid, toPosition)
     doAddCondition(cid, fight)
     doTravel(cid, getPlayerPosition(cid), getPlayerPosition(cid), boat)
     return true
end
 
@Limos can someone tell me how i do like, if you use the boat it brings u to the other island, and after this it should automatically go back to the first spot.
So its only possible to go from A to B , but not from B to A

edit:

i used the script with 2 boats, but it doesnt create the boat again.. i mean
in map theres 2 boats and i did put the position and ids aswell in script, but
when i use 1 boat, it deleteds the other one, theres only 1 boat always..

also i got this error

[Error - Action Interface]
In a timer event called from:
data/actions/scripts/other/movingboat.lua:eek:nUse
Description:
(luaDoCreateItem) Tile not found
 
Last edited:
That's the movingboat script with 2 boats (the script with 1 boat worked perfectly):

Code:
local boatpositions = {
     boat1 = {
         {id = 3592, pos = {x = 31871, y = 32283, z = 6}},
         {id = 3594, pos = {x = 31872, y = 32283, z = 6}},
         {id = 3596, pos = {x = 31873, y = 32283, z = 6}}
     },
     boat2 = {
         {id = 3587, pos = {x = 31892, y = 32278, z = 6}},
         {id = 3589, pos = {x = 31892, y = 32279, z = 6}},
         {id = 3591, pos = {x = 31892, y = 32280, z = 6}}
     }
}

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

local function doRelocateBoat(boat, remove)
     if remove then
         for x = 1, #boatpositions.boat1 do
             if boat == 1 then
                 doRemoveItem(getTileItemById(boatpositions.boat2[x].pos, boatpositions.boat2[x].id).uid, 1)
             else
                 doRemoveItem(getTileItemById(boatpositions.boat1[x].pos, boatpositions.boat1[x].id).uid, 1)
             end
         end
     else
         for c = 1, #boatpositions.boat1 do
             if boat == 1 then
                 b = doCreateItem(boatpositions.boat1[c].id, 1, boatpositions.boat1[c].pos)
             else
                 b = doCreateItem(boatpositions.boat2[c].id, 1, boatpositions.boat2[c].pos)
             end
             if c == 2 then
                 doSetItemActionId(b, 6901)
             end
         end
     end
     return true
end

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

local n, s = 0, 0
-- needed to remove part of the script else the post is to long
The top is missing with local config, you probable forgot to copy that part.
Thanks for the comments.

An other version of the moving boat, requested by andree.
Here it works with 2 boats, 1 at each side. Using 1 boat will remove the other and recreate the first one when the boat stops.
This way there will always be 1 boat at each side and people can keep using them from both sides.
Code:
local config = {
     endborders = {4644, 4646},
     speed = 300,
     ignorefirstborders = 3
}

local boatpositions = {
     boat1 = {
         {id = 3592, pos = {x = 69, y = 122, z = 7}},
         {id = 3594, pos = {x = 70, y = 122, z = 7}},
         {id = 3596, pos = {x = 71, y = 122, z = 7}}
     },
     boat2 = {
         {id = 3592, pos = {x = 60, y = 86, z = 7}},
         {id = 3594, pos = {x = 61, y = 86, z = 7}},
         {id = 3596, pos = {x = 62, y = 86, z = 7}}
     }
}

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

local function doRelocateBoat(boat, remove)
     if remove then
         for x = 1, #boatpositions.boat1 do
             if boat == 1 then
                 doRemoveItem(getTileItemById(boatpositions.boat2[x].pos, boatpositions.boat2[x].id).uid, 1)
             else
                 doRemoveItem(getTileItemById(boatpositions.boat1[x].pos, boatpositions.boat1[x].id).uid, 1)
             end
         end
     else
         for c = 1, #boatpositions.boat1 do
             if boat == 1 then
                 b = doCreateItem(boatpositions.boat1[c].id, 1, boatpositions.boat1[c].pos)
             else
                 b = doCreateItem(boatpositions.boat2[c].id, 1, boatpositions.boat2[c].pos)
             end
             if c == 2 then
                 doSetItemActionId(b, 6901)
             end
         end
     end
     return true
end

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
             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 and n
                 end
             end
         end
     end
end

local function doTravel(cid, poss, last, boat)
     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
         doRelocateBoat(boat, false)
         doRemoveCondition(cid, CONDITION_INFIGHT)
         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
                     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
             doRelocateBoat(boat, false)
             doRemoveCondition(cid, CONDITION_INFIGHT)
             n = 0
             s = 0
             return false
         end
         s = s + 1
     end
     return addEvent(doTravel, config.speed, cid, p, poss, boat)
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

     local boat = 1
     if comparePos(toPosition, boatpositions.boat2[2].pos) then
         boat = 2
     end
     doRelocateBoat(boat, true)
     doTeleportThing(cid, toPosition)
     doAddCondition(cid, fight)
     doTravel(cid, getPlayerPosition(cid), getPlayerPosition(cid), boat)
     return true
end
@Limos can someone tell me how i do like, if you use the boat it brings u to the other island, and after this it should automatically go back to the first spot.
So its only possible to go from A to B , but not from B to A
edit:
i used the script with 2 boats, but it doesnt create the boat again.. i mean
in map theres 2 boats and i did put the position and ids aswell in script, but
when i use 1 boat, it deleteds the other one, theres only 1 boat always..
also i got this error
[Error - Action Interface]
In a timer event called from:
data/actions/scripts/other/movingboat.lua:eek:nUse
Description:
(luaDoCreateItem) Tile not found
You can delete the boat when it creates the boat again at the other side or do it with a movements script, that it deletes the boat when the player steps out of it.
If it can't create the boat, the position is probable wrong.
 
can someone tell me what lines i have to remove, so people are able to use it even with battle sign?
 
Under function onUse
Code:
if getCreatureCondition(cid, CONDITION_INFIGHT) then
      return doPlayerSendCancel(cid, "You can't travel when you're in a fight.")
end
 
@Limos Is it possible to make it so an npc is riding the boat?
Was thinking of making a water town for a new ot I'm working on where some npcs will be constantly drifting on boats.
Also is it possible to make them go down & up waterfalls then continue drifting?
 
You can do it with a globalevent instead of an action script, add the npc in the boat and add the functions to the globalevent.
For the waterfall, same as it checks for itemid 4820 and the border ids, you can let it check for a different id and change the position so it continues be 1 floor higher/lower (z -1/z + 1).
 
Back
Top