public void RemoveAbility(AreaEffect ability) { if (AreaEffects == null || !AreaEffects.Any(a => a == ability)) { return; } var list = AreaEffects.ToList(); list.Remove(ability); RemovePetAdvancement(ability); AreaEffects = list.ToArray(); ColUtility.Free(list); }
public bool HasAbility(object o) { if (o is MagicalAbility) { return((MagicalAbility & (MagicalAbility)o) != 0); } if (o is SpecialAbility && SpecialAbilities != null) { return(SpecialAbilities.Any(a => a == (SpecialAbility)o)); } if (o is AreaEffect && AreaEffects != null) { return(AreaEffects.Any(a => a == (AreaEffect)o)); } if (o is WeaponAbility && WeaponAbilities != null) { return(WeaponAbilities.Any(a => a == (WeaponAbility)o)); } return(false); }
public bool AddAbility(AreaEffect ability, bool advancement = true) { if (AreaEffects == null) { AreaEffects = new AreaEffect[] { ability }; } else if (!AreaEffects.Any(a => a == ability)) { var temp = AreaEffects; AreaEffects = new AreaEffect[temp.Length + 1]; for (int i = 0; i < temp.Length; i++) { AreaEffects[i] = temp[i]; } AreaEffects[temp.Length] = ability; } OnAddAbility(ability, advancement); return(true); }
internal static void InitMiscValueTypes() { AuraEffectMiscValueTypes[(int)AuraType.AddModifierPercent] = typeof(SpellModifierType); AuraEffectMiscValueTypes[(int)AuraType.AddModifierFlat] = typeof(SpellModifierType); SetAuraEffectMiscValueType(AuraType.ModDamageDone, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModDamageDonePercent, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModDamageDoneToCreatureType, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModDamageDoneVersusCreatureType, typeof(CreatureMask)); SetAuraEffectMiscValueType(AuraType.ModDamageTaken, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModDamageTakenPercent, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModPowerCost, typeof(PowerType)); SetAuraEffectMiscValueType(AuraType.ModPowerCostForSchool, typeof(PowerType)); SetAuraEffectMiscValueType(AuraType.ModPowerRegen, typeof(PowerType)); SetAuraEffectMiscValueType(AuraType.ModPowerRegenPercent, typeof(PowerType)); SetAuraEffectMiscValueType(AuraType.ModRating, typeof(CombatRatingMask)); SetAuraEffectMiscValueType(AuraType.ModSkill, typeof(SkillId)); SetAuraEffectMiscValueType(AuraType.ModSkillTalent, typeof(SkillId)); SetAuraEffectMiscValueType(AuraType.ModStat, typeof(StatType)); SetAuraEffectMiscValueType(AuraType.ModStatPercent, typeof(StatType)); SetAuraEffectMiscValueType(AuraType.ModTotalStatPercent, typeof(StatType)); SetAuraEffectMiscValueType(AuraType.DispelImmunity, typeof(DispelType)); SetAuraEffectMiscValueType(AuraType.MechanicImmunity, typeof(SpellMechanic)); SetAuraEffectMiscValueType(AuraType.Mounted, typeof(NPCId)); SetAuraEffectMiscValueType(AuraType.ModShapeshift, typeof(ShapeshiftForm)); SetAuraEffectMiscValueType(AuraType.Transform, typeof(NPCId)); SetAuraEffectMiscValueType(AuraType.ModSpellDamageByPercentOfStat, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModSpellHealingByPercentOfStat, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.DamagePctAmplifier, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModSilenceDurationPercent, typeof(SpellMechanic)); SetAuraEffectMiscValueType(AuraType.ModMechanicDurationPercent, typeof(SpellMechanic)); SetAuraEffectMiscValueType(AuraType.TrackCreatures, typeof(CreatureType)); SetAuraEffectMiscValueType(AuraType.ModSpellHitChance, typeof(DamageSchoolMask)); SetAuraEffectMiscValueType(AuraType.ModSpellHitChance2, typeof(DamageSchoolMask)); SetAuraEffectMiscValueBType(AuraType.ModSpellDamageByPercentOfStat, typeof(StatType)); SetAuraEffectMiscValueBType(AuraType.ModSpellHealingByPercentOfStat, typeof(StatType)); SetSpellEffectEffectMiscValueType(SpellEffectType.Dispel, typeof(DispelType)); SetSpellEffectEffectMiscValueType(SpellEffectType.DispelMechanic, typeof(SpellMechanic)); SetSpellEffectEffectMiscValueType(SpellEffectType.Skill, typeof(SkillId)); SetSpellEffectEffectMiscValueType(SpellEffectType.SkillStep, typeof(SkillId)); SetSpellEffectEffectMiscValueType(SpellEffectType.Skinning, typeof(SkinningType)); SetSpellEffectEffectMiscValueType(SpellEffectType.Summon, typeof(NPCId)); SetSpellEffectEffectMiscValueType(SpellEffectType.SummonObject, typeof(GOEntryId)); SetSpellEffectEffectMiscValueType(SpellEffectType.SummonObjectSlot1, typeof(GOEntryId)); SetSpellEffectEffectMiscValueType(SpellEffectType.SummonObjectSlot2, typeof(GOEntryId)); SetSpellEffectEffectMiscValueType(SpellEffectType.SummonObjectWild, typeof(GOEntryId)); SetSpellEffectEffectMiscValueBType(SpellEffectType.Summon, typeof(SummonType)); TargetAreaEffects.AddRange(new[] { ImplicitSpellTargetType.AllAroundLocation, ImplicitSpellTargetType.AllEnemiesInArea, ImplicitSpellTargetType.AllEnemiesInAreaChanneled, ImplicitSpellTargetType.AllEnemiesInAreaInstant, ImplicitSpellTargetType.AllPartyInArea, ImplicitSpellTargetType.AllPartyInAreaChanneled, ImplicitSpellTargetType.InvisibleOrHiddenEnemiesAtLocationRadius }); AreaEffects.AddRange(TargetAreaEffects); AreaEffects.AddRange(new[] { ImplicitSpellTargetType.AllEnemiesAroundCaster, ImplicitSpellTargetType.AllPartyAroundCaster, ImplicitSpellTargetType.AllTargetableAroundLocationInRadiusOverTime, ImplicitSpellTargetType.BehindTargetLocation, ImplicitSpellTargetType.LocationInFrontCaster, ImplicitSpellTargetType.LocationInFrontCasterAtRange, ImplicitSpellTargetType.ConeInFrontOfCaster, ImplicitSpellTargetType.AreaEffectPartyAndClass, ImplicitSpellTargetType.NatureSummonLocation, ImplicitSpellTargetType.TargetAtOrientationOfCaster, ImplicitSpellTargetType.Tranquility }); }
internal void Init2() { // see http://www.wowhead.com/spell=25269 for comparison ValueMin = BasePoints + 1; ValueMax = BasePoints + DiceSides; // TODO: check this! IsTargetAreaEffect = TargetAreaEffects.Contains(ImplicitTargetA) || TargetAreaEffects.Contains(ImplicitTargetB); // prevent aoe and non-aoe effects from mixing together if (AreaEffects.Contains(ImplicitTargetA)) { IsAreaEffect = true; if (ImplicitTargetB != ImplicitSpellTargetType.None && AreaEffects.Contains(ImplicitTargetB)) { ImplicitTargetB = ImplicitSpellTargetType.None; } } else if (ImplicitTargetB != ImplicitSpellTargetType.None && AreaEffects.Contains(ImplicitTargetB)) { IsAreaEffect = true; ImplicitTargetA = ImplicitSpellTargetType.None; } if (IsPeriodic = Amplitude > 0) { _IsPeriodicAura = (AuraType == AuraType.PeriodicDamage || AuraType == AuraType.PeriodicDamagePercent || AuraType == AuraType.PeriodicEnergize || AuraType == AuraType.PeriodicHeal || AuraType == AuraType.PeriodicHealthFunnel || AuraType == AuraType.PeriodicLeech || AuraType == AuraType.PeriodicManaLeech || AuraType == AuraType.PeriodicTriggerSpell); } if (Spell.IsPassive) { // proc effect etc HarmType = HarmType.Beneficial; } else if ((HasTarget(ImplicitSpellTargetType.AllEnemiesAroundCaster, ImplicitSpellTargetType.AllEnemiesInArea, ImplicitSpellTargetType.AllEnemiesInAreaChanneled, ImplicitSpellTargetType.AllEnemiesInAreaInstant, ImplicitSpellTargetType.CurrentSelection) || HasTarget(ImplicitSpellTargetType.InFrontOfCaster, ImplicitSpellTargetType.InvisibleOrHiddenEnemiesAtLocationRadius, ImplicitSpellTargetType.LocationInFrontCaster, ImplicitSpellTargetType.NetherDrakeSummonLocation, ImplicitSpellTargetType.SelectedEnemyChanneled, ImplicitSpellTargetType.SelectedEnemyDeadlyPoison, ImplicitSpellTargetType.SingleEnemy, ImplicitSpellTargetType.SpreadableDesease, ImplicitSpellTargetType.TargetAtOrientationOfCaster)) && (!HasTarget( ImplicitSpellTargetType.Self, ImplicitSpellTargetType.AllFriendlyInAura, ImplicitSpellTargetType.AllParty, ImplicitSpellTargetType.AllPartyAroundCaster, ImplicitSpellTargetType.AllPartyInArea, ImplicitSpellTargetType.PartyAroundCaster, ImplicitSpellTargetType.AllPartyInAreaChanneled) || Spell.Mechanic.IsNegative())) { HarmType = HarmType.Harmful; } else if (!HasTarget(ImplicitSpellTargetType.Duel) && (ImplicitTargetA != ImplicitSpellTargetType.None || ImplicitTargetB != ImplicitSpellTargetType.None)) { HarmType = HarmType.Beneficial; } // do some correction for ModManaRegen if (AuraType == AuraType.ModManaRegen && Amplitude == 0) { // 5000 ms if not specified otherwise Amplitude = ModManaRegenHandler.DefaultAmplitude; } if (HasTarget(ImplicitSpellTargetType.AllFriendlyInAura)) { // whenever it's used, its used together with AllEnemiesAroundCaster in a beneficial spell) ImplicitTargetA = ImplicitSpellTargetType.AllFriendlyInAura; ImplicitTargetB = ImplicitSpellTargetType.None; } HasTargets = !NoTargetTypes.Contains(ImplicitTargetA) || !NoTargetTypes.Contains(ImplicitTargetB); HasSingleTarget = HasTargets && !IsAreaEffect; IsAreaAuraEffect = (EffectType == SpellEffectType.PersistantAreaAura || EffectType == SpellEffectType.ApplyAreaAura || EffectType == SpellEffectType.ApplyRaidAura); if (EffectType == SpellEffectType.ApplyRaidAura) { if (Radius > 0) { ImplicitTargetA = ImplicitSpellTargetType.AllPartyInArea; } else { ImplicitTargetA = ImplicitSpellTargetType.AllParty; } } IsAuraEffect = IsAreaAuraEffect || EffectType == SpellEffectType.ApplyAura || EffectType == SpellEffectType.ApplyAuraToMaster || EffectType == SpellEffectType.ApplyPetAura || EffectType == SpellEffectType.ApplyStatAura || EffectType == SpellEffectType.ApplyStatAuraPercent; IsEnhancer = IsAuraEffect && (AuraType == AuraType.AddModifierFlat || AuraType == AuraType.AddModifierPercent); if (MiscValueType == typeof(DamageSchoolMask)) { // make sure that only valid schools are used MiscValue = MiscValue & (int)DamageSchoolMask.AllSchools; } MiscBitSet = MiscValue > 0 ? Utility.GetSetIndices((uint)MiscValue) : new uint[0]; MinValue = BasePoints; // + DiceCount; TODO: check this! IsStrikeEffectFlat = EffectType == SpellEffectType.WeaponDamage || EffectType == SpellEffectType.WeaponDamageNoSchool || EffectType == SpellEffectType.NormalizedWeaponDamagePlus; IsStrikeEffectPct = EffectType == SpellEffectType.WeaponPercentDamage; IsTotem = HasTarget(ImplicitSpellTargetType.TotemAir) || HasTarget(ImplicitSpellTargetType.TotemEarth) || HasTarget(ImplicitSpellTargetType.TotemFire) || HasTarget(ImplicitSpellTargetType.TotemWater); IsProc = IsProc || ProcAuraTypes.Contains(AuraType); OverrideEffectValue = OverrideEffectValue || AuraType == AuraType.ProcTriggerSpellWithOverride; IsHealEffect = EffectType == SpellEffectType.Heal || EffectType == SpellEffectType.HealMaxHealth || AuraType == AuraType.PeriodicHeal || (TriggerSpell != null && TriggerSpell.IsHealSpell); IsDamageEffect = EffectType == SpellEffectType.SchoolDamage || IsStrikeEffect; IsModifierEffect = AuraType == AuraType.AddModifierFlat || AuraType == AuraType.AddModifierPercent; HasAffectMask = AffectMask.Any(mask => mask != 0); if (HasAffectMask) { AffectMaskBitSet = Utility.GetSetIndices(AffectMask); } if (SpellEffectHandlerCreator == null) { SpellEffectHandlerCreator = SpellHandler.SpellEffectCreators[(int)EffectType]; } if (IsAuraEffect && AuraEffectHandlerCreator == null) { AuraEffectHandlerCreator = AuraHandler.EffectHandlers[(int)AuraType]; if (AuraEffectHandlerCreator == null) { AuraEffectHandlerCreator = AuraHandler.EffectHandlers[0]; } } RepairBrokenTargetPairs(); IsEnchantmentEffect = EffectType == SpellEffectType.EnchantHeldItem || EffectType == SpellEffectType.EnchantItem || EffectType == SpellEffectType.EnchantItemTemporary; AISpellUtil.DecideDefaultTargetHandlerDefintion(this); }
public bool HasAreaEffect(AreaEffect ability) { return(AreaEffects != null && AreaEffects.Any(a => a == ability)); }
public void Parse(string lua, bool inherited, bool isChild) { if (lua != "" && !lua.EndsWith(".lua") && !lua.EndsWith(".nil")) { lua += ".lua"; } IsChild = isChild; string path = DataPath.GetPath("abilities\\" + lua); if (path != "") { StreamReader file = new StreamReader(File.OpenRead(path), System.Text.Encoding.ASCII); file.BaseStream.Seek(0, SeekOrigin.Begin); string s = file.ReadToEnd(); file.Close(); #region CHILD ABILITY if (ChildSkill == null) { Match mtc = Regex.Match(s, @"GameData\[""child_ability_name""\]\s=\s""(?<child>.*)"""); if (mtc.Success) { string child = mtc.Groups["child"].Value; if (child != "" && CheckLoop(child)) { ChildSkill = new SkillInfo(); ChildSkill.Parent = Parent; ChildSkill.LuaName = child; ChildSkill.Name = child; ChildSkill.ParentSkill = this; ChildSkill.Parse(child, false, true); } } } #endregion #region INHERITANCE Match mc = Regex.Match(s, @"GameData\s=\sInherit\(\[\[abilities\\(?<inherit>.*)\]\]\)"); if (mc.Success) { Group grp = mc.Groups["inherit"]; if (grp.Success && grp.Value != "") { Parse(grp.Value, true, isChild); } } #endregion double numValue = 0.0; string stringValue = ""; if (LuaParser.ReadNumericValue(s, @"GameData\[""refresh_time""\]\s=\s(?<refresh>.*)", out numValue)) { Refresh = numValue; } if (LuaParser.ReadStringValue(s, @"GameData\[""activation""\]\s=\sReference\(\[\[type_abilityactivation\\(?<actvationType>.*)\.lua\]\]\)", out stringValue)) { ActivationType = stringValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""duration_time""\]\s=\s(?<duration>.*)", out numValue)) { Duration = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""initial_delay_time""\]\s=\s(?<duration>.*)", out numValue)) { Delay = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""recharge_time""\]\s=\s(?<duration>.*)", out numValue)) { RechargeTime = numValue; } if (Regex.Match(s, @"GameData\[""recharge_timer_global""\]\s=\strue").Success) { GlobalTimer = true; } if (LuaParser.ReadNumericValue(s, @"GameData\[""fire_cost""\]\[""requisition""\]\s=\s(.*)", out numValue)) { RequisitionCost = (int)numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""fire_cost""\]\[""power""\]\s=\s(.*)", out numValue)) { PowerCost = (int)numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""area_effect_information""\]\[""radius""\]\s=\s(.*)", out numValue)) { Radius = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""range""\]\s=\s(.*)", out numValue)) { Range = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""time_cost""\]\[""cost""\]\[""power""\]\s=\s(.*)", out numValue)) { PowerCost = (int)numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""time_cost""\]\[""time_seconds""\]\s=\s(.*)", out numValue)) { RechargeTime = (int)numValue; } if (LuaParser.ReadStringValue(s, @"GameData\[""area_effect""\]\[""area_effect_information""\]\[""area_type""\]\s=\sReference\(\[\[type_areaeffect\\(.*)\.lua\]\]\)", out stringValue)) { AreaType = GetAreaType(stringValue); } if (LuaParser.ReadStringValue(s, @"GameData\[""area_effect""\]\[""area_effect_information""\]\[""filter_type""\]\s=\sReference\(\[\[type_areafilter\\(.*)\.lua\]\]\)", out stringValue)) { AOEFilter = stringValue; } if (Regex.Match(s, @"GameData\[""target_ground""\]\s=\strue").Success) { TargetGround = true; } if (LuaParser.ReadStringValue(s, @"GameData\[""spawned_entity_name""\]\s=\s""(?<spawn>.*\.lua)""", out stringValue)) { bool loopcheck = true; UnitInfo root = null; if (this.RootParent is UnitInfo) { root = RootParent as UnitInfo; string spawnName = Regex.Replace(stringValue, @".*\\\\", ""); if (root.FileName == spawnName) { loopcheck = false; } } if (loopcheck) { UnitInfo uInfo = new UnitInfo(); LuaParser.ParseUnit(DataPath.GetPath(Regex.Replace(stringValue, @"\\\\", "\\")), uInfo); Spawn = uInfo; } } if (LuaParser.ReadStringValue(s, @"GameData\[""ui_info""\]\[""icon_name""\]\s=\s""(.*)""", out stringValue)) { Icon = stringValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""armour_piercing""\]\s=\s(.*)", out numValue)) { BasePiercing = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""morale_damage""\]\s=\s(.*)", out numValue)) { MoraleDamage = numValue; } if (LuaParser.ReadNumericValue(s, @"\[""ui_info""\]\[""screen_name_id""\]\s=\s""\$(.*)""", out numValue)) { UI = (int)numValue; } string luaName = Regex.Replace(path, @".*\\", ""); if (!inherited && !isChild) { Name = Translation.Translate(UI, luaName); } MatchCollection mtcs = Regex.Matches(s, @"GameData\[""area_effect""\]\[""area_effect_information""\]\[""target_filter""\]\[""(?<filter_entry>entry_[0-9][0-9])""\]\s=\sReference\(\[\[type_armour\\(?<armour_type>.*)\.lua\]\]\)"); foreach (Match m in mtcs) { ArmorTypes armor; string entry = m.Groups["filter_entry"].Value; string armourType = m.Groups["armour_type"].Value; try { armor = (ArmorTypes)Enum.Parse(typeof(ArmorTypes), armourType); } catch { armor = ArmorTypes.unknown; } if (!Filter.ContainsKey(entry)) { Filter.Add(entry, armor); } else if (armor != ArmorTypes.unknown) { Filter[entry] = armor; } else { Filter.Remove(entry); } } #region DPS if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""min_damage""\]\s=\s(.*)", out numValue)) { MinDamage = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""max_damage""\]\s=\s(.*)", out numValue)) { MaxDamage = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""throw_data""\]\[""force_min""\]\s=\s(.*)", out numValue)) { MinForce = numValue; } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""throw_data""\]\[""force_max""\]\s=\s(.*)", out numValue)) { MaxForce = numValue; } MatchCollection aMcs = Regex.Matches(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""armour_piercing_types""\]\[""entry_(?<armor_entry>[0-9][0-9])""\]\[""armour_type""\]\s=\sReference\(\[\[type_armour\\(?<armor_type>.*)\.lua\]\]\)"); foreach (Match m in aMcs) // Retrieve ArmorTypes entries { string armor = m.Groups["armor_type"].Value; int armorEntry = System.Convert.ToInt32(Regex.Replace(m.Groups["armor_entry"].Value, "\b0", ""), LuaParser.NumberFormat); if (!ArmorPiercingValues.Contains(armorEntry)) { ArmorPiercing ap = new ArmorPiercing(); ap.Entry = armorEntry; try { ap.ArmorType = (ArmorTypes)Enum.Parse(typeof(ArmorTypes), armor); } catch { ap.ArmorType = ArmorTypes.unknown; } ArmorPiercingValues.Add(armorEntry, ap); } else { ArmorPiercing ap = ArmorPiercingValues[armorEntry] as ArmorPiercing; ap.Entry = armorEntry; try { ap.ArmorType = (ArmorTypes)Enum.Parse(typeof(ArmorTypes), armor); } catch { ap.ArmorType = ArmorTypes.unknown; } } } foreach (ArmorPiercing ap in ArmorPiercingValues.Values) { if (ap.ArmorType != ArmorTypes.unknown) { string subIndex = ""; int j = ap.Entry; if (j < 10) { subIndex = "0" + j.ToString(); } else { subIndex = j.ToString(); } if (LuaParser.ReadNumericValue(s, @"GameData\[""area_effect""\]\[""weapon_damage""\]\[""armour_damage""\]\[""armour_piercing_types""\]\[""entry_+" + subIndex + @"""\]\[""armour_piercing_value""\]\s=\s(.*)", out numValue)) { ap.PiercingValue = numValue; } } else { ap.PiercingValue = 0.0; } } #endregion LuaParser.ParseToolTips(s, this); LuaParser.ParseRequirements(s, this); LuaParser.ParseModifiers(s, this, this.Modifiers, AreaOfEffectTypes.area_effect); } }