• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Solved Quest teleport bug

bybbzan

mapper
Joined
Aug 4, 2012
Messages
809
Solutions
2
Reaction score
136
Location
Sweden
Hello. I got this script, but its not working properly.
When i kill the monster "dragonator" i should get teleported to the "newPosition".
But its not working, i do not get teleported, and there's no errors in console.
Please help.

creaturescript.lua
Code:
local a = {
    newPos = {x=1497, y=819, z=7}, ---new pos after kill boss
    msg = "You defeted the Dragonator and may choose a reward.",
    area = {
        fromX = 1463, toX = 846,
        fromY = 1473, toY = 856,
        z = 7
    }
}
    function onKill(cid, target, damage, flags)
    local name = getCreatureName(target):lower()
    if name == 'dragonator' then
        local players = getCreaturesInRange({x=1468, y=851,z=7}, 10, 9, FALSE, TRUE) --- pos range monster
        for i = 1, #players do
            doTeleportThing(players[i], a.newPos)
            doCreatureSay(players[i], a.msg, TALKTYPE_ORANGE_1, false, players[i], getCreaturePosition(players[i]))
        end
            local name = getCreatureName(target):lower()
    if name == 'dragonator' then
        setPlayerStorageValue(cid,7778,1)
        setGlobalStorageValue(7779, -1)
            end
    end
    return true
end

movements.lua
Code:
local pos = {x=1468, y=853, z=7} --- Position monster summon
local spawn = {x=1466, y=850, z=7} --- Spawn position
function onStepIn(cid, item, position, fromPosition)
    local newPosition = {x=1468, y=847, z=7} --- new position
    local noPosition = {x=1469, y=858, z=8} --- no position
        if(getGlobalStorageValue(7778) < 1) and (getPlayerStorageValue(cid, 7778) == -1) then 
              doTeleportThing(cid, newPosition, TRUE)
            doSummonCreature('Dragonator', spawn)
            doPlayerSendTextMessage(cid,18,'You need to kill the boss.')
            setGlobalStorageValue(7779, 1)

        else
            doTeleportThing(cid, noPosition, TRUE)
            doPlayerSendTextMessage(cid,18,'You have already done this quest.')
    end
return true
end

Please help me out.
 
Last edited by a moderator:
Solved in pm, solution: He changes TRUE to 1 and added this function (was used in getCreaturesInRange).
Code:
table.find = function (table, value)
   for i, v in pairs(table) do
     if(v == value) then
       return i
     end
   end
   return nil
end
 
ok
if he wants to clean up the script:

dupe if statement
Code:
    if name == 'dragonator' then
no need for this twice
Code:
        if(getGlobalStorageValue(7778) < 1) and (getPlayerStorageValue(cid, 7778) == -1) then
doing 2 different checks returning the same cancel message. 1 to check if quest is already done and one to see if someone is already killing the monster.

this
Code:
    area = {
        fromX = 1463, toX = 846,
        fromY = 1473, toY = 856,
        z = 7
    }
is not used.
Code:
        local players = getCreaturesInRange({x=1468, y=851,z=7}, 10, 9, FALSE, TRUE) --- pos range monster
        for i = 1, #players do
            doTeleportThing(players[i], a.newPos)
            doCreatureSay(players[i], a.msg, TALKTYPE_ORANGE_1, false, players[i], getCreaturePosition(players[i]))
        end
you are first looping through the area to find all the players, then you are going through the table afterwards to teleport them. this is not efficient because you could do everything in 1 loop. instead of putting players into a table you could just teleport them.
use this function (put in global.lua or whateve):
Code:
function mapArea(fromPos, toPos, stack)
    -- Area iterator by Colandus @ OTFans.net
    local pos = {x=fromPos.x, y=fromPos.y-1, z=fromPos.z}
    return function()
        if (pos.y < toPos.y) then
            pos.y = pos.y+1
        elseif (pos.x <= toPos.x) then
            pos.y = fromPos.y
            pos.x = pos.x+1
        else
            pos.x = fromPos.x
            pos.y = fromPos.y
            pos.z = pos.z+1
        end
        if (pos.x <= toPos.x and pos.y <= toPos.y or pos.z < toPos.z) then
            if (stack == nil) then
                return pos
            else
                pos.stackpos = stack
                return pos, getThingfromPos(pos)
            end
        end
    end
end

example usage:
Code:
for _, player in mapArea(frompos, topos) do
        if(isPlayer(player.uid)) then
                    doTeleportThing(player.uid)
                      --do whatever with your player
        end
end

also, if im not mistaken this script will only let 1 player do the quest at the time. if this is intended, its kinda waste of resources to loop through the entire area when you already know what player is doing the quest. just put the CID on the player into the global storage, and use that as your pointer to the player.

OR, you can ignore everything i wrote if you dont care if your script is a bit sloppy :P
 
Is it possible to add a function like this? its taken from svargrond arena.
Cuz right now, more than one player may do this at the same time.
Code:
        if (busy) then
        for _, uid in ipairs(thing) do
            if (isPlayer(uid) and uid ~= cid) then
                if (getPlayerSex(cid) == 0) then
                    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, ""..getCreatureName(uid).." is currently in the next arena pit. You will have to wait until she leaves.")
                else
                    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, ""..getCreatureName(uid).." is currently in the next arena pit. You will have to wait until he leaves.")
                end
                    doTeleportThing(cid, lastPosition)
                end
            end
            return true
        end
 
Code:
local pos = {x=1468, y=853, z=7} --- Position monster summon
local spawn = {x=1466, y=850, z=7} --- Spawn position
function onStepIn(cid, item, position, fromPosition)
    local newPosition = {x=1468, y=847, z=7} --- new position
    local noPosition = {x=1469, y=858, z=8} --- no position
        if(getGlobalStorageValue(7778) == -1)  then
            if(getPlayerStorageValue(cid, 7778) == -1) then
                     doTeleportThing(cid, newPosition, TRUE)
                     doSummonCreature('Dragonator', spawn)
                     doPlayerSendTextMessage(cid,18,'You need to kill the boss.')
                     setGlobalStorageValue(7778, 1)
             else        
                    doTeleportThing(cid, fromPosition, TRUE)
                     doPlayerSendTextMessage(cid,18,'You have already done this quest.')
          end
        else
            doTeleportThing(cid, fromPosition, TRUE)
            doPlayerSendTextMessage(cid,18,'You have already done this quest.')
    end
return true
end

edit this
Code:
        setGlobalStorageValue(7779, -1)
to
Code:
        setGlobalStorageValue(7778, -1)
in ondeath script

i did not test this u might need to fix bugs

if someone dies or logs out inside the room, people will never be able to enter the room. you need to make sure
Code:
setGlobalStorageValue(7778, -1)
is put in every possible way people can ruin the quest. logout, ondeath etc etc

that why you should put the global storage to cid of the quester, this will make ur life so much easier than to loop through the entire boss area

i have nothing to do, i can rewrite this script for you if you promise to try to understand it so u can learn from it
 
Last edited by a moderator:
Code:
local newPosition = {x=1468, y=847, z=7} --- new position
local spawn = {x=1466, y=850, z=7} --- Spawn position


function onStepIn(cid, item, position, fromPosition)
local quester = getGlobalStorageValue(7778)
local monster = getGlobalStorageValue(7779)

    if(isPlayer(quester) == FALSE) then
        if(getPlayerStorageValue(cid, 7778) == -1) then
            if(isMonster(monster)) then
                doRemoveCreature(monster)
            end
            doTeleportThing(cid, newPosition, TRUE)
            local dragon = doSummonCreature('Dragonator', spawn)
            doPlayerSendTextMessage(cid,18,'You need to kill the boss.')
            setGlobalStorageValue(7778, cid)
            setGlobalStorageValue(7779, dragon)
        else
            doTeleportThing(cid, fromPosition, TRUE)
            doPlayerSendTextMessage(cid,18,'You have already done this quest.')
        end
    else
        doTeleportThing(cid, fromPosition, TRUE)
        doPlayerSendTextMessage(cid,18,'Someone is currently doing the quest.')
    end
    return true
end


Code:
function onKill(cid, target, damage, flags)
    local name = getCreatureName(target):lower()
    if name == 'dragonator' then
        doTeleportThing(cid, {x=1497, y=819, z=7})
        doCreatureSay(cid, "You defeted the Dragonator and may choose a reward.", TALKTYPE_ORANGE_1, false, cid, getCreaturePosition(cid))
        setPlayerStorageValue(cid, 7778,1)
        setGlobalStorageValue(7778, -1)
        setGlobalStorageValue(7779, -1)
    end
    return true
end

NOT TESTED, but should only be minor bugs if any, im sure you can fix them.
What you need to fix yourself: if someone logs out during the quest, they need to be teleported out of the area.
 
Last edited:
Back
Top