Lua Dugeon System

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
I miss dugeon system on OTs.
I wanna make a server based in dugeon system.
I made this pseudo code to this dugeon system:

- 4 sqms (1 per vocation)
- different IPs
- a lot dugeons in same script
- some tasks min/max lvl
- 24 hours exausted per task (after in)
- only 1 team per time
- no logout zone inside task and after 15 min if players dont kill the boss and open the chest, go teleport back to fromPos
- random rewards

/lib/dugeon_system.lua
Code:
local dugeonName = "dragons"

local fromPos[1] = {x = 952, y = 1039, z = 7},
local fromPos[2] = {x = 953,, y = 1039, z = 7},
local fromPos[3] = {x = 954, y = 1039, z = 7},
local fromPos[4] = {x = 955, y = 1039, z = 7},

local toPos[1]    = {x = 952, y = 1039, z = 6},
local toPos[1]    = {x = 953, y = 1039, z = 6},
local toPos[1]    = {x = 954, y = 1039, z = 6},
local toPos[1]    = {x = 955, y = 1039, z = 6},

local playerMinimumLevel = 15
local playerMaximumLevel = 30

local rewards = {1100, 1101, 1102}

<action actionid="9602" script="dugeonsystem_lever.lua"/>
Code:
-- get a vocation's base vocation
function getBaseVocation(vocation)
    if vocation >= 5 and vocation <= 8 then
        return vocation - 4
    elseif vocation >= 9 and vocation <= 12 then
        return vocation - 8
    end
    return vocation
end

function onUse(cid)
    for i = 1, 4 do
        local pid = getTopCreature(p[i].player.position).uid
        if isPlayer(pid) then
            -- MIN / MAX level
            if getPlayerLevel(pid) > playerMinimumLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not high enough in level, minimum level is " .. playerMinimumLevel .. ".")
                return false
            end
            if getPlayerLevel(pid) < playerMinimumLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not low enough in level, maximum level is " .. playerMinimumLevel .. ".")
                return false
            end
            -- CHECK 1 PER VOCATION (1 knight, 1 paladin, 1 sorcerer, 1 druid)
            if getBaseVocation( getPlayerVocation(pid) ) == X then
            -- CHECK IF EVERY PLAYER HAVE DIFFERENT IP
            if() then

            end
            -- everything is working - GO GO GO  
            -- check if have 4 players allowed
            if() then
                doPlayerSendTextMessage(pid, MESSAGE_INFO_DESCR, "You are inside " .. dugeonName .. "dugeon! You have 15 minutes to finish this dugeon.")
                doTeleportThing(x, pos)
                -- add a PLAYER storage and if player do not finish dugeon in 15 minutes teleport back to fromPos
                -- add a PLAYER storage to set exausted for this task (24 hours)
                -- add a GLOBAL storage to block dugeon to no other team enter, if there is a team inside
            end

    end
    return true
end
<action actionid="9603" script="dugeonsystem_chest.lua"/>
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    -- STORAGE
    local storage = 9603
    -- check if player is in a dugeon (to avoid abuses)
    -- check if player is in a dugeon exausted (to avoid aabuses)
    -- ITEMS
    local rewardid = random rewards
    if getPlayerFreeCap(cid) >= getItemWeightById(rewardid, 1) then
    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have found a '..getItemNameById(rewardid)..'. It weighs '..getItemWeightById(rewardid, 1)..'.00 and it is too heavy.')
    return false
    end
    doPlayerAddItem(cid, rewardid, 1)
    -- STOP auto teleport OUT (15 min inside with no complete, teleport out...)
    -- teleport player topos
    return true
end
edit: I'm using 0.4 sources
 
Last edited:

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
Hi zabuzo

I like of your ideia, is really a cool thing to have in a RPG server. And the fact that you create a pseudo code with the schematic of things is really nice. This is not a very small system, although it can be made in a very simple way. For now I don't have time to work on this, but I can contribute with some code sometimes, so maybe we can collaborate on this.

As an start I offer to you the lib/dungeon_system.lua. This will create a Dungeon element to store all the data about a specific dungeon, and methods to make it work without polluting others scripts. Check this out:


