private void metamagicListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            syncMetamagicSelectionOrder();
            if (metamagicListBox.SelectedItems.Count > 0)
            {
                if (metamagicListBox.SelectedIndices.Count <= metamagicKnown)
                {
                    int       lastSelectedIndex   = metamagicOrderedSelection.ElementAt(metamagicOrderedSelection.Count - 1);
                    Metamagic currentSelectedItem = (Metamagic)metamagicListBox.Items[lastSelectedIndex];
                    if (currentSelectedItem != null)
                    {
                        metamagicDescriptionLabel.Text = currentSelectedItem.Name +
                                                         Environment.NewLine +
                                                         currentSelectedItem.Description;
                    }
                }
                else
                {
                    int lastSelectedIndex = metamagicOrderedSelection.ElementAt(metamagicOrderedSelection.Count - 1);
                    metamagicListBox.SelectedIndices.Remove(lastSelectedIndex);
                }

                OnMetamagicChosen(null);
            }
        }
Ejemplo n.º 2
0
        internal static bool Prefix(Metamagic metamagic, ref int __result)
        {
            switch ((ModMetamagic)metamagic)
            {
            case ModMetamagic.Dazing:
                __result = 3;
                return(false);

            case ModMetamagic.Persistent:
                __result = 2;
                return(false);

            case ModMetamagic.Rime:
            case ModMetamagic.Toppling:
            case ModMetamagic.Intensified:
            case ModMetamagic.ElementalFire:
            case ModMetamagic.ElementalCold:
            case ModMetamagic.ElementalElectricity:
            case ModMetamagic.ElementalAcid:
            case ModMetamagic.Selective:
                __result = 1;
                return(false);
            }
            return(true);
        }
Ejemplo n.º 3
0
        // Similar to `metamagic.DefaultCost()`, but returns the result before Bag of Tricks
        // modifies it to 0.
        public static int OriginalCost(this Metamagic metamagic)
        {
            // Inline this so Bag of Tricks can't mutate it.
            switch (metamagic)
            {
            case Metamagic.Empower:
                return(2);

            case Metamagic.Maximize:
                return(3);

            case Metamagic.Quicken:
                return(4);

            case Metamagic.Extend:
                return(1);

            case Metamagic.Heighten:
                return(0);

            case Metamagic.Reach:
                return(1);
            }
            UberDebug.LogError($"Unknown metamagic: {metamagic}");
            return(0);
        }
 public void add(BlueprintAbility ability, Metamagic metamagic)
 {
     if (!prepared_spells_with_metamagic.ContainsKey(ability.AssetGuid))
     {
         prepared_spells_with_metamagic.Add(ability.AssetGuid, new List <Metamagic>());
     }
     prepared_spells_with_metamagic[ability.AssetGuid].Add(metamagic);
 }
            public bool noCastingTimeIncreaseForMetamagic(BlueprintAbility ability, Metamagic metamagic, int additional_free_metamagic = 0)
            {
                bool is_ok = noCastingTimeIncreaseForMetamagicInternal(ability, metamagic, additional_free_metamagic);

                if (ability.Parent != null)
                {
                    is_ok = is_ok || noCastingTimeIncreaseForMetamagicInternal(ability.Parent, metamagic, additional_free_metamagic);
                }
                return(is_ok);
            }
            public bool authorisedMetamagic(BlueprintAbility ability, Metamagic metamagic)
            {
                //check that there exist at least one prepared spell with metamagic mask which is subset of this one
                if (!prepared_spells_with_metamagic.ContainsKey(ability.AssetGuid))
                {
                    return(false);
                }

                return(prepared_spells_with_metamagic[ability.AssetGuid].Any(m => (metamagic | m) == metamagic));
            }
 public void remove(BlueprintAbility blueprint, Metamagic metamagic)
 {
     if (!prepared_spells_with_metamagic.ContainsKey(blueprint.AssetGuid))
     {
         return;
     }
     prepared_spells_with_metamagic[blueprint.AssetGuid].RemoveAll(m => m == metamagic);
     if (prepared_spells_with_metamagic[blueprint.AssetGuid].Empty())
     {
         prepared_spells_with_metamagic.Remove(blueprint.AssetGuid);
     }
 }
            public bool isUsedWithMetamixing(BlueprintAbility ability, Metamagic metamagic)
            {
                if (!metamixingEnabled())
                {
                    return(false);
                }

                if (ability.Parent != null)
                {
                    return(prepared_spells_with_metamagic[ability.Parent.AssetGuid].Any(m => (m | metamagic) == metamagic && Helpers.PopulationCount((int)(metamagic & ~m)) == 1) &&
                           !prepared_spells_with_metamagic[ability.Parent.AssetGuid].Any(m => (m | metamagic) == metamagic && Helpers.PopulationCount((int)(metamagic & ~m)) == 0));
                }
                else
                {
                    return(prepared_spells_with_metamagic[ability.AssetGuid].Any(m => (m | metamagic) == metamagic && Helpers.PopulationCount((int)(metamagic & ~m)) == 1) &&
                           !prepared_spells_with_metamagic[ability.AssetGuid].Any(m => (m | metamagic) == metamagic && Helpers.PopulationCount((int)(metamagic & ~m)) == 0));
                }
            }
Ejemplo n.º 9
0
        public void CreateAllEchoesTest()
        {
            // Create a new Human character.
            Character objCharacter = new Character();

            objCharacter.LoadMetatype(Guid.Parse("e28e7075-f635-4c02-937c-e4fc61c51602"));

            TreeNode         objNode      = new TreeNode();
            ContextMenuStrip cmsGear      = new ContextMenuStrip();
            List <Weapon>    lstWeapons   = new List <Weapon>();
            List <TreeNode>  lstTreeNodes = new List <TreeNode>();

            XmlDocument objXmlDocument = XmlManager.Instance.Load("echoes.xml");

            foreach (XmlNode objXmlNode in objXmlDocument.SelectNodes("/chummer/metamagics/metamagic"))
            {
                Metamagic objMetamagic = new Metamagic(objCharacter);
                objMetamagic.Create(objXmlNode, objCharacter, objNode, Improvement.ImprovementSource.Metamagic);
            }
        }
Ejemplo n.º 10
0
 public static void Postfix(ref RuleCollectMetamagic __instance, int ___m_SpellLevel, Feature metamagicFeature)
 {
     if (settings.toggleMetamagicIsFree)
     {
         AddMetamagicFeat component = metamagicFeature.GetComponent <AddMetamagicFeat>();
         if (component == null)
         {
             Logger.ModLoggerDebug(String.Format("Trying to add metamagic feature without metamagic component: {0}", (object)metamagicFeature));
         }
         else
         {
             Metamagic metamagic = component.Metamagic;
             __instance.KnownMetamagics.Add(metamagicFeature);
             if (___m_SpellLevel < 0 || ___m_SpellLevel >= 10 || (___m_SpellLevel + component.Metamagic.DefaultCost() > 10 || __instance.SpellMetamagics.Contains(metamagicFeature)) || (__instance.Spell.AvailableMetamagic & metamagic) != metamagic)
             {
                 return;
             }
             __instance.SpellMetamagics.Add(metamagicFeature);
         }
     }
 }
Ejemplo n.º 11
0
        private void RemoveMetamagicFeatInSpellSlots(BlueprintFeature metafeatOld)
        {
            Metamagic          metaOld        = metafeatOld.GetComponent <AddMetamagicFeat>().Metamagic;
            List <AbilityData> spellsToRemove = new List <AbilityData>();
            List <SpellSlot>   slotsToForget  = new List <SpellSlot>();
            var unit = base.Owner;

            foreach (Spellbook spellbook in unit.Spellbooks)
            {
                int maxSplLevel = spellbook.MaxSpellLevel;
                for (int i = 1; i <= maxSplLevel; i++)
                {
                    foreach (AbilityData spell in spellbook.GetCustomSpells(i))
                    {
                        if (spell.HasMetamagic(metaOld))
                        {
                            spellsToRemove.Add(spell);
                        }
                    }
                    foreach (SpellSlot slot in spellbook.GetMemorizedSpellSlots(i))
                    {
                        if (slot.Spell != null && !slot.IsOpposition)
                        {
                            if (slot.Spell.HasMetamagic(metaOld))
                            {
                                slotsToForget.Add(slot);
                            }
                        }
                    }
                }
                foreach (SpellSlot slot in slotsToForget)
                {
                    spellbook.ForgetMemorized(slot);
                }
                foreach (AbilityData spell in spellsToRemove)
                {
                    spellbook.RemoveCustomSpell(spell);
                }
            }
        }
Ejemplo n.º 12
0
        static public bool Prefix(UnitUseAbility __instance, UnitCommand.CommandType commandType, ref AbilityData spell, TargetWrapper target)
        {
            //base ctor

            /*this.Type = commandType;
             * this.Target = target;
             * this.Cutscene = (ElementsContext.GetData<CutsceneParametersContext.ContextData>() != null);*/

            //modify spell
            if (spell == null)
            {
                return(true);
            }
            if (spell.Spellbook == null)
            {
                return(true);
            }
            if (spell.Spellbook.Blueprint.CharacterClass != ArcanistClass.arcanist)
            {
                return(true);
            }
            UnitDescriptor unit          = spell.Caster;
            bool           hadMetamagic  = spell.MetamagicData != null;
            bool           hadMetamixing = unit.Buffs.HasFact(Metamixing.buff);

            //An arcanist can't combine prepared metamagic and spontaneous metamagic, if she doesn't have
            //the Metamixing exploit.
            if (hadMetamagic && !hadMetamixing)
            {
                return(true);
            }
            //UnityModManager.Logger.Log($"spell {spell.Name} has metamagic {(spell.MetamagicData!=null?spell.MetamagicData.MetamagicMask:0)}");
            MetamagicBuilder builder = new MetamagicBuilder(spell.Spellbook, spell);
            Dictionary <Metamagic, Feature> meta_feat = new Dictionary <Metamagic, Feature>();

            foreach (var ft in builder.SpellMetamagicFeatures)
            {
                AddMetamagicFeat comp = ft.Get <AddMetamagicFeat>();
                if (comp == null)
                {
                    continue;
                }
                Metamagic metaId = comp.Metamagic;
                meta_feat[metaId] = ft;
            }
            bool flag = false;

            foreach (var kv in SponMetamagic.buffDict)
            {
                Metamagic metaId        = (Metamagic)(kv.Key.first);
                int       HeightenLevel = kv.Key.second;
                if (!meta_feat.ContainsKey(metaId))
                {
                    continue;
                }
                BlueprintBuff buff = kv.Value;
                if (!unit.HasFact(buff))
                {
                    continue;
                }

                //If the arcanist has the Metamixing exploit, she can add ONE
                //metamagic feat to a prepared spell, without using extra time to cast.
                //(regardless if the spell had metamagic feats when prepared)
                if (metaId == Metamagic.Heighten)
                {
                    int originalLevel = spell.Spellbook.GetSpellLevel(spell.Blueprint);
                    if (HeightenLevel <= originalLevel)
                    {
                        continue;
                    }
                    builder.AddHeightenMetamagic(meta_feat[metaId], HeightenLevel - originalLevel);
                    unit.RemoveFact(buff);
                    flag = true;
                    if (hadMetamixing)
                    {
                        unit.Resources.Spend(ArcaneReservoir.resource, 1);
                        break;
                    }
                }
                else
                {
                    builder.AddMetamagic(meta_feat[metaId]);
                    unit.RemoveFact(buff);
                    flag = true;
                    if (hadMetamixing)
                    {
                        unit.Resources.Spend(ArcaneReservoir.resource, 1);
                        break;
                    }
                }
            }
            if (flag && !hadMetamixing)
            {
                unit.AddBuff(SponMetamagic.flagBuff, unit.Unit);
            }
            //fix ConvertedFrom. this is used in checking if a subspell is existed in memorized spells.
            //if spell is a subspell, spell.IsAvailableInSpellbook will use its m_ConvertedFrom(which is its master spell)
            //to get the return value.
            var newSpell = builder.ResultAbilityData;

            newSpell.ConvertedFrom = spell.ConvertedFrom;
            spell = newSpell;
            //UnityModManager.Logger.Log($"new spell {spell.Name} has metamagic {(spell.MetamagicData != null ? spell.MetamagicData.MetamagicMask : 0)}");
            return(true);
        }
Ejemplo n.º 13
0
        static public BlueprintAbility CreateHeighten()
        {
            var              variants     = new List <BlueprintAbility>();
            Metamagic        heighten     = Metamagic.Heighten;
            BlueprintFeature heightenFeat = library.Get <BlueprintFeature>(MetaFeats.dict[(int)heighten]);

            for (int i = 1; i <= 9; i++)
            {
                string buffname = $"ArcanistClassSponHeighten{i}SubBuff";
                var    buff_i   = Helpers.CreateBuff(buffname, "", "",
                                                     OtherUtils.GetMd5(buffname), heightenFeat.Icon, null);
                buff_i.SetName(Helpers.CreateString($"ArcanistClass.SponMetamagic.Heighten{i}.Name"));
                buff_i.SetDescription(heightenFeat.GetDescription());

                var ablEffectComp       = Helpers.Create <AbilityEffectRunAction>();
                var ablEffectCompAction = Helpers.Create <ContextActionApplyBuff>();
                ablEffectCompAction.Buff            = buff_i;
                ablEffectCompAction.Permanent       = false;
                ablEffectCompAction.DurationValue   = PresetDurations.oneRound;
                ablEffectCompAction.IsFromSpell     = false;
                ablEffectCompAction.IsNotDispelable = false;
                ablEffectCompAction.ToCaster        = false;
                ablEffectCompAction.AsChild         = true;
                ablEffectComp.Actions = new ActionList {
                    Actions = new GameAction[] { null, ablEffectCompAction }
                };

                var ablRequirementComp = Helpers.Create <AbilityRequirementFeature>();
                ablRequirementComp.Feat = heightenFeat;
                ablRequirementComp.Not  = false;

                var ablRequirementComp2 = Helpers.Create <AbilityRequirementClassSpellLevel>();
                ablRequirementComp2.characterClass     = ArcanistClass.arcanist;
                ablRequirementComp2.RequiredSpellLevel = i;

                var abl_i_name = $"ArcanistClassSponHeighten{i}SubAbl";
                var abl_i      = Helpers.CreateAbility(abl_i_name, "", "",
                                                       OtherUtils.GetMd5(abl_i_name),
                                                       heightenFeat.Icon,
                                                       AbilityType.Special,
                                                       UnitCommand.CommandType.Free,
                                                       AbilityRange.Personal,
                                                       "", "",
                                                       ablEffectComp, ablRequirementComp, ablRequirementComp2);
                abl_i.SetName(buff_i.GetName());
                abl_i.SetDescription(buff_i.GetDescription());
                abl_i.LocalizedDuration    = Helpers.CreateString("ArcaneTide.OneRound");
                abl_i.LocalizedSavingThrow = Helpers.CreateString("ArcaneTide.WillSave.NoHarm");

                variants.Add(abl_i);
                buffDict[OtherUtils.make_pair <int, int>((int)heighten, i)] = buff_i;
            }
            BlueprintAbility abl = Helpers.CreateAbility("ArcanistClassSponHeightenAbl", "", "",
                                                         OtherUtils.GetMd5("ArcanistClassSponHeightenAbl"),
                                                         heightenFeat.Icon,
                                                         AbilityType.Special,
                                                         UnitCommand.CommandType.Free,
                                                         AbilityRange.Personal,
                                                         "", "");

            abl.SetName(heightenFeat.GetName());
            abl.SetDescription(heightenFeat.GetDescription());
            abl.LocalizedDuration    = Helpers.CreateString("ArcaneTide.OneRound");
            abl.LocalizedSavingThrow = Helpers.CreateString("ArcaneTide.WillSave.NoHarm");
            abl.AddComponent(abl.CreateAbilityVariants(variants));
            return(abl);
        }
