mirror of
https://github.com/kwsch/NHSE.git
synced 2026-08-05 17:28:45 -05:00
215 lines
8.2 KiB
C#
215 lines
8.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using NHSE.Core;
|
|
|
|
namespace NHSE.Sprites
|
|
{
|
|
public static class TerrainSprite
|
|
{
|
|
private static readonly Brush Selected = Brushes.Red;
|
|
private static readonly Brush Others = Brushes.Yellow;
|
|
private static readonly Brush Text = Brushes.White;
|
|
private static readonly Brush Tile = Brushes.Black;
|
|
private static readonly Brush Plaza = Brushes.RosyBrown;
|
|
private static readonly StringFormat BuildingTextFormat = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
|
|
|
|
private const int PlazaWidth = 6 * 2;
|
|
private const int PlazaHeight = 5 * 2;
|
|
|
|
public static void CreateMap(TerrainLayer mgr, int[] pixels)
|
|
{
|
|
int i = 0;
|
|
for (int y = 0; y < mgr.MaxHeight; y++)
|
|
{
|
|
for (int x = 0; x < mgr.MaxWidth; x++, i++)
|
|
{
|
|
pixels[i] = mgr.GetTileColor(x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Bitmap CreateMap(TerrainLayer mgr, int scale, int x, int y, int[] scale1, int[] scaleX, Bitmap map)
|
|
{
|
|
CreateMap(mgr, scale1);
|
|
ImageUtil.ScalePixelImage(scale1, scaleX, map.Width, map.Height, scale);
|
|
ImageUtil.SetBitmapData(map, scaleX);
|
|
return DrawReticle(map, mgr, x, y, scale);
|
|
}
|
|
|
|
public static Bitmap CreateMap(TerrainLayer mgr, int[] scale1, int[] scaleX, Bitmap map, int scale, int acreIndex = -1)
|
|
{
|
|
CreateMap(mgr, scale1);
|
|
ImageUtil.ScalePixelImage(scale1, scaleX, map.Width, map.Height, scale);
|
|
ImageUtil.SetBitmapData(map, scaleX);
|
|
|
|
if (acreIndex < 0)
|
|
return map;
|
|
|
|
var acre = MapGrid.Acres[acreIndex];
|
|
var x = acre.X * mgr.GridWidth;
|
|
var y = acre.Y * mgr.GridHeight;
|
|
|
|
return DrawReticle(map, mgr, x, y, scale);
|
|
}
|
|
|
|
private static Bitmap DrawReticle(Bitmap map, TileGrid mgr, int x, int y, int scale)
|
|
{
|
|
using var gfx = Graphics.FromImage(map);
|
|
using var pen = new Pen(Color.Red);
|
|
|
|
int w = mgr.GridWidth * scale;
|
|
int h = mgr.GridHeight * scale;
|
|
gfx.DrawRectangle(pen, x * scale, y * scale, w, h);
|
|
return map;
|
|
}
|
|
|
|
public static Bitmap GetMapWithBuildings(MapTerrainStructure m, Font? f, int[] scale1, int[] scaleX, Bitmap map, int scale = 4, int index = -1)
|
|
{
|
|
CreateMap(m.Terrain, scale1, scaleX, map, scale);
|
|
using var gfx = Graphics.FromImage(map);
|
|
|
|
gfx.DrawPlaza(m.Terrain, (ushort)m.PlazaX, (ushort)m.PlazaY, scale);
|
|
gfx.DrawBuildings(m.Terrain, m.Buildings, f, scale, index);
|
|
return map;
|
|
}
|
|
|
|
private static void DrawPlaza(this Graphics gfx, TerrainLayer g, ushort px, ushort py, int scale)
|
|
{
|
|
g.GetBuildingCoordinate(px, py, scale, out var x, out var y);
|
|
|
|
var width = scale * PlazaWidth;
|
|
var height = scale * PlazaHeight;
|
|
|
|
gfx.FillRectangle(Plaza, x, y, width, height);
|
|
}
|
|
|
|
private static void DrawBuildings(this Graphics gfx, TerrainLayer g, IReadOnlyList<Building> buildings, Font? f, int scale, int index = -1)
|
|
{
|
|
for (int i = 0; i < buildings.Count; i++)
|
|
{
|
|
var b = buildings[i];
|
|
if (b.BuildingType == 0)
|
|
continue;
|
|
g.GetBuildingCoordinate(b.X, b.Y, scale, out var x, out var y);
|
|
|
|
var pen = index == i ? Selected : Others;
|
|
DrawBuilding(gfx, f, scale, pen, x, y, b, Text);
|
|
}
|
|
}
|
|
|
|
private static void DrawBuilding(Graphics gfx, Font? f, int scale, Brush pen, int x, int y, Building b, Brush text)
|
|
{
|
|
gfx.FillRectangle(pen, x - scale, y - scale, scale * 2, scale * 2);
|
|
|
|
if (f != null)
|
|
{
|
|
var name = b.BuildingType.ToString();
|
|
gfx.DrawString(name, f, text, new PointF(x, y - (scale * 2)), BuildingTextFormat);
|
|
}
|
|
}
|
|
|
|
private static void SetAcreTerrainPixels(int x, int y, TerrainLayer t, int[] data, int[] scaleX, int scale)
|
|
{
|
|
GetAcre1(x, y, t, data);
|
|
ImageUtil.ScalePixelImage(data, scaleX, 16 * scale, 16 * scale, scale);
|
|
}
|
|
|
|
private static void GetAcre1(int topX, int topY, TerrainLayer t, int[] data)
|
|
{
|
|
int index = 0;
|
|
for (int y = 0; y < 16; y++)
|
|
{
|
|
var yi = y + topY;
|
|
for (int x = 0; x < 16; x++, index++)
|
|
data[index] = t.GetTileColor(x + topX, yi);
|
|
}
|
|
}
|
|
|
|
public static Bitmap GetAcre(MapView m, Font f, int[] scale1, int[] scaleX, Bitmap acre, int index, byte tbuild, byte tterrain)
|
|
{
|
|
int mx = m.X / 2;
|
|
int my = m.Y / 2;
|
|
SetAcreTerrainPixels(mx, my, m.Map.Terrain, scale1, scaleX, m.TerrainScale);
|
|
|
|
const int grid1 = unchecked((int)0xFF888888u);
|
|
const int grid2 = unchecked((int)0xFF666666u);
|
|
ImageUtil.SetBitmapData(acre, scaleX);
|
|
|
|
using var gfx = Graphics.FromImage(acre);
|
|
|
|
gfx.DrawAcrePlaza(m.Map.Terrain, mx, my, (ushort)m.Map.PlazaX, (ushort)m.Map.PlazaY, m.TerrainScale, tbuild);
|
|
|
|
var buildings = m.Map.Buildings;
|
|
var t = m.Map.Terrain;
|
|
for (var i = 0; i < buildings.Count; i++)
|
|
{
|
|
var b = buildings[i];
|
|
t.GetBuildingRelativeCoordinates(mx, my, m.TerrainScale, b.X, b.Y, out var x, out var y);
|
|
|
|
var pen = index == i ? Selected : Others;
|
|
if (tbuild != byte.MaxValue)
|
|
{
|
|
var orig = ((SolidBrush) pen).Color;
|
|
pen = new SolidBrush(Color.FromArgb(tbuild, orig));
|
|
}
|
|
DrawBuilding(gfx, null, m.TerrainScale, pen, x, y, b, Text);
|
|
}
|
|
|
|
ImageUtil.GetBitmapData(acre, scaleX);
|
|
ItemLayerSprite.DrawGrid(scaleX, acre.Width, acre.Height, m.AcreScale, grid1);
|
|
ItemLayerSprite.DrawGrid(scaleX, acre.Width, acre.Height, m.TerrainScale, grid2);
|
|
ImageUtil.SetBitmapData(acre, scaleX);
|
|
|
|
foreach (var b in buildings)
|
|
{
|
|
t.GetBuildingRelativeCoordinates(mx, my, m.TerrainScale, b.X, b.Y, out var x, out var y);
|
|
if (!t.IsWithinGrid(m.TerrainScale, x, y))
|
|
continue;
|
|
var name = b.BuildingType.ToString();
|
|
gfx.DrawString(name, f, Text, new PointF(x, y - (m.TerrainScale * 2)), BuildingTextFormat);
|
|
}
|
|
|
|
if (tterrain != 0)
|
|
DrawTerrainTileNames(mx, my, gfx, t, f, m.TerrainScale, tterrain);
|
|
|
|
return acre;
|
|
}
|
|
|
|
private static void DrawTerrainTileNames(int topX, int topY, Graphics gfx, TerrainLayer t, Font f, int scale, byte transparency)
|
|
{
|
|
var pen= transparency != byte.MaxValue ? new SolidBrush(Color.FromArgb(transparency, Color.Black)) : Tile;
|
|
|
|
for (int y = 0; y < 16; y++)
|
|
{
|
|
var yi = y + topY;
|
|
int cy = (y * scale) + (scale / 2);
|
|
for (int x = 0; x < 16; x++)
|
|
{
|
|
var xi = x + topX;
|
|
var tile = t.GetTile(xi, yi);
|
|
|
|
int cx = (x * scale) + (scale / 2);
|
|
var name = TerrainTileColor.GetTileName(tile);
|
|
gfx.DrawString(name, f, pen, new PointF(cx, cy), BuildingTextFormat);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void DrawAcrePlaza(this Graphics gfx, TerrainLayer g, int topX, int topY, ushort px, ushort py, int scale, byte transparency)
|
|
{
|
|
g.GetBuildingRelativeCoordinates(topX, topY, scale, px, py, out var x, out var y);
|
|
|
|
var width = scale * PlazaWidth;
|
|
var height = scale * PlazaHeight;
|
|
|
|
var pen = Plaza;
|
|
if (transparency != byte.MaxValue)
|
|
{
|
|
var orig = ((SolidBrush)pen).Color;
|
|
pen = new SolidBrush(Color.FromArgb(transparency, orig));
|
|
}
|
|
gfx.FillRectangle(pen, x, y, width, height);
|
|
}
|
|
}
|
|
}
|