Lua:
local dungeons = {}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }

    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end

    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end

    -- Add a player to dungeon
    function this.addPlayer(self, player)
        if player:isPlayer() and not self:isFull() then
            local level = player:getLevel()
            if level > this.maxLevel or level < this.minLevel then
                player:sendCancelMessage("You can't do this dungeon")
                return false
            end

            local vocation = this.getPlayerBaseVocation(player)
            if vocation:getName() == "knight" and not this.knight then
                this.knight = player
            elseif vocation:getName() == "druid" and not this.druid then
                this.druid = player
            elseif vocation:getName() == "paladin" and not this.paladin then
                this.paladin = player
            elseif vocation:getName() == "sorcerer" and not this.sorcerer then
                this.sorcerer = player
            end
            return true
        end
        return false
    end

    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end

    -- Finish the dungeon giving the prizes
    function this.finish(self)

    end

    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local tile = Tile(position)
            if tile then
                local topPlayer = Player(tile:getTopCreature())
                if topPlayer then
                    if topPlayer:getLevel() >= self.minLevel and topPlayer:getLevel() <= self.maxLevel then
                        this:addPlayer(topPlayer)
                    end
                end
            end
            -- Lets check next
            position.y = y
        end

        if this:isFull() then
            return true
        end

        this:clearPlayers()
        return false
    end

    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[2])
                sorcerer:teleportTo(positions[3])
                paladin:teleportTo(positions[4])
            elseif #positions == 1 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[1])
                sorcerer:teleportTo(positions[1])
                paladin:teleportTo(positions[1])
            end
        end
    end

    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(player)
        local vocation = player:getVocation()
        while(vocation:getDemotion()) do
            vocation = vocation:getDemotion()
        end
        return vocation
    end

    return this
end
So you use like this. In somewhere you create a Dungeon(name, minLevel, maxLevel, rewards) obj as global:
Lua:
g_Dungeons = {
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}
And use in the lever script like:
Lua:
if g_Dungeons.Dragons:checkRow({x = 952, y = 1039, z = 7}) then
    g_Dungeons.Dragons:teleportTo({{x = 952, y = 1039, z = 6}, {x = 953, y = 1039, z = 6}, {x = 954, y = 1039, z = 6}, {x = 955, y = 1039, z = 6}})
    g_Dungeons.Dragons:start()
end
And to finish something like:
Lua:
g_Dungeons.Dragons.teleportTo({{x = 952, y = 1039, z = 7}, {x = 953, y = 1039, z = 7}, {x = 954, y = 1039, z = 7}, {x = 955, y = 1039, z = 7}})
g_Dungeons.Dragons.finish()
In start and finish we should implement things like add/remove a storage, un/registering a event to check if is on dungeon and things like that

!CAUTION! : This is a experimental code, not fully tested, can have many errors and is incomplete.
@NOTE 1: As you don't say for what version of TFS I made this assuming something like 1.2/1.3
@NOTE 2: I can't test this in a OT. But is free of lua syntax errors as checked with lua 5.1 interpreter
@NOTE 3: This is very simple, and only assume the 4 vocations case

Good lucky with this buddy. Would be nice to have such a system for the community to use
 

supergt

Member
Joined
May 11, 2017
Messages
65
Reaction score
22
I'm 100% percent uses this if had a system works to 0.4...

A better way to kick players from dugeon was set cave no logout zone
Add global storage to server, anyway idk how to do, just giving a idea...
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
But setting no logout zone will only make the char keep up, even if the client goes x closed no? If it really kicks, this will be a clever idea

Nice to see that you would use this supergt. I don't see why we can't make this for 1.2/1.3 and for 0.4 too. I will try to make better solution for positions and vocations, and also make it compatible, or a version separated for 0.4 so you can try it out. Just need to have some free time for this
 

supergt

Member
Joined
May 11, 2017
Messages
65
Reaction score
22
But setting no logout zone will only make the char keep up, even if the client goes x closed no? If it really kicks, this will be a clever idea

Nice to see that you would use this supergt. I don't see why we can't make this for 1.2/1.3 and for 0.4 too. I will try to make better solution for positions and vocations, and also make it compatible, or a version separated for 0.4 so you can try it out. Just need to have some free time for this
Thats true, players also need a storage to get kicked off...
 
