Ir para conteúdo

Featured Replies

Postado

@MaTTch

Erro agora fica na LIB

LIB:

 

Spoiler

 


Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/modalwindowhelper.lua:onModalWindow
data/lib/citywars.lua:553: attempt to call method 'getBankBalance' (a nil value)
stack traceback:
    [C]: in function 'getBankBalance'
    data/lib/citywars.lua:553: in function 'onInviteAccepted'
    data/actions/scripts/citywar.lua:146: in function 'callback'
    data/creaturescripts/scripts/modalwindowhelper.lua:26: in function <data/creaturescripts/scripts/modalwindowhelper.lua:1

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 = 1, -- How many players should appear in the ranking message
        minGuildSize = 1, -- How many guild members need to be online
        minDifferentIPs = 1, -- Minimum number of unique ips
        inviteItemId = 1949,
        buyInMultiplier = 50000,
        fragLimitMultiplier = 1,
        teamSizeMultiplier = 1,
 
        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(518, 50, 7),
                -- Team 2 position
                [2] = Position(581, 118, 6),
            },
 
            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)

  • Respostas 8
  • Visualizações 653
  • Created
  • Última resposta

Top Posters In This Topic

Postado

Pelo erro ta dando que getBankBalance está retornando nil, como se não existisse, bem nessa parte:

if guild:getBankBalance() < options.buyIn then
	return player:sendCancelMessage('Your guild does not have enough funds in the bank to pay the buy in.')
end

 

Infelizmente eu perdi o interesse em servidores após a versão 0.4 do TFS, por isso esses scripts são zonas fora de meu conhecimento com esses metamethods. É melhor esperar outra pessoa aparecer pra ajudar vocês.

Postado

esse é o guild bank balance, a solução que encontrei foi botar dinheiro pra todas as guild bank, não tem como eles tirar o dinheiro de la, pela database da guild.

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

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.6k

Informação Importante

Confirmação de Termo