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

Zombie event problem tfs 1.3 8.6

vexler222

Active Member
Joined
Apr 22, 2012
Messages
714
Solutions
15
Reaction score
46
Hi, I have a problem with this script when the event started and the player teleported to position XYZ at the same time the script spawned zombies in the same position I don't know why

Code:
-- Store player kills
if zombieKillCount == nil then
    zombieKillCount = {}
end
 
-- Zombie Variables
ze_zombieName = "Zombie" -- Zombie name
ze_timeToStartInvasion = 30 -- When should the first zombie be summoned [seconds]
ze_zombieSpawnInerval = 15 -- The interval of each zombie that will get summoned
ze_zombieMaxSpawn = 100 -- Max zombies in the arena
ze_zombieCountGlobalStorage = 100 -- Use empty global storage
 
-- Player Variables
ze_joinStorage = 1000 -- Storage that will be added, when player join
ze_minPlayers = 2 -- Minimum players that have to join
ze_maxPlayers = 30 -- Maxnimum players that can join
ze_joinCountGlobalStorage = 101 -- Use empty global storage
 
-- States
ze_stateGlobalStorage = 102 -- Use empty global storage
ze_EVENT_CLOSED = 0
ze_EVENT_STATE_STARTUP = 1
ze_EVENT_STARTED = 2
 
-- Waiting room
ze_WaitingRoomStartPosition = Position(1158, 723, 7) -- Where should player be teleport in waiting room
ze_waitingRoomCenterPosition = Position(1158, 723, 7) -- Center of the waiting room
ze_waitingRoomRadiusX = 8 -- Depends how big the arena room is 25sqm to x
ze_waitingRoomRadiusY = 5 -- Depends how big the arena room is 25sqm to y
 
-- Zombie arena
ze_zombieArenaStartPosition = Position(1135, 770, 7) -- When even start where should player be teleported in the zombie arena?
ze_arenaCenterPosition = Position(1133, 772, 7) -- Center position of the arena
ze_arenaFromPosition = Position(1109, 740, 7) -- Pos of top left corner
ze_arenaToPosition = Position(1161, 805, 7) -- Pos of bottom right corner
ze_arenaRoomRadiusX = 20 -- Depends how big the arena room is 50sqm to x
ze_arenaRoomRadiusY = 30 -- Depends how big the arena room is 50sqm to y
ze_arenaRoomMultifloor = false -- Does the arena have more floors than one?
 
-- Other variables
ze_waitTime = 5 -- How long until the event begin?
ze_createTeleportPosition = Position(1004, 1000, 6) -- Where should the teleport be created?
ze_teleportActionId = 7000 -- Actionid of the teleport
ze_trophiesTable = {
    [1] = {itemid = 7369, itemid2 = 2160, itemid2c = 50, description = "won first place on Zombie Event."},
    [2] = {itemid = 7370, itemid2 = 2160, itemid2c = 30, description = "won second place on Zombie Event."},
    [3] = {itemid = 7371, itemid2 = 2160, itemid2c = 15, description = "won third place on Zombie Event."}
}
 
-- Get methods
function getZombieEventZombieCount()
    return Game.getStorageValue(ze_zombieCountGlobalStorage)
end
 
function getZombieEventJoinedCount()
    return Game.getStorageValue(ze_joinCountGlobalStorage)
end
 
function setZombieEventState(value)
    Game.setStorageValue(ze_stateGlobalStorage, value)
end
 
function getZombieEventState()
    return Game.getStorageValue(ze_stateGlobalStorage) or ze_EVENT_CLOSED
end
 
function resetZombieEvent()
    -- Reset variables
    Game.setStorageValue(ze_zombieCountGlobalStorage, 0)
    Game.setStorageValue(ze_joinCountGlobalStorage, 0)
    setZombieEventState(ze_EVENT_CLOSED)
 
    -- Clear the arena from zombies
    local spectator = Game.getSpectators(ze_arenaCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_arenaRoomRadiusX, 0, ze_arenaRoomRadiusY)
    for i = 1, #spectator do
        if spectator[i]:isMonster() then
            spectator[i]:remove()
        end
    end
end
 
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
            spectator[i]:teleportTo(ze_zombieArenaStartPosition)
            spectator[i]:registerEvent("ZombiePlayerDeath")
        end
 
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end
 
    -- Remove Teleport
    local item = Tile(ze_createTeleportPosition):getItemById(1387)
    if item:isTeleport() then
        item:remove()
    end
end
 
function startZombieInvasion()
    if getZombieEventState() == ze_EVENT_STARTED then
        local random = math.random
        local zombie = Game.createMonster(ze_zombieName, Position(random(ze_arenaFromPosition.x, ze_arenaToPosition.x), random(ze_arenaFromPosition.y, ze_arenaToPosition.y), random(ze_arenaFromPosition.z, ze_arenaToPosition.z)))
        if zombie then
            Game.setStorageValue(ze_zombieCountGlobalStorage, getZombieEventZombieCount() + 1)
        end
 
        addEvent(startZombieInvasion, ze_zombieSpawnInerval * 1000)
    end
end
 
function Player.joinZombieEvent(self)
    -- Set storage and teleport
    self:teleportTo(ze_WaitingRoomStartPosition)
    ze_WaitingRoomStartPosition:sendMagicEffect(CONST_ME_TELEPORT)
    self:setStorageValue(ze_joinStorage, 1)
 
    -- Add count and broadcast
    local count = getZombieEventJoinedCount()
    Game.setStorageValue(ze_joinCountGlobalStorage, count + 1)
    Game.broadcastMessage(string.format("%s has joined the Zombie Event! [%d/%d].", self:getName(), count + 1, ze_maxPlayers))
end
 
function setupZombieEvent(minPlayers, maxPlayers, waitTime)
    -- Event is not closed, then stop from start new one
    if getZombieEventState() ~= ze_EVENT_CLOSED then
        return
    end
 
    -- Create teleport and set the respective action id
    local item = Game.createItem(1387, 1, ze_createTeleportPosition)
    if item:isTeleport() then
        item:setAttribute(ITEM_ATTRIBUTE_ACTIONID, ze_teleportActionId)
    end
 
    -- Change the variables, to the new ones
    ze_minPlayers = minPlayers
    ze_maxPlayers = maxPlayers
    ze_waitTime = waitTime
 
    -- Set the counts, state, broadcast and delay the start of the event.
    Game.setStorageValue(ze_zombieCountGlobalStorage, 0)
    Game.setStorageValue(ze_joinCountGlobalStorage, 0)
    setZombieEventState(ze_EVENT_STATE_STARTUP)
    Game.broadcastMessage(string.format("[ZombieEvent] The event require atleast %d and max %d players, you have %d minutes to join. [TP Events +1 Temple]", minPlayers, maxPlayers, waitTime))
    addEvent(startZombieEvent, waitTime * 60 * 1000)
end
 
Solution
@Xikini
Found a problem xd I have monsters outside the lobby and when players teleported to the arena the script also teleported someone from the monsters (idk why) but I add this and it works but don't know if it is correct? I am not professionals

I change this function:
Code:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()...
As far as I can tell it spawns zombies in this area
Lua:
ze_arenaFromPosition = Position(1109, 740, 7) -- Pos of top left corner
ze_arenaToPosition = Position(1161, 805, 7) -- Pos of bottom right corner

That can be close to the player, or far away, depending on randomness.
 
@Xikini yeah, but i have every time same situation look at video.

When players are teleported to arena, in same time zombie be spawned on same position where is player and in one moment zombie event finished

 
@Xikini yeah, but i have every time same situation look at video.

When players are teleported to arena, in same time zombie be spawned on same position where is player and in one moment zombie event finished


Are you sure they are even teleporting to the arena? xD

I didn't even see a flash of the arena, just them teleporting to temple.

