* Use new Subs.CVar helper Removes manual config OnValueChanged calls, removes need to remember to manually unsubscribe. This both reduces boilerplate and fixes many issues where subscriptions weren't removed on entity system shutdown. * Fix a bunch of warnings * More warning fixes * Use new DateTime serializer to get rid of ISerializationHooks in changelog code. * Get rid of some more ISerializationHooks for enums * And a little more * Apply suggestions from code review Co-authored-by: 0x6273 <0x40@keemail.me> --------- Co-authored-by: 0x6273 <0x40@keemail.me>
107 lines
3.8 KiB
C#
107 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.ResourceManagement;
|
|
using Robust.Shared.ContentPack;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Timing;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using static Robust.UnitTesting.RobustIntegrationTest;
|
|
|
|
namespace Content.MapRenderer.Painters
|
|
{
|
|
public sealed class TilePainter
|
|
{
|
|
public const int TileImageSize = EyeManager.PixelsPerMeter;
|
|
|
|
private readonly ITileDefinitionManager _sTileDefinitionManager;
|
|
private readonly SharedMapSystem _sMapSystem;
|
|
private readonly IResourceManager _resManager;
|
|
|
|
public TilePainter(ClientIntegrationInstance client, ServerIntegrationInstance server)
|
|
{
|
|
_sTileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
|
|
_resManager = client.ResolveDependency<IResourceManager>();
|
|
var esm = server.ResolveDependency<IEntitySystemManager>();
|
|
_sMapSystem = esm.GetEntitySystem<SharedMapSystem>();
|
|
}
|
|
|
|
public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid)
|
|
{
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
|
|
var bounds = grid.LocalAABB;
|
|
var xOffset = -bounds.Left;
|
|
var yOffset = -bounds.Bottom;
|
|
var tileSize = grid.TileSize * TileImageSize;
|
|
|
|
var images = GetTileImages(_sTileDefinitionManager, _resManager, tileSize);
|
|
var i = 0;
|
|
|
|
_sMapSystem.GetAllTiles(gridUid, grid).AsParallel().ForAll(tile =>
|
|
{
|
|
var path = _sTileDefinitionManager[tile.Tile.TypeId].Sprite.ToString();
|
|
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
return;
|
|
|
|
var x = (int) (tile.X + xOffset);
|
|
var y = (int) (tile.Y + yOffset);
|
|
var image = images[path][tile.Tile.Variant];
|
|
|
|
gridCanvas.Mutate(o => o.DrawImage(image, new Point(x * tileSize, y * tileSize), 1));
|
|
|
|
i++;
|
|
});
|
|
|
|
Console.WriteLine($"{nameof(TilePainter)} painted {i} tiles on grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
|
}
|
|
|
|
private Dictionary<string, List<Image>> GetTileImages(
|
|
ITileDefinitionManager tileDefinitionManager,
|
|
IResourceManager resManager,
|
|
int tileSize)
|
|
{
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
|
|
var images = new Dictionary<string, List<Image>>();
|
|
|
|
foreach (var definition in tileDefinitionManager)
|
|
{
|
|
var path = definition.Sprite.ToString();
|
|
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
continue;
|
|
|
|
images[path] = new List<Image>(definition.Variants);
|
|
|
|
using var stream = resManager.ContentFileRead(path);
|
|
Image tileSheet = Image.Load<Rgba32>(stream);
|
|
|
|
if (tileSheet.Width != tileSize * definition.Variants || tileSheet.Height != tileSize)
|
|
{
|
|
throw new NotSupportedException($"Unable to use tiles with a dimension other than {tileSize}x{tileSize}.");
|
|
}
|
|
|
|
for (var i = 0; i < definition.Variants; i++)
|
|
{
|
|
var index = i;
|
|
var tileImage = tileSheet.Clone(o => o.Crop(new Rectangle(tileSize * index, 0, 32, 32)));
|
|
images[path].Add(tileImage);
|
|
}
|
|
}
|
|
|
|
Console.WriteLine($"Indexed all tile images in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");
|
|
|
|
return images;
|
|
}
|
|
}
|
|
}
|