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

GlobalEvent [TFS 1.2] Zombie Arena

rwxsu

Computer Engineer
Joined
Mar 31, 2018
Messages
121
Solutions
5
Reaction score
169
GitHub
rwxsu
Big thanks to @Fablow for sponsoring!


Map was just made for testing, you can use any map:





Step 1: Adding the library

Add in data/lib/event/zombie_arena.lua
Lua:
------------------------------------------------------
--              Zombie Arena by rwxsu               --
------------------------------------------------------
--            License: do as you please             --
------------------------------------------------------

debug = true

-- Config
zombieArena = {
    config = {
        minPlayers = 1,  -- Minimum players for the event to begin
        monsters   = 10, -- Total monsters to kill
        monster    = "Zombie",
       
        -- Time between starts
        -- This gets called recursively until event is started
        minutesBetweenStart = 0.5, 

        -- How many seconds between each zombie spawned
        secondsBetweenZombies = 2,
    },
    storages  = {
        eventOpened    = 670000,
        eventStarted   = 670001,
        eventFinished  = 670002,
        monstersLeft   = 670003,
        playerOnEvent  = 670004, -- Singular
        playersOnEvent = 670005, -- Global
    },
    positions = {
        waitingRoom = {
            center = Position(975, 990, 7),

            -- Radius is how many squares from center
            -- Do NOT count walls in radius
            radius = 5,
        },
        arena = {
            center = Position(990, 990, 7),
            radius = 5, 
        },

        -- Where to spawn teleport to waiting room
        teleport = Position(980, 1000, 7),
    },
    messages = {
        eventOpened   = "Zombie arena portal is now open!",
        eventStarted  = "Zombie arena event has started!",
        eventFinished = "All zombies have been slain! Zombie arena completed.",
        eventFailed   = "The zombies won by killing every single player...",
    },
    rewards = {
        [1] = {
            name   = "crystal coin",
            itemid = 2160,
            count  = 50,
        },
        [2] = {
            name   = "magic sword",
            itemid = 2400,
            count  = 1,
        },
--      [3] = {
--          name   = "example item",
--          itemid = 666,
--          count  = 1,
--      },
    },
}


zombieArena.__index = zombieArena


function zombieArena:autoStart()
    local function start()
        zombieArena:start()
    end

    -- Checks if event has been started recursively,
    -- if not tries again until start
    local function check()
        if not zombieArena:isStarted() then
            zombieArena:autoStart()
        end
    end

    addEvent(start, zombieArena.config.minutesBetweenStart * 60 * 1000)
    addEvent(check, zombieArena.config.minutesBetweenStart * 60 * 1000 + 5)
end

-- Main function to start event
function zombieArena:start()
    if zombieArena:isStarted() then
        zombieArena:debug("Event was already started.")
        return false
    end

    if not zombieArena:teleportPlayers() then
        return false
    end

    zombieArena:removeTeleport()
    zombieArena:summonMonsters()

    Game.broadcastMessage(zombieArena.messages.eventStarted, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena.config.monsters)
    Game.setStorageValue(zombieArena.storages.eventStarted, 1)
    return true
end


function zombieArena:openEvent()   
   
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is already open.")
        return false
    end

    if zombieArena:isStarted() then
        zombieArena:debug("Event has already started.")
        return false
    end

    -- Open event
    Game.broadcastMessage(zombieArena.messages.eventOpened, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 0)
    Game.setStorageValue(zombieArena.storages.eventOpened, 1)
    zombieArena:debug("Event opened.")
    zombieArena:createTeleport()
    return true
end


-- Creates the teleport to the waiting room
function zombieArena:createTeleport()
    local tp = Game.createItem(1387, 1, zombieArena.positions.teleport) 
    if not tp:isTeleport() then
        tp:remove()
        return false
    end

    tp:setDestination(zombieArena.positions.waitingRoom.center)
    zombieArena:debug("Teleport created.")
    return true
end


-- Removes the teleport to the waiting room
function zombieArena:removeTeleport()

    if not Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is not opened.")
        return false
    end

    Game.setStorageValue(zombieArena.storages.eventOpened, 0)
    zombieArena:debug("Event closed for new players.")

    -- Remove teleport
    local tp = Tile(zombieArena.positions.teleport)
    if tp:getItemById(1387):isTeleport() then
        tp:getItemById(1387):remove()
        zombieArena:debug("Teleport removed.")
        return true
    end
end

function zombieArena:checkWaitingRoom()
    local center = zombieArena.positions.waitingRoom.center
    local radius = zombieArena.positions.waitingRoom.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)
   
    if #players == 0 then
        zombieArena:debug("No players in waiting room.")
        return nil
    end

    if #players < zombieArena.config.minPlayers then
        local message = string.format("%d players required to start. Currently %d player(s) found. ", zombieArena.config.minPlayers, #players)
        zombieArena:messageGroup(players, message)
        zombieArena:debug(message)
        return players
    end
    return players
end

function zombieArena:checkArena()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)

    if zombieArena:getPlayersLeft() == 0 then
        zombieArena:finish(false)   
        if zombieArena:clear() then
            zombieArena:debug("All players died.")
        end
        return nil
    end
    return players
end

-- Clears all zombies from arena
function zombieArena:clear()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local monsters = Game.getSpectators(center, false, false, radius, radius, radius, radius)

    if monsters == nil then
        return false
    end

    if #monsters < 0 then
        return false
    end

    for i = 1, #monsters do
        monster = Creature(monsters[i])
        monster:remove()
    end
    zombieArena:debug("Zombie arena cleared.")
    return true
end


-- If there's more players than the required minimum, 
-- teleport all players from waiting room to the arena.
function zombieArena:teleportPlayers()
    players = zombieArena:checkWaitingRoom()
    if players ~= nil then
       
        -- Not enough players
        if #players < zombieArena.config.minPlayers then
            return false
        end

        -- Teleport players
        for i = 1, #players do
            local player = Player(players[i])
            player:teleportTo(zombieArena.positions.arena.center)
            zombieArena:debug(player:getName() .. " was teleported to arena.")
            zombieArena:addPlayer(player)
        end
        return true
    end
end

-- Adds player to the event
function zombieArena:addPlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 1)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() + 1)
    zombieArena:debug(player:getName() .. " was added to event.")
end

-- Removes player from the event
function zombieArena:removePlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() - 1)
    zombieArena:debug(player:getName() .. " was removed from event.")
end

-- Gets all players on event
function zombieArena:getPlayersLeft()
    return Game.getStorageValue(zombieArena.storages.playersOnEvent)
end


-- Message a group of people
function zombieArena:messageGroup(players, message)
    for i = 1, #players do
        local player = Player(players[i])
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
    end
end

-- Spawns a monster randomly within the radius provided in positions
function zombieArena:createMonster(i)

    -- Purposely written this way instead of using the table directly,
    -- since tables are pass by reference.
    local radius = zombieArena.positions.arena.radius 
    local x = zombieArena.positions.arena.center.x
    local y = zombieArena.positions.arena.center.y
    local z = zombieArena.positions.arena.center.z
    x = math.random(x - radius, x + radius)
    y = math.random(y - radius, y + radius)
   
    local function create()
        -- Create monster
        if zombieArena:isStarted() then
            if Game.createMonster(zombieArena.config.monster, Position(x, y, z)) then
                Position(x, y, z):sendMagicEffect(CONST_ME_BLACKSMOKE)
                local message = string.format("%s created at position {x = %d, y = %d, z = %d}", zombieArena.config.monster, x, y, z)
                zombieArena:debug(message)
                return true
            end
        end
    end

    if addEvent(create, i * zombieArena.config.secondsBetweenZombies * 1000) then
        return true
    end
   
    -- Something went wrong
    local message = string.format("Unexpected error: couldn't create %s at position {x = %d, y = %d, z = %d}", monster, x, y, z)
    zombieArena:debug(message)
    return false
end

-- Summon x monsters provided in config
function zombieArena:summonMonsters()
    for i = 1, zombieArena.config.monsters do
            zombieArena:createMonster(i)
    end
    local message = string.format("%d monsters will be summoned.", zombieArena.config.monsters)
    zombieArena:debug(message)
end

-- Gets how many monsters there left in arena
function zombieArena:getMonstersLeft()
    return Game.getStorageValue(zombieArena.storages.monstersLeft)
end


function zombieArena:onKill(killer)

    players = zombieArena:checkArena()

    -- Subtract one from monstersLeft
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena:getMonstersLeft() - 1)

    -- Check if event is complete
    if zombieArena:getMonstersLeft() == 0 then
        for i = 1, #players do
            local player = Player(players[i])
            zombieArena:reward(player)
        end

        -- Ends the event
        zombieArena:finish(true)
        return true
    end

    local message = string.format("%s killed a %s! Only %d left.", killer:getName(), zombieArena.config.monster, zombieArena:getMonstersLeft())
    if players ~= nil then 
        zombieArena:messageGroup(players, message)
    end
    zombieArena:debug(message)
end

function zombieArena:finish(playersWon)

    if playersWon then
        Game.broadcastMessage(zombieArena.messages.eventFinished, MESSAGE_STATUS_WARNING)
        zombieArena:debug(zombieArena.messages.eventFinished)
    else
        Game.broadcastMessage(zombieArena.messages.eventFailed, MESSAGE_STATUS_WARNING)
    zombieArena:debug(zombieArena.messages.eventFailed)
    end

    Game.setStorageValue(zombieArena.storages.eventStarted, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 1)
end

-- Give the players who survived the event a reward
-- and teleport to hometown
function zombieArena:reward(player)
    for i = 1, #zombieArena.rewards do
        player:addItem(zombieArena.rewards[i].itemid, zombieArena.rewards[i].count)

        local message = string.format("You received a %s.", zombieArena.rewards[i].name)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
        zombieArena:debug(player:getName() .. " received a " .. zombieArena.rewards[i].name)

    end
    player:teleportTo(player:getTown():getTemplePosition())
    zombieArena:debug(player:getName() .. " got teleported to " .. player:getTown():getName() .. ".")

    zombieArena:removePlayer(player)
    return true
end

-- Checks if event is finished
-- returns either true or false
function zombieArena:isFinished()
    if Game.getStorageValue(zombieArena.storages.eventFinished) == 1 then
        return true
    end
    return false
end

-- Checks if event has started
-- returns either true or false
function zombieArena:isStarted()
    if Game.getStorageValue(zombieArena.storages.eventStarted) == 1 then
        return true
    end
    return false
end

-- Checks if event is opened
-- returns either true or false
function zombieArena:isOpened()
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        return true
    end
    return false
end


-- Check if player is doing event
-- returns either true or false
function zombieArena:isPlayerOnEvent(player)
    if player:getStorageValue(zombieArena.storages.playerOnEvent) == 1 then
        return true
    end
    return false
end


-- Toggle debug on/off on top off this file
function zombieArena:debug(message) 
    if debug then
        message = "[ZOMBIEARENA] " .. message
        print(message)
    end
end


Don't forget to add this in data/lib/lib.lua
Lua:
dofile('data/lib/event/zombie_arena.lua')



Step 2: Configuring creature scripts


Add this in data/creaturescripts/scripts/zombie_arena/death.lua
Lua:
-- When player dies in Zombie Arena
function onDeath(player, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)

    -- Has the event started?
    if not zombieArena:isStarted() then
        return false
    end

    -- Did a player die?
    if player:isPlayer() then
       
        -- Is the player doing the event?
        if not zombieArena:isPlayerOnEvent(player) then
            return false
        end

        zombieArena:removePlayer(player)
        zombieArena:debug(player:getName() .. " got teleported to " .. player:getTown():getName() .. ".")

        zombieArena:checkArena()
    end
    return true
end


Add this in data/creaturescripts/scripts/zombie_arena/kill.lua
Lua:
-- When player kills a Zombie in Zombie Arena
function onKill(player, target, lastHit)

    -- Has the event started?
    if not zombieArena:isStarted() then
        return false
    end

    -- Was the killer a player?
    if player:isPlayer() then

        -- Is the player doing the event?
        if not zombieArena:isPlayerOnEvent(player) then
            return false
        end
       
        -- Was the monster killed a zombie?
        if target:getName() == zombieArena.config.monster then
            zombieArena:onKill(player)
            return true
        end

        return false
    end
end


Add this in data/creaturescripts/scripts/zombie_arena/logout.lua
Lua:
-- When player logs out in Zombie Arena
-- This is written just in case
-- The code should never happen
function onLogout(player)

    -- Has the event started?
    if not zombieArena:isStarted() then
        return true
    end

    -- Did a player logout?
    if player:isPlayer() then
       
        -- Is the player doing the event?
        if not zombieArena:isPlayerOnEvent(player) then
            return true
        end
       
        player:teleportTo(player:getTown():getTemplePosition())
        zombieArena:removePlayer(player)
    end   
    return true
end


IMPORTANT! Add this in data/creaturescripts/scripts/login.lua
Lua:
player:registerEvent("ZombieArenaKill")
player:registerEvent("ZombieArenaDeath")
player:registerEvent("ZombieArenaLogout")


Don't forget to add this in data/creaturescripts/creaturescripts.xml
XML:
<event type="kill"  name="ZombieArenaKill" script="zombie_arena/kill.lua" />
<event type="death" name="ZombieArenaDeath" script="zombie_arena/death.lua" />
<event type="logout" name="ZombieArenaLogout" script="zombie_arena/logout.lua" />



Step 3: Adding global events and/or talk actions


Add this in data/talkactions/scripts/zombie_arena.lua
Lua:
function onSay(player, words, param)
   
    if not player:getGroup():getAccess() then
        return true
    end

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

    if zombieArena:openEvent() then
        zombieArena:autoStart()
    end

    return true
end


Don't forget to add this in data/talkactions/talkactions.xml
XML:
<talkaction words="/zombiearena" script="zombie_arena.lua" />


Add this in data/globalevents/scripts/zombie_arena.lua
Lua:
function onThink(interval, lastExecution)

    if zombieArena:openEvent() then
        zombieArena:autoStart()
    end
 
    return true
end


Don't forget to add this in data/globalevents/globalevents.xml
XML:
<globalevent name="Zombie Arena" interval="7200000" script="zombie_arena.lua" />



Step 4: Modify data/lib/event/zombie_arena.lua

  • Change positions
  • Change total zombies
  • Change time between zombies
  • Change rewards


You are now all set up!

Enjoy,
rwxsu
 
i used tfs 1.3 and maked error :c

you can help me?
sin_ty13.png
 
i used tfs 1.3 and maked error :c

you can help me?
sin_ty13.png
It means your lib file wasn't linked correctly.

Make sure you have this in data/lib/lib.lua:
Lua:
dofile('data/lib/event/zombie_arena.lua')

If that doesn't work, there is something wrong with how the server handles the libs. In that case, you have to add the dofile code above in every file that uses the zombie event script.
 
It means your lib file wasn't linked correctly.

Make sure you have this in data/lib/lib.lua:
Lua:
dofile('data/lib/event/zombie_arena.lua')

If that doesn't work, there is something wrong with how the server handles the libs. In that case, you have to add the dofile code above in every file that uses the zombie event script.

now
asdas10.jpg


and player dont enter

asdas10.png


thanks bro
 
now
asdas10.jpg


and player dont enter

asdas10.png


thanks bro

Look at the bottom of the data/lib/event/zombie_arena.lua file. As you can see in the console, it's an error at line #433. The original file doesn't even have 433 lines. You have accidentally copied: "Don't forget to add this in data/lib/lib.lua" at the bottom of the file.

Next time you get an error, always check what's on the line of the error. In this case just erase the old data/lib/event/zombie_arena.lua and copy a new one.
 
Nice! I only change death to preparedeath players no lose exp and items :)
 
When the Zombie's attack the player he just lose hp, he don't get tpd to the temple.
No errors on console
 
how can i fix this?

34555
i did everything but on the login.lua im using tfs 1.3 i have like this
Code:
local events = {
'ZombieArenaKill',
      'ZombieArenaDeath',
       'ZombieArenaLogout',
 'CreateTeleport1',
    'CreateTeleport2',
    'CreateTeleport3',
    'CreateTeleport4',
    'CreateTeleport5',
    'CreateTeleport6',
    'CreateTeleport7',
    'CreateTeleport8',
    'CreateTeleport9',
    'CreateTeleport10',
    'Tasksystem',
    'SummonTeleport',
    'Missions',
    'ElementalSpheresOverlords',
    'BigfootBurdenVersperoth',
    'Razzagorn',
    'Shatterer',
    'Zamulosh',   
    'The Hunger',
    'The Rage',
    'Eradicator',
    'Eradicator1',
    'Rupture',
    'World Devourer',   
    'Tarbaz',
    'Shulgrax',
    'Ragiaz',
    'Plagirath',
    'Mazoran',
    'Destabilized',
    'BigfootBurdenWiggler',
    'SvargrondArenaKill',
    'NewFrontierShardOfCorruption',
    'NewFrontierTirecz',
    'ServiceOfYalaharDiseasedTrio',
    'ServiceOfYalaharAzerus',
    'ServiceOfYalaharQuaraLeaders',
    'InquisitionBosses',
    'InquisitionUngreez',
    'KillingInTheNameOfKills',
    'KillingInTheNameOfKillss',
    'KillingInTheNameOfKillsss',
    'MastersVoiceServants',
    'SecretServiceBlackKnight',
    'ThievesGuildNomad',
    'WotELizardMagistratus',
    'WotELizardNoble',
    'WotEKeeper',
    'Maxxed',
    'WotEBosses',
    'WotEZalamon',
    'WarzoneThree',
    'PlayerDeath',
    'AdvanceSave',
    'bossesWarzone',
    'AdvanceRookgaard',
    'PythiusTheRotten',
    'DropLoot',
    'Yielothax',
    'BossParticipation',
    'Energized Raging Mage',
    'Raging Mage',
    'modalMD1',
    'VibrantEgg',
    'DeathCounter',
    'KillCounter',
    'bless1',
    'lowerRoshamuul',
    'SpikeTaskQuestCrystal',
    'SpikeTaskQuestDrillworm'
}
 
 
local function onMovementRemoveProtection(cid, oldPosition, time)
    local player = Player(cid)
    if not player then
        return true
    end
 
    local playerPosition = player:getPosition()
    if (playerPosition.x ~= oldPosition.x or playerPosition.y ~= oldPosition.y or playerPosition.z ~= oldPosition.z) or player:getTarget() then
        player:setStorageValue(Storage.combatProtectionStorage, 0)
        return true
    end
 
    addEvent(onMovementRemoveProtection, 1000, cid, oldPosition, time - 1)
end
 
function onLogin(player)
    local loginStr = 'Welcome to ' .. configManager.getString(configKeys.SERVER_NAME) .. '!'
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. ' Please choose your outfit.'       
        player:setBankBalance(0)

        if player:getSex() == 1 then
            player:setOutfit({lookType = 128, lookHead = 78, lookBody = 106, lookLegs = 58, lookFeet = 76})       
        else
            player:setOutfit({lookType = 136, lookHead = 78, lookBody = 106, lookLegs = 58, lookFeet = 76})   
        end

        player:sendTutorial(1)
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format('Your last visit was on %s.', os.date('%a %b %d %X %Y', player:getLastLoginSaved()))
    end
 
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
  
    local playerId = player:getId()
    
    player:loadSpecialStorage()

    --[[-- Maintenance mode
    if (player:getGroup():getId() < 2) then
        return false
    else
        
    end--]]

    if (player:getGroup():getId() >= 4) then
        player:setGhostMode(true)
    end

    -- Stamina
    nextUseStaminaTime[playerId] = 1

    -- EXP Stamina
    nextUseXpStamina[playerId] = 1

    -- Prey Stamina
    nextUseStaminaPrey[playerId+1] = {Time = 1}
    nextUseStaminaPrey[playerId+2] = {Time = 1}
    nextUseStaminaPrey[playerId+3] = {Time = 1}

    -- Prey Data
    if (player:getVocation():getId() ~= 0) then
        local columnUnlocked = getUnlockedColumn(player)
        if (not columnUnlocked) then
            columnUnlocked = 0
        end

        for i = 0, columnUnlocked do
            sendPreyData(player, i)
        end
    end

    if (player:getAccountType() == ACCOUNT_TYPE_TUTOR) then
        local msg = [[:: Regras Tutor ::
            1*>3 Advertências você perde o cargo.
            2*>Sem conversas paralelas com jogadores no Help, se o player começar a ofender, você simplesmente o mute.
            3*>Seja educado com os player no Help e principalmente no Privado, tenta ajudar o máximo possível.
            4*>Sempre logue no seu horário, caso não tiver uma justificativa você será removido da staff.
            5*>Help é somente permitido realizar dúvidas relacionadas ao tibia.
            6*>Não é Permitido divulgar time pra upar ou para ajudar em quest.
            7*>Não é permitido venda de itens no Help.
            8*>Caso o player encontre um bug, peça para ir ao site mandar um ticket e explicar em detalhes.
            9*>Mantenha sempre o Chat dos Tutores aberto. (obrigatório).
            10*>Você terminou de cumprir seu horário, viu que não tem nenhum tutor Online, você comunica com algum CM in-game ou ts e fica no help até alguém logar, se der.
            11*>Mantenha sempre um ótimo português no Help, queremos tutores que dêem suporte, não que fiquem falando um ritual satânico.
            12*>Se ver um tutor fazendo algo que infrinja as regras, tire uma print e envie aos superiores."
            -- Comandos --
            Mutar Player: /mute nick,90. (90 segundos)
            Desmutar Player: /unmute nick.
            -- Comandos --]]
        player:popupFYI(msg)
    end
  
     -- ABRIR CHANNELS
    if(not isInArray({1,2,3,5,6,7,8}, player:getVocation():getId()) or player:getLevel() < 6) then
        player:openChannel(6)   -- advertsing rook main
    else
        player:openChannel(5)   -- advertsing main
    end

      --
    -- Rewards
    local rewards = #player:getRewardList()
    if(rewards > 0) then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have %d %s in your reward chest.", rewards, rewards > 1 and "rewards" or "reward"))
    end
 
    -- Update player id
    local stats = player:inBossFight()
    if stats then
        stats.playerId = player:getId()
    end
 
    -- fury gates
    local messageType = nil
    if (player:getClient().os == 3 or
        player:getClient().os == 5) then
        messageType = MESSAGE_EVENT_ADVANCE
    end

    player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_ORANGE, 'Bem vindo ao Tibia Global!')
    
    if Game.getStorageValue(GlobalStorage.FuryGates, (9710)) == 1 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Venore Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9711)) == 2 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Abdendriel Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9712)) == 3 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Thais Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9713)) == 4 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Carlin Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9714)) == 5 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Edron Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9716)) == 6 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Kazordoon Today.')
    end

    player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_ORANGE, '[PREY SYSTEM and IMBUIMENT] Desfrute de todos os nossos sistemas disponiveis no servidor.')
  
    -- Events
    for i = 1, #events do
        player:registerEvent(events[i])
    end
    
    if player:getStorageValue(Storage.combatProtectionStorage) <= os.time() then
        player:setStorageValue(Storage.combatProtectionStorage, os.time() + 10)
        onMovementRemoveProtection(playerId, player:getPosition(), 10)
    end
    return true
end
 
how can i fix this?

View attachment 34555
i did everything but on the login.lua im using tfs 1.3 i have like this
Code:
local events = {
'ZombieArenaKill',
      'ZombieArenaDeath',
       'ZombieArenaLogout',
'CreateTeleport1',
    'CreateTeleport2',
    'CreateTeleport3',
    'CreateTeleport4',
    'CreateTeleport5',
    'CreateTeleport6',
    'CreateTeleport7',
    'CreateTeleport8',
    'CreateTeleport9',
    'CreateTeleport10',
    'Tasksystem',
    'SummonTeleport',
    'Missions',
    'ElementalSpheresOverlords',
    'BigfootBurdenVersperoth',
    'Razzagorn',
    'Shatterer',
    'Zamulosh',  
    'The Hunger',
    'The Rage',
    'Eradicator',
    'Eradicator1',
    'Rupture',
    'World Devourer',  
    'Tarbaz',
    'Shulgrax',
    'Ragiaz',
    'Plagirath',
    'Mazoran',
    'Destabilized',
    'BigfootBurdenWiggler',
    'SvargrondArenaKill',
    'NewFrontierShardOfCorruption',
    'NewFrontierTirecz',
    'ServiceOfYalaharDiseasedTrio',
    'ServiceOfYalaharAzerus',
    'ServiceOfYalaharQuaraLeaders',
    'InquisitionBosses',
    'InquisitionUngreez',
    'KillingInTheNameOfKills',
    'KillingInTheNameOfKillss',
    'KillingInTheNameOfKillsss',
    'MastersVoiceServants',
    'SecretServiceBlackKnight',
    'ThievesGuildNomad',
    'WotELizardMagistratus',
    'WotELizardNoble',
    'WotEKeeper',
    'Maxxed',
    'WotEBosses',
    'WotEZalamon',
    'WarzoneThree',
    'PlayerDeath',
    'AdvanceSave',
    'bossesWarzone',
    'AdvanceRookgaard',
    'PythiusTheRotten',
    'DropLoot',
    'Yielothax',
    'BossParticipation',
    'Energized Raging Mage',
    'Raging Mage',
    'modalMD1',
    'VibrantEgg',
    'DeathCounter',
    'KillCounter',
    'bless1',
    'lowerRoshamuul',
    'SpikeTaskQuestCrystal',
    'SpikeTaskQuestDrillworm'
}


local function onMovementRemoveProtection(cid, oldPosition, time)
    local player = Player(cid)
    if not player then
        return true
    end

    local playerPosition = player:getPosition()
    if (playerPosition.x ~= oldPosition.x or playerPosition.y ~= oldPosition.y or playerPosition.z ~= oldPosition.z) or player:getTarget() then
        player:setStorageValue(Storage.combatProtectionStorage, 0)
        return true
    end

    addEvent(onMovementRemoveProtection, 1000, cid, oldPosition, time - 1)
end

