diff --git a/HouseRules.Essentials/AbilityTargetEffectsOverriddenRule.cs b/HouseRules.Essentials/AbilityTargetEffectsOverriddenRule.cs new file mode 100644 index 00000000..c90c062c --- /dev/null +++ b/HouseRules.Essentials/AbilityTargetEffectsOverriddenRule.cs @@ -0,0 +1,56 @@ +namespace HouseRules.Essentials.Rules +{ + using System.Collections.Generic; + using System.Linq; + using DataKeys; + using HouseRules.Core.Types; + + public sealed class AbilityTargetEffectsOverriddenRule : Rule, IConfigWritable>>, IMultiplayerSafe + { + public override string Description => "Some abilities have added secondary effects."; + + private readonly Dictionary> _adjustments; + private Dictionary> _originals; + + /// + /// Initializes a new instance of the class. + /// + /// Key-value pairs of abilityKey and List. + public AbilityTargetEffectsOverriddenRule(Dictionary> adjustments) + { + _adjustments = adjustments; + _originals = new Dictionary>(); + } + + public Dictionary> GetConfigObject() => _adjustments; + + protected override void OnPreGameCreated(Context context) + { + _originals = ReplaceAbilities(context, _adjustments); + } + + protected override void OnDeactivate(Context context) + { + ReplaceAbilities(context, _originals); + } + + private static Dictionary> ReplaceAbilities(Context context, Dictionary> replacements) + { + var originals = new Dictionary>(); + foreach (var replacement in replacements) + { + var abilityPromise = context.AbilityFactory.LoadAbility(replacement.Key); + abilityPromise.OnLoaded(ability => + { + originals[replacement.Key] = ability.targetEffects.ToList(); + ability.targetEffects = replacement.Value.ToArray(); + }); + } + + // Theoretically, there can be a race condition as there's no guarantee the promise above is fulfilled by + // the return value is used. Realistically, there's no concern since the value isn't used until after the + // promise has long been fulfilled. + return originals; + } + } +} diff --git a/HouseRules.Essentials/HouseRulesEssentialsBase.cs b/HouseRules.Essentials/HouseRulesEssentialsBase.cs index b88dce9e..87b38cfb 100644 --- a/HouseRules.Essentials/HouseRulesEssentialsBase.cs +++ b/HouseRules.Essentials/HouseRulesEssentialsBase.cs @@ -60,6 +60,7 @@ private static void RegisterRuleTypes() HR.Rulebook.Register(typeof(AbilityActionCostAdjustedRule)); HR.Rulebook.Register(typeof(AbilityRandomPieceListRule)); HR.Rulebook.Register(typeof(AbilityStealthDamageOverriddenRule)); + HR.Rulebook.Register(typeof(AbilityTargetEffectsOverriddenRule)); HR.Rulebook.Register(typeof(ApplyEffectOnHitAdjustedRule)); HR.Rulebook.Register(typeof(BackstabConfigOverriddenRule)); HR.Rulebook.Register(typeof(CourageShantyAddsHpRule)); diff --git a/HouseRules.Essentials/README.md b/HouseRules.Essentials/README.md index 56518225..e5a27ac2 100644 --- a/HouseRules.Essentials/README.md +++ b/HouseRules.Essentials/README.md @@ -189,6 +189,23 @@ The [Settings Reference](../docs/SettingsReference.md) contains lists of all dif }, ``` + #### __AbilityTargetEffectsAdjusted__: Replaces the list of addition effects to the selected abilities + - REPLACES the list of addition effects for the selected abilities. You may manually include the original effect if desired. + - To configure: + - Specify the [AbilityKey](../docs/SettingsReference.md#abilitykeys) of the ability to modify. + - Specify the list of [EffectStates](../docs/SettingsReference.md#effectstatetypes) that the ability should apply. + + ###### _Example JSON config for AbilityTargetEffectsAdjusted_ + + ```json + { + "Rule": "AbilityTargetEffectsAdjusted", + "Config": { + "Javelin": [ "Weaken1Turn" ], + "WarCry": [ "Panic", "Blinded" ] + } + ``` + #### __ApplyEffectOnHitAdjusted__: Adjusts the effect that a ♟️BoardPiece has on attackers. - For example, you can make Barricades inspire Panic on enemies that hit it. - To be useful the effect has to last at least 2 rounds.