Sizaro
Advanced OT User
I salvaged this script from another datapack and I want to make it work perfectly but I need help.
What it does
How to start the event
TESTING MAP (script should be configured for it): battlefield.otbm
GitHub - otland/forgottenserver: A free and open-source MMORPG server emulator written in C++
(I might've forgotten something).
data\creaturescripts\creaturescripts.xml
data\creaturescripts\scripts\events\battlefield.lua
data\globalevents\globalevents.xml
data\globalevents\scripts\events\bf_start.lua
data\movements\movements.xml
data\movements\scripts\events\bf_tp.lua
data\talkactions\scripts\events\btf_start.lua
data\lib\libs.lua
data\lib\events\libs.lua
data\lib\events\battlefield.lua
What it does
How to start the event
- Globalevent every 12:30 and 00:30 ingame.
- Talkaction by tutor or higher with /btf
- Puts you into a random team.
- Sets your outfit to green or purple.
- Puts you into an area where you have to prepare with your team.
- After 10 minutes, the event starts and the walls that separates the teams is removed.
- After 25 minutes, the event ends and teleports everyone to temple (untested).
- If you die, you will spawn in temple and you don't lose anything.
- If you logout, you will spawn in temple.
- It's possible to change outfit inside >> it shouldn't be possible.
- It doesn't spawn the teleport (maybe I configured it wrong?)
- Friendly fire possible, but no damage is dealt (you will still get a skull) >> make it not possible to attack friendlies.
- Possibly other things.
TESTING MAP (script should be configured for it): battlefield.otbm
GitHub - otland/forgottenserver: A free and open-source MMORPG server emulator written in C++
(I might've forgotten something).
data\creaturescripts\creaturescripts.xml
XML:
<event type="preparedeath" name="BFPrepareDeath" script="events/battlefield.lua" />
<event type="healthchange" name="BFHealthChange" script="events/battlefield.lua" />
<event type="manachange" name="BFManaChange" script="events/battlefield.lua" />
<event type="logout" name="BFLogout" script="events/battlefield.lua" />
data\creaturescripts\scripts\events\battlefield.lua
Lua:
function onLogout(player)
local info = Battlefield:findPlayer(player)
if info then
Battlefield:onLeave(player)
end
return true
end
function onPrepareDeath(player, killer)
local info = Battlefield:findPlayer(player)
if info then
Battlefield:onDeath(player, killer)
end
return false
end
function onHealthChange(player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
if not attacker then
return primaryDamage, primaryType, secondaryDamage, secondaryType
end
local thisInfo = Battlefield:findPlayer(player)
local otherInfo = Battlefield:findPlayer(attacker)
if thisInfo and otherInfo and thisInfo.team == otherInfo.team then
if primaryType ~= COMBAT_HEALING then
return COMBAT_NONE, 0, COMBAT_NONE, 0
end
end
return primaryDamage, primaryType, secondaryDamage, secondaryType
end
function onManaChange(player, attacker, manaChange, origin)
if not attacker then
return manaChange
end
local thisInfo = Battlefield:findPlayer(player)
local otherInfo = Battlefield:findPlayer(attacker)
if thisInfo and otherInfo and thisInfo.team == otherInfo.team then
return 0
end
return manaChange
end
data\globalevents\globalevents.xml
XML:
<globalevent name="BF_01" time="13:00:00" script="events/bf_start.lua" />
<globalevent name="BF_02" time="00:30:00" script="events/bf_start.lua" />
data\globalevents\scripts\events\bf_start.lua
Lua:
local function warnEvent(i)
Game.broadcastMessage("Battlefield event is about to commence!")
if i > 1 then addEvent(warnEvent, 2 * 60 * 1000, i - 1) end
end
local function openBattlefield()
Battlefield:Open()
end
local function closeBattlefield()
Battlefield:Close()
end
function onTime(interval)
Game.broadcastMessage("Battlefield event is about to commence!")
createPortal(Battlefield.teleport.pos, 16, Battlefield.teleport.aid)
addEvent(warnEvent, 2 * 60 * 1000, 4)
addEvent(removePortal, 10 * 60 * 1000, Battlefield.teleport.pos, 16)
addEvent(openBattlefield, 10 * 60 * 1000)
addEvent(closeBattlefield, 25 * 60 * 1000)
return true
end
data\movements\movements.xml
XML:
<movevent event="StepIn" actionid="45000" script="events/bf_tp.lua" />
data\movements\scripts\events\bf_tp.lua
Lua:
function onStepIn(creature, item, position, fromPosition)
local player = Player(creature)
if not player then return false end
if player:getLevel() < Battlefield.minLevel then
creature:teleportTo(fromPosition)
creature:sendTextMessage(MESSAGE_INFO_DESCR, "You need level "..Battlefield.minLevel.."+ to enter.")
return false
end
if Battlefield.maxPlayers <= Battlefield:getPlayersCount() then
creature:teleportTo(fromPosition)
creature:sendTextMessage(MESSAGE_INFO_DESCR, "Battlefield event is full.")
return false
end
Battlefield:onJoin(creature)
return true
end
data\talkactions\scripts\events\btf_start.lua
Lua:
local function warnEvent(i)
Game.broadcastMessage("Battlefield event is about to commence!")
if i > 1 then addEvent(warnEvent, 2 * 60 * 1000, i - 1) end
end
local function openBattlefield()
Battlefield:Open()
end
local function closeBattlefield()
Battlefield:Close()
end
function onSay(cid, words, param, channel)
local player = Player(cid)
if not player then return false end
if not player:getGroup():getAccess() then
return true
end
if player:getAccountType() <= ACCOUNT_TYPE_TUTOR then
return true
end
Game.broadcastMessage("Battlefield event is about to commence!")
createPortal(Battlefield.teleport.pos, 16, Battlefield.teleport.aid)
addEvent(warnEvent, 2 * 60 * 1000, 4)--4
addEvent(removePortal, 10 * 60 * 1000, Battlefield.teleport.pos, 16)
addEvent(openBattlefield, 10 * 60 * 1000)
addEvent(closeBattlefield, 25 * 60 * 1000)
return true
end
data\lib\libs.lua
Lua:
dofile('data/lib/events/libs.lua')
data\lib\events\libs.lua
Lua:
dofile('data/lib/battlefield.lua')
data\lib\events\battlefield.lua
Lua:
if not Battlefield then
Battlefield = {
open = false,
wall = {
id = 1037,
pos = {
Position(2109, 1845, 7),
Position(2110, 1845, 7),
Position(2111, 1845, 7),
Position(2112, 1845, 7)
}
},
rewards = {
-- {itemid, quantity}
{21399, 1},
},
minLevel = 100,
minPlayers = 2, --min players to start event
maxPlayers = 20, --max players in the event
players = {},
exit = Position(2078, 1844, 7), --temple
teleport = {
pos = Position(2097, 1847, 7),
aid = 45000
},
teams = {
[1] = {
name = 'Purple',
outfit = {
lookType = 138,
lookAddons = 0,
lookHead = 109,
lookLegs = 109,
lookBody = 109,
lookFeet = 109,
},
position = Position(2092, 1825, 7),
players = {},
kills = 0,
size = 0,
},
[2] = {
name = 'Green',
outfit = {
lookType = 138,
lookAddons = 0,
lookHead = 82,
lookLegs = 82,
lookBody = 82,
lookFeet = 82,
},
position = Position(2129, 1866, 7),
players = {},
kills = 0,
size = 0,
},
},
addPlayer = function (self, cid)
local player = Player(cid)
if player then
self.players[player:getId()] = 1
end
end,
removePlayer = function (self, cid)
local player = Player(cid)
if self.players[player:getId()] then
self.players[player:getId()] = nil
end
end,
getPlayers = function (self)
return self.players
end,
getPlayer = function (self, cid)
local player = Player(cid)
if self.players[player:getId()] then
return true
else
return false
end
end,
getPlayersCount = function (self)
local c = 0
for _ in pairs(self.players) do c = c + 1 end
return c
end
}
function Battlefield:Open()
if self.open then return false end
self.open = true
if Battlefield:getPlayersCount() < Battlefield.minPlayers then
Battlefield:Close()
return true
end
for i = 1, #Battlefield.wall.pos do
local tile = Tile(Battlefield.wall.pos[i])
if tile then
local item = tile:getItemById(Battlefield.wall.id)
if item then item:remove() end
end
end
return true
end
function Battlefield:Close(winner)
if not self.open then return false end
self.open = false
for i = 1, #Battlefield.wall.pos do
local tile = Tile(Battlefield.wall.pos[i])
if tile then
local item = tile:getItemById(Battlefield.wall.id)
if not item then
Game.createItem(Battlefield.wall.id, 1)
end
end
end
if not winner then
if self.teams[1].kills > self.teams[2].kills then
winner = 1
elseif self.teams[1].kills < self.teams[2].kills then
winner = 2
end
end
if winner then
Game.broadcastMessage(string.format("Team %s win the Battlefield Event!", self.teams[winner].name))
else
Game.broadcastMessage("There was a tie and nobody wins reward.")
end
for _, team in ipairs(self.teams) do
for name, info in pairs(team.players) do
local player = Player(name)
if player then
self:onLeave(player)
if _ == winner then
for k, item in ipairs(self.rewards) do
player:addItem(item[1], item[2])
end
end
end
end
end
self.teams[1].players = {}
self.teams[1].size = 0
self.teams[1].kills = 0
self.teams[2].players = {}
self.teams[2].size = 0
self.teams[2].kills = 0
return true
end
function Battlefield:findPlayer(player)
local name = player:getName()
return self.teams[1].players[name] or self.teams[2].players[name]
end
function Battlefield:onJoin(player)local team
if self.teams[1].size == self.teams[2].size then
team = math.random(1, 2)
elseif self.teams[1].size > self.teams[2].size then
team = 2
else
team = 1
end
player:setOutfit(self.teams[team].outfit)
player:teleportTo(self.teams[team].position)
local info = {name = player:getName(), team = team}
self.teams[team].size = self.teams[team].size + 1
self.teams[team].players[player:getName()] = info
Battlefield:addPlayer(player)
Game.broadcastMessage(string.format("%s entered the BattleField Event!", info.name))
player:registerEvent("BFPrepareDeath")
player:registerEvent("BFHealthChange")
player:registerEvent("BFManaChange")
player:registerEvent("BFLogout")
return true
end
function Battlefield:onLeave(player)
local info = self:findPlayer(player)
if not info then return false end
player:unregisterEvent("BFHealthChange")
player:unregisterEvent("BFPrepareDeath")
player:unregisterEvent("BFManaChange")
player:unregisterEvent("BFLogout")
Game.broadcastMessage(string.format("%s left the BattleField Event!", info.name))
player:teleportTo(self.exit)
self.teams[info.team].size = self.teams[info.team].size - 1
self.teams[info.team].players[info.name] = nil
player:addHealth(player:getMaxHealth())
player:addMana(player:getMaxMana())
player:removeCondition(CONDITION_INFIGHT)
Battlefield:removePlayer(player)
if self.teams[info.team].size == 0 then
self:Close(info.team == 1 and 2 or 1)
end
return true
end
function Battlefield:onDeath(player, killer)
local info = self:findPlayer(player)
if not info then return false end
if killer and killer.getName then
local killerInfo = self:findPlayer(killer)
if killerInfo and killerInfo.team ~= info.team then
local killerTeam = self.teams[killerInfo.team]
killerTeam.kills = killerTeam.kills + 1
end
end
self:onLeave(player)
return true
end
function createPortal(pos, effect, aid)
local tile = Tile(pos)
if tile then
local tp = tile:getItemById(1387)
if tp == nil then
local t = Game.createItem(1387, 1)
t:setAttribute(ITEM_ATTRIBUTE_ACTIONID, aid)
pos:sendMagicEffect(effect)
end
end
end
function removePortal(pos, effect)
local tile = Tile(pos)
if tile then
local tp = tile:getItemById(1387)
if tp then
tp:remove()
end
end
end
end