• 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 Last Man Standing Event bugged teleport

Danger II

tibiara.com
Joined
Nov 21, 2012
Messages
1,773
Solutions
13
Reaction score
707
Location
Germany
Here are the coordinates for the teleport:
Code:
from = {x = XX, y = YY, z = ZZ}, -- Top left cornor of the playground (random players teleportation)
to = {x = XX, y = YY, z = ZZ}, -- Bottom right cornor of the playground (random players teleportation)

Okay now the problem is players will be teleported also into walls, trees, etc.

I have added getTileInfo(pos).blocksolid to my source but not really sure how to fix this part:
Code:
if #players >= t.minPlayers then
for i = 1, #players do
local p = {x = math.random(t.from.x, t.to.x), y = math.random(t.from.y, t.to.y), z = math.random(t.from.z, t.to.z)}
doTeleportThing(players[i], p)
doSendMagicEffect(p, CONST_ME_TELEPORT)
doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The battle begins. Survive for glory!")
end
else
for i = 1, #players do
doTeleportThing(players[i], {x=876, y=1025, z=7})
  local mplayer = getPlayerMasterPos(players[i])
doTeleportThing(players[i], mplayer)
doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The event didn't start because there isn't enough players in area!")
end
end

Anyone knows how to fix this part?

It doesnt check for blocksolids here:
local p = {x = math.random(t.from.x, t.to.x), y = math.random(t.from.y, t.to.y), z = math.random(t.from.z, t.to.z)}

Is there a way to let the script check it?
 
Try adding an if that will check if there is a blocksolid, after the script sets the teleport destination. If it is, you have to make the script set new destination for the teleport. If you can't do it yourself, i will try to help you when i'm home.
 
while getTile(pos):hasProperty(CONST_PROP_IMMOVABLEBLOCKSOLID) do
like whitevo post
make new random pos
if you know there might be possible that there is not enough room, make this while loop only execute ~20 times and then close your laststand teleporting event​
end
 
Thanks for the replies.

I think calculating a new position for everyone is not working well, I prefer havin a function which let the calculator pick math.rand from non-blocksolids only.
I've tested the loop above, the problem with the loop is that when it comes to a teleport only a hand of players will be teleported (because their teleport worked well) and the others will be calculated again.
Which means the players at the arena can already prepare for the teleporting players, that aint that smart.

Is there a way to let the math.random function check only non-blocksolid positions?
 
Thanks for the replies.

I think calculating a new position for everyone is not working well, I prefer havin a function which let the calculator pick math.rand from non-blocksolids only.
I've tested the loop above, the problem with the loop is that when it comes to a teleport only a hand of players will be teleported (because their teleport worked well) and the others will be calculated again.
Which means the players at the arena can already prepare for the teleporting players, that aint that smart.

Is there a way to let the math.random function check only non-blocksolid positions?
well too bad i don't know how last stand event suppose to work.
Does player gets teleported to random pos when they die or when they first enter?
If for entering then you can simply premake the positions for all players and teleport them all at once when done calculating.
 
well too bad i don't know how last stand event suppose to work.
Does player gets teleported to random pos when they die or when they first enter?
If for entering then you can simply premake the positions for all players and teleport them all at once when done calculating.

Thats exactly what I dont know, how to let the script calculate the teleport positions and let the players teleport after..
At this moment it is like this:
Player 1 - check - non-blocksolid pos - teleport
Player 2 - check - non-blocksolid pos - teleport
Player 3 - check - blocksolid pos - nothing (checking next time script will be runned by globalevents)
Player 4 - check - non-blocksolid pos - teleport

But I would like to have it like this:
Check positions for non-blocksolid, all positions setted, teleport all players to different positions

Any idea?
 
yes, but show me full script with the while loop you used.

Code:
local t = {
tmp = {
-- Waiting room destinations
{x = X, y = Y, z = Z}, -- North west corner of waiting room where players must stand in order to join the event
{x = X, y = Y, z = Z} -- South east corner of waiting room
},
arena = {
-- Arena destinations
{x = X, y = Y, z = Z}, -- North west Corner of Arena
{x = X, y = Y, z = Z}, -- South East corner of Arena
{x = X, y = Y, z = Z} -- Center of Arena
},

from = {x = X, y = Y, z = 7}, -- Top left cornor of the playground (random players teleportation)
to = {x = X, y = Y, z = 7}, -- Bottom right cornor of the playground (random players teleportation)

minPlayers = 1, -- min players required to start the battle
noPlayers = 1, -- Leave it as it is
prize = {2160} -- Reward that player recives
}
local kick = 0
local teleportPlayer = 0

function onThink()
local arenaPlayers = {}

for x = t.arena[1].x, t.arena[2].x do
for y = t.arena[1].y, t.arena[2].y do
for z = t.arena[1].z, t.arena[2].z do
local pos = {x = x, y = y, z = z}
local n = getTileInfo(pos).creatures
if n ~= 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(arenaPlayers, c.uid)
if #arenaPlayers == n then
break
end
end
pos.stackpos = pos.stackpos + 1
c = getThingfromPos(pos)
end
end
end
end
end

