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

[Functions] indexToPos() and posToIndex() - use a number for a whole position!

Pedro B.

OpenTibia Official Dev
Joined
Aug 8, 2007
Messages
127
Reaction score
2
Location
Brazil
Hello guys!

Well, I almost never look at this forum, but since I was bored I decided to post here two simple functions. They are useful IMO, they are called indexToPos() and posToIndex(): they convert positions to numbers and numbers to positions! :eek:
yeye, I released it on OpenLua also, WHATEVER!

Hope you like it :p

Credits to Remere, since he found the right numbers to use here so they work fine with storage values.
Code:
if(bit == nil) then
	error("Your server does not have bit libraries.")
end
 
function posToIndex(pos)
	if(type(pos) ~= "table" or pos.x == nil or pos.y == nil or pos.z == nil) then
		error("[posToIndex]: Argument is not a valid position!")
		return LUA_ERROR
	end
 
	-- ((x & 0x3FFF) << 18 | (y & 0x3FFF) << 4 | (z & 0xF))
	local index = bit.bor( bit.lshift( bit.band(pos.x,16383), 18), bit.lshift( bit.band(pos.y, 16383), 4), bit.band(pos.z, 15) )
	return index
end
 
function indexToPos(index)
	if(type(index) ~= "number") then
		error("[indexToPos]: Argument is not a valid index!")
		return LUA_ERROR
	end
 
	-- pos.x = ((index) >> 18) & 0x3FFF; pos.y = ((index) >> 4) & 0x3FFF; pos.z = ((index) & 0xF);
	local x = bit.band(bit.rshift(index, 18), 16383)
	local y = bit.band(bit.rshift(index, 4), 16383)
	local z = bit.band(index, 15)
	return {x=x, y=y, z=z}
end

How to use them? Example:

Code:
setPlayerStorageValue(cid, 6000, posToIndex(getThingPos(cid)))
Code:
local pos = indexToPos(getPlayerStorageValue(cid, 6000))

Isn't that FON? :p

It's a great use for storage values.

Cya!

PS: Meh, a "Function" prefix or a "Functions" subforum should be added u.u
 
Last edited:
Pedro B @ OpenLua said:
You don't have to understand a shit of this, you just have to use it. Example:
PHP:
local pos = getThingPos(cid)
setPlayerStorageValue(cid, 6666, posToIndex(pos))
And in another place:
PHP:
local index = getPlayerStorageValue(cid, 6666)
doTeleportThing(cid, indexToPos(index))

There you go xD
 
Nice script!

Just after I did the teleports in the holy shrines the old way... One storagevalue for x, one for y and one for z...
 
Good job Pedro, but why it isnt working for me in this script:? :)
Code:
function onSay(cid, words, param)

local dir = getPlayerLookDir(cid)
local pos = getCreaturePosition(cid)

if dir == 1 then
	pos.x = pos.x + 1
elseif dir == 2 then
	pos.y = pos.y + 1
elseif dir == 3 then
	pos.x = pos.x - 1
elseif dir == 0 then
	pos.y = pos.y - 1
end

	if words == "!setpos" then
			setGlobalStorageValue(4001,posToIndex(getCreaturePosition(cid)))
			doPlayerSendTextMessage(cid,24,"New position x:"..pos.x..", 

y:"..pos.y..", z:"..pos.z)
	elseif words == "!createtp" then
			local toPos = indexToPos(getGlobalStorageValue(4001))
			doCreateTeleport(1387,toPos,pos)
	end
return FALSE
end
 
@up
try this one:
Code:
function onSay(cid, words, param)
	if words == "!setpos" then
		local pos = getCreaturePosition(cid)
		setGlobalStorageValue(4001,posToIndex(pos))
		doPlayerSendTextMessage(cid,24,"New position x:" .. pos.x .. ", y:" .. pos.y .. ", z:"..pos.z)
	elseif words == "!createtp" then
		local dir = getPlayerLookDir(cid)
		local pos = getCreaturePosition(cid)

		if dir == 1 then
			pos.x = pos.x + 1
		elseif dir == 2 then
			pos.y = pos.y + 1
		elseif dir == 3 then
			pos.x = pos.x - 1
		elseif dir == 0 then
			pos.y = pos.y - 1
		end
		local toPos = indexToPos(getGlobalStorageValue(4001))
		doCreateTeleport(1387,toPos,pos)
	end
	return FALSE
end

works fine for me.
 
It's useful when storing a position in a storage values, instead of having to set one for x, one for y and one for z, with this, you can store all the value in one storage.
 
Its a great and VERY usefull script!
Instead of storing a position in 3 different fields, it may be done in one!

Pedro, you rule, no doubts.
 
Its a great and VERY usefull script!
Instead of storing a position in 3 different fields, it may be done in one!

Pedro, you rule, no doubts.
Nah, I don't. All I did was to get the YATC's definitions of POS2INDEX and INDEX2POS and convert them to Lua functions :p
 
7 years and still useful. Update for TFS 1.x:
Code:
function Position:getIndex()
  return bit.bor(bit.lshift(bit.band(self.x, 16383), 18), bit.lshift(bit.band(self.y, 16383), 4), bit.band(self.z, 15))
end

function getIndexPos(index)
  return Position(bit.band(bit.rshift(index, 18), 16383), bit.band(bit.rshift(index, 4), 16383), bit.band(index, 15))
end
Can someone test if this returns the correct position from an indexed position on a RL map?
 
Back
Top