JSCVVDFDJPB44MYIIERF62A6R7G5I5NDGLXFTL43TP6T4OFREQHAC
class Override_X2AbilityToHitCalc_StandardAim
extends X2AbilityToHitCalc_StandardAim
config (RWRealisticAimingAngles);
//extends X2AbilityToHitCalc
//config(GameCore);
class Override_X2AbilityToHitCalc_StandardAim extends X2AbilityToHitCalc_StandardAim config (RWRealisticAimingAngles);
var bool UseIndividualConsecutiveRollsForHitChanceCriticalChanceDodgeChance;
var bool PrioritizeCriticalChanceOverDodgeChance;
var bool AlwaysRollForBothDodgeAndCriticalEvenWhenOneUnsuccesful;
var bool GuaranteedHitsCannotDodge;
var bool IndirectFireGuaranteesHit;
var bool EnableGamblerFallacySystemRoll;
var bool UseIndividualConsecutiveRollsForHitChanceCriticalChanceDodgeChance;
var bool PrioritizeCriticalChanceOverDodgeChance;
var bool AlwaysRollForBothDodgeAndCriticalEvenWhenOneUnsuccesful;
var bool GuaranteedHitsCannotDodge;
var bool IndirectFireGuaranteesHit;
var bool EnableGamblerFallacySystemRoll;
//static function StaticInternalRollForAbilityHit(X2AbilityToHitCalc_StandardAim Aim, XComGameState_Ability kAbility, AvailableTarget kTarget, bool bIsPrimaryTarget, const out AbilityResultContext ResultContext, out EAbilityHitResult Result, out ArmorMitigationResults ArmorMitigated, out int HitChance)
function InternalRollForAbilityHit( XComGameState_Ability kAbility, AvailableTarget kTarget, bool bIsPrimaryTarget, const out AbilityResultContext ResultContext, out EAbilityHitResult Result, out ArmorMitigationResults ArmorMitigated, out int HitChance)
function InternalRollForAbilityHit(XComGameState_Ability kAbility, AvailableTarget kTarget, bool bIsPrimaryTarget, const out AbilityResultContext ResultContext, out EAbilityHitResult Result, out ArmorMitigationResults ArmorMitigated, out int HitChance)
local TTile ShooterTile;
local TTile TargetTile;
local TTile ShooterHead;
local TTile TargetHead;
local TTile ShooterTorso;
// local TTile TargetTorso;
local TTile TargetLegs;
local TTile ShooterBelowFeet;
local float ShooterTargetDistance;
local float ShooterHeadRelativeElevation;
local float VerticalAngle;
local float GoodAngleBonus;
local float ExtendedLowCoverPreventingGoodAngleBonus;
local float HeightAdvantageBonus; //ALWAYS FLOATS INSTEAD OF INTS!!!!
local float HeightDisadvantageMalus; //OR YOU WILL LOOSE HOURS TRYING TO UNDERSTAND WHY
local float NoLineOfSightMalus; //THEY DIDN'T APPLY MULTIPLIERS!!! BECAUSE INT AUTO-ROUND!!! MOTHERFUCKERS!!!
local string FarCoverText;
local TTile NextTile;
local int FarCover;
local TTile ShooterTile;
local TTile TargetTile;
local TTile ShooterHead;
local TTile TargetHead;
local TTile ShooterTorso;
local TTile TargetLegs;
local TTile ShooterBelowFeet;
local float ShooterTargetDistance;
local float ShooterHeadRelativeElevation;
local float VerticalAngle;
local float GoodAngleBonus;
local float ExtendedLowCoverPreventingGoodAngleBonus;
local float HeightAdvantageBonus; //ALWAYS FLOATS INSTEAD OF INTS!!!!
local float HeightDisadvantageMalus; //OR YOU WILL LOOSE HOURS TRYING TO UNDERSTAND WHY
local float NoLineOfSightMalus; //THEY DIDN'T APPLY MULTIPLIERS!!! BECAUSE INT AUTO-ROUND!!! MOTHERFUCKERS!!!
local string FarCoverText;
local TTile NextTile;
local int FarCover;
CoverTypeOfTileAboveTarget = CoverTypeOfTileAboveCover (ShooterTile, TargetTile, VisInfo.TargetCoverAngle);
NextTileOverCoverType = NextTileOverCoverInSameDirection(ShooterTile, TargetTile);
CoverTypeOfTileAboveTarget = CoverTypeOfTileAboveCover(ShooterTile, TargetTile, VisInfo.TargetCoverAngle);
NextTileOverCoverType = NextTileOverCoverInSameDirection(ShooterTile, TargetTile);
super .AddModifier(100, AbilityTemplate.LocFriendlyName, m_ShotBreakdown, eHit_Success, bDebugLog); //WATCHOUT!!! SUPER. IS NOT ANYMORE THE PARENT
super.AddModifier(100, AbilityTemplate.LocFriendlyName, m_ShotBreakdown, eHit_Success, bDebugLog); //WATCHOUT!!! SUPER. IS NOT ANYMORE THE PARENT
//ADDED THIS PARAGRAPH!!! (GUARANTEED HIT MY ASS...)
/* TargetingObjectsRealisticallyAllowsToMissThemAndUsesConventionalHitChanceStatsPlusThisAimingBonus = 15
if(default.TargetingObjectsRealisticallyAllowsToMissThemAndUsesConventionalHitChanceStatsPlusThisAimingBonus != 100) {
TargetStateDestructibleObject = XComGameState_Destructible(History.GetGameStateForObjectID( kTarget.PrimaryTarget.ObjectID ));
NewGameStateForDestructibleObject = class'XComGameStateContext_ChangeContainer'.static.CreateChangeState("Conversion From Unit to Destructible for Aiming Stats");
TargetState = XComGameState_Unit(NewGameStateForDestructibleObject.CreateNewStateObject(class'XComGameState_Unit'));
TargetState.SetVisibilityLocation(TargetStateDestructibleObject.TileLocation); //KEYSTONEVISIBILITYLOCATION EVEN FOR OBJECTS??? REMEMBER HOW .TILELOCATION WAS BUGGY FOR UNITS!!!!
AddModifier(default.TargetingObjectsRealisticallyAllowsToMissThemAndUsesConventionalHitChanceStatsPlusThisAimingBonus, class'XLocalizedData'.default.DefenseStat, m_ShotBreakdown, eHit_Success, bDebugLog);}
else {
*/ //END OF ADDED PARAGRAPH!!!
// when targeting non-units, we have a 100% chance to hit. They can't dodge or otherwise
// mess up our shots
m_ShotBreakdown.HideShotBreakdown = true;
AddModifier(100 , class'XLocalizedData'.default.OffenseStat, m_ShotBreakdown, eHit_Success, bDebugLog);
// } //ADDED THIS LINE!!!
// when targeting non-units, we have a 100% chance to hit. They can't dodge or otherwise
// mess up our shots
m_ShotBreakdown.HideShotBreakdown = true;
AddModifier(100, class'XLocalizedData'.default.OffenseStat, m_ShotBreakdown, eHit_Success, bDebugLog);
// if( (SHOULD_DISABLE_BONUS_ON_ANGLE_TO_EXTENDED_LOW_COVER && VisInfo.TargetCover == CT_MidLevel) || (SHOULD_ENABLE_PENALTY_ON_ANGLE_TO_EXTENDED_HIGH_COVER && VisInfo.TargetCover == CT_Standing) )
if( (true && VisInfo.TargetCover == CT_MidLevel) || (false && VisInfo.TargetCover == CT_Standing) )
if((true && VisInfo.TargetCover == CT_MidLevel) || (false && VisInfo.TargetCover == CT_Standing))
NextTileOverCoverType = NextTileOverCoverInSameDirection(UnitTileLocation, TargetTileLocation );
// if( SHOULD_DISABLE_BONUS_ON_ANGLE_TO_EXTENDED_LOW_COVER && VisInfo.TargetCover == CT_MidLevel && NextTileOverCoverType == CT_MidLevel ) //EXTENDED LOW-HIGH COVER HIBRID
// if(true && (VisInfo.TargetCover == CT_MidLevel || VisInfo.TargetCover == CT_Standing) && (NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing))
if(true && VisInfo.TargetCover == CT_MidLevel && (NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing))
NextTileOverCoverType = NextTileOverCoverInSameDirection(UnitTileLocation, TargetTileLocation);
// else if(SHOULD_ENABLE_PENALTY_ON_ANGLE_TO_EXTENDED_HIGH_COVER && VisInfo.TargetCover == CT_Standing && NextTileOverCoverType == CT_Standing )
else if(false && VisInfo.TargetCover == CT_Standing && NextTileOverCoverType == CT_Standing )
else if(false && VisInfo.TargetCover == CT_Standing && NextTileOverCoverType == CT_Standing )
Alpha = FClamp((VisInfo.TargetCoverAngle - MIN_ANGLE_TO_COVER ) / (MAX_ANGLE_TO_COVER - MIN_ANGLE_TO_COVER ), 0.0, 1.0);
AngleToCoverModifier = Lerp(MAX_ANGLE_PENALTY , MIN_ANGLE_PENALTY , Alpha);
Alpha = FClamp((VisInfo.TargetCoverAngle - MIN_ANGLE_TO_COVER) / (MAX_ANGLE_TO_COVER - MIN_ANGLE_TO_COVER), 0.0, 1.0);
AngleToCoverModifier = Lerp(MAX_ANGLE_PENALTY, MIN_ANGLE_PENALTY, Alpha);
// AngleToCoverModifier = Lerp(1 , 0 , Alpha);
// AddModifier(Round(CoverValue * AngleToCoverModifier) , class'XLocalizedData'.default.AngleToTargetCover, m_ShotBreakdown, eHit_Success, bDebugLog);
GoodAngleBonus = Round(CoverValue * AngleToCoverModifier);
AddModifier(GoodAngleBonus , class'XLocalizedData'.default.AngleToTargetCover, m_ShotBreakdown, eHit_Success, bDebugLog);
// if (VisInfo.TargetCover == CT_Standing && NextTileOverCoverType == CT_MidLevel) AddModifier(-Round(GoodAngleBonus / 2) , "ExtendedLowCover preventing GoodAngle" , m_ShotBreakdown, eHit_Success, bDebugLog);
// if ((VisInfo.TargetCover == CT_MidLevel || VisInfo.TargetCover == CT_Standing) && (NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing)) AddModifier(-Round(GoodAngleBonus / 2) , "ExtendedLowCover preventing GoodAngle" , m_ShotBreakdown, eHit_Success, bDebugLog);
if ( (NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing)) {
ExtendedLowCoverPreventingGoodAngleBonus = -Round(GoodAngleBonus / 2);
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... ;)
GoodAngleBonus = Round(CoverValue * AngleToCoverModifier);
AddModifier(GoodAngleBonus, class'XLocalizedData'.default.AngleToTargetCover, m_ShotBreakdown, eHit_Success, bDebugLog);
if ((NextTileOverCoverType == CT_MidLevel || NextTileOverCoverType == CT_Standing))
{
ExtendedLowCoverPreventingGoodAngleBonus = -Round(GoodAngleBonus / 2);
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... ;)
// PI = 3.141592; //ALMIGHTY UNIVERSAL CONSTANT
// ShooterHead = ShooterTile; ShooterHead.Z += 2;
// TargetHead = TargetTile; TargetHead .Z += 2;
// ShooterHead = ShooterTile; ShooterHead.Z += UnitState .UnitHeight -1;
// TargetHead = TargetTile; TargetHead .Z += TargetState.UnitHeight -1;
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;
// TargetTorso = TargetHead ; TargetTorso .Z -= 0.5;
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;
if (default.ApplyVerticalGoodAngleAgainstLowerTargetAsProportionalHeightAdvantage &&
ShooterHeadRelativeElevation > 0 &&
((VisInfo.TargetCover == CT_MidLevel ) || //HEIGHT ADVANTAGE REDUCES ONLY LOW COVER .... OR SHOULD IT???
(VisInfo.TargetCover == CT_Standing && CoverTypeOfTileAboveTarget == CT_None) ) ){ //...WELL DEPENDS ON WETHER IT'S A VERTICAL TREE OR AN ORIZONTAL HIGHCOVER FENCE... ;)
if (default.ApplyVerticalGoodAngleAgainstLowerTargetAsProportionalHeightAdvantage && ShooterHeadRelativeElevation > 0 && ((VisInfo.TargetCover == CT_MidLevel) //HEIGHT ADVANTAGE REDUCES ONLY LOW COVER .... OR SHOULD IT???
|| (VisInfo.TargetCover == CT_Standing && CoverTypeOfTileAboveTarget == CT_None)))
{ //...WELL DEPENDS ON WETHER IT'S A VERTICAL TREE OR AN ORIZONTAL HIGHCOVER FENCE... ;)
Alpha = FClamp(((90-VerticalAngle) - default.MaximumHeightAdvantageBonusEndsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface) / (default.MinimumHeightAdvantageBonusStartsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface - default.MaximumHeightAdvantageBonusEndsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface), 0.0, 1.0);
// Alpha = FClamp((VisInfo.TargetCoverAngle - 0 ) / (45 - 0 ), 0.0, 1.0);
// Alpha = FClamp(((90-VerticalAngle) - 30 ) / (90 - 30 ), 0.0, 1.0);
Alpha = FClamp(((90-VerticalAngle) - default.MaximumHeightAdvantageBonusEndsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface) / (default.MinimumHeightAdvantageBonusStartsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface - default.MaximumHeightAdvantageBonusEndsAtThisVerticalAngleBetweenLineOfFireAndCoverSurface), 0.0, 1.0);
// HeightAdvantageBonus = round(VerticalAngle/90 * CoverValue);
AddModifier(HeightAdvantageBonus, class'XLocalizedData'.default.HeightAdvantage, m_ShotBreakdown, eHit_Success, bDebugLog);}
AddModifier(HeightAdvantageBonus, class'XLocalizedData'.default.HeightAdvantage, m_ShotBreakdown, eHit_Success, bDebugLog);
}
if (default.GiveHitChanceZeroWhenTargetableEnemiesAreInsteadNotTrulyInLineOfSight// &&
/* ShooterHeadRelativeElevation > 0 */ ){ //'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 GROUNDS
NextTile = 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;}
If (NoLineOfSightMalus != 0) AddModifier(NoLineOfSightMalus, "No Line of Sight", m_ShotBreakdown, eHit_Success, bDebugLog);}
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 GROUNDS
NextTile = 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;
}
If (NoLineOfSightMalus != 0) AddModifier(NoLineOfSightMalus, "No Line of Sight", m_ShotBreakdown, eHit_Success, bDebugLog);
}
if (default.AllowFarCoverToGiveSomeCoverProtection &&
(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 = class'Helpers'.static.DistanceBetweenTiles(TargetTile, ShooterTile, false ); //FORGETTING THE "FALSE" VARIABLE WILL GIVE "SQUARED" DISTANCE!!!! MOTHERFUCKER!!! HOW GAVE SUCH A WRONG NAME TO
ShooterTargetDistance = TilesDistance(TargetTile, ShooterTile ); //SUCH A DANGERIOUSLY MISLEADING FUNCTION!!!!??? HOWRS TRYING TO UNDERSTAND WHY DISTANCE WAS WRONGLY CALCULATED!!!
// ShooterTargetDistance = VSize(TargetLocation, ShooterLocation); // * 0.8; //NO FAR COVER 20% NEAR THE SHOOTER... NONSENSE.. ;)
if (default.AllowFarCoverToGiveSomeCoverProtection && (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!!!
if (ShooterHeadRelativeElevation == 0){ NextTile = TargetTile; FarCoverBonus = 0;
if (ShooterHeadRelativeElevation == 0)
{
NextTile = TargetTile; FarCoverBonus = 0;
if(FarCoverBonus==0 && NextTile.Z == TargetTile.Z) {NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); if (FarCover>0) FarCoverBonus = 20 / (ShooterTargetDistance*0.7) * Max(0, TilesDistance(ShooterTile, NextTile) - ShooterTargetDistance*0.3);}
if(FarCoverBonus==0 && NextTile.Z == TargetTile.Z) {NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); if (FarCover>0) FarCoverBonus = 20 / (ShooterTargetDistance*0.7) * Max(0, TilesDistance(ShooterTile, NextTile) - ShooterTargetDistance*0.3);} }
if (ShooterHead.Z - TargetLegs.Z < 0){ NextTile = TargetTile; //ABOVE SHOOTER
}
if (ShooterHead.Z - TargetLegs.Z < 0) //ABOVE SHOOTER
{
NextTile = TargetTile;
if(FarCoverBonus==0 && NextTile.Z == TargetTile.Z) {NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); if (NextTile.Z>=TargetTile.Z && FarCover>0) FarCoverBonus = 20;}}
if(FarCoverBonus==0 && NextTile.Z == TargetTile.Z) {NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); if (NextTile.Z>=TargetTile.Z && FarCover>0) FarCoverBonus = 20;}
}
if (FarCoverBonus > 0 && GoodAngleBonus > 0) {FarCoverBonus = Min(GoodAngleBonus, FarCoverBonus); FarCoverText = "FarCover Preventing GoodAngle";}
// AddModifier( -FarCoverBonus , FarCoverText, m_ShotBreakdown, eHit_Success, bDebugLog);}
AddModifier(round(-FarCoverBonus), FarCoverText, m_ShotBreakdown, eHit_Success, bDebugLog);}
if (FarCoverBonus > 0 && GoodAngleBonus > 0) {FarCoverBonus = Min(GoodAngleBonus, FarCoverBonus); FarCoverText = "FarCover Preventing GoodAngle";}
AddModifier(round(-FarCoverBonus), FarCoverText, m_ShotBreakdown, eHit_Success, bDebugLog);
}
if (default.ApplyVerticalBadAngleAgainstHigherTargetAsProportionalHeightDisadvantage &&
ShooterHead.Z - TargetLegs.Z < 0 && //TARGET STANDING ON A SURFACE HIGHER THAN THE SHOOTER'S HEAD
(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
// VisInfo.TargetCover == CT_None
){ //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 COVER
// Alpha = FClamp((VisInfo.TargetCoverAngle - MIN_ANGLE_TO_COVER ) / (MAX_ANGLE_TO_COVER - MIN_ANGLE_TO_COVER ), 0.0, 1.0);
// Alpha = FClamp((VisInfo.TargetCoverAngle - 0 ) / (45 - 0 ), 0.0, 1.0);
Alpha = FClamp((90-(-VerticalAngle) - 0 ) / (85 - 0 ), 0.0, 1.0);
// AngleToCoverModifier = Lerp(MAX_ANGLE_BONUS_MOD , MIN_ANGLE_BONUS_MOD , Alpha);
AngleToCoverModifier = Lerp(1 , 0 , Alpha);
// HeightDisadvantageMalus = round(VerticalAngle/90*(20)); //NEGATIVE RELATIVEELEVATION --> NEGATIVE VERTICALANGLE --> NEGATIVE MALUS//SOMETIMES YOU ARE SHOOTING FROM THE "SIDE OF HIS LOWCOVER" AND THE SIDE HAS ROOFCEILING AS PROTECTION...
HeightDisadvantageMalus = round(-AngleToCoverModifier*(20)); NextTile = TargetTile;
/* NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover); //EACH "STEP BACKWARDS"//THE ROOFTOP-BORDER UNTIL
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);} //NEGATIVE RELATIVEELEVATION --> NEGATIVE VERTICALANGLE --> NEGATIVE MALUS
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); NextTile = NextWalkableTile(TargetTile, NextTile, ShooterTile, FarCover);}
if (NextTile.Z >= TargetTile.Z) {HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); }
*/ if (VisInfo.TargetCover == CT_MidLevel) FarCover = 1;
if (default.ApplyVerticalBadAngleAgainstHigherTargetAsProportionalHeightDisadvantage && ShooterHead.Z - TargetLegs.Z < 0 //TARGET STANDING ON A SURFACE HIGHER THAN THE SHOOTER'S HEAD
&& (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 COVER
Alpha = 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;
// HeightDisadvantageMalus = round(HeightDisadvantageMalus + HeightDisadvantageMalus/2); //ROUNDING SMALL PERCENTAGES NEVER
HeightDisadvantageMalus = HeightDisadvantageMalus + HeightDisadvantageMalus/2 ; //GIVES LARGE SUMS! ROUND AT THE END!!!
HeightDisadvantageMalus = HeightDisadvantageMalus + HeightDisadvantageMalus/2 ; //GIVES LARGE SUMS! ROUND AT THE END!!!
// HeightDisadvantageMalus = HeightDisadvantageMalus/(TargetState.UnitHeight-1); // TALL FACELESS/SECTOPODS DON'T HIDE MUCH BEHIND HIGH BUILDINGS/CLIFFS BORDERS
// if (HeightDisadvantageMalus < -1000) HeightDisadvantageMalus = -1000;
// else if (HeightDisadvantageMalus < -20) HeightDisadvantageMalus = -20;
// AddModifier( HeightDisadvantageMalus , class'XLocalizedData'.default.HeightDisadvantage, m_ShotBreakdown, eHit_Success, bDebugLog);} //POSITIVE OR NEGATIVE???
AddModifier(round(HeightDisadvantageMalus), class'XLocalizedData'.default.HeightDisadvantage, m_ShotBreakdown, eHit_Success, bDebugLog);} //POSITIVE OR NEGATIVE???
AddModifier(round(HeightDisadvantageMalus),
class'XLocalizedData'.default.HeightDisadvantage, m_ShotBreakdown,
eHit_Success, bDebugLog); //POSITIVE OR NEGATIVE???
}
// PersistentEffect.GetToHitAsTargetModifiers(EffectState, UnitState, TargetState, kAbility , self.Class, bMeleeAttack, bFlanking, bIndirectFire, EffectModifiers);
PersistentEffect.GetToHitAsTargetModifiers(EffectState, UnitState, TargetState, kAbility, class'X2AbilitytoHitCalc_StandardAim', bMeleeAttack, bFlanking, bIndirectFire, EffectModifiers);
PersistentEffect.GetToHitAsTargetModifiers(EffectState, UnitState, TargetState, kAbility, class'X2AbilitytoHitCalc_StandardAim', bMeleeAttack, bFlanking, bIndirectFire, EffectModifiers);
function TTile NextWalkableTile( TTile OriginTile , // Y
TTile MidTile , // ^
TTile DestinationTile, // |
out int FarCover ){ // X <--
local TTile TileDifference;
local TTile NextTile;
local int Direction;
local int OriginDestinationAngle;
local int MidTileDestinationAngle;
function TTile NextWalkableTile(
TTile OriginTile, // Y
TTile MidTile, // ^
TTile DestinationTile, // |
out int FarCover) // X <--
{
local TTile TileDifference;
local TTile NextTile;
local int Direction;
local int OriginDestinationAngle;
local int MidTileDestinationAngle;
/* if( (Abs(TileDifference.X) > Abs(TileDifference.Y) && TargetCoverAngle>45) || //FROM FRONT OF X-AXIS COVER
(Abs(TileDifference.X) > Abs(TileDifference.Y) && TargetCoverAngle<45) ){ //FROM SIDE OF X-AXIS COVER
if( TileDifference.X > 0) {TileAboveCover.X += 1;}
if( TileDifference.X <=0) {TileAboveCover.X -= 1;}}
if( (Abs(TileDifference.X) <= Abs(TileDifference.Y) && TargetCoverAngle>45) || //FROM FRONT OF Y-AXIS COVER
(Abs(TileDifference.X) <= Abs(TileDifference.Y) && TargetCoverAngle<45) ){ //FROM SIDE OF Y-AXIS COVER
if( TileDifference.Y > 0) {TileAboveCover.Y += 1;}
if( TileDifference.Y <=0) {TileAboveCover.Y -= 1;}}
*/
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) ||
`XWORLD.IsTileOccupied (TileAboveCover) ) return CT_Standing;
/*
TileAboveCover = DestTile; TileAboveCover.Z += 1; TileAboveCover.X += 1;
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) ||
`XWORLD.IsTileOccupied (TileAboveCover) ) return CT_Standing;
TileAboveCover = DestTile; TileAboveCover.Z += 1; TileAboveCover.X -= 1;
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) ||
`XWORLD.IsTileOccupied (TileAboveCover) ) return CT_Standing;
TileAboveCover = DestTile; TileAboveCover.Z += 1; TileAboveCover.Y += 1;
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) ||
`XWORLD.IsTileOccupied (TileAboveCover) ) return CT_Standing;
TileAboveCover = DestTile; TileAboveCover.Z += 1; TileAboveCover.Y -= 1;
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) ||
`XWORLD.IsTileOccupied (TileAboveCover) ) return CT_Standing;
*/
if(`XWORLD.IsTileFullyOccupied(TileAboveCover) || `XWORLD.IsTileOccupied(TileAboveCover)) return CT_Standing;
function bool CoverOnBothSides( TTile ShooterTile,
TTile TargetTile) {
local TTile TileDifference;
local int DirectionX;
local int DirectionY;
function bool CoverOnBothSides(TTile ShooterTile, TTile TargetTile)
{
local TTile TileDifference;
local int DirectionX;
local int DirectionY;