Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //In X2AbilityToHitCalc.uc
- protected function FinalizeHitChance()
- {
- local int i;
- local EAbilityHitResult HitResult;
- local float GrazeScale;
- local int FinalGraze;
- `log("==" $ GetFuncName() $ "==\n", m_bDebugModifiers, 'XCom_HitRolls');
- `log("Starting values...", m_bDebugModifiers, 'XCom_HitRolls');
- for (i = 0; i < eHit_MAX; ++i)
- {
- HitResult = EAbilityHitResult(i);
- `log(HitResult $ ":" @ m_ShotBreakdown.ResultTable[i], m_bDebugModifiers, 'XCom_HitRolls');
- }
- m_ShotBreakdown.FinalHitChance = m_ShotBreakdown.ResultTable[eHit_Success];
- // if crit goes negative, hit would get a boost, so restrict it to 0
- if (m_ShotBreakdown.ResultTable[eHit_Crit] < 0)
- m_ShotBreakdown.ResultTable[eHit_Crit] = 0;
- // Crit is folded into the chance to hit, so lower accordingly
- m_ShotBreakdown.ResultTable[eHit_Success] -= m_ShotBreakdown.ResultTable[eHit_Crit];
- // Graze is scaled against Success
- if (m_ShotBreakdown.ResultTable[eHit_Graze] > 0)
- {
- GrazeScale = float(m_ShotBreakdown.ResultTable[eHit_Graze]) / 100.0f;
- GrazeScale *= float(m_ShotBreakdown.FinalHitChance);
- FinalGraze = Round(GrazeScale);
- m_ShotBreakdown.ResultTable[eHit_Success] -= FinalGraze;
- m_ShotBreakdown.ResultTable[eHit_Graze] = FinalGraze;
- }
- if (m_ShotBreakdown.FinalHitChance >= 100)
- {
- m_ShotBreakdown.ResultTable[eHit_Miss] = 0;
- }
- else
- {
- m_ShotBreakdown.ResultTable[eHit_Miss] = 100 - m_ShotBreakdown.FinalHitChance;
- }
- `log("Calculated values...", m_bDebugModifiers, 'XCom_HitRolls');
- for (i = 0; i < eHit_MAX; ++i)
- {
- HitResult = EAbilityHitResult(i);
- `log(HitResult $ ":" @ m_ShotBreakdown.ResultTable[i], m_bDebugModifiers, 'XCom_HitRolls');
- }
- `log("Final hit chance (success + crit + graze) =" @ m_ShotBreakdown.FinalHitChance, m_bDebugModifiers, 'XCom_HitRolls');
- //"Negative chance to hit" is used as a token in UI code - don't ever report that.
- if (m_ShotBreakdown.FinalHitChance < 0)
- {
- `log("FinalHitChance was less than 0 (" $ m_ShotBreakdown.FinalHitChance $ ") and was clamped to avoid confusing the UI (@btopp).", m_bDebugModifiers, 'XCom_HitRolls');
- m_ShotBreakdown.FinalHitChance = 0;
- }
- }
- //The code you're currently using is above, if for instance, a shot has a 65% to-hit and a 65% crit chance, that's actually a 100% chance to crit IF you hit, in short, that just ain't right.
- //This happens because resultTable gives the chance that a shot is a hit AND a crit, a shot is a hit AND isn't a graze or a crit, a shot is a hit AND is a graze or a shot is a miss, ignoring stuff like lightning reflexes etc, that's applied after, if I'm not mistaken.
- //You're prepping the table badly for the purposes of InternalRollForAbilityHit and GetHitChance.
- //You may want to decouple your resultTable from UI chance to crit, or have a translation function, or don't call finalizehitchance for //purely UI data.
- //Anyway, here's fixed code, it should also fix how dodge is ignored by crits, currently it's only lowering the chance for a normal hit, so a crit would never be affected by dodge, 100% crit completely ignores dodge, if you want it to do that, it's easy enough to fiddle around, but it doesn't seem like that's desired.
- protected function FinalizeHitChance()
- {
- local int i;
- local EAbilityHitResult HitResult;
- local float GrazeScale;
- `log("==" $ GetFuncName() $ "==\n", m_bDebugModifiers, 'XCom_HitRolls');
- `log("Starting values...", m_bDebugModifiers, 'XCom_HitRolls');
- for (i = 0; i < eHit_MAX; ++i)
- {
- HitResult = EAbilityHitResult(i);
- // Clamp values, optional, but generally a good idea for the final leg of hit calc
- m_ShotBreakdown.ResultTable[i] = Clamp(m_ShotBreakdown.ResultTable[i], 0, 100);
- `log(HitResult $ ":" @ m_ShotBreakdown.ResultTable[i], m_bDebugModifiers, 'XCom_HitRolls');
- }
- m_ShotBreakdown.FinalHitChance = m_ShotBreakdown.ResultTable[eHit_Success];
- // Graze is scaled against chance to hit
- if (m_ShotBreakdown.ResultTable[eHit_Graze] > 0)
- {
- GrazeScale = float(m_ShotBreakdown.ResultTable[eHit_Graze]) / 100.0f;
- m_ShotBreakdown.ResultTable[eHit_Graze] = Round(GrazeScale * float(m_ShotBreakdown.ResultTable[eHit_Success]));
- m_ShotBreakdown.ResultTable[eHit_Success] -= m_ShotBreakdown.ResultTable[eHit_Graze];
- }
- // Here's an idea, add a new eHit_Type for display purposes
- m_ShotBreakdown.ResultTable[eHit_DisplayedCrit] = m_ShotBreakdown.ResultTable[eHit_Crit];
- m_ShotBreakdown.ResultTable[eHit_Crit] = Round(float(m_ShotBreakdown.ResultTable[eHit_Crit]) / 100.0f * float(m_ShotBreakdown.ResultTable[eHit_Success]));
- m_ShotBreakdown.ResultTable[eHit_Success] -= m_ShotBreakdown.ResultTable[eHit_Crit];
- m_ShotBreakdown.FinalHitChance = m_ShotBreakdown.ResultTable[eHit_Graze] + m_ShotBreakdown.ResultTable[eHit_Success] + m_ShotBreakdown.ResultTable[eHit_Crit]
- m_ShotBreakdown.ResultTable[eHit_Miss] = 100 - m_ShotBreakdown.FinalHitChance;
- `log("Calculated values...", m_bDebugModifiers, 'XCom_HitRolls');
- for (i = 0; i < eHit_MAX; ++i)
- {
- HitResult = EAbilityHitResult(i);
- `log(HitResult $ ":" @ m_ShotBreakdown.ResultTable[i], m_bDebugModifiers, 'XCom_HitRolls');
- }
- `log("Final hit chance (success + crit + graze) =" @ m_ShotBreakdown.FinalHitChance, m_bDebugModifiers, 'XCom_HitRolls');
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement