From 44daae68353864206685a55d7122d571b625dcf0 Mon Sep 17 00:00:00 2001 From: Niphyr Date: Tue, 6 Aug 2024 15:56:06 +1000 Subject: [PATCH] The War Within updates - Updated to use TWW simc data - Updated broken tests - Fixed a newly introduced bug with double and float parsing - Fixed a rounding error with item stats that was producing off-by-one errors --- .../DataSync/CacheServiceTests.cs | 2 +- .../DataSync/RawDataExtractionServiceTests.cs | 25 +-- .../SimcGenerationServiceIntegrationTests.cs | 6 +- .../SimcItemCreationServiceTests.cs | 64 ++++--- .../SimcSpellCreationServiceTests.cs | 24 +-- SimcProfileParser/DataSync/CacheService.cs | 36 ++-- .../DataSync/RawDataExtractionService.cs | 180 ++++++++++-------- SimcProfileParser/SimcProfileParser.csproj | 6 +- SimcProfileParser/SimcUtilityService.cs | 9 +- 9 files changed, 192 insertions(+), 160 deletions(-) diff --git a/SimcProfileParser.Tests/DataSync/CacheServiceTests.cs b/SimcProfileParser.Tests/DataSync/CacheServiceTests.cs index b987cc8..1acd7af 100644 --- a/SimcProfileParser.Tests/DataSync/CacheServiceTests.cs +++ b/SimcProfileParser.Tests/DataSync/CacheServiceTests.cs @@ -61,7 +61,7 @@ public async Task CS_Downloads_File() ParsedFileType = SimcParsedFileType.CombatRatingMultipliers, RawFiles = new Dictionary() { - { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/sc_scale_data.inc" } + { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/sc_scale_data.inc" } } }; var filePath = Path.Combine(cache.BaseFileDirectory, "ScaleData.raw"); diff --git a/SimcProfileParser.Tests/DataSync/RawDataExtractionServiceTests.cs b/SimcProfileParser.Tests/DataSync/RawDataExtractionServiceTests.cs index dc1273d..af13774 100644 --- a/SimcProfileParser.Tests/DataSync/RawDataExtractionServiceTests.cs +++ b/SimcProfileParser.Tests/DataSync/RawDataExtractionServiceTests.cs @@ -1,5 +1,6 @@ using NUnit.Framework; using SimcProfileParser.DataSync; +using SimcProfileParser.Model.RawData; using System.Collections.Generic; using System.Linq; @@ -142,16 +143,16 @@ public void RDE_Generates_SpellData() var incomingRawData = new Dictionary() { - { "SpellData.raw", "{ \"Flash Heal\" , 2061, 2, " + - "0.000000, 0.000000, 0.000000, 0x0000000000000000, 0x00000010, 0, 3, 0, 0, " + - "0.000000, 40.000000, 0, 1500, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, " + - "0.000000, 0, 0, 0, 1500, { 65536, 0, 524288, 0, 0, 0, 0, 0, 16781312, 0, 0, " + - "0, 0, 1, 0 }, { 2048, 0, 0, 1073741824 }, 6, 0x80000000, 0, 0, 0, 0, 0, " + - "0, 0, 1, 1, 1, 2 }, /* 613 */\r\n" + - "{ 613, 2061, 0, 10, 0, 0, 0.000000, 0.050000, 0.000000, 2.030000, " + - "0.000000, 0, 0.000000, 0.000000, 0.0000, 0, 0, { 0, 0, 0, 0 }, 0, " + - "1.000000, 0.000000, 0.000000, 0, 0, 21, 0, 1.000000, 1.150000, 0, 0 },\r\n" + - " { 154, 2061, 0, 0, 0, 0, 0, 3.600, 0.000, 0.000 }," } + { "SpellData.raw", "{ \"Flash Heal\" , 2061, 2, 0.000000, " + + "0.000000, 0.000000, 0x0000000000000000, 0x00000010, 0, 3, 0, 0, 0.000000, 40.000000," + + " 0, 1500, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0000000000000000, 0, 0.000000, " + + "0, 0x00000000, 0x00000000, 1500, { 65536, 0, 524288, 0, 0, 0, 0, 0, 16781312, 0, 0, " + + "0, 0, 1, 0 }, { 2048, 0, 0, 1073741824 }, 6, 0x88000000, 0, 0, 0, 0, 0, 0, 0, 1, " + + "4, 1, 7 }, /* 613 */\r\n" + + "{ 613, 2061, 0, 10, 0, 0, 0x00000000, 0.000000, 0.050000, 0.000000, 3.410400, " + + "0.000000, 0, 0.000000, 0.000000, 0.0000, 0, 0, { 0, 0, 0, 0 }, 0, 1.000000, 0.000000, " + + "0.000000, 0, 0, 21, 0, 1.000000, 1.000000, 0, 0 },\r\n" + + " { 154, 2061, 137031, 0, 0, 0, 0, 3.600, 0.000, 0.000 }," } }; // Act @@ -260,7 +261,7 @@ public void RDE_Generates_SpellScale_Multi() var incomingRawData = new Dictionary() { - { "ScaleData.raw", @"static constexpr double __spell_scaling[][70] = { + { "ScaleData.raw", @"static constexpr double __spell_scaling[][80] = { { 1, 0, 0, 0, 0, // 5 }, @@ -330,7 +331,7 @@ public void RDE_Generates_SpellScale_Multi() // Assert Assert.IsNotNull(result); Assert.AreEqual(21, result.Length); - Assert.AreEqual(70, result[0].Length); + Assert.AreEqual(80, result[0].Length); Assert.AreEqual(1d, result[0][0]); Assert.AreEqual(2d, result[1][0]); Assert.AreEqual(3d, result[2][0]); diff --git a/SimcProfileParser.Tests/SimcGenerationServiceIntegrationTests.cs b/SimcProfileParser.Tests/SimcGenerationServiceIntegrationTests.cs index 4e19198..ffb145d 100644 --- a/SimcProfileParser.Tests/SimcGenerationServiceIntegrationTests.cs +++ b/SimcProfileParser.Tests/SimcGenerationServiceIntegrationTests.cs @@ -102,7 +102,7 @@ public async Task SGS_Creates_ItemSpell() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(2, spell.Effects.Count); - Assert.AreEqual(60.763805390000002d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(25.512510299999999d, spell.Effects[0].ScaleBudget); Assert.AreEqual(460.97500600000001d, spell.Effects[0].Coefficient); Assert.AreEqual(621.39996299999996d, spell.Effects[1].Coefficient); } @@ -125,7 +125,7 @@ public async Task SGS_Creates_PlayerSpell() Assert.IsNotNull(spell.Effects); Assert.AreEqual(1.32, spell.Effects[0].Coefficient); Assert.AreEqual(1.32, spell.Effects[0].Coefficient); - Assert.AreEqual(94.811015159999997d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(258.2211327d, spell.Effects[0].ScaleBudget); } [Test] @@ -138,7 +138,7 @@ public async Task SGS_Gets_Game_Version() // Assert Assert.IsNotNull(version); - Assert.AreEqual("10.", version.Substring(0, 3)); + Assert.AreEqual("11.", version.Substring(0, 3)); } } } diff --git a/SimcProfileParser.Tests/SimcItemCreationServiceTests.cs b/SimcProfileParser.Tests/SimcItemCreationServiceTests.cs index 5a67bd9..1e4c070 100644 --- a/SimcProfileParser.Tests/SimcItemCreationServiceTests.cs +++ b/SimcProfileParser.Tests/SimcItemCreationServiceTests.cs @@ -87,31 +87,47 @@ public async Task ICS_Parses_Entire_Data_file() public async Task ICS_Builds_Item_From_Options() { // Arrange - // Hopebreakers Badge - // trinket1=,id=177813,bonus_id=6907/6652/603/7215,drop_level=50 + // # Entropic Convergence Loop (519) + // # finger1=,id=202572,bonus_id=6652/10532/7981/10335/10884/1576/8767 + //var itemOptions = new SimcItemOptions() + //{ + // ItemId = 202572, + // Quality = ItemQuality.ITEM_QUALITY_COMMON, + // ItemLevel = 415, + // BonusIds = new List() { 6652, 10532, 7981, 10335, 10884, 1576, 8767 }, + //}; + + // Etchings of the Captive Revenant (519) + // back =,id = 202573,bonus_id = 6652 / 10874 / 7981 / 10335 / 10884 / 1576 / 8767 + // 702 Armor, 3422 Stamina, 460 Crit, 211 Haste var itemOptions = new SimcItemOptions() { - ItemId = 177813, + ItemId = 202573, Quality = ItemQuality.ITEM_QUALITY_COMMON, - ItemLevel = 226, - BonusIds = new List() { 6907, 6652, 603, 7215 }, - DropLevel = 50 + ItemLevel = 415, + BonusIds = new List() { 6652, 10874, 7981, 10335, 10884, 1576, 8767 }, }; + // Act var item = await _ics.CreateItemAsync(itemOptions); // Assert Assert.IsNotNull(item); - Assert.AreEqual(226, item.ItemLevel); + Assert.AreEqual(519, item.ItemLevel); Assert.AreEqual(ItemQuality.ITEM_QUALITY_EPIC, item.Quality); - Assert.AreEqual(177813, item.ItemId); - // Intellect - Assert.AreEqual(77, item.Mods[0].StatRating); - Assert.AreEqual(ItemModType.ITEM_MOD_STRENGTH_AGILITY_INTELLECT, item.Mods[0].Type); + Assert.AreEqual(InventoryType.INVTYPE_CLOAK, item.InventoryType); + Assert.AreEqual(202573, item.ItemId); + + // Stam + Assert.AreEqual(3422, item.Mods[0].StatRating); + Assert.AreEqual(ItemModType.ITEM_MOD_STAMINA, item.Mods[0].Type); // Crit rating - Assert.AreEqual(95, item.Mods[1].StatRating); + Assert.AreEqual(460, item.Mods[1].StatRating); Assert.AreEqual(ItemModType.ITEM_MOD_CRIT_RATING, item.Mods[1].Type); + // Haste rating + Assert.AreEqual(211, item.Mods[2].StatRating); + Assert.AreEqual(ItemModType.ITEM_MOD_HASTE_RATING, item.Mods[2].Type); } [Test] @@ -157,8 +173,8 @@ public async Task ICS_ItemOptions_Correct_iLvl_Scaling() Assert.AreEqual(ItemQuality.ITEM_QUALITY_EPIC, item.Quality); Assert.AreEqual(181360, item.ItemId); // This will make sure the scale value that's being pulled for spells is using the right - // item level. In this cast it's 226 = 1.3098933696746826. - Assert.AreEqual(1.2341647148132324d, item.Effects[0].Spell.CombatRatingMultiplier); + // item level. In this cast it's 226 = 1.5. + Assert.AreEqual(1.5d, item.Effects[0].Spell.CombatRatingMultiplier); } [Test] @@ -236,7 +252,7 @@ public async Task ICS_ItemOptions_Correct_iLvl_Heal_EffectScaling() Assert.AreEqual(178809, item.ItemId); // This will make sure the scale value that's being pulled for spells with healing/damage effects is using the right // item level. In this cast it's 226 = 58. - Assert.AreEqual(90.627281190000005d, item.Effects[0].Spell.Effects[0].ScaleBudget); + Assert.AreEqual(25.512510299999999d, item.Effects[0].Spell.Effects[0].ScaleBudget); } [Test] @@ -268,8 +284,8 @@ public async Task ICS_Builds_Trinket_From_ParsedItem_Secondary_Stat_UseEffect() Assert.AreEqual(336841, item.Effects[0].Spell.SpellId); Assert.AreEqual(90000, item.Effects[0].Spell.Cooldown); Assert.AreEqual(12000.0d, item.Effects[0].Spell.Duration); - Assert.AreEqual(1.2341647148132324d, item.Effects[0].Spell.CombatRatingMultiplier); - Assert.AreEqual(90.627281190000005d, item.Effects[0].Spell.Effects[0].ScaleBudget); + Assert.AreEqual(1.5d, item.Effects[0].Spell.CombatRatingMultiplier); + Assert.AreEqual(25.512510299999999d, item.Effects[0].Spell.Effects[0].ScaleBudget); Assert.IsNotNull(item.Effects[0].Spell.Effects); Assert.AreEqual(1, item.Effects[0].Spell.Effects.Count); Assert.AreEqual(2.955178d, item.Effects[1].Spell.Effects[0].Coefficient); @@ -308,14 +324,14 @@ public async Task ICS_Builds_Trinket_From_ParsedItem_HealDmg_UseEffect() Assert.AreEqual(336866, item.Effects[0].Spell.SpellId); Assert.AreEqual(90000, item.Effects[0].Spell.Cooldown); Assert.AreEqual(6000, item.Effects[0].Spell.Duration); - Assert.AreEqual(1.2341647148132324d, item.Effects[0].Spell.CombatRatingMultiplier); - Assert.AreEqual(90.627281190000005d, item.Effects[0].Spell.Effects[0].ScaleBudget); + Assert.AreEqual(1.5d, item.Effects[0].Spell.CombatRatingMultiplier); + Assert.AreEqual(25.512510299999999d, item.Effects[0].Spell.Effects[0].ScaleBudget); // Second effect Assert.AreEqual(135863, item.Effects[1].EffectId); Assert.IsNotNull(item.Effects[1].Spell); Assert.AreEqual(343538, item.Effects[1].Spell.SpellId); - Assert.AreEqual(1.2341647148132324d, item.Effects[1].Spell.CombatRatingMultiplier); - Assert.AreEqual(60.763805390000002d, item.Effects[1].Spell.Effects[0].ScaleBudget); + Assert.AreEqual(1.5d, item.Effects[1].Spell.CombatRatingMultiplier); + Assert.AreEqual(25.512510299999999d, item.Effects[1].Spell.Effects[0].ScaleBudget); Assert.IsNotNull(item.Effects[1].Spell.Effects); Assert.AreEqual(2, item.Effects[1].Spell.Effects.Count); // Second effect's spells first effect @@ -353,8 +369,8 @@ public async Task ICS_Builds_Trinket_From_ParsedItem_Primary_ProcEffectt() Assert.IsNotNull(item.Effects[0].Spell); Assert.AreEqual(344117, item.Effects[0].Spell.SpellId); Assert.AreEqual(1.5, item.Effects[0].Spell.Rppm); - Assert.AreEqual(1.2341647148132324d, item.Effects[0].Spell.CombatRatingMultiplier); - Assert.AreEqual(90.627281190000005d, item.Effects[0].Spell.Effects[0].ScaleBudget); + Assert.AreEqual(1.5d, item.Effects[0].Spell.CombatRatingMultiplier); + Assert.AreEqual(25.512510299999999d, item.Effects[0].Spell.Effects[0].ScaleBudget); // First effect's spells first effect trigger spells first effect (lol) // This is basically testing that the trigger spell gets linked. This particular spell // stores the proc coefficient in the trigger spell and multiplies it by 155. @@ -453,7 +469,7 @@ public async Task ICS_Creates_Premade_Ilvl_Scaling() Assert.AreEqual(193748, item.ItemId); Assert.AreEqual(395, item.ItemLevel); Assert.AreEqual(1, item.Mods.Count); - Assert.AreEqual(482, item.Mods[0].StatRating); + Assert.AreEqual(477, item.Mods[0].StatRating); } [Test] diff --git a/SimcProfileParser.Tests/SimcSpellCreationServiceTests.cs b/SimcProfileParser.Tests/SimcSpellCreationServiceTests.cs index 2c0e8b0..218fbec 100644 --- a/SimcProfileParser.Tests/SimcSpellCreationServiceTests.cs +++ b/SimcProfileParser.Tests/SimcSpellCreationServiceTests.cs @@ -62,7 +62,7 @@ public async Task SSC_Creates_Item_Spell_Spell_Options() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(2, spell.Effects.Count); - Assert.AreEqual(60.763805390000002d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(25.512510299999999d, spell.Effects[0].ScaleBudget); Assert.AreEqual(460.97500600000001d, spell.Effects[0].Coefficient); Assert.AreEqual(621.39996299999996d, spell.Effects[1].Coefficient); } @@ -109,7 +109,7 @@ public async Task SSC_Converts_OneScale_To_SevenScale() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(1, spell.Effects.Count); - Assert.AreEqual(189.95515439618612d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(125.98769760131836d, spell.Effects[0].ScaleBudget); Assert.AreEqual(1.65, spell.Effects[0].Coefficient); Assert.AreEqual(-7, spell.Effects[0].ScalingType); } @@ -133,7 +133,7 @@ public async Task SSC_Creates_Item_Spell_Raw_Obj() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(2, spell.Effects.Count); - Assert.AreEqual(60.763805390000002d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(25.512510299999999d, spell.Effects[0].ScaleBudget); Assert.AreEqual(460.97500600000001d, spell.Effects[0].Coefficient); Assert.AreEqual(621.39996299999996d, spell.Effects[1].Coefficient); } @@ -157,7 +157,7 @@ public async Task SSC_Creates_Item_Spell_Raw_Obj_9() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(1, spell.Effects.Count); - Assert.AreEqual(90.627281190000005d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(25.512510299999999d, spell.Effects[0].ScaleBudget); Assert.AreEqual(21.946373000000001d, spell.Effects[0].Coefficient); } @@ -169,7 +169,7 @@ public async Task SSC_Creates_Player_Spell_Spell_Options() var spellOptions = new SimcSpellOptions() { SpellId = 274740, - PlayerLevel = 60 + PlayerLevel = 80 }; // Act @@ -180,7 +180,7 @@ public async Task SSC_Creates_Player_Spell_Spell_Options() Assert.IsNotNull(spell.Effects); Assert.AreEqual(1.32, spell.Effects[0].Coefficient); Assert.AreEqual(1.32, spell.Effects[0].Coefficient); - Assert.AreEqual(94.811015159999997d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(3828.969615d, spell.Effects[0].ScaleBudget); } [Test] @@ -190,7 +190,7 @@ public async Task SSC_Creates_Player_Spell_With_Power() var spellOptions = new SimcSpellOptions() { SpellId = 274740, - PlayerLevel = 60 + PlayerLevel = 80 }; // Act @@ -200,14 +200,14 @@ public async Task SSC_Creates_Player_Spell_With_Power() Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); Assert.AreEqual(1.32, spell.Effects[0].Coefficient); - Assert.AreEqual(94.811015159999997d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(3828.969615d, spell.Effects[0].ScaleBudget); } [Test] public async Task SSC_Creates_Player_Spell_Raw() { // Arrange - var playerLevel = 60u; + var playerLevel = 70u; var spellId = 274740u; // Act @@ -216,8 +216,8 @@ public async Task SSC_Creates_Player_Spell_Raw() // Assert Assert.IsNotNull(spell); Assert.IsNotNull(spell.Effects); - Assert.AreEqual(1.32, spell.Effects[0].Coefficient); - Assert.AreEqual(94.811015159999997d, spell.Effects[0].ScaleBudget); + Assert.AreEqual(1.3200000000000001d, spell.Effects[0].Coefficient); + Assert.AreEqual(453.3443671d, spell.Effects[0].ScaleBudget); } [Test] @@ -242,7 +242,7 @@ public async Task SSC_Creates_Player_Spell_WithPower() public async Task SSC_Creates_Player_Spell_WithConduitRanks() { // Arrange - var playerLevel = 60u; + var playerLevel = 80u; var spellId = 340609u; // Act diff --git a/SimcProfileParser/DataSync/CacheService.cs b/SimcProfileParser/DataSync/CacheService.cs index 930759b..0986e65 100644 --- a/SimcProfileParser/DataSync/CacheService.cs +++ b/SimcProfileParser/DataSync/CacheService.cs @@ -43,8 +43,8 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.ItemDataNew, RawFiles = new Dictionary() { - { "ItemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_data.inc" }, - { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_effect.inc" } + { "ItemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_data.inc" }, + { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_effect.inc" } } }); @@ -54,8 +54,8 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.ItemDataOld, RawFiles = new Dictionary() { - { "ItemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_data.inc" }, - { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_effect.inc" } + { "ItemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_data.inc" }, + { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_effect.inc" } } }); @@ -65,7 +65,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.CombatRatingMultipliers, RawFiles = new Dictionary() { - { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/sc_scale_data.inc" } + { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/sc_scale_data.inc" } } }); @@ -75,7 +75,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.StaminaMultipliers, RawFiles = new Dictionary() { - { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/sc_scale_data.inc" } + { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/sc_scale_data.inc" } } }); @@ -85,7 +85,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.RandomPropPoints, RawFiles = new Dictionary() { - { "RandomPropPoints.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/rand_prop_points.inc" } + { "RandomPropPoints.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/rand_prop_points.inc" } } }); @@ -95,7 +95,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.SpellData, RawFiles = new Dictionary() { - { "SpellData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/sc_spell_data.inc" } + { "SpellData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/sc_spell_data.inc" } } }); @@ -105,7 +105,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.ItemBonusData, RawFiles = new Dictionary() { - { "ItemBonusData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_bonus.inc" } + { "ItemBonusData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_bonus.inc" } } }); @@ -115,7 +115,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.GemData, RawFiles = new Dictionary() { - { "GemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/gem_data.inc" } + { "GemData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/gem_data.inc" } } }); @@ -125,7 +125,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.ItemEnchantData, RawFiles = new Dictionary() { - { "ItemEnchantData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/spell_item_enchantment.inc" } + { "ItemEnchantData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/spell_item_enchantment.inc" } } }); @@ -135,7 +135,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.SpellScaleMultipliers, RawFiles = new Dictionary() { - { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/sc_scale_data.inc" } + { "ScaleData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/sc_scale_data.inc" } } }); @@ -145,7 +145,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.CurvePoints, RawFiles = new Dictionary() { - { "CurveData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_scaling.inc" } + { "CurveData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_scaling.inc" } } }); @@ -155,7 +155,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.RppmData, RawFiles = new Dictionary() { - { "RppmData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/real_ppm_data.inc" } + { "RppmData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/real_ppm_data.inc" } } }); @@ -165,7 +165,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.CovenantData, RawFiles = new Dictionary() { - { "CovenantData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/covenant_data.inc" } + { "CovenantData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/covenant_data.inc" } } }); @@ -175,7 +175,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.ItemEffectData, RawFiles = new Dictionary() { - { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/item_effect.inc" } + { "ItemEffectData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/item_effect.inc" } } }); @@ -185,7 +185,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.GameDataVersion, RawFiles = new Dictionary() { - { "GameDataVersion.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/client_data_version.inc" } + { "GameDataVersion.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/client_data_version.inc" } } }); @@ -195,7 +195,7 @@ public CacheService(IRawDataExtractionService rawDataExtractionService, ParsedFileType = SimcParsedFileType.TraitData, RawFiles = new Dictionary() { - { "TraitData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/dragonflight/engine/dbc/generated/trait_data.inc" } + { "TraitData.raw", "https://raw.githubusercontent.com/simulationcraft/simc/thewarwithin/engine/dbc/generated/trait_data.inc" } } }); } diff --git a/SimcProfileParser/DataSync/RawDataExtractionService.cs b/SimcProfileParser/DataSync/RawDataExtractionService.cs index eaf5a4d..68bda31 100644 --- a/SimcProfileParser/DataSync/RawDataExtractionService.cs +++ b/SimcProfileParser/DataSync/RawDataExtractionService.cs @@ -92,7 +92,7 @@ internal float[][] GenerateStaminaMultipliers(Dictionary incomin private float[] ParseRatingGroup(Group g) { - Regex items = new Regex(@"\s+([01]\.?\d*),"); + Regex items = new Regex(@"\s+([\d]\.?\d*),"); float[] values = new float[1300]; @@ -147,7 +147,7 @@ internal List GenerateItemData(Dictionary incomingR StatAllocation = Convert.ToInt32(data[1]), // 2 is the socket penalty - SocketMultiplier = Convert.ToDouble(data[2]) + SocketMultiplier = ToDoubleClean(data[2]) }; itemMods.Add(itemMod); @@ -334,10 +334,10 @@ internal List GenerateRandomPropData(Dictionary GenerateRandomPropData(Dictionary GenerateSpellData(Dictionary incomin { // First try and do an effect - they have 33 total fields. // spelleffect_data_t - if (line.Split(',').Count() == 34) + if (line.Split(',').Count() == 35) { var effect = new SimcRawSpellEffect(); @@ -410,74 +406,76 @@ internal List GenerateSpellData(Dictionary incomin // 5 is effect scaling type effect.ScalingType = Convert.ToInt32(data[5]); - // 6 is (average) spell scaling coefficient - effect.Coefficient = Convert.ToDouble(data[6]); + // 6 is effect attribute + + // 7 is (average) spell scaling coefficient + effect.Coefficient = ToDoubleClean(data[7]); - // 7 is (delta) spell scaling coefficient - effect.Delta = Convert.ToDouble(data[7]); + // 8 is (delta) spell scaling coefficient + effect.Delta = ToDoubleClean(data[8]); - // 8 is an unused unknown effect multiplier + // 9 is an unused unknown effect multiplier - // 9 is sp coeff - effect.SpCoefficient = Convert.ToDouble(data[9]); + // 10 is sp coeff + effect.SpCoefficient = ToDoubleClean(data[10]); - // 10 is ap coeff - effect.ApCoefficient = Convert.ToDouble(data[10]); + // 11 is ap coeff + effect.ApCoefficient = ToDoubleClean(data[11]); - // 11 is Amplitude (tick time) - effect.Amplitude = Convert.ToDouble(data[11]); + // 12 is Amplitude (tick time) + effect.Amplitude = ToDoubleClean(data[12]); - // 12 is Radius - effect.Radius = Convert.ToDouble(data[12]); + // 13 is Radius + effect.Radius = ToDoubleClean(data[13]); - // 13 is RadiusMax - effect.RadiusMax = Convert.ToDouble(data[13]); + // 14 is RadiusMax + effect.RadiusMax = ToDoubleClean(data[14]); - // 14 is effect base value - effect.BaseValue = Convert.ToDouble(data[14]); + // 15 is effect base value + effect.BaseValue = ToDoubleClean(data[15]); - // 15 is Misc Value 1? - effect.MiscValue1 = Convert.ToInt32(data[15]); + // 16 is Misc Value 1? + effect.MiscValue1 = Convert.ToInt32(data[16]); - // 16 is Misc Value 2? - effect.MiscValue2 = Convert.ToInt32(data[16]); + // 17 is Misc Value 2? + effect.MiscValue2 = Convert.ToInt32(data[17]); - // 17, 18, 19, 20 are class flags. + // 18, 19, 20, 21 are class flags. effect.ClassFlags = new uint[4]; - effect.ClassFlags[0] = Convert.ToUInt32(data[17]); - effect.ClassFlags[1] = Convert.ToUInt32(data[18]); - effect.ClassFlags[2] = Convert.ToUInt32(data[19]); - effect.ClassFlags[3] = Convert.ToUInt32(data[20]); + effect.ClassFlags[0] = Convert.ToUInt32(data[18]); + effect.ClassFlags[1] = Convert.ToUInt32(data[19]); + effect.ClassFlags[2] = Convert.ToUInt32(data[20]); + effect.ClassFlags[3] = Convert.ToUInt32(data[21]); - // 21 is trigger spell id - effect.TriggerSpellId = Convert.ToUInt32(data[21]); + // 22 is trigger spell id + effect.TriggerSpellId = Convert.ToUInt32(data[22]); - // 22 is chain multi - effect.ChainMultiplier = Convert.ToDouble(data[22]); + // 23 is chain multi + effect.ChainMultiplier = ToDoubleClean(data[23]); - // 23 is effect points per combo point - effect.ComboPoints = Convert.ToDouble(data[23]); + // 24 is effect points per combo point + effect.ComboPoints = ToDoubleClean(data[24]); - // 24 is real points per level - effect.RealPpl = Convert.ToDouble(data[24]); + // 25 is real points per level + effect.RealPpl = ToDoubleClean(data[25]); - // 25 is mechanic - effect.Mechanic = Convert.ToUInt32(data[25]); + // 26 is mechanic + effect.Mechanic = Convert.ToUInt32(data[26]); - // 26 is number of chain targets - effect.ChainTargets = Convert.ToInt32(data[26]); + // 27 is number of chain targets + effect.ChainTargets = Convert.ToInt32(data[27]); - // 27 is targeting 1 - effect.Targeting1 = Convert.ToUInt32(data[27]); + // 28 is targeting 1 + effect.Targeting1 = Convert.ToUInt32(data[28]); - // 28 is targeting 2 - effect.Targeting2 = Convert.ToUInt32(data[28]); + // 29 is targeting 2 + effect.Targeting2 = Convert.ToUInt32(data[29]); - // 29 is value - effect.Value = Convert.ToDouble(data[29]); + // 30 is value + effect.Value = ToDoubleClean(data[30]); - // 30 is pvp coefficient - effect.PvpCoeff = Convert.ToDouble(data[30]); + // 31 is pvp coefficient + effect.PvpCoeff = ToDoubleClean(data[31]); effects.Add(effect); } @@ -519,13 +517,13 @@ internal List GenerateSpellData(Dictionary incomin spellPower.CostPerTick = Convert.ToInt32(data[6]); // 7 is percent cost - spellPower.PercentCost = Convert.ToDouble(data[7]); + spellPower.PercentCost = ToDoubleClean(data[7]); // 8 is percent cost max - spellPower.PercentCostMax = Convert.ToDouble(data[8]); + spellPower.PercentCostMax = ToDoubleClean(data[8]); // 9 is percent cost per tick - spellPower.PercentCostPerTick = Convert.ToDouble(data[9]); + spellPower.PercentCostPerTick = ToDoubleClean(data[9]); spellPowers.Add(spellPower); } @@ -558,13 +556,13 @@ internal List GenerateSpellData(Dictionary incomin spell.School = Convert.ToUInt32(data[2]); // 3 is projectile speed - spell.ProjectileSpeed = Convert.ToDouble(data[3]); + spell.ProjectileSpeed = ToDoubleClean(data[3]); // 4 is projectile delay - spell.ProjectileDelay = Convert.ToDouble(data[4]); + spell.ProjectileDelay = ToDoubleClean(data[4]); // 5 is minimum travel time - spell.MinimumTravelTime = Convert.ToDouble(data[5]); + spell.MinimumTravelTime = ToDoubleClean(data[5]); // 6 is a hex race mask ulong.TryParse(data[6].Replace("0x", ""), @@ -589,10 +587,10 @@ internal List GenerateSpellData(Dictionary incomin spell.RequireMaxLevel = Convert.ToUInt32(data[11]); // 12 is minimum range - spell.MinRange = Convert.ToDouble(data[12]); + spell.MinRange = ToDoubleClean(data[12]); // 13 is maximum range - spell.MaxRange = Convert.ToDouble(data[13]); + spell.MaxRange = ToDoubleClean(data[13]); // 14 is cooldown spell.Cooldown = Convert.ToUInt32(data[14]); @@ -619,7 +617,7 @@ internal List GenerateSpellData(Dictionary incomin spell.MaxTargets = Convert.ToInt32(data[21]); // 22 is Duration - spell.Duration = Convert.ToDouble(data[22]); + spell.Duration = ToDoubleClean(data[22]); // 23 is max stacks spell.MaxStack = Convert.ToUInt32(data[23]); @@ -630,14 +628,16 @@ internal List GenerateSpellData(Dictionary incomin // 25 is proc charges spell.ProcCharges = Convert.ToInt32(data[25]); - // 26 is proc chance - spell.ProcFlags = Convert.ToUInt64(data[26]); + // 26 is proc flags + ulong.TryParse(data[26].Replace("0x", ""), + System.Globalization.NumberStyles.HexNumber, null, out ulong procFlags); + spell.ProcFlags = procFlags; // 27 is icd spell.InternalCooldown = Convert.ToUInt32(data[27]); // 28 is rppm - spell.Rppm = Convert.ToDouble(data[28]); + spell.Rppm = ToDoubleClean(data[28]); // 29 is eq class spell.EquippedClass = Convert.ToUInt32(data[29]); @@ -943,7 +943,7 @@ internal List GenerateItemEnchantData(Dictionary i double[][] spellScalingTable = new double[numSpellScalingTables][]; for (int i = 0; i < numSpellScalingTables; i++) { - spellScalingTable[i] = new double[70]; + spellScalingTable[i] = new double[80]; } - string key = "__spell_scaling[][70] = {"; + string key = "__spell_scaling[][80] = {"; int start = rawData.IndexOf(key) + key.Length; int end = rawData.IndexOf("};", start); @@ -1037,20 +1037,16 @@ internal List GenerateCurveData(Dictionary in curvePoint.Index = Convert.ToUInt32(data[1]); // 2 is Primary1 - float.TryParse(data[2], out float primary1); - curvePoint.Primary1 = primary1; + curvePoint.Primary1 = ToFloatClean(data[2]); // 3 is Primary2 - float.TryParse(data[3], out float primary2); - curvePoint.Primary2 = primary2; + curvePoint.Primary2 = ToFloatClean(data[3]); // 4 is Secondary1 - float.TryParse(data[4], out float secondary1); - curvePoint.Secondary1 = secondary1; + curvePoint.Secondary1 = ToFloatClean(data[4]); // 5 is value Secondary2 - float.TryParse(data[5], out float secondary2); - curvePoint.Secondary2 = secondary2; + curvePoint.Secondary2 = ToFloatClean(data[5]); curvePoints.Add(curvePoint); } @@ -1095,7 +1091,7 @@ internal List GenerateRppmData(Dictionary inco rppmEntry.ModifierType = (RppmModifierType)Convert.ToUInt32(data[2]); // 3 is Coefficient - rppmEntry.Coefficient = Convert.ToDouble(data[3]); + rppmEntry.Coefficient = ToDoubleClean(data[3]); rppmData.Add(rppmEntry); } @@ -1149,7 +1145,7 @@ internal List GenerateConduitRankData(Dictionary GenerateTraitData(Dictionary incomin return traitEntries; } + + private double ToDoubleClean(string data) + { + // We need to first remove the "f" from the end of all the doubles + data = data.Replace("f", ""); + + return Convert.ToDouble(data); + } + + private float ToFloatClean(string data) + { + // We sometimes need to remove the "f" from the end + data = data.Replace("f", ""); + + float.TryParse(data, out float outFloat); + + return outFloat; + } } } diff --git a/SimcProfileParser/SimcProfileParser.csproj b/SimcProfileParser/SimcProfileParser.csproj index daeb2a3..f49e9ac 100644 --- a/SimcProfileParser/SimcProfileParser.csproj +++ b/SimcProfileParser/SimcProfileParser.csproj @@ -3,7 +3,7 @@ net6.0 true - 1.5.0 + 1.6.0 Mechanical Priest Mechanical Priest GPL-3.0-only @@ -18,8 +18,8 @@ Simc Profile Parser true packageIcon.png - 1.5.0 - 1.5.0 + 1.6.0 + 1.6.0 diff --git a/SimcProfileParser/SimcUtilityService.cs b/SimcProfileParser/SimcUtilityService.cs index aa0621d..4d9dd1f 100644 --- a/SimcProfileParser/SimcUtilityService.cs +++ b/SimcProfileParser/SimcUtilityService.cs @@ -46,6 +46,7 @@ public int GetSlotType(ItemClass itemClass, int itemSubClass, InventoryType item return 3; } case ItemClass.ITEM_CLASS_ARMOR: + // Armor Handling is now done by slot switch (itemInventoryType) { case InventoryType.INVTYPE_HEAD: @@ -307,7 +308,7 @@ public async Task GetScaledModValueAsync(SimcItem item, ItemModType modType { // Not yet implemented var socketPenalty = 0.0d; - int rawValue = (int)(statAllocation * itemBudget * 0.0001d - socketPenalty + 0.5d); + double rawValue = statAllocation * itemBudget * 0.0001d - socketPenalty; if (GetIsCombatRating(modType)) { @@ -319,7 +320,7 @@ public async Task GetScaledModValueAsync(SimcItem item, ItemModType modType item.ItemLevel, combatRatingType); if (combatRatingMultiplier != 0) - rawValue = (int)(rawValue * combatRatingMultiplier); + rawValue = rawValue * combatRatingMultiplier; } } else if (modType == ItemModType.ITEM_MOD_STAMINA) @@ -332,11 +333,11 @@ public async Task GetScaledModValueAsync(SimcItem item, ItemModType modType item.ItemLevel, staminaRatingType); if (staminaRatingMultiplier != 0) - rawValue = (int)(rawValue * staminaRatingMultiplier); + rawValue = rawValue * staminaRatingMultiplier; } } - return rawValue; + return (int)Math.Round(rawValue); } _logger?.LogError($"Items and mods that don't scale are not yet implemented. modType: {modType}, slotType: {slotType}, statAllocation: {statAllocation}, itemBudget: {itemBudget}");