Class: XGStrategyAI - XCOM:EU 2012

From Nexus Mods Wiki
Revision as of 23:37, 15 November 2018 by Dubiousintent (talk | contribs) (Added 'Category:Mod_Creation')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search



XGStrategyAI is a class of the UPK file XComStrategyGame.upk and contains most of the functions used to generate UFOs and missions, determine type and composition of alien squads, panic changes and so on. The class is further subdivided into Structures, Variables, Functions and Default Values. The most important functions will be mentioned below.

(PS: I've never formally learned coding so this are the interpretations of an untrained eye. Please correct what you see as wrong. - Hobbes77 13:41, 24 April 2014 (BST))

Programs and Tools


Primarily these are functions that establish missions and events. Note that most calls to other functions are within this same class.


Called by XGStrategy.Init.


Function AddAIEvent is used to add a game event (kEvent) to the array of events generated each month (THQEvent). Used by GetEvents.

Each kEvent added to the array consists of a mission, its target (country) and the number of hours it will be available:

  • eMission
  • eTarget
  • iHours


Not used by XGStrategyAI but by XGMissionControlUI.UpdateEvents

Function GetEvents updates the array of events for each month (<THQEvent> arrEvents), using AddAIEvent to fill it.

XGMissionControlUI.UpdateEvents also uses the GetEvents function present on several other classes (XGGeoscape, XGHeadquarters, XGExaltEntity, etc.) to keep arrEvents updated.

It checks for several conditions:

  • If iCouncilCounter > 0, it adds a Council mission to the array using AddAIEvent (11, m_iCouncilCounter / 2, 0)
  • If the all the entries on the array of objectives (arrObjectives) are marked as completed it does nothing, otherwise for each uncompleted objective it adds a mission (eMission):
    • If objective is 0 (Recon) it doesn't add a mission.
    • If objective is 1 (Scout) then eMission = 3 (Crash)
    • If objective is 3 (Flyby) and HQ doesn't have Facility 18 (Hyperwave Relay) then eMission = 0 (None), otherwise eMission = 12 (DLC)
    • If objective is 4 (Hunt), eMission = 5 (HQAssault)
    • If objective is 2 (Harvest), eMission = 4 (LandedUFO)
    • If objective is 5 (Abduct), eMission = 2 (Abduction)
    • If objective is 6 (Terrorize), eMission = 7 (TerrorSite)
  • If there's no last mission (for the month it calls function AddAIEvent(eMission, 0, byte(m_arrObjectives[iObjective].m_iCountryTarget), arrEvents)
  • Otherwise, it calls AddAIEvent (eMission, (m_arrObjectives[iObjective].m_iNextMissionTimer - m_iCounter) / 2, byte(m_arrObjectives[iObjective].m_iCountryTarget), arrEvents)
  • Function loops until all objectives have a mission added to the array of events


Function used when a new game is started.

  • Defines the start date based on the value located on XGDateTime as 00:00:00, March 1st, 2015
  • Sets the array arrUFOsShotDown with 10 entries
  • Sets the array TObjectives with 8 entries
  • Calls BuildObjectives function
  • m_kResistance.arrCountries.Add(36);
  • m_kResistance.arrNoResistance.Add(36);
  • m_kResistance.arrHunted.Add(36);
  • LogResistance(HQ().m_arrSatellites[0].iCountry);
  • CreateAlienBase - sets location of Alien Base
  • Defines TerrorCounter as 2
  • If ISCONTROLLED() is negative (no Tutorial active) calls function AIAddNewObjectives


Not called by XGStrategyAI, but by XGGeoscape.GameTick.

Calls functions


Called by XGGeoscape.SkyrangerReturnToBase and XGGeoscape.AdjustTimeForCurrentMap.

Calls functions:


Not called by XGStrategyAI, but by XGGeoscape.AIUpdate.

Calls functions AIUpdateMissions and UpdateObjectives


Called by Update.

Function defines iNumUnits = 1 and bPaydayUpdate = false

  • If each objective (kObjective) on the array arrObjectives hasn't been completed, it calls function Update
  • If the array FirstBlitzTargets > 0 (used to define the targets of Abductions)
    • FirstBlitzCounter is reduced by 1
    • If FirstBlitzCounter <= 0 then starts function LaunchBlitz and remove entry from array FirstBlitzTargets
  • Calls World, FundingCouncil.UpdateSlingshotMission
  • If the counter HQAssaultCounter > 0, it is reduced by 1
  • if((m_iHQAssaultCounter < 2) && iNumUnits > 1) then m_iHQAssaultCounter = 2
  • If the HQAssaultCounter is 0, and the Geoscape conditions isBusy and GetFinalMission are none, then AIAddNewMission(7, none)
    • Otherwise defines HQAssaultCounter = 1
  • If PaydayUpdate is false, then calls function EXALT().UpdateObjectives(iNumUnits) and adds 1 to the Counter


Boolean, not called by XGStrategyAI or any other class on XComStrategyGame.upk.

For each kObjective on arrObjectives:

  • Checks if (GetType) is equal to the eObjective, if so, returns it as true.
  • Otherwise returns false.


Called by AddLateMission and AIAddNewObjectives.

Defines the Council counter used on GetEvents, using the values COUNCIL_DAY (20.0) and COUNCIL_RAND_DAYS (7.0) found on XComGame.UPK, XGTacticalGameCore. If the Tutorial isn't activated, the CouncilCounter is defined as:

  • CouncilCounter = 20.0 * 48 (converts to half-hours)
  • CouncilCounter + random number (7.0 * 48 *2) - random (7.0 *48)


Not called by XGStrategyAI.

Sets counter for the Base Defense mission, using the values HQASSAULT_MAX_DAYS (21) and HQASSAULT_MIN_DAYS (14) found on XComGame.UPK, XGTacticalGameCore.

  • Multiplies final value by 48 to convert to half-hours.


Called by AIAddNewObjectives.

Used after the Alien Base is assaulted to add missions, generating the following integers: iNumCouncil, iNumTerror, iNumUFOs, iNumAbductions. It creates a local array of missions (arrMissions) then populates it according to the following:

  • If there's no Terror (iNumTerror == 0) mission present, it creates 1 on the array arrMissions
  • If there's no Council iNumCouncil == 0) mission present, it creates 1 on the array arrMissions
  • If arrAbductionTargets generated by function DetermineBestAbductionTargets => 3, it creates 1 on the array arrMissions
  • Roll for LATE_UFO_CHANCE is positive (50% odds) it adds 1 to iNumUFOs
  • Afterwards it randomly chooses 1 mission type from arrMissions
    • If choice is 9 it calls functions AddNewTerrorMission and DetermineBestTerrorTarget and adds 1 to iNumTerror
    • If choice is 11 it calls functions AddCouncilMission and adds 1 to iNumCouncil
    • If choice is 2 it adds 1 to iNumAbductions


Used by:

Generates missions using the following integers: iNumCouncil, iNumTerror, iNumUFOs, iNumAbductions.

  • Checks for the game month (March = 0)
  • If the condition ceil (month, 2) it calls AddCouncilMission and adds to iNumCouncil
  • If the TerrorCounter is less or equal to 0 it calls AddNewTerrorMission and DetermineBestTerrorTarget, adds iNumTerror and resets the TerrorCounter to 2.
  • Sets both iNumUFOs and iNumAbductions equal to 1
  • If item 171 (Hyperwave Beacon) was ever present in storage it calls function AddLateMission
    • Otherwise adds iNumAbductions
    • If the month is April or May rolls for EARLY_UFO_CHANCE (50%), if successful, it adds again iNumUFOs for a 2nd UFO to appear during the month
    • It then runs AddNewAbductions and if the 2nd Abductions mission wasn't added, it adds +1 to iNumUFOs
    • It then ensures that the number of UFOs doesn't exceed the limit (2 UFOs), defined on UFO_LIMIT (on XGTacticalGameCore)
    • Creates an array of visible targets (with sats deployed) using DetermineBestVisibleTargets
    • Runs AddUFOs with the previously defined iNumUFOs and arrVisibleTargets
    • Runs AddNewOverseers


Used by GetNumAbductionSites

Sets the maximum limit of Abductions sites to 3.


Called by AIAddNewObjectives.

  • Uses DetermineBestAbductionTargets to determine how many possible target countries are present. If there's only 1 or 0 it doesn't add any Abductions.
  • If the boolean FirstBlitz is positive, it calls CreateAbductionBlitz (arrAbductionTargets, GetNumAbductionSites(), 1 + Rand(7) and removes 1 from iNumAbductions
  • Sets iAbduction = 0 and if(iAbduction < iNumAbductions)
    • Defines iNumTargets as the minimum value between the one defined by GetNumAbductionSites and the length of arrAbductionTargets
    • If the the length of arrAbductionTargets < 2, removes 1 from iNumAbductions
    • Otherwise:
      • If playing on the Tutorial the date for the first Abductions is set for the 24th
      • If not, the 1st Abductions can take place on the first 8 days (randomly chosen), and the 2nd Abductions on 11 + random 14
      • It then calls AddAbductionObjectives with (iNumTargets, iStartDate, arrAbductionTargets) already defined.


Called by AddLateMission and AIAddNewObjectives.

  • Sets iStartDate as 0
  • Runs ClearFromAbductionList
  • Randomly chooses a city from that country
  • Runs AIAddNewObjective and adds entry with the following values (6, iStartDate, CITY(iCityTarget).GetCoords(), eTarget, iCityTarget);


Called by LogUFORecord.

AddHuntTarget is used to add an UFO on a Destroy Satellite mission and to determine the UFO type, depending on the difficulty level.

  • Checks IsCountryBeingHunted
  • If difficulty <= 1 (Easy/Normal) then iMonthCutoff = 3 (June)
  • If difficulty = 2 (Classic) then iMonthCutoff = 2 (May)
  • Else (Impossible difficulty) iMonthCutoff = 1 (April)
  • If the current month => iMonthCutoff then eHunter (UFO type) = 8 (Battleship)
  • Otherwise eHunter (UFO type) = 5 (Large Scout)
  • Runs AIAddNewObjective with the following values (4, Rand(5), HQ().m_arrSatellites[HQ().GetSatellite(eTargetCountry)].v2Loc, eTargetCountry, eHunter);


Boolean, called by AddHuntTarget.

Determines if a country is being targeted for a Destroy Satellite mission.

  • If the Type 4 objective (Hunt) on the array of Objectives hasn't been completed and CountryTarget = eTargetCountry returns true.
  • If the Type 4 objective (Hunt) on the array of OldObjectives hasn't been completed and CountryTarget = eTargetCountry returns true.
  • Otherwise returns false.


Called by AddNewOverseers.


It is run by AIAddNewObjectives.

Adds Overseer UFOs each month but with a different mission than the one revealed once the Hyperwave Relay is built.

  • Checks if Storage ever had item 180 (Psi Link). If positive, it doesn't add any Overseers.
  • Uses DetermineBestVisibleTargets to create an array of targets (arrVisible)
  • Determines the number of Overseers to be added by choosing the minimum value between 3 and the length of arrVisible
  • Sets iMission = 0
  • If iMission < number of added Overseers:
    • If the game difficulty > 1 (Classic/Impossible) randomly chooses a country (eTargetCountry) from arrVisible and removes the choice from the array
    • Else, determines eTargetCountry using ChooseOverseerTarget
    • Finally, adds entry using AIAddNewObjective with the following values (3, 5 + (10 * iMission), Country(eTargetCountry).GetCoords(), eTargetCountry, 9) and adds 1 to iMission
  • Repeats until iMission = number of added Overseers.

Addendum: When the Overseer is detected by the Hyperwave Relay, it will have the eObjective = 7 "Final Preparations" rather than eObjective = 3 "Target Reconnaissance". This change is made on XGAlienObjective.Init


This function is empty and it is only used by OnObjectiveEnded. Basically an Overseer overflying a country will not generate any additional mission.


Called by:

MakeUFO creates an entry called kUFO, composed of 2 values:

  • eUFO (type of UFO, taken from the EShipType list on XComGame.XGGameData)
  • eObj (UFO objective, taken from the EAlienObjective list on XGStrategyActorNativeBase)


Used by AddUFOs.

This function uses both AddUFOToPool and MakeUFO to create a monthly pool of possible UFOs types for the Scout Target and Harvest Live Specimens objectives.

  • If iMonth => 0 (March)
    • AddUFOToPool(MakeUFO(4, 1))
    • AddUFOToPool(MakeUFO(4, 1))
  • If iMonth => 1 (April)
    • AddUFOToPool(MakeUFO(4, 2))
    • AddUFOToPool(MakeUFO(5, 1))
    • AddUFOToPool(MakeUFO(5, 1))
  • If iMonth => 2 (May)
    • AddUFOToPool(MakeUFO(5, 2))
    • AddUFOToPool(MakeUFO(6, 1))
  • If iMonth => 4 (July)
    • AddUFOToPool(MakeUFO(6, 2))
  • If iMonth => 5 (August)
    • AddUFOToPool(MakeUFO(7, 1))
  • If iMonth => 6 (September)
    • AddUFOToPool(MakeUFO(7, 2))
  • If iMonth => 7 (October)
    • AddUFOToPool(MakeUFO(8, 1))

eUFO = 4 (Small Scout), eUFO = 5 (Large Scout), eUFO = 6 (Abductor), eUFO = 7 (Supply Barge), eUFO = 8 (Battleship)


Used by AddUFOs.

Adds 2 dates to the array arrDates with the values of 9 and 16.


Used by AddUFOs and FillUFOPool.

Adds an entry (kUFO) to the array arrPool, with the following fields

  • eUFO
  • eObj


Called by ChooseUFO.

Chooses a country (iCountry) for a UFO mission.

  • If arrCountries > 0 then makes a 75 roll.
    • If positive, the country chosen (iChoice) is the first entry on arrCountries
    • Else randomly chooses from all countries present on arrCountries
    • Sets iCountry as iChoice
    • If arrCountries > 1, it removes iChoice from the array
  • If arrCountries = 0 it uses World.GetRandomCouncilCountry to determine iCountry


Used by ChooseUFOMissionType to prevent the same UFO type appearing on two consecutive missions.

Checks if the eUFO value on the kUFO different from the one used on the last mission.


Used by ChooseUFOMission

Checks to see if the UFO alien crew is compatible with the type of UFO.


Used by ChooseUFO to determine the iUFOChoice value.

  • Defines iUFO = 0 and iCounter = 4
  • If iUFO < length of arrUFOs then
    • If the entry on arrUFOs has eObj = 1 (Scout Target) it adds the iUFO value as item to arrShootDowns
    • All other entries with eObj different from 1 are added as items to arrLanded
    • Adds 1 to iUFO and repeats
    • Defines iUFOChoice = -1
  • If iUFOChoice = -1 and -- iCounter > 0
    • If length of arrShootDowns > 0 AND a positive roll of UFO_INTERCEPTION_PCT (66%)
    • If length of arrLanded > 0 AND iUFOChoice = -1
    • If iUFOChoice is still -1
      • iUFOChoice is determined choosing randomly from arrUFOs


Creates UFOs, used by AddUFOs.

  • Defines iUFOMission using ChooseUFOMission (using the arrUFOs generated by AddUFOs for the type)
  • Defines iDateChoice randomly choosing a date from the arrDates created by FillDatePool
  • Determines iCountry using the arrCountries generated by ChooseUFOTarget
  • Adds to AIAddNewObjective an entry with the following parameters: arrUFOs[iUFOChoice].eObj, arrDates[iDateChoice], Country(iCountry).GetCoords(), iCountry, arrUFOs[iUFOChoice].eUFO)
  • Sets the iChoice entry on arrUFOs as LastUFO
  • Removes date and UFO type from arrDates and arrUFOs


AddUFOs is called by AIAddNewObjectives and uses the iNumUFOs value determined by it, as well as the array arrVisible created by DetermineBestVisibleTargets. AddUFOs generates an array (arrUFOs) of UFOs for each month and uses ChooseUFO to choose from the array and add them to the game (or even adds them directly on the 1st month by using AIAddNewObjectives).

  • Uses FillDatePool to create an array of dates (arrDates)
  • Checks current month (iMonth)
  • If iMonth = 0 (March)
    • Runs AIAddNewObjective(0, 0, HQ().GetCoords(), arrVisible[0]) to create the 1st UFO
    • Decreases iNumUFOs by 1
    • AddUFOToPool(MakeUFO(4, 1))
  • If iMonth = 1 (April)
    • Adds items to arrUFOs by using MakeUFO(4, 2) and MakeUFO(5, 1)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
    • Runs AddUFOToPool using the remaining entries on arrUFOs
    • Runs AddUFOToPool(MakeUFO(5, 1))
  • If iMonth = 2 (May)
    • Adds items to arrUFOs by using MakeUFO(5, 2) and MakeUFO(6, 1)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
    • Runs AddUFOToPool using the remaining entries on arrUFOs
  • If iMonth = 3 (June) it does nothing
  • If iMonth = 4 (July)
    • Adds items to arrUFOs by using MakeUFO(6, 2)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
  • If iMonth = 5 (August)
    • Adds items to arrUFOs by using MakeUFO(7, 1)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
  • If iMonth = 6 (September)
    • Adds items to arrUFOs by using MakeUFO(7, 2)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
  • If iMonth = 7 (October)
    • Adds items to arrUFOs by using MakeUFO(8, 1)
    • Runs ChooseUFO(arrUFOs, arrDates, arrVisible)
    • Decreases iNumUFOs by 1
  • Sets iUFO = 0
  • if iUFO < iNumUFOs
    • If m_arrPool has no entries, it runs FillUFOPool
    • If arrDates has no entries, it runs FillDatePool
    • It then runs ChooseUFO (m_arrPool, arrDates, arrVisible)
  • Adds 1 to iUFOs and keeps running until iUFO = iNumUFOs


  • On March the AI adds automatically the 1st UFO (Flying Small Scout) but it has determined that iNumUFOs is always 1 so that will be the only one seen. However it also adds a Flying Small Scout to the pool.
  • On April the AI will choose between a Landed Small Scout or Flying Large Scout from arrUFOs for the 1st UFO encountered. The choice will be removed from arrUFOs.
    • If the 2nd UFO is generated it will be chosen from the arrPool, which will have the Flying Small Scout added on March, plus a Flying Large Scout and the discarded choice of arrUFOs (either a Landed Small Scout or Flying Large Scout), removing the choice.
  • On May, the choice for the 1st UFO will be between a Landed Large Scout or a Flying Abductor and any arrUFOs entries not used on April.
    • If the 2nd UFO is generated it will be chosen from arrPool, which will have added to it the 1st unused entry UFO on arrUFOs.
  • On June the choice for the 1st UFO will be from any leftover entries on arrUFOs. If there are none, then the game starts using the entries on arrPool and randomly chooses between them, and removing the choice from arrPool. If the arrPool has no entries it runs AddUFOtoPool and inserts all entries for that month and the previous ones (on June: 2 Flying SS, 1 Landed SS, 2 Flying LS, 1 Landed LS, 1 Flying Abductor).
    • From this month onwards, the 2nd UFO will only be generated if the alien base has been assaulted or if there were no 2nd round of Abductions added due to a lack of sufficient countries without sats. The 2nd UFO will also be chosen from arrPool and removed from that list, with the list refreshed when there's no more entries available.
  • From July onwards, the 1st UFO will be a specific one (July = Landed Abductor, August = Flying Supply Barge, September = Landed Supply Barge, October = Flying Battleship).
    • The AddUFOtoPool also contains entries adding these UFOs to the pool choices on the month they appear.


Used by PickAbductionTargets

  • If there's no entries on arrAvoid, returns arrCountries


  • Gets the eCont value on each country on arrCountries
  • If it searches eCont in arrAvoid and the result is negative, adds Country to arrFiltered
  • Repeats until all countries are checked
  • Returns arrFiltered

Note: seems used to ensure that target cities in different continents are selected.


Used by AddAbductionObjectives and CreateAbductionBlitz.

  • Sets the number of iNumberCities = length of arrCountries
  • Defines arrFiltered using FilterCountries (arrContinents, arrCountries)
  • If length of arrFiltered = 0, then arrFiltered = arrCountries
  • Randomly chooses 1 country from arrFiltered
  • Gets random city from Country
  • Adds choice to arrContinents and arrTargetedCities, removes choice from arrFiltered.
  • Repeats the number times defined in iNumberCities
  • Returns arrTargetedCities

Note: uses FilterCountries to try to assign different countries (arrFiltered), otherwise uses arrCountries.


Used by AddNewAbductions

  • If iNumAbductions <= 0 returns
  • Defines arrTargetCities through PickAbductionTargets, using iNumAbductions and the arrCountries
  • For each item (kTargetCity) on arrTargetCities it adds an item to arrLinkedObjectives using AIAddNewObjective (5, iStartDate, kTargetCity.GetCoords(), kTargetCity.GetCountry(), arrTargetCities[I])
  • Adds the previously created kObjective on arrLinkedObjectives to arrSimultaneousObjectives
  • Return


Called by by several functions:

Used to generate UFOs tasked with filling specific objectives (kObjective):

  • Spawns kObjective from the list of objectives at class XGAlienObjective
  • Each kObjective consists of:
    • m_arrTObjectives[eObjective]
    • iStartDate
    • v2Target
    • iCountry
    • iCity (optional)
    • eUFO (optional)
  • Adds kObjective to array arrObjectives


Used by OnObjectiveEnded

Causes a targeted country to leave the Council, with the corresponding Geoscape alert.


Used by XGAlienObjective.LaunchUFO. Not used by any other function on XGStrategyAI.

Adds item kUFO to arrUFOs.


Used by:



Used to update the list of current missions and remove/record missions failures.

Called by:


Used by Geoscape?


Used by Geoscape?














Used by AddNewAbductions to create the first Abductions.

  • If ISCONTROLLED (Tutorial active)
    • randomly chooses 2 cities from N. America and Asia and adds them to arrCities
    • Removes choices from arrPossibleTargets
    • Sets iStartDate = 1
  • Otherwise
    • arrCities is chosen using PickAbductionTargets (iNumTargets, arrPossibleTargets)
    • Each item on arrCities is added to m_arrFirstBlitzTargets
    • Sets m_iFirstBlitzCounter = iStartDate * 48


Used by UpdateObjectives CheatAbduction and CheckForAbductionBlitz.

  • If boolean bFirstBlitz is positive, it defines the arrRewards as Credits, Scientists or Engineers
  • If boolean bFirstBlitz is negative, it adds Soldier, Credits, Scientists or Engineers) to arrRewards
  • For each city on arrTargetCities it randomly chooses a reward and removes it from arrRewards
  • Defines eDiff using GetAbductionDifficulty
  • Spawns kMission with kDesc, iCity, iCountry, iContinent, iDuration, v2Coords, kAlienSquad (using DetermineAbductionSquad and eDiff), eDiff.
  • Determines DetermineAbductionReward (kReward, eDiff, eReward)
    • Determines either the Tutorial 2 N. America and Asia Pier A maps for the mission, giving each a different reward (engineers, scientists).
    • Sets iMissionType on kMission.m_kDesc as 11 (Special)
  • Runs GEOSCAPE.AddMission
  • Creates kAlert
  • Runs GEOSCAPE.Alert(kAlert)


Used to determine the difficulty level (iDifficulty) of each abduction (Easy, Moderate, Difficult, Very Difficulty). Called by LaunchBlitz.

  • iDifficulty = Game Act (1 = game start, 2 = after capturing and interrogating 1st alien, 3 = after assaulting alien base) - 1
  • iDifficulty is then added the number of panic blocks of the country (1-5)
  • iDifficulty is then added a random number between 0 and 2
  • If the difficulty level is 3 (Impossible) iDifficulty +1
  • Final iDifficulty value is clamped between 0 (Easy) and 3 (Very Difficult)
  • If IsControlled (Tutorial), iDifficulty is 0
  • Returns iDifficulty value


Used by OnObjectiveEnded and ClearFromAbductionList. First function is only used by class XGAlienObjectives while the second section is called by AddNewTerrorMission.

Uses kObj (defined on XGAlienObjectives) to create an array (arrAbductions) and for each kObj checks:

  • If they are launched Abductions
  • If they haven't been completed
  • If the last mission has been successful, adds to array arrTargetCities the iCityTarget defined on kObj

Then, for each item on arrAbductions:

  • Sets field AbductionLaunched as true

If the length of arrTargetCities > 0 calls LaunchBlitz using the array arrTargetCities. At the end returns.

This function seems to check if the UFO scouts have detected cities and launching the abduction missions on those cities.


Used by LaunchBlitz to determine the actual rewards from each mission. If the Second Wave's option High Stakes (option 11) is enabled, it calls instead function DetermineRandomAbductionReward.

  • If reward type 1, uses the ABDUCTION_REWARD_CASH default value
  • If reward type 2, uses the ABDUCTION_REWARD_ENG default value
  • If reward type 3, uses he ABDUCTION_REWARD_SCI default value
  • If reward type 0, calls function BARRACKS.PickRewardSoldierClass and clamps the returning value to 3 (Sergeant), 5 (Captain) or the rank below the highest already existing rank.


Used by DetermineAbductionReward to determine the actual rewards from each mission. If the Second Wave's option High Stakes (option 11) is enabled.

  • If reward type 1, uses the ABDUCTION_REWARD_CASH default value (200) / 2 + a random number between 0 and 200
  • If reward type 2, uses the ABDUCTION_REWARD_ENG default value (5) / 2 + a random number between 0 and 6
  • If reward type 3, uses he ABDUCTION_REWARD_SCI default value (5) / 2 + a random number between 0 and 6
  • If reward type 0, calls function BARRACKS.PickRewardSoldierClass and clamps the returning value to 3 (Sergeant), 5 (Captain) or the rank below the highest already existing rank.






Function is not called by XGStrategyAI class.

Returns arrUFOs[iUFOindex]


Used by OnUFODestroyed, ClearFromAbductionList, DestroyObjective, DestroyZombieUFOs and CreateCrashMission.

  • Calls function GEOSCAPE().RemoveUFO(kUFO)
  • Removes item kUFO from arrUFOs


Function is not called by XGStrategyAI class.


Function is not called by XGStrategyAI class. Uses variables XGShip_Interceptor kJet, XGShip_UFO kUFO.

  • Calls NotifyOfCrash (probably on Geoscape)
  • Calls DetermineCrashLoot with the kUFO value and checking the kJet weapon used (EMP Cannon more loot, etc.)
  • Calls AIAddNewMission (3, kUFO)
  • Adds stats for profile and achievements.
  • Calls AddPanic to apply the PANIC_UFO_SHOOTDOWN reduction over the country where kUFO was shot.
  • Calls RecordCountryHelped to record that the country has been helped
  • Calls CheckForHunterKiller to check for Steam achievement.
  • Returns


  • Called by OnUFOShotDown
  • Sees if arrUFOsShotDown contains 1 or more entries for all UFO types as condition for the Hunter Killer achievement.


Function is not called by XGStrategyAI class.

  • If game difficulty is Normal or higher, and if the kObjective of the UFO is not 4 (Hunt for sats), it sets the TimeInCountry field of kUFO to 0.0

Note: Unsure of what this value is used for. Possible to prevent a retaliation UFO from being generated as long as the 1st UFO is intercepted.


Returns the game's time to be used by AI in several functions to time the appearance of new alien species and UFOs:

  • It returns the iMonth value, 0 on March, then uses DifferenceInMonths on GEOSCAPE to calculate the current value.
  • If Second Wave's option 21 (Marathon) is enabled, the iMonth is instead calculated with the formula ((iMonth + 1) / 2)


Not used by XGStrategyAI.

  • It returns the iDay value, 0 on March, then uses DifferenceInDays on GEOSCAPE to calculate the current value.


Used by OnUFOShotDown. Actual amounts of UFO salvage are determined on the DetermineShipSalvage function at XGItemTree class and CreateAlienBase.

  • If item = 170 , sets iSurvivalChance with the value on UFO_PS_SURVIVE (33)
  • If item = 168 , sets iSurvivalChance with the value on UFO_NAV_SURVIVE (50)
  • If item = 166 , sets iSurvivalChance with the value on UFO_FOOD_SURVIVE (25)
  • If item = 165 , sets iSurvivalChance with the value on UFO_ENTERTAINMENT_SURVIVE (25)
  • If item = 167 , sets iSurvivalChance with the value on UFO_STASIS_SURVIVE (25)
  • If item = 169 , sets iSurvivalChance with the value on UFO_SURGERY_SURVIVE (25)
  • If default sets iAlloySurvival, chosen randomly between MIN_WRECKED_ALLOYS (0.50) and MAX_WRECKED_ALLOYS (0.75)
  • If eWeapon = 6 (EMP Cannon), iSurvivalChance is 100 and iAlloySurvival is 1.0
  • If item = 162 (Alien Alloys), iSurvived = iTotal * iAlloySurvival
  • For everything else, iSurvived = GetSurvivingCollectibles (iTotal, iSurvivalChance)

