Ejemplo n.º 1
0
 static void Postfix(SelectFeature __instance, ref StateReplacer __state)
 {
     if (__state != null)
     {
         __state.Restore();
     }
 }
Ejemplo n.º 2
0
            static void Postfix(LevelUpState state, UnitDescriptor unit)
            {
                if (IsAvailable())
                {
                    Core.Mod.AppliedMulticlassSet.Clear();
                    Core.Mod.UpdatedProgressions.Clear();

                    // get multiclass setting
                    HashSet <string> selectedMulticlassSet =
                        Core.Mod.LevelUpController.Unit.IsMainCharacter ? MainCharSet :
                        (state.IsCharGen() && unit.IsCustomCompanion()) ? CharGenSet :
                        CompanionSets.ContainsKey(unit.CharacterName) ? CompanionSets[unit.CharacterName] : null;
                    if (selectedMulticlassSet == null || selectedMulticlassSet.Count == 0)
                    {
                        return;
                    }

                    // applying classes
                    StateReplacer stateReplacer = new StateReplacer(state);
                    foreach (BlueprintCharacterClass characterClass in Core.Mod.CharacterClasses)
                    {
                        if (characterClass != stateReplacer.SelectedClass && selectedMulticlassSet.Contains(characterClass.AssetGuid))
                        {
                            stateReplacer.Replace(null, 0);
                            if (new SelectClass(characterClass).Check(state, unit))
                            {
                                Core.Debug($" - {nameof(SelectClass)}.{nameof(SelectClass.Apply)}*({characterClass}, {unit})");

                                unit.Progression.AddClassLevel_NotCharacterLevel(characterClass);
                                //state.NextClassLevel = unit.Progression.GetClassLevel(characterClass);
                                //state.SelectedClass = characterClass;
                                characterClass.RestrictPrerequisites(unit, state);
                                //EventBus.RaiseEvent<ILevelUpSelectClassHandler>(h => h.HandleSelectClass(unit, state));

                                Core.Mod.AppliedMulticlassSet.Add(characterClass);
                            }
                        }
                    }
                    stateReplacer.Restore();

                    // applying archetypes
                    ForEachAppliedMulticlass(state, unit, () =>
                    {
                        foreach (BlueprintArchetype archetype in state.SelectedClass.Archetypes)
                        {
                            if (selectedMulticlassSet.Contains(archetype.AssetGuid))
                            {
                                AddArchetype addArchetype = new AddArchetype(state.SelectedClass, archetype);
                                if (addArchetype.Check(state, unit))
                                {
                                    addArchetype.Apply(state, unit);
                                }
                            }
                        }
                    });
                }
            }
Ejemplo n.º 3
0
 static void Postfix(SelectFeature __instance, ref StateReplacer __state)
 {
     if (!settings.toggleMulticlass)
     {
         return;
     }
     if (__state != null)
     {
         __state.Restore();
     }
 }
Ejemplo n.º 4
0
 static void Prefix(SelectFeature __instance, LevelUpState state, UnitDescriptor unit, ref StateReplacer __state)
 {
     if (IsAvailable())
     {
         if (__instance.Item != null)
         {
             FeatureSelectionState selectionState =
                 GetMethodDel <SelectFeature, Func <SelectFeature, LevelUpState, FeatureSelectionState> >
                     ("GetSelectionState")(__instance, state);
             if (selectionState != null)
             {
                 BlueprintCharacterClass sourceClass = (selectionState.Source as BlueprintFeature)?.GetSourceClass(unit);
                 if (sourceClass != null)
                 {
                     __state = new StateReplacer(state);
                     __state.Replace(sourceClass, unit.Progression.GetClassLevel(sourceClass));
                 }
             }
         }
     }
 }
Ejemplo n.º 5
0
            static void Postfix(MethodBase __originalMethod, ApplySpellbook __instance, LevelUpState state, UnitDescriptor unit)
            {
                if (!IsAvailable())
                {
                    return;
                }

                if (!Core.Mod.LockedPatchedMethods.Contains(__originalMethod))
                {
                    Core.Mod.LockedPatchedMethods.Add(__originalMethod);

                    Dictionary <Spellbook, int> spellbookCasterLevels = new Dictionary <Spellbook, int>();

                    // simulate the internal caster level
                    foreach (ClassData classData in unit.Progression.Classes)
                    {
                        if (classData != null && classData.Spellbook != null)
                        {
                            int[] skipLevelList = classData.CharacterClass.GetComponent <SkipLevelsForSpellProgression>()?.Levels;
                            int   skipLevels    = 0;
                            // Eldritch Knight || Dragon Disciple
                            if (classData.CharacterClass.AssetGuid == "de52b73972f0ed74c87f8f6a8e20b542" ||
                                classData.CharacterClass.AssetGuid == "72051275b1dbb2d42ba9118237794f7c")
                            {
                                skipLevels = 1;
                            }

                            Spellbook spellbook = unit.DemandSpellbook(classData.Spellbook);
                            if (!spellbookCasterLevels.TryGetValue(spellbook, out int casterLevel))
                            {
                                casterLevel = 0;
                            }
                            for (int i = 1 + skipLevels; i <= classData.Level; i++)
                            {
                                if (skipLevelList == null || !skipLevelList.Contains(i))
                                {
                                    casterLevel++;
                                }
                            }
                            spellbookCasterLevels[spellbook] = casterLevel;
                        }
                    }

                    // f*****g Mystic
                    foreach (Feature feature in unit.Progression.Features.Enumerable
                             .Where(feature => feature.Components.Any(item => item is AddSpellbookLevel)))
                    {
                        foreach (AddSpellbookLevel fact in feature.Components
                                 .Where(item => item is AddSpellbookLevel))
                        {
                            ClassData classData     = unit.Progression.GetClassData(feature.GetSourceClass());
                            int[]     skipLevelList = classData.CharacterClass.GetComponent <SkipLevelsForSpellProgression>()?.Levels;

                            Spellbook spellbook = fact.Owner.DemandSpellbook(fact.Spellbook);
                            if (!spellbookCasterLevels.TryGetValue(spellbook, out int casterLevel))
                            {
                                casterLevel = 0;
                            }
                            for (int i = 1; i <= classData.Level; i++)
                            {
                                if (skipLevelList == null || !skipLevelList.Contains(i))
                                {
                                    casterLevel++;
                                }
                            }
                            spellbookCasterLevels[spellbook] = casterLevel;
                        }
                    }

                    // simulate the caster level
                    foreach (Spellbook spellbook in new List <Spellbook>(spellbookCasterLevels.Keys))
                    {
                        int casterLevel = spellbookCasterLevels[spellbook];
                        int maxLevel    = spellbook.Blueprint.SpellsPerDay.Levels.Length - 1;
                        if (RestrictCasterLevelToCharacterLevel.IsAvailable())
                        {
                            casterLevel = Math.Min(casterLevel, unit.Progression.CharacterLevel);
                        }
                        casterLevel = Math.Max(0, Math.Min(maxLevel, casterLevel + spellbook.Blueprint.CasterLevelModifier));
                        spellbookCasterLevels[spellbook] = casterLevel;
                        Core.Debug($"   - Recalculated spellbook: {spellbook.Blueprint.Name}, target level: {casterLevel}, current level: {spellbook.CasterLevel}");
                    }

                    // check and increase the caster level of the spellbooks
                    StateReplacer stateReplacer = new StateReplacer(state);
                    foreach (Spellbook spellbook in spellbookCasterLevels.Keys)
                    {
                        BlueprintCharacterClass characterClass = spellbook.Blueprint.GetOwnerClass(unit);
                        stateReplacer.Replace(characterClass, unit.Progression.GetClassLevel(characterClass));

                        // We need __instance.Apply(state, unit) to always lead to an increase in the caster level
                        SkipLevelsForSpellProgression skipLevels = characterClass.GetComponent <SkipLevelsForSpellProgression>();
                        int[] backup = skipLevels?.Levels;
                        if (skipLevels != null)
                        {
                            skipLevels.Levels = new int[0];
                        }

                        int casterLevel = spellbookCasterLevels[spellbook];
                        while (spellbook.CasterLevel < casterLevel)
                        {
                            Core.Debug($"   - Applying caster level: {spellbook.CasterLevel} => {casterLevel}");
                            __instance.Apply(state, unit);
                        }

                        if (skipLevels != null)
                        {
                            skipLevels.Levels = backup;
                        }
                    }
                    stateReplacer.Restore();

                    Core.Mod.LockedPatchedMethods.Remove(__originalMethod);
                }
            }