Map renderer rework (#37306)
* Update TilePainter.cs * Add support for custom offsets, grid files, and markers * Dynamic file category handling
This commit is contained in:
@@ -12,6 +12,7 @@ public sealed class CommandLineArguments
|
|||||||
public bool ExportViewerJson { get; set; } = false;
|
public bool ExportViewerJson { get; set; } = false;
|
||||||
public string OutputPath { get; set; } = DirectoryExtensions.MapImages().FullName;
|
public string OutputPath { get; set; } = DirectoryExtensions.MapImages().FullName;
|
||||||
public bool ArgumentsAreFileNames { get; set; } = false;
|
public bool ArgumentsAreFileNames { get; set; } = false;
|
||||||
|
public bool ShowMarkers { get; set; } = false;
|
||||||
|
|
||||||
public static bool TryParse(IReadOnlyList<string> args, [NotNullWhen(true)] out CommandLineArguments? parsed)
|
public static bool TryParse(IReadOnlyList<string> args, [NotNullWhen(true)] out CommandLineArguments? parsed)
|
||||||
{
|
{
|
||||||
@@ -59,6 +60,11 @@ public sealed class CommandLineArguments
|
|||||||
parsed.ArgumentsAreFileNames = true;
|
parsed.ArgumentsAreFileNames = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "-m":
|
||||||
|
case "--markers":
|
||||||
|
parsed.ShowMarkers = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case "-h":
|
case "-h":
|
||||||
case "--help":
|
case "--help":
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
@@ -95,7 +101,9 @@ Options:
|
|||||||
Defaults to Resources/MapImages
|
Defaults to Resources/MapImages
|
||||||
-f / --files
|
-f / --files
|
||||||
This option tells the map renderer that you supplied a list of map file names instead of their ids.
|
This option tells the map renderer that you supplied a list of map file names instead of their ids.
|
||||||
Example: Content.MapRenderer -f box.yml bagel.yml
|
Example: Content.MapRenderer -f /Maps/box.yml /Maps/bagel.yml
|
||||||
|
-m / --markers
|
||||||
|
Show hidden markers on map render. Defaults to false.
|
||||||
-h / --help
|
-h / --help
|
||||||
Displays this help text");
|
Displays this help text");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
using Content.Shared.Decals;
|
using Content.Shared.Decals;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.Utility;
|
using Robust.Client.Utility;
|
||||||
using Robust.Shared.ContentPack;
|
using Robust.Shared.ContentPack;
|
||||||
@@ -29,7 +31,7 @@ public sealed class DecalPainter
|
|||||||
_sPrototypeManager = server.ResolveDependency<IPrototypeManager>();
|
_sPrototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(Image canvas, Span<DecalData> decals)
|
public void Run(Image canvas, Span<DecalData> decals, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@@ -46,13 +48,13 @@ public sealed class DecalPainter
|
|||||||
|
|
||||||
foreach (var decal in decals)
|
foreach (var decal in decals)
|
||||||
{
|
{
|
||||||
Run(canvas, decal);
|
Run(canvas, decal, customOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"{nameof(DecalPainter)} painted {decals.Length} decals in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
Console.WriteLine($"{nameof(DecalPainter)} painted {decals.Length} decals in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Run(Image canvas, DecalData data)
|
private void Run(Image canvas, DecalData data, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
var decal = data.Decal;
|
var decal = data.Decal;
|
||||||
if (!_decalTextures.TryGetValue(decal.Id, out var sprite))
|
if (!_decalTextures.TryGetValue(decal.Id, out var sprite))
|
||||||
@@ -94,8 +96,10 @@ public sealed class DecalPainter
|
|||||||
.DrawImage(coloredImage, PixelColorBlendingMode.Multiply, PixelAlphaCompositionMode.SrcAtop, 1.0f)
|
.DrawImage(coloredImage, PixelColorBlendingMode.Multiply, PixelAlphaCompositionMode.SrcAtop, 1.0f)
|
||||||
.Flip(FlipMode.Vertical));
|
.Flip(FlipMode.Vertical));
|
||||||
|
|
||||||
// Very unsure why the - 1 is needed in the first place but all decals are off by exactly one pixel otherwise
|
var pointX = (int) data.X + (int) (customOffset.X * EyeManager.PixelsPerMeter);
|
||||||
|
var pointY = (int) data.Y + (int) (customOffset.Y * EyeManager.PixelsPerMeter);
|
||||||
|
|
||||||
// Woohoo!
|
// Woohoo!
|
||||||
canvas.Mutate(o => o.DrawImage(image, new Point((int) data.X, (int) data.Y - 1), alpha));
|
canvas.Mutate(o => o.DrawImage(image, new Point(pointX, pointY), alpha));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
@@ -32,7 +33,7 @@ public sealed class EntityPainter
|
|||||||
_errorImage = Image.Load<Rgba32>(_resManager.ContentFileRead("/Textures/error.rsi/error.png"));
|
_errorImage = Image.Load<Rgba32>(_resManager.ContentFileRead("/Textures/error.rsi/error.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(Image canvas, List<EntityData> entities)
|
public void Run(Image canvas, List<EntityData> entities, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@@ -43,13 +44,13 @@ public sealed class EntityPainter
|
|||||||
|
|
||||||
foreach (var entity in entities)
|
foreach (var entity in entities)
|
||||||
{
|
{
|
||||||
Run(canvas, entity, xformSystem);
|
Run(canvas, entity, xformSystem, customOffset);;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"{nameof(EntityPainter)} painted {entities.Count} entities in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
Console.WriteLine($"{nameof(EntityPainter)} painted {entities.Count} entities in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(Image canvas, EntityData entity, SharedTransformSystem xformSystem)
|
public void Run(Image canvas, EntityData entity, SharedTransformSystem xformSystem, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
if (!entity.Sprite.Visible || entity.Sprite.ContainerOccluded)
|
if (!entity.Sprite.Visible || entity.Sprite.ContainerOccluded)
|
||||||
{
|
{
|
||||||
@@ -135,8 +136,8 @@ public sealed class EntityPainter
|
|||||||
coloredImage.Mutate(o => o.BackgroundColor(imageColor));
|
coloredImage.Mutate(o => o.BackgroundColor(imageColor));
|
||||||
|
|
||||||
var (imgX, imgY) = rsi?.Size ?? (EyeManager.PixelsPerMeter, EyeManager.PixelsPerMeter);
|
var (imgX, imgY) = rsi?.Size ?? (EyeManager.PixelsPerMeter, EyeManager.PixelsPerMeter);
|
||||||
var offsetX = (int) (entity.Sprite.Offset.X * EyeManager.PixelsPerMeter);
|
var offsetX = (int) (entity.Sprite.Offset.X + customOffset.X) * EyeManager.PixelsPerMeter;
|
||||||
var offsetY = (int) (entity.Sprite.Offset.Y * EyeManager.PixelsPerMeter);
|
var offsetY = (int) (entity.Sprite.Offset.Y + customOffset.X) * EyeManager.PixelsPerMeter;
|
||||||
image.Mutate(o => o
|
image.Mutate(o => o
|
||||||
.DrawImage(coloredImage, PixelColorBlendingMode.Multiply, PixelAlphaCompositionMode.SrcAtop, 1)
|
.DrawImage(coloredImage, PixelColorBlendingMode.Multiply, PixelAlphaCompositionMode.SrcAtop, 1)
|
||||||
.Resize(imgX, imgY)
|
.Resize(imgX, imgY)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace Content.MapRenderer.Painters
|
|||||||
_decals = GetDecals();
|
_decals = GetDecals();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid)
|
public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@@ -56,10 +56,10 @@ namespace Content.MapRenderer.Painters
|
|||||||
|
|
||||||
// Decals are always painted before entities, and are also optional.
|
// Decals are always painted before entities, and are also optional.
|
||||||
if (_decals.TryGetValue(gridUid, out var decals))
|
if (_decals.TryGetValue(gridUid, out var decals))
|
||||||
_decalPainter.Run(gridCanvas, CollectionsMarshal.AsSpan(decals));
|
_decalPainter.Run(gridCanvas, CollectionsMarshal.AsSpan(decals), customOffset);
|
||||||
|
|
||||||
|
|
||||||
_entityPainter.Run(gridCanvas, entities);
|
_entityPainter.Run(gridCanvas, entities, customOffset);
|
||||||
Console.WriteLine($"{nameof(GridPainter)} painted grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
Console.WriteLine($"{nameof(GridPainter)} painted grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.IntegrationTests;
|
using Content.IntegrationTests;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.Maps;
|
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
|
using Robust.Shared.EntitySerialization;
|
||||||
|
using Robust.Shared.EntitySerialization.Systems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
|
using Robust.Shared.Map.Events;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
@@ -22,7 +26,9 @@ namespace Content.MapRenderer.Painters
|
|||||||
{
|
{
|
||||||
public sealed class MapPainter
|
public sealed class MapPainter
|
||||||
{
|
{
|
||||||
public static async IAsyncEnumerable<RenderedGridImage<Rgba32>> Paint(string map)
|
public static async IAsyncEnumerable<RenderedGridImage<Rgba32>> Paint(string map,
|
||||||
|
bool mapIsFilename = false,
|
||||||
|
bool showMarkers = false)
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@@ -33,7 +39,7 @@ namespace Content.MapRenderer.Painters
|
|||||||
Connected = true,
|
Connected = true,
|
||||||
Fresh = true,
|
Fresh = true,
|
||||||
// Seriously whoever made MapPainter use GameMapPrototype I wish you step on a lego one time.
|
// Seriously whoever made MapPainter use GameMapPrototype I wish you step on a lego one time.
|
||||||
Map = map,
|
Map = mapIsFilename ? "Empty" : map,
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = pair.Server;
|
var server = pair.Server;
|
||||||
@@ -54,9 +60,89 @@ namespace Content.MapRenderer.Painters
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (showMarkers)
|
||||||
|
await pair.WaitClientCommand("showmarkers");
|
||||||
|
|
||||||
var sEntityManager = server.ResolveDependency<IServerEntityManager>();
|
var sEntityManager = server.ResolveDependency<IServerEntityManager>();
|
||||||
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
|
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
|
||||||
|
|
||||||
|
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||||
|
var mapLoader = entityManager.System<MapLoaderSystem>();
|
||||||
|
var mapSys = entityManager.System<SharedMapSystem>();
|
||||||
|
var deps = server.ResolveDependency<IEntitySystemManager>().DependencyCollection;
|
||||||
|
|
||||||
|
Entity<MapGridComponent>[] grids = [];
|
||||||
|
|
||||||
|
if (mapIsFilename)
|
||||||
|
{
|
||||||
|
var resPath = new ResPath(map);
|
||||||
|
|
||||||
|
if (!mapLoader.TryReadFile(resPath, out var data))
|
||||||
|
throw new IOException($"File {map} could not be read");
|
||||||
|
|
||||||
|
var ev = new BeforeEntityReadEvent();
|
||||||
|
server.EntMan.EventBus.RaiseEvent(EventSource.Local, ev);
|
||||||
|
|
||||||
|
var deserializer = new EntityDeserializer(deps,
|
||||||
|
data,
|
||||||
|
DeserializationOptions.Default,
|
||||||
|
ev.RenamedPrototypes,
|
||||||
|
ev.DeletedPrototypes);
|
||||||
|
|
||||||
|
if (!deserializer.TryProcessData())
|
||||||
|
{
|
||||||
|
throw new IOException($"Failed to process entity data in {map}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deserializer.Result.Category == FileCategory.Unknown && deserializer.Result.Version < 7)
|
||||||
|
{
|
||||||
|
var mapCount = 0;
|
||||||
|
var gridCount = 0;
|
||||||
|
foreach (var (entId, ent) in deserializer.YamlEntities)
|
||||||
|
{
|
||||||
|
if (ent.Components != null && ent.Components.ContainsKey("MapGrid"))
|
||||||
|
{
|
||||||
|
gridCount++;
|
||||||
|
}
|
||||||
|
if (ent.Components != null && ent.Components.ContainsKey("Map"))
|
||||||
|
{
|
||||||
|
mapCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mapCount == 1)
|
||||||
|
deserializer.Result.Category = FileCategory.Map;
|
||||||
|
else if (mapCount == 0 && gridCount == 1)
|
||||||
|
deserializer.Result.Category = FileCategory.Grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (deserializer.Result.Category)
|
||||||
|
{
|
||||||
|
case FileCategory.Map:
|
||||||
|
await server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
if (mapLoader.TryLoadMap(resPath, out _, out var loadedGrids))
|
||||||
|
{
|
||||||
|
grids = loadedGrids.ToArray();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileCategory.Grid:
|
||||||
|
await server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
if (mapLoader.TryLoadGrid(resPath, out _, out var loadedGrids))
|
||||||
|
{
|
||||||
|
grids = [(Entity<MapGridComponent>)loadedGrids];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IOException($"Unknown category {deserializer.Result.Category}");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await pair.RunTicksSync(10);
|
await pair.RunTicksSync(10);
|
||||||
await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync());
|
await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync());
|
||||||
|
|
||||||
@@ -64,7 +150,6 @@ namespace Content.MapRenderer.Painters
|
|||||||
|
|
||||||
var tilePainter = new TilePainter(client, server);
|
var tilePainter = new TilePainter(client, server);
|
||||||
var entityPainter = new GridPainter(client, server);
|
var entityPainter = new GridPainter(client, server);
|
||||||
Entity<MapGridComponent>[] grids = null!;
|
|
||||||
var xformQuery = sEntityManager.GetEntityQuery<TransformComponent>();
|
var xformQuery = sEntityManager.GetEntityQuery<TransformComponent>();
|
||||||
var xformSystem = sEntityManager.System<SharedTransformSystem>();
|
var xformSystem = sEntityManager.System<SharedTransformSystem>();
|
||||||
|
|
||||||
@@ -77,8 +162,11 @@ namespace Content.MapRenderer.Painters
|
|||||||
sEntityManager.DeleteEntity(playerEntity.Value);
|
sEntityManager.DeleteEntity(playerEntity.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapId = sEntityManager.System<GameTicker>().DefaultMap;
|
if (!mapIsFilename)
|
||||||
grids = sMapManager.GetAllGrids(mapId).ToArray();
|
{
|
||||||
|
var mapId = sEntityManager.System<GameTicker>().DefaultMap;
|
||||||
|
grids = sMapManager.GetAllGrids(mapId).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var (uid, _) in grids)
|
foreach (var (uid, _) in grids)
|
||||||
{
|
{
|
||||||
@@ -92,32 +180,33 @@ namespace Content.MapRenderer.Painters
|
|||||||
|
|
||||||
foreach (var (uid, grid) in grids)
|
foreach (var (uid, grid) in grids)
|
||||||
{
|
{
|
||||||
// Skip empty grids
|
var tiles = mapSys.GetAllTiles(uid, grid).ToList();
|
||||||
if (grid.LocalAABB.IsEmpty())
|
if (tiles.Count == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Warning: Grid {uid} was empty. Skipping image rendering.");
|
Console.WriteLine($"Warning: Grid {uid} was empty. Skipping image rendering.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tileXSize = grid.TileSize * TilePainter.TileImageSize;
|
var tileXSize = grid.TileSize * TilePainter.TileImageSize;
|
||||||
var tileYSize = grid.TileSize * TilePainter.TileImageSize;
|
var tileYSize = grid.TileSize * TilePainter.TileImageSize;
|
||||||
|
|
||||||
var bounds = grid.LocalAABB;
|
var minX = tiles.Min(t => t.X);
|
||||||
|
var minY = tiles.Min(t => t.Y);
|
||||||
|
var maxX = tiles.Max(t => t.X);
|
||||||
|
var maxY = tiles.Max(t => t.Y);
|
||||||
|
var w = (maxX - minX + 1) * tileXSize;
|
||||||
|
var h = (maxY - minY + 1) * tileYSize;
|
||||||
|
var customOffset = new Vector2();
|
||||||
|
|
||||||
var left = bounds.Left;
|
//MapGrids don't have LocalAABB, so we offset them to align the bottom left corner with 0,0 coordinates
|
||||||
var right = bounds.Right;
|
if (grid.LocalAABB.IsEmpty())
|
||||||
var top = bounds.Top;
|
customOffset = new Vector2(-minX, -minY);
|
||||||
var bottom = bounds.Bottom;
|
|
||||||
|
|
||||||
var w = (int) Math.Ceiling(right - left) * tileXSize;
|
|
||||||
var h = (int) Math.Ceiling(top - bottom) * tileYSize;
|
|
||||||
|
|
||||||
var gridCanvas = new Image<Rgba32>(w, h);
|
var gridCanvas = new Image<Rgba32>(w, h);
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
tilePainter.Run(gridCanvas, uid, grid);
|
tilePainter.Run(gridCanvas, uid, grid, customOffset);
|
||||||
entityPainter.Run(gridCanvas, uid, grid);
|
entityPainter.Run(gridCanvas, uid, grid, customOffset);
|
||||||
|
|
||||||
gridCanvas.Mutate(e => e.Flip(FlipMode.Vertical));
|
gridCanvas.Mutate(e => e.Flip(FlipMode.Vertical));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Shared.ContentPack;
|
using Robust.Shared.ContentPack;
|
||||||
@@ -31,7 +32,7 @@ namespace Content.MapRenderer.Painters
|
|||||||
_sMapSystem = esm.GetEntitySystem<SharedMapSystem>();
|
_sMapSystem = esm.GetEntitySystem<SharedMapSystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid)
|
public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid, Vector2 customOffset = default)
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
@@ -51,8 +52,8 @@ namespace Content.MapRenderer.Painters
|
|||||||
if (string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var x = (int) (tile.X + xOffset);
|
var x = (int) (tile.X + xOffset + customOffset.X);
|
||||||
var y = (int) (tile.Y + yOffset);
|
var y = (int) (tile.Y + yOffset + customOffset.Y);
|
||||||
var image = images[path][tile.Tile.Variant];
|
var image = images[path][tile.Tile.Variant];
|
||||||
|
|
||||||
gridCanvas.Mutate(o => o.DrawImage(image, new Point(x * tileSize, y * tileSize), 1));
|
gridCanvas.Mutate(o => o.DrawImage(image, new Point(x * tileSize, y * tileSize), 1));
|
||||||
@@ -93,7 +94,7 @@ namespace Content.MapRenderer.Painters
|
|||||||
for (var i = 0; i < definition.Variants; i++)
|
for (var i = 0; i < definition.Variants; i++)
|
||||||
{
|
{
|
||||||
var index = i;
|
var index = i;
|
||||||
var tileImage = tileSheet.Clone(o => o.Crop(new Rectangle(tileSize * index, 0, 32, 32)));
|
var tileImage = tileSheet.Clone(o => o.Crop(new Rectangle(tileSize * index, 0, 32, 32)).Flip(FlipMode.Vertical));
|
||||||
images[path].Add(tileImage);
|
images[path].Add(tileImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,34 +106,7 @@ namespace Content.MapRenderer
|
|||||||
|
|
||||||
if (arguments.ArgumentsAreFileNames)
|
if (arguments.ArgumentsAreFileNames)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Retrieving map ids by map file names...");
|
Console.WriteLine("Retrieving maps by file names...");
|
||||||
|
|
||||||
Console.Write("Fetching map prototypes... ");
|
|
||||||
await using var pair = await PoolManager.GetServerClient();
|
|
||||||
var mapPrototypes = pair.Server
|
|
||||||
.ResolveDependency<IPrototypeManager>()
|
|
||||||
.EnumeratePrototypes<GameMapPrototype>()
|
|
||||||
.ToArray();
|
|
||||||
Console.WriteLine("[Done]");
|
|
||||||
|
|
||||||
var ids = new List<string>();
|
|
||||||
|
|
||||||
foreach (var mapPrototype in mapPrototypes)
|
|
||||||
{
|
|
||||||
if (arguments.Maps.Contains(mapPrototype.MapPath.Filename))
|
|
||||||
{
|
|
||||||
ids.Add(mapPrototype.ID);
|
|
||||||
Console.WriteLine($"Found map: {mapPrototype.MapName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ids.Count == 0)
|
|
||||||
{
|
|
||||||
await Console.Error.WriteLineAsync("Found no maps for the given file names!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
arguments.Maps = ids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Run(arguments);
|
await Run(arguments);
|
||||||
@@ -156,12 +129,14 @@ namespace Content.MapRenderer
|
|||||||
};
|
};
|
||||||
|
|
||||||
mapViewerData.ParallaxLayers.Add(LayerGroup.DefaultParallax());
|
mapViewerData.ParallaxLayers.Add(LayerGroup.DefaultParallax());
|
||||||
var directory = Path.Combine(arguments.OutputPath, map);
|
var directory = Path.Combine(arguments.OutputPath, Path.GetFileNameWithoutExtension(map));
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await foreach (var renderedGrid in MapPainter.Paint(map))
|
await foreach (var renderedGrid in MapPainter.Paint(map,
|
||||||
|
arguments.ArgumentsAreFileNames,
|
||||||
|
arguments.ShowMarkers))
|
||||||
{
|
{
|
||||||
var grid = renderedGrid.Image;
|
var grid = renderedGrid.Image;
|
||||||
Directory.CreateDirectory(directory);
|
Directory.CreateDirectory(directory);
|
||||||
|
|||||||
Reference in New Issue
Block a user