tracktwo Posted June 20, 2015 Share Posted June 20, 2015 (edited) You might be able to replace the 5 nops with just a variable reference, eg 01 f4 c4 ff ff. This is just a bare "m_iLowestHP" as an expression by itself and is basically a nop but one that has the right size in memory. This will only work if its a statement on its own, not a subexpression. EDIT: Lack of coffee error. This won't work in this case as changing a name reference to a variable reference means you need to make up 4 bytes of serial size without impacting the memory size. This would make the memory size difference even worse in this case. Edited June 20, 2015 by tracktwo Link to comment Share on other sites More sharing options...
LiQuiD911 Posted June 20, 2015 Share Posted June 20, 2015 Wow, the upk code patching is indeed black magic xD I get the var reference thing, without a leftvalue the variable is a nop statement but I'm not sure how to setup the pseudo code. wouldn't the variable reference cause more problems that the regular nops? Since it has different memory/serial size. Link to comment Share on other sites More sharing options...
LiQuiD911 Posted June 20, 2015 Share Posted June 20, 2015 Hmm HexToPseudoCode.exe translates XGUnit.ApplyHPStatPenalties to code which has "(" and ")" and patchergui is complaining about itlike "00 ( 1C <Engine.Engine.GetCurrentWorldInfo> 16 )" Link to comment Share on other sites More sharing options...
tracktwo Posted June 20, 2015 Share Posted June 20, 2015 Yeah, no more posting before coffee for me :) You *can* use this trick when you need to balance out the serial/memory sizes, but this won't help in your particular case. You changed a name reference (8/8) to a variable reference (4/8) and added back in 4 nops (4/4). So you wind up with a total replacement size of (8/12) which is too much in-memory size. This trick is mostly useful when you need to remove a variable entirely - you can't just replace it with nops because the in memory size won't match up. But you can just move it out and stick it as a nop somewhere else. Like wghost says, you can change the function header to re-balance this - just increase the in-memory size by 4. BUT this will alter the jump offsets of any jump later on in the function and will cause many bad things to happen unless you patch all those up too. The better, more scalable way to do this is to replace the entire function and just patch in the piece you want with pseudocode and upkutils will worry about getting the function header right and correctly computing all the jump offsets for you. Dump the function with hex2pseudocode, replace the reference to the function with a reference to the variable and re-apply the patch. Re: the patchergui error, you need to have a corresponding [@] to go with your ( ). Are you replacing the whole function? Link to comment Share on other sites More sharing options...
LiQuiD911 Posted June 20, 2015 Share Posted June 20, 2015 (edited) Yes, I dumped the entire function (from the LW XComGame) and then tried to patch it with PatcherGUI, but I get an error about unexpected token "(".. if I remove the ( and ) patchergui freezes during patching. I am an idiot.. I was using an old version, sorry for your time. Oddly unhurt units get red fog penalties if other units get hurt o_O Edited June 20, 2015 by LiQuiD911 Link to comment Share on other sites More sharing options...
tracktwo Posted June 20, 2015 Share Posted June 20, 2015 If you paste in the patched function we might be able to help figure out what's wrong. Link to comment Share on other sites More sharing options...
LiQuiD911 Posted June 20, 2015 Share Posted June 20, 2015 It's the regular LW exponential red fog, this patch by LeoKian changes only the exponential parameters (I set them to 8).What I did is put in m_iLowestHP, it's working fine most of the times.. but in some cases one unit get's a 1% battle fatigue even if it's unhurt but some other unit got damaged(I think I that enemies count too). It's not much of a problem actualy so figuring it out isn't critical, I was just curious what could cause it. I'd suggest to add this as a secondwave option but I immagine an angry mob with pitchforks xD Does m_iLowestHP take in account armor? During gameplay units get penalties only when the armor get's penetrated but that might just be the exponential function. MOD_NAME=Red Fog ModAUTHOR=LeoKianDESCRIPTION=Makes Red Fog Aim Penalty a Gaussian function;Compatible with Long war Beta15b. Probably alsowith earlier versions, not tested.Replaces the original (1-x)-like function of Red Fog optionby e^(-s x^2)-like function, where s is 1/STD.s values can be defined (see below) separately for Aim and Mobility.---------------------------------------------------------- USE PatcherGUI 7.1 or later version to install. ----------------------------------------------------------UPK_FILE=XComGame.upkOBJECT=XGUnit.ApplyHPStatPenalties:AUTO// s value for Aim function : change 8 to whatever value you like between 3 and 255.// Values over 15 tend to render Red fog option inexistant save for near-zero x values.// Do not touch anything except number!// You can enter only integer values between 3 and 255, no floating-point values are allowed!ALIAS=AimSValue:<%b 8>// s value for Mobility function : change 8 to whatever value you like between 3 and 255.// Values over 15 tend to render Red fog option inexistant save for near-zero x values.// Do not touch anything except number!// You can enter only integer values between 3 and 255, no floating-point values are allowed!ALIAS=MobSValue:<%b 8>// Do not change anything under here![REPLACEMENT_CODE]// m_aCurrentStats[1] += -m_iBWAimPenaltyA1 1A 26 01 <XGUnitNativeBase.m_aCurrentStats> 8F 01 <@m_iBWAimPenalty> 16 16// m_aCurrentStats[3] += -m_iBWMobPenaltyA1 1A 2C 03 01 <XGUnitNativeBase.m_aCurrentStats> 8F 01 <@m_iBWMobPenalty> 16 16// fPct = float(GetUnitHP()) / float(GetUnitMaxHP())0F 00 <.fPct> AC 38 3F 01 <@m_iLowestHP> 38 3F 1B <GetUnitMaxHP> 16 16// FIRST TEST// if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CharacterHasProperty(GetCharacter().m_kChar.iType, 3))// Unit is Robotic, only affected if x<=0.507 [@label_NotRobot] 19 19 2E <Class.XComGameReplicationInfo> 19 12 20 <Engine.Engine> [@] <Engine.Engine.GetCurrentWorldInfo.ReturnValue> 00 ( 1C <Engine.Engine.GetCurrentWorldInfo> 16 ) [@] <Engine.WorldInfo.GRI> 00 ( 01 <Engine.WorldInfo.GRI> ) [@] <XComGameReplicationInfo.m_kGameCore> 00 ( 01 <XComGameReplicationInfo.m_kGameCore> ) [@] <XGTacticalGameCoreNativeBase.CharacterHasProperty.ReturnValue> 00 ( 1B <CharacterHasProperty> 35 <XGTacticalGameCoreNativeBase.TCharacter.iType> <XGTacticalGameCoreNativeBase.TCharacter> 00 00 19 1B <GetCharacter> 16 [@] <XGCharacter.m_kChar> 00 ( 01 <XGCharacter.m_kChar> ) 2C 03 16 ) // fPct *= float(2); B6 00 <.fPct> 38 3F 2C 02 16 // Goto Second Test 06 [@label_If2]// Else (label_NotRobot)// Unit is not Robotic, possible will bonus to only affected if 0.5<=x<=1 when will>=60[#label_NotRobot]B6 00 <.fPct> AE 38 3F 2C 01 F5 38 3F 2C 00 AF 38 3F 2C 01 AC 38 3F 2C 3C 38 3F 1A 2C 07 01 <XGUnitNativeBase.m_aCurrentStats> 16 16 16 16 16// SECOND TEST (label_If2)// if(fPct >= float(1))// No modifications for Aim or Mob[#label_If2]07 [@label_UseFunction] B3 00 <.fPct> 38 3F 26 16 // m_iBWAimPenalty = 0; 0F 01 <@m_iBWAimPenalty> 25 // m_iBWMobPenalty = 0; 0F 01 <@m_iBWMobPenalty> 25 // Goto Modifications applying 06 [@label_ApplyModif]// Else (label_UseFunction)// Apply Functions[#label_UseFunction]// m_iBWAimPenalty = -int(Exp((fPct * fPct) * float(-AimSValue)) * class'XGTacticalGameCore'.default.SW_ABDUCTION_SITES);0F 01 <@m_iBWAimPenalty> 8F 38 44 AB BF AB AB 00 <.fPct> 00 <.fPct> 16 38 3F 8F 2C <!AimSValue> 16 16 16 12 20 <Class.XGTacticalGameCore> [@] <XGTacticalGameCoreNativeBase.SW_ABDUCTION_SITES> 00 ( 02 <XGTacticalGameCoreNativeBase.SW_ABDUCTION_SITES> ) 16 16// m_iBWMobPenalty = -int(Exp((fPct * fPct) * float(-MobSValue)) * class'XGTacticalGameCore'.default.SW_COVER_INCREASE);0F 01 <@m_iBWMobPenalty> 8F 38 44 AB BF AB AB 00 <.fPct> 00 <.fPct> 16 38 3F 8F 2C <!MobSValue> 16 16 16 12 20 <Class.XGTacticalGameCore> [@] <XGTacticalGameCoreNativeBase.SW_COVER_INCREASE> 00 ( 02 <XGTacticalGameCoreNativeBase.SW_COVER_INCREASE> ) 16 16// MODIFICATIONS APPLYING (label_ApplyModif)[#label_ApplyModif]A1 1A 26 01 <XGUnitNativeBase.m_aCurrentStats> 01 <@m_iBWAimPenalty> 16A1 1A 2C 03 01 <XGUnitNativeBase.m_aCurrentStats> 01 <@m_iBWMobPenalty> 1604 0B53{End of Mod File} Link to comment Share on other sites More sharing options...
wghost81 Posted June 21, 2015 Author Share Posted June 21, 2015 (edited) Here's pseudo-code to resize the function without changing its memory size, thus, preserving jump references:UPK_FILE=XComGame.upk OBJECT = XGUnit.ApplyHPStatPenalties : AUTO [BEFORE_CODE] 1B <GetUnitHP> 16 38 3F 1B <GetUnitMaxHP> 16 16 [AFTER_CODE] 01 <@m_iLowestHP> 38 3f 1b <GetUnitMaxHP> 16 16 0b Since we're changing 10 bytes to 6, file size also changes. But memory size stays the same, as virtual function memory size is equal to 10 and variable reference + nop = 9 + 1 = 10 bytes of memory size. Edited June 21, 2015 by wghost81 Link to comment Share on other sites More sharing options...
tracktwo Posted June 21, 2015 Share Posted June 21, 2015 That's odd. Each unit has it's own lowest HP counter, so another unit getting wounded shouldn't impact it. Are you using mind merge at all? That seems like it might be an issue with this logic. Link to comment Share on other sites More sharing options...
LiQuiD911 Posted June 21, 2015 Share Posted June 21, 2015 (edited) No, I just make a unit run away from the squad and then granade the rest. The unit can get the minimal red fog penalty at max. There's something with the logic.. regardless if I use wghost's mini patch or replace the whole function. Edited June 21, 2015 by LiQuiD911 Link to comment Share on other sites More sharing options...
Recommended Posts