mirror of
https://github.com/kwsch/NHSE.git
synced 2026-04-21 16:07:26 -05:00
Add Terrain editor
most complex editor yet could be better if I did PictureBox'es instead of buttons, so I could put an image instead of just color ppl will have to document more on what each terrain looks like, maybe could show a pic of each terrain tile?
This commit is contained in:
parent
deb4d51149
commit
8b3c650eff
|
|
@ -61,5 +61,11 @@ public void SetAcreBytes(byte[] data)
|
|||
throw new ArgumentOutOfRangeException(nameof(data.Length));
|
||||
data.CopyTo(Data, Offsets.Acres);
|
||||
}
|
||||
|
||||
public TerrainTile[] Terrain
|
||||
{
|
||||
get => TerrainTile.GetArray(Data.Slice(Offsets.Terrain, TerrainManager.TileCount * TerrainTile.SIZE));
|
||||
set => TerrainTile.SetArray(value).CopyTo(Data, Offsets.Terrain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ public abstract class MainSaveOffsets
|
|||
public abstract int TurnipExchange { get; }
|
||||
|
||||
public abstract int Acres { get; }
|
||||
public abstract int Terrain { get; }
|
||||
|
||||
public static MainSaveOffsets GetOffsets(FileHeaderInfo Info)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ public class MainSaveOffsets10 : MainSaveOffsets
|
|||
{
|
||||
public override int Villager => 0x110;
|
||||
public override int Patterns => 0x1D72F0;
|
||||
public override int Terrain => Buildings - 0x24C00; // dunno where exactly it starts???
|
||||
public override int Buildings => 0x2D0EFC;
|
||||
public override int Acres => 0x2D1294;
|
||||
public override int TurnipExchange => 0x4118C0;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ public class MainSaveOffsets11 : MainSaveOffsets
|
|||
{
|
||||
public override int Villager => 0x120;
|
||||
public override int Patterns => 0x1D7310; // +0x20 from v1.0
|
||||
public override int Terrain => Buildings - 0x24C00; // dunno where exactly it starts??? // +0x20 from v1.0
|
||||
public override int Buildings => 0x2D0F1C; // +0x20 from v1.0
|
||||
public override int Acres => 0x2D12B4; // +0x20 from v1.0
|
||||
public override int TurnipExchange => 0x412060; // +0x7A0 from v1.0
|
||||
|
|
|
|||
29
NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs
Normal file
29
NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
namespace NHSE.Core
|
||||
{
|
||||
public class AcreCoordinate
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly int X, Y;
|
||||
|
||||
public AcreCoordinate(int x, int y)
|
||||
{
|
||||
char yName = (char)('A' + y);
|
||||
char xName = (char)('0' + x);
|
||||
Name = $"{yName}{xName}";
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public static AcreCoordinate[] GetGrid(int width, int height)
|
||||
{
|
||||
var result = new AcreCoordinate[width * height];
|
||||
int i = 0;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
result[i++] = new AcreCoordinate(x, y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs
Normal file
91
NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
namespace NHSE.Core
|
||||
{
|
||||
public class TerrainManager
|
||||
{
|
||||
public readonly TerrainTile[] Tiles;
|
||||
public readonly AcreCoordinate[] Acres = AcreCoordinate.GetGrid(AcreWidth, AcreHeight);
|
||||
|
||||
public const int GridWidth = 16;
|
||||
public const int GridHeight = 16;
|
||||
|
||||
public const int AcreWidth = 7;
|
||||
public const int AcreHeight = 6;
|
||||
public const int AcreSize = GridWidth * GridHeight;
|
||||
|
||||
public const int MapHeight = AcreHeight * GridHeight; // 92
|
||||
public const int MapWidth = AcreWidth * GridWidth; // 112
|
||||
public const int TileCount = MapWidth * MapHeight; // 0x2A00
|
||||
|
||||
public TerrainManager(TerrainTile[] tiles)
|
||||
{
|
||||
Debug.Assert(TileCount == tiles.Length);
|
||||
Tiles = tiles;
|
||||
}
|
||||
|
||||
private static int GetIndex(int x, int y) => (MapHeight * x) + y;
|
||||
|
||||
public TerrainTile GetTile(int x, int y) => this[GetIndex(x, y)];
|
||||
|
||||
public TerrainTile GetTile(int acreX, int acreY, int gridX, int gridY)
|
||||
{
|
||||
var x = (acreX * GridWidth) + gridX;
|
||||
var y = (acreY * GridHeight) + gridY;
|
||||
return this[GetIndex(x, y)];
|
||||
}
|
||||
|
||||
public TerrainTile GetAcreTile(int acreIndex, int tileIndex)
|
||||
{
|
||||
var acre = Acres[acreIndex];
|
||||
var x = (tileIndex % GridWidth);
|
||||
var y = (tileIndex / GridHeight);
|
||||
return GetTile(acre.X, acre.Y, x, y);
|
||||
}
|
||||
|
||||
public TerrainTile this[int index]
|
||||
{
|
||||
get => Tiles[index];
|
||||
set => Tiles[index] = value;
|
||||
}
|
||||
|
||||
public byte[] DumpAllAcres()
|
||||
{
|
||||
var result = new byte[Tiles.Length * TerrainTile.SIZE];
|
||||
for (int i = 0; i < Tiles.Length; i++)
|
||||
Tiles[i].ToBytesClass().CopyTo(result, i * TerrainTile.SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] DumpAcre(int acre)
|
||||
{
|
||||
const int count = (GridWidth * GridHeight);
|
||||
var result = new byte[TerrainTile.SIZE * count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var tile = GetTile(acre, i);
|
||||
var bytes = tile.ToBytesClass();
|
||||
bytes.CopyTo(result, i * TerrainTile.SIZE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ImportAllAcres(byte[] data)
|
||||
{
|
||||
var tiles = TerrainTile.GetArray(data);
|
||||
for (int i = 0; i < tiles.Length; i++)
|
||||
Tiles[i].CopyFrom(tiles[i]);
|
||||
}
|
||||
|
||||
public void ImportAcre(int acre, byte[] data)
|
||||
{
|
||||
const int count = (GridWidth * GridHeight);
|
||||
var tiles = TerrainTile.GetArray(data);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var tile = GetTile(acre, i);
|
||||
tile.CopyFrom(tiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
NHSE.Core/Structures/Acres/Terrain/TerrainTile.cs
Normal file
45
NHSE.Core/Structures/Acres/Terrain/TerrainTile.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NHSE.Core
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class TerrainTile
|
||||
{
|
||||
public const int SIZE = 0xE;
|
||||
private const string Details = nameof(Details);
|
||||
|
||||
[Category(Details), Description("Terrain model to be loaded for this tile.")]
|
||||
public TerrainUnitModel UnitModel { get; set; }
|
||||
|
||||
public ushort Unk2 { get; set; }
|
||||
public ushort Unk4 { get; set; }
|
||||
public ushort Unk6 { get; set; }
|
||||
public ushort Unk8 { get; set; }
|
||||
public ushort UnkA { get; set; }
|
||||
|
||||
[Category(Details), Description("How high the terrain tile is elevated.")]
|
||||
public ushort Elevation { get; set; }
|
||||
|
||||
public static TerrainTile[] GetArray(byte[] data) => data.GetArray<TerrainTile>(SIZE);
|
||||
public static byte[] SetArray(IReadOnlyList<TerrainTile> data) => data.SetArray(SIZE);
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
UnitModel = 0;
|
||||
Unk2 = Unk4 = Unk6 = Unk8 = UnkA = Elevation = 0;
|
||||
}
|
||||
|
||||
public void CopyFrom(TerrainTile source)
|
||||
{
|
||||
UnitModel = source.UnitModel;
|
||||
Unk2 = source.Unk2;
|
||||
Unk4 = source.Unk4;
|
||||
Unk6 = source.Unk6;
|
||||
Unk8 = source.Unk8;
|
||||
UnkA = source.UnkA;
|
||||
Elevation = source.Elevation;
|
||||
}
|
||||
}
|
||||
}
|
||||
252
NHSE.Core/Structures/Acres/Terrain/TerrainUnitModel.cs
Normal file
252
NHSE.Core/Structures/Acres/Terrain/TerrainUnitModel.cs
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
namespace NHSE.Core
|
||||
{
|
||||
public enum TerrainUnitModel : ushort
|
||||
{
|
||||
Base = 0x00,
|
||||
River0A = 0x01,
|
||||
River1A = 0x04,
|
||||
River2A = 0x07,
|
||||
River2B = 0x08,
|
||||
River2C = 0x09,
|
||||
River3A = 0x0A,
|
||||
River3B = 0x0B,
|
||||
River3C = 0x0C,
|
||||
River4A = 0x0D,
|
||||
River4B = 0x0E,
|
||||
River4C = 0x0F,
|
||||
River5A = 0x10,
|
||||
River5B = 0x11,
|
||||
River6A = 0x12,
|
||||
River6B = 0x13,
|
||||
River7A = 0x14,
|
||||
River8A = 0x15,
|
||||
Cliff0A = 0x16,
|
||||
Cliff0A_2 = 0x17,
|
||||
Cliff0A_3 = 0x18,
|
||||
Cliff1A = 0x19,
|
||||
Cliff1A_2 = 0x1A,
|
||||
Cliff1A_3 = 0x1B,
|
||||
Cliff2A = 0x1C,
|
||||
Cliff2C = 0x1D,
|
||||
Cliff3A = 0x1E,
|
||||
Cliff3B = 0x1F,
|
||||
Cliff3C = 0x20,
|
||||
Cliff4A = 0x21,
|
||||
Cliff4B = 0x22,
|
||||
Cliff4C = 0x23,
|
||||
Cliff5A = 0x24,
|
||||
Cliff5B = 0x25,
|
||||
Cliff6A = 0x26,
|
||||
Cliff6B = 0x27,
|
||||
Cliff7A = 0x28,
|
||||
Cliff8 = 0x29,
|
||||
Fall101 = 0x3A,
|
||||
Fall100 = 0x3B,
|
||||
Fall300 = 0x3C,
|
||||
Fall301 = 0x3D,
|
||||
Fall302 = 0x3E,
|
||||
Fall200 = 0x3F,
|
||||
Fall201 = 0x40,
|
||||
Fall202 = 0x41,
|
||||
Fall400 = 0x42,
|
||||
Fall401 = 0x43,
|
||||
Fall402 = 0x44,
|
||||
Fall403 = 0x45,
|
||||
Fall404 = 0x46,
|
||||
RoadSoil0A = 0x47,
|
||||
RoadSoil1A = 0x48,
|
||||
RoadSoil0B = 0x49,
|
||||
RoadSoil1B = 0x4B,
|
||||
RoadSoil1C = 0x4C,
|
||||
RoadSoil2A = 0x4D,
|
||||
RoadSoil2B = 0x4E,
|
||||
RoadSoil2C = 0x4F,
|
||||
RoadSoil3A = 0x50,
|
||||
RoadSoil3B = 0x51,
|
||||
RoadSoil3C = 0x52,
|
||||
RoadSoil4A = 0x53,
|
||||
RoadSoil4B = 0x54,
|
||||
RoadSoil4C = 0x55,
|
||||
RoadSoil5A = 0x56,
|
||||
RoadSoil5B = 0x57,
|
||||
RoadSoil6A = 0x58,
|
||||
RoadSoil6B = 0x59,
|
||||
RoadSoil7A = 0x5A,
|
||||
RoadSoil8A = 0x5B,
|
||||
RoadStone0A = 0x5C,
|
||||
RoadStone0B = 0x5D,
|
||||
RoadStone1A = 0x5F,
|
||||
RoadStone1B = 0x60,
|
||||
RoadStone1C = 0x61,
|
||||
RoadStone2A = 0x62,
|
||||
RoadStone2B = 0x63,
|
||||
RoadStone2C = 0x64,
|
||||
RoadStone3A = 0x65,
|
||||
RoadStone3B = 0x66,
|
||||
RoadStone3C = 0x67,
|
||||
RoadStone4A = 0x68,
|
||||
RoadStone4B = 0x69,
|
||||
RoadStone4C = 0x6A,
|
||||
RoadStone5A = 0x6B,
|
||||
RoadStone5B = 0x6C,
|
||||
RoadStone6A = 0x6D,
|
||||
RoadStone6B = 0x6E,
|
||||
RoadStone7A = 0x6F,
|
||||
RoadStone8A = 0x70,
|
||||
Fall103 = 0x71,
|
||||
Fall102 = 0x72,
|
||||
Fall303 = 0x73,
|
||||
Fall304 = 0x74,
|
||||
Fall305 = 0x75,
|
||||
Fall306 = 0x76,
|
||||
Fall307 = 0x77,
|
||||
Fall308 = 0x78,
|
||||
Fall203 = 0x79,
|
||||
Fall204 = 0x7A,
|
||||
Fall205 = 0x7B,
|
||||
Fall206 = 0x7C,
|
||||
Fall207 = 0x7D,
|
||||
Fall208 = 0x7E,
|
||||
Fall405 = 0x7F,
|
||||
Fall406 = 0x80,
|
||||
Fall407 = 0x81,
|
||||
Fall408 = 0x82,
|
||||
Fall410 = 0x83,
|
||||
Fall409 = 0x84,
|
||||
Fall411 = 0x85,
|
||||
Fall412 = 0x86,
|
||||
Fall414 = 0x87,
|
||||
Fall413 = 0x88,
|
||||
Fall415 = 0x89,
|
||||
Fall416 = 0x8A,
|
||||
Fall418 = 0x8B,
|
||||
Fall417 = 0x8C,
|
||||
Fall419 = 0x8D,
|
||||
Fall420 = 0x8E,
|
||||
Fall422 = 0x8F,
|
||||
Fall421 = 0x90,
|
||||
Fall423 = 0x91,
|
||||
Fall424 = 0x92,
|
||||
Cliff2B = 0x93,
|
||||
RoadBrick0A = 0x94,
|
||||
RoadBrick0B = 0x95,
|
||||
RoadBrick1A = 0x97,
|
||||
RoadBrick1B = 0x98,
|
||||
RoadBrick1C = 0x99,
|
||||
RoadBrick2A = 0x9A,
|
||||
RoadBrick2B = 0x9B,
|
||||
RoadBrick2C = 0x9C,
|
||||
RoadBrick3A = 0x9D,
|
||||
RoadBrick3B = 0x9E,
|
||||
RoadBrick3C = 0x9F,
|
||||
RoadBrick4A = 0xA0,
|
||||
RoadBrick4B = 0xA1,
|
||||
RoadBrick4C = 0xA2,
|
||||
RoadBrick5A = 0xA3,
|
||||
RoadBrick5B = 0xA4,
|
||||
RoadBrick6A = 0xA5,
|
||||
RoadBrick6B = 0xA6,
|
||||
RoadBrick7A = 0xA7,
|
||||
RoadBrick8A = 0xA8,
|
||||
RoadDarkSoil0A = 0xA9,
|
||||
RoadDarkSoil0B = 0xAA,
|
||||
RoadDarkSoil1A = 0xAC,
|
||||
RoadDarkSoil1B = 0xAD,
|
||||
RoadDarkSoil1C = 0xAE,
|
||||
RoadDarkSoil2A = 0xAF,
|
||||
RoadDarkSoil2B = 0xB0,
|
||||
RoadDarkSoil2C = 0xB1,
|
||||
RoadDarkSoil3A = 0xB2,
|
||||
RoadDarkSoil3B = 0xB3,
|
||||
RoadDarkSoil3C = 0xB4,
|
||||
RoadDarkSoil4A = 0xB5,
|
||||
RoadDarkSoil4B = 0xB6,
|
||||
RoadDarkSoil4C = 0xB7,
|
||||
RoadDarkSoil5A = 0xB8,
|
||||
RoadDarkSoil5B = 0xB9,
|
||||
RoadDarkSoil6A = 0xBA,
|
||||
RoadDarkSoil6B = 0xBB,
|
||||
RoadDarkSoil7A = 0xBC,
|
||||
RoadDarkSoil8A = 0xBD,
|
||||
RoadFanPattern0A = 0xBE,
|
||||
RoadFanPattern0B = 0xBF,
|
||||
RoadFanPattern1A = 0xC1,
|
||||
RoadFanPattern1B = 0xC2,
|
||||
RoadFanPattern1C = 0xC3,
|
||||
RoadFanPattern2A = 0xC4,
|
||||
RoadFanPattern2B = 0xC5,
|
||||
RoadFanPattern2C = 0xC6,
|
||||
RoadFanPattern3A = 0xC7,
|
||||
RoadFanPattern3B = 0xC8,
|
||||
RoadFanPattern3C = 0xC9,
|
||||
RoadFanPattern4A = 0xCA,
|
||||
RoadFanPattern4B = 0xCB,
|
||||
RoadFanPattern4C = 0xCC,
|
||||
RoadFanPattern5A = 0xCD,
|
||||
RoadFanPattern5B = 0xCE,
|
||||
RoadFanPattern6A = 0xCF,
|
||||
RoadFanPattern6B = 0xD0,
|
||||
RoadFanPattern7A = 0xD1,
|
||||
RoadFanPattern8A = 0xD2,
|
||||
RoadSand0A = 0xD3,
|
||||
RoadSand0B = 0xD4,
|
||||
RoadSand1A = 0xD6,
|
||||
RoadSand1B = 0xD7,
|
||||
RoadSand1C = 0xD8,
|
||||
RoadSand2A = 0xD9,
|
||||
RoadSand2B = 0xDA,
|
||||
RoadSand2C = 0xDB,
|
||||
RoadSand3A = 0xDC,
|
||||
RoadSand3B = 0xDD,
|
||||
RoadSand3C = 0xDE,
|
||||
RoadSand4A = 0xDF,
|
||||
RoadSand4B = 0xE0,
|
||||
RoadSand4C = 0xE1,
|
||||
RoadSand5A = 0xE2,
|
||||
RoadSand5B = 0xE3,
|
||||
RoadSand6A = 0xE4,
|
||||
RoadSand6B = 0xE5,
|
||||
RoadSand7A = 0xE6,
|
||||
RoadSand8A = 0xE7,
|
||||
RoadTile0A = 0xE8,
|
||||
RoadTile0B = 0xE9,
|
||||
RoadTile1A = 0xEB,
|
||||
RoadTile1B = 0xEC,
|
||||
RoadTile1C = 0xED,
|
||||
RoadTile2A = 0xEE,
|
||||
RoadTile2B = 0xEF,
|
||||
RoadTile2C = 0xF0,
|
||||
RoadTile3A = 0xF1,
|
||||
RoadTile3B = 0xF2,
|
||||
RoadTile3C = 0xF3,
|
||||
RoadTile4A = 0xF4,
|
||||
RoadTile4B = 0xF5,
|
||||
RoadTile4C = 0xF6,
|
||||
RoadTile5A = 0xF7,
|
||||
RoadTile5B = 0xF8,
|
||||
RoadTile6A = 0xF9,
|
||||
RoadTile6B = 0xFA,
|
||||
RoadTile7A = 0xFB,
|
||||
RoadTile8A = 0xFC,
|
||||
RoadWood0A = 0xFD,
|
||||
RoadWood0B = 0xFE,
|
||||
RoadWood1A = 0x100,
|
||||
RoadWood1B = 0x101,
|
||||
RoadWood1C = 0x102,
|
||||
RoadWood2A = 0x103,
|
||||
RoadWood2B = 0x104,
|
||||
RoadWood2C = 0x105,
|
||||
RoadWood3A = 0x106,
|
||||
RoadWood3B = 0x107,
|
||||
RoadWood3C = 0x108,
|
||||
RoadWood4A = 0x109,
|
||||
RoadWood4B = 0x10A,
|
||||
RoadWood4C = 0x10B,
|
||||
RoadWood5A = 0x10C,
|
||||
RoadWood5B = 0x10D,
|
||||
RoadWood6A = 0x10E,
|
||||
RoadWood6B = 0x10F,
|
||||
RoadWood7A = 0x110,
|
||||
RoadWood8A = 0x111,
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ void DumpB(string fn, byte[] bytes)
|
|||
|
||||
DumpS("ItemKind.txt", GetPossibleEnum(pathBCSV, "ItemParam.bcsv", 0xFC275E86));
|
||||
DumpS("PlantKind.txt", GetPossibleEnum(pathBCSV, "FgMainParam.bcsv", 0x48EF0398));
|
||||
DumpS("TerrainKind.txt", GetNumberedEnumValues(pathBCSV, "FieldLandMakingUnitModelParam.bcsv", 0x39B5A93D, 0x54706054));
|
||||
|
||||
DumpB("item_kind.bin", GetItemKindArray(pathBCSV));
|
||||
DumpS("plants.txt", GetPlantedNames(pathBCSV));
|
||||
|
|
@ -68,6 +69,40 @@ private static IEnumerable<string> GetPossibleEnumValues(string pathBCSV, string
|
|||
return types;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetNumberedEnumValues(string pathBCSV, string fn, uint keyName, uint keyValue)
|
||||
{
|
||||
var path = Path.Combine(pathBCSV, fn);
|
||||
var data = File.ReadAllBytes(path);
|
||||
var bcsv = new BCSV(data);
|
||||
|
||||
var dict = bcsv.GetFieldDictionary();
|
||||
var fType = dict[keyName];
|
||||
var fitemID = dict[keyValue];
|
||||
|
||||
var types = new List<string>();
|
||||
var set = new Dictionary<string, int>();
|
||||
for (int i = 0; i < bcsv.EntryCount; i++)
|
||||
{
|
||||
var iid = bcsv.ReadValue(i, fitemID);
|
||||
var ival = ushort.Parse(iid);
|
||||
var type = bcsv.ReadValue(i, fType).TrimEnd('\0');
|
||||
if (set.TryGetValue(type, out var count))
|
||||
{
|
||||
count++;
|
||||
set[type] = count;
|
||||
type += $"_{count}";
|
||||
}
|
||||
else
|
||||
{
|
||||
set.Add(type, 1);
|
||||
}
|
||||
|
||||
types.Add($"{type} = 0x{ival:X2},");
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetPossibleEnum(string pathBCSV, string fn, uint key)
|
||||
{
|
||||
var kinds = GetPossibleEnumValues(pathBCSV, fn, key);
|
||||
|
|
|
|||
15
NHSE.Sprites/ColorUtil.cs
Normal file
15
NHSE.Sprites/ColorUtil.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Drawing;
|
||||
|
||||
namespace NHSE.Sprites
|
||||
{
|
||||
public static class ColorUtil
|
||||
{
|
||||
public static Color Blend(Color color, Color backColor, double amount)
|
||||
{
|
||||
byte r = (byte)((color.R * amount) + (backColor.R * (1 - amount)));
|
||||
byte g = (byte)((color.G * amount) + (backColor.G * (1 - amount)));
|
||||
byte b = (byte)((color.B * amount) + (backColor.B * (1 - amount)));
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,15 +75,7 @@ private static Color GetItemColor(Item item)
|
|||
var known = Colors[(int)kind];
|
||||
var color = Color.FromKnownColor(known);
|
||||
// soften the colors a little
|
||||
return Blend(Color.White, color, 0.5d);
|
||||
}
|
||||
|
||||
public static Color Blend(Color color, Color backColor, double amount)
|
||||
{
|
||||
byte r = (byte)((color.R * amount) + (backColor.R * (1 - amount)));
|
||||
byte g = (byte)((color.G * amount) + (backColor.G * (1 - amount)));
|
||||
byte b = (byte)((color.B * amount) + (backColor.B * (1 - amount)));
|
||||
return Color.FromArgb(r, g, b);
|
||||
return ColorUtil.Blend(Color.White, color, 0.5d);
|
||||
}
|
||||
|
||||
private static readonly KnownColor[] Colors = (KnownColor[])Enum.GetValues(typeof(KnownColor));
|
||||
|
|
|
|||
57
NHSE.Sprites/TerrainSprite.cs
Normal file
57
NHSE.Sprites/TerrainSprite.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using NHSE.Core;
|
||||
|
||||
namespace NHSE.Sprites
|
||||
{
|
||||
public static class TerrainSprite
|
||||
{
|
||||
public static Color GetTileColor(TerrainTile tile)
|
||||
{
|
||||
var name = tile.UnitModel.ToString();
|
||||
var baseColor = GetTileColor(name);
|
||||
if (tile.Elevation == 0)
|
||||
return baseColor;
|
||||
|
||||
return ColorUtil.Blend(baseColor, Color.White, 1d / (tile.Elevation + 1));
|
||||
}
|
||||
|
||||
private static Color GetTileColor(string name)
|
||||
{
|
||||
if (name.StartsWith("River")) // River
|
||||
return Color.DeepSkyBlue;
|
||||
if (name.StartsWith("Fall")) // Waterfall
|
||||
return Color.DarkBlue;
|
||||
if (name.Contains("Cliff"))
|
||||
return ColorUtil.Blend(Color.ForestGreen, Color.Black, 0.5d);
|
||||
return Color.ForestGreen;
|
||||
}
|
||||
|
||||
private static readonly char[] Numbers = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
|
||||
public static string GetTileName(TerrainTile tile)
|
||||
{
|
||||
var name = tile.UnitModel.ToString();
|
||||
var num = name.IndexOfAny(Numbers);
|
||||
if (num < 0)
|
||||
return name;
|
||||
return name.Substring(0, num) + Environment.NewLine + name.Substring(num);
|
||||
}
|
||||
|
||||
public static Bitmap CreateMap(TerrainManager mgr)
|
||||
{
|
||||
var bmp = new Bitmap(TerrainManager.MapWidth, TerrainManager.MapHeight);
|
||||
for (int x = 0; x < TerrainManager.MapWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < TerrainManager.MapHeight; y++)
|
||||
{
|
||||
var tile = mgr.GetTile(x, y);
|
||||
var color = GetTileColor(tile);
|
||||
bmp.SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace NHSE.Tests
|
||||
{
|
||||
public class ItemTests
|
||||
public class MarshalTests
|
||||
{
|
||||
[Fact]
|
||||
public void ItemMarshal()
|
||||
|
|
@ -29,5 +29,13 @@ public void MapItemMarshal()
|
|||
var bytes = item.ToBytesClass();
|
||||
bytes.Length.Should().Be(MapItem.SIZE);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TerrainTileMarshal()
|
||||
{
|
||||
var obj = new TerrainTile();
|
||||
var bytes = obj.ToBytesClass();
|
||||
bytes.Length.Should().Be(TerrainTile.SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
NHSE.WinForms/Editor.Designer.cs
generated
53
NHSE.WinForms/Editor.Designer.cs
generated
|
|
@ -85,10 +85,11 @@ private void InitializeComponent()
|
|||
this.NUD_PatternIndex = new System.Windows.Forms.NumericUpDown();
|
||||
this.PB_Pattern = new System.Windows.Forms.PictureBox();
|
||||
this.Tab_Map = new System.Windows.Forms.TabPage();
|
||||
this.B_EditAcres = new System.Windows.Forms.Button();
|
||||
this.B_EditTurnipExchange = new System.Windows.Forms.Button();
|
||||
this.B_EditBuildings = new System.Windows.Forms.Button();
|
||||
this.B_RecycleBin = new System.Windows.Forms.Button();
|
||||
this.B_EditTurnipExchange = new System.Windows.Forms.Button();
|
||||
this.B_EditAcres = new System.Windows.Forms.Button();
|
||||
this.B_EditTerrain = new System.Windows.Forms.Button();
|
||||
this.Menu_Editor.SuspendLayout();
|
||||
this.TC_Editors.SuspendLayout();
|
||||
this.Tab_Players.SuspendLayout();
|
||||
|
|
@ -711,6 +712,7 @@ private void InitializeComponent()
|
|||
//
|
||||
// Tab_Map
|
||||
//
|
||||
this.Tab_Map.Controls.Add(this.B_EditTerrain);
|
||||
this.Tab_Map.Controls.Add(this.B_EditAcres);
|
||||
this.Tab_Map.Controls.Add(this.B_EditTurnipExchange);
|
||||
this.Tab_Map.Controls.Add(this.B_EditBuildings);
|
||||
|
|
@ -723,6 +725,26 @@ private void InitializeComponent()
|
|||
this.Tab_Map.Text = "Map";
|
||||
this.Tab_Map.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// B_EditAcres
|
||||
//
|
||||
this.B_EditAcres.Location = new System.Drawing.Point(300, 168);
|
||||
this.B_EditAcres.Name = "B_EditAcres";
|
||||
this.B_EditAcres.Size = new System.Drawing.Size(92, 40);
|
||||
this.B_EditAcres.TabIndex = 16;
|
||||
this.B_EditAcres.Text = "Edit Acres";
|
||||
this.B_EditAcres.UseVisualStyleBackColor = true;
|
||||
this.B_EditAcres.Click += new System.EventHandler(this.B_EditAcres_Click);
|
||||
//
|
||||
// B_EditTurnipExchange
|
||||
//
|
||||
this.B_EditTurnipExchange.Location = new System.Drawing.Point(202, 168);
|
||||
this.B_EditTurnipExchange.Name = "B_EditTurnipExchange";
|
||||
this.B_EditTurnipExchange.Size = new System.Drawing.Size(92, 40);
|
||||
this.B_EditTurnipExchange.TabIndex = 15;
|
||||
this.B_EditTurnipExchange.Text = "Edit Turnip Exchange";
|
||||
this.B_EditTurnipExchange.UseVisualStyleBackColor = true;
|
||||
this.B_EditTurnipExchange.Click += new System.EventHandler(this.B_EditTurnipExchange_Click);
|
||||
//
|
||||
// B_EditBuildings
|
||||
//
|
||||
this.B_EditBuildings.Location = new System.Drawing.Point(104, 168);
|
||||
|
|
@ -743,25 +765,15 @@ private void InitializeComponent()
|
|||
this.B_RecycleBin.UseVisualStyleBackColor = true;
|
||||
this.B_RecycleBin.Click += new System.EventHandler(this.B_RecycleBin_Click);
|
||||
//
|
||||
// B_EditTurnipExchange
|
||||
// B_EditTerrain
|
||||
//
|
||||
this.B_EditTurnipExchange.Location = new System.Drawing.Point(202, 168);
|
||||
this.B_EditTurnipExchange.Name = "B_EditTurnipExchange";
|
||||
this.B_EditTurnipExchange.Size = new System.Drawing.Size(92, 40);
|
||||
this.B_EditTurnipExchange.TabIndex = 15;
|
||||
this.B_EditTurnipExchange.Text = "Edit Turnip Exchange";
|
||||
this.B_EditTurnipExchange.UseVisualStyleBackColor = true;
|
||||
this.B_EditTurnipExchange.Click += new System.EventHandler(this.B_EditTurnipExchange_Click);
|
||||
//
|
||||
// B_EditAcres
|
||||
//
|
||||
this.B_EditAcres.Location = new System.Drawing.Point(300, 168);
|
||||
this.B_EditAcres.Name = "B_EditAcres";
|
||||
this.B_EditAcres.Size = new System.Drawing.Size(92, 40);
|
||||
this.B_EditAcres.TabIndex = 16;
|
||||
this.B_EditAcres.Text = "Edit Acres";
|
||||
this.B_EditAcres.UseVisualStyleBackColor = true;
|
||||
this.B_EditAcres.Click += new System.EventHandler(this.B_EditAcres_Click);
|
||||
this.B_EditTerrain.Location = new System.Drawing.Point(300, 122);
|
||||
this.B_EditTerrain.Name = "B_EditTerrain";
|
||||
this.B_EditTerrain.Size = new System.Drawing.Size(92, 40);
|
||||
this.B_EditTerrain.TabIndex = 17;
|
||||
this.B_EditTerrain.Text = "Edit Terrain";
|
||||
this.B_EditTerrain.UseVisualStyleBackColor = true;
|
||||
this.B_EditTerrain.Click += new System.EventHandler(this.B_EditTerrain_Click);
|
||||
//
|
||||
// Editor
|
||||
//
|
||||
|
|
@ -865,6 +877,7 @@ private void InitializeComponent()
|
|||
private System.Windows.Forms.ToolStripMenuItem Menu_RAMEdit;
|
||||
private System.Windows.Forms.Button B_EditTurnipExchange;
|
||||
private System.Windows.Forms.Button B_EditAcres;
|
||||
private System.Windows.Forms.Button B_EditTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,5 +514,11 @@ private void B_EditAcres_Click(object sender, EventArgs e)
|
|||
using var editor = new AcreEditor(SAV.Main);
|
||||
editor.ShowDialog();
|
||||
}
|
||||
|
||||
private void B_EditTerrain_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var editor = new TerrainEditor(SAV.Main);
|
||||
editor.ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Subforms\TerrainEditor.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Subforms\SingleObjectEditor.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
|
|||
336
NHSE.WinForms/Subforms/TerrainEditor.Designer.cs
generated
Normal file
336
NHSE.WinForms/Subforms/TerrainEditor.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
namespace NHSE.WinForms
|
||||
{
|
||||
partial class TerrainEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.B_Cancel = new System.Windows.Forms.Button();
|
||||
this.B_Save = new System.Windows.Forms.Button();
|
||||
this.FLP_Tile = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.PG_Tile = new System.Windows.Forms.PropertyGrid();
|
||||
this.CB_Acre = new System.Windows.Forms.ComboBox();
|
||||
this.L_Acre = new System.Windows.Forms.Label();
|
||||
this.B_ZeroElevation = new System.Windows.Forms.Button();
|
||||
this.B_ClearAll = new System.Windows.Forms.Button();
|
||||
this.B_DumpAcre = new System.Windows.Forms.Button();
|
||||
this.B_DumpAllAcres = new System.Windows.Forms.Button();
|
||||
this.B_ImportAllAcres = new System.Windows.Forms.Button();
|
||||
this.B_ImportAcre = new System.Windows.Forms.Button();
|
||||
this.CM_Click = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.Menu_View = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Menu_Set = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Menu_Reset = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.B_Up = new System.Windows.Forms.Button();
|
||||
this.B_Left = new System.Windows.Forms.Button();
|
||||
this.B_Right = new System.Windows.Forms.Button();
|
||||
this.B_Down = new System.Windows.Forms.Button();
|
||||
this.PB_Map = new System.Windows.Forms.PictureBox();
|
||||
this.CM_Picture = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.Menu_SavePNG = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CM_Click.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.PB_Map)).BeginInit();
|
||||
this.CM_Picture.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// B_Cancel
|
||||
//
|
||||
this.B_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.B_Cancel.Location = new System.Drawing.Point(899, 787);
|
||||
this.B_Cancel.Name = "B_Cancel";
|
||||
this.B_Cancel.Size = new System.Drawing.Size(72, 23);
|
||||
this.B_Cancel.TabIndex = 7;
|
||||
this.B_Cancel.Text = "Cancel";
|
||||
this.B_Cancel.UseVisualStyleBackColor = true;
|
||||
this.B_Cancel.Click += new System.EventHandler(this.B_Cancel_Click);
|
||||
//
|
||||
// B_Save
|
||||
//
|
||||
this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.B_Save.Location = new System.Drawing.Point(977, 787);
|
||||
this.B_Save.Name = "B_Save";
|
||||
this.B_Save.Size = new System.Drawing.Size(72, 23);
|
||||
this.B_Save.TabIndex = 6;
|
||||
this.B_Save.Text = "Save";
|
||||
this.B_Save.UseVisualStyleBackColor = true;
|
||||
this.B_Save.Click += new System.EventHandler(this.B_Save_Click);
|
||||
//
|
||||
// FLP_Tile
|
||||
//
|
||||
this.FLP_Tile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.FLP_Tile.Location = new System.Drawing.Point(12, 12);
|
||||
this.FLP_Tile.Name = "FLP_Tile";
|
||||
this.FLP_Tile.Size = new System.Drawing.Size(802, 802);
|
||||
this.FLP_Tile.TabIndex = 8;
|
||||
//
|
||||
// PG_Tile
|
||||
//
|
||||
this.PG_Tile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.PG_Tile.Location = new System.Drawing.Point(820, 12);
|
||||
this.PG_Tile.Name = "PG_Tile";
|
||||
this.PG_Tile.Size = new System.Drawing.Size(229, 244);
|
||||
this.PG_Tile.TabIndex = 9;
|
||||
//
|
||||
// CB_Acre
|
||||
//
|
||||
this.CB_Acre.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.CB_Acre.FormattingEnabled = true;
|
||||
this.CB_Acre.Location = new System.Drawing.Point(978, 588);
|
||||
this.CB_Acre.Name = "CB_Acre";
|
||||
this.CB_Acre.Size = new System.Drawing.Size(49, 21);
|
||||
this.CB_Acre.TabIndex = 10;
|
||||
this.CB_Acre.SelectedIndexChanged += new System.EventHandler(this.ChangeAcre);
|
||||
//
|
||||
// L_Acre
|
||||
//
|
||||
this.L_Acre.AutoSize = true;
|
||||
this.L_Acre.Location = new System.Drawing.Point(940, 591);
|
||||
this.L_Acre.Name = "L_Acre";
|
||||
this.L_Acre.Size = new System.Drawing.Size(32, 13);
|
||||
this.L_Acre.TabIndex = 11;
|
||||
this.L_Acre.Text = "Acre:";
|
||||
//
|
||||
// B_ZeroElevation
|
||||
//
|
||||
this.B_ZeroElevation.Location = new System.Drawing.Point(820, 276);
|
||||
this.B_ZeroElevation.Name = "B_ZeroElevation";
|
||||
this.B_ZeroElevation.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_ZeroElevation.TabIndex = 12;
|
||||
this.B_ZeroElevation.Text = "Zero All Elevation";
|
||||
this.B_ZeroElevation.UseVisualStyleBackColor = true;
|
||||
this.B_ZeroElevation.Click += new System.EventHandler(this.B_ZeroElevation_Click);
|
||||
//
|
||||
// B_ClearAll
|
||||
//
|
||||
this.B_ClearAll.Location = new System.Drawing.Point(937, 276);
|
||||
this.B_ClearAll.Name = "B_ClearAll";
|
||||
this.B_ClearAll.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_ClearAll.TabIndex = 13;
|
||||
this.B_ClearAll.Text = "Reset All To Base\r\n(no Terrain)";
|
||||
this.B_ClearAll.UseVisualStyleBackColor = true;
|
||||
this.B_ClearAll.Click += new System.EventHandler(this.B_ClearAll_Click);
|
||||
//
|
||||
// B_DumpAcre
|
||||
//
|
||||
this.B_DumpAcre.Location = new System.Drawing.Point(820, 662);
|
||||
this.B_DumpAcre.Name = "B_DumpAcre";
|
||||
this.B_DumpAcre.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_DumpAcre.TabIndex = 14;
|
||||
this.B_DumpAcre.Text = "Dump Acre";
|
||||
this.B_DumpAcre.UseVisualStyleBackColor = true;
|
||||
this.B_DumpAcre.Click += new System.EventHandler(this.B_DumpAcre_Click);
|
||||
//
|
||||
// B_DumpAllAcres
|
||||
//
|
||||
this.B_DumpAllAcres.Location = new System.Drawing.Point(820, 708);
|
||||
this.B_DumpAllAcres.Name = "B_DumpAllAcres";
|
||||
this.B_DumpAllAcres.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_DumpAllAcres.TabIndex = 15;
|
||||
this.B_DumpAllAcres.Text = "Dump All Acres";
|
||||
this.B_DumpAllAcres.UseVisualStyleBackColor = true;
|
||||
this.B_DumpAllAcres.Click += new System.EventHandler(this.B_DumpAllAcres_Click);
|
||||
//
|
||||
// B_ImportAllAcres
|
||||
//
|
||||
this.B_ImportAllAcres.Location = new System.Drawing.Point(937, 708);
|
||||
this.B_ImportAllAcres.Name = "B_ImportAllAcres";
|
||||
this.B_ImportAllAcres.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_ImportAllAcres.TabIndex = 17;
|
||||
this.B_ImportAllAcres.Text = "Import All Acres";
|
||||
this.B_ImportAllAcres.UseVisualStyleBackColor = true;
|
||||
this.B_ImportAllAcres.Click += new System.EventHandler(this.B_ImportAllAcres_Click);
|
||||
//
|
||||
// B_ImportAcre
|
||||
//
|
||||
this.B_ImportAcre.Location = new System.Drawing.Point(937, 662);
|
||||
this.B_ImportAcre.Name = "B_ImportAcre";
|
||||
this.B_ImportAcre.Size = new System.Drawing.Size(112, 40);
|
||||
this.B_ImportAcre.TabIndex = 16;
|
||||
this.B_ImportAcre.Text = "Import Acre";
|
||||
this.B_ImportAcre.UseVisualStyleBackColor = true;
|
||||
this.B_ImportAcre.Click += new System.EventHandler(this.B_ImportAcre_Click);
|
||||
//
|
||||
// CM_Click
|
||||
//
|
||||
this.CM_Click.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.Menu_View,
|
||||
this.Menu_Set,
|
||||
this.Menu_Reset});
|
||||
this.CM_Click.Name = "CM_Click";
|
||||
this.CM_Click.Size = new System.Drawing.Size(103, 70);
|
||||
//
|
||||
// Menu_View
|
||||
//
|
||||
this.Menu_View.Name = "Menu_View";
|
||||
this.Menu_View.Size = new System.Drawing.Size(102, 22);
|
||||
this.Menu_View.Text = "View";
|
||||
this.Menu_View.Click += new System.EventHandler(this.Menu_View_Click);
|
||||
//
|
||||
// Menu_Set
|
||||
//
|
||||
this.Menu_Set.Name = "Menu_Set";
|
||||
this.Menu_Set.Size = new System.Drawing.Size(102, 22);
|
||||
this.Menu_Set.Text = "Set";
|
||||
this.Menu_Set.Click += new System.EventHandler(this.Menu_Set_Click);
|
||||
//
|
||||
// Menu_Reset
|
||||
//
|
||||
this.Menu_Reset.Name = "Menu_Reset";
|
||||
this.Menu_Reset.Size = new System.Drawing.Size(102, 22);
|
||||
this.Menu_Reset.Text = "Reset";
|
||||
this.Menu_Reset.Click += new System.EventHandler(this.Menu_Reset_Click);
|
||||
//
|
||||
// B_Up
|
||||
//
|
||||
this.B_Up.Location = new System.Drawing.Point(868, 551);
|
||||
this.B_Up.Name = "B_Up";
|
||||
this.B_Up.Size = new System.Drawing.Size(32, 32);
|
||||
this.B_Up.TabIndex = 18;
|
||||
this.B_Up.Text = "↑";
|
||||
this.B_Up.UseVisualStyleBackColor = true;
|
||||
this.B_Up.Click += new System.EventHandler(this.B_Up_Click);
|
||||
//
|
||||
// B_Left
|
||||
//
|
||||
this.B_Left.Location = new System.Drawing.Point(838, 581);
|
||||
this.B_Left.Name = "B_Left";
|
||||
this.B_Left.Size = new System.Drawing.Size(32, 32);
|
||||
this.B_Left.TabIndex = 19;
|
||||
this.B_Left.Text = "←";
|
||||
this.B_Left.UseVisualStyleBackColor = true;
|
||||
this.B_Left.Click += new System.EventHandler(this.B_Left_Click);
|
||||
//
|
||||
// B_Right
|
||||
//
|
||||
this.B_Right.Location = new System.Drawing.Point(898, 581);
|
||||
this.B_Right.Name = "B_Right";
|
||||
this.B_Right.Size = new System.Drawing.Size(32, 32);
|
||||
this.B_Right.TabIndex = 20;
|
||||
this.B_Right.Text = "→";
|
||||
this.B_Right.UseVisualStyleBackColor = true;
|
||||
this.B_Right.Click += new System.EventHandler(this.B_Right_Click);
|
||||
//
|
||||
// B_Down
|
||||
//
|
||||
this.B_Down.Location = new System.Drawing.Point(868, 611);
|
||||
this.B_Down.Name = "B_Down";
|
||||
this.B_Down.Size = new System.Drawing.Size(32, 32);
|
||||
this.B_Down.TabIndex = 22;
|
||||
this.B_Down.Text = "↓";
|
||||
this.B_Down.UseVisualStyleBackColor = true;
|
||||
this.B_Down.Click += new System.EventHandler(this.B_Down_Click);
|
||||
//
|
||||
// PB_Map
|
||||
//
|
||||
this.PB_Map.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.PB_Map.ContextMenuStrip = this.CM_Picture;
|
||||
this.PB_Map.Location = new System.Drawing.Point(821, 338);
|
||||
this.PB_Map.Name = "PB_Map";
|
||||
this.PB_Map.Size = new System.Drawing.Size(226, 194);
|
||||
this.PB_Map.TabIndex = 23;
|
||||
this.PB_Map.TabStop = false;
|
||||
//
|
||||
// CM_Picture
|
||||
//
|
||||
this.CM_Picture.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.Menu_SavePNG});
|
||||
this.CM_Picture.Name = "CM_Picture";
|
||||
this.CM_Picture.ShowImageMargin = false;
|
||||
this.CM_Picture.Size = new System.Drawing.Size(101, 26);
|
||||
//
|
||||
// Menu_SavePNG
|
||||
//
|
||||
this.Menu_SavePNG.Name = "Menu_SavePNG";
|
||||
this.Menu_SavePNG.Size = new System.Drawing.Size(155, 22);
|
||||
this.Menu_SavePNG.Text = "Save .png";
|
||||
this.Menu_SavePNG.Click += new System.EventHandler(this.Menu_SavePNG_Click);
|
||||
//
|
||||
// TerrainEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1061, 822);
|
||||
this.Controls.Add(this.PB_Map);
|
||||
this.Controls.Add(this.B_Down);
|
||||
this.Controls.Add(this.B_Right);
|
||||
this.Controls.Add(this.B_Left);
|
||||
this.Controls.Add(this.B_Up);
|
||||
this.Controls.Add(this.B_ImportAllAcres);
|
||||
this.Controls.Add(this.B_ImportAcre);
|
||||
this.Controls.Add(this.B_DumpAllAcres);
|
||||
this.Controls.Add(this.B_DumpAcre);
|
||||
this.Controls.Add(this.B_ClearAll);
|
||||
this.Controls.Add(this.B_ZeroElevation);
|
||||
this.Controls.Add(this.L_Acre);
|
||||
this.Controls.Add(this.CB_Acre);
|
||||
this.Controls.Add(this.PG_Tile);
|
||||
this.Controls.Add(this.FLP_Tile);
|
||||
this.Controls.Add(this.B_Cancel);
|
||||
this.Controls.Add(this.B_Save);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = global::NHSE.WinForms.Properties.Resources.icon;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "TerrainEditor";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Terrain Editor";
|
||||
this.CM_Click.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.PB_Map)).EndInit();
|
||||
this.CM_Picture.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button B_Cancel;
|
||||
private System.Windows.Forms.Button B_Save;
|
||||
private System.Windows.Forms.FlowLayoutPanel FLP_Tile;
|
||||
private System.Windows.Forms.PropertyGrid PG_Tile;
|
||||
private System.Windows.Forms.ComboBox CB_Acre;
|
||||
private System.Windows.Forms.Label L_Acre;
|
||||
private System.Windows.Forms.Button B_ZeroElevation;
|
||||
private System.Windows.Forms.Button B_ClearAll;
|
||||
private System.Windows.Forms.Button B_DumpAcre;
|
||||
private System.Windows.Forms.Button B_DumpAllAcres;
|
||||
private System.Windows.Forms.Button B_ImportAllAcres;
|
||||
private System.Windows.Forms.Button B_ImportAcre;
|
||||
private System.Windows.Forms.ContextMenuStrip CM_Click;
|
||||
private System.Windows.Forms.ToolStripMenuItem Menu_View;
|
||||
private System.Windows.Forms.ToolStripMenuItem Menu_Set;
|
||||
private System.Windows.Forms.ToolStripMenuItem Menu_Reset;
|
||||
private System.Windows.Forms.Button B_Up;
|
||||
private System.Windows.Forms.Button B_Left;
|
||||
private System.Windows.Forms.Button B_Right;
|
||||
private System.Windows.Forms.Button B_Down;
|
||||
private System.Windows.Forms.PictureBox PB_Map;
|
||||
private System.Windows.Forms.ContextMenuStrip CM_Picture;
|
||||
private System.Windows.Forms.ToolStripMenuItem Menu_SavePNG;
|
||||
}
|
||||
}
|
||||
302
NHSE.WinForms/Subforms/TerrainEditor.cs
Normal file
302
NHSE.WinForms/Subforms/TerrainEditor.cs
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using NHSE.Core;
|
||||
using NHSE.Sprites;
|
||||
|
||||
namespace NHSE.WinForms
|
||||
{
|
||||
public partial class TerrainEditor : Form
|
||||
{
|
||||
private readonly MainSave SAV;
|
||||
private readonly Button[] Grid;
|
||||
private readonly TerrainManager Terrain;
|
||||
|
||||
private const int SquareSize = 50;
|
||||
|
||||
public TerrainEditor(MainSave sav)
|
||||
{
|
||||
SAV = sav;
|
||||
InitializeComponent();
|
||||
|
||||
Terrain = new TerrainManager(SAV.Terrain);
|
||||
Grid = GenerateGrid(TerrainManager.GridWidth, TerrainManager.GridHeight);
|
||||
|
||||
foreach (var acre in Terrain.Acres)
|
||||
CB_Acre.Items.Add(acre.Name);
|
||||
|
||||
PG_Tile.SelectedObject = new TerrainTile();
|
||||
CB_Acre.SelectedIndex = 0;
|
||||
ReloadMap();
|
||||
}
|
||||
|
||||
private int AcreIndex => CB_Acre.SelectedIndex;
|
||||
private void ChangeAcre(object sender, EventArgs e) => LoadGrid(AcreIndex);
|
||||
|
||||
private void LoadGrid(int index)
|
||||
{
|
||||
for (int i = 0; i < TerrainManager.AcreSize; i++)
|
||||
{
|
||||
var b = Grid[i];
|
||||
var tile = Terrain.GetAcreTile(index, i);
|
||||
RefreshTile(b, tile);
|
||||
}
|
||||
UpdateArrowVisibility(index);
|
||||
}
|
||||
|
||||
private void ReloadMap()
|
||||
{
|
||||
var img = TerrainSprite.CreateMap(Terrain);
|
||||
PB_Map.Image = ImageUtil.ResizeImage(img, img.Width * 2, img.Height * 2);
|
||||
}
|
||||
|
||||
private void UpdateArrowVisibility(int index)
|
||||
{
|
||||
B_Up.Enabled = index > TerrainManager.AcreWidth;
|
||||
B_Down.Enabled = index < TerrainManager.AcreWidth * (TerrainManager.AcreHeight - 1);
|
||||
B_Left.Enabled = index % TerrainManager.AcreWidth != 0;
|
||||
B_Right.Enabled = index % TerrainManager.AcreWidth != TerrainManager.AcreWidth - 1;
|
||||
}
|
||||
|
||||
private Button[] GenerateGrid(int w, int h)
|
||||
{
|
||||
var grid = new Button[w * h];
|
||||
int i = 0;
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
var item = GetGridItem(index: i, x, y);
|
||||
FLP_Tile.Controls.Add(item);
|
||||
grid[i++] = item;
|
||||
}
|
||||
|
||||
var last = grid[i - 1];
|
||||
FLP_Tile.SetFlowBreak(last, true);
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
private Button GetGridItem(int index, int x, int y)
|
||||
{
|
||||
var button = new Button
|
||||
{
|
||||
Name = index.ToString(),
|
||||
Text = $"{index:000} ({x},{y})",
|
||||
Size = new Size(SquareSize, SquareSize),
|
||||
Padding = Padding.Empty,
|
||||
Margin = Padding.Empty,
|
||||
ContextMenuStrip = CM_Click,
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
};
|
||||
|
||||
button.Click += (sender, args) =>
|
||||
{
|
||||
GetTile(button, out var tile, out var obj);
|
||||
switch (ModifierKeys)
|
||||
{
|
||||
default: ViewTile(tile); return;
|
||||
case Keys.Shift: SetTile(tile, obj); return;
|
||||
case Keys.Alt: DeleteTile(tile, obj); return;
|
||||
}
|
||||
};
|
||||
return button;
|
||||
}
|
||||
|
||||
private void ViewTile(TerrainTile tile)
|
||||
{
|
||||
var pgt = (TerrainTile)PG_Tile.SelectedObject;
|
||||
pgt.CopyFrom(tile);
|
||||
PG_Tile.SelectedObject = pgt;
|
||||
}
|
||||
|
||||
private void SetTile(TerrainTile tile, Control obj)
|
||||
{
|
||||
var pgt = (TerrainTile)PG_Tile.SelectedObject;
|
||||
tile.CopyFrom(pgt);
|
||||
RefreshTile(obj, tile);
|
||||
ReloadMap();
|
||||
}
|
||||
|
||||
private void DeleteTile(TerrainTile tile, Control obj)
|
||||
{
|
||||
tile.Clear();
|
||||
RefreshTile(obj, tile);
|
||||
ReloadMap();
|
||||
}
|
||||
|
||||
private void B_Cancel_Click(object sender, EventArgs e) => Close();
|
||||
|
||||
private void B_Save_Click(object sender, EventArgs e)
|
||||
{
|
||||
SAV.Terrain = Terrain.Tiles;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Menu_View_Click(object sender, EventArgs e)
|
||||
{
|
||||
GetTile(sender, out var tile, out _);
|
||||
ViewTile(tile);
|
||||
}
|
||||
|
||||
private void Menu_Set_Click(object sender, EventArgs e)
|
||||
{
|
||||
GetTile(sender, out var tile, out var obj);
|
||||
SetTile(tile, obj);
|
||||
}
|
||||
|
||||
private void Menu_Reset_Click(object sender, EventArgs e)
|
||||
{
|
||||
GetTile(sender, out var tile, out var obj);
|
||||
DeleteTile(tile, obj);
|
||||
}
|
||||
|
||||
private void GetTile(object sender, out TerrainTile tile, out Button obj)
|
||||
{
|
||||
obj = WinFormsUtil.GetUnderlyingControl<Button>(sender) ?? throw new ArgumentNullException(nameof(sender));
|
||||
|
||||
var index = Array.IndexOf(Grid, obj);
|
||||
if (index < 0)
|
||||
throw new ArgumentException(nameof(Button));
|
||||
|
||||
tile = Terrain.GetAcreTile(AcreIndex, index);
|
||||
}
|
||||
|
||||
private static void RefreshTile(Control button, TerrainTile tile)
|
||||
{
|
||||
button.Text = TerrainSprite.GetTileName(tile);
|
||||
button.BackColor = TerrainSprite.GetTileColor(tile);
|
||||
}
|
||||
|
||||
private void B_Up_Click(object sender, EventArgs e) => CB_Acre.SelectedIndex -= TerrainManager.AcreWidth;
|
||||
private void B_Left_Click(object sender, EventArgs e) => --CB_Acre.SelectedIndex;
|
||||
private void B_Right_Click(object sender, EventArgs e) => ++CB_Acre.SelectedIndex;
|
||||
private void B_Down_Click(object sender, EventArgs e) => CB_Acre.SelectedIndex += TerrainManager.AcreWidth;
|
||||
|
||||
private void B_ZeroElevation_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var t in Terrain.Tiles)
|
||||
t.Elevation = 0;
|
||||
LoadGrid(AcreIndex);
|
||||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private void B_ClearAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var t in Terrain.Tiles)
|
||||
t.Clear();
|
||||
LoadGrid(AcreIndex);
|
||||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private void B_DumpAcre_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var sfd = new SaveFileDialog
|
||||
{
|
||||
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
|
||||
FileName = $"{CB_Acre.Text}.nht",
|
||||
};
|
||||
if (sfd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var path = sfd.FileName;
|
||||
var acre = AcreIndex;
|
||||
var data = Terrain.DumpAcre(acre);
|
||||
File.WriteAllBytes(path, data);
|
||||
}
|
||||
|
||||
private void B_DumpAllAcres_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var sfd = new SaveFileDialog
|
||||
{
|
||||
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
|
||||
FileName = $"{CB_Acre.Text}.nht",
|
||||
};
|
||||
if (sfd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var path = sfd.FileName;
|
||||
var data = Terrain.DumpAllAcres();
|
||||
File.WriteAllBytes(path, data);
|
||||
}
|
||||
|
||||
private void B_ImportAcre_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var ofd = new OpenFileDialog
|
||||
{
|
||||
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
|
||||
FileName = "terrainAcres.nht",
|
||||
};
|
||||
if (ofd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var path = ofd.FileName;
|
||||
var fi = new FileInfo(path);
|
||||
|
||||
const int expect = TerrainManager.AcreSize * TerrainTile.SIZE;
|
||||
if (fi.Length != expect)
|
||||
{
|
||||
WinFormsUtil.Error($"Expected size (0x{expect:X}) != Input size (0x{fi.Length:X}", path);
|
||||
return;
|
||||
}
|
||||
|
||||
var data = File.ReadAllBytes(path);
|
||||
Terrain.ImportAcre(AcreIndex, data);
|
||||
LoadGrid(AcreIndex);
|
||||
ReloadMap();
|
||||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private void B_ImportAllAcres_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var ofd = new OpenFileDialog
|
||||
{
|
||||
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
|
||||
FileName = "terrainAcres.nht",
|
||||
};
|
||||
if (ofd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var path = ofd.FileName;
|
||||
var fi = new FileInfo(path);
|
||||
|
||||
const int expect = TerrainManager.TileCount * TerrainTile.SIZE;
|
||||
if (fi.Length != expect)
|
||||
{
|
||||
WinFormsUtil.Error($"Expected size (0x{expect:X}) != Input size (0x{fi.Length:X}", path);
|
||||
return;
|
||||
}
|
||||
|
||||
var data = File.ReadAllBytes(path);
|
||||
Terrain.ImportAllAcres(data);
|
||||
LoadGrid(AcreIndex);
|
||||
ReloadMap();
|
||||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private void Menu_SavePNG_Click(object sender, EventArgs e)
|
||||
{
|
||||
var pb = WinFormsUtil.GetUnderlyingControl<PictureBox>(sender);
|
||||
if (pb?.Image == null)
|
||||
{
|
||||
WinFormsUtil.Alert("No picture loaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
const string name = "map";
|
||||
var bmp = pb.Image;
|
||||
using var sfd = new SaveFileDialog
|
||||
{
|
||||
Filter = "png file (*.png)|*.png|All files (*.*)|*.*",
|
||||
FileName = $"{name}.png",
|
||||
};
|
||||
if (sfd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
bmp.Save(sfd.FileName, ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
126
NHSE.WinForms/Subforms/TerrainEditor.resx
Normal file
126
NHSE.WinForms/Subforms/TerrainEditor.resx
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="CM_Click.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="CM_Picture.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>250, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
Loading…
Reference in New Issue
Block a user