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); } }
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); }
// 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)); } }
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); } }
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); } } }
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); } } }
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); }
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); }
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)); }
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); }
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); }
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); }