// Adds the Crossblooded Sorcerer archetype. internal static void Load() { var progressionClasses = new BlueprintCharacterClass[] { sorcererClass, dragonDiscipleClass }; var crossblooded = Helpers.Create <BlueprintArchetype>(a => { a.name = "CrossbloodedSorcererArchetype"; a.LocalizedName = Helpers.CreateString("Crossblooded.Name", RES.CrossbloodedSorcererLocalizedName_info); a.LocalizedDescription = Helpers.CreateString("Crossblooded.Description", RES.CrossbloodedSorcererLocalizedDescription_info); }); library.AddAsset(crossblooded, crossbloodedId); crossblooded.SetIcon(sorcererClass.Icon); crossblooded.ReplaceSpellbook = CreateReplacementSpellbook(); var bloodlineSelection = Helpers.bloodlineSelection; var bloodlines = bloodlineSelection.AllFeatures.Cast <BlueprintProgression>().ToList(); var sorcererFeatSelection = library.Get <BlueprintFeatureSelection>("3a60f0c0442acfb419b0c03b584e1394"); var powers = new SortedDictionary <int, SortedSet <BlueprintFeature> >(); var spells = new SortedDictionary <int, SortedSet <BlueprintFeature> >(); var powerLevels = new int[] { 1, 3, 9, 15, 20 }; var spellLevels = new int[] { 3, 5, 7, 9, 11, 13, 15, 17, 19 }; foreach (var level in powerLevels) { powers.Add(level, new SortedSet <BlueprintFeature>(BlueprintCompare.instance)); } foreach (var level in spellLevels) { spells.Add(level, new SortedSet <BlueprintFeature>(BlueprintCompare.instance)); } var crossbloodlines = new List <BlueprintProgression>(); foreach (var bloodline in bloodlines) { //Log.Write(bloodline); /*if(bloodline.AssetGuid=="a4cf06211879416ea82e10ca3062bb81") * { * break; * }*/ var levelLogic = CrossBloodlineLogic.TryCreate(bloodline); if (levelLogic == null) { continue; } var crossbloodline = library.CopyAndAdd(bloodline, $"{bloodline.name}Cross", bloodline.AssetGuid, "933224357f8d48be837a3083e33a18a8"); crossbloodline.SetName(String.Format(RES.CrossBloodlineName_info, bloodline.Name)); crossbloodline.LevelEntries = new LevelEntry[] { Helpers.LevelEntry(1, bloodline.GetLevelEntry(1).Features.Where(EldritchHeritage.IsArcanaOrClassSkill)) }; crossbloodline.Classes = progressionClasses; crossbloodline.Ranks = 1; crossbloodline.AddComponent(levelLogic); crossbloodlines.Add(crossbloodline); crossbloodForBloodline.Add(bloodline, crossbloodline); // Collect spells and abilities so we can build the choices for the main crossblooded progression. // (Note: we need to clone these, so we can change the prerequisites). foreach (var level in powerLevels) { var power = CreateBloodlinePower(bloodline, level, crossbloodline); powers[level].Add(power); } foreach (var level in spellLevels) { var spell = CreateBloodlineSpell(bloodline, level, crossbloodline); spells[level].Add(spell); } var Mutatepower = CreateMutateBloodlinePower(bloodline, 1, crossbloodline); powers[1].Add(Mutatepower); } //i commented beneath value to have it at least working FixBloodlinePrerequisites(crossblooded); crossbloodProgression = Helpers.CreateProgression("CrossbloodedProgression", crossblooded.Name, crossblooded.Description, "5f9f524c33ae4df780c54189ab9642b6", crossblooded.Icon, FeatureGroup.None); crossbloodProgression.Classes = progressionClasses; var entries = new List <LevelEntry>(); var powerGroup = new List <BlueprintFeatureBase>(); var spellGroup = new List <BlueprintFeatureBase>(); var allPowerChoices = new List <BlueprintFeature>(); //var allMutatedPowerChoices = new List<BlueprintFeature>(); var allSpellChoices = new List <BlueprintFeature>(); foreach (var level in new SortedSet <int>(powerLevels.Concat(spellLevels))) { var entry = Helpers.LevelEntry(level); entries.Add(entry); SortedSet <BlueprintFeature> powerChoices; if (powers.TryGetValue(level, out powerChoices)) { var description = RES.BloodlinePowerFeatureDescription_info; var powerSelection = Helpers.CreateFeatureSelection($"BloodlinePowerSelection{level}", RES.BloodlinePowerFeatureName_info, DescribeChoices(description, powerChoices), Helpers.MergeIds(guidsByLevel[level], "15029e64baee4db6b09ca6a6ed2d70c0"), null, FeatureGroup.None); allPowerChoices.AddRange(powerChoices); powerSelection.SetFeatures(allPowerChoices); powerGroup.Add(powerSelection); entry.Features.Add(powerSelection); } SortedSet <BlueprintFeature> spellChoices; if (spells.TryGetValue(level, out spellChoices)) { var description = RES.BloodlineSpellFeatureDescription_info; var spellSelection = Helpers.CreateFeatureSelection($"BloodlineSpellSelection{level}", RES.BloodlineSpellFeatureName_info, DescribeChoices(description, spellChoices), Helpers.MergeIds(guidsByLevel[level], "d333e2fb82ab4ab4af7d03d84aa5895c"), null, FeatureGroup.None); //spellSelection.HideInUI = true; allSpellChoices.AddRange(spellChoices); spellSelection.SetFeatures(allSpellChoices); spellGroup.Add(spellSelection); entry.Features.Add(spellSelection); } } crossbloodProgression.LevelEntries = entries.ToArray(); crossbloodProgression.UIGroups = new UIGroup[] { Helpers.CreateUIGroup(spellGroup), Helpers.CreateUIGroup(powerGroup) }; bloodlineChoice1 = Helpers.CreateFeatureSelection($"{bloodlineSelection.name}Cross1", bloodlineSelection.Name, bloodlineSelection.Description, "08cbfcda615f49218d3b118fc9322b81", bloodlineSelection.Icon, FeatureGroup.BloodLine); bloodlineChoice1.SetFeatures(crossbloodlines); bloodlineChoice2 = Helpers.CreateFeatureSelection($"{bloodlineSelection.name}Cross2", bloodlineSelection.Name, bloodlineSelection.Description, "ef595c20be9745b698e25e5a33b7d443", bloodlineSelection.Icon, FeatureGroup.BloodLine); bloodlineChoice2.SetFeatures(crossbloodlines); // var level1 = Helpers.LevelEntry(1, crossbloodProgression, Helpers.CreateFeature("CrossbloodedConflictingUrges", RES.CrossbloodedConflictingUrgesFeatureName_info, RES.CrossbloodedConflictingUrgesFeatureDescription_info, "ebefc29906f74c0d9a8b914095cc05d6", Helpers.GetIcon("983e8ad193160b44da80b38af4927e75"), // Diverse Training FeatureGroup.None, Helpers.CreateAddStatBonus(StatType.SaveWill, -2, ModifierDescriptor.Penalty)), bloodlineChoice1, bloodlineChoice2); crossblooded.RemoveFeatures = new LevelEntry[] { Helpers.LevelEntry(1, bloodlineSelection) }; crossblooded.AddFeatures = new LevelEntry[] { level1 }; crossblooded.BaseAttackBonus = sorcererClass.BaseAttackBonus; crossblooded.FortitudeSave = sorcererClass.FortitudeSave; crossblooded.ReflexSave = sorcererClass.ReflexSave; crossblooded.WillSave = sorcererClass.WillSave; Helpers.SetField(crossblooded, "m_ParentClass", sorcererClass); var archetypes = sorcererClass.Archetypes.ToList(); archetypes.Insert(0, crossblooded); sorcererClass.Archetypes = archetypes.ToArray(); //sorcererClass.Progression.LevelEntries; // Fix prestige class spellbook selection // TODO: find these automatically, or it won't be compatible with new prestige classes. FixSpellbookSelection(crossblooded, "ae04b7cdeb88b024b9fd3882cc7d3d76", "9ff7ad30e5a074346a40f80efda277c8", FeatureGroup.ArcaneTricksterSpellbook); FixSpellbookSelection(crossblooded, "8c1ba14c0b6dcdb439c56341385ee474", "fa2a2469c9ba6d54b8fc2356f4fc0e9e", FeatureGroup.DragonDiscipleSpellbook); FixSpellbookSelection(crossblooded, "dc3ab8d0484467a4787979d93114ebc3", "89d2b9f096b54804c8350dd2a899f8a4", FeatureGroup.EldritchKnightSpellbook); FixSpellbookSelection(crossblooded, "97f510c6483523c49bc779e93e4c4568", "e8013bf2853590f4fba12b4b57366bcc", FeatureGroup.MysticTheurgeArcaneSpellbook); }
// Adds the Crossblooded Sorcerer archetype. internal static void Load() { var progressionClasses = new BlueprintCharacterClass[] { sorcererClass, dragonDiscipleClass }; var crossblooded = Helpers.Create <BlueprintArchetype>(a => { a.name = "CrossbloodedSorcererArchetype"; a.LocalizedName = Helpers.CreateString("Crossblooded.Name", "Crossblooded Sorcerer"); a.LocalizedDescription = Helpers.CreateString("Crossblooded.Description", "A crossblooded sorcerer selects two different bloodlines. The sorcerer may gain access to the skills, feats, and some of the powers of both bloodlines they are descended from, but at the cost of reduced mental clarity and choice."); }); library.AddAsset(crossblooded, crossbloodedId); crossblooded.SetIcon(sorcererClass.Icon); crossblooded.ReplaceSpellbook = CreateReplacementSpellbook(); var bloodlineSelection = Helpers.bloodlineSelection; var bloodlines = bloodlineSelection.AllFeatures.Cast <BlueprintProgression>().ToList(); var sorcererFeatSelection = library.Get <BlueprintFeatureSelection>("3a60f0c0442acfb419b0c03b584e1394"); var powers = new SortedDictionary <int, SortedSet <BlueprintFeature> >(); var spells = new SortedDictionary <int, SortedSet <BlueprintFeature> >(); var powerLevels = new int[] { 1, 3, 9, 15, 20 }; var spellLevels = new int[] { 3, 5, 7, 9, 11, 13, 15, 17, 19 }; foreach (var level in powerLevels) { powers.Add(level, new SortedSet <BlueprintFeature>(BlueprintCompare.instance)); } foreach (var level in spellLevels) { spells.Add(level, new SortedSet <BlueprintFeature>(BlueprintCompare.instance)); } var crossbloodlines = new List <BlueprintProgression>(); foreach (var bloodline in bloodlines) { var levelLogic = CrossBloodlineLogic.TryCreate(bloodline); if (levelLogic == null) { continue; } var crossbloodline = library.CopyAndAdd(bloodline, $"{bloodline.name}Cross", bloodline.AssetGuid, "933224357f8d48be837a3083e33a18a8"); crossbloodline.SetName($"{bloodline.Name} (Crossblood)"); crossbloodline.LevelEntries = new LevelEntry[] { Helpers.LevelEntry(1, bloodline.GetLevelEntry(1).Features.Where(EldritchHeritage.IsArcanaOrClassSkill)) }; crossbloodline.Classes = progressionClasses; crossbloodline.Ranks = 1; crossbloodline.AddComponent(levelLogic); crossbloodlines.Add(crossbloodline); crossbloodForBloodline.Add(bloodline, crossbloodline); // Collect spells and abilities so we can build the choices for the main crossblooded progression. // (Note: we need to clone these, so we can change the prerequisites). foreach (var level in powerLevels) { var power = CreateBloodlinePower(bloodline, level, crossbloodline); powers[level].Add(power); } foreach (var level in spellLevels) { var spell = CreateBloodlineSpell(bloodline, level, crossbloodline); spells[level].Add(spell); } } FixBloodlinePrerequisites(crossblooded); crossbloodProgression = Helpers.CreateProgression("CrossbloodedProgression", crossblooded.Name, crossblooded.Description, "5f9f524c33ae4df780c54189ab9642b6", crossblooded.Icon, FeatureGroup.None); crossbloodProgression.Classes = progressionClasses; var entries = new List <LevelEntry>(); var powerGroup = new List <BlueprintFeatureBase>(); var spellGroup = new List <BlueprintFeatureBase>(); var allPowerChoices = new List <BlueprintFeature>(); var allSpellChoices = new List <BlueprintFeature>(); foreach (var level in new SortedSet <int>(powerLevels.Concat(spellLevels))) { var entry = Helpers.LevelEntry(level); entries.Add(entry); SortedSet <BlueprintFeature> powerChoices; if (powers.TryGetValue(level, out powerChoices)) { var description = "At 1st, 3rd, 9th, 15th, and 20th levels, a crossblooded sorcerer gains one of the two new bloodline powers available to their at that level. They may instead select a lower-level bloodline power they did not choose in place of one of these higher-level powers."; var powerSelection = Helpers.CreateFeatureSelection($"BloodlinePowerSelection{level}", "Bloodline Power", DescribeChoices(description, powerChoices), Helpers.MergeIds(guidsByLevel[level], "15029e64baee4db6b09ca6a6ed2d70c0"), null, FeatureGroup.None); //powerSelection.HideInUI = true; allPowerChoices.AddRange(powerChoices); powerSelection.SetFeatures(allPowerChoices); powerGroup.Add(powerSelection); entry.Features.Add(powerSelection); } SortedSet <BlueprintFeature> spellChoices; if (spells.TryGetValue(level, out spellChoices)) { var description = "A crossblooded sorcerer may select their bonus spells from either of their bloodlines. The sorcerer also has the choice to learn a lower-level bonus spell they did not choose in place of the higher-level bonus spell they would normally gain. Lower-level bonus spells learned this way always use the spell level that they would be if the sorcerer had learned them with the appropriate bonus spell."; var spellSelection = Helpers.CreateFeatureSelection($"BloodlineSpellSelection{level}", "Bloodline Spell", DescribeChoices(description, spellChoices), Helpers.MergeIds(guidsByLevel[level], "d333e2fb82ab4ab4af7d03d84aa5895c"), null, FeatureGroup.None); //spellSelection.HideInUI = true; allSpellChoices.AddRange(spellChoices); spellSelection.SetFeatures(allSpellChoices); spellGroup.Add(spellSelection); entry.Features.Add(spellSelection); } } crossbloodProgression.LevelEntries = entries.ToArray(); crossbloodProgression.UIGroups = new UIGroup[] { Helpers.CreateUIGroup(spellGroup), Helpers.CreateUIGroup(powerGroup) }; bloodlineChoice1 = Helpers.CreateFeatureSelection($"{bloodlineSelection.name}Cross1", bloodlineSelection.Name, bloodlineSelection.Description, "08cbfcda615f49218d3b118fc9322b81", bloodlineSelection.Icon, FeatureGroup.BloodLine); bloodlineChoice1.SetFeatures(crossbloodlines); bloodlineChoice2 = Helpers.CreateFeatureSelection($"{bloodlineSelection.name}Cross2", bloodlineSelection.Name, bloodlineSelection.Description, "ef595c20be9745b698e25e5a33b7d443", bloodlineSelection.Icon, FeatureGroup.BloodLine); bloodlineChoice2.SetFeatures(crossbloodlines); var level1 = Helpers.LevelEntry(1, crossbloodProgression, Helpers.CreateFeature("CrossbloodedConflictingUrges", "Crossblooded (conflicting urges)", "The conflicting urges created by the divergent nature of the crossblooded sorcerer’s dual heritage forces them to constantly take some mental effort just to remain focused on their current situation and needs. This leaves them with less mental resolve to deal with external threats. A crossblooded sorcerer always takes a –2 penalty on Will saves.", "ebefc29906f74c0d9a8b914095cc05d6", Helpers.GetIcon("983e8ad193160b44da80b38af4927e75"), // Diverse Training FeatureGroup.None, Helpers.CreateAddStatBonus(StatType.SaveWill, -2, ModifierDescriptor.Penalty)), bloodlineChoice1, bloodlineChoice2); crossblooded.RemoveFeatures = new LevelEntry[] { Helpers.LevelEntry(1, bloodlineSelection) }; crossblooded.AddFeatures = new LevelEntry[] { level1 }; crossblooded.BaseAttackBonus = sorcererClass.BaseAttackBonus; crossblooded.FortitudeSave = sorcererClass.FortitudeSave; crossblooded.ReflexSave = sorcererClass.ReflexSave; crossblooded.WillSave = sorcererClass.WillSave; Helpers.SetField(crossblooded, "m_ParentClass", sorcererClass); var archetypes = sorcererClass.Archetypes.ToList(); archetypes.Insert(0, crossblooded); sorcererClass.Archetypes = archetypes.ToArray(); // Fix prestige class spellbook selection // TODO: find these automatically, or it won't be compatible with new prestige classes. FixSpellbookSelection(crossblooded, "ae04b7cdeb88b024b9fd3882cc7d3d76", "9ff7ad30e5a074346a40f80efda277c8", FeatureGroup.ArcaneTricksterSpellbook); FixSpellbookSelection(crossblooded, "8c1ba14c0b6dcdb439c56341385ee474", "fa2a2469c9ba6d54b8fc2356f4fc0e9e", FeatureGroup.DragonDiscipleSpellbook); FixSpellbookSelection(crossblooded, "dc3ab8d0484467a4787979d93114ebc3", "89d2b9f096b54804c8350dd2a899f8a4", FeatureGroup.EldritchKnightSpellbook); FixSpellbookSelection(crossblooded, "97f510c6483523c49bc779e93e4c4568", "e8013bf2853590f4fba12b4b57366bcc", FeatureGroup.MysticTheurgeArcaneSpellbook); // Fix the SpellBookView icon support for archetypes. Main.ApplyPatch(typeof(UIUtilityUnit_CollectClassDeterminators_Patch), "Crossblooded bloodline icon in spellbook UI"); }