Amineri Posted May 1, 2014 Share Posted May 1, 2014 (edited) So there are sort of two quasi-related Suppression bugs that were introduced in Enemy Within. 1) The first is that units can become "unglued" from and unable to use cover any longer. This appears to be caused by the variable bSteppingOutOfCover which gets stuck in a true state. When true, it causes the XGUnit.ProcessNewPosition to exit early, preventing a unit from entering cover after it moves. 2) The second is that units that have stepped out from cover do not always return to cover when Suppression ends. Each XGUnit has a class variable StoredEnterCoverAction which stores the action to re-enter cover. From some reason in certain cases this action isn't taken, resulting in the unit remaining in the "stepped out" position. Unfortunately the actual code that handles this is native code : XGUnitNativeBase.ClearSuppressionTargets() appears to be the function that is supposed to clean up when a unit stops suppressing for whatever reason. To work around this, I created a new helper function out of XGUnit.DebugVisibilityForSelf. This function acts as an intermediate for ClearSuppressionTargets. All of the 15 places that ClearSuppressionTargets are normally called are redirected to DebugVisibilityForSelf. DebugVisibilityForSelf then calls the native ClearSuppressionTargets and then executes some additional "clean-up" code to try and ensure that the suppression terminated properly. The UEExplorer decompiled code for DebugVisibilityForSelf is : simulated function DebugVisibilityForSelf(optional Canvas kCanvas, optional Vector vScreenPos) { GetCharacter().m_kChar.aUpgrades[10] = GetCharacter().m_kChar.aUpgrades[10] & 1; ClearSuppressionTargets(); if(bSteppingOutOfCover) { bSteppingOutOfCover = false; // End:0xDB if((StoredEnterCoverAction != none) && !StoredEnterCoverAction.m_bExecute) { AddAction(StoredEnterCoverAction); } CallProcessNewPosition(); } return; } The first line is unrelated to the bugfix and is a Long War feature I added to make certain units automatically gain the Opportunist perk while Suppressing. This line removes the temporary boost.The second line calls the vanilla, native ClearSuppressionTargets.Following that is a test to see if bSteppingOutOfCover is still incorrectly set to true. If so, then it is set to false (which prevents the unit from ever becoming permanently "unglued" from cover).Then StoredEnterCoverAction is then checked to see if it is non-null and hasn't already either been executed or in the process of executing. If so, then the action is added in order to cause the unit to re-enter cover.Finally, CallProcessNewPosition is invoked to update the Unit state based on the current position (i.e. update cover buffs). Here is the UPKmodder modfile for this function : MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=DebugVisibilityForSelf@XGUnit RESIZE=B0 //helper function to remove free Opportunist perk for LMG suppressors when ClearSuppressionTargets is called //also attempt to fix issues with "unglued" Suppression [BEFORE_HEX] [HEADER] 03 00 00 00 03 00 00 00 [/HEADER] [code] 04 0B //return 53 // [/CODE] 00 00 00 00 01 02 [/BEFORE_HEX] [AFTER_HEX] [HEADER] EF 00 00 00 B3 00 00 00 [/HEADER] [code] //GetCharacter().m_kChar.aUpgrades[10] = GetCharacter().m_kChar.aUpgrades[10] & 1 // ePerk_Opportunist // remove extra opportunist flag 0F 1A 2C 0A 35 54 0F 00 00 58 0F 00 00 00 00 19 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 9C 1A 2C 0A 35 54 0F 00 00 58 0F 00 00 00 00 19 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 2C 01 16 1b B8 13 00 00 00 00 00 00 16 //ClearSuppressionTargets() //if(bSteppingOutOfCover) 07 E5 00 2D 01 28 3A 00 00 //bSteppingOutOfCover = false 14 2D 01 28 3A 00 00 28 //if((StoredEnterCoverAction != none) && !StoredEnterCoverAction.m_bExecute) 07 DB 00 82 77 01 C5 39 00 00 2A 16 18 22 00 81 19 01 C5 39 00 00 0A 00 37 D5 00 00 00 2D 01 37 D5 00 00 16 16 //AddAction(StoredEnterCoverAction); 1B D4 01 00 00 00 00 00 00 01 C5 39 00 00 4A 16 //CallProcessNewPosition() 1B 1B 11 00 00 00 00 00 00 16 //return 04 0B //null ops 0B 0B 0B 0B 0B 0B 0B //EOS 53 [/CODE] 00 00 00 02 01 02 [/AFTER_HEX] Note that this includes some changes to flags in the function footer to allow the function to work (thanks to JL for figuring this out). Note that leaving the first Opportunist line in a vanilla game won't have any negative side effects, since perks in vanilla are always set in bit 0. There are a couple of changes necessary in order to alter the function parameters so that the call to DebugVisibilityForSelf is the same number of bytes as ClearSuppressionTargets, making swapping the calls simpler. MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=UNSPECIFIED // no hex references in file FUNCTION=vScreenPos@DebugVisibilityForSelf@XGUnit [BEFORE_HEX] <|None|> 00 00 00 00 00 00 00 00 01 00 00 00 80 00 00 00 00 00 00 00 <|None|> 00 00 00 00 [/BEFORE_HEX] [AFTER_HEX] <|None|> 00 00 00 00 00 00 00 00 01 00 00 00 90 00 00 00 00 00 00 00 <|None|> 00 00 00 00 [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=UNSPECIFIED // no hex references in file FUNCTION=kCanvas@DebugVisibilityForSelf@XGUnit // alter flags to change parameter variable to optional parameter variable [BEFORE_HEX] <|None|> 00 00 00 00 {|vScreenPos@DebugVisibilityForSelf@XGUnit|} 01 00 00 00 80 00 00 00 00 00 00 00 <|None|> 00 00 00 00 [/BEFORE_HEX] [AFTER_HEX] <|None|> 00 00 00 00 {|vScreenPos@DebugVisibilityForSelf@XGUnit|} 01 00 00 00 90 00 00 00 00 00 00 00 <|None|> 00 00 00 00 [/AFTER_HEX] These two changes alter the parameter flags, converting the parameters into optional parameters. The next change is to re-direct the vanilla 15 calls to ClearSuppressionTargets to the DebugVisibilityForSelf helper. Following are the 15 UPKmodder files I used to update all of them: MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=RunForCover@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //ClearSuppressionTargets() 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //DebugVisibilityForSelf() 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ProcessSuppression@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kSuppressor.ClearSuppressionTargets() 19 00 D2 C6 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kSuppressor.DebugVisibilityForSelf() 19 00 D2 C6 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=OnDeath@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //ClearSuppressionTargets() 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //DebugVisibilityForSelf() 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ClearAbilitiesOnMindControl@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //ClearSuppressionTargets() 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //DebugVisibilityForSelf() 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ClearAbilitiesOnDeath@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //ClearSuppressionTargets() 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //DebugVisibilityForSelf() 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=BeginTurn@XGUnit //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //ClearSuppressionTargets() 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //DebugVisibilityForSelf() 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=Executing@XGAction_TakeDamage //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //m_kUnit.ClearSuppressionTargets() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //m_kUnit.DebugVisibilityForSelf() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=Executing@XGAction_Strangle //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //m_kTarget.ClearSuppressionTargets() 19 01 6C 97 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //m_kTarget.DebugVisibilityForSelf() 19 01 6C 97 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=BeginState@CriticallyWounded@XGAction_CriticallyWounded //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //m_kUnit.ClearSuppressionTargets() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //m_kUnit.DebugVisibilityForSelf() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ProcessSuppression@XGAction_BeginMove //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kOverwatcher.ClearSuppressionTargets() 19 00 53 90 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kOverwatcher.DebugVisibilityForSelf() 19 00 53 90 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ApplyEffect@XGAbility_Grapple //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //m_kUnit.ClearSuppressionTargets() 19 01 42 8B 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //m_kUnit.DebugVisiblityForSelf() 19 01 42 8B 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ApplyEffect@XGAbility_FlashBang //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kUnit.ClearSuppressionTargets() 19 00 5F 8D 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kUnit.DebugVisiblityForSelf() 19 00 5F 8D 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ApplyEffect@XGAbility_Electropulse //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kUnit.ClearSuppressionTargets() 19 00 50 8D 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kUnit.DebugVisiblityForSelf() 19 00 50 8D 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=RemoveEffectsFromSelf@XGAbilityTree //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kAbility.m_kUnit.ClearSuppressionTargets() 19 19 00 8C 8E 00 00 09 00 42 8B 00 00 00 01 42 8B 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kAbility.m_kUnit.DebugVisiblityForSelf() 19 19 00 8C 8E 00 00 09 00 42 8B 00 00 00 01 42 8B 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=OnExaltHackingArrayInteraction@XComRadarArrayActor //redirect ClearSuppressionTargets to DebugVisibilityForSelf [BEFORE_HEX] [code] //kAlien.ClearSuppressionTargets() 19 00 26 78 00 00 0A 00 00 00 00 00 00 1B B8 13 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [code] //kAlien.DebugVisiblityForSelf() 19 00 26 78 00 00 0A 00 00 00 00 00 00 1B 86 17 00 00 00 00 00 00 16 [/CODE] [/AFTER_HEX] This should be all that is necessary in order to add the basic EW Suppression bugfix. ------------------------------ A couple of optional changes I coded up and that are included in Long War (as of v3.0 beta 7). The first is a change that makes certain classes of weapons automatically gain the Opportunist perk when Suppressing. This was created for the Long War Gunner subclass, which has only the LMG and no Rocket Launcher : MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=ConstantCombatSuppress@XGUnit RESIZE=D0 // grant free temporary use of Opportunist for LMG-using Suppressors [BEFORE_HEX] [HEADER] A6 00 00 00 6E 00 00 00 [/HEADER] [code] //m_bSuppressing = bSuppress && kTarget != none 14 2D 01 2F C5 00 00 82 2D 00 46 C6 00 00 18 0D 00 77 00 45 C6 00 00 2A 16 16 //if(m_bSuppressing) 07 69 00 2D 01 2F C5 00 00 //m_kForceConstantCombatTarget = kTarget 0F 01 DE C4 00 00 00 45 C6 00 00 //kTarget.m_kConstantCombatUnitTargettingMe = self 0F 19 00 45 C6 00 00 09 00 DD 39 00 00 00 01 DD 39 00 00 17 //else 06 A3 00 //if(m_kForceConstantCombatTarget != none) 07 98 00 77 01 DE C4 00 00 2A 16 //m_kForceConstantCombatTarget.m_kConstantCombatUnitTargettingMe = none 0F 19 01 DE C4 00 00 09 00 DD 39 00 00 00 01 DD 39 00 00 2A //m_kForceConstantCombatTarget = none 0F 01 DE C4 00 00 2A //return 04 0B //EOS 53 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [HEADER] C2 01 00 00 3E 01 00 00 [/HEADER] [code] //m_bSuppressing = bSuppress && kTarget != none 14 2D 01 2F C5 00 00 82 2D 00 46 C6 00 00 18 0D 00 77 00 45 C6 00 00 2A 16 16 //if(m_bSuppressing) 07 7D 01 2D 01 2F C5 00 00 //m_kForceConstantCombatTarget = kTarget 0F 01 DE C4 00 00 00 45 C6 00 00 //kTarget.m_kConstantCombatUnitTargettingMe = self 0F 19 00 45 C6 00 00 09 00 DD 39 00 00 00 01 DD 39 00 00 17 //if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.WeaponHasProperty(GetInventory().GetActiveWeapon().ItemType(), 4)) // eWP_Support 07 7A 01 19 19 2E 54 32 00 00 19 12 20 35 FE FF FF 0A 00 92 F9 FF FF 00 1C D5 FB FF FF 16 09 00 50 F9 FF FF 00 01 50 F9 FF FF 09 00 46 32 00 00 00 01 46 32 00 00 44 00 D0 86 00 00 00 1B 68 7F 00 00 00 00 00 00 38 3A 19 19 1B 56 39 00 00 00 00 00 00 16 0A 00 26 0B 00 00 00 1B 4F 37 00 00 00 00 00 00 16 0A 00 E7 BB 00 00 00 1B D8 46 00 00 00 00 00 00 16 2C 04 16 //GetCharacter().m_kChar.aUpgrades[10] = GetCharacter().m_kChar.aUpgrades[10] | 2 // ePerk_Opportunist // grant extra opportunist flag 0F 1A 2C 0A 35 54 0F 00 00 58 0F 00 00 00 00 19 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 9E 1A 2C 0A 35 54 0F 00 00 58 0F 00 00 00 00 19 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 2C 02 16 //else 06 B7 01 //if(m_kForceConstantCombatTarget != none) 07 AC 01 77 01 DE C4 00 00 2A 16 //m_kForceConstantCombatTarget.m_kConstantCombatUnitTargettingMe = none 0F 19 01 DE C4 00 00 09 00 DD 39 00 00 00 01 DD 39 00 00 2A //m_kForceConstantCombatTarget = none 0F 01 DE C4 00 00 2A //return 04 0B //null ops 0B 0B 0B 0B 0B 0B 0B 0B //EOS 53 [/CODE] [/AFTER_HEX] The key line here that would need to be tweaked for vanilla is : if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.WeaponHasProperty(GetInventory().GetActiveWeapon().ItemType(), 4)) // eWP_Support This tests the current weapon for a particular property that has to be present. In Long War LMG-class weapons are tagged with eWP_Support (eWP_Heavy is used for Rocket Launchers). -------- The second optional change has to do with the timing of the Suppression reaction shot. In vanilla the reaction shot is triggered just prior to the unit exiting cover and losing its cover bonus (so the Suppression reaction shot suffers from both the reaction penalty (70% of normal chance to hit), but the unit also retains its cover bonus. The following modfile changes the order so that the Suppressive reaction shot happens immediately after the unit leaves cover and loses its cover bonus. MODFILEVERSION=4 UPKFILE=XComGame.upk GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk FUNCTION=Executing@XGAction_BeginMove // process suppression shots after the unit has left cover and lost the cover bonuses [BEFORE_HEX] [HEADER] [/HEADER] [code] //if((WorldInfo.NetMode != NM_Standalone) && !WorldInfo.IsConsoleBuild()) //07 50 00 82 9B 38 3A 19 01 A6 F9 FF FF 09 00 8F FE FF FF 00 01 8F FE FF FF 38 3A 24 00 16 18 23 00 81 19 01 A6 F9 FF FF 0B 00 C4 FE FF FF 00 1C 2E FA FF FF 4A 16 16 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 //0F 01 18 90 00 00 1E 00 00 20 41 //if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kCameraManager.WaitForCamera()) //07 01 01 19 19 2E 54 32 00 00 19 12 20 35 FE FF FF 0A 00 92 F9 FF FF 00 1C D5 FB FF FF 16 09 00 50 F9 FF FF 00 01 50 F9 FF FF 09 00 42 32 00 00 00 01 42 32 00 00 0A 00 C1 49 00 00 00 1B 07 7F 00 00 00 00 00 00 16 //Sleep(0.050) // 61 00 1E CD CC 4C 3D 16 //if(HACK_fGhettoStuckLoopingTimeoutSeconds <= 0.0) // 07 FE 00 B2 01 18 90 00 00 1E 00 00 00 00 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 // 0F 01 18 90 00 00 1E 00 00 20 41 //goto 'AfterWaitForCameraManager' // 0D 21 02 03 00 00 00 00 00 00 //goto J0x5F // 06 5F 00 //start 0x101 //if(m_kUnit.IsBeingSuppressed()) 07 25 02 19 01 25 D5 00 00 0A 00 EB 35 00 00 00 1B 7D 44 00 00 00 00 00 00 16 //ProcessSuppression(m_kUnit) 1B 7A 66 00 00 00 00 00 00 01 25 D5 00 00 16 //if(m_kUnit.m_eCoverState != 0) 07 BD 01 9B 38 3A 19 01 25 D5 00 00 09 00 20 3A 00 00 00 01 20 3A 00 00 38 3A 24 00 16 //if(m_kPawn.MovementNode != none) 07 BD 01 77 19 01 24 D5 00 00 09 00 F7 3B 00 00 00 01 F7 3B 00 00 2A 16 //m_kPawn.MovementNode.SetActiveChild(1, 0.10) 19 19 01 24 D5 00 00 09 00 F7 3B 00 00 00 01 F7 3B 00 00 10 00 00 00 00 00 00 1B 2E 6D 00 00 00 00 00 00 26 1E CD CC CC 3D 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 0F 01 18 90 00 00 1E 00 00 20 41 //if(m_kPres.CAMIsBusy()) 07 25 02 19 01 22 D5 00 00 0A 00 9B 74 00 00 00 1B 59 11 00 00 00 00 00 00 16 //Sleep(0.0) 61 00 1E 00 00 00 00 16 //if(HACK_fGhettoStuckLoopingTimeoutSeconds <= 0.0) 07 22 02 B2 01 18 90 00 00 1E 00 00 00 00 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 0F 01 18 90 00 00 1E 00 00 20 41 //goto 'AfterOverwatchProcessing' 0D 21 00 03 00 00 00 00 00 00 //goto J0x1CC 06 CC 01 // label AfterOverwatchProcessing //if(m_kUnit.GetCharacter().m_kChar.iType == 2) 07 B1 02 9A 35 56 0F 00 00 58 0F 00 00 00 00 19 19 01 25 D5 00 00 0A 00 D0 C9 00 00 00 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 2C 02 16 //m_kPawn.FlyingLegMaskNode.SetBlendTarget(0.0, 0.20) 19 19 01 24 D5 00 00 09 00 F8 3B 00 00 00 01 F8 3B 00 00 14 00 00 00 00 00 00 1B 81 6D 00 00 00 00 00 00 1E 00 00 00 00 1E CD CC 4C 3E 16 //if((m_arrReplicatedPathPoints[1].eTraversal == 1) && m_kUnit.m_eCoverState != 0) 07 29 04 82 9A 38 3A 35 35 62 00 00 37 62 00 00 00 00 1A 26 01 1C 90 00 00 38 3A 24 01 16 18 27 00 9B 38 3A 19 01 25 D5 00 00 09 00 20 3A 00 00 00 01 20 3A 00 00 38 3A 24 00 16 16 //m_kUnit.IdleStateMachine.ExitFromCover(m_arrReplicatedPathPoints[1].vRawPathPoint - m_kPawn.Location) 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 48 00 00 00 00 00 00 1B F1 30 00 00 00 00 00 00 D8 35 36 62 00 00 37 62 00 00 00 00 1A 26 01 1C 90 00 00 19 01 24 D5 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 //if(m_kUnit.IdleStateMachine.IsEvaluatingStance()) 07 B9 03 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0A 00 33 5A 00 00 00 1B E9 44 00 00 00 00 00 00 16 //Sleep(0.0) 61 00 1E 00 00 00 00 16 //while loop 06 77 03 //if(!m_kUnit.IdleStateMachine.IsDormant()) 07 29 04 81 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0A 00 35 5A 00 00 00 1B CA 44 00 00 00 00 00 00 16 16 //m_kUnit.IdleStateMachine.GoDormant() 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0D 00 00 00 00 00 00 1B B9 3C 00 00 00 00 00 00 4A 4A 4A 16 //m_kUnit.UnClaimCover() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B 77 7A 00 00 00 00 00 00 16 //m_kUnit.RemoveCoverBonuses() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B C3 68 00 00 00 00 00 00 16 [/CODE] [/BEFORE_HEX] [AFTER_HEX] [HEADER] [/HEADER] [code] //if((WorldInfo.NetMode != NM_Standalone) && !WorldInfo.IsConsoleBuild()) //07 50 00 82 9B 38 3A 19 01 A6 F9 FF FF 09 00 8F FE FF FF 00 01 8F FE FF FF 38 3A 24 00 16 18 23 00 81 19 01 A6 F9 FF FF 0B 00 C4 FE FF FF 00 1C 2E FA FF FF 4A 16 16 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 //0F 01 18 90 00 00 1E 00 00 20 41 //if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kCameraManager.WaitForCamera()) //07 01 01 19 19 2E 54 32 00 00 19 12 20 35 FE FF FF 0A 00 92 F9 FF FF 00 1C D5 FB FF FF 16 09 00 50 F9 FF FF 00 01 50 F9 FF FF 09 00 42 32 00 00 00 01 42 32 00 00 0A 00 C1 49 00 00 00 1B 07 7F 00 00 00 00 00 00 16 //Sleep(0.050) // 61 00 1E CD CC 4C 3D 16 //if(HACK_fGhettoStuckLoopingTimeoutSeconds <= 0.0) // 07 FE 00 B2 01 18 90 00 00 1E 00 00 00 00 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 // 0F 01 18 90 00 00 1E 00 00 20 41 //goto 'AfterWaitForCameraManager' // 0D 21 02 03 00 00 00 00 00 00 //goto J0x5F // 06 5F 00 //start 0x101 //if(m_kUnit.GetCharacter().m_kChar.iType == 2) 07 8D 01 9A 35 56 0F 00 00 58 0F 00 00 00 00 19 19 01 25 D5 00 00 0A 00 D0 C9 00 00 00 1B E5 37 00 00 00 00 00 00 16 09 00 03 B8 00 00 00 01 03 B8 00 00 2C 02 16 //m_kPawn.FlyingLegMaskNode.SetBlendTarget(0.0, 0.20) 19 19 01 24 D5 00 00 09 00 F8 3B 00 00 00 01 F8 3B 00 00 14 00 00 00 00 00 00 1B 81 6D 00 00 00 00 00 00 1E 00 00 00 00 1E CD CC 4C 3E 16 //if((m_arrReplicatedPathPoints[1].eTraversal == 1) && m_kUnit.m_eCoverState != 0) 07 05 03 82 9A 38 3A 35 35 62 00 00 37 62 00 00 00 00 1A 26 01 1C 90 00 00 38 3A 24 01 16 18 27 00 9B 38 3A 19 01 25 D5 00 00 09 00 20 3A 00 00 00 01 20 3A 00 00 38 3A 24 00 16 16 //m_kUnit.IdleStateMachine.ExitFromCover(m_arrReplicatedPathPoints[1].vRawPathPoint - m_kPawn.Location) 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 48 00 00 00 00 00 00 1B F1 30 00 00 00 00 00 00 D8 35 36 62 00 00 37 62 00 00 00 00 1A 26 01 1C 90 00 00 19 01 24 D5 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 //if(m_kUnit.IdleStateMachine.IsEvaluatingStance()) 07 95 02 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0A 00 33 5A 00 00 00 1B E9 44 00 00 00 00 00 00 16 //Sleep(0.0) 61 00 1E 00 00 00 00 16 //while loop 06 53 02 //if(!m_kUnit.IdleStateMachine.IsDormant()) 07 05 03 81 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0A 00 35 5A 00 00 00 1B CA 44 00 00 00 00 00 00 16 16 //m_kUnit.IdleStateMachine.GoDormant() 19 19 01 25 D5 00 00 09 00 CF 39 00 00 00 01 CF 39 00 00 0D 00 00 00 00 00 00 1B B9 3C 00 00 00 00 00 00 4A 4A 4A 16 //m_kUnit.UnClaimCover() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B 77 7A 00 00 00 00 00 00 16 //m_kUnit.RemoveCoverBonuses() 19 01 25 D5 00 00 0A 00 00 00 00 00 00 1B C3 68 00 00 00 00 00 00 16 //if(m_kUnit.IsBeingSuppressed()) 07 67 04 19 01 25 D5 00 00 0A 00 EB 35 00 00 00 1B 7D 44 00 00 00 00 00 00 16 //ProcessSuppression(m_kUnit) 1B 7A 66 00 00 00 00 00 00 01 25 D5 00 00 16 //if(m_kUnit.m_eCoverState != 0) 07 FF 03 9B 38 3A 19 01 25 D5 00 00 09 00 20 3A 00 00 00 01 20 3A 00 00 38 3A 24 00 16 //if(m_kPawn.MovementNode != none) 07 FF 03 77 19 01 24 D5 00 00 09 00 F7 3B 00 00 00 01 F7 3B 00 00 2A 16 //m_kPawn.MovementNode.SetActiveChild(1, 0.10) 19 19 01 24 D5 00 00 09 00 F7 3B 00 00 00 01 F7 3B 00 00 10 00 00 00 00 00 00 1B 2E 6D 00 00 00 00 00 00 26 1E CD CC CC 3D 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 0F 01 18 90 00 00 1E 00 00 20 41 //if(m_kPres.CAMIsBusy()) 07 67 04 19 01 22 D5 00 00 0A 00 9B 74 00 00 00 1B 59 11 00 00 00 00 00 00 16 //Sleep(0.0) 61 00 1E 00 00 00 00 16 //if(HACK_fGhettoStuckLoopingTimeoutSeconds <= 0.0) 07 64 04 B2 01 18 90 00 00 1E 00 00 00 00 16 //HACK_fGhettoStuckLoopingTimeoutSeconds = 10.0 0F 01 18 90 00 00 1E 00 00 20 41 //goto 'AfterOverwatchProcessing' 0D 21 00 03 00 00 00 00 00 00 //while loop 06 0E 04 // label AfterOverwatchProcessing //0b [/CODE] [/AFTER_HEX] [BEFORE_HEX] 0C FE 02 00 00 00 00 00 00 11 0C 00 00 00 03 00 00 00 00 00 00 25 02 00 00 // AfterOverWatchProcessing -- position 0x252 02 03 00 00 00 00 00 00 01 01 00 00 BC 09 00 00 00 00 00 00 00 00 00 00 51 60 00 00 00 00 00 00 FF FF 00 00 [/BEFORE_HEX] [AFTER_HEX] 0C FE 02 00 00 00 00 00 00 11 0C 00 00 00 03 00 00 00 00 00 00 67 04 00 00 //AfterOverwatchProcessing -- position 0x467 02 03 00 00 00 00 00 00 01 01 00 00 BC 09 00 00 00 00 00 00 00 00 00 00 51 60 00 00 00 00 00 00 FF FF 00 00 [/AFTER_HEX] Enjoy! :smile: Edited May 1, 2014 by Amineri Link to comment Share on other sites More sharing options...
Recommended Posts