OP
zabuzo

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
@TheRatazana thank you so much to this base

Fuck, i should say that i'm using 0.4 source pack (topic edited)

So to use this i have to add
data/lib/dungeon_system.lua
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }
    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end
    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end
    -- Add a player to dungeon
    function this.addPlayer(self, player)
        if player:isPlayer() and not self:isFull() then
            local level = player:getLevel()
            if level > this.maxLevel or level < this.minLevel then
                player:sendCancelMessage("You can't do this dungeon")
                return false
            end
            local vocation = this.getPlayerBaseVocation(player)
            if vocation:getName() == "knight" and not this.knight then
                this.knight = player
            elseif vocation:getName() == "druid" and not this.druid then
                this.druid = player
            elseif vocation:getName() == "paladin" and not this.paladin then
                this.paladin = player
            elseif vocation:getName() == "sorcerer" and not this.sorcerer then
                this.sorcerer = player
            end
            return true
        end
        return false
    end
    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end
    -- Finish the dungeon giving the prizes
    function this.finish(self)
    end
    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local tile = Tile(position)
            if tile then
                local topPlayer = Player(tile:getTopCreature())
                if topPlayer then
                    if topPlayer:getLevel() >= self.minLevel and topPlayer:getLevel() <= self.maxLevel then
                        this:addPlayer(topPlayer)
                    end
                end
            end
            -- Lets check next
            position.y = y
        end
        if this:isFull() then
            return true
        end
        this:clearPlayers()
        return false
    end
    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[2])
                sorcerer:teleportTo(positions[3])
                paladin:teleportTo(positions[4])
            elseif #positions == 1 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[1])
                sorcerer:teleportTo(positions[1])
                paladin:teleportTo(positions[1])
            end
        end
    end
    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(player)
        local vocation = player:getVocation()
        while(vocation:getDemotion()) do
            vocation = vocation:getDemotion()
        end
        return vocation
    end
    return this
end
And on actions:
<action actionid="9602" script="dungeon_lever.lua"/>
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
   if g_Dungeons.Dragons:checkRow({x = 952, y = 1039, z = 7}) then
       g_Dungeons.Dragons:teleportTo({{x = 952, y = 1039, z = 6}, {x = 953, y = 1039, z = 6}, {x = 954, y = 1039, z = 6}, {x = 955, y = 1039, z = 6}})
       g_Dungeons.Dragons:start()
   end
end
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
Yes. Should be this way. But since you are using 0.4 you will need to change things from Player to cid, and use like doTeleportThing passing cid instead of player:teleportTo()
 
OP
zabuzo

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
Yes. Should be this way. But since you are using 0.4 you will need to change things from Player to cid, and use like doTeleportThing passing cid instead of player:teleportTo()
Did u know about 0.4 sources?
Idk if the problem is i'm trying to convert or another problem...

But using this:

@TheRatazana thank you so much to this base

Fuck, i should say that i'm using 0.4 source pack (topic edited)

So to use this i have to add
data/lib/dungeon_system.lua
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }
    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end
    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end
    -- Add a player to dungeon
    function this.addPlayer(self, player)
        if player:isPlayer() and not self:isFull() then
            local level = player:getLevel()
            if level > this.maxLevel or level < this.minLevel then
                player:sendCancelMessage("You can't do this dungeon")
                return false
            end
            local vocation = this.getPlayerBaseVocation(player)
            if vocation:getName() == "knight" and not this.knight then
                this.knight = player
            elseif vocation:getName() == "druid" and not this.druid then
                this.druid = player
            elseif vocation:getName() == "paladin" and not this.paladin then
                this.paladin = player
            elseif vocation:getName() == "sorcerer" and not this.sorcerer then
                this.sorcerer = player
            end
            return true
        end
        return false
    end
    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end
    -- Finish the dungeon giving the prizes
    function this.finish(self)
    end
    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local tile = Tile(position)
            if tile then
                local topPlayer = Player(tile:getTopCreature())
                if topPlayer then
                    if topPlayer:getLevel() >= self.minLevel and topPlayer:getLevel() <= self.maxLevel then
                        this:addPlayer(topPlayer)
                    end
                end
            end
            -- Lets check next
            position.y = y
        end
        if this:isFull() then
            return true
        end
        this:clearPlayers()
        return false
    end
    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[2])
                sorcerer:teleportTo(positions[3])
                paladin:teleportTo(positions[4])
            elseif #positions == 1 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[1])
                sorcerer:teleportTo(positions[1])
                paladin:teleportTo(positions[1])
            end
        end
    end
    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(player)
        local vocation = player:getVocation()
        while(vocation:getDemotion()) do
            vocation = vocation:getDemotion()
        end
        return vocation
    end
    return this
end
And on actions:
<action actionid="9602" script="dungeon_lever.lua"/>
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
   if g_Dungeons.Dragons:checkRow({x = 952, y = 1039, z = 7}) then
      g_Dungeons.Dragons:teleportTo({{x = 952, y = 1039, z = 6}, {x = 953, y = 1039, z = 6}, {x = 954, y = 1039, z = 6}, {x = 955, y = 1039, z = 6}})
       g_Dungeons.Dragons:start()
   end
end
The server is not open, just freeze in:
Code:
./tfs
[13:5:18.029] The Forgotten Server 0.4

[13:5:18.029] >> Loading config (config.lua)
[13:5:18.056] >> Opening logs

>> Loading Demon Oak Lib V0.70 REV: 1 (June 26 2012) By Darkhaos (Contact: http://otland.net/members/darkhaos/)

[!] -> Checking demon oak lib...
[!] -> 0 problems loaded in 8.9000000000002e-05 seconds.

[!] -> Demon Oak Lib loaded in 0.000483 seconds.

[13:5:18.071] >> Opening logs

^C
Somebody could help me to convert it to 0.4?
Searching i found:
player:isPlayer()
In some way have to be:
isPlayer(player)

But idk what more have to be changed
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
Hi zabuzo. So, you can try this:

Lua:
local dungeons = {}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }

    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end

    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end

    -- Add a player to dungeon
    function this.addPlayer(self, cid)
        if isPlayer(cid) and not self:isFull() then
            local level = getPlayerLevel(cid)
            if level > this.maxLevel or level < this.minLevel then
                doPlayerSendTextMessage(cid, MSG_STATUS_DEFAULT,"You can't do this dungeon")
                return false
            end

            local vocation = getVocationInfo(this.getPlayerBaseVocation(cid))
            if vocation.name == "knight" and not this.knight then
                this.knight = cid
            elseif vocation.name == "druid" and not this.druid then
                this.druid = cid
            elseif vocation.name() == "paladin" and not this.paladin then
                this.paladin = cid
            elseif vocation.name() == "sorcerer" and not this.sorcerer then
                this.sorcerer = cid
            end
            return true
        end
        return false
    end

    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end

    -- Finish the dungeon giving the prizes
    function this.finish(self)

    end

    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local topPlayer = getTopCreature(pos)
            if topPlayer and isPlayer(topPlayer) then
                if getPlayerLevel(cid) >= self.minLevel and getPlayerLevel(cid) <= self.maxLevel then
                    this:addPlayer(topPlayer)
                end
            end
            -- Lets check next
            position.y = y
        end

        if this:isFull() then
            return true
        end

        this:clearPlayers()
        return false
    end

    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[2])
                doTeleportThing(this.sorcerer, positions[3])
                doTeleportThing(this.paladin, positions[4])
            elseif #positions == 1 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[1])
                doTeleportThing(this.sorcerer, positions[1])
                doTeleportThing(this.paladin, positions[1])
            end
        end
    end

    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(cid)
        local vocation = getPlayerVocation(cid)
        while(getVocationInfo(vocation).fromVocation ~= 0) do
            vocation = getVocationInfo(vocation).fromVocation
        end
        return vocation
    end

    return this
end

I tried to convert to 0.4. When I need to create something to 0.4 I use this source code:
luanluciano93/TFS_0.4_3777

Specially the luascript.cpp, const.h and enums.h. Very helpful
 
OP
zabuzo

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
Hi zabuzo. So, you can try this:

Lua:
local dungeons = {}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }

    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end

    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end

    -- Add a player to dungeon
    function this.addPlayer(self, cid)
        if isPlayer(cid) and not self:isFull() then
            local level = getPlayerLevel(cid)
            if level > this.maxLevel or level < this.minLevel then
                doPlayerSendTextMessage(cid, MSG_STATUS_DEFAULT,"You can't do this dungeon")
                return false
            end

            local vocation = getVocationInfo(this.getPlayerBaseVocation(cid))
            if vocation.name == "knight" and not this.knight then
                this.knight = cid
            elseif vocation.name == "druid" and not this.druid then
                this.druid = cid
            elseif vocation.name() == "paladin" and not this.paladin then
                this.paladin = cid
            elseif vocation.name() == "sorcerer" and not this.sorcerer then
                this.sorcerer = cid
            end
            return true
        end
        return false
    end

    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end

    -- Finish the dungeon giving the prizes
    function this.finish(self)

    end

    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local topPlayer = getTopCreature(pos)
            if topPlayer and isPlayer(topPlayer) then
                if getPlayerLevel(cid) >= self.minLevel and getPlayerLevel(cid) <= self.maxLevel then
                    this:addPlayer(topPlayer)
                end
            end
            -- Lets check next
            position.y = y
        end

        if this:isFull() then
            return true
        end

        this:clearPlayers()
        return false
    end

    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[2])
                doTeleportThing(this.sorcerer, positions[3])
                doTeleportThing(this.paladin, positions[4])
            elseif #positions == 1 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[1])
                doTeleportThing(this.sorcerer, positions[1])
                doTeleportThing(this.paladin, positions[1])
            end
        end
    end

    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(cid)
        local vocation = getPlayerVocation(cid)
        while(getVocationInfo(vocation).fromVocation ~= 0) do
            vocation = getVocationInfo(vocation).fromVocation
        end
        return vocation
    end

    return this
end

I tried to convert to 0.4. When I need to create something to 0.4 I use this source code:
luanluciano93/TFS_0.4_3777

Specially the luascript.cpp, const.h and enums.h. Very helpful

It's freezing and not open after add:
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}
function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }
    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end
    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end
    -- Add a player to dungeon
    function this.addPlayer(self, cid)
        if isPlayer(cid) and not self:isFull() then
            local level = getPlayerLevel(cid)
            if level > this.maxLevel or level < this.minLevel then
                doPlayerSendTextMessage(cid, MSG_STATUS_DEFAULT,"You can't do this dungeon")
                return false
            end
            local vocation = getVocationInfo(this.getPlayerBaseVocation(cid))
            if vocation.name == "knight" and not this.knight then
                this.knight = cid
            elseif vocation.name == "druid" and not this.druid then
                this.druid = cid
            elseif vocation.name() == "paladin" and not this.paladin then
                this.paladin = cid
            elseif vocation.name() == "sorcerer" and not this.sorcerer then
                this.sorcerer = cid
            end
            return true
        end
        return false
    end
    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end
    -- Finish the dungeon giving the prizes
    function this.finish(self)
    end
    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local topPlayer = getTopCreature(pos)
            if topPlayer and isPlayer(topPlayer) then
                if getPlayerLevel(cid) >= self.minLevel and getPlayerLevel(cid) <= self.maxLevel then
                    this:addPlayer(topPlayer)
                end
            end
            -- Lets check next
            position.y = y
        end
        if this:isFull() then
            return true
        end
        this:clearPlayers()
        return false
    end
    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[2])
                doTeleportThing(this.sorcerer, positions[3])
                doTeleportThing(this.paladin, positions[4])
            elseif #positions == 1 then
                doTeleportThing(this.druid, positions[1])
                doTeleportThing(this.knight, positions[1])
                doTeleportThing(this.sorcerer, positions[1])
                doTeleportThing(this.paladin, positions[1])
            end
        end
    end
    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(cid)
        local vocation = getPlayerVocation(cid)
        while(getVocationInfo(vocation).fromVocation ~= 0) do
            vocation = getVocationInfo(vocation).fromVocation
        end
        return vocation
    end
    return this
end
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
Sorry, but I can't help then. I know that the code is free of syntax errors and that the function dungeon works well even with lua 5.1. Maybe you're using a version more old? Is weird because there is not loop outside function declarations. And this local in dungeons or g_dungeons is an error I made. I was planning to use this as local and get dungeons through some other way, but is more complicated, just using g_dungeons = {} is better, just don't put local on it, or you will can't access this in others scripts.
 

supergt

Member
Joined
May 11, 2017
Messages
65
Reaction score
22
Sorry, but I can't help then. I know that the code is free of syntax errors and that the function dungeon works well even with lua 5.1. Maybe you're using a version more old? Is weird because there is not loop outside function declarations. And this local in dungeons or g_dungeons is an error I made. I was planning to use this as local and get dungeons through some other way, but is more complicated, just using g_dungeons = {} is better, just don't put local on it, or you will can't access this in others scripts.
I don't undertood, the dungeons should not be added on
Code:
[LIST=1]
[*]local g_Dungeons = {
[*]    -- Dungeon(name, minLevel, maxLevel, rewards)
[*]    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
[*]}
[*]function Dungeon(name, minLevel, maxLevel, rewards)
[*]    local this = {
[*]        name = name or "unamed",
[/LIST]
???

Lib are not public to use in all others scripts (actions,movemments...) !?
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
1 - Yes, they should be added there. But not using the keyword 'local' in front of g_Dungeons. This was a mistake I made for not maki the things clearly at first

2 - Yes, they are. If not declared as local, an variable from some lib is available for all other scripts, but if declared as local it's only visible for the functions and routines in that specific lib file. In the first, I was going to use a local dungeons var to store dungeons and some other global methods to add and remove from it. But only using a non-local g_Dungeons is more easy, and I forgot to remove that, what cause confusion I think

Understood now?
 

supergt

Member
Joined
May 11, 2017
Messages
65
Reaction score
22
1 - Yes, they should be added there. But not using the keyword 'local' in front of g_Dungeons. This was a mistake I made for not maki the things clearly at first

2 - Yes, they are. If not declared as local, an variable from some lib is available for all other scripts, but if declared as local it's only visible for the functions and routines in that specific lib file. In the first, I was going to use a local dungeons var to store dungeons and some other global methods to add and remove from it. But only using a non-local g_Dungeons is more easy, and I forgot to remove that, what cause confusion I think

Understood now?
Hmm ty..

So you are suggesting to declare the g_Dungeons as a global variable?
I mean, just omiting the local?
Code:
g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}
function Dungeon(name, minLevel, maxLevel, rewards)
To use in the others scripts? I think there is some sintaxy error, because doing this, the server still not openning
 
OP
zabuzo

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
Yes. Sadly I don't have a 0.4 to test this, but I can guarantee that it works with lua 5.1 so it's weird why is doing this. Look at the attached image
Strange... Idk about this, but anyone else could show why if we use this lib:
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }
    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end
    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end
    -- Add a player to dungeon
    function this.addPlayer(self, player)
        if player:isPlayer() and not self:isFull() then
            local level = player:getLevel()
            if level > this.maxLevel or level < this.minLevel then
                player:sendCancelMessage("You can't do this dungeon")
                return false
            end
            local vocation = this.getPlayerBaseVocation(player)
            if vocation:getName() == "knight" and not this.knight then
                this.knight = player
            elseif vocation:getName() == "druid" and not this.druid then
                this.druid = player
            elseif vocation:getName() == "paladin" and not this.paladin then
                this.paladin = player
            elseif vocation:getName() == "sorcerer" and not this.sorcerer then
                this.sorcerer = player
            end
            return true
        end
        return false
    end
    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end
    -- Finish the dungeon giving the prizes
    function this.finish(self)
    end
    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local tile = Tile(position)
            if tile then
                local topPlayer = Player(tile:getTopCreature())
                if topPlayer then
                    if topPlayer:getLevel() >= self.minLevel and topPlayer:getLevel() <= self.maxLevel then
                        this:addPlayer(topPlayer)
                    end
                end
            end
            -- Lets check next
            position.y = y
        end
        if this:isFull() then
            return true
        end
        this:clearPlayers()
        return false
    end
    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[2])
                sorcerer:teleportTo(positions[3])
                paladin:teleportTo(positions[4])
            elseif #positions == 1 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[1])
                sorcerer:teleportTo(positions[1])
                paladin:teleportTo(positions[1])
            end
        end
    end
    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(player)
        local vocation = player:getVocation()
        while(vocation:getDemotion()) do
            vocation = vocation:getDemotion()
        end
        return vocation
    end
    return this
