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

Script crash after death help

tomaszek123

Member
Joined
May 29, 2014
Messages
71
Solutions
1
Reaction score
18
Hi,

So i have this dungeon script and everything works fine with no issue however only when player dies or logout server crashes.

Is there any way of resolving this ?
TFS 1.5

Lua:
function onModalWindow(player, modalWindowId, buttonId, choiceId) 
    
    player:unregisterEvent("DungeonSystem_Modal")

    local dg = DUNGEON_SYSTEM.Dungeons
    local msg = DUNGEON_SYSTEM.Messages
    local modal = DUNGEON_SYSTEM.Modal
    local sto = DUNGEON_SYSTEM.Storages   

    if (modalWindowId == DUNGEON_SYSTEM.Modal.ID) then
        
        if buttonId == 200 then
            
            local players = {}
            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                        local tile = Tile(x, y, z)
                        local creature = tile:getTopCreature()
                        if creature and creature:isPlayer() then
                            players[#players+1] = creature
                        end
                    end
                end
            end
            
            if #players > 0 then
                player:getPosition():sendMagicEffect(CONST_ME_POFF)
                return player:sendTextMessage(MESSAGE_STATUS_SMALL, msg.PlayerInside)
            end
            
            if (dg[choiceId].NeedLevel) then
                if (player:getLevel() < dg[choiceId].Level) then
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedLevel, dg[choiceId].Level))
                    return false
                end
            end
            
            local pt = player:getParty()
            local partyMembers
            
            local party = {}
            party = partyMembers
            
            local fromPosPlayer = player:getPosition()
            
            if (dg[choiceId].NeedParty) then
                
                if not pt then
                    
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgUniqueNeedParty)
                    return false
                
                else
                    
                    partyMembers = pt:getMembers()
                    local party = player:getParty():getMemberCount()
                    
                    if not (pt:getLeader():getName() == player:getName()) then
                        
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgLeaderParty)
                        return false
                    
                    else
                    
                        local partyMaisUm = party+1
                        
                        if not (partyMaisUm == dg[choiceId].AmountParty) then
                            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedParty, dg[choiceId].AmountParty))
                            return false
                        end
                        
                        local names = {}
                        local posOfPlayer = {}
                        
                        for i = 1, party do
                        
                            local ppt = partyMembers[i]
                            local fromPosPpt = ppt:getPosition()
                        
                            if DUNGEON_SYSTEM.PzToEntry then
                                if not getTileInfo(fromPosPpt).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzMsg)
                                elseif not getTileInfo(fromPosPlayer).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                                end
                            end
                        
                            -- SE TEM COOLDOWN
                            if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 or ppt:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                else
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.WaitFriendsCooldown, string.diff(ppt:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                end
                                return false
                            end
                            
                            names[i] = ppt:getName()
                            
                        end
                        
                        local positionPlayer = player:getPosition()
                        local distance = DUNGEON_SYSTEM.SQMsDistanceOfLeader
                        
                        for x = positionPlayer.x - distance, positionPlayer.x + distance do
                            for y = positionPlayer.y - distance, positionPlayer.y + distance do
                                for z = positionPlayer.z, positionPlayer.z do
                                    local tileP = Tile(x, y, z)
                                    local creatureP = tileP:getTopCreature()
                                    if creatureP and creatureP:isPlayer() then
                                        for xx = 1, #names do
                                            if creatureP:getName() == names[xx] then
                                                posOfPlayer[#posOfPlayer+1] = creatureP
                                            end
                                        end
                                    end
                                end
                            end
                        end
                        
                        if #posOfPlayer+1 ~= dg[choiceId].AmountParty then
                            return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgDistanceLeader)
                        end
                        
                        if dg[choiceId].SpawnMonsters then
                            for m, l in pairs(dg[choiceId].Monsters) do
                                Game.createMonster(m, l)
                            end
                        end
                        
                        player:teleportTo(dg[choiceId].DungeonPos)
                        player:getPosition():sendMagicEffect(40)
                        player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                        
                        addEvent(function()
                            player:teleportTo(fromPosPlayer)
                            player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                            player:getPosition():sendMagicEffect(40)
                            player:popupFYI(msg.ToFail)
                            
                            -- Remove All monsters
                            local monsterPos = {}
                            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                        local tile = Tile(x, y, z)
                                        local monster = tile:getTopCreature()
                                        if monster and monster:isMonster() then
                                            monster:remove()
                                        end
                                    end
                                end
                            end
                            
                        end, dg[choiceId].DungeonTime*1000)   
                        
                        for mx = 1, party do
                        
                            local ppt = partyMembers[mx]
                            local fromPosPpt = ppt:getPosition()
                        
                            ppt:teleportTo(dg[choiceId].DungeonPos)
                            ppt:getPosition():sendMagicEffect(40)
                            
                            addEvent(function()
                                ppt:teleportTo(fromPosPpt)
                                ppt:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                                ppt:getPosition():sendMagicEffect(40)
                                ppt:popupFYI(msg.ToFail)
                            end, dg[choiceId].DungeonTime*1000)   
                        
                        end
                        
                    end
                    
                end
                
            else
                
                if DUNGEON_SYSTEM.PzToEntry then
                    if not getTileInfo(fromPosPlayer).protection then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                    end
                end
                
                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                    return false
                end
                
                if dg[choiceId].SpawnMonsters then
                    for m, l in pairs(dg[choiceId].Monsters) do
                        Game.createMonster(m, l)
                    end
                end
                    
                -- To Dungeon
                player:teleportTo(dg[choiceId].DungeonPos)
                player:getPosition():sendMagicEffect(40)
                player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                player:setStorageValue(sto.TimerDungeon, os.time() + dg[choiceId].DungeonTime)
                
                -- Back Dungeon
                addEvent(function()
                    player:teleportTo(fromPosPlayer)
                    player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                    player:getPosition():sendMagicEffect(40)
                    player:popupFYI(msg.ToFail)
                    
                    -- Remove All monsters
                    local monsterPos = {}
                    for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                        for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                            for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                local tile = Tile(x, y, z)
                                local monster = tile:getTopCreature()
                                if monster and monster:isMonster() then
                                    monster:remove()
                                end
                            end
                        end
                    end
                    
                end, dg[choiceId].DungeonTime*1000)
                
            end
            
            
        elseif buttonId == 201 then
            
            player:registerEvent("DungeonSystemDetails_Modal")
            
            local needPartyMsg, needLevelMsg = "", ""
            
            if (dg[choiceId].NeedParty) then
                needPartyMsg = string.format("Party: %s players", dg[choiceId].AmountParty)
            else
                needPartyMsg = "Party: 1 players"
            end
            
            if (dg[choiceId].NeedLevel) then
                needLevelMsg = string.format("Level: %s+", dg[choiceId].Level)
            else
                needLevelMsg = "Don't need Level"
            end
            
            local detailsModal = ModalWindow(modal.IDDetails, modal.TitleDetails, string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))
            
            detailsModal:addButton(100, "Back")
            
            detailsModal:setDefaultEnterButton(100)
            detailsModal:setDefaultEscapeButton(100)
            
            detailsModal:sendToPlayer(player)
            
            -- player:popupFYI(string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))

        end
    
    end
    
end
 
Hi,

So i have this dungeon script and everything works fine with no issue however only when player dies or logout server crashes.

Is there any way of resolving this ?
TFS 1.5

Lua:
function onModalWindow(player, modalWindowId, buttonId, choiceId)
   
    player:unregisterEvent("DungeonSystem_Modal")

    local dg = DUNGEON_SYSTEM.Dungeons
    local msg = DUNGEON_SYSTEM.Messages
    local modal = DUNGEON_SYSTEM.Modal
    local sto = DUNGEON_SYSTEM.Storages  

    if (modalWindowId == DUNGEON_SYSTEM.Modal.ID) then
       
        if buttonId == 200 then
           
            local players = {}
            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                        local tile = Tile(x, y, z)
                        local creature = tile:getTopCreature()
                        if creature and creature:isPlayer() then
                            players[#players+1] = creature
                        end
                    end
                end
            end
           
            if #players > 0 then
                player:getPosition():sendMagicEffect(CONST_ME_POFF)
                return player:sendTextMessage(MESSAGE_STATUS_SMALL, msg.PlayerInside)
            end
           
            if (dg[choiceId].NeedLevel) then
                if (player:getLevel() < dg[choiceId].Level) then
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedLevel, dg[choiceId].Level))
                    return false
                end
            end
           
            local pt = player:getParty()
            local partyMembers
           
            local party = {}
            party = partyMembers
           
            local fromPosPlayer = player:getPosition()
           
            if (dg[choiceId].NeedParty) then
               
                if not pt then
                   
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgUniqueNeedParty)
                    return false
               
                else
                   
                    partyMembers = pt:getMembers()
                    local party = player:getParty():getMemberCount()
                   
                    if not (pt:getLeader():getName() == player:getName()) then
                       
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgLeaderParty)
                        return false
                   
                    else
                   
                        local partyMaisUm = party+1
                       
                        if not (partyMaisUm == dg[choiceId].AmountParty) then
                            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedParty, dg[choiceId].AmountParty))
                            return false
                        end
                       
                        local names = {}
                        local posOfPlayer = {}
                       
                        for i = 1, party do
                       
                            local ppt = partyMembers[i]
                            local fromPosPpt = ppt:getPosition()
                       
                            if DUNGEON_SYSTEM.PzToEntry then
                                if not getTileInfo(fromPosPpt).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzMsg)
                                elseif not getTileInfo(fromPosPlayer).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                                end
                            end
                       
                            -- SE TEM COOLDOWN
                            if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 or ppt:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                else
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.WaitFriendsCooldown, string.diff(ppt:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                end
                                return false
                            end
                           
                            names[i] = ppt:getName()
                           
                        end
                       
                        local positionPlayer = player:getPosition()
                        local distance = DUNGEON_SYSTEM.SQMsDistanceOfLeader
                       
                        for x = positionPlayer.x - distance, positionPlayer.x + distance do
                            for y = positionPlayer.y - distance, positionPlayer.y + distance do
                                for z = positionPlayer.z, positionPlayer.z do
                                    local tileP = Tile(x, y, z)
                                    local creatureP = tileP:getTopCreature()
                                    if creatureP and creatureP:isPlayer() then
                                        for xx = 1, #names do
                                            if creatureP:getName() == names[xx] then
                                                posOfPlayer[#posOfPlayer+1] = creatureP
                                            end
                                        end
                                    end
                                end
                            end
                        end
                       
                        if #posOfPlayer+1 ~= dg[choiceId].AmountParty then
                            return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgDistanceLeader)
                        end
                       
                        if dg[choiceId].SpawnMonsters then
                            for m, l in pairs(dg[choiceId].Monsters) do
                                Game.createMonster(m, l)
                            end
                        end
                       
                        player:teleportTo(dg[choiceId].DungeonPos)
                        player:getPosition():sendMagicEffect(40)
                        player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                       
                        addEvent(function()
                            player:teleportTo(fromPosPlayer)
                            player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                            player:getPosition():sendMagicEffect(40)
                            player:popupFYI(msg.ToFail)
                           
                            -- Remove All monsters
                            local monsterPos = {}
                            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                        local tile = Tile(x, y, z)
                                        local monster = tile:getTopCreature()
                                        if monster and monster:isMonster() then
                                            monster:remove()
                                        end
                                    end
                                end
                            end
                           
                        end, dg[choiceId].DungeonTime*1000)  
                       
                        for mx = 1, party do
                       
                            local ppt = partyMembers[mx]
                            local fromPosPpt = ppt:getPosition()
                       
                            ppt:teleportTo(dg[choiceId].DungeonPos)
                            ppt:getPosition():sendMagicEffect(40)
                           
                            addEvent(function()
                                ppt:teleportTo(fromPosPpt)
                                ppt:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                                ppt:getPosition():sendMagicEffect(40)
                                ppt:popupFYI(msg.ToFail)
                            end, dg[choiceId].DungeonTime*1000)  
                       
                        end
                       
                    end
                   
                end
               
            else
               
                if DUNGEON_SYSTEM.PzToEntry then
                    if not getTileInfo(fromPosPlayer).protection then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                    end
                end
               
                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                    return false
                end
               
                if dg[choiceId].SpawnMonsters then
                    for m, l in pairs(dg[choiceId].Monsters) do
                        Game.createMonster(m, l)
                    end
                end
                   
                -- To Dungeon
                player:teleportTo(dg[choiceId].DungeonPos)
                player:getPosition():sendMagicEffect(40)
                player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                player:setStorageValue(sto.TimerDungeon, os.time() + dg[choiceId].DungeonTime)
               
                -- Back Dungeon
                addEvent(function()
                    player:teleportTo(fromPosPlayer)
                    player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                    player:getPosition():sendMagicEffect(40)
                    player:popupFYI(msg.ToFail)
                   
                    -- Remove All monsters
                    local monsterPos = {}
                    for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                        for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                            for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                local tile = Tile(x, y, z)
                                local monster = tile:getTopCreature()
                                if monster and monster:isMonster() then
                                    monster:remove()
                                end
                            end
                        end
                    end
                   
                end, dg[choiceId].DungeonTime*1000)
               
            end
           
           
        elseif buttonId == 201 then
           
            player:registerEvent("DungeonSystemDetails_Modal")
           
            local needPartyMsg, needLevelMsg = "", ""
           
            if (dg[choiceId].NeedParty) then
                needPartyMsg = string.format("Party: %s players", dg[choiceId].AmountParty)
            else
                needPartyMsg = "Party: 1 players"
            end
           
            if (dg[choiceId].NeedLevel) then
                needLevelMsg = string.format("Level: %s+", dg[choiceId].Level)
            else
                needLevelMsg = "Don't need Level"
            end
           
            local detailsModal = ModalWindow(modal.IDDetails, modal.TitleDetails, string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))
           
            detailsModal:addButton(100, "Back")
           
            detailsModal:setDefaultEnterButton(100)
            detailsModal:setDefaultEscapeButton(100)
           
            detailsModal:sendToPlayer(player)
           
            -- player:popupFYI(string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))

        end
   
    end
   
end
One possible solution to this issue is to add a check to see if the player is inside the dungeon before unregistering the event and performing other actions. you can store this informtion in a storage or in a variable within the players data.

For example, you could add a check at the beginning of the onModalWindow function like this:

Lua:
local playerIsInDungeon = player:getStorageValue(sto.IsInDungeon)
if not playerIsInDungeon then
  return
end
This will prevent the script from executing if the player is not currently in the dungeon.

you may want to consider adding a similar check before removing the player from the dungeon when they die or log out. This will ensure that the player is actually in the dungeon before attempting to remove them.
 
Well in my opinion there is a problem
this system getting whole "creature" to database
Lua:
players[#players+1] = creature
while it should take id of creature
Lua:
players[#players+1] = creature:getId()
and then check if Creature(id of creature) exsists.

anyway, file that you posted has no event with dying creature, so i can't help dirrectly, try find onDeath in your files for that system
 
This indeed is causing the crash, all scheduled events inside the script has no check for creature/player
So if player dies / logout, it will randomly crash [not always]

Solution: just pass the player id as argument, then do the proper check inside the events
Here: script
 
This indeed is causing the crash, all scheduled events inside the script has no check for creature/player
So if player dies / logout, it will randomly crash [not always]

Solution: just pass the player id as argument, then do the proper check inside the events
Here: script
Nice, it fixed the crash, however now any player can join the dungeon even if someone is already inside.


Here is the whole system:

Register creaturescripts:

XML:
    <event type="modalwindow" name="DungeonSystem_Modal" script="Dungeon Creaturescript.lua"/>
    <event type="modalwindow" name="DungeonSystemType_Modal" script="Type Dungeon Creaturescript.lua"/>
    <event type="modalwindow" name="DungeonSystemDetails_Modal" script="Type Dungeon Creaturescript.lua"/>


Fixed crash version by Roddet ^^
Lua:
function onModalWindow(player, modalWindowId, buttonId, choiceId)
    
    player:unregisterEvent("DungeonSystem_Modal")

    local dg = DUNGEON_SYSTEM.Dungeons
    local msg = DUNGEON_SYSTEM.Messages
    local modal = DUNGEON_SYSTEM.Modal
    local sto = DUNGEON_SYSTEM.Storages   

    if (modalWindowId == DUNGEON_SYSTEM.Modal.ID) then
        
        if buttonId == 200 then
            
            local players = {}
            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                        local tile = Tile(x, y, z)
                        local creature = tile:getTopCreature()
                        if creature and creature:isPlayer() then
                            players[#players+1] = creature
                        end
                    end
                end
            end
            
            if #players > 0 then
                player:getPosition():sendMagicEffect(CONST_ME_POFF)
                return player:sendTextMessage(MESSAGE_STATUS_SMALL, msg.PlayerInside)
            end
            
            if (dg[choiceId].NeedLevel) then
                if (player:getLevel() < dg[choiceId].Level) then
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedLevel, dg[choiceId].Level))
                    return false
                end
            end
            
            local pt = player:getParty()
            local partyMembers
            
            local party = {}
            party = partyMembers
            
            local fromPosPlayer = player:getPosition()
            
            if (dg[choiceId].NeedParty) then
                
                if not pt then
                    
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgUniqueNeedParty)
                    return false
                
                else
                    
                    partyMembers = pt:getMembers()
                    local party = player:getParty():getMemberCount()
                    
                    if not (pt:getLeader():getName() == player:getName()) then
                        
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgLeaderParty)
                        return false
                    
                    else
                    
                        local partyMaisUm = party+1
                        
                        if not (partyMaisUm == dg[choiceId].AmountParty) then
                            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.MsgNeedParty, dg[choiceId].AmountParty))
                            return false
                        end
                        
                        local names = {}
                        local posOfPlayer = {}
                        
                        for i = 1, party do
                        
                            local ppt = partyMembers[i]
                            local fromPosPpt = ppt:getPosition()
                        
                            if DUNGEON_SYSTEM.PzToEntry then
                                if not getTileInfo(fromPosPpt).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzMsg)
                                elseif not getTileInfo(fromPosPlayer).protection then
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                                end
                            end
                        
                            -- SE TEM COOLDOWN
                            if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 or ppt:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                else
                                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.WaitFriendsCooldown, string.diff(ppt:getStorageValue(sto.TimerCooldown)-os.time())))
                                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                                    ppt:getPosition():sendMagicEffect(CONST_ME_POFF)
                                end
                                return false
                            end
                            
                            names[i] = ppt:getName()
                            
                        end
                        
                        local positionPlayer = player:getPosition()
                        local distance = DUNGEON_SYSTEM.SQMsDistanceOfLeader
                        
                        for x = positionPlayer.x - distance, positionPlayer.x + distance do
                            for y = positionPlayer.y - distance, positionPlayer.y + distance do
                                for z = positionPlayer.z, positionPlayer.z do
                                    local tileP = Tile(x, y, z)
                                    local creatureP = tileP:getTopCreature()
                                    if creatureP and creatureP:isPlayer() then
                                        for xx = 1, #names do
                                            if creatureP:getName() == names[xx] then
                                                posOfPlayer[#posOfPlayer+1] = creatureP
                                            end
                                        end
                                    end
                                end
                            end
                        end
                        
                        if #posOfPlayer+1 ~= dg[choiceId].AmountParty then
                            return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.MsgDistanceLeader)
                        end
                        
                        if dg[choiceId].SpawnMonsters then
                            for m, l in pairs(dg[choiceId].Monsters) do
                                Game.createMonster(m, l)
                            end
                        end
                        
                        player:teleportTo(dg[choiceId].DungeonPos)
                        player:getPosition():sendMagicEffect(40)
                        player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                        
                        addEvent(function(cid)

                            local player = Player(cid)
                            if player then
                                player:teleportTo(fromPosPlayer)
                                player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                                player:getPosition():sendMagicEffect(40)
                                player:popupFYI(msg.ToFail)
                            end
                            
                            -- Remove All monsters
                            local monsterPos = {}
                            for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                                for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                                    for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                        local tile = Tile(x, y, z)
                                        local monster = tile:getTopCreature()
                                        if monster and monster:isMonster() then
                                            monster:remove()
                                        end
                                    end
                                end
                            end
                            
                        end, dg[choiceId].DungeonTime*1000, player:getId())   
                        
                        for mx = 1, party do
                        
                            local ppt = partyMembers[mx]
                            local fromPosPpt = ppt:getPosition()
                        
                            ppt:teleportTo(dg[choiceId].DungeonPos)
                            ppt:getPosition():sendMagicEffect(40)
                            
                            addEvent(function(cid)

                                local ppt = Player(cid)
                                if not ppt then
                                    return
                                end

                                ppt:teleportTo(fromPosPpt)
                                ppt:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                                ppt:getPosition():sendMagicEffect(40)
                                ppt:popupFYI(msg.ToFail)

                            end, dg[choiceId].DungeonTime*1000, ppt:getId())   
                        
                        end
                        
                    end
                    
                end
                
            else
                
                if DUNGEON_SYSTEM.PzToEntry then
                    if not getTileInfo(fromPosPlayer).protection then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        return player:sendTextMessage(MESSAGE_EVENT_ADVANCE, msg.NeedPzSoloMsg)
                    end
                end
                
                if player:getStorageValue(sto.TimerCooldown) - os.time() > 0 then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format(msg.ToCooldown, string.diff(player:getStorageValue(sto.TimerCooldown)-os.time())))
                    return false
                end
                
                if dg[choiceId].SpawnMonsters then
                    for m, l in pairs(dg[choiceId].Monsters) do
                        Game.createMonster(m, l)
                    end
                end
                    
                -- To Dungeon
                player:teleportTo(dg[choiceId].DungeonPos)
                player:getPosition():sendMagicEffect(40)
                player:say(msg.ToEntry, TALKTYPE_MONSTER_SAY)
                player:setStorageValue(sto.TimerDungeon, os.time() + dg[choiceId].DungeonTime)
                
                -- Back Dungeon
                addEvent(function(cid)

                    local player = Player(cid)
                    if player then
                        player:teleportTo(fromPosPlayer)
                        player:setStorageValue(sto.TimerCooldown, os.time() + DUNGEON_SYSTEM.CooldownTime)
                        player:getPosition():sendMagicEffect(40)
                        player:popupFYI(msg.ToFail)
                    end
                    
                    -- Remove All monsters
                    local monsterPos = {}
                    for x = dg[choiceId].FromPos.x, dg[choiceId].ToPos.x do
                        for y = dg[choiceId].FromPos.y, dg[choiceId].ToPos.y do
                            for z = dg[choiceId].FromPos.z, dg[choiceId].ToPos.z do
                                local tile = Tile(x, y, z)
                                local monster = tile:getTopCreature()
                                if monster and monster:isMonster() then
                                    monster:remove()
                                end
                            end
                        end
                    end
                    
                end, dg[choiceId].DungeonTime*1000, player:getId())
                
            end
            
            
        elseif buttonId == 201 then
            
            player:registerEvent("DungeonSystemDetails_Modal")
            
            local needPartyMsg, needLevelMsg = "", ""
            
            if (dg[choiceId].NeedParty) then
                needPartyMsg = string.format("Party: %s players", dg[choiceId].AmountParty)
            else
                needPartyMsg = "Party: 1 players"
            end
            
            if (dg[choiceId].NeedLevel) then
                needLevelMsg = string.format("Level: %s+", dg[choiceId].Level)
            else
                needLevelMsg = "Don't need Level"
            end
            
            local detailsModal = ModalWindow(modal.IDDetails, modal.TitleDetails, string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))
            
            detailsModal:addButton(100, "Back")
            
            detailsModal:setDefaultEnterButton(100)
            detailsModal:setDefaultEscapeButton(100)
            
            detailsModal:sendToPlayer(player)
            
            -- player:popupFYI(string.format(">> Dungeon %s <<\n\n" .. needPartyMsg .. "\n" .. needLevelMsg .."\n\nTime to Dungeon: %s", dg[choiceId].Name, string.diff(dg[choiceId].DungeonTime)))

        end
    
    end
    
