• 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

Itutorial

Excellent OT User
Joined
Dec 23, 2014
Messages
2,307
Solutions
68
Reaction score
981
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.
 
this version was very good, congratulations for bringing so much valuable content here to the forum!

Is there any possibility of you putting these features in your 1.3 version?
 
I'm having problem configuring this if im in green team and i want to step in tileid 415 with AID 5675 receive message "you cannot stand on your caputure tile"
and if go to red team 415 id AID 5675 receive message"you cannot stand on red teams capture tile". flags are not appearing either, what am i doing wrong?
placed the flags manually , can't fix the problem, have no error in console,
ctf.png
 

Attachments

Last edited:
CTF_GREEN_FLAGID -- should be the itemid of the green teams flag.
CTF_RED_FLAGID -- itemid of red teams flag

In the map editor add the flags where you want them. Make them have the same actionid as you put for: CTF_ACTIONID in the lib file.

Make sure the positions of the flags are added in the lib file for:
CTF_GREEN_FLAG_POSITION
CTF_RED_FLAG_POSITION

Do the same for the capture tiles. You must of missed something. If there are any errors let me know. I didn't have any problem while testing this.

Again, all flags and tiles should have the same actionid on them.

Incase you are mistaken. You control + click(use) on the flag to take it. Then walk on the tile on your side to turn it in.
You cannot walk on the tile without the flag.
 
im using same tile id for capture tiles id 415 in green and red team with aid 5675 and i have manyally added flags green 1437 a red flag 1435 have added same aid for tiles red/green and in flags, still having the same error if im green team i can't stand on my flag tile and can't step into red flag tile, the same happen if im red

Lua:
---CTF STATUS TRACKING DONT TOUCH --
CTF_STATUS = 0
CTF_PLAYERS_QUEUE = {}
CTF_GREEN_TEAM_PLAYERS = {}
CTF_RED_TEAM_PLAYERS = {}
CTF_GREEN_SCORE = 0
CTF_RED_SCORE = 0
CTF_GREEN_FLAG_HOLDER = nil
CTF_RED_FLAG_HOLDER = nil
CTF_PLAYER_OUTFITS = {}
------------------------------------Position(32253, 32299, 7)

-------------------- CTF MAIN CONFIG --------------------------
CTF_GREEN_FLAGID = 1437 -- Flag itemID of green team
CTF_RED_FLAGID = 1435 -- Flag itemId of red team
CTF_GREEN_CAPTURE_TILE_ID = 415 -- Itemid of tile to capture enemy flag
CTF_RED_CAPTURE_TILE_ID = 415 -- Itemid of tile to capture enemy flag
CTF_ACTIONID = 5675 -- Action id for flags and capture tiles
CTF_REMOVE_GATES_TIME = 1 -- Walls that block players from running around CTF right away. 2 minutes
CTF_WIN_SCORE = 10 -- How many times the flag is captured before the team automatically wins.

CTF_AREA = { -- Make sure all tiles in the area in included in this. Its used to reset the field --
    min = Position(32253, 32299, 7), -- Set to top left tile of CTF area --
    max = Position(32317, 32346, 7) -- Set to bottom right tile of CTF area --
}

CTF_GREEN_FLAG_POSITION = Position(32258, 32324, 6) -- Set to position that flag starts at
CTF_RED_FLAG_POSITION = Position(32312, 32324, 6)-- Set to position that flag starts at
CTF_GREEN_CAPTURE_TILE_POS = Position(32259, 32324, 6) --Position(32311, 32324, 6)--Position(32259, 32324, 6) -- Tile player walks on to capture enemy flag
CTF_RED_CAPTURE_TILE_POS = Position(32311, 32324, 6)--Position(32259, 32324, 6)--Position(32311, 32324, 6) -- Tile player walks on to capture enemy flag

CTF_GATES = { -- These will be removed when its time for players to run around in CTF. They should block exits/entrances --
    [1] = {itemid = 3766, pos = Position(32265, 32324, 7)},
    [2] = {itemid = 3766, pos = Position(32306, 32324, 7)}
}

CTF_TIME_LIMIT = 30 -- End CTF automatically after 30 minutes
CTF_RESTART_TIME = 60 -- Start CTF again after 60 minutes
CTF_CHECK_QUEUE = 5 -- Check CTF queue after 5 minutes
CTF_MIN_PLAYERS = 1 -- How many players must be queued for CTF to start.
CTF_LEVEL_REQ = 1 -- What level do you need to enter CTF.

CTF_GREEN_TEAM_START_POSITIONS = {min = Position(32257, 32322, 7), max = Position(32262, 32326, 7)} -- Green team players are teleported in this area
CTF_RED_TEAM_START_POSITIONS = {min = Position(32308, 32322, 7), max = Position(32312, 32326, 7)} -- Red team players are teleported in this area


CTF_RESPAWN_POSITIONS = { -- Multiple respawn points randomly selected for each team. Nice "unique" thing to have.
    GREEN_TEAM = {
        [1] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)},
        [2] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)},
        [3] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)}
    },
    RED_TEAM = {
        [1] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)},
        [2] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)},
        [3] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)}
    }
}

CTF_WINNER_MESSAGE = "Your team has won capture the flag!"
CTF_LOSER_MESSAGE = "Your team has lost capture the flag!"
CTF_TIE_MESSAGE = "Both teams have tied."
CTF_MSG_FLAG_RETRUNED_GREEN = "The green teams flag has been recovered by the green team."
CTF_MSG_FLAG_RETRUNED_RED = "The red teams flag has been recovered by the green red."
CTF_MSG_FLAG_CAPTURED_GREEN = "The green team has captured the red teams flag!"
CTF_MSG_FLAG_CAPTURED_RED = "The red team has captured the green teams flag!"

CTF_TELEPORT_POSITION = Position(32455, 32326, 7) -- Where players teleport after CTF is over.

CTF_GIVE_ITEM_REWARDS = true -- Set to false for no item rewards.
CTF_REWARD_TIE = true -- Gives rewards to all players if they tie.

CTF_ITEMREWARDS = { -- Rewards are given to whole team.
    [1] = {itemid = 2160, count = 5, randomAmount = true}, -- Random amount will be 1-count
    [2] = {itemid = 2157, count = 1, randomAmount = false} -- Random amount will be 1-count
}

CTF_GREEN_OUTFIT = { -- TEAM OUTFITS =D as requested
    MALE = {lookType = 128, legs = 82, head = 82, feet = 82, body = 82, addons = 0},
    FEMALE = {lookType = 136, legs = 82, head = 82, feet = 82, body = 82, addons = 0}
}

CTF_RED_OUTFIT = {
    MALE = {lookType = 128, legs = 94, head = 94, feet = 94, body = 94, addons = 0},
    FEMALE = {lookType = 136, legs = 94, head = 94, feet = 94, body = 94, addons = 0}
}



the event after finishsing ( by time beucase) can't step on flag capture tiles. noticed that the players are being teleport to the zone that is designed in the teleport, but the event itself is not being close, it must use !ctf close, otherwise i get message spamming in otclient terminal(ctrl + t)
Code:
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.

event working figured out, that flags has to have free sqm arround it and you must use it in order to get not stand in the enemy spot tile
sorry @Itutorial everything is ok, my map was wrong, than you for this amazing contribution

is there a way to close the event once the players are kicked out? to close it must do it manually with the god player. can't it be done instantly?
 
Last edited:
It finishes
im using same tile id for capture tiles id 415 in green and red team with aid 5675 and i have manyally added flags green 1437 a red flag 1435 have added same aid for tiles red/green and in flags, still having the same error if im green team i can't stand on my flag tile and can't step into red flag tile, the same happen if im red

Lua:
---CTF STATUS TRACKING DONT TOUCH --
CTF_STATUS = 0
CTF_PLAYERS_QUEUE = {}
CTF_GREEN_TEAM_PLAYERS = {}
CTF_RED_TEAM_PLAYERS = {}
CTF_GREEN_SCORE = 0
CTF_RED_SCORE = 0
CTF_GREEN_FLAG_HOLDER = nil
CTF_RED_FLAG_HOLDER = nil
CTF_PLAYER_OUTFITS = {}
------------------------------------Position(32253, 32299, 7)

-------------------- CTF MAIN CONFIG --------------------------
CTF_GREEN_FLAGID = 1437 -- Flag itemID of green team
CTF_RED_FLAGID = 1435 -- Flag itemId of red team
CTF_GREEN_CAPTURE_TILE_ID = 415 -- Itemid of tile to capture enemy flag
CTF_RED_CAPTURE_TILE_ID = 415 -- Itemid of tile to capture enemy flag
CTF_ACTIONID = 5675 -- Action id for flags and capture tiles
CTF_REMOVE_GATES_TIME = 1 -- Walls that block players from running around CTF right away. 2 minutes
CTF_WIN_SCORE = 10 -- How many times the flag is captured before the team automatically wins.