end
The server just not open?
 
OP
zabuzo

zabuzo

Member
Joined
Jun 10, 2016
Messages
116
Reaction score
16
What distro do you guys use? I downloaded and compiled the fir3element 3777 distro and started with library. The server doesn't hangup, but it appear to load the library 7 times when loading the script system and one more time after loading the map. Look at the ss:
I do using the same source, are u using this lib?
Code:
local g_Dungeons = {
    -- Dungeon(name, minLevel, maxLevel, rewards)
    Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
}

function Dungeon(name, minLevel, maxLevel, rewards)
    local this = {
        name = name or "unamed",
        minLevel = minLevel or 1,
        maxLevel = maxLevel or 1,
        rewards = rewards or {},
        druid = nil,
        knight = nil,
        sorcerer = nil,
        paladin = nil
    }
    -- Check if all positions are occuped
    function this.isFull(self)
        return self.druid and self.knight and self.sorcerer and self.paladin
    end
    -- Start dungeon teleporting the players and setting additional events
    function this.start(self)
        if self:isFull() then
        end
    end
    -- Add a player to dungeon
    function this.addPlayer(self, player)
        if player:isPlayer() and not self:isFull() then
            local level = player:getLevel()
            if level > this.maxLevel or level < this.minLevel then
                player:sendCancelMessage("You can't do this dungeon")
                return false
            end
            local vocation = this.getPlayerBaseVocation(player)
            if vocation:getName() == "knight" and not this.knight then
                this.knight = player
            elseif vocation:getName() == "druid" and not this.druid then
                this.druid = player
            elseif vocation:getName() == "paladin" and not this.paladin then
                this.paladin = player
            elseif vocation:getName() == "sorcerer" and not this.sorcerer then
                this.sorcerer = player
            end
            return true
        end
        return false
    end
    -- Clear the players on dungeon
    function this.clearPlayers(self)
        self.knight = nil
        self.druid = nil
        self.sorcerer = nil
        self.paladin = nil
    end
    -- Finish the dungeon giving the prizes
    function this.finish(self)
    end
    -- This will perform a check in a row style looking for player meeting the requirements
    -- returns true if the isFull, otherwise returns false and clear the players from dungeon obj
    function this.checkRow(self, position)
        for y = position.y, position.y + 4 do
            local tile = Tile(position)
            if tile then
                local topPlayer = Player(tile:getTopCreature())
                if topPlayer then
                    if topPlayer:getLevel() >= self.minLevel and topPlayer:getLevel() <= self.maxLevel then
                        this:addPlayer(topPlayer)
                    end
                end
            end
            -- Lets check next
            position.y = y
        end
        if this:isFull() then
            return true
        end
        this:clearPlayers()
        return false
    end
    -- Teleport all the participantes to the passed destinations
    -- positions is a table of positions = {{x,y,z},{x,y,z}}
    function this.teleportTo(positions)
        if this.isFull() then
            if #positions >=4 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[2])
                sorcerer:teleportTo(positions[3])
                paladin:teleportTo(positions[4])
            elseif #positions == 1 then
                druid:teleportTo(positions[1])
                knight:teleportTo(positions[1])
                sorcerer:teleportTo(positions[1])
                paladin:teleportTo(positions[1])
            end
        end
    end
    -- This return the base vocation from a passed player
    function this.getPlayerBaseVocation(player)
        local vocation = player:getVocation()
        while(vocation:getDemotion()) do
            vocation = vocation:getDemotion()
        end
        return vocation
    end
    return this
end
With a dugeon configured?

I mean
Code:
Dragons = Dungeon("Dragons", 15, 30, {1100, 1101, 1102})
 

TheRatazana

Member
Joined
Feb 5, 2015
Messages
37
Reaction score
29
Yes, exactly the same. Maybe could be a lib conflict then, since I using the default libs of distro and you're probably using others libs with it?
 
Top