diff --git a/ARKBreedingStats/ARKBreedingStats.csproj b/ARKBreedingStats/ARKBreedingStats.csproj index 8d16439d..74626045 100644 --- a/ARKBreedingStats/ARKBreedingStats.csproj +++ b/ARKBreedingStats/ARKBreedingStats.csproj @@ -38,6 +38,7 @@ DEBUG;TRACE prompt 4 + true AnyCPU @@ -47,6 +48,7 @@ TRACE prompt 4 + true ARKSmartBreeding.ico diff --git a/ARKBreedingStats/AboutBox1.cs b/ARKBreedingStats/AboutBox1.cs index cf430a9a..476943a8 100644 --- a/ARKBreedingStats/AboutBox1.cs +++ b/ARKBreedingStats/AboutBox1.cs @@ -105,6 +105,7 @@ private void linkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs * hallipr (FTP savefile import) * EmkioA (Cryopod import, listView tweaks) * dunger (fixes) +* Myrmecoleon (extra species images) Translations: * French by Vykan and Yanuut diff --git a/ARKBreedingStats/App.config b/ARKBreedingStats/App.config index 782834d8..35c56df3 100644 --- a/ARKBreedingStats/App.config +++ b/ARKBreedingStats/App.config @@ -85,9 +85,6 @@ True - - - True @@ -294,7 +291,11 @@ False - + + False + + False diff --git a/ARKBreedingStats/CreatureColored.cs b/ARKBreedingStats/CreatureColored.cs index d44ba1be..06cd38b7 100644 --- a/ARKBreedingStats/CreatureColored.cs +++ b/ARKBreedingStats/CreatureColored.cs @@ -12,9 +12,50 @@ namespace ARKBreedingStats { static class CreatureColored { - private const string imageFolderName = "img"; - private const string cacheFolderName = "cache"; - private const string extension = ".png"; + private const string Extension = ".png"; + private static readonly string ImgFolder = FileService.GetPath(FileService.ImageFolderName); + private static readonly string CacheFolder = FileService.GetPath(FileService.ImageFolderName, FileService.CacheFolderName); + private const int TemplateSize = 256; + + /// + /// Returns the name of the image file used for the species. E.g. parts like Aberrant or Brute are removed, they share the same graphics. + /// + internal static string SpeciesImageName(string speciesName, bool replacePolar = true) + { + if (string.IsNullOrEmpty(speciesName)) return string.Empty; + return replacePolar + ? speciesName.Replace("Aberrant ", string.Empty).Replace("Brute ", string.Empty) + .Replace("Polar Bear", "Dire Bear") + : speciesName.Replace("Aberrant ", string.Empty).Replace("Brute ", string.Empty); + } + + /// + /// Returns the image file path to the image with the according colorization. + /// + private static string ColoredCreatureCacheFilePath(string speciesName, int[] colorIds, bool listView = false) + => Path.Combine(CacheFolder, speciesName.Substring(0, Math.Min(speciesName.Length, 5)) + "_" + (speciesName + string.Join(".", colorIds.Select(i => i.ToString()))).GetHashCode().ToString("X8") + (listView ? "_lv" : string.Empty) + Extension); + + /// + /// Checks if an according species image exists in the cache folder, if not it tries to creates one. Returns false if there's no image. + /// + internal static (bool imageExists, string imagePath, string speciesListName) SpeciesImageExists(Species species, int[] colorIds) + { + string speciesImageName = SpeciesImageName(species?.name); + string speciesNameForList = SpeciesImageName(species?.name, false); + string cacheFileName = ColoredCreatureCacheFilePath(speciesImageName, colorIds, true); + if (File.Exists(cacheFileName)) + return (true, cacheFileName, speciesNameForList); + + string speciesBackgroundFilePath = Path.Combine(ImgFolder, speciesImageName + Extension); + string speciesColorMaskFilePath = Path.Combine(ImgFolder, speciesImageName + "_m" + Extension); + + if (CreateAndSaveCacheSpeciesFile(colorIds, + species?.colors.Select(c => !string.IsNullOrEmpty(c?.name)).ToArray(), + speciesBackgroundFilePath, speciesColorMaskFilePath, cacheFileName, 64)) + return (true, cacheFileName, speciesNameForList); + + return (false, null, null); + } /// /// Returns a bitmap image that represents the given colors. If a species color file is available, that is used, else a pic-chart like representation. @@ -26,160 +67,47 @@ static class CreatureColored /// /// Only return a pie-chart like color representation. /// Only return an image of the colored creature. If that's not possible, return null. + /// If given, it's tried for find a sex-specific image. /// - public static Bitmap GetColoredCreature(int[] colorIds, Species species, bool[] enabledColorRegions, int size = 128, int pieSize = 64, bool onlyColors = false, bool onlyImage = false, Library.Sex creatureSex = Sex.Unknown) + public static Bitmap GetColoredCreature(int[] colorIds, Species species, bool[] enabledColorRegions, int size = 128, int pieSize = 64, bool onlyColors = false, bool onlyImage = false, Sex creatureSex = Sex.Unknown) { if (colorIds == null) return null; - //float[][] hsl = new float[Species.ColorRegionCount][]; - int[][] rgb = new int[Species.ColorRegionCount][]; - for (int c = 0; c < Species.ColorRegionCount; c++) - { - Color cl = CreatureColors.CreatureColor(colorIds[c]); - rgb[c] = new int[] { cl.R, cl.G, cl.B }; - } - string imgFolder = Path.Combine(FileService.GetPath(), imageFolderName); - string cacheFolder = Path.Combine(FileService.GetPath(), imageFolderName, cacheFolderName); - string speciesName = species?.name ?? string.Empty; + string speciesName = SpeciesImageName(species?.name); + // check if there are sex specific images if (creatureSex != Sex.Unknown) { - string speciesNameWithSex = null; + string speciesNameWithSex; switch (creatureSex) { case Sex.Female: speciesNameWithSex = speciesName + "F"; - if (File.Exists(Path.Combine(imgFolder, speciesNameWithSex + extension))) + if (File.Exists(Path.Combine(ImgFolder, speciesNameWithSex + Extension))) speciesName = speciesNameWithSex; break; case Sex.Male: speciesNameWithSex = speciesName + "M"; - if (File.Exists(Path.Combine(imgFolder, speciesNameWithSex + extension))) + if (File.Exists(Path.Combine(ImgFolder, speciesNameWithSex + Extension))) speciesName = speciesNameWithSex; break; } } - string speciesBackgroundFilePath = Path.Combine(imgFolder, speciesName + extension); - string cacheFileName = Path.Combine(cacheFolder, speciesName.Substring(0, Math.Min(speciesName.Length, 5)) + "_" + (speciesName + string.Join(".", colorIds.Select(i => i.ToString()))).GetHashCode().ToString("X8") + extension); - string speciesColorMaskFilePath = Path.Combine(imgFolder, speciesName + "_m" + extension); - if (!onlyColors && File.Exists(speciesBackgroundFilePath) && File.Exists(speciesColorMaskFilePath) && !File.Exists(cacheFileName)) + string speciesBackgroundFilePath = Path.Combine(ImgFolder, speciesName + Extension); + string speciesColorMaskFilePath = Path.Combine(ImgFolder, speciesName + "_m" + Extension); + string cacheFilePath = ColoredCreatureCacheFilePath(speciesName, colorIds); + bool cacheFileExists = File.Exists(cacheFilePath); + if (!onlyColors && !cacheFileExists) { - using (Bitmap bmpBackground = new Bitmap(speciesBackgroundFilePath)) - using (Bitmap bmpCreature = new Bitmap(bmpBackground.Width, bmpBackground.Height, PixelFormat.Format32bppArgb)) - using (Graphics graph = Graphics.FromImage(bmpCreature)) - { - bool imageFine = false; - graph.SmoothingMode = SmoothingMode.AntiAlias; - const int defaultSizeOfTemplates = 256; - - using (Bitmap bmpMask = new Bitmap(defaultSizeOfTemplates, defaultSizeOfTemplates)) - { - using (var g = Graphics.FromImage(bmpMask)) - using (var bmpMaskOriginal = new Bitmap(speciesColorMaskFilePath)) - g.DrawImage(bmpMaskOriginal, 0, 0, - defaultSizeOfTemplates, defaultSizeOfTemplates); - float o = 0; - try - { - // shadow - using (var b = new SolidBrush(Color.FromArgb(12, 0, 0, 0))) - { - int scx = defaultSizeOfTemplates / 2; - int scy = (int)(scx * 1.6); - int factor = 25; - int sr = scx - 2 * factor; - double heightFactor = 0.3; - - for (int i = 2; i >= 0; i--) - { - int radius = sr + i * factor; - graph.FillEllipse(b, scx - radius, scy - (int)(heightFactor * .7 * radius), 2 * radius, - (int)(2 * heightFactor * radius)); - } - } - - graph.DrawImage(bmpBackground, 0, 0, defaultSizeOfTemplates, defaultSizeOfTemplates); - - for (int i = 0; i < bmpBackground.Width; i++) - { - for (int j = 0; j < bmpBackground.Height; j++) - { - Color bc = bmpBackground.GetPixel(i, j); - if (bc.A > 0) - { - var cl = bmpMask.GetPixel(i, j); - int r = cl.R; - int g = cl.G; - int b = cl.B; - for (int m = 0; m < Species.ColorRegionCount; m++) - { - if (!enabledColorRegions[m] || colorIds[m] == 0) - continue; - switch (m) - { - case 0: - o = Math.Max(0, r - g - b) / 255f; - break; - case 1: - o = Math.Max(0, g - r - b) / 255f; - break; - case 2: - o = Math.Max(0, b - r - g) / 255f; - break; - case 3: - o = Math.Min(g, b) / 255f; - break; - case 4: - o = Math.Min(r, g) / 255f; - break; - case 5: - o = Math.Min(r, b) / 255f; - break; - } - - if (o == 0) - continue; - // using "grain merge", e.g. see https://docs.gimp.org/en/gimp-concepts-layer-modes.html - int rMix = bc.R + rgb[m][0] - 128; - if (rMix < 0) rMix = 0; - else if (rMix > 255) rMix = 255; - int gMix = bc.G + rgb[m][1] - 128; - if (gMix < 0) gMix = 0; - else if (gMix > 255) gMix = 255; - int bMix = bc.B + rgb[m][2] - 128; - if (bMix < 0) bMix = 0; - else if (bMix > 255) bMix = 255; - Color c = Color.FromArgb(rMix, gMix, bMix); - bc = Color.FromArgb(bc.A, (int)(o * c.R + (1 - o) * bc.R), - (int)(o * c.G + (1 - o) * bc.G), (int)(o * c.B + (1 - o) * bc.B)); - } - - bmpCreature.SetPixel(i, j, bc); - } - } - } - - imageFine = true; - } - catch - { - // error during drawing, maybe mask is smaller than image - } - } - if (imageFine) - { - if (!Directory.Exists(cacheFolder)) - Directory.CreateDirectory(cacheFolder); - bmpCreature.Save(cacheFileName); // safe in cache} - } - } + cacheFileExists = CreateAndSaveCacheSpeciesFile(colorIds, enabledColorRegions, speciesBackgroundFilePath, speciesColorMaskFilePath, cacheFilePath); } - bool cacheFileExists = File.Exists(cacheFileName); - if (onlyImage && !cacheFileExists) return null; + if (cacheFileExists && size == TemplateSize) + return new Bitmap(cacheFilePath); + Bitmap bm = new Bitmap(size, size); using (Graphics graph = Graphics.FromImage(bm)) { @@ -191,17 +119,17 @@ public static Bitmap GetColoredCreature(int[] colorIds, Species species, bool[] graph.InterpolationMode = InterpolationMode.HighQualityBicubic; graph.SmoothingMode = SmoothingMode.HighQuality; graph.PixelOffsetMode = PixelOffsetMode.HighQuality; - graph.DrawImage(new Bitmap(cacheFileName), 0, 0, size, size); + graph.DrawImage(new Bitmap(cacheFilePath), 0, 0, size, size); } else { // draw piechart - int pieAngle = enabledColorRegions.Count(c => c); + int pieAngle = enabledColorRegions?.Count(c => c) ?? Species.ColorRegionCount; pieAngle = 360 / (pieAngle > 0 ? pieAngle : 1); int pieNr = 0; for (int c = 0; c < Species.ColorRegionCount; c++) { - if (enabledColorRegions[c]) + if (enabledColorRegions?[c] ?? true) { if (colorIds[c] > 0) { @@ -224,6 +152,214 @@ public static Bitmap GetColoredCreature(int[] colorIds, Species species, bool[] return bm; } + /// + /// Creates a colored species image and saves it as cache file. + /// + /// + private static bool CreateAndSaveCacheSpeciesFile(int[] colorIds, bool[] enabledColorRegions, + string speciesBackgroundFilePath, string speciesColorMaskFilePath, string cacheFilePath, int outputSize = 256) + { + if (!File.Exists(speciesBackgroundFilePath)) return false; + + using (Bitmap bmpBackground = new Bitmap(speciesBackgroundFilePath)) + using (Bitmap bmpColoredCreature = new Bitmap(bmpBackground.Width, bmpBackground.Height, PixelFormat.Format32bppArgb)) + using (Graphics graph = Graphics.FromImage(bmpColoredCreature)) + { + bool imageFine = true; + graph.SmoothingMode = SmoothingMode.AntiAlias; + + // shadow + using (var b = new SolidBrush(Color.FromArgb(12, 0, 0, 0))) + { + int scx = TemplateSize / 2; + int scy = (int)(scx * 1.6); + int factor = 25; + int sr = scx - 2 * factor; + double heightFactor = 0.3; + + for (int i = 2; i >= 0; i--) + { + int radius = sr + i * factor; + graph.FillEllipse(b, scx - radius, scy - (int)(heightFactor * .7 * radius), 2 * radius, + (int)(2 * heightFactor * radius)); + } + } + + // shaded base image + graph.DrawImage(bmpBackground, 0, 0, TemplateSize, TemplateSize); + + // if species has color regions, apply colors + if (File.Exists(speciesColorMaskFilePath)) + { + var rgb = new byte[Species.ColorRegionCount][]; + var useColorRegions = new bool[Species.ColorRegionCount]; + for (int c = 0; c < Species.ColorRegionCount; c++) + { + useColorRegions[c] = enabledColorRegions[c] && colorIds[c] != 0; + if (useColorRegions[c]) + { + Color cl = CreatureColors.CreatureColor(colorIds[c]); + rgb[c] = new byte[] { cl.R, cl.G, cl.B }; + } + } + imageFine = ApplyColorsUnsafe(rgb, useColorRegions, speciesColorMaskFilePath, TemplateSize, bmpBackground, bmpColoredCreature); + } + + if (imageFine) + { + string cacheFolder = Path.GetDirectoryName(cacheFilePath); + if (!Directory.Exists(cacheFolder)) + Directory.CreateDirectory(cacheFolder); + if (outputSize != TemplateSize) + { + using (var resized = new Bitmap(outputSize, outputSize)) + using (var g = Graphics.FromImage(resized)) + { + g.CompositingQuality = CompositingQuality.HighQuality; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.SmoothingMode = SmoothingMode.HighQuality; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.DrawImage(bmpColoredCreature, 0, 0, outputSize, outputSize); + resized.Save(cacheFilePath); + } + } + else bmpColoredCreature.Save(cacheFilePath); + return true; + } + } + + return false; + } + + /// + /// Applies the colors to the base image. + /// + private static bool ApplyColorsUnsafe(byte[][] rgb, bool[] enabledColorRegions, string speciesColorMaskFilePath, + int templateSize, Bitmap bmpBackground, Bitmap bmpColoredCreature) + { + var imageFine = false; + using (Bitmap bmpMask = new Bitmap(templateSize, templateSize)) + { + // get mask in correct size + using (var g = Graphics.FromImage(bmpMask)) + using (var bmpMaskOriginal = new Bitmap(speciesColorMaskFilePath)) + { + g.InterpolationMode = InterpolationMode.Bicubic; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.DrawImage(bmpMaskOriginal, 0, 0, + templateSize, templateSize); + } + + BitmapData bmpDataBackground = bmpBackground.LockBits( + new Rectangle(0, 0, bmpBackground.Width, bmpBackground.Height), ImageLockMode.ReadOnly, + bmpBackground.PixelFormat); + BitmapData bmpDataMask = bmpMask.LockBits( + new Rectangle(0, 0, bmpMask.Width, bmpMask.Height), ImageLockMode.ReadOnly, + bmpMask.PixelFormat); + BitmapData bmpDataColoredCreature = bmpColoredCreature.LockBits( + new Rectangle(0, 0, bmpColoredCreature.Width, bmpColoredCreature.Height), + ImageLockMode.WriteOnly, + bmpColoredCreature.PixelFormat); + + int bgBytes = bmpBackground.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3; + int msBytes = bmpDataMask.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3; + int ccBytes = bmpColoredCreature.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 3; + + float o = 0; + try + { + unsafe + { + byte* scan0Bg = (byte*)bmpDataBackground.Scan0.ToPointer(); + byte* scan0Ms = (byte*)bmpDataMask.Scan0.ToPointer(); + byte* scan0Cc = (byte*)bmpDataColoredCreature.Scan0.ToPointer(); + + for (int i = 0; i < bmpDataBackground.Width; i++) + { + for (int j = 0; j < bmpDataBackground.Height; j++) + { + byte* dBg = scan0Bg + j * bmpDataBackground.Stride + i * bgBytes; + // continue if the pixel is transparent + if (dBg[3] == 0) + continue; + + byte* dMs = scan0Ms + j * bmpDataMask.Stride + i * msBytes; + byte* dCc = scan0Cc + j * bmpDataColoredCreature.Stride + i * ccBytes; + + int r = dMs[2]; + int g = dMs[1]; + int b = dMs[0]; + byte finalR = dBg[2]; + byte finalG = dBg[1]; + byte finalB = dBg[0]; + + for (int m = 0; m < Species.ColorRegionCount; m++) + { + if (!enabledColorRegions[m]) + continue; + switch (m) + { + case 0: + o = Math.Max(0, r - g - b) / 255f; + break; + case 1: + o = Math.Max(0, g - r - b) / 255f; + break; + case 2: + o = Math.Max(0, b - r - g) / 255f; + break; + case 3: + o = Math.Min(g, b) / 255f; + break; + case 4: + o = Math.Min(r, g) / 255f; + break; + case 5: + o = Math.Min(r, b) / 255f; + break; + } + + if (o == 0) + continue; + // using "grain merge", e.g. see https://docs.gimp.org/en/gimp-concepts-layer-modes.html + int rMix = finalR + rgb[m][0] - 128; + if (rMix < 0) rMix = 0; + else if (rMix > 255) rMix = 255; + int gMix = finalG + rgb[m][1] - 128; + if (gMix < 0) gMix = 0; + else if (gMix > 255) gMix = 255; + int bMix = finalB + rgb[m][2] - 128; + if (bMix < 0) bMix = 0; + else if (bMix > 255) bMix = 255; + + finalR = (byte)(o * rMix + (1 - o) * finalR); + finalG = (byte)(o * gMix + (1 - o) * finalG); + finalB = (byte)(o * bMix + (1 - o) * finalB); + } + + // set final color + dCc[0] = finalB; + dCc[1] = finalG; + dCc[2] = finalR; + dCc[3] = dBg[3]; // same alpha as base image + } + } + imageFine = true; + } + } + catch + { + // error during drawing, maybe mask is smaller than image + } + + bmpBackground.UnlockBits(bmpDataBackground); + bmpMask.UnlockBits(bmpDataMask); + bmpColoredCreature.UnlockBits(bmpDataColoredCreature); + } + + return imageFine; + } + public static string RegionColorInfo(Species species, int[] colorIds) { if (species == null || colorIds == null) return null; @@ -239,5 +375,21 @@ public static string RegionColorInfo(Species species, int[] colorIds) } return creatureRegionColors.ToString(); } + + /// + /// Deletes all cached species color images with a specific pattern that weren't used for some time. + /// + internal static void CleanupCache() + { + string imgCachePath = FileService.GetPath(FileService.ImageFolderName, FileService.CacheFolderName); + if (!Directory.Exists(imgCachePath)) return; + + DirectoryInfo directory = new DirectoryInfo(imgCachePath); + var oldCacheFiles = directory.GetFiles().Where(f => f.LastAccessTime < DateTime.Now.AddDays(-5)).ToArray(); + foreach (FileInfo f in oldCacheFiles) + { + FileService.TryDeleteFile(f); + } + } } } diff --git a/ARKBreedingStats/CreatureInfoInput.cs b/ARKBreedingStats/CreatureInfoInput.cs index 09b2c564..22d708d4 100644 --- a/ARKBreedingStats/CreatureInfoInput.cs +++ b/ARKBreedingStats/CreatureInfoInput.cs @@ -449,8 +449,7 @@ public Species SelectedSpecies dhmsInputGrown.Timespan = TimeSpan.Zero; dhmsInputCooldown.Timespan = TimeSpan.Zero; } - RegionColors = new int[6]; - UpdateRegionColorImage(); + RegionColors = null; } } diff --git a/ARKBreedingStats/FileService.cs b/ARKBreedingStats/FileService.cs index 3b34c3f0..5afb0399 100644 --- a/ARKBreedingStats/FileService.cs +++ b/ARKBreedingStats/FileService.cs @@ -21,6 +21,8 @@ public static class FileService public const string ArkDataJson = "ark_data.json"; public const string IgnoreSpeciesClasses = "ignoreSpeciesClasses.json"; public const string CustomReplacingsNamePattern = "customReplacings.json"; + public const string ImageFolderName = "img"; + public const string CacheFolderName = "cache"; public static readonly string ExeFilePath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath; public static readonly string ExeLocation = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath); @@ -154,7 +156,6 @@ public static bool TryCreateDirectory(string path, out string error) /// /// Tries to delete a file, doesn't throw an exception. /// - /// public static bool TryDeleteFile(string filePath) { if (!File.Exists(filePath)) return false; @@ -163,7 +164,28 @@ public static bool TryDeleteFile(string filePath) File.Delete(filePath); return true; } - catch { } + catch + { + // ignored + } + return false; + } + + /// + /// Tries to delete a file, doesn't throw an exception. + /// + public static bool TryDeleteFile(FileInfo fileInfo) + { + if (!fileInfo.Exists) return false; + try + { + fileInfo.Delete(); + return true; + } + catch + { + // ignored + } return false; } diff --git a/ARKBreedingStats/Form1.Designer.cs b/ARKBreedingStats/Form1.Designer.cs index 6f627010..5f6ddb59 100644 --- a/ARKBreedingStats/Form1.Designer.cs +++ b/ARKBreedingStats/Form1.Designer.cs @@ -819,7 +819,7 @@ private void InitializeComponent() // this.lbInfoYellowStats.Location = new System.Drawing.Point(590, 341); this.lbInfoYellowStats.Name = "lbInfoYellowStats"; - this.lbInfoYellowStats.Size = new System.Drawing.Size(177, 187); + this.lbInfoYellowStats.Size = new System.Drawing.Size(255, 126); this.lbInfoYellowStats.TabIndex = 15; this.lbInfoYellowStats.Text = resources.GetString("lbInfoYellowStats.Text"); // diff --git a/ARKBreedingStats/Form1.collection.cs b/ARKBreedingStats/Form1.collection.cs index 003e75a4..baa1157f 100644 --- a/ARKBreedingStats/Form1.collection.cs +++ b/ARKBreedingStats/Form1.collection.cs @@ -15,7 +15,7 @@ namespace ARKBreedingStats { public partial class Form1 { - private const string COLLECTION_FILE_EXTENSION = ".asb"; + private const string CollectionFileExtension = ".asb"; private void NewCollection() { @@ -53,8 +53,7 @@ private void NewCollection() UpdateCreatureListings(); creatureBoxListView.Clear(); - Properties.Settings.Default.LastSaveFile = ""; - Properties.Settings.Default.LastImportFile = ""; + Properties.Settings.Default.LastSaveFile = null; _currentFileName = null; _fileSync.ChangeFile(_currentFileName); SetCollectionChanged(false); @@ -108,8 +107,8 @@ private void LoadCollection(bool add = false) } using (OpenFileDialog dlg = new OpenFileDialog { - Filter = $"ASB Collection Files (*{COLLECTION_FILE_EXTENSION}; *.xml)|*{COLLECTION_FILE_EXTENSION};*.xml" - + $"|ASB Collection File (*{COLLECTION_FILE_EXTENSION})|*{COLLECTION_FILE_EXTENSION}" + Filter = $"ASB Collection Files (*{CollectionFileExtension}; *.xml)|*{CollectionFileExtension};*.xml" + + $"|ASB Collection File (*{CollectionFileExtension})|*{CollectionFileExtension}" + "|Old ASB Collection File(*.xml)| *.xml" }) { @@ -139,7 +138,7 @@ private void SaveNewCollection() { using (SaveFileDialog dlg = new SaveFileDialog { - Filter = $"Creature Collection File (*{COLLECTION_FILE_EXTENSION})|*{COLLECTION_FILE_EXTENSION}" + Filter = $"Creature Collection File (*{CollectionFileExtension})|*{CollectionFileExtension}" }) { if (dlg.ShowDialog() == DialogResult.OK) @@ -293,12 +292,12 @@ private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = fal string fileNameWOExt = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); // check if new fileName is not yet existing - filePath = fileNameWOExt + COLLECTION_FILE_EXTENSION; + filePath = fileNameWOExt + CollectionFileExtension; if (File.Exists(filePath)) { int fi = 2; - while (File.Exists(fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION)) fi++; - filePath = fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION; + while (File.Exists(fileNameWOExt + "_" + fi + CollectionFileExtension)) fi++; + filePath = fileNameWOExt + "_" + fi + CollectionFileExtension; } // save converted library @@ -437,12 +436,10 @@ private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = fal speciesSelector1.SetSpecies(_creatureCollection.creatures[0].Species); // set library species to what it was before loading - if (selectedlibrarySpecies == null - || !_creatureCollection.creatures.Any(c => c.Species != null && c.Species.Equals(selectedlibrarySpecies)) - ) - selectedlibrarySpecies = speciesSelector1.SelectedSpecies; if (selectedlibrarySpecies != null) listBoxSpeciesLib.SelectedItem = selectedlibrarySpecies; + else if (Properties.Settings.Default.LibrarySelectSelectedSpeciesOnLoad) + listBoxSpeciesLib.SelectedItem = speciesSelector1.SelectedSpecies; _filterListAllowed = true; FilterLib(); @@ -467,7 +464,7 @@ private void SetCollectionChanged(bool changed, Species species = null) { if (changed) { - if (species == null || pedigree1.creature != null && pedigree1.creature.Species == species) + if (species == null || pedigree1.SelectedSpecies == species) _pedigreeNeedsUpdate = true; if (species == null || breedingPlan1.CurrentSpecies == species) breedingPlan1.breedingPlanNeedsUpdate = true; @@ -480,7 +477,7 @@ private void SetCollectionChanged(bool changed, Species species = null) { string filenameWOExt = Path.GetFileNameWithoutExtension(_currentFileName); string timeStamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); - string backupFileName = filenameWOExt + "_backup_" + timeStamp + COLLECTION_FILE_EXTENSION; + string backupFileName = filenameWOExt + "_backup_" + timeStamp + CollectionFileExtension; string backupFilePath = Path.Combine(Path.GetDirectoryName(_currentFileName), backupFileName); File.Copy(_currentFileName, backupFilePath); _lastAutoSaveBackup = DateTime.Now; diff --git a/ARKBreedingStats/Form1.cs b/ARKBreedingStats/Form1.cs index 3477df89..979b0cf4 100644 --- a/ARKBreedingStats/Form1.cs +++ b/ARKBreedingStats/Form1.cs @@ -119,7 +119,7 @@ public Form1() Regex r = new Regex(@"(? $"{{is{m.Groups[1].Value}Top{m.Groups[2].Value.ToLowerInvariant()}}}"); } @@ -145,7 +145,7 @@ public Form1() // delegates pedigree1.EditCreature += EditCreatureInTester; pedigree1.BestBreedingPartners += ShowBestBreedingPartner; - pedigree1.exportToClipboard += ExportAsTextToClipboard; + pedigree1.ExportToClipboard += ExportAsTextToClipboard; breedingPlan1.EditCreature += EditCreatureInTester; breedingPlan1.CreateIncubationTimer += CreateIncubationTimer; breedingPlan1.BestBreedingPartners += ShowBestBreedingPartner; @@ -295,7 +295,6 @@ private void Form1_Load(object sender, EventArgs e) _statIOs[(int)StatNames.Food].DomLevelLockedZero = true; InitializeCollection(); - _filterListAllowed = true; // Set up the file watcher _fileSync = new FileSync(_currentFileName, CollectionChanged); @@ -311,34 +310,6 @@ private void Form1_Load(object sender, EventArgs e) Environment.Exit(1); } - bool createNewCollection = string.IsNullOrEmpty(Properties.Settings.Default.LastSaveFile); - if (!createNewCollection) - { - // if the last loaded file was already converted by someone else (e.g. if the library-file is shared), - // ask if the converted version should be loaded instead. - if (Path.GetExtension(Properties.Settings.Default.LastSaveFile).ToLower() == ".xml") - { - string possibleConvertedCollectionPath = Path.Combine(Path.GetDirectoryName(Properties.Settings.Default.LastSaveFile), Path.GetFileNameWithoutExtension(Properties.Settings.Default.LastSaveFile) + COLLECTION_FILE_EXTENSION); - if (File.Exists(possibleConvertedCollectionPath) - && MessageBox.Show("The creature collection file seems to be already converted to the new file format.\n" - + "Path of the collection file:\n" + Properties.Settings.Default.LastSaveFile - + "\n\nIf you click No, the old file-version will be loaded and then automatically converted." - + "\nIt is recommended to load the already converted version to avoid synchronisation-issues." - + "\nDo you want to load the converted version?", "Library seems to be already converted", - MessageBoxButtons.YesNo, MessageBoxIcon.Question - ) == DialogResult.Yes) - { - Properties.Settings.Default.LastSaveFile = possibleConvertedCollectionPath; - } - } - // load last save file: - if (!LoadCollectionFile(Properties.Settings.Default.LastSaveFile)) - createNewCollection = true; - } - - if (createNewCollection) - NewCollection(); - for (int s = 0; s < Values.STATS_COUNT; s++) { _statIOs[s].Input = 0; @@ -397,27 +368,57 @@ private void Form1_Load(object sender, EventArgs e) if (DateTime.Now.AddHours(-20) > Properties.Settings.Default.lastUpdateCheck) CheckForUpdates(true); - if (!Properties.Settings.Default.AlreadyAskedToDownloadImageFiles) + if (!Properties.Settings.Default.AlreadyAskedToDownloadImageFilesTropeognathus) { - Properties.Settings.Default.AlreadyAskedToDownloadImageFiles = true; - if (!File.Exists(FileService.GetPath("img", "Giant Queen Bee.png")) - && MessageBox.Show("Download species images to display the creature colors?\n\nThe file to be downloaded has a size of ~13 MB.", + Properties.Settings.Default.AlreadyAskedToDownloadImageFilesTropeognathus = true; + if (!File.Exists(FileService.GetPath(FileService.ImageFolderName, "Tropeognathus.png")) + && MessageBox.Show("Download new species images to display the creature colors?\n\nThe file to be downloaded has a size of ~17 MB.\nYou can later download these images in the menu ? - Download Species Images", "Download species images?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) DownloadSpeciesImagesAsync(); } + _filterListAllowed = true; + // load last loaded file + bool createNewCollection = string.IsNullOrEmpty(Properties.Settings.Default.LastSaveFile); + if (!createNewCollection) + { + // if the last loaded file was already converted by someone else (e.g. if the library-file is shared), + // ask if the converted version should be loaded instead. + if (Path.GetExtension(Properties.Settings.Default.LastSaveFile).ToLower() == ".xml") + { + string possibleConvertedCollectionPath = Path.Combine(Path.GetDirectoryName(Properties.Settings.Default.LastSaveFile), Path.GetFileNameWithoutExtension(Properties.Settings.Default.LastSaveFile) + CollectionFileExtension); + if (File.Exists(possibleConvertedCollectionPath) + && MessageBox.Show("The creature collection file seems to be already converted to the new file format.\n" + + "Path of the collection file:\n" + Properties.Settings.Default.LastSaveFile + + "\n\nIf you click No, the old file-version will be loaded and then automatically converted." + + "\nIt is recommended to load the already converted version to avoid synchronisation-issues." + + "\nDo you want to load the converted version?", "Library seems to be already converted", + MessageBoxButtons.YesNo, MessageBoxIcon.Question + ) == DialogResult.Yes) + { + Properties.Settings.Default.LastSaveFile = possibleConvertedCollectionPath; + } + } + // load last save file: + if (!LoadCollectionFile(Properties.Settings.Default.LastSaveFile)) + createNewCollection = true; + } + + if (createNewCollection) + NewCollection(); + _timerGlobal.Start(); } /// - /// If the according property is set, the speechrecognition is initialized. Else it's disposed. + /// If the according property is set, the speechRecognition is initialized. Else it's disposed. /// private void InitializeSpeechRecognition() { bool speechRecognitionInitialized = false; if (Properties.Settings.Default.SpeechRecognition) { - // var speechRecognitionAvailable = (AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName.Substring(0, 13) == "System.Speech")); // TODO doens't work as intended. Should only require System.Speech if available to allow running it on MONO + // var speechRecognitionAvailable = (AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName.Substring(0, 13) == "System.Speech")); // TODO doesn't work as intended. Should only require System.Speech if available to allow running it on MONO _speechRecognition = new SpeechRecognition(_creatureCollection.maxWildLevel, _creatureCollection.considerWildLevelSteps ? _creatureCollection.wildLevelStep : 1, Values.V.speciesWithAliasesList, lbListening); if (_speechRecognition.Initialized) @@ -840,13 +841,13 @@ private void UpdateCreatureListings(Species species = null, bool keepCurrentlySe /// /// This function should be called if the creatureCollection is changed, i.e. after loading a file or adding/removing a creature. - /// It updates the listed species in the treelist and in the speciesSelector. + /// It updates the listed species in the treeList and in the speciesSelector. /// private void UpdateSpeciesLists(List creatures, bool keepCurrentlySelectedSpecies = true) { - Species selectedSpecies = keepCurrentlySelectedSpecies && listBoxSpeciesLib.SelectedItem is Species sp ? sp : null; + Species selectedSpeciesLibrary = keepCurrentlySelectedSpecies && listBoxSpeciesLib.SelectedItem is Species sp ? sp : null; - // clear specieslist + // clear speciesList listBoxSpeciesLib.Items.Clear(); List availableSpecies = new List(); @@ -869,8 +870,8 @@ private void UpdateSpeciesLists(List creatures, bool keepCurrentlySele listBoxSpeciesLib.Items.Add(s); listBoxSpeciesLib.EndUpdate(); - if (selectedSpecies != null) - listBoxSpeciesLib.SelectedItem = selectedSpecies; + if (selectedSpeciesLibrary != null) + listBoxSpeciesLib.SelectedItem = selectedSpeciesLibrary; breedingPlan1.SetSpeciesList(availableSpecies, creatures); speciesSelector1.SetLibrarySpecies(availableSpecies); @@ -881,7 +882,7 @@ private void UpdateSpeciesLists(List creatures, bool keepCurrentlySele /// private void UpdateOwnerServerTagLists() { - string notavailable = Loc.S("na"); + bool filterListAllowedKeeper = _filterListAllowed; _filterListAllowed = false; //// clear lists @@ -947,7 +948,7 @@ void AddIfNotContains(List list, string name) _creatureCollection.ownerList = owners; _creatureCollection.serverList = serverArray; - _filterListAllowed = true; + _filterListAllowed = filterListAllowedKeeper; } #region check for update @@ -1178,23 +1179,7 @@ private void Form1_FormClosed(object sender, FormClosedEventArgs e) Properties.Settings.Default.Save(); // remove old cache-files - string imgCachePath = FileService.GetPath("img", "cache"); - if (Directory.Exists(imgCachePath)) - { - DirectoryInfo directory = new DirectoryInfo(imgCachePath); - List oldCacheFiles = directory.GetFiles().Where(f => f.LastAccessTime < DateTime.Now.AddDays(-5)).ToList(); - foreach (FileInfo f in oldCacheFiles) - { - try - { - f.Delete(); - } - catch - { - // ignored - } - } - } + CreatureColored.CleanupCache(); _tt.Dispose(); _timerGlobal.Dispose(); @@ -1229,7 +1214,7 @@ private void listBoxSpeciesLib_SelectedIndexChanged(object sender, EventArgs e) } /// - /// Recalculate topstats if filters are used in topstat-calculation + /// Recalculate topStats if filters are used in topStat-calculation /// private void RecalculateTopStatsIfNeeded() { @@ -3149,7 +3134,7 @@ private void downloadSpeciesImagesToolStripMenuItem_Click(object sender, EventAr private async void DownloadSpeciesImagesAsync() { - bool overwrite = !Directory.Exists(FileService.GetPath("img")); + bool overwrite = !Directory.Exists(FileService.GetPath(FileService.ImageFolderName)); if (!overwrite) { var msgBoxResult = MessageBox.Show( diff --git a/ARKBreedingStats/Form1.importExported.cs b/ARKBreedingStats/Form1.importExported.cs index 9da1ba26..57816ada 100644 --- a/ARKBreedingStats/Form1.importExported.cs +++ b/ARKBreedingStats/Form1.importExported.cs @@ -189,8 +189,7 @@ private void ImportExportedAddIfPossible(string filePath) textColor = Color.FromArgb(255, colorSaturation, colorSaturation); } - if (_overlay != null) - _overlay.SetInfoText(infoText, textColor); + _overlay?.SetInfoText(infoText, textColor); if (added) { diff --git a/ARKBreedingStats/Form1.importSave.cs b/ARKBreedingStats/Form1.importSave.cs index 2b2726f4..87ae5921 100644 --- a/ARKBreedingStats/Form1.importSave.cs +++ b/ARKBreedingStats/Form1.importSave.cs @@ -52,7 +52,7 @@ private async void RunSavegameImport(ATImportFileLocation atImportFileLocation) return; break; default: - throw new Exception($"Unsuppoerted uri scheme: {uri.Scheme}"); + throw new Exception($"Unsupported uri scheme: {uri.Scheme}"); } } else diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs index c7ababb3..fa6a4c12 100644 --- a/ARKBreedingStats/Form1.library.cs +++ b/ARKBreedingStats/Form1.library.cs @@ -133,11 +133,16 @@ private void AddCreatureToCollection(bool fromExtractor = true, long motherArkId if (creature.Mother == null || creature.Father == null) UpdateParents(new List { creature }); + _filterListAllowed = false; UpdateCreatureListings(species, false); + // show only the added creatures' species + listBoxSpeciesLib.SelectedItem = creature.Species; + _filterListAllowed = true; + _libraryNeedsUpdate = true; + if (goToLibraryTab) { - listBoxSpeciesLib.SelectedItem = creature.Species; tabControlMain.SelectedTab = tabPageLibrary; } @@ -253,7 +258,7 @@ private int[] GetCurrentDomLevels(bool fromExtractor = true) private void InitializeCollection() { // set pointer to current collection - pedigree1.creatures = _creatureCollection.creatures; + pedigree1.SetCreatures(_creatureCollection.creatures); breedingPlan1.creatureCollection = _creatureCollection; tribesControl1.Tribes = _creatureCollection.tribes; tribesControl1.Players = _creatureCollection.players; @@ -581,7 +586,7 @@ private void UpdateIncubationParents(CreatureCollection cc) } } - private void ShowCreaturesInListView(List creatures) + private void ShowCreaturesInListView(IEnumerable creatures) { listViewLibrary.BeginUpdate(); @@ -977,7 +982,7 @@ private void LibrarySelectedIndexChanged() } /// - /// Call this list to set the listview for the library to the current filters + /// Call this list to set the listView for the library to the current filters /// private void FilterLib() { @@ -1007,12 +1012,12 @@ private void FilterLib() filteredList = ApplyLibraryFilterSettings(filteredList); // display new results - ShowCreaturesInListView(filteredList.OrderBy(c => c.name).ToList()); + ShowCreaturesInListView(filteredList); - // update creaturebox + // update creatureBox creatureBoxListView.UpdateLabel(); - // select previous selecteded creatures again + // select previous selected creatures again int selectedCount = selectedCreatures.Count; if (selectedCount > 0) { diff --git a/ARKBreedingStats/Pedigree.cs b/ARKBreedingStats/Pedigree.cs index ccdfeb4b..d0f84aa8 100644 --- a/ARKBreedingStats/Pedigree.cs +++ b/ARKBreedingStats/Pedigree.cs @@ -15,20 +15,20 @@ public partial class Pedigree : UserControl public event EditCreatureEventHandler EditCreature; public event Action BestBreedingPartners; - public event PedigreeCreature.ExportToClipboardEventHandler exportToClipboard; - public List creatures; - public Creature creature; - private List children = new List(); - private readonly List> lines = new List>(); - private List pcs = new List(); - private bool[] enabledColorRegions = { true, true, true, true, true, true }; + public event PedigreeCreature.ExportToClipboardEventHandler ExportToClipboard; + private List _creatures; + private Creature _selectedCreature; + private List _creatureChildren = new List(); + private readonly List> _lines = new List>(); + private readonly List _pcs = new List(); + private bool[] _enabledColorRegions = { true, true, true, true, true, true }; public Pedigree() { InitializeComponent(); SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); - lines.Add(new List()); - lines.Add(new List()); + _lines.Add(new List()); + _lines.Add(new List()); NoCreatureSelected(); listViewCreatures.ListViewItemSorter = new ListViewColumnSorter(); splitContainer1.Panel2.Paint += Panel2_Paint; @@ -37,7 +37,7 @@ public Pedigree() private void Panel2_Paint(object sender, PaintEventArgs e) { e.Graphics.TranslateTransform(splitContainer1.Panel2.AutoScrollPosition.X, splitContainer1.Panel2.AutoScrollPosition.Y); - if (creature != null) + if (_selectedCreature != null) DrawLines(e.Graphics); } @@ -53,7 +53,7 @@ private void DrawLines(Graphics g) myPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - foreach (int[] line in lines[0]) + foreach (int[] line in _lines[0]) { if (line[4] == 1) myPen.Color = Color.DarkRed; @@ -71,18 +71,18 @@ private void DrawLines(Graphics g) } myPen.Color = Color.DarkGray; myPen.Width = 1; - foreach (int[] line in lines[1]) + foreach (int[] line in _lines[1]) { g.DrawLine(myPen, line[0], line[1], line[2], line[3]); } - if (children.Any()) + if (_creatureChildren.Any()) g.DrawString(Loc.S("Descendants"), new Font("Arial", 14), new SolidBrush(Color.Black), 210, 170); } } public void Clear() { - creature = null; + _selectedCreature = null; ClearControls(); NoCreatureSelected(); } @@ -91,12 +91,13 @@ public void ClearControls() { // clear pedigree SuspendLayout(); - foreach (PedigreeCreature pc in pcs) + foreach (PedigreeCreature pc in _pcs) pc.Dispose(); - lines.Clear(); - lines.Add(new List()); - lines.Add(new List()); + _lines.Clear(); + _lines.Add(new List()); + _lines.Add(new List()); pictureBox.Image = null; + pictureBox.Visible = false; ResumeLayout(); } @@ -107,7 +108,7 @@ private void CreatePedigree() { // clear old pedigreeCreatures ClearControls(); - if (creature == null) + if (_selectedCreature == null) { NoCreatureSelected(); return; @@ -115,7 +116,7 @@ private void CreatePedigree() SuspendLayout(); - pedigreeCreature1.IsGlowSpecies = creature.Species?.IsGlowSpecies ?? false; + pedigreeCreature1.IsGlowSpecies = _selectedCreature.Species?.IsGlowSpecies ?? false; const int leftBorder = 40; const int pedigreeElementWidth = 325; @@ -124,16 +125,16 @@ private void CreatePedigree() lbPedigreeEmpty.Visible = false; // create ancestors - CreateParentsChild(creature, leftBorder + pedigreeElementWidth + margin, 60, true, true); - if (creature.Mother != null) + CreateParentsChild(_selectedCreature, leftBorder + pedigreeElementWidth + margin, 60, true, true); + if (_selectedCreature.Mother != null) { - if (CreateParentsChild(creature.Mother, leftBorder, 20)) - lines[1].Add(new[] { leftBorder + pedigreeElementWidth, 79, leftBorder + pedigreeElementWidth + margin, 79 }); + if (CreateParentsChild(_selectedCreature.Mother, leftBorder, 20)) + _lines[1].Add(new[] { leftBorder + pedigreeElementWidth, 79, leftBorder + pedigreeElementWidth + margin, 79 }); } - if (creature.Father != null) + if (_selectedCreature.Father != null) { - if (CreateParentsChild(creature.Father, leftBorder + 2 * (pedigreeElementWidth + margin), 20)) - lines[1].Add(new[] { leftBorder + 2 * pedigreeElementWidth + 2 * margin, 79, leftBorder + 2 * pedigreeElementWidth + margin, 159 }); + if (CreateParentsChild(_selectedCreature.Father, leftBorder + 2 * (pedigreeElementWidth + margin), 20)) + _lines[1].Add(new[] { leftBorder + 2 * pedigreeElementWidth + 2 * margin, 79, leftBorder + 2 * pedigreeElementWidth + margin, 159 }); } // create descendants @@ -141,28 +142,29 @@ private void CreatePedigree() // scrolloffsets int xS = AutoScrollPosition.X; int yS = AutoScrollPosition.Y; - foreach (Creature c in children) + foreach (Creature c in _creatureChildren) { - PedigreeCreature pc = new PedigreeCreature(c, enabledColorRegions) + PedigreeCreature pc = new PedigreeCreature(c, _enabledColorRegions) { Location = new Point(leftBorder + xS, 200 + 35 * row + yS) }; for (int s = 0; s < PedigreeCreature.displayedStatsCount; s++) { int si = PedigreeCreature.displayedStats[s]; - if (creature.valuesDom[si] > 0 && creature.levelsWild[si] >= 0 && creature.levelsWild[si] == c.levelsWild[si]) - lines[0].Add(new[] { leftBorder + 38 + 29 * s, 200 + 35 * row + 6, leftBorder + 38 + 29 * s, 200 + 35 * row + 15, 0, 0 }); + if (_selectedCreature.valuesDom[si] > 0 && _selectedCreature.levelsWild[si] >= 0 && _selectedCreature.levelsWild[si] == c.levelsWild[si]) + _lines[0].Add(new[] { leftBorder + 38 + 29 * s, 200 + 35 * row + 6, leftBorder + 38 + 29 * s, 200 + 35 * row + 15, 0, 0 }); } pc.CreatureClicked += CreatureClicked; pc.CreatureEdit += CreatureEdit; pc.BestBreedingPartners += BestBreedingPartners; - pc.ExportToClipboard += exportToClipboard; + pc.ExportToClipboard += ExportToClipboard; splitContainer1.Panel2.Controls.Add(pc); - pcs.Add(pc); + _pcs.Add(pc); row++; } - pictureBox.Image = CreatureColored.GetColoredCreature(creature.colors, creature.Species, enabledColorRegions, 256, creatureSex: creature.sex); + pictureBox.Image = CreatureColored.GetColoredCreature(_selectedCreature.colors, _selectedCreature.Species, _enabledColorRegions, 256, creatureSex: _selectedCreature.sex); + pictureBox.Visible = true; Invalidate(); ResumeLayout(); @@ -186,7 +188,7 @@ private bool CreateParentsChild(Creature creature, int x, int y, bool drawWithNo int xS = AutoScrollPosition.X; int yS = AutoScrollPosition.Y; // creature - AddCreatureControl(new PedigreeCreature(creature, enabledColorRegions) + AddCreatureControl(new PedigreeCreature(creature, _enabledColorRegions) { Location = new Point(x + xS, y + yS + 40), Highlight = highlightCreature @@ -198,14 +200,14 @@ void AddCreatureControl(PedigreeCreature _pc) _pc.CreatureClicked += CreatureClicked; _pc.CreatureEdit += CreatureEdit; _pc.BestBreedingPartners += BestBreedingPartners; - _pc.ExportToClipboard += exportToClipboard; - pcs.Add(_pc); + _pc.ExportToClipboard += ExportToClipboard; + _pcs.Add(_pc); } // mother if (creature.Mother != null) { - AddCreatureControl(new PedigreeCreature(creature.Mother, enabledColorRegions) + AddCreatureControl(new PedigreeCreature(creature.Mother, _enabledColorRegions) { Location = new Point(x + xS, y + yS) }); @@ -213,7 +215,7 @@ void AddCreatureControl(PedigreeCreature _pc) // father if (creature.Father != null) { - AddCreatureControl(new PedigreeCreature(creature.Father, enabledColorRegions) + AddCreatureControl(new PedigreeCreature(creature.Father, _enabledColorRegions) { Location = new Point(x + xS, y + yS + 80) }); @@ -235,11 +237,11 @@ void AddCreatureControl(PedigreeCreature _pc) // offspring can have stats that are up to 2 levels higher due to mutations. currently there are no decreasing levels due to mutations if (creature.Mother != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Mother.levelsWild[si] || creature.levelsWild[si] == creature.Mother.levelsWild[si] + 2)) { - lines[0].Add(new[] { 38 + x + 29 * s, y + 33, 38 + x + 29 * s, y + 42, (better == -1 ? 1 : 2), (creature.levelsWild[si] > creature.Mother.levelsWild[si] ? 1 : 0) }); + _lines[0].Add(new[] { 38 + x + 29 * s, y + 33, 38 + x + 29 * s, y + 42, (better == -1 ? 1 : 2), (creature.levelsWild[si] > creature.Mother.levelsWild[si] ? 1 : 0) }); } if (creature.Father != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Father.levelsWild[si] || creature.levelsWild[si] == creature.Father.levelsWild[si] + 2)) { - lines[0].Add(new[] { 38 + x + 29 * s, y + 83, 38 + x + 29 * s, y + 74, (better == 1 ? 1 : 2), (creature.levelsWild[si] > creature.Father.levelsWild[si] ? 1 : 0) }); + _lines[0].Add(new[] { 38 + x + 29 * s, y + 83, 38 + x + 29 * s, y + 74, (better == 1 ? 1 : 2), (creature.levelsWild[si] > creature.Father.levelsWild[si] ? 1 : 0) }); } } return true; @@ -255,6 +257,8 @@ private void CreatureEdit(Creature c, bool isVirtual) EditCreature?.Invoke(c, isVirtual); } + public void SetCreatures(List creatures) => _creatures = creatures; + /// /// Creates the pedigree with the given creature in the center. /// @@ -264,14 +268,14 @@ public void SetCreature(Creature centralCreature, bool forceUpdate = false) { if (centralCreature == null) { - creature = null; + _selectedCreature = null; ClearControls(); } - else if (creatures != null && (centralCreature != creature || forceUpdate)) + else if (_creatures != null && (centralCreature != _selectedCreature || forceUpdate)) { - creature = centralCreature; + _selectedCreature = centralCreature; // set children - children = creatures.Where(cr => cr.motherGuid == creature.guid || cr.fatherGuid == creature.guid) + _creatureChildren = _creatures.Where(cr => cr.motherGuid == _selectedCreature.guid || cr.fatherGuid == _selectedCreature.guid) .OrderBy(cr => cr.name) .ToList(); @@ -312,11 +316,11 @@ public bool[] EnabledColorRegions { if (value != null && value.Length == 6) { - enabledColorRegions = value; + _enabledColorRegions = value; } else { - enabledColorRegions = new[] { true, true, true, true, true, true }; + _enabledColorRegions = new[] { true, true, true, true, true, true }; } } } @@ -346,7 +350,7 @@ public void UpdateListView() listViewCreatures.Groups.Add(new ListViewGroup(s.DescriptiveNameAndMod)); } - foreach (Creature cr in creatures) + foreach (Creature cr in _creatures) { // if species is unknown, don't display creature if (cr.Species == null) continue; @@ -388,5 +392,7 @@ public void SetLocalizations() { Loc.ControlText(lbPedigreeEmpty); } + + public Species SelectedSpecies => _selectedCreature?.Species; } } diff --git a/ARKBreedingStats/Properties/AssemblyInfo.cs b/ARKBreedingStats/Properties/AssemblyInfo.cs index eadf483f..1f5fb00e 100644 --- a/ARKBreedingStats/Properties/AssemblyInfo.cs +++ b/ARKBreedingStats/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ // Revision // [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("0.40.1.1")] +[assembly: AssemblyFileVersion("0.40.2.0")] [assembly: NeutralResourcesLanguage("en")] diff --git a/ARKBreedingStats/Properties/Settings.Designer.cs b/ARKBreedingStats/Properties/Settings.Designer.cs index b0b2b577..b23c47bb 100644 --- a/ARKBreedingStats/Properties/Settings.Designer.cs +++ b/ARKBreedingStats/Properties/Settings.Designer.cs @@ -378,18 +378,6 @@ public bool inventoryCheckTimer { } } - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string LastImportFile { - get { - return ((string)(this["LastImportFile"])); - } - set { - this["LastImportFile"] = value; - } - } - [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] @@ -1319,12 +1307,24 @@ public bool applyNamePatternOnAutoImportForNewCreatures { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool AlreadyAskedToDownloadImageFiles { + public bool AlreadyAskedToDownloadImageFilesTropeognathus { + get { + return ((bool)(this["AlreadyAskedToDownloadImageFilesTropeognathus"])); + } + set { + this["AlreadyAskedToDownloadImageFilesTropeognathus"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool LibrarySelectSelectedSpeciesOnLoad { get { - return ((bool)(this["AlreadyAskedToDownloadImageFiles"])); + return ((bool)(this["LibrarySelectSelectedSpeciesOnLoad"])); } set { - this["AlreadyAskedToDownloadImageFiles"] = value; + this["LibrarySelectSelectedSpeciesOnLoad"] = value; } } } diff --git a/ARKBreedingStats/Properties/Settings.settings b/ARKBreedingStats/Properties/Settings.settings index 7ed599a5..5d0e0f77 100644 --- a/ARKBreedingStats/Properties/Settings.settings +++ b/ARKBreedingStats/Properties/Settings.settings @@ -92,9 +92,6 @@ True - - - True @@ -329,7 +326,10 @@ False - + + False + + False diff --git a/ARKBreedingStats/SpeciesSelector.Designer.cs b/ARKBreedingStats/SpeciesSelector.Designer.cs index 886166bb..8a91e422 100644 --- a/ARKBreedingStats/SpeciesSelector.Designer.cs +++ b/ARKBreedingStats/SpeciesSelector.Designer.cs @@ -172,7 +172,6 @@ private void InitializeComponent() this.lvSpeciesInLibrary.Size = new System.Drawing.Size(510, 208); this.lvSpeciesInLibrary.TabIndex = 4; this.lvSpeciesInLibrary.UseCompatibleStateImageBehavior = false; - this.lvSpeciesInLibrary.View = System.Windows.Forms.View.Tile; this.lvSpeciesInLibrary.SelectedIndexChanged += new System.EventHandler(this.lvSpeciesInLibrary_SelectedIndexChanged); // // splitContainer2 diff --git a/ARKBreedingStats/SpeciesSelector.cs b/ARKBreedingStats/SpeciesSelector.cs index a048282a..26cd8751 100644 --- a/ARKBreedingStats/SpeciesSelector.cs +++ b/ARKBreedingStats/SpeciesSelector.cs @@ -2,6 +2,7 @@ using ARKBreedingStats.values; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; @@ -26,45 +27,26 @@ public partial class SpeciesSelector : UserControl /// /// Items for the species list. /// - private List entryList; + private List _entryList; /// /// The TextBox control for the species searching which is outside of this control. /// - private uiControls.TextBoxSuggest textbox; + private uiControls.TextBoxSuggest _textBox; /// - /// List of species-blueprintpaths last used by the user + /// List of species-blueprintPaths last used by the user /// - private List lastSpeciesBPs; - private readonly List iconIndices; - private CancellationTokenSource cancelSource; + private List _lastSpeciesBPs; + private List _iconIndices; + private CancellationTokenSource _cancelSource; public SpeciesSelector() { InitializeComponent(); - lastSpeciesBPs = new List(); - iconIndices = new List(); + _lastSpeciesBPs = new List(); + _iconIndices = new List(); SplitterDistance = Properties.Settings.Default.SpeciesSelectorVerticalSplitterDistance; - - // imageList - ImageList lImgList = new ImageList(); - if (Directory.Exists("img")) - { - string[] speciesImageFiles = Directory.GetFiles("img", "*.png", SearchOption.TopDirectoryOnly); - foreach (string icon in speciesImageFiles) - { - int i = icon.IndexOf("_"); - if (i == -1) - { - lImgList.Images.Add(Image.FromFile(icon)); - iconIndices.Add(Path.GetFileNameWithoutExtension(icon)); - } - } - - lImgList.ImageSize = new Size(64, 64); - lvLastSpecies.LargeImageList = lImgList; - } } /// @@ -73,24 +55,66 @@ public SpeciesSelector() /// /// public void SetSpeciesLists(List species, Dictionary aliases) + { + ImageList imageList; + (_entryList, imageList, _iconIndices) = LoadSpeciesImagesAndCreateSpeciesList(species, aliases); + + imageList.ImageSize = new Size(64, 64); + lvLastSpecies.LargeImageList = imageList; + lvSpeciesInLibrary.LargeImageList = imageList; + + // autocomplete for species-input + var al = new AutoCompleteStringCollection(); + al.AddRange(_entryList.Select(e => e.SearchName).ToArray()); + _textBox.AutoCompleteCustomSource = al; + + cbDisplayUntameable.Checked = Properties.Settings.Default.DisplayNonDomesticableSpecies; + FilterList(); + } + + private static (List, ImageList, List) LoadSpeciesImagesAndCreateSpeciesList(List species, Dictionary aliases) { Dictionary speciesNameToSpecies = new Dictionary(); + var creatureColors = new int[] + {44, 42, 57, 10, 26, 78}; // uniform color pattern that is used for all species in the selector + var creatureColorsPolar = new int[] + {18, 18, 18, 18, 18, 18}; // uniform color pattern that is used for all polar species in the selector + ImageList lImgList = new ImageList(); + var iconIndices = new List(); + bool imageFolderExist = Directory.Exists(FileService.GetPath(FileService.ImageFolderName)); + + //var speciesWOImage = new List();// to determine which species have no image yet foreach (Species ss in species) { if (!speciesNameToSpecies.ContainsKey(ss.DescriptiveNameAndMod)) speciesNameToSpecies.Add(ss.DescriptiveNameAndMod, ss); + + if (imageFolderExist) + { + var (imgExists, imagePath, speciesListName) = CreatureColored.SpeciesImageExists(ss, + ss.name.Contains("Polar") ? creatureColorsPolar : creatureColors); + if (imgExists && !iconIndices.Contains(speciesListName)) + { + lImgList.Images.Add(Image.FromFile(imagePath)); + iconIndices.Add(speciesListName); + } + + //if (!imgExists && !speciesWOImage.Contains(ss.name)) speciesWOImage.Add(ss.name); + } } - entryList = new List(); + //Clipboard.SetText(string.Join("\n", speciesWOImage)); + + var entryList = new List(); foreach (var s in species) { entryList.Add(new SpeciesListEntry { - displayName = s.name, - searchName = s.name, - modName = s.Mod?.title ?? string.Empty, - species = s + DisplayName = s.name, + SearchName = s.name, + ModName = s.Mod?.title ?? string.Empty, + Species = s }); } @@ -100,23 +124,16 @@ public void SetSpeciesLists(List species, Dictionary al { entryList.Add(new SpeciesListEntry { - displayName = a.Key + " (→" + speciesNameToSpecies[a.Value].name + ")", - searchName = a.Key, - species = speciesNameToSpecies[a.Value], - modName = speciesNameToSpecies[a.Value].Mod?.title ?? string.Empty, + DisplayName = a.Key + " (→" + speciesNameToSpecies[a.Value].name + ")", + SearchName = a.Key, + Species = speciesNameToSpecies[a.Value], + ModName = speciesNameToSpecies[a.Value].Mod?.title ?? string.Empty, }); } } - entryList = entryList.OrderBy(s => s.displayName).ToList(); - - // autocomplete for species-input - var al = new AutoCompleteStringCollection(); - al.AddRange(entryList.Select(e => e.searchName).ToArray()); - textbox.AutoCompleteCustomSource = al; - - cbDisplayUntameable.Checked = Properties.Settings.Default.DisplayNonDomesticableSpecies; - FilterList(); + entryList = entryList.OrderBy(s => s.DisplayName).ToList(); + return (entryList, lImgList, iconIndices); } /// @@ -127,11 +144,17 @@ public void SetLibrarySpecies(List librarySpeciesList) { lvSpeciesInLibrary.Items.Clear(); foreach (Species s in librarySpeciesList) - lvSpeciesInLibrary.Items.Add(new ListViewItem + { + ListViewItem lvi = new ListViewItem { Text = s.DescriptiveNameAndMod, Tag = s - }); + }; + int ii = SpeciesImageIndex(s.name); + if (ii != -1) + lvi.ImageIndex = ii; + lvSpeciesInLibrary.Items.Add(lvi); + } } /// @@ -140,7 +163,7 @@ public void SetLibrarySpecies(List librarySpeciesList) private void UpdateLastSpecies() { lvLastSpecies.Items.Clear(); - foreach (string s in lastSpeciesBPs) + foreach (string s in _lastSpeciesBPs) { var species = Values.V.SpeciesByBlueprint(s); if (species != null) @@ -160,26 +183,26 @@ private void UpdateLastSpecies() private void FilterList(string part = null) { - if (entryList == null) return; + if (_entryList == null) return; lvSpeciesList.BeginUpdate(); lvSpeciesList.Items.Clear(); bool inputIsEmpty = string.IsNullOrWhiteSpace(part); - foreach (var s in entryList) + foreach (var s in _entryList) { - if ((Properties.Settings.Default.DisplayNonDomesticableSpecies || s.species.IsDomesticable) + if ((Properties.Settings.Default.DisplayNonDomesticableSpecies || s.Species.IsDomesticable) && (inputIsEmpty - || s.searchName.ToLower().Contains(part.ToLower()) + || s.SearchName.ToLower().Contains(part.ToLower()) ) ) { - lvSpeciesList.Items.Add(new ListViewItem(new[] { s.displayName, s.species.VariantInfo, s.species.IsDomesticable ? "✓" : string.Empty, s.modName }) + lvSpeciesList.Items.Add(new ListViewItem(new[] { s.DisplayName, s.Species.VariantInfo, s.Species.IsDomesticable ? "✓" : string.Empty, s.ModName }) { - Tag = s.species, - BackColor = !s.species.IsDomesticable ? Color.FromArgb(255, 245, 230) - : !string.IsNullOrEmpty(s.modName) ? Color.FromArgb(230, 245, 255) + Tag = s.Species, + BackColor = !s.Species.IsDomesticable ? Color.FromArgb(255, 245, 230) + : !string.IsNullOrEmpty(s.ModName) ? Color.FromArgb(230, 245, 255) : SystemColors.Window, - ToolTipText = s.species.blueprintPath, + ToolTipText = s.Species.blueprintPath, }); } } @@ -189,19 +212,19 @@ private void FilterList(string part = null) private void lvSpeciesList_SelectedIndexChanged(object sender, EventArgs e) { if (lvSpeciesList.SelectedItems.Count > 0) - SetSpecies((Species)lvSpeciesList.SelectedItems[0].Tag); + SetSpecies((Species)lvSpeciesList.SelectedItems[0].Tag, true); } private void lvOftenUsed_SelectedIndexChanged(object sender, EventArgs e) { if (lvLastSpecies.SelectedItems.Count > 0) - SetSpecies((Species)((ListViewItem)lvLastSpecies.SelectedItems[0]).Tag); + SetSpecies((Species)lvLastSpecies.SelectedItems[0].Tag, true); } private void lvSpeciesInLibrary_SelectedIndexChanged(object sender, EventArgs e) { if (lvSpeciesInLibrary.SelectedItems.Count > 0) - SetSpecies((Species)((ListViewItem)lvSpeciesInLibrary.SelectedItems[0]).Tag); + SetSpecies((Species)lvSpeciesInLibrary.SelectedItems[0].Tag, true); } /// @@ -216,15 +239,20 @@ public void SetSpeciesByName(string speciesName) } } - public void SetSpecies(Species species) + public void SetSpecies(Species species, bool alsoTriggerOnSameSpecies = false) { - if (species == null - || SelectedSpecies == species) return; + if (species == null) return; + if (SelectedSpecies == species) + { + if (alsoTriggerOnSameSpecies) + OnSpeciesSelected?.Invoke(false); + return; + } - lastSpeciesBPs.Remove(species.blueprintPath); - lastSpeciesBPs.Insert(0, species.blueprintPath); - if (lastSpeciesBPs.Count > Properties.Settings.Default.SpeciesSelectorCountLastSpecies) // only keep keepNrLastSpecies of the last species in this list - lastSpeciesBPs.RemoveRange(Properties.Settings.Default.SpeciesSelectorCountLastSpecies, lastSpeciesBPs.Count - Properties.Settings.Default.SpeciesSelectorCountLastSpecies); + _lastSpeciesBPs.Remove(species.blueprintPath); + _lastSpeciesBPs.Insert(0, species.blueprintPath); + if (_lastSpeciesBPs.Count > Properties.Settings.Default.SpeciesSelectorCountLastSpecies) // only keep keepNrLastSpecies of the last species in this list + _lastSpeciesBPs.RemoveRange(Properties.Settings.Default.SpeciesSelectorCountLastSpecies, _lastSpeciesBPs.Count - Properties.Settings.Default.SpeciesSelectorCountLastSpecies); UpdateLastSpecies(); SelectedSpecies = species; @@ -233,55 +261,55 @@ public void SetSpecies(Species species) public void SetTextBox(uiControls.TextBoxSuggest textbox) { - this.textbox = textbox; + this._textBox = textbox; textbox.TextChanged += Textbox_TextChanged; } private async void Textbox_TextChanged(object sender, EventArgs e) { - cancelSource?.Cancel(); - using (cancelSource = new CancellationTokenSource()) + _cancelSource?.Cancel(); + using (_cancelSource = new CancellationTokenSource()) { try { - await Task.Delay(200, cancelSource.Token); // give the textbox time to apply the selection for the appended text - FilterList(textbox.Text.Substring(0, textbox.SelectionStart)); + await Task.Delay(200, _cancelSource.Token); // give the textBox time to apply the selection for the appended text + FilterList(_textBox.Text.Substring(0, _textBox.SelectionStart)); } catch (TaskCanceledException) { return; } } - cancelSource = null; + _cancelSource = null; } public string[] LastSpecies { - get => lastSpeciesBPs.ToArray(); + get => _lastSpeciesBPs.ToArray(); set { if (value == null) - lastSpeciesBPs.Clear(); + _lastSpeciesBPs.Clear(); else { - lastSpeciesBPs = value.ToList(); + _lastSpeciesBPs = value.ToList(); UpdateLastSpecies(); } } } - private int SpeciesImageIndex(string speciesName = "") + private int SpeciesImageIndex(string speciesName = null) { if (string.IsNullOrWhiteSpace(speciesName)) speciesName = SelectedSpecies.name; else speciesName = Values.V.SpeciesName(speciesName); - if (speciesName.IndexOf("Aberrant ") != -1) - speciesName = speciesName.Substring(9); - return iconIndices.IndexOf(speciesName); + speciesName = CreatureColored.SpeciesImageName(speciesName, false); + return _iconIndices.IndexOf(speciesName); } - public Image SpeciesImage(string speciesName = "") + public Image SpeciesImage(string speciesName = null) { + if (lvLastSpecies.LargeImageList == null) return null; int ii = SpeciesImageIndex(speciesName); if (ii != -1 && ii < lvLastSpecies.LargeImageList.Images.Count) return lvLastSpecies.LargeImageList.Images[ii]; @@ -308,13 +336,10 @@ public int SplitterDistance class SpeciesListEntry { - internal string searchName; - internal string displayName; - internal string modName; - internal Species species; - public override string ToString() - { - return displayName; - } + internal string SearchName; + internal string DisplayName; + internal string ModName; + internal Species Species; + public override string ToString() => DisplayName; } } diff --git a/ARKBreedingStats/TamingControl.cs b/ARKBreedingStats/TamingControl.cs index a75dc15d..172e2d02 100644 --- a/ARKBreedingStats/TamingControl.cs +++ b/ARKBreedingStats/TamingControl.cs @@ -305,7 +305,7 @@ private void NoTamingData() labelResult.Text = Loc.S("noTamingData"); lbTimeUntilStarving.Text = Loc.S("noTamingData"); - // disable enture (i)? tab + // disable entire tab this.Enabled = false; } diff --git a/ARKBreedingStats/Updater.cs b/ARKBreedingStats/Updater.cs index 03b26481..3db9c93d 100644 --- a/ARKBreedingStats/Updater.cs +++ b/ARKBreedingStats/Updater.cs @@ -313,7 +313,7 @@ private static bool Download(string url, string outFileName) /// internal static async Task<(bool, string)> DownloadSpeciesImages(bool overwrite) { - string imagesFolderPath = FileService.GetPath("img"); + string imagesFolderPath = FileService.GetPath(FileService.ImageFolderName); string url = MasterRawUrl + "/" + SpeciesColorRegionZipFileName; string tempFilePath = Path.GetTempFileName(); var (downloaded, _) = await DownloadAsync(url, tempFilePath); diff --git a/ARKBreedingStats/Utils.cs b/ARKBreedingStats/Utils.cs index da04f4e1..92333711 100644 --- a/ARKBreedingStats/Utils.cs +++ b/ARKBreedingStats/Utils.cs @@ -2,7 +2,6 @@ using ARKBreedingStats.species; using System; using System.Drawing; -using System.Globalization; using System.Threading.Tasks; using System.Windows.Forms; @@ -19,7 +18,7 @@ static class Utils /// the calculated color. public static Color GetColorFromPercent(int percent, double light = 0, bool blue = false) { - GetRGBFromPercent(out int r, out int g, out int b, percent, light); + GetRgbFromPercent(out int r, out int g, out int b, percent, light); return blue ? Color.FromArgb(b, g, r) : Color.FromArgb(r, g, b); } @@ -32,7 +31,7 @@ public static Color GetColorFromPercent(int percent, double light = 0, bool blue /// public static string GetARKmlFromPercent(string text, int percent, double light = 0) { - GetRGBFromPercent(out int r, out int g, out int b, percent, light); + GetRgbFromPercent(out int r, out int g, out int b, percent, light); return GetARKml(text, r, g, b); } @@ -46,7 +45,8 @@ public static string GetARKmlFromPercent(string text, int percent, double light /// public static string GetARKml(string text, int r, int g, int b) { - return "" + text + ""; + return + $"{text}"; } /// @@ -57,7 +57,7 @@ public static string GetARKml(string text, int r, int g, int b) /// /// /// - private static void GetRGBFromPercent(out int r, out int g, out int b, int percent, double light = 0) + private static void GetRgbFromPercent(out int r, out int g, out int b, int percent, double light = 0) { if (light > 1) { light = 1; } if (light < -1) { light = -1; } @@ -212,13 +212,13 @@ public static string LevelPercentile(int level) return string.Format(Loc.S("topPercentileLevel"), prb[level].ToString("N2")); } - private static string[] statNames, statNamesAbb, statNamesAberrant, statNamesAberrantAbb; + private static string[] _statNames, _statNamesAbb, _statNamesAberrant, _statNamesAberrantAbb; public static void InitializeLocalizations() { - statNames = new[] { Loc.S("Health"), Loc.S("Stamina"), Loc.S("Torpidity"), Loc.S("Oxygen"), Loc.S("Food"), Loc.S("Water"), Loc.S("Temperature"), Loc.S("Weight"), Loc.S("Damage"), Loc.S("Speed"), Loc.S("Fortitude"), Loc.S("CraftingSpeed") }; - statNamesAbb = new[] { Loc.S("Health_Abb"), Loc.S("Stamina_Abb"), Loc.S("Torpidity_Abb"), Loc.S("Oxygen_Abb"), Loc.S("Food_Abb"), Loc.S("Water_Abb"), Loc.S("Temperature_Abb"), Loc.S("Weight_Abb"), Loc.S("Damage_Abb"), Loc.S("Speed_Abb"), Loc.S("Fortitude_Abb"), Loc.S("CraftingSpeed_Abb") }; - statNamesAberrant = new[] { Loc.S("Health"), Loc.S("ChargeCapacity"), Loc.S("Torpidity"), Loc.S("ChargeRegeneration"), Loc.S("Food"), Loc.S("Water"), Loc.S("Temperature"), Loc.S("Weight"), Loc.S("ChargeEmissionRange"), Loc.S("Speed"), Loc.S("Fortitude"), Loc.S("CraftingSpeed") }; - statNamesAberrantAbb = new[] { Loc.S("Health_Abb"), Loc.S("ChargeCapacity_Abb"), Loc.S("Torpidity_Abb"), Loc.S("ChargeRegeneration_Abb"), Loc.S("Food_Abb"), Loc.S("Water_Abb"), Loc.S("Temperature_Abb"), Loc.S("Weight_Abb"), Loc.S("ChargeEmissionRange_Abb"), Loc.S("Speed_Abb"), Loc.S("Fortitude_Abb"), Loc.S("CraftingSpeed_Abb") }; + _statNames = new[] { Loc.S("Health"), Loc.S("Stamina"), Loc.S("Torpidity"), Loc.S("Oxygen"), Loc.S("Food"), Loc.S("Water"), Loc.S("Temperature"), Loc.S("Weight"), Loc.S("Damage"), Loc.S("Speed"), Loc.S("Fortitude"), Loc.S("CraftingSpeed") }; + _statNamesAbb = new[] { Loc.S("Health_Abb"), Loc.S("Stamina_Abb"), Loc.S("Torpidity_Abb"), Loc.S("Oxygen_Abb"), Loc.S("Food_Abb"), Loc.S("Water_Abb"), Loc.S("Temperature_Abb"), Loc.S("Weight_Abb"), Loc.S("Damage_Abb"), Loc.S("Speed_Abb"), Loc.S("Fortitude_Abb"), Loc.S("CraftingSpeed_Abb") }; + _statNamesAberrant = new[] { Loc.S("Health"), Loc.S("ChargeCapacity"), Loc.S("Torpidity"), Loc.S("ChargeRegeneration"), Loc.S("Food"), Loc.S("Water"), Loc.S("Temperature"), Loc.S("Weight"), Loc.S("ChargeEmissionRange"), Loc.S("Speed"), Loc.S("Fortitude"), Loc.S("CraftingSpeed") }; + _statNamesAberrantAbb = new[] { Loc.S("Health_Abb"), Loc.S("ChargeCapacity_Abb"), Loc.S("Torpidity_Abb"), Loc.S("ChargeRegeneration_Abb"), Loc.S("Food_Abb"), Loc.S("Water_Abb"), Loc.S("Temperature_Abb"), Loc.S("Weight_Abb"), Loc.S("ChargeEmissionRange_Abb"), Loc.S("Speed_Abb"), Loc.S("Fortitude_Abb"), Loc.S("CraftingSpeed_Abb") }; } /// @@ -230,16 +230,16 @@ public static void InitializeLocalizations() /// public static string StatName(int statIndex, bool abbreviation = false, bool glowSpecies = false) { - if (statNames == null || statIndex < 0 || statIndex >= statNames.Length) - return ""; + if (_statNames == null || statIndex < 0 || statIndex >= _statNames.Length) + return string.Empty; if (glowSpecies) { - return abbreviation ? statNamesAberrantAbb[statIndex] : statNamesAberrant[statIndex]; + return abbreviation ? _statNamesAberrantAbb[statIndex] : _statNamesAberrant[statIndex]; } - return abbreviation ? statNamesAbb[statIndex] : statNames[statIndex]; + return abbreviation ? _statNamesAbb[statIndex] : _statNames[statIndex]; } - public static string StatName(species.StatNames sn, bool abbreviation = false, bool glowSpecies = false) + public static string StatName(StatNames sn, bool abbreviation = false, bool glowSpecies = false) { return StatName((int)sn, abbreviation, glowSpecies); } @@ -341,15 +341,15 @@ public static bool ShowTextInput(string text, out string input, string title = " }; Label textLabel = new Label { Left = 20, Top = 15, Text = text, AutoSize = true }; TextBox textBox = new TextBox { Left = 20, Top = 40, Width = 200 }; - Button buttonOK = new Button { Text = Loc.S("OK"), Left = 120, Width = 100, Top = 70, DialogResult = DialogResult.OK }; + Button buttonOk = new Button { Text = Loc.S("OK"), Left = 120, Width = 100, Top = 70, DialogResult = DialogResult.OK }; Button buttonCancel = new Button { Text = Loc.S("Cancel"), Left = 20, Width = 80, Top = 70, DialogResult = DialogResult.Cancel }; - buttonOK.Click += (sender, e) => { inputForm.Close(); }; + buttonOk.Click += (sender, e) => { inputForm.Close(); }; buttonCancel.Click += (sender, e) => { inputForm.Close(); }; inputForm.Controls.Add(textBox); - inputForm.Controls.Add(buttonOK); + inputForm.Controls.Add(buttonOk); inputForm.Controls.Add(buttonCancel); inputForm.Controls.Add(textLabel); - inputForm.AcceptButton = buttonOK; + inputForm.AcceptButton = buttonOk; inputForm.CancelButton = buttonCancel; textBox.Text = preInput; textBox.SelectAll(); @@ -428,7 +428,6 @@ public static bool GetFirstImportExportFolder(out string folder) /// /// Changes the color of a control briefly. /// - /// public static async void BlinkAsync(Control ctlr, Color c, int duration = 500, bool foreColor = true) { if (foreColor) @@ -490,7 +489,7 @@ public static void BeepSignal(int kind) Console.Beep(400, 50); Console.Beep(500, 50); Console.Beep(600, 50); - Console.Beep(650, 50); + Console.Beep(675, 50); Console.Beep(600, 100); break; } diff --git a/ARKBreedingStats/library/CreatureCollection.cs b/ARKBreedingStats/library/CreatureCollection.cs index 0a1a3f9b..4f3c6597 100644 --- a/ARKBreedingStats/library/CreatureCollection.cs +++ b/ARKBreedingStats/library/CreatureCollection.cs @@ -163,7 +163,7 @@ public bool MergeCreatureList(List creaturesToMerge, bool addPreviousl var creatureExisting = creatures.Single(c => c.guid == creatureNew.guid); if (creatureExisting.Species == null) creatureExisting.Species = creatureNew.Species; - else if (!creatureExisting.Species.Equals(creatureNew.Species)) continue; + else if (creatureExisting.speciesBlueprint != creatureNew.speciesBlueprint) continue; if (creatureNew.Mother != null) creatureExisting.Mother = creatureNew.Mother; diff --git a/ARKBreedingStats/settings/Settings.Designer.cs b/ARKBreedingStats/settings/Settings.Designer.cs index a7d5891a..b3d3c86d 100644 --- a/ARKBreedingStats/settings/Settings.Designer.cs +++ b/ARKBreedingStats/settings/Settings.Designer.cs @@ -194,6 +194,7 @@ private void InitializeComponent() this.label28 = new System.Windows.Forms.Label(); this.cbAutoImportExported = new System.Windows.Forms.CheckBox(); this.groupBox21 = new System.Windows.Forms.GroupBox(); + this.cbApplyNamePatternOnImportOnNewCreatures = new System.Windows.Forms.CheckBox(); this.label41 = new System.Windows.Forms.Label(); this.cbCopyPatternNameToClipboard = new System.Windows.Forms.CheckBox(); this.cbApplyNamePatternOnImportOnEmptyNames = new System.Windows.Forms.CheckBox(); @@ -224,7 +225,7 @@ private void InitializeComponent() this.cbbOCRApp = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); - this.cbApplyNamePatternOnImportOnNewCreatures = new System.Windows.Forms.CheckBox(); + this.CbLibrarySelectSelectedSpeciesOnLoad = new System.Windows.Forms.CheckBox(); this.groupBoxMultiplier.SuspendLayout(); this.groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudMatingSpeed)).BeginInit(); @@ -1538,7 +1539,7 @@ private void InitializeComponent() this.groupBox24.Controls.Add(this.cbKeepExpiredTimersInOverlay); this.groupBox24.Controls.Add(this.cbDeleteExpiredTimersOnSaving); this.groupBox24.Controls.Add(this.cbTimersInOverlayAutomatically); - this.groupBox24.Location = new System.Drawing.Point(6, 470); + this.groupBox24.Location = new System.Drawing.Point(6, 516); this.groupBox24.Name = "groupBox24"; this.groupBox24.Size = new System.Drawing.Size(317, 94); this.groupBox24.TabIndex = 11; @@ -1598,7 +1599,7 @@ private void InitializeComponent() // groupBox17 // this.groupBox17.Controls.Add(this.cbbLanguage); - this.groupBox17.Location = new System.Drawing.Point(6, 570); + this.groupBox17.Location = new System.Drawing.Point(6, 616); this.groupBox17.Name = "groupBox17"; this.groupBox17.Size = new System.Drawing.Size(317, 51); this.groupBox17.TabIndex = 9; @@ -1636,12 +1637,13 @@ private void InitializeComponent() // // groupBox9 // + this.groupBox9.Controls.Add(this.CbLibrarySelectSelectedSpeciesOnLoad); this.groupBox9.Controls.Add(this.cbLibraryHighlightTopCreatures); this.groupBox9.Controls.Add(this.cbApplyGlobalSpeciesToLibrary); this.groupBox9.Controls.Add(this.cbCreatureColorsLibrary); this.groupBox9.Location = new System.Drawing.Point(6, 373); this.groupBox9.Name = "groupBox9"; - this.groupBox9.Size = new System.Drawing.Size(317, 91); + this.groupBox9.Size = new System.Drawing.Size(317, 137); this.groupBox9.TabIndex = 7; this.groupBox9.TabStop = false; this.groupBox9.Text = "Library"; @@ -1649,7 +1651,7 @@ private void InitializeComponent() // cbLibraryHighlightTopCreatures // this.cbLibraryHighlightTopCreatures.AutoSize = true; - this.cbLibraryHighlightTopCreatures.Location = new System.Drawing.Point(6, 65); + this.cbLibraryHighlightTopCreatures.Location = new System.Drawing.Point(6, 88); this.cbLibraryHighlightTopCreatures.Name = "cbLibraryHighlightTopCreatures"; this.cbLibraryHighlightTopCreatures.Size = new System.Drawing.Size(136, 17); this.cbLibraryHighlightTopCreatures.TabIndex = 2; @@ -2003,7 +2005,7 @@ private void InitializeComponent() this.customSCCustom.Location = new System.Drawing.Point(6, 139); this.customSCCustom.Name = "customSCCustom"; this.customSCCustom.Size = new System.Drawing.Size(401, 23); - this.customSCCustom.SoundFile = ""; + this.customSCCustom.SoundFile = null; this.customSCCustom.TabIndex = 7; // // customSCWakeup @@ -2011,7 +2013,7 @@ private void InitializeComponent() this.customSCWakeup.Location = new System.Drawing.Point(6, 81); this.customSCWakeup.Name = "customSCWakeup"; this.customSCWakeup.Size = new System.Drawing.Size(401, 23); - this.customSCWakeup.SoundFile = null; + this.customSCWakeup.SoundFile = ""; this.customSCWakeup.TabIndex = 6; // // customSCBirth @@ -2019,7 +2021,7 @@ private void InitializeComponent() this.customSCBirth.Location = new System.Drawing.Point(6, 110); this.customSCBirth.Name = "customSCBirth"; this.customSCBirth.Size = new System.Drawing.Size(401, 23); - this.customSCBirth.SoundFile = null; + this.customSCBirth.SoundFile = ""; this.customSCBirth.TabIndex = 5; // // customSCStarving @@ -2027,7 +2029,7 @@ private void InitializeComponent() this.customSCStarving.Location = new System.Drawing.Point(6, 52); this.customSCStarving.Name = "customSCStarving"; this.customSCStarving.Size = new System.Drawing.Size(401, 23); - this.customSCStarving.SoundFile = ""; + this.customSCStarving.SoundFile = null; this.customSCStarving.TabIndex = 4; // // label20 @@ -2392,6 +2394,16 @@ private void InitializeComponent() this.groupBox21.TabStop = false; this.groupBox21.Text = "Auto naming on import"; // + // cbApplyNamePatternOnImportOnNewCreatures + // + this.cbApplyNamePatternOnImportOnNewCreatures.AutoSize = true; + this.cbApplyNamePatternOnImportOnNewCreatures.Location = new System.Drawing.Point(6, 61); + this.cbApplyNamePatternOnImportOnNewCreatures.Name = "cbApplyNamePatternOnImportOnNewCreatures"; + this.cbApplyNamePatternOnImportOnNewCreatures.Size = new System.Drawing.Size(203, 17); + this.cbApplyNamePatternOnImportOnNewCreatures.TabIndex = 12; + this.cbApplyNamePatternOnImportOnNewCreatures.Text = "if the creature is imported the first time"; + this.cbApplyNamePatternOnImportOnNewCreatures.UseVisualStyleBackColor = true; + // // label41 // this.label41.AutoSize = true; @@ -2708,15 +2720,15 @@ private void InitializeComponent() this.panel1.Size = new System.Drawing.Size(758, 30); this.panel1.TabIndex = 12; // - // cbApplyNamePatternOnImportOnNewCreatures + // CbLibrarySelectSelectedSpeciesOnLoad // - this.cbApplyNamePatternOnImportOnNewCreatures.AutoSize = true; - this.cbApplyNamePatternOnImportOnNewCreatures.Location = new System.Drawing.Point(6, 61); - this.cbApplyNamePatternOnImportOnNewCreatures.Name = "cbApplyNamePatternOnImportOnNewCreatures"; - this.cbApplyNamePatternOnImportOnNewCreatures.Size = new System.Drawing.Size(203, 17); - this.cbApplyNamePatternOnImportOnNewCreatures.TabIndex = 12; - this.cbApplyNamePatternOnImportOnNewCreatures.Text = "if the creature is imported the first time"; - this.cbApplyNamePatternOnImportOnNewCreatures.UseVisualStyleBackColor = true; + this.CbLibrarySelectSelectedSpeciesOnLoad.AutoSize = true; + this.CbLibrarySelectSelectedSpeciesOnLoad.Location = new System.Drawing.Point(6, 65); + this.CbLibrarySelectSelectedSpeciesOnLoad.Name = "CbLibrarySelectSelectedSpeciesOnLoad"; + this.CbLibrarySelectSelectedSpeciesOnLoad.Size = new System.Drawing.Size(202, 17); + this.CbLibrarySelectSelectedSpeciesOnLoad.TabIndex = 3; + this.CbLibrarySelectSelectedSpeciesOnLoad.Text = "Select currently used species on load"; + this.CbLibrarySelectSelectedSpeciesOnLoad.UseVisualStyleBackColor = true; // // Settings // @@ -3037,5 +3049,6 @@ private void InitializeComponent() private System.Windows.Forms.Label LbSpeciesSelectorCountLastUsed; private uiControls.Nud NudSpeciesSelectorCountLastUsed; private System.Windows.Forms.CheckBox cbApplyNamePatternOnImportOnNewCreatures; + private System.Windows.Forms.CheckBox CbLibrarySelectSelectedSpeciesOnLoad; } } \ No newline at end of file diff --git a/ARKBreedingStats/settings/Settings.cs b/ARKBreedingStats/settings/Settings.cs index cc670f8c..ccce77e6 100644 --- a/ARKBreedingStats/settings/Settings.cs +++ b/ARKBreedingStats/settings/Settings.cs @@ -235,6 +235,7 @@ private void LoadSettings(CreatureCollection cc) #region library cbCreatureColorsLibrary.Checked = Properties.Settings.Default.showColorsInLibrary; cbApplyGlobalSpeciesToLibrary.Checked = Properties.Settings.Default.ApplyGlobalSpeciesToLibrary; + CbLibrarySelectSelectedSpeciesOnLoad.Checked = Properties.Settings.Default.LibrarySelectSelectedSpeciesOnLoad; cbLibraryHighlightTopCreatures.Checked = Properties.Settings.Default.LibraryHighlightTopCreatures; #endregion @@ -390,6 +391,7 @@ private void SaveSettings() #region library Properties.Settings.Default.showColorsInLibrary = cbCreatureColorsLibrary.Checked; Properties.Settings.Default.ApplyGlobalSpeciesToLibrary = cbApplyGlobalSpeciesToLibrary.Checked; + Properties.Settings.Default.LibrarySelectSelectedSpeciesOnLoad = CbLibrarySelectSelectedSpeciesOnLoad.Checked; Properties.Settings.Default.LibraryHighlightTopCreatures = cbLibraryHighlightTopCreatures.Checked; #endregion diff --git a/ARKBreedingStats/settings/Settings.resx b/ARKBreedingStats/settings/Settings.resx index a5cb1c68..8e18cb83 100644 --- a/ARKBreedingStats/settings/Settings.resx +++ b/ARKBreedingStats/settings/Settings.resx @@ -126,6 +126,15 @@ 17, 17 + + True + + + True + + + 17, 17 + The creature data can be imported from the save-game, if it is available. If you set the according files below, you can start the process automatically from the file-menu. Make sure the folders are correct. @@ -139,6 +148,15 @@ If you set the according files below, you can start the process automatically fr 262, 17 + + True + + + True + + + 262, 17 + In ARK you can export a creature (hold use while looking at a creature, then choose "Options" - "Export" from the wheel). diff --git a/img.zip b/img.zip index 2e4ca58f..aecf5b96 100644 Binary files a/img.zip and b/img.zip differ