From 1315ebf2a2c123c79bcdb288ac55620a8fc3a7e3 Mon Sep 17 00:00:00 2001 From: Jyrki Vesterinen Date: Wed, 24 Oct 2018 21:58:38 +0300 Subject: [PATCH] Fix #3650: rare crash in attack prediction The calculation for the probability to be slowed was incorrect if both units had slow and neither of them was slowed. Calculating the sum of all probabilities in the "not hit" row/column is a valid approach: however, if the unit itself can slow and the other unit isn't already slowed, then some of the "not hit" cases end up into a different plane. Probabilities from that plane are now counted as well. --- src/attack_prediction.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/attack_prediction.cpp b/src/attack_prediction.cpp index cb3d33f4a0cf..868c9b440f67 100644 --- a/src/attack_prediction.cpp +++ b/src/attack_prediction.cpp @@ -945,6 +945,10 @@ double prob_matrix::prob_of_zero(bool check_a, bool check_b) const */ double prob_matrix::row_sum(unsigned plane, unsigned row) const { + if(!plane_used(plane)) { + return 0.0; + } + double sum = 0.0; for(unsigned col : used_cols_[plane]) { sum += val(plane, row, col); @@ -957,6 +961,10 @@ double prob_matrix::row_sum(unsigned plane, unsigned row) const */ double prob_matrix::col_sum(unsigned plane, unsigned column) const { + if(!plane_used(plane)) { + return 0.0; + } + double sum = 0.0; for(unsigned row : used_rows_[plane]) { sum += val(plane, row, column); @@ -2148,10 +2156,14 @@ void complex_fight(attack_prediction_mode mode, * with simple addition. * Instead, just fetch the probability from the combat matrix. */ - opp_not_hit = original_opp_not_hit * pm->col_sum(plane_index(stats, opp_stats), opp_stats.hp); + unsigned int plane = plane_index(stats, opp_stats); + double not_hit = pm->col_sum(plane, opp_stats.hp) + ((plane & 1) ? 0.0 : pm->col_sum(plane | 1, opp_stats.hp)); + opp_not_hit = original_opp_not_hit * not_hit; } if(opp_stats.slows) { - self_not_hit = original_self_not_hit * pm->row_sum(plane_index(stats, opp_stats), stats.hp); + unsigned int plane = plane_index(stats, opp_stats); + double not_hit = pm->row_sum(plane, stats.hp) + ((plane & 2) ? 0.0 : pm->row_sum(plane | 2, stats.hp)); + self_not_hit = original_self_not_hit * not_hit; } } else { debug(("Using Monte Carlo simulation.\n"));