Mateus Robeerto
Excellent OT User
I noticed that many individuals are experiencing errors, malfunctions, and so on. Therefore, I took the system posted by Ciroc and adapted it into a revscript. I removed some unnecessary components and added functional features. After testing, it worked flawlessly without any errors in the console. It's convenient and customizable, enabling configuration of the event's start time and rewards for achieving the highest points, along with other functionalities.
Revscripts.
Just add it to data/scripts or any location you prefer. You can even create a folder named 'system_events' and name the file 'snowballWarEvent.lua'.
Add it to data/lib and paste it here.
SnowBall_Configurations.lua
And also add it to global.lua.
Now, as a final step, go to globalevents/scripts/startup.lua and open it. Look for 'end' at the end of the file. Before that, add 'loadEvent() -- SnowBall event loader...
see how it looks like this here:
I have already translated everything into English now.
For those who want a ready-to-use map, just download and add it to your map... Have fun
The post by Ciroc here dates back to 2017. Check the original post here!
Note: It was tested on TFS 1.4.3.
Revscripts.
Just add it to data/scripts or any location you prefer. You can even create a folder named 'system_events' and name the file 'snowballWarEvent.lua'.
LUA:
local config = {
generator = 10103, -- Head to the center of the event map and recharge by clicking on the generator.
Time = "10:51:00", -- Enter the start time of the event.
Reward_First = { -- 'Reward_First' is for the first-place winner who receives the reward.
{2160, 100}, -- First item
{2152, 10}, -- Second item
},
Reward_Second = {2160, 50}, -- 'Reward_Second' is for the second-place winner.
Reward_Third = {2160, 10}, -- 'Reward_Third' is for the third-place winner.
-- TALKACTIONS
snowball = "!snowball", -- Command to trigger snowball actions.
shoot = "shoot", -- Use '!snowball shoot' to shoot a snowball at a player.
info = "info" -- Use '!snowball info' to check your points, ranking, etc.
}
local snowballWarEvent = Action()
function snowballWarEvent.onUse(player, item, fromPosition, target, toPosition, isHotkey)
if player:getStorageValue(10109) > 0 and player:getStorageValue(10108) <= 30 then
player:setStorageValue(10108, player:getStorageValue(10108) + SnowBall_Configurations.Ammo_Configurations.Ammo_Amount)
player:setStorageValue(10109, player:getStorageValue(10109) - SnowBall_Configurations.Ammo_Configurations.Ammo_Price)
player:sendTextMessage(29, "You have just bought " .. SnowBall_Configurations.Ammo_Configurations.Ammo_Amount .. " snowballs for " .. SnowBall_Configurations.Ammo_Configurations.Ammo_Price .. "\nYou have " .. player:getStorageValue(10108) .. " snowballs\nYou have " .. player:getStorageValue(10109) .. " point(s).")
elseif player:getStorageValue(10109) < 1 then
player:sendCancelMessage("You don't have " .. SnowBall_Configurations.Ammo_Configurations.Ammo_Price .. " point(s).")
elseif player:getStorageValue(10108) > 30 then
player:sendCancelMessage("You can only buy snowballs with a minimum of 30 balls.")
end
return true
end
snowballWarEvent:aid(config.generator)
snowballWarEvent:register()
local globalevent = GlobalEvent("SnowballWar")
local CACHE_GAMEPLAYERS = {}
function startGame(rounds)
if rounds == 0 then
if #CACHE_GAMEPLAYERS < SnowBall_Configurations.Event_MinPlayers then
for _, players in ipairs(CACHE_GAMEPLAYERS) do
Player(players):teleportTo(Player(players):getTown():getTemplePosition())
end
broadcastMessage("[Snowball Event]: The event was canceled due to not having at least " .. SnowBall_Configurations.Event_MinPlayers .. " players.")
else
for _, players in ipairs(CACHE_GAMEPLAYERS) do
Player(players):setStorageValue(10109, 0)
Player(players):setStorageValue(10108, SnowBall_Configurations.Ammo_Configurations.Ammo_Start)
Player(players):teleportTo(CACHE_GAMEAREAPOSITIONS[math.random(1, #CACHE_GAMEAREAPOSITIONS)])
end
broadcastMessage("[Snowball Event]: The event was closed. The game has started.")
addEvent(Event_endGame, SnowBall_Configurations.Event_Duration * 60 * 1000)
end
Item(getTileItemById(SnowBall_Configurations.Area_Configurations.Position_EventTeleport, 1387).uid):remove(1)
Item(getTileItemById(SnowBall_Configurations.Area_Configurations.Position_ExitWaitRoom, 1387).uid):remove(1)
return true
end
if #CACHE_GAMEPLAYERS < SnowBall_Configurations.Event_MinPlayers then
broadcastMessage("[Snowball Event]: " .. rounds .. " minute(s) left and " .. SnowBall_Configurations.Event_MinPlayers - #CACHE_GAMEPLAYERS .. " player(s) are missing to start the game.")
else
broadcastMessage("[Snowball Event]: " .. rounds .. " minute(s) left until the game starts.")
end
return addEvent(startGame, 60 * 1000, rounds - 1)
end
function Event_endGame()
table.sort(CACHE_GAMEPLAYERS, function(a, b) return Player(a):getStorageValue(10109) > Player(b):getStorageValue(10109) end)
for _, playerId in ipairs(CACHE_GAMEPLAYERS) do
local player = Player(playerId)
if player then
player:teleportTo(player:getTown():getTemplePosition())
end
end
local winner = Player(CACHE_GAMEPLAYERS[1])
local secondPlace = Player(CACHE_GAMEPLAYERS[2])
local thirdPlace = Player(CACHE_GAMEPLAYERS[3])
if winner then
for _, reward in ipairs(config.Reward_First) do
winner:addItem(reward[1], reward[2])
end
end
if secondPlace then
secondPlace:addItem(config.Reward_Second[1], config.Reward_Second[2])
end
if thirdPlace then
thirdPlace:addItem(config.Reward_Third[1], config.Reward_Third[2])
end
local winnerName = winner and winner:getName() or "Nobody"
broadcastMessage("[Snowball Event]: The winner is " .. winnerName .. "!")
local str = " ## -> SnowBall Ranking <- ##\n\n"
for rank, playerId in ipairs(CACHE_GAMEPLAYERS) do
local player = Player(playerId)
if player then
str = str .. rank .. ". " .. player:getName() .. ": " .. player:getStorageValue(10109) .. " point(s)\n"
end
end
broadcastMessage(str)
broadcastMessage("[Snowball Event]: The event has ended.")
end
function globalevent.onTime(interval)
if not SnowBall_Configurations.Event_Days[os.date("%w") + 1] then
return true
end
CACHE_GAMEPLAYERS = {}
local EventTeleport = Game.createItem(1387, 1, SnowBall_Configurations.Area_Configurations.Position_EventTeleport)
EventTeleport:setActionId(10101)
local ExitWaitRoom = Game.createItem(1387, 1, SnowBall_Configurations.Area_Configurations.Position_ExitWaitRoom)
ExitWaitRoom:setActionId(10102)
broadcastMessage("[Snowball Event]: The event has been opened. Go to the temple to participate.")
addEvent(startGame, 60 * 1000, SnowBall_Configurations.Event_WaitGame)
return true
end
globalevent:time(config.Time)
globalevent:register()
local config_move = {
actionids = {10101, 10102}
}
local moveevent = MoveEvent()
function moveevent.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if item:getActionId() == 10101 then
table.insert(CACHE_GAMEPLAYERS, player:getId())
player:teleportTo(SnowBall_Configurations.Area_Configurations.Position_WaitRoom)
elseif item:getActionId() == 10102 then
player:teleportTo(player:getTown():getTemplePosition())
for pos, players in ipairs(CACHE_GAMEPLAYERS) do
if player:getId() == players then
table.remove(CACHE_GAMEPLAYERS, pos)
return true
end
end
end
return true
end
moveevent:aid(config_move.actionids[1])
moveevent:aid(config_move.actionids[2])
moveevent:register()
local talkaction = TalkAction(config.snowball)
function talkaction.onSay(player, words, param)
if not isInArena(player) then
return false
end
local split = param:split(" ")
if split[1] == config.shoot then
local cooldownTime = 1
if player:getStorageValue(10107) + cooldownTime > os.time() then
player:sendCancelMessage("Wait to use this command again.")
return true
end
if not SnowBall_Configurations.Ammo_Configurations.Ammo_Infinity then
if player:getStorageValue(10108) > 0 then
player:setStorageValue(10108, player:getStorageValue(10108) - 1)
player:sendCancelMessage("You have " .. player:getStorageValue(10108) .. " snowballs left.")
else
player:sendCancelMessage("You are out of snowballs.")
return true
end
end
player:setStorageValue(10107, os.time())
Event_sendSnowBall(player:getId(), player:getPosition(), SnowBall_Configurations.Ammo_Configurations.Ammo_Distance, player:getDirection())
return false
elseif split[1] == config.info then
local str = " ## -> Player Infos <- ##\n\nPoints: " .. player:getStorageValue(10109) .. "\nSnowballs: " .. player:getStorageValue(10108)
str = str .. "\n\n ## -> Ranking <- ##\n\n"
for i = 1, 5 do
if CACHE_GAMEPLAYERS[i] then
str = str .. i .. ". " .. Player(CACHE_GAMEPLAYERS[i]):getName() .. "\n"
end
end
for pos, players in ipairs(CACHE_GAMEPLAYERS) do
if player:getId() == players then
str = str .. "My Ranking Pos: " .. pos
end
end
player:showTextDialog(2111, str)
return false
end
end
talkaction:separator(" ")
talkaction:register()
Add it to data/lib and paste it here.
SnowBall_Configurations.lua
LUA:
SnowBall_Configurations = {
Event_Duration = 1, -- Duration of the game in minutes.
Event_WaitGame = 3, -- Waiting time in minutes before the start of the game, inside the room.
Event_MinPlayers = 2, -- Minimum number of players for the game to start; otherwise, the game is canceled.
Event_GainPoint = 1, -- Points gained for each hit in the game.
Event_LostPoints = 1, -- Points lost for each death in the game. // To deactivate, set value = 0.
Event_Days = {1, 2, 3, 4, 5, 6, 7}, -- Days the event will occur (following the order of 1 = Sunday, 7 = Saturday)
Area_Configurations = {
Area_Arena = {{x = 724, y = 773, z = 7}, {x = 775, y = 825, z = 7}}, -- Game arena area, ({Top Left Corner}, {Bottom Right Corner})
Position_WaitRoom = {x = 748, y = 801, z = 6}, -- Waiting room position for the game
Position_ExitWaitRoom = {x = 748, y = 795, z = 6}, -- Teleport position to exit the game's waiting room
Position_EventTeleport = {x = 685, y = 602, z = 7}, -- Position where the teleport will be created for participants to go to the waiting room
},
Ammo_Configurations = {
Ammo_Price = 1, -- Price of ammunition in game points.
Ammo_Ammount = 100, -- Amount gained per purchase.
Ammo_Start = 100, -- Starting ammunition quantity for each player at the beginning of the game.
Ammo_Restart = 100, -- Player's ammunition quantity in case of death. // Set value = 0 to deactivate.
Ammo_Speed = 150, -- Speed of each shot
Ammo_Infinity = false, -- Whether ammunition is infinite or not (True / False)
Ammo_Exhaust = 1, -- Seconds to wait to use the !snowball shoot command again
Ammo_Distance = 5, -- Number of tiles the shot will reach
},
}
CACHE_GAMEPLAYERS = {}
CACHE_GAMEAREAPOSITIONS = {}
function loadEvent()
print("[SnowBall Event]: Loading the arena area.")
for newX = SnowBall_Configurations.Area_Configurations.Area_Arena[1].x, SnowBall_Configurations.Area_Configurations.Area_Arena[2].x do
for newY = SnowBall_Configurations.Area_Configurations.Area_Arena[1].y, SnowBall_Configurations.Area_Configurations.Area_Arena[2].y do
local AreaPos = {x = newX, y = newY, z = SnowBall_Configurations.Area_Configurations.Area_Arena[1].z}
if getTileThingByPos(AreaPos).itemid == 0 then
print("[SnowBall Event]: There was a problem loading position (x = " .. AreaPos.x .. " - y = " .. AreaPos.y .." - z = " .. AreaPos.z .. ") of the event's arena, please check the conditions.")
return false
elseif isWalkable(AreaPos) then
table.insert(CACHE_GAMEAREAPOSITIONS, AreaPos)
end
end
end
print("[SnowBall Event]: Arena area loading completed successfully.")
if getTileThingByPos(SnowBall_Configurations.Area_Configurations.Position_WaitRoom).itemid == 0 then
print("[SnowBall Event]: There was a problem checking the existence of the waiting room position, please verify the conditions.")
return false
end
if getTileThingByPos(SnowBall_Configurations.Area_Configurations.Position_ExitWaitRoom).itemid == 0 then
print("[SnowBall Event]: There was a problem checking the existence of the exit teleport position from the waiting room, please verify the conditions.")
return false
end
if getTileThingByPos(SnowBall_Configurations.Area_Configurations.Position_EventTeleport).itemid == 0 then
print("[SnowBall Event]: There was a problem checking the existence of the position for creating the event's teleport, please verify the conditions.")
return false
end
print("[SnowBall Event]: Event loading completed successfully.")
return true
end
local sampleConfigs = {
[0] = {dirPos = {x = 0, y = -1}},
[1] = {dirPos = {x = 1, y = 0}},
[2] = {dirPos = {x = 0, y = 1}},
[3] = {dirPos = {x = -1, y = 0}},
}
local iced_Corpses = {
[0] = {
[0] = {7303},
[1] = {7306},
[2] = {7303},
[3] = {7306},
},
[1] = {
[0] = {7305, 7307, 7309, 7311},
[1] = {7308, 7310, 7312},
[2] = {7305, 7307, 7309, 7311},
[3] = {7308, 7310, 7312},
},
}
function Event_sendSnowBall(cid, pos, rounds, dir)
local player = Player(cid)
if rounds == 0 then
return true
end
if player then
local sampleCfg = sampleConfigs[dir]
if sampleCfg then
local newPos = Position(pos.x + sampleCfg.dirPos.x, pos.y + sampleCfg.dirPos.y, pos.z)
if isWalkable(newPos) then
if Tile(newPos):getTopCreature() then
local killed = Tile(newPos):getTopCreature()
if Player(killed:getId()) then
if iced_Corpses[killed:getSex()] then
local killed_corpse = iced_Corpses[killed:getSex()][killed:getDirection()][math.random(1, #iced_Corpses[killed:getSex()][killed:getDirection()])]
Game.createItem(killed_corpse, 1, killed:getPosition())
local item = Item(getTileItemById(killed:getPosition(), killed_corpse).uid)
addEvent(function() item:remove(1) end, 3000)
end
killed:getPosition():sendMagicEffect(3)
killed:teleportTo(CACHE_GAMEAREAPOSITIONS[math.random(1, #CACHE_GAMEAREAPOSITIONS)])
killed:getPosition():sendMagicEffect(50)
killed:setStorageValue(10109, killed:getStorageValue(10109) - SnowBall_Configurations.Event_LostPoints)
killed:setStorageValue(10108, SnowBall_Configurations.Ammo_Configurations.Ammo_Restart)
killed:sendTextMessage(29, "You were hit by player " .. player:getName() .. " and lost -" .. SnowBall_Configurations.Event_LostPoints .." point(s).\nTotal: " .. killed:getStorageValue(10109) .. " point(s)")
player:setStorageValue(10109, player:getStorageValue(10109) + SnowBall_Configurations.Event_GainPoint)
player:sendTextMessage(29, "You hit player " .. killed:getName() .. " and gained +" .. SnowBall_Configurations.Event_GainPoint .." point(s).\nTotal: " .. player:getStorageValue(10109) .. " point(s)")
if(CACHE_GAMEPLAYERS[2] == player:getId()) and player:getStorageValue(10109) >= Player(CACHE_GAMEPLAYERS[1]):getStorageValue(10109) then
player:getPosition():sendMagicEffect(7)
player:sendTextMessage(29, "You are now the leader of the SnowBall ranking, congratulations!")
Player(CACHE_GAMEPLAYERS[1]):getPosition():sendMagicEffect(16)
Player(CACHE_GAMEPLAYERS[1]):sendTextMessage(29, "You have just lost the first place!")
end
table.sort(CACHE_GAMEPLAYERS, function(a, b) return Player(a):getStorageValue(10109) > Player(b):getStorageValue(10109) end)
else
newPos:sendMagicEffect(3)
end
return true
end
pos:sendDistanceEffect(newPos, 13)
pos = newPos
return addEvent(Event_sendSnowBall, SnowBall_Configurations.Ammo_Configurations.Ammo_Speed, player:getId(), pos, rounds - 1, dir)
end
newPos:sendMagicEffect(3)
return true
end
end
return true
end
function isWalkable(pos)
for i = 0, 255 do
pos.stackpos = i
local item = Item(getTileThingByPos(pos).uid)
if item ~= nil then
if item:hasProperty(2) or item:hasProperty(3) or item:hasProperty(7) then
return false
end
end
end
return true
end
function isInArena(player)
local pos = player:getPosition()
if pos.z == SnowBall_Configurations.Area_Configurations.Area_Arena[1].z then
if pos.x >= SnowBall_Configurations.Area_Configurations.Area_Arena[1].x and pos.y >= SnowBall_Configurations.Area_Configurations.Area_Arena[1].y then
if pos.x <= SnowBall_Configurations.Area_Configurations.Area_Arena[2].x and pos.y <= SnowBall_Configurations.Area_Configurations.Area_Arena[2].y then
return true
end
end
end
return false
end
And also add it to global.lua.
LUA:
dofile('data/lib/SnowBall_Configurations.lua')
Now, as a final step, go to globalevents/scripts/startup.lua and open it. Look for 'end' at the end of the file. Before that, add 'loadEvent() -- SnowBall event loader...
see how it looks like this here:
LUA:
loadEvent() -- SnowBall event loader
end
I have already translated everything into English now.
For those who want a ready-to-use map, just download and add it to your map... Have fun
The post by Ciroc here dates back to 2017. Check the original post here!
GlobalEvent - Snowball War Event (TFS 1.X)
Good morning, Otland's friends! I bring today a very fun and different event for your server that is the snowball event, the event consists of a battle of snowballs and the player that more kill wins. Command: !snowball atirar - Shoot the snowball straight to hit the target Exemple: Note...
otland.net
Attachments
-
snowballWarEvent.otbm45.7 KB · Views: 38 · VirusTotal
Last edited: