private static bool Prefix(UnitProgressionData __instance, int experience) { if (!settings.toggleAllowMythicPets) { return(true); } if (experience < 1) { PFLog.Default.Error(string.Format("Current mythic level of {0} is {1}, trying to raise to {2}! Aborting", (object)__instance.Owner, (object)__instance.MythicLevel, (object)(__instance.MythicExperience + experience))); } else { __instance.MythicExperience += experience; if (__instance.MythicExperience > 10) { PFLog.Default.Error(string.Format("Current mythic level of {0} is {1}, trying to raise to {2}! Can't do this", (object)__instance.Owner, (object)__instance.MythicLevel, (object)(__instance.MythicExperience + experience))); } var pair = UnitPartDualCompanion.GetPair(__instance.Owner.Unit); if (pair != (UnitDescriptor)null) { pair.Descriptor.Progression.MythicExperience = __instance.MythicExperience; } EventBus.RaiseEvent <IUnitGainMythicExperienceHandler>((Action <IUnitGainMythicExperienceHandler>)(h => h.HandleUnitGainMythicExperience(__instance.Owner, experience))); } return(false); }
static void Postfix(UnitProgressionData __instance, BlueprintCharacterClass characterClass, ref int __result) { var unit_fake_class_part = __instance.Owner.Get <UnitPartFakeClassLevel>(); if (__result == 0 && unit_fake_class_part != null) { __result += unit_fake_class_part.getFakeClassLevel(characterClass); } }
static bool Prefix(UnitProgressionData __instance, BlueprintCharacterClass characterClass) { if (IsAvailable() && Core.Mod.IsLevelLocked) { __instance.AddClassLevel_NotCharacterLevel(characterClass); return(false); } return(true); }
private static bool Prefix(/* ref */ UnitProgressionData __instance) { if (!tablePatched) { updateXPTable(); } //logger.Log($"AddClassLevel called on ${__instance.Owner.ToString()}"); return(true); }
public static void AddClassLevel_NotCharacterLevel(this UnitProgressionData instance, BlueprintCharacterClass characterClass) { //instance.SureClassData(characterClass).Level++; GetMethodDel <UnitProgressionData, Func <UnitProgressionData, BlueprintCharacterClass, ClassData> > ("SureClassData")(instance, characterClass).Level++; //instance.CharacterLevel++; instance.Classes.Sort(); instance.Features.AddFact(characterClass.Progression, null); instance.Owner.OnGainClassLevel(characterClass); //int[] bonuses = BlueprintRoot.Instance.Progression.XPTable.Bonuses; //int val = bonuses[Math.Min(bonuses.Length - 1, instance.CharacterLevel)]; //instance.Experience = Math.Max(instance.Experience, val); }
static void Postfix(UnitProgressionData __instance, BlueprintArchetype archetype) { var combined_archetypes = archetype.GetComponent<CombineArchetypes>(); if (combined_archetypes == null) { return; } foreach (var a in combined_archetypes.archetypes) { __instance.AddArchetype(a.GetParentClass(), a); } }
// This method is only used by `SpellBookView.SetupHeader()` to find information such // as spellbook bloodlines, cleric deity, etc. // // Unfortunately, it doesn't understand how to find data from the archetype. // So this patch addresses it. static void Postfix(BlueprintProgression progression, UnitProgressionData progressionData, ref List <BlueprintFeatureBase> __result) { try { var @class = Helpers.classes.FirstOrDefault(c => c.Progression == progression); if (@class == null) { return; } var list = __result ?? new List <BlueprintFeatureBase>(); var archetype = @class.Archetypes.FirstOrDefault(progressionData.IsArchetype); if (archetype == null) { return; } foreach (var entry in archetype.RemoveFeatures) { foreach (var feat in entry.Features.OfType <BlueprintFeatureSelection>().Where(f => !f.HideInUI)) { var selections = progressionData.GetSelections(feat, entry.Level); list.RemoveAll(f => f == feat || selections.Contains(f)); } } foreach (var entry in archetype.AddFeatures) { foreach (var feat in entry.Features.OfType <BlueprintFeatureSelection>().Where(f => !f.HideInUI)) { var selections = progressionData.GetSelections(feat, entry.Level); foreach (var s in selections) { if (IsDeterminator(s) && !list.Contains(s)) { list.Add(s); } } if (selections.Count == 0 && IsDeterminator(feat)) { list.Add(feat); } } } __result = list.Count == 0 ? null : list; } catch (Exception e) { Log.Error(e); } }
public static void AddClassLevel_NotCharacterLevel(this UnitProgressionData instance, BlueprintCharacterClass characterClass) { //instance.SureClassData(characterClass).Level++; Mod.Debug($"AddClassLevel_NotCharLevel: class = {characterClass.name.cyan()} - lvl:{instance.GetClassLevel(characterClass)} - {string.Join(", ", instance.Features.Enumerable.Select(f => f.Name.orange()))}"); ReflectionCache.GetMethod <UnitProgressionData, Func <UnitProgressionData, BlueprintCharacterClass, ClassData> > ("SureClassData")(instance, characterClass).Level++; //instance.CharacterLevel++; instance.m_ClassesOrder.Add(characterClass); instance.Classes.Sort(); instance.Features.AddFeature(characterClass.Progression, null).SetSource(characterClass, 1); instance.Owner.OnGainClassLevel(characterClass); //int[] bonuses = BlueprintRoot.Instance.Progression.XPTable.Bonuses; //int val = bonuses[Math.Min(bonuses.Length - 1, instance.CharacterLevel)]; //instance.Experience = Math.Max(instance.Experience, val); }
public static bool IsClassGestalt(this UnitProgressionData progression, BlueprintCharacterClass cl) { var chars = Game.Instance.Player.AllCharacters; foreach (var ch in chars) { //Mod.Debug($" {ch.Progression.Owner} vs { progression.Owner}"); if (ch.Progression.Owner == progression.Owner) { var result = ch.IsClassGestalt(cl); //Mod.Debug($" found: {ch.HashKey()} - {cl.Name.orange()} - IsGestalt: {result.ToString().cyan()}"); return(result); } } return(false); }
private static bool Prefix(MethodBase __originalMethod, UnitProgressionData __instance, ref int exp, bool log) { // logger.Log($"Trying to add {exp} XP to a current value of {__instance.Experience}, using {Game.Instance.Player.ExperienceRatePercent}%."); const int limit = 10000000; int temp = exp; if (temp <= limit) { return(true); } while (temp > limit) { Object[] p = { limit, log }; __originalMethod.Invoke(__instance, p); temp -= limit; // logger.Log($" ... intermediate result is {__instance.Experience}"); } exp = temp; // logger.Log($" ... final result is {__instance.Experience}"); return(true); }
static bool Prefix(UnitProgressionData __instance, ref BlueprintCharacterClass __result) { try { if (!Main.enabled) { return(true); } if (disableEquipmentClassPatch) { return(true); } if (!__instance.Owner.IsPlayerFaction) { return(true); } var characterSettings = Main.settings.GetCharacterSettings(__instance.Owner.Unit); if (characterSettings == null) { return(true); } ///__result = Utilities.GetBlueprintByName<BlueprintCharacterClass>(characterSettings.classOutfit+"Class"); __result = Utilities.GetBlueprintByGuid <BlueprintCharacterClass>(characterSettings.classOutfit.GUID); /*switch (characterSettings.classOutfit.Name) * { * case "Alchemist": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("0937bec61c0dabc468428f496580c721"); * break; * case "Barbarian": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("f7d7eb166b3dd594fb330d085df41853"); * break; * case "Bard": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("772c83a25e2268e448e841dcd548235f"); * break; * case "Cavalier": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("3adc3439f98cb534ba98df59838f02c7"); * break; * case "Cleric": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("67819271767a9dd4fbfd4ae700befea0"); * break; * case "Druid": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("610d836f3a3a9ed42a4349b62f002e96"); * break; * case "Fighter": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("48ac8db94d5de7645906c7d0ad3bcfbd"); * break; * case "Inquisitor": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("f1a70d9e1b0b41e49874e1fa9052a1ce"); * break; * case "Kineticist": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("42a455d9ec1ad924d889272429eb8391"); * break; * case "Magus": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("45a4607686d96a1498891b3286121780"); * break; * case "Monk": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("e8f21e5b58e0569468e420ebea456124"); * break; * case "Oracle": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("20ce9bf8af32bee4c8557a045ab499b1"); * break; * case "Paladin": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("bfa11238e7ae3544bbeb4d0b92e897ec"); * break; * case "Ranger": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("cda0615668a6df14eb36ba19ee881af6"); * break; * case "Rogue": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("299aa766dee3cbf4790da4efb8c72484"); * break; * case "Shaman": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("145f1d3d360a7ad48bd95d392c81b38e"); * break; * case "Skald": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("6afa347d804838b48bda16acb0573dc0"); * break; * case "Slayer": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("c75e0971973957d4dbad24bc7957e4fb"); * break; * case "Sorcerer": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("b3a505fb61437dc4097f43c3f8f9a4cf"); * break; * case "Wizard": * __result = (BlueprintCharacterClass)ResourcesLibrary.TryGetBlueprint<BlueprintCharacterClass>("ba34257984f4c41408ce1dc2004e342e"); * break; * default: * return true; * }*/ if (__result == null) { return(true); } return(false); } catch (Exception ex) { Main.Error(ex); return(true); } }
static bool Prefix(UnitProgressionData __instance, ref BlueprintCharacterClass __result) { try { if (!Main.enabled) { return(true); } if (disableEquipmentClassPatch) { return(true); } if (!__instance.Owner.IsPlayerFaction) { return(true); } var characterSettings = Main.settings.GetCharacterSettings(__instance.Owner.Unit); if (characterSettings == null) { return(true); } switch (characterSettings.classOutfit) { case "Alchemist": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["0937bec61c0dabc468428f496580c721"]; break; case "Barbarian": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["f7d7eb166b3dd594fb330d085df41853"]; break; case "Bard": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["772c83a25e2268e448e841dcd548235f"]; break; case "Cleric": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["67819271767a9dd4fbfd4ae700befea0"]; break; case "Druid": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["610d836f3a3a9ed42a4349b62f002e96"]; break; case "Fighter": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["48ac8db94d5de7645906c7d0ad3bcfbd"]; break; case "Inquisitor": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["f1a70d9e1b0b41e49874e1fa9052a1ce"]; break; case "Kineticist": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["42a455d9ec1ad924d889272429eb8391"]; break; case "Magus": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["45a4607686d96a1498891b3286121780"]; break; case "Monk": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["e8f21e5b58e0569468e420ebea456124"]; break; case "Paladin": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["bfa11238e7ae3544bbeb4d0b92e897ec"]; break; case "Ranger": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["cda0615668a6df14eb36ba19ee881af6"]; break; case "Rogue": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["299aa766dee3cbf4790da4efb8c72484"]; break; case "Sorcerer": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["b3a505fb61437dc4097f43c3f8f9a4cf"]; break; case "Wizard": __result = (BlueprintCharacterClass)ResourcesLibrary.LibraryObject.BlueprintsByAssetId["ba34257984f4c41408ce1dc2004e342e"]; break; default: return(true); } if (__result == null) { return(true); } return(false); } catch (Exception ex) { Main.DebugError(ex); return(true); } }
public static void OnGUI() { var player = Game.Instance.Player; var filterChoices = GetPartyFilterChoices(); if (filterChoices == null) { return; } charToAdd = null; charToRemove = null; var characterListFunc = UI.TypePicker <List <UnitEntityData> >( null, ref Main.settings.selectedPartyFilter, filterChoices ); var characterList = characterListFunc.func(); var mainChar = GameHelper.GetPlayerCharacter(); if (characterListFunc.name == "Nearby") { UI.Slider("Nearby Distance", ref nearbyRange, 1f, 200, 25, 0, " meters", UI.Width(250)); characterList = characterList.OrderBy((ch) => ch.DistanceTo(mainChar)).ToList(); } UI.Space(20); int chIndex = 0; respecableCount = 0; var selectedCharacter = GetSelectedCharacter(); bool isWide = Main.IsWide; foreach (UnitEntityData ch in characterList) { var classData = ch.Progression.Classes; // TODO - understand the difference between ch.Progression and ch.Descriptor.Progression UnitProgressionData progression = ch.Descriptor.Progression; BlueprintStatProgression xpTable = BlueprintRoot.Instance.Progression.XPTable; int level = progression.CharacterLevel; int mythicLevel = progression.MythicExperience; var spellbooks = ch.Spellbooks; var spellCount = spellbooks.Sum((sb) => sb.GetAllKnownSpells().Count()); using (UI.HorizontalScope()) { UI.Label(ch.CharacterName.orange().bold(), UI.Width(200)); UI.Space(25); float distance = mainChar.DistanceTo(ch);; UI.Label(distance < 1 ? "" : distance.ToString("0") + "m", UI.Width(75)); UI.Space(25); UI.Label("lvl".green() + $": {level}", UI.Width(75)); // Level up code adapted from Bag of Tricks https://www.nexusmods.com/pathfinderkingmaker/mods/2 if (player.AllCharacters.Contains(ch)) { if (progression.Experience < xpTable.GetBonus(level + 1) && level < 20) { UI.ActionButton("+1", () => { progression.AdvanceExperienceTo(xpTable.GetBonus(level + 1), true); }, UI.Width(70)); } else if (progression.Experience >= xpTable.GetBonus(level + 1) && level < 20) { UI.Label("LvUp".cyan().italic(), UI.Width(70)); } else { UI.Space(74); } } else { UI.Space(74); } UI.Space(25); UI.Label($"my".green() + $": {mythicLevel}", UI.Width(100)); if (player.AllCharacters.Contains(ch)) { if (progression.MythicExperience < 10) { UI.ActionButton("+1", () => { progression.AdvanceMythicExperience(progression.MythicExperience + 1, true); }, UI.Width(70)); } else { UI.Label("max".cyan(), UI.Width(70)); } } else { UI.Space(74); } UI.Space(35); if (!isWide) { ActionsGUI(ch); } UI.Wrap(!Main.IsWide, 303, 0); bool showClasses = ch == selectedCharacter && selectedToggle == ToggleChoice.Classes; if (UI.DisclosureToggle($"{classData.Count} Classes", ref showClasses)) { if (showClasses) { selectedCharacter = ch; selectedToggle = ToggleChoice.Classes; Logger.Log($"selected {ch.CharacterName}"); } else { selectedToggle = ToggleChoice.None; } } bool showStats = ch == selectedCharacter && selectedToggle == ToggleChoice.Stats; if (UI.DisclosureToggle("Stats", ref showStats, true, isWide ? 150 : 200)) { if (showStats) { selectedCharacter = ch; selectedToggle = ToggleChoice.Stats; } else { selectedToggle = ToggleChoice.None; } } UI.Wrap(Main.IsNarrow, 279); bool showFacts = ch == selectedCharacter && selectedToggle == ToggleChoice.Facts; if (UI.DisclosureToggle("Facts", ref showFacts, true, isWide ? 150 : 200)) { if (showFacts) { selectedCharacter = ch; selectedToggle = ToggleChoice.Facts; } else { selectedToggle = ToggleChoice.None; } } bool showBuffs = ch == selectedCharacter && selectedToggle == ToggleChoice.Buffs; if (UI.DisclosureToggle("Buffs", ref showBuffs, true, isWide ? 150 : 200)) { if (showBuffs) { selectedCharacter = ch; selectedToggle = ToggleChoice.Buffs; } else { selectedToggle = ToggleChoice.None; } } UI.Wrap(Main.IsNarrow, 304); bool showAbilities = ch == selectedCharacter && selectedToggle == ToggleChoice.Abilities; if (UI.DisclosureToggle("Abilities", ref showAbilities, true)) { if (showAbilities) { selectedCharacter = ch; selectedToggle = ToggleChoice.Abilities; } else { selectedToggle = ToggleChoice.None; } } UI.Space(25); if (spellCount > 0) { bool showSpells = ch == selectedCharacter && selectedToggle == ToggleChoice.Spells; if (UI.DisclosureToggle($"{spellCount} Spells", ref showSpells, true)) { if (showSpells) { selectedCharacter = ch; selectedToggle = ToggleChoice.Spells; } else { selectedToggle = ToggleChoice.None; } } } else { UI.Space(180); } if (isWide) { ActionsGUI(ch); } } if (!Main.IsWide) { UI.Div(20, 20); } if (selectedCharacter != spellbookEditCharacter) { editSpellbooks = false; spellbookEditCharacter = null; } if (selectedCharacter != multiclassEditCharacter) { editMultiClass = false; multiclassEditCharacter = null; } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Classes) { #if DEBUG UI.Div(100, 20); using (UI.HorizontalScope()) { UI.Space(100); UI.Toggle("Multiple Classes On Level-Up", ref settings.toggleMulticlass, 0); if (settings.toggleMulticlass) { UI.Space(39); if (UI.DisclosureToggle("Config".orange().bold(), ref editMultiClass)) { multiclassEditCharacter = selectedCharacter; } UI.Space(25); UI.Label("Experimental Preview ".magenta() + "See 'Level Up + Multiclass' for more options".green()); } else { UI.Space(50); UI.Label("Experimental Preview ".magenta()); } } #endif UI.Div(100, 20); if (editMultiClass) { var multiclassSet = ch.GetMulticlassSet(); MulticlassPicker.OnGUI(multiclassSet); ch.SetMulticlassSet(multiclassSet); } else { var prog = ch.Descriptor.Progression; using (UI.HorizontalScope()) { UI.Space(100); UI.Label("Character Level".cyan(), UI.Width(250)); UI.ActionButton("<", () => prog.CharacterLevel = Math.Max(0, prog.CharacterLevel - 1), UI.AutoWidth()); UI.Space(25); UI.Label("level".green() + $": {prog.CharacterLevel}", UI.Width(100f)); UI.ActionButton(">", () => prog.CharacterLevel = Math.Min(20, prog.CharacterLevel + 1), UI.AutoWidth()); UI.Space(25); UI.ActionButton("Reset", () => ch.resetClassLevel(), UI.Width(125)); UI.Space(23); UI.Label("This directly changes your character level but will not change exp or adjust any features associated with your character. To do a normal level up use +1 Lvl above".green()); } UI.Div(0, 25); using (UI.HorizontalScope()) { UI.Space(100); UI.Label("Mythic Level".cyan(), UI.Width(250)); UI.ActionButton("<", () => prog.MythicLevel = Math.Max(0, prog.MythicLevel - 1), UI.AutoWidth()); UI.Space(25); UI.Label("my lvl".green() + $": {prog.MythicLevel}", UI.Width(100f)); UI.ActionButton(">", () => prog.MythicLevel = Math.Min(10, prog.MythicLevel + 1), UI.AutoWidth()); UI.Space(175); UI.Label("This directly changes your mythic level but will not adjust any features associated with your character. To do a normal mythic level up use +1 my above".green()); } foreach (var cd in classData) { UI.Div(100, 20); using (UI.HorizontalScope()) { UI.Space(100); UI.Label(cd.CharacterClass.Name.orange(), UI.Width(250)); UI.ActionButton("<", () => cd.Level = Math.Max(0, cd.Level - 1), UI.AutoWidth()); UI.Space(25); UI.Label("level".green() + $": {cd.Level}", UI.Width(100f)); var maxLevel = cd.CharacterClass.Progression.IsMythic ? 10 : 20; UI.ActionButton(">", () => cd.Level = Math.Min(maxLevel, cd.Level + 1), UI.AutoWidth()); UI.Space(175); UI.Label(cd.CharacterClass.Description.green(), UI.AutoWidth()); } } } } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Stats) { UI.Div(100, 20, 755); var alignment = ch.Descriptor.Alignment.Value; using (UI.HorizontalScope()) { UI.Space(100); UI.Label("Alignment", UI.Width(425)); UI.Label($"{alignment.Name()}".color(alignment.Color()).bold(), UI.Width(1250f)); } using (UI.HorizontalScope()) { UI.Space(528); int alignmentIndex = Array.IndexOf(alignments, alignment); var titles = alignments.Select( a => a.Acronym().color(a.Color()).bold()).ToArray(); if (UI.SelectionGrid(ref alignmentIndex, titles, 3, UI.Width(250f))) { ch.Descriptor.Alignment.Set(alignments[alignmentIndex]); } } UI.Div(100, 20, 755); using (UI.HorizontalScope()) { UI.Space(100); UI.Label("Size", UI.Width(425)); var size = ch.Descriptor.State.Size; UI.Label($"{size}".orange().bold(), UI.Width(175)); } using (UI.HorizontalScope()) { UI.Space(528); UI.EnumGrid( () => ch.Descriptor.State.Size, (s) => ch.Descriptor.State.Size = s, 3, UI.Width(600)); } using (UI.HorizontalScope()) { UI.Space(528); UI.ActionButton("Reset", () => { ch.Descriptor.State.Size = ch.Descriptor.OriginalSize; }, UI.Width(197)); } UI.Div(100, 20, 755); foreach (StatType obj in Enum.GetValues(typeof(StatType))) { StatType statType = (StatType)obj; ModifiableValue modifiableValue = ch.Stats.GetStat(statType); if (modifiableValue != null) { String key = $"{ch.CharacterName}-{statType.ToString()}"; var storedValue = statEditorStorage.ContainsKey(key) ? statEditorStorage[key] : modifiableValue.BaseValue; var statName = statType.ToString(); if (statName == "BaseAttackBonus" || statName == "SkillAthletics") { UI.Div(100, 20, 755); } using (UI.HorizontalScope()) { UI.Space(100); UI.Label(statName, UI.Width(400f)); UI.Space(25); UI.ActionButton(" < ", () => { modifiableValue.BaseValue -= 1; storedValue = modifiableValue.BaseValue; }, UI.AutoWidth()); UI.Space(20); UI.Label($"{modifiableValue.BaseValue}".orange().bold(), UI.Width(50f)); UI.ActionButton(" > ", () => { modifiableValue.BaseValue += 1; storedValue = modifiableValue.BaseValue; }, UI.AutoWidth()); UI.Space(25); UI.ActionIntTextField(ref storedValue, statType.ToString(), (v) => { modifiableValue.BaseValue = v; }, null, UI.Width(75)); statEditorStorage[key] = storedValue; } } } } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Facts) { FactsEditor.OnGUI(ch, ch.Progression.Features.Enumerable.ToList()); } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Buffs) { FactsEditor.OnGUI(ch, ch.Descriptor.Buffs.Enumerable.ToList()); } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Abilities) { FactsEditor.OnGUI(ch, ch.Descriptor.Abilities.Enumerable.ToList()); } if (ch == selectedCharacter && selectedToggle == ToggleChoice.Spells) { UI.Space(20); var names = spellbooks.Select((sb) => sb.Blueprint.GetDisplayName()).ToArray(); var titles = names.Select((name, i) => $"{name} ({spellbooks.ElementAt(i).CasterLevel})").ToArray(); if (spellbooks.Any()) { using (UI.HorizontalScope()) { UI.SelectionGrid(ref selectedSpellbook, titles, 7, UI.Width(1581)); if (selectedSpellbook > names.Count()) { selectedSpellbook = 0; } // UI.DisclosureToggle("Edit", ref editSpellbooks); } var spellbook = spellbooks.ElementAt(selectedSpellbook); if (editSpellbooks) { spellbookEditCharacter = ch; var blueprints = BlueprintExensions.GetBlueprints <BlueprintSpellbook>().OrderBy((bp) => bp.GetDisplayName()); BlueprintListUI.OnGUI(ch, blueprints, 100); } else { var maxLevel = spellbook.Blueprint.MaxSpellLevel; var casterLevel = spellbook.CasterLevel; using (UI.HorizontalScope()) { UI.EnumerablePicker <int>( "Spell Level".bold() + " (count)", ref selectedSpellbookLevel, Enumerable.Range(0, casterLevel + 1), 0, (lvl) => { var levelText = lvl <= casterLevel ? $"L{lvl}".bold() : $"L{lvl}".grey(); var knownCount = spellbook.GetKnownSpells(lvl).Count(); var countText = knownCount > 0 ? $" ({knownCount})".white() : ""; return(levelText + countText); }, UI.AutoWidth() ); if (casterLevel < maxLevel) { UI.ActionButton("+1 Caster Level", () => spellbook.AddBaseLevel()); } } FactsEditor.OnGUI(ch, spellbook, selectedSpellbookLevel); } } #if false else { spellbookEditCharacter = ch; editSpellbooks = true; var blueprints = BlueprintExensions.GetBlueprints <BlueprintSpellbook>().OrderBy((bp) => bp.GetDisplayName()); BlueprintListUI.OnGUI(ch, blueprints, 100); } #endif } if (selectedCharacter != GetSelectedCharacter()) { selectedCharacterIndex = characterList.IndexOf(selectedCharacter); } chIndex += 1; } UI.Space(25); if (respecableCount > 0) { UI.Label($"{respecableCount} characters".yellow().bold() + " can be respecced. Pressing Respec will close the mod window and take you to character level up".orange()); UI.Label("WARNING".yellow().bold() + " this feature is ".orange() + "EXPERIMENTAL".yellow().bold() + " and uses unreleased and likely buggy code.".orange()); UI.Label("BACK UP".yellow().bold() + " before playing with this feature.You will lose your mythic ranks but you can restore them in this Party Editor.".orange()); } UI.Space(25); if (charToAdd != null) { UnitEntityDataUtils.AddCompanion(charToAdd); } if (charToRemove != null) { UnitEntityDataUtils.RemoveCompanion(charToRemove); } }
public FeaturesTree(UnitProgressionData progression) { Dictionary <BlueprintScriptableObject, FeatureNode> normalNodes = new Dictionary <BlueprintScriptableObject, FeatureNode>(); List <FeatureNode> parametrizedNodes = new List <FeatureNode>(); // get nodes (features / race) foreach (Feature feature in progression.Features.Enumerable) { if (feature.Blueprint is BlueprintParametrizedFeature) { parametrizedNodes.Add(new FeatureNode(feature.Name, feature.Blueprint, feature.Source)); } else { normalNodes.Add(feature.Blueprint, new FeatureNode(feature.Name, feature.Blueprint, feature.Source)); } } // get nodes (classes) foreach (BlueprintCharacterClass characterClass in progression.Classes.Select(item => item.CharacterClass)) { normalNodes.Add(characterClass, new FeatureNode(characterClass.Name, characterClass, null)); } // set source selection List <FeatureNode> selectionNodes = normalNodes.Values .Where(item => item.Blueprint is BlueprintFeatureSelection).ToList(); for (int i = 0; i <= 20; i++) { foreach (FeatureNode selection in selectionNodes) { foreach (BlueprintFeature feature in progression.GetSelections(selection.Blueprint as BlueprintFeatureSelection, i)) { FeatureNode node = default; if (feature is BlueprintParametrizedFeature) { node = parametrizedNodes .FirstOrDefault(item => item.Source != null && item.Source == selection.Source); } if (node != null || normalNodes.TryGetValue(feature, out node)) { node.Source = selection.Blueprint; } else { // missing child normalNodes.Add(feature, new FeatureNode(string.Empty, feature, selection.Blueprint) { IsMissing = true }); } } } } // build tree foreach (FeatureNode node in normalNodes.Values.Concat(parametrizedNodes).ToList()) { if (node.Source == null) { RootNodes.Add(node); } else if (normalNodes.TryGetValue(node.Source, out FeatureNode parent)) { parent.ChildNodes.Add(node); } else { // missing parent parent = new FeatureNode(string.Empty, node.Source, null) { IsMissing = true }; parent.ChildNodes.Add(node); normalNodes.Add(parent.Blueprint, parent); RootNodes.Add(parent); } } }
public FeaturesTree(UnitProgressionData progression) { Dictionary <BlueprintScriptableObject, FeatureNode> normalNodes = new(); List <FeatureNode> parametrizedNodes = new(); //Main.Log($"prog: {progression}"); // get nodes (features / race) foreach (var feature in progression.Features.Enumerable) { var name = feature.Name; if (name == null || name.Length == 0) { name = feature.Blueprint.name; } //Main.Log($"feature: {name}"); var source = feature.m_Source; //Main.Log($"source: {source}"); if (feature.Blueprint is BlueprintParametrizedFeature) { parametrizedNodes.Add(new FeatureNode(name, feature.SourceLevel, feature.Blueprint, source)); } else { normalNodes.Add(feature.Blueprint, new FeatureNode(name, feature.SourceLevel, feature.Blueprint, source)); } } // get nodes (classes) foreach (var characterClass in progression.Classes.Select(item => item.CharacterClass)) { normalNodes.Add(characterClass, new FeatureNode(characterClass.Name, 0, characterClass, null)); } // set source selection var selectionNodes = normalNodes.Values .Where(item => item.Blueprint is BlueprintFeatureSelection).ToList(); for (var level = 0; level <= 100; level++) { foreach (var selection in selectionNodes) { foreach (var feature in progression.GetSelections(selection.Blueprint as BlueprintFeatureSelection, level)) { FeatureNode node = default; if (feature is BlueprintParametrizedFeature) { node = parametrizedNodes .FirstOrDefault(item => item.Source != null && item.Source == selection.Source); } if (node != null || normalNodes.TryGetValue(feature, out node)) { node.Source = selection.Blueprint; node.Level = level; } else { // missing child normalNodes.Add(feature, new FeatureNode(string.Empty, level, feature, selection.Blueprint) { IsMissing = true }); } } } } // build tree foreach (var node in normalNodes.Values.Concat(parametrizedNodes).ToList()) { if (node.Source == null) { RootNodes.Add(node); } else if (normalNodes.TryGetValue(node.Source, out var parent)) { parent.ChildNodes.Add(node); } else { // missing parent parent = new FeatureNode(string.Empty, 0, node.Source, null) { IsMissing = true }; parent.ChildNodes.Add(node); normalNodes.Add(parent.Blueprint, parent); RootNodes.Add(parent); } } }