Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bIndirectFire hits aren't guaranteed #1213

Open
Iridar opened this issue Jun 29, 2023 · 3 comments · Fixed by #1216
Open

bIndirectFire hits aren't guaranteed #1213

Iridar opened this issue Jun 29, 2023 · 3 comments · Fixed by #1216
Assignees
Milestone

Comments

@Iridar
Copy link
Contributor

Iridar commented Jun 29, 2023

Related code

When an ability's hit is supposed to be guaranteed, current code just adds 100 to hit chance, and then chugs along merrily, potentially adding negative hit modifiers from other sources, such as Defense from a Smoke Grenade making grenades no longer guaranteed:

[0448.59] XCom_HitRolls: ===InternalRollForAbilityHit===
[0448.59] XCom_HitRolls: Attacker ID: 3115
[0448.59] XCom_HitRolls: Target ID: 2376
[0448.59] XCom_HitRolls: Ability: Throw Grenade (ThrowGrenade)
[0448.59] XCom_HitRolls: =GetHitChance=
[0448.59] XCom_HitRolls: Modifying eHit_Success +100 (Throw Grenade), New hit chance: 100
[0448.59] XCom_HitRolls: Modifying eHit_Success +0 (Throw Grenade), New hit chance: 100
[0448.59] XCom_HitRolls: Modifying eHit_Crit +0 (Throw Grenade), New hit chance: 100
[0448.59] XCom_HitRolls: Modifying eHit_Success -20 (Defensive Smoke), New hit chance: 80
[0448.59] XCom_HitRolls: ==FinalizeHitChance==

[0448.59] XCom_HitRolls: Starting values...
[0448.59] XCom_HitRolls: eHit_Success: 80
[0448.59] XCom_HitRolls: eHit_Crit: 0
[0448.59] XCom_HitRolls: eHit_Graze: 0
[0448.59] XCom_HitRolls: eHit_Miss: 0
[0448.59] XCom_HitRolls: eHit_LightningReflexes: 0
[0448.59] XCom_HitRolls: eHit_Untouchable: 0
[0448.59] XCom_HitRolls: eHit_CounterAttack: 0
[0448.59] XCom_HitRolls: eHit_Parry: 0
[0448.59] XCom_HitRolls: eHit_Deflect: 0
[0448.59] XCom_HitRolls: eHit_Reflect: 0
[0448.59] XCom_HitRolls: Calculated values...
[0448.59] XCom_HitRolls: eHit_Success: 80
[0448.59] XCom_HitRolls: eHit_Crit: 0
[0448.59] XCom_HitRolls: eHit_Graze: 0
[0448.59] XCom_HitRolls: eHit_Miss: 20
[0448.59] XCom_HitRolls: eHit_LightningReflexes: 0
[0448.59] XCom_HitRolls: eHit_Untouchable: 0
[0448.59] XCom_HitRolls: eHit_CounterAttack: 0
[0448.59] XCom_HitRolls: eHit_Parry: 0
[0448.59] XCom_HitRolls: eHit_Deflect: 0
[0448.59] XCom_HitRolls: eHit_Reflect: 0
[0448.59] XCom_HitRolls: Final hit chance (success + crit + graze) = 80
[0448.59] XCom_HitRolls: =InternalRollForAbilityHit=
[0448.59] XCom_HitRolls: Final hit chance: 80
[0448.59] XCom_HitRolls: Random roll: 95
[0448.59] XCom_HitRolls: Checking table eHit_Success (80)...
[0448.59] XCom_HitRolls: Checking table eHit_Crit (80)...
[0448.59] XCom_HitRolls: Checking table eHit_Graze (80)...
[0448.59] XCom_HitRolls: ***MISS eHit_Miss
@Iridar Iridar added this to the 1.26.0 milestone Jun 29, 2023
@Iridar Iridar self-assigned this Jun 29, 2023
@Tedster59
Copy link
Contributor

Tedster59 commented Jun 29, 2023

bIndirectFire does the same thing, thus the Kiruka fix in some Mod Jam stuff to set bGuaranteedHit for these abilities too.

The modifier for shooting non-units such as objectives is also just a flat 100 and handled in a separate if statement further down:

if (UnitState != none && TargetState == none)
	{
		// 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);
	}

Only the section for bGuaranteedHit calls super.AddModifier directly, the others call . I wonder if the short circuit condition in the version that's part of X2AbilityToHitCalc_StandardAim is triggering when it shouldn't.

Another possible explanation, the code that adds the units base aim to the modifiers is located inside the if (!bIndirectFire) block, so indirect attacks such as grenades are not getting the soldier's base aim stat added to start with, leaving the aim at the flat 100 before defense modifiers from effects come into play.

A band-aid fix would be to simply increase the values bGuaranteedHit and bIndirectFire add to aim. A proper fix would probably add some additional validation at the end to modify m_shotbreakdown if either of these variables are true.

Iridar pushed a commit to Iridar/X2WOTCCommunityHighlander that referenced this issue Jun 29, 2023
@Iridar Iridar changed the title Guaranteed hits aren't guaranteed bIndirectFire hits aren't guaranteed Jun 29, 2023
@Iridar
Copy link
Contributor Author

Iridar commented Jun 29, 2023

@Tedster59 sorry, I think I confused you with the issue name, this issue happens specifically with bIndirectFire abilities.

With both bIndirectFire and bGuaranteedHit the code adds 100 to hit chance, but the following distinct difference is that with bGuaranteedHit all other hit modifiers besides crit are ignored.

So bGuaranteedHit hits are in fact guaranteed, as far as I can tell.

Hits being "guaranteed" against interactive objects is a separate issue and was already handled in 1.25.0.

#1213 changes the code to treat bIndirectFire the same way as bGuaranteedHit for the purposes of hit modifiers.

The dev comment suggests that with bGuaranteedHit only Hit and Crit are possible outcomes, while with bIndirectFire Graze is possible too, but that comment seems to be out of touch with their own implementation that removes Graze as a possible outcome if the hit chance is 100.

I'm getting the impression that Indirect Fire as a concept is somewhat raw and unfinished. X2Effect_Persistent::GetToHitModifiers() receives bIndirectFire from the Hit Calc, suggesting that different effects may add different hit modifiers depending on if the ability is indirect fire or not.

For example, Suppression explicitly avoids adding modifiers to indirect fire abilities, as if to make it possible to implement some sort of "blind fire from behind cover" ability or to prevent Suppression from altering hit chance or scatter of grenade throws, which is not a mechanic that was ever implement in XCOM 2, but maybe it was planned at some point?

However, indirect fire ever ends up being used only for grenades and similar explosive weapons, which are never supposed to miss anyway.

With all that in mind, I feel relatively confident in making the code treat bIndirectFire and bGuaranteedHit the same way as far as ignoring hit modifiers goes, because it's the only way to reliably fix all instances of using bIndirectFire that assumed it's never supposed to miss, even if it's somewhat BC breaking and almost elevates bIndirectFire argument in GetToHitModifiers() to the deprecated status.

Iridar pushed a commit that referenced this issue Aug 10, 2023
Iridar pushed a commit to Iridar/X2WOTCCommunityHighlander that referenced this issue Aug 13, 2023
# This is the 1st commit message:

Fix a few log warnings for Issue X2CommunityCore#324

# This is the commit message #2:

Implement Issue X2CommunityCore#1213

# This is the commit message X2CommunityCore#3:

Update X2TacticalGameRulesetDataStructures.uc

Inventory slot support for extra grenades
Tedster59 added a commit to Tedster59/X2WOTCCommunityHighlander that referenced this issue Aug 20, 2023
Tedster59 added a commit to Tedster59/X2WOTCCommunityHighlander that referenced this issue Aug 20, 2023
@Iridar
Copy link
Contributor Author

Iridar commented Aug 21, 2023

#1216 that fixed this issue in 1.26 was reverted in 1.26.1 due to breaking certain abilities when used alongside XMB. Alternative approach to be figured out in 1.27.

@Iridar Iridar reopened this Aug 21, 2023
@Iridar Iridar modified the milestones: 1.26.0, 1.27.0 Aug 21, 2023
Iridar pushed a commit to Iridar/X2WOTCCommunityHighlander that referenced this issue Aug 21, 2023
@Iridar Iridar modified the milestones: 1.27.0, 1.28.0 Oct 29, 2023
@Iridar Iridar modified the milestones: 1.28.0, 1.29.0 May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants