Ir para conteúdo
  • Cadastre-se

Posts Recomendados

Se o jogador tiver offline e a citywar for iniciada, a citywar vai funcionar apenas com os membros que estavam on quando iniciou o citywar, quem está offline e entrar no game depois que a citywar tiver iniciada, ele vai da use no book normal vai aparecer join  e etc... e ao escolher qualquer opção, buga o citywar inteiro, ninguem pode cancelar nem fazer nada, vários erros ocorre no console.

Até mesmo quando passa o tempo do citywar não cancela, apenas quando servidor reiniciar.

O que fazer pra resolver?
Eu queria deixar apenas os membros que tiver on conseguir abrir o book.. da use, quem testava off não iria conseguir mas está difícil.

Alguem pode ajudar?

 

Spoiler

Lua Script Error: [CreatureScript Interface] 
data/creaturescripts/scripts/modalwindowhelper.lua:onModalWindow
data/lib/citywars.lua:306: attempt to index local 'team' (a nil value)
stack traceback:
    [C]: in function '__index'
    data/lib/citywars.lua:306: in function 'onJoin'
    data/actions/scripts/citywar.lua:161: in function 'callback'
    data/creaturescripts/scripts/modalwindowhelper.lua:26: in function <data/creaturescripts/scripts/modalwindowhelper.lua:1>

 

 

 

Spoiler

CITY_WAR_FIRST      = 0
CITY_WAR_EDRON     = 0
CITY_WAR_YALAHAR  = 1
CITY_WAR_DARASHIA      = 2
CITY_WAR_LIBERTYBAY  = 3
CITY_WAR_LAST       = 3
 
CW_RETURNVALUE_NOERROR = 0
CW_RETURNVALUE_LIVEINVITE = 1
CW_RETURNVALUE_INVITERINWAR = 2
CW_RETURNVALUE_INVITEDINWAR = 3
CW_RETURNVALUE_TOOFEWPLAYERS = 4
CW_RETURNVALUE_TOOFEWUNIQUEIPS = 5
 
local function capitalize(self)
    local tmp = self:lower()
    return tmp:sub(1, 1):upper() .. tmp:sub(2)
end
 
local function reduce(list, predicate)
    local ret = list[1]
    for i = 2, #list do
        ret = predicate(ret, list[i])
    end
    return ret
end
 
local function resumeThread(thread, info, ...)
    local suc, tmp = coroutine.resume(thread, ...)
    if not suc then
        error(tmp)
    end
 
    local wait = tonumber(tmp)
    if wait then
        info.id = addEvent(resumeThread, wait, thread, info)
    end
end
 
local function addThread(func, delay, ...)
    local thread = coroutine.create(func)
    local info = { }
    if delay == 0 then
        resumeThread(thread, info, ...)
    else
        info.id = addEvent(resumeThread, delay, thread, info, ...)
    end
    return info
end
 
if not CityWars then
    CityWars = {
        cityWarDuration = 2 * 60 * 60,
        cityWarStorage = 15600,
        rankingLimit = 10, -- How many players should appear in the ranking message
        minGuildSize = 10, -- How many guild members need to be online
        minDifferentIPs = 10, -- Minimum number of unique ips
        inviteItemId = 1949,
        buyInMultiplier = 50000,
        fragLimitMultiplier = 5,
        teamSizeMultiplier = 10,
 
        minGuildRank = 3, -- Minimum guild rank to start/accept/cancel a city war
        removeConditions = {CONDITION_POISON, CONDITION_FIRE, CONDITION_ENERGY, CONDITION_BLEEDING, CONDITION_PARALYZE, CONDITION_INFIGHT},
        -- [invitedName] = { {city = City, invitedPlayer = Player, invitedGuild = Guild, inviterPlayer = Player, inviterGuild = Guild, options = { }} }
        invites = {},
       
        [CITY_WAR_EDRON] = {
            spawns = {
                -- Team 1 position
                [1] = Position(30974, 32641, 7),
                -- Team 2 position
                [2] = Position(30909, 32519, 7),
            },
 
            name = 'edron',
 
            --  [playerId] = {player = player, name = name, team = 1/2, kills = 0, deaths = 0}
            players = { },
 
            -- [team] = {guild = guild, name = name, kills = 0, deaths = 0}
            teams = { }
        },
 
        [CITY_WAR_DARASHIA] = {
            spawns = {
                -- Team 1 position
                [1] = Position(31217, 32552, 7),
                -- Team 2 position
                [2] = Position(31295, 32639, 7),
            },
 
            name = 'darashia',
 
            --  [playerId] = {player = player, name = name, team = 1/2, kills = 0, deaths = 0}
            players = { },
 
            -- [team] = {guild = guild, name = name, kills = 0, deaths = 0}
            teams = { }
        },
 
        [CITY_WAR_LIBERTYBAY] = {
            spawns = {
                -- Team 1 position
                [1] = Position(30740, 32734, 7),
                -- Team 2 position
                [2] = Position(30767, 32567, 7),
            },
 
            name = 'liberty bay',
 
            --  [playerId] = {player = player, name = name, team = 1/2, kills = 0, deaths = 0}
            players = { },
 
            -- [team] = {guild = guild, name = name, kills = 0, deaths = 0}
            teams = { }
        },
 
        [CITY_WAR_YALAHAR] = {
            spawns = {
                -- Team 1 position
                [1] = Position(30925, 32825, 7),
                -- Team 2 position
                [2] = Position(30982, 32827, 7),
            },
 
 
            name = 'yalahar',
 
            --  [playerId] = {player = player, name = name, team = 1/2, kills = 0, deaths = 0}
            players = { },
 
            -- [team] = {guild = guild, name = name, kills = 0, deaths = 0}
            teams = { },
        },
    }
 
    local City = {}
    City.__index = City
 
    for i = CITY_WAR_FIRST, CITY_WAR_LAST do
        setmetatable(CityWars[i], City)
    end
 
    function City:onStart()
        if not self.endEvent then
            self.endEvent = addThread(
                function(city)
                    for i = 10, 1, -1 do
                        city:countdown(i)
                        coroutine.yield(60 * 1000)
                    end
 
                    local winner      
                    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
 
                    city:onEnd(winner)                
                end,
 
                (CityWars.cityWarDuration - 10 * 60) * 1000,
 
                self
            )
        end
    end
 
    function City:onEnd(winner)
        stopEvent(self.endEvent.id)
 
        for k, v in pairs(self.players) do
            if v.player and v.player:getStorageValue(CityWars.cityWarStorage) > 0 then
                v.player:teleportTo(v.player:getTown():getTemplePosition())
                v.player:addHealth(v.player:getMaxHealth())
                v.player:addMana(v.player:getMaxMana())
                v.player:setStorageValue(CityWars.cityWarStorage, -1)
                v.player:unregisterEvent('CityWarDeath')
                for _, cond in ipairs(CityWars.removeConditions) do
                    v.player:removeCondition(cond, CONDITIONID_DEFAULT)
                end
            end
        end    
 
        self:broadcastMessage(self:getRank())
 
        if not winner then
            self:broadcastMessage('The war has ended, it is a draw!')
 
            local guild1 = Guild(self.teams[1].id)
            local guild2 = Guild(self.teams[2].id)
            if guild1 then
                guild1:setBankBalance(guild1:getBankBalance() + self.options.buyIn)
            end
            if guild2 then
                guild2:setBankBalance(guild2:getBankBalance() + self.options.buyIn)
            end
        else
            self:broadcastMessage('The war has ended, "' .. self.teams[winner].name .. '" have won the war and taken home the prize of ' .. (2 * self.options.buyIn) .. ' gold coins.')
 
            local winnerGuild = Guild(self.teams[winner].id)
            if winnerGuild then
                winnerGuild:setBankBalance(winnerGuild:getBankBalance() + 2 * self.options.buyIn)
            end
        end    
 
        self.players = { }
        self.teams = { }
        self.options = { }
        self.endEvent = nil
    end
 
    function City:onCancel(player)
        if player:getGuildLevel() < CityWars.minGuildRank then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'Only leaders can cancel an ongoing city war.')
            return false
        end
 
        local registry = self.players[player:getGuid()]
        self:broadcastMessage(player:getName() .. ' has forfeited the war.')
 
        self:onEnd((registry.team == 1) and 2 or 1)
    end
 
    function City:onCastSpell(player, kind)
        if player:getStorageValue(CityWars.cityWarStorage) > 0 then
            if kind == 'ultimateExplosion' and not self.options.ultimateExplosion then
                return false
            elseif kind == 'areaSpell' and self.options.suddenDeathOnly then
                return false
            end
        end
        return true
    end
 
    function City:onScoreUpdated()
        local winner
        for i, team in ipairs(self.teams) do
            if team.kills >= self.options.fragLimit then
                winner = i
                break
            end    
        end
 
        self:broadcastScore()
        if winner then    
            self:onEnd(winner)
        end
    end
 
    function City:onJoin(player)
        local registry = self.players[player:getGuid()]
        local team = self.teams[registry.team]
        if team.players < self.options.teamSize then
            if player:getStorageValue(CityWars.cityWarStorage) < 0 then
                team.players = team.players + 1
 
                player:registerEvent('CityWarDeath')
                player:setStorageValue(CityWars.cityWarStorage, 1)
                player:teleportTo(self.spawns[registry.team])
            end
        else
            player:sendTextMessage('Your guild has reached the team limit! You may not join them right now.')
        end
    end
 
    function City:onDeath(player, registry, killer)
        if player:getStorageValue(CityWars.cityWarStorage) > 0 then        
            player:teleportTo(self.spawns[registry.team])
            player:addHealth(player:getMaxHealth())
            player:addMana(player:getMaxMana())
            for _, cond in ipairs(CityWars.removeConditions) do
                player:removeCondition(cond, CONDITIONID_DEFAULT)
            end
 
            registry.deaths = registry.deaths + 1
            local team = self.teams[registry.team]
            team.deaths = team.deaths + 1
 
            local killerRegistry
            if killer then
                if not killer:isPlayer() then
                    killer = killer:getMaster()
 
                    if not killer or not killer:isPlayer() then
                        killer = nil
                    end
                end
 
                if killer then
                    local _
                    _, killerRegistry = CityWars.getPlayerWar(killer)      
                end
            end
 
            if killerRegistry and killerRegistry.team ~= registry.team then
                killerRegistry.kills = killerRegistry.kills + 1
            end        
 
            local enemyTeam = self.teams[(registry.team == 1) and 2 or 1]
            enemyTeam.kills = enemyTeam.kills + 1
 
            self:onScoreUpdated()
            return true
        end
 
        return false
    end
 
    function City:onLeave(player)      
        if player:getStorageValue(CityWars.cityWarStorage) > 0 then        
            player:unregisterEvent('CityWarDeath')
            player:setStorageValue(CityWars.cityWarStorage, -1)
            player:teleportTo(player:getTown():getTemplePosition())
            for _, cond in ipairs(CityWars.removeConditions) do
                player:removeCondition(cond, CONDITIONID_DEFAULT)
            end
 
            local registry = self.players[player:getGuid()]
            registry.player = nil
            -- update team's player count
            local team = self.teams[registry.team]
            team.players = team.players - 1        
        end
    end
    City.onLogout = City.onLeave
 
    function City:getName()
        return capitalize(self.name)
    end
 
    function City:addPlayer(player, team)
        local current = self.players[player:getGuid()]
        if not current then
            current = {player = player, team = team, name = player:getName(), kills = 0, deaths = 0}
        else
            -- update player object
            current.player = player
        end
        self.players[player:getGuid()] = current
    end
 
    function City:countdown(minutesLeft)
        self:broadcastMessage('Countdown: ' .. minutesLeft .. ' minutes until the war ends.')
    end
 
    function City:broadcastMessage(msg)
        for k, v in pairs(self.players) do
            if v.player then
                v.player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, msg)
            end
        end
    end
 
    local broadcastFormat = 'Score: "%s" (%d) versus "%s" (%d)'
    function City:broadcastScore()
        self:broadcastMessage(broadcastFormat:format(self.teams[1].name, self.teams[1].kills, self.teams[2].name, self.teams[2].kills))
    end
 
    function City:getRank()
        local rank = {}
        for k, v in pairs(self.players) do
            table.insert(rank, {name = v.name, kills = v.kills, deaths = v.deaths, guildName = self.teams[v.team].name})
        end
        table.sort(rank,
            function(a, b)
                if a.kills ~= b.kills then
                    return a.kills > b.kills
                end
                return a.deaths < b.deaths
            end        
        )
        local msg = 'Ranking:'
        for i = 1, CityWars.rankingLimit do
            local player = rank[i]
            if player then            
                msg = msg .. '\n' .. i .. '. ' .. player.name .. ' - ' .. player.kills .. '/' .. player.deaths .. ' From: "' .. player.guildName .. '"'
            end
        end
        return msg
    end
 
    local winFormat = '"%s" has beaten "%s" by %d to %d kills.'
    local drawFormat = 'The city war between "%s" and "%s" resulted in a draw.'
    function City:broadcastResult()
        local msg
        if self.teams[1].kills > self.teams[2].kills then
            msg = winFormat:format(self.teams[1].name, self.teams[2].name, self.teams[1].kills, self.teams[2].kills)
        elseif self.teams[1].kills < self.teams[2].kills then
            msg = winFormat:format(self.teams[2].name, self.teams[1].name, self.teams[2].kills, self.teams[1].kills)
        else
            msg = drawFormat:format(self.teams[1].name, self.teams[2].name)
        end
 
        self:broadcastMessage(msg)
    end
 
    function City:isFree()
        return #self.teams == 0
    end
end
 
function CityWars.getCityByName(name)
    for i = CITY_WAR_FIRST, CITY_WAR_LAST do
        local city = CityWars[i]
        if city.name == name then
            return city
        end
    end
 
    return nil
end
 
function CityWars.getPlayerWar(player, registerPlayer)
    local playerGuild = player:getGuild()
    if not playerGuild then
        return nil
    end
    for i = CITY_WAR_FIRST, CITY_WAR_LAST do
        local city = CityWars[i]
        if not city:isFree() then
            for k, team in ipairs(city.teams) do
               
                if team.id == playerGuild:getId() then
                    local guid = player:getGuid()
                    local registry = city.players[guid]
                    if registerPlayer and (not registry or registry.team ~= k) then
                        registry = {player = player, name = player:getName(), team = k, kills = 0, deaths = 0}
                        city.players[guid] = registry
                    end
                    return city, registry
                end
            end
        end
    end
end
 
function CityWars.isValidGuild(guild)
    local onlineMembers = guild:getMembersOnline()
    if #onlineMembers < CityWars.minGuildSize then
        return CW_RETURNVALUE_TOOFEWPLAYERS
    end
 
    local uniqueIPs = 0
    local addressMap = {}
    for k, v in ipairs(onlineMembers) do
        local ip = v:getIp()
        if ip ~= 0 and not addressMap[ip] then
            addressMap[ip] = true
            uniqueIPs = uniqueIPs + 1
        end
    end
    if uniqueIPs < CityWars.minDifferentIPs then
        return CW_RETURNVALUE_TOOFEWUNIQUEIPS
    end
 
    return CW_RETURNVALUE_NOERROR
end
 
function CityWars.getGuildWar(guild)
    for i = CITY_WAR_FIRST, CITY_WAR_LAST do
        local city = CityWars[i]
        if not city:isFree() then
            for k, team in ipairs(city.teams) do
                if team.id == guild:getId() then
                    return city
                end
            end
        end
    end
end
 
function CityWars.getInvites(guildName)
    return CityWars.invites[guildName]
end
 
function CityWars.onInviteExpired(invite)
    for k, _invite in ipairs(invite.invites) do
        if _invite == invite then
            local player = Player(invite.inviterPlayerName)
            if player then
                local guild = Guild(invite.invitedGuildId)
                local guildName = guild and guild:getName() or 'deleted guild'
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'Your city war invite for guild "' .. guildName .. '" has expired.')
            end
 
            if invite.invitedLeaders then
                local guild = Guild(invite.inviterGuildId)
                local guildName = guild and guild:getName() or 'deleted guild'
                for _, leaderName in ipairs(invite.invitedLeaders) do
                    local leader = Player(leaderName)
                    if leader then
                        leader:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'You failed to answer the city war invite from guild "' .. guildName .. '" and it is now expired.')
                    end
                end
            end
 
            table.remove(invite.invites, k)
            return
        end
    end
end
 
local optionsFormat = 'City: %s | Buy in: %d gold %s | Frag limit: %d | U.E: %s | S.D only: %s | Team size: %d'
function CityWars.getOptionsString(options)
    return optionsFormat:format(options.city:getName(), options.buyIn, (options.buyIn == 1) and 'coin' or 'coins', options.fragLimit, options.ultimateExplosion and 'enabled' or 'disabled', options.suddenDeathOnly and 'true' or 'false', options.teamSize)
end
 
function CityWars.onInviteAccepted(player, invite)
    for k, _invite in ipairs(invite.invites) do
        if _invite == invite then
            stopEvent(invite.expireEvent)
            table.remove(invite.invites, k)
 
            if not invite.city:isFree() then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, invite.city:getName() .. ' is not free anymore.')
                return false
            end        
 
            local inviterGuild = Guild(invite.inviterGuildId)
            if not inviterGuild then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'Inviter guild does not exist anymore.')              
                return false
            elseif CityWars.getGuildWar(inviterGuild) then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'The inviter guild is already in war.')
            end
 
            local invitedGuild = Guild(invite.invitedGuildId)
            if not invitedGuild then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'You do not belong to a guild.')              
                return false
            elseif CityWars.getGuildWar(invitedGuild) then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'You can not accept a war invite while in another one.')
                return false
            end
 
            local msg
            local start = false
            if inviterGuild:getBankBalance() < invite.options.buyIn then
                msg = 'The guild "' .. inviterGuild:getName() .. '" can not participate in this war due to lack of funds in its guild bank.'
            elseif invitedGuild:getBankBalance() < invite.options.buyIn then
                msg = 'The guild "' .. invitedGuild:getName() .. '" can not participate in this war due to lack of funds in its guild bank.'
            else
                inviterGuild:setBankBalance(inviterGuild:getBankBalance() - invite.options.buyIn)
                invitedGuild:setBankBalance(invitedGuild:getBankBalance() - invite.options.buyIn)
                start = true
                msg = 'A city war between the guilds "' .. inviterGuild:getName() .. '" and "' .. invitedGuild:getName() .. '" has begun!\n' ..
                    CityWars.getOptionsString(invite.options) .. '\n' ..
                    'If you wish to join, head to a temple and read the guild book.'
            end
 
            for _, player in ipairs(inviterGuild:getMembersOnline()) do
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, msg)
                if start then
                    invite.city:addPlayer(player, 1)
                end
            end
 
            for _, player in ipairs(invitedGuild:getMembersOnline()) do
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, msg)
                if start then
                    invite.city:addPlayer(player, 2)
                end
            end
 
            if start then
                invite.city.teams = {
                    {id = invite.inviterGuildId, name = inviterGuild:getName(), kills = 0, deaths = 0, players = 0},
                    {id = invite.invitedGuildId, name = invitedGuild:getName(), kills = 0, deaths = 0, players = 0}
                }
                invite.city.options = invite.options
                invite.city:onStart()
            end
 
            return true
        end
    end
    return false
end
 
function CityWars.onInvite(city, inviter, invitedGuild, invitedLeaders, options)
    if CityWars.getGuildWar(inviter:getGuild()) then
        return CW_RETURNVALUE_INVITERINWAR
    end
 
    if CityWars.getGuildWar(invitedGuild) then
        return CW_RETURNVALUE_INVITEDINWAR
    end
 
    local invites = CityWars.invites[invitedGuild:getName()]
    if invites and #invites ~= 0 then
        for _, invite in ipairs(invites) do
            local guild = Guild(invite.inviterGuildId)
            if guild and guild:getId() == inviter:getGuild():getId() then
                return CW_RETURNVALUE_LIVEINVITE
            end
        end
    elseif not invites then
        invites = { }
        CityWars.invites[invitedGuild:getName()] = invites
    end
 
    local invitedLeadersNames = {}
    for k, v in ipairs(invitedLeaders) do
        table.insert(invitedLeadersNames, v:getName())
    end
 
    local invite = {
        city = city,
        invites = invites,
        inviterPlayerName = inviter:getName(),
        inviterGuildId = inviter:getGuild():getId(),
        invitedGuildId = invitedGuild:getId(),
        invitedLeaders = invitedLeadersNames,
        options = options
    }
    invite.expireEvent = addEvent(CityWars.onInviteExpired, 15 * 1000, invite)
    table.insert(invites, invite)
 
    return CW_RETURNVALUE_NOERROR
end

 

 

Editado por GustavaoTibia (veja o histórico de edições)
Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por LeoTK
      Salve galera neste tópico irei postar algumas prints do mapa do servidor para quem queira acompanhar e quem sabe até utilizar de inspiração para mapear o seu NTO.
       
      #Att 11/08/2022

       
       
       
       
      Konoha (Em Desenvolvimento)
       
       
       
       
    • Por DiigooMix
      Como o título já diz, será que alguém possui sprite do hitto e se possível as transformações dele?
    • Por OmegaZero
      Olá gostaria que alguém me ajudasse com uma "scripting" não sei se é pela mesma, seria o seguinte uma determinada arma teria a chance de dar double hit e não sei oque fazer alguem poderia ajudar?

      OBS:não sei se é o local correto se não for mova, desculpe
    • Por Madarasenju
      Olá galera do Tibia King, queria por uns npc's no meu server que não tem função de trade nem nada do tipo, queria que eles só andassem como enfeite, Rep+ Pra quem me ajudar... grato desde já.
    • Por SilenceRoot
      A magia é assim o você usa a a magia e ela ficará ativado por 10 segundos, até que o inimigo lance a primeira magia ou todos de uma vez, quando ele lançar a primeira magia, ele não lhe acertará ou seja esquivando dela, e logo em seguida será teletransportado aleatoriamente ao redor do inimigo que usou.
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo