diff --git a/ElectronicObserver.Core/Types/Serialization/EquipmentUpgrade/UpgradeCostDataEqualityComparer.cs b/ElectronicObserver.Core/Types/Serialization/EquipmentUpgrade/UpgradeCostDataEqualityComparer.cs
new file mode 100644
index 000000000..1956a5727
--- /dev/null
+++ b/ElectronicObserver.Core/Types/Serialization/EquipmentUpgrade/UpgradeCostDataEqualityComparer.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+
+namespace ElectronicObserver.Core.Types.Serialization.EquipmentUpgrade;
+
+///
+/// This equality comparer is used to group upgrade data based on the cost of levels 0 -> 5 and 6 -> max
+/// Conversion & extra costs are ignored
+///
+public class UpgradeCostDataEqualityComparer : IEqualityComparer
+{
+ public bool Equals(EquipmentUpgradeImprovementModel? x, EquipmentUpgradeImprovementModel? y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (x is null || y is null)
+ return false;
+
+ return Equals(x.Costs, y.Costs);
+ }
+
+ private bool Equals(EquipmentUpgradeImprovementCost? x, EquipmentUpgradeImprovementCost? y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (x is null || y is null)
+ return false;
+
+ if (x.Fuel != y.Fuel) return false;
+ if (x.Ammo != y.Ammo) return false;
+ if (x.Steel != y.Steel) return false;
+ if (x.Bauxite != y.Bauxite) return false;
+
+ if (!Equals(x.Cost0To5, y.Cost0To5)) return false;
+ if (!Equals(x.Cost6To9, y.Cost6To9)) return false;
+
+ return true;
+ }
+
+ private bool Equals(EquipmentUpgradeImprovementCostDetail? x, EquipmentUpgradeImprovementCostDetail? y)
+ {
+ if (ReferenceEquals(x, y))
+ return true;
+
+ if (x is null || y is null)
+ return false;
+
+ if (x.DevmatCost != y.DevmatCost) return false;
+ if (x.SliderDevmatCost != y.SliderDevmatCost) return false;
+ if (x.ImproveMatCost != y.ImproveMatCost) return false;
+ if (x.SliderImproveMatCost != y.SliderImproveMatCost) return false;
+
+ foreach (EquipmentUpgradeImprovementCostItemDetail costItem in x.ConsumableDetail)
+ {
+ EquipmentUpgradeImprovementCostItemDetail? matchingCostItem = y.ConsumableDetail.Find(c => c.Id == costItem.Id);
+
+ if (matchingCostItem is null || costItem.Count != matchingCostItem.Count)
+ return false;
+ }
+
+ foreach (EquipmentUpgradeImprovementCostItemDetail costItem in x.EquipmentDetail)
+ {
+ EquipmentUpgradeImprovementCostItemDetail? matchingCostItem = y.EquipmentDetail.Find(c => c.Id == costItem.Id);
+
+ if (matchingCostItem is null || costItem.Count != matchingCostItem.Count)
+ return false;
+ }
+
+ return true;
+ }
+
+ public int GetHashCode(EquipmentUpgradeImprovementModel obj) => GetHashCode(obj.Costs);
+
+ private int GetHashCode(EquipmentUpgradeImprovementCost cost)
+ {
+ HashCode hash = new();
+
+ hash.Add(cost.Fuel);
+ hash.Add(cost.Ammo);
+ hash.Add(cost.Steel);
+ hash.Add(cost.Bauxite);
+
+ hash.Add(GetHashCode(cost.Cost0To5));
+ hash.Add(GetHashCode(cost.Cost6To9));
+
+ return hash.ToHashCode();
+ }
+
+ private int GetHashCode(EquipmentUpgradeImprovementCostDetail cost)
+ {
+ HashCode hash = new();
+
+ hash.Add(cost.DevmatCost);
+ hash.Add(cost.SliderDevmatCost);
+ hash.Add(cost.ImproveMatCost);
+ hash.Add(cost.SliderImproveMatCost);
+
+ foreach (EquipmentUpgradeImprovementCostItemDetail costItem in cost.ConsumableDetail.OrderBy(c => c.Id))
+ {
+ hash.Add(costItem.Id);
+ hash.Add(costItem.Count);
+ }
+
+ foreach (EquipmentUpgradeImprovementCostItemDetail costItem in cost.EquipmentDetail.OrderBy(e => e.Id))
+ {
+ hash.Add(costItem.Id);
+ hash.Add(costItem.Count);
+ }
+
+ return hash.ToHashCode();
+ }
+}
diff --git a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/DialogAlbumMasterEquipmentWpf.xaml b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/DialogAlbumMasterEquipmentWpf.xaml
index a5334eb72..5048e1409 100644
--- a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/DialogAlbumMasterEquipmentWpf.xaml
+++ b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/DialogAlbumMasterEquipmentWpf.xaml
@@ -179,7 +179,12 @@
-
+
+
+
+
+
+
@@ -367,7 +372,7 @@
/>
-
+
@@ -638,25 +643,25 @@
-
+
-
+
-
+
-
+
@@ -673,9 +678,47 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeControl.xaml b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeControl.xaml
index d565567ad..f4189c8c9 100644
--- a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeControl.xaml
+++ b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeControl.xaml
@@ -7,13 +7,13 @@
xmlns:helpers="clr-namespace:ElectronicObserver.Window.Tools.EquipmentUpgradePlanner.Helpers"
xmlns:local="clr-namespace:ElectronicObserver.Window.Tools.DialogAlbumMasterEquipment.EquipmentUpgrade"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- d:DataContext="{d:DesignInstance local:AlbumMasterEquipmentUpgradeViewModel}"
+ d:DataContext="{d:DesignInstance local:AlbumMasterEquipmentUpgradeGroupViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
>
-
+
@@ -83,31 +83,9 @@
-
-
-
-
-
-
-
-
-
-
-
+ /// Equipment upgrade cost, its the first cost found for this equipment so it's accurate for fuel, ammo, ... and devmats/screws for 0 -> 9 upgrades
+ ///
+ public EquipmentUpgradeImprovementCost EquipmentUpgradeCost { get; private set; } = new();
+
+ public List RequiredItemsPerLevel { get; set; } = [];
+
+ public List ConversionViewModel { get; private set; } = [];
+
+ public List Helpers { get; private set; } = [];
+
+ public AlbumMasterEquipmentUpgradeTranslationViewModel EquipmentUpgradeTranslation { get; }
+
+ public List Models { get; }
+
+ public AlbumMasterEquipmentUpgradeGroupViewModel(List improvements, AlbumMasterEquipmentUpgradeTranslationViewModel translations, IEquipmentDataMaster equipment)
+ {
+ Models = improvements;
+ EquipmentUpgradeTranslation = translations;
+ Equipment = equipment;
+
+ LoadUpgradeData();
+ }
+
+ private void LoadUpgradeData()
+ {
+ EquipmentUpgradeImprovementModel? firstImprovement = Models.FirstOrDefault();
+
+ if (firstImprovement is null) return;
+
+ EquipmentUpgradeCost = firstImprovement.Costs;
+
+ Helpers = Models
+ .SelectMany(improvement => improvement.Helpers)
+ .Select(helperGroup => new EquipmentUpgradeHelpersViewModel(helperGroup))
+ .ToList();
+
+ InitializeCostPerLevel();
+
+ ConversionViewModel = Models
+ .Where(improvement => improvement.ConversionData is not null)
+ .Where(improvement => improvement.Costs.CostMax is not null)
+ .Select(improvement => new EquipmentUpgradeConversionViewModel(improvement))
+ .ToList();
+ }
+
+ private void InitializeCostPerLevel()
+ {
+ RequiredItemsPerLevel = EquipmentUpgradeCost
+ .GetCostPerLevelRange()
+ .Where(range => range.StartLevel != UpgradeLevel.Conversion)
+ .Select(range => new AlbumMasterEquipmentUpgradeLevelViewModel(range))
+ .ToList();
+ }
+
+ public void UnsubscribeFromApis()
+ {
+ ConversionViewModel.ForEach(viewModel => viewModel.UnsubscribeFromApis());
+ Helpers.ForEach(viewModel => viewModel.UnsubscribeFromApis());
+ RequiredItemsPerLevel.ForEach(viewModel => viewModel.UnsubscribeFromApis());
+ }
+}
diff --git a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModelProxy.cs b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeGroupViewModelProxy.cs
similarity index 52%
rename from ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModelProxy.cs
rename to ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeGroupViewModelProxy.cs
index 2ecf0f702..10027e7d4 100644
--- a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModelProxy.cs
+++ b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeGroupViewModelProxy.cs
@@ -2,6 +2,6 @@
namespace ElectronicObserver.Window.Tools.DialogAlbumMasterEquipment.EquipmentUpgrade;
-public class AlbumMasterEquipmentUpgradeViewModelProxy : BindingProxy
+public class AlbumMasterEquipmentUpgradeGroupViewModelProxy : BindingProxy
{
}
diff --git a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModel.cs b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModel.cs
index 65143a558..e6217fa39 100644
--- a/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModel.cs
+++ b/ElectronicObserver/Window/Tools/DialogAlbumMasterEquipment/EquipmentUpgrade/AlbumMasterEquipmentUpgradeViewModel.cs
@@ -5,28 +5,18 @@
using ElectronicObserver.Core.Types.Serialization.EquipmentUpgrade;
using ElectronicObserver.Data;
using ElectronicObserver.Data.Translation;
-using ElectronicObserver.Utility.Data;
-using ElectronicObserver.Window.Tools.EquipmentUpgradePlanner.Helpers;
namespace ElectronicObserver.Window.Tools.DialogAlbumMasterEquipment.EquipmentUpgrade;
public class AlbumMasterEquipmentUpgradeViewModel
{
- public EquipmentUpgradeDataModel? UpgradeData { get; private set; }
- public IEquipmentDataMaster Equipment { get; }
+ public int Fuel { get; set; }
+ public int Ammo { get; set; }
+ public int Steel { get; set; }
+ public int Bauxite { get; set; }
- public bool CanBeUpgraded => UpgradeData?.Improvement.FirstOrDefault() is not null;
-
- ///
- /// Equipment upgrade cost, its the first cost found for this equipment so it's accurate for fuel, ammo, ... and devmats/screws for 0 -> 9 upgrades
- ///
- public EquipmentUpgradeImprovementCost EquipmentUpgradeCost { get; private set; } = new();
-
- public List RequiredItemsPerLevel { get; set; } = [];
-
- public List ConversionViewModel { get; private set; } = new();
-
- public List Helpers { get; private set; } = new();
+ public List UpgradeViewModels { get; private set; } = [];
+ private IEquipmentDataMaster Equipment { get; }
public AlbumMasterEquipmentUpgradeTranslationViewModel EquipmentUpgradeTranslation { get; }
@@ -41,44 +31,39 @@ public AlbumMasterEquipmentUpgradeViewModel(IEquipmentDataMaster equipment)
private void LoadUpgradeData()
{
EquipmentUpgradeData upgradeData = KCDatabase.Instance.Translation.EquipmentUpgrade;
- UpgradeData = upgradeData.UpgradeList.FirstOrDefault(upgrade => upgrade.EquipmentId == Equipment.ID);
+ EquipmentUpgradeDataModel? data = upgradeData.UpgradeList.FirstOrDefault(upgrade => upgrade.EquipmentId == Equipment.ID);
- if (UpgradeData is null) return;
+ if (data is null) return;
- EquipmentUpgradeImprovementModel? firstImprovement = UpgradeData.Improvement.FirstOrDefault();
+ EquipmentUpgradeImprovementModel? firstImprovement = data.Improvement.FirstOrDefault();
if (firstImprovement is null) return;
- EquipmentUpgradeCost = firstImprovement.Costs;
-
- Helpers = UpgradeData.Improvement
- .SelectMany(improvement => improvement.Helpers)
- .Select(helperGroup => new EquipmentUpgradeHelpersViewModel(helperGroup))
- .ToList();
-
- InitializeCostPerLevel();
-
- ConversionViewModel = UpgradeData
- .Improvement
- .Where(improvement => improvement.ConversionData is not null)
- .Where(improvement => improvement.Costs.CostMax is not null)
- .Select(improvement => new EquipmentUpgradeConversionViewModel(improvement))
- .ToList();
- }
-
- private void InitializeCostPerLevel()
- {
- RequiredItemsPerLevel = EquipmentUpgradeCost
- .GetCostPerLevelRange()
- .Where(range => range.StartLevel != UpgradeLevel.Conversion)
- .Select(range => new AlbumMasterEquipmentUpgradeLevelViewModel(range))
- .ToList();
+ Fuel = firstImprovement.Costs.Fuel;
+ Ammo = firstImprovement.Costs.Ammo;
+ Steel = firstImprovement.Costs.Steel;
+ Bauxite = firstImprovement.Costs.Bauxite;
+
+ List conversions = data.Improvement.Select(i => i.ConversionData?.IdEquipmentAfter).OfType().ToList();
+
+ if (conversions.Count != conversions.Distinct().Count())
+ {
+ // Special case : 12.7cm連装砲A型 conversion cost is different depending on ship
+ UpgradeViewModels = data.Improvement
+ .Select(improvement => new AlbumMasterEquipmentUpgradeGroupViewModel([improvement], EquipmentUpgradeTranslation, Equipment))
+ .ToList();
+ }
+ else
+ {
+ UpgradeViewModels = data.Improvement
+ .GroupBy(improvement => improvement, new UpgradeCostDataEqualityComparer())
+ .Select(group => new AlbumMasterEquipmentUpgradeGroupViewModel(group.ToList(), EquipmentUpgradeTranslation, Equipment))
+ .ToList();
+ }
}
public void UnsubscribeFromApis()
{
- ConversionViewModel.ForEach(viewModel => viewModel.UnsubscribeFromApis());
- Helpers.ForEach(viewModel => viewModel.UnsubscribeFromApis());
- RequiredItemsPerLevel.ForEach(viewModel => viewModel.UnsubscribeFromApis());
+ UpgradeViewModels.ForEach(vm => vm.UnsubscribeFromApis());
}
}