GetPerkInTree before after 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 ToolBoks Custom Mods, they are here : ToolBoks Custom Mods for GetPerkInTree

Programs and Tools

  • UE Explorer
  • HxD Hex Editor

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.

Hex Change

XcomPerkManager.GetPerkInTreeAssault
original: 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 57 01 00 00 0F 01 00 00 07 15 00 9A 00 37 66 00 00 26 16 04 2C 06 06 4A 01 07 4F 00 9A 00 37 66 00 00 2C 02 16 07 3A 00 9A 00 36 66 00 00 25 16 04 2C 20 06 4C 00 07 4C 00 9A 00 36 66 00 00 26 16 04 2C 21 06 4A 01 07 89 00 9A 00 37 66 00 00 2C 03 16 07 74 00 9A 00 36 66 00 00 25 16 04 2C 22 06 86 00 07 86 00 9A 00 36 66 00 00 26 16 04 2C 23 06 4A 01 07 C3 00 9A 00 37 66 00 00 2C 04 16 07 AE 00 9A 00 36 66 00 00 25 16 04 2C 24 06 C0 00 07 C0 00 9A 00 36 66 00 00 26 16 04 2C 25 06 4A 01 07 FD 00 9A 00 37 66 00 00 2C 05 16 07 E8 00 9A 00 36 66 00 00 25 16 04 2C 27 06 FA 00 07 FA 00 9A 00 36 66 00 00 26 16 04 2C 28 06 4A 01 07 13 01 9A 00 37 66 00 00 2C 06 16 04 2C 1B 06 4A 01 07 4A 01 9A 00 37 66 00 00 2C 07 16 07 38 01 9A 00 36 66 00 00 25 16 04 2C 29 06 4A 01 07 4A 01 9A 00 36 66 00 00 26 16 04 2C 2B 04 25 04 3A 35 66 00 00 53
new: 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 9F 00 36 66 00 00 38 3F 2C 08 16 05 37 66 00 00 00 00 37 66 00 00 0A 3C 00 2C 01 04 9C 2C FF 95 1D 06 00 23 00 00 36 66 00 00 16 16 0A 56 00 2C 02 04 9C 2C FF 95 1D 06 25 21 00 00 36 66 00 00 16 16 0A 70 00 2C 03 04 9C 2C FF 95 1D 22 25 20 00 00 36 66 00 00 16 16 0A 8A 00 2C 04 04 9C 2C FF 95 1D 24 25 23 00 00 36 66 00 00 16 16 0A A4 00 2C 05 04 9C 2C FF 95 1D 27 00 28 00 00 36 66 00 00 16 16 0A BE 00 2C 06 04 9C 2C FF 95 1D 00 1B 00 00 00 36 66 00 00 16 16 0A D8 00 2C 07 04 9C 2C FF 95 1D 29 00 2B 00 00 36 66 00 00 16 16 0A F2 00 2C 08 04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 0A 0C 01 2C 09 04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 0A 26 01 2C 0A 04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 0A 40 01 2C 0B 04 9C 2C FF 95 1D 00 00 00 00 00 36 66 00 00 16 16 0A FF FF 04 25 0B 53

Decompiled Code

Original Code
function int GetPerkInTreeAssault(int branch, int Option)
{
    // End:0x15
    if(branch == 1)
    {
        return 6;
    }
    // End:0x14A
    else
    {
        // End:0x4F
        if(branch == 2)
        {
            // End:0x3A
            if(Option == 0)
            {
                return 32;
            }
            // End:0x4C
            else
            {
                // End:0x4C
                if(Option == 1)
                {
                    return 33;
                }
            }
        }
        // End:0x14A
        else
        {
            // End:0x89
            if(branch == 3)
            {
                // End:0x74
                if(Option == 0)
                {
                    return 34;
                }
                // End:0x86
                else
                {
                    // End:0x86
                    if(Option == 1)
                    {
                        return 35;
                    }
                }
            }
            // End:0x14A
            else
            {
                // End:0xC3
                if(branch == 4)
                {
                    // End:0xAE
                    if(Option == 0)
                    {
                        return 36;
                    }
                    // End:0xC0
                    else
                    {
                        // End:0xC0
                        if(Option == 1)
                        {
                            return 37;
                        }
                    }
                }
                // End:0x14A
                else
                {
                    // End:0xFD
                    if(branch == 5)
                    {
                        // End:0xE8
                        if(Option == 0)
                        {
                            return 39;
                        }
                        // End:0xFA
                        else
                        {
                            // End:0xFA
                            if(Option == 1)
                            {
                                return 40;
                            }
                        }
                    }
                    // End:0x14A
                    else
                    {
                        // End:0x113
                        if(branch == 6)
                        {
                            return 27;
                        }
                        // End:0x14A
                        else
                        {
                            // End:0x14A
                            if(branch == 7)
                            {
                                // End:0x138
                                if(Option == 0)
                                {
                                    return 41;
                                }
                                // End:0x14A
                                else
                                {
                                    // End:0x14A
                                    if(Option == 1)
                                    {
                                        return 43;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
    //return ReturnValue;    
}

New Code
function int GetPerkInTreeAssault(int branch, int Option)
{
    Option *= float(8);
    switch(branch)
    {
        // End:0x3C
        case 1:
            return 255 & (2293766 >> Option);
        // End:0x56
        case 2:
            return 255 & (2172166 >> Option);
        // End:0x70
        case 3:
            return 255 & (2106658 >> Option);
        // End:0x8A
        case 4:
            return 255 & (2303268 >> Option);
        // End:0xA4
        case 5:
            return 255 & (2621479 >> Option);
        // End:0xBE
        case 6:
            return 255 & (6912 >> Option);
        // End:0xD8
        case 7:
            return 255 & (2818089 >> Option);
        // End:0xF2
        case 8:
            return 255 & (0 >> Option);
        // End:0x10C
        case 9:
            return 255 & (0 >> Option);
        // End:0x126
        case 10:
            return 255 & (0 >> Option);
        // End:0x140
        case 11:
            return 255 & (0 >> Option);
        // End:0xFFFF
        default:
            return 0;
    }        
}

GetPerkInTreeHeavy

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

Hex Change

XcomPerkManager.GetPerkInTreeHeavyWeapons
original: 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 57 01 00 00 0F 01 00 00 07 15 00 9A 00 33 66 00 00 26 16 04 2C 12 06 4A 01 07 4F 00 9A 00 33 66 00 00 2C 02 16 07 3A 00 9A 00 32 66 00 00 25 16 04 2C 13 06 4C 00 07 4C 00 9A 00 32 66 00 00 26 16 04 2C 1A 06 4A 01 07 89 00 9A 00 33 66 00 00 2C 03 16 07 74 00 9A 00 32 66 00 00 25 16 04 2C 15 06 86 00 07 86 00 9A 00 32 66 00 00 26 16 04 2C 16 06 4A 01 07 C3 00 9A 00 33 66 00 00 2C 04 16 07 AE 00 9A 00 32 66 00 00 25 16 04 2C 17 06 C0 00 07 C0 00 9A 00 32 66 00 00 26 16 04 2C 5B 06 4A 01 07 FD 00 9A 00 33 66 00 00 2C 05 16 07 E8 00 9A 00 32 66 00 00 25 16 04 2C 19 06 FA 00 07 FA 00 9A 00 32 66 00 00 26 16 04 2C 18 06 4A 01 07 13 01 9A 00 33 66 00 00 2C 06 16 04 2C 11 06 4A 01 07 4A 01 9A 00 33 66 00 00 2C 07 16 07 38 01 9A 00 32 66 00 00 25 16 04 2C 5E 06 4A 01 07 4A 01 9A 00 32 66 00 00 26 16 04 2C 5D 04 25 04 3A 31 66 00 00 53
new: 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 9F 00 32 66 00 00 38 3F 2C 08 16 05 33 66 00 00 00 00 33 66 00 00 0A 3C 00 2C 01 04 9C 2C FF 95 1D 12 00 1A 00 00 32 66 00 00 16 16 0A 56 00 2C 02 04 9C 2C FF 95 1D 12 18 15 00 00 32 66 00 00 16 16 0A 70 00 2C 03 04 9C 2C FF 95 1D 16 17 13 00 00 32 66 00 00 16 16 0A 8A 00 2C 04 04 9C 2C FF 95 1D 18 05 5B 00 00 32 66 00 00 16 16 0A A4 00 2C 05 04 9C 2C FF 95 1D 19 00 11 00 00 32 66 00 00 16 16 0A BE 00 2C 06 04 9C 2C FF 95 1D 19 00 11 00 00 32 66 00 00 16 16 0A D8 00 2C 07 04 9C 2C FF 95 1D 5E 00 5D 00 00 32 66 00 00 16 16 0A F2 00 2C 08 04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 0A 0C 01 2C 09 04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 0A 26 01 2C 0A 04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 0A 40 01 2C 0B 04 9C 2C FF 95 1D 00 00 00 00 00 32 66 00 00 16 16 0A FF FF 04 25 0B 53

Decompiled Code

Original Code
function int GetPerkInTreeHeavyWeapons(int branch, int Option)
{
    // End:0x15
    if(branch == 1)
    {
        return 18;
    }
    // End:0x14A
    else
    {
        // End:0x4F
        if(branch == 2)
        {
            // End:0x3A
            if(Option == 0)
            {
                return 19;
            }
            // End:0x4C
            else
            {
                // End:0x4C
                if(Option == 1)
                {
                    return 26;
                }
            }
        }
        // End:0x14A
        else
        {
            // End:0x89
            if(branch == 3)
            {
                // End:0x74
                if(Option == 0)
                {
                    return 21;
                }
                // End:0x86
                else
                {
                    // End:0x86
                    if(Option == 1)
                    {
                        return 22;
                    }
                }
            }
            // End:0x14A
            else
            {
                // End:0xC3
                if(branch == 4)
                {
                    // End:0xAE
                    if(Option == 0)
                    {
                        return 23;
                    }
                    // End:0xC0
                    else
                    {
                        // End:0xC0
                        if(Option == 1)
                        {
                            return 91;
                        }
                    }
                }
                // End:0x14A
                else
                {
                    // End:0xFD
                    if(branch == 5)
                    {
                        // End:0xE8
                        if(Option == 0)
                        {
                            return 25;
                        }
                        // End:0xFA
                        else
                        {
                            // End:0xFA
                            if(Option == 1)
                            {
                                return 24;
                            }
                        }
                    }
                    // End:0x14A
                    else
                    {
                        // End:0x113
                        if(branch == 6)
                        {
                            return 17;
                        }
                        // End:0x14A
                        else
                        {
                            // End:0x14A
                            if(branch == 7)
                            {
                                // End:0x138
                                if(Option == 0)
                                {
                                    return 94;
                                }
                                // End:0x14A
                                else
                                {
                                    // End:0x14A
                                    if(Option == 1)
                                    {
                                        return 93;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
    //return ReturnValue;    
}

New Code
function int GetPerkInTreeHeavyWeapons(int branch, int Option)
{
    Option *= float(8);
    switch(branch)
    {
        // End:0x3C
        case 1:
            return 255 & (1703954 >> Option);
        // End:0x56
        case 2:
            return 255 & (1382418 >> Option);
        // End:0x70
        case 3:
            return 255 & (1251094 >> Option);
        // End:0x8A
        case 4:
            return 255 & (5965080 >> Option);
        // End:0xA4
        case 5:
            return 255 & (1114137 >> Option);
        // End:0xBE
        case 6:
            return 255 & (1114137 >> Option);
        // End:0xD8
        case 7:
            return 255 & (6094942 >> Option);
        // End:0xF2
        case 8:
            return 255 & (0 >> Option);
        // End:0x10C
        case 9:
            return 255 & (0 >> Option);
        // End:0x126
        case 10:
            return 255 & (0 >> Option);
        // End:0x140
        case 11:
            return 255 & (0 >> Option);
        // End:0xFFFF
        default:
            return 0;
    }        
}

GetPerkInTreeSniper

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

Hex Change

XcomPerkManager.GetPerkInTreeSniper
original: 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 57 01 00 00 0F 01 00 00 07 15 00 9A 00 2F 66 00 00 26 16 04 2C 02 06 4A 01 07 4F 00 9A 00 2F 66 00 00 2C 02 16 07 3A 00 9A 00 2E 66 00 00 25 16 04 2C 03 06 4C 00 07 4C 00 9A 00 2E 66 00 00 26 16 04 2C 10 06 4A 01 07 89 00 9A 00 2F 66 00 00 2C 03 16 07 74 00 9A 00 2E 66 00 00 25 16 04 2C 0F 06 86 00 07 86 00 9A 00 2E 66 00 00 26 16 04 2C 5F 06 4A 01 07 C3 00 9A 00 2F 66 00 00 2C 04 16 07 AE 00 9A 00 2E 66 00 00 25 16 04 2C 08 06 C0 00 07 C0 00 9A 00 2E 66 00 00 26 16 04 2C 09 06 4A 01 07 FD 00 9A 00 2F 66 00 00 2C 05 16 07 E8 00 9A 00 2E 66 00 00 25 16 04 2C 0A 06 FA 00 07 FA 00 9A 00 2E 66 00 00 26 16 04 2C 0B 06 4A 01 07 13 01 9A 00 2F 66 00 00 2C 06 16 04 2C 05 06 4A 01 07 4A 01 9A 00 2F 66 00 00 2C 07 16 07 38 01 9A 00 2E 66 00 00 25 16 04 2C 0D 06 4A 01 07 4A 01 9A 00 2E 66 00 00 26 16 04 2C 0E 04 25 04 3A 2D 66 00 00 53
new: 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 9F 00 2E 66 00 00 38 3F 2C 08 16 05 2F 66 00 00 00 00 2F 66 00 00 0A 3C 00 2C 01 04 9C 2C FF 95 1D 03 00 10 00 00 2E 66 00 00 16 16 0A 56 00 2C 02 04 9C 2C FF 95 1D 0F 09 02 00 00 2E 66 00 00 16 16 0A 70 00 2C 03 04 9C 2C FF 95 1D 0F 00 5F 00 00 2E 66 00 00 16 16 0A 8A 00 2C 04 04 9C 2C FF 95 1D 08 02 09 00 00 2E 66 00 00 16 16 0A A4 00 2C 05 04 9C 2C FF 95 1D 0A 00 0B 00 00 2E 66 00 00 16 16 0A BE 00 2C 06 04 9C 2C FF 95 1D 00 05 00 00 00 2E 66 00 00 16 16 0A D8 00 2C 07 04 9C 2C FF 95 1D 0D 00 0E 00 00 2E 66 00 00 16 16 0A F2 00 2C 08 04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 0A 0C 01 2C 09 04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 0A 26 01 2C 0A 04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 0A 40 01 2C 0B 04 9C 2C FF 95 1D 00 00 00 00 00 2E 66 00 00 16 16 0A FF FF 04 25 0B 53

Decompiled Code

Original Code
function int GetPerkInTreeSniper(int branch, int Option)
{
    // End:0x15
    if(branch == 1)
    {
        return 2;
    }
    // End:0x14A
    else
    {
        // End:0x4F
        if(branch == 2)
        {
            // End:0x3A
            if(Option == 0)
            {
                return 3;
            }
            // End:0x4C
            else
            {
                // End:0x4C
                if(Option == 1)
                {
                    return 16;
                }
            }
        }
        // End:0x14A
        else
        {
            // End:0x89
            if(branch == 3)
            {
                // End:0x74
                if(Option == 0)
                {
                    return 15;
                }
                // End:0x86
                else
                {
                    // End:0x86
                    if(Option == 1)
                    {
                        return 95;
                    }
                }
            }
            // End:0x14A
            else
            {
                // End:0xC3
                if(branch == 4)
                {
                    // End:0xAE
                    if(Option == 0)
                    {
                        return 8;
                    }
                    // End:0xC0
                    else
                    {
                        // End:0xC0
                        if(Option == 1)
                        {
                            return 9;
                        }
                    }
                }
                // End:0x14A
                else
                {
                    // End:0xFD
                    if(branch == 5)
                    {
                        // End:0xE8
                        if(Option == 0)
                        {
                            return 10;
                        }
                        // End:0xFA
                        else
                        {
                            // End:0xFA
                            if(Option == 1)
                            {
                                return 11;
                            }
                        }
                    }
                    // End:0x14A
                    else
                    {
                        // End:0x113
                        if(branch == 6)
                        {
                            return 5;
                        }
                        // End:0x14A
                        else
                        {
                            // End:0x14A
                            if(branch == 7)
                            {
                                // End:0x138
                                if(Option == 0)
                                {
                                    return 13;
                                }
                                // End:0x14A
                                else
                                {
                                    // End:0x14A
                                    if(Option == 1)
                                    {
                                        return 14;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
    //return ReturnValue;    
}

New Code
function int GetPerkInTreeSniper(int branch, int Option)
{
    Option *= float(8);
    switch(branch)
    {
        // End:0x3C
        case 1:
            return 255 & (1048579 >> Option);
        // End:0x56
        case 2:
            return 255 & (133391 >> Option);
        // End:0x70
        case 3:
            return 255 & (6225935 >> Option);
        // End:0x8A
        case 4:
            return 255 & (590344 >> Option);
        // End:0xA4
        case 5:
            return 255 & (720906 >> Option);
        // End:0xBE
        case 6:
            return 255 & (1280 >> Option);
        // End:0xD8
        case 7:
            return 255 & (917517 >> Option);
        // End:0xF2
        case 8:
            return 255 & (0 >> Option);
        // End:0x10C
        case 9:
            return 255 & (0 >> Option);
        // End:0x126
        case 10:
            return 255 & (0 >> Option);
        // End:0x140
        case 11:
            return 255 & (0 >> Option);
        // End:0xFFFF
        default:
            return 0;
    }        
}

GetPerkInTreeSupport

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

Hex Change

XcomPerkManager.GetPerkInTreeSupport
original: 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 57 01 00 00 0F 01 00 00 07 15 00 9A 00 3B 66 00 00 26 16 04 2C 2C 06 4A 01 07 4F 00 9A 00 3B 66 00 00 2C 02 16 07 3A 00 9A 00 3A 66 00 00 25 16 04 2C 2F 06 4C 00 07 4C 00 9A 00 3A 66 00 00 26 16 04 2C 1F 06 4A 01 07 89 00 9A 00 3B 66 00 00 2C 03 16 07 74 00 9A 00 3A 66 00 00 25 16 04 2C 5C 06 86 00 07 86 00 9A 00 3A 66 00 00 26 16 04 2C 30 06 4A 01 07 C3 00 9A 00 3B 66 00 00 2C 04 16 07 AE 00 9A 00 3A 66 00 00 25 16 04 2C 31 06 C0 00 07 C0 00 9A 00 3A 66 00 00 26 16 04 2C 38 06 4A 01 07 FD 00 9A 00 3B 66 00 00 2C 05 16 07 E8 00 9A 00 3A 66 00 00 25 16 04 2C 33 06 FA 00 07 FA 00 9A 00 3A 66 00 00 26 16 04 2C 34 06 4A 01 07 13 01 9A 00 3B 66 00 00 2C 06 16 04 2C 35 06 4A 01 07 4A 01 9A 00 3B 66 00 00 2C 07 16 07 38 01 9A 00 3A 66 00 00 25 16 04 2C 36 06 4A 01 07 4A 01 9A 00 3A 66 00 00 26 16 04 2C 37 04 25 04 3A 39 66 00 00 53
new: 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 9F 00 3A 66 00 00 38 3F 2C 08 16 05 3B 66 00 00 00 00 3B 66 00 00 0A 3C 00 2C 01 04 9C 2C FF 95 1D 2C 31 30 00 00 3A 66 00 00 16 16 0A 56 00 2C 02 04 9C 2C FF 95 1D 2C 33 1F 00 00 3A 66 00 00 16 16 0A 70 00 2C 03 04 9C 2C FF 95 1D 31 2F 30 00 00 3A 66 00 00 16 16 0A 8A 00 2C 04 04 9C 2C FF 95 1D 5C 2F 38 00 00 3A 66 00 00 16 16 0A A4 00 2C 05 04 9C 2C FF 95 1D 31 00 34 00 00 3A 66 00 00 16 16 0A BE 00 2C 06 04 9C 2C FF 95 1D 00 35 00 00 00 3A 66 00 00 16 16 0A D8 00 2C 07 04 9C 2C FF 95 1D 36 00 37 00 00 3A 66 00 00 16 16 0A F2 00 2C 08 04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 0A 0C 01 2C 09 04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 0A 26 01 2C 0A 04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 0A 40 01 2C 0B 04 9C 2C FF 95 1D 00 00 00 00 00 3A 66 00 00 16 16 0A FF FF 04 25 0B 53

Decompiled Code

Original Code
function int GetPerkInTreeSupport(int branch, int Option)
{
    // End:0x15
    if(branch == 1)
    {
        return 44;
    }
    // End:0x14A
    else
    {
        // End:0x4F
        if(branch == 2)
        {
            // End:0x3A
            if(Option == 0)
            {
                return 47;
            }
            // End:0x4C
            else
            {
                // End:0x4C
                if(Option == 1)
                {
                    return 31;
                }
            }
        }
        // End:0x14A
        else
        {
            // End:0x89
            if(branch == 3)
            {
                // End:0x74
                if(Option == 0)
                {
                    return 92;
                }
                // End:0x86
                else
                {
                    // End:0x86
                    if(Option == 1)
                    {
                        return 48;
                    }
                }
            }
            // End:0x14A
            else
            {
                // End:0xC3
                if(branch == 4)
                {
                    // End:0xAE
                    if(Option == 0)
                    {
                        return 49;
                    }
                    // End:0xC0
                    else
                    {
                        // End:0xC0
                        if(Option == 1)
                        {
                            return 56;
                        }
                    }
                }
                // End:0x14A
                else
                {
                    // End:0xFD
                    if(branch == 5)
                    {
                        // End:0xE8
                        if(Option == 0)
                        {
                            return 51;
                        }
                        // End:0xFA
                        else
                        {
                            // End:0xFA
                            if(Option == 1)
                            {
                                return 52;
                            }
                        }
                    }
                    // End:0x14A
                    else
                    {
                        // End:0x113
                        if(branch == 6)
                        {
                            return 53;
                        }
                        // End:0x14A
                        else
                        {
                            // End:0x14A
                            if(branch == 7)
                            {
                                // End:0x138
                                if(Option == 0)
                                {
                                    return 54;
                                }
                                // End:0x14A
                                else
                                {
                                    // End:0x14A
                                    if(Option == 1)
                                    {
                                        return 55;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
    //return ReturnValue;    
}

New Code
function int GetPerkInTreeSupport(int branch, int Option)
{
    Option *= float(8);
    switch(branch)
    {
        // End:0x3C
        case 1:
            return 255 & (3158316 >> Option);
        // End:0x56
        case 2:
            return 255 & (2044716 >> Option);
        // End:0x70
        case 3:
            return 255 & (3157809 >> Option);
        // End:0x8A
        case 4:
            return 255 & (3682140 >> Option);
        // End:0xA4
        case 5:
            return 255 & (3407921 >> Option);
        // End:0xBE
        case 6:
            return 255 & (13568 >> Option);
        // End:0xD8
        case 7:
            return 255 & (3604534 >> Option);
        // End:0xF2
        case 8:
            return 255 & (0 >> Option);
        // End:0x10C
        case 9:
            return 255 & (0 >> Option);
        // End:0x126
        case 10:
            return 255 & (0 >> Option);
        // End:0x140
        case 11:
            return 255 & (0 >> Option);
        // End:0xFFFF
        default:
            return 0;
    }        
}

GetPerkInTreePsi

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

Hex Change

XcomPerkManager.GetPerkInTreePsi
original: 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 A9 00 00 00 85 00 00 00 07 15 00 9A 00 2B 66 00 00 26 16 04 2C 45 06 9C 00 07 4F 00 9A 00 2B 66 00 00 2C 02 16 07 3A 00 9A 00 2A 66 00 00 25 16 04 2C 46 06 4C 00 07 4C 00 9A 00 2A 66 00 00 26 16 04 2C 47 06 9C 00 07 89 00 9A 00 2B 66 00 00 2C 03 16 07 74 00 9A 00 2A 66 00 00 25 16 04 2C 48 06 86 00 07 86 00 9A 00 2A 66 00 00 26 16 04 2C 49 06 9C 00 07 9C 00 9A 00 2B 66 00 00 2C 04 16 04 2C 4A 04 25 04 3A 29 66 00 00 53
new: 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 9F 00 2A 66 00 00 38 3F 2C 08 16 05 2B 66 00 00 00 00 2B 66 00 00 0A 3C 00 2C 01 04 9C 2C FF 95 1D 00 45 00 00 00 2A 66 00 00 16 16 0A 56 00 2C 02 04 9C 2C FF 95 1D 46 00 47 00 00 2A 66 00 00 16 16 0A 70 00 2C 03 04 9C 2C FF 95 1D 48 00 49 00 00 2A 66 00 00 16 16 0A 8A 00 2C 04 04 9C 2C FF 95 1D 00 4A 00 00 00 2A 66 00 00 16 16 04 25 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 53

Decompiled Code

Original Code
function int GetPerkInTreePsi(int branch, int Option)
{
    // End:0x15
    if(branch == 1)
    {
        return 69;
    }
    // End:0x9C
    else
    {
        // End:0x4F
        if(branch == 2)
        {
            // End:0x3A
            if(Option == 0)
            {
                return 70;
            }
            // End:0x4C
            else
            {
                // End:0x4C
                if(Option == 1)
                {
                    return 71;
                }
            }
        }
        // End:0x9C
        else
        {
            // End:0x89
            if(branch == 3)
            {
                // End:0x74
                if(Option == 0)
                {
                    return 72;
                }
                // End:0x86
                else
                {
                    // End:0x86
                    if(Option == 1)
                    {
                        return 73;
                    }
                }
            }
            // End:0x9C
            else
            {
                // End:0x9C
                if(branch == 4)
                {
                    return 74;
                }
            }
        }
    }
    return 0;
    //return ReturnValue;    
}

New Code
function int GetPerkInTreePsi(int branch, int Option)
{
    Option *= float(8);
    switch(branch)
    {
        // End:0x3C
        case 1:
            return 255 & (17664 >> Option);
        // End:0x56
        case 2:
            return 255 & (4653126 >> Option);
        // End:0x70
        case 3:
            return 255 & (4784200 >> Option);
        // End:0x8A
        case 4:
            return 255 & (18944 >> Option);
        return 0;                                                                                                                                                                        
}


References

Referred to by this article:

That refer to this article: