Claim and Perk File Changes Additional Items Mod XCOM:EU - 2012
Contents
Overview
This contains the file changes to alter the claim system and allow for perks to be granted as a side effect of equipping items.
Details
This package of changes consists of five separate hex changes:
- Remove call to RemoveLoadout in UnloadSoldier
- Change RemoveLoadout into a helper function to add/remove perks as side-effect of equip/unequip
- Rewrite ReleaseItem
- Rewrite ClaimItem
- Alter BuildItem to set perk to assign for an item
File Changes
All hex changes are applied to the XComStrategyGame.upk
UnloadSoldier
This hex change alters XGFacility_Barracks.UnloadSoldier so that RemoveLoadout is no longer called when a soldier is MIA (or if SW option "Total Loss" is enabled). Because of the claim system change, it is no longer required.
The two "dummy" variable calls are used to preserve the virtual/memory size of the function.
The following hex change will also work if the SHIV Loadout 1.0 mod (SHIV weapons only) is installed, although the hex location within the upk will be different.
The SHIV Loadout 1.0 mod will incorrectly remove an additional SHIV weapon if the SHIV is MIA or if "Total Loss" is enabled.
original: | 19 1B 23 27 00 00 00 00 00 00 16 13 00 00 00 00 00 00 1B B3 22 00 00 00 00 00 00 00 3D 28 00 00 16 |
new: | 00 3D 28 00 00 00 3D 28 00 00 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B |
Decompiled Code
XGFacility_Barracks.UnloadSoldier
Original Code
STORAGE().RemoveLoadout(kSoldier);
New Code
kSoldier kSoldier
RemoveLoadout
This hex change completely rewrites XGStorage.RemoveLoadout into a helper function to set/remove perks as a side-effect of equipping/unequipping an item.
original: | A7 40 00 00 AB 1F 00 00 00 00 00 00 A4 40 00 00 00 00 00 00 00 00 00 00 A7 40 00 00 00 00 00 00 64 01 00 00 B1 27 00 00 87 01 00 00 03 01 00 00 0F 00 A6 40 00 00 35 B6 F9 FF FF 7E FA FF FF 00 00 19 00 A7 40 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 1B 9D 22 00 00 00 00 00 00 00 A7 40 00 00 16 1B B0 22 00 00 00 00 00 00 35 8C FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 4A 16 1B B0 22 00 00 00 00 00 00 35 88 FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 4A 16 0F 00 A5 40 00 00 25 07 10 01 96 00 A5 40 00 00 35 8A FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 16 1B B0 22 00 00 00 00 00 00 1A 00 A5 40 00 00 35 8E FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 4A 16 A5 00 A5 40 00 00 16 06 A7 00 0F 00 A5 40 00 00 25 07 84 01 96 00 A5 40 00 00 35 89 FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 16 1B B0 22 00 00 00 00 00 00 1A 00 A5 40 00 00 35 8D FB FF FF 77 FA FF FF 00 00 00 A6 40 00 00 4A 16 A5 00 A5 40 00 00 16 06 1B 01 04 0B 53 |
new: | A7 40 00 00 AB 1F 00 00 00 00 00 00 A4 40 00 00 00 00 00 00 00 00 00 00 A7 40 00 00 00 00 00 00 64 01 00 00 B1 27 00 00 53 01 00 00 03 01 00 00 0F 00 A2 40 00 00 35 BC 02 00 00 BD 02 00 00 01 00 19 1B 1A 15 00 00 00 00 00 00 16 1A 00 94 35 00 00 00 1B 63 0F 00 00 00 00 00 00 9C 10 2C C2 01 67 40 00 00 2C FF 16 16 07 F6 00 97 00 A2 40 00 00 25 16 07 B7 00 97 9C 10 2C C2 01 67 40 00 00 94 26 2C 10 16 16 25 16 A1 1A 00 A2 40 00 00 35 A7 FB FF FF 7E FA FF FF 00 00 19 00 A7 40 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 2C 02 16 06 F6 00 A2 1A 00 A2 40 00 00 35 A7 FB FF FF 7E FA FF FF 00 00 19 00 A7 40 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 2C 02 16 0F 10 2C C2 01 67 40 00 00 25 04 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 53 |
Decompiled Code
XGStorage.RemoveLoadout
Original Code
function RemoveLoadout(XGStrategySoldier kSoldier) { local TInventory kTempInv; local int I; kTempInv = kSoldier.m_kChar.kInventory; ReleaseLoadout(kSoldier); RemoveItem(kTempInv.iArmor); RemoveItem(kTempInv.iPistol); I = 0; J0xa7: // End:0x110 Loop:True if(I < kTempInv.iNumLargeItems) { RemoveItem(kTempInv.arrLargeItems[I]); ++ I; // This is an implied JumpToken; Continue! goto J0xa7; } I = 0; J0x11b: // End:0x184 Loop:True if(I < kTempInv.iNumSmallItems) { RemoveItem(kTempInv.arrSmallItems[I]); ++ I; // This is an implied JumpToken; Continue! goto J0x11b; } }
New Code
function RemoveLoadout(XGStrategySoldier kSoldier) { local TInventory kTempInv; local int I; iNumCaptives = ITEMTREE().GetItem(m_arrItems[194] & 255).iStructureReq; // End:0xF6 if(iNumCaptives > 0) { // End:0xB7 if((m_arrItems[194] & (1 << 16)) > 0) { kSoldier.m_kChar.aUpgrades[iNumCaptives] += 2; } // End:0xF6 else { kSoldier.m_kChar.aUpgrades[iNumCaptives] -= 2; } } m_arrItems[194] = 0; return; }
ReleaseItem
This hex changes alters the XGStorage.ReleaseItem function in two ways:
- It alters the function to add the item to the m_arrItems[] array instead of removing it from the m_arrClaims[] array
- It calls the rebuilt helper function RemoveLoadout to remove a perk when the item is unequipped
original: | 89 40 00 00 AB 1F 00 00 00 00 00 00 86 40 00 00 00 00 00 00 00 00 00 00 89 40 00 00 00 00 00 00 BD 00 00 00 8A 16 00 00 69 00 00 00 4D 00 00 00 07 1A 00 1B 7A 14 00 00 00 00 00 00 38 3D 00 89 40 00 00 16 04 27 07 2B 00 9A 00 89 40 00 00 25 16 04 27 07 46 00 96 10 00 89 40 00 00 01 65 40 00 00 26 16 04 28 A2 10 00 89 40 00 00 01 65 40 00 00 26 16 04 27 04 3A 87 40 00 00 53 |
new: | 89 40 00 00 AB 1F 00 00 00 00 00 00 86 40 00 00 00 00 00 00 00 00 00 00 89 40 00 00 00 00 00 00 BD 00 00 00 8A 16 00 00 65 00 00 00 4D 00 00 00 07 1A 00 1B 7A 14 00 00 00 00 00 00 38 3D 00 89 40 00 00 16 04 27 0F 10 2C C2 01 67 40 00 00 00 85 40 00 00 1B B3 22 00 00 00 00 00 00 00 88 40 00 00 16 A1 10 00 89 40 00 00 01 67 40 00 00 26 16 04 27 0B 0B 0B 0B 0B 0B 0B 0B 0B 53 |
Decompiled Code
XGStorage.ReleaseItem
Original Code
function bool ReleaseItem(int iItemType, XGStrategySoldier kSoldier) { // End:0x1a Loop:False if(IsInfinite(byte(iItemType))) { return true; } // End:0x2b Loop:False if(iItemType == 0) { return true; } // End:0x46 Loop:False if(m_arrClaims[iItemType] < 1) { return false; } m_arrClaims[iItemType] -= 1; return true; }
New Code
function bool ReleaseItem(int iItemType, XGStrategySoldier kSoldier) { // End:0x1A if(IsInfinite(byte(iItemType))) { return true; } m_arrItems[194] = iItemType; RemoveLoadout(kSoldier); m_arrItems[iItemType] += 1; return true; }
ClaimItem
This hex change to XGStorage.ClaimItem does the following two things:
- Alters ClaimItem to remove the item from the m_arrItems[] array instead of adding it to the m_arrClaims[] array
- Calls the rebuilt helper function RemoveLoadout to enable adding a perk from equiping an item
original: | 85 40 00 00 AB 1F 00 00 00 00 00 00 82 40 00 00 00 00 00 00 00 00 00 00 85 40 00 00 00 00 00 00 AE 00 00 00 24 15 00 00 69 00 00 00 51 00 00 00 07 1A 00 1B 7A 14 00 00 00 00 00 00 38 3D 00 85 40 00 00 16 04 27 07 2B 00 9A 00 85 40 00 00 25 16 04 27 07 46 00 96 1B CC 0F 00 00 00 00 00 00 00 85 40 00 00 16 26 16 04 28 A1 10 00 85 40 00 00 01 65 40 00 00 26 16 04 27 04 3A 83 40 00 00 53 |
new: | 85 40 00 00 AB 1F 00 00 00 00 00 00 82 40 00 00 00 00 00 00 00 00 00 00 85 40 00 00 00 00 00 00 AE 00 00 00 24 15 00 00 69 00 00 00 51 00 00 00 07 1A 00 1B 7A 14 00 00 00 00 00 00 38 3D 00 85 40 00 00 16 04 27 0F 10 2C C2 01 67 40 00 00 9E 00 85 40 00 00 94 26 2C 10 16 16 1B B3 22 00 00 00 00 00 00 00 84 40 00 00 16 A2 10 00 85 40 00 00 01 67 40 00 00 26 16 04 27 0B 0B 0B 0B 0B 0B 53 |
Decompiled Code
XGStorage.ClaimItem
Original Code
function bool ClaimItem(int iItemType, XGStrategySoldier kSoldier) { // End:0x1a Loop:False if(IsInfinite(byte(iItemType))) { return true; } // End:0x2b Loop:False if(iItemType == 0) { return true; } // End:0x46 Loop:False if(GetNumItemsAvailable(iItemType) < 1) { return false; } m_arrClaims[iItemType] += 1; return true; }
New Code
function bool ClaimItem(int iItemType, XGStrategySoldier kSoldier) { // End:0x1A if(IsInfinite(byte(iItemType))) { return true; } m_arrItems[194] = iItemType | (1 << 16); RemoveLoadout(kSoldier); m_arrItems[iItemType] -= 1; return true; }
BuildItem
This hex change to XGItemTree.BuildItem allows the setting of the .iStructureReq, which is used to define what perk will be assigned as a side effect of equipping a particular item.
To set a perk, the iEngineer parameter of the BuildItem call in XGItemTree.BuildItems is set to the desired perk ID. The iEngineer parameter for the item will be overwriten by the DGC.ini ItemBalance= array.
original: | 0F 35 C0 02 00 00 C8 02 00 00 00 01 10 00 1D 36 00 00 01 66 35 00 00 00 18 36 00 00 |
new: | 0F 35 BC 02 00 00 BD 02 00 00 00 01 10 00 1D 36 00 00 01 66 35 00 00 00 18 36 00 00 |
Decompiled Code
XGItemTree.BuildItem
Original Code
m_arrItems[iItem].iMaxEngineers = iMaxEngineers;
New Code
m_arrItems[iItem].iStructureReq = iMaxEngineers;
References
Referred to by this article:
That refer to this article:
- <none>