Merge pull request #4391 from pchote/rectangular-tiles

Add support for TS terrain sprites and non-square cell sizes.
This commit is contained in:
Matthias Mailänder
2013-12-29 14:34:52 -08:00
21 changed files with 234 additions and 73 deletions

View File

@@ -11,11 +11,16 @@ NEW:
Converted production exits to world coordinates.
Converted weapon projectiles to world coordinates.
Converted actor speed to world coordinates.
Added support for rectangular cells with forced perspective.
Added initial support for Tmp(TS) sprites.
Asset Browser:
Filenames are now listed in alphabetical order
Mod / Custom map compatibility:
Altitude is no longer parsed from actor templates in maps. Specify CenterPosition instead.
Run `OpenRA.Utility.exe --upgrade-mod <mod> 20131223` to automatically upgrade mod rules.
Run `OpenRA.Utility.exe --upgrade-map <map path> 20131223` to automatically upgrade custom map rules.
Added a new trait Demolishable for buildings to handle the C4 demolition.
Mods that use custom TileSize must specify both width and height.
20131223:
All mods:

View File

@@ -63,8 +63,8 @@ namespace OpenRA.Editor
public void Preview(Surface surface, SGraphics g)
{
g.DrawImage(brushTemplate.Bitmap,
surface.TileSetRenderer.TileSize.Width * surface.GetBrushLocation().X * surface.Zoom + surface.GetOffset().X,
surface.TileSetRenderer.TileSize.Height * surface.GetBrushLocation().Y * surface.Zoom + surface.GetOffset().Y,
surface.TileSetRenderer.TileSize * surface.GetBrushLocation().X * surface.Zoom + surface.GetOffset().X,
surface.TileSetRenderer.TileSize * surface.GetBrushLocation().Y * surface.Zoom + surface.GetOffset().Y,
brushTemplate.Bitmap.Width * surface.Zoom,
brushTemplate.Bitmap.Height * surface.Zoom);
}

View File

@@ -145,7 +145,7 @@ namespace OpenRA.Editor
{
Rules.LoadRules(manifest, map);
tileset = Rules.TileSets[map.Tileset];
tilesetRenderer = new TileSetRenderer(tileset, new Size(manifest.TileSize, manifest.TileSize));
tilesetRenderer = new TileSetRenderer(tileset, manifest.TileSize);
var shadowIndex = new int[] { 3, 4 };
var palette = new Palette(FileSystem.Open(tileset.Palette), shadowIndex);

View File

@@ -257,7 +257,7 @@ namespace OpenRA.Editor
Bitmap RenderChunk(int u, int v)
{
var bitmap = new Bitmap(ChunkSize * TileSetRenderer.TileSize.Width, ChunkSize * TileSetRenderer.TileSize.Height);
var bitmap = new Bitmap(ChunkSize * TileSetRenderer.TileSize, ChunkSize * TileSetRenderer.TileSize);
var data = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
@@ -274,9 +274,9 @@ namespace OpenRA.Editor
var tile = TileSetRenderer.Data(tr.Type);
var index = (tr.Index < tile.Count) ? tr.Index : (byte)0;
var rawImage = tile[index];
for (var x = 0; x < TileSetRenderer.TileSize.Width; x++)
for (var y = 0; y < TileSetRenderer.TileSize.Height; y++)
p[(j * TileSetRenderer.TileSize.Width + y) * stride + i * TileSetRenderer.TileSize.Width + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize.Width * y]).ToArgb();
for (var x = 0; x < TileSetRenderer.TileSize; x++)
for (var y = 0; y < TileSetRenderer.TileSize; y++)
p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize * y]).ToArgb();
if (Map.MapResources.Value[u * ChunkSize + i, v * ChunkSize + j].Type != 0)
{
@@ -287,12 +287,12 @@ namespace OpenRA.Editor
int* q = (int*)srcdata.Scan0.ToPointer();
var srcstride = srcdata.Stride >> 2;
for (var x = 0; x < TileSetRenderer.TileSize.Width; x++)
for (var y = 0; y < TileSetRenderer.TileSize.Height; y++)
for (var x = 0; x < TileSetRenderer.TileSize; x++)
for (var y = 0; y < TileSetRenderer.TileSize; y++)
{
var c = q[y * srcstride + x];
if ((c & 0xff000000) != 0) /* quick & dirty, i cbf doing real alpha */
p[(j * TileSetRenderer.TileSize.Width + y) * stride + i * TileSetRenderer.TileSize.Width + x] = c;
p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = c;
}
resourceImage.UnlockBits(srcdata);
@@ -303,14 +303,16 @@ namespace OpenRA.Editor
bitmap.UnlockBits(data);
if (ShowGrid)
{
using (var g = SGraphics.FromImage(bitmap))
{
var ts = Game.modData.Manifest.TileSize;
var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
ControlPaint.DrawGrid(g, rect, new Size(2, Game.CellSize), Color.DarkRed);
ControlPaint.DrawGrid(g, rect, new Size(Game.CellSize, 2), Color.DarkRed);
ControlPaint.DrawGrid(g, rect, new Size(Game.CellSize, Game.CellSize), Color.Red);
ControlPaint.DrawGrid(g, rect, new Size(2, ts.Height), Color.DarkRed);
ControlPaint.DrawGrid(g, rect, new Size(ts.Width, 2), Color.DarkRed);
ControlPaint.DrawGrid(g, rect, new Size(ts.Width, ts.Height), Color.Red);
}
}
return bitmap;
}
@@ -318,15 +320,15 @@ namespace OpenRA.Editor
{
var vX = (int)Math.Floor((mousePos.X - Offset.X) / Zoom);
var vY = (int)Math.Floor((mousePos.Y - Offset.Y) / Zoom);
return new CPos(vX / TileSetRenderer.TileSize.Width, vY / TileSetRenderer.TileSize.Height);
return new CPos(vX / TileSetRenderer.TileSize, vY / TileSetRenderer.TileSize);
}
public CPos GetBrushLocationBR()
{
var vX = (int)Math.Floor((mousePos.X - Offset.X) / Zoom);
var vY = (int)Math.Floor((mousePos.Y - Offset.Y) / Zoom);
return new CPos((vX + TileSetRenderer.TileSize.Width - 1) / TileSetRenderer.TileSize.Width,
(vY + TileSetRenderer.TileSize.Height - 1) / TileSetRenderer.TileSize.Height);
return new CPos((vX + TileSetRenderer.TileSize - 1) / TileSetRenderer.TileSize,
(vY + TileSetRenderer.TileSize - 1) / TileSetRenderer.TileSize);
}
public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp)
@@ -340,11 +342,11 @@ namespace OpenRA.Editor
float2 GetDrawPosition(CPos location, Bitmap bmp, bool centered)
{
float offsetX = centered ? bmp.Width / 2 - TileSetRenderer.TileSize.Width / 2 : 0;
float drawX = TileSetRenderer.TileSize.Width * location.X * Zoom + Offset.X - offsetX;
float offsetX = centered ? bmp.Width / 2 - TileSetRenderer.TileSize / 2 : 0;
float drawX = TileSetRenderer.TileSize * location.X * Zoom + Offset.X - offsetX;
float offsetY = centered ? bmp.Height / 2 - TileSetRenderer.TileSize.Height / 2 : 0;
float drawY = TileSetRenderer.TileSize.Height * location.Y * Zoom + Offset.Y - offsetY;
float offsetY = centered ? bmp.Height / 2 - TileSetRenderer.TileSize / 2 : 0;
float drawY = TileSetRenderer.TileSize * location.Y * Zoom + Offset.Y - offsetY;
return new float2(drawX, drawY);
}
@@ -412,24 +414,24 @@ namespace OpenRA.Editor
var bmp = Chunks[x];
var drawX = TileSetRenderer.TileSize.Width * (float)ChunkSize * (float)x.X * Zoom + Offset.X;
var drawY = TileSetRenderer.TileSize.Height * (float)ChunkSize * (float)x.Y * Zoom + Offset.Y;
var drawX = TileSetRenderer.TileSize * (float)ChunkSize * (float)x.X * Zoom + Offset.X;
var drawY = TileSetRenderer.TileSize * (float)ChunkSize * (float)x.Y * Zoom + Offset.Y;
RectangleF sourceRect = new RectangleF(0, 0, bmp.Width, bmp.Height);
RectangleF destRect = new RectangleF(drawX, drawY, bmp.Width * Zoom, bmp.Height * Zoom);
e.Graphics.DrawImage(bmp, destRect, sourceRect, GraphicsUnit.Pixel);
}
e.Graphics.DrawRectangle(CordonPen,
Map.Bounds.Left * TileSetRenderer.TileSize.Width * Zoom + Offset.X,
Map.Bounds.Top * TileSetRenderer.TileSize.Height * Zoom + Offset.Y,
Map.Bounds.Width * TileSetRenderer.TileSize.Width * Zoom,
Map.Bounds.Height * TileSetRenderer.TileSize.Height * Zoom);
Map.Bounds.Left * TileSetRenderer.TileSize * Zoom + Offset.X,
Map.Bounds.Top * TileSetRenderer.TileSize * Zoom + Offset.Y,
Map.Bounds.Width * TileSetRenderer.TileSize * Zoom,
Map.Bounds.Height * TileSetRenderer.TileSize * Zoom);
e.Graphics.DrawRectangle(SelectionPen,
(SelectionStart.X * TileSetRenderer.TileSize.Width * Zoom) + Offset.X,
(SelectionStart.Y * TileSetRenderer.TileSize.Height * Zoom) + Offset.Y,
(SelectionEnd - SelectionStart).X * TileSetRenderer.TileSize.Width * Zoom,
(SelectionEnd - SelectionStart).Y * TileSetRenderer.TileSize.Height * Zoom);
(SelectionStart.X * TileSetRenderer.TileSize * Zoom) + Offset.X,
(SelectionStart.Y * TileSetRenderer.TileSize * Zoom) + Offset.Y,
(SelectionEnd - SelectionStart).X * TileSetRenderer.TileSize * Zoom,
(SelectionEnd - SelectionStart).Y * TileSetRenderer.TileSize * Zoom);
if (IsPaste)
{
@@ -438,10 +440,10 @@ namespace OpenRA.Editor
var height = Math.Abs((SelectionStart - SelectionEnd).Y);
e.Graphics.DrawRectangle(PastePen,
(loc.X * TileSetRenderer.TileSize.Width * Zoom) + Offset.X,
(loc.Y * TileSetRenderer.TileSize.Height * Zoom) + Offset.Y,
width * (TileSetRenderer.TileSize.Width * Zoom),
height * (TileSetRenderer.TileSize.Height * Zoom));
(loc.X * TileSetRenderer.TileSize * Zoom) + Offset.X,
(loc.Y * TileSetRenderer.TileSize * Zoom) + Offset.Y,
width * (TileSetRenderer.TileSize * Zoom),
height * (TileSetRenderer.TileSize * Zoom));
}
foreach (var ar in Map.Actors.Value)
@@ -457,8 +459,8 @@ namespace OpenRA.Editor
foreach (var ar in Map.Actors.Value)
if (!ar.Key.StartsWith("Actor")) // if it has a custom name
e.Graphics.DrawStringContrast(Font, ar.Key,
(int)(ar.Value.Location().X * TileSetRenderer.TileSize.Width * Zoom + Offset.X),
(int)(ar.Value.Location().Y * TileSetRenderer.TileSize.Height * Zoom + Offset.Y),
(int)(ar.Value.Location().X * TileSetRenderer.TileSize * Zoom + Offset.X),
(int)(ar.Value.Location().Y * TileSetRenderer.TileSize * Zoom + Offset.Y),
Brushes.White,
Brushes.Black);
@@ -468,7 +470,7 @@ namespace OpenRA.Editor
{
if (i % 8 == 0)
{
PointF point = new PointF(i * TileSetRenderer.TileSize.Width * Zoom + Offset.X, (Map.Bounds.Top - 8) * TileSetRenderer.TileSize.Height * Zoom + Offset.Y);
PointF point = new PointF(i * TileSetRenderer.TileSize * Zoom + Offset.X, (Map.Bounds.Top - 8) * TileSetRenderer.TileSize * Zoom + Offset.Y);
e.Graphics.DrawString((i - Map.Bounds.Left).ToString(), MarkerFont, TextBrush, point);
}
}
@@ -477,7 +479,7 @@ namespace OpenRA.Editor
{
if (i % 8 == 0)
{
PointF point = new PointF((Map.Bounds.Left - 8) * TileSetRenderer.TileSize.Width * Zoom + Offset.X, i * TileSetRenderer.TileSize.Height * Zoom + Offset.Y);
PointF point = new PointF((Map.Bounds.Left - 8) * TileSetRenderer.TileSize * Zoom + Offset.X, i * TileSetRenderer.TileSize * Zoom + Offset.Y);
e.Graphics.DrawString((i - Map.Bounds.Left).ToString(), MarkerFont, TextBrush, point);
}
}

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
@@ -21,7 +22,27 @@ namespace OpenRA.Editor
{
public TileSet TileSet;
Dictionary<ushort, List<byte[]>> templates;
public Size TileSize;
public readonly int TileSize;
// Extract a square tile that the editor can render
byte[] ExtractSquareTile(ISpriteFrame frame)
{
var data = new byte[TileSize * TileSize];
// Invalid tile size: return blank tile
if (frame.Size.Width < TileSize || frame.Size.Height < TileSize)
return data;
var frameData = frame.Data;
var xOffset = (frame.Size.Width - TileSize) / 2;
var yOffset = (frame.Size.Height - TileSize) / 2;
for (var y = 0; y < TileSize; y++)
for (var x = 0; x < TileSize; x++)
data[y * TileSize + x] = frameData[(yOffset + y) * frame.Size.Width + x + xOffset];
return data;
}
List<byte[]> LoadTemplate(string filename, string[] exts, Dictionary<string, ISpriteSource> sourceCache, int[] frames)
{
@@ -42,18 +63,18 @@ namespace OpenRA.Editor
var ret = new List<byte[]>();
var srcFrames = source.Frames.ToArray();
foreach (var i in frames)
ret.Add(srcFrames[i].Data);
ret.Add(ExtractSquareTile(srcFrames[i]));
return ret;
}
return source.Frames.Select(f => f.Data).ToList();
return source.Frames.Select(f => ExtractSquareTile(f)).ToList();
}
public TileSetRenderer(TileSet tileset, Size tileSize)
{
this.TileSet = tileset;
this.TileSize = tileSize;
this.TileSize = Math.Min(tileSize.Width, tileSize.Height);
templates = new Dictionary<ushort, List<byte[]>>();
var sourceCache = new Dictionary<string, ISpriteSource>();
@@ -66,7 +87,7 @@ namespace OpenRA.Editor
var template = TileSet.Templates[id];
var templateData = templates[id];
var bitmap = new Bitmap(TileSize.Width * template.Size.X, TileSize.Height * template.Size.Y,
var bitmap = new Bitmap(TileSize * template.Size.X, TileSize * template.Size.Y,
PixelFormat.Format8bppIndexed);
bitmap.Palette = p.AsSystemPalette();
@@ -86,15 +107,15 @@ namespace OpenRA.Editor
var rawImage = templateData[u + v * template.Size.X];
if (rawImage != null && rawImage.Length > 0)
{
for (var i = 0; i < TileSize.Width; i++)
for (var j = 0; j < TileSize.Height; j++)
q[(v * TileSize.Width + j) * stride + u * TileSize.Width + i] = rawImage[i + TileSize.Width * j];
for (var i = 0; i < TileSize; i++)
for (var j = 0; j < TileSize; j++)
q[(v * TileSize + j) * stride + u * TileSize + i] = rawImage[i + TileSize * j];
}
else
{
for (var i = 0; i < TileSize.Width; i++)
for (var j = 0; j < TileSize.Height; j++)
q[(v * TileSize.Width + j) * stride + u * TileSize.Width + i] = 0;
for (var i = 0; i < TileSize; i++)
for (var j = 0; j < TileSize; j++)
q[(v * TileSize + j) * stride + u * TileSize + i] = 0;
}
}
}

View File

@@ -282,6 +282,12 @@ namespace OpenRA.FileFormats
return ret;
}
else if (fieldType == typeof(Size))
{
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return new Size(int.Parse(parts[0]), int.Parse(parts[1]));
}
else if (fieldType == typeof(int2))
{
var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

View File

@@ -29,7 +29,7 @@ namespace OpenRA.FileFormats
bool CacheWhenLoadingTileset { get; }
}
public enum SpriteType { Unknown, ShpTD, ShpTS, ShpD2, TmpTD, TmpRA, R8 }
public enum SpriteType { Unknown, ShpTD, ShpTS, ShpD2, TmpTD, TmpRA, TmpTS, R8 }
public static class SpriteSource
{
static bool IsTmpRA(Stream s)
@@ -57,6 +57,29 @@ namespace OpenRA.FileFormats
return a == 0 && b == 0x0D1AFFFF;
}
static bool IsTmpTS(Stream s)
{
var start = s.Position;
s.Position += 8;
var sx = s.ReadUInt32();
var sy = s.ReadUInt32();
// Find the first frame
var offset = s.ReadUInt32();
if (offset > s.Length - 52)
{
s.Position = start;
return false;
}
s.Position = offset + 12;
var test = s.ReadUInt32();
s.Position = start;
return test == sx * sy / 2 + 52;
}
static bool IsShpTS(Stream s)
{
var start = s.Position;
@@ -204,6 +227,9 @@ namespace OpenRA.FileFormats
if (IsTmpTD(s))
return SpriteType.TmpTD;
if (IsTmpTS(s))
return SpriteType.TmpTS;
if (IsShpD2(s))
return SpriteType.ShpD2;
@@ -225,6 +251,8 @@ namespace OpenRA.FileFormats
return new TmpRAReader(s);
case SpriteType.TmpTD:
return new TmpTDReader(s);
case SpriteType.TmpTS:
return new TmpTSReader(s);
case SpriteType.ShpD2:
return new ShpD2Reader(s);
case SpriteType.Unknown:

View File

@@ -0,0 +1,75 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
namespace OpenRA.FileFormats
{
public class TmpTSTile : ISpriteFrame
{
public Size Size { get; private set; }
public Size FrameSize { get { return Size; } }
public float2 Offset { get { return float2.Zero; } }
public byte[] Data { get; set; }
public TmpTSTile(Stream s, Size size)
{
Size = size;
// Ignore tile header for now
s.Position += 52;
Data = new byte[size.Width * size.Height];
// Unpack tile data
var width = 4;
for (var i = 0; i < size.Height; i++)
{
var start = i * size.Width + (size.Width - width) / 2;
for (var j = 0; j < width; j++)
Data[start + j] = s.ReadUInt8();
width += (i < size.Height / 2 - 1? 1 : -1) * 4;
}
// Ignore Z-data for now
// Ignore extra data for now
}
}
public class TmpTSReader : ISpriteSource
{
readonly List<TmpTSTile> tiles = new List<TmpTSTile>();
public IEnumerable<ISpriteFrame> Frames { get { return tiles.Cast<ISpriteFrame>(); } }
public bool CacheWhenLoadingTileset { get { return false; } }
public TmpTSReader(Stream s)
{
var templateWidth = s.ReadUInt32();
var templateHeight = s.ReadUInt32();
var tileWidth = s.ReadInt32();
var tileHeight = s.ReadInt32();
var size = new Size(tileWidth, tileHeight);
var offsets = new uint[templateWidth * templateHeight];
for (var i = 0; i < offsets.Length; i++)
offsets[i] = s.ReadUInt32();
for (var i = 0; i < offsets.Length; i++)
{
s.Position = offsets[i];
tiles.Add(new TmpTSTile(s, size));
}
}
}
}

View File

@@ -9,6 +9,7 @@
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
@@ -28,7 +29,7 @@ namespace OpenRA.FileFormats
public readonly MiniYaml LoadScreen;
public readonly MiniYaml LobbyDefaults;
public readonly Dictionary<string, Pair<string, int>> Fonts;
public readonly int TileSize = 24;
public readonly Size TileSize = new Size(24, 24);
public Manifest(string mod)
{
@@ -68,7 +69,7 @@ namespace OpenRA.FileFormats
int.Parse(x.Value.NodesDict["Size"].Value)));
if (yaml.ContainsKey("TileSize"))
TileSize = int.Parse(yaml["TileSize"].Value);
TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value);
// Allow inherited mods to import parent maps.
var compat = new List<string>();

View File

@@ -156,6 +156,7 @@
<Compile Include="FileSystem\Pak.cs" />
<Compile Include="CPos.cs" />
<Compile Include="CVec.cs" />
<Compile Include="Graphics\TmpTSReader.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

View File

@@ -27,8 +27,6 @@ namespace OpenRA
{
public static class Game
{
public static int CellSize { get { return modData.Manifest.TileSize; } }
public static MouseButtonPreference mouseButtonPreference = new MouseButtonPreference();
public static ModData modData;

View File

@@ -235,8 +235,8 @@ namespace OpenRA.Graphics
// Conversion between world and screen coordinates
public float2 ScreenPosition(WPos pos)
{
var c = Game.CellSize / 1024f;
return new float2(c * pos.X, c * (pos.Y - pos.Z));
var ts = Game.modData.Manifest.TileSize;
return new float2(ts.Width * pos.X / 1024f, ts.Height * (pos.Y - pos.Z) / 1024f);
}
public int2 ScreenPxPosition(WPos pos)
@@ -249,8 +249,8 @@ namespace OpenRA.Graphics
// For scaling vectors to pixel sizes in the voxel renderer
public float[] ScreenVector(WVec vec)
{
var c = Game.CellSize / 1024f;
return new float[] { c * vec.X, c * vec.Y, c * vec.Z, 1 };
var ts = Game.modData.Manifest.TileSize;
return new float[] { ts.Width * vec.X / 1024f, ts.Height * vec.Y / 1024f, ts.Height * vec.Z / 1024f, 1 };
}
public int2 ScreenPxOffset(WVec vec)
@@ -262,12 +262,14 @@ namespace OpenRA.Graphics
public float ScreenZPosition(WPos pos, int offset)
{
return (pos.Y + pos.Z + offset) * Game.CellSize / 1024f;
var ts = Game.modData.Manifest.TileSize;
return (pos.Y + pos.Z + offset) * ts.Height / 1024f;
}
public WPos Position(int2 screenPx)
{
return new WPos(1024 * screenPx.X / Game.CellSize, 1024 * screenPx.Y / Game.CellSize, 0);
var ts = Game.modData.Manifest.TileSize;
return new WPos(1024 * screenPx.X / ts.Width, 1024 * screenPx.Y / ts.Height, 0);
}
}
}

View File

@@ -36,8 +36,9 @@ namespace OpenRA.Traits
public ScreenMap(World world, ScreenMapInfo info)
{
this.info = info;
cols = world.Map.MapSize.X * Game.CellSize / info.BinSize + 1;
rows = world.Map.MapSize.Y * Game.CellSize / info.BinSize + 1;
var ts = Game.modData.Manifest.TileSize;
cols = world.Map.MapSize.X * ts.Width / info.BinSize + 1;
rows = world.Map.MapSize.Y * ts.Height / info.BinSize + 1;
frozen = new Cache<Player, Dictionary<FrozenActor, Rectangle>[]>(InitializeFrozenActors);
actors = new Dictionary<Actor, Rectangle>[rows * cols];

View File

@@ -95,9 +95,9 @@ namespace OpenRA.Mods.RA
// Synthesize unexplored tile if it isn't defined
if (!info.Index.Contains(0))
{
var size = new Size(Game.modData.Manifest.TileSize, Game.modData.Manifest.TileSize);
var data = Exts.MakeArray<byte>(size.Width * size.Height, _ => (byte)info.ShroudColor);
var s = Game.modData.SheetBuilder.Add(data, size);
var ts = Game.modData.Manifest.TileSize;
var data = Exts.MakeArray<byte>(ts.Width * ts.Height, _ => (byte)info.ShroudColor);
var s = Game.modData.SheetBuilder.Add(data, ts);
unexploredTile = new Sprite(s.sheet, s.bounds, s.offset, s.channel, info.ShroudBlend);
}
else

View File

@@ -181,7 +181,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
if (assetSource == null)
return;
var files = assetSource.AllFileNames();
var files = assetSource.AllFileNames().OrderBy(s => s);
foreach (var file in files)
{
if (AllowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture)))

View File

@@ -43,7 +43,8 @@ namespace OpenRA.Utility
static void ConvertPxToRange(ref string input, int scaleMult, int scaleDiv)
{
var value = int.Parse(input);
var world = value * 1024 * scaleMult / (scaleDiv * Game.CellSize);
var ts = Game.modData.Manifest.TileSize;
var world = value * 1024 * scaleMult / (scaleDiv * ts.Height);
var cells = world / 1024;
var subcells = world - 1024 * cells;
@@ -59,7 +60,8 @@ namespace OpenRA.Utility
static void ConvertInt2ToWVec(ref string input)
{
var offset = FieldLoader.GetValue<int2>("(value)", input);
var world = new WVec(offset.X * 1024 / Game.CellSize, offset.Y * 1024 / Game.CellSize, 0);
var ts = Game.modData.Manifest.TileSize;
var world = new WVec(offset.X * 1024 / ts.Width, offset.Y * 1024 / ts.Height, 0);
input = world.ToString();
}

View File

@@ -91,7 +91,7 @@ Notifications:
TileSets:
mods/d2k/tilesets/arrakis.yaml
TileSize: 32
TileSize: 32,32
Music:
mods/d2k/music.yaml

Binary file not shown.

Binary file not shown.

View File

@@ -19,8 +19,6 @@ MapFolders:
~^/maps/ts
Packages:
# Red Alert
interior.mix
# Tiberian Sun
~scores.mix:CRC32
~sidenc01.mix:CRC32
@@ -132,7 +130,9 @@ Notifications:
mods/ts/notifications.yaml
TileSets:
mods/ra/tilesets/interior.yaml
mods/ts/tilesets/interior.yaml
TileSize: 48,24
Music:
mods/ts/music.yaml

View File

@@ -0,0 +1,19 @@
General:
Name: Interior
Id: INTERIOR
Extensions: .tem, .shp
Palette: isotem.pal
Terrain:
TerrainType@Clear:
Type: Clear
AcceptsSmudgeType: Crater, Scorch
Color: 0, 0, 0
Templates:
Template@255:
Id: 255
Image: clear01
Size: 1,1
Tiles:
0: Clear