protected void UpdateDamage(HeroData data, Dictionary <ElementType, AbilityDamageBase> damageLevels, IEnumerable <GroupType> tags) { if (abilityBase.abilityType == AbilityType.AURA || abilityBase.abilityType == AbilityType.SELF_BUFF) { return; } IList <GroupType> damageTags = abilityBase.GetGroupTypes(); Weapon mainWeapon = null, offWeapon = null; float flatDamageMod = abilityBase.flatDamageMultiplier; DualWielding = false; int[] mainConvertedDamageMin = new int[7]; int[] mainConvertedDamageMax = new int[7]; int[] offConvertedDamageMin = new int[7]; int[] offConvertedDamageMax = new int[7]; if (data.GetEquipmentInSlot(EquipSlotType.WEAPON) is Weapon) { mainWeapon = data.GetEquipmentInSlot(EquipSlotType.WEAPON) as Weapon; } if (data.GetEquipmentInSlot(EquipSlotType.OFF_HAND) is Weapon) { offWeapon = data.GetEquipmentInSlot(EquipSlotType.OFF_HAND) as Weapon; DualWielding = true; } HashSet <GroupType> nonWeaponTags = data.GetGroupTypes(false); HashSet <GroupType> mainHandTags = new HashSet <GroupType>(nonWeaponTags); if (mainWeapon != null) { mainHandTags.UnionWith(mainWeapon.GetGroupTypes()); if (DualWielding && !AlternatesAttacks || DualWielding && abilityBase.abilityType == AbilityType.SPELL) { mainHandTags.UnionWith(offWeapon.GetGroupTypes()); } } foreach (ElementType element in Enum.GetValues(typeof(ElementType))) { float offMinDamage = 0, offMaxDamage = 0, baseMinDamage = 0, baseMaxDamage = 0; if (damageLevels.ContainsKey(element)) { MinMaxRange abilityBaseDamage = damageLevels[element].damage[abilityLevel]; baseMinDamage = abilityBaseDamage.min; baseMaxDamage = abilityBaseDamage.max; } float mainMaxDamage; float mainMinDamage; if (abilityBase.abilityType == AbilityType.ATTACK) { float weaponMulti = abilityBase.weaponMultiplier + abilityBase.weaponMultiplierScaling * abilityLevel; flatDamageMod = weaponMulti; if (mainWeapon != null) { MinMaxRange mainWeaponDamage = mainWeapon.GetWeaponDamage(element); mainMinDamage = (mainWeaponDamage.min + baseMinDamage) * weaponMulti; mainMaxDamage = (mainWeaponDamage.max + baseMaxDamage) * weaponMulti; if (DualWielding) { MinMaxRange offWeaponDamage = offWeapon.GetWeaponDamage(element); offMinDamage = (offWeaponDamage.min + baseMinDamage) * weaponMulti; offMaxDamage = (offWeaponDamage.max + baseMaxDamage) * weaponMulti; offhandDamageBase[element].baseMin = offMinDamage; offhandDamageBase[element].baseMax = offMaxDamage; if (!AlternatesAttacks) { mainMinDamage = (mainMinDamage + offMinDamage) * 0.5f; mainMaxDamage = (mainMaxDamage + offMaxDamage) * 0.5f; } } } else { if (element == ElementType.PHYSICAL) { baseMinDamage += 4; baseMaxDamage += 9; } mainMinDamage = baseMinDamage * weaponMulti; mainMaxDamage = baseMaxDamage * weaponMulti; } } else { mainMinDamage = baseMinDamage; mainMaxDamage = baseMaxDamage; } mainDamageBase[element].baseMin = mainMinDamage; mainDamageBase[element].baseMax = mainMaxDamage; //Helpers.GetDamageTypes(element, abilityType, abilityBase.abilityShotType, damageTags, min, max, multi); HashSet <BonusType> min = new HashSet <BonusType>(); HashSet <BonusType> max = new HashSet <BonusType>(); HashSet <BonusType> multi = new HashSet <BonusType>(); Helpers.GetGlobalAndFlatDamageTypes(element, abilityBase.abilityType, abilityBase.abilityShotType, damageTags, min, max, multi); multi.UnionWith(Helpers.GetMultiplierTypes(abilityBase.abilityType, element)); mainDamageBase[element].ClearBonuses(); data.GetMultiStatBonus(mainDamageBase[element].minBonus, abilityBonuses, mainHandTags, min.ToArray()); data.GetMultiStatBonus(mainDamageBase[element].maxBonus, abilityBonuses, mainHandTags, max.ToArray()); data.GetMultiStatBonus(mainDamageBase[element].multiplierBonus, abilityBonuses, mainHandTags, multi.ToArray()); HashSet <BonusType> availableConversions = data.BonusesIntersection(abilityBonuses.Keys, Helpers.GetConversionTypes(element)); if (availableConversions.Count > 0) { GetElementConversionValues(data, mainHandTags, availableConversions, mainDamageBase[element].conversions, abilityBonuses); MinMaxRange baseRange = CalculateDamageConversion(data, flatDamageMod, mainConvertedDamageMin, mainConvertedDamageMax, mainHandTags, mainDamageBase[element], element, multi); mainDamageBase[element].calculatedRange.min = baseRange.min; mainDamageBase[element].calculatedRange.max = baseRange.max; } else { mainDamageBase[element].CalculateRange(flatDamageMod, finalDamageModifier); } if (DualWielding && AlternatesAttacks) { HashSet <GroupType> offHandTags = new HashSet <GroupType>(nonWeaponTags); offHandTags.UnionWith(offWeapon.GetGroupTypes()); offhandDamageBase[element].ClearBonuses(); data.GetMultiStatBonus(offhandDamageBase[element].minBonus, abilityBonuses, offHandTags, min.ToArray()); data.GetMultiStatBonus(offhandDamageBase[element].maxBonus, abilityBonuses, offHandTags, max.ToArray()); multi.UnionWith(Helpers.GetMultiplierTypes(abilityBase.abilityType, element)); data.GetMultiStatBonus(offhandDamageBase[element].multiplierBonus, abilityBonuses, offHandTags, multi.ToArray()); availableConversions = data.BonusesIntersection(abilityBonuses.Keys, Helpers.GetConversionTypes(element)); if (availableConversions.Count > 0) { GetElementConversionValues(data, offHandTags, availableConversions, offhandDamageBase[element].conversions, abilityBonuses); MinMaxRange baseRange = CalculateDamageConversion(data, flatDamageMod, offConvertedDamageMin, offConvertedDamageMax, offHandTags, offhandDamageBase[element], element, multi); offhandDamageBase[element].calculatedRange.min = Math.Max(baseRange.min, 0); offhandDamageBase[element].calculatedRange.max = Math.Max(baseRange.max, 0); } else { offhandDamageBase[element].CalculateRange(flatDamageMod, finalDamageModifier); } } } foreach (ElementType element in Enum.GetValues(typeof(ElementType))) { mainDamageBase[element].calculatedRange.min += mainConvertedDamageMin[(int)element]; mainDamageBase[element].calculatedRange.max += mainConvertedDamageMax[(int)element]; if (DualWielding && AlternatesAttacks) { offhandDamageBase[element].calculatedRange.min += offConvertedDamageMin[(int)element]; offhandDamageBase[element].calculatedRange.max += offConvertedDamageMax[(int)element]; } } }