ModEnc is currently in Maintenance Mode: Changes could occur at any given moment, without advance warning.

AITriggerTypes: Difference between revisions

From ModEnc
Jump to navigation Jump to search
Creating, every time this section confuses you, a kitten dies... Somebody, PLEASE, find a nicer way to explain this stuff...
 
Crimsonum (talk | contribs)
Removed unverified information.
 
(15 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{WrongTitle|[AITriggerTypes]}}
{{WrongTitle|[AITriggerTypes]}}
{{SideBar|[[AI programming]]|Template:AI}}
{{AIBar}}{{clr}}
In {{ts}} through {{yr}}, this section defines a list of all AI Triggers in the game. An AI Trigger (different from a [[Maps/Triggers|Map Trigger]]) describes the conditions under which the AI will consider creating this trigger's associated Team(s) to perform a specific task.  
{{MappingBar}}
In {{ts}} through {{yr}}, this section defines a list of all AI Triggers in the game. An AI Trigger (different from a [[Triggers|Map Trigger]]) describes the conditions under which the AI will consider creating this trigger's associated Team(s) to perform a specific task.  


== Format ==
== Format ==
{{HorizontalBar|{{W}} This section is provided here mostly for completeness' sake. Editing this section, especially the comparator part, manually is not advised unless you really know what you are doing. Consider using [[FinalAlert 2]]'s AI Editor or DCoder's [[AI Editor V2]] instead.}}
{{HorizontalBar|{{W}} This section is provided here mostly for completeness' sake. Editing this section, especially the comparator part, manually is not advised unless you really know what you are doing. Consider using [[C&C AI Editor]] or [[FinalAlert 2]]'s AI Editor instead.}}


This section uses a convoluted and complex data format:
This section uses a convoluted and complex data format:
[AITriggerTypes]
<pre style="overflow: auto; white-space: pre;">
;format example
[AITriggerTypes]
ID=Name,Team1,OwnerHouse,TechLevel,ConditionType,ConditionObject,Comparator,StartingWeight,MinimumWeight,MaximumWeight,IsForSkirmish,unused,Side,IsBaseDefense,Team2,EnabledInE,EnabledInM,EnabledInH
;format example
ID=Name,Team1,OwnerHouse,TechLevel,ConditionType,ConditionObject,Comparator,StartingWeight,MinimumWeight,MaximumWeight,IsForSkirmish,unused,Side,IsBaseDefense,Team2,EnabledInE,EnabledInM,EnabledInH
;actual example triggers
0CAD0C7C-G=Allied Anti-Weather,0A6E513C-G,<all>,9,0,GAWEAT,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,1,0,0CB246CC-G,0,1,1
0D535EDC-G=Nation German Tank 1,0A87293C-G,Germans,2,4,<none>,0000000003000000000000000000000000000000000000000000000000000000,500.000000,10.000000,500.000000,1,0,1,0,<none>,1,1,1
0D2769BC-G=Soviet Iron Curtain Easy,0D27E06C-G,<all>,2,5,<none>,0000000000000000000000000000000000000000000000000000000000000000,5000.000000,10.000000,5000.000000,1,0,2,0,<none>,1,0,0
08B9767C-G=Yuri Capture Oil,08B97B3C-G,<all>,1,7,CAOILD,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,3,0,<none>,0,1,1


;actual example triggers
0CAD0C7C-G=Allied Anti-Weather,0A6E513C-G,<all>,9,0,GAWEAT,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,1,0,0CB246CC-G,0,1,1
0D535EDC-G=Nation German Tank 1,0A87293C-G,Germans,2,4,<none>,0000000003000000000000000000000000000000000000000000000000000000,500.000000,10.000000,500.000000,1,0,1,0,<none>,1,1,1
0D2769BC-G=Soviet Iron Curtain Easy,0D27E06C-G,<all>,2,5,<none>,0000000000000000000000000000000000000000000000000000000000000000,5000.000000,10.000000,5000.000000,1,0,2,0,<none>,1,0,0
08B9767C-G=Yuri Capture Oil,08B97B3C-G,<all>,1,7,CAOILD,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,3,0,<none>,0,1,1
</pre>
{| style="width: 90%" border=1 class="table_descrowdesccol"
{| style="width: 90%" border=1 class="table_descrowdesccol"
|+ Meanings of each string
|+ Meanings of each string
Line 33: Line 34:
|-
|-
! {{Anchor|OwnerHouse|}}
! {{Anchor|OwnerHouse|}}
| The [[Countries|Country]] that should use this AI Trigger. Defaults to {{Tt|<none>}}, can be set to an individual country's name or to {{Tt|<all>}}, indicating that all countries of the appropriate Side can use this AI Trigger.
| The [[House]]/[[Countries|Country]] that should use this AI Trigger. Defaults to {{Tt|<none>}}, can be set to an individual house/country's name or to {{Tt|<all>}}, indicating that all houses/countries of the appropriate Side can use this AI Trigger.
|-
|-
! {{Anchor|TechLevel|}}
! {{Anchor|TechLevel|}}
| Minimum [[TechLevel]] required for this AI Trigger. Is recalculated internally to be the minimum TechLevel required to build all the units in this AI Trigger's first and second TeamTypes.
| Minimum [[TechLevel]] (as in [[MultiplayerDialogSettings]]) required for this AI Trigger. Is recalculated internally to be the minimum TechLevel required to build all the units in this AI Trigger's first and second TeamTypes.
|-
|-
! {{Anchor|ConditionType|}}
! {{Anchor|ConditionType|}}
Line 47: Line 48:
|-
|-
! style="font-family: monospace; width: 50px; text-align: center; " | -1
! style="font-family: monospace; width: 50px; text-align: center; " | -1
| Special case - Pool team ([[#Pool Teams|see below {{arr|d}}]])
| No condition check, always true.
|-
|-
! style="font-family: monospace; width: 50px; text-align: center; " | 0
! style="font-family: monospace; width: 50px; text-align: center; " | 0
Line 65: Line 66:
|-
|-
! style="font-family: monospace; width: 50px; text-align: center; " | 5
! style="font-family: monospace; width: 50px; text-align: center; " | 5
| "OwnerHouse has an [[Iron Curtain]] charged to at least {{sl|General|AIMinorSuperReadyPercent}} percentage"
| [RA2/YR only] "OwnerHouse has an [[Iron Curtain]] charged to at least {{sl|General|AIMinorSuperReadyPercent}} percentage"
|-
|-
! style="font-family: monospace; width: 50px; text-align: center; " | 6
! style="font-family: monospace; width: 50px; text-align: center; " | 6
| "OwnerHouse has a [[ChronoSphere]] charged to at least {{sl|General|AIMinorSuperReadyPercent}} percentage"
| [RA2/YR only] "OwnerHouse has a [[ChronoSphere]] charged to at least {{sl|General|AIMinorSuperReadyPercent}} percentage"
|-
|-
! style="font-family: monospace; width: 50px; text-align: center; " | 7
! style="font-family: monospace; width: 50px; text-align: center; " | 7
| "Neutral/civilian house owns ????"
| [RA2/YR only] "Neutral/civilian{{fnl|1}} house owns ????"
|}
|}
{{fn|1|To find this house, the game scans all houses from the {{sl|Countries}} list, starting with the first one on the {{sl|Sides|Civilian}} list and going down the list, when it finds the first one with {{f|Side|Civilian|link}} set.}}


|-
|-
! {{Anchor|ComparisonObject|}}
! {{Anchor|ComparisonObject|}}
| Specifies the object that will be used as the Comparison Object (see the section on [[#ConditionType|ConditionType]] for more information). IDs of [[AircraftTypes]], [[InfantryTypes]] and [[VehicleTypes]] are accepted here.
| Specifies the object that will be used as the Comparison Object (see the section on [[#ConditionType|ConditionType]] for more information). IDs of [[AircraftTypes]], [[BuildingTypes]], [[InfantryTypes]] and [[VehicleTypes]] are accepted here.
|-
|-
! {{anchor|Comparator|}}
! {{anchor|Comparator|}}
| Defines the comparator for the [[#ConditionType|ConditionType]]. A normal comparison contains two operands and a comparison operator. The first operand is dependant on the ConditionType (typically amount of objects owned, or credits owned). The second operand is encoded in this argument. The comparison operator is one of (less, less-or-equal, equal, more-or-equal, more, not equal) and is also encoded in this argument. This argument is composed of eight chunks of eight hexadecimal characters each (64 characters in total). Each octet contains a textual representation of a little-endian hexadecimal number. The first octet contains the second argument, the second octet contains the operator (0 stands for "{{Tt|<}}", 1 - "{{Tt|<{{equal}}}}", 2 - "{{Tt|{{equal}}}}", 3 - "{{Tt|>{{equal}}}}", 4 - "{{Tt|>}}", 5 - "{{Tt|!{{equal}}}}"), the next six octets are unused.  
| Defines the comparator for the [[#ConditionType|ConditionType]]. A normal comparison contains two operands and a comparison operator. The first operand is dependant on the ConditionType (typically amount of objects owned, or credits owned). The second operand is encoded in this argument. The comparison operator is one of (less, less-or-equal, equal, more-or-equal, more, not equal) and is also encoded in this argument. This argument is composed of eight chunks of eight hexadecimal characters each (64 characters in total). Each octet contains a textual representation of a little-endian hexadecimal number. The first octet contains the second argument, the second octet contains the operator (0 stands for "{{Tt|<}}", 1 - "{{Tt|<{{equal}}}}", 2 - "{{Tt|{{equal}}}}", 3 - "{{Tt|>{{equal}}}}", 4 - "{{Tt|>}}", 5 - "{{Tt|!{{equal}}}}"), the next six octets are unused. See below for Condition check segment examples.
|-
|-
! {{Anchor|StartingWeight|}}
! {{Anchor|StartingWeight|}}
Line 97: Line 99:
|-
|-
! {{anchor|Side|}}
! {{anchor|Side|}}
| Indicates the [[Sides|Side]] that may use this AI Trigger. {{Tt|0}} stands for "all sides", positive values indicate the owning side - Allied, Soviet, Yuri, ... .
| Indicates the [[Sides|Side]] that may use this AI Trigger. {{Tt|0}} stands for "all sides", positive values indicate the owning side - Allied, Soviet, Yuri, etc.
 
Note that in {{ts}}, this refers to the {{f|ActsLike|link}} setting of a [[house]], incremented by one. For example, if this value is {{Tt|1}}, the AI Trigger is applicable to any houses with {{f|ActsLike|0}}. If this value is {{Tt|2}}, it is applicable to houses with {{f|ActsLike|1}}. And so on.
|-
|-
! {{Anchor|IsBaseDefense|}}
! {{Anchor|IsBaseDefense|}}
| If set to a non-zero integer value, this AI Trigger is interpreted as "Base Defense". If so, it is subject to limits set by {{Sl|General|MinimumAIDefensiveTeams}} and {{Sl|General|MaximumAIDefensiveTeams}}.
| Unused, usually set to 0.
|-
|-
! {{anchor|Team2|}}
! {{anchor|Team2|}}
Line 114: Line 118:
| If set to a zero value, this AI Trigger will not be considered by AI houses playing in Hard difficulty.
| If set to a zero value, this AI Trigger will not be considered by AI houses playing in Hard difficulty.
|}
|}
== Condition check segment examples ==
For simplicity only the segments of [[#ConditionType|ConditionType]], [[#ComparisonObject|ComparisonObject]] and first octet (amount) and second octet ([[#Comparator|Comparator]]) are shown. An octet consists of 8 hex digits (4 bytes). Values are in hexadecimal and represented in little endian format. For a decimal value of 3, its hex value is 0x3, its octet representation becomes 03000000. For a decimal value of 500, its hex value is 0x1F4, its octet representation becomes F4010000.
<pre>-1,<none>,0000000000000000 - no condition check, always true. TechType and the two octets are irrelevant and can hold any valid values.
0,GAREFN,0400000003000000 - when AI's enemy owns greater or equal to 4 allied ore refineries.
1,SHK,0300000001000000 - when AI's own troops has less than or equal to 3 shock troopers.
4,<none>,8813000003000000 - when AI's enemy has greater or equal to 5000 credits, hex value 0x1388, octet 88130000.</pre>


== Weights ==
== Weights ==
Line 119: Line 130:
AI Triggers are given "weights" to define how important they are. Larger weight makes the AI Trigger more likely to get selected.
AI Triggers are given "weights" to define how important they are. Larger weight makes the AI Trigger more likely to get selected.


Each time an AI Trigger's Teams are dissolved (when they complete their ScriptType or are destroyed), said AI Trigger's weight is modified:
Each time an AI controlled team is dissolved (when they complete their script or are destroyed), all AI Triggers using that TeamType as their primary ({{Tt|Team1}}) get their weight modified:
;if the Team has executed a [[ScriptTypes/ScriptActions#action_49|Script Action 49, 0]] in this lifetime,
;if the Team has executed a [[ScriptTypes/ScriptActions#action_49|Script Action 49, 0]] in this lifetime,
:{{sl|General|AITriggerSuccessWeightDelta}} is added to its weight,  
:{{sl|General|AITriggerSuccessWeightDelta}} is added to its weight,  
Line 126: Line 137:
Care is taken not to push the weight outside the limits set by MinimumWeight and MaximumWeight while doing so.
Care is taken not to push the weight outside the limits set by MinimumWeight and MaximumWeight while doing so.


<span id="weight_5000">A Weight equivalent to {{Tt|5000.0}}</span> stands for "ignore all other AI Triggers and fire this one immediately, if its condition is met". It is originally used for Teams utilising minor SuperWeapons, the Iron Curtain or the ChronoSphere.
=== Special Values ===
 
==== Weight 0 ====
 
If an AI trigger's weight drops to zero, it will not be considered for production. This can be used to remove certain AI triggers from play for the rest of the game if they fail too many times.
 
==== Weight 5000 ====
In {{ra2}} and {{yr}}, <span id="weight_5000">A Weight equivalent to {{Tt|5000.0}}</span> stands for "ignore all other AI Triggers and fire this one immediately, if its condition is met". It is originally used for Teams utilising minor SuperWeapons, the Iron Curtain or the ChronoSphere.
 
=== Flawed Design ===
 
In the unmodified games, AI teams are typically configured to succeed after attacking a specific category of enemy targets ([[QuarryTypes|a quarry]]). Unfortunately, this attack mission, [[ScriptTypes/ScriptActions|{{tt|#0 Attack...}}]], is only completed once ''all'' enemy objects matching the given quarry are destroyed. This means every such attack team has a slim to none chance of actually succeeding in its mission, causing their respective AI triggers to lose weight over time. The end result of this flawed design is that the production chances of AI triggers are almost entirely governed by their initial and minimum weights.


== Global and Local ==
== Global and Local ==


Unlike other AI components, AITriggerTypes do care where they were defined - the ones defined in {{Ini|ai}} are enabled by default, whereas ones defined in the map need to be enabled via {{sl|AITriggerTypesEnable}} to function. Global AITriggerTypes can be redefined in the map.
Unlike other AI components, AITriggerTypes do care where they were defined - the ones defined in {{Ini|ai}} are enabled by default, whereas ones defined in the map need to be enabled via {{sl|AITriggerTypesEnable}} to function. However, the {{sl|Basic|IgnoreGlobalAITriggers}} setting, if enabled, disables '''all''' AI Triggers declared in {{ini|ai}}, overriding the {{Tt|[AITriggerTypesEnable]}}.
 
== Pool Teams ==


"Pool Teams" are special in the sense that they do not use the normal comparator logic, and multiple Pool Teams controlled by the same House cannot be active at one time. If such an AI Trigger is activated, the Teams are simply created if doing so would not violate the {{TTL|BuildLimit}} or other conditions which limit human <!-- !!! --> object construction, without doing a check with the comparator logic.
Global AITriggerTypes can be redefined in the map.


== Additional information ==
== Additional information ==


*This section is read from {{Ini|ai}} and the current map file.  
*This section is read from {{Ini|ai}} and the current map file.
*The infamous {{Tt|-G}} suffix has no meaning whatsoever.  
*The infamous {{Tt|-G}} suffix is used to distinguish global AITriggerTypes from local ones (which have no suffix). It has no effect however.
*Unlike [[TaskForces]], there is no effect to prefixing an AITriggerType's ID with a hexadecimal prefix.
*Unlike [[TaskForces]], there is no effect to prefixing an AITriggerType's ID with a hexadecimal prefix.
[[Category:AI(md).ini Sections]]
[[Category:Maps Sections]]

Latest revision as of 21:48, 23 June 2024

This page should correctly be named "[AITriggerTypes]"; it is wrong due to technical restrictions.




In Tiberian Sun through Yuri's Revenge, this section defines a list of all AI Triggers in the game. An AI Trigger (different from a Map Trigger) describes the conditions under which the AI will consider creating this trigger's associated Team(s) to perform a specific task.

Format

This section is provided here mostly for completeness' sake. Editing this section, especially the comparator part, manually is not advised unless you really know what you are doing. Consider using C&C AI Editor or FinalAlert 2's AI Editor instead.


This section uses a convoluted and complex data format:

[AITriggerTypes]
;format example
ID=Name,Team1,OwnerHouse,TechLevel,ConditionType,ConditionObject,Comparator,StartingWeight,MinimumWeight,MaximumWeight,IsForSkirmish,unused,Side,IsBaseDefense,Team2,EnabledInE,EnabledInM,EnabledInH

;actual example triggers
0CAD0C7C-G=Allied Anti-Weather,0A6E513C-G,<all>,9,0,GAWEAT,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,1,0,0CB246CC-G,0,1,1
0D535EDC-G=Nation German Tank 1,0A87293C-G,Germans,2,4,<none>,0000000003000000000000000000000000000000000000000000000000000000,500.000000,10.000000,500.000000,1,0,1,0,<none>,1,1,1
0D2769BC-G=Soviet Iron Curtain Easy,0D27E06C-G,<all>,2,5,<none>,0000000000000000000000000000000000000000000000000000000000000000,5000.000000,10.000000,5000.000000,1,0,2,0,<none>,1,0,0
08B9767C-G=Yuri Capture Oil,08B97B3C-G,<all>,1,7,CAOILD,0100000003000000000000000000000000000000000000000000000000000000,70.000000,10.000000,70.000000,1,0,3,0,<none>,0,1,1
Meanings of each string
String Meaning
ID This AI Trigger's ID.
Name A plain string used as a name. Must not contain commas, will be truncated to 47 characters for internal representation.
Team1 The first TeamType that will be created when this AI Trigger meets its condition.
OwnerHouse The House/Country that should use this AI Trigger. Defaults to <none>, can be set to an individual house/country's name or to <all>, indicating that all houses/countries of the appropriate Side can use this AI Trigger.
TechLevel Minimum TechLevel (as in MultiplayerDialogSettings) required for this AI Trigger. Is recalculated internally to be the minimum TechLevel required to build all the units in this AI Trigger's first and second TeamTypes.
ConditionType Specifies a number to use as a Condition. This, along with "ComparisonObject" and "Comparator" desribed below, defines a logical comparison like "enemy house has more than 0 rhino tanks". In this example, "more than 0" is the Comparator, "rhino tanks" is the ComparisonObject, and "enemy house has ?????" is the Condition.
Possible values
Value Meaning
-1 No condition check, always true.
0 "Enemy house owns ????"
1 "Owning house owns ????"
2 "Enemy house in low power (yellow)"
3 "Enemy house in low power (red)"
4 "Enemy house has ??? credits"
5 [RA2/YR only] "OwnerHouse has an Iron Curtain charged to at least [General]AIMinorSuperReadyPercent= percentage"
6 [RA2/YR only] "OwnerHouse has a ChronoSphere charged to at least [General]AIMinorSuperReadyPercent= percentage"
7 [RA2/YR only] "Neutral/civilian1 house owns ????"

1 To find this house, the game scans all houses from the [Countries] list, starting with the first one on the [Sides]Civilian= list and going down the list, when it finds the first one with Side=Civilian set.

ComparisonObject Specifies the object that will be used as the Comparison Object (see the section on ConditionType for more information). IDs of AircraftTypes, BuildingTypes, InfantryTypes and VehicleTypes are accepted here.
Comparator Defines the comparator for the ConditionType. A normal comparison contains two operands and a comparison operator. The first operand is dependant on the ConditionType (typically amount of objects owned, or credits owned). The second operand is encoded in this argument. The comparison operator is one of (less, less-or-equal, equal, more-or-equal, more, not equal) and is also encoded in this argument. This argument is composed of eight chunks of eight hexadecimal characters each (64 characters in total). Each octet contains a textual representation of a little-endian hexadecimal number. The first octet contains the second argument, the second octet contains the operator (0 stands for "<", 1 - "<=", 2 - "=", 3 - ">=", 4 - ">", 5 - "!="), the next six octets are unused. See below for Condition check segment examples.
StartingWeight Specifies a floating point value that will be set as this AI Trigger's Starting Weight when the game starts. (See the section on Trigger Weights for more info.)
MinimumWeight Specifies a floating point value that will be interpreted as this AI Trigger's Minimum Weight. (See the section on Trigger Weights for more info.)
MaximumWeight Specifies a floating point value that will be interpreted as this AI Trigger's Maximum Weight. (See the section on Trigger Weights for more info.)
IsForSkirmish This AI Trigger is enabled in any game modes except Singleplayer Campaign if and only if this is set to an integer other than 0.
unused A value that is unused. Must not contain commas, always set to 0 in the game's (no longer used) data saving routines.
Side Indicates the Side that may use this AI Trigger. 0 stands for "all sides", positive values indicate the owning side - Allied, Soviet, Yuri, etc.

Note that in Tiberian Sun, this refers to the ActsLike setting of a house, incremented by one. For example, if this value is 1, the AI Trigger is applicable to any houses with ActsLike=0. If this value is 2, it is applicable to houses with ActsLike=1. And so on.

IsBaseDefense Unused, usually set to 0.
Team2 The second TeamType that will be created when this AI Trigger meets its condition.
EnabledInE If set to a zero value, this AI Trigger will not be considered by AI houses playing in Easy difficulty.
EnabledInM If set to a zero value, this AI Trigger will not be considered by AI houses playing in Normal difficulty.
EnabledInH If set to a zero value, this AI Trigger will not be considered by AI houses playing in Hard difficulty.

Condition check segment examples

For simplicity only the segments of ConditionType, ComparisonObject and first octet (amount) and second octet (Comparator) are shown. An octet consists of 8 hex digits (4 bytes). Values are in hexadecimal and represented in little endian format. For a decimal value of 3, its hex value is 0x3, its octet representation becomes 03000000. For a decimal value of 500, its hex value is 0x1F4, its octet representation becomes F4010000.

-1,<none>,0000000000000000 - no condition check, always true. TechType and the two octets are irrelevant and can hold any valid values.
0,GAREFN,0400000003000000 - when AI's enemy owns greater or equal to 4 allied ore refineries.
1,SHK,0300000001000000 - when AI's own troops has less than or equal to 3 shock troopers.
4,<none>,8813000003000000 - when AI's enemy has greater or equal to 5000 credits, hex value 0x1388, octet 88130000.

Weights

AI Triggers are given "weights" to define how important they are. Larger weight makes the AI Trigger more likely to get selected.

Each time an AI controlled team is dissolved (when they complete their script or are destroyed), all AI Triggers using that TeamType as their primary (Team1) get their weight modified:

if the Team has executed a Script Action 49, 0 in this lifetime,
[General]AITriggerSuccessWeightDelta= is added to its weight,
otherwise,
[General]AITriggerFailureWeightDelta= multiplied by [General]AITriggerTrackRecordCoefficient= (the former is usually negative) is added.

Care is taken not to push the weight outside the limits set by MinimumWeight and MaximumWeight while doing so.

Special Values

Weight 0

If an AI trigger's weight drops to zero, it will not be considered for production. This can be used to remove certain AI triggers from play for the rest of the game if they fail too many times.

Weight 5000

In Red Alert 2 and Yuri's Revenge, A Weight equivalent to 5000.0 stands for "ignore all other AI Triggers and fire this one immediately, if its condition is met". It is originally used for Teams utilising minor SuperWeapons, the Iron Curtain or the ChronoSphere.

Flawed Design

In the unmodified games, AI teams are typically configured to succeed after attacking a specific category of enemy targets (a quarry). Unfortunately, this attack mission, #0 Attack..., is only completed once all enemy objects matching the given quarry are destroyed. This means every such attack team has a slim to none chance of actually succeeding in its mission, causing their respective AI triggers to lose weight over time. The end result of this flawed design is that the production chances of AI triggers are almost entirely governed by their initial and minimum weights.

Global and Local

Unlike other AI components, AITriggerTypes do care where they were defined - the ones defined in ai(md).ini are enabled by default, whereas ones defined in the map need to be enabled via [AITriggerTypesEnable] to function. However, the [Basic]IgnoreGlobalAITriggers= setting, if enabled, disables all AI Triggers declared in ai(md).ini, overriding the [AITriggerTypesEnable].

Global AITriggerTypes can be redefined in the map.

Additional information

  • This section is read from ai(md).ini and the current map file.
  • The infamous -G suffix is used to distinguish global AITriggerTypes from local ones (which have no suffix). It has no effect however.
  • Unlike TaskForces, there is no effect to prefixing an AITriggerType's ID with a hexadecimal prefix.