• 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 Dungeon System

Kabo Flow

New Member
Joined
May 17, 2020
Messages
50
Reaction score
4
Location
Mexico
Twitch
KaboFlow18
I have this script and I want it to be with command and not by tile
example! dungeon

killing all will give you a teleport to the chest

Actions
XML:
-- simple reward script, using actionid and the global table.
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local action_ID = item.actionid
    local reward = dungeon_system_config[action_ID]
    if not reward then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "LUA ERROR: Contact Administrator. Error code: Xikini_2") -- actionid on tile is incorrect or not in table.
        return true
    end

    -- if storage == -1, then we know that all monsters are dead, and reward has been obtained.
    -- if storage > 0 then monsters are still alive, since we count backwards to 0 monsters alive, when then allows the player to get their reward.
    local cur_storage = getPlayerStorageValue(cid, action_ID)
    if cur_storage == -1 then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "You've already obtained the reward. Please enter the teleport to exit the dungeon.")
        return true
    elseif cur_storage > 0 then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "There is still " .. cur_storage .. " monsters that need to be killed in this dungeon.")
        return true
    end

    if getItemWeightById(reward.reward_itemid, reward.reward_amount) > getPlayerFreeCap(cid) then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "You do not have enough capacity to obtain this reward.")
        return true
    end

    if reward.experience > 0 then
        doPlayerAddExperience(cid, reward.experience)
    end
    doPlayerAddItem(cid, reward.reward_itemid, reward.reward_amount, true)
    setPlayerStorageValue(cid, action_ID, -1)
    doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "Congratulations! Enter the teleport to exit the dungeon.")
    return true
end

Creaturescripts

XML:
function onLogin(cid)
    local teleport = 0
        if getPlayerStorageValue(cid, v) ~= -1 then
            teleport = 1
            setPlayerStorageValue(cid, v, -1)
    end
    if teleport == 1 then
        doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
    end
    return true
end


Movements
XML:
local function dungeon_system_updater(cid, storage, timer, index)
    if not isCreature(cid) then
        index[1][1] = 0 -- if player dies or logs out, reset player data to indicate dungeon is empty.
        return true
    end
    
    -- check if any monsters have died, and update player storage.
    local new_count = -1
    for i = #index[2], 1, -1 do
        if not isCreature(index[2][i]) then
            new_count = getPlayerStorageValue(cid, storage) - 1
            setPlayerStorageValue(cid, storage, new_count)
            table.remove(index[2], i)
        end
    end
    
    -- tell player that monsters have died.
    if new_count > 0 then
        local monster_count = #index[4]
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "You have killed [" .. (monster_count - new_count) .. " / " .. monster_count .."]")
    elseif new_count == 0 then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "You have killed all the creatures in this dungeon. Go open the chest for your reward.")
    end
    
    -- checks if the player is still inside the dungeon (so if player has completed dungeon but not yet left the dungeon, we can continue timer until auto-kick)
    local creature_pos = getPlayerPosition(cid)
    if creature_pos.x >= index[3][2].x and creature_pos.x <= index[3][3].x and creature_pos.y >= index[3][2].y and creature_pos.y <= index[3][3].y and creature_pos.z >= index[3][2].z and creature_pos.z <= index[3][3].z then
        timer = timer + 0.5 -- timer counts every 0.5 seconds, to check if player has run out of time.
        if timer < dungeon_system_config[storage].timeout then
            addEvent(dungeon_system_updater, 500, cid, storage, timer, index)
        else
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "Out of time! You've been removed from the Dungeon.")
            doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
            setPlayerStorageValue(cid, storage, -1)
            index[1][1] = 0
        end
    else
        index[1][1] = 0 -- if player leaves the dungeon, reset player data to indicate dungeon is empty.
    end
end

