public static bool Prefix([NotNull] LevelUpState state, [NotNull] UnitDescriptor unit, [NotNull] BlueprintProgression progression) { if (!settings.toggleMulticlass) { return(false); } ProgressionData progressionData = unit.Progression.SureProgressionData(progression); int level = progressionData.Level; int nextLevel = progressionData.Blueprint.CalcLevel(unit); // TODO - this is from the mod but we need to figure out if max level 20 still makes sense with mythic levels // int maxLevel = 20 // unit.Progression.CharacterLevel; // if (nextLevel > maxLevel) // nextLevel = maxLevel; progressionData.Level = nextLevel; if (level >= nextLevel || (UnityEngine.Object)progression.ExclusiveProgression != (UnityEngine.Object)null && (UnityEngine.Object)state.SelectedClass != (UnityEngine.Object)progression.ExclusiveProgression) { return(false); } if (!progression.GiveFeaturesForPreviousLevels) { level = nextLevel - 1; } for (int i = level + 1; i <= nextLevel; ++i) { if (!AllowProceed(progression)) { break; } LevelEntry levelEntry = progressionData.GetLevelEntry(i); LevelUpHelper.AddFeaturesFromProgression(state, unit, levelEntry.Features, (FeatureSource)progression, i); } return(false); }
public static bool Prefix([NotNull] LevelUpState state, [NotNull] UnitDescriptor unit, [NotNull] BlueprintProgression progression) { if (!settings.toggleMulticlass) { return(true); } var progressionData = unit.Progression.SureProgressionData(progression); var level = progressionData.Level; var nextLevel = progressionData.Blueprint.CalcLevel(unit); progressionData.Level = nextLevel; // TODO - this is from the mod but we need to figure out if max level 20 still makes sense with mythic levels // int maxLevel = 20 // unit.Progression.CharacterLevel; // if (nextLevel > maxLevel) // nextLevel = maxLevel; Mod.Debug($"LevelUpHelper_UpdateProgression_Patch - {unit.CharacterName.orange()} - class: {state.SelectedClass} level: {level} nextLvl: {nextLevel}"); if (level >= nextLevel || progression.ExclusiveProgression != null && state.SelectedClass != progression.ExclusiveProgression) { return(false); } if (!progression.GiveFeaturesForPreviousLevels) { level = nextLevel - 1; } for (var lvl = level + 1; lvl <= nextLevel; ++lvl) { // if (!AllowProceed(progression)) break; var levelEntry = progressionData.GetLevelEntry(lvl); Mod.Debug($" LevelUpHelper_UpdateProgression_Patch - {string.Join(", ", levelEntry.Features.Select(f => f.name.yellow()))}"); LevelUpHelper.AddFeaturesFromProgression(state, unit, levelEntry.Features, (FeatureSource)progression, lvl); } return(false); }
private void SetupNewCharacher() { this.Unit.Unit.View.UpdateAsks(); this.Unit.BirthDay = this.BirthDay; this.Unit.BirthMonth = this.BirthMonth; if (this.Doll != null) { this.Unit.Doll = this.Doll.CreateData(); this.Unit.LeftHandedOverride = new bool?(this.Doll.LeftHanded); } if (this.State.Mode != LevelUpState.CharBuildMode.PreGen) { ItemsCollection.DoWithoutEvents(delegate { LevelUpHelper.AddStartingItems(this.Unit); }); } else { this.Unit.Body.Initialize(); } this.Unit.AddStartingInventory(); foreach (Spellbook spellbook in this.Unit.Spellbooks) { spellbook.UpdateAllSlotsSize(true); int num = spellbook.GetTotalFreeSlotsCount(); for (int i = 0; i < 100; i++) { if (num <= 0) { break; } foreach (BlueprintAbility blueprint in BlueprintRoot.Instance.Progression.CharGenMemorizeSpells) { AbilityData data = new AbilityData(blueprint, spellbook); spellbook.Memorize(data, null); } int totalFreeSlotsCount = spellbook.GetTotalFreeSlotsCount(); if (num <= totalFreeSlotsCount) { break; } num = totalFreeSlotsCount; } } RestController.ApplyRest(this.Unit); if (this.Unit.IsCustomCompanion() && this.State.Mode != LevelUpState.CharBuildMode.Respec) { Game.Instance.EntityCreator.AddEntity(this.Unit.Unit, Game.Instance.Player.CrossSceneState); Game.Instance.Player.RemoteCompanions.Add(this.Unit.Unit); Game.Instance.Player.InvalidateCharacterLists(); this.Unit.Unit.IsInGame = false; this.Unit.Unit.AttachToViewOnLoad(null); if (this.Unit.Unit.View != null) { this.Unit.Unit.View.transform.SetParent(Game.Instance.DynamicRoot, true); } } }
public static int?GetTotalSkillPoints(UnitDescriptor unit, int nextLevel) { var intelligenceSkillPoints = LevelUpHelper.GetTotalIntelligenceSkillPoints(unit, nextLevel); var classes = unit.Progression.Classes; var split = classes.GroupBy(cd => unit.IsClassGestalt(cd.CharacterClass)); var total = 0; var gestaltCount = 0; var baseTotal = 0; var gestaltSumOrMax = 0; foreach (var group in split) { if (group.Key == false) { baseTotal += group.ToList().Sum(cd => cd.CalcTotalSkillPointsNonMythic()); } else { var gestaltClasses = group.ToList(); gestaltCount = gestaltClasses.Count; if (gestaltCount > 0) { switch (Main.settings.multiclassSkillPointPolicy) { case ProgressionPolicy.Largest: gestaltSumOrMax += gestaltClasses.Max(cl => cl.CalcTotalSkillPointsNonMythic()); break; case ProgressionPolicy.Average: case ProgressionPolicy.Sum: gestaltSumOrMax += gestaltClasses.Sum(cl => cl.CalcTotalSkillPointsNonMythic()); break; default: break; } } } } total = Main.settings.multiclassSkillPointPolicy switch { ProgressionPolicy.Largest => Mathf.Max(baseTotal, gestaltSumOrMax), ProgressionPolicy.Average => (gestaltSumOrMax + baseTotal) / (gestaltCount + 1), ProgressionPolicy.Sum => gestaltSumOrMax + baseTotal, _ => baseTotal, }; return(Mathf.Max(intelligenceSkillPoints + total, nextLevel)); }
public static bool Prefix(LevelUpState state, UnitDescriptor unit) { if (!settings.toggleMulticlass) { return(true); } Mod.Debug($"ApplyClassMechanics_ApplyProgressions_Patch - {unit.CharacterName.orange()} - class: {state.SelectedClass} nextLevel: {state.NextClassLevel}"); BlueprintCharacterClass blueprintCharacterClass = null; if (unit.TryGetPartyMemberForLevelUpVersion(out var ch) && ch.TryGetClass(state.SelectedClass, out var cl) && state.NextClassLevel >= cl.Level ) { blueprintCharacterClass = state.SelectedClass; } //var blueprintCharacterClass = state.NextClassLevel <= 1 ? state.SelectedClass : (BlueprintCharacterClass)null; var features = unit.Progression.Features.Enumerable; var progressions = features.Select(f => f.Blueprint).OfType <BlueprintProgression>().ToList(); // this ToList is important because it prevents mutation exceptions foreach (var blueprintProgression in progressions) { var p = blueprintProgression; Mod.Debug($" prog: {p.name.yellow()}"); if (blueprintCharacterClass != null // && p.Classes.Contains<BlueprintCharacterClass>(blueprintCharacterClass)) && p.IsChildProgressionOf(unit, blueprintCharacterClass) // Mod Line replacing above ) { var feature = unit.Progression.Features.Enumerable.FirstItem(f => f.Blueprint == p); feature?.SetSource(blueprintCharacterClass, state.NextClassLevel); Mod.Debug($" feature: {feature.Name.cyan()} - levlel: {state.NextClassLevel}"); //feature?.SetSource(blueprintCharacterClass, 1); } LevelUpHelper.UpdateProgression(state, unit, p); } return(true); }
private void OnAddLevelUpFeature(int level) { Log.Write($"AddFactOnLevelUpCondtion::OnAddLevelUpFeature(), name: {Fact.Blueprint.name}"); var fact = appliedFact; if (fact == null) { return; } var feature = fact.Blueprint as BlueprintFeature; if (feature == null) { return; } // If we're in the level-up UI, update selections/progressions as needed. var unit = Owner; var levelUp = Game.Instance.UI.CharacterBuildController.LevelUpController; if (unit == levelUp.Preview || unit == levelUp.Unit) { var selection = feature as BlueprintFeatureSelection; if (selection != null) { Log.Write($"{GetType().Name}: add selection ${selection.name}"); levelUp.State.AddSelection(null, selection, selection, level); } var progression = feature as BlueprintProgression; if (progression != null) { Log.Write($"{GetType().Name}: update progression ${selection.name}"); LevelUpHelper.UpdateProgression(levelUp.State, unit, progression); } } }
public static bool Prefix(LevelUpState state, UnitDescriptor unit) { if (!settings.toggleMulticlass) { return(false); } BlueprintCharacterClass blueprintCharacterClass = state.NextClassLevel <= 1 ? state.SelectedClass : (BlueprintCharacterClass)null; foreach (BlueprintProgression blueprintProgression in unit.Progression.Features.Enumerable.Select <Feature, BlueprintFeature>((Func <Feature, BlueprintFeature>)(f => f.Blueprint)).OfType <BlueprintProgression>().ToList <BlueprintProgression>()) { BlueprintProgression p = blueprintProgression; if (blueprintCharacterClass != null // && p.Classes.Contains<BlueprintCharacterClass>(blueprintCharacterClass)) && p.IsChildProgressionOf(unit, blueprintCharacterClass) // Mod Line replacing above ) { unit.Progression.Features.Enumerable.FirstItem <Feature>( (f => f.Blueprint == p))?.SetSource((FeatureSource)blueprintCharacterClass, 1 ); } LevelUpHelper.UpdateProgression(state, unit, p); } return(true); }
public static bool Prefix([NotNull] LevelUpState state, [NotNull] UnitDescriptor unit, [NotNull] IList <BlueprintFeatureBase> features, [CanBeNull] FeatureSource source, int level) { if (!Main.IsInGame) { return(false); } #if true //Logger.Log($"feature count = {features.ToArray().Count()} "); var description = source.Blueprint.GetDescription() ?? "nil"; //Logger.Log($"source: {source.Blueprint.name} - {description}"); foreach (BlueprintFeature blueprintFeature in features.OfType <BlueprintFeature>()) { if (blueprintFeature.MeetsPrerequisites((FeatureSelectionState)null, unit, state, true)) { //Logger.Log($" name: {blueprintFeature.Name} : {blueprintFeature.GetType()}"); if (blueprintFeature is IFeatureSelection selection) { // Bug Fix - due to issues in the implementation of FeatureSelectionState.CanSelectAnything we can get level up blocked so this is an attempt to work around for that var numToAdd = settings.featsMultiplier; if (selection is BlueprintFeatureSelection bpFS) { var bpFeatures = bpFS; var items = bpFS.ExtractSelectionItems(unit, null); //Logger.Log($" items: {items.Count()}"); var availableCount = 0; foreach (var item in items) { #if false if (bpFS.is BlueprintParametrizedFeature bppF) { Logger.Log($"checking parameterized feature {bppF.Name}"); if (selection.CanSelect(unit, state, null, item)) { Logger.Log($" {item.Feature.name} is avaiable"); availableCount++; } } else #endif if (!unit.Progression.Features.HasFact(item.Feature)) { availableCount++; // Logger.Log($" {item.Feature.name} is avaiable"); } #if false if (selection.CanSelect(unit, state, null, item)) { Logger.Log($" {item.Feature.name} is avaiable"); availableCount++; } else { Logger.Log($" {item.Feature.name} is NOT avaiable"); } if (!unit.Progression.Features.HasFact(item.Feature)) { if (item.Feature.MeetsPrerequisites(null, unit, state, true)) { Logger.Log($" {item.Feature.name} is avaiable"); availableCount++; } } else { Logger.Log($" has Fact {item.Feature.Name}"); } #endif } if (numToAdd > availableCount) { Logger.Log($"reduced numToAdd: {numToAdd} -> {availableCount}"); numToAdd = availableCount; } } //Logger.Log($" IFeatureSelection: {selection} adding: {numToAdd}"); for (int i = 0; i < numToAdd; ++i) { state.AddSelection((FeatureSelectionState)null, source, selection, level); } } Kingmaker.UnitLogic.Feature feature = (Kingmaker.UnitLogic.Feature)unit.AddFact((BlueprintUnitFact)blueprintFeature); BlueprintProgression progression = blueprintFeature as BlueprintProgression; if ((UnityEngine.Object)progression != (UnityEngine.Object)null) { //Logger.Log($" BlueprintProgression: {progression}"); LevelUpHelper.UpdateProgression(state, unit, progression); } FeatureSource source1 = source; int level1 = level; feature.SetSource(source1, level1); }