GetPerkInTree UPK mods Enhanced Perk Tree - XCOM:EU 2012

From Nexus Mods Wiki
Jump to: navigation, search

Overview

This page deals with the upk changes modifying the GetPerkInTree functions, which are necessary to fully implement the Enhanced Perk Tree mod

All of these changes are applied to XcomGame.upk

For those who require or prefer the before/after hex blocks, they are here : Before/after hex for GetPerkInTree

Programs and Tools

  • UE Explorer
  • ToolBoks v1.20 or greater

Details

There are five separate hex changes necessary to implement this portion of the Enhanced Perk Tree mod.


The PerkInTree functions refer to 'option' and 'branch'

  • Row corresponds with 'option', and relates to the number of ability icons displayed per rank
  • Column corresponds with 'branch', and relates to the soldier rank


  1. Rewrite GetPerkInTreeAssault to support up to 44 perk definitions
  2. Rewrite GetPerkInTreeHeavy to support up to 44 perk definitions
  3. Rewrite GetPerkInTreeSniper to support up to 44 perk definitions
  4. Rewrite GetPerkInTreeSupport to support up to 44 perk definitions
  5. Rewrite GetPerkInTreePsi to support up to 16 perk definitions

Support for 11 branches is present in the Class functions, although the initial release only utilizes the first 7 branches Support for 4 options per branch is present in all five functions, although the initial release only utilizes the first 3

These functions all follow a common format.

  • The branch is selected using a switch/case statement
  • The option is selected by byte-shifting a four byte integer to select byte 0, 1, 2, or 3.
    • byte 0 corresponds to option 0
    • byte 1 corresponds to option 1
    • byte 2 corresponds to option 2
    • byte 3 corresponds to option 3

File Changes

All functions share the following format:

Option *= float(8);
switch(branch)
{
    case 1:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 2:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 3:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 4:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 5:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 6:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 7:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 8:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 9:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 10:
        return((## ## ## ## >> Option) & 0xFF); // numbers are based on perk ID
    
    case 11:
        return (## ## ## ## >> Option) & 0xFF; // numbers are based on perk ID
        
    default:
        return 0
}

GetPerkInTreePsi is identical excepting that the cases only go up to (and including) 4.

  • 'break;' statements are not required because the function always returns after entering a case
  • The heart of the operation is the (## ## ## ## >> Option) & 0xFF; operation
    • ## ## ## ## is a four byte integer value
      • represented in hexadecimal, each 2 digit part represents a perk
        • Ex: 0x00242C30 represents : perk0 = 0x30, perk1 = 0x2C, perk2 = 0x24, perk3 = 0x0
      • represented in decimal, the numbers are jumbled together, but are represented by perk3*2^24 + perk2*2^16 + perk1*2^8 + perk0
        • Ex: perk0 = 0x30 = 48, perk1 = 0x2C = 44, perk2 = 0x24 = 36 results in 36*2^16 + 44*2^8 + 48 = 2,370,608
        • Note that 2,370,608 = 0x242C30
    • The >> is the shift-left operator : See wikipedia article [1] for more info
    • Option enters the function as the value 0, 1, 2, or 3
      • Option is then multiplied by 8 to become 0, 8, 16 or 24
        • The shift-left operator places the correct byte into bits 0-7
          • The bit-wise AND operator then masks the rest of the 4-byte integer

Hex code replacements compatible with Toolboks' Custom Mod feature will be presented below for each of the five functions.

GetPerkInTreeAssault

This replaces the default function with one using the format described above.

Custom Mod

MOD_NAME=Assault Expanded Perk List
AUTHOR=amineri
DESCRIPTION=Modifies the assault perk list.

This mod is only compatible with the Expanded Perk Tree mod.

Version: 1.0

Compatible with XCOM Enemy Unknown versions:
 - Patch 4 ( Changelist: 356266 )


UPK_FILE=XComGame.upk
OFFSET=7170224
[MODDED_HEX]
{ offset = 0x6D68B0}
{ Assault Tree }
{header}
49 66 00 00 50 55 00 00 00 00 00 00 34 66 00 00 00 00 00 00 00 00 00 00 37 66 00 00 00 00 00 00 92 01 00 00 DB 3D 00 00 47 01 00 00 0F 01 00 00 

{
00 36 66 00 00 -- local variable Option 
00 37 66 00 00 -- local variable branch 
}

{body}
{Option *= float(8);}
9F 00 36 66 00 00 38 3F 2C 08 16 

{switch(branch)}
05 37 66 00 00 00 00 37 66 00 00 

    {case 1:}
    0A 3C 00 2C 01 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 06 00 23 00 00 36 66 00 00 16 16 
    
    {case 2:}
    0A 56 00 2C 02 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 06 25 21 00 00 36 66 00 00 16 16 
    
    {case 3:}
    0A 70 00 2C 03 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 22 25 20 00 00 36 66 00 00 16 16 
    
    {case 4:}
    0A 8A 00 2C 04 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 24 25 23 00 00 36 66 00 00 16 16 
    
    {case 5:}
    0A A4 00 2C 05 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 27 00 28 00 00 36 66 00 00 16 16 
    
    {case 6:}
    0A BE 00 2C 06 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 1B 00 00 00 36 66 00 00 16 16 
    
    {case 7:}
    0A D8 00 2C 07 

       { return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 29 00 2B 00 00 36 66 00 00 16 16 
    
    {case 8:}
    0A F2 00 2C 08 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 
    
    {case 9:}
    0A 0C 01 2C 09 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 
    
    {case 10:}
    0A 26 01 2C 0A 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 
    
    {case 11:}
    0A 40 01 2C 0B 

        {return ((p0 p1 p2 p3 >> Option) & 0xFF; // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 
        
    {default:}
    0A FF FF 
    
{return 0}
04 25 

{null-ops (1 bytes)}
0B 

{endofscript}
53 

{last byte at +0x13E = offset 0x6D69EE}


GetPerkInTreeHeavy

This replaces the default function with one using the format described above.

Custom Mod

MOD_NAME=Heavy Expanded Perk List
AUTHOR=amineri
DESCRIPTION=Modifies the heavy perk list.

This mod is only compatible with the Expanded Perk Tree mod.

Version: 1.0

Compatible with XCOM Enemy Unknown versions:
 - Patch 4 ( Changelist: 356266 )


UPK_FILE=XComGame.upk
OFFSET=7169770
[MODDED_HEX]
{ offset = 0x6D66EA}
{ Heavy Tree }
{header}
45 66 00 00 50 55 00 00 00 00 00 00 30 66 00 00 00 00 00 00 00 00 00 00 33 66 00 00 00 00 00 00 5F 01 00 00 20 3A 00 00 47 01 00 00 0F 01 00 00 

{
00 32 66 00 00 -- local variable Option 
00 33 66 00 00 -- local variable branch 
}

{body}
{Option *= float(8);}
9F 00 32 66 00 00 38 3F 2C 08 16 

{switch(branch)}
05 33 66 00 00 00 00 33 66 00 00 

    {case 1:}
    0A 3C 00 2C 01 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 12 00 1A 00 00 32 66 00 00 16 16 
    
    {case 2:}
    0A 56 00 2C 02 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 12 18 15 00 00 32 66 00 00 16 16 
    
    {case 3:}
    0A 70 00 2C 03 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 16 17 13 00 00 32 66 00 00 16 16 
    
    {case 4:}
    0A 8A 00 2C 04 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 18 05 5B 00 00 32 66 00 00 16 16 
    
    {case 5:}
    0A A4 00 2C 05 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 19 00 11 00 00 32 66 00 00 16 16 
    
    {case 6:}
    0A BE 00 2C 06 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 19 00 11 00 00 32 66 00 00 16 16 
    
    {case 7:}
    0A D8 00 2C 07 

       { return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 5E 00 5D 00 00 32 66 00 00 16 16 
    
    {case 8:}
    0A F2 00 2C 08 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 
    
    {case 9:}
    0A 0C 01 2C 09 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 
    
    {case 10:}
    0A 26 01 2C 0A 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 
    
    {case 11:}
    0A 40 01 2C 0B 

        {return ((p0 p1 p2 p3 >> Option) & 0xFF; // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 
        
    {default:}
    0A FF FF 
    
{return 0}
04 25 

{null-ops (1 bytes)}
0B 

{endofscript}
53 

{last byte at +0x13E = offset 0x6D6828}


GetPerkInTreeSniper

This replaces the default function with one using the format described above.

Custom Mod

MOD_NAME=Sniper Expanded Perk List
AUTHOR=amineri
DESCRIPTION=Modifies the sniper perk list.

This mod is only compatible with the Expanded Perk Tree mod.

Version: 1.0

Compatible with XCOM Enemy Unknown versions:
 - Patch 4 ( Changelist: 356266 )


UPK_FILE=XComGame.upk
OFFSET=7169316
[MODDED_HEX]
{ offset = 0x6D6524}
{ Sniper Tree }
{header}
41 66 00 00 50 55 00 00 00 00 00 00 2C 66 00 00 00 00 00 00 00 00 00 00 2F 66 00 00 00 00 00 00 2C 01 00 00 65 36 00 00 47 01 00 00 0F 01 00 00 

{
00 2E 66 00 00 -- local variable Option 
00 2F 66 00 00 -- local variable branch 
}

{body}
{Option *= float(8);}
9F 00 2E 66 00 00 38 3F 2C 08 16 

{switch(branch)}
05 2F 66 00 00 00 00 2F 66 00 00 

    {case 1:}
    0A 3C 00 2C 01 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 03 00 10 00 00 2E 66 00 00 16 16 
    
    {case 2:}
    0A 56 00 2C 02 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 0F 09 02 00 00 2E 66 00 00 16 16 
    
    {case 3:}
    0A 70 00 2C 03 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 0F 00 5F 00 00 2E 66 00 00 16 16 
    
    {case 4:}
    0A 8A 00 2C 04 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 08 02 09 00 00 2E 66 00 00 16 16 
    
    {case 5:}
    0A A4 00 2C 05 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 0A 00 0B 00 00 2E 66 00 00 16 16 
    
    {case 6:}
    0A BE 00 2C 06 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 05 00 00 00 2E 66 00 00 16 16 
    
    {case 7:}
    0A D8 00 2C 07 

       { return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 0D 00 0E 00 00 2E 66 00 00 16 16 
    
    {case 8:}
    0A F2 00 2C 08 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 
    
    {case 9:}
    0A 0C 01 2C 09 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 
    
    {case 10:}
    0A 26 01 2C 0A 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 
    
    {case 11:}
    0A 40 01 2C 0B 

        {return ((p0 p1 p2 p3 >> Option) & 0xFF; // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 
        
    {default:}
    0A FF FF 
    
{return 0}
04 25 

{null-ops (1 bytes)}
0B 

{endofscript}
53 

{last byte at +0x13E = offset 0x6D6662}


GetPerkInTreeSupport

This replaces the default function with one using the format described above.

Custom Mod

MOD_NAME=Support Expanded Perk List
AUTHOR=amineri
DESCRIPTION=Modifies the support perk list.

This mod is only compatible with the Expanded Perk Tree mod.

Version: 1.0

Compatible with XCOM Enemy Unknown versions:
 - Patch 4 ( Changelist: 356266 )


UPK_FILE=XComGame.upk
OFFSET=7170678
[MODDED_HEX]
{ offset = 0x6D6A76 }
{ Support Tree }
{header}
4D 66 00 00 50 55 00 00 00 00 00 00 38 66 00 00 00 00 00 00 00 00 00 00 3B 66 00 00 00 00 00 00 C5 01 00 00 A2 41 00 00 47 01 00 00 0F 01 00 00 

{
00 3A 66 00 00 -- local variable Option
00 3B 66 00 00 -- local variable branch
}

{body}
{Option *= float(8);}
9F 00 3A 66 00 00 38 3F 2C 08 16 

{switch(branch)}
05 3B 66 00 00 00 00 3B 66 00 00 

    {case 1:}
    0A 3C 00 2C 01 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 2C 00 30 00 00 3A 66 00 00 16 16 
    
    {case 2:}
    0A 56 00 2C 02 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 2C 33 1F 00 00 3A 66 00 00 16 16 
    
    {case 3:}
    0A 70 00 2C 03 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 31 2F 30 00 00 3A 66 00 00 16 16 
    
    {case 4:}
    0A 8A 00 2C 04 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 5C 2F 38 00 00 3A 66 00 00 16 16 
    
    {case 5:}
    0A A4 00 2C 05 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 31 00 34 00 00 3A 66 00 00 16 16 
    
    {case 6:}
    0A BE 00 2C 06 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 35 00 00 00 3A 66 00 00 16 16 
    
    {case 7:}
    0A D8 00 2C 07 

       { return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 36 00 37 00 00 3A 66 00 00 16 16 
    
    {case 8:}
    0A F2 00 2C 08 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 
    
    {case 9:}
    0A 0C 01 2C 09 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 
    
    {case 10:}
    0A 26 01 2C 0A 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 
    
    {case 11:}
    0A 40 01 2C 0B 

        {return ((p0 p1 p2 p3 >> Option) & 0xFF; // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 
        
    {default:}
    0A FF FF 
    
{return 0}
04 25 

{null-ops (1 bytes)}
0B 

{endofscript}
53 

{last byte at +0x13E = offset 0x6D6BB4}



GetPerkInTreePsi

This replaces the default function with one using the format described above.

Custom Mod

MOD_NAME=Psi Expanded Perk List
AUTHOR=amineri
DESCRIPTION=Modifies the psi perk list.

This mod is only compatible with the Expanded Perk Tree mod.

Version: 1.0

Compatible with XCOM Enemy Unknown versions:
 - Patch 4 ( Changelist: 356266 )


UPK_FILE=XComGame.upk
OFFSET=7169000
[MODDED_HEX]
{ offset = 0x6D63E8 }
{ Psi Tree }
{header}
3D 66 00 00 50 55 00 00 00 00 00 00 28 66 00 00 00 00 00 00 00 00 00 00 2B 66 00 00 00 00 00 00 10 01 00 00 67 34 00 00 A1 00 00 00 85 00 00 00 

{
00 2A 66 00 00 -- local variable Option 
00 2B 66 00 00 -- local variable branch  
}

{body}
{Option *= float(8);}
9F 00 2A 66 00 00 38 3F 2C 08 16 

{switch(branch)}
05 2B 66 00 00 00 00 2B 66 00 00 

    {case 1:}
    0A 3C 00 2C 01 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 45 00 00 00 2A 66 00 00 16 16 
    
    {case 2:}
    0A 56 00 2C 02 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 46 00 47 00 00 2A 66 00 00 16 16 
    
    {case 3:}
    0A 70 00 2C 03 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 48 00 49 00 00 2A 66 00 00 16 16 
    
    {case 4:}
    0A 8A 00 2C 04 

        {return((p0 p1 p2 p3 >> Option) & 0xFF); // numbers are based on perk ID}
        04 9C 2C FF 95 1D 00 4A 00 00 00 2A 66 00 00 16 16 
    
    
{return 0}
04 25 

{null-ops (20 bytes)}
0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 

{endofscript}
53 

{last byte at +0xB4 => offset 0x6D649C}





References

Referred to by this article:

That refer to this article: