Jump to content

Mod- Dynamic Stat Adjustment


Amineri

Recommended Posts

I like it, it seems it'll be easier and a lot more clearer this way for the final user to edit the ini file.
May I suggest a little tweak? Could it be possible that instead of automatically upgrading the aliens instead it picked a random upgrade from those available due to date? And could that be done on a per-alien basis? I think that'd help making things a bit easier and also it'd bring a bit of variety. It even could be used right from the begining, there could be 3HP sectoids that regenerate and 5HP sectoids that don't. Is there any problem in making the upgrades non-accumulative so only 1 applies per alien?

Link to comment
Share on other sites

  • Replies 59
  • Created
  • Last Reply

Top Posters In This Topic

I like it, it seems it'll be easier and a lot more clearer this way for the final user to edit the ini file.

May I suggest a little tweak? Could it be possible that instead of automatically upgrading the aliens instead it picked a random upgrade from those available due to date? And could that be done on a per-alien basis? I think that'd help making things a bit easier and also it'd bring a bit of variety. It even could be used right from the begining, there could be 3HP sectoids that regenerate and 5HP sectoids that don't. Is there any problem in making the upgrades non-accumulative so only 1 applies per alien?

 

Randomization of alien stats isn't really possible in the place that this code is running. This part of the code is defining the character template which is then applied to all characters of that type. If I did apply randomization here it would apply to all aliens spawned for that mission, which could easily lead to to-hard or too-easy missions.

 

It is possible to add in alien randomization, but that's a different mod (will be packaged with the increased pod size mod). That randomization applies separately to each alien unit, and allows for randomization of both stats and additional assigned perks as desired.

 

Unfortunately it's going to be tricky to make the stats a straight-up assignment and not accumulate. My current test version (which hangs the game when it launches) has only 1 free byte left over, and adding in an assignment instead of accumulation would take more bytes. That would mean dropping stat assignments for normal.

 

I am a little concerned about having to build separate alien progression tables for each difficulty. It's a bit more work, but allows for a lot more control.

 

Here is an example section for "Classic" difficulty that I am planning on using for testing. The value are based on Long War 1.08 (but I didn't include regen/DR).

 

 

 

;Difficulty 2 "Classic"
;Soldier
BalanceMods_Hard=(eType=eChar_Soldier,			iDamage=0,iCritHit=0,  iAim=0, iDefense=0,iHP=-2,iMobility=0,iWill=0)
;Sectoid
BalanceMods_Hard=(eType=eChar_Sectoid,			iDamage=0, iCritHit=15,iAim=0,iDefense=0,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,			iDamage=1, iCritHit=60,iAim=0,iDefense=10,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,			iDamage=1, iCritHit=120,iAim=10,iDefense=0,iHP=1, iMobility=1,iWill=0)
;Floater
BalanceMods_Hard=(eType=eChar_Floater,			iDamage=0,iCritHit=0, iAim=0,iDefense=0,iHP=0, iMobility=5,iWill=0)
BalanceMods_Hard=(eType=eChar_Floater,			iDamage=0, iCritHit=60,iAim=0,iDefense=0,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Floater,			iDamage=1, iCritHit=150,iAim=10,iDefense=0,iHP=1, iMobility=0,iWill=0)
;Thinman
BalanceMods_Hard=(eType=eChar_Thinman,			iDamage=0,iCritHit=0, iAim=10,iDefense=0,iHP=0, iMobility=1000,iWill=0)
BalanceMods_Hard=(eType=eChar_Thinman,			iDamage=0, iCritHit=90,iAim=0,iDefense=0,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Thinman,			iDamage=2, iCritHit=150,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
;Muton
BalanceMods_Hard=(eType=eChar_Muton,			iDamage=0, iCritHit=90,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Muton,			iDamage=1, iCritHit=210,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
;Cyberdisc
BalanceMods_Hard=(eType=eChar_Cyberdisc,		iDamage=0, iCritHit=240,iAim=0,iDefense=0,iHP=1, iMobility=1,iWill=0)
BalanceMods_Hard=(eType=eChar_Cyberdisc,		iDamage=0, iCritHit=330,iAim=0,iDefense=0,iHP=1, iMobility=1,iWill=0)
;SectoidCommander
BalanceMods_Hard=(eType=eChar_SectoidCommander,		iDamage=3,iCritHit=0, iAim=10,iDefense=3500,iHP=0, iMobility=1000,iWill=0)
BalanceMods_Hard=(eType=eChar_SectoidCommander,		iDamage=2, iCritHit=240,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_SectoidCommander,		iDamage=0, iCritHit=300,iAim=0,iDefense=10,iHP=3, iMobility=0,iWill=10)
;Heavy Floater
BalanceMods_Hard=(eType=eChar_FloaterHeavy,		iDamage=0,iCritHit=0, iAim=0,iDefense=0,iHP=0, iMobility=4,iWill=0)
BalanceMods_Hard=(eType=eChar_FloaterHeavy,		iDamage=0, iCritHit=240,iAim=10,iDefense=10,iHP=3, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_FloaterHeavy,		iDamage=1, iCritHit=300,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
;Muton Eliet
BalanceMods_Hard=(eType=eChar_MutonElite,		iDamage=0,iCritHit=0, iAim=0,iDefense=10,iHP=0,iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonElite,		iDamage=1, iCritHit=270,iAim=0,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonElite,		iDamage=0, iCritHit=300,iAim=0,iDefense=0,iHP=5, iMobility=0,iWill=0)
;Ethereal
BalanceMods_Hard=(eType=eChar_Ethereal,			iDamage=0,iCritHit=10, iAim=10,iDefense=3500,iHP=5, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Ethereal,			iDamage=0, iCritHit=330,iAim=0,iDefense=0,iHP=5, iMobility=0,iWill=0)
;Chyrssalid
BalanceMods_Hard=(eType=eChar_Chryssalid,		iDamage=2,iCritHit=0, iAim=0, iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Chryssalid,		iDamage=0, iCritHit=180,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Chryssalid,		iDamage=1, iCritHit=300,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
;Zombie
BalanceMods_Hard=(eType=eChar_Zombie,			iDamage=2,iCritHit=0, iAim=0, iDefense=0,iHP=0, iMobility=-2,iWill=0)
BalanceMods_Hard=(eType=eChar_Zombie,			iDamage=0, iCritHit=180,iAim=0,iDefense=0,iHP=3, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Zombie,			iDamage=3, iCritHit=300,iAim=0,iDefense=0,iHP=2, iMobility=0,iWill=0)
;Muton Berserker
BalanceMods_Hard=(eType=eChar_MutonBerserker,		iDamage=1,iCritHit=0, iAim=0, iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonBerserker,		iDamage=2, iCritHit=300,iAim=0,iDefense=10,iHP=3, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonBerserker,		iDamage=2, iCritHit=360,iAim=0,iDefense=0,iHP=0, iMobility=2,iWill=0)
;Drone
BalanceMods_Hard=(eType=eChar_Drone,			iDamage=1, iCritHit=180,iAim=0,iDefense=0,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Drone,			iDamage=1, iCritHit=240,iAim=0,iDefense=0,iHP=1, iMobility=0,iWill=0)
;Outsider
BalanceMods_Hard=(eType=eChar_Outsider,			iDamage=0,iCritHit=0, iAim=10,iDefense=10,iHP=0,iMobility=1005,iWill=0)
BalanceMods_Hard=(eType=eChar_Outsider,			iDamage=3, iCritHit=150,iAim=0,iDefense=0,iHP=3, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Outsider,			iDamage=2, iCritHit=210,iAim=0,iDefense=0,iHP=2, iMobility=1,iWill=0)
;Uber Ethereal
BalanceMods_Hard=(eType=eChar_EtherealUber,            iDamage=0,iCritHit=0, iAim=10,iDefense=1010,iHP=0, iMobility=2000,iWill=0)

As you can see it does start to chew up a bit of DGC.ini space, but it does so in a reasonably efficient manner, in that there would be no line entries that don't do anything.
This will almost certainly require the mod to the executable that causes the DGC.ini to load from the file instead of the Resource Cache.
Link to comment
Share on other sites

  • 5 months later...

So having played through most of my C/I campaign, I can tell that the functionality of this mod is definitely going to be needed for Enemy Within still.

 

Have poked around the code and discovered that things were fairly substantially cleaned up. The XGTacticalGameCore.GenerateArmorFragments function that I was using as a helper has been removed. However ModifyStatsByDifficulty now has a helper function GetCharacterBalanceMods that searches through the dynamic array for the particular character type like so:

            foreach BalanceMods_Hard(It,)
            {
                if(It.eType == CharType)
                {
                    break;
                }                

In EU it used the CharType as an index into the dynamic array position, which meant that every BalanceMod entry was required and could not be out-of-order.

 

The BalanceMods entries now allows having entries missing and be out-of-order (data is managed by the eType, for example :eType=eChar_Thinman instead) just like the ItemBalance and most of the other large config variable entries.

 

The bad news is that this made the overall vanilla hex code smaller (plus the removal of my helper function) so fitting the new functionality in is going to be a bit of fun. I still have some tricks, though :smile:.

 

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

 

The other issue is that the character stats have been altered.

 

In EU stats 4, 5, and 6 were Strength, Psi, and PsiDefense. All were unused.

 

In EW these stats are now Strength, ShieldHP, and CouncilMedalAccrued. Only Strength is unused.

 

I had been using Strength to store Damage Reduction and Psi to store Regeneration. However I might be able to use eStat_CriticalWoundChance to store Regeneration (it is set but appears unused), or I might byte-pack the two values into the Strength stat. I'm also thinking of using the new EW mechanic (a la Repair Servos) that grants a maximum amount of regeneration that a unit can perform.

 

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

 

To free up the space, I'm thinking of using just one of the BalanceMod entries (using all four requires duplicate code to handle each of the four cases). The difficulty would be digit-packed into one of the existing entries.

 

The current Balancemod entires are pretty straightforward:

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=-2,iCritHit=0,iAim=0,iDefense=0,iHP=-1,iMobility=0,iWill=0)

As mentioned the eType is now used to 'align' the dynamic array and make sure that the stat adjustments are applied to the correct unit type.

 

What I'm thinking of doing is:

  • iDamage remains unchanged in order to allow negative values
  • iCritHit will pack Crit bonus, day to apply. Low 2 digits are crit, next 4 digits are day. So 000610 ==> 0060 - 10 means day 60, +10 crit. Day 0 means the unit starts with the adjustments.
  • iAim will pack difficulty and aim adjustment. Low 2 digits are aim, next digit is difficulty. So 305 ==> 3 - 05 means difficulty 3 (Impossible), +5 aim.
  • iDefense will have Defense and Damage Reduction. Low 2 digits are defense, next 2 digits are DR. So 0410 ==> 04 - 10 means 4 points of Damage Reduction and +10 Defense.
  • iHP will have HP, regen, and max regen packed in. Low 2 digits are bonus max HP, next 2 digits are regen per turn, next 3 digits are max regen amount. So 0120302 ==> 012 - 03 - 02 means 12 max regen per battle, 3 max regen per turn, +2 to max HP.
  • iMobility will remain unchanged
  • iWill will remain unchanged.

Multiple entries for the same unit for the same difficulty will be allowed.

 

To upgrade the Thin Man unit type slowly, for example :

 

Initial adjustment, Classic Difficulty, -1 Damage

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=-1, iCritHit=0, iAim=200, iDefense=0, iHP=0, iMobility=0, iWill=0) 

Day 60 adjustment, +1 HP, +1 Damage, +3 Aim, +5 Critical

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=1, iCritHit=6005, iAim=203, iDefense=0, iHP=1, iMobility=0, iWill=0) 

Day 90 adjustment, +1 HP, +3 Aim, +1 Mobility, +5 defense

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=0, iCritHit=9000, iAim=203, iDefense=5, iHP=1, iMobility=1, iWill=0) 

Day 180 adjustment, +1 HP, +4 Aim, +1 Mobility, +5 Critical, 2 regen/turn with max 10 regen/battle

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=0, iCritHit=18005, iAim=204, iDefense=0, iHP=100201, iMobility=1, iWill=0) 

The effects are cumulative per alien type.

 

So by Day 180 the example Thin Man would have:

  • HP: 0 + 1 + 1 + 1 = +3 HP
  • Aim : 0 + 3 + 3 + 4 = +10 Aim
  • Defense : 0 + 0 + 5 + 0 = +5 Defense
  • Damage : -1 + 1 + 0 + 0 = +0 Damage
  • Mobility : 0 + 0 + 0 + 1 = +1 Mobility
  • Critical : 0 + 5 + 0 + 5 = +10 Critical

In the DGC.ini these entries would be placed immediately continguous:

BalanceMods_Normal=(eType=eChar_Thinman, iDamage=-1, iCritHit=0, iAim=200, iDefense=0, iHP=0, iMobility=0, iWill=0) 
BalanceMods_Normal=(eType=eChar_Thinman, iDamage=1, iCritHit=6005, iAim=203, iDefense=0, iHP=1, iMobility=0, iWill=0) 
BalanceMods_Normal=(eType=eChar_Thinman, iDamage=0, iCritHit=9000, iAim=203, iDefense=5, iHP=1, iMobility=1, iWill=0) 
BalanceMods_Normal=(eType=eChar_Thinman, iDamage=0, iCritHit=18005, iAim=204, iDefense=0, iHP=100201, iMobility=1, iWill=0)  

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

 

Any number of upgrade points could be defined for each unit. The upgrade path for each unit would be definable separately for each difficulty setting.

 

This also leaves the other three BalanceMod variables unused (since everything is packed into BalanceMod_Normal). This creates the possibility of using those config variables to define other things (such as alien leader upgrade characteristics).

 

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

 

Any feedback on this is, as always, welcome.

 

Link to comment
Share on other sites

I would vote for devoting a byte to add that perk on upgrade (which would be much easier than hardcoding them)

 

And a byte to make the upgrade conditional. If it's zero, the upgrade always happens once the day threshold is reached. If the byte is set between 1 to 10, it's the leader bonus for that level (and greater levels) when that day is reached, if it's 11 to 99, it's the percent chance of the alien gaining that upgrade (like LW's 1 in 6 chance of an alien being a navigator, with extra hp and a perk) after the day threshold.

Edited by johnnylump
Link to comment
Share on other sites

I would vote for devoting a byte to add that perk on upgrade (which would be much easier than hardcoding them)

 

And a byte to make the upgrade conditional. If it's zero, the upgrade always happens once the day threshold is reached. If the byte is set between 1 to 10, it's the leader bonus for that level (and greater levels) when that day is reached, if it's 11 to 99, it's the percent chance of the alien gaining that upgrade (like LW's 1 in 6 chance of an alien being a navigator, with extra hp and a perk) after the day threshold.

 

I'm leaning toward using one of the other BalanceMod structures (maybe BalanceMod_Easy, just for the irony) to define how pod leaders level up. That way not too much information has to get squeezed into a single structure.

 

Depending on how much hex space there is once I actually start coding, I might use three of the structures: one to upgrade the core stats (as is defined in the structure), a second to upgrade damage reduction and regeneration related stats, and a third to allow upgrading of alien leaders (which would include stats and perks, as well as probabilities).

 

The good news is that all of that could be configured based on difficulty level, and done so in the DGC.ini config file. The bad news is that it is a lot of configuration work, though I suppose copy/paste could be a friend here. :)

 

This would still leave a fourth config array for future use.

Link to comment
Share on other sites

Works for me -- I would request perk upgrades be available to non-leaders, as well. I don't find iWill terribly useful and would be willing to sacrifice it if necessary.

 

Likely what I'll do is put the 'navigator-type' upgrades in with the pod leader upgrades and follow your suggestion -- have a field for 'upgrade chance'.

 

There's two sets of stat adjustments, really:

  1. Stat adjustments common to all aliens -- applied in XGTacticalGameCore.ModifyStatsByDifficulty. This adjusts the TCharacter template info.
  2. Stat adjustments that vary between aliens of the same type -- applied in XGUnit.DebugAnims (function taken over as helper).

The help keep things clear I'm thinking it would be easier to read data for each of these from separate config variables. In Long War with EU all of the (2) info was hard-coded into the DebugAnims function, but I think I can make it configurable via the DGC.ini now.

Link to comment
Share on other sites

I've made a first cut at rewriting the new helper function so that it loops over the entire array. My first issue is that the hex is a bit tighter than I had estimated.

 

This test version drops the ability to adjust iCritHit and iWill. iCritHit now holds the difficulty and iWill holds the day. With this change the re-written function had 7 bytes to spare. I'm going to experiment with changing the name of the config variables and see if the config file itself has to be updated to match (depends on whether the config loading is set at compile-time or run-time).

 

If you're interested in such things the new decompiled code looks like:

 

 

simulated function GetCharacterBalanceMods(XGGameData.ECharacter CharType, out TCharacterBalance Mods)
{
    local TCharacterBalance It;

    // End:0x1C2
    foreach BalanceMods_Hard(It,)
    {
        // End:0x1C1
        if(It.iCritHit == m_iDifficulty) // check if difficulty matches
        {
            // End:0x1C1
            if(It.eType == CharType) // check if unit type matches
            {
                // End:0x1C1
                if((CalcHitChance_NonUnitTarget(It.iWill, none, none, none, none)) > 0) // call helper to check if enough days have elapsed
                {
                    Mods.iAim += It.iAim;
                    Mods.iDefense += It.iDefense;
                    Mods.iMobility += It.iMobility;
                    Mods.iHP += It.iHP;
                    Mods.iDamage += It.iDamage;
                }
            }
        }        
    }    
    return;                                    
} 

 

 

 

So, I'm thinking that this only allow changing iHP, iAim, iDefense, iDamage and iMobility. Current plan is to put the iCritHit and iWill modifications into the individual unit code. Am debating as to whether to put the DR and regen in there also or whether to pack them on top of iHP and iDefense.

Link to comment
Share on other sites

Here's my alpha release for dynamically upgrading aliens for EW.

 

I've done some initial testing to ensure it doesn't crash, but haven't tested a lot of situations. Method is the same that I used in EU.

 

This initial version :

  • does not include damage reduction or regeneration
  • does not allow adjusting Crit Chance or Will
  • does allow configuration of all four difficulties
  • does allow for unlimited number of upgrades for any alien

I do plan on adding DR, Regen, Crit Chance, configurable leaders with perks, and more goodies as time goes on.

 

Here are the hex changes required to XComGame.upk:

 

 

EW - Dynamic Alien Stat Adjustment Hex Changes

XGTacticalGameCore.GetCharacterBalanceMods -- accumulate stats

vanilla EW hex:
BF 84 00 00 76 5F 00 00 00 00 00 00 A4 84 00 00 00 00 00 00 00 00 00 00 A7 84 00 00 00 00 00 00 ED 04 00 00 3F A3 00 00 A2 01 00 00 22 01 00 00 05 87 83 00 00 00 01 87 83 00 00 0A 64 00 25 58 01 0E 12 00 00 00 A5 84 00 00 00 4A 60 00 07 5F 00 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 06 60 00 31 30 06 5C 01 0A B6 00 2C 02 58 01 0C 12 00 00 00 A5 84 00 00 00 4A B2 00 07 B1 00 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 06 B2 00 31 30 06 5C 01 0A 08 01 2C 03 58 01 0B 12 00 00 00 A5 84 00 00 00 4A 04 01 07 03 01 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 06 04 01 31 30 06 5C 01 0A 0C 01 26 0A FF FF 58 01 0D 12 00 00 00 A5 84 00 00 00 4A 58 01 07 57 01 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 06 58 01 31 30 06 5C 01 07 8C 01 9B 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 04 0B 0F 48 A6 84 00 00 00 A5 84 00 00 04 0B 53 

new EW GetCharacterBalanceMods (jump offsets fixed):
BF 84 00 00 76 5F 00 00 00 00 00 00 A4 84 00 00 00 00 00 00 00 00 00 00 A7 84 00 00 00 00 00 00 ED 04 00 00 3F A3 00 00 CE 01 00 00 22 01 00 00 58 01 0C 12 00 00 00 A5 84 00 00 00 4A BF 01 07 BE 01 9A 35 D2 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 01 87 83 00 00 16 07 BE 01 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 38 3A 00 A7 84 00 00 16 07 BE 01 1B C2 10 00 00 00 00 00 00 35 CD 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 2A 2A 2A 2A 16 A1 35 D1 0F 00 00 D5 0F 00 00 00 00 48 A6 84 00 00 35 D1 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 16 A1 35 D0 0F 00 00 D5 0F 00 00 00 00 48 A6 84 00 00 35 D0 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 16 A1 35 CE 0F 00 00 D5 0F 00 00 00 00 48 A6 84 00 00 35 CE 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 16 A1 35 CF 0F 00 00 D5 0F 00 00 00 00 48 A6 84 00 00 35 CF 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 16 A1 35 D3 0F 00 00 D5 0F 00 00 00 00 48 A6 84 00 00 35 D3 0F 00 00 D5 0F 00 00 00 00 00 A5 84 00 00 16 31 30 04 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 53 



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


Helper function:

Rename XGTacticalGameCore.CalcHitChance_NonUnitTarget to #CheckCurrentDayForUpgrades

change name of function from CalcHitChance_NonUnitTarget:
1C 00 00 00 43 61 6C 63 48 69 74 43 68 61 6E 63 65 5F 4E 6F 6E 55 6E 69 74 54 61 72 67 65 74 00 

to #CheckCurrentDayForUpgrades:
1C 00 00 00 23 43 68 65 63 6B 43 75 72 72 65 6E 74 44 61 79 46 6F 72 55 70 67 72 61 64 65 73 00

---

change ReturnValue object-table entry from int:
7A FE FF FF 00 00 00 00 FE 83 00 00 0A 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 07 00 28 00 00 00 50 69 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

to boolean:
88 FE FF FF 00 00 00 00 FE 83 00 00 0A 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 07 00 28 00 00 00 50 69 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

---

Remove out modifier from function parameters
aShooterStats:
change:
12 84 00 00 76 5F 00 00 00 00 00 00 FA 83 00 00 13 00 00 00 80 01 00 00 00 00 00 00 76 5F 00 00 00 00 00 00 25 0C 00 00

to:
12 84 00 00 76 5F 00 00 00 00 00 00 FA 83 00 00 01 00 00 00 80 00 00 00 00 00 00 00 76 5F 00 00 00 00 00 00 00 00 00 00


kShooter:
change:
13 84 00 00 76 5F 00 00 00 00 00 00 FB 83 00 00 01 00 00 00 80 01 40 00 00 00 00 00 76 5F 00 00 00 00 00 00 00 00 00 00 58 0F 00 00

to:
13 84 00 00 76 5F 00 00 00 00 00 00 FB 83 00 00 01 00 00 00 80 00 40 00 00 00 00 00 76 5F 00 00 00 00 00 00 00 00 00 00 58 0F 00 00

---

function change to check day count
vanilla EW hex:
15 84 00 00 76 5F 00 00 00 00 00 00 F3 83 00 00 00 00 00 00 00 00 00 00 FD 83 00 00 00 00 00 00 6F 02 00 00 82 47 00 00 FD 00 00 00 AD 00 00 00 0F 00 F4 83 00 00 1E 00 00 C8 42 07 C3 00 84 9A 00 FD 83 00 00 2C 07 16 18 0E 00 9A 00 FD 83 00 00 2C 13 16 16 0F 00 F6 83 00 00 1E 00 00 A0 40 0F 00 F5 83 00 00 1E 00 00 40 40 0F 00 F7 83 00 00 38 44 AB AF 00 FA 83 00 00 00 F6 83 00 00 16 00 F5 83 00 00 16 0F 00 F7 83 00 00 F9 2C 64 00 F7 83 00 00 16 0F 00 F7 83 00 00 FA 25 00 F7 83 00 00 16 0F 00 F4 83 00 00 AF 1E 00 00 C8 42 38 3F 00 F7 83 00 00 16 07 E6 00 2D 00 F9 83 00 00 B9 00 F4 83 00 00 38 3F 01 1D 12 00 00 16 04 38 44 00 F4 83 00 00 04 3A F8 83 00 00 53 

new EW hex: (fixed offsets)
15 84 00 00 76 5F 00 00 00 00 00 00 F3 83 00 00 00 00 00 00 00 00 00 00 FD 83 00 00 00 00 00 00 6F 02 00 00 82 47 00 00 FD 00 00 00 AD 00 00 00 07 F7 00 77 19 2E BD 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 C9 32 00 00 00 01 C9 32 00 00 2A 16 07 7B 00 1B 3B 45 00 00 00 00 00 00 2C 07 16 9F 00 FD 83 00 00 02 1B 11 00 00 16 0B 0B 04 99 19 19 2E BD 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 C9 32 00 00 00 01 C9 32 00 00 0C 00 06 B0 00 00 00 1B 0F 73 00 00 00 00 00 00 26 16 00 FD 83 00 00 16 0B 0B 0B 0B 0B 04 28 0B 0B 0B 53 

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

remove conditional in ModifyStatsByDifficulty checking type
if(Mods.eType == kCharacter.iType)
07 19 02 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 AD 84 00 00 35 56 0F 00 00 58 0F 00 00 00 00 48 AE 84 00 00 16 

to:
if(Mods.eType == kCharacter.iType)
0B 0B 0B 9A 38 3A 35 D4 0F 00 00 D5 0F 00 00 00 00 00 AD 84 00 00 35 56 0F 00 00 58 0F 00 00 00 00 48 AE 84 00 00 16 

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


Remove call to helper function in XGAbility_Targeted_RollForHit
vanilla EW hex:
0F 01 DD D2 00 00 19 19 2E 2D 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 1F 32 00 00 00 01 1F 32 00 00 A5 00 F8 83 00 00 00 1B C2 10 00 00 00 00 00 00 38 3A 19 01 AE D2 00 00 0A 00 CC B9 00 00 00 1B 8B 36 00 00 00 00 00 00 16 19 19 01 27 89 00 00 0A 00 B3 C7 00 00 00 1B 8F 37 00 00 00 00 00 00 16 09 00 E8 B5 00 00 00 01 E8 B5 00 00 19 01 27 89 00 00 09 00 38 3A 00 00 00 01 38 3A 00 00 01 E0 D2 00 00 19 01 27 89 00 00 0A 00 91 38 00 00 00 1B 62 45 00 00 00 00 00 00 16 16 

new EW hex:
0F 01 DD D2 00 00 2C 64 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 01 DD D2 00 00 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B  

 

 

 

----------

 

This also changes rather substantially how the BalanceMod entries are using in the DefaultGameCore.ini.

  • iWill is now the day which the upgrade will be applied. Is the number of days since the campaign start (normally March 1). A zero value here will apply the upgrade at the campaign start
  • iCritHit is now the difficulty. The only BalanceMod that is used is BalanceMod_Hard. All other BalanceMod entries will do nothing.
  • Multiple entries for the same alien at the same difficulty are cumulative. All bonuses unlocked will add.

I've made an example replacement BalanceMod replacement section, with a few examples in Classic Difficulty. You can simply add this to the DGC.ini, but should comment out at least the previous BalanceMod_Hard entries.

 

 

 

DASA rewritten Balance Mod Entries

;Easy Difficulty (0)
BalanceMods_Hard=( eType=eChar_Civilian,            iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Soldier,             iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=1,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Tank,                iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Sectoid,             iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Floater,             iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Thinman,             iDamage=-2, iCritHit=0,   iAim=0,   iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Muton,               iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Cyberdisc,           iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_SectoidCommander,    iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_FloaterHeavy,        iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_MutonElite,          iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Ethereal,            iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Chryssalid,          iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Zombie,              iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_MutonBerserker,      iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Sectopod,            iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Drone,               iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Outsider,            iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_EtherealUber,        iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_BattleScanner,       iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=0,  iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Mechtoid,            iDamage=-1, iCritHit=0,   iAim=-10, iDefense=0, iHP=-4, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_Seeker,              iDamage=0,  iCritHit=0,   iAim=0,   iDefense=0, iHP=-1, iMobility=-2, iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltOperative,      iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltSniper,         iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltHeavy,          iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltMedic,          iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltEliteOperative, iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltEliteSniper,    iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltEliteHeavy,     iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )
BalanceMods_Hard=( eType=eChar_ExaltEliteMedic,     iDamage=0,  iCritHit=0,   iAim=-10, iDefense=0, iHP=-1, iMobility=0,  iWill=0 )

;Normal Difficulty (1)
BalanceMods_Hard=(eType=eChar_Civilian,             iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Soldier,              iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Tank,                 iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Floater,              iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=-2,iCritHit=1,iAim=0,  iDefense=0,iHP=-1,iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Cyberdisc,            iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_SectoidCommander,     iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_FloaterHeavy,         iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonElite,           iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Ethereal,             iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Chryssalid,           iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Zombie,               iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonBerserker,       iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectopod,             iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Drone,                iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Outsider,             iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_EtherealUber,         iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_BattleScanner,        iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Mechtoid,             iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Seeker,               iDamage=0, iCritHit=1,iAim=0,  iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltOperative,       iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltSniper,          iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltHeavy,           iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltMedic,           iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteOperative,  iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteSniper,     iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteHeavy,      iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteMedic,      iDamage=0, iCritHit=1,iAim=-10,iDefense=0,iHP=0, iMobility=0,iWill=0)

;Classic Difficulty (2)
BalanceMods_Hard=(eType=eChar_Civilian,             iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Soldier,              iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=-1,iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Tank,                 iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=1, iMobility=0,iWill=15)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=0,  iDefense=5,  iHP=1, iMobility=1,iWill=45)
BalanceMods_Hard=(eType=eChar_Floater,              iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=60)
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=90)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=1, iMobility=0,iWill=80)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=120)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=2, iAim=0,  iDefense=5,  iHP=1, iMobility=0,iWill=150)
BalanceMods_Hard=(eType=eChar_Cyberdisc,            iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_SectoidCommander,     iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=4, iMobility=0,iWill=0) ;vanilla +25 will
BalanceMods_Hard=(eType=eChar_FloaterHeavy,         iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonElite,           iDamage=0, iCritHit=2, iAim=10, iDefense=10, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Ethereal,             iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=0, iMobility=0,iWill=0) ; vanilla +25 will
BalanceMods_Hard=(eType=eChar_Chryssalid,           iDamage=2, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Zombie,               iDamage=2, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonBerserker,       iDamage=1, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectopod,             iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Drone,                iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Outsider,             iDamage=0, iCritHit=2, iAim=10, iDefense=10, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_EtherealUber,         iDamage=0, iCritHit=2, iAim=10, iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_BattleScanner,        iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Mechtoid,             iDamage=2, iCritHit=2, iAim=10, iDefense=0,  iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Seeker,               iDamage=0, iCritHit=2, iAim=0,  iDefense=10, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltOperative,       iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltSniper,          iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltHeavy,           iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltMedic,           iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteOperative,  iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteSniper,     iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteHeavy,      iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteMedic,      iDamage=0, iCritHit=2, iAim=0,  iDefense=0,  iHP=1, iMobility=0,iWill=0)

;Impossible Difficulty (3)
BalanceMods_Hard=(eType=eChar_Civilian,             iDamage=0, iCritHit=3, iAim=0, iDefense=0, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Soldier,              iDamage=0, iCritHit=3, iAim=0, iDefense=0, iHP=-2,iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Tank,                 iDamage=0, iCritHit=3, iAim=0, iDefense=0, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Floater,              iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Muton,                iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Cyberdisc,            iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_SectoidCommander,     iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=4, iMobility=0,iWill=0) ; vanilla +35 will
BalanceMods_Hard=(eType=eChar_FloaterHeavy,         iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonElite,           iDamage=0, iCritHit=3, iAim=20,iDefense=10,iHP=6, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Ethereal,             iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=5, iMobility=0,iWill=0) ; vanilla +35 will
BalanceMods_Hard=(eType=eChar_Chryssalid,           iDamage=2, iCritHit=3, iAim=0, iDefense=0, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Zombie,               iDamage=4, iCritHit=3, iAim=0, iDefense=0, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_MutonBerserker,       iDamage=3, iCritHit=3, iAim=0, iDefense=0, iHP=5, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectopod,             iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Drone,                iDamage=0, iCritHit=3, iAim=10,iDefense=0, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Outsider,             iDamage=0, iCritHit=3, iAim=20,iDefense=10,iHP=2, iMobility=5,iWill=0)
BalanceMods_Hard=(eType=eChar_EtherealUber,         iDamage=0, iCritHit=3, iAim=10,iDefense=10,iHP=5, iMobility=0,iWill=0) ; vanilla +10 will
BalanceMods_Hard=(eType=eChar_BattleScanner,        iDamage=0, iCritHit=3, iAim=0, iDefense=0, iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Mechtoid,             iDamage=4, iCritHit=3, iAim=10,iDefense=0, iHP=4, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Seeker,               iDamage=0, iCritHit=3, iAim=0, iDefense=10,iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltOperative,       iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltSniper,          iDamage=0, iCritHit=3, iAim=0, iDefense=0, iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltHeavy,           iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltMedic,           iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteOperative,  iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteSniper,     iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=1, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteHeavy,      iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=2, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_ExaltEliteMedic,      iDamage=0, iCritHit=3, iAim=5, iDefense=0, iHP=1, iMobility=0,iWill=0)
 

 

 

 

Here are some sample lines:

BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=0)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=1, iMobility=0,iWill=15)
BalanceMods_Hard=(eType=eChar_Sectoid,              iDamage=0, iCritHit=2, iAim=0,  iDefense=5,  iHP=1, iMobility=1,iWill=45)

These are all for Classic difficulty (iCritHit = 2).

  • Sectoids start off with only +5 aim instead of the usual +10 aim in Classic.
  • However, after 15 days Sectoids upgrade with another +5 aim and +1 HP.
  • In the middle of April Sectoids gain an additional +1 HP and +1 mobility.
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=0, iMobility=0,iWill=60)
BalanceMods_Hard=(eType=eChar_Thinman,              iDamage=0, iCritHit=2, iAim=5,  iDefense=0,  iHP=1, iMobility=0,iWill=90)

This is also for Classic difficulty:

  • This starts Thin Men off with no initial boost (so basic 65 aim and 4 HP)
  • After 60 days (roughly end of April) Thin Men get +5 aim
  • After 90 days (roughly end of May) Thin Men get an additional +5 aim (getting them to usual Classic aim) and +1 HP

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

 

For any unit any number of upgrade point can be defined.

 

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

 

I've figured out some new tricks to hex-mangling -- I've been able to change the return value of a function and can change the type of a variable now.

 

