Amineri Posted April 12, 2013 Share Posted April 12, 2013 (edited) This mod is primarily about adjusting the repair times for SHIVs. However, it also includes a tweak to the Soldier Recovery time that may interest some. ------------------------------------------------------------------- How Repair / Recovery currently work 1) The following DGC.ini variables are read in: (I don't recall what the vanilla default values are) BASE_DAYS_INJURED_TANKRAND_DAYS_INJURED_TANK BASE_DAYS_INJUREDRAND_DAYS_INJURED If a unit is at 50% or above health then therecovery time is the BASE_DAYS + Rand(RAND_DAYS)However, there is an additional (hard-coded) 15% chance to get a second Rand(RAND_DAYS) amount added onto the time. If a unit is below 50% health, then an additionalBASE_DAYS + Rand(RAND_DAYS) is added onto the amount above. An example, with numbers:BASE_DAYS_INJURED = 10RAND_DAYS_INJURED = 20Soldier has 6 HP max. If soldier has 3-5 HP, then85% chance of 10 + 0-19 = 10-29 days15% chance of 10 + 0-19 + 0-19 = 10-48 days If soldier has 1-2 HP, then85% chance of 10 + 0-19 + 10 + 0-19 = 20-58 days15% chance of 10 + 0-19 + 10 + 0-19 + 0-19 = 20-77 days I've seen people posting about very long recovery times -- this extra 15% chance is the likely culprit. SHIVs follow the same rules as soldiers, but have no armor. This means that taking even 1 point of damage makes a SHIV require repair. In contrast, a rookie wearing Titan Armor (3+10 on Classic) needs no recovery time until over 10 points of damage are taken. This leads to SHIVs being either too easy to repair or too difficult -- if using the vanilla method. -------------------------------------------------------------------- How Repair / Recovery works with this mod Soldier recover time is mostly unaffected. However : This mod removes the 15% chance to get the extra random roll. For SHIVs I've come up with a completely new method. I won't try and write the equations (and bore / lose people ^_^), but the new method drastically reduces the random amount, and instead scales the repair time linearly with the amount of damage taken. Below 1/3 health, the repair time per point of damage rises dramatically. For a 12 HP SHIV, the new repair times for this mod are as follows:Damage Taken Repair Days1 1 + 0-3 = 1-4 (2.5 average)2 2 + 0-3 = 2-5 (3.5 average)3 3 + 0-3 = 3-6 (4.5 average)4 4 + 0-3 = 4-7 (5.5 average)5 5 + 0-3 = 5-8 (6.5 average)6 6 + 0-3 = 6-9 (7.5 average)7 7 + 0-3 = 7-10 (8.5 average)8 8 + 0-3 = 8-11 (9.5 average)9 12 + 0-5 = 12-17 (15.5 average)10 16 + 0-7 = 16-23 (19.5 average)11 20 + 0-9 = 20-29 (24.5 average) For a 22 HP SHIV (for example, an Alloy SHIV) the new repair times would be:Damage Taken Repair Days1 1 + 0-3 = 1-4 (2.5 average)2 2 + 0-3 = 2-5 (3.5 average)3 3 + 0-3 = 3-6 (4.5 average)4 4 + 0-3 = 4-7 (5.5 average)5 5 + 0-3 = 5-8 (6.5 average)6 6 + 0-3 = 6-9 (7.5 average)7 7 + 0-3 = 7-10 (8.5 average)8 8 + 0-3 = 8-11 (9.5 average)9 9 + 0-3 = 9-12 (10.5 average)10 10 + 0-4 = 10-14 (12 average)11 11 + 0-4 = 11-15 (13 average)12 12 + 0-5 = 12-17 (14.5 average)13 13 + 0-5 = 13-18 (15.5 average)14 14 + 0-6 = 14-20 (17 average)15 15 + 0-6 = 15-21 (18 average)16 19 + 0-8 = 19-27 (23 average)17 23 + 0-10 = 23-33 (28 average)18 27 + 0-12 = 27-39 (33 average)19 31 + 0-14 = 31-45 (38 average)20 35 + 0-16 = 35-51 (43 average)21 39 + 0-18 = 39-57 (48 average) The overall repair requirement is scalable via the DGC.ini variable BASE_DAYS_INJURED_TANK. With this mod, the RAND_DAYS_INJURED_TANK variable no longer has a game effect (the random amount is scaled to the base amount automatically). However, the BASE_DAYS_INJURED_TANK is now HOURS to repair a point of damage. The above charts show the value for BASE_DAYS_INJURED_TANK = 24 (1 day (24 hours) per point of damage). -------------------------------------------------------------- Hex Changes There are two hex changes:1) Primary change to XcomStrategyGame.upk, XGFacility_Barracks.DetermineTimeOut (this now fixes a previous version bug that affected soldier's with odd MaxHP) original hex: 4D 28 00 00 AB 1F 00 00 00 00 00 00 4A 28 00 00 00 00 00 00 00 00 00 00 4D 28 00 00 00 00 00 00 BC 03 00 00 A6 69 00 00 35 03 00 00 51 02 00 00 07 77 00 81 19 00 4D 28 00 00 0A 00 30 45 00 00 00 1B 1B 14 00 00 00 00 00 00 16 16 0F 00 4C 28 00 00 12 20 6D FE FF FF 09 00 15 FC FF FF 00 02 15 FC FF FF 0F 00 4B 28 00 00 12 20 6D FE FF FF 09 00 C5 FB FF FF 00 02 C5 FB FF FF 06 C7 00 0F 00 4C 28 00 00 12 20 6D FE FF FF 09 00 14 FC FF FF 00 02 14 FC FF FF 0F 00 4B 28 00 00 12 20 6D FE FF FF 09 00 C4 FB FF FF 00 02 C4 FB FF FF 07 32 03 82 19 00 4D 28 00 00 0A 00 2C 45 00 00 00 1B 7C 14 00 00 00 00 00 00 16 18 24 00 97 19 00 4D 28 00 00 0B 00 FD 44 00 00 00 1B E5 0E 00 00 00 00 00 00 25 16 25 16 16 0F 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 90 2C 18 92 00 4C 28 00 00 A7 00 4B 28 00 00 16 16 16 07 CD 01 96 19 00 4D 28 00 00 0B 00 FD 44 00 00 00 1B E5 0E 00 00 00 00 00 00 25 16 91 19 00 4D 28 00 00 0B 00 FA 44 00 00 00 1B 8F 0F 00 00 00 00 00 00 25 16 2C 02 16 16 A1 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 90 2C 18 92 00 4C 28 00 00 A7 00 4B 28 00 00 16 16 16 16 07 0B 02 1B 37 23 00 00 00 00 00 00 2C 0F 16 A1 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 90 2C 18 A7 00 4B 28 00 00 16 16 16 07 64 02 82 1B 17 11 00 00 00 00 00 00 24 04 16 18 22 00 81 19 00 4D 28 00 00 0A 00 30 45 00 00 00 1B 1B 14 00 00 00 00 00 00 16 16 16 A0 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 07 D1 02 82 19 1B 75 0B 00 00 00 00 00 00 16 0C 00 7C 2A 00 00 00 1B 65 14 00 00 00 00 00 00 2C 05 16 18 20 00 19 00 4D 28 00 00 0A 00 30 45 00 00 00 1B 1B 14 00 00 00 00 00 00 16 16 A0 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 07 04 03 1B A7 14 00 00 00 00 00 00 24 07 16 9F 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 1B C7 26 00 00 00 00 00 00 24 11 91 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 2C 18 16 16 04 0B 53 new hex:4D 28 00 00 AB 1F 00 00 00 00 00 00 4A 28 00 00 00 00 00 00 00 00 00 00 4D 28 00 00 00 00 00 00 BC 03 00 00 A6 69 00 00 49 03 00 00 51 02 00 00 0F 01 AA 27 00 00 19 00 4D 28 00 00 0B 00 FA 44 00 00 00 1B 8F 0F 00 00 00 00 00 00 25 16 0F 01 A9 27 00 00 19 00 4D 28 00 00 0B 00 FD 44 00 00 00 1B E5 0E 00 00 00 00 00 00 25 16 07 2F 03 82 19 00 4D 28 00 00 0A 00 2C 45 00 00 00 1B 7C 14 00 00 00 00 00 00 16 18 0D 00 97 01 A9 27 00 00 25 16 16 07 BD 01 19 00 4D 28 00 00 0A 00 30 45 00 00 00 1B 1B 14 00 00 00 00 00 00 16 0F 00 4C 28 00 00 12 20 6D FE FF FF 09 00 14 FC FF FF 00 02 14 FC FF FF 0F 00 4B 28 00 00 90 00 4C 28 00 00 93 01 AA 27 00 00 01 A9 27 00 00 16 16 A1 00 4B 28 00 00 FA 90 00 4C 28 00 00 93 01 AA 27 00 00 90 01 A9 27 00 00 2C 03 16 16 16 25 16 16 A1 00 4B 28 00 00 A7 FA 91 00 4B 28 00 00 2C 02 16 2C 04 16 16 16 0F 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 00 4B 28 00 00 07 BA 01 19 1B 75 0B 00 00 00 00 00 00 16 0C 00 7C 2A 00 00 00 1B 65 14 00 00 00 00 00 00 2C 05 16 A0 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 06 CE 02 0F 00 4C 28 00 00 12 20 6D FE FF FF 09 00 15 FC FF FF 00 02 15 FC FF FF 0F 00 4B 28 00 00 12 20 6D FE FF FF 09 00 C5 FB FF FF 00 02 C5 FB FF FF 0F 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 90 2C 18 92 00 4C 28 00 00 A7 00 4B 28 00 00 16 16 16 07 9B 02 96 90 01 A9 27 00 00 2C 02 16 01 AA 27 00 00 16 A1 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 90 2C 18 92 00 4C 28 00 00 A7 00 4B 28 00 00 16 16 16 16 07 CE 02 1B 17 11 00 00 00 00 00 00 24 04 16 A0 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 07 01 03 1B A7 14 00 00 00 00 00 00 24 07 16 9F 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 38 3F 2C 02 16 1B C7 26 00 00 00 00 00 00 24 11 91 19 00 4D 28 00 00 09 00 E8 44 00 00 00 01 E8 44 00 00 2C 18 16 16 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 04 0B 53 Decompiled code for this:function DetermineTimeOut(XGStrategySoldier kSoldier){ local int iBaseTimeOut, iRandTimeOut; m_iAlloyTankCounter = kSoldier.GetMaxStat(0); m_iHoverTankCounter = kSoldier.GetCurrentStat(0); // End:0x32F if(kSoldier.IsInjured() && m_iHoverTankCounter > 0) { // End:0x1BD if(kSoldier.IsATank()) { iBaseTimeOut = class'XGTacticalGameCore'.default.BASE_DAYS_INJURED_TANK; iRandTimeOut = iBaseTimeOut * (m_iAlloyTankCounter - m_iHoverTankCounter); iRandTimeOut += Max(iBaseTimeOut * (m_iAlloyTankCounter - (m_iHoverTankCounter * 3)), 0); iRandTimeOut += Rand(Max(iRandTimeOut / 2, 4)); kSoldier.m_iTurnsOut = iRandTimeOut; // End:0x1BA if(ENGINEERING().IsFoundryTechResearched(5)) { kSoldier.m_iTurnsOut /= float(2); } } // End:0x2CE else { iBaseTimeOut = class'XGTacticalGameCore'.default.BASE_DAYS_INJURED; iRandTimeOut = class'XGTacticalGameCore'.default.RAND_DAYS_INJURED; kSoldier.m_iTurnsOut = 24 * (iBaseTimeOut + Rand(iRandTimeOut)); // End:0x29B if((m_iHoverTankCounter * 2) < m_iAlloyTankCounter) { kSoldier.m_iTurnsOut += (24 * (iBaseTimeOut + Rand(iRandTimeOut))); } // End:0x2CE if(HasOTSUpgrade(4)) { kSoldier.m_iTurnsOut /= float(2); } } // End:0x301 if(IsOptionEnabled(7)) { kSoldier.m_iTurnsOut *= float(2); } STAT_AddStat(17, kSoldier.m_iTurnsOut / 24); } //return; } 2) Cosmetic change to prevent duplicate SHIV names as a side effect in XcomStrategyGame.upk, XGFacility_Barracks.AddTankoriginal hex:01 AA 27 00 00 16 16 A1 1A 25 35 A8 FB FF FF 7E FA FF FF 00 01 19 00 CD 27 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 12 20 6D FE FF FF 09 00 17 FC FF FF 00 02 17 FC FF FF 16 06 17 02 07 CD 01 9A 38 3A 00 CF 27 00 00 38 3A 24 77 16 0F 35 E3 F9 FF FF 74 FA FF FF 00 01 19 00 CD 27 00 00 09 00 EC 44 00 00 00 01 EC 44 00 00 70 01 98 27 00 00 38 53 A3 01 A9 27 00 00 16 16 A1 1A 25 35 A8 FB FF FF 7E FA FF FF 00 01 19 00 CD 27 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 12 20 6D FE FF FF 09 00 06 FC FF FF 00 02 06 FC FF FF 16 06 17 02 0F 35 E3 F9 FF FF 74 FA FF FF 00 01 19 00 CD 27 00 00 09 00 EC 44 00 00 00 01 EC 44 00 00 70 01 9A 27 00 00 38 53 A3 01 AB 27 00 00 16 16 new hex:01 AB 27 00 00 16 16 A1 1A 25 35 A8 FB FF FF 7E FA FF FF 00 01 19 00 CD 27 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 12 20 6D FE FF FF 09 00 17 FC FF FF 00 02 17 FC FF FF 16 06 17 02 07 CD 01 9A 38 3A 00 CF 27 00 00 38 3A 24 77 16 0F 35 E3 F9 FF FF 74 FA FF FF 00 01 19 00 CD 27 00 00 09 00 EC 44 00 00 00 01 EC 44 00 00 70 01 98 27 00 00 38 53 A3 01 AB 27 00 00 16 16 A1 1A 25 35 A8 FB FF FF 7E FA FF FF 00 01 19 00 CD 27 00 00 09 00 ED 44 00 00 00 01 ED 44 00 00 12 20 6D FE FF FF 09 00 06 FC FF FF 00 02 06 FC FF FF 16 06 17 02 0F 35 E3 F9 FF FF 74 FA FF FF 00 01 19 00 CD 27 00 00 09 00 EC 44 00 00 00 01 EC 44 00 00 70 01 9A 27 00 00 38 53 A3 01 AB 27 00 00 16 16 ------------------------------------------------------------- Notes Don't forget to change the BASE_DAYS_INJURED_TANK value ! In order to create the space, I had to create a small side-effect. The vanilla game consecutively numbers each SHIV generated, maintaining a separate count for each SHIV type (basic, alloy, hover). With this mod, the count is now shared between all three types. OTS Upgrade will function normally -- reducing recovery time of soldiers-only to 50% of defaultFoundry Upgrade will function normally -- reducing repair time of SHIVs-only to 50% of defaultSW Option Marathon will function normally -- doubling recovery / repair times for all units Edited April 17, 2013 by Amineri Link to comment Share on other sites More sharing options...
dubiousintent Posted April 12, 2013 Share Posted April 12, 2013 Sweet. Do you recommend using this with the 'Tank Damage Reduction' mod or not? BTW: I am presuming it does not make any difference as to which part of these multi-part modlets are installed in which order, unless you specifically say otherwise. I ask because the order in which you present them implies a sequence, especially when they affect the same section of the game. (I'm making all these SHIV related mods into modlets for installation with 'ToolBoks' and 'Custom Mod Builder and Manager' as appropriate. I'd hate to have one fail due to a faulty assumption.) -Dubious- Link to comment Share on other sites More sharing options...
Amineri Posted April 12, 2013 Author Share Posted April 12, 2013 I highly recommend using this with the Tank Damage Reduction modlet. I'm currently running with the altered repair times and DR (albeit a slightly mutated form of tank DR that's in the Long War mod). This does make SHIVs pretty beastly. The current version has the basic SHIV with DR 2 and 12 hit points. To balance it out, the base SHIV cost is 300 cash :o. It can also be a little unbalancing without the SHIV Loadout mod installed, since you get "Free" SHIV plasmas with every SHIV once they are unlocked in the Foundry. The SHIV mods (DR, repair time, loadout) can be installed in any order or any combination -- the code SHOULD run without glitches. Balance is another issue, though :) ------------------------------------------------------ I believe that all of the modlets that I've released are compatible with each other. I have installed all of them together into my own game, so there shouldn't be any issues. I do strive to make them all independent of each other -- sometimes that means leaving a particular enhancement out, as it depends upon another mod being installed. And yes, ToolBoks is a great way to install most of these. The only little issue is with some of the mods that required multiple hex changes (I'm looking at YOU SHIV Loadout mod >:p ). As far as I know, there is no way to set up a ToolBoks Custom Mod file to apply multiple hex changes in multiple places. Oh well! Link to comment Share on other sites More sharing options...
dubiousintent Posted April 13, 2013 Share Posted April 13, 2013 (edited) I believe that all of the modlets that I've released are compatible with each other. I have installed all of them together into my own game, so there shouldn't be any issues. I do strive to make them all independent of each other -- sometimes that means leaving a particular enhancement out, as it depends upon another mod being installed.Thanks. It had looked that way, but wanted to be sure.And yes, ToolBoks is a great way to install most of these. The only little issue is with some of the mods that required multiple hex changes (I'm looking at YOU SHIV Loadout mod > :P ). As far as I know, there is no way to set up a ToolBoks Custom Mod file to apply multiple hex changes in multiple places. Oh well!At this point I have a set of 13 ToolBoks 'SHIV Loadout' modlets, which prompted my query. I don't see any other way to deal with it either, unless I want to investigate some other tool like 'ModPatcher' to see if it will let me combine some. (Trying to avoid confusing myself.) I'm still using 'Custom Mod Builder and Manager' for the couple of INI/INT file changes (and Tank Damage Reduction, and SHIV BuildItems for Starting Foundry) because that's still experimental in ToolBoks. Now to start the testing. -Dubious- Edited April 13, 2013 by dubiousintent Link to comment Share on other sites More sharing options...
Amineri Posted April 14, 2013 Author Share Posted April 14, 2013 I'd hinted out bokauk to see if the Custom Mod tool in ToolBoks could be enhanced to apply multiple hex changes in multiple places. However, given that her schedule seems kind of tight, I don't want to run the risk of appearing pushy. Maybe anUser (or someone else familiar with java programming could write a small app that would allow these small mods to be applied directly, without opening the hex editor. And one with the ability to apply multiple changes. Just a thought. Link to comment Share on other sites More sharing options...
anUser Posted April 14, 2013 Share Posted April 14, 2013 I've never used it but if bokauk lets us have the source code I could take a look and see if it's so simple as just implementing a loop or what. btw what you want is to write several [FIND] and [REPLACE] pairs in a file, right? Link to comment Share on other sites More sharing options...
Amineri Posted April 14, 2013 Author Share Posted April 14, 2013 I've never used it but if bokauk lets us have the source code I could take a look and see if it's so simple as just implementing a loop or what. btw what you want is to write several [FIND] and [REPLACE] pairs in a file, right? That is correct. I don't care if it is a set of [FIND] at the beginning, and a corresponding set of [REPLACE] at the end, or if it is sequential pairs of [FIND] / [REPLACE], or even some other mechanism altogether. Functionally it would be nice to be able to apply multiple hex changes, in multiple locations, based on information in a single file. Even nicer if the changes could be in multiple upk files. (For example, SHIV loadout requires changes to both XcomGame.upk and XcomStrategyGame.upk) Link to comment Share on other sites More sharing options...
anUser Posted April 14, 2013 Share Posted April 14, 2013 Got it, already pm bokauk Link to comment Share on other sites More sharing options...
Amineri Posted April 14, 2013 Author Share Posted April 14, 2013 (edited) There appears to be some sort of glitch in the calculation of recovery times for soldiers. I just had a rookie come back from a mission with 1 HP -- marked as Gravely Wounded, but only 9 days of recovery time. This is with BASE_DAYS_INJURED = 7 and RAND_DAYS_INJURED=18 This should have been 7 + 0-17 + 7 + 0-17 = 14 + 0-34 ---- no possibility of getting 9 days injured. Clearly it wasn't executing the extra recovery time for below below 1/2 health. Looking at the code, the issue is that if the soldier has 3 health max (A rookie) and they have 1 health remaining, then it checks if 1 < 3/2. Since this is integer division, 3/2 =1, and 1 < 1 is false, so the extra recovery time is not added. To fix this I need to check if (current_health * 2 < maximum_health). This is a relatively minor glitch, so it might be a little bit until I get an updated version out there. Figured I would let people now about this small glitch that may pop up with soldiers with odd-amounts of max health. ((it also will happen if the soldier has 5 max health and 2 remaining, or 7 max health and 3 remaining)) Edited April 17, 2013 by Amineri Link to comment Share on other sites More sharing options...
Amineri Posted April 17, 2013 Author Share Posted April 17, 2013 Here is the bug fix for soldiers with odd MaxHP. To patch a previous install of the modlet, replace: before:07 9B 02 96 01 A9 27 00 00 91 01 AA 27 00 00 2C 02 16 16 if(m_iHoverTankCounter < m_iAlloyTankCounter/2)after:07 9B 02 96 90 01 A9 27 00 00 2C 02 16 01 AA 27 00 00 16 if(m_iHoverTankCounter*2 < m_iAlloyTankCounter) I've updated the overall hex change in the main post with the change as well (or will immediately after posting this update ^_^ ). Link to comment Share on other sites More sharing options...
Recommended Posts