Jump to content

Mod- Dynamic Stat Adjustment


Amineri

Recommended Posts

  • Replies 59
  • Created
  • Last Reply

Top Posters In This Topic

At first it seems too much of a mess, but if the complication is only in calculating this apparently odd number and writting it in the ini in it's due place I think everybody interested can handle that. On the other hand, if it involves lots of hex edits and tricky stuff it may not be worth all the headaches. I think 2 upgrades per alien is ok

 

I haven't calculated the bytes it's take, but it seems to me that eliminating one difficulty level all this options plus DR plus regen could be applied TWICE for each alien without need of byte-packing.

 

What I was suggesting was to use all of the BalanceMods_Classic stats (highest difficulty) for what they are ment (ie to increase alien stats if playing Impossible), then use all of the BalanceMods_Easy to set all the stats that will get upgraded the first time (all of them, no fake value here), then do the same for BalanceMods_Normal to set the second upgrade (again, keeping all the values) and finally using the BalanceMods_Hard to set 4 fake values to choose from the seven or eight available, to set #1 time of first upgrade, #2 time of second upgrade, #3 DR, #4 regeneration, and there's still room for giving each unit 2 DR and regen rates. This way most of the values in the ini somehow correspond to what they are for (except for "Hard" entries). The drawback of this method is that we're left with only 2 levels of difficulty (easy-normal-hard -> No Stats Changed; and Impossible -> Stats Changed). If you want to play a more relaxed game you can always reduce aliens' default stats and increase them for Impossible to compensate.

 

Again, I haven't counted the bytes. but it seems that removing all the calls following this (m_iDifficulty == 2) could free up enough space to update some extra stat. Moreover, neither damage reduction or regeneration need to be set here, right?

Link to comment
Share on other sites

Right -- I see what you are saying. Use the same Day-count variables that define the two upgrade times (defined in the Easy and Normal BalanceMods) to define when DR and Regen are applied.

 

That code would look something like:

if((GenerateArmorFragments(BalanceMods_Easy[kCharacter.iType].iCritHit)) > 0)
{
kCharacter.aStats[1] += BalanceMods_Easy[kCharacter.iType].iAim;
kCharacter.aStats[2] += BalanceMods_Easy[kCharacter.iType].iDefense;
kCharacter.aStats[3] += BalanceMods_Easy[kCharacter.iType].iMobility;
kCharacter.aStats[7] += BalanceMods_Easy[kCharacter.iType].iWill;
kCharacter.aStats[0] += BalanceMods_Easy[kCharacter.iType].iHP;
kCharacter.aStats[12] += BalanceMods_Easy[kCharacter.iType].iDamage;

kCharacter.aStats[4] += BalanceMods_Hard[kCharacter.iType].iDamage; <-- Add the deltaDR value into Strength stat

kCharacter.aStats[5] += BalanceMods_Hard[kCharacter.iType].iHP; <-- Add the deltaRegen value into the Psi stat
}

 

There would also be a couple of calls added at the beginning to define the default DR and regen, like so:

 

kCharacter.aStats[4] = BalanceMods_Hard[kCharacter.iType].iWill; <-- Store the starting DR value into Strength stat

 

To recover the stats later would be something like : m_kUnit.GetCharacter().aStats[4] ((4 for DR, 5 for regen))

 

This has the nice added bonus (as you point out) that it leaves 2 extra variables available for future use.

Link to comment
Share on other sites

the 7th and 8th value could actualy be initial DR & regen, so both values could keep 2 updates as well. If later on we find something worth two variables here we can always cut out the 2nd DR or regen update. I wouldn't bother leaving them aside "just in case"...

 

Well, I have to say I haven't tried to implement this yet but I'm already considering several combinations, and this promises lots of fun... I was just thinking that this could be used to make certain units change their role, so not all the changes have to be necessarily an upgrade, for example Muton Elite could be given armor granting them extra HP and DR but slowing them down. And maybe mutons don't need to get tougher and more accurate, but just need extra mobility and huge health regeneration... that's what I mean about changing unit's role, if before mutons were holding ground and floaters were the flanking ones, now maybe you've got muton elite in a more static position and regular mutons trying to flank you (not because their behaviour has changed, but because of their condition). Well it's just a thought, I guess that's a matter of personal preference... I hope in a future a post with custom alien progression became as popular as those posts with custom perk trees...

 

Oh, and now that aliens can be upgraded I def. wold like to see more of the "deprecated" aliens later on the game. I seem to recall there's some function where you can set how early you want each alien to appear, but I completely ignore how the game manages that, and less of all what makes it decides some alien will no longer appear. Any tip where to look at?

Link to comment
Share on other sites

You are totally right -- I miscounted. Two fields would be used for the starting DR/Regen values, and four fields would be used for the DR/regen upgrade delta amounts, for a total of six fields used, leaving only one extra.

 

I'm going to give it a day or so, and ponder it ... see if any more suggestions pop up. So far this looks like the 'best' option.

 

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

 

Aliens are picked via a 2-step process.

1) Build arrays of possible aliens -- done in XGStrategyAI.GetPossibleAliens

2) Picking the actual alien -- done in XGStrategyAI.ChooseAlien

 

Most of the configuration is done in GetPossibleAliens. I builds up a set of weights for each alien type, based on month. These weights are all then normalized into probabilities. Also, there are four categories of possible aliens -- commanders, soldiers, secondaries, and roamers.

 

For example, in the last month my current version (Long War) has:

 

 

AddPossible(4, 10, kSquad.arrPossibleSoldiers);
AddPossible(5, 10, kSquad.arrPossibleSoldiers);
AddPossible(6, 10, kSquad.arrPossibleSoldiers);
AddPossible(7, 25, kSquad.arrPossibleSoldiers);
AddPossible(8, 25, kSquad.arrPossibleSoldiers);
AddPossible(15, 50, kSquad.arrPossibleSoldiers);
AddPossible(10, 50, kSquad.arrPossibleSoldiers);
AddPossible(11, 100, kSquad.arrPossibleSoldiers, 2);
AddPossible(5, 10, kSquad.arrPossibleSecondaries);
AddPossible(8, 25, kSquad.arrPossibleSecondaries);
AddPossible(15, 25, kSquad.arrPossibleSecondaries);
AddPossible(10, 25, kSquad.arrPossibleSecondaries);
AddPossible(13, 35, kSquad.arrPossibleSecondaries);
AddPossible(16, 100, kSquad.arrPossibleSecondaries, 1);
AddPossible(17, 100, kSquad.arrPossibleRoaming);
Looking at the Soldiers, Sectoids (4) have a weight of 10. But the total weights of all the Soldiers are : 10 + 10 + 10 + 25 + 25 + 50 + 50 + 100 = 280.
This means that the actual Sectoid probability of appearing is 10 / 280 = 0.036, or a 3.6% chance. The same is true for Thin Men (5) and Floaters (6). This is a chance per soldier squad, however, not the overall probability of appearing on a mission
Meanwhile Muton Elites (11) have a weight of 100, and 100/280 = 0.357, so 35.7% of the soldier squads will be Muton Elites.
Character types are defined in XGGameData with the enum ECharacter
Link to comment
Share on other sites

That's an old GetPossibleAliens, FYI -- I've changed it for 1.08 beta.

 

Soldiers appear on Abductions, Council Missions, and all UFOs.

Secondaries appear on Terror Missions and large UFOs.

I think roamers aren't in the game at all.

 

Here's an updated Regenerate function

function UpdateEquipment()
{
    local XGInventory kInventory;
    local XGWeapon kWeapon;
    local int I;

    I = GetPawnType();
    // End:0x32
    if(I == 43)
    {
        HealBy(3);
    }
    // End:0x4E
    if(I == 33)
    {
        HealBy(5);
    }
    // End:0x12E
    if(XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.STAT_GetStat(1) >= 180)
    {
        // End:0xDA
        if(I == 39)
        {
            HealBy(5);
        }
        // End:0xF6
        if(I == 39)
        {
            HealBy(4);
        }
        // End:0x112
        if(I == 36)
        {
            HealBy(5);
        }
        // End:0x12E
        if(I == 29)
        {
            HealBy(4);
        }
    }
    //return;    
}
Link to comment
Share on other sites

It looks like the HealBy function worked out. Looking cleaner! Although I'm not sure why you have regeneration set twice for PawnType == 39 ... glitch?

 

And yes, you were totally right ... I forgot I was copying from an old stored copy of the code ... I guess that is the vanilla setup.

Link to comment
Share on other sites

Thanks for the codes and tips, JL. good trick this HealBy. I still think this function could use a switch statement, but I think I'll wait for Amineri to finish this scalable version. Amineri, I was actualy counting on using all of the values in the ini, to keep iCritHit as a stat, as well as iWill, so all the values from easy and normal would be stats, then from Hard 2 to set starting dates and 6 for DR and regen (2 default + 4 upgrades). If there's not enough space to set them all then some stat can be left un upgraded
Link to comment
Share on other sites

Thanks -- The one time I tried to code a switch, I found it wasn't as efficient in saving bytes as I had hoped. (And full credit to Amineri for suggesting HealBy())

 

It would be very easy to change more of the upgrades to default instead of conditional on time -- just change the jump before the time conditional.

 

Here's the hex, in case anyone is after it. Again, it requires Amineri's GenerateOpName() to set Stat1 to the days passed for the conditional to work.

 

Original XComGame.upk >> XGUnit >> UpdateEquipment

4D 01 00 00 F1 00 00 00 0F 00 34 B3 00 00 1B CC 32 00 00 00 00 00 00 16 07 4A 01 77 00 34 B3 00 00 2A 16 0F 00 32 B3 00 00 25 07 4A 01 96 00 32 B3 00 00 2C 16 16 0F 00 33 B3 00 00 2E 58 B9 00 00 19 00 34 B3 00 00 15 00 25 0A 00 00 00 1B D1 32 00 00 00 00 00 00 38 3D 00 32 B3 00 00 16 07 8D 00 72 00 33 B3 00 00 2A 16 06 3C 01 07 3C 01 82 19 00 33 B3 00 00 0C 00 4F B9 00 00 00 1B 9A 36 00 00 00 00 00 00 2C 0B 16 18 20 00 19 00 33 B3 00 00 0A 00 47 B9 00 00 00 1B F8 3D 00 00 00 00 00 00 16 16 07 1B 01 98 19 00 33 B3 00 00 09 00 1C B9 00 00 00 01 1C B9 00 00 25 16 19 00 33 B3 00 00 0A 00 00 00 00 00 00 1B B5 12 00 00 00 00 00 00 16 06 3C 01 A2 19 00 33 B3 00 00 09 00 1C B9 00 00 00 01 1C B9 00 00 26 16 A5 00 32 B3 00 00 16 06 2E 00 04 0b 53
to
31 01 00 00 F1 00 00 00 0F 00 32 B3 00 00 38 3A 1B F1 33 00 00 00 00 00 00 16 07 32 00 9A 00 32 B3 00 00 24 2B 16 1B D8 36 00 00 00 00 00 00 2C 03 16 07 4E 00 9A 00 32 B3 00 00 24 21 16 1B D8 36 00 00 00 00 00 00 2C 05 16 07 2E 01 99 19 19 2E 64 2D 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 71 2D 00 00 00 01 71 2D 00 00 0C 00 CF 9D 00 00 00 1B 3E 67 00 00 00 00 00 00 26 16 24 B4 16 07 DA 00 9A 00 32 B3 00 00 24 27 16 1B D8 36 00 00 00 00 00 00 2C 05 16 07 F6 00 9A 00 32 B3 00 00 24 23 16 1B D8 36 00 00 00 00 00 00 2C 04 16 07 12 01 9A 00 32 B3 00 00 24 24 16 1B D8 36 00 00 00 00 00 00 2C 05 16 07 2E 01 9A 00 32 B3 00 00 24 1D 16 1B D8 36 00 00 00 00 00 00 2C 04 16 04 0B 53 
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...