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

TFS 1.3 Capture the Flag

Itutorial

Excellent OT User
Joined
Dec 23, 2014
Messages
2,307
Solutions
68
Reaction score
982
This is probably the best CTF code that has been released here. 100% tested.

What this code can do:
-Players queue for CTF with talkaction
-Players are divided into teams
-Players do not enter if they have condition isInFight
-If time limit for CTF is reached it will end and the code will handle winners, losers, and ties
-If a team captures the flag the set time to win (eg. 10x) code will end CTF.
-The code will reset the field by itself.
-No storages are used in this system.
-Players spawn in specified room in config
-Gates block exits for x amount of time specified in config.
-Players that have the flag are marked with a magic effect
-Messages are broadcasted only to CTF players
-You can add items rewards to the winners.
-Players that die with the enemy flag will drop the flag on the ground
If a player of the team that the flag belongs to uses it first the flag is returned to their base
If a player of the enemy team uses the flag first he will pick it up
-Players are sent to a spawn area specified in the config when they die.
-Players are given skulls (red/green) to know whos team they are on

TALKACTIONS
!ctf enter/leave -- for players
!ctf start/stop -- Gods only

data/lib/ctf.lua
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 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 = 2 -- 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(2928, 2309, 7), -- Set to top left tile of CTF area --
    max = Position(2949, 2318, 7) -- Set to bottom right tile of CTF area --
}

CTF_GREEN_FLAG_POSITION = Position(2932, 2313, 7) -- Set to position that flag starts at
CTF_RED_FLAG_POSITION = Position(2946, 2313, 7) -- Set to position that flag starts at
CTF_GREEN_CAPTURE_TILE_POS = Position(2932, 2314, 7) -- Tile player walks on to capture enemy flag
CTF_RED_CAPTURE_TILE_POS = Position(2946, 2314, 7) -- 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 = 8538, pos = Position(2939, 2313, 7)},
    [2] = {itemid = 8538, pos = Position(2939, 2314, 7)}
}

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

CTF_GREEN_TEAM_START_POSITIONS = {min = Position(2933, 2313, 7), max = Position(2934, 2314, 7)} -- Green team players are teleported in this area
CTF_RED_TEAM_START_POSITIONS = {min = Position(2944, 2313, 7), max = Position(2945, 2314, 7)} -- Red team players are teleported in this area

CTF_GREEN_RESPAWN_AREA = {min = Position(2933, 2313, 7), max = Position(2934, 2314, 7)} -- This is where the green players respawn.
CTF_RED_RESPAWN_AREA = {min = Position(2933, 2313, 7), max = Position(2934, 2314, 7)} -- This is where the red players respawn.

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(3000, 3003, 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
}
---------------------------------------------------------------

---------- FUNCTIONS ------------
function isGreenTeam(playerName)
    local isGreen = false
    for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        if CTF_GREEN_TEAM_PLAYERS[i] == playerName then
            isGreen = true
            break
        end
    end
  
    if isGreen then
        return true
    end
  
    return false
end

function isRedTeam(playerName)
    local isRed = false
    for i = 1, #CTF_RED_TEAM_PLAYERS do
        if CTF_RED_TEAM_PLAYERS[i] == playerName then
            isRed = true
            break
        end
    end
  
    if isRed then
        return true
    end
  
    return false
end

function broadcastToCTFPlayers(msg)
    for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
      
        if player then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, msg)
        end
    end
  
    for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
      
        if player then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, msg)
        end
    end
end

function checkCTFPlayers()

    for i = 1, #CTF_PLAYERS_QUEUE do
        local player = Player(CTF_PLAYERS_QUEUE)
      
        if player and player:hasCondition(CONDITION_ISINFIGHT) then
            CTF_PLAYERS_QUEUE[i] = nil
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You are in combat and cannot enter capture the flag. You have been removed from the queue.")
        end
    end

    if #CTF_PLAYERS_QUEUE < CTF_MIN_PLAYERS then
        Game.broadcastMessage("There are not enough players for CTF to start. CTF will try again in 30 minutes. You do not need to requeue.", 1)
        addEvent(restartCTF, 30 * 60 * 1000)
    else
        startCTF()
    end
end

function restartCTF()
    CTF_STATUS = 0
end

function startCTF()
    CTF_STATUS = 2
  
    for i = 1, #CTF_PLAYERS_QUEUE do
        if #CTF_GREEN_TEAM_PLAYERS > #CTF_RED_TEAM_PLAYERS then
            CTF_RED_TEAM_PLAYERS[#CTF_RED_TEAM_PLAYERS + 1] = CTF_PLAYERS_QUEUE[i]
        else
            CTF_GREEN_TEAM_PLAYERS[#CTF_GREEN_TEAM_PLAYERS + 1] = CTF_PLAYERS_QUEUE[i]
        end
    end
  
    CTF_PLAYERS_QUEUE = {}
  
    for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
      
        if player then
            player:teleportTo(Position(math.random(CTF_GREEN_TEAM_START_POSITIONS.min.x, CTF_GREEN_TEAM_START_POSITIONS.max.x), math.random(CTF_GREEN_TEAM_START_POSITIONS.min.y, CTF_GREEN_TEAM_START_POSITIONS.max.y), math.random(CTF_GREEN_TEAM_START_POSITIONS.min.z, CTF_GREEN_TEAM_START_POSITIONS.max.z)))
            player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
            Creature(player):setSkull(SKULL_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Welcome to capture the flag. You are on the green team! The gates will open in 2 minutes.")
        end
    end
  
    for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
      
        if player then
            player:teleportTo(Position(math.random(CTF_RED_TEAM_START_POSITIONS.min.x, CTF_RED_TEAM_START_POSITIONS.max.x), math.random(CTF_RED_TEAM_START_POSITIONS.min.y, CTF_RED_TEAM_START_POSITIONS.max.y), math.random(CTF_RED_TEAM_START_POSITIONS.min.z, CTF_RED_TEAM_START_POSITIONS.max.z)))
            player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
            Creature(player):setSkull(SKULL_RED)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Welcome to capture the flag. You are on the green team! The gates will open in 2 minutes.")
        end
    end
  
    Game.broadcastMessage("Capture the flag is now closed. Good luck to the participants.", 1)
    addEvent(removeGates, CTF_REMOVE_GATES_TIME * 60 * 1000)
    addEvent(stopCTF, CTF_TIME_LIMIT * 60 * 1000)
end

function removeGates()
    for i = 1, #CTF_GATES do
        local position = CTF_GATES[i].pos
        if Tile(position) and Tile(position):getItemById(CTF_GATES[i].itemid) then
            Tile(position):getItemById(CTF_GATES[i].itemid):remove()
        end
    end
  
    for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
      
        if player then
            player:say("CHARGE", TALKTYPE_MONSTER_SAY, 0, 1, player:getPosition())
        end
    end
  
    for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
      
        if player then
            player:say("CHARGE", TALKTYPE_MONSTER_SAY, 0, 1, player:getPosition())
        end
    end
end

function stopCTF()
    if CTF_GREEN_SCORE == CTF_RED_SCORE then
        for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_TIE_MESSAGE)
                Creature(player):setSkull(SKULL_NONE)
              
                if CTF_GIVE_ITEM_REWARDS and CTF_REWARD_TIE then
                    for i = 1, #CTF_ITEMREWARDS do
                        if CTF_ITEMREWARDS[i].randomAmount then
                            player:addItem(CTF_ITEMREWARDS[i].itemid, math.random(CTF_ITEMREWARDS[i].count))
                        else
                            player:addItem(CTF_ITEMREWARDS[i].itemid, CTF_ITEMREWARDS[i].count)
                        end
                    end
                end
              
                player:teleportTo(CTF_TELEPORT_POSITION)
            end
        end
      
        for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_TIE_MESSAGE)
                Creature(player):setSkull(SKULL_NONE)
              
                if CTF_GIVE_ITEM_REWARDS and CTF_REWARD_TIE then
                    for i = 1, #CTF_ITEMREWARDS do
                        if CTF_ITEMREWARDS[i].randomAmount then
                            player:addItem(CTF_ITEMREWARDS[i].itemid, math.random(CTF_ITEMREWARDS[i].count))
                        else
                            player:addItem(CTF_ITEMREWARDS[i].itemid, CTF_ITEMREWARDS[i].count)
                        end
                    end
                end
              
                player:teleportTo(CTF_TELEPORT_POSITION)
            end
        end
      
    elseif CTF_GREEN_SCORE > CTF_RED_SCORE then
        for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_WINNER_MESSAGE)
                Creature(player):setSkull(SKULL_NONE)
              
                if CTF_GIVE_ITEM_REWARDS and CTF_REWARD_TIE then
                    for i = 1, #CTF_ITEMREWARDS do
                        if CTF_ITEMREWARDS[i].randomAmount then
                            player:addItem(CTF_ITEMREWARDS[i].itemid, math.random(CTF_ITEMREWARDS[i].count))
                        else
                            player:addItem(CTF_ITEMREWARDS[i].itemid, CTF_ITEMREWARDS[i].count)
                        end
                    end
                end
              
                player:teleportTo(CTF_TELEPORT_POSITION)
            end
        end
  
        for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_LOSER_MESSAGE)
                player:teleportTo(CTF_TELEPORT_POSITION)
                Creature(player):setSkull(SKULL_NONE)
            end
        end
      
    else
  
        for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_WINNER_MESSAGE)
                Creature(player):setSkull(SKULL_NONE)
              
                if CTF_GIVE_ITEM_REWARDS and CTF_REWARD_TIE then
                    for i = 1, #CTF_ITEMREWARDS do
                        if CTF_ITEMREWARDS[i].randomAmount then
                            player:addItem(CTF_ITEMREWARDS[i].itemid, math.random(CTF_ITEMREWARDS[i].count))
                        else
                            player:addItem(CTF_ITEMREWARDS[i].itemid, CTF_ITEMREWARDS[i].count)
                        end
                    end
                end
              
                player:teleportTo(CTF_TELEPORT_POSITION)
            end
        end
  
        for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
            if player then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, CTF_LOSER_MESSAGE)
                player:teleportTo(CTF_TELEPORT_POSITION)
                Creature(player):setSkull(SKULL_NONE)
            end
        end
    end
  
    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
  
    if not Tile(CTF_GREEN_FLAG_POSITION):getItemById(CTF_GREEN_FLAGID) then
        local flag = Game.createItem(CTF_GREEN_FLAGID, 1, CTF_GREEN_FLAG_POSITION)
        flag:setAttribute('aid', CTF_ACTIONID)
    end
  
    if not Tile(CTF_RED_FLAG_POSITION):getItemById(CTF_RED_FLAGID) then
        local flag = Game.createItem(CTF_RED_FLAGID, 1, CTF_RED_FLAG_POSITION)
        flag:setAttribute('aid', CTF_ACTIONID)
    end
  
    for x = CTF_AREA.min.x, CTF_AREA.max.x do
        x = x
        for y = CTF_AREA.min.y, CTF_AREA.max.y do
            y = y
            for z = CTF_AREA.min.z, CTF_AREA.max.z do
                local position = Position(x, y, z)
                local tile = Tile(position)
              
                if tile then
                    if tile:getItemById(CTF_GREEN_FLAGID) and position ~= CTF_GREEN_FLAG_POSITION then
                        tile:getItemById(CTF_GREEN_FLAGID):remove()
                    elseif tile:getItemById(CTF_RED_FLAGID) and position ~= CTF_RED_FLAG_POSITION then
                        tile:getItemById(CTF_RED_FLAGID):remove()
                    end
                end
            end
        end
    end
  
    for i = 1, #CTF_GATES do
        if Tile(CTF_GATES[i].pos) and not Tile(CTF_GATES[i].pos):getItemById(CTF_GATES[i].itemid) then
            Game.createItem(CTF_GATES[i].itemid, 1, CTF_GATES[i].pos)
        end
    end
  
    addEvent(restartCTF, CTF_RESTART_TIME * 60 * 1000)
