diff --git a/FModel/App.config b/FModel/App.config index f02f0150..7e47646f 100644 --- a/FModel/App.config +++ b/FModel/App.config @@ -1,7 +1,7 @@ - + - +
@@ -132,4 +132,12 @@ + + + + + + + + \ No newline at end of file diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 609cf788..a7658de7 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -120,13 +120,13 @@ - - + + @@ -179,6 +179,7 @@ + @@ -233,6 +234,7 @@ + diff --git a/FModel/MainWindow.cs b/FModel/MainWindow.cs index 474f6a9a..6ffa5f9e 100644 --- a/FModel/MainWindow.cs +++ b/FModel/MainWindow.cs @@ -27,6 +27,7 @@ namespace FModel { public partial class MainWindow : Form { + #region to refactor private static Stopwatch StopWatch { get; set; } private static string[] _paksArray { get; set; } public static string[] PakAsTxt { get; set; } @@ -36,6 +37,7 @@ namespace FModel private static List _itemsToDisplay { get; set; } public static string ExtractedFilePath { get; set; } public static string[] SelectedItemsArray { get; set; } + #endregion public MainWindow() { @@ -1217,257 +1219,7 @@ namespace FModel Image bg512 = Resources.BG512; g.DrawImage(bg512, new Point(5, 383)); - #region DRAW TEXT - try - { - g.DrawString(theItem.DisplayName, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("DisplayName ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //NAME - try - { - g.DrawString(theItem.Description, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("Description ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //DESCRIPTION - if (specialMode == "athIteDef") - { - try - { - g.DrawString(theItem.ShortDescription, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("ShortDescription ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //TYPE - try - { - g.DrawString(theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.Source."))].Substring(17), new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } - catch (IndexOutOfRangeException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("as ", Color.Black); - AppendText("Cosmetics.Source ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //COSMETIC SOURCE - if (theItem.ExportType == "AthenaItemWrapDefinition" && Checking.WasFeatured && ItemIcon.ItemIconPath.Contains("WeaponRenders")) //ONLY TRIGGER IF THE WEAPON RENDER IS TRIGGERED - { - string wrapAddImg = theItem.LargePreviewImage.AssetPathName.Substring(theItem.LargePreviewImage.AssetPathName.LastIndexOf(".", StringComparison.Ordinal) + 1); - - UpdateConsole("Additional image " + wrapAddImg, Color.FromArgb(255, 244, 132, 66), "Waiting"); - ItemIcon.ItemIconPath = JohnWick.AssetToTexture2D(wrapAddImg); - - if (File.Exists(ItemIcon.ItemIconPath)) - { - Image itemIcon; - using (var bmpTemp = new Bitmap(ItemIcon.ItemIconPath)) - { - itemIcon = new Bitmap(bmpTemp); - } - g.DrawImage(ImageUtilities.ResizeImage(itemIcon, 122, 122), new Point(395, 282)); - } - } - } - if (specialMode == "consAndWeap") - { - try - { - g.DrawString(theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Athena.ItemAction."))].Substring(18), new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } - catch (IndexOutOfRangeException) - { - try - { - g.DrawString(theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Weapon."))].Substring(7), new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } - catch (IndexOutOfRangeException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("as ", Color.Black); - AppendText("Athena.ItemAction ", Color.SteelBlue); - AppendText("or ", Color.Black); - AppendText("Weapon ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } - } //ACTION - if (ExtractedFilePath.Contains("Items\\Consumables")) - { - try - { - g.DrawString("Max Stack Size: " + theItem.MaxStackSize, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("MaxStackSize ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //MAX STACK SIZE - } - if (theItem.AmmoData != null && theItem.AmmoData.AssetPathName.Contains("Ammo")) //TO AVOID TRIGGERING CONSUMABLES, NAME SHOULD CONTAIN "AMMO" - { - ItemIcon.GetAmmoData(theItem.AmmoData.AssetPathName, g); - } - } - if (specialMode == "variant") - { - try - { - g.DrawString(theItem.ShortDescription, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("ShortDescription ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //TYPE - try - { - g.DrawString(theItem.CosmeticItem, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("Cosmetic Item ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //COSMETIC ITEM - } - try - { - if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("Animated")) - { - Image animatedLogo = Resources.T_Icon_Animated_64; - g.DrawImage(ImageUtilities.ResizeImage(animatedLogo, 32, 32), new Point(6, -2)); - } - else if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("HasUpgradeQuests") && theItem.ExportType != "AthenaPetCarrierItemDefinition") - { - Image questLogo = Resources.T_Icon_Quests_64; - g.DrawImage(ImageUtilities.ResizeImage(questLogo, 32, 32), new Point(6, 6)); - } - else if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("HasUpgradeQuests") && theItem.ExportType == "AthenaPetCarrierItemDefinition") - { - Image petLogo = Resources.T_Icon_Pets_64; - g.DrawImage(ImageUtilities.ResizeImage(petLogo, 32, 32), new Point(6, 6)); - } - else if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("HasVariants")) - { - Image variantsLogo = Resources.T_Icon_Variant_64; - g.DrawImage(ImageUtilities.ResizeImage(variantsLogo, 32, 32), new Point(6, 6)); - } - else if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("Reactive")) - { - Image reactiveLogo = Resources.T_Icon_Adaptive_64; - g.DrawImage(ImageUtilities.ResizeImage(reactiveLogo, 32, 32), new Point(7, 7)); - } - else if (theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))].Contains("Traversal")) - { - Image traversalLogo = Resources.T_Icon_Traversal_64; - g.DrawImage(ImageUtilities.ResizeImage(traversalLogo, 32, 32), new Point(6, 3)); - } - } - catch (Exception) { } //COSMETIC USER FACING FLAGS - - if (specialMode == "stwHeroes") - { - try - { - g.DrawString(theItem.AttributeInitKey.AttributeInitCategory, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("AttributeInitCategory ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //CHARACTER TYPE - try - { - g.DrawString("Power " + theItem.MinLevel + " to " + theItem.MaxLevel, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("Level ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //LEVEL - } - if (specialMode == "stwDefenders") - { - try - { - g.DrawString(theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("NPC.CharacterType.Survivor.Defender."))].Substring(36), new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } - catch (IndexOutOfRangeException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("GameplayTags ", Color.SteelBlue); - AppendText("as ", Color.Black); - AppendText("NPC.CharacterType.Survivor.Defender ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //CHARACTER TYPE - try - { - g.DrawString("Power " + theItem.MinLevel + " to " + theItem.MaxLevel, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); - } - catch (NullReferenceException) - { - AppendText(ThePak.CurrentUsedItem + " ", Color.Red); - AppendText("No ", Color.Black); - AppendText("Level ", Color.SteelBlue); - AppendText("found", Color.Black, true); - } //LEVEL - } - #endregion + DrawText.DrawTexts(theItem, g, specialMode); UpdateConsole(theItem.DisplayName, Color.FromArgb(255, 66, 244, 66), "Success"); if (autoSaveImagesToolStripMenuItem.Checked || updateModeToolStripMenuItem.Checked) @@ -1654,7 +1406,7 @@ namespace FModel ExtractButton.Enabled = true; })); } - public void ExtractButton_Click(object sender, EventArgs e) + private void ExtractButton_Click(object sender, EventArgs e) { scintilla1.Text = ""; pictureBox1.Image = null; diff --git a/FModel/Methods/BackPAKs/DynamicPAKs.cs b/FModel/Methods/BackPAKs/DynamicPAKs.cs index 67046578..c6f296b0 100644 --- a/FModel/Methods/BackPAKs/DynamicPAKs.cs +++ b/FModel/Methods/BackPAKs/DynamicPAKs.cs @@ -1,6 +1,5 @@ -using FModel.Methods.BackupPAKs.Parser.AccessTokenParser; -using FModel.Methods.BackupPAKs.Parser.AccessCodeParser; -using FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser; +using FModel.Methods.BackupPAKs.Parser.AccessCodeParser; +using FModel.Methods.BackupPAKs.Parser.TokenParser; using RestSharp; using System; using Newtonsoft.Json.Linq; @@ -54,7 +53,7 @@ namespace FModel getAccessTokenRequest.AddHeader("Authorization", "basic MzQ0NmNkNzI2OTRjNGE0NDg1ZDgxYjc3YWRiYjIxNDE6OTIwOWQ0YTVlMjVhNDU3ZmI5YjA3NDg5ZDMxM2I0MWE="); getAccessTokenRequest.AddHeader("Content-Type", "application/x-www-form-urlencoded"); - return AccessTokenParser.FromJson(getAccessTokenClient.Execute(getAccessTokenRequest).Content).AccessToken; + return TokenParser.FromJson(getAccessTokenClient.Execute(getAccessTokenRequest).Content).AccessToken; } private static string getAccessCode(string accessToken) { @@ -77,7 +76,7 @@ namespace FModel getExchangeTokenRequest.AddParameter("includePerms", true); getExchangeTokenRequest.AddParameter("token_type", "eg1"); - return ExchangeTokenParser.FromJson(getExchangeTokenClient.Execute(getExchangeTokenRequest).Content).AccessToken; + return TokenParser.FromJson(getExchangeTokenClient.Execute(getExchangeTokenRequest).Content).AccessToken; } private static IEnumerable SplitGuid(string str, int chunkSize) diff --git a/FModel/Methods/BackPAKs/Parser/AccessTokenParser.cs b/FModel/Methods/BackPAKs/Parser/AccessTokenParser.cs deleted file mode 100644 index afcbd1f5..00000000 --- a/FModel/Methods/BackPAKs/Parser/AccessTokenParser.cs +++ /dev/null @@ -1,96 +0,0 @@ -// -// -// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: -// -// using FModel.Methods.BackupPAKs.Parser.AccessTokenParser; -// -// var accessTokenParser = AccessTokenParser.FromJson(jsonString); - -namespace FModel.Methods.BackupPAKs.Parser.AccessTokenParser -{ - using System; - - using System.Globalization; - using Newtonsoft.Json; - using Newtonsoft.Json.Converters; - - public partial class AccessTokenParser - { - [JsonProperty("access_token")] - public string AccessToken { get; set; } - - [JsonProperty("expires_in")] - public long ExpiresIn { get; set; } - - [JsonProperty("expires_at")] - public DateTimeOffset ExpiresAt { get; set; } - - [JsonProperty("token_type")] - public string TokenType { get; set; } - - [JsonProperty("refresh_token")] - public string RefreshToken { get; set; } - - [JsonProperty("refresh_expires")] - public long RefreshExpires { get; set; } - - [JsonProperty("refresh_expires_at")] - public DateTimeOffset RefreshExpiresAt { get; set; } - - [JsonProperty("account_id")] - public string AccountId { get; set; } - - [JsonProperty("client_id")] - public string ClientId { get; set; } - - [JsonProperty("internal_client")] - public bool InternalClient { get; set; } - - [JsonProperty("client_service")] - public string ClientService { get; set; } - - [JsonProperty("lastPasswordValidation")] - public DateTimeOffset LastPasswordValidation { get; set; } - - [JsonProperty("perms")] - public Perm[] Perms { get; set; } - - [JsonProperty("app")] - public string App { get; set; } - - [JsonProperty("in_app_id")] - public string InAppId { get; set; } - } - - public partial class Perm - { - [JsonProperty("resource")] - public string Resource { get; set; } - - [JsonProperty("action")] - public long Action { get; set; } - } - - public partial class AccessTokenParser - { - public static AccessTokenParser FromJson(string json) => JsonConvert.DeserializeObject(json, FModel.Methods.BackupPAKs.Parser.AccessTokenParser.Converter.Settings); - } - - public static class Serialize - { - public static string ToJson(this AccessTokenParser self) => JsonConvert.SerializeObject(self, FModel.Methods.BackupPAKs.Parser.AccessTokenParser.Converter.Settings); - } - - internal static class Converter - { - public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings - { - MetadataPropertyHandling = MetadataPropertyHandling.Ignore, - DateParseHandling = DateParseHandling.None, - Converters = - { - new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } - }, - }; - } -} diff --git a/FModel/Methods/BackPAKs/Parser/ExchangeTokenParser.cs b/FModel/Methods/BackPAKs/Parser/TokenParser.cs similarity index 78% rename from FModel/Methods/BackPAKs/Parser/ExchangeTokenParser.cs rename to FModel/Methods/BackPAKs/Parser/TokenParser.cs index 2834e648..082ef63d 100644 --- a/FModel/Methods/BackPAKs/Parser/ExchangeTokenParser.cs +++ b/FModel/Methods/BackPAKs/Parser/TokenParser.cs @@ -4,9 +4,9 @@ // // using FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser; // -// var exchangeTokenParser = ExchangeTokenParser.FromJson(jsonString); +// var TokenParser = ExchangeTokenParser.FromJson(jsonString); -namespace FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser +namespace FModel.Methods.BackupPAKs.Parser.TokenParser { using System; @@ -14,7 +14,7 @@ namespace FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser using Newtonsoft.Json; using Newtonsoft.Json.Converters; - public partial class ExchangeTokenParser + public partial class TokenParser { [JsonProperty("access_token")] public string AccessToken { get; set; } @@ -68,14 +68,14 @@ namespace FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser public long Action { get; set; } } - public partial class ExchangeTokenParser + public partial class TokenParser { - public static ExchangeTokenParser FromJson(string json) => JsonConvert.DeserializeObject(json, FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser.Converter.Settings); + public static TokenParser FromJson(string json) => JsonConvert.DeserializeObject(json, FModel.Methods.BackupPAKs.Parser.TokenParser.Converter.Settings); } public static class Serialize { - public static string ToJson(this ExchangeTokenParser self) => JsonConvert.SerializeObject(self, FModel.Methods.BackupPAKs.Parser.ExchangeTokenParser.Converter.Settings); + public static string ToJson(this TokenParser self) => JsonConvert.SerializeObject(self, FModel.Methods.BackupPAKs.Parser.TokenParser.Converter.Settings); } internal static class Converter diff --git a/FModel/Methods/IconGenerator/DrawText.cs b/FModel/Methods/IconGenerator/DrawText.cs new file mode 100644 index 00000000..a2b55aca --- /dev/null +++ b/FModel/Methods/IconGenerator/DrawText.cs @@ -0,0 +1,326 @@ +using csharp_wick; +using FModel.Parser.Items; +using FModel.Properties; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Drawing; +using System.IO; + +namespace FModel +{ + static class DrawText + { + private static string cosmeticSource { get; set; } + private static string shortDescription { get; set; } + private static string cosmeticId { get; set; } + private static string maxStackSize { get; set; } + private static string itemAction { get; set; } + private static string weaponRowName { get; set; } + private static string cosmeticUFF { get; set; } + private static string heroType { get; set; } + private static string defenderType { get; set; } + private static string minToMax { get; set; } + + public static void DrawTexts(ItemsIdParser theItem, Graphics myGraphic, string Mode) + { + DrawDisplayName(theItem, myGraphic); + DrawDescription(theItem, myGraphic); + + setTexts(theItem); + + switch (Mode) + { + case "athIteDef": + DrawToLeft(shortDescription, myGraphic); + DrawToRight(cosmeticSource, myGraphic); + break; + case "consAndWeap": + DrawToRight(itemAction, myGraphic); + if (MainWindow.ExtractedFilePath.Contains("Items\\Consumables\\")) + { + DrawToLeft(maxStackSize, myGraphic); + } + break; + case "variant": + DrawToLeft(shortDescription, myGraphic); + DrawToRight(cosmeticId, myGraphic); + break; + case "stwHeroes": + DrawToRight(heroType, myGraphic); + DrawToLeft(minToMax, myGraphic); + break; + case "stwDefenders": + DrawToRight(defenderType, myGraphic); + DrawToLeft(minToMax, myGraphic); + break; + } + + if (theItem.ExportType == "AthenaItemWrapDefinition" && Checking.WasFeatured && ItemIcon.ItemIconPath.Contains("WeaponRenders")) + { + DrawAdditionalImage(theItem, myGraphic); + } + if (theItem.AmmoData != null && theItem.AmmoData.AssetPathName.Contains("Ammo")) //TO AVOID TRIGGERING CONSUMABLES, NAME SHOULD CONTAIN "AMMO" + { + ItemIcon.GetAmmoData(theItem.AmmoData.AssetPathName, myGraphic); + DrawWeaponStat(weaponRowName, myGraphic); + } + + DrawCosmeticUFF(theItem, myGraphic); + } + + private static void setTexts(ItemsIdParser theItem) + { + cosmeticSource = ""; + shortDescription = ""; + cosmeticId = ""; + maxStackSize = ""; + itemAction = ""; + weaponRowName = ""; + cosmeticUFF = ""; + heroType = ""; + defenderType = ""; + minToMax = ""; + + try + { + shortDescription = theItem.ShortDescription; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + cosmeticSource = theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.Source."))].Substring(17); + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + cosmeticId = theItem.CosmeticItem; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + maxStackSize = "Max Stack Size: " + theItem.MaxStackSize; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + itemAction = theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Athena.ItemAction."))].Substring(18); + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + if (theItem.WeaponStatHandle.RowName != "Harvest_Pickaxe_Athena_C_T01") + { + weaponRowName = theItem.WeaponStatHandle.RowName; + } + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + cosmeticUFF = theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("Cosmetics.UserFacingFlags."))]; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + heroType = theItem.AttributeInitKey.AttributeInitCategory; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + defenderType = theItem.GameplayTags.GameplayTagsGameplayTags[Array.FindIndex(theItem.GameplayTags.GameplayTagsGameplayTags, x => x.StartsWith("NPC.CharacterType.Survivor.Defender."))].Substring(36); + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + try + { + minToMax = "Power " + theItem.MinLevel + " to " + theItem.MaxLevel; + } + catch (Exception) + { + //avoid generator to stop when a string isn't found + } + } + + /// + /// search for a known Cosmetics.UserFacingFlags, if found draw the uff icon + /// Cosmetics.UserFacingFlags icons are basically the style icon or the animated/reactive/traversal icon + /// + /// + /// + private static void DrawCosmeticUFF(ItemsIdParser theItem, Graphics myGraphic) + { + if (cosmeticUFF != null) + { + if (cosmeticUFF.Contains("Animated")) + { + Image animatedLogo = Resources.T_Icon_Animated_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(animatedLogo, 32, 32), new Point(6, -2)); + } + else if (cosmeticUFF.Contains("HasUpgradeQuests") && theItem.ExportType != "AthenaPetCarrierItemDefinition") + { + Image questLogo = Resources.T_Icon_Quests_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(questLogo, 32, 32), new Point(6, 6)); + } + else if (cosmeticUFF.Contains("HasUpgradeQuests") && theItem.ExportType == "AthenaPetCarrierItemDefinition") + { + Image petLogo = Resources.T_Icon_Pets_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(petLogo, 32, 32), new Point(6, 6)); + } + else if (cosmeticUFF.Contains("HasVariants")) + { + Image variantsLogo = Resources.T_Icon_Variant_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(variantsLogo, 32, 32), new Point(6, 6)); + } + else if (cosmeticUFF.Contains("Reactive")) + { + Image reactiveLogo = Resources.T_Icon_Adaptive_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(reactiveLogo, 32, 32), new Point(7, 7)); + } + else if (cosmeticUFF.Contains("Traversal")) + { + Image traversalLogo = Resources.T_Icon_Traversal_64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(traversalLogo, 32, 32), new Point(6, 3)); + } + } + } + + /// + /// draw item name if exist + /// + /// + /// + private static void DrawDisplayName(ItemsIdParser theItem, Graphics myGraphic) + { + if (theItem.DisplayName != null) + { + myGraphic.DrawString(theItem.DisplayName, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString); + } + } + + /// + /// draw item description if exist + /// + /// + /// + private static void DrawDescription(ItemsIdParser theItem, Graphics myGraphic) + { + if (theItem.Description != null) + { + myGraphic.DrawString(theItem.Description, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine); + } + } + + /// + /// draw text at bottom right + /// + /// + /// + private static void DrawToRight(string text, Graphics myGraphic) + { + myGraphic.DrawString(text, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(522 - 5, 500), FontUtilities.rightString); + } + + /// + /// draw text at bottom left + /// + /// + /// + private static void DrawToLeft(string text, Graphics myGraphic) + { + myGraphic.DrawString(text, new Font(FontUtilities.pfc.Families[0], 13), new SolidBrush(Color.White), new Point(5, 500)); + } + + /// + /// this is only triggered for wraps, in case the featured (weapon render) image is drawn + /// also draw the non featured image to make it clear it's a wrap, not a weapon + /// + /// + /// + private static void DrawAdditionalImage(ItemsIdParser theItem, Graphics myGraphic) + { + string wrapAddImg = theItem.LargePreviewImage.AssetPathName.Substring(theItem.LargePreviewImage.AssetPathName.LastIndexOf(".", StringComparison.Ordinal) + 1); + + ItemIcon.ItemIconPath = JohnWick.AssetToTexture2D(wrapAddImg); + + if (File.Exists(ItemIcon.ItemIconPath)) + { + Image itemIcon; + using (var bmpTemp = new Bitmap(ItemIcon.ItemIconPath)) + { + itemIcon = new Bitmap(bmpTemp); + } + myGraphic.DrawImage(ImageUtilities.ResizeImage(itemIcon, 122, 122), new Point(395, 282)); + } + } + + /// + /// this is only triggered for weapons + /// draw the damage per bullet as well as the reload time + /// + /// + /// + public static void DrawWeaponStat(string weaponName, Graphics myGraphic) + { + ItemIcon.ItemIconPath = string.Empty; + string extractedWeaponsStatPath = JohnWick.ExtractAsset(ThePak.AllpaksDictionary["AthenaRangedWeapons"], "AthenaRangedWeapons"); + if (extractedWeaponsStatPath != null) + { + if (extractedWeaponsStatPath.Contains(".uasset") || extractedWeaponsStatPath.Contains(".uexp") || extractedWeaponsStatPath.Contains(".ubulk")) + { + JohnWick.MyAsset = new PakAsset(extractedWeaponsStatPath.Substring(0, extractedWeaponsStatPath.LastIndexOf('.'))); + try + { + if (JohnWick.MyAsset.GetSerialized() != null) + { + string parsedJson = JToken.Parse(JohnWick.MyAsset.GetSerialized()).ToString().TrimStart('[').TrimEnd(']'); + JObject jo = JObject.Parse(parsedJson); + foreach (JToken token in jo.FindTokens(weaponName)) + { + var statParsed = Parser.Weapons.WeaponStatParser.FromJson(token.ToString()); + + Image bulletImage = Resources.dmg64; + myGraphic.DrawImage(ImageUtilities.ResizeImage(bulletImage, 15, 15), new Point(5, 500)); + + if (statParsed.DmgPb != 0 && statParsed.ClipSize != 0) + { + DrawToRight("Reload Time: " + statParsed.ReloadTime + " seconds", myGraphic); + DrawToLeft(" " + statParsed.DmgPb, myGraphic); //damage per bullet + } + } + } + } + catch (JsonSerializationException) + { + //do not crash when JsonSerialization does weird stuff + } + } + } + } + } +} diff --git a/FModel/Parser/Items/ItemIDParser.cs b/FModel/Parser/Items/ItemIDParser.cs index 9e246b33..b3227b84 100644 --- a/FModel/Parser/Items/ItemIDParser.cs +++ b/FModel/Parser/Items/ItemIDParser.cs @@ -62,6 +62,9 @@ namespace FModel.Parser.Items [JsonProperty("MaxLevel")] public long MaxLevel { get; set; } + + [JsonProperty("WeaponStatHandle")] + public WeaponStatHandle WeaponStatHandle { get; set; } } public class GameplayTags @@ -106,6 +109,15 @@ namespace FModel.Parser.Items public string AttributeInitSubCategory { get; set; } } + public partial class WeaponStatHandle + { + [JsonProperty("DataTable")] + public string DataTable { get; set; } + + [JsonProperty("RowName")] + public string RowName { get; set; } + } + public partial class ItemsIdParser { public static ItemsIdParser[] FromJson(string json) => JsonConvert.DeserializeObject(json, Converter.Settings); diff --git a/FModel/Parser/Weapons/WeaponStatParser.cs b/FModel/Parser/Weapons/WeaponStatParser.cs new file mode 100644 index 00000000..1626ed42 --- /dev/null +++ b/FModel/Parser/Weapons/WeaponStatParser.cs @@ -0,0 +1,538 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using FModel.Parser.Weapons; +// +// var weaponStatParser = WeaponStatParser.FromJson(jsonString); + +namespace FModel.Parser.Weapons +{ + using System; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + + public partial class WeaponStatParser + { + [JsonProperty("export_type")] + public string ExportType { get; set; } + + [JsonProperty("Spread")] + public double Spread { get; set; } + + [JsonProperty("SpreadDownsights")] + public double SpreadDownsights { get; set; } + + [JsonProperty("StandingStillSpreadMultiplier")] + public double StandingStillSpreadMultiplier { get; set; } + + [JsonProperty("AthenaCrouchingSpreadMultiplier")] + public double AthenaCrouchingSpreadMultiplier { get; set; } + + [JsonProperty("AthenaJumpingFallingSpreadMultiplier")] + public long AthenaJumpingFallingSpreadMultiplier { get; set; } + + [JsonProperty("AthenaSprintingSpreadMultiplier")] + public double AthenaSprintingSpreadMultiplier { get; set; } + + [JsonProperty("MinSpeedForSpreadMultiplier")] + public long MinSpeedForSpreadMultiplier { get; set; } + + [JsonProperty("MaxSpeedForSpreadMultiplier")] + public long MaxSpeedForSpreadMultiplier { get; set; } + + [JsonProperty("SpreadDownsightsAdditionalCooldownTime")] + public long SpreadDownsightsAdditionalCooldownTime { get; set; } + + [JsonProperty("HeatX1")] + public double HeatX1 { get; set; } + + [JsonProperty("HeatY1")] + public double HeatY1 { get; set; } + + [JsonProperty("HeatX2")] + public double HeatX2 { get; set; } + + [JsonProperty("HeatY2")] + public double HeatY2 { get; set; } + + [JsonProperty("HeatX3")] + public long HeatX3 { get; set; } + + [JsonProperty("HeatY3")] + public double HeatY3 { get; set; } + + [JsonProperty("HeatXScale")] + public long HeatXScale { get; set; } + + [JsonProperty("HeatYScale")] + public long HeatYScale { get; set; } + + [JsonProperty("CoolX1")] + public double CoolX1 { get; set; } + + [JsonProperty("CoolY1")] + public double CoolY1 { get; set; } + + [JsonProperty("CoolX2")] + public double CoolX2 { get; set; } + + [JsonProperty("CoolY2")] + public long CoolY2 { get; set; } + + [JsonProperty("CoolX3")] + public long CoolX3 { get; set; } + + [JsonProperty("CoolY3")] + public long CoolY3 { get; set; } + + [JsonProperty("CoolXScale")] + public long CoolXScale { get; set; } + + [JsonProperty("CoolYScale")] + public long CoolYScale { get; set; } + + [JsonProperty("PerfectAimCooldown")] + public long PerfectAimCooldown { get; set; } + + [JsonProperty("BulletsPerCartridge")] + public long BulletsPerCartridge { get; set; } + + [JsonProperty("FiringRate")] + public double FiringRate { get; set; } + + [JsonProperty("ROFScale")] + public long RofScale { get; set; } + + [JsonProperty("BurstFiringRate")] + public long BurstFiringRate { get; set; } + + [JsonProperty("FiringRateDownsightsMultiplier")] + public long FiringRateDownsightsMultiplier { get; set; } + + [JsonProperty("AutofireAcquisitionDelay")] + public double AutofireAcquisitionDelay { get; set; } + + [JsonProperty("AutofireCooldown")] + public long AutofireCooldown { get; set; } + + [JsonProperty("RecoilVert")] + public double RecoilVert { get; set; } + + [JsonProperty("RecoilVertScale")] + public long RecoilVertScale { get; set; } + + [JsonProperty("RecoilVertScaleGamepad")] + public double RecoilVertScaleGamepad { get; set; } + + [JsonProperty("VertRecoilDownChance")] + public long VertRecoilDownChance { get; set; } + + [JsonProperty("RecoilHoriz")] + public double RecoilHoriz { get; set; } + + [JsonProperty("RecoilHorizScale")] + public long RecoilHorizScale { get; set; } + + [JsonProperty("RecoilHorizScaleGamepad")] + public long RecoilHorizScaleGamepad { get; set; } + + [JsonProperty("RecoilInterpSpeed")] + public long RecoilInterpSpeed { get; set; } + + [JsonProperty("RecoilRecoveryInterpSpeed")] + public double RecoilRecoveryInterpSpeed { get; set; } + + [JsonProperty("RecoilRecoveryDelay")] + public long RecoilRecoveryDelay { get; set; } + + [JsonProperty("RecoilRecoveryFraction")] + public long RecoilRecoveryFraction { get; set; } + + [JsonProperty("RecoilDownsightsMultiplier")] + public double RecoilDownsightsMultiplier { get; set; } + + [JsonProperty("AthenaRecoilMagnitudeMin")] + public long AthenaRecoilMagnitudeMin { get; set; } + + [JsonProperty("AthenaRecoilMagnitudeMax")] + public long AthenaRecoilMagnitudeMax { get; set; } + + [JsonProperty("AthenaRecoilMagnitudeScale")] + public long AthenaRecoilMagnitudeScale { get; set; } + + [JsonProperty("AthenaRecoilAngleMin")] + public long AthenaRecoilAngleMin { get; set; } + + [JsonProperty("AthenaRecoilAngleMax")] + public long AthenaRecoilAngleMax { get; set; } + + [JsonProperty("AthenaRecoilRollMagnitudeMin")] + public long AthenaRecoilRollMagnitudeMin { get; set; } + + [JsonProperty("AthenaRecoilRollMagnitudeMax")] + public long AthenaRecoilRollMagnitudeMax { get; set; } + + [JsonProperty("AthenaRecoilInterpSpeed")] + public long AthenaRecoilInterpSpeed { get; set; } + + [JsonProperty("AthenaRecoilRecoveryInterpSpeed")] + public long AthenaRecoilRecoveryInterpSpeed { get; set; } + + [JsonProperty("AthenaRecoilDownsightsMultiplier")] + public double AthenaRecoilDownsightsMultiplier { get; set; } + + [JsonProperty("AthenaRecoilHipFireMultiplier")] + public long AthenaRecoilHipFireMultiplier { get; set; } + + [JsonProperty("AthenaAimAssistRange")] + public long AthenaAimAssistRange { get; set; } + + [JsonProperty("ADSTransitionInTime")] + public double AdsTransitionInTime { get; set; } + + [JsonProperty("ADSTransitionOutTime")] + public double AdsTransitionOutTime { get; set; } + + [JsonProperty("MaxSpareAmmo")] + public long MaxSpareAmmo { get; set; } + + [JsonProperty("BulletsPerTracer")] + public long BulletsPerTracer { get; set; } + + [JsonProperty("AIDelayBeforeFiringMin")] + public long AiDelayBeforeFiringMin { get; set; } + + [JsonProperty("AIDelayBeforeFiringMax")] + public double AiDelayBeforeFiringMax { get; set; } + + [JsonProperty("AIFireDurationMin")] + public double AiFireDurationMin { get; set; } + + [JsonProperty("AIFireDurationMax")] + public double AiFireDurationMax { get; set; } + + [JsonProperty("AIMinSpreadDuration")] + public long AiMinSpreadDuration { get; set; } + + [JsonProperty("AIMaxSpreadDuration")] + public long AiMaxSpreadDuration { get; set; } + + [JsonProperty("AIDurationSpreadMultiplier")] + public long AiDurationSpreadMultiplier { get; set; } + + [JsonProperty("AIAdditionalSpreadForTargetMovingLaterally")] + public long AiAdditionalSpreadForTargetMovingLaterally { get; set; } + + [JsonProperty("AIAthenaHearFiringNoiseRange")] + public long AiAthenaHearFiringNoiseRange { get; set; } + + [JsonProperty("EQSDensity")] + public long EqsDensity { get; set; } + + [JsonProperty("MinApproachRange")] + public long MinApproachRange { get; set; } + + [JsonProperty("MinActualRange")] + public long MinActualRange { get; set; } + + [JsonProperty("MinPreferredRange")] + public long MinPreferredRange { get; set; } + + [JsonProperty("MinPreferredRangeEQS")] + public long MinPreferredRangeEqs { get; set; } + + [JsonProperty("MaxPreferredRangeEQS")] + public long MaxPreferredRangeEqs { get; set; } + + [JsonProperty("MaxPreferredRange")] + public long MaxPreferredRange { get; set; } + + [JsonProperty("MaxActualRange")] + public long MaxActualRange { get; set; } + + [JsonProperty("MaxApproachRange")] + public long MaxApproachRange { get; set; } + + [JsonProperty("SweepRadius")] + public long SweepRadius { get; set; } + + [JsonProperty("AutoReloadDelayOverride")] + public long AutoReloadDelayOverride { get; set; } + + [JsonProperty("OverheatingMaxValue")] + public long OverheatingMaxValue { get; set; } + + [JsonProperty("OverheatHeatingValue")] + public long OverheatHeatingValue { get; set; } + + [JsonProperty("OverheatingCoolingValue")] + public long OverheatingCoolingValue { get; set; } + + [JsonProperty("HeatingCooldownDelay")] + public long HeatingCooldownDelay { get; set; } + + [JsonProperty("OverheatedCooldownDelay")] + public long OverheatedCooldownDelay { get; set; } + + [JsonProperty("FortHomingTurnSpeedMin")] + public long FortHomingTurnSpeedMin { get; set; } + + [JsonProperty("FortHomingTurnSpeedMax")] + public long FortHomingTurnSpeedMax { get; set; } + + [JsonProperty("FortHomingTimeUntilMaxTurnSpeed")] + public long FortHomingTimeUntilMaxTurnSpeed { get; set; } + + [JsonProperty("BaseLevel")] + public long BaseLevel { get; set; } + + [JsonProperty("NamedWeightRow")] + public string NamedWeightRow { get; set; } + + [JsonProperty("DmgPB")] + public long DmgPb { get; set; } + + [JsonProperty("DmgMid")] + public double DmgMid { get; set; } + + [JsonProperty("DmgLong")] + public double DmgLong { get; set; } + + [JsonProperty("DmgMaxRange")] + public double DmgMaxRange { get; set; } + + [JsonProperty("EnvDmgPB")] + public long EnvDmgPb { get; set; } + + [JsonProperty("EnvDmgMid")] + public long EnvDmgMid { get; set; } + + [JsonProperty("EnvDmgLong")] + public long EnvDmgLong { get; set; } + + [JsonProperty("EnvDmgMaxRange")] + public long EnvDmgMaxRange { get; set; } + + [JsonProperty("ImpactDmgPB")] + public long ImpactDmgPb { get; set; } + + [JsonProperty("ImpactDmgMid")] + public long ImpactDmgMid { get; set; } + + [JsonProperty("ImpactDmgLong")] + public double ImpactDmgLong { get; set; } + + [JsonProperty("ImpactDmgMaxRange")] + public double ImpactDmgMaxRange { get; set; } + + [JsonProperty("bForceControl")] + public bool BForceControl { get; set; } + + [JsonProperty("RngPB")] + public long RngPb { get; set; } + + [JsonProperty("RngMid")] + public long RngMid { get; set; } + + [JsonProperty("RngLong")] + public long RngLong { get; set; } + + [JsonProperty("RngMax")] + public long RngMax { get; set; } + + [JsonProperty("DmgScaleTable")] + [JsonConverter(typeof(ParseStringConverter))] + public long DmgScaleTable { get; set; } + + [JsonProperty("DmgScaleTableRow")] + public string DmgScaleTableRow { get; set; } + + [JsonProperty("DmgScale")] + public long DmgScale { get; set; } + + [JsonProperty("EnvDmgScaleTable")] + [JsonConverter(typeof(ParseStringConverter))] + public long EnvDmgScaleTable { get; set; } + + [JsonProperty("EnvDmgScaleTableRow")] + public string EnvDmgScaleTableRow { get; set; } + + [JsonProperty("EnvDmgScale")] + public long EnvDmgScale { get; set; } + + [JsonProperty("ImpactDmgScaleTable")] + [JsonConverter(typeof(ParseStringConverter))] + public long ImpactDmgScaleTable { get; set; } + + [JsonProperty("ImpactDmgScaleTableRow")] + public string ImpactDmgScaleTableRow { get; set; } + + [JsonProperty("ImpactDmgScale")] + public long ImpactDmgScale { get; set; } + + [JsonProperty("SurfaceRatioRowName")] + public string SurfaceRatioRowName { get; set; } + + [JsonProperty("DamageZone_Light")] + public long DamageZoneLight { get; set; } + + [JsonProperty("DamageZone_Normal")] + public long DamageZoneNormal { get; set; } + + [JsonProperty("DamageZone_Critical")] + public long DamageZoneCritical { get; set; } + + [JsonProperty("DamageZone_Vulnerability")] + public long DamageZoneVulnerability { get; set; } + + [JsonProperty("KnockbackMagnitude")] + public long KnockbackMagnitude { get; set; } + + [JsonProperty("MidRangeKnockbackMagnitude")] + public long MidRangeKnockbackMagnitude { get; set; } + + [JsonProperty("LongRangeKnockbackMagnitude")] + public long LongRangeKnockbackMagnitude { get; set; } + + [JsonProperty("KnockbackZAngle")] + public long KnockbackZAngle { get; set; } + + [JsonProperty("StunTime")] + public long StunTime { get; set; } + + [JsonProperty("StunScale")] + public long StunScale { get; set; } + + [JsonProperty("Durability")] + public string Durability { get; set; } + + [JsonProperty("DurabilityRowName")] + public string DurabilityRowName { get; set; } + + [JsonProperty("DurabilityScale")] + public long DurabilityScale { get; set; } + + [JsonProperty("DurabilityPerUse")] + public long DurabilityPerUse { get; set; } + + [JsonProperty("DiceCritChance")] + public long DiceCritChance { get; set; } + + [JsonProperty("DiceCritDamageMultiplier")] + public long DiceCritDamageMultiplier { get; set; } + + [JsonProperty("ReloadTime")] + public double ReloadTime { get; set; } + + [JsonProperty("ReloadScale")] + public long ReloadScale { get; set; } + + [JsonProperty("ReloadType")] + public string ReloadType { get; set; } + + [JsonProperty("bAllowReloadInterrupt")] + public bool BAllowReloadInterrupt { get; set; } + + [JsonProperty("bReloadInterruptIsImmediate")] + public bool BReloadInterruptIsImmediate { get; set; } + + [JsonProperty("NumIndividualBulletsToReload")] + public long NumIndividualBulletsToReload { get; set; } + + [JsonProperty("ClipSize")] + public long ClipSize { get; set; } + + [JsonProperty("ClipScale")] + public long ClipScale { get; set; } + + [JsonProperty("InitialClips")] + public long InitialClips { get; set; } + + [JsonProperty("CartridgePerFire")] + public long CartridgePerFire { get; set; } + + [JsonProperty("AmmoCostPerFire")] + public long AmmoCostPerFire { get; set; } + + [JsonProperty("MaxAmmoCostPerFire")] + public long MaxAmmoCostPerFire { get; set; } + + [JsonProperty("MinChargeTime")] + public long MinChargeTime { get; set; } + + [JsonProperty("MaxChargeTime")] + public long MaxChargeTime { get; set; } + + [JsonProperty("ChargeDownTime")] + public long ChargeDownTime { get; set; } + + [JsonProperty("MinChargeDamageMultiplier")] + public long MinChargeDamageMultiplier { get; set; } + + [JsonProperty("MaxChargeDamageMultiplier")] + public long MaxChargeDamageMultiplier { get; set; } + + [JsonProperty("EquipAnimRate")] + public long EquipAnimRate { get; set; } + + [JsonProperty("QuickBarSlotCooldownDuration")] + public long QuickBarSlotCooldownDuration { get; set; } + } + + public partial class WeaponStatParser + { + public static WeaponStatParser FromJson(string json) => JsonConvert.DeserializeObject(json, FModel.Parser.Weapons.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this WeaponStatParser self) => JsonConvert.SerializeObject(self, FModel.Parser.Weapons.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + internal class ParseStringConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + long l; + if (Int64.TryParse(value, out l)) + { + return l; + } + throw new Exception("Cannot unmarshal type long"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (long)untypedValue; + serializer.Serialize(writer, value.ToString()); + return; + } + + public static readonly ParseStringConverter Singleton = new ParseStringConverter(); + } +} diff --git a/FModel/Properties/Resources.Designer.cs b/FModel/Properties/Resources.Designer.cs index 170fccad..d70beca0 100644 --- a/FModel/Properties/Resources.Designer.cs +++ b/FModel/Properties/Resources.Designer.cs @@ -110,6 +110,16 @@ namespace FModel.Properties { } } + /// + /// Recherche une ressource localisée de type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dmg64 { + get { + object obj = ResourceManager.GetObject("dmg64", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Recherche une ressource localisée de type System.Drawing.Bitmap. /// diff --git a/FModel/Properties/Resources.resx b/FModel/Properties/Resources.resx index 3bb7f365..6e2d18d3 100644 --- a/FModel/Properties/Resources.resx +++ b/FModel/Properties/Resources.resx @@ -208,4 +208,7 @@ ..\Resources\Challenges_Slider.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\dmg64.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/FModel/Resources/Quest.png b/FModel/Resources/Quest.png deleted file mode 100644 index e1770444..00000000 Binary files a/FModel/Resources/Quest.png and /dev/null differ diff --git a/FModel/Resources/dmg64.png b/FModel/Resources/dmg64.png new file mode 100644 index 00000000..7967c7fe Binary files /dev/null and b/FModel/Resources/dmg64.png differ