Initial soldier appearance - XCOM:EU 2012
Overview
The following is derived from discoveries in the Nexus XCOM Mod Talk forum threads Unlock all Decorative Armors for all Armors, Cybernetic Warfare Mod ideas and Planning, Initial soldier appearance, and the wiki article DefaultLoadouts.ini.
DefaultLoadouts.INI consists of the inventory of Soldiers and Aliens, and CharacterLoadouts of Aliens. (See wiki article DefaultLoadouts.ini for details.) Some initial inventory changes are a simple text edit to that file, such as selecting different armor or weapon packages. Unfortunately, changing the initial appearance of Soldiers in matters like color schemes or whether or not they have helmets requires more complex changes, from enabling the decorative armors to modifying the XComGame.UPK function: XGCharacterGenerator.CreateTSoldier.
Programs and Tools
Details
Most games since the release of Windows Vista write stuff into My Games because the game folder itself is often in Program Files which the Windows OS now makes inaccessible to alteration for security reasons.
For instance, XComGameCore.ini resides in the My Games\XCOM Enemy (Unknown/Within)\XComGame\Config folder. It is a mirror copy of the DefaultGameCore.ini file found in the game config folder: <Steam install path>\XCOM - Enemy Unknown[\XEW]\XComGame\Config. (Note that EW files are located under the XEW folder that is added to the XCOM - Enemy Unknown folder when that expansion is added.) Making changes to XComGameCore.ini won't work because the original DefaultGameCore.ini file would overwrite it at game launch.
INI files that begin with the word Default (i.e. DefaultContent.INI) and found in the install path get combined with DLC content INI files, which begin with the word XCom (i.e. XComContent.INI) and also are found within the install path. They are automatically merged together into a XCom pre-fixed version of the file located in the My Games folder (i.e. XComContent.INI), if they do not exist. DLC content uses this merged version of the file. If you make changes to the Default versions later, double-check those changes are propagated to the My Games folder XCom versions of the same files.
Decorative Armors, Basic Game
Edit <Steam install path>\XCom-Enemy-Unknown[add \XEM for EW]\XComGame\Config\DefaultGame.INI by adding the following to the end of the file:
[XComStrategyGame.XGCustomizeUI] bArmorDecoAvailable=true bArmorTintAvailable=true
This enables the embedded decorative armor and tints art assets.
Decorative Armors are defined as kits in the <Steam install path>\XCom-Enemy-Unknown[\XEM]\XComGame\Config\DefaultContent.INI file. You need to replace all the current ArmorDeco= lines with the following:
ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar0) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar1) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar2) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton0) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton1) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton2) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace0) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace1) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace2) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost0) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost1) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost2) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan0) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan1) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan2) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel0) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel1) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel2) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi0) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi1) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi2)
Then it is necessary to modify the <Steam install path>\XCom-Enemy-Unknown[\XEM]\XComGame\DLC\PCConsole\DLC_PackIn\Config\XComContent.INI file in a similar fashion. Remove all the "; (Armor Name) Deco 0" lines and replace them with the following code:
; Kevlar Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Kevlar Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Kevlar Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Skeleton Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Skeleton Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Skeleton Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Carapace Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Carapace Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Carapace Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Ghost Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Ghost Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Ghost Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Titan Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Titan Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Titan Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Archangel Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Archangel Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Archangel Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Psi Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Psi Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Psi Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0")
This assigns the decorative versions of various armor kits to the standard armor types. NOTE: Some decorative kits depend upon having purchased specific DLC content. Otherwise the specific art assets are not present. See the Separate Content section for including the Slingshot DLC decoratives.
As a side note: the decorative armors were only designed to go with their base armors and do have some clipping issues with the other armor. Some more seriously than others: mainly the Carapace doesn't play well with others.
Initial Appearance
Normally it would still be necessary to assign these customizations to each soldier individually within the Barracks. But the Soldier's initial appearance can be set in XComGame.UPK, XGCharacterGenerator.CreateTSoldier.
We already touched this topic in the Cybernetic Warfare Mod ideas and Planning thread, point 2: Helmets for everybody! Especially for starting and hired soldiers. With new shiny armor tint! The hex changed, but process is the same.
Helmets have to be filled into an array by GetContentIds calls and a loop clearing helmets from the array has to be disabled. Then it takes 2 new lines before calling return kSoldier:
kSoldier.kAppearance.iHaircut = Hairs[X]; kSoldier.kAppearance.iArmorTint = X;
Where "X" is your desired Base Soldier "Customize" User Interface (UI) spinner number; as for example:
- .iHaircut = Hairs[10];
- .iArmorTint = 0; // for standard; no tint
in the image below.
[Image by eld10, used with permission.]
For details as to how the "packages" in the INI files are turned into Base Soldier "Customize" User Interface (UI) spinner numbers, see the UI Customization Process in the Separate Content section.
To customize the colors and tints used for Armor, Skin, and Hairs, see the wiki articles Color Palettes - XCOM:EU 2012, Adding and changing art assets - XCOM:EU 2012, and Changing colors and tints - XCOM:EU 2012.
Tables
To use these tables, find the desired armor tint or Hair/Helmet combination in the Base Soldier "Customize" UI display. Look up that decimal number in the first column of the table, and confirm the description. (You can click on the thumbnail to see an enlarged version of the image.) Use the decimal value from the first table column within the mod.
The UI option's number is different in EU and EW. In EU this also depends upon if the player has one or all of EU's DLC installed. For example the original soldier's hair is UI option 17 in EW, and option 28 in EU with all DLC.
These tables are based upon EW option numbers. EU players may need to adjust to their UI displayed values.
UI-armor Tint | Color combo | Thumb |
---|---|---|
0 | Standard: tan top over black bottom | |
1 | brown top over grey dark bottom | |
2 | cyan light over brown | |
3 | green dark over yellow dark | |
4 | orange over grey dark | |
5 | white over black | |
6 | red over black | |
7 | yellow over black | |
8 | cyan over brown | |
9 | green dark over off-white | |
10 | black over white | |
11 | blue dark over white | |
12 | purple-blue over grey dark | |
13 | purple over white | |
14 | pink light over white | |
15 | black over yellow | |
16 | yellow bright over black | |
17 | blue dark over off-white | |
18 | red bright over yellow bright | |
19 | blue bright over yellow | |
20 | pink dark over green | |
21 | blue over orange | |
22 | blue dark over orange | |
23 | yellow dark over grey | |
24 | purple dark over yellow | |
25 | pink bright over blue bright | |
26 | orange bright over purple | |
27 | green light over orange dark | |
28 | cyan light over off-white | |
29 | yellow light over white | |
30 | brown light over off-white | |
31 | green bright over green bright | |
32 | black over black |
[Images by eld10, used with permission.]
The Hair selection in the Base Soldier "Customize" UI is preselected based upon gender, so they are presented as separate tables here. Note the "UI-Hair" type spinner value is the same for both genders as a consequence, and includes hairs from DLCs. Use the decimal value in the first column of the table within the mod.
[Hair color in all images is "Blonde" (UI spinner 1).]
UI-Hair(/Helmet) | Package ID | Filename | Thumb |
---|---|---|---|
1 | NA | No Hair | |
2 | 1 | Hair_FemHair_A | |
3 | 2 | Hair_FemHair_B | |
4 | 3 | Hair_FemHair_C | |
5 | 4 | Hair_FemHair_D | |
6 | 5 | Hair_FemHair_E | |
7 | 6 | Hair_FemHair_F | |
8 | 7 | Hair_FemHair_G | |
9 | 8 | Hair_FemHair_H | |
10 | 9 | Hair_FemHair_I | |
11 | 10 | Hair_FemHair_J | |
12 | 11 | Hair_FemHair_K | |
13 | 12 | Hair_FemHair_L | |
14 | 13 | Hair_FemHair_M | |
15 | 14 | Hair_FemHair_N | |
16 | 15 | Hair_FemHair_O | |
17 | 16 | Hair_FemHair_P |
UI-Hair(/Helmet) | Package ID | Filename | Thumb |
---|---|---|---|
1 | NA | No Hair | |
2 | 14 | Hair_MaleHair_A | |
3 | 15 | Hair_MaleHair_B | |
4 | 16 | Hair_MaleHair_C | |
5 | 17 | Hair_MaleHair_D | |
6 | 18 | Hair_MaleHair_E | |
7 | 19 | Hair_MaleHair_F | |
8 | 20 | Hair_MaleHair_G | |
9 | 21 | Hair_MaleHair_H | |
10 | 22 | Hair_MaleHair_I | |
11 | 23 | Hair_MaleHair_J | |
12 | 24 | Hair_MaleHair_K | |
13 | 25 | Hair_MaleHair_L | |
14 | 26 | Hair_MaleHair_M | |
15 | 27 | Hair_MaleHair_N | |
16 | 28 | Hair_MaleHair_O | |
17 | 29 | Hair_MaleHair_P |
Helmet selection is an extension of the Hair selection in the Base Soldier "Customize" UI, because Helmet textures replace Hair textures. The selection option only appears if "decorative armor" has been enabled, as described in the Decorative Armors, Basic Game section. Use the decimal value in the first column of the table within the mod.
UI-(Hair/)Helmet | Package ID | Description | Thumb |
---|---|---|---|
18 | 200 | Motorcycle helmet, closed | |
19 | 303 | Beret and sunglasses | |
20 | 403 | Modern Kevlar Helmet, open-faced | |
21 | 305 | Ball cap & headset | |
22 | 308 | Beret | |
23 | 310 | Beanie w/goggles & headset | |
24 | 425 | Ball Cap | |
25 | 426 | Ball cap, Backwards | |
26 | 427 | Ball cap, Backwards w/Headset | |
27 | 428 | Beanie | |
28 | 202 | Stormtrooper helmet | |
29 | 401 | Gold Plate w/Breather Helmet | |
30 | 320 | Gold Plate Face Helmet | |
31 | 322 | Gold Eyes SciFi Helmet | |
32 | 302 | Sleek SciFi Helmet | |
33 | 402 | Blocky, faceless SciFi Helmet | |
34 | 315 | Bugface SciFi Helmet | |
35 | 313 | Hybrid SciFi Helmet | |
36 | 304 | Skull-Face Helmet | |
37 | 404 | Sleek Round SciFi Helmet | |
38 | 201 | Red-eye helmet | |
39 | 405 | Robocop | |
40 | 430 | Gold Eye Plate w/Breather | |
41 | 460 | Fedora |
[Images by eld10, used with permission.]
Mod file
Below is a mod file for PatcherGUI 3.1 (and higher) and both Enemy Unknown and Enemy Within. Just save it to a text file and feed it to PatcherGUI. You can change the default appearance numbers to your liking. Comments appearing after "double slashes" (//) or within "{curly braces}" are ignored, including multiple blocks of lines between "{curly braces}" or "/*" and "*/".
MOD_NAME=Default Helmet and Armor Tint AUTHOR=Drakous79 DESCRIPTION=Sets default helmet and armor tint to specified value.
Use PatcherGUI or PatchUPK 3.1 and higher.
This mod works with both Enemy Within and Enemy Unknown. It is designed to be used with the displayed Armor Tint and Hair/Helmet type values seen in the Base Soldier "Customize" screen.
Enemy Within Installation ------------------------- * Start PatcherGUI. * Click the 1st Browse button and navigate to <Steam install path>\XCom-Enemy-Unknown\XEW and confirm. * Click the 2nd Browse button and select this mod file. * Click Apply button, run the game and enjoy.
Enemy Unknown Installation -------------------------- * Start PatcherGUI. * Click the 1st Browse button and navigate to <Steam install path>\XCom-Enemy-Unknown and confirm. * Click the 2nd Browse button and select this mod file. * Comment signs // are used to comment parts of code. Uncomment 4 lines after "Enemy Unknown memory and serial size (DISABLED)". * Click Save and then Apply button. * Update XComGame.UPK hash by any means (XSHAPE, XCOMModHelper, edit XComGame.exe). You can check out an article on Nexus Wiki: http://wiki.tesnexus.com/index.php/Basic_Guide_to_installing_mods#Disabling_Hash_checks * Run the game and enjoy.
UPK_FILE=XComGame.upk OBJECT=XGCharacterGenerator.CreateTSoldier:AUTO
// *** Correct memory and serial script size in function's header. ***
// *** Enemy Within memory and serial size (ENABLED) *** REL_OFFSET=0x28 [MODDED_HEX] 92 0F 00 00 16 0A 00 00
// *** Enemy Unknown memory and serial size (DISABLED); uncomment next 4 lines to enable *** // REL_OFFSET=0x28 // [MODDED_HEX] // 15 0C 00 00 // F1 07 00 00
// *** Add helmets to the 'Hairs' array by setting bAllowHelmets=true (the last 4A to 27) in three GetContentIds calls bellow. ***
{ XComContentManager(class'Engine'.static.GetEngine().GetContentManager()).GetContentIdsForRace(6, byte(kSoldier.kAppearance.iRace), RaceHairs,, true) } FIND_CODE=00 <.RaceHairs> 4A 4A 16 [MODDED_CODE] 00 <.RaceHairs> 4A 27 16
{ XComContentManager(class'Engine'.static.GetEngine().GetContentManager()).GetContentIdsForGender(6, byte(kSoldier.kAppearance.iGender), GenderHairs,, true) } FIND_CODE=00 <.GenderHairs> 4A 4A 16 [MODDED_CODE] 00 <.GenderHairs> 4A 27 16
{ XComContentManager(class'Engine'.static.GetEngine().GetContentManager()).GetContentIdsForCharacter(6, 2, CharacterHairs,, true) } FIND_CODE=00 <.CharacterHairs> 4A 4A 16 [MODDED_CODE] 00 <.CharacterHairs> 4A 27 16
// *** Skip a loop clearing helmets from the 'Hairs' array. ***
{ Idx = Hairs.Length - 1 ... if(Idx >= 0) } FIND_CODE=0F 00 <.Idx> 93 36 00 <.Hairs> 26 16 07 [MODDED_CODE] 0F 00 <.Idx> 93 36 00 <.Hairs> 26 16 06
// *** Set custom numbers. ***
FIND_CODE=16 04 00 <.kSoldier> [MODDED_CODE] 16 { kSoldier.kAppearance.iHaircut = Hairs[number-2] } 0F 35 <XGTacticalGameCoreNativeBase.TAppearance.iHaircut> <XGTacticalGameCoreNativeBase.TAppearance> 00 00 35 <XGTacticalGameCoreNativeBase.TSoldier.kAppearance> <XGTacticalGameCoreNativeBase.TSoldier> 00 01 00 <.kSoldier> 10 93 2C // _________________________________ // DEFAULT HAIR/HELMET <%b21> // change the number after %b // _________________________________ 2C 02 16 00 <.Hairs>
{ kSoldier.kAppearance.iArmorTint = [number-1] } 0F 35 <XGTacticalGameCoreNativeBase.TAppearance.iArmorTint> <XGTacticalGameCoreNativeBase.TAppearance> 00 00 35 <XGTacticalGameCoreNativeBase.TSoldier.kAppearance> <XGTacticalGameCoreNativeBase.TSoldier> 00 01 00 <.kSoldier> 93 2C // _________________________________ // DEFAULT ARMOR TINT <%b10> // change the number after %b // _________________________________ 26 16
{ return kSoldier } 04 00 <.kSoldier>
{ EOF }
Mod file example
To select the default Armor Tint Table value, pick the Base Soldier "Customize" screen "Tint number" under "UI-Tint" column. As in:
UI-Tint | Color combo |
---|---|
2 | cyan light over brown |
and then in the mod, find section:
// DEFAULT ARMOR TINT <%b10> // change the number after %b; where "10" = "black over white"
and change "<%b10>" to "<%b2>" ("2" = cyan light over brown).
To select the default Hair/Helmet Table value, pick the Base Soldier "Customize screen type number under the "UI-Helmets" column, OR the same number after locating the DefaultContent.INI file "HairPackageInfo 'ID='" number under the "Package ID column. As in:
UI-Helmets | Package ID | Color combo |
---|---|---|
18 | 200 | Motorcycle helmet, closed |
and then in the mod, find section:
// DEFAULT HAIR/HELMET <%b21> // change the number after %b; where "21" = "Ball cap & headset"
and change "<%b21>" to "<%b18>" ("18" = Motorcycle helmet, closed).
Separate Content
Decorative Armors, including Slingshot DLC
As for the basic decorative armors, edit <Steam install path>\XCom-Enemy-Unknown\XComGame\Config\DefaultContent.INI file. You need to replace all the current ArmorDeco= lines with the following, which basically just adds six additional slots (4-9 per armor type):
ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar0) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar1) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar2) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar3) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar4) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar5) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar6) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar7) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar8) ArmorDeco=(Armor=eItem_ArmorKevlar,ArmorKit=eKit_Deco_Kevlar9) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton0) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton1) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton2) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton3) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton4) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton5) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton6) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton7) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton8) ArmorDeco=(Armor=eItem_ArmorSkeleton,ArmorKit=eKit_Deco_Skeleton9) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace0) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace1) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace2) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace3) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace4) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace5) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace6) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace7) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace8) ArmorDeco=(Armor=eItem_ArmorCarapace,ArmorKit=eKit_Deco_Carapace9) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost0) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost1) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost2) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost3) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost4) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost5) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost6) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost7) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost8) ArmorDeco=(Armor=eItem_ArmorGhost,ArmorKit=eKit_Deco_Ghost9) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan0) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan1) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan2) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan3) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan4) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan5) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan6) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan7) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan8) ArmorDeco=(Armor=eItem_ArmorTitan,ArmorKit=eKit_Deco_Titan9) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel0) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel1) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel2) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel3) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel4) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel5) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel6) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel7) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel8) ArmorDeco=(Armor=eItem_ArmorArchangel,ArmorKit=eKit_Deco_Archangel9) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi0) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi1) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi2) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi3) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi4) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi5) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi6) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi7) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi8) ArmorDeco=(Armor=eItem_ArmorPsi,ArmorKit=eKit_Deco_Psi9)
Then it is necessary to modify the <Steam install path>\XCom-Enemy-Unknown\XComGame\DLC\PCConsole\DLC_PackIn\Config\XComContent.INI file in a similar fashion. Remove all the "; (Armor Name) Deco 0" lines and replace them with the following code:
; Kevlar Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Kevlar Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Kevlar Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Skeleton Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Skeleton Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Skeleton Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Carapace Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Carapace Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Carapace Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Ghost Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Ghost Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Ghost Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Titan Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Titan Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Titan Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Archangel Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Archangel Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Archangel Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0") ; ; Psi Deco 0 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi0,ArchetypeName="Deco_Kevlar0.ARC_Deco_Kevlar0") ; Psi Deco 1 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi1,ArchetypeName="Deco_Skeleton0.ARC_Deco_Skeleton0") ; Psi Deco 2 +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi2,ArchetypeName="Deco_Carapace0.ARC_Deco_Carapace0")
Then for the Slingshot DLC content, navigate to edit the <Steam install path>\XCom-Enemy-Unknown\XComGame\DLC\PCConsole\DLC_Day060\Config\XComContent.INI file. Copy the code below and paste over everything starting with "+ArmorKitPackageInfo=" (it should be the first chunk you see):
+ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Archangel9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Carapace9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Ghost9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Psi9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Skeleton9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan3,ArchetypeName="Deco_Kevlar1.ARC_Deco_Kevlar1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan4,ArchetypeName="Deco_Archangel0.ARC_Deco_Archangel0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan5,ArchetypeName="Deco_Carapace1.ARC_Deco_Carapace1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan6,ArchetypeName="Deco_Ghost0.ARC_Deco_Ghost0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan7,ArchetypeName="Deco_Psi0.ARC_Deco_Psi0") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan8,ArchetypeName="Deco_Skeleton1.ARC_Deco_Skeleton1") +ArmorKitPackageInfo=(KitType=eKit_Deco_Titan9,ArchetypeName="Deco_Titan0.ARC_Deco_Titan0")
There will be some clipping but you'll have a lot more choices for Armor.
Weapon Kits as selectable deco options
It is possible to make various weaopns kits into selectable deco armor options.
An example would be a Rookie with an Assault Rifle, setup with the Heavy LMG-style armor overlay as a selected deco armor.
To DefaultContent.INI in the main XCOM game folder, add the line:
ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar4,ArchetypeName="Kit_LMG_I_Medium.ARC_LMG_I_Medium")
This sets the Kevlar+LMG armor kit as DecoKevlar4.
With both of the first two DLC packages (pre-order Bonus Soldier and Slingshot), add the following just before the definition block that defines the weapon kits (omit the ellipsis [...], which merely indicate there are other entries):
...
WeaponPackageInfo=(ItemType=eItem_OutsiderWeapon,ArchetypeName="Weapon_PlasmaRfLtOutsider.GD_PlasmaRifleLightOutsider")
ArmorKitPackageInfo=(KitType=eKit_Deco_Kevlar4,ArchetypeName="Kit_LMG_I_Medium.ARC_LMG_I_Medium")
ArmorKitPackageInfo=(KitType=eKit_AssaultRifle_Kevlar,ArchetypeName="Kit_AssaultRifle_I_Medium.ARC_Kit_AssaultRifle_I_Medium")
...
Adjust and add as necessary for your own preferred kits.
Not quite sure what the limit is on the number of possible deco kits, although the deco enum only seems to go up to 12, so that might well be the limit.
Gene Mod Armor
The GeneMod is the character model, not the armor, so you just get plating sticking wierdly out of their skin.
The function that maps character type to pawn, at least for soldiers, in EW is implemented in UPK instead of native code, which means it can be modded.
The function is XGBattleDesc.MapSoldierToPawn:
static function int MapSoldierToPawn(int iArmor, int iGender, bool bGeneMod)
It's basically a big switch/case statement over iArmor, with conditionals for iGender and bGeneMod. For example:
case 59: if(iGender == 1) { return ((bGeneMod) ? 80 : 16); } else { return ((bGeneMod) ? 73 : 5); } break;
Simply changing both numbers for the ternary conditional with bGeneMod to the second case will result in soldiers always using the non-genemod armor pawn. E.g.:
return ((bGeneMod) ? 16 : 16);
(To clarify the coder talk: the first number in the return statement (80/73) is the GeneMod version of the armor; the second is the normal version. The first return statement, under the if(iGender == 1) line, is for one type of gender, and the second, under the else line, is for the other gender.)
Note this method results in GeneMod soldiers losing their weapon kits and also runs into the max deco limit of 12.
GeneMods using default armor deco
Some people simply want to make the game use default armor decos for their GeneMod soldiers. This simply requires an edit to the DefaultContent.INI file armor deco lines similar to the following example:
UnitPackageInfo=(PawnType=ePawnType_Male_2_Skeleton,ArchetypeName="Soldier_MaleSkeleton.ARC_MaleSkeleton")
copied into something like this:
UnitPackageInfo=(PawnType=ePawnType_Male_2_Skeleton_GM,ArchetypeName="Soldier_MaleSkeleton.ARC_MaleSkeleton")
See how we added the "_GM" that is outside of the quotations to the standard UnitPackageInfo PawnType' name? That makes it so that when the game goes to look for the GM model it finds it, however, we changed the model it ends up using by removing the GM from the current "GM" texture file name, the part in quotations behind the "ArchetypeName=" identifier. That name (in the quotations) is now the name of the file for the normal armor deco assets instead of the GeneMod (_GM) assets.
Think of it as letting the game know the GM model, but redirecting it to use the default art model asset instead.
This modification does not allow for weapon-specific elements on the armors, such as shoulder pads when you use the shotgun.
Disabling Genemod skin
(Thanks to Decilete for this tip and mini-tutorial.)
Digging about within XComGame.UPK, found a common theme with regard to GeneMod soldiers. Most of the checks regarding whether to use GeneMod skins or just normal skins was being determined by the function HasAnyGeneMod.
XComPerkManager.HasAnyGeneMod basically states if any of the GeneMod perk values are greater than zero, then the soldier has a GeneMod. This obviously leads to the various skins and decos being used, etc.
To change this behavior, fire up UE Explorer, open up a copy of XComGame.UPK and navigate to XComPerkManager. Expand the functions section and open HasAnyGeneMod. Right click that and select the UE "view buffer" command. This should give you the hex table for the code you are viewing along with tooltips for all the tokens.
Now we get to the more complicated bit.
- Get a hex editor like HxD and open your copy of XComGame.UPK.
- Now, search with HxD using a hex string from HasAnyGeneMod; you can see these in the buffer window of UE Explorer. You'll need to search for a long enough string of characters that you only get one search result, which will mean you're in the right place.
- Now you want to find in UE Explorer all the tokens in HasAnyGeneMod that have the tag intzero (integer zero). They should appear as 25 in hex code. Using HxD, you want to change the 25 to a 26, which will change the tag after you've saved the file to intone (integer one) instead.
- Use your newly modded copy of XComGame.UPK instead of the original.
Now, since you can't have multiples of the same mod, you'll never have a value higher than 1. This will result in your GeneMod soldiers looking exactly like your regular soldiers, deco and weapon kits, et al.
UI Customization Process
This information is provided for mod creators who wish to understand how the game code internally converts the entries in the INI file into the Base Soldier "Customize" screen spinner values.
DefaultContent.INI contains lines like the following examples:
HairPackageInfo=(Id=11,ArchetypeName="Hair_FemHair_K.ARC_Hair_FemHair_K", Gender=eGender_Female) HairPackageInfo=(Id=17,ArchetypeName="Hair_MaleHair_D.ARC_Hair_MaleHair_D", Gender=eGender_Male) HairPackageInfo=(Id=200,ArchetypeName="Helmet_Kevlar0.KevlarHelmet0",bIsHelmet=true) HairPackageInfo=(Id=303,ArchetypeName="Helmet_Kevlar1.KevlarHelmet1",bIsHelmet=true) HairPackageInfo=(Id=403,ArchetypeName="Helmet_Kevlar2.KevlarHelmet2",bIsHelmet=true)
Note the Gender definitions for Hair, and the Helmet pairings with specific Armor types.
Those lines are added to a HairPackageInfo array used by XComContentManager.
HairPackageInfo(10)=(Id=11,Gender=EGender.eGender_Female,ArchetypeName="Hair_FemHair_K.ARC_Hair_FemHair_K") HairPackageInfo(14)=(Id=17,Gender=EGender.eGender_Male,ArchetypeName="Hair_MaleHair_D.ARC_Hair_MaleHair_D") HairPackageInfo(32)=(Id=200,bIsHelmet=true,ArchetypeName="Helmet_Kevlar0.KevlarHelmet0") HairPackageInfo(33)=(Id=303,bIsHelmet=true,ArchetypeName="Helmet_Kevlar1.KevlarHelmet1") HairPackageInfo(34)=(Id=403,bIsHelmet=true,ArchetypeName="Helmet_Kevlar2.KevlarHelmet2")
When the game is creating UI spinners, it calls several functions. GetContentIds<snip> serves like a filter and IntersectContentIds builds the final array Hairs. Males and females have the same number of hair options. Otherwise the UI wouldn't work the same for both genders.
GetContentIdsForRace(6, byte(kSoldier.kAppearance.iRace), RaceHairs,, true); GetContentIdsForGender(6, byte(kSoldier.kAppearance.iGender), GenderHairs,, true); GetContentIdsForCharacter(6, 2, CharacterHairs,, true); IntersectContentIds(RaceHairs, GenderHairs, GenderRaceHairs); IntersectContentIds(GenderRaceHairs, CharacterHairs, Hairs);
In the end, there is one "Hairs" array looking like this (female hair and helmets example):
Hairs[0]=1 // Hair_FemHair_A ... Hairs[16]=200 // Helmet_Kevlar0 Hairs[17]=303 // Helmet_Kevlar1 Hairs[18]=403 // Helmet_Kevlar2 ...
Note the first "Hairs" array index is "0".
This array is passed to the Hair/Helmet UI Flash Actionscript code, but the spinner's UI range starts at 1. And because option 1 is "no hair", the first hair from the array is listed as spinner option 2. So there is -2 compensation to the Hair/Helmet UI spinner number needed to arrive at the correct array index, while setting values in XComGame.UPK, XGCharacterGenerator.CreateTSoldier.
kSoldier.kAppearance.iHaircut = Hairs[21 - 2]; // 21 in the game
The Armor Tint array index starts at zero (0-31), while the UI spinner starts at 1 (1-32). The Helmet "Type" package ID starts at 200, but has skips in the numbering sequence; and the array index starts at 18 (18-41). The same internal array is used for both Hair and Helmets, but Hair choices are preselected based upon Gender.
The mod presented in this article deals with adjusting the spinner decimal values to the correct array indexes, in hex, so the player doesn't have to, as follows:
Hair = dec2hex(customization screen number - 2) Armor Tint = dec2hex(customization screen number - 1)
Code responsible for the spinner's UI string (current option) is set in XComStrategyGame.UPK, XGCustomizeUI.UpdateMainMenu:
kOption.strHelp = "" $ string((GetHairIndex()) + 2);
The spinner's true range is set in XComStrategyGame.UPK, XGCustomizeUI.AdvanceHair:
NumHairs = m_kPawn.PossibleHairs.Length; CurIdx = GetHairIndex(); NewIdx = CurIdx + Dir; if(NewIdx < -1) // this one { NewIdx = NumHairs - 1; } if(NewIdx >= NumHairs) { NewIdx = -1; // and this one } NewHair = ((NewIdx > -1) ? m_kPawn.PossibleHairs[NewIdx] : -1); m_kPawn.SetHair(NewHair); ...
"-1" in this case enables the "no hair" option (which does not have a "Hair Package") for spinner value of "1".
References
Referred to by this article:
- Unlock all Decorative Armors for all Armors
- Cybernetic Warfare Mod ideas and Planning
- Initial soldier appearance
- DefaultLoadouts.ini
- Basic_Guide_to_installing_mods
- Modding_Tools_-_XCOM:EU_2012
- Color_Palettes_-_XCOM:EU_2012
- Adding_and_changing_art_assets_-_XCOM:EU_2012
- Changing_colors_and_tints_-_XCOM:EU_2012
That refer to this article:
- Basic Guide to installing mods
- Color_Palettes_-_XCOM:EU_2012
- Adding_and_changing_art_assets_-_XCOM:EU_2012
- Changing_colors_and_tints_-_XCOM:EU_2012