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

Capture The Flag

It is possible that it asks for an object to be able to do the event, I am testing it seems to work wellotland.png
I think it is not compatible with the canary version

I have only been able to observe 2 failures you can change color test character no gm and when you die you lose level
to die do not return to the event but thais
 
Last edited:
It is possible that it asks for an object to be able to do the event, I am testing it seems to work wellView attachment 68181
I think it is not compatible with the canary version

I have only been able to observe 2 failures you can change color test character no gm and when you die you lose level
to die do not return to the event but thais
Send me a PM and post your data/events/scripts/creature.lua (before you modified with this system)
 
Cool Release thanks and reviewed the psot from jhonsamir and it's working cool
 
Last edited:
Send me a PM and post your data/events/scripts/creature.lua (before you modified with this system)
How do i instantly close event after end? Instead of closing it with the gm?
Could be possible to create a teleport in every temple town instead of command?(!ctf join)
so few minutes before start a teleport gets created, player gets in and are being sent to the waiting room of their respective team. that way it wont be possible to teleport pekers or players that are in X scenarios
and players need to retype !ctf leave. how to do so this command get executed for every player after event ends?
 
error
Lua:
Lua Script Error: [Scripts Interface]
/home/otserv/data/scripts/ctf.lua:callback
/home/otserv/data/scripts/ctf.lua:257: attempt to index global 'posMax' (a nil v                  alue)
stack traceback:
        [C]: in function '__index'
        /home/otserv/data/scripts/ctf.lua:257: in function </home/otserv/data/sc                  ripts/ctf.lua:240>
 
This is a remake of my previous version. This CTF system uses outfits to show which team the players are on.

Check here for a list of features: TFS 1.3 Capture the Flag (https://otland.net/threads/tfs-1-3-capture-the-flag.271357/)

Key differences:
1) Outfits instead of skulls
2) Multiple respawn positions
3) Cannot attack allies
4) Cannot change outfit while in CTF
5) More testing/less bugs
6) Revscript


MAKE SURE THE CTF AREA IS NO LOGOUT

Add a file in data/libs and include it in data/libs/libs.lua

Add a folder/file in data/scripts named ctf and add this
Lua:
--- TALKACTION --
local ctfTalk = TalkAction("!ctf", "!CTF")

function ctfTalk.onSay(player, words, param)
    if param == "enter" then
        for i = 1, #CTF_PLAYERS_QUEUE do
            if CTF_PLAYERS_QUEUE[i] == player:getName() then
                player:sendCancelMessage("You are already queued for capture the flag.")
                return false
            end
        end
       
        if player:getLevel() < CTF_LEVEL_REQ then
            player:sendCancelMessage("You must be level "..CTF_LEVEL_REQ.." to enter capture the flag.")
            return false
        end
     
        CTF_PLAYERS_QUEUE[#CTF_PLAYERS_QUEUE + 1] = player:getName()
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You are now queued for capture the flag. You may type !ctf leave to leave the queue.")
    elseif param == "leave" then
        for i = 1, #CTF_PLAYERS_QUEUE do
            if CTF_PLAYERS_QUEUE[i] == player:getName() then
                CTF_PLAYERS_QUEUE[i] = nil
                player:sendCancelMessage("You have left the capture the flag queue.")
                return false
            end
        end
    
        player:sendCancelMessage("You are not queued in capture the flag.")
        return false
     
    elseif param == "start" then
        if not player:getGroup():getAccess() then
            return true
        end

        if player:getAccountType() < ACCOUNT_TYPE_GOD then
            return true
        end
       
        if CTF_STATUS > 0 then
            player:sendCancelMessage("Capture the flag is already started.")
            return false
        end
     
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in " ..CTF_CHECK_QUEUE.. " minutes.")
        CTF_STATUS = 1
        CTF_GREEN_TEAM_PLAYERS = {}
        CTF_RED_TEAM_PLAYERS = {}
        CTF_PLAYER_OUTFITS = {}
        CTF_GREEN_SCORE = 0
        CTF_RED_SCORE = 0
        CTF_GREEN_FLAG_HOLDER = nil
        CTF_RED_FLAG_HOLDER = nil
        addEvent(checkCTFPlayers, CTF_CHECK_QUEUE * 60 * 1000)
     
    elseif param == "cancel" or param == "stop" then
        if not player:getGroup():getAccess() then
            return true
        end

        if player:getAccountType() < ACCOUNT_TYPE_GOD then
            return true
        end
     
        stopCTF()
    end
    return false
end

ctfTalk:separator(" ")
ctfTalk:register()

-- GLOBALEVENT --
local ctfGlobal = GlobalEvent("CTF_GLOBAL")

function ctfGlobal.onThink(...)
    if CTF_STATUS == 0 then
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.", 1)
        addEvent(checkCTFPlayers, 1 * 60 * 1000)
    end
 
    if CTF_GREEN_FLAG_HOLDER then
        local player = Player(CTF_GREEN_FLAG_HOLDER)
     
        if player then
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
        end
    end
 
    if CTF_RED_FLAG_HOLDER then
        local player = Player(CTF_RED_FLAG_HOLDER)
     
        if player then
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
        end
    end
    return true
end

ctfGlobal:interval(1000)
ctfGlobal:register()

-- ACTION --
local ctfAction = Action()

function ctfAction.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == CTF_GREEN_FLAGID then
        if isGreenTeam(player:getName()) then
            if item:getPosition() == CTF_GREEN_FLAG_POSITION then
                return player:sendCancelMessage("You cannot pick up your own flag.")
            else
                item:moveTo(CTF_GREEN_FLAG_POSITION)
                broadcastToCTFPlayers(CTF_MSG_FLAG_RETRUNED_GREEN)
            end
        else
            CTF_GREEN_FLAG_HOLDER = player:getName()
            item:remove()
            broadcastToCTFPlayers("The green flag has been taken by "..player:getName().."!")
        end
 
    elseif item.itemid == CTF_RED_FLAGID then
        if isRedTeam(player:getName()) then
            if item:getPosition() == CTF_RED_FLAG_POSITION then
                return player:sendCancelMessage("You cannot pick up your own flag.")
            else
                item:moveTo(CTF_RED_FLAG_POSITION)
                broadcastToCTFPlayers(CTF_MSG_FLAG_RETRUNED_RED)
             
            end
        else
            CTF_RED_FLAG_HOLDER = player:getName()
            item:remove()
            broadcastToCTFPlayers("The red flag has been taken by "..player:getName().."!")
        end
    end
    return true
end

ctfAction:aid(CTF_ACTIONID)
ctfAction:register()

-- Moveevent --
local ctfMovement = MoveEvent()

function ctfMovement.onStepIn(creature, item, position, fromPosition)
    local player = Player(creature)
 
    if not player then return true end

    if item.itemid == CTF_GREEN_CAPTURE_TILE_ID and item.actionid == CTF_ACTIONID and item:getPosition() == CTF_GREEN_CAPTURE_TILE_POS then
        if isGreenTeam(player:getName()) then
            if CTF_RED_FLAG_HOLDER ~= player:getName() then
                player:teleportTo(fromPosition, true)
                player:sendCancelMessage("You cannot stand on your capture tile.")
                return false
            else
                player:teleportTo(fromPosition, true)
                CTF_RED_FLAG_HOLDER = nil
                CTF_GREEN_SCORE = CTF_GREEN_SCORE + 1
                local flag = Game.createItem(CTF_RED_FLAGID, 1, CTF_RED_FLAG_POSITION)
                flag:setAttribute('aid', CTF_ACTIONID)
             
                if CTF_GREEN_SCORE == CTF_WIN_SCORE then
                    stopCTF()
                    return true
                end
             
                broadcastToCTFPlayers(CTF_MSG_FLAG_CAPTURED_GREEN.." The green team now has "..CTF_GREEN_SCORE.." point(s).")
            end
             
        else
            player:teleportTo(fromPosition, true)
            player:sendCancelMessage("You cannot stand on the green teams capture tile.")
            return false
        end
     
    elseif item.itemid == CTF_RED_CAPTURE_TILE_ID and item.actionid == CTF_ACTIONID and item:getPosition() == CTF_RED_CAPTURE_TILE_POS then
        if isRedTeam(player:getName()) then
            if CTF_GREEN_FLAG_HOLDER ~= player:getName() then
                player:teleportTo(fromPosition, true)
                player:sendCancelMessage("You cannot stand on your capture tile.")
                return false
            else
                player:teleportTo(fromPosition, true)
                CTF_GREEN_FLAG_HOLDER = nil
                CTF_RED_SCORE = CTF_RED_SCORE + 1
                local flag = Game.createItem(CTF_GREEN_FLAGID, 1, CTF_GREEN_FLAG_POSITION)
                flag:setAttribute('aid', CTF_ACTIONID)
             
                if CTF_RED_SCORE == CTF_WIN_SCORE then
                    stopCTF()
                    return true
                end
             
                broadcastToCTFPlayers(CTF_MSG_FLAG_CAPTURED_RED.." The red team now has "..CTF_RED_SCORE.." point(s).")
            end
             
        else
            player:teleportTo(fromPosition, true)
            player:sendCancelMessage("You cannot stand on the red teams capture tile.")
            return false
        end
    end
    return true
end

ctfMovement:aid(CTF_ACTIONID)
ctfMovement:register()

-- CreatureEvents --
local ctfPrepareDeath = CreatureEvent("CTF_PREPAREDEATH")

function ctfPrepareDeath.onPrepareDeath(creature, killer)
    if not creature:isPlayer() then return true end
 
    local player = Player(creature)
 
    if isGreenTeam(player:getName()) then
        if CTF_RED_FLAG_HOLDER and CTF_RED_FLAG_HOLDER == player:getName() then
            CTF_RED_FLAG_HOLDER = nil
            local flag = Game.createItem(CTF_RED_FLAGID, 1, player:getPosition())
            flag:setAttribute('aid', CTF_ACTIONID)
        end
        player:addHealth(999999)
        player:addMana(999999)
       
        local randSpawn = math.random(3)
        local posMin = CTF_RESPAWN_POSITIONS.GREEN_TEAM[randSpawn].min
        local posMan = CTF_RESPAWN_POSITIONS.GREEN_TEAM[randSpawn].max
        local spawnPos = Position(math.random(posMin.x, posMax.x), math.random(posMin.y, posMax.y), math.random(posMin.z, posMax.z))
        player:teleportTo(spawnPos)
        return false
 
    elseif isRedTeam(player:getName()) then
        if CTF_GREEN_FLAG_HOLDER and CTF_GREEN_FLAG_HOLDER == player:getName() then
            CTF_GREEN_FLAG_HOLDER = nil
            local flag = Game.createItem(CTF_GREEN_FLAGID, 1, player:getPosition())
            flag:setAttribute('aid', CTF_ACTIONID)
        end
        player:addHealth(999999)
        player:addMana(999999)
       
        local randSpawn = math.random(3)
        local posMin = CTF_RESPAWN_POSITIONS.RED_TEAM[randSpawn].min
        local posMax = CTF_RESPAWN_POSITIONS.RED_TEAM[randSpawn].max
        local spawnPos = Position(math.random(posMin.x, posMax.x), math.random(posMin.y, posMax.y), math.random(posMin.z, posMax.z))
        player:teleportTo(spawnPos)
        return false
    end
    return true
end

ctfPrepareDeath:register()

In data/creaturescripts/scripts/login.lua add
Lua:
player:registerEvent("CTF_PREPAREDEATH")

In data/events/scripts/creature.lua
Lua:
function Creature:onChangeOutfit(outfit)
    local player = Player(self)
    if player and CTF_STATUS == 2 then
        if isGreenTeam(player:getName()) or isRedTeam(player:getName()) then
            player:sendCancelMessage("You cannot change outfit while in capture the flag.")
        return false
        end
    end

    if hasEventCallback(EVENT_CALLBACK_ONCHANGEMOUNT) then
        if not EventCallback(EVENT_CALLBACK_ONCHANGEMOUNT, self, outfit.lookMount) then
            return false
        end
    end
    if hasEventCallback(EVENT_CALLBACK_ONCHANGEOUTFIT) then
        return EventCallback(EVENT_CALLBACK_ONCHANGEOUTFIT, self, outfit)
    else
        return true
    end
end

function Creature:onAreaCombat(tile, isAggressive)
    local player = Player(self)
    local target = tile:getTopCreature()
    if player and target and CTF_STATUS == 2 then
        if isGreenTeam(player:getName()) and isGreenTeam(target:getName()) then
            return false
        elseif isRedTeam(player:getName()) and isRedTeam(target:getName()) then
            return false
        end
    end

    if hasEventCallback(EVENT_CALLBACK_ONAREACOMBAT) then
        return EventCallback(EVENT_CALLBACK_ONAREACOMBAT, self, tile, isAggressive)
    else
        return RETURNVALUE_NOERROR
    end
end

function Creature:onTargetCombat(target)
    local player = Player(self)
    if player and target and CTF_STATUS == 2 then
        if isGreenTeam(player:getName()) and isGreenTeam(target:getName()) then
            return false
        elseif isRedTeam(player:getName()) and isRedTeam(target:getName()) then
            return false
        end
    end

    if hasEventCallback(EVENT_CALLBACK_ONTARGETCOMBAT) then
        return EventCallback(EVENT_CALLBACK_ONTARGETCOMBAT, self, target)
    else
        return RETURNVALUE_NOERROR
    end
end

Make sure you enable the events in data/events/events.xml
XML:
    <event class="Creature" method="onChangeOutfit" enabled="1" />
    <event class="Creature" method="onAreaCombat" enabled="1" />
    <event class="Creature" method="onTargetCombat" enabled="1" />

Let me know if there are any issues. Hope people use it.
Hello, I hope you are well and I hope you continue to support this system, I tried to install it but I don't know if I did something wrong or what could be happening, I leave you the error, thanks in advance if you manage to help me, I use TFS 1.3

rtutrutrur.png
 
Back
Top