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

Solved getTopCreature Issue

botter1234

Member
Joined
Jun 20, 2008
Messages
103
Reaction score
7
Okay I'm having a problem with getTopCreature in events, if players are stacked it takes one of them.. I need a way to prevent players from stacking in event areas or a workaround for it to detect all of them

Sorry for the double post I poorly titled the last and couldn't figure out how to edit the title
 
Last edited:
There are several large areas which if I can find a function that will allow me to set players so that they can't walk on each other in event areas I can set an action I'd to the tiles but preferably would like to be able to get all players on one tile
 
Made a quick example for you to parse on one tile through all stackpositions, however havn't tested it.
Lua:
local pos = {x = x, y = y, z = z}
local players = {}
local stack = 1
local pos.stackpos = stack
local topPlayer = {x = pos.x, y = pos.y, z = pos.z, stackpos = STACKPOS_TOP_CREATURE}
while isPlayer(getThingFromPos(pos).uid) then
	if getThingFromPos(pos).uid == getThingFromPos(topPlayer).uid then
		table.insert(players, getThingFromPos(pos).uid)
		break
	end
	stack = stack + 1
	table.insert(players, getThingFromPos(pos).uid)
else
	break
end

quick example:
Lua:
local newPos = {x = 5, y = 6, z = 1}
for i = 1, #players do
	doTeleportThing(players[i], newPos, false)
end

would re locate all the players on that certain tile we parsed before to another tile.




kind regards, Evil Hero.
 
for players you should use getPlayersOnline().
Is more efficient in most cases and gets all players even if they are stacked in a single tile. Just check if they are in the area.
 
Made a quick example for you to parse on one tile through all stackpositions, however havn't tested it.
Lua:
local pos = {x = x, y = y, z = z}
local players = {}
local stack = 1
local pos.stackpos = stack
local topPlayer = {x = pos.x, y = pos.y, z = pos.z, stackpos = STACKPOS_TOP_CREATURE}
while isPlayer(getThingFromPos(pos).uid) then
	if getThingFromPos(pos).uid == getThingFromPos(topPlayer).uid then
		table.insert(players, getThingFromPos(pos).uid)
		break
	end
	stack = stack + 1
	table.insert(players, getThingFromPos(pos).uid)
else
	break
end

quick example:
Lua:
local newPos = {x = 5, y = 6, z = 1}
for i = 1, #players do
	doTeleportThing(players[i], newPos, false)
end

would re locate all the players on that certain tile we parsed before to another tile.




kind regards, Evil Hero.
@Evil Hero
Ughm this isn't exactly what I'm looking for but I may be able to evolve from it.

@Summ
You're right Summ but as I said these players are in an event, aka only the players participating in the event aka in the area I am trying to retrieve them from.
I may just have to do this though, give all the players a storage value who have entered the event and then use the getPlayersOnline to check which ones have that value...
The issue with this is I've created a custom event that works in stages based on level so they are in a spot that looks exactly the same but each for there level and with monsters of their level, so I feel that it would add a high amount of stress to the server to check all of that at once if they just so happen to win around the same time?

What do you think?
 
Lua:
local function getPlayers(from, to)
	local t = {}
	for x = from.x, to.x do
		for y = from.y, to.y do
			local pos = {x = x, y = y, z = from.z}
			local creatures = getTileInfo(pos).creatures
			if creatures ~= 0 then
				pos.stackpos = 1
				local c = getThingfromPos(pos)
				while c.uid ~= 0 do
					if c.itemid == 1 and c.type == 1 then
						table.insert(t, c.uid)
						if #t == creatures then
							break
						end
					end
					pos.stackpos = pos.stackpos + 1
					c = getThingfromPos(pos)
				end
			end
		end
	end
	return t
end

example for usage
Lua:
	local t = getPlayers(area1, area2)
	local pos = {x=1, y=1, z=1}
	if #t > 10 then -- returns the amount of players
		for i = 1, #t do -- looping all the players in area
			doTeleportThing(t[i], pos) -- teleport them to a place
		end
	else
		-- do something
	end
 