end

Type Dungeon Creaturescript.lua

Lua:
function modalDungeon(player)

    player:registerEvent("DungeonSystem_Modal")
    
    local window = ModalWindow(DUNGEON_SYSTEM.Modal.ID, DUNGEON_SYSTEM.Modal.Title, DUNGEON_SYSTEM.Modal.Msg)
    
    window:addButton(200, "Confirm")
    window:addButton(202, "Exit")
    

    
    window:setDefaultEnterButton(200)
    window:setDefaultEscapeButton(202)
    
    window:sendToPlayer(player)
    
end

function onModalWindow(player, modalWindowId, buttonId, choiceId) 
    
    player:unregisterEvent("DungeonSystemType_Modal")

    local dg = DUNGEON_SYSTEM.Dungeons
    local msg = DUNGEON_SYSTEM.Messages
    local modal = DUNGEON_SYSTEM.Modal
    local sto = DUNGEON_SYSTEM.Storages   
    
    if buttonId == 100 then
        
        modalDungeon(player)
        
    end
    
end



Actions

XML:
<action actionid="5597" script="Dungeon Actions.lua"/>

Lua:
function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)
    
    player:registerEvent("DungeonSystem_Modal")
    
    local window = ModalWindow(DUNGEON_SYSTEM.Modal.ID, DUNGEON_SYSTEM.Modal.Title, DUNGEON_SYSTEM.Modal.Msg)
    
    window:addButton(200, "Confirm")
    window:addButton(201, "Details")
    window:addButton(202, "Exit")
    
    for k,v in pairs(DUNGEON_SYSTEM.Dungeons) do
        window:addChoice(k, "" .. v.Name)
    end
    
    window:setDefaultEnterButton(200)
    window:setDefaultEscapeButton(202)
    
    window:sendToPlayer(player)
    
    return true
end



Libs:

Lua:
DUNGEON_SYSTEM = {

    Storages = {
        timerDungeon = 49356,
        timerCooldown = 50203,
        storageReward = 50205,
    },
    
    Modal = {
        IDType = 2049,
        TitleType = "Daily Monster Hunt",
        MsgType = "Select this type:",
    
        ID = 2050,
        Title = "Daily Monster Hunt",
        Msg = "Select your hunt:",
        
        IDDetails = 2051,
        TitleDetails = "Details Dungeon",
    },
    
    Messages = {
        ToEntry = "Welcome to the monster hunt",
        ToFail = "Your time has finished!",
        
        WaitFriendsCooldown = "Wait your friend: %s",
        ToCooldown = "You're in cooldown to enter in a dungeon again. Cooldown: %s.",
        MsgNeedLevel = "You don't have level required. You need level %s.",
        MsgUniqueNeedParty = "You need party, to entry in dungeon",
        MsgNeedParty = "You need to be at a party to enter the dungeon. You need %s players",
        MsgLeaderParty = "You are not the leader of the Party.",
        
        MsgDistanceLeader = "Your friends need to be close to you.",
        
        NeedPzSoloMsg = "You need to be in a safe area [PZ].",
        NeedPzMsg = "Your team needs to go a safe area [PZ].",
    
        PlayerInside = "Already is inside.",
    },
    
    CooldownTime = 1000,
    
    PzToEntry = true,
    
    SQMsDistanceOfLeader = 5,

    Dungeons = {

        [1] = {
            -- Name
            Name = "Hellcave",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = true,
            Level = 100,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2219, 879, 5),

            -- Position Dungeon
            FromPos = {x = 2109, y = 747, z = 5},     --{x = 2105, y = 750, z = 5}
            ToPos = {x = 2309, y = 916, z = 5},        --{x = 2336, y = 946, z = 5}
            
            SpawnMonsters = false,
            Monsters = {
                ["Demon"] = Position(2231, 873, 5),
            },
            
        },
        
        [2] = {
            -- Name
            Name = "Pirate Island",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = false,
            Level = 200,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2418, 863, 6),

            -- Position Dungeon
            FromPos = {x = 2390, y = 746, z = 7},     -- Position /\ < from the dungeon{x = 2231, y = 1007, z = 6}
            ToPos = {x = 2548, y = 904, z = 0},        -- Position \/ > from the dungeon{x = 2298, y = 1067, z = 6}
            
            SpawnMonsters = true,
            Monsters = {
                ["Demon"] = Position(1170, 934, 7),
                ["Rat"] = Position(1170, 935, 7),
                ["Hydra"] = Position(1167, 932, 7),
            },
            
        },

        [3] = {
            -- Name
            Name = "Depth of Death",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = false,
            Level = 300,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2715, 829, 5),

            -- Position Dungeon
            FromPos = {x = 2660, y = 774, z = 5},     -- Position /\ < from the dungeon{x = 2231, y = 1007, z = 6}
            ToPos = {x = 2771, y = 856, z = 5},        -- Position \/ > from the dungeon{x = 2298, y = 1067, z = 6}
            
            SpawnMonsters = true,
            Monsters = {
                ["Demon"] = Position(1170, 934, 7),
                ["Rat"] = Position(1170, 935, 7),
                ["Hydra"] = Position(1167, 932, 7),
            },
            
        },

        [4] = {
            -- Name
            Name = "Lava Bridge",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = false,
            Level = 300,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2928, 823, 7),

            -- Position Dungeon
            FromPos = {x = 2846, y = 794, z = 7},     -- Position /\ < from the dungeon{x = 2231, y = 1007, z = 6}
            ToPos = {x = 2963, y = 854, z = 0},        -- Position \/ > from the dungeon{x = 2298, y = 1067, z = 6}
            
            SpawnMonsters = true,
            Monsters = {
                ["Demon"] = Position(1170, 934, 7),
                ["Rat"] = Position(1170, 935, 7),
                ["Hydra"] = Position(1167, 932, 7),
            },
            
        },

        [5] = {
            -- Name
            Name = "Icy Island",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = false,
            Level = 300,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2533, 1086, 7),

            -- Position Dungeon
            FromPos = {x = 2380, y = 997, z = 7},     -- Position /\ < from the dungeon{x = 2231, y = 1007, z = 6}
            ToPos = {x = 2576, y = 1108, z = 4},        -- Position \/ > from the dungeon{x = 2298, y = 1067, z = 6}
            
            SpawnMonsters = true,
            Monsters = {
                ["Demon"] = Position(1170, 934, 7),
                ["Rat"] = Position(1170, 935, 7),
                ["Hydra"] = Position(1167, 932, 7),
            },
            
        },

        [6] = {
            -- Name
            Name = "Frozen Fortress [HARD]",
            
            -- Party
            NeedParty = false,
            AmountParty = 1,
            
            -- Level
            NeedLevel = false,
            Level = 300,
                        
            -- Dungeon
            DungeonTime = 10, -- 5 min, 30 seconds
            DungeonPos = Position(2730, 1060, 6),

            -- Position Dungeon
            FromPos = {x = 2614, y = 1010, z = 8},     -- Position /\ < from the dungeon{x = 2231, y = 1007, z = 6}
            ToPos = {x = 2881, y = 1219, z = 0},        -- Position \/ > from the dungeon{x = 2298, y = 1067, z = 6}
            
            SpawnMonsters = true,
            Monsters = {
                ["Demon"] = Position(1170, 934, 7),
                ["Rat"] = Position(1170, 935, 7),
                ["Hydra"] = Position(1167, 932, 7),
            },
            
        },
        
        
    

    },
    
}




Many thanks, guys!
 
Back
Top