public static bool Prefix(CharacterBuildController __instance, BlueprintAbility spell, int spellLevel, bool multilevel) { if (!settings.toggleMulticlass) { return(false); } BlueprintSpellbook spellbook = __instance.Spells.CurrentSpellSelectionData.Spellbook; BlueprintSpellList spellList = __instance.Spells.CurrentSpellSelectionData.SpellList; int spellsCollectionIndex = __instance.Spells.CurrentSpellsCollectionIndex; if (multilevel) { __instance.LevelUpController.UnselectSpell(spellbook, spellList, spellsCollectionIndex, spellLevel); } else { __instance.LevelUpController.UnselectSpell(spellbook, spellList, spellsCollectionIndex, -1); } if (!__instance.LevelUpController.SelectSpell(spellbook, spellList, spellLevel, spell, spellsCollectionIndex)) { return(true); } // Begin Mod Lines BlueprintCharacterClass selectedClass = __instance.LevelUpController.State.SelectedClass; __instance.LevelUpController.State.SelectedClass = spellbook.CharacterClass; // End Mod Lines __instance.DefineAvailibleData(); __instance.Spells.IsDirty = true; __instance.Total.IsDirty = true; __instance.Spells.SetSpellbooklevel(spellLevel); __instance.SetupUI(); __instance.LevelUpController.State.SelectedClass = selectedClass; // Mod Line return(true); }
static public void Test() { BlueprintFeature abjurationFeat = library.Get <BlueprintFeature>("30f20e6f850519b48aa59e8c0ff66ae9"); BlueprintSpellList abjurationSpellList = library.Get <BlueprintSpellList>("c7a55e475659a944f9229d89c4dc3a8e"); abjurationFeat.AddComponent(Helpers.Create <AddSpecialSpellList>(a => { a.CharacterClass = ArcanistClass.arcanist; a.SpellList = abjurationSpellList; })); }
public void UnselectSpell([NotNull] BlueprintSpellbook spellbook, [NotNull] BlueprintSpellList spellList, int slotIndex, int level) { if (level >= 0) { this.RemoveAction <SelectSpell>((SelectSpell a) => a.SlotIndex == slotIndex && a.SpellLevel == level && a.SpellList == spellList && a.Spellbook == spellbook); } else { this.RemoveAction <SelectSpell>((SelectSpell a) => a.SlotIndex == slotIndex && a.SpellList == spellList && a.Spellbook == spellbook); } this.UpdatePreview(); }
public static CasterSpellProgression GetCasterSpellProgression(this BlueprintSpellList spellList) { if (spellList.GetSpells(9).Count > 0) { return(CasterSpellProgression.FullCaster); } else if (spellList.GetSpells(6).Count > 0) { return(CasterSpellProgression.ThreeQuartersCaster); } else if (spellList.GetSpells(4).Count > 0) { return(CasterSpellProgression.HalfCaster); } return(CasterSpellProgression.UnknownCaster); }
public static void AddToSpellList(this BlueprintAbility spell, BlueprintSpellList spellList, int level) { var comp = Helpers.Create <SpellListComponent>(); comp.SpellLevel = level; comp.SpellList = spellList; spell.AddComponent(comp); spellList.SpellsByLevel[level].Spells.Add(spell); if (spellList == Main.objects.wizardSpellList) { var school = spell.School; var specialistList = specialistSchoolList.Value[(int)school]; specialistList?.SpellsByLevel[level].Spells.Add(spell); var thassilonianList = thassilonianSchoolList.Value[(int)school]; thassilonianList?.SpellsByLevel[level].Spells.Add(spell); } }
public void Load() { var library = Main.library; // For some reason, Eldritch Scion is a class and an archetype. const string eldritchScionClassId = "f5b8c63b141b2f44cbb8c2d7579c34f5"; classes = library.Root.Progression.CharacterClasses.Where(c => c.AssetGuid != eldritchScionClassId) .ToList(); prestigeClasses = classes.Where(c => c.PrestigeClass).ToList(); sorcererClass = GetClass("b3a505fb61437dc4097f43c3f8f9a4cf"); magusClass = GetClass("45a4607686d96a1498891b3286121780"); dragonDiscipleClass = GetClass("72051275b1dbb2d42ba9118237794f7c"); eldritchScionArchetype = magusClass.Archetypes.First(a => a.AssetGuid == "d078b2ef073f2814c9e338a789d97b73"); human = library.Get <BlueprintRace>("0a5d473ead98b0646b94495af250fdc4"); halfElf = library.Get <BlueprintRace>("b3646842ffbd01643ab4dac7479b20b0"); halfOrc = library.Get <BlueprintRace>("1dc20e195581a804890ddc74218bfd8e"); elf = library.Get <BlueprintRace>("25a5878d125338244896ebd3238226c8"); dwarf = library.Get <BlueprintRace>("c4faf439f0e70bd40b5e36ee80d06be7"); halfling = library.Get <BlueprintRace>("b0c3ef2729c498f47970bb50fa1acd30"); gnome = library.Get <BlueprintRace>("ef35a22c9a27da345a4528f0d5889157"); aasimar = library.Get <BlueprintRace>("b7f02ba92b363064fb873963bec275ee"); tiefling = library.Get <BlueprintRace>("5c4e42124dc2b4647af6e36cf2590500"); races = new[] { human, halfElf, halfOrc, elf, dwarf, halfling, gnome, aasimar, tiefling }; skillFocusFeat = library.Get <BlueprintFeatureSelection>("c9629ef9eebb88b479b2fbc5e836656a"); tenMinPerLevelDuration = library.Get <BlueprintAbility>("5b77d7cc65b8ab74688e74a37fc2f553").LocalizedDuration; // barkskin minutesPerLevelDuration = library.Get <BlueprintAbility>("ef768022b0785eb43a18969903c537c4").LocalizedDuration; // shield hourPerLevelDuration = library.Get <BlueprintAbility>("9e1ad5d6f87d19e4d8883d63a6e35568").LocalizedDuration; // mage armor roundsPerLevelDuration = library.Get <BlueprintAbility>("486eaff58293f6441a5c2759c4872f98").LocalizedDuration; // haste oneRoundDuration = library.Get <BlueprintAbility>("2c38da66e5a599347ac95b3294acbe00").LocalizedDuration; // true strike reflexHalfDamage = library.Get <BlueprintAbility>("2d81362af43aeac4387a3d4fced489c3").LocalizedSavingThrow; // fireball savingThrowNone = library.Get <BlueprintAbility>("4ac47ddb9fa1eaf43a1b6809980cfbd2").LocalizedSavingThrow; // magic missle wizardSpellList = library.Get <BlueprintSpellList>("ba0401fdeb4062f40a7aa95b6f07fe89"); magusSpellList = library.Get <BlueprintSpellList>("4d72e1e7bd6bc4f4caaea7aa43a14639"); druidSpellList = library.Get <BlueprintSpellList>("bad8638d40639d04fa2f80a1cac67d6b"); clericSpellList = library.Get <BlueprintSpellList>("8443ce803d2d31347897a3d85cc32f53"); paladinSpellList = library.Get <BlueprintSpellList>("9f5be2f7ea64fe04eb40878347b147bc"); inquisitorSpellList = library.Get <BlueprintSpellList>("57c894665b7895c499b3dce058c284b3"); alchemistSpellList = library.Get <BlueprintSpellList>("f60d0cd93edc65c42ad31e34a905fb2f"); bardSpellList = library.Get <BlueprintSpellList>("25a5013493bdcf74bb2424532214d0c8"); touchWeapon = library.Get <BlueprintItemWeapon>("bb337517547de1a4189518d404ec49d4"); // TouchItem bloodlineSelection = library.Get <BlueprintFeatureSelection>("24bef8d1bee12274686f6da6ccbc8914"); ghostTouch = library.Get <BlueprintWeaponEnchantment>("47857e1a5a3ec1a46adf6491b1423b4f"); // Note: we can't easily scan all class spell lists, because some spells are // only added via special lists, like the ice version of burning hands. foreach (var blueprint in Main.library.GetAllBlueprints()) { switch (blueprint) { case BlueprintAbility spell when spell.Type == AbilityType.Spell: // Tiefling racial SLAs are marked as spells rather than SLAs. // (We can find them by the presence of the resource logic.) if (spell.GetComponent <AbilityResourceLogic>() != null) { spellsWithResources.Add(spell); } else { allSpells.Add(spell); } break; case BlueprintLoot loot: allLoots.Add(loot); break; case BlueprintUnitLoot unitLoot: allUnitLoots.Add(unitLoot); break; } } BlueprintCharacterClass GetClass(String assetId) => classes.First(c => c.AssetGuid == assetId); }
internal static List <BlueprintFeature> FillTripleSpellSelection(BlueprintFeatureSelection selection, int minLevel, int maxLevel, BlueprintSpellList spellList, Func <int, BlueprintComponent[]> createComponents, BlueprintCharacterClass learnSpellClass = null) { var choices = new List <BlueprintFeature>(); //var choicelist = new List<BlueprintFeature>(); string[] GuidList = new string[] { null, "3921FC7C8617472CAB3F86835D95FE62", "E8828D65304F4AE5AB8094F9893A0CCC", //"C77D3987222B4609A609A117BCF2E28D" }; //foreach(string thirdGuid in GuidList) { for (int level = minLevel; level <= maxLevel; level++) { var spellArrayAll = Helpers.Create <SelectAnySpellAtLevel>(); var spellChoice = Helpers.CreateParamSelection <SelectAnySpellAtLevel>( $"{selection.name}Level{level}", $"{selection.Name} (Spell Level {level})", selection.Description, Helpers.MergeIds(selection.AssetGuid, FavoredClassBonus.spellLevelGuids[level - 1], GuidList[2]), null, FeatureGroup.None, createComponents(level)); spellChoice.SpellList = spellList; spellChoice.SpellLevel = level; spellChoice.SpellcasterClass = learnSpellClass; spellChoice.CheckNotKnown = learnSpellClass != null; choices.Add(spellChoice); } choices.Add(UndoSelection.Feature.Value); return(choices); }
internal static void FillSpellSelection(BlueprintFeatureSelection selection, int minLevel, int maxLevel, BlueprintSpellList spellList, Func <int, BlueprintComponent[]> createComponents, BlueprintCharacterClass learnSpellClass = null) { var choices = new List <BlueprintFeature>(); for (int level = minLevel; level <= maxLevel; level++) { var spellChoice = Helpers.CreateParamSelection <SelectAnySpellAtLevel>( $"{selection.name}Level{level}", $"{selection.Name} (Spell Level {level})", selection.Description, Helpers.MergeIds(selection.AssetGuid, FavoredClassBonus.spellLevelGuids[level - 1]), null, FeatureGroup.None, createComponents(level)); spellChoice.SpellList = spellList; spellChoice.SpellLevel = level; spellChoice.SpellcasterClass = learnSpellClass; spellChoice.CheckNotKnown = learnSpellClass != null; choices.Add(spellChoice); } choices.Add(UndoSelection.Feature.Value); selection.SetFeatures(choices); }
static BlueprintProgression createSubdomain(string name, string display_name, string description, BlueprintProgression base_progression, BlueprintFeature[] old_features, BlueprintFeature[] new_features, BlueprintSpellList spell_list = null) { bool[] features_replaced = new bool[old_features.Length]; List <LevelEntry> new_level_entries = new List <LevelEntry>(); var progression = library.CopyAndAdd(base_progression, name + "Progression", ""); progression.SetNameDescription(display_name, description); foreach (var le in base_progression.LevelEntries) { var features = le.Features.ToArray(); for (int i = 0; i < old_features.Length; i++) { if (!features_replaced[i]) { if (features.Contains(old_features[i])) { features_replaced[i] = true; features = features.RemoveFromArray(old_features[i]); if (new_features[i] != null) { features = features.AddToArray(new_features[i]); } } } } if (!features.Empty()) { new_level_entries.Add(Helpers.LevelEntry(le.Level, features)); } } progression.LevelEntries = new_level_entries.ToArray(); if (spell_list != null) { progression.ReplaceComponent <LearnSpellList>(l => l.SpellList = spell_list); } features_replaced = new bool[old_features.Length]; List <UIGroup> ui_groups = new List <UIGroup>(); foreach (var uig in base_progression.UIGroups) { var features = uig.Features.ToArray(); for (int i = 0; i < old_features.Length; i++) { if (!features_replaced[i]) { if (features.Contains(old_features[i])) { features_replaced[i] = true; features = features.RemoveFromArray(old_features[i]); if (new_features[i] != null) { features = features.AddToArray(new_features[i]); } } } } if (!features.Empty()) { ui_groups.Add(Helpers.CreateUIGroup(features)); } } progression.UIGroups = ui_groups.ToArray(); //add domain spells var f0 = progression.LevelEntries[0].Features[0]; var comp = f0.GetComponent <AddFeatureOnClassLevel>(); if (comp != null) { f0 = library.CopyAndAdd(f0, name + f0.name, ""); f0.RemoveComponent(comp); } var give_spells = Helpers.CreateFeature(name + "SpellListFeature", "", "", "", null, FeatureGroup.None, Helpers.Create <AddSpecialSpellList>(a => { a.CharacterClass = cleric_class; a.SpellList = spell_list; }) ); give_spells.IsClassFeature = true; give_spells.HideInUI = true; f0.AddComponent(Helpers.CreateAddFeatureOnClassLevel(give_spells, 1, new BlueprintCharacterClass[] { cleric_class })); progression.LevelEntries[0].Features[0] = f0; return(progression); }
static void createNatureBondAndWindLord() { var domains = new BlueprintProgression[] { library.Get <BlueprintProgression>("4a3516fdc4cda764ebd1279b22d10205"), library.Get <BlueprintProgression>("3aef017b78329db4fa53fe8560069886"), Subdomains.lightning_domain_druid, Subdomains.storm_domain_druid }; var domain_primary_domain_map = new Dictionary <BlueprintFeature, BlueprintFeature>(); var domain_secondary_domain_map = new Dictionary <BlueprintFeature, BlueprintFeature>(); foreach (var d in domains) { BlueprintSpellList spell_list = d.LevelEntries[0].Features[1].GetComponent <AddSpecialSpellList>().SpellList; var primary_domain = library.CopyAndAdd <BlueprintProgression>(d.AssetGuid, "StormLord" + d.name, ""); var spells = Common.getSpellsFromSpellList(spell_list); var spells_array = Common.createSpelllistsForSpontaneousConversion(spells); for (int i = 0; i < spells_array.Length; i++) { primary_domain.AddComponent(Common.createSpontaneousSpellConversion(archetype.GetParentClass(), spells_array[i].ToArray())); } var secondary_domain = library.CopyAndAdd <BlueprintProgression>(primary_domain.AssetGuid, "StormLordSecondary" + d.name, ""); List <LevelEntry> secondary_level_entries = new List <LevelEntry>(); secondary_level_entries.Add(Helpers.LevelEntry(9)); foreach (var level_entry in d.LevelEntries) { if (level_entry.Level <= 9) { secondary_level_entries[0].Features.AddRange(level_entry.Features); } else { secondary_level_entries.Add(level_entry); } } if (d.LevelEntries[0].Features.Count == 1) { secondary_domain.AddComponent(d.GetComponent <AddSpecialSpellList>()); primary_domain.AddComponent(d.GetComponent <AddSpecialSpellList>()); } secondary_domain.LevelEntries = secondary_level_entries.ToArray(); secondary_domain.AddComponent(Helpers.PrerequisiteNoFeature(primary_domain)); domain_primary_progressions.Add(primary_domain); domain_secondary_progressions.Add(secondary_domain); domain_primary_domain_map.Add(d, primary_domain); domain_secondary_domain_map.Add(d, secondary_domain); } foreach (var d in domain_primary_progressions) { d.ReplaceComponent <PrerequisiteNoFeature>(p => p.Feature = domain_primary_domain_map[p.Feature]); } foreach (var d in domain_secondary_progressions) { d.ReplaceComponent <PrerequisiteNoFeature>(p => p.Feature = domain_primary_domain_map[p.Feature]); } nature_bond = Helpers.CreateFeatureSelection("NatureBondStormLordFeatureSelection", "Nature Bond", "A storm druid may not choose an animal companion. A storm druid must choose the Air or Weather domain or their subdomains.", "", library.Get <BlueprintAbility>("7cfbefe0931257344b2cb7ddc4cdff6f").Icon, //storm bolts FeatureGroup.DruidDomain); nature_bond.AllFeatures = domain_primary_progressions.ToArray(); wind_lord = Helpers.CreateFeatureSelection("WindLordStormLordFeatureSelection", "Wind Lord", "At 9th level, a storm druid can select another domain or subdomain from those available to her through her nature bond.", "", library.Get <BlueprintFeature>("f2fa7541f18b8af4896fbaf9f2a21dfe").Icon, //cyclone FeatureGroup.DruidDomain); wind_lord.AllFeatures = domain_secondary_progressions.ToArray(); spontaneous_casting = Helpers.CreateFeature("SpontaneousCastingStormLord", "Spontaneous Domain Casting", "A storm druid can channel stored spell energy into domain spells that she has not prepared ahead of time. She can “lose” a prepared spell in order to cast any domain spell of the same level or lower.", "", library.Get <BlueprintAbility>("0bd54216d38852947930320f6269a9d7").Icon, FeatureGroup.None ); }
static BlueprintProgression createSubdomain(string name, string display_name, string description, BlueprintProgression base_progression, BlueprintFeature[] old_features, BlueprintFeature[] new_features, BlueprintSpellList spell_list = null) { bool[] features_replaced = new bool[old_features.Length]; List <LevelEntry> new_level_entries = new List <LevelEntry>(); var progression = library.CopyAndAdd(base_progression, name + "Progression", ""); progression.SetNameDescription(display_name, description); foreach (var le in base_progression.LevelEntries) { var features = le.Features.ToArray(); for (int i = 0; i < old_features.Length; i++) { if (!features_replaced[i]) { if (features.Contains(old_features[i])) { features_replaced[i] = true; features = features.RemoveFromArray(old_features[i]); if (new_features[i] != null) { features = features.AddToArray(new_features[i]); } } } } if (!features.Empty()) { new_level_entries.Add(Helpers.LevelEntry(le.Level, features)); } } progression.LevelEntries = new_level_entries.ToArray(); if (spell_list != null) { progression.ReplaceComponent <LearnSpellList>(l => l.SpellList = spell_list); } features_replaced = new bool[old_features.Length]; List <UIGroup> ui_groups = new List <UIGroup>(); foreach (var uig in base_progression.UIGroups) { var features = uig.Features.ToArray(); for (int i = 0; i < old_features.Length; i++) { if (!features_replaced[i]) { if (features.Contains(old_features[i])) { features_replaced[i] = true; features = features.RemoveFromArray(old_features[i]); if (new_features[i] != null) { features = features.AddToArray(new_features[i]); } } } } if (!features.Empty()) { ui_groups.Add(Helpers.CreateUIGroup(features)); } } progression.UIGroups = ui_groups.ToArray(); return(progression); }
public bool SelectSpell([NotNull] BlueprintSpellbook spellbook, [NotNull] BlueprintSpellList spellList, int spellLevel, [NotNull] BlueprintAbility spell, int slotIndex) { return(this.AddAction(new SelectSpell(spellbook, spellList, spellLevel, spell, slotIndex), false)); }
static public void CreateFeats() { if (!prepared) { LoadSpecialSpells(); } if (addSpecialSpellFeat != null) { return; } BlueprintSpellList specialList = Helpers.Create <BlueprintSpellList>(); specialList.name = "RisiaBossSpecialSpells"; specialList.SpellsByLevel = new SpellLevelList[10]; for (int i = 0; i < 10; i++) { specialList.SpellsByLevel[i] = new SpellLevelList(i); } int len = specialSpellLevels.Count; for (int i = 0; i < len; i++) { specialList.SpellsByLevel[specialSpellLevels[i]].Spells.Add(specialSpells[i]); } library.AddAsset(specialList, OtherUtils.GetMd5("Risia.Boss.AddSpecialSpellList.List")); addSpecialSpellListFeat = Helpers.CreateFeature("RisiaAddSpecialSpellListFeat", "", "", OtherUtils.GetMd5("Risia.Boss.AddSpecialSpellList.Feat"), IconSet.elvenmagic, FeatureGroup.None, Helpers.Create <AddSpecialSpellList>(a => { a.CharacterClass = ArcanistClass.arcanist; a.SpellList = specialList; })); /*addSpecialSpellFeat = Helpers.CreateFeature("RisiaAddSpecialSpellFeat", "", "", * OtherUtils.GetMd5("Risia.AddSpecialSpell.Feat"), * IconSet.elvenmagic, * FeatureGroup.None);*/ addSpecialSpellFeat = Helpers.CreateProgression("RisiaAddSpecialSpellProgression", "", "", OtherUtils.GetMd5("Risia.AddSpecialSpell.Progression.Feat"), null, FeatureGroup.None); addSpecialSpellFeat.IsClassFeature = false; addSpecialSpellFeat.Classes = new BlueprintCharacterClass[] { ArcanistClass.arcanist }; addSpecialSpellFeat.LevelEntries = new LevelEntry[20]; for (int i = 0; i < 20; i++) { addSpecialSpellFeat.LevelEntries[i] = new LevelEntry { Level = i + 1 }; } BlueprintFeature[] subFeats = new BlueprintFeature[10]; for (int i = 0; i < 10; i++) { subFeats[i] = Helpers.CreateFeature($"Risia.AddSpecialSpellFeat.Level{i}", "", "", OtherUtils.GetMd5($"Risia.AddSpecialSpellFeat.Level{i}"), null, FeatureGroup.None); } for (int i = 0; i < len; i++) { subFeats[specialSpellLevels[i]].AddComponent(specialSpells[i].CreateAddKnownSpell(ArcanistClass.arcanist, specialSpellLevels[i])); } for (int i = 1; i <= 9; i++) { int firstArcanistLevel = (i == 1 ? 1 : i * 2) + 1; addSpecialSpellFeat.LevelEntries[firstArcanistLevel - 1] = Helpers.LevelEntry(firstArcanistLevel, subFeats[i]); } addSpecialSpellFeat.SetName(Helpers.CreateString("Risia.AddSpecialSpell.Feat.Name")); addSpecialSpellFeat.SetDescription(Helpers.CreateString("Risia.AddSpecialSpell.Feat.Desc")); }