• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

GlobalEvent [TFS 1.2] Hunger Games Event [with maps]

Karain

Jack of all trades
Joined
Jul 9, 2009
Messages
338
Solutions
3
Reaction score
147
Location
Egypt
Good morning/evening/afternoon ladies and gentlemen, Today you will witness my first contribution to this wonderful community (finally graduating from being a lurker.. ahem). I present to you:

HUNGER GAMES EVENT

Inspired from the minecraft mini-game of the same name, i've created this event back when TFS 0.4 was a thing, and after seeing some request for this event on otland, i have decided to convert it to the latest TFS 1.2 and publish it for all of you lovely users to use, modify and improve. it's time i pay back your generosities, yes?

Anyway, back on topic.


How does the game work?

firstly if a player decides to queue up to join the event, he'll simply type in "!join hunger games" and he'll be on the waiting list.

fc4b71f2f012e7348303a7b1b55f9667.png


after a configurable amount of time and if there is enough players queued up for a round of hunger games, they will be teleported, have all their items moved safely into a configurable depot box.

on each map there will be chests that have a random chance to hold a bunch of items, the players need to find and collect items in order to survive and be the last player alive. winner gets configurable prizes, standard stuff.

7013b08211a4d0262c12edded6df280e.png


Maps:

2435n5h.jpg

vxdx02.jpg

2wqbl1u.jpg


now that you have a solid idea about the event. let's get into the technicalities.

DOWNLOAD THE MAP HERE
(small note: i didn't create the maps, i've downloaded them from otland's map download section, if you are the creator of the map, please link me your download topic and you will receive full credits)

CODE:

globalevents/globalevents.xml

Code:
<globalevent type="startup" name="hunger" script="hunger.lua"/>

globalevents/scripts/hunger.lua



Code:
currentgameid = 201
killstreak = 60013
depotbox= {x=700,y=760,z=5} --location of a depot box, recommended to be accessible by players incase of bugs or crashes
game = {{name="Hunger Games Arena 1", cheststartid=60100, minplayers=8, maxplayers=16, chests=299, startpos={
    {x = 814, y = 760, z = 7},
    {x = 809, y = 758, z = 7},
    {x = 807, y = 753, z = 7},
    {x = 809, y = 748, z = 7},
    {x = 814, y = 746, z = 7},
    {x = 819, y = 748, z = 7},
    {x = 821, y = 753, z = 7},
    {x = 819, y = 758, z = 7},
    {x = 811, y = 759, z = 7},
    {x = 808, y = 756, z = 7},
    {x = 808, y = 750, z = 7},
    {x = 811, y = 747, z = 7},
    {x = 817, y = 747, z = 7},
    {x = 820, y = 750, z = 7},
    {x = 820, y = 756, z = 7},
    {x = 817, y = 759, z = 7}
    }
    },
        {
    name="Hunger Games Arena 2", cheststartid=61100, minplayers=2, maxplayers=4, chests=299, startpos={
    {x = 1036, y = 910, z = 6},
    {x = 1032, y = 906, z = 6},
    {x = 1036, y = 902, z = 6},
    {x = 1040, y = 906, z = 6}
    }
    },
        {
    name="Hunger Games Arena 3", cheststartid=62100, minplayers=4, maxplayers=8, chests=299, startpos={
    {x = 1047, y = 1158, z = 7},
    {x = 1048, y = 1158, z = 7},
    {x = 1052, y = 1158, z = 7},
    {x = 1053, y = 1158, z = 7},
    {x = 1047, y = 1167, z = 7},
    {x = 1048, y = 1167, z = 7},
    {x = 1052, y = 1167, z = 7},
    {x = 1053, y = 1167, z = 7}
    }
    }
    }

    availablearenas = {1,2,3} -- script starts with all arenas as "available"
    gameplayers = {}
    prize = {{2160,1},{5097,10},{2128,1}}

function Player:removeAllItems() -- function to clear the player's inventory
    local depotpos = Tile(Position(depotbox.x, depotbox.y, depotbox.z)):getItemByType(ITEM_TYPE_DEPOT)
    local depotid = getDepotId(depotpos:getUniqueId())
    local depot = self:getDepotChest(depotid,true)
    local box = depot:addItem(1988)
    box:setAttribute(ITEM_ATTRIBUTE_NAME,"player gear box")
    for i=1,10 do
        local item = self:getSlotItem(i)
        if item then
            item:moveTo(box)
        end
    end
end

function Player:getBackItems() -- function to clear the player's inventory
  local depotpos = Tile(Position(depotbox.x, depotbox.y, depotbox.z)):getItemByType(ITEM_TYPE_DEPOT)
  local depotid = getDepotId(depotpos:getUniqueId())
  local depot = self:getDepotChest(depotid,true)
  local box = depot:getItem(0)
  for i= box:getSize()-1, 0, -1 do
     local item = box:getItem(i)
     if item then
        item:clone():moveTo(self)
     end
  end
  box:remove()
end

local function teleportThing(seconds)
    if seconds <= 0 and #queue >= 1 then
    local looparenas = availablearenas -- preventing possible conflicts with looping
        for a,b in pairs(looparenas) do
            if #queue >= game[looparenas[a]].minplayers then
                local p = 1
                while p < game[looparenas[a]].maxplayers do
                    for i, pname in pairs(queue) do
                        local player = Player(pname)
                        if player then
                            player:setStorageValue(currentgameid, looparenas[a])
                            local pos = Position(game[looparenas[a]].startpos[p].x, game[looparenas[a]].startpos[p].y, game[looparenas[a]].startpos[p].z)
                            player:teleportTo(pos)
                            player:removeAllItems()
                            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Welcome to The Hunger Games, Your objective is to loot, kill and be the last man standing, Good luck!")
                            if gameplayers[looparenas[a]] == nil then
                                gameplayers[looparenas[a]] = {}
                            end
                            table.insert(gameplayers[looparenas[a]], player:getName())
                            table.remove(queue,i)
                        end
                    end
                    p = p+1
                end
                for i = game[looparenas[a]].cheststartid, game[looparenas[a]].cheststartid+game[looparenas[a]].chests do
                    Game.setStorageValue(i, -1)
                end
                Game.broadcastMessage(MESSAGE_EVENT_ADVANCE,"Hunger Games started in " ..game[looparenas[a]].name.."!")
                for k,v in pairs(availablearenas) do
                    if v == r then
                        table.remove(availablearenas,i)
                    end
                end
            else
                for _, player in pairs(queue) do
                    Player(player):sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Sorry, There is not enough players to start "..game[availablearenas[a]].name)
                end
            end
        end
    return teleportThing(3600)
    end
    if seconds == 60 then
        for _, player in pairs(queue) do
            Player(player):sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The Hunger Games will begin in " .. seconds/60 .. " minute, Get Ready!")
        end
    elseif seconds % 60 == 0 and seconds ~= 60 and seconds ~= 300 and seconds < 300 then
        for _, player in pairs(queue) do
            Player(player):sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The Hunger Games will begin in " .. seconds/60 .. " minutes!")
        end
    elseif seconds == 300 then
        Game.broadcastMessage(MESSAGE_EVENT_ADVANCE,"The Hunger Games will begin in " .. seconds/60 .. " minutes! To join say /join hunger games")
    end
    if seconds ~= 0 then
        addEvent(teleportThing, 60000, seconds - 60)
    end
    return true
end

function onStartup()
    teleportThing(600)
    return true
end
 
Last edited:
creaturescripts/creaturescripts.xml


Code:
<event type="logout" name="eventlogout" script="eventlogout.lua"/>
<event type="death" name="hunger" script="hunger.lua"/>

creaturescripts/scripts/login.lua

add this before "return true"
Code:
player:registerEvent("hunger")

creaturescripts/scripts/eventlogout.lua

Code:
function onLogout(player)
local gameid = player:getStorageValue(currentgameid)
if(gameid > 0 ) then
player:getBackItems()
player:setStorageValue(currentgameid, -1)
if gameplayers[gameid] then
for i=1,#gameplayers[gameid] do
Player(gameplayers[gameid][i]):sendTextMessage(MESSAGE_STATUS_CONSOLE_RED, player:getName() .. " has left the hunger games with "..player:getStorageValue(killstreak).." kills | Tributes still alive: " .. #gameplayers[gameid])
end
for k,v in pairs(gameplayers[gameid]) do
if v == player:getName() then
table.remove(gameplayers[gameid],k)
end
end
end
player:setStorageValue(killstreak, 0)
player:teleportTo((player:getTown()):getTemplePosition())
if gameplayers[gameid] and #gameplayers[gameid] == 1 then
Player(gameplayers[gameid][1]):getBackItems()
Player(gameplayers[gameid][1]):setStorageValue(gameid, -1)
Game.broadcastMessage(MESSAGE_EVENT_ADVANCE,gameplayers[gameid][1] .." Has won The Hunger Games in ".. game[gameid].name .." with "..Player(gameplayers[gameid][1]):getStorageValue(killstreak).." Kill Streaks! Congratulations!")
Player(gameplayers[gameid][1]):teleportTo((Player(gameplayers[gameid][1]):getTown()):getTemplePosition())
Player(gameplayers[gameid][1]):setStorageValue(killstreak, 0)
for _, item in pairs(prize) do
Player(gameplayers[gameid][1]):addItem(item[1],item[2])
end
for k,v in pairs(gameplayers[gameid]) do
if v == gameplayers[gameid][1] then
table.remove(gameplayers[gameid],i)
end
end
table.insert(availablearenas, gameid)
elseif gameplayers[gameid] and #gameplayers[gameid] < 1 then
Game.broadcastMessage(MESSAGE_EVENT_ADVANCE,game[gameid].name .." Has Ended without winners because all players have left the game!")
table.insert(availablearenas, gameid)
end
end
for k,v in pairs(queue) do
if v == player:getName() then
table.remove(queue,i)
end
end
return true
end

creaturescripts/scripts/hunger.lua


Code:
function onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
local gameid = player:getStorageValue(currentgameid)
if gameid > 0 then
if killer and killer:isPlayer() then
for _, gamer in pairs(gameplayers[gameid]) do
Player(gamer):sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, player:getName() .. " has been killed by " .. killer:getName() .. " with "..player:getStorageValue(killstreak).." kills | Tributes still alive: " .. #gameplayers[gameid])
end
killer:setStorageValue(killstreak, killer:getStorageValue(killstreak)+1)
else
for  _, gamer in pairs(gameplayers[gameid]) do
Player(gamer):sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, player:getName() .. " has died with "..player:getStorageValue(killstreak).." kills | Tributes still alive: " .. #gameplayers[gameid])
end
end
player:setStorageValue(killstreak, 0)
player:setStorageValue(currentgameid, -1)
player:getBackItems()
for k,v in pairs(gameplayers[gameid]) do
if v == player:getName() then
table.remove(gameplayers[gameid],k)
end
end
if #gameplayers[gameid] == 1 then
Game.broadcastMessage(MESSAGE_EVENT_ADVANCE,Player(gameplayers[gameid][1]):getName() .." Has won The Hunger Games in ".. game[gameid].name .." with ".. Player(gameplayers[gameid][1]):getStorageValue(killstreak) .." Kill Streaks! Congratulations!")
Player(gameplayers[gameid][1]):teleportTo((Player(gameplayers[gameid][1]):getTown()):getTemplePosition())
Player(gameplayers[gameid][1]):setStorageValue(killstreak, 0)
Player(gameplayers[gameid][1]):setStorageValue(currentgameid, -1)
Player(gameplayers[gameid][1]):getBackItems()
for _, item in pairs(prize) do
Player(gameplayers[gameid][1]):addItem(item[1],item[2])
end
for k,v in pairs(gameplayers[gameid]) do
if v == gameplayers[gameid][1] then
table.remove(gameplayers[gameid],i)
end
end
table.insert(availablearenas, gameid)
end
end
return true
end
 
Last edited:
talkactions/talkactions.xml

Code:
<talkaction words="!join" separator=" " script="join.lua"/>
<talkaction words="!ragequit" separator=" " script="leave.lua"/>

talkactions/scripts/join.lua

Code:
local gamename = {
    "hunger games"
}
queue = {}

function onSay(player, words, param)
    local id = 0
    for i=1, #gamename do
        if param == gamename[i] then
            id = i
        end
    end
    local currentgame = player:getStorageValue(currentgameid)
    if (id ~= 0) then
        if currentgame <= 0 then
            for _, playerid in pairs(queue) do
                if player:getName() == playerid then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are already queue for this game.")
                return player:getPosition():sendMagicEffect(CONST_ME_POFF)
                end
            end
            table.insert(queue, player:getName())
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have queued up for "..gamename[id].." with "..#queue.." total players")
            return player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are already in a game.")
            return player:getPosition():sendMagicEffect(CONST_ME_POFF)
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "!join hunger games")
        return player:getPosition():sendMagicEffect(CONST_ME_POFF)
    end
end

talkactions/scripts/leave.lua

Code:
function onSay(player, words, param)
local currentgame = player:getStorageValue(currentgameid)
if currentgame > 0 then
return player:addHealth(-player:getMaxHealth())
else
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You can only do that in an event game.")
return player:getPosition():sendMagicEffect(CONST_ME_POFF)
end
end

actions/actions.xml


Code:
<!-- Hunger Games Chests -->
    <action fromaid="60101" toaid="60499" script="games/hunger.lua"/>
    <action fromaid="61101" toaid="61499" script="games/hunger.lua"/>
    <action fromaid="62101" toaid="62499" script="games/hunger.lua"/>

actions/scripts/hunger.lua

Code:
local tier = {
{                    --tier1
{id =2120 , chance = 10, count = 1}, --rope
{id =2554 , chance = 5, count = 1}, --shovel
{id =1991 , chance = 10, count = 1}, --bag
{id =1998 , chance = 5, count = 1}, --backpack
{id =2376 , chance = 10, count = 1}, --sword1
{id =2409 , chance = 5, count = 1}, --sword2
{id =2461 , chance = 10, count = 1}, --helmet1
{id =2458 , chance = 5, count = 1}, --helmet2
{id =2467 , chance = 10, count = 1}, --armor1
{id =2464 , chance = 5, count = 1}, --armor2
{id =2649 , chance = 10, count = 1}, --legs1
{id =2648 , chance = 5, count = 1}, --legs2
{id =2643 , chance = 10, count = 1}, --feet1
{id =2642 , chance = 5, count = 1}, --feet2
{id =2684 , chance = 20, count = 10}, --food1
{id =2689 , chance = 20, count = 10}, --food2
{id =2691 , chance = 20, count = 10}, --food3
{id =2677 , chance = 20, count = 20}, --food4
{id =2674 , chance = 20, count = 10}, --food5
{id =2386 , chance = 10, count = 1}, --axe1
{id =2441 , chance = 5, count = 1}, --axe2
{id =2437 , chance = 10, count = 1}, --club1
{id =2398 , chance = 5, count = 1}, --club2
{id =2190 , chance = 5, count = 1}, --wand1
{id =2191 , chance = 5, count = 1}, --wand2
{id =2456 , chance = 5, count = 1}, --bow1
{id =7438 , chance = 5, count = 1}, --bow2
{id =2512 , chance = 10, count = 1}, --shield1
{id =2529 , chance = 5, count = 1}, --shield2
{id =2331 , chance = 10, count = 10}, --rune1
{id =2313 , chance = 5, count = 10}, --rune2
{id =2544 , chance = 10, count = 10}, --ammo1
{id =2545 , chance = 5, count = 10}, --ammo2
{id =8704 , chance = 10, count = 1}, --potion1
{id =7618 , chance = 5, count = 1} --potion2
},
{                    --tier2
{id =2392 , chance = 10, count = 1}, --sword1
{id =7385 , chance = 5, count = 1}, --sword2
{id =2460 , chance = 10, count = 1}, --helmet1
{id =2480 , chance = 5, count = 1}, --helmet2
{id =2465 , chance = 10, count = 1}, --armor1
{id =2463 , chance = 5, count = 1}, --armor2
{id =2478 , chance = 10, count = 1}, --legs1
{id =2647 , chance = 5, count = 1}, --legs2
{id =11303 , chance = 10, count = 1}, --feet1
{id =7453 , chance = 5, count = 1}, --feet2
{id =2428 , chance = 10, count = 1}, --axe1
{id =2429 , chance = 5, count = 1}, --axe2
{id =2439 , chance = 10, count = 1}, --club1
{id =2423 , chance = 5, count = 1}, --club2
{id =2188 , chance = 5, count = 1}, --wand1
{id =8921 , chance = 5, count = 1}, --wand2
{id =8857 , chance = 5, count = 1}, --bow1
{id =8855 , chance = 5, count = 1}, --bow2
{id =2524 , chance = 10, count = 1}, --shield1
{id =2525 , chance = 5, count = 1}, --shield2
{id =2288 , chance = 10, count = 10}, --rune1
{id =2274 , chance = 5, count = 10}, --rune2
{id =7364 , chance = 10, count = 10}, --ammo1
{id =15648 , chance = 5, count = 10} --ammo2

}
}
function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)
    chesttier = math.floor(((item.actionid % 1000) + 100 ) / 200)
    if Game.getStorageValue(item:getActionId()) ~= 1 then
    for a=item:getSize()-1 , 0, -1 do
        item:getItem(i):remove() -- cleaning any old remaining items from previous games.
    end
    for i=1,20 do
        percentage = math.random(1,100)
        randomitem = math.random(1,#tier[chesttier])
            if percentage <= tier[chesttier][randomitem].chance then
            item:addItem(tier[chesttier][randomitem].id, math.random(1,tier[chesttier][randomitem].count))    --adding random item
            end
    end
    Game.setStorageValue(item:getActionId(), 1)
    end
end
 
Last edited:
If you have any bugs, optimizations, possible features, please let me know.

Known Bugs:
Code:
None so far...

Future Features:
Code:
- a small timer after being teleported into the event with players frozen in place then released after the game starts

Changelog:
Code:
1.0.0 23rd of july 2015 : Released

1.0.1 29th of july 2015 : Fixed a bug where items refresh in chest each time a player opens it.

1.0.2 30th of july 2015 :
-Fixed a fatal bug where the code breaks when a player dies or leaves the game through logout.
-added !ragequit command that causes the player to suicide in the event.

1.0.3 8th of August 2015: Fixed a bug where the event death script would run in any pvp situation.

1.0.4 9th of August 2015: Fixed client debug with broadcasts thanks to silveralol, files changed:
-globalevents/scripts/hunger.lua
-creaturescripts/scripts/hunger.lua
-creaturescripts/scripts/eventlogout.lua

1.0.5 31st of August 2015: Fixed a bug where a player cannot get his items back automatically after the event ends -- Big thanks to Mokerhamer, Files changed:
-globalevents/scripts/hunger.lua only

1.0.6 18th of October 2016: Fixed a bug that would prevent the event from restarting again after the first time.
 
Last edited:
something tells me they'd rather make tibia maps than whatever they're doing now.

Razor, please take your rude remarks elsewhere. I dont like the way you are talking about my mappers who i pay 35 cents an hour.
 
Everytime you open a chest all items gets renewed (You can spam open the chest for abuse). Change the chest action to a globalevent happening every 5 minutes, filling all chests with actionid with random items.
 
Back
Top