From d1091a0f9d5d572396f2b6ad3b7c44d45e586cb8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 13:44:00 +0000 Subject: [PATCH 1/4] Initial plan From efe816e22176ead7eed0b0fd45c9459781f9a51f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 13:50:42 +0000 Subject: [PATCH 2/4] Add HasShadows flag support to BuildingComponentsViewModel Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com> --- .../Graphics/ImageTableViewModel.cs | 5 +++-- .../LocoTypes/ObjectEditorViewModel.cs | 4 +++- .../Building/BuildingComponentsViewModel.cs | 20 +++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Gui/ViewModels/Graphics/ImageTableViewModel.cs b/Gui/ViewModels/Graphics/ImageTableViewModel.cs index b92cc625..f3bee884 100644 --- a/Gui/ViewModels/Graphics/ImageTableViewModel.cs +++ b/Gui/ViewModels/Graphics/ImageTableViewModel.cs @@ -5,6 +5,7 @@ using Common.Logging; using Definitions.ObjectModels; using Definitions.ObjectModels.Graphics; +using Definitions.ObjectModels.Objects.Building; using Definitions.ObjectModels.Objects.Common; using Gui.ViewModels.LocoTypes.Objects.Building; using ReactiveUI; @@ -94,7 +95,7 @@ public class ImageTableViewModel : ReactiveObject, IExtraContentViewModel ImageTable Model { get; init; } - public ImageTableViewModel(ImageTable imageTable, ILogger logger, BuildingComponents? buildingComponents = null) + public ImageTableViewModel(ImageTable imageTable, ILogger logger, BuildingComponents? buildingComponents = null, BuildingObjectFlags? buildingFlags = null) { ArgumentNullException.ThrowIfNull(imageTable); @@ -116,7 +117,7 @@ public ImageTableViewModel(ImageTable imageTable, ILogger logger, BuildingCompon // building components if (buildingComponents != null) { - BuildingComponents = new(buildingComponents, imageTable); + BuildingComponents = new(buildingComponents, imageTable, buildingFlags); } _ = this.WhenAnyValue(o => o.SelectedPrimarySwatch).Skip(1) diff --git a/Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs b/Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs index 4966b28d..7f5b0d21 100644 --- a/Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs +++ b/Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs @@ -6,6 +6,7 @@ using Dat.Data; using Dat.FileParsing; using Definitions.ObjectModels; +using Definitions.ObjectModels.Objects.Building; using Definitions.ObjectModels.Objects.Common; using Definitions.ObjectModels.Objects.Sound; using Definitions.ObjectModels.Types; @@ -264,7 +265,8 @@ public override void Load() else { var bc = CurrentObject.LocoObject.ObjectType == ObjectType.Building ? (CurrentObject.LocoObject.Object as IHasBuildingComponents)?.BuildingComponents : null; - ExtraContentViewModel = new ImageTableViewModel(CurrentObject.LocoObject.ImageTable, Model.Logger, bc); + var buildingFlags = CurrentObject.LocoObject.ObjectType == ObjectType.Building ? (CurrentObject.LocoObject.Object as BuildingObject)?.Flags : null; + ExtraContentViewModel = new ImageTableViewModel(CurrentObject.LocoObject.ImageTable, Model.Logger, bc, buildingFlags); } } } diff --git a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs index fc3d75db..e336f33e 100644 --- a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs +++ b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs @@ -42,6 +42,8 @@ public class BuildingComponentsViewModel : ReactiveObject protected ImageTable ImageTable { get; set; } + protected BuildingObjectFlags? BuildingFlags { get; set; } + public BuildingComponentsViewModel() { _ = this.WhenAnyValue(x => x.BuildingVariations) @@ -53,12 +55,13 @@ public BuildingComponentsViewModel() _ = MessageBus.Current.Listen().Subscribe(UpdateBuildingComponents); } - public BuildingComponentsViewModel(BuildingComponents buildingComponents, ImageTable imageTable) : this() + public BuildingComponentsViewModel(BuildingComponents buildingComponents, ImageTable imageTable, BuildingObjectFlags? buildingFlags = null) : this() { ArgumentNullException.ThrowIfNull(buildingComponents); ArgumentNullException.ThrowIfNull(imageTable); ImageTable = imageTable; + BuildingFlags = buildingFlags; UpdateBuildingComponents(buildingComponents); } @@ -85,6 +88,8 @@ protected void RecomputeBuildingVariationViewModels(List> building MaxWidth = layers.Max(x => x.Max(y => y.Width)) + 16; MaxHeight = (layers.Max(x => x.Max(y => y.Height)) * buildingHeights.Count) + buildingHeights.Sum(x => x) + buildingVariations.Max(x => x.Count) * (VerticalLayerSpacing * 2); + var hasShadows = BuildingFlags?.HasFlag(BuildingObjectFlags.HasShadows) ?? false; + var x = 0; foreach (var variation in buildingVariations) { @@ -102,7 +107,18 @@ protected void RecomputeBuildingVariationViewModels(List> building }; var cumulativeOffset = 0; - foreach (var variationItem in variation) + + // When HasShadows flag is set, the first 4 images (part 0) are the base layer + // and the second 4 images (part 1) are the shadows. + // Shadows should be rendered first (below/behind the base layer). + var reorderedVariation = variation; + if (hasShadows && variation.Count >= 2) + { + // Reorder so shadows (part 1) come before base (part 0) + reorderedVariation = [variation[1], variation[0], .. variation.Skip(2)]; + } + + foreach (var variationItem in reorderedVariation) { if (layers.Count > variationItem) { From 7d90213de1d77e4870e5abb7d3ee03fd2cff4d97 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 13:53:48 +0000 Subject: [PATCH 3/4] Address code review: Add named constants for shadow reordering Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com> --- .../Objects/Building/BuildingComponentsViewModel.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs index e336f33e..56ba736d 100644 --- a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs +++ b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs @@ -81,6 +81,10 @@ void UpdateBuildingComponents(BuildingComponents buildingComponents) protected void RecomputeBuildingVariationViewModels(List> buildingVariations, List buildingHeights) { + const int minPartsForShadowReordering = 2; + const int shadowPartIndex = 1; + const int basePartIndex = 0; + var layers = ImageTable.Groups.ConvertAll(x => x.GraphicsElements); BuildingVariationViewModels.Clear(); @@ -112,10 +116,10 @@ protected void RecomputeBuildingVariationViewModels(List> building // and the second 4 images (part 1) are the shadows. // Shadows should be rendered first (below/behind the base layer). var reorderedVariation = variation; - if (hasShadows && variation.Count >= 2) + if (hasShadows && variation.Count >= minPartsForShadowReordering) { // Reorder so shadows (part 1) come before base (part 0) - reorderedVariation = [variation[1], variation[0], .. variation.Skip(2)]; + reorderedVariation = [variation[shadowPartIndex], variation[basePartIndex], .. variation.Skip(minPartsForShadowReordering)]; } foreach (var variationItem in reorderedVariation) From b5236610973d1c81df0c910afe02fb38d67b94e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 13:58:41 +0000 Subject: [PATCH 4/4] Add clarifying comment about shadow reordering logic Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com> --- .../LocoTypes/Objects/Building/BuildingComponentsViewModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs index 56ba736d..acc21134 100644 --- a/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs +++ b/Gui/ViewModels/LocoTypes/Objects/Building/BuildingComponentsViewModel.cs @@ -115,10 +115,12 @@ protected void RecomputeBuildingVariationViewModels(List> building // When HasShadows flag is set, the first 4 images (part 0) are the base layer // and the second 4 images (part 1) are the shadows. // Shadows should be rendered first (below/behind the base layer). + // Example: variation [0, 1, 2] becomes [1, 0, 2] - swap first two parts, keep rest var reorderedVariation = variation; if (hasShadows && variation.Count >= minPartsForShadowReordering) { // Reorder so shadows (part 1) come before base (part 0) + // Skip(2) skips the first 2 parts we're explicitly including, avoiding duplication reorderedVariation = [variation[shadowPartIndex], variation[basePartIndex], .. variation.Skip(minPartsForShadowReordering)]; }