• 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!

TFS 1.X+ team battel event work100% need to convert to revscript

abdala ragab

Veteran OT User
Joined
Aug 18, 2018
Messages
521
Solutions
14
Reaction score
388
Location
gamelaot.sytes.net
Hi, as stated in the title, I want to convert this event to revscript. If anyone can do that, I would be grateful.
creaturescripts

XML:
     <!-- Battlefield Event -->
    <event type="healthchange" name="BattlefieldEventHealthChange" script="BattlefieldEventHealthChange.lua"/>
    <event type="manachange" name="BattlefieldEventManaChange" script="BattlefieldEventManaChange.lua"/>
BattlefieldEventHealthChange
Lua:
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local damage = primaryDamage + secondaryDamage
    local check = battleFieldEvent:canDealDamage(creature, attacker, damage, primaryType)
    if (check) then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    else
        return 0, COMBAT_NONE, 0, COMBAT_NONE
    end
end

function onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
print(1)
    local damage = primaryDamage + secondaryDamage
    local check = battleFieldEvent:canDealDamage(creature, attacker, damage)
    if (check) then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    else
        return 0, COMBAT_NONE, 0, COMBAT_NONE
    end
end
BattlefieldEventManaChange
Lua:
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    --player from same team can't deal damage to team-mates
    --player from different team can't heal to oposite team
        --summons must respect that

    --kill player quit from event
    --there is not attacker? Check damage to kick member if required

    local myHealth = creature:getHealth()

    if (not attacker) then
        --kill player
    --    totalDamage = primaryDamage + secondaryDamage

    --    if (totalDamage >= myHealth) then
            
    --        battleFieldEvent:removeMember(creature, true)
            return 0, primaryType, 0, secondaryType
    --    end     
    --    return primaryDamage, primaryType, secondaryDamage, secondaryType
    end


    local sameTeam = false
    local myTeam = battleFieldEvent:getTeam(creature)
    local totalDamage = 0


    if (attacker:isMonster()) then
        local monster = attacker
        local team = battleFieldEvent:getOwnerTeam(monster)
        if (not team) then
            return primaryDamage, primaryType, secondaryDamage, secondaryType
        end
        attacker = attacker:getMaster()

        if (team == myTeam) then
            sameTeam = true
        end

    else
        local team = battleFieldEvent:getTeam(attacker)
        if (team == myTeam) then
            sameTeam = true
        end
    end

    if (sameTeam) then
        if (primaryType ~= COMBAT_HEALING or secondaryType ~= COMBAT_HEALING) then
            return 0, primaryType, 0, secondaryType
        end
    else
        if (primaryType == COMBAT_HEALING or secondaryType == COMBAT_HEALING) then
            return 0, primaryType, 0, secondaryType
        end

        --kill player
        totalDamage = primaryDamage + secondaryDamage
        totalDamage = math.abs(totalDamage)
        if (totalDamage >= myHealth) then
            
            battleFieldEvent:removeMember(creature, attacker)
            return 0, primaryType, 0, secondaryType
        end

    end
    
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

function onManaChange(creature, attacker, manaChange, origin)
    if (not attacker) then return manaChange end
    local myHealth = creature:getHealth()

    local sameTeam = false
    local myTeam = battleFieldEvent:getTeam(creature)
    local myHealth = creature:getMana() + creature:getHealth()


    if (attacker:isMonster()) then
        local monster = attacker
        local team = battleFieldEvent:getOwnerTeam(monster)
        if (not team) then
            return manaChange
        end

        if (team == myTeam) then
            sameTeam = true
        end

    else
        local team = battleFieldEvent:getTeam(attacker)
        if (team == myTeam) then
            sameTeam = true
        end
    end

    if (sameTeam) then
        return 0
    end
    

    return manaChange
end
globalevents
XML:
 <globalevent name="battlefield" time="01:08:00" script="battlefield.lua" />
Lua:
    local minutesToStart = 5
    function onTime(interval)
        announcebattleFieldEvent(minutesToStart, 0)
        return true
    end
data/battleFieldEvent
Lua:
BFE_Storage = 35000

battleFieldEvent =
{
    goal = 25,--goal to reach (kills)
    teamNames =
    {
        [1] = "BlueTeam",
        [2] = "RedTeam",

    },

    eventNames =
    {
        "BattlefieldEventHealthChange",
        "BattlefieldEventManaChange"
    }, --used for healthchange events

    name = "[Battlefield Event]",
    command = "!joinbf",
    storages =
    {
        players =
        {
            status = BFE_Storage,
            team = BFE_Storage + 1
        },

        globals =
        {
            status = BFE_Storage + 2,
            teamScore =
            {
                BFE_Storage + 3,
                BFE_Storage + 4,
            }
        }
    },

    status =
    {
        ["STATUS_INACTIVE"] = 0,
        ["STATUS_WAITING"] = 1,
        ["STATUS_ACTIVE"] = 2
    },

    config =
    {
        prize =
        {
            itemId = 2638,
            count = 50
        },
        outfits =
        {
            genders = {269, 268},
            colors = {88, 94}
        },
        minPlayers = 2,
        minLevel = 400,
        times =
        {
            ["start"] = 0.3,
            ["close"] = 2,
        },

        positions =
        {
            ["waitArea"] = {x = 2828, y = 3063, z = 6}, --wait position

            battleArea =
            {
                --positions where teams will be teleported
                {x = 1349, y = 2677, z = 9}, --first team               
                {x = 1333, y = 2661, z = 7} --second team
            },

            teleportPosition = {x = 2998, y = 3117, z = 7} --position where teleport will be created
        },

        messages =
        {
            players =
            {
                ["enterWaitArea"] = "You have entered to wait area",
                ["eventStarted"] = "Event has started, you are in %s team!",
                ["killed"] = "You have been killed!",
            },

            global =
            {
                ["waitMessage"] = "Event will start in %d minutes, go to teleport in events room to join",
                ["startedMessage"] = "Event has started.",
                ["finishedMessage"] = "Event has finished.",
                ["killedPlayerMessage"] = "%s has killed %s from %s team!"
            }
        }
    }
}

-- Creates the teleport to the waiting room
function battleFieldEvent:createTeleport()
    local tp = Game.createItem(1387, 1, self.config.positions.teleportPosition)
    tp:setActionId(16282)

    return true
end
 
 
-- Removes the teleport to the waiting room
function battleFieldEvent:removeTeleport()
 
    local tile = Tile(self.config.positions.teleportPosition)
    local findTp = tile:getItemById(1387)
    if (findTp) then
        findTp:remove()
        return true
    end
end


function battleFieldEvent:sendScore(teamId)
    --[[
        score teams
    ]]--


    local msg = string.format("%s %s (%d kills) | %s (%d kills)", self.name, self.teamNames[1], self:getTeamScore(1), self.teamNames[2], self:getTeamScore(2))
    local receivers = self:getMembers(self.status.STATUS_ACTIVE)
    
    if (teamId > 0 and teamId <= 2) then
        receivers = self:getTeamMembers(receivers, teamId)
    end

    self:sendMessageToPlayerList(receivers, msg)

end

function battleFieldEvent:getTeamScore(teamId)
    local value = Game.getStorageValue(self.storages.globals.teamScore[teamId])
    return value and math.max(value, 0) or 0
end

function battleFieldEvent:setTeamScore(teamId, score)
    Game.setStorageValue(self.storages.globals.teamScore[teamId], score)
end

function battleFieldEvent:addTeamScore(teamId, score)
    local actualScore = self:getTeamScore(teamId)
    actualScore = actualScore + score

    self:setTeamScore(teamId, actualScore)

    --print(string.format("Team %d has %d score", teamId, actualScore))
end

function battleFieldEvent:givePrize(players)
    local prize = self.config.prize
    if (#players > 1) then
        --.itemId.count
        local player
        for i = 1, #players do
            player = players[i]
            if (player) then
                player:addItem(prize.itemId, prize.count)
            end
        end
    else
        players[1]:addItem(prize.itemId, prize.count)
    end

end

function battleFieldEvent:setOutfit(player, teamId)
    if (player) then
        local gender = player:getSex()
        local outfit = player:getOutfit()
        local color = self.config.outfits.colors[teamId]

        outfit.lookHead = color
        outfit.lookBody = color
        outfit.lookLegs = color
        outfit.lookFeet = color
        outfit.lookType = self.config.outfits.genders[gender + 1]

        local condition = Condition(CONDITION_OUTFIT)
        condition:setTicks(-1)
        condition:setOutfit(outfit)
        
        player:addCondition(condition)

        --player:setOutfit(outfit)
    end
    -- body
end

function battleFieldEvent:setStatus(status)
    Game.setStorageValue(self.storages.globals.status, status)
end

function battleFieldEvent:getStatus()
    local value = Game.getStorageValue(self.storages.globals.status)
    return value and math.max(value, 0) or 0
end

function announcebattleFieldEvent(times, done)
    if (done == 0) then
        battleFieldEvent:createTeleport()
    end
    if (battleFieldEvent:getStatus() > battleFieldEvent.status.STATUS_WAITING) then
        return true
    end

    if (battleFieldEvent:getStatus() ~= battleFieldEvent.status.STATUS_WAITING) then
        battleFieldEvent:setStatus(battleFieldEvent.status.STATUS_WAITING)
    end

    if (times == done) then
        battleFieldEvent:startEvent()
        battleFieldEvent:removeTeleport()
        return true
    end

    local msg = string.format(battleFieldEvent.config.messages.global.waitMessage, times - done, battleFieldEvent.command)
    msg = battleFieldEvent.name.." "..msg
    Game.broadcastMessage(msg)
    addEvent(announcebattleFieldEvent, 1 * 60 * 1000, times, done + 1)   
end

function battleFieldEvent:tryToBalance()
   local members = self:getMembers(self.status.STATUS_WAITING)

   if (#members >= 3) then
      local player = members[#members]
      if (player) then
          self:removeMember(player, false)
          return true
      end
   end

   return false
end

function battleFieldEvent:assignTeams()
    local members = self:getMembers(self.status.STATUS_WAITING)

    local cupos = #members / 2
    local first = {}
    local second = {}

    local val
    
    for i = 1, #members do
       val = math.random(2)
       if (val == 1 ) then
          if (#first == cupos) then
             second[#second + 1] = members[i]
          else
             first[#first + 1] = members[i]
          end
       else
          if (#second == cupos) then
             first[#first + 1] = members[i]
          else
             second[#second + 1] = members[i]
          end
       end
    end

    for i = 1, #first do
        self:addMember(first[i], 1)
    end

    for i = 1, #second do
        self:addMember(second[i], 2)
    end

end

function battleFieldEvent:checkBalance()
    local members = self:getMembers(self.status.STATUS_WAITING)
    if (#members % 2 == 0) then
       return true
    else
        return false
    end
end

function battleFieldEvent:kickMembers(status)
    local members = self:getMembers(status)
    if (#members > 0) then
        local player
        for i = 1, #members do
            player = members[i]
            self:kickMember(player)
        end
    end
end

function battleFieldEvent:kickMember(player)
    if (player) then
        self:setMemberStatus(player, self.status.STATUS_INACTIVE)
        player:unregisterEvent(self.eventNames[1])
        player:unregisterEvent(self.eventNames[2])
        
        player:setSkull(SKULL_NONE)
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())

        player:removeCondition(CONDITION_OUTFIT)

        local town = player:getTown()
        if (town) then
            player:teleportTo(town:getTemplePosition())
        end
    end
    -- body
end

function battleFieldEvent:close(winnerTeam)

    self:setStatus(self.status.STATUS_INACTIVE)
    local message

    if (winnerTeam) then
        local allMembers = self:getMembers(self.status.STATUS_ACTIVE)
        local winnerMembers = self:getTeamMembers(allMembers, winnerTeam)
        local teamName = winnerTeam == 1 and "BlueTeam" or "RedTeam"
        message = string.format("%s Event finished, %s won.", self.name, teamName)
        --give prize to them
        self:givePrize(winnerMembers)
    else
        message = self.name.." Event finished, anyone won."
    end

    --kick players
    self:kickMembers(self.status.STATUS_ACTIVE)
    Game.broadcastMessage(message)

    --reset scores
    self:setTeamScore(1, 0)
    self:setTeamScore(2, 0)
end

function battleFieldEvent:kickWinner(player)
    if (player) then
         self:setMemberStatus(cid, self.status.STATUS_INACTIVE)
        self:kickMember(player)
        --give prize

    end
end

function battleFieldEvent:startEvent()
    
    if (not self:checkBalance()) then
        self:tryToBalance()
    end

    if (not self:checkBalance()) then
        local msg = string.format("%s Could not start event. Could not balance players.", self.name)
        Game.broadcastMessage(msg)
        battleFieldEvent:kickMembers(self.status.STATUS_WAITING)
        -- TODO kick all players
        return true       
    end

    if (#self:getMembers(self.status.STATUS_WAITING) < self.config.minPlayers) then
        Game.broadcastMessage(string.format("%s Not enough members to start event.", self.name))
        battleFieldEvent:kickMembers(self.status.STATUS_WAITING)   
        battleFieldEvent:setStatus(self.status.STATUS_INACTIVE)
        return true
    end
    --assignTeams   
    self:assignTeams()

    --check if number waiting players are balanced
        --if not then remove (if can)
    battleFieldEvent:setStatus(self.status.STATUS_ACTIVE)

end

function battleFieldEvent:closeEvent()
    battleFieldEvent:setStatus(status)
end

function battleFieldEvent:setTeam(player, team)
    player:setStorageValue(self.storages.players.team, team)
end

function battleFieldEvent:getTeam(player)
    if (player) then
        local team = player:getStorageValue(self.storages.players.team)
        return team and math.max(team, 0) or 0
    end
end

function battleFieldEvent:setMemberStatus(player, status)
    player:setStorageValue(self.storages.players.status, status)
end

function battleFieldEvent:getMemberStatus(player)
    if (player) then
        local status = player:getStorageValue(self.storages.players.status)
        return status and math.max(status, 0) or 0
    end
end

function battleFieldEvent:getMembers(type)
    local players = {}
    local onlinePlayers = Game.getPlayers()
    
    local player

    for i = 1, #onlinePlayers do
        player = onlinePlayers[i]
        if (player) then
            if (self:getMemberStatus(player) == type) then
                players[#players + 1] = player
            end
        end
    end

    return players
end

function battleFieldEvent:getTeamMembers(members, team)
    local teamMembers = {}

    if (#members > 0) then
        local player
        if (#members > 1) then
            for i = 1, #members do
                player = members[i]
                if (player) then
                    if (self:getTeam(player) == team) then
                        teamMembers[#teamMembers + 1] = player
                    end
                end
            end
        else
            player = members[1]
            if (player) then
                if (self:getTeam(player) == team) then
                    teamMembers[#teamMembers + 1] = player
                end
            end
        end
    end

    return teamMembers
end

function battleFieldEvent:addMemberToWait(player)
    if (player) then
        self:setMemberStatus(player, self.status.STATUS_WAITING)
        player:teleportTo(self.config.positions.waitArea)
    end
end

function battleFieldEvent:isWaiting(player)
    if (player) then
        local status = self:setMemberStatus(player)
        return status and status == self.status.STATUS_WAITING
    end
end

function battleFieldEvent:addMember(player, teamId)
    if (player) then
        self:setOutfit(player, teamId)
        self:setMemberStatus(player, self.status.STATUS_ACTIVE)
        player:teleportTo(self.config.positions.battleArea[teamId])
        self:setTeam(player, teamId)
        local msg = string.format(self.config.messages.players.eventStarted, teamId == 1 and "first" or "second")
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, msg)
        player:registerEvent(self.eventNames[1])
        player:registerEvent(self.eventNames[2])

    end
end

function battleFieldEvent:respawnMember(player, teamId)
    if (player) then

        player:teleportTo(self.config.positions.battleArea[teamId])
        player:addHealth(player:getMaxHealth())
        player:addMana(player:getMaxMana())
    end
    --[[
        tp to enter area
        give full mana
        give full health
    ]]--
end

function battleFieldEvent:killMember(player, killer)
    local teamId = self:getTeam(player)
    local enemyTeamId = teamId == 1 and 2 or 1
    local enemyScore = self:getTeamScore(enemyTeamId)
    local myScore = self:getTeamScore(teamId)


    enemyScore = enemyScore + 1

    self:addTeamScore(enemyTeamId, 1)
    self:sendScore(3) --1 is for first

    if (enemyScore == self.goal) then
        self:close(enemyTeamId)
    end

    if (self:getStatus() == battleFieldEvent.status.STATUS_ACTIVE) then
        self:respawnMember(player, teamId)
    end     
end

function battleFieldEvent:removeMember(player, killer)
    self:setMemberStatus(player, self.status.STATUS_INACTIVE)
    player:unregisterEvent(self.eventNames[1])
    player:unregisterEvent(self.eventNames[2])

    if (killer) then
        --check num players --to close
        local players = self:getMembers(self.status.STATUS_ACTIVE)
        
        local RedTeam = self:getTeamMembers(players, 1)
        local BlueTeam = self:getTeamMembers(players, 2)

        local needToClose = false

        if (#firstTeam == 0 or #secondTeam == 0) then
            needToClose = true
        end

        if (needToClose) then
            if (#firstTeam <= 0 and #secondTeam <= 0) then
                --anyone won
                self:close()
            elseif(#firstTeam <= 0) then
                self:close(2)
            elseif(#secondTeam <= 0) then
                self:close(1)
            end
        end

        local msg = string.format(self.config.messages.global.killedPlayerMessage, self.name, killer:getName(), player:getName())
        self:sendMessageToPlayers(self.status.STATUS_ACTIVE, msg)

        player:sendTextMessage(MESSAGE_STATUS_SMALL, self.name.." You have been killed.")
    end

    local town = player:getTown()
    if (town) then
        player:teleportTo(town:getTemplePosition())
    end

end

function battleFieldEvent:sendMessageToPlayerList(players, message)
    if (#players > 0) then
        local player
        for i = 1, #players do
            player = players[i]
            if (player) then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, message)       
            end
        end
    end
end

function battleFieldEvent:sendMessageToPlayers(typePlayers, message)
    local players = self:getMembers(typePlayers)
    if (#players > 0) then
        local player
        for i = 1, #players do
            player = players[i]
            if (player) then
                player:sendTextMessage(MESSAGE_STATUS_DEFAULT, message)       
            end
        end
    end
end


---summons related
function battleFieldEvent:getOwnerTeam(monster)
    if (monster) then
        if (monster:getMaster()) then
            local player = monster:getMaster()
            return self:getTeam(player)
        end
    end
end

function battleFieldEvent:canDealDamage(creature, attacker, damage, primaryType)
    if (not attacker) then
        return false
    end   

    if (not attacker:isPlayer()) then
        if (attacker:getMaster() and attacker:getMaster():isPlayer()) then
            attacker = creature:getMaster()
        end
    end

    local checkSame = false
    if (creature ~= attacker) then
        local myTeam = battleFieldEvent:getTeam(creature)
        local enemyTeam = battleFieldEvent:getTeam(attacker)

        if (myTeam == enemyTeam) then
            checkSame = true
        else
            local myHealth = creature:getHealth()
            local totalDamage = math.abs(damage)
            if (totalDamage >= myHealth) then
                battleFieldEvent:killMember(creature, attacker)
                return false
            end
        end

    else
        checkSame = true
    end

    if (checkSame) then
        if (primaryType) then
            if (primaryType ~= COMBAT_HEALING) then
                return false
            end
        else
            return false
        end
    end

    return true
end
global.lua
Lua:
dofile('data/battleFieldEvent.lua')
movements
XML:
<movevent event="StepIn" actionid="16282" script="battleFieldJoin.lua" />
Lua:
function onStepIn(creature, item, position, fromPosition)
    if (creature:isPlayer()) then
        local player = creature
        local tpBack = false

        if (battleFieldEvent:getStatus() == battleFieldEvent.status.STATUS_WAITING) then
            if (battleFieldEvent:getMemberStatus(player) == battleFieldEvent.status.STATUS_INACTIVE) then
                if (player:getLevel() < battleFieldEvent.config.minLevel) then
                    msg = battleFieldEvent.name.." Sorry, you don't have enough level to enter to event"
                    tpBack = true
                else
                    msg = battleFieldEvent.name.." You have entered to wait area"
                    battleFieldEvent:addMemberToWait(player)
                end
            end
        else
            msg = "Event is not available yet."
            tpBack = true
        end

        if (msg ~= "") then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, msg)
        end
        if (tpBack) then
            player:teleportTo(fromPosition)
        end
    end

    return true
end
That's it
Thank you in advance whoever helps
 
Back
Top