Template:XGCharacter Soldier.LeveledUp - XCOM:EU 2012
Overview
From file XComGame.upk, Class= XGCharacter_Soldier, Function= XGCharacter_Soldier.LeveledUp.
- Main purpose is to provide the required information for modifying this "Function" (a.k.a. "Object"), using the utility PatcherGUI (a separate download from UPK Utils Nexus "Files" page).
Programs and Tools
- UE Explorer
- UE Explorer (version 1.2.7.1) was used to obtain the desired function's "view=Object" (below), "view=Disassembled Tokens" (below) & "[BEFORE_HEX]" (below) from the XComGame.upk file.
- UPK Utils
- PatcherGUI (version 7.3, 04/10/15) utility was used to verify the "[BEFORE_CODE]" (below) from the XComGame.upk file.
- HexToPseudoCode utility provides an alternative method for obtaining the "[BEFORE_CODE]" (below) from an UnrealPackage file, in this case from the XComGame.upk file.
- ... this 'command-line' utility's output may be used as a "seed" (to start a PatcherGUI mod file with).
Details
1. Find the desired function (in Unreal Engine Explorer - view=Object) :
XGCharacter_Soldier.LeveledUp 1 function bool LeveledUp() 2 { 3 // End:0xB6 4 if(CanGainXP()) 5 { 6 return m_kSoldier.iXP >= XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(m_kSoldier.iRank + 1); 7 } 8 // End:0xB8 9 else 10 { 11 return false; 12 } 13 //return ReturnValue; 14 }
2. Discover (reveal) the hexidecimal values (in Unreal Engine Explorer - view=Disassembled Tokens) :
XGCharacter_Soldier.LeveledUp 1 (0-2;000/000) [07 B6 00 1B 77 0F 00 00 00 00 00 00 16] 2 JumpIfNotToken(13/13) 3 if(CanGainXP()) 4 5 (1-2;003/003) [1B 77 0F 00 00 00 00 00 00 16] 6 VirtualFunctionToken(10/10) 7 CanGainXP() 8 9 (2-2;00C/00C) [16] 10 EndFunctionParmsToken(1/1) 11 ) 12 13 (3-24;00D/00D) [04 99 35 35 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 29 00 BC 76 00 00 00 1B 83 35 00 00 00 00 00 00 92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16 16 16] 14 ReturnToken(166/106) 15 return m_kSoldier.iXP >= XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(m_kSoldier.iRank + 1) 16 17 (4-24;00E/00E) [99 35 35 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 29 00 BC 76 00 00 00 1B 83 35 00 00 00 00 00 00 92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16 16 16] 18 NativeFunctionToken(165/105) 19 m_kSoldier.iXP >= XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(m_kSoldier.iRank + 1) 20 21 (5-6;00F/00F) [35 35 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00] 22 StructMemberToken(28/16) 23 m_kSoldier.iXP 24 25 (6-6;022/01A) [01 8A A3 00 00] 26 InstanceVariableToken(9/5) 27 m_kSoldier 28 29 (7-23;02B/01F) [19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 29 00 BC 76 00 00 00 1B 83 35 00 00 00 00 00 00 92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16 16] 30 ContextToken(135/87) 31 XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(m_kSoldier.iRank + 1) 32 33 (8-16;02C/020) [19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00] 34 ContextToken(82/50) 35 XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore 36 37 (9-15;02D/021) [2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF] 38 DynamicCastToken(61/37) 39 XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI) 40 41 (10-15;036/026) [19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF] 42 ContextToken(52/32) 43 class'Engine'.static.GetCurrentWorldInfo().GRI 44 45 (11-14;037/027) [12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16] 46 ClassContextToken(31/19) 47 class'Engine'.static.GetCurrentWorldInfo() 48 49 (12-12;038/028) [20 4F FE FF FF] 50 ObjectConstToken(9/5) 51 class'Engine' 52 53 (13-14;04C/034) [1C F6 FB FF FF 16] 54 FinalFunctionToken(10/6) 55 GetCurrentWorldInfo() 56 57 (14-14;055/039) [16] 58 EndFunctionParmsToken(1/1) 59 ) 60 61 (15-15;061/041) [01 98 F9 FF FF] 62 InstanceVariableToken(9/5) 63 GRI 64 65 (16-16;075/04D) [01 F0 2C 00 00] 66 InstanceVariableToken(9/5) 67 m_kGameCore 68 69 (17-23;089/059) [1B 83 35 00 00 00 00 00 00 92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16 16] 70 VirtualFunctionToken(41/29) 71 GetXPRequired(m_kSoldier.iRank + 1) 72 73 (18-22;092/062) [92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16] 74 NativeFunctionToken(31/19) 75 m_kSoldier.iRank + 1 76 77 (19-20;093/063) [35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00] 78 StructMemberToken(28/16) 79 m_kSoldier.iRank 80 81 (20-20;0A6/06E) [01 8A A3 00 00] 82 InstanceVariableToken(9/5) 83 m_kSoldier 84 85 (21-21;0AF/073) [26] 86 IntOneToken(1/1) 87 1 88 89 (22-22;0B0/074) [16] 90 EndFunctionParmsToken(1/1) 91 ) 92 93 (23-23;0B1/075) [16] 94 EndFunctionParmsToken(1/1) 95 ) 96 97 (24-24;0B2/076) [16] 98 EndFunctionParmsToken(1/1) 99 ) 100 101 (25-25;0B3/077) [06 B8 00] 102 JumpToken(3/3) 103 goto J0xB8 104 105 (26-27;0B6/07A) [04 28] 106 ReturnToken(2/2) 107 return false 108 109 (27-27;0B7/07B) [28] 110 FalseToken(1/1) 111 false 112 113 (28-29;0B8/07C) [04 3A B3 A3 00 00] 114 ReturnToken(10/6) 115 return ReturnValue 116 117 (29-29;0B9/07D) [3A B3 A3 00 00] 118 ReturnNothingToken(9/5) 119 ReturnValue
3. Capture the function's hexidecimal code (as shown here - PatcherGUI ready) :
UPK_FILE=XComGame.upk OBJECT=XGCharacter_Soldier.LeveledUp:KEEP [BEFORE_HEX] 07 B6 00 1B 77 0F 00 00 00 00 00 00 16 04 99 35 35 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 29 00 BC 76 00 00 00 1B 83 35 00 00 00 00 00 00 92 35 38 0E 00 00 3D 0E 00 00 00 00 01 8A A3 00 00 26 16 16 16 06 B8 00 04 28 04 3A B3 A3 00 00 [/BEFORE_HEX] // The Mod Developer / Programmer has to do all the Offset and Size arithmetic!
4. By whatever means obtain the required UPKUtils pseodo-code (that will produce the -above- 'captured' hexidecimal code) :
UPK_FILE=XComGame.upk OBJECT=XGCharacter_Soldier.LeveledUp:AUTO [BEFORE_CODE] 07 [@elseXGCSlu] 1B <CanGainXP> 16 04 99 35 <XGTacticalGameCoreNativeBase.TSoldier.iXP> <XGTacticalGameCoreNativeBase.TSoldier> 00 00 01 <XGCharacter_Soldier.m_kSoldier> 19 19 2E <Class.XComGameReplicationInfo> 19 12 20 <Engine.Engine> [@] <Engine.Engine.GetCurrentWorldInfo.ReturnValue> 00 ( 1C <Engine.Engine.GetCurrentWorldInfo> 16 ) [@] <Engine.WorldInfo.GRI> 00 ( 01 <Engine.WorldInfo.GRI> ) [@] <XComGameReplicationInfo.m_kGameCore> 00 ( 01 <XComGameReplicationInfo.m_kGameCore> ) [@] <XGTacticalGameCore.GetXPRequired.ReturnValue> 00 ( 1B <GetXPRequired> 92 35 <XGTacticalGameCoreNativeBase.TSoldier.iRank> <XGTacticalGameCoreNativeBase.TSoldier> 00 00 01 <XGCharacter_Soldier.m_kSoldier> 26 16 16 ) 16 06 [@endXGCSlu] [#elseXGCSlu] 04 28 [#endXGCSlu] 04 3A <.ReturnValue> [/BEFORE_CODE] { When properly coded - PatcherGUI will do the Offset and Size arithmetic; while also doing any required expanding or shrinking. } [AFTER_CODE] // modified PatcherGUI script (more properly stated: a mixture of hexidecimal code and UPKUtils pseudo-code) goes here ... // or the BEFORE_CODE values may be copied here to confirm that the BEFORE_CODE values are correct, without making any actual modifications. [/AFTER_CODE]
References
Referred to by this article:
That refer to this article: