Jump to content

UPK Utils


wghost81

Recommended Posts

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 by tracktwo
Link to comment
Share on other sites

  • Replies 235
  • Created
  • Last Reply

Top Posters In This Topic

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

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

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 by LiQuiD911
Link to comment
Share on other sites

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 Mod
AUTHOR=LeoKian
DESCRIPTION=Makes Red Fog Aim Penalty a Gaussian function;

Compatible with Long war Beta15b. Probably also
with earlier versions, not tested.
Replaces the original (1-x)-like function of Red Fog option
by 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.upk
OBJECT=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_iBWAimPenalty
A1 1A 26 01 <XGUnitNativeBase.m_aCurrentStats> 8F 01 <@m_iBWAimPenalty> 16 16
// m_aCurrentStats[3] += -m_iBWMobPenalty
A1 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.5
07 [@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> 16
A1 1A 2C 03 01 <XGUnitNativeBase.m_aCurrentStats> 01 <@m_iBWMobPenalty> 16
04 0B
53


{End of Mod File}

 

 

Link to comment
Share on other sites

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 by wghost81
Link to comment
Share on other sites

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 by LiQuiD911
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...