using System; using System.Collections.Generic; namespace NHSE.Core { public class FieldItemLayer : ItemLayer { public const int TilesPerAcreDim = 32; public const int FieldItemWidth = TilesPerAcreDim * AcreWidth; public const int FieldItemHeight = TilesPerAcreDim * AcreHeight; public FieldItemLayer(Item[] tiles) : base(tiles, FieldItemWidth, FieldItemHeight, TilesPerAcreDim, TilesPerAcreDim) { } public Item GetTile(int acreX, int acreY, int gridX, int gridY) => this[GetTileIndex(acreX, acreY, gridX, gridY)]; public Item GetAcreTile(int acreIndex, int tileIndex) => this[GetAcreTileIndex(acreIndex, tileIndex)]; public byte[] DumpAcre(int acre) { int count = GridTileCount; var result = new byte[Item.SIZE * count]; for (int i = 0; i < count; i++) { var tile = GetAcreTile(acre, i); var bytes = tile.ToBytesClass(); bytes.CopyTo(result, i * Item.SIZE); } return result; } public void ImportAcre(int acre, byte[] data) { int count = GridTileCount; var tiles = Item.GetArray(data); for (int i = 0; i < count; i++) { var tile = GetAcreTile(acre, i); tile.CopyFrom(tiles[i]); } } public int ClearFieldPlanted(Func criteria) => ClearFieldPlanted(0, 0, MaxWidth, MaxHeight, criteria); public int RemoveAll(Func criteria) => RemoveAll(0, 0, MaxWidth, MaxHeight, criteria); public int RemoveAll(HashSet items) => RemoveAll(0, 0, MaxWidth, MaxHeight, z => items.Contains(z.DisplayItemId)); public int RemoveAll(ushort item) => RemoveAll(0, 0, MaxWidth, MaxHeight, z => z.DisplayItemId == item); public int ClearFieldPlanted(int xmin, int ymin, int width, int height, Func criteria) { int count = 0; var fi = FieldItemList.Items; for (int x = xmin; x < xmin + width; x++) { for (int y = ymin; y < ymin + height; y++) { var t = GetTile(x, y); var disp = t.DisplayItemId; if (!fi.TryGetValue(disp, out var val)) continue; if (!criteria(val.Kind)) continue; t.Delete(); count++; } } return count; } public int ModifyAll(int xmin, int ymin, int width, int height, Func criteria, Action action) { int count = 0; for (int x = xmin; x < xmin + width; x++) { for (int y = ymin; y < ymin + height; y++) { var t = GetTile(x, y); if (!criteria(t)) continue; action(t); count++; } } return count; } public int RemoveAllHoles(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z == FieldItemKind.UnitIconHole); public int RemoveAllWeeds(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsWeed()); public int RemoveAllTrees(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsTree()); public int RemoveAllPlants(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsPlant()); public int RemoveAllFences(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsFence()); public int RemoveAllFlowers(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsFlower()); public int RemoveAllBushes(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, z => z.IsBush()); public int RemoveAllObjects(int xmin, int ymin, int width, int height) => ClearFieldPlanted(xmin, ymin, width, height, _ => true); public int RemoveAll(int xmin, int ymin, int width, int height) => RemoveAll(xmin, ymin, width, height, _ => true); public int RemoveAllShells(int xmin, int ymin, int width, int height) => RemoveAll(xmin, ymin, width, height, z => GameLists.Shells.Contains(z.DisplayItemId)); public int RemoveAllBranches(int xmin, int ymin, int width, int height) => RemoveAll(xmin, ymin, width, height, z => z.DisplayItemId == 2500); public int RemoveAllPlacedItems(int xmin, int ymin, int width, int height) => RemoveAll(xmin, ymin, width, height, z => !z.IsNone && !FieldItemList.Items.ContainsKey(z.DisplayItemId)); public int RemoveAllLike(int xmin, int ymin, int width, int height, Item item) => RemoveAll(xmin, ymin, width, height, z => !z.IsNone && item.DisplayItemId == z.DisplayItemId); public int WaterAllFlowers(int xmin, int ymin, int width, int height, bool all) { var fi = FieldItemList.Items; bool IsFlowerWaterable(Item item) { if (item.IsNone) return false; if (!item.IsRoot) return false; if (!fi.TryGetValue(item.ItemId, out var def)) return false; if (!def.Kind.IsFlower()) return false; return true; } return ModifyAll(xmin, ymin, width, height, IsFlowerWaterable, z => z.Water(all)); } } }