I drastically re-wrote the vanilla function:

 

 

simulated function int CalcHitChance_NonUnitTarget(int iWeapon, out TCharacter kShooter, out int aShooterStats[ECharacterStat], float fDistanceToTarget, bool bIsPoisoned)
{
    local int iDistanceChanceModifier;
    local float fMinDistanceFactor, fDistanceChanceFactor, fHitChance;

    fHitChance = 100.0;
    if((iWeapon == 7) || iWeapon == 19)
    {
        fMinDistanceFactor = 5.0;
        fDistanceChanceFactor = 3.0;
        iDistanceChanceModifier = int((fDistanceToTarget - fMinDistanceFactor) * fDistanceChanceFactor);
        iDistanceChanceModifier = Min(100, iDistanceChanceModifier);
        iDistanceChanceModifier = Max(0, iDistanceChanceModifier);
        fHitChance = 100.0 - float(iDistanceChanceModifier);
    }
    if(bIsPoisoned)
    {
        fHitChance -= float(POISONED_AIM_PENALTY);
    }
    return int(fHitChance);
    //return ReturnValue;    
}

 

 

into :

 

 

simulated function bool #CheckCurrentDayForUpgrades(int iWeapon, TCharacter kShooter, int aShooterStats, float fDistanceToTarget, bool bIsPoisoned)
{
    local int iDistanceChanceModifier;
    local float fMinDistanceFactor, fDistanceChanceFactor, fHitChance;

    if(XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle != none)
    {
        if(IsOptionEnabled(7))
        {
            iWeapon *= default.SW_MARATHON;
        }                
        return XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.STAT_GetStat(1) >= iWeapon;                                        
    }
    return false;                
}

 

 

 

I changed:

  • The function name
  • The function return value from int to bool
  • The parameter 'out TCharacter kShooter' to no longer be an out variable
  • The parameter out int aShooterStats[ECharacterStat] to no longer be an out variable or an array (is just a basic int)
  • Completely rewrote inner workings of function.
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...