end

data/lib/lib.lua
Lua:
dofile('data/lib/ctf.lua')

globalevents.xml
XML:
<globalevent name="CTF" interval="1000" script="CTF.lua" />

data/globalevents/scripts/CTF.lua
Lua:
function onThink(interval)
    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, 5 * 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

talkactions.xml
XML:
<talkaction words="!ctf" separator=" " script="CTF.lua" />

data/talkactions/scripts/CTF.lua
Lua:
function 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:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "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 false
        end
      
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.")
        CTF_STATUS = 1
        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
        addEvent(checkCTFPlayers, 1 * 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 false
        end
      
        stopCTF()
    end
    return false
end

actions.xml
XML:
<action actionid="5675" script="custom/CTF.lua" />

data/actions/scripts/custom/CTF.lua
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == CTF_GREEN_FLAGID and item.actionid == CTF_ACTIONID 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 and item.actionid == CTF_ACTIONID 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

movements.xml
XML:
<movevent event="StepIn" actionid="5675" script="CTF.lua" />

data/movements/scripts/CTF.lua
Lua:
function 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

creaturescripts.xml
XML:
<event type="preparedeath" name="CTF" script="CTF.lua" />

data/creaturescripts/scripts/CTF.lua
Lua:
function 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)
        player:teleportTo(Position(math.random(CTF_GREEN_RESPAWN_AREA.min.x, CTF_GREEN_RESPAWN_AREA.max.x), math.random(CTF_GREEN_RESPAWN_AREA.min.y, CTF_GREEN_RESPAWN_AREA.max.y), math.random(CTF_GREEN_RESPAWN_AREA.min.z, CTF_GREEN_RESPAWN_AREA.max.z)))
        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)
        player:teleportTo(Position(math.random(CTF_RED_RESPAWN_AREA.min.x, CTF_RED_RESPAWN_AREA.max.x), math.random(CTF_RED_RESPAWN_AREA.min.y, CTF_RED_RESPAWN_AREA.max.y), math.random(CTF_RED_RESPAWN_AREA.min.z, CTF_RED_RESPAWN_AREA.max.z)))
        return false
    end
    return false
end

data/creaturescripts/scripts/login.lua
Lua:
player:registerEvent("CTF")
 
Last edited:
If you guys seen anything that should be added or would be cool to see in this code please let me know so I can make the best CTF system there is.

Currently working on Guild vs Guild CTF added to this system.
 
Aww man i added CTF and mapped it myself a few weeks ago 🤣 But ill try this version 👌 thanks for contributing
 
If you guys seen anything that should be added or would be cool to see in this code please let me know so I can make the best CTF system there is.

Currently working on Guild vs Guild CTF added to this system.
Hey, Maybe instead of skulls would it also be possible to use outfits? For example the Jersey outfits in the colors red/green and lock them so ppl won't be able to change them untill the event is over.
 
Last edited:
only the green team gets a skulls which disappears after time anyway tfs 1.2 8.6 can You help me fix ?
 
Awesome ! Can You do ctf with outfit change ? no skulls ? Thanks for this !
 
only the green team gets a skulls which disappears after time anyway tfs 1.2 8.6 can You help me fix ?
Try this data/globalevents/scripts/CTF.lua if you are still using this code.

Lua:
function onThink(interval)
    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, 5 * 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
    
    for i = 1, #CTF_GREEN_TEAM_PLAYERS do
        local player = Player(CTF_GREEN_TEAM_PLAYERS[i])
      
        if player then
            Creature(player):setSkull(SKULL_GREEN)
        end
    end
  
    for i = 1, #CTF_RED_TEAM_PLAYERS do
        local player = Player(CTF_RED_TEAM_PLAYERS[i])
      
        if player then
            Creature(player):setSkull(SKULL_RED)
        end
    end
    
return true
end
Post automatically merged:

@Itutorial Can You Add unregisterEvent ? Because when the event ends, player can't die
How does the event end? Is it after the time limit, or after players get all flags
 
data/movements/movements.xml - i no have this file. I have only data/scripts/movements/ folder
 
Nice script, I tested on 8.6 OTX 3.9 Vanxi. The only thing I would add is not being able to attack team mates.
 
Nice script! I am having some errors though, how do i score once i have the flag? My character will just hold onto the flag and i can't place the flag anywhere.. Also if i say !ctf enter i can re start the whole event. May just need a few tweaks and would be perfect!
 
Nice script! I am having some errors though, how do i score once i have the flag? My character will just hold onto the flag and i can't place the flag anywhere.. Also if i say !ctf enter i can re start the whole event. May just need a few tweaks and would be perfect!
Working fine for me, what tfs are you using? You're supposed to score by bringing the other teams flag to your own flag.
 
Please make sure its the correct TFS version. If you still have problems I will test the system more thoroughly.
Nice script! I am having some errors though, how do i score once i have the flag? My character will just hold onto the flag and i can't place the flag anywhere.. Also if i say !ctf enter i can re start the whole event. May just need a few tweaks and would be perfect!
 
It was very good, with the glovalevents update the skulls fixed with active battle.
However, there is a problem when the player leaves the event he doesn't die. I tried some functions but I was not successful.
Can you tell me how to direct this?
 

Attachments

Can you check some things:
1) Does it happen to anyone that entered CTF or just a specific team
2) Does it continue even if they log out and back in

Post automatically merged:

Nice script! I am having some errors though, how do i score once i have the flag? My character will just hold onto the flag and i can't place the flag anywhere.. Also if i say !ctf enter i can re start the whole event. May just need a few tweaks and would be perfect!
You just walk onto the tile you specified for the team with the flag. So red flag would go to green side capture tile. Just walk on it....

The fix for !CTF enter
Lua:
function onSay(player, words, param)
    if param == "enter" then
        if CTF_STATUS ~= 1 then
            player:sendCancelMessage("You cannot queue for capture the flag now.")
            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
        for i = 1, #CTF_PLAYERS_QUEUE do
            if CTF_PLAYERS_QUEUE[i] == player:getName() then
                CTF_PLAYERS_QUEUE[i] = nil
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "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 false
        end
     
        Game.broadcastMessage("Capture the flag is now open. Type !ctf enter to join the queue. It will start in 5 minutes.")
        CTF_STATUS = 1
        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
        addEvent(checkCTFPlayers, 1 * 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 false
        end
     
        stopCTF()
    end
    return false
end
Post automatically merged:

UPDATE: I am creating this in revscript now. TFS 1.4.1+
 
Last edited:
after installing the system, the player no longer dies, being outside the event, however, inside the event it continues to work perfectly
bug2.png

I'm using your system to be the PVP base of my MOBA server. Just need to fix this so I can open the server for testing.
 
Last edited:
after installing the system, the player no longer dies, being outside the event, however, inside the event it continues to work perfectly
View attachment 66191

I'm using your system to be the PVP base of my MOBA server. Just need to fix this so I can open the server for testing.

In
Code:
function onPrepareDeath(creature, killer)

Change last
Code:
 return false

to
Code:
return true
 
Back
Top