function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)
    local storage = item.actionid
    local dungeon = dungeon_system_config[storage]
    if not dungeon then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "LUA ERROR: Contact Administrator. Error code: Xikini_1") -- actionid on tile is incorrect or not in table.
        return true
    end
    
    dungeon = dungeon.area_info -- re-using local when possible, to make script cleaner
    
    -- check if player is already in a dungeon, and teleport them out.
    for i = 1, #dungeon do
        if dungeon[i][1][1] == cid then
            local cur_storage = getPlayerStorageValue(cid, storage)
            if cur_storage == -1 then
                doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "Dungeon Completed Successfully.")
                return true
            else
                if cur_storage == 0 then
                    doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "You must collect your reward before exiting the dungeon.")
                else
                    doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "There is still " .. cur_storage .. " monsters that need to be killed in this dungeon.")
                end
                doTeleportThing(cid, fromPosition)
                return true
            end
        end
    end
    
    -- find a dungeon that is empty.
    local area = 0
    for i = 1, #dungeon do
        if not isCreature(dungeon[i][1][1]) then
            area = i
            break
        end
        local creature_pos = getPlayerPosition(dungeon[i][1][1])
        if creature_pos.x >= dungeon[i][3][2].x and creature_pos.x <= dungeon[i][3][3].x and creature_pos.y >= dungeon[i][3][2].y and creature_pos.y <= dungeon[i][3][3].y and creature_pos.z >= dungeon[i][3][2].z and creature_pos.z <= dungeon[i][3][3].z then
        else
            area = i
            break
        end               
    end
    
    -- if no dungeons empty
    if area == 0 then
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "Sorry, no dungeons are empty. Try again later.")
        doTeleportThing(cid, fromPosition)
        return true
    end
    
    dungeon = dungeon[area]
    dungeon[1][1] = cid -- hold player data for later checking if dungeon is empty
    local monster_count = #dungeon[4]
    setPlayerStorageValue(cid, storage, monster_count) -- player storage is set as max monsters, and count down to 0 later.
    
    -- remove any monsters that are still alive in dungeon. (if a player died in the dungeon or timed out)
    for i = #dungeon[2], 1, -1 do
        if isCreature(dungeon[2][i]) then
            doRemoveCreature(dungeon[2][i])
        end
    end
    
    -- add all monsters into the dungeon, and store creatureids in table.
    for i = 1, monster_count do
        local monster = doCreateMonster(dungeon[4][i][1], dungeon[4][i][2])
        table.insert(dungeon[2], monster)
    end
    
    -- addEvent for timer and creature death tracking.
    addEvent(dungeon_system_updater, 500, cid, storage, 0, dungeon)
    doTeleportThing(cid, dungeon[3][1])
    return true
end

LIB
XML:
dungeon_system_config = {
    ---------------------------
    -- 45001 is a single dungeon, with multiple area's.
    -- since it is a single dungeon, the reward for all area's of this dungeon is the same.
    -- if area 1 is occupied, then player teleports to area 2.
    -- if area 2 is occupied, then it tries to goto area 3. if area 3 doesn't exist, player must wait for a dungeon to be empty.
    -- you can create only 1 area per dungeon if you want, or you can create infinite area's. Just depends on what you add into the table.
    [45001] = {
        timeout = 600, -- seconds until they timeout and teleport out of dungeon
        reward_itemid = 8777,
        reward_amount = 5,
        experience = 100000,
        area_info = {
      
            ---> {0} -- this holds player data to check if dungeon is empty or not.
            ---> {}  -- this holds monster data to check if monsters in dungeon have been killed.
            { {0}, {}, -- area 1 start
                {    {x = 159, y = 756, z = 8}, -- teleport_in_pos
                    {x = 146, y = 736, z = 8}, -- top_left_corner
                    {x = 170, y = 760, z = 8} -- bot_right_corner
                },
                {    {"Rattata", {x = 157, y = 752, z = 8}},
                    {"Rattata", {x = 157, y = 745, z = 8}},
                    {"Rattata", {x = 164, y = 745, z = 8}},
                    {"Rattata", {x = 164, y = 753, z = 8}}
                }
            }, -- area 1 end
      
            { {0}, {}, -- area 2 start
                {    {x = 159, y = 756, z = 8}, -- teleport_in_pos
                    {x = 146, y = 736, z = 8}, -- top_left_corner
                    {x = 170, y = 760, z = 8} -- bot_right_corner
                },
                {    {"Raticate", {x = 155, y = 752, z = 8}},
                    {"Raticate", {x = 162, y = 752, z = 8}},
                    {"Raticate", {x = 162, y = 744, z = 8}},
                    {"Raticate", {x = 155, y = 744, z = 8}}
                }
            } -- area 2 end
      
        }
    },
 
Back
Top