diff --git a/ARKBreedingStats/ARKBreedingStats.csproj b/ARKBreedingStats/ARKBreedingStats.csproj index 3e17757fb..9876bbd05 100644 --- a/ARKBreedingStats/ARKBreedingStats.csproj +++ b/ARKBreedingStats/ARKBreedingStats.csproj @@ -62,6 +62,7 @@ + @@ -82,6 +83,7 @@ AboutBox1.cs + @@ -245,7 +247,6 @@ StatsMultiplierTesting.cs - @@ -963,7 +964,7 @@ - 44.0.1 + 48.0.3 3.3.4 @@ -971,7 +972,7 @@ all - 13.0.2 + 13.0.3 diff --git a/ARKBreedingStats/ARKOverlay.cs b/ARKBreedingStats/ARKOverlay.cs index 784d9876e..210aeac7b 100644 --- a/ARKBreedingStats/ARKOverlay.cs +++ b/ARKBreedingStats/ARKOverlay.cs @@ -190,9 +190,9 @@ private void SetTimerAndNotesText() { var sb = new StringBuilder(); + var timerListChanged = false; if (timers?.Any() ?? false) { - var timerListChanged = false; foreach (TimerListEntry tle in timers) { var timeLeft = tle.time.Subtract(DateTime.Now); @@ -216,6 +216,7 @@ private void SetTimerAndNotesText() { sb.AppendLine(); sb.AppendLine(Loc.S("Incubation")); + timerListChanged = false; foreach (var it in IncubationTimers) { var timeLeft = it.incubationEnd.Subtract(DateTime.Now); @@ -225,6 +226,7 @@ private void SetTimerAndNotesText() if (!Properties.Settings.Default.KeepExpiredTimersInOverlay && secLeft < -20) { it.ShowInOverlay = false; + timerListChanged = true; RemoveTimer(it); continue; } @@ -232,11 +234,14 @@ private void SetTimerAndNotesText() } sb.AppendLine($"{Utils.Duration(timeLeft)} : {(it.Mother?.Species ?? it.Father?.Species)?.DescriptiveName ?? "unknown species"}"); } + if (timerListChanged) + IncubationTimers = IncubationTimers.Where(it => it.ShowInOverlay).ToList(); } if (CreatureTimers?.Any() ?? false) { sb.AppendLine(); sb.AppendLine(Loc.S("Maturation")); + timerListChanged = false; foreach (var c in CreatureTimers) { var timeLeft = c.growingUntil?.Subtract(DateTime.Now); @@ -246,7 +251,7 @@ private void SetTimerAndNotesText() if (!Properties.Settings.Default.KeepExpiredTimersInOverlay && secLeft < -20) { c.ShowInOverlay = false; - RemoveTimer(c); + timerListChanged = true; continue; } @@ -254,6 +259,8 @@ private void SetTimerAndNotesText() } sb.AppendLine($"{(timeLeft == null ? "grown" : Utils.Duration(timeLeft.Value))} : {c.name} ({c.Species.DescriptiveName})"); } + if (timerListChanged) + CreatureTimers = CreatureTimers.Where(c => c.ShowInOverlay).ToList(); } sb.Append(_notes); labelTimer.Text = sb.ToString(); diff --git a/ARKBreedingStats/App.config b/ARKBreedingStats/App.config index 574e253b9..e132a5906 100644 --- a/ARKBreedingStats/App.config +++ b/ARKBreedingStats/App.config @@ -505,6 +505,9 @@ True + + + diff --git a/ARKBreedingStats/Ark.cs b/ARKBreedingStats/Ark.cs index 84507fef2..70dc623ea 100644 --- a/ARKBreedingStats/Ark.cs +++ b/ARKBreedingStats/Ark.cs @@ -188,5 +188,23 @@ public static class Stats CraftingSpeedMultiplier, Torpidity }; + + /// + /// Returns the stat indices for the stats usually displayed for species (e.g. no crafting speed Gacha) in game. + /// + public static readonly bool[] UsuallyVisibleStats = { + true, //Health, + true, //Stamina, + true, //Torpidity, + true, //Oxygen, + true, //Food, + false, //Water, + false, //Temperature, + true, //Weight, + true, //MeleeDamageMultiplier, + true, //SpeedMultiplier, + false, //TemperatureFortitude, + false, //CraftingSpeedMultiplier + }; } } diff --git a/ARKBreedingStats/AsbServer/Connection.cs b/ARKBreedingStats/AsbServer/Connection.cs new file mode 100644 index 000000000..cee24de1c --- /dev/null +++ b/ARKBreedingStats/AsbServer/Connection.cs @@ -0,0 +1,237 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; +using ARKBreedingStats.importExportGun; +using ARKBreedingStats.Library; +using Newtonsoft.Json.Linq; + +namespace ARKBreedingStats.AsbServer +{ + /// + /// Connects to a server to receive creature data, e.g. sent by the export gun mod. + /// + internal static class Connection + { + private const string ApiUri = "https://export.arkbreeder.com/api/v1/"; + + private static SimpleCancellationToken _lastCancellationToken; + + public static async void StartListeningAsync( + IProgress<(string jsonText, string serverHash, string message)> progressDataSent, string token = null) + { + if (string.IsNullOrEmpty(token)) return; + + // stop previous listening if any + StopListening(); + var cancellationToken = new SimpleCancellationToken(); + _lastCancellationToken = cancellationToken; + + var requestUri = ApiUri + "listen/" + token; // "https://httpstat.us/429"; + + try + { + using (var client = new HttpClient()) + using (var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead)) + { + if (!response.IsSuccessStatusCode) + { + var statusCode = (int)response.StatusCode; + string serverMessage = await response.Content.ReadAsStringAsync(); + + try + { + serverMessage = JObject.Parse(serverMessage).SelectToken("error.message").ToString(); + } + catch + { + // server message in unknown format, use raw content string + } + + serverMessage = Environment.NewLine + serverMessage; + + switch (statusCode) + { + case 400: // Bad Request + WriteMessage($"Something went wrong with the server connection.{serverMessage}", response); + return; + case 429: // Too Many Requests + WriteMessage($"The server is currently at the rate limit and cannot process the request. Try again later.{serverMessage}", response); + return; + case 507: // Insufficient Storage + WriteMessage($"Too many connections to the server. Try again later.{serverMessage}", response); + return; + default: + var errorMessage = statusCode >= 500 + ? "Something went wrong with the server or its proxy." + Environment.NewLine + : null; + WriteMessage($"{errorMessage}{serverMessage}", response); + return; + } + } + + using (var stream = await response.Content.ReadAsStreamAsync()) + using (var reader = new StreamReader(stream)) + { + await ReadServerSentEvents(reader, progressDataSent, token, cancellationToken); + } + } + } + catch (Exception ex) + { + WriteMessage($"ASB Server listening exception:\n{ex.Message}\n\nStack trace:\n{ex.StackTrace}"); + } + finally + { +#if DEBUG + Console.WriteLine($"ASB Server listening stopped using token: {token}"); +#endif + } + + return; + + // Displays an error message in the UI, also logs on the console if in debug mode + void WriteMessage(string message, HttpResponseMessage response = null) + { + if (response != null) + { + message = $"{(int)response.StatusCode}: {response.ReasonPhrase}{Environment.NewLine}{message}"; + } +#if DEBUG + Console.WriteLine(message); +#endif + progressDataSent.Report((null, null, message)); + } + } + + private static Regex _eventRegex = new Regex(@"^event: (welcome|ping|replaced|export|server|closing)(?: (\-?\d+))?(?:\ndata:\s(.+))?$"); + + private static async Task ReadServerSentEvents(StreamReader reader, IProgress<(string jsonText, string serverHash, string message)> progressDataSent, string token, SimpleCancellationToken cancellationToken) + { +#if DEBUG + Console.WriteLine($"Now listening using token: {token}"); +#endif + while (!cancellationToken.IsCancellationRequested) + { + var received = await reader.ReadLineAsync(); + if (string.IsNullOrEmpty(received)) + continue; // empty line marks end of event + +#if DEBUG + Console.WriteLine($"{received} (token: {token})"); +#endif + switch (received) + { + case "event: welcome": + continue; + case "event: ping": + continue; + case "event: replaced": + if (!cancellationToken.IsCancellationRequested) + progressDataSent.Report((null, null, + "ASB Server listening stopped. Connection used by a different user")); + return; + case "event: closing": + // only report closing if the user hasn't done this already + if (!cancellationToken.IsCancellationRequested) + progressDataSent.Report((null, null, + "ASB Server listening stopped. Connection closed by the server")); + return; + } + + if (received != "event: export" && !received.StartsWith("event: server")) + { + Console.WriteLine($"unknown server event: {received}"); + continue; + } + + received += "\n" + await reader.ReadLineAsync(); + if (cancellationToken.IsCancellationRequested) + break; + var m = _eventRegex.Match(received); + if (m.Success) + { + switch (m.Groups[1].Value) + { + case "export": + progressDataSent.Report((m.Groups[3].Value, null, null)); + break; + case "server": + progressDataSent.Report((m.Groups[3].Value, m.Groups[2].Value, null)); + break; + } + } + } + } + + public static void StopListening() + { + if (_lastCancellationToken == null) + return; // nothing to stop + + _lastCancellationToken.Cancel(); + _lastCancellationToken = null; + } + + /// + /// Sends creature data to the server, this is done for testing, usually other tools like the export gun mod do this. + /// + public static async void SendCreatureData(Creature creature, string token) + { + if (creature == null || string.IsNullOrEmpty(token)) return; + + using (var client = new HttpClient()) + { + var contentString = Newtonsoft.Json.JsonConvert.SerializeObject(ImportExportGun.ConvertCreatureToExportGunFile(creature, out _)); + var msg = new HttpRequestMessage(HttpMethod.Put, ApiUri + "export/" + token); + msg.Content = new StringContent(contentString, Encoding.UTF8, "application/json"); + msg.Content.Headers.Add("Content-Length", contentString.Length.ToString()); + var response = await client.SendAsync(msg); + Console.WriteLine($"Sent creature data of {creature} using token: {token}\nContent:\n{contentString}"); + Console.WriteLine(msg.ToString()); + Console.WriteLine($"Response: Status: {(int)response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}"); + } + } + + public static string CreateNewToken() + { + var allowedCharacters = Enumerable.Range(0x31, 9) // 1-9 + .Concat(Enumerable.Range(0x61, 8)) // a-h + .Concat(new[] { 0x6b, 0x6d, 0x6e }) // k, m, n + .Concat(Enumerable.Range(0x70, 11)) // p-z + .Select(i => (char)i) + .ToArray(); + var l = allowedCharacters.Length; + + var guid = Guid.NewGuid().ToByteArray(); + const int tokenLength = 14; // from these each 5th character is a dash for readability + var token = new char[tokenLength]; + for (var i = 0; i < tokenLength; i++) + { + if ((i + 1) % 5 == 0) + { + token[i] = '-'; + continue; + } + token[i] = allowedCharacters[guid[i] % l]; + } + + return new string(token); + } + + /// + /// Simple replacement of CancellationTokenSource to avoid unnecessary complexities with disposal of CTS when the token is still in use. + /// + private class SimpleCancellationToken + { + public bool IsCancellationRequested; + public void Cancel() => IsCancellationRequested = true; + } + } +} diff --git a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs index 76c71ee19..bdb553126 100644 --- a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs +++ b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs @@ -830,8 +830,8 @@ private void SetParents(int comboIndex) } int? levelStep = CreatureCollection.getWildLevelStep(); - Creature crB = new Creature(_currentSpecies, string.Empty, levelsWild: new int[Stats.StatsCount], isBred: true, levelStep: levelStep); - Creature crW = new Creature(_currentSpecies, string.Empty, levelsWild: new int[Stats.StatsCount], isBred: true, levelStep: levelStep); + Creature crB = new Creature(_currentSpecies, string.Empty, levelsWild: new int[Stats.StatsCount], levelsMutated: new int[Stats.StatsCount], isBred: true, levelStep: levelStep); + Creature crW = new Creature(_currentSpecies, string.Empty, levelsWild: new int[Stats.StatsCount], levelsMutated: new int[Stats.StatsCount], isBred: true, levelStep: levelStep); Creature mother = _breedingPairs[comboIndex].Mother; Creature father = _breedingPairs[comboIndex].Father; crB.Mother = mother; @@ -845,10 +845,12 @@ private void SetParents(int comboIndex) { if (s == Stats.Torpidity) continue; crB.levelsWild[s] = _statWeights[s] < 0 ? Math.Min(mother.levelsWild[s], father.levelsWild[s]) : BreedingScore.GetHigherBestLevel(mother.levelsWild[s], father.levelsWild[s], _statOddEvens[s]); - crB.valuesBreeding[s] = StatValueCalculation.CalculateValue(_currentSpecies, s, crB.levelsWild[s], 0, true, 1, 0); + crB.levelsMutated[s] = (crB.levelsWild[s] == mother.levelsWild[s] ? mother : father).levelsMutated?[s] ?? 0; + crB.valuesBreeding[s] = StatValueCalculation.CalculateValue(_currentSpecies, s, crB.levelsWild[s], crB.levelsMutated[s], 0, true, 1, 0); crB.topBreedingStats[s] = (_currentSpecies.stats[s].IncPerTamedLevel != 0 && crB.levelsWild[s] == _bestLevels[s]); crW.levelsWild[s] = _statWeights[s] < 0 ? Math.Max(mother.levelsWild[s], father.levelsWild[s]) : Math.Min(mother.levelsWild[s], father.levelsWild[s]); - crW.valuesBreeding[s] = StatValueCalculation.CalculateValue(_currentSpecies, s, crW.levelsWild[s], 0, true, 1, 0); + crB.levelsMutated[s] = (crW.levelsWild[s] == mother.levelsWild[s] ? mother : father).levelsMutated?[s] ?? 0; + crW.valuesBreeding[s] = StatValueCalculation.CalculateValue(_currentSpecies, s, crW.levelsWild[s], crW.levelsMutated[s], 0, true, 1, 0); crW.topBreedingStats[s] = (_currentSpecies.stats[s].IncPerTamedLevel != 0 && crW.levelsWild[s] == _bestLevels[s]); if (crB.levelsWild[s] == -1 || crW.levelsWild[s] == -1) totalLevelUnknown = true; @@ -932,7 +934,7 @@ private void listViewSpeciesBP_SelectedIndexChanged(object sender, EventArgs e) public int MaxWildLevels { - set => offspringPossibilities1.maxWildLevel = value; + set => offspringPossibilities1.maxWildLevel = value <= 0 ? 150 : value; } public void SetSpecies(Species species) diff --git a/ARKBreedingStats/CreatureBox.Designer.cs b/ARKBreedingStats/CreatureBox.Designer.cs index 7becd3222..13e98f46f 100644 --- a/ARKBreedingStats/CreatureBox.Designer.cs +++ b/ARKBreedingStats/CreatureBox.Designer.cs @@ -52,12 +52,12 @@ private void InitializeComponent() this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.statsDisplay1 = new ARKBreedingStats.uiControls.StatsDisplay(); this.panel2 = new System.Windows.Forms.Panel(); + this.labelSpecies = new System.Windows.Forms.Label(); this.LbFather = new System.Windows.Forms.Label(); this.LbMotherAndWildInfo = new System.Windows.Forms.Label(); this.labelNotes = new System.Windows.Forms.Label(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.regionColorChooser1 = new ARKBreedingStats.uiControls.RegionColorChooser(); - this.labelSpecies = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.panel1.SuspendLayout(); this.panelParents.SuspendLayout(); @@ -285,7 +285,7 @@ private void InitializeComponent() this.statsDisplay1.Location = new System.Drawing.Point(0, 0); this.statsDisplay1.Margin = new System.Windows.Forms.Padding(0); this.statsDisplay1.Name = "statsDisplay1"; - this.statsDisplay1.Size = new System.Drawing.Size(189, 203); + this.statsDisplay1.Size = new System.Drawing.Size(189, 196); this.statsDisplay1.TabIndex = 28; // // panel2 @@ -298,12 +298,20 @@ private void InitializeComponent() this.panel2.Controls.Add(this.pictureBox1); this.panel2.Controls.Add(this.regionColorChooser1); this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel2.Location = new System.Drawing.Point(0, 203); + this.panel2.Location = new System.Drawing.Point(0, 196); this.panel2.Margin = new System.Windows.Forms.Padding(0); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(189, 187); + this.panel2.Size = new System.Drawing.Size(189, 191); this.panel2.TabIndex = 29; // + // labelSpecies + // + this.labelSpecies.AutoSize = true; + this.labelSpecies.Location = new System.Drawing.Point(3, 174); + this.labelSpecies.Name = "labelSpecies"; + this.labelSpecies.Size = new System.Drawing.Size(0, 13); + this.labelSpecies.TabIndex = 26; + // // LbFather // this.LbFather.AutoSize = true; @@ -315,10 +323,9 @@ private void InitializeComponent() // // LbMotherAndWildInfo // - this.LbMotherAndWildInfo.AutoSize = true; this.LbMotherAndWildInfo.Location = new System.Drawing.Point(0, 0); this.LbMotherAndWildInfo.Name = "LbMotherAndWildInfo"; - this.LbMotherAndWildInfo.Size = new System.Drawing.Size(0, 13); + this.LbMotherAndWildInfo.Size = new System.Drawing.Size(183, 35); this.LbMotherAndWildInfo.TabIndex = 17; this.LbMotherAndWildInfo.Click += new System.EventHandler(this.LbMotherClick); // @@ -356,14 +363,6 @@ private void InitializeComponent() this.regionColorChooser1.TabIndex = 27; this.regionColorChooser1.VerboseButtonTexts = false; // - // labelSpecies - // - this.labelSpecies.AutoSize = true; - this.labelSpecies.Location = new System.Drawing.Point(3, 174); - this.labelSpecies.Name = "labelSpecies"; - this.labelSpecies.Size = new System.Drawing.Size(0, 13); - this.labelSpecies.TabIndex = 26; - // // CreatureBox // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/ARKBreedingStats/CreatureInfoInput.cs b/ARKBreedingStats/CreatureInfoInput.cs index 05139fd84..56f15bc04 100644 --- a/ARKBreedingStats/CreatureInfoInput.cs +++ b/ARKBreedingStats/CreatureInfoInput.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.Drawing.Text; using System.Windows.Forms; using System.Windows.Threading; using ARKBreedingStats.Library; @@ -24,7 +23,7 @@ public partial class CreatureInfoInput : UserControl /// Check for existing color id of the given region is requested. if the region is -1, all regions are requested. /// public event Action ColorsChanged; - public delegate void RequestCreatureDataEventHandler(CreatureInfoInput sender, bool openPatternEditor, bool updateInheritance, bool showDuplicateNameWarning, int namingPatternIndex); + public delegate void RequestCreatureDataEventHandler(CreatureInfoInput sender, bool openPatternEditor, bool updateInheritance, bool showDuplicateNameWarning, int namingPatternIndex, Creature alreadyExistingCreature); public event RequestCreatureDataEventHandler CreatureDataRequested; private Sex _sex; private CreatureFlags _creatureFlags; @@ -36,6 +35,7 @@ public partial class CreatureInfoInput : UserControl private readonly ToolTip _tt; private bool _updateMaturation; private Creature[] _sameSpecies; + public int LibraryCreatureCount; public List NamesOfAllCreatures; private string[] _ownersTribes; private byte[] _regionColorIDs; @@ -43,9 +43,9 @@ public partial class CreatureInfoInput : UserControl private bool _tribeLock, _ownerLock; public long MotherArkId, FatherArkId; // is only used when importing creatures with set parents. these ids are set externally after the creature data is set in the info input /// - /// True if creature is new, false if creature already exists + /// Creature if it's already existing in the library. /// - private bool _isNewCreature; + private Creature _alreadyExistingCreature; private readonly Debouncer _parentsChangedDebouncer = new Debouncer(); private readonly Debouncer _nameChangedDebouncer = new Debouncer(); @@ -93,7 +93,7 @@ public CreatureInfoInput() { if (_selectedSpecies != null) { - CreatureDataRequested?.Invoke(this, false, false, true, localIndex); + CreatureDataRequested?.Invoke(this, false, false, true, localIndex, _alreadyExistingCreature); } }; // open naming pattern editor @@ -101,7 +101,7 @@ public CreatureInfoInput() { if (e.Button == MouseButtons.Right) { - CreatureDataRequested?.Invoke(this, true, false, false, localIndex); + CreatureDataRequested?.Invoke(this, true, false, false, localIndex, _alreadyExistingCreature); } }; } @@ -559,7 +559,7 @@ private void parentComboBox_SelectedIndexChanged(object sender, EventArgs e) } private void ParentsChanged() - => CreatureDataRequested?.Invoke(this, false, true, false, 0); + => CreatureDataRequested?.Invoke(this, false, true, false, 0, _alreadyExistingCreature); /// /// It's assumed that if a parent has a higher mutation-count than the current set one, the set one is not valid and will be updated. @@ -581,16 +581,17 @@ private void UpdateMutations() private void btNamingPatternEditor_Click(object sender, EventArgs e) { - CreatureDataRequested?.Invoke(this, true, false, false, 0); + CreatureDataRequested?.Invoke(this, true, false, false, 0, _alreadyExistingCreature); } /// /// Generates a creature name with a given pattern /// - public void GenerateCreatureName(Creature creature, int[] speciesTopLevels, int[] speciesLowestLevels, Dictionary customReplacings, bool showDuplicateNameWarning, int namingPatternIndex) + public void GenerateCreatureName(Creature creature, Creature alreadyExistingCreature, int[] speciesTopLevels, int[] speciesLowestLevels, Dictionary customReplacings, bool showDuplicateNameWarning, int namingPatternIndex) { SetCreatureData(creature); - CreatureName = NamePattern.GenerateCreatureName(creature, _sameSpecies, speciesTopLevels, speciesLowestLevels, customReplacings, showDuplicateNameWarning, namingPatternIndex, false, colorsExisting: ColorAlreadyExistingInformation); + CreatureName = NamePattern.GenerateCreatureName(creature, alreadyExistingCreature, _sameSpecies, speciesTopLevels, speciesLowestLevels, customReplacings, + showDuplicateNameWarning, namingPatternIndex, false, colorsExisting: ColorAlreadyExistingInformation, libraryCreatureCount: LibraryCreatureCount); if (CreatureName.Length > Ark.MaxCreatureNameLength) SetMessageLabelText?.Invoke($"The generated name is longer than {Ark.MaxCreatureNameLength} characters, the name will look like this in game:\r\n" + CreatureName.Substring(0, Ark.MaxCreatureNameLength), MessageBoxIcon.Error); } @@ -599,7 +600,7 @@ public void OpenNamePatternEditor(Creature creature, int[] speciesTopLevels, int { if (!parentListValid) ParentListRequested?.Invoke(this); - using (var pe = new PatternEditor(creature, _sameSpecies, speciesTopLevels, speciesLowestLevels, ColorAlreadyExistingInformation, customReplacings, namingPatternIndex, reloadCallback)) + using (var pe = new PatternEditor(creature, _sameSpecies, speciesTopLevels, speciesLowestLevels, ColorAlreadyExistingInformation, customReplacings, namingPatternIndex, reloadCallback, LibraryCreatureCount)) { if (pe.ShowDialog() == DialogResult.OK) { @@ -697,15 +698,15 @@ public bool TribeLock /// /// If set to true, it's assumed the creature is already existing. /// - public bool UpdateExistingCreature + public Creature AlreadyExistingCreature { set { - btAdd2Library.Text = value ? + btAdd2Library.Text = value != null ? Loc.S("btUpdateLibraryCreature") : Loc.S("btAdd2Library"); - _isNewCreature = !value; + _alreadyExistingCreature = value; SetAdd2LibColor(btAdd2Library.Enabled); } } @@ -719,7 +720,7 @@ private void SetAdd2LibColor(bool buttonEnabled) { btAdd2Library.BackColor = !buttonEnabled ? SystemColors.Control - : _isNewCreature ? Color.LightGreen + : _alreadyExistingCreature != null ? Color.LightGreen : Color.LightSkyBlue; } diff --git a/ARKBreedingStats/Extraction.cs b/ARKBreedingStats/Extraction.cs index 9d150cb45..933ed9e01 100644 --- a/ARKBreedingStats/Extraction.cs +++ b/ARKBreedingStats/Extraction.cs @@ -234,7 +234,7 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l { // e.g. Griffin // get lowest wild level at which the creature is alive - while (StatValueCalculation.CalculateValue(species, s, ww, 0, true, lowerTEBound, 0, false) <= 0) + while (StatValueCalculation.CalculateValue(species, s, ww, 0, 0, true, lowerTEBound, 0, false) <= 0) { ww++; } @@ -257,8 +257,8 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l if (stats[s].IncPerWildLevel == 0) { // check if the input value is valid - MinMaxDouble possibleStatValues = new MinMaxDouble(StatValueCalculation.CalculateValue(species, s, 0, 0, PostTamed, lowerTEBound, _imprintingBonusRange.Min, false), - StatValueCalculation.CalculateValue(species, s, 0, 0, PostTamed, upperTEBound, _imprintingBonusRange.Max, false)); + MinMaxDouble possibleStatValues = new MinMaxDouble(StatValueCalculation.CalculateValue(species, s, 0, 0, 0, PostTamed, lowerTEBound, _imprintingBonusRange.Min, false), + StatValueCalculation.CalculateValue(species, s, 0, 0, 0, PostTamed, upperTEBound, _imprintingBonusRange.Max, false)); if (inputValue.Overlaps(possibleStatValues)) Results[s].Add(new StatResult(0, 0)); } @@ -484,8 +484,8 @@ private List CalculateImprintingBonus(Species species, double impr { int support = 0; MinMaxDouble imprintingBonusRange = new MinMaxDouble( - (((torpor - 0.05) / (1 + species.stats[Stats.Torpidity].MultAffinity) - species.stats[Stats.Torpidity].AddWhenTamed) / StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, false, 0, 0) - 1) / imprintingBonusTorporFinal, - (((torpor + 0.05) / (1 + species.stats[Stats.Torpidity].MultAffinity) - species.stats[Stats.Torpidity].AddWhenTamed) / StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, false, 0, 0) - 1) / imprintingBonusTorporFinal); + (((torpor - 0.05) / (1 + species.stats[Stats.Torpidity].MultAffinity) - species.stats[Stats.Torpidity].AddWhenTamed) / StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, 0, false, 0, 0) - 1) / imprintingBonusTorporFinal, + (((torpor + 0.05) / (1 + species.stats[Stats.Torpidity].MultAffinity) - species.stats[Stats.Torpidity].AddWhenTamed) / StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, 0, false, 0, 0) - 1) / imprintingBonusTorporFinal); // check for each possible food-level the IB-range and if it can narrow down the range derived from the torpor (deriving from food is more precise, due to the higher values) @@ -498,12 +498,12 @@ private List CalculateImprintingBonus(Species species, double impr MinMaxDouble imprintingBonusFromFood = new MinMaxDouble( (((food - 0.05) / (1 + species.stats[Stats.Food].MultAffinity) - species.stats[Stats.Food].AddWhenTamed) / - StatValueCalculation.CalculateValue(species, Stats.Food, foodLevel, 0, false, 0, 0) - + StatValueCalculation.CalculateValue(species, Stats.Food, foodLevel, 0, 0, false, 0, 0) - 1) / imprintingBonusFoodFinal, (((food + 0.05) / (1 + species.stats[Stats.Food].MultAffinity) - species.stats[Stats.Food].AddWhenTamed) / - StatValueCalculation.CalculateValue(species, Stats.Food, foodLevel, 0, false, 0, 0) - + StatValueCalculation.CalculateValue(species, Stats.Food, foodLevel, 0, 0, false, 0, 0) - 1) / imprintingBonusFoodFinal); @@ -517,9 +517,9 @@ private List CalculateImprintingBonus(Species species, double impr { MinMaxDouble intersectionIB = new MinMaxDouble(imprintingBonusRange); intersectionIB.SetToIntersectionWith(imprintingBonusFromFood); - if (StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, true, 1, + if (StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, 0, true, 1, intersectionIB.Min) <= torpor - && StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, true, + && StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, 0, true, 1, intersectionIB.Max) >= torpor) { //imprintingBonusFromTorpor = imprintingBonusFromFood; @@ -532,7 +532,7 @@ private List CalculateImprintingBonus(Species species, double impr // if the imprinting bonus value considering only the fixed imprinting gain by cuddles results in a value in the possible range, take this, probably most exact value if (imprintingBonusRange.Includes(imprintingBonusFromGainPerCuddle) - && Math.Abs(StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, true, 1, imprintingBonusFromGainPerCuddle) - torpor) <= 0.5) + && Math.Abs(StatValueCalculation.CalculateValue(species, Stats.Torpidity, torporLevel, 0, 0, true, 1, imprintingBonusFromGainPerCuddle) - torpor) <= 0.5) { imprintingBonusRange.MinMax = imprintingBonusFromGainPerCuddle; support++; diff --git a/ARKBreedingStats/Form1.Designer.cs b/ARKBreedingStats/Form1.Designer.cs index 1fd74aa8a..37b6c9e58 100644 --- a/ARKBreedingStats/Form1.Designer.cs +++ b/ARKBreedingStats/Form1.Designer.cs @@ -144,6 +144,10 @@ private void InitializeComponent() this.devToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.addRandomCreaturesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.colorDefinitionsToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.serverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.listenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.listenWithNewTokenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sendExampleCreatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.panelSums = new System.Windows.Forms.Panel(); this.lbShouldBe = new System.Windows.Forms.Label(); this.lbSumDomSB = new System.Windows.Forms.Label(); @@ -153,6 +157,7 @@ private void InitializeComponent() this.rbWildExtractor = new System.Windows.Forms.RadioButton(); this.tabControlMain = new System.Windows.Forms.TabControl(); this.tabPageStatTesting = new System.Windows.Forms.TabPage(); + this.CbLinkWildMutatedLevelsTester = new System.Windows.Forms.CheckBox(); this.pictureBoxColorRegionsTester = new System.Windows.Forms.PictureBox(); this.statPotentials1 = new ARKBreedingStats.uiControls.StatPotentials(); this.gbStatChart = new System.Windows.Forms.GroupBox(); @@ -164,6 +169,7 @@ private void InitializeComponent() this.groupBox2 = new System.Windows.Forms.GroupBox(); this.flowLayoutPanelStatIOsTester = new System.Windows.Forms.FlowLayoutPanel(); this.panel2 = new System.Windows.Forms.Panel(); + this.label4 = new System.Windows.Forms.Label(); this.lbCurrentValue = new System.Windows.Forms.Label(); this.panelStatTesterFootnote = new System.Windows.Forms.Panel(); this.LbWarningLevel255 = new System.Windows.Forms.Label(); @@ -178,7 +184,6 @@ private void InitializeComponent() this.creatureInfoInputTester = new ARKBreedingStats.CreatureInfoInput(); this.tabPageExtractor = new System.Windows.Forms.TabPage(); this.LbAsa = new System.Windows.Forms.Label(); - this.creatureAnalysis1 = new ARKBreedingStats.uiControls.CreatureAnalysis(); this.LbBlueprintPath = new System.Windows.Forms.Label(); this.BtCopyIssueDumpToClipboard = new System.Windows.Forms.Button(); this.llOnlineHelpExtractionIssues = new System.Windows.Forms.LinkLabel(); @@ -192,10 +197,12 @@ private void InitializeComponent() this.gbStatsExtractor = new System.Windows.Forms.GroupBox(); this.flowLayoutPanelStatIOsExtractor = new System.Windows.Forms.FlowLayoutPanel(); this.panel1 = new System.Windows.Forms.Panel(); + this.label5 = new System.Windows.Forms.Label(); this.lbCurrentStatEx = new System.Windows.Forms.Label(); this.btExtractLevels = new System.Windows.Forms.Button(); this.cbQuickWildCheck = new System.Windows.Forms.CheckBox(); this.labelErrorHelp = new System.Windows.Forms.Label(); + this.creatureAnalysis1 = new ARKBreedingStats.uiControls.CreatureAnalysis(); this.parentInheritanceExtractor = new ARKBreedingStats.uiControls.ParentInheritance(); this.numericUpDownLevel = new ARKBreedingStats.uiControls.Nud(); this.creatureInfoInputExtractor = new ARKBreedingStats.CreatureInfoInput(); @@ -220,12 +227,24 @@ private void InitializeComponent() this.columnHeaderOx = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderFo = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderWa = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeaderTemp = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderTm = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderWe = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderDm = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderSp = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderFr = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderCr = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderHPM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderStM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderToM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderOxM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderFoM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderWaM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderTmM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderWeM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderDmM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderSpM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderFrM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderCrM = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderColor0 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderColor1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderColor2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); @@ -359,6 +378,11 @@ private void InitializeComponent() this.TbMessageLabel = new System.Windows.Forms.TextBox(); this.contextMenuStripLibraryHeader = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripMenuItemResetLibraryColumnWidths = new System.Windows.Forms.ToolStripMenuItem(); + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.restoreMutationLevelsASAToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.collapseMutationsLevelsASEToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator27 = new System.Windows.Forms.ToolStripSeparator(); + this.resetColumnOrderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.speciesSelector1 = new ARKBreedingStats.SpeciesSelector(); this.groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownImprintingBonusTester)).BeginInit(); @@ -583,7 +607,7 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.numericUpDownImprintingBonusTester); this.groupBox1.Controls.Add(this.NumericUpDownTestingTE); this.groupBox1.Controls.Add(this.labelTesterTE); - this.groupBox1.Location = new System.Drawing.Point(321, 6); + this.groupBox1.Location = new System.Drawing.Point(373, 6); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(229, 72); this.groupBox1.TabIndex = 2; @@ -668,7 +692,7 @@ private void InitializeComponent() // groupBoxPossibilities // this.groupBoxPossibilities.Controls.Add(this.listViewPossibilities); - this.groupBoxPossibilities.Location = new System.Drawing.Point(590, 43); + this.groupBoxPossibilities.Location = new System.Drawing.Point(642, 43); this.groupBoxPossibilities.Name = "groupBoxPossibilities"; this.groupBoxPossibilities.Size = new System.Drawing.Size(189, 295); this.groupBoxPossibilities.TabIndex = 11; @@ -720,7 +744,7 @@ private void InitializeComponent() // this.groupBoxDetailsExtractor.Controls.Add(this.panelExtrImpr); this.groupBoxDetailsExtractor.Controls.Add(this.panelExtrTE); - this.groupBoxDetailsExtractor.Location = new System.Drawing.Point(321, 6); + this.groupBoxDetailsExtractor.Location = new System.Drawing.Point(373, 6); this.groupBoxDetailsExtractor.Name = "groupBoxDetailsExtractor"; this.groupBoxDetailsExtractor.Size = new System.Drawing.Size(229, 75); this.groupBoxDetailsExtractor.TabIndex = 4; @@ -886,7 +910,7 @@ private void InitializeComponent() // lbBreedingValueTester // this.lbBreedingValueTester.AutoSize = true; - this.lbBreedingValueTester.Location = new System.Drawing.Point(218, 0); + this.lbBreedingValueTester.Location = new System.Drawing.Point(270, 0); this.lbBreedingValueTester.Name = "lbBreedingValueTester"; this.lbBreedingValueTester.Size = new System.Drawing.Size(79, 13); this.lbBreedingValueTester.TabIndex = 33; @@ -895,7 +919,7 @@ private void InitializeComponent() // lbTesterWildLevel // this.lbTesterWildLevel.AutoSize = true; - this.lbTesterWildLevel.Location = new System.Drawing.Point(18, 0); + this.lbTesterWildLevel.Location = new System.Drawing.Point(8, 0); this.lbTesterWildLevel.Name = "lbTesterWildLevel"; this.lbTesterWildLevel.Size = new System.Drawing.Size(45, 13); this.lbTesterWildLevel.TabIndex = 31; @@ -904,7 +928,7 @@ private void InitializeComponent() // lbTesterDomLevel // this.lbTesterDomLevel.AutoSize = true; - this.lbTesterDomLevel.Location = new System.Drawing.Point(73, 0); + this.lbTesterDomLevel.Location = new System.Drawing.Point(112, 0); this.lbTesterDomLevel.Name = "lbTesterDomLevel"; this.lbTesterDomLevel.Size = new System.Drawing.Size(46, 13); this.lbTesterDomLevel.TabIndex = 32; @@ -912,7 +936,7 @@ private void InitializeComponent() // // lbInfoYellowStats // - this.lbInfoYellowStats.Location = new System.Drawing.Point(590, 341); + this.lbInfoYellowStats.Location = new System.Drawing.Point(642, 341); this.lbInfoYellowStats.Name = "lbInfoYellowStats"; this.lbInfoYellowStats.Size = new System.Drawing.Size(255, 126); this.lbInfoYellowStats.TabIndex = 15; @@ -929,7 +953,7 @@ private void InitializeComponent() // labelHBV // this.labelHBV.AutoSize = true; - this.labelHBV.Location = new System.Drawing.Point(218, 0); + this.labelHBV.Location = new System.Drawing.Point(270, 0); this.labelHBV.Name = "labelHBV"; this.labelHBV.Size = new System.Drawing.Size(79, 13); this.labelHBV.TabIndex = 27; @@ -938,7 +962,7 @@ private void InitializeComponent() // lbExtractorDomLevel // this.lbExtractorDomLevel.AutoSize = true; - this.lbExtractorDomLevel.Location = new System.Drawing.Point(172, 0); + this.lbExtractorDomLevel.Location = new System.Drawing.Point(224, 0); this.lbExtractorDomLevel.Name = "lbExtractorDomLevel"; this.lbExtractorDomLevel.Size = new System.Drawing.Size(46, 13); this.lbExtractorDomLevel.TabIndex = 26; @@ -965,7 +989,7 @@ private void InitializeComponent() // lbSumDom // this.lbSumDom.AutoSize = true; - this.lbSumDom.Location = new System.Drawing.Point(189, 2); + this.lbSumDom.Location = new System.Drawing.Point(241, 2); this.lbSumDom.Name = "lbSumDom"; this.lbSumDom.Size = new System.Drawing.Size(25, 13); this.lbSumDom.TabIndex = 31; @@ -990,7 +1014,8 @@ private void InitializeComponent() this.libraryFilterToolStripMenuItem, this.settingsToolStripMenuItem, this.helpToolStripMenuItem, - this.devToolStripMenuItem}); + this.devToolStripMenuItem, + this.serverToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(1878, 24); @@ -1385,6 +1410,38 @@ private void InitializeComponent() this.colorDefinitionsToClipboardToolStripMenuItem.Text = "Color definitions to clipboard"; this.colorDefinitionsToClipboardToolStripMenuItem.Click += new System.EventHandler(this.colorDefinitionsToClipboardToolStripMenuItem_Click); // + // serverToolStripMenuItem + // + this.serverToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.listenToolStripMenuItem, + this.listenWithNewTokenToolStripMenuItem, + this.sendExampleCreatureToolStripMenuItem}); + this.serverToolStripMenuItem.Name = "serverToolStripMenuItem"; + this.serverToolStripMenuItem.Size = new System.Drawing.Size(51, 20); + this.serverToolStripMenuItem.Text = "Server"; + // + // listenToolStripMenuItem + // + this.listenToolStripMenuItem.CheckOnClick = true; + this.listenToolStripMenuItem.Name = "listenToolStripMenuItem"; + this.listenToolStripMenuItem.Size = new System.Drawing.Size(194, 22); + this.listenToolStripMenuItem.Text = "Listen"; + this.listenToolStripMenuItem.CheckedChanged += new System.EventHandler(this.listenToolStripMenuItem_CheckedChanged); + // + // listenWithNewTokenToolStripMenuItem + // + this.listenWithNewTokenToolStripMenuItem.Name = "listenWithNewTokenToolStripMenuItem"; + this.listenWithNewTokenToolStripMenuItem.Size = new System.Drawing.Size(194, 22); + this.listenWithNewTokenToolStripMenuItem.Text = "Listen with new token"; + this.listenWithNewTokenToolStripMenuItem.Click += new System.EventHandler(this.listenWithNewTokenToolStripMenuItem_Click); + // + // sendExampleCreatureToolStripMenuItem + // + this.sendExampleCreatureToolStripMenuItem.Name = "sendExampleCreatureToolStripMenuItem"; + this.sendExampleCreatureToolStripMenuItem.Size = new System.Drawing.Size(194, 22); + this.sendExampleCreatureToolStripMenuItem.Text = "Send example creature"; + this.sendExampleCreatureToolStripMenuItem.Click += new System.EventHandler(this.sendExampleCreatureToolStripMenuItem_Click); + // // panelSums // this.panelSums.Controls.Add(this.lbShouldBe); @@ -1394,7 +1451,7 @@ private void InitializeComponent() this.panelSums.Controls.Add(this.lbSumDom); this.panelSums.Location = new System.Drawing.Point(3, 26); this.panelSums.Name = "panelSums"; - this.panelSums.Size = new System.Drawing.Size(295, 32); + this.panelSums.Size = new System.Drawing.Size(344, 32); this.panelSums.TabIndex = 8; // // lbShouldBe @@ -1409,7 +1466,7 @@ private void InitializeComponent() // lbSumDomSB // this.lbSumDomSB.AutoSize = true; - this.lbSumDomSB.Location = new System.Drawing.Point(189, 15); + this.lbSumDomSB.Location = new System.Drawing.Point(241, 15); this.lbSumDomSB.Name = "lbSumDomSB"; this.lbSumDomSB.Size = new System.Drawing.Size(25, 13); this.lbSumDomSB.TabIndex = 51; @@ -1482,13 +1539,14 @@ private void InitializeComponent() this.tabControlMain.Location = new System.Drawing.Point(0, 103); this.tabControlMain.Name = "tabControlMain"; this.tabControlMain.SelectedIndex = 1; - this.tabControlMain.Size = new System.Drawing.Size(1878, 775); + this.tabControlMain.Size = new System.Drawing.Size(1878, 810); this.tabControlMain.TabIndex = 3; this.tabControlMain.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged); // // tabPageStatTesting // this.tabPageStatTesting.AutoScroll = true; + this.tabPageStatTesting.Controls.Add(this.CbLinkWildMutatedLevelsTester); this.tabPageStatTesting.Controls.Add(this.pictureBoxColorRegionsTester); this.tabPageStatTesting.Controls.Add(this.statPotentials1); this.tabPageStatTesting.Controls.Add(this.gbStatChart); @@ -1500,14 +1558,25 @@ private void InitializeComponent() this.tabPageStatTesting.Location = new System.Drawing.Point(4, 22); this.tabPageStatTesting.Name = "tabPageStatTesting"; this.tabPageStatTesting.Padding = new System.Windows.Forms.Padding(3); - this.tabPageStatTesting.Size = new System.Drawing.Size(1870, 749); + this.tabPageStatTesting.Size = new System.Drawing.Size(1870, 784); this.tabPageStatTesting.TabIndex = 1; this.tabPageStatTesting.Text = "Stat Testing"; this.tabPageStatTesting.UseVisualStyleBackColor = true; // + // CbLinkWildMutatedLevelsTester + // + this.CbLinkWildMutatedLevelsTester.AutoSize = true; + this.CbLinkWildMutatedLevelsTester.Location = new System.Drawing.Point(259, 10); + this.CbLinkWildMutatedLevelsTester.Name = "CbLinkWildMutatedLevelsTester"; + this.CbLinkWildMutatedLevelsTester.Size = new System.Drawing.Size(108, 17); + this.CbLinkWildMutatedLevelsTester.TabIndex = 14; + this.CbLinkWildMutatedLevelsTester.Text = "Link wild-mutated"; + this.CbLinkWildMutatedLevelsTester.UseVisualStyleBackColor = true; + this.CbLinkWildMutatedLevelsTester.CheckedChanged += new System.EventHandler(this.CbLinkWildMutatedLevelsTester_CheckedChanged); + // // pictureBoxColorRegionsTester // - this.pictureBoxColorRegionsTester.Location = new System.Drawing.Point(589, 489); + this.pictureBoxColorRegionsTester.Location = new System.Drawing.Point(641, 489); this.pictureBoxColorRegionsTester.Name = "pictureBoxColorRegionsTester"; this.pictureBoxColorRegionsTester.Size = new System.Drawing.Size(256, 256); this.pictureBoxColorRegionsTester.TabIndex = 13; @@ -1516,7 +1585,7 @@ private void InitializeComponent() // // statPotentials1 // - this.statPotentials1.Location = new System.Drawing.Point(808, 9); + this.statPotentials1.Location = new System.Drawing.Point(860, 9); this.statPotentials1.Name = "statPotentials1"; this.statPotentials1.Size = new System.Drawing.Size(293, 433); this.statPotentials1.TabIndex = 12; @@ -1524,7 +1593,7 @@ private void InitializeComponent() // gbStatChart // this.gbStatChart.Controls.Add(this.radarChart1); - this.gbStatChart.Location = new System.Drawing.Point(589, 9); + this.gbStatChart.Location = new System.Drawing.Point(641, 9); this.gbStatChart.Name = "gbStatChart"; this.gbStatChart.Size = new System.Drawing.Size(213, 228); this.gbStatChart.TabIndex = 11; @@ -1591,7 +1660,7 @@ private void InitializeComponent() this.groupBox2.Controls.Add(this.flowLayoutPanelStatIOsTester); this.groupBox2.Location = new System.Drawing.Point(8, 37); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(307, 639); + this.groupBox2.Size = new System.Drawing.Size(359, 639); this.groupBox2.TabIndex = 1; this.groupBox2.TabStop = false; this.groupBox2.Text = "Stats"; @@ -1605,12 +1674,13 @@ private void InitializeComponent() this.flowLayoutPanelStatIOsTester.Location = new System.Drawing.Point(6, 19); this.flowLayoutPanelStatIOsTester.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanelStatIOsTester.Name = "flowLayoutPanelStatIOsTester"; - this.flowLayoutPanelStatIOsTester.Size = new System.Drawing.Size(301, 617); + this.flowLayoutPanelStatIOsTester.Size = new System.Drawing.Size(353, 617); this.flowLayoutPanelStatIOsTester.TabIndex = 53; this.flowLayoutPanelStatIOsTester.WrapContents = false; // // panel2 // + this.panel2.Controls.Add(this.label4); this.panel2.Controls.Add(this.lbTesterWildLevel); this.panel2.Controls.Add(this.lbTesterDomLevel); this.panel2.Controls.Add(this.lbBreedingValueTester); @@ -1618,13 +1688,22 @@ private void InitializeComponent() this.panel2.Location = new System.Drawing.Point(0, 3); this.panel2.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(300, 17); + this.panel2.Size = new System.Drawing.Size(350, 17); this.panel2.TabIndex = 54; // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(60, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(53, 13); + this.label4.TabIndex = 37; + this.label4.Text = "Mutations"; + // // lbCurrentValue // this.lbCurrentValue.AutoSize = true; - this.lbCurrentValue.Location = new System.Drawing.Point(126, 0); + this.lbCurrentValue.Location = new System.Drawing.Point(178, 0); this.lbCurrentValue.Name = "lbCurrentValue"; this.lbCurrentValue.Size = new System.Drawing.Size(71, 13); this.lbCurrentValue.TabIndex = 36; @@ -1639,7 +1718,7 @@ private void InitializeComponent() this.panelStatTesterFootnote.Controls.Add(this.lbNotYetTamed); this.panelStatTesterFootnote.Location = new System.Drawing.Point(3, 26); this.panelStatTesterFootnote.Name = "panelStatTesterFootnote"; - this.panelStatTesterFootnote.Size = new System.Drawing.Size(295, 128); + this.panelStatTesterFootnote.Size = new System.Drawing.Size(344, 128); this.panelStatTesterFootnote.TabIndex = 54; // // LbWarningLevel255 @@ -1649,7 +1728,7 @@ private void InitializeComponent() this.LbWarningLevel255.Location = new System.Drawing.Point(8, 52); this.LbWarningLevel255.Name = "LbWarningLevel255"; this.LbWarningLevel255.Padding = new System.Windows.Forms.Padding(3); - this.LbWarningLevel255.Size = new System.Drawing.Size(283, 70); + this.LbWarningLevel255.Size = new System.Drawing.Size(333, 70); this.LbWarningLevel255.TabIndex = 50; // // lbWildLevelTester @@ -1693,7 +1772,7 @@ private void InitializeComponent() this.gpPreviewEdit.Controls.Add(this.lbCurrentCreature); this.gpPreviewEdit.Controls.Add(this.labelCurrentTesterCreature); this.gpPreviewEdit.Controls.Add(this.lbTestingInfo); - this.gpPreviewEdit.Location = new System.Drawing.Point(321, 84); + this.gpPreviewEdit.Location = new System.Drawing.Point(373, 84); this.gpPreviewEdit.Name = "gpPreviewEdit"; this.gpPreviewEdit.Size = new System.Drawing.Size(229, 91); this.gpPreviewEdit.TabIndex = 3; @@ -1742,7 +1821,7 @@ private void InitializeComponent() this.creatureInfoInputTester.DomesticatedAt = new System.DateTime(2014, 12, 31, 0, 0, 0, 0); this.creatureInfoInputTester.Father = null; this.creatureInfoInputTester.GrowingUntil = null; - this.creatureInfoInputTester.Location = new System.Drawing.Point(321, 184); + this.creatureInfoInputTester.Location = new System.Drawing.Point(373, 184); this.creatureInfoInputTester.LockServer = false; this.creatureInfoInputTester.Mother = null; this.creatureInfoInputTester.MutationCounterFather = 0; @@ -1767,7 +1846,6 @@ private void InitializeComponent() // this.tabPageExtractor.AutoScroll = true; this.tabPageExtractor.Controls.Add(this.LbAsa); - this.tabPageExtractor.Controls.Add(this.creatureAnalysis1); this.tabPageExtractor.Controls.Add(this.LbBlueprintPath); this.tabPageExtractor.Controls.Add(this.BtCopyIssueDumpToClipboard); this.tabPageExtractor.Controls.Add(this.llOnlineHelpExtractionIssues); @@ -1785,13 +1863,14 @@ private void InitializeComponent() this.tabPageExtractor.Controls.Add(this.groupBoxPossibilities); this.tabPageExtractor.Controls.Add(this.lbLevel); this.tabPageExtractor.Controls.Add(this.labelErrorHelp); + this.tabPageExtractor.Controls.Add(this.creatureAnalysis1); this.tabPageExtractor.Controls.Add(this.parentInheritanceExtractor); this.tabPageExtractor.Controls.Add(this.numericUpDownLevel); this.tabPageExtractor.Controls.Add(this.creatureInfoInputExtractor); this.tabPageExtractor.Location = new System.Drawing.Point(4, 22); this.tabPageExtractor.Name = "tabPageExtractor"; this.tabPageExtractor.Padding = new System.Windows.Forms.Padding(3); - this.tabPageExtractor.Size = new System.Drawing.Size(1870, 749); + this.tabPageExtractor.Size = new System.Drawing.Size(1870, 784); this.tabPageExtractor.TabIndex = 0; this.tabPageExtractor.Text = "Extractor"; this.tabPageExtractor.UseVisualStyleBackColor = true; @@ -1801,26 +1880,19 @@ private void InitializeComponent() this.LbAsa.AutoSize = true; this.LbAsa.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.LbAsa.ForeColor = System.Drawing.Color.DarkGray; - this.LbAsa.Location = new System.Drawing.Point(295, 66); + this.LbAsa.Location = new System.Drawing.Point(346, 66); this.LbAsa.Name = "LbAsa"; this.LbAsa.Size = new System.Drawing.Size(20, 9); this.LbAsa.TabIndex = 56; this.LbAsa.Text = "ASA"; // - // creatureAnalysis1 - // - this.creatureAnalysis1.Location = new System.Drawing.Point(851, 265); - this.creatureAnalysis1.Name = "creatureAnalysis1"; - this.creatureAnalysis1.Size = new System.Drawing.Size(346, 199); - this.creatureAnalysis1.TabIndex = 55; - // // LbBlueprintPath // this.LbBlueprintPath.Font = new System.Drawing.Font("Microsoft Sans Serif", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.LbBlueprintPath.ForeColor = System.Drawing.Color.DarkGray; this.LbBlueprintPath.Location = new System.Drawing.Point(8, 34); this.LbBlueprintPath.Name = "LbBlueprintPath"; - this.LbBlueprintPath.Size = new System.Drawing.Size(307, 41); + this.LbBlueprintPath.Size = new System.Drawing.Size(338, 41); this.LbBlueprintPath.TabIndex = 54; this.LbBlueprintPath.Text = "/Game/​PrimalEarth/​Dinos/​Direwolf/ ​Direwolf_Character_BP.Direwolf_Character_BP" + ""; @@ -1828,7 +1900,7 @@ private void InitializeComponent() // // BtCopyIssueDumpToClipboard // - this.BtCopyIssueDumpToClipboard.Location = new System.Drawing.Point(590, 703); + this.BtCopyIssueDumpToClipboard.Location = new System.Drawing.Point(642, 703); this.BtCopyIssueDumpToClipboard.Name = "BtCopyIssueDumpToClipboard"; this.BtCopyIssueDumpToClipboard.Size = new System.Drawing.Size(345, 23); this.BtCopyIssueDumpToClipboard.TabIndex = 53; @@ -1839,7 +1911,7 @@ private void InitializeComponent() // llOnlineHelpExtractionIssues // this.llOnlineHelpExtractionIssues.AutoSize = true; - this.llOnlineHelpExtractionIssues.Location = new System.Drawing.Point(593, 599); + this.llOnlineHelpExtractionIssues.Location = new System.Drawing.Point(645, 599); this.llOnlineHelpExtractionIssues.Name = "llOnlineHelpExtractionIssues"; this.llOnlineHelpExtractionIssues.Size = new System.Drawing.Size(141, 13); this.llOnlineHelpExtractionIssues.TabIndex = 50; @@ -1849,7 +1921,7 @@ private void InitializeComponent() // // PbCreatureColorsExtractor // - this.PbCreatureColorsExtractor.Location = new System.Drawing.Point(589, 489); + this.PbCreatureColorsExtractor.Location = new System.Drawing.Point(641, 489); this.PbCreatureColorsExtractor.Name = "PbCreatureColorsExtractor"; this.PbCreatureColorsExtractor.Size = new System.Drawing.Size(256, 256); this.PbCreatureColorsExtractor.TabIndex = 51; @@ -1859,7 +1931,7 @@ private void InitializeComponent() // groupBoxRadarChartExtractor // this.groupBoxRadarChartExtractor.Controls.Add(this.radarChartExtractor); - this.groupBoxRadarChartExtractor.Location = new System.Drawing.Point(785, 6); + this.groupBoxRadarChartExtractor.Location = new System.Drawing.Point(837, 6); this.groupBoxRadarChartExtractor.Name = "groupBoxRadarChartExtractor"; this.groupBoxRadarChartExtractor.Size = new System.Drawing.Size(150, 163); this.groupBoxRadarChartExtractor.TabIndex = 11; @@ -1882,7 +1954,7 @@ private void InitializeComponent() this.lbImprintingFailInfo.BackColor = System.Drawing.Color.MistyRose; this.lbImprintingFailInfo.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.lbImprintingFailInfo.ForeColor = System.Drawing.Color.Maroon; - this.lbImprintingFailInfo.Location = new System.Drawing.Point(589, 612); + this.lbImprintingFailInfo.Location = new System.Drawing.Point(641, 612); this.lbImprintingFailInfo.Name = "lbImprintingFailInfo"; this.lbImprintingFailInfo.Size = new System.Drawing.Size(443, 88); this.lbImprintingFailInfo.TabIndex = 49; @@ -1894,7 +1966,7 @@ private void InitializeComponent() // groupBoxTamingInfo // this.groupBoxTamingInfo.Controls.Add(this.labelTamingInfo); - this.groupBoxTamingInfo.Location = new System.Drawing.Point(590, 60); + this.groupBoxTamingInfo.Location = new System.Drawing.Point(642, 60); this.groupBoxTamingInfo.Name = "groupBoxTamingInfo"; this.groupBoxTamingInfo.Size = new System.Drawing.Size(174, 423); this.groupBoxTamingInfo.TabIndex = 48; @@ -1911,7 +1983,7 @@ private void InitializeComponent() // // button2TamingCalc // - this.button2TamingCalc.Location = new System.Drawing.Point(590, 32); + this.button2TamingCalc.Location = new System.Drawing.Point(642, 32); this.button2TamingCalc.Name = "button2TamingCalc"; this.button2TamingCalc.Size = new System.Drawing.Size(177, 23); this.button2TamingCalc.TabIndex = 9; @@ -1925,7 +1997,7 @@ private void InitializeComponent() this.gbStatsExtractor.Controls.Add(this.flowLayoutPanelStatIOsExtractor); this.gbStatsExtractor.Location = new System.Drawing.Point(8, 76); this.gbStatsExtractor.Name = "gbStatsExtractor"; - this.gbStatsExtractor.Size = new System.Drawing.Size(307, 639); + this.gbStatsExtractor.Size = new System.Drawing.Size(359, 639); this.gbStatsExtractor.TabIndex = 3; this.gbStatsExtractor.TabStop = false; this.gbStatsExtractor.Text = "Stats"; @@ -1940,21 +2012,31 @@ private void InitializeComponent() this.flowLayoutPanelStatIOsExtractor.Location = new System.Drawing.Point(6, 19); this.flowLayoutPanelStatIOsExtractor.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanelStatIOsExtractor.Name = "flowLayoutPanelStatIOsExtractor"; - this.flowLayoutPanelStatIOsExtractor.Size = new System.Drawing.Size(301, 617); + this.flowLayoutPanelStatIOsExtractor.Size = new System.Drawing.Size(353, 617); this.flowLayoutPanelStatIOsExtractor.TabIndex = 52; this.flowLayoutPanelStatIOsExtractor.WrapContents = false; // // panel1 // + this.panel1.Controls.Add(this.label5); this.panel1.Controls.Add(this.lbCurrentStatEx); this.panel1.Controls.Add(this.lbExtractorWildLevel); this.panel1.Controls.Add(this.labelHBV); this.panel1.Controls.Add(this.lbExtractorDomLevel); this.panel1.Location = new System.Drawing.Point(3, 3); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(295, 17); + this.panel1.Size = new System.Drawing.Size(344, 17); this.panel1.TabIndex = 53; // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(174, 0); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(53, 13); + this.label5.TabIndex = 51; + this.label5.Text = "Mutations"; + // // lbCurrentStatEx // this.lbCurrentStatEx.AutoSize = true; @@ -1966,7 +2048,7 @@ private void InitializeComponent() // // btExtractLevels // - this.btExtractLevels.Location = new System.Drawing.Point(321, 110); + this.btExtractLevels.Location = new System.Drawing.Point(373, 110); this.btExtractLevels.Name = "btExtractLevels"; this.btExtractLevels.Size = new System.Drawing.Size(229, 68); this.btExtractLevels.TabIndex = 6; @@ -1977,7 +2059,7 @@ private void InitializeComponent() // cbQuickWildCheck // this.cbQuickWildCheck.AutoSize = true; - this.cbQuickWildCheck.Location = new System.Drawing.Point(556, 8); + this.cbQuickWildCheck.Location = new System.Drawing.Point(608, 8); this.cbQuickWildCheck.Name = "cbQuickWildCheck"; this.cbQuickWildCheck.Size = new System.Drawing.Size(155, 17); this.cbQuickWildCheck.TabIndex = 8; @@ -1987,15 +2069,22 @@ private void InitializeComponent() // // labelErrorHelp // - this.labelErrorHelp.Location = new System.Drawing.Point(590, 43); + this.labelErrorHelp.Location = new System.Drawing.Point(642, 43); this.labelErrorHelp.Name = "labelErrorHelp"; this.labelErrorHelp.Size = new System.Drawing.Size(239, 569); this.labelErrorHelp.TabIndex = 40; this.labelErrorHelp.Text = resources.GetString("labelErrorHelp.Text"); // + // creatureAnalysis1 + // + this.creatureAnalysis1.Location = new System.Drawing.Point(903, 265); + this.creatureAnalysis1.Name = "creatureAnalysis1"; + this.creatureAnalysis1.Size = new System.Drawing.Size(346, 199); + this.creatureAnalysis1.TabIndex = 55; + // // parentInheritanceExtractor // - this.parentInheritanceExtractor.Location = new System.Drawing.Point(851, 470); + this.parentInheritanceExtractor.Location = new System.Drawing.Point(903, 470); this.parentInheritanceExtractor.Name = "parentInheritanceExtractor"; this.parentInheritanceExtractor.Size = new System.Drawing.Size(337, 182); this.parentInheritanceExtractor.TabIndex = 52; @@ -2039,7 +2128,7 @@ private void InitializeComponent() this.creatureInfoInputExtractor.DomesticatedAt = new System.DateTime(2014, 12, 31, 0, 0, 0, 0); this.creatureInfoInputExtractor.Father = null; this.creatureInfoInputExtractor.GrowingUntil = null; - this.creatureInfoInputExtractor.Location = new System.Drawing.Point(321, 184); + this.creatureInfoInputExtractor.Location = new System.Drawing.Point(373, 184); this.creatureInfoInputExtractor.LockServer = false; this.creatureInfoInputExtractor.Mother = null; this.creatureInfoInputExtractor.MutationCounterFather = 0; @@ -2065,7 +2154,7 @@ private void InitializeComponent() this.tabPageLibrary.Location = new System.Drawing.Point(4, 22); this.tabPageLibrary.Name = "tabPageLibrary"; this.tabPageLibrary.Padding = new System.Windows.Forms.Padding(3); - this.tabPageLibrary.Size = new System.Drawing.Size(1870, 749); + this.tabPageLibrary.Size = new System.Drawing.Size(1870, 784); this.tabPageLibrary.TabIndex = 2; this.tabPageLibrary.Text = "Library"; this.tabPageLibrary.UseVisualStyleBackColor = true; @@ -2082,7 +2171,7 @@ private void InitializeComponent() this.tableLayoutPanelLibrary.Name = "tableLayoutPanelLibrary"; this.tableLayoutPanelLibrary.RowCount = 1; this.tableLayoutPanelLibrary.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanelLibrary.Size = new System.Drawing.Size(1864, 743); + this.tableLayoutPanelLibrary.Size = new System.Drawing.Size(1864, 778); this.tableLayoutPanelLibrary.TabIndex = 4; // // listViewLibrary @@ -2107,12 +2196,24 @@ private void InitializeComponent() this.columnHeaderOx, this.columnHeaderFo, this.columnHeaderWa, - this.columnHeaderTemp, + this.columnHeaderTm, this.columnHeaderWe, this.columnHeaderDm, this.columnHeaderSp, this.columnHeaderFr, this.columnHeaderCr, + this.columnHeaderHPM, + this.columnHeaderStM, + this.columnHeaderToM, + this.columnHeaderOxM, + this.columnHeaderFoM, + this.columnHeaderWaM, + this.columnHeaderTmM, + this.columnHeaderWeM, + this.columnHeaderDmM, + this.columnHeaderSpM, + this.columnHeaderFrM, + this.columnHeaderCrM, this.columnHeaderColor0, this.columnHeaderColor1, this.columnHeaderColor2, @@ -2131,7 +2232,7 @@ private void InitializeComponent() this.listViewLibrary.Location = new System.Drawing.Point(204, 3); this.listViewLibrary.Name = "listViewLibrary"; this.listViewLibrary.ShowItemToolTips = true; - this.listViewLibrary.Size = new System.Drawing.Size(1657, 737); + this.listViewLibrary.Size = new System.Drawing.Size(1657, 772); this.listViewLibrary.TabIndex = 2; this.listViewLibrary.UseCompatibleStateImageBehavior = false; this.listViewLibrary.View = System.Windows.Forms.View.Details; @@ -2171,45 +2272,45 @@ private void InitializeComponent() // // columnHeaderDomesticated // - this.columnHeaderDomesticated.DisplayIndex = 23; + this.columnHeaderDomesticated.DisplayIndex = 36; this.columnHeaderDomesticated.Text = "Domesticated"; // // columnHeaderTopness // - this.columnHeaderTopness.DisplayIndex = 19; + this.columnHeaderTopness.DisplayIndex = 30; this.columnHeaderTopness.Text = "Tp%"; this.columnHeaderTopness.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderTopness.Width = 33; // // columnHeaderTopStatsNr // - this.columnHeaderTopStatsNr.DisplayIndex = 18; + this.columnHeaderTopStatsNr.DisplayIndex = 31; this.columnHeaderTopStatsNr.Text = "Top"; this.columnHeaderTopStatsNr.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderTopStatsNr.Width = 31; // // columnHeaderGen // - this.columnHeaderGen.DisplayIndex = 20; + this.columnHeaderGen.DisplayIndex = 32; this.columnHeaderGen.Text = "Gen"; this.columnHeaderGen.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; this.columnHeaderGen.Width = 34; // // columnHeaderFound // - this.columnHeaderFound.DisplayIndex = 21; + this.columnHeaderFound.DisplayIndex = 33; this.columnHeaderFound.Text = "LW"; this.columnHeaderFound.Width = 30; // // columnHeaderMutations // - this.columnHeaderMutations.DisplayIndex = 22; + this.columnHeaderMutations.DisplayIndex = 34; this.columnHeaderMutations.Text = "Mu"; this.columnHeaderMutations.Width = 30; // // columnHeaderCooldown // - this.columnHeaderCooldown.DisplayIndex = 24; + this.columnHeaderCooldown.DisplayIndex = 37; this.columnHeaderCooldown.Text = "Cooldown/Growing"; // // columnHeaderHP @@ -2221,140 +2322,224 @@ private void InitializeComponent() // // columnHeaderSt // - this.columnHeaderSt.DisplayIndex = 7; + this.columnHeaderSt.DisplayIndex = 8; this.columnHeaderSt.Text = "St"; this.columnHeaderSt.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderSt.Width = 30; // // columnHeaderTo // - this.columnHeaderTo.DisplayIndex = 17; + this.columnHeaderTo.DisplayIndex = 28; this.columnHeaderTo.Text = "To"; this.columnHeaderTo.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderTo.Width = 30; // // columnHeaderOx // - this.columnHeaderOx.DisplayIndex = 8; + this.columnHeaderOx.DisplayIndex = 10; this.columnHeaderOx.Text = "Ox"; this.columnHeaderOx.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderOx.Width = 30; // // columnHeaderFo // - this.columnHeaderFo.DisplayIndex = 9; + this.columnHeaderFo.DisplayIndex = 12; this.columnHeaderFo.Text = "Fo"; this.columnHeaderFo.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderFo.Width = 30; // // columnHeaderWa // - this.columnHeaderWa.DisplayIndex = 10; + this.columnHeaderWa.DisplayIndex = 14; this.columnHeaderWa.Text = "Wa"; this.columnHeaderWa.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderWa.Width = 30; // - // columnHeaderTemp + // columnHeaderTm // - this.columnHeaderTemp.DisplayIndex = 11; - this.columnHeaderTemp.Text = "Te"; - this.columnHeaderTemp.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; - this.columnHeaderTemp.Width = 30; + this.columnHeaderTm.DisplayIndex = 16; + this.columnHeaderTm.Text = "Te"; + this.columnHeaderTm.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderTm.Width = 30; // // columnHeaderWe // - this.columnHeaderWe.DisplayIndex = 12; + this.columnHeaderWe.DisplayIndex = 18; this.columnHeaderWe.Text = "We"; this.columnHeaderWe.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderWe.Width = 30; // // columnHeaderDm // - this.columnHeaderDm.DisplayIndex = 13; this.columnHeaderDm.Text = "Dm"; this.columnHeaderDm.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderDm.Width = 30; // // columnHeaderSp // - this.columnHeaderSp.DisplayIndex = 14; + this.columnHeaderSp.DisplayIndex = 22; this.columnHeaderSp.Text = "Sp"; this.columnHeaderSp.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderSp.Width = 30; // // columnHeaderFr // - this.columnHeaderFr.DisplayIndex = 15; + this.columnHeaderFr.DisplayIndex = 24; this.columnHeaderFr.Text = "Fr"; this.columnHeaderFr.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderFr.Width = 30; // // columnHeaderCr // - this.columnHeaderCr.DisplayIndex = 16; + this.columnHeaderCr.DisplayIndex = 26; this.columnHeaderCr.Text = "Cr"; this.columnHeaderCr.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.columnHeaderCr.Width = 30; // + // columnHeaderHPM + // + this.columnHeaderHPM.DisplayIndex = 7; + this.columnHeaderHPM.Text = "HPM"; + this.columnHeaderHPM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderHPM.Width = 35; + // + // columnHeaderStM + // + this.columnHeaderStM.DisplayIndex = 9; + this.columnHeaderStM.Text = "StM"; + this.columnHeaderStM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderStM.Width = 35; + // + // columnHeaderToM + // + this.columnHeaderToM.DisplayIndex = 29; + this.columnHeaderToM.Text = "ToM"; + this.columnHeaderToM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderToM.Width = 35; + // + // columnHeaderOxM + // + this.columnHeaderOxM.DisplayIndex = 11; + this.columnHeaderOxM.Text = "OxM"; + this.columnHeaderOxM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderOxM.Width = 35; + // + // columnHeaderFoM + // + this.columnHeaderFoM.DisplayIndex = 13; + this.columnHeaderFoM.Text = "FoM"; + this.columnHeaderFoM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderFoM.Width = 35; + // + // columnHeaderWaM + // + this.columnHeaderWaM.DisplayIndex = 15; + this.columnHeaderWaM.Text = "WaM"; + this.columnHeaderWaM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderWaM.Width = 0; + // + // columnHeaderTmM + // + this.columnHeaderTmM.DisplayIndex = 17; + this.columnHeaderTmM.Text = "TeM"; + this.columnHeaderTmM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderTmM.Width = 0; + // + // columnHeaderWeM + // + this.columnHeaderWeM.DisplayIndex = 19; + this.columnHeaderWeM.Text = "WeM"; + this.columnHeaderWeM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderWeM.Width = 35; + // + // columnHeaderDmM + // + this.columnHeaderDmM.DisplayIndex = 21; + this.columnHeaderDmM.Text = "DmM"; + this.columnHeaderDmM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderDmM.Width = 35; + // + // columnHeaderSpM + // + this.columnHeaderSpM.DisplayIndex = 23; + this.columnHeaderSpM.Text = "SpM"; + this.columnHeaderSpM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderSpM.Width = 35; + // + // columnHeaderFrM + // + this.columnHeaderFrM.DisplayIndex = 25; + this.columnHeaderFrM.Text = "FrM"; + this.columnHeaderFrM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderFrM.Width = 0; + // + // columnHeaderCrM + // + this.columnHeaderCrM.DisplayIndex = 27; + this.columnHeaderCrM.Text = "CrM"; + this.columnHeaderCrM.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.columnHeaderCrM.Width = 0; + // // columnHeaderColor0 // - this.columnHeaderColor0.DisplayIndex = 25; + this.columnHeaderColor0.DisplayIndex = 38; this.columnHeaderColor0.Text = "C0"; this.columnHeaderColor0.Width = 25; // // columnHeaderColor1 // - this.columnHeaderColor1.DisplayIndex = 26; + this.columnHeaderColor1.DisplayIndex = 39; this.columnHeaderColor1.Text = "C1"; this.columnHeaderColor1.Width = 25; // // columnHeaderColor2 // - this.columnHeaderColor2.DisplayIndex = 27; + this.columnHeaderColor2.DisplayIndex = 40; this.columnHeaderColor2.Text = "C2"; this.columnHeaderColor2.Width = 25; // // columnHeaderColor3 // - this.columnHeaderColor3.DisplayIndex = 28; + this.columnHeaderColor3.DisplayIndex = 41; this.columnHeaderColor3.Text = "C3"; this.columnHeaderColor3.Width = 25; // // columnHeaderColor4 // - this.columnHeaderColor4.DisplayIndex = 29; + this.columnHeaderColor4.DisplayIndex = 42; this.columnHeaderColor4.Text = "C4"; this.columnHeaderColor4.Width = 25; // // columnHeaderColor5 // - this.columnHeaderColor5.DisplayIndex = 30; + this.columnHeaderColor5.DisplayIndex = 43; this.columnHeaderColor5.Text = "C5"; this.columnHeaderColor5.Width = 25; // // columnHeaderSpecies // - this.columnHeaderSpecies.DisplayIndex = 31; + this.columnHeaderSpecies.DisplayIndex = 44; this.columnHeaderSpecies.Text = "Species"; // // columnHeaderStatus // - this.columnHeaderStatus.DisplayIndex = 32; + this.columnHeaderStatus.DisplayIndex = 0; this.columnHeaderStatus.Text = "Status"; // // columnHeaderTribe // - this.columnHeaderTribe.DisplayIndex = 33; + this.columnHeaderTribe.DisplayIndex = 45; this.columnHeaderTribe.Text = "Tribe"; // // columnHeaderStatusIcon // - this.columnHeaderStatusIcon.DisplayIndex = 0; + this.columnHeaderStatusIcon.DisplayIndex = 46; this.columnHeaderStatusIcon.Text = "Status"; this.columnHeaderStatusIcon.Width = 35; // // columnHeaderMutagen // + this.columnHeaderMutagen.DisplayIndex = 35; this.columnHeaderMutagen.Text = "Mutagen"; this.columnHeaderMutagen.Width = 30; // @@ -2678,7 +2863,7 @@ private void InitializeComponent() this.tableLayoutPanel1.RowCount = 2; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(195, 737); + this.tableLayoutPanel1.Size = new System.Drawing.Size(195, 772); this.tableLayoutPanel1.TabIndex = 6; // // tabControlLibFilter @@ -2690,7 +2875,7 @@ private void InitializeComponent() this.tabControlLibFilter.Location = new System.Drawing.Point(3, 415); this.tabControlLibFilter.Name = "tabControlLibFilter"; this.tabControlLibFilter.SelectedIndex = 0; - this.tabControlLibFilter.Size = new System.Drawing.Size(189, 319); + this.tabControlLibFilter.Size = new System.Drawing.Size(189, 354); this.tabControlLibFilter.TabIndex = 5; // // tabPage1 @@ -2699,7 +2884,7 @@ private void InitializeComponent() this.tabPage1.Location = new System.Drawing.Point(4, 22); this.tabPage1.Name = "tabPage1"; this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(181, 293); + this.tabPage1.Size = new System.Drawing.Size(181, 328); this.tabPage1.TabIndex = 0; this.tabPage1.Text = "Species"; this.tabPage1.UseVisualStyleBackColor = true; @@ -2710,7 +2895,7 @@ private void InitializeComponent() this.listBoxSpeciesLib.FormattingEnabled = true; this.listBoxSpeciesLib.Location = new System.Drawing.Point(3, 3); this.listBoxSpeciesLib.Name = "listBoxSpeciesLib"; - this.listBoxSpeciesLib.Size = new System.Drawing.Size(175, 287); + this.listBoxSpeciesLib.Size = new System.Drawing.Size(175, 322); this.listBoxSpeciesLib.TabIndex = 0; this.listBoxSpeciesLib.Click += new System.EventHandler(this.listBoxSpeciesLib_Click); this.listBoxSpeciesLib.SelectedIndexChanged += new System.EventHandler(this.listBoxSpeciesLib_SelectedIndexChanged); @@ -2721,7 +2906,7 @@ private void InitializeComponent() this.tabPage3.Location = new System.Drawing.Point(4, 22); this.tabPage3.Name = "tabPage3"; this.tabPage3.Padding = new System.Windows.Forms.Padding(3); - this.tabPage3.Size = new System.Drawing.Size(181, 293); + this.tabPage3.Size = new System.Drawing.Size(181, 328); this.tabPage3.TabIndex = 2; this.tabPage3.Text = "Stats"; this.tabPage3.UseVisualStyleBackColor = true; @@ -2740,7 +2925,7 @@ private void InitializeComponent() this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F)); - this.tableLayoutPanel2.Size = new System.Drawing.Size(175, 287); + this.tableLayoutPanel2.Size = new System.Drawing.Size(175, 322); this.tableLayoutPanel2.TabIndex = 0; // // checkedListBoxConsiderStatTop @@ -2750,13 +2935,13 @@ private void InitializeComponent() this.checkedListBoxConsiderStatTop.FormattingEnabled = true; this.checkedListBoxConsiderStatTop.Location = new System.Drawing.Point(3, 35); this.checkedListBoxConsiderStatTop.Name = "checkedListBoxConsiderStatTop"; - this.checkedListBoxConsiderStatTop.Size = new System.Drawing.Size(169, 220); + this.checkedListBoxConsiderStatTop.Size = new System.Drawing.Size(169, 255); this.checkedListBoxConsiderStatTop.TabIndex = 3; // // buttonRecalculateTops // this.buttonRecalculateTops.Dock = System.Windows.Forms.DockStyle.Fill; - this.buttonRecalculateTops.Location = new System.Drawing.Point(3, 261); + this.buttonRecalculateTops.Location = new System.Drawing.Point(3, 296); this.buttonRecalculateTops.Name = "buttonRecalculateTops"; this.buttonRecalculateTops.Size = new System.Drawing.Size(169, 23); this.buttonRecalculateTops.TabIndex = 2; @@ -2779,7 +2964,7 @@ private void InitializeComponent() this.tabPageLibRadarChart.Location = new System.Drawing.Point(4, 22); this.tabPageLibRadarChart.Name = "tabPageLibRadarChart"; this.tabPageLibRadarChart.Padding = new System.Windows.Forms.Padding(3); - this.tabPageLibRadarChart.Size = new System.Drawing.Size(181, 293); + this.tabPageLibRadarChart.Size = new System.Drawing.Size(181, 328); this.tabPageLibRadarChart.TabIndex = 4; this.tabPageLibRadarChart.Text = "Chart"; this.tabPageLibRadarChart.UseVisualStyleBackColor = true; @@ -2811,7 +2996,7 @@ private void InitializeComponent() this.tabPageLibraryInfo.Location = new System.Drawing.Point(4, 22); this.tabPageLibraryInfo.Name = "tabPageLibraryInfo"; this.tabPageLibraryInfo.Padding = new System.Windows.Forms.Padding(3); - this.tabPageLibraryInfo.Size = new System.Drawing.Size(1870, 749); + this.tabPageLibraryInfo.Size = new System.Drawing.Size(1870, 784); this.tabPageLibraryInfo.TabIndex = 14; this.tabPageLibraryInfo.Text = "Library Info"; this.tabPageLibraryInfo.UseVisualStyleBackColor = true; @@ -2829,7 +3014,7 @@ private void InitializeComponent() this.tlpLibraryInfo.Name = "tlpLibraryInfo"; this.tlpLibraryInfo.RowCount = 1; this.tlpLibraryInfo.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tlpLibraryInfo.Size = new System.Drawing.Size(1864, 743); + this.tlpLibraryInfo.Size = new System.Drawing.Size(1864, 778); this.tlpLibraryInfo.TabIndex = 0; // // CbLibraryInfoUseFilter @@ -2859,7 +3044,7 @@ private void InitializeComponent() this.tabPagePedigree.Location = new System.Drawing.Point(4, 22); this.tabPagePedigree.Name = "tabPagePedigree"; this.tabPagePedigree.Padding = new System.Windows.Forms.Padding(3); - this.tabPagePedigree.Size = new System.Drawing.Size(1870, 749); + this.tabPagePedigree.Size = new System.Drawing.Size(1870, 784); this.tabPagePedigree.TabIndex = 3; this.tabPagePedigree.Text = "Pedigree"; this.tabPagePedigree.UseVisualStyleBackColor = true; @@ -2871,7 +3056,7 @@ private void InitializeComponent() this.pedigree1.LeftColumnWidth = 203; this.pedigree1.Location = new System.Drawing.Point(3, 3); this.pedigree1.Name = "pedigree1"; - this.pedigree1.Size = new System.Drawing.Size(1864, 743); + this.pedigree1.Size = new System.Drawing.Size(1864, 778); this.pedigree1.TabIndex = 0; // // tabPageTaming @@ -2880,7 +3065,7 @@ private void InitializeComponent() this.tabPageTaming.Location = new System.Drawing.Point(4, 22); this.tabPageTaming.Name = "tabPageTaming"; this.tabPageTaming.Padding = new System.Windows.Forms.Padding(3); - this.tabPageTaming.Size = new System.Drawing.Size(1870, 749); + this.tabPageTaming.Size = new System.Drawing.Size(1870, 784); this.tabPageTaming.TabIndex = 8; this.tabPageTaming.Text = "Taming"; this.tabPageTaming.UseVisualStyleBackColor = true; @@ -2891,7 +3076,7 @@ private void InitializeComponent() this.tamingControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tamingControl1.Location = new System.Drawing.Point(3, 3); this.tamingControl1.Name = "tamingControl1"; - this.tamingControl1.Size = new System.Drawing.Size(1864, 743); + this.tamingControl1.Size = new System.Drawing.Size(1864, 778); this.tamingControl1.TabIndex = 0; this.tamingControl1.WeaponDamages = new double[] { 100D, @@ -2909,7 +3094,7 @@ private void InitializeComponent() this.tabPageBreedingPlan.Location = new System.Drawing.Point(4, 22); this.tabPageBreedingPlan.Name = "tabPageBreedingPlan"; this.tabPageBreedingPlan.Padding = new System.Windows.Forms.Padding(3); - this.tabPageBreedingPlan.Size = new System.Drawing.Size(1870, 749); + this.tabPageBreedingPlan.Size = new System.Drawing.Size(1870, 784); this.tabPageBreedingPlan.TabIndex = 4; this.tabPageBreedingPlan.Text = "Breeding Plan"; this.tabPageBreedingPlan.UseVisualStyleBackColor = true; @@ -2922,7 +3107,7 @@ private void InitializeComponent() this.breedingPlan1.Location = new System.Drawing.Point(3, 3); this.breedingPlan1.MutationLimit = 0; this.breedingPlan1.Name = "breedingPlan1"; - this.breedingPlan1.Size = new System.Drawing.Size(1864, 743); + this.breedingPlan1.Size = new System.Drawing.Size(1864, 778); this.breedingPlan1.TabIndex = 0; // // tabPageHatching @@ -2931,7 +3116,7 @@ private void InitializeComponent() this.tabPageHatching.Location = new System.Drawing.Point(4, 22); this.tabPageHatching.Name = "tabPageHatching"; this.tabPageHatching.Padding = new System.Windows.Forms.Padding(3); - this.tabPageHatching.Size = new System.Drawing.Size(1870, 749); + this.tabPageHatching.Size = new System.Drawing.Size(1870, 784); this.tabPageHatching.TabIndex = 13; this.tabPageHatching.Text = "Hatching"; this.tabPageHatching.UseVisualStyleBackColor = true; @@ -2941,7 +3126,7 @@ private void InitializeComponent() this.hatching1.Dock = System.Windows.Forms.DockStyle.Fill; this.hatching1.Location = new System.Drawing.Point(3, 3); this.hatching1.Name = "hatching1"; - this.hatching1.Size = new System.Drawing.Size(1864, 743); + this.hatching1.Size = new System.Drawing.Size(1864, 778); this.hatching1.TabIndex = 0; // // tabPageRaising @@ -2950,7 +3135,7 @@ private void InitializeComponent() this.tabPageRaising.Location = new System.Drawing.Point(4, 22); this.tabPageRaising.Name = "tabPageRaising"; this.tabPageRaising.Padding = new System.Windows.Forms.Padding(3); - this.tabPageRaising.Size = new System.Drawing.Size(1870, 749); + this.tabPageRaising.Size = new System.Drawing.Size(1870, 784); this.tabPageRaising.TabIndex = 9; this.tabPageRaising.Text = "Raising"; this.tabPageRaising.UseVisualStyleBackColor = true; @@ -2961,7 +3146,7 @@ private void InitializeComponent() this.raisingControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.raisingControl1.Location = new System.Drawing.Point(3, 3); this.raisingControl1.Name = "raisingControl1"; - this.raisingControl1.Size = new System.Drawing.Size(1864, 743); + this.raisingControl1.Size = new System.Drawing.Size(1864, 778); this.raisingControl1.TabIndex = 0; // // tabPageTimer @@ -2970,7 +3155,7 @@ private void InitializeComponent() this.tabPageTimer.Location = new System.Drawing.Point(4, 22); this.tabPageTimer.Name = "tabPageTimer"; this.tabPageTimer.Padding = new System.Windows.Forms.Padding(3); - this.tabPageTimer.Size = new System.Drawing.Size(1870, 749); + this.tabPageTimer.Size = new System.Drawing.Size(1870, 784); this.tabPageTimer.TabIndex = 6; this.tabPageTimer.Text = "Timer"; this.tabPageTimer.UseVisualStyleBackColor = true; @@ -2980,7 +3165,7 @@ private void InitializeComponent() this.timerList1.Dock = System.Windows.Forms.DockStyle.Fill; this.timerList1.Location = new System.Drawing.Point(3, 3); this.timerList1.Name = "timerList1"; - this.timerList1.Size = new System.Drawing.Size(1864, 743); + this.timerList1.Size = new System.Drawing.Size(1864, 778); this.timerList1.TabIndex = 0; this.timerList1.TimerAlertsCSV = ""; // @@ -2990,7 +3175,7 @@ private void InitializeComponent() this.tabPagePlayerTribes.Location = new System.Drawing.Point(4, 22); this.tabPagePlayerTribes.Name = "tabPagePlayerTribes"; this.tabPagePlayerTribes.Padding = new System.Windows.Forms.Padding(3); - this.tabPagePlayerTribes.Size = new System.Drawing.Size(1870, 749); + this.tabPagePlayerTribes.Size = new System.Drawing.Size(1870, 784); this.tabPagePlayerTribes.TabIndex = 7; this.tabPagePlayerTribes.Text = "Player"; this.tabPagePlayerTribes.UseVisualStyleBackColor = true; @@ -3000,7 +3185,7 @@ private void InitializeComponent() this.tribesControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tribesControl1.Location = new System.Drawing.Point(3, 3); this.tribesControl1.Name = "tribesControl1"; - this.tribesControl1.Size = new System.Drawing.Size(1864, 743); + this.tribesControl1.Size = new System.Drawing.Size(1864, 778); this.tribesControl1.TabIndex = 0; // // tabPageNotes @@ -3009,7 +3194,7 @@ private void InitializeComponent() this.tabPageNotes.Location = new System.Drawing.Point(4, 22); this.tabPageNotes.Name = "tabPageNotes"; this.tabPageNotes.Padding = new System.Windows.Forms.Padding(3); - this.tabPageNotes.Size = new System.Drawing.Size(1870, 749); + this.tabPageNotes.Size = new System.Drawing.Size(1870, 784); this.tabPageNotes.TabIndex = 10; this.tabPageNotes.Text = "Notes"; this.tabPageNotes.UseVisualStyleBackColor = true; @@ -3019,7 +3204,7 @@ private void InitializeComponent() this.notesControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.notesControl1.Location = new System.Drawing.Point(3, 3); this.notesControl1.Name = "notesControl1"; - this.notesControl1.Size = new System.Drawing.Size(1864, 743); + this.notesControl1.Size = new System.Drawing.Size(1864, 778); this.notesControl1.TabIndex = 0; // // TabPageOCR @@ -3028,7 +3213,7 @@ private void InitializeComponent() this.TabPageOCR.Location = new System.Drawing.Point(4, 22); this.TabPageOCR.Name = "TabPageOCR"; this.TabPageOCR.Padding = new System.Windows.Forms.Padding(3); - this.TabPageOCR.Size = new System.Drawing.Size(1870, 749); + this.TabPageOCR.Size = new System.Drawing.Size(1870, 784); this.TabPageOCR.TabIndex = 5; this.TabPageOCR.Text = "Experimental OCR"; this.TabPageOCR.UseVisualStyleBackColor = true; @@ -3038,7 +3223,7 @@ private void InitializeComponent() this.ocrControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.ocrControl1.Location = new System.Drawing.Point(3, 3); this.ocrControl1.Name = "ocrControl1"; - this.ocrControl1.Size = new System.Drawing.Size(1864, 743); + this.ocrControl1.Size = new System.Drawing.Size(1864, 778); this.ocrControl1.TabIndex = 2; // // tabPageExtractionTests @@ -3047,7 +3232,7 @@ private void InitializeComponent() this.tabPageExtractionTests.Location = new System.Drawing.Point(4, 22); this.tabPageExtractionTests.Name = "tabPageExtractionTests"; this.tabPageExtractionTests.Padding = new System.Windows.Forms.Padding(3); - this.tabPageExtractionTests.Size = new System.Drawing.Size(1870, 749); + this.tabPageExtractionTests.Size = new System.Drawing.Size(1870, 784); this.tabPageExtractionTests.TabIndex = 11; this.tabPageExtractionTests.Text = "Extraction Tests"; this.tabPageExtractionTests.UseVisualStyleBackColor = true; @@ -3057,7 +3242,7 @@ private void InitializeComponent() this.extractionTestControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.extractionTestControl1.Location = new System.Drawing.Point(3, 3); this.extractionTestControl1.Name = "extractionTestControl1"; - this.extractionTestControl1.Size = new System.Drawing.Size(1864, 743); + this.extractionTestControl1.Size = new System.Drawing.Size(1864, 778); this.extractionTestControl1.TabIndex = 0; // // tabPageMultiplierTesting @@ -3066,7 +3251,7 @@ private void InitializeComponent() this.tabPageMultiplierTesting.Location = new System.Drawing.Point(4, 22); this.tabPageMultiplierTesting.Name = "tabPageMultiplierTesting"; this.tabPageMultiplierTesting.Padding = new System.Windows.Forms.Padding(3); - this.tabPageMultiplierTesting.Size = new System.Drawing.Size(1870, 749); + this.tabPageMultiplierTesting.Size = new System.Drawing.Size(1870, 784); this.tabPageMultiplierTesting.TabIndex = 12; this.tabPageMultiplierTesting.Text = "Multiplier Testing"; this.tabPageMultiplierTesting.UseVisualStyleBackColor = true; @@ -3076,7 +3261,7 @@ private void InitializeComponent() this.statsMultiplierTesting1.Dock = System.Windows.Forms.DockStyle.Fill; this.statsMultiplierTesting1.Location = new System.Drawing.Point(3, 3); this.statsMultiplierTesting1.Name = "statsMultiplierTesting1"; - this.statsMultiplierTesting1.Size = new System.Drawing.Size(1864, 743); + this.statsMultiplierTesting1.Size = new System.Drawing.Size(1864, 778); this.statsMultiplierTesting1.TabIndex = 0; // // btReadValuesFromArk @@ -3106,7 +3291,7 @@ private void InitializeComponent() this.toolStripProgressBar1, this.toolStripStatusLabel, this.ToolStripStatusLabelImport}); - this.statusStrip1.Location = new System.Drawing.Point(0, 878); + this.statusStrip1.Location = new System.Drawing.Point(0, 913); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Size = new System.Drawing.Size(1878, 22); this.statusStrip1.TabIndex = 44; @@ -3513,6 +3698,7 @@ private void InitializeComponent() // this.TbMessageLabel.AcceptsReturn = true; this.TbMessageLabel.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.TbMessageLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.TbMessageLabel.Location = new System.Drawing.Point(470, 3); this.TbMessageLabel.Multiline = true; this.TbMessageLabel.Name = "TbMessageLabel"; @@ -3525,24 +3711,62 @@ private void InitializeComponent() // contextMenuStripLibraryHeader // this.contextMenuStripLibraryHeader.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripMenuItemResetLibraryColumnWidths}); + this.toolStripMenuItemResetLibraryColumnWidths, + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem, + this.restoreMutationLevelsASAToolStripMenuItem, + this.collapseMutationsLevelsASEToolStripMenuItem, + this.toolStripSeparator27, + this.resetColumnOrderToolStripMenuItem}); this.contextMenuStripLibraryHeader.Name = "contextMenuStrip1"; - this.contextMenuStripLibraryHeader.Size = new System.Drawing.Size(180, 26); + this.contextMenuStripLibraryHeader.Size = new System.Drawing.Size(333, 120); // // toolStripMenuItemResetLibraryColumnWidths // this.toolStripMenuItemResetLibraryColumnWidths.Name = "toolStripMenuItemResetLibraryColumnWidths"; - this.toolStripMenuItemResetLibraryColumnWidths.Size = new System.Drawing.Size(179, 22); - this.toolStripMenuItemResetLibraryColumnWidths.Text = "Reset column width"; + this.toolStripMenuItemResetLibraryColumnWidths.Size = new System.Drawing.Size(332, 22); + this.toolStripMenuItemResetLibraryColumnWidths.Text = "Reset all column widths"; this.toolStripMenuItemResetLibraryColumnWidths.Click += new System.EventHandler(this.toolStripMenuItemResetLibraryColumnWidths_Click); // + // resetColumnWidthNoMutationLevelColumnsToolStripMenuItem + // + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem.Name = "resetColumnWidthNoMutationLevelColumnsToolStripMenuItem"; + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem.Size = new System.Drawing.Size(332, 22); + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem.Text = "Reset all column widths, collapse mutation levels"; + this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem.Click += new System.EventHandler(this.resetColumnWidthNoMutationLevelColumnsToolStripMenuItem_Click); + // + // restoreMutationLevelsASAToolStripMenuItem + // + this.restoreMutationLevelsASAToolStripMenuItem.Name = "restoreMutationLevelsASAToolStripMenuItem"; + this.restoreMutationLevelsASAToolStripMenuItem.Size = new System.Drawing.Size(332, 22); + this.restoreMutationLevelsASAToolStripMenuItem.Text = "Restore mutation levels (ASA)"; + this.restoreMutationLevelsASAToolStripMenuItem.Click += new System.EventHandler(this.restoreMutationLevelsASAToolStripMenuItem_Click); + // + // collapseMutationsLevelsASEToolStripMenuItem + // + this.collapseMutationsLevelsASEToolStripMenuItem.Name = "collapseMutationsLevelsASEToolStripMenuItem"; + this.collapseMutationsLevelsASEToolStripMenuItem.Size = new System.Drawing.Size(332, 22); + this.collapseMutationsLevelsASEToolStripMenuItem.Text = "Collapse mutations levels (ASE)"; + this.collapseMutationsLevelsASEToolStripMenuItem.Click += new System.EventHandler(this.collapseMutationsLevelsASEToolStripMenuItem_Click); + // + // toolStripSeparator27 + // + this.toolStripSeparator27.Name = "toolStripSeparator27"; + this.toolStripSeparator27.Size = new System.Drawing.Size(329, 6); + // + // resetColumnOrderToolStripMenuItem + // + this.resetColumnOrderToolStripMenuItem.Name = "resetColumnOrderToolStripMenuItem"; + this.resetColumnOrderToolStripMenuItem.Size = new System.Drawing.Size(332, 22); + this.resetColumnOrderToolStripMenuItem.Text = "Reset column order"; + this.resetColumnOrderToolStripMenuItem.Click += new System.EventHandler(this.resetColumnOrderToolStripMenuItem_Click); + // // speciesSelector1 // this.speciesSelector1.Dock = System.Windows.Forms.DockStyle.Fill; this.speciesSelector1.LastSpecies = new string[0]; this.speciesSelector1.Location = new System.Drawing.Point(0, 103); this.speciesSelector1.Name = "speciesSelector1"; - this.speciesSelector1.Size = new System.Drawing.Size(1878, 775); + this.speciesSelector1.Size = new System.Drawing.Size(1878, 810); this.speciesSelector1.SplitterDistance = 500; this.speciesSelector1.TabIndex = 0; // @@ -3552,7 +3776,7 @@ private void InitializeComponent() this.AllowDrop = true; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1878, 900); + this.ClientSize = new System.Drawing.Size(1878, 935); this.Controls.Add(this.tabControlMain); this.Controls.Add(this.speciesSelector1); this.Controls.Add(this.panelToolBar); @@ -3592,6 +3816,7 @@ private void InitializeComponent() this.panelWildTamedBred.PerformLayout(); this.tabControlMain.ResumeLayout(false); this.tabPageStatTesting.ResumeLayout(false); + this.tabPageStatTesting.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxColorRegionsTester)).EndInit(); this.gbStatChart.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.radarChart1)).EndInit(); @@ -3705,7 +3930,7 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader columnHeaderFo; private System.Windows.Forms.ColumnHeader columnHeaderWa; private System.Windows.Forms.ColumnHeader columnHeaderWe; - private System.Windows.Forms.ColumnHeader columnHeaderTemp; + private System.Windows.Forms.ColumnHeader columnHeaderTm; private System.Windows.Forms.ColumnHeader columnHeaderDm; private System.Windows.Forms.ColumnHeader columnHeaderSp; private System.Windows.Forms.ColumnHeader columnHeaderFr; @@ -3980,5 +4205,29 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader columnHeaderMutagen; private System.Windows.Forms.Label LbAsa; private System.Windows.Forms.ToolStripMenuItem discordServerToolStripMenuItem; + private System.Windows.Forms.ColumnHeader columnHeaderHPM; + private System.Windows.Forms.ColumnHeader columnHeaderStM; + private System.Windows.Forms.ColumnHeader columnHeaderToM; + private System.Windows.Forms.ColumnHeader columnHeaderOxM; + private System.Windows.Forms.ColumnHeader columnHeaderFoM; + private System.Windows.Forms.ColumnHeader columnHeaderWaM; + private System.Windows.Forms.ColumnHeader columnHeaderTmM; + private System.Windows.Forms.ColumnHeader columnHeaderWeM; + private System.Windows.Forms.ColumnHeader columnHeaderDmM; + private System.Windows.Forms.ColumnHeader columnHeaderSpM; + private System.Windows.Forms.ColumnHeader columnHeaderFrM; + private System.Windows.Forms.ColumnHeader columnHeaderCrM; + private System.Windows.Forms.ToolStripMenuItem resetColumnOrderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem resetColumnWidthNoMutationLevelColumnsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem restoreMutationLevelsASAToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem collapseMutationsLevelsASEToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator27; + private System.Windows.Forms.ToolStripMenuItem serverToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem listenToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem sendExampleCreatureToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem listenWithNewTokenToolStripMenuItem; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.CheckBox CbLinkWildMutatedLevelsTester; } } diff --git a/ARKBreedingStats/Form1.collection.cs b/ARKBreedingStats/Form1.collection.cs index b4a82a364..f4a9c5d75 100644 --- a/ARKBreedingStats/Form1.collection.cs +++ b/ARKBreedingStats/Form1.collection.cs @@ -793,11 +793,12 @@ private void OpenRecentlyUsedFile(object sender, EventArgs e) /// /// Imports creature from file created by the export gun mod. - /// Returns true if the last imported creature already exists in the library. + /// Returns already existing Creature or null if it's a new creature. /// - private bool ImportExportGunFiles(string[] filePaths, out bool creatureAdded, out Creature lastAddedCreature) + private Creature ImportExportGunFiles(string[] filePaths, out bool creatureAdded, out Creature lastAddedCreature, out bool copiedNameToClipboard) { creatureAdded = false; + copiedNameToClipboard = false; var newCreatures = new List(); var importedCounter = 0; @@ -807,7 +808,7 @@ private bool ImportExportGunFiles(string[] filePaths, out bool creatureAdded, ou string serverMultipliersHash = null; bool? multipliersImportSuccessful = null; string serverImportResult = null; - bool creatureAlreadyExists = false; + Creature alreadyExistingCreature = null; var gameSettingBefore = _creatureCollection.Game; foreach (var filePath in filePaths) @@ -861,12 +862,30 @@ private bool ImportExportGunFiles(string[] filePaths, out bool creatureAdded, ou lastAddedCreature = newCreatures.LastOrDefault(); if (lastAddedCreature != null) { - creatureAlreadyExists = IsCreatureAlreadyInLibrary(lastAddedCreature.guid, lastAddedCreature.ArkId, out _); creatureAdded = true; } + var totalCreatureCount = _creatureCollection.GetTotalCreatureCount(); + // select creature objects that will be in the library (i.e. new creature, or existing creature), and the old name + var persistentCreaturesAndOldName = newCreatures.Select(c => (creature: + IsCreatureAlreadyInLibrary(c.guid, c.ArkId, out alreadyExistingCreature) + ? alreadyExistingCreature + : c, oldName: alreadyExistingCreature?.name)).ToArray(); + _creatureCollection.MergeCreatureList(newCreatures, true); - UpdateCreatureParentLinkingSort(); + UpdateCreatureParentLinkingSort(false); + + // apply naming pattern if needed. This can only be done after parent linking to get correct name pattern values related to parents + Species lastSpecies = null; + Creature[] creaturesOfSpecies = null; + foreach (var c in persistentCreaturesAndOldName) + { + copiedNameToClipboard = SetNameOfImportedCreature(c.creature, lastSpecies == c.creature.Species ? creaturesOfSpecies : null, out creaturesOfSpecies, new Creature(c.creature.Species, c.oldName), totalCreatureCount); + lastSpecies = c.creature.Species; + if (c.oldName == null) totalCreatureCount++; // if creature was added, increase total count for name pattern + } + + UpdateListsAfterCreaturesAdded(); var resultText = (importedCounter > 0 || importFailedCounter > 0 ? $"Imported {importedCounter} creatures successfully.{(importFailedCounter > 0 ? $"Failed to import {importFailedCounter} files. Last error:{Environment.NewLine}{lastError}" : $"{Environment.NewLine}Last file: {lastCreatureFilePath}")}" @@ -884,16 +903,17 @@ private bool ImportExportGunFiles(string[] filePaths, out bool creatureAdded, ou if (listBoxSpeciesLib.SelectedItem != null && listBoxSpeciesLib.SelectedItem != lastAddedCreature.Species) listBoxSpeciesLib.SelectedItem = lastAddedCreature.Species; + _ignoreNextMessageLabel = true; // keep import message SelectCreatureInLibrary(lastAddedCreature); } - return creatureAlreadyExists; + return alreadyExistingCreature; } /// /// Call after creatures were added (imported) to the library. Updates parent linkings, creature lists, set collection as changed /// - private void UpdateCreatureParentLinkingSort() + private void UpdateCreatureParentLinkingSort(bool updateLists = true) { UpdateParents(_creatureCollection.creatures); @@ -904,6 +924,13 @@ private void UpdateCreatureParentLinkingSort() UpdateIncubationParents(_creatureCollection); + if (updateLists) + UpdateListsAfterCreaturesAdded(); + } + + + private void UpdateListsAfterCreaturesAdded() + { // update UI SetCollectionChanged(true); UpdateCreatureListings(); @@ -916,5 +943,52 @@ private void UpdateCreatureParentLinkingSort() UpdateTempCreatureDropDown(); } + + /// + /// Imports a creature when listening to a server. + /// + private void AsbServerDataSent((string jsonData, string serverHash, string errorMessage) data) + { + if (!string.IsNullOrEmpty(data.errorMessage)) + { + SetMessageLabelText(data.errorMessage, MessageBoxIcon.Error); + // don't remove the error message with the stop listening message + _ignoreNextMessageLabel = true; + listenToolStripMenuItem.Checked = false; + return; + } + + string resultText; + if (string.IsNullOrEmpty(data.serverHash)) + { + // import creature + var creature = ImportExportGun.ImportCreatureFromJson(data.jsonData, null, out resultText, out _); + if (creature == null) + { + SetMessageLabelText(resultText, MessageBoxIcon.Error); + return; + } + + _creatureCollection.MergeCreatureList(new[] { creature }, true); + UpdateCreatureParentLinkingSort(); + + if (resultText == null) + resultText = $"Received creature from server: {creature}"; + + SetMessageLabelText(resultText, MessageBoxIcon.Information); + + tabControlMain.SelectedTab = tabPageLibrary; + if (listBoxSpeciesLib.SelectedItem != null && + listBoxSpeciesLib.SelectedItem != creature.Species) + listBoxSpeciesLib.SelectedItem = creature.Species; + _ignoreNextMessageLabel = true; + SelectCreatureInLibrary(creature); + return; + } + + // import server settings + var success = ImportExportGun.ImportServerMultipliersFromJson(_creatureCollection, data.jsonData, data.serverHash, out resultText); + SetMessageLabelText(resultText, success ? MessageBoxIcon.Information : MessageBoxIcon.Error, resultText); + } } } diff --git a/ARKBreedingStats/Form1.cs b/ARKBreedingStats/Form1.cs index 9a4550432..f170a44c5 100644 --- a/ARKBreedingStats/Form1.cs +++ b/ARKBreedingStats/Form1.cs @@ -14,13 +14,14 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Threading.Tasks; using System.Windows.Forms; -using ARKBreedingStats.importExportGun; using ARKBreedingStats.mods; using ARKBreedingStats.NamePatterns; using ARKBreedingStats.utils; using static ARKBreedingStats.settings.Settings; using Color = System.Drawing.Color; +using Newtonsoft.Json.Linq; namespace ARKBreedingStats { @@ -54,7 +55,7 @@ public delegate void bool triggeredByFileWatcher = false); public delegate void SetMessageLabelTextEventHandler(string text = null, - MessageBoxIcon icon = MessageBoxIcon.None, string actionInfo = null); + MessageBoxIcon icon = MessageBoxIcon.None, string path = null, string clipboardContent = null); private bool _updateTorporInTester; private bool _filterListAllowed; @@ -214,6 +215,7 @@ public Form1() statIoTesting.LevelChanged += TestingStatIoValueUpdate; statIo.InputValueChanged += StatIOQuickWildLevelCheck; + statIo.LevelChanged += ExtractorStatLevelChanged; statIo.Click += StatIO_Click; _considerStatHighlight[s] = (Properties.Settings.Default.consideredStats & (1 << s)) != 0; @@ -250,20 +252,31 @@ private void Form1_Load(object sender, EventArgs e) Properties.Settings.Default.MainWindowMaximized); // Load column-widths, display-indices and sort-order of the TimerControlListView - LoadListViewSettings(timerList1.ListViewTimers, "TCLVColumnWidths", "TCLVColumnDisplayIndices", "TCLVSortCol", "TCLVSortAsc"); + + LoadListViewSettings(timerList1.ListViewTimers, nameof(Properties.Settings.Default.TCLVColumnWidths), + nameof(Properties.Settings.Default.TCLVColumnDisplayIndices), + nameof(Properties.Settings.Default.TCLVSortCol), nameof(Properties.Settings.Default.TCLVSortAsc)); if (Properties.Settings.Default.PedigreeWidthLeftColum > 20) pedigree1.LeftColumnWidth = Properties.Settings.Default.PedigreeWidthLeftColum; - LoadListViewSettings(pedigree1.ListViewCreatures, "PedigreeListViewColumnWidths"); + LoadListViewSettings(pedigree1.ListViewCreatures, nameof(Properties.Settings.Default.PedigreeListViewColumnWidths)); // Load column-widths, display-indices and sort-order of the listViewLibrary - LoadListViewSettings(listViewLibrary, "columnWidths", "libraryColumnDisplayIndices"); + // new columns were added, reset widths and order, old settings don't match the new indices + if ((Properties.Settings.Default.columnWidths?.Length ?? 0) < 40) + { + resetColumnOrderToolStripMenuItem_Click(null, null); + toolStripMenuItemResetLibraryColumnWidths_Click(null, null); + } + else + LoadListViewSettings(listViewLibrary, nameof(Properties.Settings.Default.columnWidths), nameof(Properties.Settings.Default.libraryColumnDisplayIndices)); _creatureListSorter.SortColumnIndex = Properties.Settings.Default.listViewSortCol; _creatureListSorter.Order = Properties.Settings.Default.listViewSortAsc ? SortOrder.Ascending : SortOrder.Descending; - LoadListViewSettings(tribesControl1.ListViewPlayers, "PlayerListColumnWidths", "PlayerListColumnDisplayIndices", "PlayerListSortColumn", "PlayerListSortAsc"); + LoadListViewSettings(tribesControl1.ListViewPlayers, nameof(Properties.Settings.Default.PlayerListColumnWidths), nameof(Properties.Settings.Default.PlayerListColumnDisplayIndices), + nameof(Properties.Settings.Default.PlayerListSortColumn), nameof(Properties.Settings.Default.PlayerListSortAsc)); _creatureListSorter.UseNaturalSort = Properties.Settings.Default.UseNaturalSort; _creatureListSorter.IgnoreSpacesBetweenWords = Properties.Settings.Default.NaturalSortIgnoreSpaces; @@ -369,9 +382,6 @@ private void Form1_Load(object sender, EventArgs e) //// initialize controls - radarChart1.InitializeVariables(_creatureCollection.maxChartLevel); - radarChartExtractor.InitializeVariables(_creatureCollection.maxChartLevel); - radarChartLibrary.InitializeVariables(_creatureCollection.maxChartLevel); extractionTestControl1.CopyToExtractor += ExtractionTestControl1_CopyToExtractor; extractionTestControl1.CopyToTester += ExtractionTestControl1_CopyToTester; @@ -381,6 +391,7 @@ private void Form1_Load(object sender, EventArgs e) tabControlMain.TabPages.Remove(tabPageExtractionTests); tabControlMain.TabPages.Remove(tabPageMultiplierTesting); devToolStripMenuItem.Visible = false; + sendExampleCreatureToolStripMenuItem.Visible = false; } else { @@ -633,6 +644,7 @@ private void SpeciesSelector1OnSpeciesSelected(bool speciesChanged) creatureInfoInputExtractor.SelectedSpecies = species; creatureInfoInputTester.SelectedSpecies = species; + radarChart1.SetLevels(species: species); var statNames = species.statNames; for (int s = 0; s < Stats.StatsCount; s++) @@ -680,7 +692,7 @@ private void SpeciesSelector1OnSpeciesSelected(bool speciesChanged) { UpdateAllTesterValues(); statPotentials1.Species = species; - statPotentials1.SetLevels(_testingIOs.Select(s => s.LevelWild).ToArray(), true); + statPotentials1.SetLevels(_testingIOs.Select(s => s.LevelWild).ToArray(), _testingIOs.Select(s => s.LevelMut).ToArray(), true); SetTesterInfoInputCreature(); } else if (tabControlMain.SelectedTab == tabPageLibrary) @@ -1155,6 +1167,7 @@ private void UpdateParentListInput(CreatureInfoInput input) .Where(c => c.Species == speciesSelector1.SelectedSpecies).ToArray(); input.parentListValid = true; input.NamesOfAllCreatures = _creatureCollection.creatures.Select(c => c.name).ToList(); + input.LibraryCreatureCount = _creatureCollection.creatures.Count; } private void newToolStripMenuItem_Click(object sender, EventArgs e) @@ -1338,8 +1351,9 @@ private void Form1_FormClosed(object sender, FormClosedEventArgs e) /// Text to display /// Back color of the message /// If valid path to file or folder, the user can click on the message to display the path in the explorer + /// If not null, user can copy this text to the clipboard by clicking on the label private void SetMessageLabelText(string text = null, MessageBoxIcon icon = MessageBoxIcon.None, - string path = null) + string path = null, string clipboardText = null) { if (_ignoreNextMessageLabel) { @@ -1348,7 +1362,7 @@ private void SetMessageLabelText(string text = null, MessageBoxIcon icon = Messa } // a TextBox needs \r\n for a new line, only \n will not result in a line break. TbMessageLabel.Text = text; - SetMessageLabelLink(path); + SetMessageLabelLink(path, clipboardText); switch (icon) { @@ -1370,11 +1384,13 @@ private void SetMessageLabelText(string text = null, MessageBoxIcon icon = Messa /// /// If valid path to file or folder, the user can click on the message to display the path in the explorer /// - private void SetMessageLabelLink(string path = null) + private void SetMessageLabelLink(string path = null, string clipboardText = null) { - _librarySelectionInfoClickPath = path; + _messageLabelPath = path; + _messageLabelClipboardContent = clipboardText; - if (string.IsNullOrEmpty(path)) + if (string.IsNullOrEmpty(path) + && string.IsNullOrEmpty(clipboardText)) { TbMessageLabel.Cursor = null; _tt.SetToolTip(TbMessageLabel, null); @@ -1382,14 +1398,22 @@ private void SetMessageLabelLink(string path = null) else { TbMessageLabel.Cursor = Cursors.Hand; - _tt.SetToolTip(TbMessageLabel, Loc.S("ClickDisplayFile")); + _tt.SetToolTip(TbMessageLabel, + (string.IsNullOrEmpty(path) ? string.Empty : Loc.S("ClickDisplayFile")) + + (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(clipboardText) ? Environment.NewLine : string.Empty) + + (string.IsNullOrEmpty(clipboardText) ? string.Empty : Loc.S("ClickCopyToClipboard"))); } } /// /// Contains the path to open if the library selection info label is clicked, used to open the path in the explorer. /// - private string _librarySelectionInfoClickPath; + private string _messageLabelPath; + + /// + /// Contains the content to copy to the clipboard if the message label is clicked. + /// + private string _messageLabelClipboardContent; /// /// If true, the next message is ignored to preserve the previous one. This is used to avoid that the library selection info overwrites the results of the save game import. @@ -1398,7 +1422,9 @@ private void SetMessageLabelLink(string path = null) private void TbMessageLabel_Click(object sender, EventArgs e) { - OpenFolderInExplorer(_librarySelectionInfoClickPath); + if (!string.IsNullOrEmpty(_messageLabelClipboardContent)) + Clipboard.SetText(_messageLabelClipboardContent); + OpenFolderInExplorer(_messageLabelPath); } private void listBoxSpeciesLib_SelectedIndexChanged(object sender, EventArgs e) @@ -1554,7 +1580,7 @@ private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { UpdateAllTesterValues(); statPotentials1.Species = speciesSelector1.SelectedSpecies; - statPotentials1.SetLevels(_testingIOs.Select(s => s.LevelWild).ToArray(), true); + statPotentials1.SetLevels(_testingIOs.Select(s => s.LevelWild).ToArray(), _testingIOs.Select(s => s.LevelMut).ToArray(), true); } else if (tabControlMain.SelectedTab == tabPageLibrary) { @@ -2009,6 +2035,7 @@ private void OpenSettingsDialog(SettingsTabPages page = SettingsTabPages.Unknown if (Properties.Settings.Default.DevTools) statsMultiplierTesting1.CheckIfMultipliersAreEqualToSettings(); devToolStripMenuItem.Visible = Properties.Settings.Default.DevTools; + sendExampleCreatureToolStripMenuItem.Visible = Properties.Settings.Default.DevTools; bool recalculateTopStats = considerWastedStatsForTopCreatures != Properties.Settings.Default.ConsiderWastedStatsForTopCreatures; if (recalculateTopStats) @@ -2084,6 +2111,7 @@ private void StatIOQuickWildLevelCheck(StatIO sIo) (speciesSelector1.SelectedSpecies.stats[sIo.statIndex].BaseValue * speciesSelector1.SelectedSpecies.stats[sIo.statIndex].IncPerWildLevel)); sIo.LevelWild = lvlWild < 0 ? 0 : lvlWild; + sIo.LevelMut = 0; sIo.LevelDom = 0; if (sIo.statIndex == Stats.Torpidity) { @@ -2462,6 +2490,7 @@ private void toolStripButtonCopy2Tester_Click(object sender, EventArgs e) for (int s = 0; s < Stats.StatsCount; s++) { _testingIOs[s].LevelWild = _statIOs[s].LevelWild; + _testingIOs[s].LevelMut = _statIOs[s].LevelMut; _testingIOs[s].LevelDom = _statIOs[s].LevelDom; TestingStatIoValueUpdate(_testingIOs[s]); } @@ -2501,8 +2530,9 @@ private void toolStripButtonClear_Click(object sender, EventArgs e) { for (int s = 0; s < Stats.StatsCount; s++) { - _testingIOs[s].LevelDom = 0; _testingIOs[s].LevelWild = 0; + _testingIOs[s].LevelMut = 0; + _testingIOs[s].LevelDom = 0; } creatureInfoInputTester.Clear(); @@ -2669,7 +2699,7 @@ private void labelImprintedCount_MouseClick(object sender, MouseEventArgs e) double imprintingBonus = imprintingFactorTorpor != 0 ? (_statIOs[Stats.Torpidity].Input / StatValueCalculation.CalculateValue( speciesSelector1.SelectedSpecies, Stats.Torpidity, - _testingIOs[Stats.Torpidity].LevelWild, 0, true, 1, 0) - 1) / imprintingFactorTorpor + _testingIOs[Stats.Torpidity].LevelWild, 0, 0, true, 1, 0) - 1) / imprintingFactorTorpor : 0; if (imprintingBonus < 0) imprintingBonus = 0; @@ -2875,7 +2905,7 @@ private void toolStripCBTempCreatures_SelectedIndexChanged(object sender, EventA toolStripCBTempCreatures.SelectedIndex < _creatureCollection.creaturesValues.Count) { ExtractValuesInExtractor(_creatureCollection.creaturesValues[toolStripCBTempCreatures.SelectedIndex], - null, false, false); + null, false, false, out _); toolStripButtonDeleteTempCreature.Visible = true; } else @@ -2890,6 +2920,7 @@ private void SetCreatureValuesToTester(CreatureValues cv) for (int s = 0; s < Stats.StatsCount; s++) { _testingIOs[s].LevelWild = cv.levelsWild[s]; + _testingIOs[s].LevelMut = cv.levelsMut[s]; _testingIOs[s].LevelDom = cv.levelsDom[s]; } @@ -3003,7 +3034,7 @@ private void UpdateTempCreatureDropDown() /// Collects the data needed for the name pattern editor. /// private void CreatureInfoInput_CreatureDataRequested(CreatureInfoInput input, bool openPatternEditor, - bool updateInheritance, bool showDuplicateNameWarning, int namingPatternIndex) + bool updateInheritance, bool showDuplicateNameWarning, int namingPatternIndex, Creature alreadyExistingCreature) { var cr = CreateCreatureFromExtractorOrTester(input); @@ -3029,7 +3060,7 @@ private void CreatureInfoInput_CreatureDataRequested(CreatureInfoInput input, bo colorAlreadyExistingInformation = _creatureCollection.ColorAlreadyAvailable(cr.Species, input.RegionColors, out _); input.ColorAlreadyExistingInformation = colorAlreadyExistingInformation; - input.GenerateCreatureName(cr, _topLevels.TryGetValue(cr.Species, out var tl) ? tl : null, + input.GenerateCreatureName(cr, alreadyExistingCreature, _topLevels.TryGetValue(cr.Species, out var tl) ? tl : null, _lowestLevels.TryGetValue(cr.Species, out var ll) ? ll : null, _customReplacingNamingPattern, showDuplicateNameWarning, namingPatternIndex); if (Properties.Settings.Default.PatternNameToClipboardAfterManualApplication) @@ -3053,6 +3084,7 @@ private Creature CreateCreatureFromExtractorOrTester(CreatureInfoInput input) if (input == creatureInfoInputExtractor) { cr.levelsWild = _statIOs.Select(s => s.LevelWild).ToArray(); + cr.levelsMutated = _statIOs.Select(s => s.LevelMut).ToArray(); cr.imprintingBonus = _extractor.ImprintingBonus; cr.tamingEff = _extractor.UniqueTamingEffectiveness(); cr.isBred = rbBredExtractor.Checked; @@ -3062,6 +3094,7 @@ private Creature CreateCreatureFromExtractorOrTester(CreatureInfoInput input) else { cr.levelsWild = _testingIOs.Select(s => s.LevelWild).ToArray(); + cr.levelsMutated = _testingIOs.Select(s => s.LevelMut).ToArray(); cr.imprintingBonus = (double)numericUpDownImprintingBonusTester.Value / 100; cr.tamingEff = TamingEffectivenessTester; cr.isBred = rbBredTester.Checked; @@ -3236,7 +3269,7 @@ private void copyToMultiplierTesterToolStripButton_Click(object sender, EventArg { statValues[s] = _statIOs[s].IsActive ? _statIOs[s].Input - : StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, s, 0, 0, tamed || bred); + : StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, s, 0, 0, 0, tamed || bred); } var wildLevels = GetCurrentWildLevels(false); @@ -3346,7 +3379,7 @@ private void ProcessDroppedFiles(string[] files) OpenCompressedFile(filePath, true); return; case ".ini" when files.Length == 1: - ExtractExportedFileInExtractor(filePath); + ExtractExportedFileInExtractor(filePath, out _, out _); break; case ".ini": ShowExportedCreatureListControl(); @@ -3354,7 +3387,7 @@ private void ProcessDroppedFiles(string[] files) break; case ".sav": case ".json": - ImportExportGunFiles(files, out _, out _); + ImportExportGunFiles(files, out _, out _, out _); break; case ".asb": case ".xml": @@ -3469,6 +3502,7 @@ private void GenerateCreatureNames() var creaturesToUpdate = new List(); Creature[] sameSpecies = null; + var libraryCreatureCount = _creatureCollection.GetTotalCreatureCount(); foreach (int i in listViewLibrary.SelectedIndices) { @@ -3478,10 +3512,10 @@ private void GenerateCreatureNames() sameSpecies = _creatureCollection.creatures.Where(c => c.Species == cr.Species).ToArray(); // set new name - cr.name = NamePattern.GenerateCreatureName(cr, sameSpecies, + cr.name = NamePattern.GenerateCreatureName(cr, cr, sameSpecies, _topLevels.ContainsKey(cr.Species) ? _topLevels[cr.Species] : null, _lowestLevels.ContainsKey(cr.Species) ? _lowestLevels[cr.Species] : null, - _customReplacingNamingPattern, false, 0); + _customReplacingNamingPattern, false, 0, libraryCreatureCount: libraryCreatureCount); creaturesToUpdate.Add(cr); } @@ -3547,12 +3581,6 @@ private void ReloadNamePatternCustomReplacings(PatternEditor pe = null) else if (pe != null) pe.SetCustomReplacings(_customReplacingNamingPattern); } - private void toolStripMenuItemResetLibraryColumnWidths_Click(object sender, EventArgs e) - { - for (int ci = 0; ci < listViewLibrary.Columns.Count; ci++) - listViewLibrary.Columns[ci].Width = ((ci >= ColumnIndexFirstStat && ci < ColumnIndexPostColor) || ci == ColumnIndexMutagenApplied) ? 30 : 60; - } - private void copyInfographicToClipboardToolStripMenuItem_Click(object sender, EventArgs e) { if (listViewLibrary.SelectedIndices.Count != 0) @@ -3822,5 +3850,53 @@ private void discordServerToolStripMenuItem_Click(object sender, EventArgs e) { Process.Start(RepositoryInfo.DiscordServerInviteLink); } + + #region Server + + private void listenToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + if (listenToolStripMenuItem.Checked) + AsbServerStartListening(); + else AsbServerStopListening(); + } + + private void listenWithNewTokenToolStripMenuItem_Click(object sender, EventArgs e) + { + listenToolStripMenuItem.Checked = false; + Properties.Settings.Default.ExportServerToken = null; + listenToolStripMenuItem.Checked = true; + } + + private void AsbServerStartListening() + { + AsbServer.Connection.StopListening(); + var progressDataSent = new Progress<(string jsonText, string serverHash, string message)>(AsbServerDataSent); + if (string.IsNullOrEmpty(Properties.Settings.Default.ExportServerToken)) + Properties.Settings.Default.ExportServerToken = AsbServer.Connection.CreateNewToken(); + Task.Factory.StartNew(() => AsbServer.Connection.StartListeningAsync(progressDataSent, Properties.Settings.Default.ExportServerToken)); + MessageServerListening(Properties.Settings.Default.ExportServerToken); + } + + private void AsbServerStopListening() + { + AsbServer.Connection.StopListening(); + SetMessageLabelText($"ASB Server listening stopped using token: {Properties.Settings.Default.ExportServerToken}", MessageBoxIcon.Error); + } + + private void MessageServerListening(string token) + { + SetMessageLabelText($"Now listening to the export server using the token (also copied to clipboard){Environment.NewLine}{token}", MessageBoxIcon.Information, clipboardText: token); + if (!string.IsNullOrEmpty(token)) + Clipboard.SetText(token); + } + + private void sendExampleCreatureToolStripMenuItem_Click(object sender, EventArgs e) + { + // debug function, sends a test creature to the server + AsbServer.Connection.SendCreatureData(DummyCreatures.CreateCreature(speciesSelector1.SelectedSpecies), Properties.Settings.Default.ExportServerToken); + } + + #endregion + } } diff --git a/ARKBreedingStats/Form1.extractor.cs b/ARKBreedingStats/Form1.extractor.cs index efc2db3ae..9751feec3 100644 --- a/ARKBreedingStats/Form1.extractor.cs +++ b/ARKBreedingStats/Form1.extractor.cs @@ -9,7 +9,6 @@ using System.Linq; using System.Threading; using System.Windows.Forms; -using ARKBreedingStats.importExportGun; using ARKBreedingStats.utils; using ARKBreedingStats.ocr; @@ -114,7 +113,7 @@ private void ShowSumOfChosenLevels() bool allValid = valid && inbound && torporLevelValid && _extractor.ValidResults; if (allValid) { - radarChartExtractor.SetLevels(_statIOs.Select(s => s.LevelWild).ToArray()); + radarChartExtractor.SetLevels(_statIOs.Select(s => s.LevelWild).ToArray(), _statIOs.Select(s => s.LevelMut).ToArray(), speciesSelector1.SelectedSpecies); cbExactlyImprinting.BackColor = Color.Transparent; var species = speciesSelector1.SelectedSpecies; var checkTopLevels = _topLevels.TryGetValue(species, out int[] topSpeciesLevels); @@ -211,7 +210,7 @@ private void ShowSumOfChosenLevels() groupBoxRadarChartExtractor.Visible = allValid; creatureAnalysis1.Visible = allValid; // update inheritance info - CreatureInfoInput_CreatureDataRequested(creatureInfoInputExtractor, false, true, false, 0); + CreatureInfoInput_CreatureDataRequested(creatureInfoInputExtractor, false, true, false, 0, null); } /// @@ -257,7 +256,7 @@ private void ClearAll(bool clearExtraCreatureData = true) creatureInfoInputExtractor.SetArkId(0, false); } - creatureInfoInputExtractor.UpdateExistingCreature = false; + creatureInfoInputExtractor.AlreadyExistingCreature = null; } private void buttonExtract_Click(object sender, EventArgs e) @@ -476,6 +475,7 @@ private void UpdateQuickTamingInfo() { int lvlWild = (int)Math.Round((_statIOs[s].Input - speciesSelector1.SelectedSpecies.stats[s].BaseValue) / (speciesSelector1.SelectedSpecies.stats[s].BaseValue * speciesSelector1.SelectedSpecies.stats[s].IncPerWildLevel)); _statIOs[s].LevelWild = lvlWild < 0 ? 0 : lvlWild; + _statIOs[s].LevelMut = 0; _statIOs[s].LevelDom = 0; } SetQuickTamingInfo(_statIOs[Stats.Torpidity].LevelWild + 1); @@ -745,7 +745,7 @@ private void SetLevelCombination(int s, int i, bool validateCombination = false) { _statIOs[s].LevelWild = _extractor.Results[s][i].levelWild; _statIOs[s].LevelDom = _extractor.Results[s][i].levelDom; - _statIOs[s].BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, s, _extractor.Results[s][i].levelWild, 0, true, 1, 0); + _statIOs[s].BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, s, _extractor.Results[s][i].levelWild, 0, 0, true, 1, 0); _extractor.ChosenResults[s] = i; if (validateCombination) { @@ -788,7 +788,7 @@ private void SetWildUnknownLevelsAccordingToOthers() // if all other stats are unique, set level var statIndex = unknownLevelIndices[0]; _statIOs[statIndex].LevelWild = Math.Max(0, notDeterminedLevels); - _statIOs[statIndex].BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, statIndex, _statIOs[statIndex].LevelWild, 0, true, 1, 0); + _statIOs[statIndex].BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, statIndex, _statIOs[statIndex].LevelWild, 0, 0, true, 1, 0); return; default: // if not all other levels are unique, set the indifferent stats to unknown @@ -867,9 +867,11 @@ private void CopyExtractionToClipboard() /// Returns true if the creature already exists in the library. /// Returns null if file couldn't be loaded. /// - private bool? ExtractExportedFileInExtractor(string exportFilePath) + private bool? ExtractExportedFileInExtractor(string exportFilePath, out bool nameCopiedToClipboard, out Creature alreadyExistingCreature) { CreatureValues cv = null; + nameCopiedToClipboard = false; + alreadyExistingCreature = null; // if the file is blocked, try it again const int waitingTimeBase = 200; @@ -917,7 +919,7 @@ private void CopyExtractionToClipboard() && LoadModValuesOfCollection(_creatureCollection, true, true) && oldModHash != _creatureCollection.modListHash) { - return ExtractExportedFileInExtractor(exportFilePath); + return ExtractExportedFileInExtractor(exportFilePath, out nameCopiedToClipboard, out alreadyExistingCreature); } return false; @@ -925,8 +927,8 @@ private void CopyExtractionToClipboard() tabControlMain.SelectedTab = tabPageExtractor; - bool creatureAlreadyExists = ExtractValuesInExtractor(cv, exportFilePath, true); - GenerateCreatureNameAndCopyNameToClipboardIfSet(creatureAlreadyExists); + bool creatureAlreadyExists = ExtractValuesInExtractor(cv, exportFilePath, true, true, out alreadyExistingCreature); + nameCopiedToClipboard = GenerateCreatureNameAndCopyNameToClipboardIfSet(alreadyExistingCreature); return creatureAlreadyExists; } @@ -934,24 +936,20 @@ private void CopyExtractionToClipboard() /// /// Copies the creature name to the clipboard if the conditions according to the user settings are fulfilled. /// - /// - private void GenerateCreatureNameAndCopyNameToClipboardIfSet(bool creatureAlreadyExists) + private bool GenerateCreatureNameAndCopyNameToClipboardIfSet(Creature alreadyExistingCreature) { if (Properties.Settings.Default.applyNamePatternOnAutoImportAlways || (Properties.Settings.Default.applyNamePatternOnImportIfEmptyName && string.IsNullOrEmpty(creatureInfoInputExtractor.CreatureName)) - || (!creatureAlreadyExists + || (alreadyExistingCreature == null && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures) ) { - CreatureInfoInput_CreatureDataRequested(creatureInfoInputExtractor, false, false, false, 0); - if (Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied) - { - Clipboard.SetText(string.IsNullOrEmpty(creatureInfoInputExtractor.CreatureName) - ? "" - : creatureInfoInputExtractor.CreatureName); - } + CreatureInfoInput_CreatureDataRequested(creatureInfoInputExtractor, false, false, false, 0, alreadyExistingCreature); + return CopyCreatureNameToClipboardOnImportIfSetting(creatureInfoInputExtractor.CreatureName); } + + return false; } /// @@ -964,8 +962,8 @@ private void ExtractExportedFileInExtractor(importExported.ExportedCreatureContr if (ecc == null) return; - bool creatureAlreadyExists = ExtractValuesInExtractor(ecc.creatureValues, ecc.exportedFile, false); - GenerateCreatureNameAndCopyNameToClipboardIfSet(creatureAlreadyExists); + ExtractValuesInExtractor(ecc.creatureValues, ecc.exportedFile, false, true, out var alreadyExistingCreature); + GenerateCreatureNameAndCopyNameToClipboardIfSet(alreadyExistingCreature); // gets deleted in extractLevels() _exportedCreatureControl = ecc; @@ -974,7 +972,6 @@ private void ExtractExportedFileInExtractor(importExported.ExportedCreatureContr creatureInfoInputExtractor.CreatureOwner += _exportedCreatureList.ownerSuffix; } - /// /// Sets the values of a creature to the extractor and extracts its levels. /// It returns true if the creature is already present in the library. @@ -984,9 +981,9 @@ private void ExtractExportedFileInExtractor(importExported.ExportedCreatureContr /// /// If values from an export file with increased precision are given, extraction can be improved by using that. /// - private bool ExtractValuesInExtractor(CreatureValues cv, string filePath, bool autoExtraction, bool highPrecisionValues = true) + private bool ExtractValuesInExtractor(CreatureValues cv, string filePath, bool autoExtraction, bool highPrecisionValues, out Creature alreadyExistingCreature) { - bool creatureExists = IsCreatureAlreadyInLibrary(cv.guid, cv.ARKID, out Creature existingCreature); + bool creatureExists = IsCreatureAlreadyInLibrary(cv.guid, cv.ARKID, out alreadyExistingCreature); if (creatureExists) { @@ -994,9 +991,9 @@ private bool ExtractValuesInExtractor(CreatureValues cv, string filePath, bool a //if (string.IsNullOrEmpty(cv.server) && !string.IsNullOrEmpty(existingCreature.server)) // cv.server = existingCreature.server; - SetExistingValueIfNewValueIsEmpty(ref cv.server, ref existingCreature.server); - SetExistingValueIfNewValueIsEmpty(ref cv.tribe, ref existingCreature.tribe); - SetExistingValueIfNewValueIsEmpty(ref cv.note, ref existingCreature.note); + SetExistingValueIfNewValueIsEmpty(ref cv.server, ref alreadyExistingCreature.server); + SetExistingValueIfNewValueIsEmpty(ref cv.tribe, ref alreadyExistingCreature.tribe); + SetExistingValueIfNewValueIsEmpty(ref cv.note, ref alreadyExistingCreature.note); void SetExistingValueIfNewValueIsEmpty(ref string newValue, ref string oldValue) { @@ -1006,26 +1003,26 @@ void SetExistingValueIfNewValueIsEmpty(ref string newValue, ref string oldValue) // ARK doesn't export parent and mutation info always // if export file doesn't contain parent info, use the existing ones - if (cv.Mother == null && cv.motherArkId == 0 && existingCreature.Mother != null) - cv.Mother = existingCreature.Mother; - if (cv.Father == null && cv.fatherArkId == 0 && existingCreature.Father != null) - cv.Father = existingCreature.Father; + if (cv.Mother == null && cv.motherArkId == 0 && alreadyExistingCreature.Mother != null) + cv.Mother = alreadyExistingCreature.Mother; + if (cv.Father == null && cv.fatherArkId == 0 && alreadyExistingCreature.Father != null) + cv.Father = alreadyExistingCreature.Father; // if export file doesn't contain mutation info and existing creature does, use that - if (cv.mutationCounterMother == 0 && existingCreature.mutationsMaternal != 0) - cv.mutationCounterMother = existingCreature.mutationsMaternal; - if (cv.mutationCounterFather == 0 && existingCreature.mutationsPaternal != 0) - cv.mutationCounterFather = existingCreature.mutationsPaternal; + if (cv.mutationCounterMother == 0 && alreadyExistingCreature.mutationsMaternal != 0) + cv.mutationCounterMother = alreadyExistingCreature.mutationsMaternal; + if (cv.mutationCounterFather == 0 && alreadyExistingCreature.mutationsPaternal != 0) + cv.mutationCounterFather = alreadyExistingCreature.mutationsPaternal; // if existing creature has no altColorIds, don't add them again - if (existingCreature.ColorIdsAlsoPossible == null) + if (alreadyExistingCreature.ColorIdsAlsoPossible == null) cv.ColorIdsAlsoPossible = null; else if (cv.ColorIdsAlsoPossible != null) { - var l = Math.Min(cv.ColorIdsAlsoPossible.Length, existingCreature.ColorIdsAlsoPossible.Length); + var l = Math.Min(cv.ColorIdsAlsoPossible.Length, alreadyExistingCreature.ColorIdsAlsoPossible.Length); for (int i = 0; i < l; i++) { - cv.ColorIdsAlsoPossible[i] = existingCreature.ColorIdsAlsoPossible[i]; + cv.ColorIdsAlsoPossible[i] = alreadyExistingCreature.ColorIdsAlsoPossible[i]; } } } @@ -1035,12 +1032,12 @@ void SetExistingValueIfNewValueIsEmpty(ref string newValue, ref string oldValue) // exported stat-files have values for all stats, so activate all stats the species uses SetStatsActiveAccordingToUsage(cv.Species); - ExtractLevels(autoExtraction, highPrecisionValues, existingCreature: existingCreature, possiblyMutagenApplied: cv.flags.HasFlag(CreatureFlags.MutagenApplied)); + ExtractLevels(autoExtraction, highPrecisionValues, existingCreature: alreadyExistingCreature, possiblyMutagenApplied: cv.flags.HasFlag(CreatureFlags.MutagenApplied)); SetCreatureValuesToInfoInput(cv, creatureInfoInputExtractor); UpdateParentListInput(creatureInfoInputExtractor); // this function is only used for single-creature extractions, e.g. LastExport - creatureInfoInputExtractor.UpdateExistingCreature = creatureExists; + creatureInfoInputExtractor.AlreadyExistingCreature = alreadyExistingCreature; if (!string.IsNullOrEmpty(filePath)) - SetMessageLabelText(Loc.S("creatureOfFile") + "\r\n" + filePath, path: filePath); + SetMessageLabelText(Loc.S("creatureOfFile") + Environment.NewLine + filePath, path: filePath); return creatureExists; } @@ -1242,6 +1239,11 @@ private void LbBlueprintPath_Click(object sender, EventArgs e) Clipboard.SetText(bp); } + private void ExtractorStatLevelChanged(StatIO _) + { + radarChartExtractor.SetLevels(_statIOs.Select(s => s.LevelWild).ToArray(), _statIOs.Select(s => s.LevelMut).ToArray(), speciesSelector1.SelectedSpecies); + } + #region OCR label sets private void InitializeOcrLabelSets() diff --git a/ARKBreedingStats/Form1.importExported.cs b/ARKBreedingStats/Form1.importExported.cs index 76ec1ab5a..1c73b3714 100644 --- a/ARKBreedingStats/Form1.importExported.cs +++ b/ARKBreedingStats/Form1.importExported.cs @@ -121,7 +121,7 @@ private void ImportLastExportedCreature() firstExportFolder.FolderPath = lastExportFile.DirectoryName; exportFolders[0] = firstExportFolder.ToString(); - ExtractExportedFileInExtractor(lastExportFile.FullName); + ExtractExportedFileInExtractor(lastExportFile.FullName, out _, out _); } return; } @@ -132,7 +132,7 @@ private void ImportLastExportedCreature() { case ".ini": // ini files need to be processed by the extractor - ExtractExportedFileInExtractor(newestExportFile); + ExtractExportedFileInExtractor(newestExportFile, out _, out _); return; case ".sav": case ".json": @@ -189,13 +189,14 @@ private Creature ImportExportedAddIfPossible(string filePath) bool addedToLibrary = false; bool uniqueExtraction = false; Creature creature = null; + Creature alreadyExistingCreature = null; bool copiedNameToClipboard = false; Creature[] creaturesOfSpecies = null; switch (Path.GetExtension(filePath)) { case ".ini": - var loadResult = ExtractExportedFileInExtractor(filePath); + var loadResult = ExtractExportedFileInExtractor(filePath, out copiedNameToClipboard, out alreadyExistingCreature); if (loadResult == null) return null; alreadyExists = loadResult.Value; @@ -207,43 +208,16 @@ private Creature ImportExportedAddIfPossible(string filePath) && Properties.Settings.Default.OnAutoImportAddToLibrary) { creature = AddCreatureToCollection(true, goToLibraryTab: Properties.Settings.Default.AutoImportGotoLibraryAfterSuccess); - SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creature.name} ({species.name}) of the exported file\r\n" + filePath, MessageBoxIcon.Information, filePath); + SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creature.name} ({species.name}) of the exported file" + Environment.NewLine + filePath, MessageBoxIcon.Information, filePath); addedToLibrary = true; } - - copiedNameToClipboard = Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied - && (Properties.Settings.Default.applyNamePatternOnAutoImportAlways - || Properties.Settings.Default.applyNamePatternOnImportIfEmptyName - || (!alreadyExists && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures) - ); break; case ".sav": case ".json": - alreadyExists = ImportExportGunFiles(new[] { filePath }, out addedToLibrary, out creature); + alreadyExistingCreature = ImportExportGunFiles(new[] { filePath }, out addedToLibrary, out creature, out copiedNameToClipboard); + alreadyExists = alreadyExistingCreature != null; if (!addedToLibrary || creature == null) return null; uniqueExtraction = true; - - if (Properties.Settings.Default.applyNamePatternOnAutoImportAlways - || (Properties.Settings.Default.applyNamePatternOnImportIfEmptyName - && string.IsNullOrEmpty(creature.name)) - || (!alreadyExists - && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures) - ) - { - creaturesOfSpecies = _creatureCollection.creatures.Where(c => c.Species == creature.Species).ToArray(); - creature.name = NamePattern.GenerateCreatureName(creature, creaturesOfSpecies, - _topLevels.TryGetValue(creature.Species, out var topLevels) ? topLevels : null, - _lowestLevels.TryGetValue(creature.Species, out var lowestLevels) ? lowestLevels : null, - _customReplacingNamingPattern, false, 0); - - if (Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied) - { - Clipboard.SetText(string.IsNullOrEmpty(creature.name) - ? "" - : creature.name); - copiedNameToClipboard = true; - } - } break; default: return null; } @@ -282,10 +256,10 @@ private Creature ImportExportedAddIfPossible(string filePath) string namePattern = Properties.Settings.Default.AutoImportedExportFileRenamePattern; string newFileName = Properties.Settings.Default.AutoImportedExportFileRename && !string.IsNullOrWhiteSpace(namePattern) - ? NamePattern.GenerateCreatureName(creature, + ? NamePattern.GenerateCreatureName(creature, alreadyExistingCreature, creaturesOfSpecies ?? _creatureCollection.creatures.Where(c => c.Species == creature.Species).ToArray(), null, null, - _customReplacingNamingPattern, false, -1, false, namePattern) + _customReplacingNamingPattern, false, -1, false, namePattern, libraryCreatureCount: _creatureCollection.GetTotalCreatureCount()) : Path.GetFileName(filePath); // remove invalid characters @@ -304,7 +278,7 @@ private Creature ImportExportedAddIfPossible(string filePath) if (FileService.TryMoveFile(filePath, newFilePath)) { - _librarySelectionInfoClickPath = newFilePath; + _messageLabelPath = newFilePath; SetMessageLabelLink(newFilePath); } } @@ -343,6 +317,61 @@ private Creature ImportExportedAddIfPossible(string filePath) return addedToLibrary ? creature : null; } + /// + /// Sets the name of an imported creature and copies it to the clipboard depending on the user settings. + /// + /// True if name was copied to clipboard + private bool SetNameOfImportedCreature(Creature creature, Creature[] creaturesOfSpeciesIn, out Creature[] creaturesOfSpecies, Creature alreadyExistingCreature, int totalCreatureCount) + { + creaturesOfSpecies = creaturesOfSpeciesIn; + if (ApplyNamingPattern(creature, alreadyExistingCreature)) + { + // don't overwrite existing ASB creature name with empty ingame name + if (!string.IsNullOrEmpty(alreadyExistingCreature?.name) && string.IsNullOrEmpty(creature.name)) + { + creature.name = alreadyExistingCreature.name; + } + else + { + if (creaturesOfSpecies == null) + creaturesOfSpecies = _creatureCollection.creatures.Where(c => c.Species == creature.Species) + .ToArray(); + creature.name = NamePattern.GenerateCreatureName(creature, alreadyExistingCreature, creaturesOfSpecies, + _topLevels.TryGetValue(creature.Species, out var topLevels) ? topLevels : null, + _lowestLevels.TryGetValue(creature.Species, out var lowestLevels) ? lowestLevels : null, + _customReplacingNamingPattern, false, 0, libraryCreatureCount: totalCreatureCount); + if (alreadyExistingCreature != null) + alreadyExistingCreature.name = creature.name; // if alreadyExistingCreature was already updated and creature is not used anymore make sure name is not lost + } + + return CopyCreatureNameToClipboardOnImportIfSetting(creature.name); + } + + return false; + } + + /// + /// Returns true if the naming pattern should be applied according to the settings. + /// + private bool ApplyNamingPattern(Creature creature, Creature alreadyExistingCreature) => + Properties.Settings.Default.applyNamePatternOnAutoImportAlways + || (Properties.Settings.Default.applyNamePatternOnImportIfEmptyName + && string.IsNullOrEmpty(creature.name)) + || (alreadyExistingCreature == null + && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures); + + /// + /// Copies name to clipboard if the according setting is enabled. Returns true if copied. + /// + private bool CopyCreatureNameToClipboardOnImportIfSetting(string creatureName) + { + if (!Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied) return false; + Clipboard.SetText(string.IsNullOrEmpty(creatureName) + ? "" + : creatureName); + return true; + } + /// /// Give feedback in overlay for imported creature. /// diff --git a/ARKBreedingStats/Form1.l10n.cs b/ARKBreedingStats/Form1.l10n.cs index f355d40a9..914247d7f 100644 --- a/ARKBreedingStats/Form1.l10n.cs +++ b/ARKBreedingStats/Form1.l10n.cs @@ -133,9 +133,21 @@ private void SetLocalizations(bool initialize = true) columnHeaderSp.Text = Utils.StatName(Stats.SpeedMultiplier, true); columnHeaderTo.Text = Utils.StatName(Stats.Torpidity, true); columnHeaderWa.Text = Utils.StatName(Stats.CraftingSpeedMultiplier, true); - columnHeaderTemp.Text = Utils.StatName(Stats.Temperature, true); + columnHeaderTm.Text = Utils.StatName(Stats.Temperature, true); columnHeaderCr.Text = Utils.StatName(Stats.Water, true); columnHeaderFr.Text = Utils.StatName(Stats.TemperatureFortitude, true); + columnHeaderHPM.Text = Utils.StatName(Stats.Health, true) + "M"; + columnHeaderStM.Text = Utils.StatName(Stats.Stamina, true) + "M"; + columnHeaderOxM.Text = Utils.StatName(Stats.Oxygen, true) + "M"; + columnHeaderFoM.Text = Utils.StatName(Stats.Food, true) + "M"; + columnHeaderWeM.Text = Utils.StatName(Stats.Weight, true) + "M"; + columnHeaderDmM.Text = Utils.StatName(Stats.MeleeDamageMultiplier, true) + "M"; + columnHeaderSpM.Text = Utils.StatName(Stats.SpeedMultiplier, true) + "M"; + columnHeaderToM.Text = Utils.StatName(Stats.Torpidity, true) + "M"; + columnHeaderWaM.Text = Utils.StatName(Stats.CraftingSpeedMultiplier, true) + "M"; + columnHeaderTmM.Text = Utils.StatName(Stats.Temperature, true) + "M"; + columnHeaderCrM.Text = Utils.StatName(Stats.Water, true) + "M"; + columnHeaderFrM.Text = Utils.StatName(Stats.TemperatureFortitude, true) + "M"; columnHeaderTopStatsNr.Text = Loc.S("Top"); columnHeaderTopness.Text = Loc.S("topPercentage"); columnHeaderGen.Text = Loc.S("Generation_Abb"); diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs index dbe0b1bc4..92d2b37b7 100644 --- a/ARKBreedingStats/Form1.library.cs +++ b/ARKBreedingStats/Form1.library.cs @@ -205,29 +205,29 @@ private int[] GetCurrentWildLevels(bool fromExtractor = true) } /// - /// Returns the domesticated levels from the extractor or tester in an array. + /// Returns the mutated levels from the extractor or tester in an array. /// - private int[] GetCurrentDomLevels(bool fromExtractor = true) + private int[] GetCurrentMutLevels(bool fromExtractor = true) { - int[] levelsDom = new int[Stats.StatsCount]; + int[] levelsMut = new int[Stats.StatsCount]; for (int s = 0; s < Stats.StatsCount; s++) { - levelsDom[s] = fromExtractor ? _statIOs[s].LevelDom : _testingIOs[s].LevelDom; + levelsMut[s] = fromExtractor ? _statIOs[s].LevelMut : _testingIOs[s].LevelMut; } - return levelsDom; + return levelsMut; } /// - /// Returns the mutated levels from the extractor or tester in an array. + /// Returns the domesticated levels from the extractor or tester in an array. /// - private int[] GetCurrentMutLevels(bool fromExtractor = true) + private int[] GetCurrentDomLevels(bool fromExtractor = true) { - int[] levelsMut = new int[Stats.StatsCount]; + int[] levelsDom = new int[Stats.StatsCount]; for (int s = 0; s < Stats.StatsCount; s++) { - levelsMut[s] = fromExtractor ? _statIOs[s].LevelMut : _testingIOs[s].LevelMut; + levelsDom[s] = fromExtractor ? _statIOs[s].LevelDom : _testingIOs[s].LevelDom; } - return levelsMut; + return levelsDom; } /// @@ -919,7 +919,7 @@ private void SelectCreaturesInLibrary(HashSet selectedCreatures, bool } } - _reactOnCreatureSelectionChange = true; // make sure it reacts again even if the previously creature is not visible anymore + _reactOnCreatureSelectionChange = true; // make sure it reacts again even if the previous creature is not visible anymore } /// @@ -962,9 +962,9 @@ private void UpdateCreatureListViewItem(Creature creature) private const int ColumnIndexMutations = 10; private const int ColumnIndexCountdown = 11; private const int ColumnIndexFirstStat = 12; - private const int ColumnIndexFirstColor = 24; - private const int ColumnIndexPostColor = 30; - private const int ColumnIndexMutagenApplied = 34; + private const int ColumnIndexFirstColor = 36; + private const int ColumnIndexPostColor = 42; + private const int ColumnIndexMutagenApplied = 46; private ListViewItem CreateCreatureLvItem(Creature cr, bool displayIndex = false) { @@ -993,7 +993,8 @@ private ListViewItem CreateCreatureLvItem(Creature cr, bool displayIndex = false cr.Mutations.ToString(), DisplayedCreatureCountdown(cr, out var cooldownForeColor, out var cooldownBackColor) } - .Concat(cr.levelsWild.Select(x => x.ToString())) + .Concat(cr.levelsWild.Select(l => l.ToString())) + .Concat((cr.levelsMutated ?? new int[Stats.StatsCount]).Select(l => l.ToString())) .Concat(Properties.Settings.Default.showColorsInLibrary ? cr.colors.Select(cl => cl.ToString()) : new string[Ark.ColorRegionCount] @@ -1029,6 +1030,17 @@ private ListViewItem CreateCreatureLvItem(Creature cr, bool displayIndex = false else lvi.SubItems[ColumnIndexFirstStat + s].BackColor = Utils.GetColorFromPercent((int)(cr.levelsWild[s] * (s == Stats.Torpidity ? colorFactor / 7 : colorFactor)), // TODO set factor to number of other stats (flyers have 6, Gacha has 8?) _considerStatHighlight[s] ? cr.topBreedingStats[s] ? 0.2 : 0.7 : 0.93); + + // mutated levels + if (cr.levelsMutated == null || cr.valuesDom[s] == 0) + { + // not used + lvi.SubItems[ColumnIndexFirstStat + Stats.StatsCount + s].ForeColor = Color.White; + lvi.SubItems[ColumnIndexFirstStat + Stats.StatsCount + s].BackColor = Color.White; + } + else + lvi.SubItems[ColumnIndexFirstStat + Stats.StatsCount + s].BackColor = Utils.GetColorFromPercent((int)(cr.levelsMutated[s] * (s == Stats.Torpidity ? colorFactor / 7 : colorFactor)), + _considerStatHighlight[s] ? cr.topBreedingStats[s] ? 0.2 : 0.7 : 0.93); } lvi.SubItems[ColumnIndexSex].BackColor = cr.flags.HasFlag(CreatureFlags.Neutered) ? Color.FromArgb(220, 220, 220) : cr.sex == Sex.Female ? Color.FromArgb(255, 230, 255) : @@ -1256,7 +1268,7 @@ private void LibrarySelectedIndexChanged() Creature c = _creaturesDisplayed[listViewLibrary.SelectedIndices[0]]; creatureBoxListView.SetCreature(c); if (tabControlLibFilter.SelectedTab == tabPageLibRadarChart) - radarChartLibrary.SetLevels(c.levelsWild); + radarChartLibrary.SetLevels(c.levelsWild, c.levelsMutated, c.Species); pedigree1.PedigreeNeedsUpdate = true; } @@ -1326,7 +1338,10 @@ private void FilterLib(bool selectFirstIfNothingIsSelected = false) } for (int s = 0; s < Stats.StatsCount; s++) + { listViewLibrary.Columns[ColumnIndexFirstStat + s].Text = Utils.StatName(s, true, customStatNames); + listViewLibrary.Columns[ColumnIndexFirstStat + Stats.StatsCount + s].Text = Utils.StatName(s, true, customStatNames) + "M"; + } _creaturesPreFiltered = ApplyLibraryFilterSettings(filteredList).ToArray(); } @@ -2033,5 +2048,74 @@ private void importFromTabSeparatedFileToolStripMenuItem_Click(object sender, Ev MessageBoxes.ShowMessageBox(result, "Creatures imported from tsv file", MessageBoxIcon.Information); } + + #region library list view columns + + private void resetColumnOrderToolStripMenuItem_Click(object sender, EventArgs e) + { + listViewLibrary.BeginUpdate(); + var colIndices = new[] { 1, 2, 4, 5, 6, 36, 31, 32, 33, 34, 35, 37, 7, 9, 29, 11, 13, 15, 17, 19, 21, 23, 25, 27, 8, 10, 30, 12, 14, 16, 18, 20, 22, 24, 26, 28, 40, 41, 42, 43, 44, 45, 46, 38, 3, 0, 39 }; + + // indices have to be set increasingly, or they will "push" other values up + var colIndicesOrdered = colIndices.Select((i, c) => (columnIndex: c, displayIndex: i)) + .OrderBy(c => c.displayIndex).ToArray(); + for (int c = 0; c < colIndicesOrdered.Length && c < listViewLibrary.Columns.Count; c++) + listViewLibrary.Columns[colIndicesOrdered[c].columnIndex].DisplayIndex = colIndicesOrdered[c].displayIndex; + + listViewLibrary.EndUpdate(); + } + + private void toolStripMenuItemResetLibraryColumnWidths_Click(object sender, EventArgs e) + { + ResetColumnWidthListViewLibrary(false); + } + + private void resetColumnWidthNoMutationLevelColumnsToolStripMenuItem_Click(object sender, EventArgs e) + { + ResetColumnWidthListViewLibrary(true); + } + + private void restoreMutationLevelsASAToolStripMenuItem_Click(object sender, EventArgs e) + { + LibraryColumnsMutationsWidth(false); + } + + private void collapseMutationsLevelsASEToolStripMenuItem_Click(object sender, EventArgs e) + { + LibraryColumnsMutationsWidth(true); + } + + private void ResetColumnWidthListViewLibrary(bool mutationColumnWidthsZero) + { + listViewLibrary.BeginUpdate(); + var statWidths = Stats.UsuallyVisibleStats.Select(w => w ? 30 : 0).ToArray(); + for (int ci = 0; ci < listViewLibrary.Columns.Count; ci++) + listViewLibrary.Columns[ci].Width = ci == ColumnIndexMutagenApplied ? 30 + : ci < ColumnIndexFirstStat || ci >= ColumnIndexPostColor ? 60 + : ci >= ColumnIndexFirstStat + Stats.StatsCount + Stats.StatsCount ? 30 // color + : ci < ColumnIndexFirstStat + Stats.StatsCount ? statWidths[ci - ColumnIndexFirstStat] // wild levels + : (int)(statWidths[ci - ColumnIndexFirstStat - Stats.StatsCount] * 1.24); // mutated needs space for one more letter + + if (mutationColumnWidthsZero) + LibraryColumnsMutationsWidth(true); + + listViewLibrary.EndUpdate(); + } + + /// + /// Set width of mutation level columns to zero or restore. + /// + private void LibraryColumnsMutationsWidth(bool collapse) + { + listViewLibrary.BeginUpdate(); + var statWidths = Stats.UsuallyVisibleStats.Select(w => !collapse && w ? 38 : 0).ToArray(); + for (int c = 0; c < Stats.StatsCount; c++) + { + listViewLibrary.Columns[c + ColumnIndexFirstStat + Stats.StatsCount].Width = statWidths[c]; + } + listViewLibrary.EndUpdate(); + } + + #endregion } } diff --git a/ARKBreedingStats/Form1.tester.cs b/ARKBreedingStats/Form1.tester.cs index 3b7f54222..e4cb127d2 100644 --- a/ARKBreedingStats/Form1.tester.cs +++ b/ARKBreedingStats/Form1.tester.cs @@ -50,7 +50,7 @@ private void EditCreatureInTester(Creature c, bool virtualCreature = false) for (int s = 0; s < Stats.StatsCount; s++) { if (s != Stats.Torpidity && c.levelsWild[s] > 0) - _hiddenLevelsCreatureTester -= c.levelsWild[s]; + _hiddenLevelsCreatureTester -= c.levelsWild[s] + (c.levelsMutated?[s] ?? 0); } for (int s = 0; s < Stats.StatsCount; s++) @@ -58,6 +58,7 @@ private void EditCreatureInTester(Creature c, bool virtualCreature = false) if (s == Stats.Torpidity) continue; _testingIOs[s].LevelWild = c.levelsWild[s]; + _testingIOs[s].LevelMut = c.levelsMutated?[s] ?? 0; _testingIOs[s].LevelDom = c.levelsDom[s]; } tabControlMain.SelectedTab = tabPageStatTesting; @@ -100,7 +101,8 @@ private void TestingStatIoValueUpdate(StatIO sIo) for (int s = 0; s < Stats.StatsCount; s++) { if (s != Stats.Torpidity) - torporLvl += _testingIOs[s].LevelWild > 0 ? _testingIOs[s].LevelWild : 0; + torporLvl += (_testingIOs[s].LevelWild > 0 ? _testingIOs[s].LevelWild : 0) + + _testingIOs[s].LevelMut; } _testingIOs[Stats.Torpidity].LevelWild = torporLvl + _hiddenLevelsCreatureTester; } @@ -125,10 +127,11 @@ private void TestingStatIoValueUpdate(StatIO sIo) creatureInfoInputTester.parentListValid = false; int[] levelsWild = _testingIOs.Select(s => s.LevelWild).ToArray(); - if (!_testingIOs[2].Enabled) - levelsWild[2] = 0; - radarChart1.SetLevels(levelsWild); - statPotentials1.SetLevels(levelsWild, false); + int[] levelsMutations = _testingIOs.Select(s => s.LevelMut).ToArray(); + if (!_testingIOs[Stats.Torpidity].Enabled) + levelsWild[Stats.Torpidity] = 0; + radarChart1.SetLevels(levelsWild, levelsMutations); + statPotentials1.SetLevels(levelsWild, levelsMutations, false); //statGraphs1.setGraph(sE, 0, testingIOs[0].LevelWild, testingIOs[0].LevelDom, !radioButtonTesterWild.Checked, (double)NumericUpDownTestingTE.Value / 100, (double)numericUpDownImprintingBonusTester.Value / 100); if (sIo.statIndex == Stats.Torpidity) @@ -152,8 +155,8 @@ private void TestingStatIoValueUpdate(StatIO sIo) private void TestingStatIOsRecalculateValue(StatIO sIo) { - sIo.BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, 0, true, 1, 0); - sIo.Input = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, sIo.LevelDom, + sIo.BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, sIo.LevelMut, 0, true, 1, 0); + sIo.Input = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, sIo.LevelMut, sIo.LevelDom, rbTamedTester.Checked || rbBredTester.Checked, rbBredTester.Checked ? 1 : Math.Max(0, TamingEffectivenessTester), rbBredTester.Checked ? (double)numericUpDownImprintingBonusTester.Value / 100 : 0); @@ -169,21 +172,23 @@ private void creatureInfoInputTester_Save2Library_Clicked(CreatureInfoInput send if (_creatureTesterEdit == null) return; // check if wild levels are changed, if yes warn that the creature can become invalid + // TODO adjust check if mutated levels have a different multiplier than wild levels bool wildChanged = Math.Abs(_creatureTesterEdit.tamingEff - TamingEffectivenessTester) > .0005; if (!wildChanged) { - int[] wildLevels = GetCurrentWildLevels(false); + var wildLevels = GetCurrentWildLevels(false); + var mutatedLevels = GetCurrentMutLevels(false); for (int s = 0; s < Stats.StatsCount; s++) { - if (wildLevels[s] != _creatureTesterEdit.levelsWild[s]) + if (wildLevels[s] + mutatedLevels[s] != _creatureTesterEdit.levelsWild[s] + (_creatureTesterEdit.levelsMutated?[s] ?? 0)) { wildChanged = true; break; } } } - if (wildChanged && MessageBox.Show("The wild levels or the taming-effectiveness were changed. Save values anyway?\n" + - "Only save if the wild levels or taming-effectiveness were extracted wrongly!\nIf you are not sure, don't save. " + + if (wildChanged && MessageBox.Show("The wild or mutated levels or the taming-effectiveness were changed. Save values anyway?\n" + + "Only save if the wild or mutated levels or the taming-effectiveness were extracted wrongly!\nIf you are not sure, don't save. " + "The breeding-values could become invalid.", "Wild levels have been changed", MessageBoxButtons.OKCancel, @@ -201,6 +206,7 @@ private void creatureInfoInputTester_Save2Library_Clicked(CreatureInfoInput send || _creatureTesterEdit.mutationsPaternal != creatureInfoInputTester.MutationCounterFather; bool parentsChanged = _creatureTesterEdit.Mother != creatureInfoInputTester.Mother || _creatureTesterEdit.Father != creatureInfoInputTester.Father; _creatureTesterEdit.levelsWild = GetCurrentWildLevels(false); + _creatureTesterEdit.levelsMutated = GetCurrentMutLevels(false); _creatureTesterEdit.levelsDom = GetCurrentDomLevels(false); _creatureTesterEdit.tamingEff = TamingEffectivenessTester; _creatureTesterEdit.isBred = rbBredTester.Checked; @@ -303,7 +309,7 @@ private void SetCreatureValuesToExtractor(Creature c, bool onlyWild = false) for (int s = 0; s < Stats.StatsCount; s++) { _statIOs[s].Input = onlyWild - ? StatValueCalculation.CalculateValue(species, s, c.levelsWild[s], 0, true, c.tamingEff, + ? StatValueCalculation.CalculateValue(species, s, c.levelsWild[s], c.levelsMutated[s], 0, true, c.tamingEff, c.imprintingBonus) : c.valuesDom[s]; if (c.levelsDom[s] > 0) _statIOs[s].DomLevelLockedZero = false; @@ -406,5 +412,11 @@ private double TamingEffectivenessTester get => rbWildTester.Checked ? -3 : (double)NumericUpDownTestingTE.Value / 100; set => NumericUpDownTestingTE.ValueSave = (decimal)(value >= 0 ? value * 100 : -1); } + private void CbLinkWildMutatedLevelsTester_CheckedChanged(object sender, EventArgs e) + { + var linkWildMutated = CbLinkWildMutatedLevelsTester.Checked; + for (int s = 0; s < Stats.StatsCount; s++) + _testingIOs[s].LinkWildMutated = linkWildMutated; + } } } diff --git a/ARKBreedingStats/NamePatterns/NamePattern.cs b/ARKBreedingStats/NamePatterns/NamePattern.cs index 2250280d4..f6f989ff8 100644 --- a/ARKBreedingStats/NamePatterns/NamePattern.cs +++ b/ARKBreedingStats/NamePatterns/NamePattern.cs @@ -19,9 +19,10 @@ public static class NamePattern /// /// Generate a creature name with the naming pattern. /// - public static string GenerateCreatureName(Creature creature, Creature[] sameSpecies, int[] speciesTopLevels, int[] speciesLowestLevels, Dictionary customReplacings, + /// If the creature already exists in the library, null if the creature is new. + public static string GenerateCreatureName(Creature creature, Creature alreadyExistingCreature, Creature[] sameSpecies, int[] speciesTopLevels, int[] speciesLowestLevels, Dictionary customReplacings, bool showDuplicateNameWarning, int namingPatternIndex, bool showTooLongWarning = true, string pattern = null, bool displayError = true, Dictionary tokenDictionary = null, - CreatureCollection.ColorExisting[] colorsExisting = null) + CreatureCollection.ColorExisting[] colorsExisting = null, int libraryCreatureCount = 0) { if (pattern == null) { @@ -63,7 +64,7 @@ public static string GenerateCreatureName(Creature creature, Creature[] sameSpec } if (tokenDictionary == null) - tokenDictionary = CreateTokenDictionary(creature, sameSpecies, speciesTopLevels, speciesLowestLevels); + tokenDictionary = CreateTokenDictionary(creature, alreadyExistingCreature, sameSpecies, speciesTopLevels, speciesLowestLevels, libraryCreatureCount); // first resolve keys, then functions string name = ResolveFunctions( ResolveKeysToValues(tokenDictionary, pattern.Replace("\r", string.Empty).Replace("\n", string.Empty)), @@ -190,14 +191,13 @@ private static string ResolveFunction(Match m, NamePatternParameters parameters) /// This method creates the token dictionary for the dynamic creature name generation. /// /// Creature with the data + /// If the creature is already existing in the library, i.e. if the name is created for a creature that is updated /// A list of all currently stored creatures of the species /// top levels of that species /// lowest levels of that species /// A dictionary containing all tokens and their replacements - public static Dictionary CreateTokenDictionary(Creature creature, Creature[] speciesCreatures, int[] speciesTopLevels, int[] speciesLowestLevels) + public static Dictionary CreateTokenDictionary(Creature creature, Creature alreadyExistingCreature, Creature[] speciesCreatures, int[] speciesTopLevels, int[] speciesLowestLevels, int libraryCreatureCount) { - var creatureInLibrary = creature.guid != Guid.Empty ? speciesCreatures.FirstOrDefault(c => c.guid == creature.guid) : null; - string dom = creature.isBred ? "B" : "T"; double imp = creature.imprintingBonus * 100; @@ -247,7 +247,7 @@ public static Dictionary CreateTokenDictionary(Creature creature if (creature.guid != Guid.Empty) { - oldName = creatureInLibrary?.name ?? creature.name; + oldName = (alreadyExistingCreature != null ? alreadyExistingCreature.name : creature.name) ?? string.Empty; } else if (creature.ArkId != 0) { @@ -263,8 +263,9 @@ public static Dictionary CreateTokenDictionary(Creature creature spcsNm = spcsNm.Remove(spcsNm.LastIndexOfAny(vowels), 1); // remove last vowel (not the first letter) // for counting, add 1 if the creature is not yet in the library - var addOne = creatureInLibrary == null ? 1 : 0; + var addOne = alreadyExistingCreature == null ? 1 : 0; int speciesCount = (speciesCreatures?.Length ?? 0) + addOne; + if (addOne == 1) libraryCreatureCount++; // the index of the creature in its generation, ordered by addedToLibrary int nrInGeneration = (speciesCreatures?.Count(c => c.guid != creature.guid && c.addedToLibrary != null && c.generation == generation && (creature.addedToLibrary == null || c.addedToLibrary < creature.addedToLibrary)) ?? 0) + addOne; int nrInGenerationAndSameSex = (speciesCreatures?.Count(c => c.guid != creature.guid && c.sex == creature.sex && c.addedToLibrary != null && c.generation == generation && (creature.addedToLibrary == null || c.addedToLibrary < creature.addedToLibrary)) ?? 0) + addOne; @@ -331,6 +332,7 @@ public static Dictionary CreateTokenDictionary(Creature creature { "nr_in_gen", nrInGeneration.ToString()}, { "nr_in_gen_sex", nrInGenerationAndSameSex.ToString()}, { "rnd", randStr }, + { "ln", libraryCreatureCount.ToString()}, { "tn", speciesCount.ToString()}, { "sn", speciesSexCount.ToString()}, { "dom", dom}, @@ -365,6 +367,9 @@ public static Dictionary CreateTokenDictionary(Creature creature // highest stats and according levels dict.Add("highest" + (s + 1) + "l", usedStatsCount > s ? levelOrder[s].Item2.ToString() : string.Empty); dict.Add("highest" + (s + 1) + "s", usedStatsCount > s ? Utils.StatName(levelOrder[s].Item1, true, creature.Species.statNames) : string.Empty); + + // mutated levels + dict.Add(StatAbbreviationFromIndex[s] + "_m", (creature.levelsMutated?[s] ?? 0).ToString()); } return dict; diff --git a/ARKBreedingStats/NamePatterns/PatternEditor.cs b/ARKBreedingStats/NamePatterns/PatternEditor.cs index c0b131f03..cc1bfeb12 100644 --- a/ARKBreedingStats/NamePatterns/PatternEditor.cs +++ b/ARKBreedingStats/NamePatterns/PatternEditor.cs @@ -17,8 +17,10 @@ public partial class PatternEditor : Form { private readonly Creature _creature; private readonly Creature[] _creaturesOfSameSpecies; + private readonly Creature _alreadyExistingCreature; private readonly int[] _speciesTopLevels; private readonly int[] _speciesLowestLevels; + private readonly int _libraryCreatureCount; private readonly CreatureCollection.ColorExisting[] _colorExistings; private Dictionary _customReplacings; private readonly Dictionary _tokenDictionary; @@ -38,7 +40,7 @@ public PatternEditor() InitializeComponent(); } - public PatternEditor(Creature creature, Creature[] creaturesOfSameSpecies, int[] speciesTopLevels, int[] speciesLowestLevels, CreatureCollection.ColorExisting[] colorExistings, Dictionary customReplacings, int namingPatternIndex, Action reloadCallback) : this() + public PatternEditor(Creature creature, Creature[] creaturesOfSameSpecies, int[] speciesTopLevels, int[] speciesLowestLevels, CreatureCollection.ColorExisting[] colorExistings, Dictionary customReplacings, int namingPatternIndex, Action reloadCallback, int libraryCreatureCount) : this() { Utils.SetWindowRectangle(this, Settings.Default.PatternEditorFormRectangle); if (Settings.Default.PatternEditorSplitterDistance > 0) @@ -53,13 +55,15 @@ public PatternEditor(Creature creature, Creature[] creaturesOfSameSpecies, int[] _colorExistings = colorExistings; _customReplacings = customReplacings; _reloadCallback = reloadCallback; + _libraryCreatureCount = libraryCreatureCount; txtboxPattern.Text = Properties.Settings.Default.NamingPatterns?[namingPatternIndex] ?? string.Empty; CbPatternNameToClipboardAfterManualApplication.Checked = Properties.Settings.Default.PatternNameToClipboardAfterManualApplication; txtboxPattern.SelectionStart = txtboxPattern.Text.Length; - Text = $"Naming Pattern Editor: pattern {(namingPatternIndex + 1)}"; + Text = $"Naming Pattern Editor: pattern {namingPatternIndex + 1}"; - _tokenDictionary = NamePatterns.NamePattern.CreateTokenDictionary(creature, _creaturesOfSameSpecies, _speciesTopLevels, _speciesLowestLevels); + _alreadyExistingCreature = _creaturesOfSameSpecies?.FirstOrDefault(c => c.guid == creature.guid); + _tokenDictionary = NamePatterns.NamePattern.CreateTokenDictionary(creature, _alreadyExistingCreature, _creaturesOfSameSpecies, _speciesTopLevels, _speciesLowestLevels, _libraryCreatureCount); _keyDebouncer = new Debouncer(); _functionDebouncer = new Debouncer(); @@ -479,6 +483,7 @@ private void InsertText(string text) { "nr_in_gen", "The number of the creature in its generation, ordered by added to the library" }, { "nr_in_gen_sex", "The number of the creature in its generation with the same sex, ordered by added to the library" }, { "rnd", "6-digit random number in the range 0 – 999999" }, + { "ln", "number of creatures in the library + 1" }, { "tn", "number of creatures of the current species in the library + 1" }, { "sn", "number of creatures of the current species with the same sex in the library + 1" }, { "arkid", "the Ark-Id (as entered or seen in-game)"}, @@ -496,6 +501,19 @@ private void InsertText(string text) { "highest4s", "the name of the fourth highest stat-level of this creature (excluding torpidity)" }, { "highest5s", "the name of the fifth highest stat-level of this creature (excluding torpidity)" }, { "highest6s", "the name of the sixth highest stat-level of this creature (excluding torpidity)" }, + + { "hp_m", "Mutated levels of " + Utils.StatName(Stats.Health, customStatNames:customStatNames) }, + { "st_m", "Mutated levels of " + Utils.StatName(Stats.Stamina, customStatNames:customStatNames) }, + { "to_m", "Mutated levels of " + Utils.StatName(Stats.Torpidity, customStatNames:customStatNames) }, + { "ox_m", "Mutated levels of " + Utils.StatName(Stats.Oxygen, customStatNames:customStatNames) }, + { "fo_m", "Mutated levels of " + Utils.StatName(Stats.Food, customStatNames:customStatNames) }, + { "wa_m", "Mutated levels of " + Utils.StatName(Stats.Water, customStatNames:customStatNames) }, + { "te_m", "Mutated levels of " + Utils.StatName(Stats.Temperature, customStatNames:customStatNames) }, + { "we_m", "Mutated levels of " + Utils.StatName(Stats.Weight, customStatNames:customStatNames) }, + { "dm_m", "Mutated levels of " + Utils.StatName(Stats.MeleeDamageMultiplier, customStatNames:customStatNames) }, + { "sp_m", "Mutated levels of " + Utils.StatName(Stats.SpeedMultiplier, customStatNames:customStatNames) }, + { "fr_m", "Mutated levels of " + Utils.StatName(Stats.TemperatureFortitude, customStatNames:customStatNames) }, + { "cr_m", "Mutated levels of " + Utils.StatName(Stats.CraftingSpeedMultiplier, customStatNames:customStatNames) } }; // list of possible functions, expected format: @@ -549,8 +567,8 @@ private void txtboxPattern_TextChanged(object sender, EventArgs e) private void DisplayPreview() { - cbPreview.Text = NamePatterns.NamePattern.GenerateCreatureName(_creature, _creaturesOfSameSpecies, _speciesTopLevels, _speciesLowestLevels, _customReplacings, - false, -1, false, txtboxPattern.Text, false, _tokenDictionary, _colorExistings); + cbPreview.Text = NamePatterns.NamePattern.GenerateCreatureName(_creature, _alreadyExistingCreature, _creaturesOfSameSpecies, _speciesTopLevels, _speciesLowestLevels, _customReplacings, + false, -1, false, txtboxPattern.Text, false, _tokenDictionary, _colorExistings, _libraryCreatureCount); } private void TbFilterKeys_TextChanged(object sender, EventArgs e) diff --git a/ARKBreedingStats/OffspringPossibilities.cs b/ARKBreedingStats/OffspringPossibilities.cs index 082511327..dc9058f06 100644 --- a/ARKBreedingStats/OffspringPossibilities.cs +++ b/ARKBreedingStats/OffspringPossibilities.cs @@ -1,5 +1,4 @@ using ARKBreedingStats.species; -using ARKBreedingStats.values; using System; using System.Collections.Generic; using System.Linq; @@ -92,6 +91,12 @@ public void Calculate(Species species, int[] wildLevels1, int[] wildLevels2) private void DrawBars(Dictionary levelProbabilities, double maxProbability) { + if (maxProbability == 0) + { + Clear(); + return; + } + SuspendLayout(); Clear(false); diff --git a/ARKBreedingStats/Pedigree/PedigreeCreature.cs b/ARKBreedingStats/Pedigree/PedigreeCreature.cs index 86da2bd44..7cf3c6a1a 100644 --- a/ARKBreedingStats/Pedigree/PedigreeCreature.cs +++ b/ARKBreedingStats/Pedigree/PedigreeCreature.cs @@ -235,7 +235,10 @@ public Creature Creature _labels[s].ForeColor = Parent?.ForeColor ?? Color.Black; // needed so text is not transparent on overlay _ttMonospaced.SetToolTip(_labels[s], Utils.StatName(si, false, _creature.Species?.statNames) + ": " + $"{_creature.valuesBreeding[si] * (Utils.Precision(si) == 3 ? 100 : 1),7:#,0.0}" - + (Utils.Precision(si) == 3 ? "%" : string.Empty)); + + (Utils.Precision(si) == 3 ? "%" : string.Empty) + + (_creature.levelsMutated == null ? string.Empty + : Environment.NewLine + Loc.S("Mutations") + ": " + _creature.levelsMutated[s] + )); } // fonts are strange, and this seems to work. The assigned font-object is probably only used to read out the properties and then not used anymore. using (var font = new Font("Microsoft Sans Serif", 8.25F, (_creature.topBreedingStats?[si]).GetValueOrDefault() ? FontStyle.Bold : FontStyle.Regular, GraphicsUnit.Point, 0)) diff --git a/ARKBreedingStats/Properties/AssemblyInfo.cs b/ARKBreedingStats/Properties/AssemblyInfo.cs index bfd1b27db..662f76668 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.58.1.0")] +[assembly: AssemblyFileVersion("0.59.2.0")] [assembly: NeutralResourcesLanguage("en")] diff --git a/ARKBreedingStats/Properties/Settings.Designer.cs b/ARKBreedingStats/Properties/Settings.Designer.cs index b57dfe60e..9a64ca3fe 100644 --- a/ARKBreedingStats/Properties/Settings.Designer.cs +++ b/ARKBreedingStats/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace ARKBreedingStats.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -2254,5 +2254,17 @@ public bool KeepMultipliersForNewLibrary { this["KeepMultipliersForNewLibrary"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ExportServerToken { + get { + return ((string)(this["ExportServerToken"])); + } + set { + this["ExportServerToken"] = value; + } + } } } diff --git a/ARKBreedingStats/Properties/Settings.settings b/ARKBreedingStats/Properties/Settings.settings index da0f382fc..5dbadeb6a 100644 --- a/ARKBreedingStats/Properties/Settings.settings +++ b/ARKBreedingStats/Properties/Settings.settings @@ -566,5 +566,8 @@ True + + + \ No newline at end of file diff --git a/ARKBreedingStats/RadarChart.cs b/ARKBreedingStats/RadarChart.cs index 78b1dfaff..06696bed2 100644 --- a/ARKBreedingStats/RadarChart.cs +++ b/ARKBreedingStats/RadarChart.cs @@ -1,28 +1,49 @@ -using ARKBreedingStats.species; -using System; +using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; +using ARKBreedingStats.species; +using Color = System.Drawing.Color; +using Pen = System.Drawing.Pen; namespace ARKBreedingStats { internal class RadarChart : PictureBox { - private int _maxLevel; // outer border of graph - private List _maxPs, _ps; // coords of outer points + /// + /// outer border of graph + /// + private int _maxLevel; + /// + /// Coords of outer points + /// + private readonly List _maxPs = new List(); + /// + /// Coords of wild levels + /// + private readonly List _ps = new List(); + /// + /// Coords of mutated levels + /// + private readonly List _psm = new List(); private int _maxR, _xm, _ym; // max-radius, centerX, centerY - private readonly int[] _oldLevels; - private PathGradientBrush _grBrushBg, _grBrushFg; + private readonly int[] _currentWildLevels = new int[Stats.StatsCount]; + private readonly int[] _currentMutatedLevels = new int[Stats.StatsCount]; + /// + /// Displayed stats as bit flag + /// + private int _displayedStats; + + private readonly List _displayedStatIndices = new List(); + private double _anglePerStat; + private PathGradientBrush _grBrushBg, _grBrushFg, _grBrushMutations; private int _step; - private const int DisplayedStats = 7; - private const double AnglePerStat = Math.PI * 2 / DisplayedStats; private const double AngleOffset = Math.PI / 2; public RadarChart() { SizeMode = PictureBoxSizeMode.Zoom; - _oldLevels = new int[DisplayedStats]; Disposed += RadarChart_Disposed; InitializeVariables(50); @@ -34,81 +55,141 @@ private void RadarChart_Disposed(object sender, EventArgs e) _grBrushFg.Dispose(); } - /// - /// Initialize with a new max chart level. - /// - /// - public void InitializeVariables(int maxLevel) + private bool SetSize() { - _maxLevel = maxLevel; - _maxR = Math.Min(Width, Height) / 2; + var maxRadius = Math.Min(Width, Height) / 2; + if (_maxR == maxRadius) + return false; // already set + + _maxR = maxRadius; _xm = _maxR + 1; _ym = _maxR + 1; _maxR -= 15; - _step = (int)Math.Round(maxLevel / 25d); - if (_step < 1) _step = 1; - _step *= 5; - - _maxPs = new List(); - _ps = new List(); - int r = 0; - for (int s = 0; s < DisplayedStats; s++) - { - double angle = AnglePerStat * s - AngleOffset; - _ps.Add(new Point(_xm + (int)(r * Math.Cos(angle)), _ym + (int)(r * Math.Sin(angle)))); + InitializePoints(); - _maxPs.Add(new Point(_xm + (int)(_maxR * Math.Cos(angle)), _ym + (int)(_maxR * Math.Sin(angle)))); - } - - // color gradient - GraphicsPath path = new GraphicsPath(); - path.AddEllipse(_xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); + // color gradients _grBrushBg?.Dispose(); _grBrushFg?.Dispose(); - _grBrushBg = new PathGradientBrush(path); - _grBrushFg = new PathGradientBrush(path); + _grBrushMutations?.Dispose(); - Color[] colorsBg = + float[] relativePositions = { 0, 0.45f, 1 }; + GraphicsPath path = new GraphicsPath(); + path.AddEllipse(_xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); + _grBrushBg = new PathGradientBrush(path) + { + InterpolationColors = new ColorBlend + { + Colors = new[] { + Color.FromArgb(0, 90, 0), + Color.FromArgb(90, 90, 0), + Color.FromArgb(90, 0, 0) + }, + Positions = relativePositions + } + }; + _grBrushFg = new PathGradientBrush(path) { - Color.FromArgb(0, 90, 0), - Color.FromArgb(90, 90, 0), - Color.FromArgb(90, 0, 0) + InterpolationColors = new ColorBlend + { + Colors = new[] { + Color.FromArgb(0, 180, 0), + Color.FromArgb(180, 180, 0), + Color.FromArgb(180, 0, 0) + }, + Positions = relativePositions + } }; - - Color[] colorsFg = + _grBrushMutations = new PathGradientBrush(path) { - Color.FromArgb(0, 180, 0), - Color.FromArgb(180, 180, 0), - Color.FromArgb(180, 0, 0) + InterpolationColors = new ColorBlend + { + Colors = new[] { + Color.FromArgb(0, 180, 180), + Color.FromArgb(90, 90, 180), + Color.FromArgb(180, 0, 180) + }, + Positions = relativePositions + } }; + return true; + } - float[] relativePositions = { 0, 0.45f, 1 }; + private bool SetMaxLevel(int maxLevel) + { + if (_maxLevel == maxLevel) + return false; + + _maxLevel = maxLevel; + + _step = (int)Math.Round(_maxLevel / 25d); + if (_step < 1) _step = 1; + _step *= 5; + + return true; + } + + /// + /// Initialize with a new max chart level. + /// + /// + public void InitializeVariables(int maxLevel) + { + if (SetSize() | SetMaxLevel(maxLevel)) + SetLevels(); // update graph + } - ColorBlend colorBlendBg = new ColorBlend + private void InitializeStats(int displayedStats) + { + if (displayedStats == _displayedStats) return; + _displayedStats = displayedStats; + _displayedStatIndices.Clear(); + for (int s = 0; s < Stats.StatsCount; s++) { - Colors = colorsBg, - Positions = relativePositions - }; - _grBrushBg.InterpolationColors = colorBlendBg; + _currentMutatedLevels[s] = 0; + _currentWildLevels[s] = 0; + if (s == Stats.Torpidity || (_displayedStats & (1 << s)) == 0) continue; + _displayedStatIndices.Add(s); + } + + _anglePerStat = Math.PI * 2 / _displayedStatIndices.Count; - ColorBlend colorBlendFg = new ColorBlend + InitializePoints(); + } + + /// + /// Resets points, call after size or stat count was changed. + /// + private void InitializePoints() + { + _maxPs.Clear(); + _ps.Clear(); + _psm.Clear(); + for (var s = 0; s < _displayedStatIndices.Count; s++) { - Colors = colorsFg, - Positions = relativePositions - }; - _grBrushFg.InterpolationColors = colorBlendFg; + _ps.Add(new Point(_xm, _ym)); + _psm.Add(new Point(_xm, _ym)); + double angle = _anglePerStat * s - AngleOffset; + _maxPs.Add(Coords(_maxR, angle)); + } + } - SetLevels(); + private Point Coords(int radius, double angle) + { + if (radius < 0) radius = 0; + if (radius > _maxR) radius = _maxR; + return new Point(_xm + (int)(radius * Math.Cos(angle)), _ym + (int)(radius * Math.Sin(angle))); } /// /// Draws a chart with the given levels. /// - /// If null, the previous values are redrawn. - public void SetLevels(int[] levels = null) + /// If null, the previous values are redrawn. + public void SetLevels(int[] levelsWild = null, int[] levelMutations = null, Species species = null) { - if ((levels != null && levels.Length <= 6) || _maxR <= 5) return; + InitializeStats(species?.DisplayedStats ?? _displayedStats); + + if (_maxR <= 5 || _ps.Count == 0) return; // image too small Bitmap bmp = new Bitmap(Width, Height); using (Graphics g = Graphics.FromImage(bmp)) @@ -117,32 +198,41 @@ public void SetLevels(int[] levels = null) { g.SmoothingMode = SmoothingMode.AntiAlias; - // the indices of the displayed stats - var levelIndices = new[] + if (levelsWild != null || levelMutations != null) { - (int) Stats.Health, (int) Stats.Stamina, (int) Stats.Oxygen, (int) Stats.Food, - (int) Stats.Weight, (int) Stats.MeleeDamageMultiplier, (int) Stats.SpeedMultiplier - }; - - for (int s = 0; s < levelIndices.Length; s++) - { - if (levels == null || levels[levelIndices[s]] != _oldLevels[s]) + var displayedStatIndex = 0; + foreach (var s in _displayedStatIndices) { - if (levels != null) - _oldLevels[s] = levels[levelIndices[s]]; - int r = _oldLevels[s] * _maxR / _maxLevel; - if (r < 0) r = 0; - if (r > _maxR) r = _maxR; - double angle = AnglePerStat * s - AngleOffset; - _ps[s] = new Point(_xm + (int)(r * Math.Cos(angle)), _ym + (int)(r * Math.Sin(angle))); + double angle = _anglePerStat * displayedStatIndex - AngleOffset; + var wildLevelChanged = levelsWild != null && levelsWild[s] != _currentWildLevels[s]; + var mutatedLevelChanged = levelMutations != null && levelMutations[s] != _currentMutatedLevels[s]; + + + if (wildLevelChanged || mutatedLevelChanged) + { + if (wildLevelChanged) + { + _currentWildLevels[s] = levelsWild[s]; + _ps[displayedStatIndex] = Coords(_currentWildLevels[s] * _maxR / _maxLevel, angle); + } + + if (mutatedLevelChanged) + _currentMutatedLevels[s] = levelMutations[s]; + _psm[displayedStatIndex] = Coords((_currentWildLevels[s] + _currentMutatedLevels[s]) * _maxR / _maxLevel, angle); + } + + displayedStatIndex++; } } g.FillEllipse(_grBrushBg, _xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); + g.FillPolygon(_grBrushMutations, _psm.ToArray()); + g.DrawPolygon(penLine, _psm.ToArray()); g.FillPolygon(_grBrushFg, _ps.ToArray()); g.DrawPolygon(penLine, _ps.ToArray()); + // grid circles double stepFactor = (double)_step / _maxLevel; for (int r = 0; r < 5; r++) { @@ -151,24 +241,41 @@ public void SetLevels(int[] levels = null) (int)(_xm - _maxR * r * stepFactor), (int)(_ym - _maxR * r * stepFactor), (int)(2 * _maxR * r * stepFactor + 1), (int)(2 * _maxR * r * stepFactor + 1)); } - + // outline using (var pen = new Pen(Utils.GetColorFromPercent(100, -0.4))) g.DrawEllipse(pen, _xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); + // stat lines and bullet points using (var pen = new Pen(Color.Gray)) - for (int s = 0; s < levelIndices.Length; s++) + for (var sdi = 0; sdi < _displayedStatIndices.Count; sdi++) { - pen.Width = 1; - pen.Color = Color.Gray; - g.DrawLine(pen, _xm, _ym, _maxPs[s].X, _maxPs[s].Y); - Color cl = Utils.GetColorFromPercent(100 * _oldLevels[s] / _maxLevel); - pen.Color = cl; - pen.Width = 3; - g.DrawLine(pen, _xm, _ym, _ps[s].X, _ps[s].Y); - Brush b = new SolidBrush(cl); - g.FillEllipse(b, _ps[s].X - 4, _ps[s].Y - 4, 8, 8); - g.DrawEllipse(penLine, _ps[s].X - 4, _ps[s].Y - 4, 8, 8); - b.Dispose(); + var s = _displayedStatIndices[sdi]; + DrawRadialGridLine(_maxPs[sdi]); + DrawLineAndBullet(_currentWildLevels[s] + _currentMutatedLevels[s], _psm[sdi]); + DrawLineAndBullet(_currentWildLevels[s], _ps[sdi]); + + void DrawRadialGridLine(Point maxCoords) + { + pen.Width = 1; + pen.Color = Color.Gray; + g.DrawLine(pen, _xm, _ym, maxCoords.X, maxCoords.Y); + } + + void DrawLineAndBullet(int level, Point coords) + { + Color cl = Utils.GetColorFromPercent(100 * level / _maxLevel); + pen.Color = cl; + pen.Width = 3; + g.DrawLine(pen, _xm, _ym, coords.X, coords.Y); + const int bulletRadius = 4; + using (var b = new SolidBrush(cl)) + { + g.FillEllipse(b, coords.X - bulletRadius, coords.Y - bulletRadius, 2 * bulletRadius, + 2 * bulletRadius); + } + g.DrawEllipse(penLine, coords.X - bulletRadius, coords.Y - bulletRadius, 2 * bulletRadius, + 2 * bulletRadius); + } } using (var brush = new SolidBrush(Color.FromArgb(190, 255, 255, 255))) @@ -187,10 +294,11 @@ public void SetLevels(int[] levels = null) using (var brushBlack = new SolidBrush(Color.Black)) { - for (int s = 0; s < levelIndices.Length; s++) + for (var sdi = 0; sdi < _displayedStatIndices.Count; sdi++) { - double angle = AnglePerStat * s - AngleOffset; - g.DrawString(Utils.StatName(levelIndices[s], true), font, + var s = _displayedStatIndices[sdi]; + double angle = _anglePerStat * sdi - AngleOffset; + g.DrawString(Utils.StatName(s, true), font, brushBlack, _xm - 9 + (int)((_maxR + 10) * Math.Cos(angle)), _ym - 5 + (int)((_maxR + 10) * Math.Sin(angle))); } diff --git a/ARKBreedingStats/SpeciesSelector.cs b/ARKBreedingStats/SpeciesSelector.cs index 8eeeaa1a8..4a21c20b2 100644 --- a/ARKBreedingStats/SpeciesSelector.cs +++ b/ARKBreedingStats/SpeciesSelector.cs @@ -82,7 +82,7 @@ public void SetSpeciesLists(List species, Dictionary al // autocomplete for species-input var al = new AutoCompleteStringCollection(); - al.AddRange(_entryList.Select(e => e.SearchName).ToArray()); + al.AddRange(_entryList.Select(e => e.DisplayName).ToArray()); _textBox.AutoCompleteCustomSource = al; VariantSelector.SetVariants(species); @@ -105,7 +105,7 @@ private static List CreateSpeciesList(List species, D entryList.Add(new SpeciesListEntry { DisplayName = s.name, - SearchName = s.name, + SearchName = (s.name + " " + s.blueprintPath).ToLowerInvariant(), ModName = s.Mod?.title ?? string.Empty, Species = s }); @@ -118,7 +118,7 @@ private static List CreateSpeciesList(List species, D entryList.Add(new SpeciesListEntry { DisplayName = a.Key + " (→" + aliasSpecies.name + ")", - SearchName = a.Key, + SearchName = a.Key.ToLowerInvariant(), Species = aliasSpecies, ModName = aliasSpecies.Mod?.title ?? string.Empty, }); @@ -265,12 +265,13 @@ private void FilterList(string part = null) lvSpeciesList.BeginUpdate(); lvSpeciesList.Items.Clear(); var newItems = new List(); + part = part?.ToLowerInvariant(); bool inputIsEmpty = string.IsNullOrWhiteSpace(part); foreach (var s in _entryList) { if ((Properties.Settings.Default.DisplayNonDomesticableSpecies || s.Species.IsDomesticable) && (inputIsEmpty - || s.SearchName.ToLower().Contains(part.ToLower()) + || s.SearchName.Contains(part) ) && (noVariantFiltering || (string.IsNullOrEmpty(s.Species.VariantInfo) ? !VariantSelector.DisabledVariants.Contains(string.Empty) @@ -445,6 +446,9 @@ private void button1_Click(object sender, EventArgs e) class SpeciesListEntry { + /// + /// Used for search filter, expected lower case. + /// internal string SearchName; internal string DisplayName; internal string ModName; diff --git a/ARKBreedingStats/Stats.cs b/ARKBreedingStats/Stats.cs index f7c289a19..4dffedc24 100644 --- a/ARKBreedingStats/Stats.cs +++ b/ARKBreedingStats/Stats.cs @@ -9,7 +9,7 @@ public static class StatValueCalculation { //private const double ROUND_UP_DELTA = 0.0001; // remove for now. Rounding issues should be handled during extraction with value-ranges. - public static double CalculateValue(Species species, int stat, int levelWild, int levelDom, bool dom, double tamingEff = 0, double imprintingBonus = 0, bool roundToIngamePrecision = true) + public static double CalculateValue(Species species, int stat, int levelWild, int levelMut, int levelDom, bool dom, double tamingEff = 0, double imprintingBonus = 0, bool roundToIngamePrecision = true) { if (species == null) return 0; @@ -42,7 +42,7 @@ public static double CalculateValue(Species species, int stat, int levelWild, in // adding an epsilon to handle rounding-errors double result = (species.stats[stat].BaseValue * tamedBaseHP * - (1 + species.stats[stat].IncPerWildLevel * levelWild) * imprintingM + add) * + (1 + species.stats[stat].IncPerWildLevel * levelWild + species.stats[stat].IncPerMutatedLevel * levelMut) * imprintingM + add) * domMult;// + (Utils.precision(stat) == 3 ? ROUND_UP_DELTA * 0.01 : ROUND_UP_DELTA); if (result <= 0) return 0; diff --git a/ARKBreedingStats/Taming.cs b/ARKBreedingStats/Taming.cs index 9daeabdcc..df5e3a91e 100644 --- a/ARKBreedingStats/Taming.cs +++ b/ARKBreedingStats/Taming.cs @@ -70,7 +70,7 @@ public static void TamingTimes(Species species, int level, ServerMultipliers ser { // consider wake taming multiplicators (non - violent taming) foodAffinity *= species.taming.wakeAffinityMult; - foodValue = foodValue * species.taming.wakeFoodDeplMult; + foodValue *= species.taming.wakeFoodDeplMult; } foodAffinity *= serverMultipliers.TamingSpeedMultiplier * HardCodedTamingMultiplier; @@ -91,7 +91,8 @@ public static void TamingTimes(Species species, int level, ServerMultipliers ser if (species.name == "Mantis") seconds = foodPiecesNeeded * 180; else - seconds = (int)Math.Ceiling(foodPiecesNeeded * foodValue / (species.taming.foodConsumptionBase * species.taming.foodConsumptionMult * serverMultipliers.DinoCharacterFoodDrainMultiplier)); + seconds = (int)Math.Ceiling(foodPiecesNeeded * foodValue / (species.taming.foodConsumptionBase * species.taming.foodConsumptionMult + * serverMultipliers.DinoCharacterFoodDrainMultiplier * serverMultipliers.WildDinoCharacterFoodDrainMultiplier)); affinityNeeded -= foodPiecesNeeded * foodAffinity; // new approach with 1/(1 + IM*IA*N/AO + ID*D) from https://forums.unrealengine.com/development-discussion/modding/ark-survival-evolved/56959-tutorial-dinosaur-taming-parameters?85457-Tutorial-Dinosaur-Taming-Parameters= @@ -321,7 +322,7 @@ public static int DurationAfterFirstFeeding(Species species, int level, double f species.taming != null && species.taming.nonViolent) { - s = (int)(0.1 * StatValueCalculation.CalculateValue(species, Stats.Food, (int)Math.Ceiling(level / 7d), 0, false, 0, 0) / foodDepletion); + s = (int)(0.1 * StatValueCalculation.CalculateValue(species, Stats.Food, (int)Math.Ceiling(level / 7d), 0, 0, false, 0, 0) / foodDepletion); } return s; } diff --git a/ARKBreedingStats/TamingControl.cs b/ARKBreedingStats/TamingControl.cs index 4cd3fc1a1..6a378a6d2 100644 --- a/ARKBreedingStats/TamingControl.cs +++ b/ARKBreedingStats/TamingControl.cs @@ -13,12 +13,13 @@ namespace ARKBreedingStats public partial class TamingControl : UserControl { private readonly List _foodControls = new List(); + private readonly List _foodControlsVisible = new List(); private bool _updateCalculation; private Species _selectedSpecies; public event TimerControl.CreateTimerEventHandler CreateTimer; private DateTime _wakeUpTime; private DateTime _starvingTime; - private ServerMultipliers _serverMultipliers =new ServerMultipliers(); + private ServerMultipliers _serverMultipliers = new ServerMultipliers(); private string _koNumbers; private string _boneDamageAdjustersImmobilization; public string quickTamingInfos; @@ -74,7 +75,39 @@ public void SetSpecies(Species species, bool forceRefresh = false) linkLabelWikiPage.Tag = speciesName; _tt.SetToolTip(linkLabelWikiPage, ArkWiki.WikiUrl(speciesName)); - // bone damage adjusters + UpdateBoneDamageControls(); + + TamingData td = species.taming; + _kibbleRecipe = string.Empty; + + // list all recipes of kibbles that give a reasonable affinity (assuming that is larger or equal than 100) + foreach (var k in Kibbles.K.kibble) + { + var kibbleName = $"{k.Key} Kibble"; + var kibbleFood = Values.V.GetTamingFood(species, kibbleName); + + if (kibbleFood != null + && kibbleFood.affinity >= 100) + { + _kibbleRecipe += $"\n\n{k.Key} Kibble:{k.Value.RecipeAsText()}"; + } + } + + _foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * _serverMultipliers.DinoCharacterFoodDrainMultiplier * _serverMultipliers.WildDinoCharacterFoodDrainMultiplier; + UpdateFirstFeedingWaiting(); + EstimateFoodValue(); + + SetTamingFoodControls(species, true, false); + + if (Properties.Settings.Default.TamingFoodOrderByTime) + SetOrderOfTamingFood(true, true); + + ResumeLayout(); + this.ResumeDrawing(); + } + + private void UpdateBoneDamageControls() + { _boneDamageAdjustersImmobilization = Taming.BoneDamageAdjustersImmobilization(_selectedSpecies, out Dictionary boneDamageAdjusters); @@ -100,46 +133,27 @@ public void SetSpecies(Species species, bool forceRefresh = false) for (int j = ib + 1; j < _rbBoneDamageAdjusters.Count; j++) _rbBoneDamageAdjusters[j].Visible = false; _rbBoneDamageAdjusters[0].Checked = true; - // bone damage adjusters adjusted - - _updateCalculation = false; - TamingData td = species.taming; - _kibbleRecipe = string.Empty; - - // list all recipes of kibbles that give a reasonable affinity (assuming that is larger or equal than 100) - foreach (var k in Kibbles.K.kibble) - { - var kibbleName = $"{k.Key} Kibble"; - var kibbleFood = Values.V.GetTamingFood(species, kibbleName); - - if (kibbleFood != null - && kibbleFood.affinity >= 100) - { - _kibbleRecipe += $"\n\n{k.Key} Kibble:{k.Value.RecipeAsText()}"; - } - } - - _foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * _serverMultipliers.DinoCharacterFoodDrainMultiplier; - - SetTamingFoodControls(species); - - _updateCalculation = true; - UpdateFirstFeedingWaiting(); - UpdateTamingData(); - if (Properties.Settings.Default.TamingFoodOrderByTime) - SetOrderOfTamingFood(true, true); - - ResumeLayout(); - this.ResumeDrawing(); } /// /// Sets the taming food controls. /// - private void SetTamingFoodControls(Species species) + private void SetTamingFoodControls(Species species, bool resetFoodToBest, bool suspendLayout) { + if (suspendLayout) + { + this.SuspendDrawing(); + SuspendLayout(); + } + + var setFoodAmount = resetFoodToBest + ? null + : _foodControlsVisible.Where(fc => fc.Amount > 0 && !string.IsNullOrEmpty(fc.FoodName)).ToDictionary(fc => fc.FoodName, fc => fc.Amount); var td = species.taming; int i = 0; + var firstVisibleFoodIndex = -1; + _foodControlsVisible.Clear(); + _updateCalculation = false; if (td.eats != null) { var length = td.eats.Length; @@ -155,6 +169,7 @@ private void SetTamingFoodControls(Species species) { tf = _foodControls[i]; tf.FoodName = f; + tf.Amount = 0; tf.Hide(); } continue; @@ -176,21 +191,53 @@ private void SetTamingFoodControls(Species species) tf.Show(); } + _foodControlsVisible.Add(tf); + tf.Amount = 0; + if (firstVisibleFoodIndex == -1) + firstVisibleFoodIndex = i; + // special cases where a creature eats multiple food items of one kind at once var food = Values.V.GetTamingFood(species, f); if (food != null && food.quantity > 1) - tf.foodNameDisplay = food.quantity + "× " + tf.foodNameDisplay; + tf.FoodNameDisplay = food.quantity + "× " + tf.FoodNameDisplay; } } for (int fci = _foodControls.Count - 1; fci >= i; fci--) { _foodControls[fci].FoodName = null; + _foodControls[fci].Amount = 0; _foodControls[fci].Hide(); } - if (i > 0) - _foodControls[0].amount = Taming.FoodAmountNeeded(species, (int)nudLevel.Value, _serverMultipliers.TamingSpeedMultiplier, _foodControls[0].FoodName, td.nonViolent, CbSanguineElixir.Checked); + if (resetFoodToBest) + { + if (firstVisibleFoodIndex >= 0) + _foodControls[firstVisibleFoodIndex].Amount = Taming.FoodAmountNeeded(species, (int)nudLevel.Value, _serverMultipliers.TamingSpeedMultiplier, _foodControls[0].FoodName, td.nonViolent, CbSanguineElixir.Checked); + } + else + { + foreach (var food in setFoodAmount) + { + foreach (var fc in _foodControlsVisible) + { + if (fc.FoodName == food.Key) + { + fc.Amount = food.Value; + break; + } + } + } + } + + if (suspendLayout) + { + ResumeLayout(); + this.ResumeDrawing(); + } + _updateCalculation = true; + + UpdateTamingData(); } /// @@ -203,8 +250,8 @@ private void SetOrderOfTamingFood(bool orderByTamingTime, bool forceDo = false) Properties.Settings.Default.TamingFoodOrderByTime = orderByTamingTime; - var order = _foodControls.Where(c => c.FoodName != null) - .Select(c => (c, orderByTamingTime ? c.TamingSeconds : c.maxFood)).OrderBy(ct => ct.Item2).ToArray(); + var order = _foodControlsVisible.Where(c => c.FoodName != null) + .Select(c => (c, orderByTamingTime ? c.TamingSeconds : c.MaxFood)).OrderBy(ct => ct.Item2).ToArray(); this.SuspendDrawing(); for (int i = 0; i < order.Length; i++) @@ -230,11 +277,21 @@ private void nudLevel_ValueChanged(object sender, EventArgs e) () => { UpdateFirstFeedingWaiting(); + EstimateFoodValue(); UpdateTamingData(); }, Dispatcher.CurrentDispatcher); } + /// + /// Approximating the food level on species or level change. + /// + private void EstimateFoodValue() + { + nudTotalFood.Value = (decimal)(_selectedSpecies.stats[Stats.Food].BaseValue * (1 + _selectedSpecies.stats[Stats.Food].IncPerWildLevel * ((int)nudLevel.Value / 7))); // approximating the food level + nudCurrentFood.Value = nudTotalFood.Value; + } + private void UpdateTamingData() { if (!_updateCalculation || _selectedSpecies == null) @@ -264,24 +321,29 @@ private void UpdateTamingData() if (tameable && _selectedSpecies.taming.eats != null) { - int foodCounter = _selectedSpecies.taming.eats.Length; - foreach (TamingFoodControl tfc in _foodControls) + foreach (TamingFoodControl tfc in _foodControlsVisible) { - if (foodCounter == 0) - break; - foodCounter--; + if (tfc.Amount > 0) + { + usedFood.Add(tfc.FoodName); + foodAmount.Add(tfc.Amount); + } - usedFood.Add(tfc.FoodName); - foodAmount.Add(tfc.amount); - tfc.maxFood = Taming.FoodAmountNeeded(_selectedSpecies, level, _serverMultipliers.TamingSpeedMultiplier, tfc.FoodName, _selectedSpecies.taming.nonViolent, CbSanguineElixir.Checked); - tfc.tamingDuration = Taming.TamingDuration(_selectedSpecies, tfc.maxFood, tfc.FoodName, _serverMultipliers.DinoCharacterFoodDrainMultiplier, _selectedSpecies.taming.nonViolent); + tfc.MaxFood = Taming.FoodAmountNeeded(_selectedSpecies, level, _serverMultipliers.TamingSpeedMultiplier, tfc.FoodName, _selectedSpecies.taming.nonViolent, CbSanguineElixir.Checked); + tfc.TamingDuration = Taming.TamingDuration(_selectedSpecies, tfc.MaxFood, tfc.FoodName, + _serverMultipliers.DinoCharacterFoodDrainMultiplier * _serverMultipliers.WildDinoCharacterFoodDrainMultiplier, _selectedSpecies.taming.nonViolent); } Taming.TamingTimes(_selectedSpecies, level, _serverMultipliers, usedFood, foodAmount, out foodAmountUsed, out duration, out narcoBerries, out ascerbicMushrooms, out narcotics, out bioToxines, out te, out _neededHunger, out bonusLevel, out enoughFood, CbSanguineElixir.Checked); - for (int f = 0; f < foodAmountUsed.Count; f++) + foreach (var fc in _foodControlsVisible) { - _foodControls[f].foodUsed = foodAmountUsed[f]; + var indexOfFoodUsed = usedFood.IndexOf(fc.FoodName); + if (indexOfFoodUsed != -1) + { + fc.FoodUsed = foodAmount[indexOfFoodUsed]; + } + else { fc.FoodUsed = 0; } } } @@ -311,20 +373,18 @@ private void UpdateTamingData() numericUpDownCurrentTorpor.ValueSave = (decimal)(_selectedSpecies.stats[Stats.Torpidity].BaseValue * (1 + _selectedSpecies.stats[Stats.Torpidity].IncPerWildLevel * (level - 1))); - nudTotalFood.Value = (decimal)(_selectedSpecies.stats[Stats.Food].BaseValue * (1 + _selectedSpecies.stats[Stats.Food].IncPerWildLevel * (level / 7))); // approximating the food level - nudCurrentFood.Value = nudTotalFood.Value; UpdateTimeToFeedAll(enoughFood); //// quickTame infos if (foodAmountUsed.Any()) { - quickTamingInfos = Taming.QuickInfoOneFood(_selectedSpecies, level, _serverMultipliers, _foodControls[0].FoodName, _foodControls[0].maxFood, _foodControls[0].foodNameDisplay); + quickTamingInfos = Taming.QuickInfoOneFood(_selectedSpecies, level, _serverMultipliers, _foodControlsVisible[0].FoodName, _foodControlsVisible[0].MaxFood, _foodControlsVisible[0].FoodNameDisplay); // show raw meat or mejoberries as alternative (often used) for (int i = 1; i < usedFood.Count; i++) { if (usedFood[i] == "Raw Meat" || usedFood[i] == "Mejoberry") { - quickTamingInfos += "\n\n" + Taming.QuickInfoOneFood(_selectedSpecies, level, _serverMultipliers, _foodControls[i].FoodName, _foodControls[i].maxFood, _foodControls[i].foodNameDisplay); + quickTamingInfos += "\n\n" + Taming.QuickInfoOneFood(_selectedSpecies, level, _serverMultipliers, _foodControlsVisible[i].FoodName, _foodControlsVisible[i].MaxFood, _foodControlsVisible[i].FoodNameDisplay); break; } } @@ -344,7 +404,7 @@ private void UpdateTimeToFeedAll(bool enoughFood = true) double hunger = (double)(nudTotalFood.Value - nudCurrentFood.Value); if (hunger < 0) hunger = 0; if (hunger > _neededHunger) hunger = _neededHunger; - var durationStarving = new TimeSpan(0, 0, (int)((_neededHunger - hunger) / _foodDepletion)); + var durationStarving = TimeSpan.FromSeconds((_neededHunger - hunger) / _foodDepletion); lbTimeUntilStarving.Text = (enoughFood ? $"{Loc.S("TimeUntilFeedingAllFood")}: {Utils.Duration(durationStarving)}" : string.Empty); if ((double)nudTotalFood.Value < _neededHunger) { @@ -379,9 +439,9 @@ private void OnlyOneFood(string food) return; } _updateCalculation = false; - foreach (TamingFoodControl tfc in _foodControls) + foreach (TamingFoodControl tfc in _foodControlsVisible) { - tfc.amount = tfc.FoodName == food ? tfc.maxFood : 0; + tfc.Amount = tfc.FoodName == food ? tfc.MaxFood : 0; } _updateCalculation = true; UpdateTamingData(); @@ -520,12 +580,12 @@ private void LinkLabelWikiPage_LinkClicked(object sender, LinkLabelLinkClickedEv private void checkBoxAugmented_CheckedChanged(object sender, EventArgs e) { - SetSpecies(_selectedSpecies, true); + SetTamingFoodControls(_selectedSpecies, false, true); } private void CbSanguineElixir_CheckedChanged(object sender, EventArgs e) { - SetSpecies(_selectedSpecies, true); + SetTamingFoodControls(_selectedSpecies, false, true); } public void SetLocalizations() diff --git a/ARKBreedingStats/TamingControl.resx b/ARKBreedingStats/TamingControl.resx index a24067c66..01c4dc393 100644 --- a/ARKBreedingStats/TamingControl.resx +++ b/ARKBreedingStats/TamingControl.resx @@ -937,7 +937,7 @@ 77, 20 - 7 + 1 nudTotalFood @@ -964,7 +964,7 @@ 58, 13 - 6 + 0 Total Food @@ -988,7 +988,7 @@ 77, 20 - 4 + 3 nudCurrentFood @@ -1012,7 +1012,7 @@ 157, 23 - 3 + 5 add Starving-Timer @@ -1042,7 +1042,7 @@ 68, 13 - 5 + 2 Current Food @@ -1069,7 +1069,7 @@ 207, 68 - 2 + 4 Time until starving: diff --git a/ARKBreedingStats/TamingFoodControl.cs b/ARKBreedingStats/TamingFoodControl.cs index 32f5cb3cb..3090668d8 100644 --- a/ARKBreedingStats/TamingFoodControl.cs +++ b/ARKBreedingStats/TamingFoodControl.cs @@ -33,7 +33,7 @@ public string FoodName set { _foodName = value; - foodNameDisplay = _foodName; + FoodNameDisplay = _foodName; // display specific colors of kibbles switch (_foodName) @@ -49,22 +49,22 @@ public string FoodName } } - public int amount + /// + /// Food amount currently set. + /// + public int Amount { get => (int)numericUpDown1.Value; - set - { - if (value >= 0) numericUpDown1.Value = value; - } + set => numericUpDown1.Value = Math.Max(0, value); } - public string foodNameDisplay + public string FoodNameDisplay { get => groupBox1.Text; set => groupBox1.Text = value; } - public int maxFood + public int MaxFood { get => maxFoodAmount; set @@ -74,7 +74,7 @@ public int maxFood } } - public TimeSpan tamingDuration + public TimeSpan TamingDuration { set { @@ -90,7 +90,10 @@ private void numericUpDown1_ValueChanged(object sender, EventArgs e) valueChanged?.Invoke(); } - public int foodUsed + /// + /// Amount of food used during taming. + /// + public int FoodUsed { set => labelFoodUsed.Text = value.ToString(); } diff --git a/ARKBreedingStats/Utils.cs b/ARKBreedingStats/Utils.cs index 9f5001dbc..69b0d9c42 100644 --- a/ARKBreedingStats/Utils.cs +++ b/ARKBreedingStats/Utils.cs @@ -585,6 +585,14 @@ public static Guid ConvertArkIdToGuid(long arkId) return new Guid(bytes); } + /// + /// This function may only be used if the Guid is created by an imported Ark id (i.e. two int32) + /// + public static long ConvertCreatureGuidToArkId(Guid guid) + { + return BitConverter.ToInt64(guid.ToByteArray(), 0); + } + public static bool IsArkIdImported(long arkId, Guid guid) { return arkId != 0 @@ -603,6 +611,11 @@ public static bool IsArkIdImported(long arkId, Guid guid) /// public static long ConvertArkIdsToLongArkId(int id1, int id2) => ((long)id1 << 32) | (id2 & 0xFFFFFFFFL); + /// + /// Converts int64 Ark id to two int32 ids, like used in the game. + /// + public static (int, int) ConvertArkId64ToArkIds32(long id) => ((int)(id >> 32), (int)id); + /// /// returns a shortened string with an ellipsis in the middle. One third of the beginning is shown and two thirds of then end /// diff --git a/ARKBreedingStats/_manifest.json b/ARKBreedingStats/_manifest.json index f7a554706..49ac3de59 100644 --- a/ARKBreedingStats/_manifest.json +++ b/ARKBreedingStats/_manifest.json @@ -4,7 +4,7 @@ "ARK Smart Breeding": { "Id": "ARK Smart Breeding", "Category": "main", - "version": "0.58.1.0" + "version": "0.59.2.0" }, "SpeciesColorImages": { "Id": "SpeciesColorImages", diff --git a/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs b/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs index a8ed4ada9..908b6eff7 100644 --- a/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs +++ b/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; namespace ARKBreedingStats.importExportGun @@ -9,6 +10,7 @@ namespace ARKBreedingStats.importExportGun [JsonObject] internal class ExportGunCreatureFile { + public int Version { get; set; } = 1; public string DinoName { get; set; } public string SpeciesName { get; set; } public string TribeName { get; set; } @@ -16,12 +18,25 @@ internal class ExportGunCreatureFile public string OwningPlayerName { get; set; } public string ImprinterName { get; set; } public int OwningPlayerID { get; set; } - public int DinoID1 { get; set; } - public int DinoID2 { get; set; } + public string DinoID1 { get; set; } + public string DinoID2 { get; set; } + [JsonIgnore] + public int DinoId1Int { get => int.TryParse(DinoID1, out var id) ? id : 0; set => DinoID1 = value.ToString(); } + [JsonIgnore] + public int DinoId2Int { get => int.TryParse(DinoID2, out var id) ? id : 0; set => DinoID2 = value.ToString(); } public Ancestry Ancestry { get; set; } public string BlueprintPath { get; set; } public Stat[] Stats { get; set; } - public byte[] ColorSetIndices { get; set; } + + [JsonIgnore] + public byte[] ColorIds; + [JsonProperty] + private int[] ColorSetIndices + { + set => ColorIds = value?.Select(i => (byte)i).ToArray(); + get => ColorIds?.Select(i => (int)i).ToArray(); + } + public Dictionary ColorSetValues { get; set; } public bool IsFemale { get; set; } public float NextAllowedMatingTimeDuration { get; set; } @@ -43,11 +58,19 @@ internal class ExportGunCreatureFile internal class Ancestry { public string MaleName { get; set; } - public int MaleDinoId1 { get; set; } - public int MaleDinoId2 { get; set; } + public string MaleDinoId1 { get; set; } + public string MaleDinoId2 { get; set; } public string FemaleName { get; set; } - public int FemaleDinoId1 { get; set; } - public int FemaleDinoId2 { get; set; } + public string FemaleDinoId1 { get; set; } + public string FemaleDinoId2 { get; set; } + [JsonIgnore] + public int MaleDinoId1Int { get => int.TryParse(MaleDinoId1, out var id) ? id : 0; set => MaleDinoId1 = value.ToString(); } + [JsonIgnore] + public int MaleDinoId2Int { get => int.TryParse(MaleDinoId2, out var id) ? id : 0; set => MaleDinoId2 = value.ToString(); } + [JsonIgnore] + public int FemaleDinoId1Int { get => int.TryParse(FemaleDinoId1, out var id) ? id : 0; set => FemaleDinoId1 = value.ToString(); } + [JsonIgnore] + public int FemaleDinoId2Int { get => int.TryParse(FemaleDinoId2, out var id) ? id : 0; set => FemaleDinoId2 = value.ToString(); } } [JsonObject] diff --git a/ARKBreedingStats/importExportGun/ExportGunServerFile.cs b/ARKBreedingStats/importExportGun/ExportGunServerFile.cs index f0a942020..0ebc519cb 100644 --- a/ARKBreedingStats/importExportGun/ExportGunServerFile.cs +++ b/ARKBreedingStats/importExportGun/ExportGunServerFile.cs @@ -16,18 +16,19 @@ internal class ExportGunServerFile public double WildLevelStepSize { get; set; } public int MaxWildLevel { get; set; } public int DestroyTamesOverLevelClamp { get; set; } - public double TamingSpeedMultiplier { get; set; } - public double WildDinoTorporDrainMultiplier { get; set; } - public double DinoCharacterFoodDrainMultiplier { get; set; } - public double MatingSpeedMultiplier { get; set; } - public double MatingIntervalMultiplier { get; set; } - public double EggHatchSpeedMultiplier { get; set; } - public double BabyMatureSpeedMultiplier { get; set; } - public double BabyCuddleIntervalMultiplier { get; set; } - public double BabyImprintAmountMultiplier { get; set; } - public double BabyImprintingStatScaleMultiplier { get; set; } - public double BabyFoodConsumptionSpeedMultiplier { get; set; } - public double TamedDinoCharacterFoodDrainMultiplier { get; set; } + public double TamingSpeedMultiplier { get; set; } = 1; + public double WildDinoTorporDrainMultiplier { get; set; } = 1; + public double DinoCharacterFoodDrainMultiplier { get; set; } = 1; + public double WildDinoCharacterFoodDrainMultiplier { get; set; } = 1; + public double TamedDinoCharacterFoodDrainMultiplier { get; set; } = 1; + public double MatingSpeedMultiplier { get; set; } = 1; + public double MatingIntervalMultiplier { get; set; } = 1; + public double EggHatchSpeedMultiplier { get; set; } = 1; + public double BabyMatureSpeedMultiplier { get; set; } = 1; + public double BabyCuddleIntervalMultiplier { get; set; } = 1; + public double BabyImprintAmountMultiplier { get; set; } = 1; + public double BabyImprintingStatScaleMultiplier { get; set; } = 1; + public double BabyFoodConsumptionSpeedMultiplier { get; set; } = 1; public bool AllowSpeedLeveling { get; set; } public bool AllowFlyerSpeedLeveling { get; set; } public bool UseSingleplayerSettings { get; set; } diff --git a/ARKBreedingStats/importExportGun/ImportExportGun.cs b/ARKBreedingStats/importExportGun/ImportExportGun.cs index 0dc1776b9..cf72e7d35 100644 --- a/ARKBreedingStats/importExportGun/ImportExportGun.cs +++ b/ARKBreedingStats/importExportGun/ImportExportGun.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading; using ARKBreedingStats.Library; using ARKBreedingStats.values; using Newtonsoft.Json; @@ -21,38 +22,61 @@ public static Creature ImportCreature(string filePath, out string resultText, ou if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) return null; - try + const int tryLoadCount = 3; + const int waitAfterFailedLoadMs = 200; + + for (int tryIndex = 0; tryIndex < tryLoadCount; tryIndex++) { - string jsonText = null; - switch (Path.GetExtension(filePath)) + try { - case ".sav": - jsonText = ReadExportFile.ReadFile(filePath, "DinoExportGunSave_C", out resultText); - break; - case ".json": - jsonText = File.ReadAllText(filePath); - break; - } + string jsonText = null; + switch (Path.GetExtension(filePath)) + { + case ".sav": + jsonText = ReadExportFile.ReadFile(filePath, "DinoExportGunSave_C", out resultText); + break; + case ".json": + jsonText = File.ReadAllText(filePath); + break; + } - if (string.IsNullOrEmpty(jsonText)) + return ImportCreatureFromJson(jsonText, resultText, out resultText, out serverMultipliersHash); + + } + catch (IOException) when (tryIndex < tryLoadCount - 1) { - resultText = $"Error when importing file {filePath}: {resultText}"; + // file is probably still being written. Try up to 3 times again after some time. + Thread.Sleep(waitAfterFailedLoadMs * (1 << tryIndex)); + } + catch (Exception ex) + { + resultText = $"Error when importing file {filePath}: {ex.Message}"; return null; } + } - var exportedCreature = JsonConvert.DeserializeObject(jsonText); - if (exportedCreature == null) return null; - - serverMultipliersHash = exportedCreature.ServerMultipliersHash; + return null; + } - return ConvertExportGunToCreature(exportedCreature, out resultText); + public static Creature ImportCreatureFromJson(string jsonText, string resultSoFar, out string resultText, out string serverMultipliersHash, string filePath = null) + { + resultText = resultSoFar; + serverMultipliersHash = null; + if (string.IsNullOrEmpty(jsonText)) + { + resultText = $"Error when importing file {filePath}: {resultText}"; + return null; } - catch (Exception ex) + var exportedCreature = JsonConvert.DeserializeObject(jsonText); + if (exportedCreature == null) { - resultText = $"Error when importing file {filePath}: {ex.Message}"; + resultText = "jsonText couldn't be deserialized"; + return null; } - return null; + serverMultipliersHash = exportedCreature.ServerMultipliersHash; + + return ConvertExportGunToCreature(exportedCreature, out resultText); } private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out string error) @@ -79,7 +103,7 @@ private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out si++; } - var arkId = Utils.ConvertArkIdsToLongArkId(ec.DinoID1, ec.DinoID2); + var arkId = Utils.ConvertArkIdsToLongArkId(ec.DinoId1Int, ec.DinoId2Int); var isWild = string.IsNullOrEmpty(ec.DinoName) && string.IsNullOrEmpty(ec.TribeName) @@ -98,10 +122,11 @@ private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out guid = Utils.ConvertArkIdToGuid(arkId), ArkIdImported = true, ArkIdInGame = Utils.ConvertImportedArkIdToIngameVisualization(arkId), - colors = ec.ColorSetIndices, + colors = ec.ColorIds, Maturation = ec.BabyAge, mutationsMaternal = ec.RandomMutationsFemale, - mutationsPaternal = ec.RandomMutationsMale + mutationsPaternal = ec.RandomMutationsMale, + generation = -1 // indication that it has to be recalculated }; c.RecalculateCreatureValues(CreatureCollection.CurrentCreatureCollection?.wildLevelStep); @@ -113,19 +138,79 @@ private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out c.flags |= CreatureFlags.Neutered; if (ec.Ancestry != null) { - if (ec.Ancestry.FemaleDinoId1 != 0 || ec.Ancestry.FemaleDinoId2 != 0) + if (ec.Ancestry.FemaleDinoId1Int != 0 || ec.Ancestry.FemaleDinoId2Int != 0) c.motherGuid = - Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId(ec.Ancestry.FemaleDinoId1, - ec.Ancestry.FemaleDinoId2)); - if (ec.Ancestry.MaleDinoId1 != 0 || ec.Ancestry.MaleDinoId2 != 0) + Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId(ec.Ancestry.FemaleDinoId1Int, + ec.Ancestry.FemaleDinoId2Int)); + if (ec.Ancestry.MaleDinoId1Int != 0 || ec.Ancestry.MaleDinoId2Int != 0) c.fatherGuid = - Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId(ec.Ancestry.MaleDinoId1, - ec.Ancestry.MaleDinoId2)); + Utils.ConvertArkIdToGuid(Utils.ConvertArkIdsToLongArkId(ec.Ancestry.MaleDinoId1Int, + ec.Ancestry.MaleDinoId2Int)); } return c; } + public static ExportGunCreatureFile ConvertCreatureToExportGunFile(Creature c, out string error) + { + error = null; + if (c == null) return null; + + var stats = new Stat[Stats.StatsCount]; + + for (var si = 0; si < Stats.StatsCount; si++) + { + stats[si] = new Stat + { + Wild = c.levelsWild?[si] ?? 0, + Tamed = c.levelsDom?[si] ?? 0, + Mutated = c.levelsMutated?[si] ?? 0, + Value = (float)c.valuesDom[si] + }; + } + + var (id1, id2) = Utils.ConvertArkId64ToArkIds32(c.ArkId); + + Ancestry ancestry = null; + if (c.motherGuid != Guid.Empty || c.fatherGuid != Guid.Empty) + { + ancestry = new Ancestry(); + if (c.motherGuid != Guid.Empty) + (ancestry.FemaleDinoId1Int, ancestry.FemaleDinoId2Int) = + Utils.ConvertArkId64ToArkIds32(Utils.ConvertCreatureGuidToArkId(c.motherGuid)); + if (c.fatherGuid != Guid.Empty) + (ancestry.MaleDinoId1Int, ancestry.MaleDinoId2Int) = + Utils.ConvertArkId64ToArkIds32(Utils.ConvertCreatureGuidToArkId(c.fatherGuid)); + } + + var ec = new ExportGunCreatureFile + { + BlueprintPath = c.speciesBlueprint, + Stats = stats, + DinoId1Int = id1, + DinoId2Int = id2, + DinoName = c.name, + ImprinterName = c.imprinterName, + Ancestry = ancestry, + BabyAge = (float)c.Maturation, + BaseCharacterLevel = c.Level, + ColorIds = c.colors, + DinoImprintingQuality = (float)c.imprintingBonus, + IsFemale = c.sex == Sex.Female, + MutagenApplied = c.flags.HasFlag(CreatureFlags.MutagenApplied), + SpeciesName = c.Species?.name, + Neutered = c.flags.HasFlag(CreatureFlags.Neutered), + RandomMutationsFemale = c.mutationsMaternal, + RandomMutationsMale = c.mutationsPaternal, + TameEffectiveness = (float)c.tamingEff, + TamerString = c.owner, + TribeName = c.tribe, + NextAllowedMatingTimeDuration = c.cooldownUntil == null ? 0 : (c.cooldownUntil.Value - DateTime.Now).Seconds + }; + + return ec; + } + /// /// Import server multipliers file from the export gun mod. /// @@ -136,50 +221,74 @@ public static bool ImportServerMultipliers(CreatureCollection cc, string filePat return SetServerMultipliers(cc, exportedServerMultipliers, newServerMultipliersHash); } + /// + /// Import server multipliers file from the export gun mod. + /// + public static bool ImportServerMultipliersFromJson(CreatureCollection cc, string jsonServerMultipliers, string newServerMultipliersHash, out string resultText) + { + var exportedServerMultipliers = ReadServerMultipliersFromJson(jsonServerMultipliers, null, out resultText); + if (exportedServerMultipliers == null) return false; + return SetServerMultipliers(cc, exportedServerMultipliers, newServerMultipliersHash); + } + internal static ExportGunServerFile ReadServerMultipliers(string filePath, out string resultText) { resultText = null; if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) return null; - try + const int tryLoadCount = 3; + const int waitAfterFailedLoadMs = 200; + + for (int tryIndex = 0; tryIndex < tryLoadCount; tryIndex++) { - string jsonText = null; - string game = null; - switch (Path.GetExtension(filePath)) + try { - case ".sav": - jsonText = ReadExportFile.ReadFile(filePath, "DinoExportGunServerSave_C", out resultText); - game = "ASE"; - break; - case ".json": - jsonText = File.ReadAllText(filePath); - game = "ASA"; - break; + string jsonText = null; + string game = null; + switch (Path.GetExtension(filePath)) + { + case ".sav": + jsonText = ReadExportFile.ReadFile(filePath, "DinoExportGunServerSave_C", out resultText); + game = "ASE"; + break; + case ".json": + jsonText = File.ReadAllText(filePath); + game = "ASA"; + break; + } + + return ReadServerMultipliersFromJson(jsonText, resultText, out resultText, game, filePath); } - if (jsonText == null) + catch (IOException) when (tryIndex < tryLoadCount - 1) { - resultText = $"Error when importing file {filePath}: {resultText}"; - return null; + // file is probably still being written. Try up to 3 times again after some time. + Thread.Sleep(waitAfterFailedLoadMs * (1 << tryIndex)); } - - var exportedServerMultipliers = JsonConvert.DeserializeObject(jsonText); - if (exportedServerMultipliers?.WildLevel == null) + catch (Exception ex) { - resultText = $"Unknown error when importing file {filePath}"; + resultText = $"Error when importing file {filePath}: {ex.Message}"; return null; } - - exportedServerMultipliers.Game = game; - resultText = $"Server multipliers imported from {filePath}"; - return exportedServerMultipliers; } - catch (Exception ex) + + return null; + } + + public static ExportGunServerFile ReadServerMultipliersFromJson(string jsonText, string resultSoFar, out string resultText, string game = null, string filePath = null) + { + resultText = resultSoFar; + var exportedServerMultipliers = JsonConvert.DeserializeObject(jsonText); + if (string.IsNullOrEmpty(jsonText)) { - resultText = $"Error when importing file {filePath}: {ex.Message}"; + resultText = $"Error when importing file {filePath}: {resultText}"; + return null; } - return null; + if (string.IsNullOrEmpty(exportedServerMultipliers.Game)) + exportedServerMultipliers.Game = game; + resultText = $"Server multipliers imported from {filePath}"; + return exportedServerMultipliers; } internal static bool SetServerMultipliers(CreatureCollection cc, ExportGunServerFile esm, string newServerMultipliersHash) @@ -199,6 +308,8 @@ internal static bool SetServerMultipliers(CreatureCollection cc, ExportGunServer cc.maxServerLevel = esm.DestroyTamesOverLevelClamp; cc.serverMultipliers.TamingSpeedMultiplier = Math.Round(esm.TamingSpeedMultiplier, roundToDigits); cc.serverMultipliers.DinoCharacterFoodDrainMultiplier = Math.Round(esm.DinoCharacterFoodDrainMultiplier, roundToDigits); + cc.serverMultipliers.WildDinoCharacterFoodDrainMultiplier = Math.Round(esm.WildDinoCharacterFoodDrainMultiplier, roundToDigits); + cc.serverMultipliers.TamedDinoCharacterFoodDrainMultiplier = Math.Round(esm.TamedDinoCharacterFoodDrainMultiplier, roundToDigits); cc.serverMultipliers.WildDinoTorporDrainMultiplier = Math.Round(esm.WildDinoTorporDrainMultiplier, roundToDigits); cc.serverMultipliers.MatingSpeedMultiplier = Math.Round(esm.MatingSpeedMultiplier, roundToDigits); cc.serverMultipliers.MatingIntervalMultiplier = Math.Round(esm.MatingIntervalMultiplier, roundToDigits); @@ -208,7 +319,6 @@ internal static bool SetServerMultipliers(CreatureCollection cc, ExportGunServer cc.serverMultipliers.BabyImprintAmountMultiplier = Math.Round(esm.BabyImprintAmountMultiplier, roundToDigits); cc.serverMultipliers.BabyImprintingStatScaleMultiplier = Math.Round(esm.BabyImprintingStatScaleMultiplier, roundToDigits); cc.serverMultipliers.BabyFoodConsumptionSpeedMultiplier = Math.Round(esm.BabyFoodConsumptionSpeedMultiplier, roundToDigits); - cc.serverMultipliers.TamedDinoCharacterFoodDrainMultiplier = Math.Round(esm.TamedDinoCharacterFoodDrainMultiplier, roundToDigits); cc.serverMultipliers.AllowSpeedLeveling = esm.AllowSpeedLeveling; cc.serverMultipliers.AllowFlyerSpeedLeveling = esm.AllowFlyerSpeedLeveling; cc.singlePlayerSettings = esm.UseSingleplayerSettings; diff --git a/ARKBreedingStats/json/values/ASA-values.json b/ARKBreedingStats/json/values/ASA-values.json index e97284143..471706e61 100644 --- a/ARKBreedingStats/json/values/ASA-values.json +++ b/ARKBreedingStats/json/values/ASA-values.json @@ -1,12 +1,11 @@ { - "version": "25.53.449746", + "version": "32.11.468629", "format": "1.15-asa", "mod": { "id": "ASA", "tag": "", "title": "Ark: Survival Ascended", - "shortTitle": "ASA", - "official": true + "shortTitle": "ASA" }, "species": [ { @@ -1341,7 +1340,21 @@ }, { "blueprintPath": "/Game/PrimalEarth/Dinos/Rhyniognatha/Rhynio_Character_BP.Rhynio_Character_BP", - "skipWildLevelStats": 512 + "skipWildLevelStats": 512, + "fullStatsRaw": [ + [ 900, 0.17, 0.1755, 0.5, 0 ], + [ 350, 0.05, 0.06, 0, 0 ], + [ 800, 0.06, 0, 0.5, 0 ], + [ 800, 0.1, 0.1, 0, 0 ], + [ 1600, 0.1, 0.1, 0, 0.15 ], + null, + null, + [ 1100, 0.02, 0.04, 0, 0 ], + [ 1, 0.05, 0.1, 0.5, 0.4 ], + [ 1, 0, 0.01, 0, 0 ], + null, + null + ] }, { "blueprintPath": "/Game/PrimalEarth/Dinos/Saber/Saber_Character_BP.Saber_Character_BP", diff --git a/ARKBreedingStats/json/values/_manifest.json b/ARKBreedingStats/json/values/_manifest.json index ba0af9543..288ef31d7 100644 --- a/ARKBreedingStats/json/values/_manifest.json +++ b/ARKBreedingStats/json/values/_manifest.json @@ -30,7 +30,7 @@ "mod": { "id": "1139775728", "tag": "Confuciusornis", "title": "Confuciusornis" } }, "1169020368-Trex.json": { - "version": "358.17.1700597183", + "version": "358.17.1701004683", "mod": { "id": "1169020368", "tag": "Trex", "title": "Ark Creature Rebalance (AG Reborn)" } }, "1178308359-ShadDragon.json": { @@ -310,11 +310,11 @@ "mod": { "id": "2362246280", "tag": "GigaFullTame", "title": "Giga Full Tame" } }, "2447186973-ArkOmega.json": { - "version": "358.17.1697907008", + "version": "358.17.1701673974", "mod": { "id": "2447186973", "tag": "ArkOmega", "title": "Ark Omega" } }, "2453342929-MoreDragonsMod.json": { - "version": "358.11.1691443191", + "version": "358.17.1701039233", "mod": { "id": "2453342929", "tag": "MoreDragonsMod", "title": "More Dragons Evolved" } }, "2472371628-MilicrocaWarriors_MOD.json": { @@ -378,7 +378,7 @@ "mod": { "id": "883957187", "tag": "WyvernWorld", "title": "Wyvern World" } }, "893735676-AE.json": { - "version": "358.17.1696662074", + "version": "358.17.1701815786", "mod": { "id": "893735676", "tag": "AE", "title": "Ark Eternal" } }, "895711211-ClassicFlyers.json": { @@ -398,9 +398,9 @@ "mod": { "id": "919470289", "tag": "SSFlyer", "title": "SSFlyer" } }, "ASA-values.json": { - "version": "25.53.449746", + "version": "32.11.468629", "format": "1.15-asa", - "mod": { "id": "ASA", "tag": "", "title": "Ark: Survival Ascended", "shortTitle": "ASA", "official": true } + "mod": { "id": "ASA", "tag": "", "title": "Ark: Survival Ascended", "shortTitle": "ASA" } }, "CrystalIsles-CrystalIsles.json": { "version": "345.39.8870324.1", diff --git a/ARKBreedingStats/library/Creature.cs b/ARKBreedingStats/library/Creature.cs index 88403c448..d1c7eae96 100644 --- a/ARKBreedingStats/library/Creature.cs +++ b/ARKBreedingStats/library/Creature.cs @@ -445,8 +445,8 @@ public void RecalculateCreatureValues(int? levelStep) InitializeArrays(); for (int s = 0; s < Stats.StatsCount; s++) { - valuesBreeding[s] = StatValueCalculation.CalculateValue(Species, s, levelsWild[s], 0, true, 1, 0); - valuesDom[s] = StatValueCalculation.CalculateValue(Species, s, levelsWild[s], levelsDom[s], true, tamingEff, imprintingBonus); + valuesBreeding[s] = StatValueCalculation.CalculateValue(Species, s, levelsWild[s], levelsMutated?[s] ?? 0, 0, true, 1, 0); + valuesDom[s] = StatValueCalculation.CalculateValue(Species, s, levelsWild[s], levelsMutated?[s] ?? 0, levelsDom[s], true, tamingEff, imprintingBonus); } } diff --git a/ARKBreedingStats/library/CreatureCollection.cs b/ARKBreedingStats/library/CreatureCollection.cs index dad0e9a9a..424290ac5 100644 --- a/ARKBreedingStats/library/CreatureCollection.cs +++ b/ARKBreedingStats/library/CreatureCollection.cs @@ -148,6 +148,7 @@ public CreatureCollection() public Dictionary CustomSpeciesStats; private Dictionary _creatureCountBySpecies; + private int _totalCreatureCount; /// /// Calculates a hashcode for a list of mods and their order. Can be used to check for changes. @@ -317,6 +318,14 @@ void UpdateString(ref string oldCreatureValue, ref string newCreatureValue) creaturesWereAddedOrUpdated = true; } + if ((creatureExisting.levelsMutated == null && creatureNew.levelsMutated != null) + || (creatureExisting.levelsMutated != null && creatureNew.levelsMutated != null && !creatureExisting.levelsMutated.SequenceEqual(creatureNew.levelsMutated))) + { + creatureExisting.levelsMutated = creatureNew.levelsMutated; + recalculate = true; + creaturesWereAddedOrUpdated = true; + } + if (!creatureExisting.levelsDom.SequenceEqual(creatureNew.levelsDom)) { creatureExisting.levelsDom = creatureNew.levelsDom; @@ -354,6 +363,7 @@ void UpdateString(ref string oldCreatureValue, ref string newCreatureValue) { ResetExistingColors(onlyOneSpeciesAdded ? onlyThisSpeciesBlueprintAdded : null); _creatureCountBySpecies = null; + _totalCreatureCount = -1; } return creaturesWereAddedOrUpdated; @@ -371,6 +381,7 @@ internal void DeleteCreature(Creature c) DeletedCreatureGuids.Add(c.guid); ResetExistingColors(c.Species.blueprintPath); _creatureCountBySpecies = null; + _totalCreatureCount = -1; } public int? getWildLevelStep() @@ -631,5 +642,16 @@ public Dictionary GetCreatureCountBySpecies(bool recalculate = fals return _creatureCountBySpecies; } + + /// + /// Returns total creature count. Ignoring placeholders. + /// + /// + public int GetTotalCreatureCount() + { + if (_totalCreatureCount == -1) + _totalCreatureCount = creatures.Count(c => !c.flags.HasFlag(CreatureFlags.Placeholder)); + return _totalCreatureCount; + } } } diff --git a/ARKBreedingStats/library/CreatureInfoGraphic.cs b/ARKBreedingStats/library/CreatureInfoGraphic.cs index 9b4fa4259..46190ad6c 100644 --- a/ARKBreedingStats/library/CreatureInfoGraphic.cs +++ b/ARKBreedingStats/library/CreatureInfoGraphic.cs @@ -54,7 +54,7 @@ public static Bitmap InfoGraphic(this Creature creature, CreatureCollection cc, if (maxGraphLevel < 1) maxGraphLevel = 50; int height = infoGraphicHeight < 1 ? 180 : infoGraphicHeight; // 180 - int width = height * 11 / 6; // 330 + int width = height * 12 / 6; // 330 if (displayExtraRegionNames) width += height / 2; @@ -127,10 +127,11 @@ public static Bitmap InfoGraphic(this Creature creature, CreatureCollection cc, double meanLetterWidth = fontSize * 7d / 10; int xStatName = (int)meanLetterWidth; // x position of level number. torpor is the largest level number. - int xRightLevelValue = (int)(xStatName + ((displayWithDomLevels ? 6 : 5) + creature.levelsWild[2].ToString().Length) * meanLetterWidth); - int xRightLevelDomValue = xRightLevelValue; + int xRightLevelValue = (int)(xStatName + ((displayWithDomLevels ? 6 : 5) + creature.levelsWild[Stats.Torpidity].ToString().Length) * meanLetterWidth); + int xRightLevelMutValue = xRightLevelValue + (creature.levelsMutated == null ? 0 : (int)((creature.levelsMutated.Max().ToString().Length + 3) * meanLetterWidth)); + int xRightLevelDomValue = xRightLevelMutValue; if (displayWithDomLevels) - xRightLevelDomValue += (int)((creature.levelsDom.Max().ToString().Length) * meanLetterWidth); + xRightLevelDomValue += (int)(creature.levelsDom.Max().ToString().Length * meanLetterWidth); int xRightBrValue = (int)(xRightLevelDomValue + (2 + MaxCharLength(creature.valuesBreeding)) * meanLetterWidth); int maxBoxLength = xRightBrValue - xStatName; int statBoxHeight = Math.Max(2, height / 90); @@ -169,8 +170,11 @@ public static Bitmap InfoGraphic(this Creature creature, CreatureCollection cc, g.DrawString($"{Utils.StatName(statIndex, true, creature.Species.statNames, secondaryCulture)}", font, fontBrush, xStatName, y); // stat level number - g.DrawString($"{(creature.levelsWild[statIndex] < 0 ? "?" : creature.levelsWild[statIndex].ToString())}{(displayWithDomLevels ? " +" : null)}", + g.DrawString($"{(creature.levelsWild[statIndex] < 0 ? "?" : creature.levelsWild[statIndex].ToString())}{(creature.levelsMutated != null ? " |" : displayWithDomLevels ? " +" : null)}", font, fontBrush, xRightLevelValue, y, stringFormatRight); + if (creature.levelsMutated != null) + g.DrawString($"{(creature.levelsMutated[statIndex] < 0 ? string.Empty : creature.levelsMutated[statIndex].ToString())}{(displayWithDomLevels ? " +" : null)}", + font, fontBrush, xRightLevelMutValue, y, stringFormatRight); // dom level number if (displayWithDomLevels) g.DrawString($"{creature.levelsDom[statIndex]}", diff --git a/ARKBreedingStats/library/CreatureValues.cs b/ARKBreedingStats/library/CreatureValues.cs index 4a433fc49..74ebec38a 100644 --- a/ARKBreedingStats/library/CreatureValues.cs +++ b/ARKBreedingStats/library/CreatureValues.cs @@ -39,6 +39,8 @@ public class CreatureValues [JsonProperty] public int[] levelsWild = new int[Stats.StatsCount]; [JsonProperty] + public int[] levelsMut = new int[Stats.StatsCount]; + [JsonProperty] public int[] levelsDom = new int[Stats.StatsCount]; [JsonProperty] public int level; diff --git a/ARKBreedingStats/library/DummyCreatures.cs b/ARKBreedingStats/library/DummyCreatures.cs index ba92895d2..e304a14b7 100644 --- a/ARKBreedingStats/library/DummyCreatures.cs +++ b/ARKBreedingStats/library/DummyCreatures.cs @@ -115,7 +115,7 @@ public static List CreateCreatures(int count, Species species = null, /// /// Creates a creature for testing. /// - public static Creature CreateCreature(Species species, double difficulty, bool doTame = true, Random rand = null, bool setOwner = true, bool setTribe = true, bool setServer = true, Dictionary nameCounter = null) + public static Creature CreateCreature(Species species, double difficulty = 5, bool doTame = true, Random rand = null, bool setOwner = true, bool setTribe = true, bool setServer = true, Dictionary nameCounter = null) { if (rand == null) rand = new Random(); @@ -165,7 +165,8 @@ public static Creature CreateCreature(Species species, double difficulty, bool d var creature = new Creature(species, name, sex: sex, levelsWild: levelsWild, levelsDom: levelsDom, tamingEff: tamingEffectiveness) { - guid = Guid.NewGuid() + guid = Guid.NewGuid(), + ArkId = Utils.ConvertArkIdsToLongArkId(rand.Next(), rand.Next()) }; creature.RecalculateCreatureValues((int)difficulty); diff --git a/ARKBreedingStats/local/strings.de.resx b/ARKBreedingStats/local/strings.de.resx index 7759a37b6..9e65eabfc 100644 --- a/ARKBreedingStats/local/strings.de.resx +++ b/ARKBreedingStats/local/strings.de.resx @@ -1328,4 +1328,7 @@ Es ist auch möglich Tiere mit einer Farbe in mehreren möglichen Regionen zu fi Verhungern von + + Klicken um in die Zwischenablage zu kopieren + \ No newline at end of file diff --git a/ARKBreedingStats/local/strings.fr.resx b/ARKBreedingStats/local/strings.fr.resx index d5a8e64ba..6da36a643 100644 --- a/ARKBreedingStats/local/strings.fr.resx +++ b/ARKBreedingStats/local/strings.fr.resx @@ -1335,4 +1335,7 @@ Il est également possible de filtrer les créatures par couleur dans l'une des Ce nom existe déjà dans la bibliothèque + + Affamement de + \ No newline at end of file diff --git a/ARKBreedingStats/local/strings.resx b/ARKBreedingStats/local/strings.resx index d012cb520..e32916878 100644 --- a/ARKBreedingStats/local/strings.resx +++ b/ARKBreedingStats/local/strings.resx @@ -1340,4 +1340,7 @@ It's also possible to filter for creatures with a color in one of multiple possi Starving of + + Click to copy to clipboard + \ No newline at end of file diff --git a/ARKBreedingStats/settings/Settings.Designer.cs b/ARKBreedingStats/settings/Settings.Designer.cs index 6f338223c..f6b49e4f8 100644 --- a/ARKBreedingStats/settings/Settings.Designer.cs +++ b/ARKBreedingStats/settings/Settings.Designer.cs @@ -213,6 +213,7 @@ private void InitializeComponent() this.label50 = new System.Windows.Forms.Label(); this.tabPageImportSavegame = new System.Windows.Forms.TabPage(); this.groupBox12 = new System.Windows.Forms.GroupBox(); + this.label68 = new System.Windows.Forms.Label(); this.CbImportUnclaimedBabies = new System.Windows.Forms.CheckBox(); this.cbSaveImportCryo = new System.Windows.Forms.CheckBox(); this.cbIgnoreUnknownBPOnSaveImport = new System.Windows.Forms.CheckBox(); @@ -348,7 +349,8 @@ private void InitializeComponent() this.label1 = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); this.colorDialog1 = new System.Windows.Forms.ColorDialog(); - this.label68 = new System.Windows.Forms.Label(); + this.label69 = new System.Windows.Forms.Label(); + this.NudWildDinoCharacterFoodDrainMultiplier = new ARKBreedingStats.uiControls.Nud(); this.groupBoxMultiplier.SuspendLayout(); this.groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudTamedDinoCharacterFoodDrain)).BeginInit(); @@ -457,6 +459,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).BeginInit(); this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).BeginInit(); this.SuspendLayout(); // // groupBoxMultiplier @@ -627,9 +630,9 @@ private void InitializeComponent() this.groupBox2.Controls.Add(this.nudBabyImprintingStatScale); this.groupBox2.Controls.Add(this.label8); this.groupBox2.Controls.Add(this.nudEggHatchSpeed); - this.groupBox2.Location = new System.Drawing.Point(394, 263); + this.groupBox2.Location = new System.Drawing.Point(394, 290); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(346, 255); + this.groupBox2.Size = new System.Drawing.Size(345, 255); this.groupBox2.TabIndex = 7; this.groupBox2.TabStop = false; this.groupBox2.Text = "Breeding-Multiplier"; @@ -1483,6 +1486,8 @@ private void InitializeComponent() // // groupBox5 // + this.groupBox5.Controls.Add(this.NudWildDinoCharacterFoodDrainMultiplier); + this.groupBox5.Controls.Add(this.label69); this.groupBox5.Controls.Add(this.label67); this.groupBox5.Controls.Add(this.NudWildDinoTorporDrainMultiplier); this.groupBox5.Controls.Add(this.nudDinoCharacterFoodDrainEvent); @@ -1493,7 +1498,7 @@ private void InitializeComponent() this.groupBox5.Controls.Add(this.nudTamingSpeed); this.groupBox5.Location = new System.Drawing.Point(394, 158); this.groupBox5.Name = "groupBox5"; - this.groupBox5.Size = new System.Drawing.Size(345, 99); + this.groupBox5.Size = new System.Drawing.Size(345, 126); this.groupBox5.TabIndex = 6; this.groupBox5.TabStop = false; this.groupBox5.Text = "Taming-Multiplier"; @@ -1501,7 +1506,7 @@ private void InitializeComponent() // label67 // this.label67.AutoSize = true; - this.label67.Location = new System.Drawing.Point(10, 73); + this.label67.Location = new System.Drawing.Point(10, 99); this.label67.Name = "label67"; this.label67.Size = new System.Drawing.Size(147, 13); this.label67.TabIndex = 5; @@ -1511,7 +1516,7 @@ private void InitializeComponent() // this.NudWildDinoTorporDrainMultiplier.DecimalPlaces = 6; this.NudWildDinoTorporDrainMultiplier.ForeColor = System.Drawing.SystemColors.WindowText; - this.NudWildDinoTorporDrainMultiplier.Location = new System.Drawing.Point(183, 71); + this.NudWildDinoTorporDrainMultiplier.Location = new System.Drawing.Point(183, 97); this.NudWildDinoTorporDrainMultiplier.Maximum = new decimal(new int[] { 10000, 0, @@ -1524,7 +1529,7 @@ private void InitializeComponent() 0, 0}); this.NudWildDinoTorporDrainMultiplier.Size = new System.Drawing.Size(72, 20); - this.NudWildDinoTorporDrainMultiplier.TabIndex = 4; + this.NudWildDinoTorporDrainMultiplier.TabIndex = 5; this.NudWildDinoTorporDrainMultiplier.Value = new decimal(new int[] { 1, 0, @@ -1572,7 +1577,7 @@ private void InitializeComponent() 0, 0}); this.nudTamingSpeedEvent.Size = new System.Drawing.Size(72, 20); - this.nudTamingSpeedEvent.TabIndex = 2; + this.nudTamingSpeedEvent.TabIndex = 1; this.nudTamingSpeedEvent.Value = new decimal(new int[] { 1, 0, @@ -1614,7 +1619,7 @@ private void InitializeComponent() 0, 0}); this.nudDinoCharacterFoodDrain.Size = new System.Drawing.Size(72, 20); - this.nudDinoCharacterFoodDrain.TabIndex = 1; + this.nudDinoCharacterFoodDrain.TabIndex = 2; this.nudDinoCharacterFoodDrain.Value = new decimal(new int[] { 1, 0, @@ -1647,7 +1652,7 @@ private void InitializeComponent() // // label15 // - this.label15.Location = new System.Drawing.Point(451, 554); + this.label15.Location = new System.Drawing.Point(451, 575); this.label15.Name = "label15"; this.label15.Size = new System.Drawing.Size(289, 77); this.label15.TabIndex = 9; @@ -1821,7 +1826,7 @@ private void InitializeComponent() this.tabControlSettings.Location = new System.Drawing.Point(0, 0); this.tabControlSettings.Name = "tabControlSettings"; this.tabControlSettings.SelectedIndex = 0; - this.tabControlSettings.Size = new System.Drawing.Size(758, 748); + this.tabControlSettings.Size = new System.Drawing.Size(758, 770); this.tabControlSettings.TabIndex = 11; // // tabPageMultipliers @@ -1851,7 +1856,7 @@ private void InitializeComponent() this.tabPageMultipliers.Location = new System.Drawing.Point(4, 22); this.tabPageMultipliers.Name = "tabPageMultipliers"; this.tabPageMultipliers.Padding = new System.Windows.Forms.Padding(3); - this.tabPageMultipliers.Size = new System.Drawing.Size(750, 722); + this.tabPageMultipliers.Size = new System.Drawing.Size(750, 744); this.tabPageMultipliers.TabIndex = 1; this.tabPageMultipliers.Text = "Multipliers"; this.tabPageMultipliers.UseVisualStyleBackColor = true; @@ -1871,7 +1876,7 @@ private void InitializeComponent() // BtAutoImportLocalSettings // this.BtAutoImportLocalSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192))))); - this.BtAutoImportLocalSettings.Location = new System.Drawing.Point(407, 621); + this.BtAutoImportLocalSettings.Location = new System.Drawing.Point(407, 642); this.BtAutoImportLocalSettings.Name = "BtAutoImportLocalSettings"; this.BtAutoImportLocalSettings.Size = new System.Drawing.Size(152, 23); this.BtAutoImportLocalSettings.TabIndex = 17; @@ -1913,7 +1918,7 @@ private void InitializeComponent() // // BtImportSettingsSelectFile // - this.BtImportSettingsSelectFile.Location = new System.Drawing.Point(565, 621); + this.BtImportSettingsSelectFile.Location = new System.Drawing.Point(565, 642); this.BtImportSettingsSelectFile.Name = "BtImportSettingsSelectFile"; this.BtImportSettingsSelectFile.Size = new System.Drawing.Size(167, 23); this.BtImportSettingsSelectFile.TabIndex = 15; @@ -1933,7 +1938,7 @@ private void InitializeComponent() // // BtSettingsToClipboard // - this.BtSettingsToClipboard.Location = new System.Drawing.Point(600, 692); + this.BtSettingsToClipboard.Location = new System.Drawing.Point(600, 713); this.BtSettingsToClipboard.Name = "BtSettingsToClipboard"; this.BtSettingsToClipboard.Size = new System.Drawing.Size(142, 23); this.BtSettingsToClipboard.TabIndex = 13; @@ -1975,7 +1980,7 @@ private void InitializeComponent() // // label34 // - this.label34.Location = new System.Drawing.Point(404, 655); + this.label34.Location = new System.Drawing.Point(404, 676); this.label34.Name = "label34"; this.label34.Size = new System.Drawing.Size(338, 34); this.label34.TabIndex = 10; @@ -1984,7 +1989,7 @@ private void InitializeComponent() // // btExportMultipliers // - this.btExportMultipliers.Location = new System.Drawing.Point(407, 692); + this.btExportMultipliers.Location = new System.Drawing.Point(407, 713); this.btExportMultipliers.Name = "btExportMultipliers"; this.btExportMultipliers.Size = new System.Drawing.Size(187, 23); this.btExportMultipliers.TabIndex = 11; @@ -2026,7 +2031,7 @@ private void InitializeComponent() // this.label27.AutoSize = true; this.label27.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label27.Location = new System.Drawing.Point(408, 555); + this.label27.Location = new System.Drawing.Point(408, 576); this.label27.Name = "label27"; this.label27.Size = new System.Drawing.Size(37, 26); this.label27.TabIndex = 12; @@ -2105,7 +2110,7 @@ private void InitializeComponent() // // buttonEventToDefault // - this.buttonEventToDefault.Location = new System.Drawing.Point(604, 524); + this.buttonEventToDefault.Location = new System.Drawing.Point(604, 547); this.buttonEventToDefault.Name = "buttonEventToDefault"; this.buttonEventToDefault.Size = new System.Drawing.Size(136, 23); this.buttonEventToDefault.TabIndex = 8; @@ -2879,6 +2884,16 @@ private void InitializeComponent() this.groupBox12.TabStop = false; this.groupBox12.Text = "Import Data from Save-File"; // + // label68 + // + this.label68.AutoSize = true; + this.label68.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label68.Location = new System.Drawing.Point(6, 16); + this.label68.Name = "label68"; + this.label68.Size = new System.Drawing.Size(506, 20); + this.label68.TabIndex = 1; + this.label68.Text = "Only ARK: Survival Evolved is support, no support for ASA yet."; + // // CbImportUnclaimedBabies // this.CbImportUnclaimedBabies.AutoSize = true; @@ -3691,7 +3706,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 = 4; // // customSCWakeup @@ -3699,7 +3714,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 = 2; // // customSCBirth @@ -3707,7 +3722,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 = 3; // // customSCStarving @@ -3715,7 +3730,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 = 1; // // label20 @@ -4429,20 +4444,43 @@ private void InitializeComponent() this.panel1.Controls.Add(this.buttonCancel); this.panel1.Controls.Add(this.buttonOK); this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel1.Location = new System.Drawing.Point(0, 748); + this.panel1.Location = new System.Drawing.Point(0, 770); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(758, 30); this.panel1.TabIndex = 12; // - // label68 + // label69 // - this.label68.AutoSize = true; - this.label68.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label68.Location = new System.Drawing.Point(6, 16); - this.label68.Name = "label68"; - this.label68.Size = new System.Drawing.Size(506, 20); - this.label68.TabIndex = 1; - this.label68.Text = "Only ARK: Survival Evolved is support, no support for ASA yet."; + this.label69.AutoSize = true; + this.label69.Location = new System.Drawing.Point(10, 73); + this.label69.Name = "label69"; + this.label69.Size = new System.Drawing.Size(186, 13); + this.label69.TabIndex = 7; + this.label69.Text = "WildDinoCharacterFoodDrainMultiplier"; + // + // NudWildDinoCharacterFoodDrainMultiplier + // + this.NudWildDinoCharacterFoodDrainMultiplier.DecimalPlaces = 6; + this.NudWildDinoCharacterFoodDrainMultiplier.ForeColor = System.Drawing.SystemColors.WindowText; + this.NudWildDinoCharacterFoodDrainMultiplier.Location = new System.Drawing.Point(183, 71); + this.NudWildDinoCharacterFoodDrainMultiplier.Maximum = new decimal(new int[] { + 10000, + 0, + 0, + 0}); + this.NudWildDinoCharacterFoodDrainMultiplier.Name = "NudWildDinoCharacterFoodDrainMultiplier"; + this.NudWildDinoCharacterFoodDrainMultiplier.NeutralNumber = new decimal(new int[] { + 0, + 0, + 0, + 0}); + this.NudWildDinoCharacterFoodDrainMultiplier.Size = new System.Drawing.Size(72, 20); + this.NudWildDinoCharacterFoodDrainMultiplier.TabIndex = 4; + this.NudWildDinoCharacterFoodDrainMultiplier.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); // // Settings // @@ -4451,7 +4489,7 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.buttonCancel; - this.ClientSize = new System.Drawing.Size(758, 778); + this.ClientSize = new System.Drawing.Size(758, 800); this.Controls.Add(this.tabControlSettings); this.Controls.Add(this.panel1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; @@ -4605,6 +4643,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).EndInit(); this.panel1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).EndInit(); this.ResumeLayout(false); } @@ -4930,5 +4969,7 @@ private void InitializeComponent() private System.Windows.Forms.Label label67; private uiControls.Nud NudWildDinoTorporDrainMultiplier; private System.Windows.Forms.Label label68; + private uiControls.Nud NudWildDinoCharacterFoodDrainMultiplier; + private System.Windows.Forms.Label label69; } } \ No newline at end of file diff --git a/ARKBreedingStats/settings/Settings.cs b/ARKBreedingStats/settings/Settings.cs index f4059994f..1a03ec687 100644 --- a/ARKBreedingStats/settings/Settings.cs +++ b/ARKBreedingStats/settings/Settings.cs @@ -5,7 +5,6 @@ using System.Drawing; using System.IO; using System.Linq; -using System.Runtime.Serialization; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Windows.Threading; @@ -99,6 +98,7 @@ private void InitializeData() } nudTamingSpeed.NeutralNumber = 1; nudDinoCharacterFoodDrain.NeutralNumber = 1; + NudWildDinoCharacterFoodDrainMultiplier.NeutralNumber = 1; NudWildDinoTorporDrainMultiplier.NeutralNumber = 1; nudTamedDinoCharacterFoodDrain.NeutralNumber = 1; nudMatingInterval.NeutralNumber = 1; @@ -236,6 +236,7 @@ private void LoadSettings(CreatureCollection cc) nudBabyImprintAmount.ValueSave = (decimal)multipliers.BabyImprintAmountMultiplier; nudTamingSpeed.ValueSave = (decimal)multipliers.TamingSpeedMultiplier; nudDinoCharacterFoodDrain.ValueSave = (decimal)multipliers.DinoCharacterFoodDrainMultiplier; + NudWildDinoCharacterFoodDrainMultiplier.ValueSave = (decimal)multipliers.WildDinoCharacterFoodDrainMultiplier; NudWildDinoTorporDrainMultiplier.ValueSave = (decimal)multipliers.WildDinoTorporDrainMultiplier; nudTamedDinoCharacterFoodDrain.ValueSave = (decimal)multipliers.TamedDinoCharacterFoodDrainMultiplier; nudBabyFoodConsumptionSpeed.ValueSave = (decimal)multipliers.BabyFoodConsumptionSpeedMultiplier; @@ -482,7 +483,7 @@ private void SaveSettings() _cc.maxWildLevel = (int)nudMaxWildLevels.Value; _cc.maxServerLevel = (int)nudMaxServerLevel.Value; _cc.maxChartLevel = (int)nudMaxGraphLevel.Value; - _cc.serverMultipliers.AllowSpeedLeveling = CbAllowSpeedLeveling.Checked; + _cc.serverMultipliers.AllowSpeedLeveling = CbAllowSpeedLeveling.Checked || RbGameAse.Checked; _cc.serverMultipliers.AllowFlyerSpeedLeveling = CbAllowFlyerSpeedLeveling.Checked; _cc.maxBreedingSuggestions = (int)numericUpDownMaxBreedingSug.Value; Properties.Settings.Default.IgnoreSexInBreedingPlan = cbIgnoreSexInBreedingPlan.Checked; @@ -492,6 +493,7 @@ private void SaveSettings() #region non-event-multiplier _cc.serverMultipliers.TamingSpeedMultiplier = (double)nudTamingSpeed.Value; _cc.serverMultipliers.DinoCharacterFoodDrainMultiplier = (double)nudDinoCharacterFoodDrain.Value; + _cc.serverMultipliers.WildDinoCharacterFoodDrainMultiplier = (double)NudWildDinoCharacterFoodDrainMultiplier.Value; _cc.serverMultipliers.WildDinoTorporDrainMultiplier = (double)NudWildDinoTorporDrainMultiplier.Value; _cc.serverMultipliers.TamedDinoCharacterFoodDrainMultiplier = (double)nudTamedDinoCharacterFoodDrain.Value; _cc.serverMultipliers.MatingSpeedMultiplier = (double)nudMatingSpeed.Value; @@ -841,6 +843,7 @@ void ParseAndSetStatMultiplier(int multiplierIndex, string regexPattern) // GameUserSettings.ini ParseAndSetValue(nudTamingSpeed, @"TamingSpeedMultiplier ?= ?(\d*\.?\d+)"); ParseAndSetValue(nudDinoCharacterFoodDrain, @"DinoCharacterFoodDrainMultiplier ?= ?(\d*\.?\d+)"); + ParseAndSetValue(NudWildDinoCharacterFoodDrainMultiplier, @"WildDinoCharacterFoodDrainMultiplier ?= ?(\d*\.?\d+)"); // Game.ini ParseAndSetValue(NudWildDinoTorporDrainMultiplier, @"WildDinoTorporDrainMultiplier ?= ?(\d*\.?\d+)"); @@ -944,6 +947,7 @@ private void LoadServerMultipliersFromSavFile(string filePath) nudMaxServerLevel.ValueSave = esm.DestroyTamesOverLevelClamp; nudTamingSpeed.ValueSaveDouble = Math.Round(esm.TamingSpeedMultiplier, roundToDigits); nudDinoCharacterFoodDrain.ValueSaveDouble = Math.Round(esm.DinoCharacterFoodDrainMultiplier, roundToDigits); + NudWildDinoCharacterFoodDrainMultiplier.ValueSaveDouble = Math.Round(esm.WildDinoCharacterFoodDrainMultiplier, roundToDigits); NudWildDinoTorporDrainMultiplier.ValueSaveDouble = Math.Round(esm.WildDinoTorporDrainMultiplier, roundToDigits); nudMatingSpeed.ValueSaveDouble = Math.Round(esm.MatingSpeedMultiplier, roundToDigits); nudMatingInterval.ValueSaveDouble = Math.Round(esm.MatingIntervalMultiplier, roundToDigits); @@ -1105,6 +1109,7 @@ private void ApplyMultiplierPreset(ServerMultipliers sm, bool onlyStatMultiplier { nudTamingSpeed.ValueSave = (decimal)sm.TamingSpeedMultiplier; nudDinoCharacterFoodDrain.ValueSave = (decimal)sm.DinoCharacterFoodDrainMultiplier; + NudWildDinoCharacterFoodDrainMultiplier.ValueSave = (decimal)sm.WildDinoCharacterFoodDrainMultiplier; NudWildDinoTorporDrainMultiplier.ValueSave = (decimal)sm.WildDinoTorporDrainMultiplier; nudTamedDinoCharacterFoodDrain.ValueSave = (decimal)sm.TamedDinoCharacterFoodDrainMultiplier; nudEggHatchSpeed.ValueSave = (decimal)sm.EggHatchSpeedMultiplier; @@ -1222,6 +1227,7 @@ private string GetMultiplierSettings() // taming multipliers sb.AppendLine($"TamingSpeedMultiplier = {nudTamingSpeed.Value.ToString(cultureForStrings)}"); sb.AppendLine($"DinoCharacterFoodDrainMultiplier = {nudDinoCharacterFoodDrain.Value.ToString(cultureForStrings)}"); + sb.AppendLine($"WildDinoCharacterFoodDrainMultiplier = {NudWildDinoCharacterFoodDrainMultiplier.Value.ToString(cultureForStrings)}"); sb.AppendLine($"WildDinoTorporDrainMultiplier = {NudWildDinoTorporDrainMultiplier.Value.ToString(cultureForStrings)}"); //// the settings below are not settings that appear in ARK server config files and are used only in ASB diff --git a/ARKBreedingStats/species/CreatureStat.cs b/ARKBreedingStats/species/CreatureStat.cs index 9e9f21821..f48e4bfe9 100644 --- a/ARKBreedingStats/species/CreatureStat.cs +++ b/ARKBreedingStats/species/CreatureStat.cs @@ -7,6 +7,7 @@ public class CreatureStat { public double BaseValue; public double IncPerWildLevel; + public double IncPerMutatedLevel; public double IncPerTamedLevel; public double AddWhenTamed; public double MultAffinity; diff --git a/ARKBreedingStats/species/Species.cs b/ARKBreedingStats/species/Species.cs index e4013dfc2..87857ca77 100644 --- a/ARKBreedingStats/species/Species.cs +++ b/ARKBreedingStats/species/Species.cs @@ -67,8 +67,8 @@ public class Species /// /// Indicates if a stat is shown in game represented by bit-flags /// - [JsonProperty] - private int displayedStats; + [JsonProperty("displayedStats")] + public int DisplayedStats { private set; get; } public const int displayedStatsDefault = 927; /// /// Indicates if a species uses a stat represented by bit-flags @@ -333,14 +333,14 @@ public void ApplyCanLevelOptions(bool canLevelSpeedStat, bool canFlyerLevelSpeed bool speedStatCanBeLeveled = canLevelSpeedStat && (canFlyerLevelSpeedStat || !isFlyer); if (speedStatCanBeLeveled) { - displayedStats |= statBit; + DisplayedStats |= statBit; StatImprintMultipliers[Stats.SpeedMultiplier] = (statImprintMultOverride ?? statImprintMult ?? StatImprintMultipliersDefaultAse)[Stats.SpeedMultiplier]; _skipWildLevelStatsWithServerSettings &= ~statBit; } else { - displayedStats &= ~statBit; + DisplayedStats &= ~statBit; StatImprintMultipliers[Stats.SpeedMultiplier] = 0; _skipWildLevelStatsWithServerSettings |= statBit; } @@ -354,7 +354,7 @@ public void ApplyCanLevelOptions(bool canLevelSpeedStat, bool canFlyerLevelSpeed /// /// Returns if the species displays a stat ingame in the inventory. /// - public bool DisplaysStat(int statIndex) => (displayedStats & (1 << statIndex)) != 0; + public bool DisplaysStat(int statIndex) => (DisplayedStats & (1 << statIndex)) != 0; /// /// Returns if a spawned creature can have wild or mutated levels in a stat. @@ -425,7 +425,7 @@ public void LoadOverrides(Species overrides) if (overrides.variants != null) variants = overrides.variants; if (overrides.fullStatsRaw != null) fullStatsRaw = overrides.fullStatsRaw; if (overrides.altBaseStatsRaw != null) altBaseStatsRaw = overrides.altBaseStatsRaw; - if (overrides.displayedStats != 0) displayedStats = overrides.displayedStats; + if (overrides.DisplayedStats != 0) DisplayedStats = overrides.DisplayedStats; if (overrides.skipWildLevelStats != 0) skipWildLevelStats = overrides.skipWildLevelStats; if (overrides.TamedBaseHealthMultiplier != null) TamedBaseHealthMultiplier = overrides.TamedBaseHealthMultiplier; if (overrides.statImprintMult != null) statImprintMult = overrides.statImprintMult; diff --git a/ARKBreedingStats/species/SpeciesListBoxEntry.cs b/ARKBreedingStats/species/SpeciesListBoxEntry.cs deleted file mode 100644 index e34a16e04..000000000 --- a/ARKBreedingStats/species/SpeciesListBoxEntry.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace ARKBreedingStats.species -{ - /// - /// Currently not used. - /// - class SpeciesListBoxEntry - { - public Species species; - public override string ToString() - { - return species.name; - } - - public SpeciesListBoxEntry(Species species) - { - this.species = species; - } - } -} diff --git a/ARKBreedingStats/uiControls/Hatching.cs b/ARKBreedingStats/uiControls/Hatching.cs index 7b4b9876b..4ae6b7a89 100644 --- a/ARKBreedingStats/uiControls/Hatching.cs +++ b/ARKBreedingStats/uiControls/Hatching.cs @@ -41,14 +41,14 @@ public void SetSpecies(Species species, int[] highLevels, int[] lowLevels) if (!species.UsesStat(si)) continue; var precision = Utils.Precision(si); - var statValue = StatValueCalculation.CalculateValue(species, si, highLevels[si], 0, true, 1, 0); + var statValue = StatValueCalculation.CalculateValue(species, si, highLevels[si], 0, 0, true, 1, 0); var statRepresentation = precision == 3 ? $"{statValue * 100:0.0} %" : $"{statValue:0.0} "; sbNames += $"{Utils.StatName(si, customStatNames: species.statNames)}\n"; sbValues += statRepresentation + "\n"; sbLevels += highLevels[si] + "\n"; - statValue = StatValueCalculation.CalculateValue(species, si, lowLevels[si], 0, true, 1, 0); + statValue = StatValueCalculation.CalculateValue(species, si, lowLevels[si], 0, 0, true, 1, 0); statRepresentation = precision == 3 ? $"{statValue * 100:0.0} %" : $"{statValue:0.0} "; sbLowestValues += statRepresentation + "\n"; diff --git a/ARKBreedingStats/uiControls/StatGraphs.cs b/ARKBreedingStats/uiControls/StatGraphs.cs index 3b56d54c8..7aced5b72 100644 --- a/ARKBreedingStats/uiControls/StatGraphs.cs +++ b/ARKBreedingStats/uiControls/StatGraphs.cs @@ -18,17 +18,17 @@ public StatGraphs() ChartAreas[0].AxisX.Minimum = 0; } - public void setGraph(Species species, int statIndex, int wildLevels, int domLevels, bool tamed, double TE, double imprinting) + public void SetGraph(Species species, int statIndex, int wildLevels, int mutatedLevel, int domLevels, bool tamed, double TE, double imprinting) { if (species != null && statIndex >= 0 && statIndex < 12) { CreatureStat stat = species.stats[statIndex]; serie.Points.Clear(); serie.Points.AddXY("Base", stat.BaseValue); - serie.Points.AddXY("Wild", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, 0, false, 0, 0)); - serie.Points.AddXY("Tamed", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, 0, true, TE, 0)); - serie.Points.AddXY("Dom", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, domLevels, true, TE, 0)); - serie.Points.AddXY("Impr", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, domLevels, true, TE, imprinting)); + serie.Points.AddXY("Wild", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, mutatedLevel, 0, false, 0, 0)); + serie.Points.AddXY("Tamed", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, mutatedLevel, 0, true, TE, 0)); + serie.Points.AddXY("Dom", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, mutatedLevel, domLevels, true, TE, 0)); + serie.Points.AddXY("Impr", StatValueCalculation.CalculateValue(species, statIndex, wildLevels, mutatedLevel, domLevels, true, TE, imprinting)); } } } diff --git a/ARKBreedingStats/uiControls/StatIO.Designer.cs b/ARKBreedingStats/uiControls/StatIO.Designer.cs index 5451640a6..2de2bc5f3 100644 --- a/ARKBreedingStats/uiControls/StatIO.Designer.cs +++ b/ARKBreedingStats/uiControls/StatIO.Designer.cs @@ -30,21 +30,25 @@ private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.panelBarDomLevels = new System.Windows.Forms.Panel(); + this.panelBarMutLevels = new System.Windows.Forms.Panel(); + this.panelBarWildLevels = new System.Windows.Forms.Panel(); this.panelFinalValue = new System.Windows.Forms.Panel(); + this.labelMutatedLevel = new System.Windows.Forms.Label(); this.checkBoxFixDomZero = new System.Windows.Forms.CheckBox(); this.labelDomLevel = new System.Windows.Forms.Label(); this.labelWildLevel = new System.Windows.Forms.Label(); - this.panelBarWildLevels = new System.Windows.Forms.Panel(); + this.numericUpDownInput = new ARKBreedingStats.uiControls.Nud(); this.inputPanel = new System.Windows.Forms.Panel(); + this.nudLvM = new ARKBreedingStats.uiControls.Nud(); this.labelFinalValue = new System.Windows.Forms.Label(); - this.labelBValue = new System.Windows.Forms.Label(); - this.numericUpDownInput = new ARKBreedingStats.uiControls.Nud(); this.numLvD = new ARKBreedingStats.uiControls.Nud(); this.numLvW = new ARKBreedingStats.uiControls.Nud(); + this.labelBValue = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.panelFinalValue.SuspendLayout(); - this.inputPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInput)).BeginInit(); + this.inputPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudLvM)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.numLvD)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.numLvW)).BeginInit(); this.SuspendLayout(); @@ -52,14 +56,15 @@ private void InitializeComponent() // groupBox1 // this.groupBox1.Controls.Add(this.panelBarDomLevels); - this.groupBox1.Controls.Add(this.panelFinalValue); + this.groupBox1.Controls.Add(this.panelBarMutLevels); this.groupBox1.Controls.Add(this.panelBarWildLevels); + this.groupBox1.Controls.Add(this.panelFinalValue); this.groupBox1.Controls.Add(this.inputPanel); this.groupBox1.Controls.Add(this.labelBValue); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.groupBox1.Location = new System.Drawing.Point(0, 0); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(295, 50); + this.groupBox1.Size = new System.Drawing.Size(347, 50); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; // @@ -67,28 +72,58 @@ private void InitializeComponent() // this.panelBarDomLevels.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); this.panelBarDomLevels.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panelBarDomLevels.Location = new System.Drawing.Point(6, 43); + this.panelBarDomLevels.Location = new System.Drawing.Point(6, 44); this.panelBarDomLevels.Name = "panelBarDomLevels"; this.panelBarDomLevels.Size = new System.Drawing.Size(2, 3); this.panelBarDomLevels.TabIndex = 5; // + // panelBarMutLevels + // + this.panelBarMutLevels.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); + this.panelBarMutLevels.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panelBarMutLevels.Location = new System.Drawing.Point(6, 41); + this.panelBarMutLevels.Name = "panelBarMutLevels"; + this.panelBarMutLevels.Size = new System.Drawing.Size(2, 4); + this.panelBarMutLevels.TabIndex = 6; + // + // panelBarWildLevels + // + this.panelBarWildLevels.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); + this.panelBarWildLevels.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panelBarWildLevels.Location = new System.Drawing.Point(6, 38); + this.panelBarWildLevels.Name = "panelBarWildLevels"; + this.panelBarWildLevels.Size = new System.Drawing.Size(2, 6); + this.panelBarWildLevels.TabIndex = 4; + this.panelBarWildLevels.Click += new System.EventHandler(this.panelBar_Click); + // // panelFinalValue // + this.panelFinalValue.Controls.Add(this.labelMutatedLevel); this.panelFinalValue.Controls.Add(this.checkBoxFixDomZero); this.panelFinalValue.Controls.Add(this.labelDomLevel); this.panelFinalValue.Controls.Add(this.labelWildLevel); this.panelFinalValue.Controls.Add(this.numericUpDownInput); this.panelFinalValue.Location = new System.Drawing.Point(6, 14); this.panelFinalValue.Name = "panelFinalValue"; - this.panelFinalValue.Size = new System.Drawing.Size(217, 25); + this.panelFinalValue.Size = new System.Drawing.Size(269, 25); this.panelFinalValue.TabIndex = 9; this.panelFinalValue.Click += new System.EventHandler(this.panelFinalValue_Click); // + // labelMutatedLevel + // + this.labelMutatedLevel.Location = new System.Drawing.Point(171, 5); + this.labelMutatedLevel.Name = "labelMutatedLevel"; + this.labelMutatedLevel.Size = new System.Drawing.Size(35, 13); + this.labelMutatedLevel.TabIndex = 13; + this.labelMutatedLevel.Text = "0"; + this.labelMutatedLevel.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.labelMutatedLevel.Click += new System.EventHandler(this.labelMutatedLevel_Click); + // // checkBoxFixDomZero // this.checkBoxFixDomZero.Appearance = System.Windows.Forms.Appearance.Button; this.checkBoxFixDomZero.Image = global::ARKBreedingStats.Properties.Resources.unlocked; - this.checkBoxFixDomZero.Location = new System.Drawing.Point(199, 9); + this.checkBoxFixDomZero.Location = new System.Drawing.Point(251, 9); this.checkBoxFixDomZero.Name = "checkBoxFixDomZero"; this.checkBoxFixDomZero.Size = new System.Drawing.Size(14, 17); this.checkBoxFixDomZero.TabIndex = 12; @@ -98,7 +133,7 @@ private void InitializeComponent() // // labelDomLevel // - this.labelDomLevel.Location = new System.Drawing.Point(162, 5); + this.labelDomLevel.Location = new System.Drawing.Point(214, 5); this.labelDomLevel.Name = "labelDomLevel"; this.labelDomLevel.Size = new System.Drawing.Size(35, 13); this.labelDomLevel.TabIndex = 11; @@ -116,45 +151,6 @@ private void InitializeComponent() this.labelWildLevel.TextAlign = System.Drawing.ContentAlignment.TopRight; this.labelWildLevel.Click += new System.EventHandler(this.labelWildLevel_Click); // - // panelBarWildLevels - // - this.panelBarWildLevels.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); - this.panelBarWildLevels.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panelBarWildLevels.Location = new System.Drawing.Point(6, 39); - this.panelBarWildLevels.Name = "panelBarWildLevels"; - this.panelBarWildLevels.Size = new System.Drawing.Size(2, 6); - this.panelBarWildLevels.TabIndex = 4; - this.panelBarWildLevels.Click += new System.EventHandler(this.panelBar_Click); - // - // inputPanel - // - this.inputPanel.Controls.Add(this.labelFinalValue); - this.inputPanel.Controls.Add(this.numLvD); - this.inputPanel.Controls.Add(this.numLvW); - this.inputPanel.Location = new System.Drawing.Point(6, 14); - this.inputPanel.Name = "inputPanel"; - this.inputPanel.Size = new System.Drawing.Size(217, 25); - this.inputPanel.TabIndex = 8; - // - // labelFinalValue - // - this.labelFinalValue.Location = new System.Drawing.Point(119, 5); - this.labelFinalValue.Name = "labelFinalValue"; - this.labelFinalValue.Size = new System.Drawing.Size(70, 13); - this.labelFinalValue.TabIndex = 10; - this.labelFinalValue.Text = "0"; - this.labelFinalValue.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // labelBValue - // - this.labelBValue.Location = new System.Drawing.Point(219, 19); - this.labelBValue.Name = "labelBValue"; - this.labelBValue.Size = new System.Drawing.Size(70, 13); - this.labelBValue.TabIndex = 3; - this.labelBValue.Text = "BreedVal"; - this.labelBValue.TextAlign = System.Drawing.ContentAlignment.TopRight; - this.labelBValue.Click += new System.EventHandler(this.labelBValue_Click); - // // numericUpDownInput // this.numericUpDownInput.DecimalPlaces = 1; @@ -181,10 +177,50 @@ private void InitializeComponent() this.numericUpDownInput.ValueChanged += new System.EventHandler(this.numericUpDownInput_ValueChanged); this.numericUpDownInput.Enter += new System.EventHandler(this.numericUpDown_Enter); // + // inputPanel + // + this.inputPanel.Controls.Add(this.nudLvM); + this.inputPanel.Controls.Add(this.labelFinalValue); + this.inputPanel.Controls.Add(this.numLvD); + this.inputPanel.Controls.Add(this.numLvW); + this.inputPanel.Location = new System.Drawing.Point(6, 14); + this.inputPanel.Name = "inputPanel"; + this.inputPanel.Size = new System.Drawing.Size(269, 25); + this.inputPanel.TabIndex = 8; + // + // nudLvM + // + this.nudLvM.ForeColor = System.Drawing.SystemColors.GrayText; + this.nudLvM.Location = new System.Drawing.Point(55, 3); + this.nudLvM.Maximum = new decimal(new int[] { + 9999, + 0, + 0, + 0}); + this.nudLvM.Name = "nudLvM"; + this.nudLvM.NeutralNumber = new decimal(new int[] { + 0, + 0, + 0, + 0}); + this.nudLvM.Size = new System.Drawing.Size(46, 20); + this.nudLvM.TabIndex = 1; + this.nudLvM.ValueChanged += new System.EventHandler(this.nudLvM_ValueChanged); + this.nudLvM.Enter += new System.EventHandler(this.numericUpDown_Enter); + // + // labelFinalValue + // + this.labelFinalValue.Location = new System.Drawing.Point(171, 5); + this.labelFinalValue.Name = "labelFinalValue"; + this.labelFinalValue.Size = new System.Drawing.Size(70, 13); + this.labelFinalValue.TabIndex = 10; + this.labelFinalValue.Text = "0"; + this.labelFinalValue.TextAlign = System.Drawing.ContentAlignment.TopRight; + // // numLvD // this.numLvD.ForeColor = System.Drawing.SystemColors.GrayText; - this.numLvD.Location = new System.Drawing.Point(55, 3); + this.numLvD.Location = new System.Drawing.Point(107, 3); this.numLvD.Maximum = new decimal(new int[] { 9999, 0, @@ -197,7 +233,7 @@ private void InitializeComponent() 0, 0}); this.numLvD.Size = new System.Drawing.Size(46, 20); - this.numLvD.TabIndex = 7; + this.numLvD.TabIndex = 2; this.numLvD.ValueChanged += new System.EventHandler(this.numLvD_ValueChanged); this.numLvD.Enter += new System.EventHandler(this.numericUpDown_Enter); // @@ -222,10 +258,20 @@ private void InitializeComponent() 0, 0}); this.numLvW.Size = new System.Drawing.Size(46, 20); - this.numLvW.TabIndex = 6; + this.numLvW.TabIndex = 0; this.numLvW.ValueChanged += new System.EventHandler(this.numLvW_ValueChanged); this.numLvW.Enter += new System.EventHandler(this.numericUpDown_Enter); // + // labelBValue + // + this.labelBValue.Location = new System.Drawing.Point(272, 19); + this.labelBValue.Name = "labelBValue"; + this.labelBValue.Size = new System.Drawing.Size(70, 13); + this.labelBValue.TabIndex = 3; + this.labelBValue.Text = "BreedVal"; + this.labelBValue.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.labelBValue.Click += new System.EventHandler(this.labelBValue_Click); + // // StatIO // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -233,11 +279,12 @@ private void InitializeComponent() this.Controls.Add(this.groupBox1); this.Margin = new System.Windows.Forms.Padding(2); this.Name = "StatIO"; - this.Size = new System.Drawing.Size(295, 50); + this.Size = new System.Drawing.Size(347, 50); this.groupBox1.ResumeLayout(false); this.panelFinalValue.ResumeLayout(false); - this.inputPanel.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInput)).EndInit(); + this.inputPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.nudLvM)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.numLvD)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.numLvW)).EndInit(); this.ResumeLayout(false); @@ -259,5 +306,8 @@ private void InitializeComponent() private System.Windows.Forms.Label labelFinalValue; private System.Windows.Forms.CheckBox checkBoxFixDomZero; private System.Windows.Forms.Panel panelBarDomLevels; + private System.Windows.Forms.Label labelMutatedLevel; + private uiControls.Nud nudLvM; + private System.Windows.Forms.Panel panelBarMutLevels; } } diff --git a/ARKBreedingStats/uiControls/StatIO.cs b/ARKBreedingStats/uiControls/StatIO.cs index 30bdf75bd..57e3206d0 100644 --- a/ARKBreedingStats/uiControls/StatIO.cs +++ b/ARKBreedingStats/uiControls/StatIO.cs @@ -20,6 +20,9 @@ public partial class StatIO : UserControl private bool _domZeroFixed; private readonly ToolTip _tt; public int barMaxLevel = 45; + private const int MaxBarLength = 335; + private bool _linkWildMutated; + private int _wildMutatedSum; public StatIO() { @@ -49,7 +52,7 @@ public double Input } else { - value = value * (percent ? 100 : 1); + if (percent) value *= 100; numericUpDownInput.ValueSave = (decimal)value; labelFinalValue.Text = value.ToString("N1"); } @@ -72,42 +75,45 @@ public int LevelWild { int v = value; if (v < 0) + { numLvW.Value = -1; // value can be unknown if multiple stats are not shown (e.g. wild speed and oxygen) + _wildMutatedSum = -1; + } else { if (v > numLvW.Maximum) v = (int)numLvW.Maximum; + _wildMutatedSum = (int)(v + nudLvM.Value); numLvW.Value = v; } labelWildLevel.Text = (value < 0 ? "?" : v.ToString()); } } + public int LevelMut + { + get => (short)nudLvM.Value; + set + { + labelMutatedLevel.Text = value.ToString(); + if (numLvW.Value < 0) + _wildMutatedSum = -1; + else + _wildMutatedSum = (int)(numLvW.Value + value); + nudLvM.Value = value; + } + } + public int LevelDom { get => (short)numLvD.Value; set { labelDomLevel.Text = value.ToString(); - labelDomLevel.ForeColor = value == 0 ? Color.Gray : Color.Black; numLvD.Value = value; } } - public int LevelMut - { - get => 0; - set { } - // TODO - //get => (short)numLvM.Value; - //set - //{ - // labelMutLevel.Text = value.ToString(); - // labelMutLevel.ForeColor = value == 0 ? Color.Gray : Color.Black; - // numLvM.Value = value; - //} - } - public double BreedingValue { get => _breedingValue; @@ -262,8 +268,9 @@ public void Clear() TopLevel = LevelStatus.Neutral; numLvW.Value = 0; numLvD.Value = 0; - labelDomLevel.Text = "0"; labelWildLevel.Text = "0"; + labelMutatedLevel.Text = "0"; + labelDomLevel.Text = "0"; labelFinalValue.Text = "0"; labelBValue.Text = string.Empty; } @@ -280,10 +287,39 @@ private void numLvW_ValueChanged(object sender, EventArgs e) { lengthPercentage = 0; } - panelBarWildLevels.Width = lengthPercentage * 283 / 100; + panelBarWildLevels.Width = lengthPercentage * MaxBarLength / 100; panelBarWildLevels.BackColor = Utils.GetColorFromPercent(lengthPercentage); _tt.SetToolTip(panelBarWildLevels, Utils.LevelPercentile((int)numLvW.Value)); + if (_linkWildMutated && _wildMutatedSum != -1) + { + nudLvM.ValueSave = Math.Max(0, _wildMutatedSum - numLvW.Value); + } + + if (_inputType != StatIOInputType.FinalValueInputType) + LevelChangedDebouncer(); + } + + private void nudLvM_ValueChanged(object sender, EventArgs e) + { + int lengthPercentage = 100 * (int)nudLvM.Value / barMaxLevel; // in percentage of the max bar width + + if (lengthPercentage > 100) + { + lengthPercentage = 100; + } + if (lengthPercentage < 0) + { + lengthPercentage = 0; + } + panelBarMutLevels.Width = lengthPercentage * MaxBarLength / 100; + panelBarMutLevels.BackColor = Utils.GetColorFromPercent(lengthPercentage); + + if (_linkWildMutated && _wildMutatedSum != -1) + { + numLvW.ValueSave = Math.Max(0, _wildMutatedSum - nudLvM.Value); + } + if (_inputType != StatIOInputType.FinalValueInputType) LevelChangedDebouncer(); } @@ -300,7 +336,7 @@ private void numLvD_ValueChanged(object sender, EventArgs e) { lengthPercentage = 0; } - panelBarDomLevels.Width = lengthPercentage * 283 / 100; + panelBarDomLevels.Width = lengthPercentage * MaxBarLength / 100; panelBarDomLevels.BackColor = Utils.GetColorFromPercent(lengthPercentage); if (_inputType != StatIOInputType.FinalValueInputType) @@ -316,9 +352,11 @@ private void numLvD_ValueChanged(object sender, EventArgs e) private void numericUpDownInput_ValueChanged(object sender, EventArgs e) { if (InputType == StatIOInputType.FinalValueInputType) - InputValueChanged?.Invoke(this); + _levelChangedDebouncer.Debounce(200, FireStatValueChanged, Dispatcher.CurrentDispatcher); } + private void FireStatValueChanged() => InputValueChanged?.Invoke(this); + private void numericUpDown_Enter(object sender, EventArgs e) { NumericUpDown n = (NumericUpDown)sender; @@ -338,6 +376,25 @@ private void labelBValue_Click(object sender, EventArgs e) private void labelWildLevel_Click(object sender, EventArgs e) { OnClick(e); + + if (LevelMut > 1) + { + LevelWild += 2; + LevelMut -= 2; + LevelChangedDebouncer(); + } + } + + private void labelMutatedLevel_Click(object sender, EventArgs e) + { + OnClick(e); + + if (LevelWild > 1) + { + LevelWild -= 2; + LevelMut += 2; + LevelChangedDebouncer(); + } } private void labelDomLevel_Click(object sender, EventArgs e) @@ -366,6 +423,18 @@ public bool DomLevelLockedZero get => _domZeroFixed; set => checkBoxFixDomZero.Checked = value; } + + /// + /// If true, the control tries to keep the sum of the wild and mutated levels equal. + /// + public bool LinkWildMutated + { + set + { + _linkWildMutated = value; + _wildMutatedSum = (int)(numLvW.Value + nudLvM.Value); + } + } } public enum StatIOStatus diff --git a/ARKBreedingStats/uiControls/StatPotential.cs b/ARKBreedingStats/uiControls/StatPotential.cs index 175b6d93f..b8641d9e9 100644 --- a/ARKBreedingStats/uiControls/StatPotential.cs +++ b/ARKBreedingStats/uiControls/StatPotential.cs @@ -25,7 +25,7 @@ public StatPotential(int stat, bool percent) label1.Text = Utils.StatName(_statIndex, true); } - public void SetLevel(Species species, int wildLevel) + public void SetLevel(Species species, int wildLevel, int mutationLevels) { if (levelGraphMax > 0) { @@ -35,9 +35,9 @@ public void SetLevel(Species species, int wildLevel) labelDomLevels.Width = 60; labelImprinting.Location = new Point(33 + labelWildLevels.Width, 0); labelDomLevels.Location = new Point(35 + labelWildLevels.Width + labelImprinting.Width, 0); - labelWildLevels.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, 0, true, 1, 0) * (_percent ? 100 : 1) + (_percent ? "%" : ""); - labelImprinting.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, 0, true, 1, 1) * (_percent ? 100 : 1) + (_percent ? "%" : ""); - labelDomLevels.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, maxDomLevel, true, 1, 1) * (_percent ? 100 : 1) + (_percent ? "%" : ""); + labelWildLevels.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, mutationLevels, 0, true, 1, 0) * (_percent ? 100 : 1) + (_percent ? "%" : ""); + labelImprinting.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, mutationLevels, 0, true, 1, 1) * (_percent ? 100 : 1) + (_percent ? "%" : ""); + labelDomLevels.Text = StatValueCalculation.CalculateValue(species, _statIndex, wildLevel, mutationLevels, maxDomLevel, true, 1, 1) * (_percent ? 100 : 1) + (_percent ? "%" : ""); _tt.SetToolTip(labelWildLevels, labelWildLevels.Text); _tt.SetToolTip(labelImprinting, labelImprinting.Text); _tt.SetToolTip(labelDomLevels, labelDomLevels.Text); diff --git a/ARKBreedingStats/uiControls/StatPotentials.cs b/ARKBreedingStats/uiControls/StatPotentials.cs index 293c707b5..3a8647fa3 100644 --- a/ARKBreedingStats/uiControls/StatPotentials.cs +++ b/ARKBreedingStats/uiControls/StatPotentials.cs @@ -7,7 +7,8 @@ public partial class StatPotentials : UserControl { private readonly StatPotential[] _stats; private Species _selectedSpecies; - private readonly int[] _oldLevels; + private readonly int[] _currentLevelsWild = new int[Stats.StatsCount]; + private readonly int[] _currentLevelsMutations = new int[Stats.StatsCount]; public StatPotentials() { @@ -25,7 +26,6 @@ public StatPotentials() flpStats.Controls.Add(_stats[si]); flpStats.SetFlowBreak(_stats[si], true); } - _oldLevels = new int[Stats.StatsCount]; } public Species Species @@ -41,15 +41,16 @@ public Species Species } } - public void SetLevels(int[] levelsWild, bool forceUpdate) + public void SetLevels(int[] levelsWild, int[] levelsMutations, bool forceUpdate) { SuspendLayout(); for (int s = 0; s < Stats.StatsCount; s++) { - if (forceUpdate || _oldLevels[s] != levelsWild[s]) + if (forceUpdate || _currentLevelsWild[s] != levelsWild[s] || _currentLevelsMutations[s] != levelsMutations[s]) { - _oldLevels[s] = levelsWild[s]; - _stats[s].SetLevel(_selectedSpecies, levelsWild[s]); + _currentLevelsWild[s] = levelsWild[s]; + _currentLevelsMutations[s] = levelsMutations[s]; + _stats[s].SetLevel(_selectedSpecies, levelsWild[s], levelsMutations[s]); } } ResumeLayout(); diff --git a/ARKBreedingStats/values/ServerMultipliers.cs b/ARKBreedingStats/values/ServerMultipliers.cs index bc7ac54f2..21467845e 100644 --- a/ARKBreedingStats/values/ServerMultipliers.cs +++ b/ARKBreedingStats/values/ServerMultipliers.cs @@ -23,6 +23,8 @@ public class ServerMultipliers public double DinoCharacterFoodDrainMultiplier { get; set; } = 1; [JsonProperty] public double TamedDinoCharacterFoodDrainMultiplier { get; set; } = 1; + [JsonProperty] + public double WildDinoCharacterFoodDrainMultiplier { get; set; } = 1; [JsonProperty] public double MatingSpeedMultiplier { get; set; } = 1; @@ -41,6 +43,10 @@ public class ServerMultipliers public double BabyImprintingStatScaleMultiplier { get; set; } = 1; [JsonProperty] public double BabyImprintAmountMultiplier { get; set; } = 1; + + /// + /// Setting introduced in ASA, for ASE it's always true. + /// [JsonProperty] public bool AllowSpeedLeveling { get; set; } [JsonProperty] @@ -72,6 +78,7 @@ public ServerMultipliers Copy(bool withStatMultipliers) TamingSpeedMultiplier = TamingSpeedMultiplier, WildDinoTorporDrainMultiplier = WildDinoTorporDrainMultiplier, DinoCharacterFoodDrainMultiplier = DinoCharacterFoodDrainMultiplier, + WildDinoCharacterFoodDrainMultiplier = WildDinoCharacterFoodDrainMultiplier, TamedDinoCharacterFoodDrainMultiplier = TamedDinoCharacterFoodDrainMultiplier, MatingIntervalMultiplier = MatingIntervalMultiplier, EggHatchSpeedMultiplier = EggHatchSpeedMultiplier, diff --git a/ARKBreedingStats/values/Values.cs b/ARKBreedingStats/values/Values.cs index 9d2174dc9..c23f5016c 100644 --- a/ARKBreedingStats/values/Values.cs +++ b/ARKBreedingStats/values/Values.cs @@ -534,6 +534,7 @@ public void ApplyMultipliers(CreatureCollection cc, bool eventMultipliers = fals } sp.stats[s].IncPerWildLevel = GetRawStatValue(s, 1, customOverrideForThisStatExists) * statMultipliers[3]; + sp.stats[s].IncPerMutatedLevel = sp.stats[s].IncPerWildLevel; // todo consider adjustments if they're implemented // set troodonism values if (sp.altStats?[s] != null && sp.stats[s].BaseValue != 0) diff --git a/ASB-Updater/ASB Updater.csproj b/ASB-Updater/ASB Updater.csproj index b349ad769..e408a30a7 100644 --- a/ASB-Updater/ASB Updater.csproj +++ b/ASB-Updater/ASB Updater.csproj @@ -142,7 +142,7 @@ all - 13.0.2 + 13.0.3 4.3.0 diff --git a/ArkSavegameToolkit b/ArkSavegameToolkit index 3c32f3cec..13d49402f 160000 --- a/ArkSavegameToolkit +++ b/ArkSavegameToolkit @@ -1 +1 @@ -Subproject commit 3c32f3ceccccc9fb7d2d0a690be4187c83d4d997 +Subproject commit 13d49402f40bbb7eaae295827f2498772cada67f diff --git a/translations.txt b/translations.txt index af8d6de21..a26fd8f7b 100644 --- a/translations.txt +++ b/translations.txt @@ -268,6 +268,7 @@ Mutations Mutations Mutations_Abb Mu na n/a Name Name +nameAlreadyExistsInLibrary This name already exists in the library Narcotics Narcotics naYet n/a yet Neck Neck @@ -370,6 +371,7 @@ Temperature_Abb Te Time Time TimeBetweenMating Time between mating timerFeedAll Feed all for +timerStarvingOf Starving of timerWakeupOf Wakeup of TimeUntilFeedingAllFood Time until you can feed all needed food in one go timeUntilStarving Time until starving: