From 3b4b5aa1e0e2f2f4c5b0a0ac65d2933a449fedb9 Mon Sep 17 00:00:00 2001 From: Lynn Pye Date: Tue, 8 Nov 2022 14:29:08 -0600 Subject: [PATCH] added scaling skills, code cleanup --- ChampionFeats/ChampionFeats.csproj | 1 + ChampionFeats/ChampionFeatsPatcher.cs | 28 ++++- .../Components/AddScalingSavingThrows.cs | 7 +- .../Components/AddScalingSkillBonus.cs | 114 ++++++++++++++++++ ChampionFeats/Config/Blueprints.cs | 10 +- ChampionFeats/Config/Blueprints.json | 21 ++-- ChampionFeats/Main.cs | 8 ++ ChampionFeats/Settings.cs | 3 + Info.json | 2 +- 9 files changed, 178 insertions(+), 16 deletions(-) create mode 100644 ChampionFeats/Components/AddScalingSkillBonus.cs diff --git a/ChampionFeats/ChampionFeats.csproj b/ChampionFeats/ChampionFeats.csproj index 493065c..e2c7b97 100644 --- a/ChampionFeats/ChampionFeats.csproj +++ b/ChampionFeats/ChampionFeats.csproj @@ -131,6 +131,7 @@ + diff --git a/ChampionFeats/ChampionFeatsPatcher.cs b/ChampionFeats/ChampionFeatsPatcher.cs index a6558fa..0496975 100644 --- a/ChampionFeats/ChampionFeatsPatcher.cs +++ b/ChampionFeats/ChampionFeatsPatcher.cs @@ -206,7 +206,9 @@ static void AddChampionDefences() } bp.Ranks = 1; bp.SetName("Champion Saves"); - bp.SetDescription(string.Format("Your natural ability to avoid danger protects you from harm. You gain +{0} to all saving throws per level.", Main.settings.ScalingSaveBonusPerLevel)); + string stepString = getStepString(Main.settings.ScalingSaveLevelsPerStep); + bp.SetDescription(string.Format("Your natural ability to avoid danger protects you from harm. You gain +{0} to all saving throws. {1} level beyond that, increases it by +{0}.", + Main.settings.ScalingSaveBonusPerLevel, stepString)); bp.m_DescriptionShort = bp.m_Description; bp.AddComponent(Helpers.Create()); @@ -229,6 +231,28 @@ static void AddChampionDefences() static void AddChampionOffences() { + var ChampionSkills = Helpers.CreateBlueprint(AddScalingSkillBonus.BLUEPRINTNAME, bp => + { + bp.IsClassFeature = true; + bp.ReapplyOnLevelUp = true; + if (!Main.settings.FeatsAreMythic) + { + bp.Groups = new FeatureGroup[] { FeatureGroup.CombatFeat, FeatureGroup.Feat }; + } + else + { + bp.Groups = new FeatureGroup[] { FeatureGroup.MythicFeat }; + } + bp.Ranks = 1; + bp.SetName("Champion Skills"); + string stepString = getStepString(Main.settings.ScalingSkillsLevelsPerStep); + bp.SetDescription(string.Format("Your prowess knows no boundaries, picking up new skills at an inexplicable pace. You gain +{0} to all skills. {1} level beyond that, this bonus increases by +{0}.", + Main.settings.ScalingSkillsBonusPerLevel, stepString)); + bp.m_DescriptionShort = bp.m_Description; + + bp.AddComponent(Helpers.Create()); + }); + var ChampionOffenceAB = Helpers.CreateBlueprint(AddScalingAttackBonus.BLUEPRINTNAME, bp => { bp.IsClassFeature = true; bp.ReapplyOnLevelUp = true; @@ -274,11 +298,13 @@ static void AddChampionOffences() if (!Main.settings.FeatsAreMythic) { + FeatTools.AddAsFeat(ChampionSkills); FeatTools.AddAsFeat(ChampionOffenceAB); FeatTools.AddAsFeat(ChampionOffenceDam); } else { + FeatTools.AddAsMythicFeats(ChampionSkills); FeatTools.AddAsMythicFeats(ChampionOffenceAB); FeatTools.AddAsMythicFeats(ChampionOffenceDam); } diff --git a/ChampionFeats/Components/AddScalingSavingThrows.cs b/ChampionFeats/Components/AddScalingSavingThrows.cs index b3b35b8..0bdf032 100644 --- a/ChampionFeats/Components/AddScalingSavingThrows.cs +++ b/ChampionFeats/Components/AddScalingSavingThrows.cs @@ -45,8 +45,11 @@ private static void UpdateSavingThrows() foreach (var unit in Game.Instance.State.Units) { Feature feature = unit.GetFeature(Resources.GetModBlueprint(BLUEPRINTNAME)); - feature.TurnOff(); - feature.TurnOn(); + if (feature != null) + { + feature.TurnOff(); + feature.TurnOn(); + } } } diff --git a/ChampionFeats/Components/AddScalingSkillBonus.cs b/ChampionFeats/Components/AddScalingSkillBonus.cs new file mode 100644 index 0000000..2d33d5b --- /dev/null +++ b/ChampionFeats/Components/AddScalingSkillBonus.cs @@ -0,0 +1,114 @@ +using Kingmaker; +using Kingmaker.Blueprints; +using Kingmaker.Blueprints.Classes; +using Kingmaker.Blueprints.Facts; +using Kingmaker.Blueprints.JsonSystem; +using Kingmaker.EntitySystem; +using Kingmaker.EntitySystem.Entities; +using Kingmaker.EntitySystem.Stats; +using Kingmaker.UnitLogic; +using Kingmaker.UnitLogic.Buffs.Blueprints; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace ChampionFeats.Components +{ + [AllowedOn(typeof(BlueprintBuff))] + [AllowedOn(typeof(BlueprintFeature))] + [AllowedOn(typeof(BlueprintUnitFact), false)] + [AllowMultipleComponents] + [TypeId("9804852F50534445A3A51769CC00DD80")] + public class AddScalingSkillBonus : UnitFactComponentDelegate + { + public const string BLUEPRINTNAME = "RMChampionFeatSkills"; + + public static void OnSettingsSave() + { + UpdateSkillBonuses(); + } + + private static void UpdateSkillBonuses() + { + foreach (var unit in Game.Instance.State.Units) + { + Feature feature = unit.GetFeature(Resources.GetModBlueprint(BLUEPRINTNAME)); + if (feature != null) + { + feature.TurnOff(); + feature.TurnOn(); + } + } + } + + private static void RemoveSkillBonus(UnitEntityData unit, StatType skillType) + { + SkillModifier modToRemove = null; + foreach (var list in unit.Stats.GetStat(skillType).ModifierList) + { + foreach (var mod in list.Value) + { + if (mod is SkillModifier) + { + modToRemove = (SkillModifier)mod; + } + if (modToRemove != null) + { + break; + } + } + if (modToRemove != null) + { + break; + } + } + if (modToRemove != null) + { + unit.Stats.GetStat(skillType).RemoveModifier(modToRemove); + } + } + + private static void RemoveSkillBonuses(UnitEntityData unit, EntityFactComponent runtime) + { + foreach (StatType type in StatTypeHelper.Skills) + { + RemoveSkillBonus(unit, type); + } + } + + private static void AddSkillBonuses(UnitEntityData unit, EntityFactComponent runtime) + { + foreach (StatType type in StatTypeHelper.Skills) + { + unit.Stats.GetStat(type).AddModifier(GetNewModifier(unit, runtime)); + } + } + + private static ModifiableValue.Modifier GetNewModifier(UnitEntityData unit, EntityFactComponent runtime) + { + return new SkillModifier() + { + ModDescriptor = Kingmaker.Enums.ModifierDescriptor.UntypedStackable, + Source = runtime.Fact, + ModValue = (((unit.Progression.CharacterLevel - 1) / Main.settings.ScalingSkillsLevelsPerStep) + 1) * Main.settings.ScalingSkillsBonusPerLevel + }; + } + + public override void OnTurnOff() + { + RemoveSkillBonuses(base.Owner, base.Runtime); + } + + public override void OnTurnOn() + { + AddSkillBonuses(base.Owner, base.Runtime); + } + } + + public class SkillModifier : ModifiableValue.Modifier + { + } +} diff --git a/ChampionFeats/Config/Blueprints.cs b/ChampionFeats/Config/Blueprints.cs index 28f232b..1884597 100644 --- a/ChampionFeats/Config/Blueprints.cs +++ b/ChampionFeats/Config/Blueprints.cs @@ -145,7 +145,10 @@ public override void RunAction() foreach (var u in Game.Instance.State.Units) { BlueprintFeature feat = Resources.GetModBlueprint(AddScalingSavingThrows.BLUEPRINTNAME); - u.GetFeature(feat).TurnOff(); + u.GetFeature(feat)?.TurnOff(); + + feat = Resources.GetModBlueprint(AddScalingSkillBonus.BLUEPRINTNAME); + u.GetFeature(feat)?.TurnOff(); } } } @@ -162,7 +165,10 @@ public override void RunAction() foreach (var u in Game.Instance.State.Units) { BlueprintFeature feat = Resources.GetModBlueprint(AddScalingSavingThrows.BLUEPRINTNAME); - u.GetFeature(feat).TurnOn(); + u.GetFeature(feat)?.TurnOn(); + + feat = Resources.GetModBlueprint(AddScalingSkillBonus.BLUEPRINTNAME); + u.GetFeature(feat)?.TurnOn(); } } } diff --git a/ChampionFeats/Config/Blueprints.json b/ChampionFeats/Config/Blueprints.json index 964c558..a0e816c 100644 --- a/ChampionFeats/Config/Blueprints.json +++ b/ChampionFeats/Config/Blueprints.json @@ -1,15 +1,16 @@ { "OverrideIds": false, - "NewBlueprints": { - "RMChampionFeatDefenceDR": "ab678c3f-346e-44cf-8ad5-c157324e8c28", - "RMChampionFeatDefenceAC": "d0f2447e-6aa3-4dce-8f7f-17a5baeff9dc", - "RMChampionFeatOffenceAim": "c60fe592-1c11-4c89-9bdc-5a7e76344412", - "RMChampionFeatOffenceDam": "ea14baff-008f-4bf1-b492-26581ca67de9", - "RMChampionFeatOffenceSpellDam": "d9538dec-e371-4d71-803a-18ede627638b", - "RMChampionFeatOffenceSpellDC": "b666f5b3-ee66-4b0f-9cb9-e9c974858982", - "RMChampionFeatOffenceSpellPen": "042a76ff-d6e1-4b86-8765-16da19fdbe6d", - "RMChampionFeatSavingThrow": "D09E14DC-C147-4870-8E79-AE101363676D" - }, + "NewBlueprints": { + "RMChampionFeatDefenceDR": "ab678c3f-346e-44cf-8ad5-c157324e8c28", + "RMChampionFeatDefenceAC": "d0f2447e-6aa3-4dce-8f7f-17a5baeff9dc", + "RMChampionFeatOffenceAim": "c60fe592-1c11-4c89-9bdc-5a7e76344412", + "RMChampionFeatOffenceDam": "ea14baff-008f-4bf1-b492-26581ca67de9", + "RMChampionFeatOffenceSpellDam": "d9538dec-e371-4d71-803a-18ede627638b", + "RMChampionFeatOffenceSpellDC": "b666f5b3-ee66-4b0f-9cb9-e9c974858982", + "RMChampionFeatOffenceSpellPen": "042a76ff-d6e1-4b86-8765-16da19fdbe6d", + "RMChampionFeatSavingThrow": "D09E14DC-C147-4870-8E79-AE101363676D", + "RMChampionFeatSkills": "A21CE248-AC0F-4851-89A4-70A0BD87E0AF" + }, "AutoGenerated": {}, "UnusedGUIDs": {} } \ No newline at end of file diff --git a/ChampionFeats/Main.cs b/ChampionFeats/Main.cs index 4e25d79..7cc6423 100644 --- a/ChampionFeats/Main.cs +++ b/ChampionFeats/Main.cs @@ -43,6 +43,7 @@ private static void OnSaveGUI(UnityModManager.ModEntry modEntry) { settings.Save(modEntry); AddScalingSavingThrows.OnSettingsSave(); + AddScalingSkillBonus.OnSettingsSave(); } private static void vert10() @@ -92,6 +93,13 @@ private static void OnGUI(UnityModManager.ModEntry modEntry) GUILayout.Label(String.Format("Bonus Per Level: {0}", settings.ScalingSaveBonusPerLevel), options); settings.ScalingSaveBonusPerLevel = Mathf.RoundToInt(GUILayout.HorizontalSlider(settings.ScalingSaveBonusPerLevel, 1, 10, options)); + vert10(); + GUILayout.Label("Champion Skills (Skill Bonus):", options); + GUILayout.Label(String.Format("Levels Per Step: {0}", settings.ScalingSkillsLevelsPerStep), options); + settings.ScalingSkillsLevelsPerStep = Mathf.RoundToInt(GUILayout.HorizontalSlider(settings.ScalingSkillsLevelsPerStep, 1, 10, options)); + GUILayout.Label(String.Format("Bonus Per Step: {0}", settings.ScalingSkillsBonusPerLevel), options); + settings.ScalingSkillsBonusPerLevel = Mathf.RoundToInt(GUILayout.HorizontalSlider(settings.ScalingSkillsBonusPerLevel, 1, 10, options)); + vert10(); GUILayout.Label("Champion Aim (Weapon AB):", options); GUILayout.Label(String.Format("Levels Per Step: {0}", settings.ScalingABLevelsPerStep), options); diff --git a/ChampionFeats/Settings.cs b/ChampionFeats/Settings.cs index d2a859b..7f13226 100644 --- a/ChampionFeats/Settings.cs +++ b/ChampionFeats/Settings.cs @@ -25,6 +25,9 @@ public override void Save(UnityModManager.ModEntry modEntry) // Champion Saves public int ScalingSaveLevelsPerStep = 1; public int ScalingSaveBonusPerLevel = 2; + // Champion Skills + public int ScalingSkillsLevelsPerStep = 2; + public int ScalingSkillsBonusPerLevel = 1; // Champion Aim public int ScalingABLevelsPerStep = 2; public int ScalingABBonusPerStep = 1; diff --git a/Info.json b/Info.json index 82883ff..caf0897 100644 --- a/Info.json +++ b/Info.json @@ -2,7 +2,7 @@ "Id": "ChampionFeatsAnew", "DisplayName": "Champion Feats Anew", "Author": "RealityMachina, lynnpye", - "Version": "1.0.12", + "Version": "1.0.13", "ManagerVersion": "0.23.0.0", "GameVersion": "1.0.0s", "Requirements": [],