How do players join the event?
I don't see any script for that here.
 
@Xikini yes im sure all player teleporting to the arena, cuz after teleport to temple i see in logs damage from monster Zombie, i recorded new video from character in arena.


There is script from movements, player go to teleport and got teleport to waiting room, after X min they got teleport to zombie arena

Code:
function onStepIn(creature, item, position, fromPosition)

    local player = creature:getPlayer()

    if not player == nil then
        return true
    end

    -- If it's a staff memeber, just teleport inside and do not count as participant
    if player:getGroup():getAccess() then
        player:teleportTo(ze_WaitingRoomStartPosition)
        return true
    end

    -- If the event state is closed or started, then stop players from enter
    if isInArray({ze_EVENT_CLOSED, ze_EVENT_STARTED}, getZombieEventState()) then
        player:teleportTo(fromPosition, true)
        fromPosition:sendMagicEffect(CONST_ME_TELEPORT)
        return true
    end

    -- Check if the event has already max players
    if getZombieEventJoinedCount() >= ze_maxPlayers then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "The Zombie Event is already full.")
        player:teleportTo(fromPosition, true)
        fromPosition:sendMagicEffect(CONST_ME_TELEPORT)
        return true
    end

    -- Execute join event
    player:joinZombieEvent()
    return true
end
 
@Xikini yes im sure all player teleporting to the arena, cuz after teleport to temple i see in logs damage from monster Zombie, i recorded new video from character in arena.


There is script from movements, player go to teleport and got teleport to waiting room, after X min they got teleport to zombie arena

Code:
function onStepIn(creature, item, position, fromPosition)

    local player = creature:getPlayer()

    if not player == nil then
        return true
    end

    -- If it's a staff memeber, just teleport inside and do not count as participant
    if player:getGroup():getAccess() then
        player:teleportTo(ze_WaitingRoomStartPosition)
        return true
    end

    -- If the event state is closed or started, then stop players from enter
    if isInArray({ze_EVENT_CLOSED, ze_EVENT_STARTED}, getZombieEventState()) then
        player:teleportTo(fromPosition, true)
        fromPosition:sendMagicEffect(CONST_ME_TELEPORT)
        return true
    end

    -- Check if the event has already max players
    if getZombieEventJoinedCount() >= ze_maxPlayers then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "The Zombie Event is already full.")
        player:teleportTo(fromPosition, true)
        fromPosition:sendMagicEffect(CONST_ME_TELEPORT)
        return true
    end

    -- Execute join event
    player:joinZombieEvent()
    return true
end
Hmm. well this is the only thing that spawns zombies
Lua:
function startZombieInvasion()
    if getZombieEventState() == ze_EVENT_STARTED then
        local random = math.random
        local zombie = Game.createMonster(ze_zombieName, Position(random(ze_arenaFromPosition.x, ze_arenaToPosition.x), random(ze_arenaFromPosition.y, ze_arenaToPosition.y), random(ze_arenaFromPosition.z, ze_arenaToPosition.z)))
        if zombie then
            Game.setStorageValue(ze_zombieCountGlobalStorage, getZombieEventZombieCount() + 1)
        end
 
        addEvent(startZombieInvasion, ze_zombieSpawnInerval * 1000)
    end
end

So, I guess let's re-create it, so we can print out the location of the zombie spawns.

Try this, and tell us what shows in console.
Lua:
function startZombieInvasion()
    if getZombieEventState() == ze_EVENT_STARTED then
        local x = math.random(ze_arenaFromPosition.x, ze_arenaToPosition.x)
        local y = math.random(ze_arenaFromPosition.y, ze_arenaToPosition.y)
        local z = math.random(ze_arenaFromPosition.z, ze_arenaToPosition.z)
        print("Atempting to spawn zombie at Position(" .. x .. "," .. y .. "," .. z .. ")")
        local zombie = Game.createMonster(ze_zombieName, Position(x, y, z))
        if zombie then
            print("Successfully spawned zombie.")
            Game.setStorageValue(ze_zombieCountGlobalStorage, getZombieEventZombieCount() + 1)
        else
            print("Failed to spawn zombie.")
        end
    
        addEvent(startZombieInvasion, ze_zombieSpawnInerval * 1000)
    end
end
 
@Xikini
Found a problem xd I have monsters outside the lobby and when players teleported to the arena the script also teleported someone from the monsters (idk why) but I add this and it works but don't know if it is correct? I am not professionals

I change this function:
Code:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
            spectator[i]:teleportTo(ze_zombieArenaStartPosition)
            spectator[i]:registerEvent("ZombiePlayerDeath")
        end
 
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end
 
    -- Remove Teleport
    local item = Tile(ze_createTeleportPosition):getItemById(1387)
    if item:isTeleport() then
        item:remove()
    end
end

To:
Code:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
        if spectator[i]:isMonster() then
            spectator[i]:remove()
        else
            spectator[i]:teleportTo(ze_zombieArenaStartPosition)
            spectator[i]:registerEvent("ZombiePlayerDeath")
        end
    end
 
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end

I added only one "if"

Code:
        if spectator[i]:isMonster() then
            spectator[i]:remove()
 
Last edited:
@Xikini
Found a problem xd I have monsters outside the lobby and when players teleported to the arena the script also teleported someone from the monsters (idk why) but I add this and it works but don't know if it is correct? I am not professionals

I change this function:
Code:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
            spectator[i]:teleportTo(ze_zombieArenaStartPosition)
            spectator[i]:registerEvent("ZombiePlayerDeath")
        end
 
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end
 
    -- Remove Teleport
    local item = Tile(ze_createTeleportPosition):getItemById(1387)
    if item:isTeleport() then
        item:remove()
    end
end

To:
Code:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
            spectator[i]:setStorageValue(ze_joinStorage, 0)
        end
 
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
        if spectator[i]:isMonster() then
            spectator[i]:remove()
        else
            spectator[i]:teleportTo(ze_zombieArenaStartPosition)
            spectator[i]:registerEvent("ZombiePlayerDeath")
        end
    end
 
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end

I added only one "if"

Code:
        if spectator[i]:isMonster() then
            spectator[i]:remove()
Ah.
In your example, you are removing the monsters, teleporting the players & teleporting potential npc's that are in the scan area.

I'd do it this way, so that we are only teleporting the intended targets (players), and never touching anything else.

More specifically, I'd add all event participants and event monsters to a table, so that you don't need to do area scans at all, but that's neither here nor there, since it would require to basically re-script the entire event lol.

Anyway, this should work as you wanted.
Lua:
function startZombieEvent()
    local spectator = Game.getSpectators(ze_waitingRoomCenterPosition, ze_arenaRoomMultifloor, false, 0, ze_waitingRoomRadiusX, 0, ze_waitingRoomRadiusY)
    if getZombieEventJoinedCount() < ze_minPlayers then
        for i = 1, #spectator do
            if spectator[i]:isPlayer() then
                spectator[i]:teleportTo(spectator[i]:getTown():getTemplePosition())
                spectator[i]:setStorageValue(ze_joinStorage, 0)
            end
        end
    
        resetZombieEvent()
        Game.broadcastMessage("Zombie event failed to start, due to not enough of participants.")
    else
        for i = 1, #spectator do
            if spectator[i]:isPlayer() then
                spectator[i]:teleportTo(ze_zombieArenaStartPosition)
                spectator[i]:registerEvent("ZombiePlayerDeath")
            end
        end
    
        Game.broadcastMessage("Zombie Event has started, good luck to all participants.")
        setZombieEventState(ze_EVENT_STARTED)
        addEvent(startZombieInvasion, ze_timeToStartInvasion * 1000)
    end
    
    -- Remove Teleport
    local item = Tile(ze_createTeleportPosition):getItemById(1387)
    if item:isTeleport() then
        item:remove()
    end
end
 
Solution
Back
Top