Additional Items Mod XCOM:EU - 2012

From Nexus Mods Wiki
Jump to: navigation, search
XCOM Engineering Build Item UI with Additional Items


Overview

This article describes a series of changes that allow additional items to be added to the game through the DefaultGameCore.ini settings - XCOM:EU 2012 (DGC.INI) file. The original discovery and discussion may be found in the thread R&D Inventory, Items & Weapons Overhaul, with later information from Enemy Within: Items slots modding in the XCOM Mod Talk section on the Nexus Forums.

This DOES NOT include the ability to add item meshes or animations. These new items are intended only to add new gameplay effects. In some cases a new item may re-use an existing item's mesh/animation assets.

Game Version Compatibility

This mod was developed under EU Patch 4 ( Changelist: 356266 ).

Known Issues

  • Item Cards for new items do not work correctly
    • Incorrect images and information are displayed
  • If installed with the SHIV Loadout 1.0 (SHIV Weapons), a MIA SHIV will remove 1 extra SHIV weapon from inventory than it should.

Programs and Tools

The following tools are described and linked in the article Modding Tools - XCOM:EU 2012.

ToolBoks v 1.21

UE Explorer

HxD

Resource Hacker

  • With the new mod that forces xcomgame.exe to load from the DefaultGameCore.ini file instead of the embedded Resource, Resource Hacker is no longer as essential to applying the configuration changes
  • Resource Hacker is almost essential in order to install this mod. Large swaths of configuration data in the DGC.ini is being replaced.
    • ToolBoks is not capable of adding additional lines at this time (May 2013).
    • Unsure whether ModPatcher is capable of making the extensive changes required (author is unfamiliar with ModPatcher)

Details

(Taken from Enemy Within: Items slots modding thread).

Once you get beyond the designed 3 small items, the matter becomes a little bit complex. You have to mod some functions.

The game has two different inventory systems:

1) struct TInventory contains just arrays of item IDs. It contains space for 1 armor, 1 pistol, 16 large items and 16 small items. This system is used by the strategy game for the most part.

2) class XGInventory is a dynamic graph of class objects. These are primarily used for attaching/displaying item models onto units.

In the Enemy Within expansion there are 25 slot attachment points. These are used to attach item objects to units. Note that eSlot 15 is ESlot_Head. This is how soldier customization is done.

enum ELocation
{
   eSlot_None,
   eSlot_RightBack,
   eSlot_LeftBack,
   eSlot_RightHand,
   eSlot_LeftHand,
   eSlot_Grapple,
   eSlot_RightThigh,
   eSlot_LeftThigh,
   eSlot_LeftBelt,
   eSlot_RightChest,
   eSlot_LeftChest,
   eSlot_RightForearm,
   eSlot_RightSling,
   eSlot_RearBackPack,
   eSlot_PsiSource,
   eSlot_Head,
   eSlot_CenterChest,
   eSlot_Claw_R,
   eSlot_Claw_L,
   eSlot_ChestCannon,
   eSlot_KineticStrike,
   eSlot_Flamethrower,
   eSlot_ElectroPulse,
   eSlot_GrenadeLauncher,
   eSlot_PMineLauncher,
   eSlot_RestorativeMist,
   eSlot_MAX
};

There is a function XGLoadoutMgr.ConvertTInventoryToSoldierLoadout that handles the conversion from the basic TInventory structure into the XGInventory design. For example:

if(I < kInventory.iNumLargeItems)
   {
       if(kChar.eClass == 6)
       {
           <snip>
       }
       else
       {
           if(I == 0)
           {
               Loadout.Items[1] = class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.arrLargeItems[I]));
           }

For non-MECs (MECs are introduced in Enemy Within) this loads the first large-item into eSlot 1, which is eSlot_RightBack. The 2nd large item goes into eSlot 2, eSlot_LeftBack. This is why the Rocket Launcher goes onto the left and the main weapon is holstered to the right. For example, if you give a Heavy a medkit and watch the animation, the unit has both LMG and Rocket Launcher on the back while the medikit is in hand.

Any subsequent large items (anything more than 2) gets tossed into a non-display backpack dynamic array with:

Loadout.Backpack.AddItem(class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.arrLargeItems[I])));

Small items work a little differently.

The rules for small items are:

  • Any item marked as eWP_Backpack goes into the backpack
  • The 1st non-backpack small item goes into eSlot 7, eSlot_LeftThigh
  • The 2nd non-backpack small item goes into eSlot 10, eSlot_LeftChest
  • The 3rd non-backpack small item goes into eSlot 8, eSlot_LeftBelt

Unlike with the large items, there is no default behavior forcing any additional non-backpack items above 3 into the backpack. They simply are not converted to the XGInventory. Everything in the tactical game draws from the XGInventory, so those items are effectively lost during the tactical battle.

This is a slight design flaw that is only is exposed when more than 3 non-backpack small items are equipped to a character.

Apparently there is a bug in XGUnit.SwapEquip, which swaps or rotates weapons between slots. The key is probably a bug in the (inaccessable) native code that identifies primary and secondary weapons. It is suspected the reason the Arc Thrower as a pistol animation display is buggy was that it wasn't a valid secondary weapon.

(Based upon R&D Inventory, Items & Weapons Overhaul discoveries.)

The mod consists of several distinct parts.

  1. A completely rewritten XComStrategyGame.upk >> XGItemTree.BuildItems function.
  2. Complete replacement of the Weapons= configuration array in the DGC.ini.
  3. Complete replacement of the ItemBalance= configuration array in the DGC.ini.
  4. Claim and Perk system changes.
  5. Changes to Loadout System.
  6. Other Changes.
  7. Changes necessary to configure or make individual items work correctly

BuildItems

The BuildItems function consists of a large number of individual BuildItem calls such as:

  • BuildItem(2, -1, -1, -1, 37); // pistol
  • BuildItem(11, 30, 25, 7, 12, 21, 26); // Heavy Laser

Values of -1 take up 5 bytes of hex, while regular integers take up 2 bytes. There are 10 parameters in a BuildItems call.

  1. int iItem
  2. optional int iCashCost
  3. optional int iEleriumCost
  4. optional int iAlloyCost
  5. optional int iTime
  6. optional int iMaxEngineers
  7. optional XComGame.XGGameData.ETechType eTechReq
  8. optional XComGame.XGGameData.EItemType eItemReq
  9. optional XComGame.XGGameData.EFoundryTech eFTech
  10. optional int EImage

All but 1 of the parameters are optional, leading to a wide variety of appearances when decompiled.

The iCashCost, iEleriumCost, iAlloyCost, iTime and iMaxEngineer values are overwritten if there is a ItemBalance= entry in the DGC.ini. To free up space in BuildItems, all five of these values are called with zero values (consumes only 1 byte) in the BuildItems call, and are then overwritten via a ItemBalance= entry. Items that did not previous have ItemBalance= entries (such as the Pistol) will have a ItemBalance= entry added.

Example: Pistol BuildItem hex before: 1B 6E 04 00 00 00 00 00 00 2C 02 1D FF FF FF FF 4A 4A 1D FF FF FF FF 1D FF FF FF FF 4A 4A 4A 2C 25 16 // pistol

Pistol BuildItem hex after (reduced): 1B 6E 04 00 00 00 00 00 00 2C 02 25 25 25 25 25 2C 00 4A 2C 00 2C 25 16 {// pistol}

This allows approximately 26 additional BuildItem calls to be made in BuildItems


Weapons= DGC Entries

Each Weapon= entry allows for configuration of the stats, abilities, and properties of each "weapon" in the game. XCOM only has Weapons and Armor items, so the "weapon" category includes things such as S.C.O.P.E.s, Combat Stims, and even Medikits.

A new weapon entry is added for each new item being built in the BuildItems function above.

Example : Pistol Weapons=(iType=eItem_Pistol,ABILITIES[0]=eAbility_ShotStandard,ABILITIES[1]=eAbility_Overwatch,ABILITIES[2]=eAbility_NONE,ABILITIES[3]=eAbility_NONE,ABILITIES[4]=eAbility_NONE,ABILITIES[5]=eAbility_NONE,Properties[0]=eWP_Pistol,Properties[1]=eWP_UnlimitedAmmo,Properties[2]=eWP_None,Properties[3]=eWP_None,Properties[4]=eWP_None,Properties[5]=eWP_None,iDamage=1,iEnvironmentDamage=10,iRange=27,iReactionRange=-1,iReactionAngle=200,iRadius=0,iCritical=0,iOffenseBonus=0,iSuppression=0,iSize=eItemSize_Small,iHPBonus=0,iWillBonus=0)

Each entry is quite long. It can contain up to 6 abilities, 6 properties, as well as a variety of stat bonuses granted by having the item equipped. Some of these values may only work in certain situations.

In order to save space in the DGC.ini, all eAbility_None and eWP_None values will be replaced with 0.

Example : Pistol Weapons=(iType=eItem_Pistol,ABILITIES[0]=eAbility_ShotStandard,ABILITIES[1]=eAbility_Overwatch,ABILITIES[2]=0,ABILITIES[3]=0,ABILITIES[4]=0,ABILITIES[5]=0,Properties[0]=eWP_Pistol,Properties[1]=0,Properties[2]=0,Properties[3]=0,Properties[4]=0,Properties[5]=0,iDamage=1,iEnvironmentDamage=10,iRange=20,iReactionRange=20,iReactionAngle=200,iRadius=0,iCritical=0,iOffenseBonus=0,iSuppression=0,iSize=eItemSize_Small,iHPBonus=0,iWillBonus=0)


ItemBalance= DGC Entries

Each ItemBalance= entry allows overwriting of the following values first defined via BuildItem calls in BuildItems:

  1. optional int iCashCost
  2. optional int iEleriumCost
  3. optional int iAlloyCost
  4. optional int iTime
  5. optional int iMaxEngineers

Since the re-built BuildItems initializes all of these values with zero, it is necessary to have an ItemBalance= entry for every item in the strategy game. If an item does not have an ItemBalance= entry, it will be buildable for zero resources in zero time.

Example : Heavy Plasma ItemBalance=(eItem=eItem_HeavyPlasma, iCash=250, iElerium=30, iAlloys=30, iTime=10, iEng=25)

Some items (e.g. Pistol, Shotgun) did not have ItemBalance= entries. Entries for these items will be added.


Claim and Perk System

Claim System

This mod also reworks the storage claim system present in the default game.

By default, items in XGStorage are tracked through two arrays:

  • XGStorage.m_arrItems
    • tracks the number of items that have been built
  • XGStorage.m_arrClaims
    • tracks the number of items that have been claimed by soldiers

When an item is built, its corresponding position in m_arrItems is added to. Items are only every removed from m_arrItems if:

  • Soldier goes MIA or is killed with the Second Wave option "Total Loss"
  • Item is sold in the grey market
  • Item is sold via a Funding Council Request
  • Item is used to manufacture another item
  • Item is consumed for Research / Foundry

When an item is equipped to a soldier, its corresponding position in m_arrClaims is added to. When an item is unequipped, its corresponding position in m_arrClaims is subtracted from.

This mods removes the functionality of m_arrClaims, and instead uses only the m_arrItems array to track all items in storage.

With this mod, when a soldier equips an item, its corresponding position in m_arrItems is subtracted from. When an item is unequipped, its corresponding position in m_arrItems is added to. This is to enable future functionality for consumable items (e.g. grenades).


Perk System

This mod also adds the ability configure each item to add a perk-ability when equipped. The perk ability is removed when the item is unequipped.

The perk is stored in the previously unused .StructureReq of the XGItemTree.m_arrItems structure array. It is set by setting the iEngineers field to the desired perk in the item's BuildItem call in BuildItems. The real iEngineer value is set using the ItemBalance= entry in the DGC.ini.


Loadout System

When the tactical game system is loading a new battle, items are converted from the soldier inventory used in the strategy game to the system used in the tactical game. In order to supply mesh/animation assets, each soldier contains a "Loadout" array consisting of 22 possibily Loadout positions that are represented on the Soldier's body mesh via attachment points.

Each item to be added to this loadout is required to have a class defined. The classes are all of type class'XGWeapon_<type>' and are extensions of the parent class'XGWeapon'. Conversion of the item ID to the appropriate class-type is performed using an array defined in XGItemLibrary. ItemIDs that do not have classes are not loaded out, and so will fail to be present in the tactical game XGInventory. This will cause the item to fail to apply any stats to the soldier, nor will a HasItem() call return true for the item.

To get around this, several changes are necessary to the XGLoadoutMgr class functions ConvertTInventoryToSoldierLoadout and ApplyLoadout. The ItemID is set via a default value in each XGWeapon_<type> class. This value must be changed to the correct ItemID in order for the new item to function properly.

The parameter to be changed is m_eType in XGWeapon's parent class XGItem. Because m_eType is a protected variable with no "Set" function, the ApplyOverheatIncrement function in XGWeapon will be re-purposed in order to set this parameter.

The access function to m_eType returns default.m_eType, which makes changing the value non-functional. The XGItem.ItemType function is modified in order to return the current instead of default value.

There are two different access functions in XGItem : GameplayType() and ItemType(). These return values of the same enum type, but can return different results. ItemType() returns the m_eType stored in XGItem, while GameplayType()'s behavior is unknown due to it being a native function.

The function XGInventory.GetRearBackpackItemArray uses the accessor function GameplayType() to retrieve the itemID for backpack items. This will return a non-functioning result for some items with existing classes such as class'XGWeapon_MutonGrenade' and class'XGWeapon_SectoidGrenade'. The accessor function is changed from GameplayType() to ItemType()

The final change is to the XGItemLibrary.GetItem function to return the class'XGWeapon_TargetingModule' for any previously undefined class.


Other Changes

When adding new items, both the strategy-game and tactical game charges have to be adjusted.

In the strategy game, the function XGSoldierUI.GetItemCharges controls how many icons are displayed in the Soldier's Inventory when the item is equipped (e.g. a soldier with Field Medic perk equipping a Medikit)

In the tactical game, the function XGUnit.UpdateItemCharges controls how many charges are granted to each soldier based on items and perks.

The charges set here are:

  • m_iAlienGrenades
  • m_iArcThrowerCharges
  • m_iBattleScanners
  • m_iFragGrenades
  • m_iGhostCharges
  • m_iMediKitCharges
  • m_iRockets
  • m_iSmokeGrenades


Item Specific Changes

Specific changes are necessary to make each of the following new items work properly:

  • First Aid Kit
  • Laser Sight
  • Smoke Grenade
  • Battlescanner

File Changes

File changes are quite lengthy. Details will be provided for each set of changes on their own pages.


XGItemTree.BuildItems

The BuildItems function will be completely overwritten. All BuildItem calls will have their iCash, iAlloys, iElerium, iTime, and iEngineers fields set to 0. These values will be set later using the data defined in the ItemBalance= configuration data.

Some BuildItem calls will have a non-zero value for iEngineers. This will set the perk to be granted when that item is equipped.

Build Item File Changes


Weapons= Config Data

The Weapons= section of the DGC.ini config data embedded in xcomgame.exe will require new entries for the new items being added. A block-replace file was developed to easily replace the entire section. Item order within the Weapons= was changed to match the order defined within BuildItems.

Weapons Config File Changes


ItemBalance= Config Data

The ItemBalance= section of the DGC.ini config data embedded in xcomgame.exe will require new entries for the new items being added. A block-replace file was developed to easily replace the entire section. Item order within the ItemBalance= was changed to match the order defined within BuildItems.

ItemBalance Config File Changes


Claim and Perk system Changes

The claim and perk system changes are implemented in the same functions. Because of this, they are not easily separable, and so are installed together.

Claim and Perk File Changes


Loadout Changes

Changes to the Loadout system to allow addition of Backpack items that use ItemIDs without corresponding a XGWeapon_<type> class. Without these changes only items with a corresponding class can apply stat bonuses to soldiers in the tactical game.

Loadout File Changes

Other Changes

Changes to the item charges in both the tactical and strategy games for newly defined items are made here.

The strategy charges are only to used to display information to the player -- they have no gameplay effect.

The tactical charges control how often various abilities can be used.

Strategy Charges File Changes

Tactical Charges File Changes

Individual Item Changes

Individual items sometimes require specific file changes in order to implement them. The file changes for each particular item are described here.

First Aid Kit File Changes

Laser Sight Kit File Changes

Smoke Grenade Kit File Changes

Battlescanner File Changes

Localization Changes

Fairly extensive Localization changes are necessary in order to display any information for newly added items.

As of May 23, 2013, only of a few of these items are fully functional.

  • First Aid Kit
  • Ceramic Plating
  • Alien Trophies
  • Laser Sight

The rest are planned future development.

The changes are made to the XComGame.int file:

Lines to add:

  • m_aItemNames[eItem_END_ITEMS]="(NEW) First Aid Kit"
  • m_aItemNames[eItem_PlaceholderGrenade0]="(NEW) Elerium Supercharger"
  • m_aItemNames[eItem_PlaceholderGrenade1]="(NEW) Grenade Launcher"
  • m_aItemNames[eItem_BEGIN_ITEMS]="(NEW) Alloy Ammo Feeds"
  • m_aItemNames[eItem_PlaceholderIntWeapon1]="(NEW) High Energy Ammo"
  • m_aItemNames[eItem_BEGIN_GRENADES]="(NEW) HoloTargeter"
  • m_aItemNames[eItem_PlaceholderWeapon0]="(NEW) Alloy Assault Rifle"
  • m_aItemNames[eItem_PlaceholderWeapon1]="(NEW) Alloy Shotgun"
  • m_aItemNames[eItem_PlaceholderWeapon2]="(NEW) Alloy LMG"
  • m_aItemNames[eItem_PlaceholderWeapon3]="(NEW) Alloy Sniper Rifle"
  • m_aItemNames[eItem_BEGIN_ALIEN_GRENADES]="(NEW) Energy Damper"
  • m_aItemNames[eItem_END_ALIEN_GRENADES]="(NEW) Ghost Module"
  • m_aItemNames[eItem_PlaceholderVehicle0]="(NEW) Ablative Armor"
  • m_aItemNames[eItem_PlaceholderVehicle1]="(NEW) Multi-barrel Weapon"
  • m_aItemNames[eItem_PlaceholderShivUpgrade0]="(NEW) HEAT Ammor"
  • m_aItemNames[eItem_PlaceholderShivUpgrade1]="(NEW) High Energy Rounds"
  • m_aItemNames[eItem_BEGIN_VEHICLE_UPGRADES]="(NEW) Reinforced Armor"


Lines being changed:

  • m_aItemNames[eItem_CyberdiscGrenade]="(NEW) Rocket"
  • m_aItemNames[eItem_ThinManGrenade]="(NEW) Ceramic Plating"
  • m_aItemNames[eItem_MutonGrenade]="(NEW) Alien Trophies"
  • m_aItemNames[eItem_SectoidGrenade]="(NEW) Laser Sight"
  • m_aItemNames[eItem_FloaterGrenade]="(NEW) Core Armoring"


References

Referred to by this article:



That refer to this article: