/// <summary> /// Computes the <see cref="ItemAttributes"/> brought by the set bonuses. /// </summary> /// <param name="items"></param> /// <returns></returns> public static ItemAttributes GetActivatedSetBonus(this List<Item> items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } var attributeSetItemDiscount = items .Select(i => i.AttributesRaw.AttributeSetItemDiscount) .Where(asid => asid != null) .Aggregate(ItemValueRange.Zero, (asid, current) => current + asid); var result = new ItemAttributes(); foreach (var set in items.GetActivatedSets()) { var setItemsCount = set.CountItemsOfSet(items); if (setItemsCount >= 2) { setItemsCount += (int)Math.Round(attributeSetItemDiscount.Min); } result += set.GetBonus(setItemsCount); } return result; }
public static ItemAttributes operator -(ItemAttributes left, ItemAttributes right) { var target = new ItemAttributes(left); var type = target.GetType(); foreach (var fieldInfo in type.GetTypeInfo().DeclaredFields) { if (fieldInfo.Name != "UnmanagedAttributes" && fieldInfo.GetValue(right) != null) { var targetValueRange = (ItemValueRange)fieldInfo.GetValue(target); var rightValueRange = (ItemValueRange)fieldInfo.GetValue(right); if (targetValueRange == null) { targetValueRange = new ItemValueRange(); } targetValueRange -= rightValueRange; if (targetValueRange.Min == 0 && targetValueRange.Max == 0) { targetValueRange = null; } fieldInfo.SetValue(target, targetValueRange - rightValueRange); } } return(target); }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var attr = new ItemAttributes { hitpointsRegenPerSecond = new ItemValueRange(620) }; attr += (new ResistancesMultiplier(multiplier)).GetBonus(calculator); return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var attr = new ItemAttributes { armorBonusItem = 0.25 * calculator.GetHeroArmor() }; attr += new ThornsMultiplier(multiplier).GetBonus(calculator); return attr; }
public void OperatorAddNullAndRight() { var right = new ItemAttributes { armorItem = new ItemValueRange(2), powerCooldownReductionPercentAll = new ItemValueRange(0.20) }; var sum = null + right; Assert.AreEqual(new ItemValueRange(2), sum.armorItem); Assert.AreEqual(new ItemValueRange(0.20), sum.powerCooldownReductionPercentAll); }
public void OperatorAddLeftAndNull() { var left = new ItemAttributes { armorItem = new ItemValueRange(1), powerCooldownReductionPercentAll = new ItemValueRange(0.10) }; var sum = left + null; Assert.AreEqual(new ItemValueRange(1), sum.armorItem); Assert.AreEqual(new ItemValueRange(0.10), sum.powerCooldownReductionPercentAll); }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var attr = new ItemAttributes { armorBonusItem = 0.20 * calculator.GetHeroArmor(), hitpointsRegenPerSecond = new ItemValueRange(620) }; return attr; }
/// <summary> /// Returns the final bonus as an <see cref="ItemAttributes"/> instance. /// </summary> /// <returns></returns> public ItemAttributes GetBonus() { var attr = new ItemAttributes(); if (!String.IsNullOrEmpty(AttributeName)) { attr.SetAttributeByName(AttributeName, CurrentPoints * BonusPerPoint); } return attr; }
/// <summary> /// Computes the sum of a sequence of <see cref="ItemAttributes"/> values. /// </summary> /// <param name="itemAttributes">A sequence of <see cref="ItemAttributes"/> values to calculate the sum of.</param> /// <returns></returns> public static ItemAttributes Sum(this IEnumerable<ItemAttributes> itemAttributes) { var target = new ItemAttributes(); foreach (var attr in itemAttributes.Where(a => a != null)) { ItemAttributes.SumIntoLeftOperand(target, attr); } return target; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var stuff = calculator.HeroStatsItem.AttributesRaw; var attr = new ItemAttributes(); if (stuff.critPercentBonusCapped != null) attr.critPercentBonusCapped = ItemValueRange.One - stuff.critPercentBonusCapped; else attr.critPercentBonusCapped = ItemValueRange.One; return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var attr = new ItemAttributes { hitpointsMaxPercentBonusItem = new ItemValueRange(0.10), armorBonusItem = multiplier * calculator.GetHeroArmor() }; attr += (new ResistancesMultiplier(multiplier)).GetBonus(calculator); return attr; }
/// <summary> /// Returns final bonus the <paramref name="set"/> give when <paramref name="count"/> items from the set are weared /// </summary> /// <param name="set"></param> /// <param name="count">Number of items from set weared</param> /// <returns></returns> public static ItemAttributes GetBonus(this Set set, int count) { var attr = new ItemAttributes(); if (count > 1) { attr = set.ranks .Where(rank => count >= rank.Required) .Aggregate(attr, (current, setRank) => current + setRank.AttributesRaw); } return attr; }
public D3Calculator(Hero hero, Item mainHand, Item offHand, IEnumerable<Item> items) { HeroClass = hero.heroClass; HeroLevel = hero.level; // Build unique item equivalent to items worn HeroStatsItem = new StatsItem(mainHand, offHand, items); levelAttributes = new ItemAttributesFromLevel(hero); paragonLevelAttributes = new ItemAttributesFromParagonLevel(hero); Update(); }
/// <summary> /// Creates a new instance by copying fields of <paramref name="itemAttributes"/> (deep copy). /// </summary> /// <param name="itemAttributes"></param> public ItemAttributes(ItemAttributes itemAttributes) { var type = GetType(); foreach (var fieldInfo in type.GetTypeInfo().DeclaredFields) { var valueRange = fieldInfo.GetValue(itemAttributes) as ItemValueRange; if (valueRange != null) { fieldInfo.SetValue(this, new ItemValueRange(valueRange)); } } }
public static ItemAttributes operator +(ItemAttributes left, ItemAttributes right) { if (left == null) { return(new ItemAttributes(right)); } var target = new ItemAttributes(left); SumIntoLeftOperand(target, right); return(target); }
/// <summary> /// Returns final bonus the <paramref name="set"/> give when <paramref name="count"/> items from the set are weared /// </summary> /// <param name="set"></param> /// <param name="count">Number of items from set weared</param> /// <returns></returns> public static ItemAttributes GetBonus(this Set set, int count) { var attr = new ItemAttributes(); if (count > 1) { attr = set.ranks .Where(rank => count >= rank.Required) .Select(rank => rank.AttributesRaw) .Sum(); } return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { Item stuff = calculator.HeroStatsItem; var attr = new ItemAttributes { resistance_All = multiplier*stuff.AttributesRaw.resistance_All, resistance_Arcane = multiplier*stuff.AttributesRaw.resistance_Arcane, resistance_Cold = multiplier*stuff.AttributesRaw.resistance_Cold, resistance_Fire = multiplier*stuff.AttributesRaw.resistance_Fire, resistance_Lightning = multiplier*stuff.AttributesRaw.resistance_Lightning, resistance_Physical = multiplier*stuff.AttributesRaw.resistance_Physical, resistance_Poison = multiplier*stuff.AttributesRaw.resistance_Poison }; return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { Item stuff = calculator.HeroStatsItem; var attr = new ItemAttributes(); foreach (var resist in damageResists) { foreach (var damage in damagePrefixes) { var value = stuff.GetAttributeByName(damage + resist); attr.SetAttributeByName(damage + resist, multiplier * value); } } return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var stuff = calculator.HeroStatsItem.AttributesRaw; var attr = new ItemAttributes { resistance_All = 0.40 * (stuff.resistance_Arcane + stuff.resistance_Cold + stuff.resistance_Fire + stuff.resistance_Lightning + stuff.resistance_Physical + stuff.resistance_Poison) }; return attr; }
/// <inheritdoc /> public ItemAttributes GetBonus(D3Calculator calculator) { var stuff = calculator.HeroStatsItem.AttributesRaw; var attr = new ItemAttributes(); double maxResist = 0; var resistanceArcane = calculator.GetHeroResistance("Arcane").Min; if (resistanceArcane > maxResist) maxResist = resistanceArcane; var resistanceCold = calculator.GetHeroResistance("Cold").Min; if (resistanceCold > maxResist) maxResist = resistanceCold; var resistanceFire = calculator.GetHeroResistance("Fire").Min; if (resistanceFire > maxResist) maxResist = resistanceFire; var resistanceLightning = calculator.GetHeroResistance("Lightning").Min; if (resistanceLightning > maxResist) maxResist = resistanceLightning; var resistancePhysical = calculator.GetHeroResistance("Physical").Min; if (resistancePhysical > maxResist) maxResist = resistancePhysical; var resistancePoison = calculator.GetHeroResistance("Poison").Min; if (resistancePoison > maxResist) maxResist = resistancePoison; if (stuff.resistance_Arcane != null) attr.resistance_Arcane = ItemValueRange.Zero - stuff.resistance_Arcane; if (stuff.resistance_Cold != null) attr.resistance_Cold = ItemValueRange.Zero - stuff.resistance_Cold; if (stuff.resistance_Fire != null) attr.resistance_Fire = ItemValueRange.Zero - stuff.resistance_Fire; if (stuff.resistance_Lightning != null) attr.resistance_Lightning = ItemValueRange.Zero - stuff.resistance_Lightning; if (stuff.resistance_Physical != null) attr.resistance_Physical = ItemValueRange.Zero - stuff.resistance_Physical; if (stuff.resistance_Poison != null) attr.resistance_Poison = ItemValueRange.Zero - stuff.resistance_Poison; if (stuff.resistance_All != null) attr.resistance_All = new ItemValueRange(maxResist - calculator.getHeroResistance_All()); return attr; }
/// <summary> /// Sums up <paramref name="right"/> operand into <paramref name="left"/> operand. /// <paramref name="left"/> is updated by this method (used as a memory and speed optimization of <c>left = left + right</c>). /// </summary> /// <param name="left">Left operand of the addition, can't be <c>null</c>.</param> /// <param name="right">Right operand of the addition, can be <c>null</c>.</param> public static void SumIntoLeftOperand(ItemAttributes left, ItemAttributes right) { if (right == null) { return; } var typeInfo = left.GetType().GetTypeInfo(); var targetType = typeof(ItemValueRange); // TODO: find a better way to handle this particular case... var powerCooldownReductionPercentAll = left.powerCooldownReductionPercentAll; foreach (var fieldInfo in typeInfo.DeclaredFields) { if (fieldInfo.FieldType == targetType) { var rightValue = fieldInfo.GetValue(right); if (rightValue != null) { var leftValueRange = (ItemValueRange)fieldInfo.GetValue(left); var rightValueRange = (ItemValueRange)rightValue; if (leftValueRange == null) { fieldInfo.SetValue(left, new ItemValueRange(rightValueRange)); } else { fieldInfo.SetValue(left, leftValueRange + rightValueRange); } } } } // TODO: find a better way to handle this particular case... if (powerCooldownReductionPercentAll != null) { left.powerCooldownReductionPercentAll = powerCooldownReductionPercentAll; ItemValueRange.SumAsPercentOnRemainingIntoLeftOperand(left.powerCooldownReductionPercentAll, right.powerCooldownReductionPercentAll); } }
public D3Calculator(Follower follower, HeroClass heroClass, Item mainHand, Item offHand, IEnumerable<Item> items) { HeroClass = heroClass; HeroLevel = follower.level; foreach (var item in items.Union(new[] { mainHand, offHand })) { ApplyFollowersBonusMalusOnItemAttributes(item.AttributesRaw, heroClass); if (item.Gems != null) { foreach (var gem in item.Gems) { ApplyFollowersBonusMalusOnItemAttributes(gem.AttributesRaw, heroClass); } } } // Build unique item equivalent to items worn HeroStatsItem = new StatsItem(mainHand, offHand, items); levelAttributes = new Followers.ItemAttributesFromLevel(follower, heroClass); Update(); }
public void SetSkillsBonus(ItemAttributes addedBonus) { this.addedBonus = addedBonus; }
public void SetParagonLevelBonus(ItemAttributes itemParagonLevel) { attrParagonLevel = itemParagonLevel; }
public void SetLevelBonus(ItemAttributes levelAttr) { this.levelAttr = levelAttr; }
public void Update() { AttributesRaw = new ItemAttributes(); // Add bonus from level and paragon if (levelAttr != null) { AttributesRaw += levelAttr; } if (attrParagonLevel != null) { AttributesRaw += attrParagonLevel; } // Build a list of all items with fields var stuff = new List<Item>(items); // Add bonus (skills, buffs) if (addedBonus != null) { AttributesRaw += addedBonus; } // Merge gems with their items foreach (var item in items.Where(item => item.Gems != null)) { item.MergeSocketedGems(); } if (MainHand.Gems != null) { MainHand.MergeSocketedGems(); } if (offHand.Gems != null) { offHand.MergeSocketedGems(); } // Add items foreach (var item in stuff) { AttributesRaw += item.AttributesRaw; } // Add weapons - Note: we don't want attackPerSecondItem to include weapon's value, only stuff or skills bonuses var attackPerSecondItem = AttributesRaw.attacksPerSecondItem; if (IsAmbidexterity()) { ambidexterityWeapon = new Item(ComputeAmbidexterityWeaponAttributes()); AttributesRaw += ambidexterityWeapon.AttributesRaw; // Ambidextry gets a 15% attack speed bonus AttributesRaw += new ItemAttributes { attacksPerSecondPercent = new ItemValueRange(0.15) }; } else { AttributesRaw += MainHand.AttributesRaw; AttributesRaw += offHand.AttributesRaw; } AttributesRaw.attacksPerSecondItem = attackPerSecondItem; }
public ItemValueRange GetValue(ItemAttributes attributes) { ItemValueRange value; if (refAttribute == null) { value = attributes.GetAttributeByName(targetAttribute); } else { value = attributes.GetAttributeByName(targetAttribute) + attributes.GetAttributeByName(refAttribute); } if (Percent) { value *= 100; } return value; }
private static void UpdateEditedItem(ViewGroup layout) { var numberDecimalSeparator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; var attr = new ItemAttributes(); for (var index = 0; index < layout.ChildCount; index++) { var view = layout.GetChildAt(index); var editText = view.FindViewById<EditText>(Resource.Id.attributeValue); if (editText != null) { var tag = (JavaLangObject<Field>)(view.Tag); Console.WriteLine(tag.Value + " = " + editText.Text); var text = editText.Text.Replace(numberDecimalSeparator == "," ? "." : ",", numberDecimalSeparator); double value; if (Double.TryParse(text, out value)) { tag.Value.SetValue(attr, value); } } } D3Context.Instance.EditingItem.AttributesRaw += attr; }
public Item(ItemAttributes itemAttributes) { AttributesRaw = itemAttributes; }
public static ItemAttributes operator *(ItemAttributes left, ItemAttributes right) { var target = new ItemAttributes(left); var type = target.GetType(); foreach (var fieldInfo in type.GetTypeInfo().DeclaredFields) { if (fieldInfo.Name != "UnmanagedAttributes" && fieldInfo.GetValue(right) != null) { var targetValueRange = (ItemValueRange)fieldInfo.GetValue(target); var rightValueRange = (ItemValueRange)fieldInfo.GetValue(right); if (targetValueRange == null) { targetValueRange = new ItemValueRange(1); } fieldInfo.SetValue(target, targetValueRange * rightValueRange); } } return target; }
public static ItemAttributes operator +(ItemAttributes left, ItemAttributes right) { if (left == null) { return new ItemAttributes(right); } var target = new ItemAttributes(left); SumIntoLeftOperand(target, right); return target; }
public void SetValue(ItemAttributes attributes, double value) { if (Percent) { value /= 100; } if (refAttribute == null) { attributes.SetAttributeByName(targetAttribute, new ItemValueRange(value)); } else { attributes.SetAttributeByName(targetAttribute, new ItemValueRange(value) - attributes.GetAttributeByName(refAttribute)); } }
/// <summary> /// Creates a new instance by copying fields of <paramref name="itemAttributes"/> (deep copy). /// Note: Only fields of type <see cref="ItemValueRange"/> are copied. /// </summary> /// <param name="itemAttributes"></param> public ItemAttributes(ItemAttributes itemAttributes) { if (itemAttributes == null) { return; } var type = GetType(); foreach (var fieldInfo in type.GetTypeInfo().DeclaredFields) { var valueRange = fieldInfo.GetValue(itemAttributes) as ItemValueRange; if (valueRange != null) { fieldInfo.SetValue(this, new ItemValueRange(valueRange)); } } }
public Item GetEditedItem() { var item = new Item(); var attr = new ItemAttributes(); item.Name = guiItemName.Text; item.Id = guiItemId.Text; item.Type = new ItemType(guiItemTypeId.Text, false); attr.dexterityItem = GetData(guiDexterity); attr.intelligenceItem = GetData(guiIntelligence); attr.strengthItem = GetData(guiStrength); attr.vitalityItem = GetData(guiVitality); attr.attacksPerSecondPercent = GetDataPercent(guiAttackSpeed); attr.critDamagePercent = GetDataPercent(guiCriticDamage); attr.critPercentBonusCapped = GetDataPercent(guiCriticChance); attr.hitpointsMaxPercentBonusItem = GetDataPercent(guiHitpointsMaxPercent); attr.armorItem = GetData(guiArmor); attr.attacksPerSecondItem = GetData(guiWeaponAttackPerSecond); attr.damageWeaponPercentBonus_Physical = GetDataPercent(guiWeaponDamagePercentBonus); var damageWeaponPercentBonus_Physical = (attr.damageWeaponPercentBonus_Physical == null ? 0 : attr.damageWeaponPercentBonus_Physical.Min); attr.damageWeaponMin_Arcane = GetData(guiWeaponDamageMinArcane); attr.damageWeaponMin_Cold = GetData(guiWeaponDamageMinCold); attr.damageWeaponMin_Fire = GetData(guiWeaponDamageMinFire); attr.damageWeaponMin_Holy = GetData(guiWeaponDamageMinHoly); attr.damageWeaponMin_Lightning = GetData(guiWeaponDamageMinLightning); attr.damageWeaponMin_Physical = GetData(guiWeaponDamageMinPhysical) / (1 + damageWeaponPercentBonus_Physical); attr.damageWeaponMin_Poison = GetData(guiWeaponDamageMinPoison); attr.damageWeaponDelta_Arcane = GetData(guiWeaponDamageMaxArcane) - attr.damageWeaponMin_Arcane; attr.damageWeaponDelta_Cold = GetData(guiWeaponDamageMaxCold) - attr.damageWeaponMin_Cold; attr.damageWeaponDelta_Fire = GetData(guiWeaponDamageMaxFire) - attr.damageWeaponMin_Fire; attr.damageWeaponDelta_Holy = GetData(guiWeaponDamageMaxHoly) - attr.damageWeaponMin_Holy; attr.damageWeaponDelta_Lightning = GetData(guiWeaponDamageMaxLightning) - attr.damageWeaponMin_Lightning; attr.damageWeaponDelta_Physical = GetData(guiWeaponDamageMaxPhysical) / (1 + damageWeaponPercentBonus_Physical) - attr.damageWeaponMin_Physical; attr.damageWeaponDelta_Poison = GetData(guiWeaponDamageMaxPoison) - attr.damageWeaponMin_Poison; attr.damageMin_Arcane = GetData(guiBonusDamageMinArcane); attr.damageMin_Cold = GetData(guiBonusDamageMinCold); attr.damageMin_Fire = GetData(guiBonusDamageMinFire); attr.damageMin_Holy = GetData(guiBonusDamageMinHoly); attr.damageMin_Lightning = GetData(guiBonusDamageMinLightning); attr.damageMin_Physical = GetData(guiBonusDamageMinPhysical); attr.damageMin_Poison = GetData(guiBonusDamageMinPoison); attr.damageDelta_Arcane = GetData(guiBonusDamageMaxArcane) - attr.damageMin_Arcane; attr.damageDelta_Cold = GetData(guiBonusDamageMaxCold) - attr.damageMin_Cold; attr.damageDelta_Fire = GetData(guiBonusDamageMaxFire) - attr.damageMin_Fire; attr.damageDelta_Holy = GetData(guiBonusDamageMaxHoly) - attr.damageMin_Holy; attr.damageDelta_Lightning = GetData(guiBonusDamageMaxLightning) - attr.damageMin_Lightning; attr.damageDelta_Physical = GetData(guiBonusDamageMaxPhysical) - attr.damageMin_Physical; attr.damageDelta_Poison = GetData(guiBonusDamageMaxPoison) - attr.damageMin_Poison; attr.damageTypePercentBonus_Arcane = GetDataPercent(guiBonusDamagePercentArcane); attr.damageTypePercentBonus_Cold = GetDataPercent(guiBonusDamagePercentCold); attr.damageTypePercentBonus_Fire = GetDataPercent(guiBonusDamagePercentFire); attr.damageTypePercentBonus_Holy = GetDataPercent(guiBonusDamagePercentHoly); attr.damageTypePercentBonus_Lightning = GetDataPercent(guiBonusDamagePercentLightning); attr.damageTypePercentBonus_Physical = GetDataPercent(guiBonusDamagePercentPhysical); attr.damageTypePercentBonus_Poison = GetDataPercent(guiBonusDamagePercentPoison); attr.damageDealtPercentBonusArcane = GetDataPercent(guiSkillBonusPercentArcane); attr.damageDealtPercentBonusCold = GetDataPercent(guiSkillBonusPercentCold); attr.damageDealtPercentBonusFire = GetDataPercent(guiSkillBonusPercentFire); attr.damageDealtPercentBonusHoly = GetDataPercent(guiSkillBonusPercentHoly); attr.damageDealtPercentBonusLightning = GetDataPercent(guiSkillBonusPercentLightning); attr.damageDealtPercentBonusPhysical = GetDataPercent(guiSkillBonusPercentPhysical); attr.damageDealtPercentBonusPoison = GetDataPercent(guiSkillBonusPercentPoison); attr.powerCooldownReductionPercentAll = GetDataPercent(guiSkillCooldownReductionAll); attr.damagePercentBonusVsElites = GetDataPercent(guiBonusEliteDamagePercent); attr.resistance_All = GetData(guiResistance_All); attr.resistance_Arcane = GetData(guiResistance_Arcane); attr.resistance_Cold = GetData(guiResistance_Cold); attr.resistance_Fire = GetData(guiResistance_Fire); attr.resistance_Lightning = GetData(guiResistance_Lightning); attr.resistance_Physical = GetData(guiResistance_Physical); attr.resistance_Poison = GetData(guiResistance_Poison); // Shield attr.blockChanceItem = GetData(guiShieldBlockPercent); attr.blockAmountItemMin = GetData(guiShieldBlockMin); attr.blockAmountItemDelta = GetData(guiShieldBlockMax) - attr.blockAmountItemMin; attr.hitpointsOnHit = GetData(guiHitpointsOnHit); attr.hitpointsRegenPerSecond = GetData(guiHitpointsRegenPerSecond); attr.stealHealthPercent = GetDataPercent(guiLifeSteal); attr.damagePercentReductionFromElites = GetDataPercent(guiReductionFromElitesPercent); attr.damagePercentReductionFromMelee = GetDataPercent(guiReductionFromMeleePercent); attr.damagePercentReductionFromRanged = GetDataPercent(guiReductionFromRangedPercent); item.AttributesRaw = attr; var gems = new List<SocketedGem>(); if (guiGem1.SelectedIndex > 0) { var gem = new SocketedGem(new Item(((GemsListViewItem)guiGem1.SelectedItem).Item)); gems.Add(gem); } if (guiGem2.SelectedIndex > 0) { var gem = new SocketedGem(new Item(((GemsListViewItem)guiGem2.SelectedItem).Item)); gems.Add(gem); } if (guiGem3.SelectedIndex > 0) { var gem = new SocketedGem(new Item(((GemsListViewItem)guiGem3.SelectedItem).Item)); gems.Add(gem); } item.Gems = gems.ToArray(); return item; }