• 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 BETA! [Tfs 1.0] Vers: 0.5

Printer

if Printer then print("LUA") end
Senator
Premium User
Joined
Dec 27, 2009
Messages
5,782
Solutions
31
Reaction score
2,285
Location
Sweden?
Hello,

Comment any suggestions and etc...

Features:
*Optimized
*Min Players/Max Players
*Trophy reward with description!
*Max Zombies
*Zombie dont summon on walls
*Automatic start through globalevent
*Cleaning zombies after event end
*Join also through talkaction
*Etc...

Creaturescripts:
in creaturescripts/creaturescripts.xml add these lines:
Code:
<event type="preparedeath" name="ZE_Death" script="zombie_death.lua"/>
<event type="death" name="ZE_Mon_Death" script="zombie_death.lua"/>

and inside creaturescripts/scripts create lua and name it: zombie_death.lua
Code:
dofile('data/zombie_system.lua')

function onDeath(cid, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    local monster = Monster(cid)
    monster:say("I WILL BE BACK!", TALKTYPE_MONSTER_YELL)
    monster:getPosition():sendMagicEffect(CONST_ME_MORTAREA)
    doSummonZombie()
    Game.setStorageValue(zeZombieCountGlobalStorage, Game.getStorageValue(zeZombieCountGlobalStorage) - 1)
end

function onPrepareDeath(cid, killer)
    local player = Player(cid)
    local winner = 0
    if player:getStorageValue(zeJoinStorage) == 1 then
        Game.setStorageValue(zeJoinedCountGlobalStorage, Game.getStorageValue(zeJoinedCountGlobalStorage) - 1)
        player:teleportTo(player:getTown():getTemplePosition())
        player:setStorageValue(zeJoinStorage, 0)
        player:addHealth(player:getMaxHealth())
        if Game.getStorageValue(zeJoinedCountGlobalStorage) <= 1 then --Event ended, someone won!
            local players = Game.getPlayers()
            for _, tmpPlayer in ipairs(players) do
                local stor = tmpPlayer:getStorageValue(zeJoinStorage)
                if stor == 1 then
                    winner = tmpPlayer:getId()
                    break
                end
            end
            winner = Player(winner)
            if winner then
                winner:teleportTo(winner:getTown():getTemplePosition())
                local trophy = winner:addItem(zeTrophy, 1)
                if trophy then
                    trophy:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, '['.. winner:getName() ..'] has won the Zombie Event.')
                end
                 Game.broadcastMessage(string.format('%s is the winner of Zombie Event Versus %s Zombies.', winner:getName(), Game.getStorageValue(zeZombieCountGlobalStorage)), MESSAGE_STATUS_WARNING)
            end
            doClearZombieArena()
            resetVariables()
        end
        return false
    end
    return true
end

Now go into login.lua and paste this under PlayerDeath registration:
Code:
player:registerEvent("ZE_Death")
    if player:getStorageValue(1000) == 1 then --write ze_join_storage number here
        player:setStorageValue(1000, 0) --write ze_join_storage number here
    end

Globalevents:
in globalevents/globalevents.xml add this line:
Code:
<globalevent name="zombie" interval="7200000" script="zombie_think.lua"/>

and in globalevents/scripts create new lua and name it: zombie_think.lua
Code:
dofile('data/zombie_system.lua')

function onThink(interval, lastExecution, thinkInterval)
    if Game.getStorageValue(zeStartedGlobalStorage) < 1 then
        local teleport = Game.createItem(1387, 1, zeCreateTeleportPosition)
        if teleport then
            teleport:setAttribute(ITEM_ATTRIBUTE_UNIQUEID, 7000)
        end
        Game.setStorageValue(zeStartedGlobalStorage, 1)
        print('Zombie Event has started & waiting for players to join! Min: '.. zeMinPlayers ..'/'.. zeMaxPlayers ..'.')
        Game.broadcastMessage('The Zombie Event has started! You have '.. zeWaitMinutes ..' minutes to join!', MESSAGE_STATUS_WARNING)
        addEvent(startZombie, zeWaitMinutes * 60 * 1000)
    end
    return true
end

Movements:
in movements/movements.xml add this line:
Code:
<movevent event="StepIn" uniqueid="7000" script="zombie_teleport.lua"/>

and now create new lua in movements/scripts and name it: zombie_teleport.lua
Code:
dofile('data/zombie_system.lua')

function onStepIn(cid, item, position, fromPosition)
        local player = Player(cid)
    if not player then
            return false
        end
  
        if Game.getStorageValue(zeStartedGlobalStorage) == 2 then
            player:sendTextMessage(MESSAGE_INFO_DESCR, 'The Zombie Event has already started.')
            player:teleportTo(fromPosition, true)
            return false
        end
  
        if Game.getStorageValue(zeStartedGlobalStorage) == 0 then
            player:sendTextMessage(MESSAGE_INFO_DESCR, 'The Zombie Event has not started yet.')
            player:teleportTo(fromPosition, true)
            return false
        end
  
       if Game.getStorageValue(zeJoinedCountGlobalStorage) > zeMaxPlayers then
            player:teleportTo(fromPosition, true)
            player:sendTextMessage(MESSAGE_INFO_DESCR, 'The Zombie Event is already full! ['.. Game.getStorageValue(zeJoinedCountGlobalStorage) ..'/'.. zeMaxPlayers ..']')
            return false
        end
  
        player:teleportTo(zeWaitingRoomPos)
        Game.setStorageValue(zeJoinedCountGlobalStorage, Game.getStorageValue(zeJoinedCountGlobalStorage) + 1)
        Game.broadcastMessage(string.format('%s has joined the Zombie Event! [%s/'.. zeMaxPlayers ..'].', player:getName(), Game.getStorageValue(zeJoinedCountGlobalStorage)), MESSAGE_STATUS_WARNING)
        player:setStorageValue(zeJoinStorage, 1)
        return true
end

Create new xml file and name it: Zombie_Event.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<monster name="Zombie" nameDescription="a zombie" race="undead" experience="0" speed="100" manacost="0">
    <health now="500" max="500"/>
    <look type="311" corpse="0"/>
    <targetchange interval="4000" chance="10"/>
    <strategy attack="100" defense="0"/>
    <flags>
        <flag summonable="0"/>
        <flag attackable="1"/>
        <flag hostile="1"/>
        <flag illusionable="0"/>
        <flag convinceable="0"/>
        <flag pushable="0"/>
        <flag canpushitems="1"/>
        <flag canpushcreatures="1"/>
        <flag targetdistance="1"/>
        <flag staticattack="90"/>
        <flag runonhealth="0"/>
    </flags>
    <attacks>
        <attack name="melee" interval="2000" skill="9999999" attack="9999999"/>
    </attacks>
    <defenses armor="15" defense="15"/>
    <elements>
        <element firePercent="50"/>
    </elements>
    <immunities>
        <immunity death="1"/>
        <immunity energy="1"/>
        <immunity ice="1"/>
        <immunity earth="1"/>
        <immunity drown="1"/>
        <immunity drunk="1"/>
        <immunity lifedrain="1"/>
        <immunity paralyze="1"/>
    </immunities>
    <voices interval="5000" chance="10">
        <voice sentence="Mst.... klll...."/>
        <voice sentence="Whrrrr... ssss.... mmm.... grrrrl"/>
        <voice sentence="Dnnnt... cmmm... clsrrr...."/>
        <voice sentence="Httt.... hmnnsss..."/>
    </voices>
    <script>
            <event name="ZE_Mon_Death"/>
        </script>
</monster>

Go to part2, to add the other functions
 
Last edited:
Now in same folder as global.lua or compat.lua, create new lua and name it: zombie_system.lua
Code:
-- Zombie Variables
zeZombieName = 'Zombie Event' --Zombie Name
zombieSpawnInterval = 5 --how many seconds until a new zombie spawns
zeMaxZombies = 20 --max zombies in the arena?
zeJoinedCountGlobalStorage = 100 --Player joined event count

-- Players Variables
zeJoinStorage = 1000 --player join storage
zeMinPlayers = 1 --min players needed when time runout
zeMaxPlayers = 5 --max players to join
zeTrophy = 7369 --trophy itemid
zeJoinedCountGlobalStorage = 101 --Zombie spawned Count

-- Other Variables
zeWaitMinutes = 1 --when event has opened, how long until it starts?
zeWaitingRoomPos = Position(1998, 1999, 5) --middle of waiting room
zeZombieArena = Position(2000, 2000, 6) --when even start where should player be teleported in the zombie arena?
zeArenaFromPosition = Position(1995, 1996, 5) --pos of top left corner
zeArenaToPosition = Position(2001, 2003, 5) --pos of bottom right corner
zeMiddleZombieArena = Position(1998, 1999, 5) --Middle pos of the arena
zeWaitingRoomRadiusX = 20 --depends how big the waiting room is 20sqm to x
zeWaitingRoomRadiusY = 20 --depends how big the waiting room is 20sqm to y
zeZombieArenaRadiusX = 50 --Depends how big the zombie arena is 50sqm to x
zeZombieArenaRadiusY = 50 --Depends how big the zombie arena is 50sqm to y
zeStartedGlobalStorage = 102 -- Value: 0 == false, 1 == true, 2 == started --State of the event
zeCreateTeleportPosition = Position(1000, 1000, 7) --Where should the teleport be created?

function startZombie()
    local specs = Game.getSpectators(zeWaitingRoomPos, false, true, 0, zeWaitingRoomRadiusX, 0, zeWaitingRoomRadiusY)
        if Game.getStorageValue(zeJoinedCountGlobalStorage) < zeMinPlayers then
            for i = 1, #specs do
                    specs[i]:teleportTo(specs[i]:getTown():getTemplePosition(), false)
                    specs[i]:setStorageValue(zeJoinStorage, 0)
            end
            resetVariables()
            Game.broadcastMessage('Zombie Event failed to start, because of to little players joined the event!', MESSAGE_STATUS_WARNING)
            return true
        end
 
        for i = 1, #specs do
            specs[i]:teleportTo(zeZombieArena)
        end
        Game.broadcastMessage("Zombie Event has started, good luck to all participant.", MESSAGE_STATUS_WARNING)
        Game.setStorageValue(zeStartedGlobalStorage, 2)
        doStartZombieEvasion()
end

function doSummonZombie()
        if Game.getStorageValue(zeZombieCountGlobalStorage) > zeMaxZombies then
            return false
        end
 
        local zombie = Game.createMonster(zeZombieName, {x = math.random(zeArenaFromPosition.x, zeArenaToPosition.x), y = math.random(zeArenaFromPosition.y, zeArenaToPosition.y), z = math.random(zeArenaFromPosition.z, zeArenaToPosition.z)})
        if zombie then
            Game.createMonster(zeZombieName, {x = math.random(zeArenaFromPosition.x, zeArenaToPosition.x), y = math.random(zeArenaFromPosition.y, zeArenaToPosition.y), z = math.random(zeArenaFromPosition.z, zeArenaToPosition.z)})
        end
        Game.setStorageValue(zeZombieCountGlobalStorage, Game.getStorageValue(zeZombieCountGlobalStorage) + 1)
end

function doStartZombieEvasion()
        if Game.getStorageValue(zeStartedGlobalStorage) == 2 then
               doSummonZombie()
            addEvent(doStartZombieEvasion, 5 * 1000)
        end
end

function resetVariables()
        Game.setStorageValue(zeJoinedCountGlobalStorage, 0)
        Game.setStorageValue(zeZombieCountGlobalStorage, 0)
        Game.setStorageValue(zeStartedGlobalStorage, 0)
end

function doClearZombieArena()
        local specs = Game.getSpectators(zeMiddleZombieArena, false, false, 0, zeZombieArenaRadiusX, 0, zeZombieArenaRadiusY)
        for i = 1, #specs do
            if specs[i]:getName() == zeZombieName then
                    specs[i]:remove()
            end
        end
end

You can also make them join through talkaction:

Add this into talkactions/talkactions.xml
Code:
<talkaction words="!zombie" script="zombie_join.lua"/>

and now go to talkactions/scripts and create new lua and name it "zombie_join.lua"

Code:
dofile('data/zombie_system.lua')

function onSay(cid, words, param)
    local player = Player(cid)

    if Game.getStorageValue(zeStartedGlobalStorage) == 2 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, 'The Zombie Event has already started.')
        return false
    end

   if Game.getStorageValue(zeStartedGlobalStorage) < 1 then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "The Zombie Event has not started yet.")
        return false
    end

    if Game.getStorageValue(zeJoinedCountGlobalStorage) > zeMaxPlayers then
        player:sendTextMessage(MESSAGE_INFO_DESCR, 'The Zombie Event is already full! ['.. Game.getStorageValue(zeJoinedCountGlobalStorage) ..'/'.. zeMaxPlayers ..']')
        return false
    end

    if player:isPzLocked() then
        player:sendCancelMessage('You can\'t join the zombie while you are in a fight!')
        return false
    end
    
    player:teleportTo(zeWaitingRoomPos)
    if not player:getGroup():getAccess() then
        Game.setStorageValue(zeJoinedCountGlobalStorage, Game.getStorageValue(zeJoinedCountGlobalStorage) + 1)
        Game.broadcastMessage(string.format('%s has joined the Zombie Event! [%s/'.. zeMaxPlayers ..'].', player:getName(), Game.getStorageValue(zeJoinedCountGlobalStorage)), MESSAGE_STATUS_WARNING)
        player:setStorageValue(zeJoinStorage, 1)
    end
    return false
end
 
Last edited:
Ill try to post a example of map with the posistions, so you guys get the idea how to configure it.
 
can you make it when I type !zombie I will teleported to the waiting room but if the event is closed no one can enter with !zombie and if there are enough players to start the event !zombie says that it is full.
sorry for bad english
 
Why do you broadcast once for each player?
Code:
for _, tmpPlayer in ipairs(Game.getPlayers()) do
  broadcastMessage("The Zombie Event has started! You have "..ze_wait_minutes.." minutes to join!", MESSAGE_STATUS_WARNING)
end

Also, it does not seems to clean the spawned Zombies when finished.
 
Why do you broadcast once for each player?
Code:
for _, tmpPlayer in ipairs(Game.getPlayers()) do
  broadcastMessage("The Zombie Event has started! You have "..ze_wait_minutes.." minutes to join!", MESSAGE_STATUS_WARNING)
end

Also, it does not seems to clean the spawned Zombies when finished.
Ups my fault there, thanks for notice that.

As i said, its still on beta stage, i may forgot some functions to add ^^
 
Added clean function and also join zombie through talkaction.
 
the zombie is attacking me instead of tp me out
and the winner will get his reward but stay in the area
Ive fixed that winner now is tped out, so update the zombie_death.lua.

Also could you explain what you mean about "the zombie is attacking me instead of tp me out"
 
Ive fixed that winner now is tped out, so update the zombie_death.lua.

Also could you explain what you mean about "the zombie is attacking me instead of tp me out"

normally you will be thrown out as soon as you get hit 1 time but now the zombie attacks me and I just thrown out there when I'm dead
 
Well, it can be fixed also by change the dmg on the zombie, recopy the Zombie file.
 
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/zombie_death.lua:eek:nPrepareDeath
data/creaturescripts/scripts/zombie_death.lua:33: attempt to call global 'doClearZombieArena' (a nil value)
stack traceback:
[C]: in function 'doClearZombieArena'
data/creaturescripts/scripts/zombie_death.lua:33: in function <data/creaturescripts/scripts/zombie_death.lua:10>
 
The clear zombie function is missing, did you recopy the zombie_system.lua?
 
recopied the files but still this error:

Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/zombie_death.lua:eek:nPrepareDeath
attempt to index a nil value
stack traceback:
[C]: ?
[C]: in function 'getSpectators'
data/zombie_system.lua:68: in function 'doClearZombieArena'
data/creaturescripts/scripts/zombie_death.lua:33: in function <data/creaturescripts/scripts/zombie_death.lua:10>
 
I cant reproduce that error.
 
so how does this event function? Is it so that zombies attack you and you loose or must all players fight untill one remains or must all survive X number of waves?

Best way would be all players fight to survive X number or waves, each player gets 3 lives or 3 attempts, at end of waves all players get a prize.
 
Back
Top