I dont know yet, still looking for answer. been debugging all dayif a zombie catches me, nothing happens. there are no errors in the console.
can you tell me what the reason is?
TFS1.4

I dont know yet, still looking for answer. been debugging all dayif a zombie catches me, nothing happens. there are no errors in the console.
can you tell me what the reason is?
TFS1.4
thanksI dont know yet, still looking for answer. been debugging all dayi will update you if i found out why. But im using TFS1.5
I dont know if this solution will help you RevScripts - Zombie Event [Players doesn't die] (https://otland.net/threads/zombie-event-players-doesnt-die.279391/#post-2683205)thanks
I missed your comment with the same error
Thanks, it worked. But I didn't get the reward. everything is also without an error in the consoleI dont know if this solution will help you RevScripts - Zombie Event [Players doesn't die] (https://otland.net/threads/zombie-event-players-doesnt-die.279391/#post-2683205)
it didnt work for me, but maybe it works for you
Lua Script Error: [Scripts Interface]
C:\Users\slim\Documents\GitHub\pro-ot\data\scripts\movements\teleports\item_teleport_destinations.lua:callback
...ripts\movements\teleports\item_teleport_destinations.lua:4: attempt to index global 'ItemTeleports' (a nil value)
stack traceback:
...ripts\movements\teleports\item_teleport_destinations.lua:4: in function <...ripts\movements\teleports\item_teleport_destinations.lua:3>
[C]: in function 'createItem'
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:56: in function 'initEvent'
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:195: in function <...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:183>
Lua Script Error: [Scripts Interface]
C:\Users\slim\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:callback
LuaScriptInterface::getNumber(). Argument 2 has out-of-range value for unsigned short: 567837
stack traceback:
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:57: in function 'initEvent'
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:195: in function <...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:183>
Lua Script Error: [Scripts Interface]
C:\Users\slim\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:callback
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:3: attempt to call field 'mod' (a nil value)
stack traceback:
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:3: in function 'secondsToReadable'
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:63: in function 'initEvent'
...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:195: in function <...m\Documents\GitHub\pro-ot\data\scripts\zombie\zombie.lua:183>
function Creature:onTargetCombat(target)
local player = Player(self)
if player and target and CTF_STATUS == 2 then
if isGreenTeam(player:getName()) and isGreenTeam(target:getName()) then
return false
elseif isRedTeam(player:getName()) and isRedTeam(target:getName()) then
return false
end
end
if hasEventCallback(EVENT_CALLBACK_ONTARGETCOMBAT) then
return EventCallback(EVENT_CALLBACK_ONTARGETCOMBAT, self, target)
else
return RETURNVALUE_NOERROR
end
end
function Cr
with this the event seems working but players does not get killed by zombies how to fix? no errors in console@Snavy it's fine if you update the script
You should check ifcreature
andtarget
in theonTargetCombat
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 Defaultindex
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)
with this the event does not even start, how to fix?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
<event class="Creature" method="onTargetCombat" enabled="1" />
function Creature:onChangeOutfit(outfit)
local onChangeMount = EventCallback.onChangeMount
if onChangeMount then
if not onChangeMount(self, outfit.lookMount) then
return false
end
end
local onChangeOutfit = EventCallback.onChangeOutfit
if onChangeOutfit then
return onChangeOutfit(self, outfit)
end
return true
end
function Creature:onAreaCombat(tile, isAggressive)
local onAreaCombat = EventCallback.onAreaCombat
if onAreaCombat then
return onAreaCombat(self, tile, isAggressive)
end
return RETURNVALUE_NOERROR
end
function Creature:onTargetCombat(target)
local onTargetCombat = EventCallback.onTargetCombat
if onTargetCombat then
return onTargetCombat(self, target)
end
return RETURNVALUE_NOERROR
end
local unpack = unpack
local pack = table.pack
local EventCallbackData, callbacks, updateableParameters, autoID = {}, {}, {}, 0
-- This metatable creates an auto-configuration mechanism to create new types of EventCallbacks
local ec = setmetatable({}, { __newindex = function(self, key, value)
autoID = autoID + 1
callbacks[key] = autoID
local info, update = {}, {}
for k, v in pairs(value) do
if type(k) == "string" then
info[k] = v
else
update[k] = v
end
end
updateableParameters[autoID] = update
callbacks[autoID] = info
EventCallbackData[autoID] = {maxn = 0}
EVENT_CALLBACK_LAST = autoID
end})
--@ Definitions of valid EventCallback types to hook according to the given field name
--@ The fields within the assigned table, allow to save arbitrary information
-- Creature
ec.onChangeOutfit = {}
ec.onChangeMount = {}
ec.onAreaCombat = {returnValue=true}
ec.onTargetCombat = {returnValue=true}
ec.onHear = {}
ec.onChangeZone = {}
-- Party
ec.onJoin = {}
ec.onLeave = {}
ec.onDisband = {}
ec.onShareExperience = {}
ec.onInvite = {}
ec.onRevokeInvitation = {}
ec.onPassLeadership = {}
-- Player
ec.onBrowseField = {}
ec.onLook = {[5] = 1}
ec.onLookInBattleList = {[4] = 1}
ec.onLookInTrade = {[5] = 1}
ec.onLookInShop = {[4] = 1}
ec.onLookInMarket = {}
ec.onTradeRequest = {}
ec.onTradeAccept = {}
ec.onTradeCompleted = {}
ec.onMoveItem = {returnValue=true}
ec.onItemMoved = {}
ec.onMoveCreature = {}
ec.onReportRuleViolation = {}
ec.onReportBug = {}
ec.onTurn = {}
ec.onRotateItem = {}
ec.onGainExperience = {[3] = 1}
ec.onLoseExperience = {[2] = 1}
ec.onGainSkillTries = {[3] = 1}
ec.onWrapItem = {}
ec.onInventoryUpdate = {}
ec.onUpdateStorage = {}
-- Monster
ec.onDropLoot = {}
ec.onSpawn = {}
EventCallback = {
register = function (self, index)
if isScriptsInterface() then
local type, call = rawget(self, "type"), rawget(self, "call")
if type and call then
EventCallbackData[type][#EventCallbackData[type] + 1] = {call, tonumber(index) or 0}
table.sort(EventCallbackData[type], function (a, b) return a[2] < b[2] end)
return rawset(self, "type", nil) and rawset(self, "call", nil)
end
debugPrint("[Warning - EventCallback::register] is need to set up a callback before register.")
end
end,
clear = function (self)
EventCallbackData = {}
for i = 1, EVENT_CALLBACK_LAST do
EventCallbackData[i] = {}
end
end
}
setmetatable(EventCallback, {
__index = function (self) return self end,
__newindex = function (self, k, v)
if isScriptsInterface() then
local ecType = callbacks[k]
if ecType then
if type(v) == "function" then
return rawset(self, "type", ecType) and rawset(self, "call", v)
end
debugPrint(string.format("[Warning - EventCallback::%s] a function is expected.", k))
else
debugPrint(string.format("[Warning - EventCallback::%s] is not a valid callback.", k))
end
end
end,
__call = function (self, type, ...)
local eventTable, ret = EventCallbackData[type]
local args, events = table.pack(...), #eventTable
for k, ev in pairs(eventTable) do
ret = {ev[1](unpack(args))}
if k == events or (ret[1] ~= nil and (ret[1] == false or table.contains({EVENT_CALLBACK_ONAREACOMBAT, EVENT_CALLBACK_ONTARGETCOMBAT}, type) and ret[1] ~= RETURNVALUE_NOERROR)) then
return unpack(ret)
end
for k, v in pairs(auxargs[type] or {}) do args[k] = ret[v] end
end
end
})
-- can't be overwritten on reloads
EventCallback:clear()
local function secondsToReadable(s)
local hours = math.floor(s / 3600)
local minutes = math.floor(math.fmod(s, 3600)/60)
local seconds = math.floor(math.fmod(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:13: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 = 2,
-- 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(32340, 32218, 7),
waitingRoom = {
topLeft = Position(32231, 32182, 7),
bottomRight = Position(32243, 32191, 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(32216, 32203, 8),
bottomRight = Position(32264, 32234, 8)
},
-- 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 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)
Im buying you a shawermaPreview
![]()
![]()
map setup
code
zombski.lua
- Create new folder in
data/scripts
, call itzombie
- Inside
data/scripts/zombie/
add the following files:
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)