use real LOS functions to determine Far Cover (automatically accounts for roof edge protection)
Dependencies
- [2]
UA2L2WYUuse correct config file - [3]
MPALURGPmaximum far cover is low cover malus - [4]
7GQHYDUFXCom are always at red alert - [5]
X4IR7ZAHbaseline from krumiro's [WotC] RW Realistic Aiming Angles - [6]
JSCVVDFDremove commented code and excess tabs
Change contents
- file move: Override_X2AbilityToHitCalc_StandardAim.uc → Override_X2AbilityToHitCalc_StandardAim.uc
- edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 42
- edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 587
local TTile ShooterTorso;local TTile TargetLegs;local TTile ShooterBelowFeet;local float ShooterTargetDistance; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 590
local float ExtendedLowCoverPreventingGoodAngleBonus; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 591
local float HeightDisadvantageMalus; //OR YOU WILL LOOSE HOURS TRYING TO UNDERSTAND WHYlocal float NoLineOfSightMalus; //THEY DIDN'T APPLY MULTIPLIERS!!! BECAUSE INT AUTO-ROUND!!! MOTHERFUCKERS!!!local string FarCoverText;local TTile NextTile;local int FarCover;local GameRulesCache_VisibilityInfo VisibilityInfo; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 592
local TTile PeekTile, PeekHead, LosTile, TargetPeekTile;local VoxelRaytraceCheckResult RayTrace;local int FarCover; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 792[5.3509]→[5.3509:3697](∅→∅),[5.3697]→[3.74:200](∅→∅),[3.200]→[5.3697:3964](∅→∅),[5.3697]→[5.3697:3964](∅→∅)
if ((NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing)){ExtendedLowCoverPreventingGoodAngleBonus = -Round(GoodAngleBonus / 2);`log("ExtendedLowCoverPreventingGoodAngleBonus:"@ExtendedLowCoverPreventingGoodAngleBonus, true, 'XCom_HitRolls');AddModifier(ExtendedLowCoverPreventingGoodAngleBonus , "ExtendedLowCover preventing GoodAngle", m_ShotBreakdown, eHit_Success, bDebugLog);} //WHEN ONLY "HALF OF" THE HIGHCOVER IS REDUCED BY THE GOODANGLE BECAUSE THE OTHER HALF IS COVERED BY LOWCOVER... ;) - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 808
- replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 811[5.61710]→[5.3965:4244](∅→∅),[5.4244]→[5.62411:62474](∅→∅),[5.62411]→[5.62411:62474](∅→∅),[5.62474]→[5.4245:4276](∅→∅)
ShooterHead = ShooterTile; ShooterHead.Z = `XWORLD.GetFloorTileZ(ShooterHead) + UnitState.UnitHeight -1;TargetHead = TargetTile; TargetHead.Z = `XWORLD.GetFloorTileZ(TargetHead ) + TargetState.UnitHeight -1;ShooterTorso = ShooterHead; ShooterTorso.Z -= 0.5;ShooterBelowFeet = ShooterTile; ShooterBelowFeet.Z -= 2;TargetLegs = TargetTile;ShooterHead = ShooterTile; ShooterHead.Z = `XWORLD.GetFloorTileZ(ShooterHead) + UnitState.UnitHeight;TargetHead = TargetTile; TargetHead.Z = `XWORLD.GetFloorTileZ(TargetHead ) + TargetState.UnitHeight; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 829
if (default.AllowFarCoverToGiveSomeCoverProtection || default.GiveHitChanceZeroWhenTargetableEnemiesAreInsteadNotTrulyInLineOfSight){// Both these modifiers are based off far coverFarCover = 0;PeekTile = VisInfo.SourceTile;PeekHead = PeekTile; PeekHead.Z = `XWORLD.GetFloorTileZ(PeekTile) + UnitState.UnitHeight;`log("PeekTile:"@PeekTile.X@","@PeekTile.Y@","@PeekTile.Z, true, 'XCom_HitRolls');`log("PeekHead:"@PeekHead.X@","@PeekHead.Y@","@PeekHead.Z, true, 'XCom_HitRolls');TargetPeekTile = VisInfo.DestTile;`log("TargetTile:"@TargetTile.X@","@TargetTile.Y@","@TargetTile.Z, true, 'XCom_HitRolls');`log("TargetPeekTile:"@TargetPeekTile.X@","@TargetPeekTile.Y@","@TargetPeekTile.Z, true, 'XCom_HitRolls');`log("Target Height:"@TargetState.UnitHeight, true, 'XCom_HitRolls'); - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 845[5.64791]→[5.5173:6985](∅→∅),[5.6985]→[3.284:362](∅→∅),[3.362]→[5.6985:7116](∅→∅),[5.6985]→[5.6985:7116](∅→∅),[5.7116]→[5.7116:7124](∅→∅)
if (default.GiveHitChanceZeroWhenTargetableEnemiesAreInsteadNotTrulyInLineOfSight){ //'FAR' COVER BLOCKING VISIBILITY CHECK...if (ShooterHead.Z - TargetLegs.Z >= 0) //SAME HEIGHT OR BELOW SHOOTER{NextTile = ShooterTile;NextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (NextTile.Z>=ShooterTile.Z && FarCover>0 && !`XWORLD.CanSeeTileToTile(ShooterTorso, TargetHead, VisibilityInfo)) NoLineOfSightMalus = -1000;NextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (NextTile.Z>=ShooterTile.Z && FarCover>0 && !`XWORLD.CanSeeTileToTile(ShooterTorso, TargetHead, VisibilityInfo)) NoLineOfSightMalus = -1000; //LOW COVER IN CALCULATING VISIBILITY.NextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (NextTile.Z>=ShooterTile.Z && FarCover>0 && !`XWORLD.CanSeeTileToTile(ShooterTorso, TargetHead, VisibilityInfo)) NoLineOfSightMalus = -1000; //THIS NONSENSE HAD TO BE MODDED AWAY...}if (ShooterHead.Z - TargetLegs.Z < 0) //ABOVE SHOOTER{NextTile = ShooterTile;NextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (FarCover == 1 && !`XWORLD.CanSeeTileToTile(ShooterBelowFeet, TargetLegs, VisibilityInfo)) NoLineOfSightMalus = -1000; //DIFFERENT CHECK FOR HIGH GROUNDSNextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (FarCover == 1 && !`XWORLD.CanSeeTileToTile(ShooterBelowFeet, TargetLegs, VisibilityInfo)) NoLineOfSightMalus = -1000; //IN CALCULATING VISIBILITY.NextTile = NextWalkableTile(ShooterTile, NextTile, TargetTile, FarCover); if (FarCover == 1 && !`XWORLD.CanSeeTileToTile(ShooterBelowFeet, TargetLegs, VisibilityInfo)) NoLineOfSightMalus = -1000;}`log("NoLineOfSightMalus:"@NoLineOfSightMalus, true, 'XCom_HitRolls');If (NoLineOfSightMalus != 0) AddModifier(NoLineOfSightMalus, "No Line of Sight", m_ShotBreakdown, eHit_Success, bDebugLog);} - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 846[5.66768]→[4.72:621](∅→∅),[4.621]→[5.7636:7714](∅→∅),[5.7636]→[5.7636:7714](∅→∅),[5.7714]→[5.7714:7722](∅→∅),[5.7722]→[5.7722:7908](∅→∅),[5.7908]→[5.67963:67998](∅→∅),[5.67963]→[5.67963:67998](∅→∅),[5.67998]→[5.7909:7955](∅→∅)
if (default.AllowFarCoverToGiveSomeCoverProtection && (TargetState.GetTeam() == eTeam_XCom || TargetState.GetCurrentStat(eStat_AlertLevel)==`ALERT_LEVEL_RED || (TargetState.GetCurrentStat(eStat_AlertLevel)!=`ALERT_LEVEL_RED && !default.OnlyAlertedTargetsCanHaveTheExtraProtectionOfFarCoverAndHeightDisadvantage)) && (VisInfo.TargetCover==CT_None || (GoodAngleBonus > 0 && ExtendedLowCoverPreventingGoodAngleBonus == 0)) && //FAR COVER ONLY IF NOT IN COVER OR IF THE COVER TAKEN IS NOT IN THE DIRECTION OF THE SHOOTER (MORE FLANKING THAN COVER)TileDistance > 2 && TargetState.GetMyTemplate().bCanTakeCover == true){ShooterTargetDistance = TilesDistance(TargetTile, ShooterTile); //SUCH A DANGERIOUSLY MISLEADING FUNCTION!!!!??? HOWRS TRYING TO UNDERSTAND WHY DISTANCE WAS WRONGLY CALCULATED!!!FarCoverText = "Far Cover";if (ShooterHeadRelativeElevation == 0)// FarCover to a tile which may already be granting coverLosTile = TargetTile;LosTile.Z = `XWORLD.GetFloorTileZ(TargetTile);for (i=0; i<=TargetState.UnitHeight; i++) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 851
NextTile = TargetTile; FarCoverBonus = 0;for (i = 0; i < 16 && FarCoverBonus==0 && NextTile.Z == TargetTile.Z; ++i)if (`XWORLD.VoxelRaytrace_Tiles(PeekTile, LosTile, RayTrace)) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 853
NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);if (FarCover>0)if ((i == 0 && VisInfo.TargetCover == CT_None) || ((i == 1 || i == 2) && VisInfo.TargetCover != CT_Standing) || i > 2) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 855
FarCoverBonus = LOW_COVER_BONUS / (ShooterTargetDistance*0.7) * Max(0, TilesDistance(ShooterTile, NextTile) - ShooterTargetDistance*0.3);`log("LOS blocked by far cover:"@i@","@VisInfo.TargetCover, true, 'XCom_HitRolls');FarCover += 1; - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 859
}if (ShooterHead.Z - TargetLegs.Z < 0) //ABOVE SHOOTER{NextTile = TargetTile;for (i = 0; i < 5 && FarCoverBonus==0 && NextTile.Z == TargetTile.Z; ++i)if (`XWORLD.VoxelRaytrace_Tiles(PeekHead, LosTile, RayTrace)) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 862
NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);if (NextTile.Z>=TargetTile.Z && FarCover>0)if ((i == 0 && VisInfo.TargetCover == CT_None) || ((i == 1 || i == 2) && VisInfo.TargetCover != CT_Standing) || i > 2) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 864
FarCoverBonus = LOW_COVER_BONUS; //DIFFERENT VALUE FOR FAR COVER ON ELEVATED GROUND`log("LOS blocked by far cover:"@i@","@VisInfo.TargetCover, true, 'XCom_HitRolls');FarCover += 1; - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 868[3.1100]→[5.8602:8611](∅→∅),[5.8602]→[5.8602:8611](∅→∅),[5.8611]→[5.73867:74012](∅→∅),[5.73867]→[5.73867:74012](∅→∅)
}if (TilesDistance(TargetTile, NextTile) >= ShooterTargetDistance) {FarCoverBonus = 0;} //DON'T CONSIDER FAR COVER "BEHIND" SHOOTER... ;) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 869[2.1192]→[5.8612:8767](∅→∅),[5.74012]→[5.8612:8767](∅→∅),[5.8767]→[3.1101:1177](∅→∅),[3.1177]→[5.8767:8874](∅→∅),[5.8767]→[5.8767:8874](∅→∅)
if (FarCoverBonus > 0 && GoodAngleBonus > 0) {FarCoverBonus = Min(GoodAngleBonus, FarCoverBonus); FarCoverText = "FarCover Preventing GoodAngle";}`log("FarCoverBonus:"@round(-FarCoverBonus), true, 'XCom_HitRolls');AddModifier(round(-FarCoverBonus), FarCoverText, m_ShotBreakdown, eHit_Success, bDebugLog);}LosTile.Z++;} - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 872[5.74372]→[5.8875:9064](∅→∅),[5.9064]→[4.622:1040](∅→∅),[4.1040]→[5.9444:9871](∅→∅),[5.9444]→[5.9444:9871](∅→∅),[5.9871]→[2.1193:1240](∅→∅)
if (default.ApplyVerticalBadAngleAgainstHigherTargetAsProportionalHeightDisadvantage && ShooterHead.Z - TargetLegs.Z < 0 //TARGET STANDING ON A SURFACE HIGHER THAN THE SHOOTER'S HEAD&& (TargetState.GetTeam() == eTeam_XCom || TargetState.GetCurrentStat(eStat_AlertLevel)==`ALERT_LEVEL_RED || (TargetState.GetCurrentStat(eStat_AlertLevel)!=`ALERT_LEVEL_RED && !default.OnlyAlertedTargetsCanHaveTheExtraProtectionOfFarCoverAndHeightDisadvantage)) && TargetState.GetMyTemplate().bCanTakeCover == true) //HIGHER, LOWER OR SAME LEVEL, FAR COVER MUST GIVE SOME ADVANTAGE NO MATTER THE HEIGHT{ //HEIGHT DISADVANTAGE DOESN'T INCREASE TARGET'S HIGH/LOW COVER... BUT ONLY ADDS FROM 1 TO 19 COVER WHEN BUILDING/CLIFF PARTIALLY ACTS AS LOW COVERAlpha = FClamp((90-(-VerticalAngle) - 0) / (85 - 0), 0.0, 1.0);AngleToCoverModifier = Lerp(1, 0, Alpha);HeightDisadvantageMalus = round(-AngleToCoverModifier*(20)); NextTile = TargetTile;if (VisInfo.TargetCover == CT_MidLevel) FarCover = 1;if (VisInfo.TargetCover != CT_MidLevel)// FarCover for which cover hasn't been determined alreadyLosTile = TargetPeekTile;LosTile.Z = `XWORLD.GetFloorTileZ(TargetTile);for (i=0; i<=TargetState.UnitHeight; i++) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 877
for (i=1;i==20;++i)if (`XWORLD.VoxelRaytrace_Tiles(PeekTile, LosTile, RayTrace)){`log("LOS blocked by far cover:"@i, true, 'XCom_HitRolls');FarCover += 1;}if (`XWORLD.VoxelRaytrace_Tiles(PeekHead, LosTile, RayTrace)) - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 885
NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); if (NextTile.Z < TargetTile.Z) break;HeightDisadvantageMalus = HeightDisadvantageMalus + HeightDisadvantageMalus/2 ; //GIVES LARGE SUMS! ROUND AT THE END!!!`log("LOS blocked by far cover:"@i, true, 'XCom_HitRolls');FarCover += 1; - replacement in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 888[2.1298]→[2.1298:1349](∅→∅),[2.1349]→[5.80287:80366](∅→∅),[5.80287]→[5.80287:80366](∅→∅),[5.80366]→[5.10002:10186](∅→∅)
}if (FarCover==1) HeightDisadvantageMalus = 2 * HeightDisadvantageMalus;AddModifier(round(HeightDisadvantageMalus),class'XLocalizedData'.default.HeightDisadvantage, m_ShotBreakdown,eHit_Success, bDebugLog); //POSITIVE OR NEGATIVE???LosTile.Z++;}// Big things are easy to hit even if partially coveredif (TargetState.UnitHeight > 2){FarCover = Max(0, FarCover - (TargetState.UnitHeight - 2) * 2);}if (default.GiveHitChanceZeroWhenTargetableEnemiesAreInsteadNotTrulyInLineOfSight && FarCover == 12){`log("NoLineOfSightMalus: -1000", true, 'XCom_HitRolls');AddModifier(-1000, "No Line of Sight", m_ShotBreakdown, eHit_Success, bDebugLog);}else if (default.AllowFarCoverToGiveSomeCoverProtection && (TargetState.GetTeam() == eTeam_XCom || TargetState.GetCurrentStat(eStat_AlertLevel)==`ALERT_LEVEL_RED || (TargetState.GetCurrentStat(eStat_AlertLevel)!=`ALERT_LEVEL_RED && !default.OnlyAlertedTargetsCanHaveTheExtraProtectionOfFarCoverAndHeightDisadvantage))){// Scale far cover to high coverFarCoverBonus = FarCover * HIGH_COVER_BONUS / 12; // 12 is the maximum considered ray`log("FarCoverBonus:"@round(-FarCoverBonus), true, 'XCom_HitRolls');AddModifier(round(-FarCoverBonus), "Far Cover", m_ShotBreakdown, eHit_Success, bDebugLog);} - edit in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 1097[5.90960]→[5.90960:90964](∅→∅),[5.90964]→[5.11018:11168](∅→∅),[5.11168]→[5.91132:91789](∅→∅),[5.91132]→[5.91132:91789](∅→∅),[5.91789]→[5.11169:11235](∅→∅),[5.11235]→[5.91857:91859](∅→∅),[5.91857]→[5.91857:91859](∅→∅),[5.91859]→[5.91859:91861](∅→∅),[5.91863]→[5.91863:92146](∅→∅),[5.86531]→[5.10388:10689](∅→∅),[5.10689]→[5.86878:87018](∅→∅),[5.86878]→[5.86878:87018](∅→∅),[5.87018]→[5.10690:10791](∅→∅),[5.10791]→[5.87121:87284](∅→∅),[5.87121]→[5.87121:87284](∅→∅),[5.87502]→[5.87502:87651](∅→∅),[5.87869]→[5.87869:88570](∅→∅)
function bool CoverOnBothSides(TTile ShooterTile, TTile TargetTile){local TTile TileDifference;local int DirectionX;local int DirectionY;local TileData TargetTileData;TileDifference.X = TargetTile.X - ShooterTile.X;TileDifference.Y = TargetTile.Y - ShooterTile.Y;DirectionX = 0;DirectionY = 0;if( Abs(TileDifference.X) > Abs(TileDifference.Y) ) {if( TileDifference.X > 0) {DirectionX = `XWORLD.COVER_West;}if( TileDifference.X <=0) {DirectionX = `XWORLD.COVER_East;}}if( Abs(TileDifference.X) <= Abs(TileDifference.Y) ) {if( TileDifference.Y > 0) {DirectionY = `XWORLD.COVER_North;}if( TileDifference.Y <=0) {DirectionY = `XWORLD.COVER_South;}}`XWORLD.GetTileData(TargetTile, TargetTileData);if ((TargetTileData.CoverFlags & DirectionX) != 0 &&(TargetTileData.CoverFlags & DirectionY) != 0) return true;}static function float TilesDistance(TTile TileA, TTile TileB){local XComWorldData World;local vector LocA, LocB;World = `XWORLD;LocA = World.GetPositionFromTileCoordinates(TileA);LocB = World.GetPositionFromTileCoordinates(TileB);return VSize(LocA - LocB);}function TTile NextWalkableTile(TTile OriginTile, // YTTile MidTile, // ^TTile DestinationTile, // |out int FarCover) // X <--{local TTile TileDifference;local TTile NextTile;local int Direction;local int OriginDestinationAngle;local int MidTileDestinationAngle;local TileData NextTileData;OriginDestinationAngle = Abs(DestinationTile.X - OriginTile.X) / Abs(DestinationTile.Y - OriginTile.Y);MidTileDestinationAngle = Abs(DestinationTile.X - MidTile.X) / Abs(DestinationTile.Y - MidTile.Y);NextTile = MidTile;TileDifference.X = DestinationTile.X - MidTile.X;TileDifference.Y = DestinationTile.Y - MidTile.Y;Direction = 0;FarCover = 0;if (OriginDestinationAngle <= MidTileDestinationAngle){if( TileDifference.X > 0) {++NextTile.X;}if( TileDifference.X <=0) {--NextTile.X;}}if (OriginDestinationAngle > MidTileDestinationAngle){if( TileDifference.Y > 0) {++NextTile.Y;}if( TileDifference.Y <=0) {--NextTile.Y;}}if (Abs(TileDifference.X) > Abs(TileDifference.Y)){if( TileDifference.X > 0) {Direction = `XWORLD.COVER_WLow;}if( TileDifference.X <=0) {Direction = `XWORLD.COVER_ELow;}}if (Abs(TileDifference.X) <= Abs(TileDifference.Y)){if( TileDifference.Y > 0) {Direction = `XWORLD.COVER_NLow;}if( TileDifference.Y <=0) {Direction = `XWORLD.COVER_SLow;}}NextTile.Z = `XWORLD.GetFloorTileZ(NextTile);`XWORLD.GetTileData(NextTile, NextTileData);if ((NextTileData.CoverFlags & Direction) != 0) FarCover = 1;return NextTile;} - resolve order conflict in RWRealisticAimingAnglesHL/Src/RWRealisticAimingAnglesHL/Classes/Override_X2AbilityToHitCalc_StandardAim.uc at line 1097[5.90956]