static void createDivineBond()
        {
            var loh_resource = library.Get <BlueprintAbilityResource>("9dedf41d995ff4446a181f143c3db98c");
            var resource     = Helpers.CreateAbilityResource("SacredServantDivineBondResource", "", "", "", null);

            resource.SetIncreasedByLevelStartPlusDivStep(1, 9, 1, 4, 1, 0, 0.0f, new BlueprintCharacterClass[] { archetype.GetParentClass() });
            divine_bond_buff = Helpers.CreateBuff("SacredServantDivineBondBuff",
                                                  "Divine Bond",
                                                  "At 5th level, instead of forming a divine bond with her weapon or a mount, a sacred servant forms a bond with her holy symbol.\n"
                                                  + "At 5th level, the spirit grants one bonus. For every three levels beyond 5th, the spirit grants one additional bonus. These bonuses can be spent in a number of ways to grant the paladin enhanced abilities to channel positive energy and to cast spells.\n"
                                                  + "Each bonus can be used to grant one of the following enhancements:\n"
                                                  + "+1 caster level to any paladin spell cast,\n"
                                                  + "+1 to the DC to halve the damage of channel positive energy when used to harm undead,\n"
                                                  + "+1d6 to channel positive energy,\n"
                                                  + "restore one use/day of lay on hands.\n"
                                                  + "These enhancements stack and can be selected multiple times. The enhancements granted by the spirit are determined when the spirit is called and cannot be changed until the spirit is called again. If the sacred servant increases her number of uses of lay on hands per day in this way, that choice is set for the rest of the day, and once used, these additional uses are not restored (even if the spirit is called again that day). The celestial spirit imparts no enhancements if the holy symbol is held by anyone other than the sacred servant, but resumes giving enhancements if returned to the sacred servant. A sacred servant can use this ability once per day at 5th level, and one additional time per day for every four levels beyond 5th, to a total of four times per day at 17th level.",
                                                  "",
                                                  LoadIcons.Image2Sprite.Create(@"AbilityIcons/Wish.png"),
                                                  null);

            divine_bond_ability = library.CopyAndAdd <BlueprintAbility>("7ff088ab58c69854b82ea95c2b0e35b4", "SacredServantDivineBondAbility", "");
            divine_bond_ability.SetNameDescriptionIcon(divine_bond_buff);
            var apply_buff = Common.createContextActionApplyBuff(divine_bond_buff, Helpers.CreateContextDuration(Helpers.CreateContextValue(AbilityRankType.Default), DurationRate.Minutes), dispellable: false);

            divine_bond_ability.ReplaceComponent <AbilityResourceLogic>(a => a.RequiredResource = resource);
            divine_bond_ability.ReplaceComponent <AbilityEffectRunAction>(a => a.Actions        = Helpers.CreateActionList(apply_buff,
                                                                                                                           Helpers.Create <ResourceMechanics.RestoreResourceAmountEqualToRemainingGroupSize>(r => { r.resource = loh_resource; r.group = ActivatableAbilityGroup.DivineWeaponProperty; }))
                                                                          );
            divine_bond_ability.setMiscAbilityParametersSelfOnly();

            var cl_icon           = Helpers.GetIcon("1bc83efec9f8c4b42a46162d72cbf494"); //burst of glory
            var channel_dice_icon = Helpers.GetIcon("0d657aa811b310e4bbd8586e60156a2d"); //cure critical wounds
            var channel_dc_icon   = Helpers.GetIcon("a9a52760290591844a96d0109e30e04d"); //undeath to death

            var cl_bonuses           = new BlueprintActivatableAbility[6];
            var channel_dc_bonuses   = new BlueprintActivatableAbility[6];
            var channel_dice_bonuses = new BlueprintActivatableAbility[6];



            cl_bonuses = createSacredBondAbility("SacredServantDivineBondCLBonus",
                                                 "Caster Level Bonus",
                                                 divine_bond_buff.Description,
                                                 cl_icon,
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 1; }),
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 2; }),
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 3; }),
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 4; }),
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 5; }),
                                                 Helpers.Create <NewMechanics.IncreaseAllSpellsCLForSpecificSpellbook>(cl => { cl.spellbook = archetype.GetParentClass().Spellbook; cl.Value = 6; })
                                                 );

            var channels = ChannelEnergyEngine.getChannelAbilities(e => e.scalesWithClass(archetype.GetParentClass())).ToArray();

            channel_dc_bonuses = createSacredBondAbility("SacredServantDivineBondChannelDCBonus",
                                                         "Channel Energy DC Bonus",
                                                         divine_bond_buff.Description,
                                                         channel_dc_icon,
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 1; }),
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 2; }),
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 3; }),
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 4; }),
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 5; }),
                                                         Helpers.Create <NewMechanics.ContextIncreaseAbilitiesDC>(c => { c.abilities = channels; c.Value = 6; })
                                                         );

            channel_dice_bonuses = createSacredBondAbility("SacredServantDivineBondChannelDiceBonus",
                                                           "Channel Energy Dice Bonus",
                                                           divine_bond_buff.Description,
                                                           channel_dice_icon,
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 2; }),
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 4; }),
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 6; }),
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 8; }),
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 10; }),
                                                           Helpers.Create <NewMechanics.ContextIncreaseCasterLevelForSelectedSpells>(c => { c.spells = channels; c.value = 12; })
                                                           );

            for (int i = 0; i < 6; i++)
            {
                divine_bond[i] = Helpers.CreateFeature($"SacredServantDivineBond{i+1}Feature",
                                                       divine_bond_ability.Name,
                                                       divine_bond_ability.Description,
                                                       "",
                                                       divine_bond_ability.Icon,
                                                       FeatureGroup.None);
                if (i == 0)
                {
                    divine_bond[i].AddComponent(resource.CreateAddAbilityResource());
                    divine_bond[i].AddComponent(Helpers.CreateAddFact(divine_bond_ability));
                }
                else
                {
                    divine_bond[i].AddComponent(Common.createIncreaseActivatableAbilityGroupSize(ActivatableAbilityGroup.DivineWeaponProperty));
                }
                divine_bond[i].AddComponent(Helpers.CreateAddFacts(cl_bonuses[i], channel_dc_bonuses[i], channel_dice_bonuses[i]));
            }
        }
        static void createPhantom(string name, string display_name, string descripton, UnityEngine.Sprite icon,
                                  BlueprintArchetype archetype,
                                  BlueprintFeature feature1, BlueprintFeature feature7, BlueprintFeature feature12, BlueprintFeature feature17,
                                  StatType[] skills, int str_value, int dex_value,
                                  BlueprintAbility[] spell_like_abilities,
                                  BlueprintFeature exciter_feature1 = null, BlueprintFeature exciter_feature2 = null
                                  )
        {
            var ghost_fx = library.Get <BlueprintBuff>("20f79fea035330b479fc899fa201d232");

            var natural_armor2 = library.Get <BlueprintUnitFact>("45a52ce762f637f4c80cc741c91f58b7");
            var spectre        = library.Get <BlueprintUnit>("2f91d7337b60e3b4b9b137198a8c8745");
            var unit           = library.CopyAndAdd <BlueprintUnit>(spectre, name + "PhantomUnit", "");


            unit.Alignment                     = Alignment.TrueNeutral;
            unit.Strength                      = str_value;
            unit.Dexterity                     = dex_value;
            unit.Constitution                  = 13;
            unit.Intelligence                  = 7;
            unit.Wisdom                        = 10;
            unit.Charisma                      = 13;
            unit.Speed                         = 30.Feet();
            unit.AddFacts                      = new BlueprintUnitFact[] { natural_armor2, ghost_fx };
            unit.Body                          = unit.Body.CloneObject();
            unit.Body.EmptyHandWeapon          = library.Get <BlueprintItemWeapon>("767e6932882a99c4b8ca95c88d823137");
            unit.Body.PrimaryHand              = null;
            unit.Body.SecondaryHand            = null;
            unit.Body.AdditionalLimbs          = new BlueprintItemWeapon[0];
            unit.Body.AdditionalSecondaryLimbs = new BlueprintItemWeapon[0];
            unit.Body.DisableHands             = false;
            unit.ReplaceComponent <AddClassLevels>(a =>
            {
                a.DoNotApplyAutomatically = true;
                a.Levels         = 0;
                a.Archetypes     = new BlueprintArchetype[] { archetype };
                a.CharacterClass = phantom_class;
                a.Skills         = new StatType[] { StatType.SkillAthletics, StatType.SkillMobility, StatType.SkillStealth, StatType.SkillPersuasion, StatType.SkillKnowledgeArcana }.RemoveFromArray(skills[0]).RemoveFromArray(skills[1]);
                a.Selections     = new SelectionEntry[0];
            });
            Helpers.SetField(unit, "m_Portrait", phantom_portrait);
            unit.AddComponents(Helpers.Create <Eidolon.EidolonComponent>());
            unit.AddComponents(Helpers.Create <AllowDyingCondition>());
            unit.AddComponents(Helpers.Create <AddResurrectOnRest>());
            unit.LocalizedName        = unit.LocalizedName.CreateCopy();
            unit.LocalizedName.String = Helpers.CreateString(unit.name + ".Name", display_name + " Phantom");
            unit.RemoveComponents <Experience>();
            unit.RemoveComponents <AddTags>();
            unit.Brain                        = library.Get <BlueprintBrain>("cf986dd7ba9d4ec46ad8a3a0406d02ae");   //character brain
            unit.Faction                      = library.Get <BlueprintFaction>("d8de50cc80eb4dc409a983991e0b77ad"); //neutrals
            unit.Visual                       = library.Get <BlueprintUnit>("8a6986e17799d7d4b90f0c158b31c5b9").Visual.CloneObject();
            unit.Visual.BloodType             = Kingmaker.Visual.HitSystem.BloodType.BlackUndead;
            unit.Visual.FootstepSoundSizeType = Kingmaker.Visual.Sound.FootstepSoundSizeType.Ghost;
            unit.Visual.Barks                 = spectre.Visual.Barks;
            unit.Race = null;
            var pain_unit = library.CopyAndAdd(unit, "Pain" + unit.name, "");

            pain_unit.ReplaceComponent <AddClassLevels>(a => a.Archetypes = new BlueprintArchetype[] { pain_phantom_archetype_map[archetype] });

            var progression = Helpers.CreateProgression(name + "PhantomProgression",
                                                        "Emotion Focus: " + display_name,
                                                        descripton,
                                                        "",
                                                        icon,
                                                        FeatureGroup.AnimalCompanion,
                                                        library.Get <BlueprintFeature>("126712ef923ab204983d6f107629c895").ComponentsArray
                                                        );

            progression.IsClassFeature   = true;
            progression.ReapplyOnLevelUp = true;
            progression.Classes          = new BlueprintCharacterClass[] { Spiritualist.spiritualist_class };
            progression.ReplaceComponent <AddPet>(a => a.Pet = unit);

            var feature1_s  = Common.createAddFeatToAnimalCompanion(feature1, "");
            var feature7_s  = Common.createAddFeatToAnimalCompanion(feature7, "");
            var feature12_s = Common.createAddFeatToAnimalCompanion(feature12, "");
            var feature17_s = Common.createAddFeatToAnimalCompanion(feature17, "");


            BlueprintFeature[] spell_likes = new BlueprintFeature[spell_like_abilities.Length];

            for (int i = 0; i < spell_like_abilities.Length; i++)
            {
                var resource = Helpers.CreateAbilityResource(name + spell_like_abilities[i].name + "Resource", "", "", "", null);
                resource.SetIncreasedByLevelStartPlusDivStep(0, i == 3 ? 16 : 5 + i * 2, 1, 4, 1, 0, 0.0f, Spiritualist.getSpiritualistArray());

                BlueprintAbility ability          = null;
                BlueprintAbility ability_charisma = null;
                if (!spell_like_abilities[i].HasVariants)
                {
                    ability = Common.convertToSpellLike(spell_like_abilities[i], name, Spiritualist.getSpiritualistArray(), StatType.Wisdom,
                                                        resource);
                    ability_charisma = Common.convertToSpellLike(spell_like_abilities[i], "Charisma" + name, Spiritualist.getSpiritualistArray(), StatType.Charisma,
                                                                 resource);
                }
                else
                {
                    List <BlueprintAbility> variants          = new List <BlueprintAbility>();
                    List <BlueprintAbility> variants_charisma = new List <BlueprintAbility>();
                    foreach (var v in spell_like_abilities[i].Variants)
                    {
                        var a = Common.convertToSpellLike(v, name, Spiritualist.getSpiritualistArray(), StatType.Wisdom,
                                                          resource);
                        variants.Add(a);

                        var a_charisma = Common.convertToSpellLike(v, "Charisma" + name, Spiritualist.getSpiritualistArray(), StatType.Charisma,
                                                                   resource);
                        variants_charisma.Add(a_charisma);
                    }

                    ability = Common.createVariantWrapper(name + spell_like_abilities[i].name, "", variants.ToArray());
                    ability.SetNameDescriptionIcon(spell_like_abilities[i]);

                    ability_charisma = Common.createVariantWrapper("Charisma" + name + spell_like_abilities[i].name, "", variants_charisma.ToArray());
                    ability_charisma.SetNameDescriptionIcon(spell_like_abilities[i]);
                }
                spell_likes[i] = Common.AbilityToFeature(ability, false);
                spell_likes[i].SetComponents(Common.createAddFeatureIfHasFact(Spiritualist.charisma_spellcasting, ability, not: true),
                                             Common.createAddFeatureIfHasFact(Spiritualist.charisma_spellcasting, ability_charisma)
                                             );
                spell_likes[i].AddComponent(resource.CreateAddAbilityResource());
                spell_likes[i].SetNameDescription("Emotional Power: " + spell_likes[i].Name,
                                                  "A spiritualist gains a number of spell-like abilities, which are tied to her phantom’s emotional focus. She gains one spell-like ability at 5th level, a second at 7th level, a third at 9th level, and a fourth at 16th level. A spiritualist can use each of these abilities once per day, plus one additional time per day for every 4 spiritualist levels she possesses beyond the level at which she gained the spell-like ability. The saving throw DCs for these spell-like abilities are equal to 10 + 1/2 spiritualist class level + Wisdom modifier, rather than being based on the spell’s level.\n"
                                                  + spell_like_abilities[i].Name + ": " + spell_like_abilities[i].Description);
            }

            progression.LevelEntries = new LevelEntry[] { Helpers.LevelEntry(1, feature1_s),
                                                          Helpers.LevelEntry(5, spell_likes[0]),
                                                          Helpers.LevelEntry(7, feature7_s, spell_likes[1]),
                                                          Helpers.LevelEntry(9, spell_likes[2]),
                                                          Helpers.LevelEntry(12, feature12_s),
                                                          Helpers.LevelEntry(16, spell_likes[3]),
                                                          Helpers.LevelEntry(17, feature17_s) };
            progression.UIGroups = new UIGroup[] { Helpers.CreateUIGroup(feature1_s, feature7_s, feature12_s, feature17_s),
                                                   Helpers.CreateUIGroup(spell_likes) };

            var pain_progression = library.CopyAndAdd(progression, "Pain" + progression.name, "");

            pain_progression.ReplaceComponent <AddPet>(a => a.Pet = pain_unit);

            var capstone = Helpers.CreateFeature(name + "PotentPhantomFeature",
                                                 "Potent Phantom: " + display_name,
                                                 descripton,
                                                 "",
                                                 icon,
                                                 FeatureGroup.None,
                                                 Helpers.CreateAddFacts(feature1_s, feature7_s, feature12_s, feature17_s),
                                                 Helpers.PrerequisiteNoFeature(progression)
                                                 );

            phantom_progressions[name]      = progression;
            pain_phantom_progressions[name] = pain_progression;
            progression.AddComponent(Helpers.Create <NewMechanics.FeatureReplacement>(f => f.replacement_feature = pain_progression));
            potent_phantom[name] = capstone;

            phantom_skill_foci[name] = new List <BlueprintFeature>();
            var skill_foci = library.Get <BlueprintFeatureSelection>("c9629ef9eebb88b479b2fbc5e836656a").AllFeatures;

            for (int i = 0; i < skill_foci.Length; i++)
            {
                StatType stat = skill_foci[i].GetComponent <AddContextStatBonus>().Stat;
                if (skills.Contains(stat))
                {
                    phantom_skill_foci[name].Add(skill_foci[i]);
                }
            }


            if (exciter_feature1 == null)
            {
                return;
            }

            var exciter_progression = Helpers.CreateProgression(name + "ExciterProgression",
                                                                "Emotion Focus: " + display_name,
                                                                descripton,
                                                                "",
                                                                icon,
                                                                FeatureGroup.AnimalCompanion
                                                                );

            exciter_progression.Classes      = new BlueprintCharacterClass[] { Spiritualist.spiritualist_class };
            exciter_progression.LevelEntries = new LevelEntry[] { Helpers.LevelEntry(2, exciter_feature1),
                                                                  Helpers.LevelEntry(5, spell_likes[0]),
                                                                  Helpers.LevelEntry(7, exciter_feature2, spell_likes[1]),
                                                                  Helpers.LevelEntry(9, spell_likes[2]),
                                                                  Helpers.LevelEntry(16, spell_likes[3]) };
            exciter_progression.UIGroups = new UIGroup[] { Helpers.CreateUIGroup(exciter_feature1, exciter_feature2),
                                                           Helpers.CreateUIGroup(spell_likes) };
            exciter_progressions[name] = exciter_progression;


            var exciter_capstone = Helpers.CreateFeature(name + "ExciterPotentPhantomFeature",
                                                         "Potent Phantom: " + display_name,
                                                         descripton,
                                                         "",
                                                         icon,
                                                         FeatureGroup.None,
                                                         Helpers.CreateAddFacts(exciter_feature1, exciter_feature2),
                                                         Helpers.PrerequisiteNoFeature(exciter_progression)
                                                         );
        }