How to detect if a specific Civ is at war?

Raitaki

Chieftain
Joined
Oct 19, 2015
Messages
25
I would like to implement an UA that provides bonuses while the Civ that has it is at war--ergo, an UA that places dummy buildings in that player's cities when a war starts involving them, then removes all those dummy buildings once the war ends. Is there an existing LUA function (either from the game itself or from CBP) that I can use to check if a player is at war? It's sufficient to just know if the player is at war or not, it's not important for me to check who or how many players they are at war with..

In addition, if the above is possible, then is it possible to further check if the player in question had someone else declare war on them, or if they were the one who started the war?
 
http://modiki.civfanatics.com/index.php?title=Team.GetAtWarCount_(Civ5_API)

Seems to do what you want.

Haven't run it, but something like this...

Code:
function OnPlayerDoTurn(iPlayer)
    local pPlayer = Players[iPlayer]
    local pTeam = Teams[pPlayer:GetTeam()]
    if pTeam:getAtWarCount(true) > 0 then -- true if you want wars with minor Civs to be ignored, otherwise false
        -- do something
    end
end
GameEvents.PlayerDoTurn.Add(OnPlayerDoTurn)

...should do the job if it works like I think it does.

Don't know about that other question.
 
Last edited:
I would like to implement an UA that provides bonuses while the Civ that has it is at war--ergo, an UA that places dummy buildings in that player's cities when a war starts involving them, then removes all those dummy buildings once the war ends. Is there an existing LUA function (either from the game itself or from CBP) that I can use to check if a player is at war? It's sufficient to just know if the player is at war or not, it's not important for me to check who or how many players they are at war with..

In addition, if the above is possible, then is it possible to further check if the player in question had someone else declare war on them, or if they were the one who started the war?

This should tell you if the Player is at war with anyone:

Code:
function C15_IsPlayerAtWarWithAnyone(playerID, bIncludeMinors)
    local pPlayer = Players[playerID]
    local iTeam = pPlayer:GetTeam()
    local pTeam = Teams[iTeam]
    local bIsAtWar = false
    for i = 0, GameDefines.MAX_CIV_PLAYERS - 1 do -- Iterate through everyone
        if i ~= playerID then -- If this isn't the Player, since you can't be at war with yourself...
            local pOtherPlayer = Players[i]
            if pOtherPlayer:IsAlive() then -- Can't be at war with the dead :p
                if not pOtherPlayer:IsBarbarian() then -- You're always at war with Barbs so ignore them
                    if (bIncludeMinors) or ((not bIncludeMinors) and (not pOtherPlayer:IsMinorCiv())) then -- If you've said to include City-States, then everyone will qualify; if you've said to not include them, then make sure pOtherPlayer isn't a City-State
                        local iOtherTeam = pOtherPlayer:GetTeam()
                        if pTeam:IsAtWar(iOtherTeam) then -- The crucial Method
                            bIsAtWar = true
                            break -- We've found someone we're at war with, so we don't need to check for any longer
                        end
                    end
                end
            end
        end
    end
    return bIsAtWar -- Returns either true or false to wherever you called the function
end

An example:

Code:
local bYesIWantToIncludeCityStates = false
local civilizationID = GameInfoTypes["CIVILIZATION_"]

function Whatever(playerID)
    local pPlayer = Players[playerID]
    if pPlayer:IsAlive() and pPlayer:GetCivilizationType() == civilizationID then
        if C15_IsPlayerAtWarWithAnyone(playerID, bYesIWantToIncludeCityStates) then
            print("Add buildings")
        else
            print("Remove buildings")
        end
    end
end

GameEvents.PlayerDoTurn.Add(Whatever)

As for a GameEvent for War Declaration:

Code:
local civilizationID = GameInfoTypes["CIVILIZATION_"]

function OnDeclareWar(iAttackingTeam, iDefendingTeam)
    for i = 0, GameDefines.MAX_MAJOR_CIVS - 1 do -- Only need to iterate through Majors this time, since you won't be playing as a City-State
        local pPlayer = Players[i]
        if pPlayer:GetCivilizationType() == civilizationID then
            local iTeam = pPlayer:GetTeam()
            if iTeam == iAttackingTeam then -- Player is part of Team Aggressor!
                print("Do stuff")
            elseif iTeam == iDefendingTeam -- Player is part of Team Helpless Victim!
                print("Do other stuff")
            else -- Player is part of neither - you don't need this bit, it's just for illustration
                print("Do nothing")
            end
           
        end
    end
end

GameEvents.DeclareWar.Add(OnDeclareWar)

Now we must simply wait for LeeS to explain this better than I have :p

[WHAT_WOULD_BE_AN_EDIT_IF_CFC_DIDN'T_HAVE_NEW_NINJA_AVOIDING_MECHANICS]

That... is very smart...

Although fwiw that example wouldn't work:

Code:
local bIgnoreMinors = false
function OnPlayerDoTurn(iPlayer)
   local pPlayer = Players[iPlayer]
    if pPlayer:IsAlive() and pPlayer:GetCivilizationType() == civilizationID then
        local pTeam = Teams[pPlayer:GetTeam()]
        if pTeam:GetAtWarCount(bIgnoreMinors) > 0 then -- Methods are invoked with colons, not full stops; team is the name of the table in which the Method is defined, but you're wanting to invoke it on pTeam for obvious reasons; I only did the bIgnoreMinors bit so I could fit this comment in :p
            -- do something
        end
    end
end
GameEvents.PlayerDoTurn.Add(OnPlayerDoTurn)

And I'm going to assume that ignores Barbarians because it's a Firaxis Method and they don't include any provision to include/dis... include... them
 
And I'm going to assume that ignores Barbarians because it's a Firaxis Method and they don't include any provision to include/dis... include... them
Last time I checked it indeed ignored Barbs. Would be a pretty useless function otherwise ;)

[WHAT_WOULD_BE_AN_EDIT_IF_CFC_DIDN'T_HAVE_NEW_NINJA_AVOIDING_MECHANICS]
The same ninja avoiding mechanics avoided a double post from me as well :ninja:
 
Nice, thanks a lot for all of your help! After opening the thread, I tried out the way aschulak's American Dominion mod detected war declarations (https://forums.civfanatics.com/resources/american-domination-gods-and-kings-v34.21098/), which is inserting an event into Events.WarStateChanged and seeing which players are on iTeam2, but during live testing for some reason I always ended up on iTeam2 regardless of whether I declared war on AI or provoked it into declaring war on me. I didn't know about GameEvents.DeclareWar, that seems like a much better way to handle this.

As an aside, would the Vassalage feature from the CBP affect the team definitions at all? I'm a bit worried that the script might lose track of who the player is currently fighting a defensive war against if one of the AIs in question becomes someone else's Vassal and their team slot is left vacant.

Edit: It works! Now I just have to field test to see whether mid-war Vassalage can interfere with it. Thanks for replying!
 
Last edited:
Back
Top Bottom