Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Gui/ViewModels/Graphics/ImageTableViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -53,12 +55,13 @@ public BuildingComponentsViewModel()
_ = MessageBus.Current.Listen<BuildingComponents>().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);
}

Expand All @@ -78,13 +81,19 @@ void UpdateBuildingComponents(BuildingComponents buildingComponents)

protected void RecomputeBuildingVariationViewModels(List<List<uint8_t>> buildingVariations, List<byte> buildingHeights)
{
const int minPartsForShadowReordering = 2;
const int shadowPartIndex = 1;
const int basePartIndex = 0;

var layers = ImageTable.Groups.ConvertAll(x => x.GraphicsElements);

BuildingVariationViewModels.Clear();

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)
{
Expand All @@ -102,7 +111,20 @@ protected void RecomputeBuildingVariationViewModels(List<List<uint8_t>> 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).
// 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)];
}

foreach (var variationItem in reorderedVariation)
{
if (layers.Count > variationItem)
{
Expand Down