function onLogin(player)
    local loginStr = 'Welcome to ' .. configManager.getString(configKeys.SERVER_NAME) .. '!'
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. ' Please choose your outfit.'      
        player:setBankBalance(0)

        if player:getSex() == 1 then
            player:setOutfit({lookType = 128, lookHead = 78, lookBody = 106, lookLegs = 58, lookFeet = 76})      
        else
            player:setOutfit({lookType = 136, lookHead = 78, lookBody = 106, lookLegs = 58, lookFeet = 76})  
        end

        player:sendTutorial(1)
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format('Your last visit was on %s.', os.date('%a %b %d %X %Y', player:getLastLoginSaved()))
    end

    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
 
    local playerId = player:getId()
   
    player:loadSpecialStorage()

    --[[-- Maintenance mode
    if (player:getGroup():getId() < 2) then
        return false
    else
       
    end--]]

    if (player:getGroup():getId() >= 4) then
        player:setGhostMode(true)
    end

    -- Stamina
    nextUseStaminaTime[playerId] = 1

    -- EXP Stamina
    nextUseXpStamina[playerId] = 1

    -- Prey Stamina
    nextUseStaminaPrey[playerId+1] = {Time = 1}
    nextUseStaminaPrey[playerId+2] = {Time = 1}
    nextUseStaminaPrey[playerId+3] = {Time = 1}

    -- Prey Data
    if (player:getVocation():getId() ~= 0) then
        local columnUnlocked = getUnlockedColumn(player)
        if (not columnUnlocked) then
            columnUnlocked = 0
        end

        for i = 0, columnUnlocked do
            sendPreyData(player, i)
        end
    end

    if (player:getAccountType() == ACCOUNT_TYPE_TUTOR) then
        local msg = [[:: Regras Tutor ::
            1*>3 Advertências você perde o cargo.
            2*>Sem conversas paralelas com jogadores no Help, se o player começar a ofender, você simplesmente o mute.
            3*>Seja educado com os player no Help e principalmente no Privado, tenta ajudar o máximo possível.
            4*>Sempre logue no seu horário, caso não tiver uma justificativa você será removido da staff.
            5*>Help é somente permitido realizar dúvidas relacionadas ao tibia.
            6*>Não é Permitido divulgar time pra upar ou para ajudar em quest.
            7*>Não é permitido venda de itens no Help.
            8*>Caso o player encontre um bug, peça para ir ao site mandar um ticket e explicar em detalhes.
            9*>Mantenha sempre o Chat dos Tutores aberto. (obrigatório).
            10*>Você terminou de cumprir seu horário, viu que não tem nenhum tutor Online, você comunica com algum CM in-game ou ts e fica no help até alguém logar, se der.
            11*>Mantenha sempre um ótimo português no Help, queremos tutores que dêem suporte, não que fiquem falando um ritual satânico.
            12*>Se ver um tutor fazendo algo que infrinja as regras, tire uma print e envie aos superiores."
            -- Comandos --
            Mutar Player: /mute nick,90. (90 segundos)
            Desmutar Player: /unmute nick.
            -- Comandos --]]
        player:popupFYI(msg)
    end
 
     -- ABRIR CHANNELS
    if(not isInArray({1,2,3,5,6,7,8}, player:getVocation():getId()) or player:getLevel() < 6) then
        player:openChannel(6)   -- advertsing rook main
    else
        player:openChannel(5)   -- advertsing main
    end

      --
    -- Rewards
    local rewards = #player:getRewardList()
    if(rewards > 0) then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have %d %s in your reward chest.", rewards, rewards > 1 and "rewards" or "reward"))
    end

    -- Update player id
    local stats = player:inBossFight()
    if stats then
        stats.playerId = player:getId()
    end

    -- fury gates
    local messageType = nil
    if (player:getClient().os == 3 or
        player:getClient().os == 5) then
        messageType = MESSAGE_EVENT_ADVANCE
    end

    player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_ORANGE, 'Bem vindo ao Tibia Global!')
   
    if Game.getStorageValue(GlobalStorage.FuryGates, (9710)) == 1 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Venore Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9711)) == 2 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Abdendriel Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9712)) == 3 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Thais Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9713)) == 4 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Carlin Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9714)) == 5 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Edron Today.')
    elseif Game.getStorageValue(GlobalStorage.FuryGates, (9716)) == 6 then
        player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_BLUE, 'Fury Gate is on Kazordoon Today.')
    end

    player:sendTextMessage(messageType or MESSAGE_STATUS_CONSOLE_ORANGE, '[PREY SYSTEM and IMBUIMENT] Desfrute de todos os nossos sistemas disponiveis no servidor.')
 
    -- Events
    for i = 1, #events do
        player:registerEvent(events[i])
    end
   
    if player:getStorageValue(Storage.combatProtectionStorage) <= os.time() then
        player:setStorageValue(Storage.combatProtectionStorage, os.time() + 10)
        onMovementRemoveProtection(playerId, player:getPosition(), 10)
    end
    return true
end