CTF_AREA = { -- Make sure all tiles in the area in included in this. Its used to reset the field --
    min = Position(32253, 32299, 7), -- Set to top left tile of CTF area --
    max = Position(32317, 32346, 7) -- Set to bottom right tile of CTF area --
}

CTF_GREEN_FLAG_POSITION = Position(32258, 32324, 6) -- Set to position that flag starts at
CTF_RED_FLAG_POSITION = Position(32312, 32324, 6)-- Set to position that flag starts at
CTF_GREEN_CAPTURE_TILE_POS = Position(32259, 32324, 6) --Position(32311, 32324, 6)--Position(32259, 32324, 6) -- Tile player walks on to capture enemy flag
CTF_RED_CAPTURE_TILE_POS = Position(32311, 32324, 6)--Position(32259, 32324, 6)--Position(32311, 32324, 6) -- Tile player walks on to capture enemy flag

CTF_GATES = { -- These will be removed when its time for players to run around in CTF. They should block exits/entrances --
    [1] = {itemid = 3766, pos = Position(32265, 32324, 7)},
    [2] = {itemid = 3766, pos = Position(32306, 32324, 7)}
}

CTF_TIME_LIMIT = 30 -- End CTF automatically after 30 minutes
CTF_RESTART_TIME = 60 -- Start CTF again after 60 minutes
CTF_CHECK_QUEUE = 5 -- Check CTF queue after 5 minutes
CTF_MIN_PLAYERS = 1 -- How many players must be queued for CTF to start.
CTF_LEVEL_REQ = 1 -- What level do you need to enter CTF.

CTF_GREEN_TEAM_START_POSITIONS = {min = Position(32257, 32322, 7), max = Position(32262, 32326, 7)} -- Green team players are teleported in this area
CTF_RED_TEAM_START_POSITIONS = {min = Position(32308, 32322, 7), max = Position(32312, 32326, 7)} -- Red team players are teleported in this area


CTF_RESPAWN_POSITIONS = { -- Multiple respawn points randomly selected for each team. Nice "unique" thing to have.
    GREEN_TEAM = {
        [1] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)},
        [2] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)},
        [3] = {min = Position(32260, 32324, 7), max = Position(1013, 984, 7)}
    },
    RED_TEAM = {
        [1] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)},
        [2] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)},
        [3] = {min = Position(32310, 32324, 7), max = Position(1032, 984, 7)}
    }
}

CTF_WINNER_MESSAGE = "Your team has won capture the flag!"
CTF_LOSER_MESSAGE = "Your team has lost capture the flag!"
CTF_TIE_MESSAGE = "Both teams have tied."
CTF_MSG_FLAG_RETRUNED_GREEN = "The green teams flag has been recovered by the green team."
CTF_MSG_FLAG_RETRUNED_RED = "The red teams flag has been recovered by the green red."
CTF_MSG_FLAG_CAPTURED_GREEN = "The green team has captured the red teams flag!"
CTF_MSG_FLAG_CAPTURED_RED = "The red team has captured the green teams flag!"

CTF_TELEPORT_POSITION = Position(32455, 32326, 7) -- Where players teleport after CTF is over.

CTF_GIVE_ITEM_REWARDS = true -- Set to false for no item rewards.
CTF_REWARD_TIE = true -- Gives rewards to all players if they tie.

CTF_ITEMREWARDS = { -- Rewards are given to whole team.
    [1] = {itemid = 2160, count = 5, randomAmount = true}, -- Random amount will be 1-count
    [2] = {itemid = 2157, count = 1, randomAmount = false} -- Random amount will be 1-count
}

CTF_GREEN_OUTFIT = { -- TEAM OUTFITS =D as requested
    MALE = {lookType = 128, legs = 82, head = 82, feet = 82, body = 82, addons = 0},
    FEMALE = {lookType = 136, legs = 82, head = 82, feet = 82, body = 82, addons = 0}
}

CTF_RED_OUTFIT = {
    MALE = {lookType = 128, legs = 94, head = 94, feet = 94, body = 94, addons = 0},
    FEMALE = {lookType = 136, legs = 94, head = 94, feet = 94, body = 94, addons = 0}
}



the event after finishsing ( by time beucase) can't step on flag capture tiles. noticed that the players are being teleport to the zone that is designed in the teleport, but the event itself is not being close, it must use !ctf close, otherwise i get message spamming in otclient terminal(ctrl + t)
Code:
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.

event working figured out, that flags has to have free sqm arround it and you must use it in order to get not stand in the enemy spot tile
sorry @Itutorial everything is ok, my map was wrong, than you for this amazing contribution

is there a way to close the event once the players are kicked out? to close it must do it manually with the god player. can't it be done instantly?
It finishes when they capture the flag however many times you specify.
Lua:
CTF_WIN_SCORE = 10 -- How many times the flag is captured before the team automatically wins.
Post automatically merged:

If you want a time limit then do this:

data/lib/ctf.lua

add
Lua:
CTF_END_TIME = 15 -- How long before event automatically end. (minutes)

under
Lua:
CTF_WIN_SCORE

in data/scripts/ctf.lua
add
Lua:
local CTF_END_SELF = nil

to the very top of the file first line

then add
Lua:
if CTF_STATUS == 2 and not CTF_END_SELF then
        CTF_ENDTIME = os.time() + (CTF_END_TIME * 60)
    elseif CTF_STATUS == 2 and CTF_END_SELF and CTF_END_SELF <= os.time() then
        CTF_END_SELF = nil
        stopCTF()
    end

under
Lua:
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
 
Last edited:
It finishes

It finishes when they capture the flag however many times you specify.
Lua:
CTF_WIN_SCORE = 10 -- How many times the flag is captured before the team automatically wins.
Post automatically merged:

If you want a time limit then do this:

data/lib/ctf.lua

add
Lua:
CTF_END_TIME = 15 -- How long before event automatically end. (minutes)

under
Lua:
CTF_WIN_SCORE

in data/scripts/ctf.lua
add
Lua:
local CTF_END_SELF = nil

to the very top of the file first line

then add
Lua:
if CTF_STATUS == 2 and not CTF_END_SELF then
        CTF_ENDTIME = os.time() + (CTF_END_TIME * 60)
    elseif CTF_STATUS == 2 and CTF_END_SELF and CTF_END_SELF <= os.time() then
        CTF_END_SELF = nil
        stopCTF()
    end

under
Lua:
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
Thank you bro ! Super
i added the code but is not being stoped after the event is done i get this message spam in otcv terminal
Lua:
 onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
@Itutorial

would be good if after event everything get instantly closed and players have to requeue to avoid that spam
 
Last edited:
Thank you bro ! Super
i added the code but is not being stoped after the event is done i get this message spam in otcv terminal
Lua:
 onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
ERROR: Unhandled onTextMessage message mode 1: There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.
ERROR: Unhandled onTextMessage message mode 1: Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.
@Itutorial

would be good if after event everything get instantly closed and players have to requeue to avoid that spam
How fast does it spam it? It is every 30 minutes or is it faster?
 
data/scripts/ctf.lua
Lua:
function ctfGlobal.onThink(...)

change the first if end with this
Lua:
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)
        CTF_STATUS = 1
        addEvent(checkCTFPlayers, 1 * 60 * 1000)
    end
 
data/scripts/ctf.lua
Lua:
function ctfGlobal.onThink(...)

change the first if end with this
Lua:
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)
        CTF_STATUS = 1
        addEvent(checkCTFPlayers, 1 * 60 * 1000)
    end
now is working not spamming don't know why global message is not being sent to players when gm opens the ctf event
Lua:
-- 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)
        CTF_STATUS = 1
        addEvent(checkCTFPlayers, 1 * 60 * 1000)
    end
    if CTF_STATUS == 2 and not CTF_END_SELF then
        CTF_ENDTIME = os.time() + (CTF_END_TIME * 60)
    elseif CTF_STATUS == 2 and CTF_END_SELF and CTF_END_SELF <= os.time() then
        CTF_END_SELF = nil
        stopCTF()
    end

 
    if CTF_GREEN_FLAG_HOLDER then
        local player = Player(CTF_GREEN_FLAG_HOLDER)
      
        if player then
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
        end
 
now is working not spamming don't know why global message is not being sent to players when gm opens the ctf event
Lua:
-- 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)
        CTF_STATUS = 1
        addEvent(checkCTFPlayers, 1 * 60 * 1000)
    end
    if CTF_STATUS == 2 and not CTF_END_SELF then
        CTF_ENDTIME = os.time() + (CTF_END_TIME * 60)
    elseif CTF_STATUS == 2 and CTF_END_SELF and CTF_END_SELF <= os.time() then
        CTF_END_SELF = nil
        stopCTF()
    end

 
    if CTF_GREEN_FLAG_HOLDER then
        local player = Player(CTF_GREEN_FLAG_HOLDER)
     
        if player then
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
        end
Going through the code and testing it again. Ill let you know when I finish it.
 
Alright, lets see if this is better.

data/lib/ctf.lua
PASTEBIN FILE

data/scripts/ctf.lua
Lua:
local CTF_END_SELF = nil

--- TALKACTION --
local ctfTalk = TalkAction("!ctf", "!CTF")

function ctfTalk.onSay(player, words, param)
    if param == "enter" then
        if CTF_STATUS ~= 0 then
            player:sendCancelMessage("The queue for capture the flag is not open.")
            return false
        end
   
        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
        if CTF_STATUS ~= 0 then
            player:sendCancelMessage("Your team needs you!")
            return false
        end
       
        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 and CTF_STATUS ~= 2 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 = 0
        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
       
        if CTF_STATUS == 2 then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "Capture the flag is not runing.")
            return false
        end
       
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, "You have stopped capture the flag.")
        stopCTF()
    end
    return false
end

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

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

function ctfGlobal.onThink(...)
    if CTF_STATUS == -1 then
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in "..CTF_CHECK_QUEUE.." minutes.", 1)
        CTF_STATUS = 0
        addEvent(checkCTFPlayers, CTF_CHECK_QUEUE * 60 * 1000)
    end
   
    if CTF_STATUS == 1 and not CTF_END_SELF then
        CTF_END_SELF = os.time() + (CTF_TIME_LIMIT * 60)
    elseif CTF_STATUS == 1 and CTF_END_SELF and CTF_END_SELF <= os.time() then
        CTF_END_SELF = nil
        stopCTF()
    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()

and data/events/scripts/creature.lua
Lua:
function Creature:onChangeOutfit(outfit)
    local player = Player(self)
    if player and CTF_STATUS == 1 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 == 1 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 == 1 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
@johnsamir
 
Last edited:
the event is working but players are not receiving brodcasts message on event start
this mesage is not working after gm uses !ctf start aso would be good to add condition pz lock during event to prevent players log out on event i can't use no log out tile since i use 7.72

Lua:
function ctfGlobal.onThink(...)
    if CTF_STATUS == -1 then
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in "..CTF_CHECK_QUEUE.." minutes.", 1)
        CTF_STATUS = 0
        addEvent(checkCTFPlayers, CTF_CHECK_QUEUE * 60 * 1000)
    end
 
Last edited:
Those messages work on my end.
normal client or otc? might be my client then going to test with normal client, thank you but it's weird because it was working before
and with others events i get the message, the player recieves all message but not the global message that the event has started
@Itutorial could you give me a code to add into the script to add pzlock while players on event and remove after event ends if player get kick out?

example of globalevent messages
21:53 Zombie event will begin in 1 minute 40 seconds , Hurry up!
21:57 The map has been changed to Thais Next map change will be in 30 minutes! Type !shop list to view the items available in shop!
Post automatically merged:

this message is not being received by players does not matter if they are queued in the event or not
Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in " ..CTF_CHECK_QUEUE.. " minutes.")
 
Last edited:
Hello, can someone explain to me a little what these points mean, I don't understand, thanks

Lua:
CTF_GATES = { -- These will be removed when its time for players to run around in CTF. They should block exits/entrances --
    [1] = {itemid = 3766, pos = Position(1016, 986, 7)},
    [2] = {itemid = 3766, pos = Position(1028, 986, 7)}
}

Can you say that they are waiting points and event starts?
 
Hello, can someone explain to me a little what these points mean, I don't understand, thanks

Lua:
CTF_GATES = { -- These will be removed when its time for players to run around in CTF. They should block exits/entrances --
    [1] = {itemid = 3766, pos = Position(1016, 986, 7)},
    [2] = {itemid = 3766, pos = Position(1028, 986, 7)}
}

Can you say that they are waiting points and event starts?
When players are teleported into the event. They should be stuck in a room or something to wait for everyone to get ready. After a certain amount of time you can remove items to let them out. Those positions and items are saying where the code should remove items.
If you don't want a waiting room, or you dont need this part of the code, just remove it.
 
thanks for the information, the event configured this

Lua:
CTF_TIME_LIMIT = 30 -- End CTF automatically after 30 minutes
CTF_RESTART_TIME = 1 -- Start CTF again after 60 minutes
CTF_CHECK_QUEUE = 5 -- Check CTF queue after 5 minutes
CTF_MIN_PLAYERS = 1 -- How many players must be queued for CTF to start.
CTF_LEVEL_REQ = 1 -- What level do you need to enter CTF.

and never start the event 0 errors
 
Back
Top