After calculating the iSurvived:

  • If item = 170 (Power Source), the salvage of item = 161 (Elerium) is calculated through:
    • A random number is calculated within the range of (MIN_LOST_WRECKED_ELERIUM (0.50) * UFO_ELERIUM_PER_POWER_SOURCE (30 on Easy, 25 on the other difficulties) and (MAX_LOST_WRECKED_ELERIUM (0.75) * UFO_ELERIUM_PER_POWER_SOURCE (30 or 50))
    • This number is then multiplied by the result of (iTotal - iSurvived)
    • Elerium salvaged is reduced by this number
  • If item = 170 , sets Salvage = iTotal - iSurvived
  • If item = 168 , sets Salvage = iTotal - iSurvived
  • If item = 166 , sets Salvage = iTotal - iSurvived
  • If item = 165 , sets Salvage = iTotal - iSurvived
  • If item = 167 , sets Salvage = iTotal - iSurvived
  • If item = 169 , sets Salvage = iTotal - iSurvived


Used by DetermineCrashLoot.

  • Each iItem has a random check using its iSurvivalChance, if it survives it is added to iSurviving and the value returned.


Used by InitNewGame (adds the starting country).

  • Adds + 1 to field Resistance for each iCountry entry on arrCountries
  • Sets to 0 the field Resistance for each iCountry entry on arrNoResistance


Not used by XGStrategyAI.

  • If the field Resistance on the iCountry entry on arrCountries > 0
  • Adds +1 to the field Resistance for each iCountry entry on arrNoResistance


Used by OnObjectiveEnded.

  • Calls function RemoveSatellite(iCountry) on class XGHeadQuarters
  • Creates alert (MakeAlert) on GEOSCAPE
  • Uses AddPanic to apply the panic results on both the iCountry and the iContinent
  • Adds +1 to field Monthly.iSatellitesLost on the iContinent
  • Sets Resistance.arrCountries[iCountry] = 0
  • Sets Resistance.arrNoResistance[iCountry] = 0
  • Adds 1 to Stat 24
  • For each item on arrUFOs
    • Sets field DetectedBy as negative
    • Calls functions SetDetection and DetectUFO on GEOSCAPE


Used by InitNewGame and EndOfMonth to create a template of objectives and UFO missions assigned to them. The entries appear to be latter overwritten by AIAddNewObjectives. Possibly also used to generate test missions when using the Developer Console.

  • BuildObjective(1=Scout, false)
  • AddUFOMission(Scout, start day 1, SmallScout, QuickScout, -1 radius, 7 rand days)
  • BuildObjective(3=Flyby, false)
  • AddUFOMission(Flyby, start day 1, SmallScout, Flyby, -1 radius, 7 rand days)
  • BuildObjective(2=Harvest, false)
  • AddUFOMission(Harvest, start day 1, SmallScout, QuickSpecimen, -1 radius, 7 rand days)
  • BuildObjective(4=Hunt, false)
  • AddUFOMission(Hunt, start day 1, LargeScout, Seek, -1 radius, 1 rand days)
  • BuildObjective(0=Recon, false)
  • AddUFOMission(Recon, start day 10, SmallScout, QuickScout, -1 radius, 5 rand days)
  • BuildObjective(5=Abduct, true)
  • AddUFOMission(Abduct, start day 1, LargeScout, QuickScout, 500 radius, 1 rand days)
  • AddUFOMission(Abduct, start day 3, Abductor, Direct, 0 radius, 0 rand days)
  • BuildObjective(6=Terrorize, false)
  • AddUFOMission(Terrorize, start day 9, Battleship, Flyby, 100 radius, 3 rand days)
  • AddUFOMission(Terrorize, start day 20, Battleship, Direct, 0 radius, 7 rand days)
  • BuildObjective(7=Infiltrate, true)
  • AddUFOMission(Infiltrate, start day 1, Overseer, LongScout, 100 radius, 0 rand days)
  • AddUFOMission(Infiltrate, start day 4, Overseer, Direct, 0 radius, 3 rand days)

Note: The game never generates missions of Objective 7 type. However, the game has been modded to launch UFOs in this type of mission.


Function is used by CheckIsComplete on class XGAlienObjective. Calls for further alien missions, if the last one has been successful.

  • Checks if the boolean LastMissionSuccessful on each kObj is true. Then, for each type of objective:
    • If type is 5 (Abduct) it calls CheckForAbductionBlitz(kObj.m_arrSimultaneousObjs)
    • If type is 6 (Terrorize) it calls AIAddNewMission with a value of 9, which then calls CreateTerrorMission
    • If type is 7 (Infiltrate, it calls function SignPact with the values of kLastUFO, kObj.m_iCountryTarget)
    • If type is 4 (Hunt), it checks and if kObj has boolean FoundSat positive, it calls OnSatelliteDestroyed
      • Else, it sets the satellite as hidden
    • If type is 3 (Flyby) and kLastUFO = 9 (Overseer), it runs OnEtherealFlyby(kLastUFO), which results in no follow up mission.


Used by LogUFORecord. Uses XComGame.XGGameData.EShipType and XGStrategyActorNativeBase.EUFOMissionResult enums.

  • If eUFO = 9 (Overseer) returns false
  • If eResult different from 1 (Detected) returns false
  • If difficulty is 3 (Impossible) returns true
  • If eUFO = 8 (Battleship) returns negative
  • If difficulty is <= 1 (Easy/Normal) and length arrSatellites < 2 returns negative
  • Otherwise, return positive


Creates array arrUFORecord and defines kRecord with the fields:

  • eUFO (kUFO.m_kTShip.eType)
  • eObjective (kUFO.m_kObjective.m_kTObjective.eType)
  • eResult
  • ECountry (using GetCountry) and month (using GetMonth)

It then checks:

  • If eUFO = 9 (Overseer), return
  • If eResult different from 0 (Undetected):
    • If eObjective different from 4 (Hunt):
      • If eResult = 1 (Detected)
        • Sets boolean UFOIgnored as true on GEOSCAPE
        • Calls AddPanic, adding to kCountry the PANIC_UFO_IGNORED value on class XGTacticalGameCore
      • Else, if eResult = 2 (Intercepted)
        • Calls AddPanic, adding to kCountry the PANIC_UFO_ESCAPED value on class XGTacticalGameCore
      • If boolean ShouldHunt is true
    • If eObjective different from 5 (Abduct) or 6 (Terrorize)
      • Adds kContinent and kCountry of the UFO to the kRecord on the arrUFORecords
  • Return


Not used by XGStrategyAI. Called by XGGeoscape.RemoveMission.

  • If difficulty = 0, switches to the values defined on XGTacticalGameCore and defines:
  • Does the same to the rest of the difficulty levels
  • Then, as default
    • Gets kCountry and kContinent from kMission
    • For each MissionType on kMission:
      • If mission = 2 (Abductions)
        • kContinent.m_kMonthly.iAbductions += 1
        • kResultContinent.eContinentAffected = kContinent byte value
        • kResultCountry.eCountryAffected = kCountry byte value
        • If boolean XComSuccess is positive:
          • Defines kContinent.PanicChange using PANIC_ABDUCTION_THWARTED_CONTINENT
          • Defines kCountry.PanicChange using PANIC_ABDUCTION_THWARTED_COUNTRY
          • kContinent.m_kMonthly.iAbductionsThwarted +1
        • Otherwise, if negative:
          • kContinent.PanicChange = iContPanic
          • kCountry.PanicChange = iCountryPanic
          • kContinent.RecordCountryNotHelped is added the value of the country
        • If kResultContinent.iPanicChange != 0 and boolean DontApplyToContinent is negative
          • Adds the kResultContinent.eContinentAffected value to the panic levels of the rest of the continent
          • Adds result kResultContinent as kLastResult to arrContinentResults

Work in progress



Used by AddNewAbductions and AddLateMission.

  • Goes through the all entries on list of countries on XComGame.XGGameData.ECountry and doesn't do anything if the following apply to each country:
    • Country does not belong to the Council
    • Country has left XCOM
    • Country has satellite
    • Country has been targeted for Terror mission
  • Otherwise, adds country to arrPossibleCountries
  • Returns arrPossibleCountries

Note: AddLateMission and AddNewAbductions use this function to generate arrAbductionTargets instead of arrPossibleCountries.







Used to ensure that Overseers will be generated over countries located in continents with Firestorms assigned. Used by DetermineBestOverseerTargets and XGAlienObjective.LaunchUFO

  • If kCountry has SatelliteCoverage it then:
    • Checks if arrJets > 0 and if iJet = Firestorm, if positive returns true value
    • Otherwise returns false and keeps checking for all continents with countries that have sats deployed
  • Otherwise Returns false


Used by ChooseOverseerTarget and XGAlienObjective.OverseerUpdate.

  • Checks each country with the IsGoodOverseerTarget function
  • If true, it adds the eTargetCountry to arrTargets
  • After it finishes and if arrTargets length is 0, it determines arrTargets = DetermineBestVisibleTargets(true)
  • Returns arrTargets


Used by DetermineBestOverseerTargets, AIAddNewObjectives and AddNewOverseers.

  • Checks each eTargetCountry with HasSatelliteCoverage
  • If true, it adds eTargetCountry to a random position on arrTargets
  • After all eTargetsCountry are checked, it sees if boolean bUnsorted is negative, if so, it sorts arrTargets
  • Returns arrTargets




Creates a template of eObjective for arrObjectives, is used by BuildObjectives. Template consists of:

  • strName
  • eType
  • bAbandonMission (boolean, if true the 2nd mission will be aborted if the 1st is shot down)


Called by BuildObjectives. Expands the eObjective template used by arrObjectives by adding the following items from several arrays:

  • iStartDate from arrStartDates
  • eUFO from arrUFOs (defined by ChooseUFO and AddUFOs)
  • eMission from arrMissions
  • iMissionRadius from arrRadii





Referred to by this article:

That refer to this article:

  • None as yet