private static float GetRerollResult(RollResult baseResult, int off, int def, int roll, SaveIncrease saveBoost, SaveIncrease monsterSaveBoost, ref float maxMiss, ref float minCrit) { if (monsterSaveBoost.HasFlag(SaveIncrease.AURA_OF_MISFORTUNE)) { float result = 0; for (int i = 1; i <= 20; i++) { result += GetRollResult(Math.Min(i, roll), off, def, saveBoost, SaveIncrease.NONE, ref maxMiss, ref minCrit); } return(result / 20f); } if (baseResult < RollResult.SUCCESS && maxMiss < roll) { maxMiss = roll; } if (baseResult > RollResult.SUCCESS && minCrit > roll) { minCrit = roll; } float total = 0; if ((saveBoost.HasFlag(SaveIncrease.REROLL_FAILURE_PLUS_2) || saveBoost.HasFlag(SaveIncrease.REROLL_FAILURE)) && baseResult == RollResult.FAIL) { total = RollSimpleSave(baseResult, off + (saveBoost.HasFlag(SaveIncrease.REROLL_FAILURE_PLUS_2) ? 2 : 0), def, saveBoost, (int)RollResult.FAIL); return(((int)baseResult * 3 + (total / 20)) / 4); } if ((saveBoost.HasFlag(SaveIncrease.REROLL_CRITICAL_FAILURE_PLUS_2) || saveBoost.HasFlag(SaveIncrease.REROLL_CRITICAL_FAILURE)) && baseResult == RollResult.CRIT_FAIL) { total = RollSimpleSave(baseResult, off + (saveBoost.HasFlag(SaveIncrease.REROLL_CRITICAL_FAILURE_PLUS_2) ? 2 : 0), def, saveBoost); return(((int)baseResult * 3 + (total / 20)) / 4); } if (saveBoost.HasFlag(SaveIncrease.DISADVANTAGE) && baseResult == RollResult.SUCCESS) { total = RollSimpleSave(baseResult, off, def, saveBoost, (int)RollResult.CRIT_FAIL, (int)baseResult); return(Math.Min(total, (int)baseResult)); } return((int)baseResult); }
private static float RollSimpleSave(RollResult baseResult, int off, int def, SaveIncrease saveBoost, int minimumResult = 0, int maximumResult = 3) { float total = 0; for (int i = 1; i <= 20; i++) { if (i == 1) { if (saveBoost.HasFlag(SaveIncrease.CRIT_FAIL_IS_FAIL)) { total += Math.Max(Math.Min((int)RollResult.FAIL, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.CRIT_FAIL, maximumResult), minimumResult); } continue; } if (i == 20) { if (off + i >= def) { total += Math.Max(Math.Min((int)RollResult.CRIT_SUCCESS, maximumResult), minimumResult); } else if (off + i >= def - 10) { if (saveBoost.HasFlag(SaveIncrease.SUCCESS_IS_CRIT_SUCCESS)) { total += Math.Max(Math.Min((int)RollResult.CRIT_SUCCESS, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.SUCCESS, maximumResult), minimumResult); } } else { if (saveBoost.HasFlag(SaveIncrease.FAIL_IS_SUCCESS)) { total += Math.Max(Math.Min((int)RollResult.SUCCESS, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.FAIL, maximumResult), minimumResult); } } continue; } if (off + i >= def) //save { if (off + i >= def + 10) //crit { total += Math.Max(Math.Min((int)RollResult.CRIT_SUCCESS, maximumResult), minimumResult); } else { if (saveBoost.HasFlag(SaveIncrease.SUCCESS_IS_CRIT_SUCCESS)) { total += Math.Max(Math.Min((int)RollResult.CRIT_SUCCESS, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.SUCCESS, maximumResult), minimumResult); } } } else //fail { if (off + i <= def - 10) { if (saveBoost.HasFlag(SaveIncrease.CRIT_FAIL_IS_FAIL)) { total += Math.Max(Math.Min((int)RollResult.FAIL, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.CRIT_FAIL, maximumResult), minimumResult); } } else //crit { if (saveBoost.HasFlag(SaveIncrease.FAIL_IS_SUCCESS)) { total += Math.Max(Math.Min((int)RollResult.SUCCESS, maximumResult), minimumResult); } else { total += Math.Max(Math.Min((int)RollResult.FAIL, maximumResult), minimumResult); } } } } return(total); }
private static float GetRollResult(int i, int off, int def, SaveIncrease saveBoost, SaveIncrease monsterSaveBoost, ref float maxMiss, ref float minCrit) { if (saveBoost.HasFlag(SaveIncrease.MINIMUM_10)) { i = Math.Max(i, 10); } if (i == 1) { if (saveBoost.HasFlag(SaveIncrease.CRIT_FAIL_IS_FAIL)) { return(GetRerollResult(RollResult.FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.CRIT_FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } if (i == 20 || (saveBoost.HasFlag(SaveIncrease.CRIT_ON_19) && i == 19)) { if (off + i >= def) { return(GetRerollResult(RollResult.CRIT_SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else if (off + i >= def - 10 && i == 20) { if (saveBoost.HasFlag(SaveIncrease.SUCCESS_IS_CRIT_SUCCESS)) { return(GetRerollResult(RollResult.CRIT_SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } else { if (saveBoost.HasFlag(SaveIncrease.FAIL_IS_SUCCESS)) { return(GetRerollResult(RollResult.SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } } if (off + i >= def) //save { if (off + i >= def + 10) //crit { return(GetRerollResult(RollResult.CRIT_SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { if (saveBoost.HasFlag(SaveIncrease.SUCCESS_IS_CRIT_SUCCESS)) { return(GetRerollResult(RollResult.CRIT_SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } } else //fail { if (off + i <= def - 10) { if (saveBoost.HasFlag(SaveIncrease.CRIT_FAIL_IS_FAIL)) { return(GetRerollResult(RollResult.FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.CRIT_FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } else //crit { if (saveBoost.HasFlag(SaveIncrease.FAIL_IS_SUCCESS)) { return(GetRerollResult(RollResult.SUCCESS, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } else { return(GetRerollResult(RollResult.FAIL, off, def, i, saveBoost, monsterSaveBoost, ref maxMiss, ref minCrit)); } } } }