diff --git a/ARKBreedingStats/Form1.cs b/ARKBreedingStats/Form1.cs index a79d4449..ef185a61 100644 --- a/ARKBreedingStats/Form1.cs +++ b/ARKBreedingStats/Form1.cs @@ -409,32 +409,6 @@ private void LoadAppSettings() } UpdatePatternButtons(); - // conversion of global color level settings to specific options. Remove around 2024-09 - if (Properties.Settings.Default.ChartHueEvenMax != int.MaxValue) - { - var defaultSettings = StatsLevelColors.StatsOptionsDict[string.Empty].StatOptions; - for (var s = 0; s < Stats.StatsCount; s++) - { - defaultSettings[s].LevelGraphRepresentation.LowerColor = Utils.ColorFromHue(Properties.Settings.Default.ChartHueEvenMin); - defaultSettings[s].LevelGraphRepresentation.UpperColor = Utils.ColorFromHue(Properties.Settings.Default.ChartHueEvenMax); - defaultSettings[s].LevelGraphRepresentation.ColorGradientReversed = Properties.Settings.Default.ChartHueEvenMax < Properties.Settings.Default.ChartHueEvenMin; - - if (Properties.Settings.Default.HighlightEvenOdd) - { - defaultSettings[s].LevelGraphRepresentationOdd = new LevelGraphRepresentation - { - LowerColor = Utils.ColorFromHue(Properties.Settings.Default.ChartHueOddMin), - UpperColor = Utils.ColorFromHue(Properties.Settings.Default.ChartHueOddMax), - ColorGradientReversed = Properties.Settings.Default.ChartHueOddMax < Properties.Settings.Default.ChartHueOddMin, - }; - defaultSettings[s].UseDifferentColorsForOddLevels = true; - } - } - - Properties.Settings.Default.ChartHueEvenMax = int.MaxValue; - } - // end of level color settings conversion - // Load column-widths, display-indices and sort-order of the TimerControlListView LoadListViewSettings(timerList1.ListViewTimers, nameof(Properties.Settings.Default.TCLVColumnWidths), nameof(Properties.Settings.Default.TCLVColumnDisplayIndices), diff --git a/ARKBreedingStats/Form1.extractor.cs b/ARKBreedingStats/Form1.extractor.cs index 0b47483f..359fda38 100644 --- a/ARKBreedingStats/Form1.extractor.cs +++ b/ARKBreedingStats/Form1.extractor.cs @@ -1283,7 +1283,7 @@ private void SetCreatureValuesToExtractor(CreatureValues cv, bool setInfoInput = } else if (cv.motherArkId != 0) { - cv.Mother = new Creature(cv.motherArkId); + cv.Mother = new Creature(cv.motherArkId, cv.Species); _creatureCollection.creatures.Add(cv.Mother); } } @@ -1296,7 +1296,7 @@ private void SetCreatureValuesToExtractor(CreatureValues cv, bool setInfoInput = } else if (cv.fatherArkId != 0) { - cv.Father = new Creature(cv.fatherArkId); + cv.Father = new Creature(cv.fatherArkId, cv.Species); _creatureCollection.creatures.Add(cv.Father); } } diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs index 6fdac78f..bbd6c41c 100644 --- a/ARKBreedingStats/Form1.library.cs +++ b/ARKBreedingStats/Form1.library.cs @@ -572,7 +572,8 @@ private void CalculateTopStats(List creatures, Species onlySpecies = n var considerTopStats = new Dictionary(); foreach (Creature c in creatures) { - if (c.Species == null) continue; + if (c.Species == null || c.flags.HasFlag(CreatureFlags.Placeholder)) + continue; if (!considerTopStats.TryGetValue(c.Species, out var consideredTopStats)) { consideredTopStats = StatsTopStats.GetStatsOptions(c.Species).StatOptions.Select(si => si.ConsiderStat).ToArray(); diff --git a/ARKBreedingStats/Properties/AssemblyInfo.cs b/ARKBreedingStats/Properties/AssemblyInfo.cs index fa146b31..ed3d532f 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.63.0.1")] +[assembly: AssemblyFileVersion("0.63.1.0")] [assembly: NeutralResourcesLanguage("en")] diff --git a/ARKBreedingStats/StatsOptions/LevelColorSettings/LevelGraphOptionsControl.cs b/ARKBreedingStats/StatsOptions/LevelColorSettings/LevelGraphOptionsControl.cs index 17f350c8..003efa1d 100644 --- a/ARKBreedingStats/StatsOptions/LevelColorSettings/LevelGraphOptionsControl.cs +++ b/ARKBreedingStats/StatsOptions/LevelColorSettings/LevelGraphOptionsControl.cs @@ -1,4 +1,5 @@ -using System.Windows.Forms; +using System; +using System.Windows.Forms; namespace ARKBreedingStats.StatsOptions.LevelColorSettings { @@ -15,16 +16,28 @@ protected override void InitializeStatControls() { var c = new StatLevelGraphOptionsControl($"[{si}] {Utils.StatName(si, true)}", si, Tt); _statOptionsControls[si] = c; - StatsContainer.Controls.Add(c); - StatsContainer.SetFlowBreak(c, true); + AddWithFlowBreak(c); } - StatsContainer.Controls.Add(new Label + + AddWithFlowBreak(new Label { Text = @"Drag color gradient with mouse for fast editing. On color gradients use shift + right click to copy and shift + left click to paste color settings. Ctrl + left click to cycle through presets.", AutoSize = true }); + + var btReset = new Button { Text = "Reset all stats to default colors and ranges", AutoSize = true }; + btReset.Click += ResetCurrentSettingsToDefault; + AddWithFlowBreak(btReset); + + return; + + void AddWithFlowBreak(Control c) + { + StatsContainer.Controls.Add(c); + StatsContainer.SetFlowBreak(c, true); + } } protected override void UpdateStatsControls(bool isNotRoot) @@ -32,5 +45,23 @@ protected override void UpdateStatsControls(bool isNotRoot) for (var si = 0; si < Stats.StatsCount; si++) _statOptionsControls[si].SetStatOptions(SelectedStatsOptions.StatOptions?[si], isNotRoot, SelectedStatsOptions.ParentOptions); } + + private void ResetCurrentSettingsToDefault(object sender, EventArgs e) + { + if (SelectedStatsOptions == null) return; + if (SelectedStatsOptions.StatOptions == null) + SelectedStatsOptions.StatOptions = new StatLevelColors[Stats.StatsCount]; + + var isNotRoot = !string.IsNullOrEmpty(SelectedStatsOptions.Name); + for (var si = 0; si < Stats.StatsCount; si++) + { + SelectedStatsOptions.StatOptions[si] = new StatLevelColors + { + LevelGraphRepresentation = LevelGraphRepresentation.GetDefaultValue, + LevelGraphRepresentationMutation = LevelGraphRepresentation.GetDefaultMutationLevelValue + }; + _statOptionsControls[si].SetStatOptions(SelectedStatsOptions.StatOptions[si], isNotRoot, SelectedStatsOptions.ParentOptions); + } + } } } diff --git a/ARKBreedingStats/StatsOptions/LevelColorSettings/StatLevelGraphOptionsControl.cs b/ARKBreedingStats/StatsOptions/LevelColorSettings/StatLevelGraphOptionsControl.cs index f508c2ff..ea6121b6 100644 --- a/ARKBreedingStats/StatsOptions/LevelColorSettings/StatLevelGraphOptionsControl.cs +++ b/ARKBreedingStats/StatsOptions/LevelColorSettings/StatLevelGraphOptionsControl.cs @@ -20,7 +20,7 @@ public StatLevelGraphOptionsControl(string name, int statIndex, ToolTip tt) : th _statIndex = statIndex; hueControl.UpdateTooltips(tt); hueControlOdd.UpdateTooltips(tt); - tt.SetToolTip(CbUseDifferentColorsForOddLevels, "Use different colors for odd levels"); + tt.SetToolTip(CbUseDifferentColorsForOddLevels, "Use different colors for odd wild levels"); tt.SetToolTip(CbUseDifferentColorsForMutationLevels, "Use different colors for mutation levels"); } @@ -33,7 +33,7 @@ public void SetStatOptions(StatLevelColors so, bool isNotRoot, StatsOptions where T : StatOptionsBase [JsonProperty] public T[] StatOptions; + /// + /// List of species these settings are valid. + /// Possible values are the blueprint path and shorter defined names, e.g. Species.name, Species.DescriptiveName. + /// + [JsonProperty("sp", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string[] AffectedSpecies; + + /// + /// Used for UI layout. + /// public int HierarchyLevel; } } diff --git a/ARKBreedingStats/StatsOptions/StatsOptionsControl.cs b/ARKBreedingStats/StatsOptions/StatsOptionsControl.cs index 9c177d04..cab650d4 100644 --- a/ARKBreedingStats/StatsOptions/StatsOptionsControl.cs +++ b/ARKBreedingStats/StatsOptions/StatsOptionsControl.cs @@ -19,8 +19,11 @@ internal class StatsOptionsControl : TableLayoutPanel where T : StatOptionsBa protected Button BtRemove; protected TextBox TbOptionsName; protected Label LbParent; + protected Label LbParentParent; + protected Label LbAffectedSpecies; protected StatsOptions SelectedStatsOptions; protected StatsOptionsSettings StatsOptionsSettings; + protected TextBox TbAffectedSpecies; protected FlowLayoutPanel StatsContainer; protected ToolTip Tt; private bool _ignoreIndexChange; @@ -74,6 +77,22 @@ protected void InitializeControls(StatsOptionsSettings settings, ToolTip tt) CbbParent.SelectedIndexChanged += CbbParent_SelectedIndexChanged; flpHeaderControls.Controls.Add(CbbParent); + var marginLabelDefault = new Padding(5, 7, 5, 0); + + LbParentParent = new Label { Margin = marginLabelDefault, AutoSize = true }; + tt.SetToolTip(LbParentParent, "If the parent setting has no value for a stat, the parent's parent's values are used etc."); + flpHeaderControls.Controls.Add(LbParentParent); + flpHeaderControls.SetFlowBreak(LbParentParent, true); + + LbAffectedSpecies = new Label { Text = "Affected species: ", Margin = marginLabelDefault, AutoSize = true }; + tt.SetToolTip(LbAffectedSpecies, @"Comma separated list of species affected by this setting. +More specific identifier will be used first. Specificity order is +BlueprintPath > DescriptiveNameAndMod > DescriptiveName > Name"); + flpHeaderControls.Controls.Add(LbAffectedSpecies); + TbAffectedSpecies = new TextBox { AutoSize = true, MinimumSize = new Size(50, 0) }; + flpHeaderControls.Controls.Add(TbAffectedSpecies); + TbAffectedSpecies.Leave += TbAffectedSpeciesLeave; + InitializeStatControls(); InitializeOptions(); } @@ -150,6 +169,10 @@ private void CbbOptions_SelectedIndexChanged(object sender, EventArgs e) LbParent.Visible = isNotRoot; CbbParent.Visible = isNotRoot; BtRemove.Visible = isNotRoot; + LbParentParent.Text = ParentsParentText(SelectedStatsOptions.ParentOptions); + LbAffectedSpecies.Visible = isNotRoot; + TbAffectedSpecies.Visible = isNotRoot; + TbAffectedSpecies.Text = SelectedStatsOptions.AffectedSpecies == null ? string.Empty : string.Join(", ", SelectedStatsOptions.AffectedSpecies); UpdateStatsControls(isNotRoot); @@ -157,6 +180,36 @@ private void CbbOptions_SelectedIndexChanged(object sender, EventArgs e) this.ResumeDrawing(); } + private void TbAffectedSpeciesLeave(object sender, EventArgs e) + { + if (SelectedStatsOptions == null) return; + var sp = TbAffectedSpecies.Text + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)) + .Distinct() + .ToArray(); + SelectedStatsOptions.AffectedSpecies = sp.Any() ? sp : null; + } + + private string ParentsParentText(StatsOptions selectedStatsOptions) + { + var maxGenerationsShown = 5; + var currentParent = selectedStatsOptions?.ParentOptions; + var parentText = string.Empty; + while (currentParent != null) + { + if (maxGenerationsShown-- <= 0) + { + parentText += " \u2794 …"; + break; + } + parentText += " \u2794 " + (string.IsNullOrEmpty(currentParent.Name) ? currentParent.ToString() : currentParent.Name); + currentParent = currentParent.ParentOptions; + } + + return parentText; + } + /// /// Override this method to update the UI of the stat controls. /// @@ -167,7 +220,9 @@ private void CbbParent_SelectedIndexChanged(object sender, EventArgs e) if (_ignoreIndexChange) return; SelectedStatsOptions = CbbOptions.SelectedItem as StatsOptions; if (SelectedStatsOptions == null) return; - SelectedStatsOptions.ParentOptions = CbbParent.SelectedItem as StatsOptions; + var selectedParent = CbbParent.SelectedItem as StatsOptions; + if (SelectedStatsOptions == selectedParent) return; // ignore if node itself is selected as parent + SelectedStatsOptions.ParentOptions = selectedParent; InitializeOptions(true); StatsOptionsSettings.ClearSpeciesCache(); } @@ -187,6 +242,9 @@ private void TbOptionsName_Leave(object sender, EventArgs e) StatsOptionsSettings.StatsOptionsDict.Add(newName, SelectedStatsOptions); // update text in combobox CbbOptions.Items[CbbOptions.SelectedIndex] = SelectedStatsOptions; + var cbbParentIndex = CbbParent.Items.IndexOf(SelectedStatsOptions); + if (cbbParentIndex >= 0) + CbbParent.Items[cbbParentIndex] = SelectedStatsOptions; StatsOptionsSettings.ClearSpeciesCache(); } diff --git a/ARKBreedingStats/StatsOptions/StatsOptionsSettings.cs b/ARKBreedingStats/StatsOptions/StatsOptionsSettings.cs index 9a41252f..7010edbc 100644 --- a/ARKBreedingStats/StatsOptions/StatsOptionsSettings.cs +++ b/ARKBreedingStats/StatsOptions/StatsOptionsSettings.cs @@ -9,7 +9,7 @@ namespace ARKBreedingStats.StatsOptions { /// - /// Base access to stats options. + /// Base access to all stats options of one kind, e.g. all level color options. /// /// public class StatsOptionsSettings where T : StatOptionsBase @@ -150,10 +150,18 @@ public StatsOptions GetStatsOptions(Species species) if (_cache.TryGetValue(species.blueprintPath, out var o)) return o; StatsOptions speciesStatsOptions; - if (StatsOptionsDict.TryGetValue(species.blueprintPath, out o) - || StatsOptionsDict.TryGetValue(species.DescriptiveNameAndMod, out o) - || StatsOptionsDict.TryGetValue(species.DescriptiveName, out o) - || StatsOptionsDict.TryGetValue(species.name, out o)) + + var dict = new Dictionary>(); + var list = StatsOptionsDict + .Where(kv => kv.Value.AffectedSpecies != null) + .SelectMany(kv => kv.Value.AffectedSpecies.Select(sp => (sp, kv.Value))); + foreach (var sp in list) + dict[sp.sp] = sp.Value; + + if (dict.TryGetValue(species.blueprintPath, out o) + || dict.TryGetValue(species.DescriptiveNameAndMod, out o) + || dict.TryGetValue(species.DescriptiveName, out o) + || dict.TryGetValue(species.name, out o)) { speciesStatsOptions = GenerateStatsOptions(o); } diff --git a/ARKBreedingStats/_manifest.json b/ARKBreedingStats/_manifest.json index 81f87c27..953789b1 100644 --- a/ARKBreedingStats/_manifest.json +++ b/ARKBreedingStats/_manifest.json @@ -4,7 +4,7 @@ "ARK Smart Breeding": { "Id": "ARK Smart Breeding", "Category": "main", - "version": "0.63.0.1" + "version": "0.63.1.0" }, "SpeciesColorImages": { "Id": "SpeciesColorImages", diff --git a/ARKBreedingStats/library/Creature.cs b/ARKBreedingStats/library/Creature.cs index 696ba5e3..7a5b5571 100644 --- a/ARKBreedingStats/library/Creature.cs +++ b/ARKBreedingStats/library/Creature.cs @@ -287,11 +287,12 @@ public Species Species /// Creates a placeholder creature with the given ArkId, which have to be imported /// /// ArkId from an imported source (no user input) - public Creature(long arkId) + public Creature(long arkId, Species species) { ArkId = arkId; ArkIdImported = true; guid = Utils.ConvertArkIdToGuid(arkId); + Species = species; flags = CreatureFlags.Placeholder; }