This is code that decides where to relocate items from doors when player walks away:
A free and open-source MMORPG server emulator written in C++ - otland/forgottenserver
github.com
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