/* * Refer MainMenu.StartChargen which also calls CharacterBuildController.HandleLevelUpStart * */ internal static void TestLevelup() { var unit = CreateUnit(); var descriptorJson = UnitSerialization.Serialize(unit.Descriptor);; if (Main.settings.ShowDollRoom) { ShowDollRoom(unit); } CharacterBuildController characterBuildController = Game.Instance.UI.CharacterBuildController; LevelPlanManager.CurrentLevelUpController = LevelUpController.Start( unit: unit.Descriptor, instantCommit: false, unitJson: descriptorJson, onSuccess: null, mode: LevelUpState.CharBuildMode.CharGen); /*CurrentLevelUpController.SelectPortrait(Game.Instance.BlueprintRoot.CharGen.Portraits[0]); * CurrentLevelUpController.SelectGender(Gender.Male); * CurrentLevelUpController.SelectRace(Game.Instance.BlueprintRoot.Progression.CharacterRaces[0]); * CurrentLevelUpController.SelectAlignment(Kingmaker.Enums.Alignment.TrueNeutral); * CurrentLevelUpController.SelectVoice(Game.Instance.BlueprintRoot.CharGen.MaleVoices[0]); * CurrentLevelUpController.SelectName("LevelPlan");*/ Traverse.Create(characterBuildController).Property <LevelUpController>("LevelUpController").Value = LevelPlanManager.CurrentLevelUpController; characterBuildController.Unit = unit.Descriptor; characterBuildController.Show(true); }
static void Prefix(LevelUpController __instance, BlueprintCharacterClass characterClass, bool applyMechanics) { if (IsAvailable()) { Core.Debug($"{nameof(LevelUpController)}.{nameof(LevelUpController.SelectClass)}({characterClass}, {applyMechanics})"); } }
static void Prefix(LevelUpController __instance) { if (Core.Enabled) { Core.Mod.LevelUpController = __instance; } }
static void Prefix(LevelUpController __instance, UnitDescriptor unit, bool autoCommit, JToken unitJson, LevelUpState.CharBuildMode mode) { if (Core.Enabled) { Core.Debug($"{nameof(LevelUpController)}..ctor({unit}, {(autoCommit ? "isAutoCommit" : "notAutoCommit")}, {unitJson?.Type}, {mode})"); } }
/* * Uses the CharacterBuildController to edit level plans * Refer MainMenu.StartChargen which sets up the state and then calls CharacterBuildController.HandleLevelUpStart * */ public static void EditLevelPlan(LevelPlanHolder levelPlanHolder, int level) { var unit = levelPlanHolder.CreateUnit(level); if (Main.settings.ShowDollRoom) { ShowDollRoom(unit); } CharacterBuildController characterBuildController = Game.Instance.UI.CharacterBuildController; var mode = level == 1 ? LevelUpState.CharBuildMode.CharGen : LevelUpState.CharBuildMode.LevelUp; CurrentLevelUpController = LevelUpController.Start( unit: unit.Descriptor, instantCommit: false, unitJson: null, onSuccess: null, mode: mode); CurrentLevelUpController.SelectPortrait(Game.Instance.BlueprintRoot.CharGen.Portraits[0]); CurrentLevelUpController.SelectGender(Gender.Male); CurrentLevelUpController.SelectRace(Game.Instance.BlueprintRoot.Progression.CharacterRaces[0]); CurrentLevelUpController.SelectAlignment(Kingmaker.Enums.Alignment.TrueNeutral); CurrentLevelUpController.SelectVoice(Game.Instance.BlueprintRoot.CharGen.MaleVoices[0]); CurrentLevelUpController.SelectName("LevelPlan"); Traverse.Create(characterBuildController).Property <LevelUpController>("LevelUpController").Value = CurrentLevelUpController; Traverse.Create(characterBuildController).Field("Mode").SetValue(CurrentLevelUpController.State.Mode); Traverse.Create(characterBuildController).Field("Unit").SetValue(unit.Descriptor); characterBuildController.Show(true); }
static void Postfix(LevelUpController __instance) { if (!Settings.StateManager.State.cheatCombineParametrizedFeats) { return; } Main.DebugLog("Commit: Char=" + __instance.Unit?.CharacterName); if (__instance.State == null || __instance.State.Selections == null) { return; } foreach (var selection in __instance.State.Selections) { if (selection.SelectedItem?.Feature?.AssetGuid == null || selection.SelectedItem.Param?.WeaponCategory == null) { continue; } Main.DebugLog("Selection: " + selection.SelectedItem.Name); if (guid_list.Contains(selection.SelectedItem.Feature.AssetGuid)) { Process(__instance.Unit, selection.SelectedItem.Feature.AssetGuid, selection.SelectedItem.Param.WeaponCategory.Value); } } }
private LevelUpController AddLevel(UnitDescriptor unit, Dictionary <SelectionEntry, HashSet <int> > selectionsHistory, HashSet <int> spellHistory) { LevelUpController levelUpController = LevelUpController.Start(unit, true, null, null, LevelUpState.CharBuildMode.LevelUp); if (levelUpController.State.CanSelectRace) { BlueprintRace race = unit.Progression.Race; DefaultBuildData data = ElementsContext.GetData <DefaultBuildData>(); if (data != null) { race = data.Race; } if (race != null) { levelUpController.SelectRace(race); } } if (levelUpController.State.CanSelectRaceStat) { levelUpController.SelectRaceStat(instance.RaceStat); } this.ApplyStatsDistributionPreset(levelUpController); if (unit.Progression.GetClassLevel(instance.CharacterClass) <= 0) { foreach (BlueprintArchetype archetype in instance.Archetypes) { levelUpController.AddArchetype(instance.CharacterClass, archetype); } } levelUpController.SelectClass(instance.CharacterClass, false); levelUpController.ApplyClassMechanics(); this.PerformSelections(levelUpController, selectionsHistory, new LevelUpActionPriority?(LevelUpActionPriority.ReplaceSpellbook)); levelUpController.ApplySpellbook(); while (levelUpController.State.AttributePoints > 0 && instance.LevelsStat.IsAttribute()) { levelUpController.SpendAttributePoint(instance.LevelsStat); } this.PerformSelections(levelUpController, selectionsHistory, new LevelUpActionPriority?(LevelUpActionPriority.ApplySkillPoints)); levelUpController.ApplySkillPoints(); while (levelUpController.State.SkillPointsRemaining > 0) { int skillPointsRemaining = levelUpController.State.SkillPointsRemaining; foreach (StatType skill in instance.Skills) { if (levelUpController.State.SkillPointsRemaining <= 0) { break; } levelUpController.SpendSkillPoint(skill); } if (skillPointsRemaining == levelUpController.State.SkillPointsRemaining) { break; } } this.PerformSelections(levelUpController, selectionsHistory, null); this.PerformSpellSelections(levelUpController, spellHistory); return(levelUpController); }
public static bool IsManualPlayerUnit(this LevelUpController controller, bool allowPet = false, bool allowAutoCommit = false, bool allowPregen = false) { return(controller != null && controller.Unit.IsPlayerFaction && (allowPet || !controller.Unit.IsPet) && (allowAutoCommit || !controller.AutoCommit) && (allowPregen || !controller.State.IsPreGen())); }
private static bool Prefix(LevelUpController __instance) { if (Main.Enabled) { MultipleClasses.levelUpController = __instance; } return(true); }
public LevelUpState(StateMachine stateMachine, PlayerService playerService) : base(stateMachine) { _playerService = playerService; _levelUpModel = new LevelUpModel(); _spriteBatch = new SpriteBatch(StateMachine.Game.GraphicsDevice); _view = new LevelUpView(StateMachine.Game.Content, _spriteBatch, _levelUpModel, _playerService); _controller = new LevelUpController(_levelUpModel, _playerService); }
static bool Prefix(LevelUpController __instance) { if (Main.Enabled) { levelUpController = __instance; } return(true); }
private static void Prefix(LevelUpController __instance) { if (IsAvailable()) { // This is the critical place that gets called once before we go through all the level computations for setting up the level up screen Mod.Debug("LevelUpController_UpdatePreview_Patch"); //Main.multiclassMod.AppliedMulticlassSet.Clear(); //Main.multiclassMod.UpdatedProgressions.Clear(); } }
public void ApplyPlanAsFarAsPossible() { int effectiveLevel = LevelUpController.GetEffectiveLevel(this.Unit.Unit); while (this.Preview.Progression.CharacterLevel < effectiveLevel && this.HasNextLevelPlan) { this.ApplyLevelUpPlan(true); this.Commit(); } }
static void Postfix(LevelUpController __instance) { if (IsAvailable()) { if (__instance.State.IsCharGen() && __instance.Unit.IsCustomCompanion() && CharGenSet.Count > 0) { CompanionSets.Add(__instance.Unit.CharacterName, new HashSet <string>(CharGenSet)); CharGenSet.Clear(); } } }
public static bool IsManualPlayerUnit(this LevelUpController controller, bool allowPet = false, bool allowAutoCommit = false, bool allowPregen = false) => //Main.Log($"controller: {controller} AutoCommit: {controller.AutoCommit}"); //Main.Log($" unit: {controller.Unit} isPlayerFaction: {controller.Unit.IsPlayerFaction} isPet: {controller.Unit.IsPet}"); //Main.Log($" levelup state: {controller.State}"); controller != null && controller.Unit.IsPlayerFaction && (allowPet || !controller.Unit.IsPet //&& (allowAutoCommit || !controller.AutoCommit) //&& (allowPregen || !controller.State.IsPreGen() );
public override void OnFactActivate() { // Note: this is different from the other favored class bonus components, // because the feature remains on the character, and kicks in at each level up. LevelUpController levelUp = Game.Instance.UI.CharacterBuildController.LevelUpController; if (levelUp.State.NextLevel == 1 && (Owner == levelUp.Preview || Owner == levelUp.Unit)) { // Handle the level 1 hit point adjustment in the character generator. Apply(levelUp.State); } }
static void Postfix(LevelUpController __instance) { if (IsAvailable()) { var charGenMulticlassSet = settings.charGenMulticlassSet; if (__instance.State.IsCharGen() && __instance.Unit.IsCustomCompanion() && charGenMulticlassSet.Count > 0) { __instance.Unit.SetMulticlassSet(charGenMulticlassSet); } } }
/* * Refer AddClassLevels.LevelUp and Player.CreateCustomCompanion */ public UnitEntityData CreateUnit(int level) { //var playerUnit = ResourcesLibrary.TryGetBlueprint<BlueprintUnit>("4391e8b9afbb0cf43aeba700c089f56d"); //var unit = new UnitDescriptor(playerUnit, null); var unit = Main.settings.DefaultPointBuy25 ? Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.DefaultPlayerCharacter) : Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.CustomCompanion); ApplyLevelPlan(unit.Descriptor); for (int i = 0; i < level; i++) { var levelUpController = LevelUpController.Start(unit.Descriptor, true); } return(unit); }
static void Prefix(LevelUpController __instance, UnitDescriptor unit, bool autoCommit, LevelUpState.CharBuildMode mode) { if (IsAvailable() && unit.Progression.CharacterLevel > 0 && unit.IsPlayerFaction && !unit.IsPet && !autoCommit && mode != LevelUpState.CharBuildMode.PreGen) { Core.Mod.IsLevelLocked = true; } else if (Core.Enabled) { Core.Mod.IsLevelLocked = false; } }
static void CreateLevelPlan() { var unit = Game.Instance.Player.MainCharacter.Value.Descriptor; var unitJson = UnitSerialization.Serialize(unit); CharacterBuildController characterBuildController = Game.Instance.UI.CharacterBuildController; CurrentLevelUpController = LevelUpController.Start( unit: unit, instantCommit: false, unitJson: unitJson, onSuccess: null, mode: LevelUpState.CharBuildMode.PreGen); Traverse.Create(characterBuildController).Property <LevelUpController>("LevelUpController").Value = CurrentLevelUpController; Traverse.Create(characterBuildController).Field("Mode").SetValue(CurrentLevelUpController.State.Mode); Traverse.Create(characterBuildController).Field("Unit").SetValue(unit); characterBuildController.Show(true); }
private void ApplyStatsDistributionPreset(LevelUpController controller) { if (instance.Fact == null) { return; } LevelUpState state = controller.State; if (!state.StatsDistribution.Available) { return; } StatsDistributionPreset statsDistributionPreset = instance.Fact.Blueprint.GetComponents <StatsDistributionPreset>().FirstOrDefault((StatsDistributionPreset sd) => sd.TargetPoints == state.StatsDistribution.Points); if (statsDistributionPreset == null) { return; } controller.ApplyStatsDistributionPreset(statsDistributionPreset); }
private void LevelUp(UnitDescriptor unit, int levels, bool fromFact) { using (new IgnorePrerequisites()) { ClassLevelLimit component = unit.Blueprint.GetComponent <ClassLevelLimit>(); int classLevelLimit = component == null ? int.MaxValue : component.LevelLimit; if (ElementsContext.GetData <DefaultBuildData>() != null) { classLevelLimit = 0; } Dictionary <SelectionEntry, HashSet <int> > selectionsHistory = new Dictionary <SelectionEntry, HashSet <int> >(); HashSet <int> spellHistory = (instance.SelectSpells.Length <= 0) ? null : new HashSet <int>(); for (int i = 0; i < levels; i++) { if (unit.Progression.CharacterLevel < classLevelLimit) { Main.Log($"A: Adding level {i} unitlevel {unit.Progression.CharacterLevel}"); this.AddLevel(unit, selectionsHistory, spellHistory); } else { Main.Log($"B: Adding level {i} unitlevel {unit.Progression.CharacterLevel}"); LevelUpPlanUnitHolder levelUpPlanUnitHolder = unit.Get <LevelUpPlanUnitHolder>(); if (levelUpPlanUnitHolder != null) { UnitDescriptor unitDescriptor = levelUpPlanUnitHolder.RequestPlan(); LevelUpController levelUpController = this.AddLevel(unitDescriptor, selectionsHistory, spellHistory); unit.Progression.AddLevelPlan(levelUpController.GetPlan()); } } } this.PrepareSpellbook(unit); unit.Progression.ReapplyFeaturesOnLevelUp(); UnitEntityView view = unit.Unit.View; if (view != null) { view.UpdateClassEquipment(); } RestController.ApplyRest(unit); } }
private void PerformSpellSelections(LevelUpController controller, HashSet <int> spellHistory) { for (int i = 0; i < instance.SelectSpells.Length; i++) { BlueprintAbility spell = instance.SelectSpells[i]; if (!spellHistory.Contains(i)) { foreach (SpellSelectionData spellSelectionData in controller.State.SpellSelections) { if (spellSelectionData.HasEmpty()) { int level = spellSelectionData.SpellList.GetLevel(spell); if (level >= 0) { SpellSelectionData.SpellSelectionState spellSelectionState = spellSelectionData.LevelCount[level]; BlueprintAbility[] array = ((spellSelectionState != null) ? spellSelectionState.SpellSelections : null) ?? ((spellSelectionData.ExtraMaxLevel < level) ? null : spellSelectionData.ExtraSelected); if (array != null) { int slotIndex = 0; for (int j = 0; j < array.Length; j++) { if (array[j] == null) { slotIndex = j; break; } } if (controller.SelectSpell(spellSelectionData.Spellbook, spellSelectionData.SpellList, level, spell, slotIndex)) { spellHistory.Add(i); break; } } } } } } } }
public override void OnFactActivate() { try { Log.Write($"{GetType()}.OnFactActivate(), applied rank? {appliedRank}"); int rank = Fact.GetRank(); if (appliedRank >= rank) { return; } // If we're in the level-up UI, apply the component LevelUpController levelUp = Game.Instance.UI.CharacterBuildController.LevelUpController; if (Owner == levelUp.Preview || Owner == levelUp.Unit) { for (; appliedRank < rank; appliedRank++) { Apply(levelUp.State); } } } catch (Exception e) { Log.Error(e); } }
private static void Postfix(CharGenClassSelectorItemVM __instance, BlueprintCharacterClass cls, BlueprintArchetype archetype, LevelUpController levelUpController, INestedListSource source, ReactiveProperty <CharGenClassSelectorItemVM> selectedArchetype, ReactiveProperty <TooltipBaseTemplate> tooltipTemplate, bool prerequisitesDone, bool canSelect, bool allowSwitchOff) { if (__instance.HasClassLevel) { var classData = levelUpController.Unit.Progression.GetClassData(cls); if (!classData.Archetypes.Any()) { return; } var name = classData.ArchetypesName(); var DisplayName = AccessTools.Field(typeof(CharGenClassSelectorItemVM), "DisplayName"); DisplayName.SetValue(__instance, $"{cls.Name} — {name}"); } }
static bool Prefix(LevelUpController __instance, [CanBeNull] JToken unitJson) { EventBus.RaiseEvent <ILevelUpStartHandler>((Action <ILevelUpStartHandler>)(h => h.HandleLevelUpStart(__instance.Unit))); return(true); }
void Start() { Leveller = this; setVillage(); updating = false; }
/* * Create a level plan from BlueprintCharacterClass' defaultBuild * Refer AddClassLevels.LevelUp and LevelController.ApplyStatsDistributionPreset * LevelUpController.SelectDefaultClassBuild and CharacterBuildController.LoadDefaultProgression * * AddClassLevels and StatsDistributionPreset are both components of * BlueprintCharacterClass.DefaultBuild */ public LevelPlanHolder(BlueprintCharacterClass defaultClass) { bool IsDefaultBuildPriority(LevelUpActionPriority priority) { return(priority != LevelUpActionPriority.Visual && priority != LevelUpActionPriority.Race && priority != LevelUpActionPriority.Class && priority != LevelUpActionPriority.ApplyClass && priority != LevelUpActionPriority.ApplySpellbook && priority != LevelUpActionPriority.ApplySkillPoints && priority != LevelUpActionPriority.Alignment); } using (new CodeTimer("Create default build")) { var defaultBuild = defaultClass.DefaultBuild; var addClassLevels = defaultBuild.GetComponent <AddClassLevels>(); var targetPoints = Main.settings.DefaultPointBuy25 ? 25 : 20; var stats = defaultBuild.GetComponents <StatsDistributionPreset>().FirstOrDefault(sd => sd.TargetPoints == targetPoints); //var race = Game.Instance.BlueprintRoot.Progression.CharacterRaces[0]; var race = ResourcesLibrary.TryGetBlueprint <BlueprintRace>("5c4e42124dc2b4647af6e36cf2590500"); UnitEntityData unit = Main.settings.DefaultPointBuy25 ? Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.DefaultPlayerCharacter) : Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.CustomCompanion); var levelUpController = LevelUpController.Start(unit.Descriptor, instantCommit: true, mode: LevelUpState.CharBuildMode.CharGen); if (!levelUpController.SelectPortrait(Game.Instance.BlueprintRoot.CharGen.Portraits[0])) { throw new Exception("Error selecting portrait"); } if (!levelUpController.SelectGender(Gender.Male)) { throw new Exception("Error selecting gender"); } if (!levelUpController.SelectRace(race)) { throw new Exception("Error selecting race"); } //Default build must be aquired after selecting race but before selecting class levelUpController.Unit.Ensure <LevelUpPlanUnitHolder>(); levelUpController.Unit.Progression.DropLevelPlans(); levelUpController.Unit.AddFact(defaultBuild, null, null); LevelPlanData levelPlan = levelUpController.Unit.Progression.GetLevelPlan(levelUpController.State.NextLevel); if (!levelUpController.SelectClass(defaultClass)) { throw new Exception("Error selecting class"); } levelUpController.LevelUpActions.RemoveAll((ILevelUpAction a) => IsDefaultBuildPriority(a.Priority)); levelUpController.LevelUpActions.AddRange(from a in levelPlan.Actions where IsDefaultBuildPriority(a.Priority) select a); levelUpController.LevelUpActions = (from a in levelUpController.LevelUpActions orderby a.Priority select a).ToList(); if (!levelUpController.SelectAlignment(Kingmaker.Enums.Alignment.TrueNeutral)) { throw new Exception("Error selecting alignment"); } if (!levelUpController.SelectName($"Default {defaultClass.Name} Build")) { throw new Exception("Error selecting name"); } for (int i = 0; i < 20; i++) { var plan = unit.Descriptor.Progression.GetLevelPlan(i + 1); LevelPlanData[i] = plan; } LevelPlanData[0] = new LevelPlanData(1, levelUpController.LevelUpActions.ToArray()); } using (new CodeTimer("Verify default build")) { VerifyLevelPlan(); } }
/* * Verify that a level plan is valid. We do this by creating a test unit and try to level it up with the leveling plan * Refer LevelUpController, LevelUpState.IsComplete CharacterBuildController.Next * CharBPhase.IsUnlocked */ void VerifyLevelPlan() { var unitEntityData = Main.settings.DefaultPointBuy25 ? Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.DefaultPlayerCharacter) : Game.Instance.CreateUnitVacuum(BlueprintRoot.Instance.CustomCompanion); for (int i = 0; i < 20; i++) { if (i > 0) { ValidLevels[i] = false; Message[i] = "TODO"; continue; } var levelUpLog = new List <string>(); var mode = i == 0 ? LevelUpState.CharBuildMode.CharGen : LevelUpState.CharBuildMode.LevelUp; var levelUpController = LevelUpController.Start(unitEntityData.Descriptor, instantCommit: false, mode: mode); if (LevelPlanData[i] == null) { throw new Exception($"Level plan is null for index {i}"); } if (LevelPlanData[i].Actions == null) { throw new Exception($"Actions not set for level plan {i}, level {LevelPlanData[i].Level}"); } foreach (var action in LevelPlanData[i].Actions) { if (!action.Check(levelUpController.State, unitEntityData.Descriptor)) { levelUpLog.Add($"Invalid action: {Util.MakeActionReadable(action)}"); } else { levelUpController.LevelUpActions.Add(action); action.Apply(levelUpController.State, unitEntityData.Descriptor); levelUpController.State.OnApplyAction(); } } unitEntityData.Descriptor.Progression.ReapplyFeaturesOnLevelUp(); ValidLevels[i] = levelUpController.State.IsComplete() && levelUpLog.Count == 0; if (!levelUpController.State.IsComplete()) { if (!levelUpController.State.StatsDistribution.IsComplete()) { levelUpLog.Add("Stat Distribution is incomplete"); } if (levelUpController.State.CanSelectAlignment) { levelUpLog.Add("Alignment not selected"); } if (levelUpController.State.CanSelectRace) { levelUpLog.Add("Race not selected"); } if (levelUpController.State.CanSelectRaceStat) { levelUpLog.Add("CanSelectRaceStat"); } if (levelUpController.State.CanSelectName) { levelUpLog.Add("CanSelectName"); } if (levelUpController.State.CanSelectPortrait) { levelUpLog.Add("CanSelectPortrait"); } if (levelUpController.State.CanSelectGender) { levelUpLog.Add("CanSelectGender"); } if (!levelUpController.State.CanSelectVoice) { levelUpLog.Add("CanSelectVoice"); } if (levelUpController.State.AttributePoints > 0) { levelUpLog.Add("Unassigned Attribute Points"); } if (levelUpController.State.SelectedClass == null) { levelUpLog.Add("Class is null"); } if (!levelUpController.State.IsSkillPointsComplete()) { levelUpLog.Add("Unassigned Skill Points"); } if (levelUpController.State.Selections.Any((FeatureSelectionState s) => !s.Selected && s.CanSelectAnything(levelUpController.State, unitEntityData.Descriptor))) { levelUpLog.Add("Unassinged Features"); } if (levelUpController.State.SpellSelections.Any((SpellSelectionData data) => data.CanSelectAnything(unitEntityData.Descriptor))) { levelUpLog.Add("Unassigned Spells"); } } if (ValidLevels[i]) { Message[i] = "Valid level plan"; } else { Message[i] = $"Invalid level plan:\n{string.Join("\n", levelUpLog)}"; } } }
private static void Postfix(LevelUpController __instance) { Mod.Debug("Clearing Cache because LevelUpController.Commit called"); CasterHelpers.ClearCachedSpellsLearned(__instance.Unit); CasterHelpers.CacheSpellsLearned(__instance.Unit); }
private void Awake() { userDataController = new UserDataController(this, this); baseDataController = new BaseDataController(this, null); levelUpController = new LevelUpController(this, null); }