add in the:
local events = {
'eventname'
in ur case i guess 'kill' and 'death', should work for you
 
When the event starts and players are moved from the waiting room to the arena, they debug the client after a few seconds

TFS 1.2 8.6 Client heelp
 
Working on OTX 4 after that small modifiation
Lua:
------------------------------------------------------
--              Zombie Arena by rwxsu               --
------------------------------------------------------
--            License: do as you please             --
------------------------------------------------------

-- Config
zombieArena = {
    config = {
        minPlayers = 1,  -- Minimum players for the event to begin
        monsters   = 10, -- Total monsters to kill
        monster    = 'zombie',
      
        -- Time between starts
        -- This gets called recursively until event is started
        minutesBetweenStart = 0.5,

        -- How many seconds between each zombie spawned
        secondsBetweenZombies = 2,
    },
    storages  = {
        eventOpened    = 670000,
        eventStarted   = 670001,
        eventFinished  = 670002,
        monstersLeft   = 670003,
        playerOnEvent  = 670004, -- Singular
        playersOnEvent = 670005, -- Global
    },
    positions = {
        waitingRoom = {
            center = Position(888, 975, 7),

            -- Radius is how many squares from center
            -- Do NOT count walls in radius
            radius = 5,
        },
        arena = {
            center = Position(846, 961, 7),
            radius = 7,
        },

        -- Where to spawn teleport to waiting room
        teleport = Position(147, 51, 7),
    },
    messages = {
        eventOpened   = "Zombie arena portal is now open!",
        eventStarted  = "Zombie arena event has started!",
        eventFinished = "All zombies have been slain! Zombie arena completed.",
        eventFailed   = "The zombies won by killing every single player...",
    },
    rewards = {
        [1] = {
            name   = "crystal coin",
            itemid = 2160,
            count  = 50,
        },
        [2] = {
            name   = "magic sword",
            itemid = 2400,
            count  = 1,
        },
--      [3] = {
--          name   = "example item",
--          itemid = 666,
--          count  = 1,
--      },
    },
}


zombieArena.__index = zombieArena


function zombieArena:autoStart()
    local function start()
        zombieArena:start()
    end

    -- Checks if event has been started recursively,
    -- if not tries again until start
    local function check()
        if not zombieArena:isStarted() then
            zombieArena:autoStart()
        end
    end

    addEvent(start, zombieArena.config.minutesBetweenStart * 60 * 1000)
    addEvent(check, zombieArena.config.minutesBetweenStart * 60 * 1000 + 5)
end

-- Main function to start event
function zombieArena:start()
    if zombieArena:isStarted() then
        zombieArena:debug("Event was already started.")
        return false
    end

    if not zombieArena:teleportPlayers() then
        return false
    end

    zombieArena:removeTeleport()
    zombieArena:summonMonsters()

    Game.broadcastMessage(zombieArena.messages.eventStarted, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena.config.monsters)
    Game.setStorageValue(zombieArena.storages.eventStarted, 1)
    return true
end


function zombieArena:openEvent()   
  
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is already open.")
        return false
    end

    if zombieArena:isStarted() then
        zombieArena:debug("Event has already started.")
        return false
    end

    -- Open event
    Game.broadcastMessage(zombieArena.messages.eventOpened, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 0)
    Game.setStorageValue(zombieArena.storages.eventOpened, 1)
    zombieArena:debug("Event opened.")
    zombieArena:createTeleport()
    return true
end


-- Creates the teleport to the waiting room
function zombieArena:createTeleport()
    local tp = Game.createItem(1387, 1, zombieArena.positions.teleport)
    if not tp:isTeleport() then
        tp:remove()
        return false
    end

    tp:setDestination(zombieArena.positions.waitingRoom.center)
    zombieArena:debug("Teleport created.")
    return true
end


-- Removes the teleport to the waiting room
function zombieArena:removeTeleport()

    if not Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is not opened.")
        return false
    end

    Game.setStorageValue(zombieArena.storages.eventOpened, 0)
    zombieArena:debug("Event closed for new players.")

    -- Remove teleport
    local tp = Tile(zombieArena.positions.teleport)
    if tp:getItemById(1387):isTeleport() then
        tp:getItemById(1387):remove()
        zombieArena:debug("Teleport removed.")
        return true
    end
end

function zombieArena:checkWaitingRoom()
    local center = zombieArena.positions.waitingRoom.center
    local radius = zombieArena.positions.waitingRoom.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)
  
    if #players == 0 then
        zombieArena:debug("No players in waiting room.")
        return nil
    end

    if #players < zombieArena.config.minPlayers then
        local message = string.format("%d players required to start. Currently %d player(s) found. ", zombieArena.config.minPlayers, #players)
        zombieArena:messageGroup(players, message)
        zombieArena:debug(message)
        return players
    end
    return players
end

function zombieArena:checkArena()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)

    if zombieArena:getPlayersLeft() == 0 then
        zombieArena:finish(false)   
        if zombieArena:clear() then
            zombieArena:debug("All players died.")
        end
        return nil
    end
    return players
end

-- Clears all zombies from arena
function zombieArena:clear()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local monsters = Game.getSpectators(center, false, false, radius, radius, radius, radius)

    if monsters == nil then
        return false
    end

    if #monsters < 0 then
        return false
    end

    for i = 1, #monsters do
        monster = Creature(monsters[i])
        monster:remove()
    end
    zombieArena:debug("Zombie arena cleared.")
    return true
end


-- If there's more players than the required minimum,
-- teleport all players from waiting room to the arena.
function zombieArena:teleportPlayers()
    players = zombieArena:checkWaitingRoom()
    if players ~= nil then
      
        -- Not enough players
        if #players < zombieArena.config.minPlayers then
            return false
        end

        -- Teleport players
        for i = 1, #players do
            local player = Player(players[i])
            player:teleportTo(zombieArena.positions.arena.center)
            zombieArena:debug(player:getName() .. " was teleported to arena.")
            zombieArena:addPlayer(player)
        end
        return true
    end
end

-- Adds player to the event
function zombieArena:addPlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 1)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() + 1)
    zombieArena:debug(player:getName() .. " was added to event.")
end

-- Removes player from the event
function zombieArena:removePlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() - 1)
    zombieArena:debug(player:getName() .. " was removed from event.")
end

-- Gets all players on event
function zombieArena:getPlayersLeft()
    return Game.getStorageValue(zombieArena.storages.playersOnEvent)
end


-- Message a group of people
function zombieArena:messageGroup(players, message)
    for i = 1, #players do
        local player = Player(players[i])
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
    end
end

-- Spawns a monster randomly within the radius provided in positions
function zombieArena:createMonster(i)

    -- Purposely written this way instead of using the table directly,
    -- since tables are pass by reference.
    local radius = zombieArena.positions.arena.radius
    local x = zombieArena.positions.arena.center.x
    local y = zombieArena.positions.arena.center.y
    local z = zombieArena.positions.arena.center.z
    x = math.random(x - radius, x + radius)
    y = math.random(y - radius, y + radius)
  
    local function create()
        -- Create monster
        if zombieArena:isStarted() then
            if Game.createMonster(zombieArena.config.monster, Position(x, y, z)) then
                Position(x, y, z):sendMagicEffect(CONST_ME_BLACKSMOKE)
                local message = string.format("%s created at position {x = %d, y = %d, z = %d}", zombieArena.config.monster, x, y, z)
                zombieArena:debug(message)
                return true
            end
        end
    end

    if addEvent(create, i * zombieArena.config.secondsBetweenZombies * 1000) then
        return true
    end
  
    -- Something went wrong
    local message = string.format("Unexpected error: couldn't create %s at position {x = %d, y = %d, z = %d}", monster, x, y, z)
    zombieArena:debug(message)
    return false
end

-- Summon x monsters provided in config
function zombieArena:summonMonsters()
    for i = 1, zombieArena.config.monsters do
            zombieArena:createMonster(i)
    end
    local message = string.format("%d monsters will be summoned.", zombieArena.config.monsters)
    zombieArena:debug(message)
end

-- Gets how many monsters there left in arena
function zombieArena:getMonstersLeft()
    return Game.getStorageValue(zombieArena.storages.monstersLeft)
end


function zombieArena:onKill(killer)

    players = zombieArena:checkArena()

    -- Subtract one from monstersLeft
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena:getMonstersLeft() - 1)

    -- Check if event is complete
    if zombieArena:getMonstersLeft() == 0 then
        for i = 1, #players do
            local player = Player(players[i])
            zombieArena:reward(player)
        end

        -- Ends the event
        zombieArena:finish(true)
        return true
    end

    local message = string.format("%s killed a %s! Only %d left.", killer:getName(), zombieArena.config.monster, zombieArena:getMonstersLeft())
    if players ~= nil then
        zombieArena:messageGroup(players, message)
    end
    zombieArena:debug(message)
end

function zombieArena:finish(playersWon)

    if playersWon then
        Game.broadcastMessage(zombieArena.messages.eventFinished, MESSAGE_STATUS_WARNING)
        zombieArena:debug(zombieArena.messages.eventFinished)
    else
        Game.broadcastMessage(zombieArena.messages.eventFailed, MESSAGE_STATUS_WARNING)
    zombieArena:debug(zombieArena.messages.eventFailed)
    end

    Game.setStorageValue(zombieArena.storages.eventStarted, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 1)
end

-- Give the players who survived the event a reward
-- and teleport to hometown
function zombieArena:reward(player)
    for i = 1, #zombieArena.rewards do
        player:addItem(zombieArena.rewards[i].itemid, zombieArena.rewards[i].count)

        local message = string.format("You received a %s.", zombieArena.rewards[i].name)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
        zombieArena:debug(player:getName() .. " received a " .. zombieArena.rewards[i].name)

    end
    player:teleportTo(player:getTown():getTemplePosition())
    zombieArena:debug(player:getName() .. " got teleported to " .. player:getTown():getName() .. ".")

    zombieArena:removePlayer(player)
    return true
end

-- Checks if event is finished
-- returns either true or false
function zombieArena:isFinished()
    if Game.getStorageValue(zombieArena.storages.eventFinished) == 1 then
        return true
    end
    return false
end

-- Checks if event has started
-- returns either true or false
function zombieArena:isStarted()
    if Game.getStorageValue(zombieArena.storages.eventStarted) == 1 then
        return true
    end
    return false
end

-- Checks if event is opened
-- returns either true or false
function zombieArena:isOpened()
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        return true
    end
    return false
end


-- Check if player is doing event
-- returns either true or false
function zombieArena:isPlayerOnEvent(player)
    if player:getStorageValue(zombieArena.storages.playerOnEvent) == 1 then
        return true
    end
    return false
end


-- Toggle debug on/off on top off this file
function zombieArena:debug(message)
    if debug then
        message = "[ZOMBIEARENA] " .. message
        print(message)
    end
end
 
Working on OTX 4 after that small modifiation
Lua:
------------------------------------------------------
--              Zombie Arena by rwxsu               --
------------------------------------------------------
--            License: do as you please             --
------------------------------------------------------

-- Config
zombieArena = {
    config = {
        minPlayers = 1,  -- Minimum players for the event to begin
        monsters   = 10, -- Total monsters to kill
        monster    = 'zombie',
     
        -- Time between starts
        -- This gets called recursively until event is started
        minutesBetweenStart = 0.5,

        -- How many seconds between each zombie spawned
        secondsBetweenZombies = 2,
    },
    storages  = {
        eventOpened    = 670000,
        eventStarted   = 670001,
        eventFinished  = 670002,
        monstersLeft   = 670003,
        playerOnEvent  = 670004, -- Singular
        playersOnEvent = 670005, -- Global
    },
    positions = {
        waitingRoom = {
            center = Position(888, 975, 7),

            -- Radius is how many squares from center
            -- Do NOT count walls in radius
            radius = 5,
        },
        arena = {
            center = Position(846, 961, 7),
            radius = 7,
        },

        -- Where to spawn teleport to waiting room
        teleport = Position(147, 51, 7),
    },
    messages = {
        eventOpened   = "Zombie arena portal is now open!",
        eventStarted  = "Zombie arena event has started!",
        eventFinished = "All zombies have been slain! Zombie arena completed.",
        eventFailed   = "The zombies won by killing every single player...",
    },
    rewards = {
        [1] = {
            name   = "crystal coin",
            itemid = 2160,
            count  = 50,
        },
        [2] = {
            name   = "magic sword",
            itemid = 2400,
            count  = 1,
        },
--      [3] = {
--          name   = "example item",
--          itemid = 666,
--          count  = 1,
--      },
    },
}


zombieArena.__index = zombieArena


function zombieArena:autoStart()
    local function start()
        zombieArena:start()
    end

    -- Checks if event has been started recursively,
    -- if not tries again until start
    local function check()
        if not zombieArena:isStarted() then
            zombieArena:autoStart()
        end
    end

    addEvent(start, zombieArena.config.minutesBetweenStart * 60 * 1000)
    addEvent(check, zombieArena.config.minutesBetweenStart * 60 * 1000 + 5)
end

-- Main function to start event
function zombieArena:start()
    if zombieArena:isStarted() then
        zombieArena:debug("Event was already started.")
        return false
    end

    if not zombieArena:teleportPlayers() then
        return false
    end

    zombieArena:removeTeleport()
    zombieArena:summonMonsters()

    Game.broadcastMessage(zombieArena.messages.eventStarted, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena.config.monsters)
    Game.setStorageValue(zombieArena.storages.eventStarted, 1)
    return true
end


function zombieArena:openEvent()  
 
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is already open.")
        return false
    end

    if zombieArena:isStarted() then
        zombieArena:debug("Event has already started.")
        return false
    end

    -- Open event
    Game.broadcastMessage(zombieArena.messages.eventOpened, MESSAGE_STATUS_WARNING)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 0)
    Game.setStorageValue(zombieArena.storages.eventOpened, 1)
    zombieArena:debug("Event opened.")
    zombieArena:createTeleport()
    return true
end


-- Creates the teleport to the waiting room
function zombieArena:createTeleport()
    local tp = Game.createItem(1387, 1, zombieArena.positions.teleport)
    if not tp:isTeleport() then
        tp:remove()
        return false
    end

    tp:setDestination(zombieArena.positions.waitingRoom.center)
    zombieArena:debug("Teleport created.")
    return true
end


-- Removes the teleport to the waiting room
function zombieArena:removeTeleport()

    if not Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        zombieArena:debug("Event is not opened.")
        return false
    end

    Game.setStorageValue(zombieArena.storages.eventOpened, 0)
    zombieArena:debug("Event closed for new players.")

    -- Remove teleport
    local tp = Tile(zombieArena.positions.teleport)
    if tp:getItemById(1387):isTeleport() then
        tp:getItemById(1387):remove()
        zombieArena:debug("Teleport removed.")
        return true
    end
end