if #arenaPlayers == 1 then
local p = getPlayerMasterPos(arenaPlayers[1])
doTeleportThing(arenaPlayers[1], p)
doSendMagicEffect(p, CONST_ME_TELEPORT)
doPlayerSendTextMessage(arenaPlayers[1], MESSAGE_STATUS_CONSOLE_BLUE, "You have won the event and received your reward.")
doBroadcastMessage(getCreatureName(arenaPlayers[1]) .." won a Last Man Standing Event.")
doPlayerAddItem(arenaPlayers[1], t.prize[math.random(#t.prize)], 10)
kick = 0
elseif #arenaPlayers > 1 then
if kick == 0 then
kick = os.time()
else
if os.time() - kick >= 840 then
kick = 0
for i = 1, #arenaPlayers do
local mp = getPlayerMasterPos(arenaPlayers[i])
doTeleportThing(arenaPlayers[i], mp)
doPlayerSendTextMessage(arenaPlayers[i], MESSAGE_STATUS_WARNING, "Too even, try harder next time.")
end
end
end
elseif #arenaPlayers == 0 then
kick = 0

local players = {}
for x = t.tmp[1].x, t.tmp[2].x do
for y = t.tmp[1].y, t.tmp[2].y do
for z = t.tmp[1].z, t.tmp[2].z do
local c = getTopCreature({x = x, y = y, z = z})
if c.type == 1 then
table.insert(players, c.uid)
end
end
end
end

if #players >= t.minPlayers then
for i = 1, #players do
local p = {x = math.random(t.from.x, t.to.x), y = math.random(t.from.y, t.to.y), z = math.random(t.from.z, t.to.z)}
while getTileInfo(p).blocksolid == true do
local teleportPlayer = 1
end
if teleportPlayer == 1 then
doTeleportThing(players[i], p)
doSendMagicEffect(p, CONST_ME_TELEPORT)
doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The battle begins. Survive for glory!")
end
end
else
for i = 1, #players do
  local mplayer = getPlayerMasterPos(players[i])
doTeleportThing(players[i], mplayer)
doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The event didn't start because there isn't enough players in area!")
end
end
end
return true
end
 
uh this code looks ugly xD took a while to understand it (no offence)
Anyway, i don't see any visual problem with script.
But what i think your problem is: you are using onThink too frequently.
You should add new boolean value what says: has event started or not.
and it should only start once. Right now it looks like every time player goes to the event waiting room, he will be teleported on next interval.
 
Code:
local t =
{
    tmp =
    {
        -- Waiting room destinations
        {x = X, y = Y, z = Z}, -- North west corner of waiting room where players must stand in order to join the event
        {x = X, y = Y, z = Z} -- South east corner of waiting room
    },
 
    arena =
    {
        -- Arena destinations
        {x = X, y = Y, z = Z}, -- North west Corner of Arena
        {x = X, y = Y, z = Z}, -- South East corner of Arena
        {x = X, y = Y, z = Z} -- Center of Arena
    },

    from = {x = X, y = Y, z = 7}, -- Top left cornor of the playground (random players teleportation)
    to = {x = X, y = Y, z = 7}, -- Bottom right cornor of the playground (random players teleportation)

    minPlayers = 1, -- min players required to start the battle
    noPlayers = 1, -- Leave it as it is
    prize = {2160} -- Reward that player recives
}

local kick = 0
local teleportPlayer = 0

function onThink()
    local arenaPlayers = {}
    for x = t.arena[1].x, t.arena[2].x do
        for y = t.arena[1].y, t.arena[2].y do
            for z = t.arena[1].z, t.arena[2].z do
            local pos = {x = x, y = y, z = z}
            local n = getTileInfo(pos).creatures
                if n ~= 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(arenaPlayers, c.uid)
                            if #arenaPlayers == n then
                                break
                            end
                        end
                            pos.stackpos = pos.stackpos + 1
                            c = getThingfromPos(pos)
                    end
                end
            end
        end
    end

    if #arenaPlayers == 1 then
        local p = getPlayerMasterPos(arenaPlayers[1])
        doTeleportThing(arenaPlayers[1], p)
        doSendMagicEffect(p, CONST_ME_TELEPORT)
        doPlayerSendTextMessage(arenaPlayers[1], MESSAGE_STATUS_CONSOLE_BLUE, "You have won the event and received your reward.")
        doBroadcastMessage(getCreatureName(arenaPlayers[1]) .." won a Last Man Standing Event.")
        doPlayerAddItem(arenaPlayers[1], t.prize[math.random(#t.prize)], 10)
        kick = 0
    elseif #arenaPlayers > 1 then
        if kick == 0 then
            kick = os.time()
        else
            if os.time() - kick >= 840 then
                kick = 0
                for i = 1, #arenaPlayers do
                    local mp = getPlayerMasterPos(arenaPlayers[i])
                    doTeleportThing(arenaPlayers[i], mp)
                    doPlayerSendTextMessage(arenaPlayers[i], MESSAGE_STATUS_WARNING, "Too even, try harder next time.")
                end
            end
        end
    elseif #arenaPlayers == 0 then
        kick = 0
        local players = {}
            for x = t.tmp[1].x, t.tmp[2].x do
                for y = t.tmp[1].y, t.tmp[2].y do
                    for z = t.tmp[1].z, t.tmp[2].z do
                        local c = getTopCreature({x = x, y = y, z = z})
                        if c.type == 1 then
                            table.insert(players, c.uid)
                        end
                    end
                end
            end
         
    if #players >= t.minPlayers then
        for i = 1, #players do
            local p = {x = math.random(t.from.x, t.to.x), y = math.random(t.from.y, t.to.y), z = math.random(t.from.z, t.to.z)}
            while getTileInfo(p).blocksolid == true do
                local teleportPlayer = 1
            end
            if teleportPlayer == 1 then
                doTeleportThing(players[i], p)
                doSendMagicEffect(p, CONST_ME_TELEPORT)
                doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The battle begins. Survive for glory!")
            end
        end
    else
        for i = 1, #players do
            local mplayer = getPlayerMasterPos(players[i])
            doTeleportThing(players[i], mplayer)
            doPlayerSendTextMessage(players[i], MESSAGE_STATUS_WARNING, "The event didn't start because there isn't enough players in area!")
        end
    end
end
    return true
end

Only tabbed it!!
 
Back
Top