Ejemplo n.º 14
0
 public MetaRage(Metamagic metamagic_to_apply, BlueprintAbilityResource resource_to_use)
 {
     Metamagic = metamagic_to_apply;
     resource  = resource_to_use;
 }
            private bool noCastingTimeIncreaseForMetamagicInternal(BlueprintAbility ability, Metamagic metamagic, int additional_free_metamagic)
            {
                if (!prepared_spells_with_metamagic.ContainsKey(ability.AssetGuid))
                {
                    return(false);
                }

                int free_metamagics = additional_free_metamagic;

                if (metamixingEnabled())
                {
                    free_metamagics++;
                }

                return(prepared_spells_with_metamagic[ability.AssetGuid].Any(m => (m | metamagic) == metamagic && Helpers.PopulationCount((int)(metamagic & ~m)) <= free_metamagics));
            }
Ejemplo n.º 16
0
            public override bool CanBeUsedOn(BlueprintAbility ability, [CanBeNull] AbilityData data)
            {
                bool is_metamagic_not_available = ability == null || data?.Spellbook == null || ability.Type != AbilityType.Spell ||
                                                  ((ability.AvailableMetamagic & Metamagic) == 0);

                if (is_metamagic_not_available)
                {
                    return(false);
                }

                if (!checkSpellbook(data?.Spellbook?.Blueprint))
                {
                    return(false);
                }


                int cost = calculate_cost(this.Owner.Unit);

                if (resource != null && this.Owner.Resources.GetResourceAmount((BlueprintScriptableObject)this.resource) < cost)
                {
                    return(false);
                }


                if (limit_spell_level && data.Spellbook.MaxSpellLevel < data.SpellLevel + Metamagic.DefaultCost())
                {
                    return(false);
                }

                return(true);
            }
Ejemplo n.º 17
0
            public override bool CanBeUsedOn(BlueprintAbility ability, [CanBeNull] AbilityData data)
            {
                bool is_metamagic_not_available = ability == null || data?.Spellbook == null || ability.Type != AbilityType.Spell ||
                                                  ((ability.AvailableMetamagic & Metamagic) == 0);

                if (is_metamagic_not_available)
                {
                    return(false);
                }

                if (!Helpers.checkSpellbook(spellbook, specific_class, data?.Spellbook, this.Owner))
                {
                    return(false);
                }

                if (this.Abilities != null && !this.Abilities.Empty() && !this.Abilities.Contains(ability))
                {
                    return(false);
                }

                if (!spell_descriptor.HasAnyFlag(data.Blueprint.SpellDescriptor) && spell_descriptor != SpellDescriptor.None)
                {
                    return(false);
                }

                int cost = calculate_cost(this.Owner.Unit);

                if (resource != null && this.Owner.Resources.GetResourceAmount((BlueprintScriptableObject)this.resource) < cost)
                {
                    return(false);
                }


                if (limit_spell_level && data.Spellbook.MaxSpellLevel < data.SpellLevel + Metamagic.DefaultCost())
                {
                    return(false);
                }

                return(true);
            }
Ejemplo n.º 18
0
        static public BlueprintFeature Create()
        {
            if (library.BlueprintsByAssetId.ContainsKey("b04d23c4d4f14d431d316063db884fe5"))
            {
                return(library.Get <BlueprintFeature>("b04d23c4d4f14d431d316063db884fe5"));
            }
            var variants = new List <BlueprintAbility>();

            buffDict = new Dictionary <Pair <int, int>, BlueprintBuff>();
            flagBuff = Helpers.CreateBuff("ArcanistClassSponMetamagicFlagBuff", "", "",
                                          OtherUtils.GetMd5("ArcanistClassSponMetamagicFlagBuff"), null, null);
            flagBuff.SetBuffFlags(flagBuff.GetBuffFlags() | BuffFlags.HiddenInUi);

            //make metamagics other than heighten
            foreach (var kv in MetaFeats.dict)
            {
                Metamagic        metaId   = (Metamagic)(kv.Key);
                BlueprintFeature metaFeat = library.Get <BlueprintFeature>(kv.Value);
                if (metaId == Metamagic.Heighten)
                {
                    continue;
                }
                RealMetamagicOnNextSpell comp = Helpers.Create <RealMetamagicOnNextSpell>();
                comp.metamagic = metaId;
                var buff_i = Helpers.CreateBuff($"ArcanistClassSponMetamagic{metaId}SubBuff", "", "",
                                                OtherUtils.GetMd5($"ArcanistClassSponMetamagic{metaId}SubBuff"),
                                                metaFeat.Icon, null, comp);
                buff_i.SetName(metaFeat.GetName());
                buff_i.SetDescription(metaFeat.GetDescription());

                var ablEffectComp       = Helpers.Create <AbilityEffectRunAction>();
                var ablEffectCompAction = Helpers.Create <ContextActionApplyBuff>();
                ablEffectCompAction.Buff            = buff_i;
                ablEffectCompAction.Permanent       = false;
                ablEffectCompAction.DurationValue   = PresetDurations.oneRound;
                ablEffectCompAction.IsFromSpell     = false;
                ablEffectCompAction.IsNotDispelable = false;
                ablEffectCompAction.ToCaster        = false;
                ablEffectCompAction.AsChild         = true;
                ablEffectComp.Actions = new ActionList {
                    Actions = new GameAction[] { null, ablEffectCompAction }
                };

                var ablRequirementComp = Helpers.Create <AbilityRequirementFeature>();
                ablRequirementComp.Feat = metaFeat;
                ablRequirementComp.Not  = false;

                var abl_i = Helpers.CreateAbility($"ArcanistClassSponMetamagic{metaId}SubAbl", "", "",
                                                  OtherUtils.GetMd5($"ArcanistClassSponMetamagic{metaId}SubAbl"),
                                                  metaFeat.Icon,
                                                  AbilityType.Special,
                                                  UnitCommand.CommandType.Free,
                                                  AbilityRange.Personal,
                                                  "", "",
                                                  ablEffectComp, ablRequirementComp);
                abl_i.SetName(metaFeat.GetName());
                abl_i.SetDescription(metaFeat.GetDescription());
                abl_i.LocalizedDuration    = Helpers.CreateString("ArcaneTide.OneRound");
                abl_i.LocalizedSavingThrow = Helpers.CreateString("ArcaneTide.WillSave.NoHarm");

                variants.Add(abl_i);
                buffDict[OtherUtils.make_pair <int, int>((int)metaId, 0)] = buff_i;
            }


            var abl = Helpers.CreateAbility("ArcanistClassSponMetamagicAbl", "", "",
                                            "d4abbfad4a4cd0eadde062132945f7bf",//MD5-32[ArcanistClass.SponMetamagic.Abl]
                                            IconSet.metamagic,
                                            AbilityType.Special,
                                            UnitCommand.CommandType.Free,
                                            AbilityRange.Personal,
                                            "", "");

            abl.SetName(Helpers.CreateString("ArcanistClass.SponMetamagic.Abl.Name"));
            abl.SetDescription(Helpers.CreateString("ArcanistClass.SponMetamagic.Abl.Desc"));
            abl.LocalizedDuration    = Helpers.CreateString("ArcaneTide.OneRound");
            abl.LocalizedSavingThrow = Helpers.CreateString("ArcaneTide.WillSave.NoHarm");
            abl.AddComponent(Helpers.CreateAbilityVariants(abl, variants));

            var ablHeighten = CreateHeighten();

            feat = Helpers.CreateFeature("ArcanistClassSponMetamagicFeat", "", "",
                                         "b04d23c4d4f14d431d316063db884fe5",//MD5-32[ArcanistClass.SponMetamagic.Feat]
                                         null,
                                         FeatureGroup.None,
                                         Helpers.Create <AddFacts>(a => a.Facts = new BlueprintUnitFact[] { abl, ablHeighten }));
            feat.HideInUI = true;
            return(feat);
        }