function zombieArena:checkWaitingRoom()
    local center = zombieArena.positions.waitingRoom.center
    local radius = zombieArena.positions.waitingRoom.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)
 
    if #players == 0 then
        zombieArena:debug("No players in waiting room.")
        return nil
    end

    if #players < zombieArena.config.minPlayers then
        local message = string.format("%d players required to start. Currently %d player(s) found. ", zombieArena.config.minPlayers, #players)
        zombieArena:messageGroup(players, message)
        zombieArena:debug(message)
        return players
    end
    return players
end

function zombieArena:checkArena()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local players = Game.getSpectators(center, false, true, radius, radius, radius, radius)

    if zombieArena:getPlayersLeft() == 0 then
        zombieArena:finish(false)  
        if zombieArena:clear() then
            zombieArena:debug("All players died.")
        end
        return nil
    end
    return players
end

-- Clears all zombies from arena
function zombieArena:clear()
    local center = zombieArena.positions.arena.center
    local radius = zombieArena.positions.arena.radius
    local monsters = Game.getSpectators(center, false, false, radius, radius, radius, radius)

    if monsters == nil then
        return false
    end

    if #monsters < 0 then
        return false
    end

    for i = 1, #monsters do
        monster = Creature(monsters[i])
        monster:remove()
    end
    zombieArena:debug("Zombie arena cleared.")
    return true
end


-- If there's more players than the required minimum,
-- teleport all players from waiting room to the arena.
function zombieArena:teleportPlayers()
    players = zombieArena:checkWaitingRoom()
    if players ~= nil then
     
        -- Not enough players
        if #players < zombieArena.config.minPlayers then
            return false
        end

        -- Teleport players
        for i = 1, #players do
            local player = Player(players[i])
            player:teleportTo(zombieArena.positions.arena.center)
            zombieArena:debug(player:getName() .. " was teleported to arena.")
            zombieArena:addPlayer(player)
        end
        return true
    end
end

-- Adds player to the event
function zombieArena:addPlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 1)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() + 1)
    zombieArena:debug(player:getName() .. " was added to event.")
end

-- Removes player from the event
function zombieArena:removePlayer(player)
    player:setStorageValue(zombieArena.storages.playerOnEvent, 0)
    Game.setStorageValue(zombieArena.storages.playersOnEvent, zombieArena:getPlayersLeft() - 1)
    zombieArena:debug(player:getName() .. " was removed from event.")
end

-- Gets all players on event
function zombieArena:getPlayersLeft()
    return Game.getStorageValue(zombieArena.storages.playersOnEvent)
end


-- Message a group of people
function zombieArena:messageGroup(players, message)
    for i = 1, #players do
        local player = Player(players[i])
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
    end
end

-- Spawns a monster randomly within the radius provided in positions
function zombieArena:createMonster(i)

    -- Purposely written this way instead of using the table directly,
    -- since tables are pass by reference.
    local radius = zombieArena.positions.arena.radius
    local x = zombieArena.positions.arena.center.x
    local y = zombieArena.positions.arena.center.y
    local z = zombieArena.positions.arena.center.z
    x = math.random(x - radius, x + radius)
    y = math.random(y - radius, y + radius)
 
    local function create()
        -- Create monster
        if zombieArena:isStarted() then
            if Game.createMonster(zombieArena.config.monster, Position(x, y, z)) then
                Position(x, y, z):sendMagicEffect(CONST_ME_BLACKSMOKE)
                local message = string.format("%s created at position {x = %d, y = %d, z = %d}", zombieArena.config.monster, x, y, z)
                zombieArena:debug(message)
                return true
            end
        end
    end

    if addEvent(create, i * zombieArena.config.secondsBetweenZombies * 1000) then
        return true
    end
 
    -- Something went wrong
    local message = string.format("Unexpected error: couldn't create %s at position {x = %d, y = %d, z = %d}", monster, x, y, z)
    zombieArena:debug(message)
    return false
end

-- Summon x monsters provided in config
function zombieArena:summonMonsters()
    for i = 1, zombieArena.config.monsters do
            zombieArena:createMonster(i)
    end
    local message = string.format("%d monsters will be summoned.", zombieArena.config.monsters)
    zombieArena:debug(message)
end

-- Gets how many monsters there left in arena
function zombieArena:getMonstersLeft()
    return Game.getStorageValue(zombieArena.storages.monstersLeft)
end


function zombieArena:onKill(killer)

    players = zombieArena:checkArena()

    -- Subtract one from monstersLeft
    Game.setStorageValue(zombieArena.storages.monstersLeft, zombieArena:getMonstersLeft() - 1)

    -- Check if event is complete
    if zombieArena:getMonstersLeft() == 0 then
        for i = 1, #players do
            local player = Player(players[i])
            zombieArena:reward(player)
        end

        -- Ends the event
        zombieArena:finish(true)
        return true
    end

    local message = string.format("%s killed a %s! Only %d left.", killer:getName(), zombieArena.config.monster, zombieArena:getMonstersLeft())
    if players ~= nil then
        zombieArena:messageGroup(players, message)
    end
    zombieArena:debug(message)
end

function zombieArena:finish(playersWon)

    if playersWon then
        Game.broadcastMessage(zombieArena.messages.eventFinished, MESSAGE_STATUS_WARNING)
        zombieArena:debug(zombieArena.messages.eventFinished)
    else
        Game.broadcastMessage(zombieArena.messages.eventFailed, MESSAGE_STATUS_WARNING)
    zombieArena:debug(zombieArena.messages.eventFailed)
    end

    Game.setStorageValue(zombieArena.storages.eventStarted, 0)
    Game.setStorageValue(zombieArena.storages.eventFinished, 1)
end

-- Give the players who survived the event a reward
-- and teleport to hometown
function zombieArena:reward(player)
    for i = 1, #zombieArena.rewards do
        player:addItem(zombieArena.rewards[i].itemid, zombieArena.rewards[i].count)

        local message = string.format("You received a %s.", zombieArena.rewards[i].name)
        player:sendTextMessage(MESSAGE_STATUS_WARNING, message)
        zombieArena:debug(player:getName() .. " received a " .. zombieArena.rewards[i].name)

    end
    player:teleportTo(player:getTown():getTemplePosition())
    zombieArena:debug(player:getName() .. " got teleported to " .. player:getTown():getName() .. ".")

    zombieArena:removePlayer(player)
    return true
end

-- Checks if event is finished
-- returns either true or false
function zombieArena:isFinished()
    if Game.getStorageValue(zombieArena.storages.eventFinished) == 1 then
        return true
    end
    return false
end

-- Checks if event has started
-- returns either true or false
function zombieArena:isStarted()
    if Game.getStorageValue(zombieArena.storages.eventStarted) == 1 then
        return true
    end
    return false
end

-- Checks if event is opened
-- returns either true or false
function zombieArena:isOpened()
    if Game.getStorageValue(zombieArena.storages.eventOpened) == 1 then
        return true
    end
    return false
end


-- Check if player is doing event
-- returns either true or false
function zombieArena:isPlayerOnEvent(player)
    if player:getStorageValue(zombieArena.storages.playerOnEvent) == 1 then
        return true
    end
    return false
end


-- Toggle debug on/off on top off this file
function zombieArena:debug(message)
    if debug then
        message = "[ZOMBIEARENA] " .. message
        print(message)
    end
end
Still the same
 
Back
Top