Template:XGCharacter Soldier.LeveledUp - XCOM:EU 2012

From Nexus Mods Wiki
Jump to: navigation, search

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: