1. Can only ever ally with 1 AI player
2. Only opposing sides can ally, GDI + GDI and Nod + Nod alliances won't work. This could be corrected with AI only sides for GDI and Nod, but I won't cover that here.
3. Has to be enabled for each map specifically. Though this could be considered a good thing since the logic might force human players to ally with each other, so I would leave it for skirmish only maps or figure something else out.
Let's begin in rules.ini. Create this new infantry first:
Code:
; Informant
[INFORM]
Name=
Image=E1 ; Should use an invisible infantry SHP here
Category=Support
Prerequisite=CABHUT
Primary=none
Crushable=no
Immune=yes
Insignificant=yes
Strength=100
Armor=none
TechLevel=1
Sight=0
Speed=5
Owner=GDI,Nod
AllowedToStartInMultiplayer=no
Cost=0
Points=0
PhysicalSize=1
JumpJet=yes
Locomotor={92612C46-F71F-11d1-AC9F-006008055BB5}
MovementZone=Fly
ThreatPosed=0
ImmuneToVeins=yes
Then search for [VariableNames] and add these to the bottom:
Code:
...
12=GDI Exists
13=Nod Exists
Next up ai.ini. First we need to define a taskforce. Just as a reminder, remember to add each taskforce, script and teamtype to their respective index lists.
Code:
[00000001-G]
Name=Inform
0=1,INFORM
Group=-1
Then a few triggers.
Code:
[00000002-G]
Name=GDI Exists
0=12,12 ; Set "GDI exists" global variable "true"
1=3,97 ; Move to waypoint 97 to get out of the way
[00000003-G]
Name=Nod Exists
0=12,13 ; Set "Nod exists" global variable "true"
1=3,97 ; Move to waypoint 97 to get out of the way
Get's bit messier here, need to add a bunch of teamtypes. They are pretty much copies of each other, only the side and scripts are changed.
Code:
[00000004-G]
Name=GDI set self
House=GDI
Priority=1
Max=1
Script=00000002-G ; Set GDI
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
[00000005-G]
Name=GDI set GDI
House=GDI
Priority=1
Max=1
Script=00000002-G ; Set GDI
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
[00000006-G]
Name=GDI set Nod
House=GDI
Priority=1
Max=1
Script=00000003-G ; Set Nod
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
[00000007-G]
Name=Nod set self
House=Nod
Priority=1
Max=1
Script=00000003-G ; Set Nod
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
[00000008-G]
Name=Nod set Nod
House=Nod
Priority=1
Max=1
Script=00000003-G ; Set Nod
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
[00000009-G]
Name=Nod set GDI
House=Nod
Priority=1
Max=1
Script=00000002-G ; Set GDI
TaskForce=00000001-G
Aggressive=no
AvoidThreats=no
Annoyance=no
Suicide=yes
Whiner=no
Group=-1
Reinforce=no
AreTeamMembersRecruitable=no
Recruiter=no
LooseRecruit=no
IsBaseDefense=no
GuardSlower=no
OnlyTargetHouseEnemy=yes
Autocreate=no
Prebuild=no
Loadable=no
OnTransOnly=no
TransportsReturnOnUnload=no
VeteranLevel=1
TechLevel=0
IonImmune=no
Droppod=no
Full=no
Finally, the triggers.
Code:
;GDI set self
00000010-G=GDI 1,00000004-G,<all>,1,1,GAPILE,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,1,0,<none>,1,1,1
;GDI set GDI
00000011-G=GDI 2,00000005-G,<all>,1,0,GAPILE,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,1,0,<none>,1,1,1
;GDI set Nod
00000012-G=GDI 3,00000006-G,<all>,1,0,NAHAND,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,1,0,<none>,1,1,1
;Nod set self
00000013-G=Nod 1,00000007-G,<all>,1,1,NAHAND,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,2,0,<none>,1,1,1
;Nod set Nod
00000014-G=Nod 2,00000008-G,<all>,1,0,NAHAND,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,2,0,<none>,1,1,1
;Nod set GDI
00000015-G=Nod 3,00000009-G,<all>,1,0,GAPILE,0100000003000000000000000000000000000000000000000000000000000000,5000.000000,5000.000000,5000.000000,1,0,2,0,<none>,1,1,1
If you haven't been scared away yet, I will explain what the idea is here. Normally alliances can't be formed on multiplayer maps cause we don't know which factions are actually participating in the match. Trying to ally with a faction that doesn't exist in the match would result in a crash. Since there's no apparent way to check if a certain faction exists (since the check itself would crash if that faction didn't exists), we let the AI do the work. Each AI will first look if they own a GDI Barracks or Hand of Nod, and if so set each faction's global variable enabled. E.g. Nod AI sees that he has a Hand of Nod, thus we can assume Nod is present in the match, and set the global variable true. Then the AI does the same check on their enemy, checking if they have a GDI Barracks or Hand of Nod, and again set the global variable true. This is needed because human players wouldn't be setting any global variables, so the AI needs to do it instead. After this ai.ini stuff, we now know which factions are present in the mission.
P.S. That new fake infantry is needed so the AI will only do these checks once. If the infantry could be killed the AI would keep replacing it.
Final part is to make use of all this in the map file. Open FinalSun and open the Trigger Editor. You need to add 2 new triggers, one for GDI and one for Nod. Below shows the GDI trigger details:
Nothing special here...

Here you need to add another event in addition to the one shown in the pic. Event 1 should be exactly the same as the one here, just change the Parameter value to 13.

...

Now add the trigger for Nod. Just clone this one and change every GDI value to Nod, and vice versa. Finally, add the special waypoint 97 to your map to make the AI send out their fake infantry away from blocking base construction. Should be placed somewhere remote.

That should cover it, if you run into any problems just ask here. There are a few instances where no alliances are made:
1. All players are of the same faction. Since GDI can't ally with GDI, nothing will happen.
2. A really small chance that the human player is the only one playing a certain faction (e.g. Nod) while all the AI are playing GDI, AND none of the AI's consider the player an enemy. Thus Nod's existence would never be set true, at least not until one of the AI's got mad at the Nod human player.