• 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 [TFS 1.3] Help with script logic

E

Evil Puncker

Guest
Hello, I'm breaking my head to get this to work but no success, currently I have tried the following:

Lua:
    local tile2 = Tile(toPosition)
    if tile2 and not tile2:hasFlag(TILESTATE_HOUSE) and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end

What I need is, the script is a OnMoveItem event that needs to do the following:
  • if the moved item have the getAttribute("wrapid") it will only be possible to move to backpack or the character house floor
  • if you try to move it out of the house it should return 'not possible'

but right now my script prevents it to move anywhere, thanks in advance
 
Solution
Lua:
if fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION then
    if not Tile(toPosition):getHouse() and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end
end
Wanna post the whole thing?
What does each check return?

Specifically:
Lua:
    local tile2 = Tile(toPosition)
    if tile2 and item:getAttribute("wrapid") then
        print(tile2:hasFlag(TILESTATE_HOUSE))
        if not tile2:hasFlag(TILESTATE_HOUSE) then
            self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
            return false
        end
    end
    return true
 
Last edited:
Lua:
function Player:isContainerOwner(pos) -- Check if pos is with player (pos is in inventory or backpacks)
  if pos.x ~= CONTAINER_POSITION then return false end
  if pos.y >= CONST_SLOT_FIRST and pos.y <= CONST_SLOT_LAST then return true end
  if bit.band(pos.y, BIT_CONTAINER) ~= 64 then return false end
  local container = self:getContainerById(bit.band(pos.y, BIT_CONTAINER_ID))
  return container and container:getTopParent() == self or false
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)

   local tile2 = Tile(toPosition)
    if tile2 and item:getAttribute("wrapid") then
        local movingToPlayer = not self:isContainerOwner(fromPosition) and self:isContainerOwner(toPosition)
        if movingToPlayer then return true end
        if not tile2:hasFlag(TILESTATE_HOUSE) then return false end
     end
  
    return true
end
 
Last edited:
Lua:
function Player:isContainerOwner(pos) -- Check if pos is with player (pos is in inventory or backpacks)
  if pos.x ~= CONTAINER_POSITION then return false end
  if pos.y >= CONST_SLOT_FIRST and pos.y <= CONST_SLOT_LAST then return true end
  if bit.band(pos.y, BIT_CONTAINER) ~= 64 then return false end
  local container = self:getContainerById(bit.band(pos.y, BIT_CONTAINER_ID))
  return container and container:getTopParent() == self or false
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)

   local tile2 = Tile(toPosition)
    if tile2 and item:getAttribute("wrapid") then
        local movingToPlayer = not self:isContainerOwner(fromPosition) and self:isContainerOwner(toPosition)
        if movingToPlayer then return true end
        if not tile2:hasFlag(TILESTATE_HOUSE) then return false end
    else
         return false
     end
  
    return true
end
can't move it anywhere either

I must be doing something really wrong, it is not possible that all your guys script are not working
 
I can move it to my backpack now, but can't move it in the house
dont make sense... if NOT is house tile, it return false. I dont know where is the error
Lua:
  if not tile2:hasFlag(TILESTATE_HOUSE) then return false end

edit: probably your server dont have this function "TILESTATE_HOUSE", check in your sources
 
Last edited:
okay guys, progress!!!

Lua:
    if not Tile(toPosition):getHouse() and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end

this work for the can't move item outside house, only move in the house, but I need still to find a way to be able to move item to/from backpack (CONTAINER_POSITION) too
 
Lua:
if fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION then
    if not Tile(toPosition):getHouse() and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end
end
 
Solution
Lua:
if fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION then
    if not Tile(toPosition):getHouse() and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end
end
thanks good sir, one more thing if you don't mind (just trying to make this as good as I can), how to make it check if the toPosition is a door? :)isDoor()) and not allow to move it there too?

2020-04-06 23_34_26-Tibia - Perflex.png (moving carpets into doors makes them unreachable)
 
You can find the doors array in global.lua
Its structure is
Lua:
doors = {
    [<closed door id>] = <open door id>,
So it should look like this
Lua:
if fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION then
    if not Tile(toPosition):getHouse() and item:getAttribute("wrapid") then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
       
        return false
    end
   
    for closedDoorId, openDoorId in pairs(doors) do
        if Tile(toPosition):getItemById(openDoorId) then
            self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
           
            return false
        end
    end
end
 
about the door, we have a :isDoor already for that
Not really (ItemType method) but close. There are 3 doors related methods in House userdata.
getDoors - returns list of doors that are a part of the house
getDoorCount - returns number of doors that are a part of the house
getDoorIdByPosition - returns door id by given position (or nil if no door is found), we should use that one

If you are using userdata constructors like Tile(), Player(), Creature() with same argument more than once then store it as a local variable, saves processing time.
Lua:
if fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION then
    local tile = Tile(toPosition)
    if tile then -- make sure there is a tile, we don't want unnecessary errors
        local house = tile:getHouse()
        if not house and item:getAttribute("wrapid") or house and house:getDoorIdByPosition(toPosition) then
            self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
            return false
        end
    end
end
 
Last edited:
Back
Top