Lua:
local function getPlayers(from, to)
	local t = {}
	for x = from.x, to.x do
		for y = from.y, to.y do
			local pos = {x = x, y = y, z = from.z}
			local creatures = getTileInfo(pos).creatures
			if creatures ~= 0 then
				pos.stackpos = 1
				local c = getThingfromPos(pos)
				while c.uid ~= 0 do
					if c.itemid == 1 and c.type == 1 then
						table.insert(t, c.uid)
						if #t == creatures then
							break
						end
					end
					pos.stackpos = pos.stackpos + 1
					c = getThingfromPos(pos)
				end
			end
		end
	end
	return t
end

example for usage
Lua:
	local t = getPlayers(area1, area2)
	local pos = {x=1, y=1, z=1}
	if #t > 10 then -- returns the amount of players
		for i = 1, #t do -- looping all the players in area
			doTeleportThing(t[i], pos) -- teleport them to a place
		end
	else
		-- do something
	end

Yeah this is great, deffinately the best way to do it but, my tfs does not support
Lua:
local creatures = getTileInfo(pos).creatures

- - - Updated - - -

Okay I played around a bit, and managed to come up with this =d
Lua:
       local players = {}
       for x = from.x, to.x do
		for y = from.y, to.y do
			for z = from.z, to.z do
				if getTopCreature({x = x, y = y, z = z}).uid ~= 0 then
					for stackpos = 0, 255 do
						if(isPlayer(getThingFromPos({x = x, y = y, z = z, stackpos = stackpos}).uid)) then
							if not(isInArray(players, getThingFromPos({x = x, y = y, z = z, stackpos = stackpos}).uid)) then
								table.insert(players, getThingFromPos({x = x, y = y, z = z, stackpos = stackpos}).uid)
							end							
						end
					end
				end
			end
		end
	end

Tested and works, so if anyone needs anything like this now here it is
obviously
Lua:
for stackpos = 0, 255 do
is not necessary to be from 0 to 255, unless you honestly think that you could have 255 players stacked on top of eachother
 
Last edited:
i've used this on a movement script, then it's no-logout tiles with actionid. players couldn't stack in same tile
Code:
function getBottomPlayer(pos)
    for i = 1, getTileInfo(pos).things do
        pos.stackpos = getTileInfo(pos).things-i
        local cid = getThingFromPos(pos).uid
        if isPlayer(cid) then
            return cid
        end
    end
    return 0
end

function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)


    if not isPlayer(cid) then
        return doTeleportThing(cid, fromPosition, false)
    end


    if isPlayer(getBottomPlayer(position)) and cid ~= getBottomPlayer(position) then
        doPlayerSendCancel(cid, 'This tile only allows 1 player in it.')
        return doTeleportThing(cid, fromPosition, false)
    end    
    return true
end
i don't remember if there's a onPlayerWalk creaturescript that would make this more efficient
 
i've used this on a movement script, then it's no-logout tiles with actionid. players couldn't stack in same tile
Code:
function getBottomPlayer(pos)
    for i = 1, getTileInfo(pos).things do
        pos.stackpos = getTileInfo(pos).things-i
        local cid = getThingFromPos(pos).uid
        if isPlayer(cid) then
            return cid
        end
    end
    return 0
end

function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)


    if not isPlayer(cid) then
        return doTeleportThing(cid, fromPosition, false)
    end


    if isPlayer(getBottomPlayer(position)) and cid ~= getBottomPlayer(position) then
        doPlayerSendCancel(cid, 'This tile only allows 1 player in it.')
        return doTeleportThing(cid, fromPosition, false)
    end    
    return true
end
i don't remember if there's a onPlayerWalk creaturescript that would make this more efficient

This is actually great, because even if there isn't there is globalevent on startup, and also I can have the event create the action ids on the tiles, so this is perfect =), I already created a script for checking stacked players as you see, but this script will deffinately come in handy, thank you
 
Back
Top