Jump to content

UI Mod - Bigger Perk Tree


Amineri

Recommended Posts

  • Replies 193
  • Created
  • Last Reply

Top Posters In This Topic

  • 3 weeks later...

Hello!

 

So I know this thread had been dead for a month, but it has shown the most promise for solving my problem, I just can't seem to find my answer. What I'd like to know is can you make it so you can choose two or three perks per rank? In such a way that a soldier would have greater then 7 perks total.

 

The wiki page for Amineri's UI mod lists one of the mod's rules as prohibiting multiple perk choices per rank, so I was wondering if this could be changed... I'm not very good at script hunting and modding myself, but I know my way around ToolBoks and can successfully implement a original hex / modified hex modlet if that what solving this problem will take.

 

P.S. I'm a huge fan of what this modding community has done, thanks for making this game awesome! =)

 

P.P.S. Failing more perks per rank, is there a way to increase the total number or ranks beyond 7? These ranks do not need to provide perks, just stat increases that can be handled in the .ini. My questions must sound odd, lol.

Edited by Satoron
Link to comment
Share on other sites

Nope, not odd questions at all! Sorry the delay in responding, as I was trying to think about how this could be handled.

 

The vanilla game prevents multiple perks by level by checking to see if any perk at the new rank is already possessed by the soldier. While this is fine as long as a perk doesn't appear in the tree more than once, with the larger tree I could foresee giving the chance to take a particular perk more than once.

 

In my perk tree mod, ranks with perks assigned are explicitly assigned. I took over a variable named m_iEnergy (I think supposed to represent fatigue in soldiers) that was no longer used, and re-purposed it as a bitflag to store which ranks have had perks assigned.

 

If you disabled the function that checks to see if the flag has been set, then every perk would be available -- at least in theory. Unfortunately I'm pretty sure that the game would get hung up and never advance beyond the first rank's perk choice. Later rank choices are not displayed / allowed until earlier ranks are selected. This is what allows the branching creation of 8 "subclasses" in Long War. The bottom six ranks' perks are conditional upon the first rank perk selected.

 

I've been trying to think of an easy way to allow for multiple perks per rank, but so far haven't thought of one. I'd probably need to modify the use of the m_iEnergy bitflag to use/store 2 bits per rank instead of 1, which could reflect a number of perks chosen per rank of up to 3. That could store still (in theory) up to 16 ranks, which is more than enough. Currently only 10 are used -- 7 for regular and 3 for psi.

 

I did leave room for the addition of more perk choices (up to 4) through the psi tree UI, since it has 4 free spaces at the bottom now that it re-uses the regular tree's sprite. However, I haven't implemented the additional four choices, as in practice it's proven a bit difficult to fill up even 7 ranks (particularly with the subclasses, which means 7 ranks * 4 choices * 4 classes = 112 perk slots). Even with the addition of a few new perks, it's tough to fill out such a large perk structure.

 

It should be possible to increase the number of ranks, for the purpose of granting additional stat increases.

 

The xp progression config variable that is set via the DGC.ini is a dynamic array, so more entries can be added.

 

I do believe that the max of 7 is hard-coded somewhere in the strategy game, plus there might be some glitchiness with the rank name / icon that would need to be sorted out.

 

But it shouldn't be impossibly difficult :)

Link to comment
Share on other sites

  • 3 months later...

So, some pretty big changes with the Enemy Within expansion in terms of how perks are handled.

 

One big change is that perks are now configured in the DGC.ini. EU had four different GetPerkInTree____ functions, one for each class. The new system has a single GetPerkInTree function that reads perk data from the config file. There is still a separate GetPerkInTreePsi function, although psi perks are also configured via the DGC.ini.

 

Regular soldier perks are defined in the SoldierPerkTrees structure.

Psi perks are defined in the PsiPerkTree structure.

And Gene mod perks are defined in the GeneModPerkTree structure.

 

Unfortunately these data structures are hard-coded with the 1/2/2/2/2/1/2 (for soldier perks), 1/2/2 (for psi perks) and 2/2/2/2/2 (for gene mod perks), so I'll have to figure out some creative way to configure more perks per rank/whatever.

 

Also there is a dynamic array called RandomPerks that contains the list of perks that can be granted via the Training Roulette SW option.

 

This includes BulletSwarm, so that perk must be unlocked from Heavy in EW. Double Tap isn't on the list, though.

 

--------------------

 

There are also a lot of new perks. Most MEC abilities, gene-mods and medal bonuses appear to have been added as perks. The EPerkType enum now contains 171 entries compared to the 111 in EU. Many of these are deprecated or are granted via other mechanisms (like ePerk_RifleSuppression_DEPRECATED and ePerk_OnlyForGermanModeStrings_ItemRangeBonus)

 

------------------

 

On the strategy side there is a new variable in XGStrategySoldier called m_arrRandomPerks. This is how the Training Roulette function is implemented. There is a function AssignRandomPerks that fills out the array.

 

Here's basically how it works:

1) Loop through perks (for vanilla this is 12 perks per soldier)

2) Look up the soldier's default class perk. If this is not in the random perk array then use the default perk (for example RunAndGun isn't on the random perk list so every Assault will get RunAndGun as the first perk).

3) Otherwise pick a random perk and then check for special case exclusions :

a) Rapid Reaction and Sentinel are mutually exclusive -- soldier can only have 1 of these

b) Gunslinger cannot be given to Heavies and MECs

c) Bullet Swarm cannot be given to Assaults

 

arrRandomPerks is filled out in SetSoldierClass when class is assigned. Typically after promotion to squaddie, but I think can also happen for MECs when they are augmented.

 

This is going to pose some slight problems for the Long War extension because I was deferring calling this function until after the first perk was picked, allowing SetSoldierClass to define the particulars of the subclass. Time for some re-design ^_^

Link to comment
Share on other sites

Well, there's good news and bad news with the perk tree stuff.

 

It's good that perks are configurable in the config files (as opposed to requiring hex edits a la EU).

 

Here's the TSoldierPerkTree config variable type:

struct native TSoldierPerkTree
{
    var XGTacticalGameCoreData.ESoldierClass SoldierType;
    var XGTacticalGameCoreNativeBase.EPerkType Squaddie;
    var XGTacticalGameCoreNativeBase.EPerkType Corporal1;
    var XGTacticalGameCoreNativeBase.EPerkType Corporal2;
    var XGTacticalGameCoreNativeBase.EPerkType Sergeant1;
    var XGTacticalGameCoreNativeBase.EPerkType Sergeant2;
    var XGTacticalGameCoreNativeBase.EPerkType Lieutenant1;
    var XGTacticalGameCoreNativeBase.EPerkType Lieutenant2;
    var XGTacticalGameCoreNativeBase.EPerkType Captain1;
    var XGTacticalGameCoreNativeBase.EPerkType Captain2;
    var XGTacticalGameCoreNativeBase.EPerkType Major;
    var XGTacticalGameCoreNativeBase.EPerkType Colonel1;
    var XGTacticalGameCoreNativeBase.EPerkType Colonel2;

You can see that the bad news is that Firaxis hard-coded the structure with the 1/2/2/2/2/1/2 format. Fair enough I suppose since the actionscript UI is basically hard-coded to the same structure.

 

The good news is that the config variable itself is a dynamic array:

config array<config TSoldierPerkTree> SoldierPerkTrees

This means that there can be any number of elements in SoldierPerkTrees (it's not limited to just 4).

 

What the vanilla EW (finally got to say it! :wink: ) GetPerkInTree function does is:

1) Loop over the dynamic array until it find the right class:

    foreach SoldierPerkTrees(kTree,)
    {
        if(kTree.SoldierType == soldierClass)
        {
            bFound = true;
            // End:0x8C
            break;
        }        
    }    

2) Extract the correct branch/option (this terminology is unchanged from EU). For example:

        switch(branch)
        {
            case 1:
                return kTree.Squaddie;
            case 2:
                if(Option == 0)
                {
                    return kTree.Corporal1;
                }
                else
                {
                    return kTree.Corporal2;
                }

Now, with a little finagling I think it would be possible to define one array element for each rank of each class. Each such element would only hold a single perk choice.

 

Basically it would work like this:

1) If looking for option X of a class, loop over the config array until you find the Xth entry that corresponds to that class. If there aren't that many entries then return 0 (empty perk option).

2) Return the appropriate rank's perk from that struct element.

 

-----------------

 

For example, to define 3 Squaddie perk choices for Assault, the config arrays would look something like:

SoldierPerkTrees=(SoldierType=eSC_Assault, Squaddie=ePerk_RunAndGun, ...
SoldierPerkTrees=(SoldierType=eSC_Assault, Squaddie=ePerk_BulletSwarm, ...
SoldierPerkTrees=(SoldierType=eSC_Assault, Squaddie=ePerk_RapidFire, ...

To support three perk choices per class (and MEC perks are defined in this same manner so there are 5 perk-configurable classes now), you'd have 15 such lines (3 perks/rank x 5 classes).

 

To support four perk choices per class would require 20 lines. In theory this could be configured to support as many perk choices as the UI would allow.

 

---------------------

 

As an added bonus I think it may be possible (will require some testing) to use hard-coded values in SoldierType, like:

SoldierPerkTrees=(SoldierType=8, Squaddie=ePerk_BulletSwarm, ...

to add additional classes. I'm not totally sure what will happen if the value exceeds the defined enum range, hence the testing.

 

This is good news because it means that for Long War we'll be able to define 8 fully independent classes (at least perk-wise) instead of each of the 2 subclasses having to share 2 common perks.

Link to comment
Share on other sites

I'm a huge fan of your curiosity and diligence!

 

My first game with Enemy Within I chose the roulette perk option. It has made for a highly replay-able vanilla game, at least until your team releases a ported Long War experience. Amusingly, so far in my play through only the Heavies got the "use medkit 3 times" perk as an option, instead of the Support class, as I've grown accustomed to in LW. Balance wise, because of all the new grenades, secondary slots and medals, that particular perk hasn't been vital to the squad's survival as it was in Enemy Unknown. Considering all the options your team made available before, making LW balanced is gonna be a work of art.

 

I wish you happy delving! Don't forget to finish the game (the base defense mission is sweet)!

 

 

Well, there's good news and bad news with the perk tree stuff...

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...