private Vector2 DrawMod(ModValue item, Vector2 position) { const float EPSILON = 0.001f; const int MARGIN_BOTTOM = 4, MARGIN_LEFT = 50; Vector2 oldPosition = position; ItemModsSettings settings = Settings.ItemMods; string prefix = item.AffixType == ModsDat.ModType.Prefix ? "[P]" : item.AffixType == ModsDat.ModType.Suffix ? "[S]" : "[?]"; if (item.AffixType != ModsDat.ModType.Hidden) { if (item.CouldHaveTiers()) { prefix += string.Format(" T{0} ", item.Tier); } Graphics.DrawText(prefix, settings.ModTextSize, position.Translate(5 - MARGIN_LEFT, 0)); Size2 textSize = Graphics.DrawText(item.AffixText, settings.ModTextSize, position, item.Color); if (textSize != new Size2()) { position.Y += textSize.Height; } } for (int i = 0; i < 4; i++) { IntRange range = item.Record.StatRange[i]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord stat = item.Record.StatNames[i]; int value = item.StatValue[i]; if (value <= -1000 || stat == null) { continue; } float percents = range.GetPercentage(value); bool noSpread = !range.HasSpread(); double hue = percents > 1 ? 180 : 120 * percents; if (noSpread) { hue = 300; } string line2 = string.Format(noSpread ? "{0}" : "{0} [{1}]", stat, range); Graphics.DrawText(line2, settings.ModTextSize, position, Color.White); string statText = stat.ValueToString(value); Vector2 statPosition = position.Translate(-5, 0); Color statColor = ColorUtils.ColorFromHsv(hue, 1, 1); Size2 txSize = Graphics.DrawText(statText, settings.ModTextSize, statPosition, statColor, FontDrawFlags.Right); position.Y += txSize.Height; } return(Math.Abs(position.Y - oldPosition.Y) > EPSILON?position.Translate(0, MARGIN_BOTTOM) : oldPosition); }
private void DrawWeaponDps(RectangleF clientRect) { var weapon = itemEntity.GetComponent <Weapon>(); float aSpd = 1000f / weapon.AttackTime; int cntDamages = Enum.GetValues(typeof(DamageType)).Length; var doubleDpsPerStat = new float[cntDamages]; float physDmgMultiplier = 1; doubleDpsPerStat[(int)DamageType.Physical] = weapon.DamageMax + weapon.DamageMin; foreach (ModValue mod in mods) { for (int iStat = 0; iStat < 4; iStat++) { IntRange range = mod.Record.StatRange[iStat]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord theStat = mod.Record.StatNames[iStat]; int value = mod.StatValue[iStat]; switch (theStat.Key) { case "physical_damage_+%": case "local_physical_damage_+%": physDmgMultiplier += value / 100f; break; case "local_attack_speed_+%": aSpd *= (100f + value) / 100; break; case "local_minimum_added_physical_damage": case "local_maximum_added_physical_damage": doubleDpsPerStat[(int)DamageType.Physical] += value; break; case "local_minimum_added_fire_damage": case "local_maximum_added_fire_damage": case "unique_local_minimum_added_fire_damage_when_in_main_hand": case "unique_local_maximum_added_fire_damage_when_in_main_hand": doubleDpsPerStat[(int)DamageType.Fire] += value; break; case "local_minimum_added_cold_damage": case "local_maximum_added_cold_damage": case "unique_local_minimum_added_cold_damage_when_in_off_hand": case "unique_local_maximum_added_cold_damage_when_in_off_hand": doubleDpsPerStat[(int)DamageType.Cold] += value; break; case "local_minimum_added_lightning_damage": case "local_maximum_added_lightning_damage": doubleDpsPerStat[(int)DamageType.Lightning] += value; break; case "unique_local_minimum_added_chaos_damage_when_in_off_hand": case "unique_local_maximum_added_chaos_damage_when_in_off_hand": case "local_minimum_added_chaos_damage": case "local_maximum_added_chaos_damage": doubleDpsPerStat[(int)DamageType.Chaos] += value; break; } } } doubleDpsPerStat[(int)DamageType.Physical] *= physDmgMultiplier; int quality = itemEntity.GetComponent <Quality>().ItemQuality; if (quality > 0) { doubleDpsPerStat[(int)DamageType.Physical] += (weapon.DamageMax + weapon.DamageMin) * quality / 100f; } float pDps = doubleDpsPerStat[(int)DamageType.Physical] / 2 * aSpd; float eDps = 0; int firstEmg = 0; Color eDpsColor = Color.White; for (int i = 1; i < cntDamages; i++) { eDps += doubleDpsPerStat[i] / 2 * aSpd; if (doubleDpsPerStat[i] > 0) { if (firstEmg == 0) { firstEmg = i; eDpsColor = elementalDmgColors[i]; } else { eDpsColor = Color.DarkViolet; } } } WeaponDpsSettings settings = Settings.WeaponDps; var textPosition = new Vector2(clientRect.Right - 2, clientRect.Y + 1); Size2 pDpsSize = pDps > 0 ? Graphics.DrawText(pDps.ToString("#.#"), settings.DpsTextSize, textPosition, FontDrawFlags.Right) : new Size2(); Size2 eDpsSize = eDps > 0 ? Graphics.DrawText(eDps.ToString("#.#"), settings.DpsTextSize, textPosition.Translate(0, pDpsSize.Height), eDpsColor, FontDrawFlags.Right) : new Size2(); Vector2 dpsTextPosition = textPosition.Translate(0, pDpsSize.Height + eDpsSize.Height); Graphics.DrawText("DPS", settings.DpsNameTextSize, dpsTextPosition, Color.White, FontDrawFlags.Right); }
public static float DPS(Item item) { Settings settings = Main.Core.Settings; Weapon weapon = item.Original.Item.GetComponent <Weapon>(); float aSpd = (float)Math.Round(1000f / weapon.AttackTime, 2); int cntDamages = Enum.GetValues(typeof(DamageType)).Length; float[] doubleDpsPerStat = new float[cntDamages]; float physDmgMultiplier = 1; int PhysHi = weapon.DamageMax; int PhysLo = weapon.DamageMin; foreach (ModValue mod in item.Mods) { for (int iStat = 0; iStat < 4; iStat++) { IntRange range = mod.Record.StatRange[iStat]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord theStat = mod.Record.StatNames[iStat]; int value = mod.StatValue[iStat]; switch (theStat.Key) { case "physical_damage_+%": case "local_physical_damage_+%": physDmgMultiplier += value / 100f; break; case "local_attack_speed_+%": aSpd *= (100f + value) / 100; break; case "local_minimum_added_physical_damage": PhysLo += value; break; case "local_maximum_added_physical_damage": PhysHi += value; break; case "local_minimum_added_fire_damage": case "local_maximum_added_fire_damage": case "unique_local_minimum_added_fire_damage_when_in_main_hand": case "unique_local_maximum_added_fire_damage_when_in_main_hand": doubleDpsPerStat[(int)DamageType.Fire] += value; break; case "local_minimum_added_cold_damage": case "local_maximum_added_cold_damage": case "unique_local_minimum_added_cold_damage_when_in_off_hand": case "unique_local_maximum_added_cold_damage_when_in_off_hand": doubleDpsPerStat[(int)DamageType.Cold] += value; break; case "local_minimum_added_lightning_damage": case "local_maximum_added_lightning_damage": doubleDpsPerStat[(int)DamageType.Lightning] += value; break; case "unique_local_minimum_added_chaos_damage_when_in_off_hand": case "unique_local_maximum_added_chaos_damage_when_in_off_hand": case "local_minimum_added_chaos_damage": case "local_maximum_added_chaos_damage": doubleDpsPerStat[(int)DamageType.Chaos] += value; break; } } } physDmgMultiplier += item.Original.Item.GetComponent <Quality>().ItemQuality / 100f; PhysLo = (int)Math.Round(PhysLo * physDmgMultiplier); PhysHi = (int)Math.Round(PhysHi * physDmgMultiplier); doubleDpsPerStat[(int)DamageType.Physical] = PhysLo + PhysHi; aSpd = (float)Math.Round(aSpd, 2); float pDps = doubleDpsPerStat[(int)DamageType.Physical] / 2 * aSpd; float eDps = 0; for (int i = 1; i < cntDamages; i++) { eDps += doubleDpsPerStat[i] / 2 * aSpd; } float dps = pDps * settings.PhysicalDPSWeight + eDps * settings.EleDPSWeight; return(dps); }
private void RenderWeaponStats(RenderingContext rc, Rect clientRect) { const int innerPadding = 3; float aSpd = ((float)1000) / _weaponAttack.AttackDelay; int cntDamages = Enum.GetValues(typeof(DamageType)).Length; float[] doubleDpsPerStat = new float[cntDamages]; float physDmgMultiplier = 1; doubleDpsPerStat[(int)DamageType.Physical] = _weaponAttack.MaxDamage + _weaponAttack.MinDamage; foreach (RollValue roll in _explicitMods) { for (int iStat = 0; iStat < 4; iStat++) { IntRange range = roll.TheMod.StatRange[iStat]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord theStat = roll.TheMod.StatNames[iStat]; int val = roll.StatValue[iStat]; switch (theStat.Key) { case "physical_damage_+%": case "local_physical_damage_+%": physDmgMultiplier += val / 100f; break; case "local_attack_speed_+%": aSpd *= (100f + val) / 100; break; case "local_minimum_added_physical_damage": case "local_maximum_added_physical_damage": doubleDpsPerStat[(int)DamageType.Physical] += val; break; case "local_minimum_added_fire_damage": case "local_maximum_added_fire_damage": case "unique_local_minimum_added_fire_damage_when_in_main_hand": case "unique_local_maximum_added_fire_damage_when_in_main_hand": doubleDpsPerStat[(int)DamageType.Fire] += val; break; case "local_minimum_added_cold_damage": case "local_maximum_added_cold_damage": case "unique_local_minimum_added_cold_damage_when_in_off_hand": case "unique_local_maximum_added_cold_damage_when_in_off_hand": doubleDpsPerStat[(int)DamageType.Cold] += val; break; case "local_minimum_added_lightning_damage": case "local_maximum_added_lightning_damage": doubleDpsPerStat[(int)DamageType.Lightning] += val; break; case "unique_local_minimum_added_chaos_damage_when_in_off_hand": case "unique_local_maximum_added_chaos_damage_when_in_off_hand": case "local_minimum_added_chaos_damage": case "local_maximum_added_chaos_damage": doubleDpsPerStat[(int)DamageType.Chaos] += val; break; default: break; } } } doubleDpsPerStat[(int)DamageType.Physical] *= physDmgMultiplier; if (_quality > 0) { doubleDpsPerStat[(int)DamageType.Physical] += (_weaponAttack.MaxDamage + _weaponAttack.MinDamage) * _quality / 100f; } float pDps = doubleDpsPerStat[(int)DamageType.Physical] / 2 * aSpd; float eDps = 0; int firstEmg = 0; Color eDpsColor = Color.White; for (int i = 1; i < cntDamages; i++) { eDps += doubleDpsPerStat[i] / 2 * aSpd; if (doubleDpsPerStat[i] > 0) { if (firstEmg == 0) { firstEmg = i; eDpsColor = eleCols[i]; } else { eDpsColor = Color.DarkViolet; } } } Vec2 sz = new Vec2(); if (pDps > 0) { sz = rc.AddTextWithHeight(new Vec2(clientRect.X + clientRect.W - Settings.OffsetInnerX, clientRect.Y + Settings.OffsetInnerY), pDps.ToString("#.#"), Color.White, Settings.DpsFontSize, DrawTextFormat.Right); } Vec2 sz2 = new Vec2(); if (eDps > 0) { sz2 = rc.AddTextWithHeight(new Vec2(clientRect.X + clientRect.W - Settings.OffsetInnerX, clientRect.Y + Settings.OffsetInnerY + sz.Y), eDps.ToString("#.#"), eDpsColor, Settings.DpsFontSize, DrawTextFormat.Right); } rc.AddTextWithHeight(new Vec2(clientRect.X + clientRect.W - Settings.OffsetInnerX, clientRect.Y + Settings.OffsetInnerY + sz.Y + sz2.Y), "DPS", Color.White, 8, DrawTextFormat.Right); }
private Vector2 DrawMod(ModValue item, Vector2 position) { const float EPSILON = 0.001f; const int MARGIN_BOTTOM = 4, MARGIN_LEFT = 50; Vector2 oldPosition = position; ItemModsSettings settings = Settings.ItemMods; string affix = item.AffixType == ModsDat.ModType.Prefix ? "[P]" : item.AffixType == ModsDat.ModType.Suffix ? "[S]" : "[?]"; Dictionary <int, Color> TColors = new Dictionary <int, Color> { { 1, settings.T1Color }, { 2, settings.T2Color }, { 3, settings.T3Color } }; if (item.AffixType != ModsDat.ModType.Hidden) { if (item.CouldHaveTiers()) { affix += $" T{item.Tier} "; } if (item.AffixType == ModsDat.ModType.Prefix) { Graphics.DrawText(affix, settings.ModTextSize, position.Translate(5 - MARGIN_LEFT, 0), settings.PrefixColor); if (!TColors.TryGetValue(item.Tier, out TColor)) { TColor = settings.PrefixColor; } } if (item.AffixType == ModsDat.ModType.Suffix) { Graphics.DrawText(affix, settings.ModTextSize, position.Translate(5 - MARGIN_LEFT, 0), settings.SuffixColor); if (!TColors.TryGetValue(item.Tier, out TColor)) { TColor = settings.SuffixColor; } } Size2 textSize = Graphics.DrawText(item.AffixText, settings.ModTextSize, position, TColor); if (textSize != new Size2()) { position.Y += textSize.Height; } } for (int i = 0; i < 4; i++) { IntRange range = item.Record.StatRange[i]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord stat = item.Record.StatNames[i]; int value = item.StatValue[i]; if (value <= -1000 || stat == null) { continue; } bool noSpread = !range.HasSpread(); string line2 = string.Format(noSpread ? "{0}" : "{0} [{1}]", stat, range); Graphics.DrawText(line2, settings.ModTextSize, position, Color.Gainsboro); string statText = stat.ValueToString(value); Vector2 statPosition = position.Translate(-5, 0); Size2 txSize = Graphics.DrawText(statText, settings.ModTextSize, statPosition, Color.Gainsboro, FontDrawFlags.Right); position.Y += txSize.Height; } return(Math.Abs(position.Y - oldPosition.Y) > EPSILON?position.Translate(0, MARGIN_BOTTOM) : oldPosition); }
private void DrawWeaponDps(RectangleF clientRect) { var weapon = itemEntity.GetComponent <Weapon>(); float aSpd = (float)Math.Round(1000f / weapon.AttackTime, 2); int cntDamages = Enum.GetValues(typeof(DamageType)).Length; var doubleDpsPerStat = new float[cntDamages]; float physDmgMultiplier = 1; int PhysHi = weapon.DamageMax; int PhysLo = weapon.DamageMin; foreach (ModValue mod in mods) { for (int iStat = 0; iStat < 4; iStat++) { IntRange range = mod.Record.StatRange[iStat]; if (range.Min == 0 && range.Max == 0) { continue; } StatsDat.StatRecord theStat = mod.Record.StatNames[iStat]; int value = mod.StatValue[iStat]; switch (theStat.Key) { case "physical_damage_+%": case "local_physical_damage_+%": physDmgMultiplier += value / 100f; break; case "local_attack_speed_+%": aSpd *= (100f + value) / 100; break; case "local_minimum_added_physical_damage": PhysLo += value; break; case "local_maximum_added_physical_damage": PhysHi += value; break; case "local_minimum_added_fire_damage": case "local_maximum_added_fire_damage": case "unique_local_minimum_added_fire_damage_when_in_main_hand": case "unique_local_maximum_added_fire_damage_when_in_main_hand": doubleDpsPerStat[(int)DamageType.Fire] += value; break; case "local_minimum_added_cold_damage": case "local_maximum_added_cold_damage": case "unique_local_minimum_added_cold_damage_when_in_off_hand": case "unique_local_maximum_added_cold_damage_when_in_off_hand": doubleDpsPerStat[(int)DamageType.Cold] += value; break; case "local_minimum_added_lightning_damage": case "local_maximum_added_lightning_damage": doubleDpsPerStat[(int)DamageType.Lightning] += value; break; case "unique_local_minimum_added_chaos_damage_when_in_off_hand": case "unique_local_maximum_added_chaos_damage_when_in_off_hand": case "local_minimum_added_chaos_damage": case "local_maximum_added_chaos_damage": doubleDpsPerStat[(int)DamageType.Chaos] += value; break; } } } WeaponDpsSettings settings = Settings.WeaponDps; Color[] elementalDmgColors = { Color.White, settings.DmgFireColor, settings.DmgColdColor, settings.DmgLightningColor, settings.DmgChaosColor }; physDmgMultiplier += itemEntity.GetComponent <Quality>().ItemQuality / 100f; PhysLo = (int)Math.Round(PhysLo * physDmgMultiplier); PhysHi = (int)Math.Round(PhysHi * physDmgMultiplier); doubleDpsPerStat[(int)DamageType.Physical] = PhysLo + PhysHi; aSpd = (float)Math.Round(aSpd, 2); float pDps = doubleDpsPerStat[(int)DamageType.Physical] / 2 * aSpd; float eDps = 0; int firstEmg = 0; Color DpsColor = settings.pDamageColor; for (int i = 1; i < cntDamages; i++) { eDps += doubleDpsPerStat[i] / 2 * aSpd; if (doubleDpsPerStat[i] > 0) { if (firstEmg == 0) { firstEmg = i; DpsColor = elementalDmgColors[i]; } else { DpsColor = settings.eDamageColor; } } } var textPosition = new Vector2(clientRect.Right - 2, clientRect.Y + 1); Size2 pDpsSize = pDps > 0 ? Graphics.DrawText(pDps.ToString("#.#") + " pDps", settings.DpsTextSize, textPosition, FontDrawFlags.Right) : new Size2(); Size2 eDpsSize = eDps > 0 ? Graphics.DrawText(eDps.ToString("#.#") + " eDps", settings.DpsTextSize, textPosition.Translate(0, pDpsSize.Height), DpsColor, FontDrawFlags.Right) : new Size2(); var dps = pDps + eDps; Size2 dpsSize = dps > 0 ? Graphics.DrawText(dps.ToString("#.#") + " Dps", settings.DpsTextSize, textPosition.Translate(0, pDpsSize.Height + eDpsSize.Height), Color.White, FontDrawFlags.Right) : new Size2(); Vector2 dpsTextPosition = textPosition.Translate(0, pDpsSize.Height + eDpsSize.Height + dpsSize.Height); Graphics.DrawText("dps", settings.DpsNameTextSize, dpsTextPosition, settings.TextColor, FontDrawFlags.Right); Graphics.DrawImage("preload-end.png", new RectangleF(textPosition.X - 86, textPosition.Y - 6, 90, 65), settings.BackgroundColor); }