public static SpellConcentrationLogic Create(ContextDurationValue duration = null)
        {
            var s = Helpers.Create <SpellConcentrationLogic>();

            s.Duration = duration;
            return(s);
        }
        private static List <BlueprintFeature> AddWarriorSpirit()
        {
            BlueprintItemEnchantment[] defaultEnchantments = new BlueprintItemEnchantment[]
            {
                library.Get <BlueprintItemEnchantment>("d704f90f54f813043a525f304f6c0050"),
                library.Get <BlueprintItemEnchantment>("9e9bab3020ec5f64499e007880b37e52"),
                library.Get <BlueprintItemEnchantment>("d072b841ba0668846adeb007f623bd6c"),
                library.Get <BlueprintItemEnchantment>("6a6a0901d799ceb49b33d4851ff72132"),
                library.Get <BlueprintItemEnchantment>("746ee366e50611146821d61e391edf16")
            };

            BlueprintActivatableAbility[] MagusFacts = new BlueprintActivatableAbility[]
            {
                library.Get <BlueprintActivatableAbility>("05b7cbe45b1444a4f8bf4570fb2c0208"),
                library.Get <BlueprintActivatableAbility>("b338e43a8f81a2f43a73a4ae676353a5"),
                library.Get <BlueprintActivatableAbility>("a3a9e9a2f909cd74e9aee7788a7ec0c6"),
                library.Get <BlueprintActivatableAbility>("24fe1f546e07987418557837b0e0f8f5"),
                library.Get <BlueprintActivatableAbility>("85742dd6788c6914f96ddc4628b23932")
            };
            BlueprintActivatableAbility[] facts = new BlueprintActivatableAbility[MagusFacts.Length];

            for (int i = 0; i < MagusFacts.Length; i++)
            {
                BlueprintActivatableAbility magusAbility = MagusFacts[i];
                BlueprintActivatableAbility temp         = library.CopyAndAdd(magusAbility, magusAbility.Name, Helpers.getGuid(magusAbility.AssetGuid + "WarriorSpirit"));
                temp.AddComponent(Helpers.Create <ActivatableAbilityGroupSizeRestriction>(x =>
                {
                    x.EnchantPool        = EnchantPoolType.ArcanePool;
                    x.ActivatableAbility = temp;
                }));
                facts[i] = temp;
            }

            ContextDurationValue contextDurationValue = Helpers.CreateContextDuration(rate: DurationRate.Minutes, bonus: 1);

            BlueprintAbility         arcaneWeaponSwitchAbility = library.Get <BlueprintAbility>("3c89dfc82c2a3f646808ea250eb91b91");
            BlueprintAbilityResource arcanePoolResourse        = library.Get <BlueprintAbilityResource>("effc3e386331f864e9e06d19dc218b37");


            var divineFavor = library.Get <BlueprintAbility>("9d5d2d3ffdd73c648af3eb3e585b1113");

            List <BlueprintFeature> features = new List <BlueprintFeature>();

            foreach (var weaponTraining in _weaponTrainingBluePrints)
            {
                string weaponTrainingName        = getWeaponTrainingName(weaponTraining, true);
                string weaponTrainingDisplayName = getWeaponTrainingName(weaponTraining);

                BlueprintAbilityResource resource = Helpers.Create <WarriorSpiritPoolLogic>(x => x.WeaponTraining = weaponTraining);
                resource.name                 = "WarriorSpiritResource" + weaponTrainingName;
                resource.LocalizedName        = Helpers.CreateString("WarriorSpiritResource.Name", "Warrior Spirit Resource (" + weaponTrainingDisplayName + ")");
                resource.LocalizedDescription = Helpers.CreateString("WarriorSpiritResource.Name", "Each day, he designates one such weapon and gains a number of points of spiritual energy equal to 1 + his weapon training bonus.");
                resource.SetIcon(arcaneWeaponSwitchAbility.Icon);

                Traverse traverseOne = Traverse.Create(arcanePoolResourse);
                Traverse traverseTwo = Traverse.Create(resource);
                traverseTwo.Field("m_MaxAmount").SetValue(traverseOne.Field("m_MaxAmount").GetValue());

                Main.library.AddAsset(resource, Helpers.getGuid("WarriorSpiritResource" + weaponTrainingName));

                ContextActionWeaponEnchantPoolWarriorSpirit contextActionWeaponEnchantPool = Helpers.Create <ContextActionWeaponEnchantPoolWarriorSpirit>();
                contextActionWeaponEnchantPool.DurationValue       = contextDurationValue;
                contextActionWeaponEnchantPool.EnchantPool         = EnchantPoolType.ArcanePool;
                contextActionWeaponEnchantPool.Group               = ActivatableAbilityGroup.ArcaneWeaponProperty;
                contextActionWeaponEnchantPool.DefaultEnchantments = defaultEnchantments;
                contextActionWeaponEnchantPool.Feature             = weaponTraining;


                BlueprintAbility warriorSpiritSwitchAbility = Helpers.CreateAbility(
                    "WarriorSpiritSwitchAbility" + weaponTrainingName,
                    "Warrior Spirit " + getWeaponTrainingName(weaponTraining),
                    "The fighter can forge a spiritual bond with a weapon that belongs to the associated weapon group, allowing him to unlock the weapon’s potential. Each day, he designates one such weapon and gains a number of points of spiritual energy equal to 1 + his weapon training bonus. While wielding this weapon, he can spend 1 point of spiritual energy to grant the weapon an enhancement bonus equal to his weapon training bonus. Enhancement bonuses gained by this advanced weapon training option stack with those of the weapon, to a maximum of +5. The fighter can also imbue the weapon with any one weapon special ability with an equivalent enhancement bonus less than or equal to his maximum bonus by reducing the granted enhancement bonus by the amount of the equivalent enhancement bonus. The item must have an enhancement bonus of at least +1 (from the item itself or from warrior spirit) to gain a weapon special ability. In either case, these bonuses last for 1 minute.",
                    Helpers.getGuid("WarriorSpiritSwitchAbility" + weaponTrainingName),
                    arcaneWeaponSwitchAbility.Icon,
                    AbilityType.Supernatural,
                    arcaneWeaponSwitchAbility.ActionType,
                    arcaneWeaponSwitchAbility.Range,
                    "1 min",
                    arcaneWeaponSwitchAbility.LocalizedSavingThrow,
                    divineFavor.GetComponent <AbilitySpawnFx>(), // TODO!!!!!
                    Helpers.CreateContextRankConfig(
                        ContextRankBaseValueType.FeatureRank,
                        ContextRankProgression.AsIs,
                        AbilityRankType.Default,
                        feature: weaponTraining),
                    Helpers.CreateRunActions(contextActionWeaponEnchantPool),
                    Helpers.Create <AbilityResourceLogic>(x =>
                {
                    x.Amount           = 1;
                    x.RequiredResource = resource;
                    x.IsSpendResource  = true;
                    x.CostIsCustom     = false;
                })
                    );

                features.Add(Helpers.CreateFeature(
                                 "WarriorSpiritFeature" + weaponTrainingName,
                                 "Warrior Spirit (" + weaponTrainingDisplayName + ")",
                                 "The fighter can forge a spiritual bond with a weapon that belongs to the associated weapon group, allowing him to unlock the weapon’s potential. Each day, he designates one such weapon and gains a number of points of spiritual energy equal to 1 + his weapon training bonus. While wielding this weapon, he can spend 1 point of spiritual energy to grant the weapon an enhancement bonus equal to his weapon training bonus. Enhancement bonuses gained by this advanced weapon training option stack with those of the weapon, to a maximum of +5. The fighter can also imbue the weapon with any one weapon special ability with an equivalent enhancement bonus less than or equal to his maximum bonus by reducing the granted enhancement bonus by the amount of the equivalent enhancement bonus. The item must have an enhancement bonus of at least +1 (from the item itself or from warrior spirit) to gain a weapon special ability. In either case, these bonuses last for 1 minute.",
                                 Helpers.getGuid("WarriorSpiritFeature" + weaponTrainingName),
                                 arcaneWeaponSwitchAbility.Icon,
                                 FeatureGroup.CombatFeat,
                                 warriorSpiritSwitchAbility.CreateAddFact(),
                                 resource.CreateAddAbilityResource(),
                                 Helpers.CreateAddFacts(facts),
                                 weaponTraining.PrerequisiteFeature(),
                                 Helpers.Create <IncreaseActivatableAbilityGroupSizeBaseOnFeatureRanks>(x =>
                {
                    x.Group   = ActivatableAbilityGroup.ArcaneWeaponProperty;
                    x.Feature = weaponTraining;
                })
                                 ));
            }

            return(features);
        }
        static (BlueprintFeature, BlueprintFeature, BlueprintAbility, BlueprintBuff) createStunningFistVariant(string name, string display_name, string description, BlueprintBuff buff, ContextDurationValue duration, int level)
        {
            var stunning_fist_ability = library.Get <BlueprintAbility>("732ae7773baf15447a6737ae6547fc1e");
            var stunning_fist_buff    = library.Get <BlueprintBuff>("d9eaeba5690a7704da8bbf626456a50e");

            var new_buff = library.CopyAndAdd(stunning_fist_buff, name + "OwnerBuff", "");

            new_buff.SetNameDescriptionIcon(display_name, description, buff.Icon);

            var old_stunned = library.Get <BlueprintBuff>("09d39b38bb7c6014394b6daced9bacd3");

            foreach (var attack_trigger in new_buff.GetComponents <AddInitiatorAttackWithWeaponTrigger>().ToArray())
            {
                var actionst = attack_trigger.Action.Actions;
                actionst = Common.changeAction <ContextActionApplyBuff>(actionst, c =>
                {
                    if (c.Buff == old_stunned)
                    {
                        c.Buff = buff;
                        if (duration == null)
                        {
                            c.Permanent = true;
                        }
                        else
                        {
                            c.DurationValue = duration;
                        }
                    }
                }
                                                                        );
                actionst = Common.changeAction <ContextActionRemoveBuff>(actionst, c =>
                {
                    c.Buff = new_buff;
                }
                                                                         );
                new_buff.ReplaceComponent(attack_trigger, attack_trigger.CreateCopy(a => a.Action = Helpers.CreateActionList(actionst)));
            }

            var new_ability = library.CopyAndAdd(stunning_fist_ability, name + "Ability", "");

            new_ability.SetNameDescriptionIcon(new_buff);
            new_ability.GetComponent <AbilityCasterHasNoFacts>().Facts = new_ability.GetComponent <AbilityCasterHasNoFacts>().Facts.AddToArray(new_buff);

            var actions = new_ability.GetComponent <AbilityEffectRunAction>().Actions.Actions;

            actions = Common.changeAction <ContextActionApplyBuff>(actions, c => c.Buff = new_buff);

            new_ability.ReplaceComponent <AbilityEffectRunAction>(a => a.Actions = Helpers.CreateActionList(actions));
            new_ability.ReplaceComponent <SpellDescriptorComponent>(buff.GetComponent <SpellDescriptorComponent>());

            var feature_monk = Common.AbilityToFeature(new_ability, false);

            feature_monk.AddComponent(Helpers.Create <ReplaceAbilityDC>(r => { r.Ability = new_ability; r.Stat = StatType.Wisdom; }));
            var scaled_fist_feature = library.CopyAndAdd <BlueprintFeature>(feature_monk, "ScaledFist" + feature_monk.name, "");

            scaled_fist_feature.ReplaceComponent <ReplaceAbilityDC>(r => r.Stat = StatType.Charisma);

            var monk_progression = library.Get <BlueprintProgression>("8a91753b978e3b34b9425419179aafd6");
            var scaled_fist      = library.Get <BlueprintArchetype>("5868fc82eb11a4244926363983897279");


            foreach (var le in monk_progression.LevelEntries)
            {
                if (le.Level == level)
                {
                    le.Features.Add(feature_monk);
                }
            }
            bool processed = false;

            foreach (var le in scaled_fist.RemoveFeatures)
            {
                if (le.Level == level)
                {
                    le.Features.Add(feature_monk);
                    processed = true;
                    break;
                }
            }
            if (!processed)
            {
                scaled_fist.RemoveFeatures = scaled_fist.RemoveFeatures.AddToArray(Helpers.LevelEntry(level, feature_monk));
            }

            processed = false;
            foreach (var le in scaled_fist.AddFeatures)
            {
                if (le.Level == level)
                {
                    le.Features.Add(scaled_fist_feature);
                    processed = true;
                    break;
                }
            }
            if (!processed)
            {
                scaled_fist.AddFeatures = scaled_fist.AddFeatures.AddToArray(Helpers.LevelEntry(level, feature_monk));
            }

            monk_progression.UIGroups[9].Features.Add(scaled_fist_feature);
            monk_progression.UIGroups[9].Features.Add(feature_monk);

            return(feature_monk, scaled_fist_feature, new_ability, new_buff);
        }