As this thread explains, and gsthoed's tests confirm, I_LocalFaction can take on a (seemingly) different meaning in hotseat. Wishing to confirm this statement...

Originally Posted by
Withwnar
It's when "faction" is exported in an event that can fire in somebody else's turn that the danger lies, that "not FactionIsLocal" does not necessarily mean "is the AI" in hotseat and is therefore potentially hotseat incompatible. Some examples spring to mind: PostBattle and (if scripted to do so) such things as CharacterSelected, MultiTurnMove, GeneralAssaultsResidence, etc.
... I ran some more tests...
All tests were done in vanilla Kingdoms Grand Campaign. Therefore the three tested factions - england, france & hre - are in that order.
Test 1 : faction's own turn
This checks the results of I_LocalFaction, FactionIsLocal, I_IsFactionAIControlled and IsFactionAIControlled during the faction's own turn. That is, in an event that fires on the faction in its own turn: FactionTurnStart in this case. The same would apply to any event that fires on the faction (or its characters/settlements) in its own turn.
Script:
Code:
monitor_event FactionTurnStart FactionType france
and FactionIsLocal
log always france turn: FactionIsLocal (france) = true
end_monitor
monitor_event FactionTurnStart FactionType france
and I_LocalFaction france
log always france turn: I_LocalFaction france = true
end_monitor
monitor_event FactionTurnStart FactionType france
and IsFactionAIControlled
log always france turn: IsFactionAIControlled (france) = true
end_monitor
monitor_event FactionTurnStart FactionType france
and I_IsFactionAIControlled france
log always france turn: I_IsFactionAIControlled france = true
end_monitor
monitor_event FactionTurnStart FactionType france
and not FactionIsLocal
log always france turn: FactionIsLocal (france) = false
end_monitor
monitor_event FactionTurnStart FactionType france
and not I_LocalFaction france
log always france turn: I_LocalFaction france = false
end_monitor
monitor_event FactionTurnStart FactionType france
and not IsFactionAIControlled
log always france turn: IsFactionAIControlled (france) = false
end_monitor
monitor_event FactionTurnStart FactionType france
and not I_IsFactionAIControlled france
log always france turn: I_IsFactionAIControlled france = false
end_monitor
monitor_event FactionTurnStart FactionType france
and I_LocalFaction england
log always ### france turn: I_LocalFaction england = true
end_monitor
monitor_event FactionTurnStart FactionType england
and FactionIsLocal
log always england turn: FactionIsLocal (england) = true
end_monitor
monitor_event FactionTurnStart FactionType england
and I_LocalFaction england
log always england turn: I_LocalFaction england = true
end_monitor
monitor_event FactionTurnStart FactionType england
and IsFactionAIControlled
log always england turn: IsFactionAIControlled (england) = true
end_monitor
monitor_event FactionTurnStart FactionType england
and I_IsFactionAIControlled england
log always england turn: I_IsFactionAIControlled england = true
end_monitor
monitor_event FactionTurnStart FactionType england
and not FactionIsLocal
log always england turn: FactionIsLocal (england) = false
end_monitor
monitor_event FactionTurnStart FactionType england
and not I_LocalFaction england
log always england turn: I_LocalFaction england = false
end_monitor
monitor_event FactionTurnStart FactionType england
and not IsFactionAIControlled
log always england turn: IsFactionAIControlled (england) = false
end_monitor
monitor_event FactionTurnStart FactionType england
and not I_IsFactionAIControlled england
log always england turn: I_IsFactionAIControlled england = false
end_monitor
monitor_event FactionTurnStart FactionType england
and I_LocalFaction france
log always ### england turn: I_LocalFaction france = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and FactionIsLocal
log always hre turn: FactionIsLocal (hre) = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and I_LocalFaction hre
log always hre turn: I_LocalFaction hre = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and IsFactionAIControlled
log always hre turn: IsFactionAIControlled (hre) = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and I_IsFactionAIControlled hre
log always hre turn: I_IsFactionAIControlled hre = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and not FactionIsLocal
log always hre turn: FactionIsLocal (hre) = false
end_monitor
monitor_event FactionTurnStart FactionType hre
and not I_LocalFaction hre
log always hre turn: I_LocalFaction hre = false
end_monitor
monitor_event FactionTurnStart FactionType hre
and not IsFactionAIControlled
log always hre turn: IsFactionAIControlled (hre) = false
end_monitor
monitor_event FactionTurnStart FactionType hre
and not I_IsFactionAIControlled hre
log always hre turn: I_IsFactionAIControlled hre = false
end_monitor
monitor_event FactionTurnStart FactionType hre
and I_LocalFaction england
log always ### hre turn: I_LocalFaction england = true
end_monitor
monitor_event FactionTurnStart FactionType hre
and I_LocalFaction france
log always ### hre turn: I_LocalFaction france = true
end_monitor
A: Single Player, player = england
No surprises here of course. As england is the only player "I_LocalFaction england" is true in every faction's turn.
Code:
england turn: FactionIsLocal (england) = true
england turn: I_LocalFaction england = true
england turn: IsFactionAIControlled (england) = false
england turn: I_IsFactionAIControlled england = false
france turn: IsFactionAIControlled (france) = true
france turn: I_IsFactionAIControlled france = true
france turn: FactionIsLocal (france) = false
france turn: I_LocalFaction france = false
### france turn: I_LocalFaction england = true
hre turn: IsFactionAIControlled (hre) = true
hre turn: I_IsFactionAIControlled hre = true
hre turn: FactionIsLocal (hre) = false
hre turn: I_LocalFaction hre = false
### hre turn: I_LocalFaction england = true
B: Single Player, player = france
Same result, naturally, but for france instead.
Code:
france turn: FactionIsLocal (france) = true
france turn: I_LocalFaction france = true
france turn: IsFactionAIControlled (france) = false
france turn: I_IsFactionAIControlled france = false
england turn: IsFactionAIControlled (england) = true
england turn: I_IsFactionAIControlled england = true
england turn: FactionIsLocal (england) = false
england turn: I_LocalFaction england = false
### england turn: I_LocalFaction france = true
hre turn: IsFactionAIControlled (hre) = true
hre turn: I_IsFactionAIControlled hre = true
hre turn: FactionIsLocal (hre) = false
hre turn: I_LocalFaction hre = false
### hre turn: I_LocalFaction france = true
C: Hotseat, player = england
These results are identical to test 1A.
Code:
england turn: FactionIsLocal (england) = true
england turn: I_LocalFaction england = true
england turn: IsFactionAIControlled (england) = false
england turn: I_IsFactionAIControlled england = false
france turn: IsFactionAIControlled (france) = true
france turn: I_IsFactionAIControlled france = true
france turn: FactionIsLocal (france) = false
france turn: I_LocalFaction france = false
### france turn: I_LocalFaction england = true
hre turn: IsFactionAIControlled (hre) = true
hre turn: I_IsFactionAIControlled hre = true
hre turn: FactionIsLocal (hre) = false
hre turn: I_LocalFaction hre = false
### hre turn: I_LocalFaction england = true
D: Hotseat, player = france
These results are identical to test 1B.
Code:
france turn: FactionIsLocal (france) = true
france turn: I_LocalFaction france = true
france turn: IsFactionAIControlled (france) = false
france turn: I_IsFactionAIControlled france = false
england turn: IsFactionAIControlled (england) = true
england turn: I_IsFactionAIControlled england = true
england turn: FactionIsLocal (england) = false
england turn: I_LocalFaction england = false
### england turn: I_LocalFaction france = true
hre turn: IsFactionAIControlled (hre) = true
hre turn: I_IsFactionAIControlled hre = true
hre turn: FactionIsLocal (hre) = false
hre turn: I_LocalFaction hre = false
### hre turn: I_LocalFaction france = true
E: Hotseat, player = england + france
The only 'oddity' here is that in hre's turn I_LocalFaction=france (not england - the other player faction). But we knew that already: hre is AI and france was the most recent player faction in the sequence before hre's turn, therefore I_LocalFaction remained france and does so until the next player faction's turn.
Also, in france's turn, I_LocalFaction=france, not england. Which stands to reason: in france's turn france is the most recent player faction. Likewise, in england's turn I_LocalFaction=england.
FactionIsLocal is true for england in england's turn, true for france in france's turn, and false for hre in hre's turn. As one would expect.
Code:
england turn: FactionIsLocal (england) = true
england turn: I_LocalFaction england = true
england turn: IsFactionAIControlled (england) = false
england turn: I_IsFactionAIControlled england = false
france turn: FactionIsLocal (france) = true
france turn: I_LocalFaction france = true
france turn: IsFactionAIControlled (france) = false
france turn: I_IsFactionAIControlled france = false
hre turn: IsFactionAIControlled (hre) = true
hre turn: I_IsFactionAIControlled hre = true
hre turn: FactionIsLocal (hre) = false
hre turn: I_LocalFaction hre = false
### hre turn: I_LocalFaction france = true
These tests show that for events happening to a faction in its own turn, FactionIsLocal does not behave any differently between Single Player and Hotseat.
Neither does I_LocalFaction if the faction being tested is the faction whose turn it is and it is a player faction. Otherwise I_LocalFaction can't be relied upon in Hotseat.
I_IsFactionAIControlled and IsFactionAIControlled both behave as expected. And always do. They're only included in these tests for completeness, and proof I suppose.
Okay, so FactionIsLocal is reliable in Hotseat here. In both game modes it always means "the player whose turn it is" and will always be false for an AI faction.
Test 2 : in another faction's turn
So what if an event fires on a player faction when it's not their turn?
This test uses the PostBattle event. This fires on the commander of both armies after the battle (if any soldiers are left alive) for both AI and players. It exports faction so we can use FactionIsLocal on it. AI attacks the player in their (AI's) own turn, so this is a classic case of an event firing on a player faction, where FactionIsLocal can be used, but not within the player faction's own turn.
Script:
Only results for england and hre are being tested here.
Code:
monitor_event PostBattle FactionType england
and FactionIsLocal
log always PostBattle (england): FactionIsLocal (england) = true
end_monitor
monitor_event PostBattle FactionType england
and I_LocalFaction england
log always PostBattle (england): I_LocalFaction england = true
end_monitor
monitor_event PostBattle FactionType england
and IsFactionAIControlled
log always PostBattle (england): IsFactionAIControlled (england) = true
end_monitor
monitor_event PostBattle FactionType england
and I_IsFactionAIControlled england
log always PostBattle (england): I_IsFactionAIControlled england = true
end_monitor
monitor_event PostBattle FactionType england
and not FactionIsLocal
log always PostBattle (england): FactionIsLocal (england) = false
end_monitor
monitor_event PostBattle FactionType england
and not I_LocalFaction england
log always PostBattle (england): I_LocalFaction england = false
end_monitor
monitor_event PostBattle FactionType england
and not IsFactionAIControlled
log always PostBattle (england): IsFactionAIControlled (england) = false
end_monitor
monitor_event PostBattle FactionType england
and not I_IsFactionAIControlled england
log always PostBattle (england): I_IsFactionAIControlled england = false
end_monitor
monitor_event PostBattle FactionType hre
and FactionIsLocal
log always PostBattle (hre): FactionIsLocal (hre) = true
end_monitor
monitor_event PostBattle FactionType hre
and I_LocalFaction hre
log always PostBattle (hre): I_LocalFaction hre = true
end_monitor
monitor_event PostBattle FactionType hre
and IsFactionAIControlled
log always PostBattle (hre): IsFactionAIControlled (hre) = true
end_monitor
monitor_event PostBattle FactionType hre
and I_IsFactionAIControlled hre
log always PostBattle (hre): I_IsFactionAIControlled hre = true
end_monitor
monitor_event PostBattle FactionType hre
and not FactionIsLocal
log always PostBattle (hre): FactionIsLocal (hre) = false
end_monitor
monitor_event PostBattle FactionType hre
and not I_LocalFaction hre
log always PostBattle (hre): I_LocalFaction hre = false
end_monitor
monitor_event PostBattle FactionType hre
and not IsFactionAIControlled
log always PostBattle (hre): IsFactionAIControlled (hre) = false
end_monitor
monitor_event PostBattle FactionType hre
and not I_IsFactionAIControlled hre
log always PostBattle (hre): I_IsFactionAIControlled hre = false
end_monitor
Single Player: no tests. We know that everything works as expected there.
A: Hotseat, player = england, attacking hre in england turn
Nothing to see here. It's in the player's turn so all is at is should be.
Code:
PostBattle (england): FactionIsLocal (england) = true
PostBattle (england): I_LocalFaction england = true
PostBattle (england): IsFactionAIControlled (england) = false
PostBattle (england): I_IsFactionAIControlled england = false
PostBattle (hre): IsFactionAIControlled (hre) = true
PostBattle (hre): I_IsFactionAIControlled hre = true
PostBattle (hre): FactionIsLocal (hre) = false
PostBattle (hre): I_LocalFaction hre = false
B: Hotseat, player = england, hre attacking england in hre turn
Still fine. england is the only player faction so they're still the "local faction" in anybody's turn (hre's in this test).
Code:
PostBattle (england): FactionIsLocal (england) = true
PostBattle (england): I_LocalFaction england = true
PostBattle (england): IsFactionAIControlled (england) = false
PostBattle (england): I_IsFactionAIControlled england = false
PostBattle (hre): IsFactionAIControlled (hre) = true
PostBattle (hre): I_IsFactionAIControlled hre = true
PostBattle (hre): FactionIsLocal (hre) = false
PostBattle (hre): I_LocalFaction hre = false
C: Hotseat, player = england + france, hre attacking england in hre turn
Now we have two player factions: england and france. In hre's (AI) turn france was the most recent player faction, therefore france is the "local faction" in hre's turn, not england.
Boom: FactionIsLocal is false for england, even though they're the player faction in the battle.
Code:
PostBattle (england): FactionIsLocal (england) = false
PostBattle (england): I_LocalFaction england = false
PostBattle (england): IsFactionAIControlled (england) = false
PostBattle (england): I_IsFactionAIControlled england = false
PostBattle (hre): IsFactionAIControlled (hre) = true
PostBattle (hre): I_IsFactionAIControlled hre = true
PostBattle (hre): FactionIsLocal (hre) = false
PostBattle (hre): I_LocalFaction hre = false
Conclusion
FactionIsLocal is Hotseat-compatible only for events that fire on a player faction within their own turn. Otherwise it's unreliable at best.
This is consistent with I_LocalFaction, where that too can only reliably be used for a faction during that faction's own turn. (In Hotseat.)
Example:
Code:
;--------------------------------
Trigger trigger1
WhenToTest PostBattle
Condition FactionIsLocal
and WonBattle
Affects TraitA 1 Chance 100
;--------------------------------
Trigger trigger2
WhenToTest PostBattle
Condition not FactionIsLocal
and WonBattle
Affects TraitB 1 Chance 100
If the intention of the "Local" conditions here is to distinguish between player (trigger1 -> TraitA) and AI (trigger2 -> TraitB) then it can fail in Hotseat.
In that Test 2C scenario:
- the england commander (player) would NOT get TraitA if he won
- the england commander (player) WOULD get TraitB if he won: FactionIsLocal is false for england, therefore "not FactionIsLocal" is true for england.
It's fine for the hre commander: he's AI therefore FactionIsLocal will always be false for him and "not FactionIsLocal" will always be true.
Presumably CharacterIsLocal - and any other "xxxLocal" condition - is also broken in Hotseat in this way.
Therefore, for Hotseat compatibility, if you mean "is the AI" then use IsFactionAIControlled/I_IsFactionAIControlled, and for "is a player" use "not IsFactionAIControlled / not I_IsFactionAIControlled". Use FactionIsLocal/I_LocalFaction (or "not" of them), and any other xxxLocal conditions, only when you're certain that the event is firing within their own turn.