mirror of
https://github.com/kwsch/NHSE.git
synced 2026-10-02 06:46:36 -05:00
Add item[]->field item column/offset for injection
This commit is contained in:
24
NHSE.Core/Editing/FieldItem/FieldItemColumn.cs
Normal file
24
NHSE.Core/Editing/FieldItem/FieldItemColumn.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace NHSE.Core
|
||||
{
|
||||
public sealed class FieldItemColumn
|
||||
{
|
||||
/// <summary> X Coordinate within the Field Item Layer </summary>
|
||||
public readonly int X;
|
||||
|
||||
/// <summary> Y Coordinate within the Field Item Layer </summary>
|
||||
public readonly int Y;
|
||||
|
||||
/// <summary> Offset relative to the start of the Field Item Layer </summary>
|
||||
public readonly int Offset;
|
||||
|
||||
public readonly byte[] Data;
|
||||
|
||||
public FieldItemColumn(int x, int y, int offset, byte[] data)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Offset = offset;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
103
NHSE.Core/Editing/FieldItem/FieldItemDropper.cs
Normal file
103
NHSE.Core/Editing/FieldItem/FieldItemDropper.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NHSE.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts <see cref="Item"/> into columns of writable Item tiles.
|
||||
/// </summary>
|
||||
public static class FieldItemDropper
|
||||
{
|
||||
private const int MapHeight = FieldItemLayer.FieldItemHeight;
|
||||
private const int MapWidth = FieldItemLayer.FieldItemWidth;
|
||||
|
||||
// Each dropped item is a 2x2 square, with the top left tile being the root node, and the other 3 being extensions pointing back to the root.
|
||||
|
||||
public static bool CanFitDropped(int x, int y, int count, int vStride)
|
||||
{
|
||||
if (2 * (Math.Max(16, y) + vStride) > MapHeight - 32)
|
||||
return false;
|
||||
|
||||
var xStride = count / vStride;
|
||||
if (2 * (Math.Max(16, x) + xStride) > MapWidth - 32)
|
||||
return false;
|
||||
|
||||
return count < (MapHeight * MapWidth / 32);
|
||||
}
|
||||
|
||||
public static IReadOnlyList<FieldItemColumn> InjectItemsAsDropped(int mapX, int mapY, IReadOnlyList<Item> item)
|
||||
{
|
||||
int yStride = (item.Count > 16) ? 16 : item.Count;
|
||||
return InjectItemsAsDropped(mapX, mapY, item, yStride);
|
||||
}
|
||||
|
||||
public static IReadOnlyList<FieldItemColumn> InjectItemsAsDropped(int mapX, int mapY, IReadOnlyList<Item> item, int yStride)
|
||||
{
|
||||
var xStride = item.Count / yStride;
|
||||
List<FieldItemColumn> result = new(yStride * xStride);
|
||||
for (int i = 0; i < xStride; i++)
|
||||
{
|
||||
var x = mapX + (i * 2);
|
||||
var y = mapY;
|
||||
var itemSlice = item.Skip(i * yStride).Take(yStride).ToArray();
|
||||
|
||||
// Root+ExtensionY
|
||||
var offset = GetTileOffset(x, y);
|
||||
var data = GetColumnRoot(itemSlice);
|
||||
var column = new FieldItemColumn(x, y, offset, data);
|
||||
result.Add(column);
|
||||
|
||||
// Ex X/XY
|
||||
++x;
|
||||
offset = GetTileOffset(x, y);
|
||||
data = GetColumnExtension(itemSlice);
|
||||
column = new FieldItemColumn(x, y, offset, data);
|
||||
result.Add(column);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] GetColumnRoot(Item[] items)
|
||||
{
|
||||
var col = new Item[items.Length * 2];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
var idx = i * 2;
|
||||
col[idx] = GetDroppedItem(item);
|
||||
col[idx + 1] = GetExtension(item, 0, 1);
|
||||
}
|
||||
return Item.SetArray(col);
|
||||
}
|
||||
|
||||
private static byte[] GetColumnExtension(Item[] items)
|
||||
{
|
||||
var col = new Item[items.Length * 2];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
var idx = i * 2;
|
||||
col[idx] = GetExtension(item, 1, 0);
|
||||
col[idx + 1] = GetExtension(item, 1, 1);
|
||||
}
|
||||
return Item.SetArray(col);
|
||||
}
|
||||
|
||||
private static int GetTileOffset(int x, int y)
|
||||
{
|
||||
return Item.SIZE * (y + (x * MapHeight));
|
||||
}
|
||||
|
||||
private static Item GetDroppedItem(Item item)
|
||||
{
|
||||
var copy = new Item();
|
||||
copy.CopyFrom(item);
|
||||
copy.ClearFlags();
|
||||
copy.IsDropped = true;
|
||||
return copy;
|
||||
}
|
||||
|
||||
private static Item GetExtension(Item item, byte x, byte y) => new(Item.EXTENSION) { ExtensionItemId = item.ItemId, ExtensionX = x, ExtensionY = y };
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,14 @@ public class Item : ICopyableItem<Item>
|
||||
[field: FieldOffset(3)] public byte AdditionalParam { get; set; }
|
||||
[field: FieldOffset(4)] public int FreeParam { get; set; }
|
||||
|
||||
public int Rotation => SystemParam & 3;
|
||||
public bool IsBuried => (SystemParam & 4) != 0;
|
||||
public bool Is_08 => (SystemParam & 0x08) != 0;
|
||||
public bool Is_10 => (SystemParam & 0x10) != 0;
|
||||
public bool IsDropped => (SystemParam & 0x20) != 0;
|
||||
public bool Is_40 => (SystemParam & 0x40) != 0;
|
||||
public bool Is_80 => (SystemParam & 0x80) != 0;
|
||||
public void ClearFlags() => SystemParam = 0;
|
||||
public int Rotation { get => SystemParam & 3; set => SystemParam = (byte)((SystemParam & ~3) | (value & 3)); }
|
||||
public bool IsBuried { get => (SystemParam & 0x04) != 0; set => SystemParam = (byte) ((SystemParam & ~0x04) | (value ? 0x04 : 0)); }
|
||||
public bool Is_08 { get => (SystemParam & 0x08) != 0; set => SystemParam = (byte) ((SystemParam & ~0x08) | (value ? 0x08 : 0)); }
|
||||
public bool Is_10 { get => (SystemParam & 0x10) != 0; set => SystemParam = (byte) ((SystemParam & ~0x10) | (value ? 0x10 : 0)); }
|
||||
public bool IsDropped { get => (SystemParam & 0x20) != 0; set => SystemParam = (byte) ((SystemParam & ~0x20) | (value ? 0x20 : 0)); }
|
||||
public bool Is_40 { get => (SystemParam & 0x40) != 0; set => SystemParam = (byte) ((SystemParam & ~0x40) | (value ? 0x40 : 0)); }
|
||||
public bool Is_80 { get => (SystemParam & 0x80) != 0; set => SystemParam = (byte) ((SystemParam & ~0x80) | (value ? 0x80 : 0)); }
|
||||
|
||||
#region Flag1 (Wrapping / Etc)
|
||||
public bool IsWrapped
|
||||
|
||||
Reference in New Issue
Block a user