• 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!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

MoveEvent [1.3] Zombski 🧠🧟‍♂️

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,249
Solutions
71
Reaction score
610
Location
Hell
Preview

map setup
Skärmavbild 2021-04-30 kl. 20.03.45.png


code
  • Create new folder in data/scripts, call it zombie
  • Inside data/scripts/zombie/ add the following files:
zombski.lua
Lua:
local mType = Game.createMonsterType("Zombski")
local monster = {}
monster.description = "a zombski"
monster.experience = 1
monster.outfit = {
    lookType = 311
}
monster.health = 100
monster.maxHealth = monster.health
monster.race = "undead"
monster.corpse = 9875
monster.speed = 200
monster.maxSummons = 0
monster.changeTarget = {
    interval = 1000,
    chance   = 40
}
monster.flags = {
    hostile            = true,
    summonable         = false,
    attackable         = false,
    convinceable       = false,
    illusionable       = false,
    canPushItems       = true,
    canPushCreatures   = false,
    targetDistance     = 1,
    staticAttackChance = 100
}
monster.voices = {
    interval = 5000,
    chance   = 10,
    {text = "KHGKHGKH", yell = false},
    {text = "KHAAAA",   yell = false}
}
monster.attacks = {
    {name = "melee", attack = 1, skill = 1, effect = CONST_ME_DRAWBLOOD, interval = 1500}
}
monster.defenses = {
    defense = 55,
    armor = 55,
--  {name = "combat", type = COMBAT_HEALING, chance = 15, interval = 2*1000, minDamage = 180, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE},
--  {name = "speed", chance = 15, interval = 2*1000, speed = 320, effect = CONST_ME_MAGIC_RED}
}
monster.elements = {
    {type = COMBAT_PHYSICALDAMAGE, percent = 100},
    {type = COMBAT_DEATHDAMAGE,    percent = 100},
    {type = COMBAT_ENERGYDAMAGE,   percent = 100},
    {type = COMBAT_EARTHDAMAGE,    percent = 100},
    {type = COMBAT_ICEDAMAGE,      percent = 100},
    {type = COMBAT_HOLYDAMAGE,     percent = 100},
    {type = COMBAT_POISONDAMAGE,   percent = 100},
    {type = COMBAT_FIREDAMAGE,     percent = 100},
    {type = COMBAT_DROWNDAMAGE,    percent = 100},
    {type = COMBAT_LIFEDRAIN,      percent = 100}
}
monster.immunities = {
    {type = "fire", combat = true, condition = true},
    {type = "drown", condition = true},
    {type = "lifedrain", combat = true},
    {type = "paralyze", condition = true},
    {type = "invisible", condition = true}
}
mType:register(monster)

zombie.lua
Lua:
local function secondsToReadable(s)
    local hours   = math.floor(s / 3600)
    local minutes = math.floor(math.mod(s, 3600)/60)
    local seconds = math.floor(math.mod(s, 60))
    return (hours   > 0 and (hours   .. ' hour'   .. (hours   > 1 and 's ' or ' ')) or '') ..
           (minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
           (seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local zombie = {}
-- keeps track of players & zombies
zombie.players = {}
zombie.zombies = {}
--#
zombie.config  = {
    startTime = '19:44:30', -- Hours:minutes:seconds
    -- How many players needed to start the event.
    minimumPlayers = 2,
    -- How many players can enter at most.
    maximumPlayers = 10,
    -- %chance of a player dying from zombie attack
    playerDeathChance = 20, -- %
    -- How many zombies should spawn in the beginning?
    zombieStartAmount = 3,
    -- Name of the monster to be spawned
    zombieName = 'zombski',
    -- This is used to check if zombie event has started.
    storageEventStarted = 191817,
    -- Position for the teleport which is going..
    -- ..to send players to the waiting room.
    teleportSpawnPosition = Position(80, 396, 7),
    waitingRoom = {
        topLeft     = Position(78, 392, 7),
        bottomRight = Position(82, 394, 7)
    },
    -- How long players will wait in the waiting room.
    waitingTime = 10, -- 10 seconds
    teleportId = 1387, -- ID of teleport item
    teleportActionId = 56783, -- action ID used on the teleport for detecting players
    -- Zombie arena; Where players will try to survive
    arena = {
        topLeft     = Position(61, 388, 7),
        bottomRight = Position(74, 395, 7)
    },
    -- set to `true` if you want the rewards..
    -- ..to be given randomly instead of all at once.
    randomReward = false,
    rewardBagId = 1987,
    rewards = {
        {2160, 1}, -- Crystal Coin
        {2159, 2}, -- Scarab Coin
        {9020, 5}  -- Vampire Token
    }
}
--#
zombie.initEvent = function(self)
    local teleportItem = Game.createItem(self.config.teleportId, 1, self.config.teleportSpawnPosition)
    teleportItem:setActionId(self.config.teleportActionId)
    Teleport(teleportItem.uid):setDestination(Position(
        math.random(self.config.waitingRoom.topLeft.x, self.config.waitingRoom.bottomRight.x),
        math.random(self.config.waitingRoom.topLeft.y, self.config.waitingRoom.bottomRight.y),
        self.config.waitingRoom.topLeft.z
    ))
    Game.broadcastMessage('Zombie event will begin in '.. secondsToReadable(self.config.waitingTime) ..', Hurry up!')
    addEvent(function(z)
        local tpTile = Tile(z.config.teleportSpawnPosition)
        local tpItem = tpTile:getItemById(z.config.teleportId)
        if tpItem then
            tpItem:remove()
        end
        if z:countPlayers() < z.config.minimumPlayers then
            Game.broadcastMessage('Zombie event shutting down... not enough players.', MESSAGE_STATUS_CONSOLE_RED)
            z:kickPlayers()
            return
        end
        z:startEvent()
    end, self.config.waitingTime * 1000, self)
end
--#
zombie.startEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, 1)
    Game.broadcastMessage('Zombie event has begun, Good luck!')
    for _, player in pairs(self.players) do
        if player then
            player:teleportTo(Position(
                math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
                math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
                self.config.arena.topLeft.z
            ))
        end
    end
    for i = self.config.zombieStartAmount, 1, -1 do
        self:spawnZombie(Position(
            math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
            math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
            self.config.arena.topLeft.z
        ))
    end
end
--#
zombie.stopEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, -1)
    local winner = self:getWinner()
    if not winner then return end
    local depot = winner:getDepotChest(winner:getTown():getId(), true)
    local bag   = Game.createItem(self.config.rewardBagId, 1)
    local itemId = nil
    local itemCount = nil
    if self.config.randomReward then
        local randomRewardItem = self.config.rewards[math.random(1, #self.config.rewards)]
        itemId = randomRewardItem[1]
        itemCount = randomRewardItem[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
        depot:addItemEx(bag)
        winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received a reward item. Check your depot.')
        return
    end
    for _, reward in pairs(self.config.rewards) do
        itemId = reward[1]
        itemCount = reward[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
    end
    depot:addItemEx(bag)
    winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received reward items. Check your depot.')
    Game.broadcastMessage(winner:getName() .. ' has won zombie event.')
    zombie:kickPlayers()
    zombie:clearZombies()
end
--#
zombie.addPlayer = function(self, p)
    self.players[p:getId()] = p
end
--#
zombie.removePlayer = function(self, player)
    self.players[player:getId()] = nil
    player:teleportTo(player:getTown():getTemplePosition())
    player:addHealth(player:getMaxHealth())
    if self:countPlayers() == 1 then
        self:stopEvent()
    end
end
--#
zombie.countPlayers = function(self)
    local n = 0
    for _, player in pairs(self.players) do
        if player then n = n + 1 end
    end
    return n
end
--#
zombie.kickPlayers = function(self)
    for _, player in pairs(self.players) do
        if player then
            self:removePlayer(player)
        end
    end
    self.players = {}
end
--#
zombie.getWinner = function(self)
    for _, player in pairs(self.players) do
        if player then
            return player
        end
    end
    return nil
end
--#
zombie.clearZombies = function(self)
    for _, zombski in pairs(self.zombies) do
        if zombski then
            zombski:remove()
        end
    end
end
--#
zombie.spawnZombie = function(self, position)
    local zombie = Game.createMonster(self.config.zombieName, position, false, true)
    self.zombies[zombie:getId()] = zombie
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
end
--#
local ge = GlobalEvent('zombieStart')
function ge.onTime(interval)
    local eventStorage = Game.getStorageValue(zombie.config.storageEventStarted)
    local hasStarted = (eventStorage and (eventStorage == 1)) or false
    if hasStarted then
        print('[Error - ZombieEvent:onTime] The event has already started.')
        return true
    end
    local tile = Tile(zombie.config.teleportSpawnPosition)
    if not tile then
        print('[Error - ZombieEvent:onTime] Could not create teleport, tile not found!')
        return true
    end
    zombie:initEvent()
    return true
end
ge:time(zombie.config.startTime)
ge:register()
--#
local enterZombie = MoveEvent('enterZombie')
function enterZombie.onStepIn(player, item, position, fromPosition)
    if not item:getId() == zombie.config.teleportId then
        return true
    end
    zombie:addPlayer(player)
    Game.broadcastMessage(player:getName() .. ' has entered zombie event.', MESSAGE_STATUS_CONSOLE_RED)
    if zombie:countPlayers() >= zombie.config.maximumPlayers then
        Game.broadcastMessage('Zombie event will begin in a moment... Get ready!')
        addEvent(function() zombie:startEvent() end, 3 * 1000)
    end
    return true
end
enterZombie:aid(zombie.config.teleportActionId)
enterZombie:register()
--#
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if (not creature:isMonster())
    or (creature:getName():lower() ~= zombie.config.zombieName:lower())
    or (not target:isPlayer()) then
        return true
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return true
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return true
end
eventCallback:register(-1)
 
Last edited:

adrenyslopez

Member
Joined
Dec 22, 2015
Messages
201
Reaction score
14
Preview

map setup


code
  • Create new folder in data/scripts, call it zombie
  • Inside data/scripts/zombie/ add the following files:
zombski.lua
Lua:
local mType = Game.createMonsterType("Zombski")
local monster = {}
monster.description = "a zombski"
monster.experience = 1
monster.outfit = {
    lookType = 311
}
monster.health = 100
monster.maxHealth = monster.health
monster.race = "undead"
monster.corpse = 9875
monster.speed = 200
monster.maxSummons = 0
monster.changeTarget = {
    interval = 1000,
    chance   = 40
}
monster.flags = {
    hostile            = true,
    summonable         = false,
    attackable         = false,
    convinceable       = false,
    illusionable       = false,
    canPushItems       = true,
    canPushCreatures   = false,
    targetDistance     = 1,
    staticAttackChance = 100
}
monster.voices = {
    interval = 5000,
    chance   = 10,
    {text = "KHGKHGKH", yell = false},
    {text = "KHAAAA",   yell = false}
}
monster.attacks = {
    {name = "melee", attack = 1, skill = 1, effect = CONST_ME_DRAWBLOOD, interval = 1500}
}
monster.defenses = {
    defense = 55,
    armor = 55,
--  {name = "combat", type = COMBAT_HEALING, chance = 15, interval = 2*1000, minDamage = 180, maxDamage = 250, effect = CONST_ME_MAGIC_BLUE},
--  {name = "speed", chance = 15, interval = 2*1000, speed = 320, effect = CONST_ME_MAGIC_RED}
}
monster.elements = {
    {type = COMBAT_PHYSICALDAMAGE, percent = 100},
    {type = COMBAT_DEATHDAMAGE,    percent = 100},
    {type = COMBAT_ENERGYDAMAGE,   percent = 100},
    {type = COMBAT_EARTHDAMAGE,    percent = 100},
    {type = COMBAT_ICEDAMAGE,      percent = 100},
    {type = COMBAT_HOLYDAMAGE,     percent = 100},
    {type = COMBAT_POISONDAMAGE,   percent = 100},
    {type = COMBAT_FIREDAMAGE,     percent = 100},
    {type = COMBAT_DROWNDAMAGE,    percent = 100},
    {type = COMBAT_LIFEDRAIN,      percent = 100}
}
monster.immunities = {
    {type = "fire", combat = true, condition = true},
    {type = "drown", condition = true},
    {type = "lifedrain", combat = true},
    {type = "paralyze", condition = true},
    {type = "invisible", condition = true}
}
mType:register(monster)

zombie.lua
Lua:
local function secondsToReadable(s)
    local hours   = math.floor(s / 3600)
    local minutes = math.floor(math.mod(s, 3600)/60)
    local seconds = math.floor(math.mod(s, 60))
    return (hours   > 0 and (hours   .. ' hour'   .. (hours   > 1 and 's ' or ' ')) or '') ..
           (minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
           (seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local zombie = {}
-- keeps track of players & zombies
zombie.players = {}
zombie.zombies = {}
--#
zombie.config  = {
    startTime = '19:44:30', -- Hours:minutes:seconds
    -- How many players needed to start the event.
    minimumPlayers = 2,
    -- How many players can enter at most.
    maximumPlayers = 10,
    -- %chance of a player dying from zombie attack
    playerDeathChance = 20, -- %
    -- How many zombies should spawn in the beginning?
    zombieStartAmount = 3,
    -- Name of the monster to be spawned
    zombieName = 'zombski',
    -- This is used to check if zombie event has started.
    storageEventStarted = 191817,
    -- Position for the teleport which is going..
    -- ..to send players to the waiting room.
    teleportSpawnPosition = Position(80, 396, 7),
    waitingRoom = {
        topLeft     = Position(78, 392, 7),
        bottomRight = Position(82, 394, 7)
    },
    -- How long players will wait in the waiting room.
    waitingTime = 10, -- 10 seconds
    teleportId = 1387, -- ID of teleport item
    teleportActionId = 56783, -- action ID used on the teleport for detecting players
    -- Zombie arena; Where players will try to survive
    arena = {
        topLeft     = Position(61, 388, 7),
        bottomRight = Position(74, 395, 7)
    },
    -- set to `true` if you want the rewards..
    -- ..to be given randomly instead of all at once.
    randomReward = false,
    rewardBagId = 1987,
    rewards = {
        {2160, 1}, -- Crystal Coin
        {2159, 2}, -- Scarab Coin
        {9020, 5}  -- Vampire Token
    }
}
--#
zombie.initEvent = function(self)
    local teleportItem = Game.createItem(self.config.teleportId, 1, self.config.teleportSpawnPosition)
    teleportItem:setActionId(self.config.teleportActionId)
    Teleport(teleportItem.uid):setDestination(Position(
        math.random(self.config.waitingRoom.topLeft.x, self.config.waitingRoom.bottomRight.x),
        math.random(self.config.waitingRoom.topLeft.y, self.config.waitingRoom.bottomRight.y),
        self.config.waitingRoom.topLeft.z
    ))
    Game.broadcastMessage('Zombie event will begin in '.. secondsToReadable(self.config.waitingTime) ..', Hurry up!')
    addEvent(function(z)
        local tpTile = Tile(z.config.teleportSpawnPosition)
        local tpItem = tpTile:getItemById(z.config.teleportId)
        if tpItem then
            tpItem:remove()
        end
        if z:countPlayers() < z.config.minimumPlayers then
            Game.broadcastMessage('Zombie event shutting down... not enough players.', MESSAGE_STATUS_CONSOLE_RED)
            z:kickPlayers()
            return
        end
        z:startEvent()
    end, self.config.waitingTime * 1000, self)
end
--#
zombie.startEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, 1)
    Game.broadcastMessage('Zombie event has begun, Good luck!')
    for _, player in pairs(self.players) do
        if player then
            player:teleportTo(Position(
                math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
                math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
                self.config.arena.topLeft.z
            ))
        end
    end
    for i = self.config.zombieStartAmount, 1, -1 do
        self:spawnZombie(Position(
            math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
            math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
            self.config.arena.topLeft.z
        ))
    end
end
--#
zombie.stopEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, -1)
    local winner = self:getWinner()
    if not winner then return end
    local depot = winner:getDepotChest(winner:getTown():getId(), true)
    local bag   = Game.createItem(self.config.rewardBagId, 1)
    local itemId = nil
    local itemCount = nil
    if self.config.randomReward then
        local randomRewardItem = self.config.rewards[math.random(1, #self.config.rewards)]
        itemId = randomRewardItem[1]
        itemCount = randomRewardItem[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
        depot:addItemEx(bag)
        winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received a reward item. Check your depot.')
        return
    end
    for _, reward in pairs(self.config.rewards) do
        itemId = reward[1]
        itemCount = reward[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
    end
    depot:addItemEx(bag)
    winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received reward items. Check your depot.')
    Game.broadcastMessage(winner:getName() .. ' has won zombie event.')
    zombie:kickPlayers()
    zombie:clearZombies()
end
--#
zombie.addPlayer = function(self, p)
    self.players[p:getId()] = p
end
--#
zombie.removePlayer = function(self, player)
    self.players[player:getId()] = nil
    player:teleportTo(player:getTown():getTemplePosition())
    player:addHealth(player:getMaxHealth())
    if self:countPlayers() == 1 then
        self:stopEvent()
    end
end
--#
zombie.countPlayers = function(self)
    local n = 0
    for _, player in pairs(self.players) do
        if player then n = n + 1 end
    end
    return n
end
--#
zombie.kickPlayers = function(self)
    for _, player in pairs(self.players) do
        if player then
            self:removePlayer(player)
        end
    end
    self.players = {}
end
--#
zombie.getWinner = function(self)
    for _, player in pairs(self.players) do
        if player then
            return player
        end
    end
    return nil
end
--#
zombie.clearZombies = function(self)
    for _, zombski in pairs(self.zombies) do
        if zombski then
            zombski:remove()
        end
    end
end
--#
zombie.spawnZombie = function(self, position)
    local zombie = Game.createMonster(self.config.zombieName, position, false, true)
    self.zombies[zombie:getId()] = zombie
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
end
--#
local ge = GlobalEvent('zombieStart')
function ge.onTime(interval)
    local eventStorage = Game.getStorageValue(zombie.config.storageEventStarted)
    local hasStarted = (eventStorage and (eventStorage == 1)) or false
    if hasStarted then
        print('[Error - ZombieEvent:onTime] The event has already started.')
        return true
    end
    local tile = Tile(zombie.config.teleportSpawnPosition)
    if not tile then
        print('[Error - ZombieEvent:onTime] Could not create teleport, tile not found!')
        return true
    end
    zombie:initEvent()
    return true
end
ge:time(zombie.config.startTime)
ge:register()
--#
local enterZombie = MoveEvent('enterZombie')
function enterZombie.onStepIn(player, item, position, fromPosition)
    if not item:getId() == zombie.config.teleportId then
        return true
    end
    zombie:addPlayer(player)
    Game.broadcastMessage(player:getName() .. ' has entered zombie event.', MESSAGE_STATUS_CONSOLE_RED)
    if zombie:countPlayers() >= zombie.config.maximumPlayers then
        Game.broadcastMessage('Zombie event will begin in a moment... Get ready!')
        addEvent(function() zombie:startEvent() end, 3 * 1000)
    end
    return true
end
enterZombie:aid(zombie.config.teleportActionId)
enterZombie:register()
--#
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if (not creature:isMonster())
    or (not creature:getName():lower() == zombie.config.zombieName)
    or (not target:isPlayer()) then
        return true
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return true
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return true
end
eventCallback:register(-1)
Lua:
Lua Script Error: [Scripts Interface]
/home/forgottenserver/data/scripts/zombie/zombie.lua
/home/forgottenserver/data/scripts/zombie/zombie.lua:218: attempt to index local 'eventCallback' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        /home/forgottenserver/data/scripts/zombie/zombie.lua:218: in main chunk
> zombie.lua [error]

scripts:
Code:
local function secondsToReadable(s)
    local hours   = math.floor(s / 3600)
    local minutes = math.floor(math.mod(s, 3600)/60)
    local seconds = math.floor(math.mod(s, 60))
    return (hours   > 0 and (hours   .. ' hour'   .. (hours   > 1 and 's ' or ' ')) or '') ..
           (minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
           (seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local zombie = {}
-- keeps track of players & zombies
zombie.players = {}
zombie.zombies = {}
--#
zombie.config  = {
    startTime = '19:44:30', -- Hours:minutes:seconds
    -- How many players needed to start the event.
    minimumPlayers = 2,
    -- How many players can enter at most.
    maximumPlayers = 60,
    -- %chance of a player dying from zombie attack
    playerDeathChance = 20, -- %
    -- How many zombies should spawn in the beginning?
    zombieStartAmount = 3,
    -- Name of the monster to be spawned
    zombieName = 'zombski',
    -- This is used to check if zombie event has started.
    storageEventStarted = 191817,
    -- Position for the teleport which is going..
    -- ..to send players to the waiting room.
    teleportSpawnPosition = Position(32835, 33150, 7),
    waitingRoom = {
        topLeft     = Position(32830, 33152, 8),
        bottomRight = Position(32842, 33163, 8)
    },
    -- How long players will wait in the waiting room.
    waitingTime = 10, -- 10 seconds
    teleportId = 1387, -- ID of teleport item
    teleportActionId = 56783, -- action ID used on the teleport for detecting players
    -- Zombie arena; Where players will try to survive
    arena = {
        topLeft     = Position(32824, 33148, 7),
        bottomRight = Position(32846, 33167, 7)
    },
    -- set to `true` if you want the rewards..
    -- ..to be given randomly instead of all at once.
    randomReward = false,
    rewardBagId = 1987,
    rewards = {
        {2160, 1}, -- Crystal Coin
        {2159, 2}, -- Scarab Coin
        {9020, 5}  -- Vampire Token
    }
}
--#
zombie.initEvent = function(self)
    local teleportItem = Game.createItem(self.config.teleportId, 1, self.config.teleportSpawnPosition)
    teleportItem:setActionId(self.config.teleportActionId)
    Teleport(teleportItem.uid):setDestination(Position(
        math.random(self.config.waitingRoom.topLeft.x, self.config.waitingRoom.bottomRight.x),
        math.random(self.config.waitingRoom.topLeft.y, self.config.waitingRoom.bottomRight.y),
        self.config.waitingRoom.topLeft.z
    ))
    Game.broadcastMessage('Zombie event will begin in '.. secondsToReadable(self.config.waitingTime) ..', Hurry up!')
    addEvent(function(z)
        local tpTile = Tile(z.config.teleportSpawnPosition)
        local tpItem = tpTile:getItemById(z.config.teleportId)
        if tpItem then
            tpItem:remove()
        end
        if z:countPlayers() < z.config.minimumPlayers then
            Game.broadcastMessage('Zombie event shutting down... not enough players.', MESSAGE_STATUS_CONSOLE_RED)
            z:kickPlayers()
            return
        end
        z:startEvent()
    end, self.config.waitingTime * 1000, self)
end
--#
zombie.startEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, 1)
    Game.broadcastMessage('Zombie event has begun, Good luck!')
    for _, player in pairs(self.players) do
        if player then
            player:teleportTo(Position(
                math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
                math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
                self.config.arena.topLeft.z
            ))
        end
    end
    for i = self.config.zombieStartAmount, 1, -1 do
        self:spawnZombie(Position(
            math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
            math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
            self.config.arena.topLeft.z
        ))
    end
end
--#
zombie.stopEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, -1)
    local winner = self:getWinner()
    if not winner then return end
    local depot = winner:getDepotChest(winner:getTown():getId(), true)
    local bag   = Game.createItem(self.config.rewardBagId, 1)
    local itemId = nil
    local itemCount = nil
    if self.config.randomReward then
        local randomRewardItem = self.config.rewards[math.random(1, #self.config.rewards)]
        itemId = randomRewardItem[1]
        itemCount = randomRewardItem[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
        depot:addItemEx(bag)
        winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received a reward item. Check your depot.')
        return
    end
    for _, reward in pairs(self.config.rewards) do
        itemId = reward[1]
        itemCount = reward[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
    end
    depot:addItemEx(bag)
    winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received reward items. Check your depot.')
    Game.broadcastMessage(winner:getName() .. ' has won zombie event.')
    zombie:kickPlayers()
    zombie:clearZombies()
end
--#
zombie.addPlayer = function(self, p)
    self.players[p:getId()] = p
end
--#
zombie.removePlayer = function(self, player)
    self.players[player:getId()] = nil
    player:teleportTo(player:getTown():getTemplePosition())
    player:addHealth(player:getMaxHealth())
    if self:countPlayers() == 1 then
        self:stopEvent()
    end
end
--#
zombie.countPlayers = function(self)
    local n = 0
    for _, player in pairs(self.players) do
        if player then n = n + 1 end
    end
    return n
end
--#
zombie.kickPlayers = function(self)
    for _, player in pairs(self.players) do
        if player then
            self:removePlayer(player)
        end
    end
    self.players = {}
end
--#
zombie.getWinner = function(self)
    for _, player in pairs(self.players) do
        if player then
            return player
        end
    end
    return nil
end
--#
zombie.clearZombies = function(self)
    for _, zombski in pairs(self.zombies) do
        if zombski then
            zombski:remove()
        end
    end
end
--#
zombie.spawnZombie = function(self, position)
    local zombie = Game.createMonster(self.config.zombieName, position, false, true)
    self.zombies[zombie:getId()] = zombie
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
end
--#
local ge = GlobalEvent('zombieStart')
function ge.onTime(interval)
    local eventStorage = Game.getStorageValue(zombie.config.storageEventStarted)
    local hasStarted = (eventStorage and (eventStorage == 1)) or false
    if hasStarted then
        print('[Error - ZombieEvent:onTime] The event has already started.')
        return true
    end
    local tile = Tile(zombie.config.teleportSpawnPosition)
    if not tile then
        print('[Error - ZombieEvent:onTime] Could not create teleport, tile not found!')
        return true
    end
    zombie:initEvent()
    return true
end
ge:time(zombie.config.startTime)
ge:register()
--#
local enterZombie = MoveEvent('enterZombie')
function enterZombie.onStepIn(player, item, position, fromPosition)
    if not item:getId() == zombie.config.teleportId then
        return true
    end
    zombie:addPlayer(player)
    Game.broadcastMessage(player:getName() .. ' has entered zombie event.', MESSAGE_STATUS_CONSOLE_RED)
    if zombie:countPlayers() >= zombie.config.maximumPlayers then
        Game.broadcastMessage('Zombie event will begin in a moment... Get ready!')
        addEvent(function() zombie:startEvent() end, 3 * 1000)
    end
    return true
end
enterZombie:aid(zombie.config.teleportActionId)
enterZombie:register()
--#
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if (not creature:isMonster())
    or (not creature:getName():lower() == zombie.config.zombieName)
    or (not target:isPlayer()) then
        return true
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return true
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return true
end
eventCallback:register(-1)
 
OP
OP
Snavy

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,249
Solutions
71
Reaction score
610
Location
Hell
Lua:
Lua Script Error: [Scripts Interface]
/home/forgottenserver/data/scripts/zombie/zombie.lua
/home/forgottenserver/data/scripts/zombie/zombie.lua:218: attempt to index local 'eventCallback' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        /home/forgottenserver/data/scripts/zombie/zombie.lua:218: in main chunk
> zombie.lua [error]

scripts:
Code:
local function secondsToReadable(s)
    local hours   = math.floor(s / 3600)
    local minutes = math.floor(math.mod(s, 3600)/60)
    local seconds = math.floor(math.mod(s, 60))
    return (hours   > 0 and (hours   .. ' hour'   .. (hours   > 1 and 's ' or ' ')) or '') ..
           (minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
           (seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local zombie = {}
-- keeps track of players & zombies
zombie.players = {}
zombie.zombies = {}
--#
zombie.config  = {
    startTime = '19:44:30', -- Hours:minutes:seconds
    -- How many players needed to start the event.
    minimumPlayers = 2,
    -- How many players can enter at most.
    maximumPlayers = 60,
    -- %chance of a player dying from zombie attack
    playerDeathChance = 20, -- %
    -- How many zombies should spawn in the beginning?
    zombieStartAmount = 3,
    -- Name of the monster to be spawned
    zombieName = 'zombski',
    -- This is used to check if zombie event has started.
    storageEventStarted = 191817,
    -- Position for the teleport which is going..
    -- ..to send players to the waiting room.
    teleportSpawnPosition = Position(32835, 33150, 7),
    waitingRoom = {
        topLeft     = Position(32830, 33152, 8),
        bottomRight = Position(32842, 33163, 8)
    },
    -- How long players will wait in the waiting room.
    waitingTime = 10, -- 10 seconds
    teleportId = 1387, -- ID of teleport item
    teleportActionId = 56783, -- action ID used on the teleport for detecting players
    -- Zombie arena; Where players will try to survive
    arena = {
        topLeft     = Position(32824, 33148, 7),
        bottomRight = Position(32846, 33167, 7)
    },
    -- set to `true` if you want the rewards..
    -- ..to be given randomly instead of all at once.
    randomReward = false,
    rewardBagId = 1987,
    rewards = {
        {2160, 1}, -- Crystal Coin
        {2159, 2}, -- Scarab Coin
        {9020, 5}  -- Vampire Token
    }
}
--#
zombie.initEvent = function(self)
    local teleportItem = Game.createItem(self.config.teleportId, 1, self.config.teleportSpawnPosition)
    teleportItem:setActionId(self.config.teleportActionId)
    Teleport(teleportItem.uid):setDestination(Position(
        math.random(self.config.waitingRoom.topLeft.x, self.config.waitingRoom.bottomRight.x),
        math.random(self.config.waitingRoom.topLeft.y, self.config.waitingRoom.bottomRight.y),
        self.config.waitingRoom.topLeft.z
    ))
    Game.broadcastMessage('Zombie event will begin in '.. secondsToReadable(self.config.waitingTime) ..', Hurry up!')
    addEvent(function(z)
        local tpTile = Tile(z.config.teleportSpawnPosition)
        local tpItem = tpTile:getItemById(z.config.teleportId)
        if tpItem then
            tpItem:remove()
        end
        if z:countPlayers() < z.config.minimumPlayers then
            Game.broadcastMessage('Zombie event shutting down... not enough players.', MESSAGE_STATUS_CONSOLE_RED)
            z:kickPlayers()
            return
        end
        z:startEvent()
    end, self.config.waitingTime * 1000, self)
end
--#
zombie.startEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, 1)
    Game.broadcastMessage('Zombie event has begun, Good luck!')
    for _, player in pairs(self.players) do
        if player then
            player:teleportTo(Position(
                math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
                math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
                self.config.arena.topLeft.z
            ))
        end
    end
    for i = self.config.zombieStartAmount, 1, -1 do
        self:spawnZombie(Position(
            math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
            math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
            self.config.arena.topLeft.z
        ))
    end
end
--#
zombie.stopEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, -1)
    local winner = self:getWinner()
    if not winner then return end
    local depot = winner:getDepotChest(winner:getTown():getId(), true)
    local bag   = Game.createItem(self.config.rewardBagId, 1)
    local itemId = nil
    local itemCount = nil
    if self.config.randomReward then
        local randomRewardItem = self.config.rewards[math.random(1, #self.config.rewards)]
        itemId = randomRewardItem[1]
        itemCount = randomRewardItem[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
        depot:addItemEx(bag)
        winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received a reward item. Check your depot.')
        return
    end
    for _, reward in pairs(self.config.rewards) do
        itemId = reward[1]
        itemCount = reward[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
    end
    depot:addItemEx(bag)
    winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received reward items. Check your depot.')
    Game.broadcastMessage(winner:getName() .. ' has won zombie event.')
    zombie:kickPlayers()
    zombie:clearZombies()
end
--#
zombie.addPlayer = function(self, p)
    self.players[p:getId()] = p
end
--#
zombie.removePlayer = function(self, player)
    self.players[player:getId()] = nil
    player:teleportTo(player:getTown():getTemplePosition())
    player:addHealth(player:getMaxHealth())
    if self:countPlayers() == 1 then
        self:stopEvent()
    end
end
--#
zombie.countPlayers = function(self)
    local n = 0
    for _, player in pairs(self.players) do
        if player then n = n + 1 end
    end
    return n
end
--#
zombie.kickPlayers = function(self)
    for _, player in pairs(self.players) do
        if player then
            self:removePlayer(player)
        end
    end
    self.players = {}
end
--#
zombie.getWinner = function(self)
    for _, player in pairs(self.players) do
        if player then
            return player
        end
    end
    return nil
end
--#
zombie.clearZombies = function(self)
    for _, zombski in pairs(self.zombies) do
        if zombski then
            zombski:remove()
        end
    end
end
--#
zombie.spawnZombie = function(self, position)
    local zombie = Game.createMonster(self.config.zombieName, position, false, true)
    self.zombies[zombie:getId()] = zombie
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
end
--#
local ge = GlobalEvent('zombieStart')
function ge.onTime(interval)
    local eventStorage = Game.getStorageValue(zombie.config.storageEventStarted)
    local hasStarted = (eventStorage and (eventStorage == 1)) or false
    if hasStarted then
        print('[Error - ZombieEvent:onTime] The event has already started.')
        return true
    end
    local tile = Tile(zombie.config.teleportSpawnPosition)
    if not tile then
        print('[Error - ZombieEvent:onTime] Could not create teleport, tile not found!')
        return true
    end
    zombie:initEvent()
    return true
end
ge:time(zombie.config.startTime)
ge:register()
--#
local enterZombie = MoveEvent('enterZombie')
function enterZombie.onStepIn(player, item, position, fromPosition)
    if not item:getId() == zombie.config.teleportId then
        return true
    end
    zombie:addPlayer(player)
    Game.broadcastMessage(player:getName() .. ' has entered zombie event.', MESSAGE_STATUS_CONSOLE_RED)
    if zombie:countPlayers() >= zombie.config.maximumPlayers then
        Game.broadcastMessage('Zombie event will begin in a moment... Get ready!')
        addEvent(function() zombie:startEvent() end, 3 * 1000)
    end
    return true
end
enterZombie:aid(zombie.config.teleportActionId)
enterZombie:register()
--#
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if (not creature:isMonster())
    or (not creature:getName():lower() == zombie.config.zombieName)
    or (not target:isPlayer()) then
        return true
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return true
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return true
end
eventCallback:register(-1)
OTBR doesn't have eventcallback as far as I know
 

Acubens

Old Penguin
Joined
May 6, 2008
Messages
1,187
Solutions
12
Reaction score
151
Location
Venezuela
Nice system i was testing it and for strange reason my players outside from the event got hits from other monsters and show the message !survive o.o, im using latest tfs i do this to solve it tell me if is good way

Lua:
function eventCallback.onTargetCombat(creature, target)
    if zombie.status == 2 then
        if(creature) then
            if creature:isMonster() and creature:getName():lower() == zombie.config.zombieName and target:isPlayer() then
                local deathChance = zombie.config.playerDeathChance
                math.randomseed(os.time())
                if math.random(1, 100) <= deathChance then
                    local targetPos = target:getPosition()
                    targetPos:sendMagicEffect(CONST_ME_MORTAREA)
                    targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
                    target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
                    zombie:spawnZombie(targetPos)
                    zombie:removePlayer(target)
                    return true
                end
                target:say('!survived!', TALKTYPE_MONSTER_SAY)
                target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
                target:sendTextMessage(MESSAGE_INFO_DESCR, "[Zombie Event]: OMG! you evade the attack of the zombie!")
            end
        end
    end
    return true
end
 
OP
OP
Snavy

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,249
Solutions
71
Reaction score
610
Location
Hell
players outside from the event got hits from other monsters and show the message !survive
🤔

Change
Lua:
or (not creature:getName():lower() == zombie.config.zombieName)
to
Lua:
or (creature:getName():lower() ~= zombie.config.zombieName:lower())
 

damian00912

Member
Joined
Sep 11, 2009
Messages
89
Reaction score
5
whyyyyyyyyy

Lua:
Lua Script Error: [Scripts Interface]
/home/asd/data/scripts/zombie/zombie.lua
/home/asd/data/scripts/zombie/zombie.lua:218: attempt to index local 'eventCallback' (a nil value)
stack traceback:
    [C]: in function '__newindex'
    /home/asd/data/scripts/zombie/zombie.lua:218: in main chunk
> zombie.lua [error]
 

Xikini

I whore myself out for likes
Senator
Joined
Nov 17, 2010
Messages
6,245
Solutions
545
Reaction score
4,481
whyyyyyyyyy

Lua:
Lua Script Error: [Scripts Interface]
/home/asd/data/scripts/zombie/zombie.lua
/home/asd/data/scripts/zombie/zombie.lua:218: attempt to index local 'eventCallback' (a nil value)
stack traceback:
    [C]: in function '__newindex'
    /home/asd/data/scripts/zombie/zombie.lua:218: in main chunk
> zombie.lua [error]
OTBR doesn't have eventcallback as far as I know
Post automatically merged:

🤔

Change
Lua:
or (not creature:getName():lower() == zombie.config.zombieName)
to
Lua:
or (creature:getName():lower() ~= zombie.config.zombieName:lower())
I think the problem is that you aren't confirming that the zombies / players are inside the event area.

So validate against the table of players/creatures in event area, or validate against the zombie.config.arena positions
 

jeanmarcanzzoni

New Member
Joined
Oct 21, 2020
Messages
8
Reaction score
1
Lua:
Lua Script Error: [Event Interface]
data/events/scripts/creature.lua:[email protected]
/home/server/data/scripts/zombie/zombie.lua:221: attempt to index local 'creature' (a nil value)
stack traceback:
        [C]: in function '__index'
        /home/server/data/scripts/zombie/zombie.lua:221: in function </home/server/data/scripts/zombie/zombie.lua:220>
        /home/server/data/scripts/lib/event_callbacks.lua:127: in function </home/server/data/scripts/lib/event_callbacks.lua:123>
        [C]: in function 'doTargetCombatHealth'
        data/movements/scripts/others/trap.lua:30: in function <data/movements/scripts/others/trap.lua:8>

This error appears every time I start the console.
 
Last edited:

Sarah Wesker

ค∂vαηcε รүηтαx ❤
Support Team
Joined
Mar 16, 2017
Messages
1,185
Solutions
129
Reaction score
1,454
Location
London
GitHub
MillhioreBT
Twitch
millhiore_bt
@Snavy it's fine if you update the script
You should check if creature and target in the onTargetCombat event are valid to be able to use these variables correctly

You should also change the index of the callback to 1, so that it is executed after the default event. "This little detail is thanks to me changing the default index of callbacks in this commit: GitHub Default index EventCallback Order"

Lua:
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if not creature or not target then
        return RETURNVALUE_NOERROR
    end
    if (not creature:isMonster())
    or (creature:getName():lower() ~= zombie.config.zombieName:lower())
    or (not target:isPlayer()) then
        return RETURNVALUE_NOERROR
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return RETURNVALUE_NOERROR
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return RETURNVALUE_NOERROR
end
eventCallback:register(1)
 

Nefre

Member
Joined
May 17, 2012
Messages
41
Reaction score
10
Lua Script Error: [Scripts Interface]
/home/ots/data/scripts/zombie.lua:callback
/home/ots/data/scripts/zombie.lua:82: attempt to call field 'mod' (a nil value)
stack traceback:
[C]: in function 'mod'
/home/ots/data/scripts/zombie.lua:82: in function 'secondsToReadable'
/home/ots/data/scripts/zombie.lua:142: in function 'initEvent'
/home/ots/data/scripts/zombie.lua:274: in function </home/ots/data/scripts/zombie.lua:262>

Tfs 1.3 nekiro downgrade 8.6
Can sb help?
 
OP
OP
Snavy

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,249
Solutions
71
Reaction score
610
Location
Hell
Lua Script Error: [Scripts Interface]
/home/ots/data/scripts/zombie.lua:callback
/home/ots/data/scripts/zombie.lua:82: attempt to call field 'mod' (a nil value)
stack traceback:
[C]: in function 'mod'
/home/ots/data/scripts/zombie.lua:82: in function 'secondsToReadable'
/home/ots/data/scripts/zombie.lua:142: in function 'initEvent'
/home/ots/data/scripts/zombie.lua:274: in function </home/ots/data/scripts/zombie.lua:262>

Tfs 1.3 nekiro downgrade 8.6
Can sb help?
try math.fmod instead of math.mod
 

Shalaby

Time has made me wiser, but no more patient.
Joined
Feb 17, 2011
Messages
222
Solutions
5
Reaction score
65
Location
Egypt
Greetings, A simple suggestion
Could u add options for weekdays like choosing a day to start the event for example "Saturday" or "everyday" option for launching the event every day?
 

Alpha

Relentless
Premium User
Joined
Apr 3, 2011
Messages
732
Solutions
38
Reaction score
557
Location
South Korea
Greetings, A simple suggestion
Could u add options for weekdays like choosing a day to start the event for example "Saturday" or "everyday" option for launching the event every day?
Lua:
local function secondsToReadable(s)
    local hours   = math.floor(s / 3600)
    local minutes = math.floor(math.mod(s, 3600)/60)
    local seconds = math.floor(math.mod(s, 60))
    return (hours   > 0 and (hours   .. ' hour'   .. (hours   > 1 and 's ' or ' ')) or '') ..
           (minutes > 0 and (minutes .. ' minute' .. (minutes > 1 and 's ' or ' ')) or '') ..
           (seconds > 0 and (seconds .. ' second' .. (seconds > 1 and 's ' or ' ')) or '')
end
local zombie = {}
-- keeps track of players & zombies
zombie.players = {}
zombie.zombies = {}
--#
zombie.config  = {
    startTime = {
        time = '19:44:30', -- Hours:minutes:seconds
        days = { -- set to "false" to disable specific days
            ["monday"] = true,
            ["tuesday"] = true,
            ["wednesday"] = true,
            ["thursday"] = true,
            ["friday"] = true,
            ["saturday"] = true,
            ["sunday"] = true,
        },
    },
    -- How many players needed to start the event.
    minimumPlayers = 2,
    -- How many players can enter at most.
    maximumPlayers = 10,
    -- %chance of a player dying from zombie attack
    playerDeathChance = 20, -- %
    -- How many zombies should spawn in the beginning?
    zombieStartAmount = 3,
    -- Name of the monster to be spawned
    zombieName = 'zombski',
    -- This is used to check if zombie event has started.
    storageEventStarted = 191817,
    -- Position for the teleport which is going..
    -- ..to send players to the waiting room.
    teleportSpawnPosition = Position(80, 396, 7),
    waitingRoom = {
        topLeft     = Position(78, 392, 7),
        bottomRight = Position(82, 394, 7)
    },
    -- How long players will wait in the waiting room.
    waitingTime = 10, -- 10 seconds
    teleportId = 1387, -- ID of teleport item
    teleportActionId = 56783, -- action ID used on the teleport for detecting players
    -- Zombie arena; Where players will try to survive
    arena = {
        topLeft     = Position(61, 388, 7),
        bottomRight = Position(74, 395, 7)
    },
    -- set to `true` if you want the rewards..
    -- ..to be given randomly instead of all at once.
    randomReward = false,
    rewardBagId = 1987,
    rewards = {
        {2160, 1}, -- Crystal Coin
        {2159, 2}, -- Scarab Coin
        {9020, 5}  -- Vampire Token
    }
}
--#
zombie.initEvent = function(self)
    local teleportItem = Game.createItem(self.config.teleportId, 1, self.config.teleportSpawnPosition)
    teleportItem:setActionId(self.config.teleportActionId)
    Teleport(teleportItem.uid):setDestination(Position(
        math.random(self.config.waitingRoom.topLeft.x, self.config.waitingRoom.bottomRight.x),
        math.random(self.config.waitingRoom.topLeft.y, self.config.waitingRoom.bottomRight.y),
        self.config.waitingRoom.topLeft.z
    ))
    Game.broadcastMessage('Zombie event will begin in '.. secondsToReadable(self.config.waitingTime) ..', Hurry up!')
    addEvent(function(z)
        local tpTile = Tile(z.config.teleportSpawnPosition)
        local tpItem = tpTile:getItemById(z.config.teleportId)
        if tpItem then
            tpItem:remove()
        end
        if z:countPlayers() < z.config.minimumPlayers then
            Game.broadcastMessage('Zombie event shutting down... not enough players.', MESSAGE_STATUS_CONSOLE_RED)
            z:kickPlayers()
            return
        end
        z:startEvent()
    end, self.config.waitingTime * 1000, self)
end
--#
zombie.startEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, 1)
    Game.broadcastMessage('Zombie event has begun, Good luck!')
    for _, player in pairs(self.players) do
        if player then
            player:teleportTo(Position(
                math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
                math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
                self.config.arena.topLeft.z
            ))
        end
    end
    for i = self.config.zombieStartAmount, 1, -1 do
        self:spawnZombie(Position(
            math.random(self.config.arena.topLeft.x, self.config.arena.bottomRight.x),
            math.random(self.config.arena.topLeft.y, self.config.arena.bottomRight.y),
            self.config.arena.topLeft.z
        ))
    end
end
--#
zombie.stopEvent = function(self)
    Game.setStorageValue(self.config.storageEventStarted, -1)
    local winner = self:getWinner()
    if not winner then return end
    local depot = winner:getDepotChest(winner:getTown():getId(), true)
    local bag   = Game.createItem(self.config.rewardBagId, 1)
    local itemId = nil
    local itemCount = nil
    if self.config.randomReward then
        local randomRewardItem = self.config.rewards[math.random(1, #self.config.rewards)]
        itemId = randomRewardItem[1]
        itemCount = randomRewardItem[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
        depot:addItemEx(bag)
        winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received a reward item. Check your depot.')
        return
    end
    for _, reward in pairs(self.config.rewards) do
        itemId = reward[1]
        itemCount = reward[2]
        bag:addItemEx(Game.createItem(itemId, itemCount), INDEX_WHEREEVER, FLAG_NOLIMIT)
    end
    depot:addItemEx(bag)
    winner:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, '[Zombie] You have received reward items. Check your depot.')
    Game.broadcastMessage(winner:getName() .. ' has won zombie event.')
    zombie:kickPlayers()
    zombie:clearZombies()
end
--#
zombie.addPlayer = function(self, p)
    self.players[p:getId()] = p
end
--#
zombie.removePlayer = function(self, player)
    self.players[player:getId()] = nil
    player:teleportTo(player:getTown():getTemplePosition())
    player:addHealth(player:getMaxHealth())
    if self:countPlayers() == 1 then
        self:stopEvent()
    end
end
--#
zombie.countPlayers = function(self)
    local n = 0
    for _, player in pairs(self.players) do
        if player then n = n + 1 end
    end
    return n
end
--#
zombie.kickPlayers = function(self)
    for _, player in pairs(self.players) do
        if player then
            self:removePlayer(player)
        end
    end
    self.players = {}
end
--#
zombie.getWinner = function(self)
    for _, player in pairs(self.players) do
        if player then
            return player
        end
    end
    return nil
end
--#
zombie.clearZombies = function(self)
    for _, zombski in pairs(self.zombies) do
        if zombski then
            zombski:remove()
        end
    end
end
--#
zombie.spawnZombie = function(self, position)
    local zombie = Game.createMonster(self.config.zombieName, position, false, true)
    self.zombies[zombie:getId()] = zombie
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
end
--#
local ge = GlobalEvent('zombieStart')
function ge.onTime(interval)
    local currentDay = os.date("%A"):lower()
    if not zombie.config.startTime.days[currentDay] then
        return true
    end

    local eventStorage = Game.getStorageValue(zombie.config.storageEventStarted)
    local hasStarted = (eventStorage and (eventStorage == 1)) or false
    if hasStarted then
        print('[Error - ZombieEvent:onTime] The event has already started.')
        return true
    end
    local tile = Tile(zombie.config.teleportSpawnPosition)
    if not tile then
        print('[Error - ZombieEvent:onTime] Could not create teleport, tile not found!')
        return true
    end
    zombie:initEvent()
    return true
end
ge:time(zombie.config.startTime.time)
ge:register()
--#
local enterZombie = MoveEvent('enterZombie')
function enterZombie.onStepIn(player, item, position, fromPosition)
    if not item:getId() == zombie.config.teleportId then
        return true
    end
    zombie:addPlayer(player)
    Game.broadcastMessage(player:getName() .. ' has entered zombie event.', MESSAGE_STATUS_CONSOLE_RED)
    if zombie:countPlayers() >= zombie.config.maximumPlayers then
        Game.broadcastMessage('Zombie event will begin in a moment... Get ready!')
        addEvent(function() zombie:startEvent() end, 3 * 1000)
    end
    return true
end
enterZombie:aid(zombie.config.teleportActionId)
enterZombie:register()
--#
local eventCallback = EventCallback
function eventCallback.onTargetCombat(creature, target)
    if (not creature:isMonster())
    or (creature:getName():lower() ~= zombie.config.zombieName:lower())
    or (not target:isPlayer()) then
        return true
    end
    local deathChance = zombie.config.playerDeathChance
    math.randomseed(os.time())
    if math.random(1, 100) <= deathChance then
        local targetPos = target:getPosition()
        targetPos:sendMagicEffect(CONST_ME_MORTAREA)
        targetPos:sendMagicEffect(CONST_ME_BIGPLANTS)
        target:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have been killed by a zombie.')
        zombie:spawnZombie(targetPos)
        zombie:removePlayer(target)
        return true
    end
    target:say('!survived!', TALKTYPE_MONSTER_SAY)
    target:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
    return true
end
eventCallback:register(-1)
 
Top