public void OnEventDidTrigger(RuleRollD20 evt) { if (evt.RerollsAmount > 0) { Log.Write($"Persistent spell: reroll {evt.Result}."); } }
public override void OnEventAboutToTrigger(RuleRollD20 evt) { Log.Write("ModifyD20AndSpendResource: RuleRollD20 about to trigger"); var previous = Rulebook.CurrentContext.PreviousEvent; if (Rule == RuleType.SavingThrow) { var rule = previous as RuleSavingThrow; if (rule == null) { return; } // Ensure saving throws get their stat bonus. var modValue = Owner.Stats.GetStat(rule.StatType); var statValue = (modValue as ModifiableValueAttributeStat)?.Bonus ?? modValue.ModifiedValue; if (!rule.IsSuccessRoll(evt.PreRollDice(), statValue - rule.StatValue)) { evt.SetReroll(1, TakeBest); } } else if (Rule == RuleType.SpellResistance) { var rule = previous as RuleSpellResistanceCheck; if (rule == null) { return; } var isSpellResisted = !rule.Initiator.Descriptor.State.Features.PrimalMagicEssence && (rule.SpellResistance > rule.SpellPenetration + evt.PreRollDice()); if (isSpellResisted) { evt.SetReroll(1, TakeBest); } } else { base.OnEventAboutToTrigger(evt); } if (evt.RerollsAmount > 0) { Log.Write($"ModifyD20AndSpendResource: reroll for {Rule}, preroll was {evt.PreRollDice()}"); Owner.Resources.Spend(RequiredResource, 1); if (Owner.Resources.GetResourceAmount(RequiredResource) == 0) { (Fact as Buff)?.Remove(); } } else { Log.Write($"ModifyD20AndSpendResource: no reroll needed for {Rule}"); } }
static bool Prefix(RuleRollD20 __instance, ref int?___m_PreRolledResult, ref int __result) { int?preRolledResult = ___m_PreRolledResult; int val1 = !preRolledResult.HasValue ? RulebookEvent.Dice.D20 : preRolledResult.Value; for (int rerollsAmount = __instance.RerollsAmount; rerollsAmount > 0; --rerollsAmount) { int old_value = val1; int new_value = RulebookEvent.Dice.D20; val1 = !__instance.TakeBest ? Math.Min(val1, new_value) : Math.Max(val1, new_value); Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value} >> {new_value}, retains {(__instance.TakeBest ? "best" : "worst")})"); } __result = val1; return(false); }
static bool Prefix(RuleRollD20 __instance, ref int?___m_PreRolledResult, ref int __result) { int?preRolledResult = ___m_PreRolledResult; int val1 = !preRolledResult.HasValue ? RulebookEvent.Dice.D20 : preRolledResult.Value; int rerollsAmount = __instance.RerollsAmount; if (__instance.TakeBest && rerollsAmount > 0 && (__instance.Initiator.Get <ExtraTakeBestRerollUnitPart>()?.active()).GetValueOrDefault()) { rerollsAmount++; } if (!__instance.TakeBest && rerollsAmount > 0 && (__instance.Initiator.Get <IgnoreTakeWorstRerollsUnitPart>()?.active()).GetValueOrDefault()) { rerollsAmount = 0; } List <int> rerolls_history = new List <int>() { val1 }; for (; rerollsAmount > 0; --rerollsAmount) { int old_value = val1; int new_value = RulebookEvent.Dice.D20; rerolls_history.Add(new_value); val1 = !__instance.TakeBest ? Math.Min(val1, new_value) : Math.Max(val1, new_value); Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value} >> {new_value}, retains {(__instance.TakeBest ? "best" : "worst")})"); } if (!__instance.TakeBest && rerolls_history.Count > 1 && (__instance.Initiator.Get <ExtraGoodRerollOnTakeWorstUnitPart>()?.active()).GetValueOrDefault()) { int old_value = val1; int new_value = RulebookEvent.Dice.D20; rerolls_history.Add(new_value); rerolls_history.Sort(); int retained_value = rerolls_history[1]; val1 = retained_value; Common.AddBattleLogMessage(__instance.Initiator.CharacterName + " rerolls: " + $"({old_value} >> {new_value}, retains {retained_value})"); } __result = val1; return(false); }
public void OnEventAboutToTrigger(RuleRollD20 evt) { try { var rule = Rulebook.CurrentContext.PreviousEvent as RuleSavingThrow; if (rule == null) { return; } var context = rule.Reason.Context?.SourceAbilityContext; if (context?.Caster != Owner.Unit || !context.HasMetamagic((Metamagic)ModMetamagic.Persistent) || context.AbilityBlueprint.Type != AbilityType.Spell) { return; } // Note: RuleSavingThrow rolls the D20 before setting the stat bonus, so we need to pass it in. // (The game's ModifyD20 component has a bug because of this.) var modValue = Owner.Stats.GetStat(rule.StatType); var statValue = (modValue as ModifiableValueAttributeStat)?.Bonus ?? modValue.ModifiedValue; int roll = evt.PreRollDice(); if (rule.IsSuccessRoll(roll, statValue - rule.StatValue)) { Log.Write($"Persistent spell ({context}): roll {roll} passed, force reroll."); evt.SetReroll(1, false); } else { Log.Write($"Persistent spell ({context}): roll {roll} failed, not rerolling."); } } catch (Exception e) { Log.Error(e); } }