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

TFS 1.X+ [1.4.2] Experience Door - Distro BUG!

OTcreator

Active Member
Joined
Feb 14, 2022
Messages
425
Solutions
1
Reaction score
44
Hi,
I found a bug in the 1.4.2 release.
If a player lays open the experience door and stands on the open door, throws an item underneath and exits to the right side, the door closes automatically and the item underneath is removed.
This happens only to the player (on the GM it works normally) and only when exiting the door to the right.
 
Solution
This is code that decides where to relocate items from doors when player walks away:

1. It tries to move items to x+1 position and then to y+1 position. For unknown (bug?) reason it check if its possible (queryAdd) to relocate Player (creature), not first moveable item from tile:
Lua:
Tile(newPosition):queryAdd(creature)
If player for some reason (PZ-lock, there is already monster etc.) cannot walk into tested items relocation position, it will remove items, not relocate them.
This happens only to the player sounds like that problem. GM can walk anywhere, so it always return true and is able...
This is code that decides where to relocate items from doors when player walks away:

1. It tries to move items to x+1 position and then to y+1 position. For unknown (bug?) reason it check if its possible (queryAdd) to relocate Player (creature), not first moveable item from tile:
Lua:
Tile(newPosition):queryAdd(creature)
If player for some reason (PZ-lock, there is already monster etc.) cannot walk into tested items relocation position, it will remove items, not relocate them.
This happens only to the player sounds like that problem. GM can walk anywhere, so it always return true and is able to relocate items.

2. I'm also not sure, if it should use position or fromPosition as reference position in:
Lua:
local newPosition = {x = position.x + 1, y = position.y, z = position.z}
It should use door position, not position to which player walks/walked. Doors position is probably in fromPosition, maybe it should be get from item ex. item:getPosition()

EDIT:
@OTcreator
Version with these bugs fixed - NOT TESTED:
Lua:
-- based on doRelocate
function Tile.getTopMovableItem(self)
	for i = self:getThingCount() - 1, 0, -1 do
		local thing = self:getThing(i)
		if thing and thing:isItem() and ItemType(thing:getId()):isMovable() then
			return thing
		end
	end

	return nil
end

function onStepOut(creature, item, position, fromPosition)
	local tile = Tile(position)
	if tile:getCreatureCount() > 0 then
		return true
	end

	-- fix problem 2: get right position
	local doorPosition = item:getPosition()
	-- fix problem 1: queryAdd top movable item, not player
	local topMovableItem = Tile(doorPosition):getTopMovableItem()
	if topMovableItem then
		local newPosition = {x = doorPosition.x + 1, y = doorPosition.y, z = doorPosition.z}
		local query = Tile(newPosition):queryAdd(topMovableItem)
		if query ~= RETURNVALUE_NOERROR or query == RETURNVALUE_NOTENOUGHROOM then
			newPosition.x = newPosition.x - 1
			newPosition.y = newPosition.y + 1
			query = Tile(newPosition):queryAdd(topMovableItem)
		end

		if query == RETURNVALUE_NOERROR or query ~= RETURNVALUE_NOTENOUGHROOM then
			doRelocate(doorPosition, newPosition)
		end
	end

	local i, tileItem, tileCount = 1, true, tile:getThingCount()
	while tileItem and i < tileCount do
		tileItem = tile:getThing(i)
		if tileItem and tileItem:getUniqueId() ~= item.uid and tileItem:getType():isMovable() then
			tileItem:remove()
		else
			i = i + 1
		end
	end

	item:transform(item.itemid - 1)
	return true
end
 
Last edited:
Solution
This is code that decides where to relocate items from doors when player walks away:

1. It tries to move items to x+1 position and then to y+1 position. For unknown (bug?) reason it check if its possible (queryAdd) to relocate Player (creature), not first moveable item from tile:
Lua:
Tile(newPosition):queryAdd(creature)
If player for some reason (PZ-lock, there is already monster etc.) cannot walk into tested items relocation position, it will remove items, not relocate them.
This happens only to the player sounds like that problem. GM can walk anywhere, so it always return true and is able to relocate items.

2. I'm also not sure, if it should use position or fromPosition as reference position in:
Lua:
local newPosition = {x = position.x + 1, y = position.y, z = position.z}
It should use door position, not position to which player walks/walked. Doors position is probably in fromPosition, maybe it should be get from item ex. item:getPosition()

EDIT:
@OTcreator
Version with these bugs fixed - NOT TESTED:
Lua:
-- based on doRelocate
function Tile.getTopMovableItem(self)
    for i = self:getThingCount() - 1, 0, -1 do
        local thing = self:getThing(i)
        if thing and thing:isItem() and ItemType(thing:getId()):isMovable() then
            return thing
        end
    end

    return nil
end

function onStepOut(creature, item, position, fromPosition)
    local tile = Tile(position)
    if tile:getCreatureCount() > 0 then
        return true
    end

    -- fix problem 2: get right position
    local doorPosition = item:getPosition()
    -- fix problem 1: queryAdd top movable item, not player
    local topMovableItem = Tile(doorPosition):getTopMovableItem()
    if topMovableItem then
        local newPosition = {x = doorPosition.x + 1, y = doorPosition.y, z = doorPosition.z}
        local query = Tile(newPosition):queryAdd(topMovableItem)
        if query ~= RETURNVALUE_NOERROR or query == RETURNVALUE_NOTENOUGHROOM then
            newPosition.x = newPosition.x - 1
            newPosition.y = newPosition.y + 1
            query = Tile(newPosition):queryAdd(topMovableItem)
        end

        if query == RETURNVALUE_NOERROR or query ~= RETURNVALUE_NOTENOUGHROOM then
            doRelocate(doorPosition, newPosition)
        end
    end

    local i, tileItem, tileCount = 1, true, tile:getThingCount()
    while tileItem and i < tileCount do
        tileItem = tile:getThing(i)
        if tileItem and tileItem:getUniqueId() ~= item.uid and tileItem:getType():isMovable() then
            tileItem:remove()
        else
            i = i + 1
        end
    end

    item:transform(item.itemid - 1)
    return true
end

Great job! All wroking fine. Thank you.
 
Back
Top