diff --git a/Directory.Build.targets b/Directory.Build.targets index a3d7b9d4e..cf5cab7ac 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,6 +1,6 @@ - 3.9.0 + 3.9.0.9145 craftworkgames https://github.com/craftworkgames/MonoGame.Extended https://github.com/craftworkgames/MonoGame.Extended diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/ContentImporterContextExtensions.cs b/src/cs/MonoGame.Extended.Content.Pipeline/ContentImporterContextExtensions.cs new file mode 100644 index 000000000..7f6381555 --- /dev/null +++ b/src/cs/MonoGame.Extended.Content.Pipeline/ContentImporterContextExtensions.cs @@ -0,0 +1,15 @@ +using System.IO; +using Microsoft.Xna.Framework.Content.Pipeline; + +namespace MonoGame.Extended.Content.Pipeline; + +public static class ContentImporterContextExtensions +{ + public static string AddDependencyWithLogging(this ContentImporterContext context, string filePath, string source) + { + source = Path.Combine(Path.GetDirectoryName(filePath), source); + ContentLogger.Log($"Adding dependency '{source}'"); + context.AddDependency(source); + return source; + } +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/ContentItem.cs b/src/cs/MonoGame.Extended.Content.Pipeline/ContentItem.cs index 487f31efe..e69d48e16 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/ContentItem.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/ContentItem.cs @@ -28,10 +28,10 @@ public void BuildExternalReference(ContentProcessorContext context, stri public ExternalReference GetExternalReference(string source) { - if (_externalReferences.TryGetValue(source, out var contentItem)) + if (source is not null && _externalReferences.TryGetValue(source, out var contentItem)) return contentItem as ExternalReference; return null; } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledContentItem.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledContentItem.cs new file mode 100644 index 000000000..b3762524b --- /dev/null +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledContentItem.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework.Content.Pipeline; +using Microsoft.Xna.Framework.Content.Pipeline.Graphics; +using MonoGame.Extended.Tiled.Serialization; + +namespace MonoGame.Extended.Content.Pipeline.Tiled; + +public class TiledContentItem: ContentItem +{ + public TiledContentItem(T data) : base(data) + { + } + + public void BuildExternalReference(ContentProcessorContext context, TiledMapImageContent image) + { + var parameters = new OpaqueDataDictionary + { + { "ColorKeyColor", image.TransparentColor }, + { "ColorKeyEnabled", true } + }; + BuildExternalReference(context, image.Source, parameters); + } +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapContentItem.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapContentItem.cs index 7f381e423..b0b7b5dd0 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapContentItem.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapContentItem.cs @@ -2,11 +2,11 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled { - public class TiledMapContentItem : ContentItem + public class TiledMapContentItem : TiledContentItem { - public TiledMapContentItem(TiledMapContent data) + public TiledMapContentItem(TiledMapContent data) : base(data) { } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapProcessor.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapProcessor.cs index da130a4cf..9668a7232 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapProcessor.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapProcessor.cs @@ -75,7 +75,7 @@ public static void Process(TiledMapObjectContent obj, ContentProcessorContext co } } } - + [ContentProcessor(DisplayName = "Tiled Map Processor - MonoGame.Extended")] public class TiledMapProcessor : ContentProcessor @@ -95,14 +95,7 @@ public override TiledMapContentItem Process(TiledMapContentItem contentItem, Con if (string.IsNullOrWhiteSpace(tileset.Source)) { // Load the Texture2DContent for the tileset as it will be saved into the map content file. - //var externalReference = new ExternalReference(tileset.Image.Source); - var parameters = new OpaqueDataDictionary - { - { "ColorKeyColor", tileset.Image.TransparentColor }, - { "ColorKeyEnabled", true } - }; - //tileset.Image.ContentRef = context.BuildAsset(externalReference, "", parameters, "", ""); - contentItem.BuildExternalReference(context, tileset.Image.Source, parameters); + contentItem.BuildExternalReference(context, tileset.Image); } else { @@ -114,7 +107,7 @@ public override TiledMapContentItem Process(TiledMapContentItem contentItem, Con } ProcessLayers(contentItem, map, context, map.Layers); - + return contentItem; } catch (Exception ex) @@ -132,14 +125,7 @@ private static void ProcessLayers(TiledMapContentItem contentItem, TiledMapConte { case TiledMapImageLayerContent imageLayer: ContentLogger.Log($"Processing image layer '{imageLayer.Name}'"); - //var externalReference = new ExternalReference(imageLayer.Image.Source); - var parameters = new OpaqueDataDictionary - { - { "ColorKeyColor", imageLayer.Image.TransparentColor }, - { "ColorKeyEnabled", true } - }; - //imageLayer.Image.ContentRef = context.BuildAsset(externalReference, "", parameters, "", ""); - contentItem.BuildExternalReference(context, imageLayer.Image.Source, parameters); + contentItem.BuildExternalReference(context, imageLayer.Image); ContentLogger.Log($"Processed image layer '{imageLayer.Name}'"); break; @@ -335,4 +321,4 @@ private static Stream OpenStream(byte[] decodedData, string compressionMode) }; } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetContentItem.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetContentItem.cs index 4280ccdf2..d4b2221dd 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetContentItem.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetContentItem.cs @@ -1,12 +1,14 @@ -using MonoGame.Extended.Tiled.Serialization; +using Microsoft.Xna.Framework.Content.Pipeline; +using Microsoft.Xna.Framework.Content.Pipeline.Graphics; +using MonoGame.Extended.Tiled.Serialization; namespace MonoGame.Extended.Content.Pipeline.Tiled { - public class TiledMapTilesetContentItem : ContentItem + public class TiledMapTilesetContentItem : TiledContentItem { - public TiledMapTilesetContentItem(TiledMapTilesetContent data) + public TiledMapTilesetContentItem(TiledMapTilesetContent data) : base(data) { } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetImporter.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetImporter.cs index a1b53e0bb..c848bde51 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetImporter.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetImporter.cs @@ -39,23 +39,18 @@ private TiledMapTilesetContent DeserializeTiledMapTilesetContent(string filePath var tilesetSerializer = new XmlSerializer(typeof(TiledMapTilesetContent)); var tileset = (TiledMapTilesetContent)tilesetSerializer.Deserialize(reader); - tileset.Image.Source = Path.Combine(Path.GetDirectoryName(filePath), tileset.Image.Source); - ContentLogger.Log($"Adding dependency '{tileset.Image.Source}'"); - context.AddDependency(tileset.Image.Source); + if (tileset.Image is not null) + tileset.Image.Source = context.AddDependencyWithLogging(filePath, tileset.Image.Source); foreach (var tile in tileset.Tiles) { foreach (var obj in tile.Objects) { if (!string.IsNullOrWhiteSpace(obj.TemplateSource)) - { - obj.TemplateSource = Path.Combine(Path.GetDirectoryName(filePath), obj.TemplateSource); - ContentLogger.Log($"Adding dependency '{obj.TemplateSource}'"); - - // We depend on the template. - context.AddDependency(obj.TemplateSource); - } + obj.TemplateSource = context.AddDependencyWithLogging(filePath, obj.TemplateSource); } + if (tile.Image is not null) + tile.Image.Source = context.AddDependencyWithLogging(filePath, tile.Image.Source); } return tileset; diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetProcessor.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetProcessor.cs index cefd62ad4..5682602f9 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetProcessor.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetProcessor.cs @@ -15,16 +15,10 @@ public override TiledMapTilesetContentItem Process(TiledMapTilesetContentItem co ContentLogger.Logger = context.Logger; ContentLogger.Log($"Processing tileset '{tileset.Name}'"); - + // Build the Texture2D asset and load it as it will be saved as part of this tileset file. - //var externalReference = new ExternalReference(tileset.Image.Source); - var parameters = new OpaqueDataDictionary - { - { "ColorKeyColor", tileset.Image.TransparentColor }, - { "ColorKeyEnabled", true } - }; - //tileset.Image.ContentRef = context.BuildAsset(externalReference, "", parameters, "", ""); - contentItem.BuildExternalReference(context, tileset.Image.Source, parameters); + if (tileset.Image is not null) + contentItem.BuildExternalReference(context, tileset.Image); foreach (var tile in tileset.Tiles) { @@ -32,6 +26,8 @@ public override TiledMapTilesetContentItem Process(TiledMapTilesetContentItem co { TiledMapContentHelper.Process(obj, context); } + if (tile.Image is not null) + contentItem.BuildExternalReference(context, tile.Image); } ContentLogger.Log($"Processed tileset '{tileset.Name}'"); diff --git a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetWriter.cs b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetWriter.cs index 19c52740b..6c9ebc573 100644 --- a/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetWriter.cs +++ b/src/cs/MonoGame.Extended.Content.Pipeline/Tiled/TiledMapTilesetWriter.cs @@ -30,9 +30,9 @@ protected override void Write(ContentWriter writer, TiledMapTilesetContentItem c public static void WriteTileset(ContentWriter writer, TiledMapTilesetContent tileset, IExternalReferenceRepository externalReferenceRepository) { - var externalReference = externalReferenceRepository.GetExternalReference(tileset.Image.Source); - + var externalReference = externalReferenceRepository.GetExternalReference(tileset.Image?.Source); writer.WriteExternalReference(externalReference); + writer.Write(tileset.TileWidth); writer.Write(tileset.TileHeight); writer.Write(tileset.TileCount); @@ -42,13 +42,17 @@ public static void WriteTileset(ContentWriter writer, TiledMapTilesetContent til writer.Write(tileset.Tiles.Count); foreach (var tilesetTile in tileset.Tiles) - WriteTilesetTile(writer, tilesetTile); + WriteTilesetTile(writer, tilesetTile, externalReferenceRepository); writer.WriteTiledMapProperties(tileset.Properties); } - private static void WriteTilesetTile(ContentWriter writer, TiledMapTilesetTileContent tilesetTile) + private static void WriteTilesetTile(ContentWriter writer, TiledMapTilesetTileContent tilesetTile, + IExternalReferenceRepository externalReferenceRepository) { + var externalReference = externalReferenceRepository.GetExternalReference(tilesetTile.Image?.Source); + writer.WriteExternalReference(externalReference); + writer.Write(tilesetTile.LocalIdentifier); writer.Write(tilesetTile.Type); writer.Write(tilesetTile.Frames.Count); diff --git a/src/cs/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs b/src/cs/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs index c1fb73f43..b73194563 100644 --- a/src/cs/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs +++ b/src/cs/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs @@ -52,12 +52,16 @@ private IEnumerable CreateTileLayerModels(TiledMap map, Tile var tileGid = tile.GlobalIdentifier; var localTileIdentifier = tileGid - firstGlobalIdentifier; var position = GetTilePosition(map, tile); - var tilesetColumns = tileset.Columns == 0 ? 1 : tileset.Columns; // fixes a problem (what problem exactly?) - var sourceRectangle = TiledMapHelper.GetTileSourceRectangle(localTileIdentifier, tileset.TileWidth, tileset.TileHeight, tilesetColumns, tileset.Margin, tileset.Spacing); + var sourceRectangle = tileset.GetTileRegion(localTileIdentifier); var flipFlags = tile.Flags; // animated tiles var tilesetTile = tileset.Tiles.FirstOrDefault(x => x.LocalTileIdentifier == localTileIdentifier); + if (tilesetTile?.Texture is not null) + { + position.Y += map.TileHeight - sourceRectangle.Height; + texture = tilesetTile.Texture; + } if (tilesetTile is TiledMapTilesetAnimatedTile animatedTilesetTile) { @@ -117,4 +121,4 @@ private static Point2 GetTilePosition(TiledMap map, TiledMapTile mapTile) } } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapTileset.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapTileset.cs index d5c5c5154..8736f54a9 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapTileset.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapTileset.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MonoGame.Extended.TextureAtlases; @@ -58,7 +59,10 @@ public TextureRegion2D GetRegion(int column, int row) public Rectangle GetTileRegion(int localTileIdentifier) { - return TiledMapHelper.GetTileSourceRectangle(localTileIdentifier, TileWidth, TileHeight, Columns, Margin, Spacing); + return Texture is not null + ? TiledMapHelper.GetTileSourceRectangle(localTileIdentifier, TileWidth, TileHeight, Columns, Margin, + Spacing) + : Tiles.FirstOrDefault(x => x.LocalTileIdentifier == localTileIdentifier).Texture.Bounds; } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetAnimatedTile.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetAnimatedTile.cs index dc7795c8c..395f2d0be 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetAnimatedTile.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetAnimatedTile.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; namespace MonoGame.Extended.Tiled { @@ -12,8 +13,9 @@ public class TiledMapTilesetAnimatedTile : TiledMapTilesetTile public ReadOnlyCollection AnimationFrames { get; } public TiledMapTilesetTileAnimationFrame CurrentAnimationFrame { get; private set; } - public TiledMapTilesetAnimatedTile(int localTileIdentifier, TiledMapTilesetTileAnimationFrame[] frames, string type = null, TiledMapObject[] objects = null) - : base(localTileIdentifier, type, objects) + public TiledMapTilesetAnimatedTile(int localTileIdentifier, + TiledMapTilesetTileAnimationFrame[] frames, string type = null, TiledMapObject[] objects = null, Texture2D texture = null) + : base(localTileIdentifier, type, objects, texture) { if (frames.Length == 0) throw new InvalidOperationException("There must be at least one tileset animation frame"); @@ -33,4 +35,4 @@ public void Update(GameTime gameTime) CurrentAnimationFrame = AnimationFrames[_frameIndex]; } } -} \ No newline at end of file +} diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetReader.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetReader.cs index 8ce0bb345..9dee3735b 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetReader.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetReader.cs @@ -29,25 +29,35 @@ public static TiledMapTileset ReadTileset(ContentReader reader) var tileset = new TiledMapTileset(texture, tileWidth, tileHeight, tileCount, spacing, margin, columns); for (var tileIndex = 0; tileIndex < explicitTileCount; tileIndex++) - { - var localTileIdentifier = reader.ReadInt32(); - var type = reader.ReadString(); - var animationFramesCount = reader.ReadInt32(); - var tilesetTile = animationFramesCount <= 0 - ? ReadTiledMapTilesetTile(reader, tileset, objects => - new TiledMapTilesetTile(localTileIdentifier, type, objects)) - : ReadTiledMapTilesetTile(reader, tileset, objects => - new TiledMapTilesetAnimatedTile(localTileIdentifier, ReadTiledMapTilesetAnimationFrames(reader, tileset, animationFramesCount), type, objects)); - - ReadProperties(reader, tilesetTile.Properties); - tileset.Tiles.Add(tilesetTile); - } + ReadTile(reader, tileset); ReadProperties(reader, tileset.Properties); return tileset; } - private static TiledMapTilesetTileAnimationFrame[] ReadTiledMapTilesetAnimationFrames(ContentReader reader, TiledMapTileset tileset, int animationFramesCount) + private static void ReadTile(ContentReader reader, TiledMapTileset tileset) + { + var texture = reader.ReadExternalReference(); + + var localTileIdentifier = reader.ReadInt32(); + var type = reader.ReadString(); + var animationFramesCount = reader.ReadInt32(); + var objectCount = reader.ReadInt32(); + var objects = new TiledMapObject[objectCount]; + + for (var i = 0; i < objectCount; i++) + objects[i] = ReadTiledMapObject(reader, tileset); + + var tilesetTile = animationFramesCount <= 0 + ? new TiledMapTilesetTile(localTileIdentifier, type, objects, texture) + : new TiledMapTilesetAnimatedTile(localTileIdentifier, + ReadTiledMapTilesetAnimationFrames(reader, tileset, animationFramesCount), type, objects, texture); + + ReadProperties(reader, tilesetTile.Properties); + tileset.Tiles.Add(tilesetTile); + } + + private static TiledMapTilesetTileAnimationFrame[] ReadTiledMapTilesetAnimationFrames(ContentReader reader, TiledMapTileset tileset, int animationFramesCount) { var animationFrames = new TiledMapTilesetTileAnimationFrame[animationFramesCount]; @@ -64,6 +74,7 @@ private static TiledMapTilesetTileAnimationFrame[] ReadTiledMapTilesetAnimationF private static TiledMapTilesetTile ReadTiledMapTilesetTile(ContentReader reader, TiledMapTileset tileset, Func createTile) { + var texture = reader.ReadExternalReference(); var objectCount = reader.ReadInt32(); var objects = new TiledMapObject[objectCount]; diff --git a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetTile.cs b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetTile.cs index 9adc17d77..e378aa3f1 100644 --- a/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetTile.cs +++ b/src/cs/MonoGame.Extended.Tiled/TiledMapTilesetTile.cs @@ -1,12 +1,15 @@ using System.Collections.Generic; using System.Diagnostics; +using Microsoft.Xna.Framework.Graphics; namespace MonoGame.Extended.Tiled { [DebuggerDisplay("{LocalTileIdentifier}: Type: {Type}, Properties: {Properties.Count}, Objects: {Objects.Count}")] public class TiledMapTilesetTile { - public TiledMapTilesetTile(int localTileIdentifier, string type = null, TiledMapObject[] objects = null) + // For remove libraries + public TiledMapTilesetTile(int localTileIdentifier, string type = null, + TiledMapObject[] objects = null) { LocalTileIdentifier = localTileIdentifier; Type = type; @@ -14,9 +17,20 @@ public TiledMapTilesetTile(int localTileIdentifier, string type = null, TiledMap Properties = new TiledMapProperties(); } + public TiledMapTilesetTile(int localTileIdentifier, string type = null, + TiledMapObject[] objects = null, Texture2D texture = null) + { + Texture = texture; + LocalTileIdentifier = localTileIdentifier; + Type = type; + Objects = objects != null ? new List(objects) : new List(); + Properties = new TiledMapProperties(); + } + public int LocalTileIdentifier { get; } public string Type { get; } public TiledMapProperties Properties { get; } public List Objects { get; } + public Texture2D Texture { get; } } -} \ No newline at end of file +}