mirror of
https://github.com/kwsch/NHSE.git
synced 2026-04-22 08:27:28 -05:00
Add layer2->layer1 check (isSupported), add logic for isActive
isActive: indicates if the tile is animated (eg: bonfire has fire or is extinguished) isSupported: layer2 tile checks beneath it (layer1) to see if there's something to hold it up on that layer (sanity check) Dunno how to handle the isActive set-on-save. I saw there was an isActive flag in my plaza, assumedly left there from a radio or something. NHSE does not change flag state at this time.
This commit is contained in:
parent
8edf0a6ec4
commit
4a49caf6da
|
|
@ -182,8 +182,19 @@ public void SetAcreBytes(byte[] data)
|
|||
public TerrainTile[] GetTerrainTiles() => TerrainTile.GetArray(Data.Slice(Offsets.LandMakingMap, MapGrid.MapTileCount16x16 * TerrainTile.SIZE));
|
||||
public void SetTerrainTiles(IReadOnlyList<TerrainTile> array) => TerrainTile.SetArray(array).CopyTo(Data, Offsets.LandMakingMap);
|
||||
|
||||
public FieldItem[] GetFieldItems() => FieldItem.GetArray(Data.Slice(Offsets.FieldItem, MapGrid.MapTileCount32x32 * FieldItem.SIZE * 2));
|
||||
public void SetFieldItems(IReadOnlyList<FieldItem> array) => FieldItem.SetArray(array).CopyTo(Data, Offsets.FieldItem);
|
||||
private const int FieldItemLayerSize = MapGrid.MapTileCount32x32 * FieldItem.SIZE;
|
||||
private const int FieldItemFlagSize = MapGrid.MapTileCount32x32 / 8; // bitflags
|
||||
|
||||
private int FieldItemLayer1 => Offsets.FieldItem;
|
||||
private int FieldItemLayer2 => Offsets.FieldItem + FieldItemLayerSize;
|
||||
public int FieldItemFlag1 => Offsets.FieldItem + (FieldItemLayerSize * 2);
|
||||
public int FieldItemFlag2 => Offsets.FieldItem + (FieldItemLayerSize * 2) + FieldItemFlagSize;
|
||||
|
||||
public FieldItem[] GetFieldItemLayer1() => FieldItem.GetArray(Data.Slice(FieldItemLayer1, FieldItemLayerSize));
|
||||
public void SetFieldItemLayer1(IReadOnlyList<FieldItem> array) => FieldItem.SetArray(array).CopyTo(Data, FieldItemLayer1);
|
||||
|
||||
public FieldItem[] GetFieldItemLayer2() => FieldItem.GetArray(Data.Slice(FieldItemLayer2, FieldItemLayerSize));
|
||||
public void SetFieldItemLayer2(IReadOnlyList<FieldItem> array) => FieldItem.SetArray(array).CopyTo(Data, FieldItemLayer2);
|
||||
|
||||
public ushort OutsideFieldTemplateUniqueId
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NHSE.Core
|
||||
{
|
||||
|
|
@ -7,30 +8,67 @@ public class FieldItemManager
|
|||
public readonly FieldItemLayer Layer1;
|
||||
public readonly FieldItemLayer Layer2;
|
||||
|
||||
public FieldItemManager(FieldItem[] layer1, FieldItem[] layer2)
|
||||
public readonly MainSave SAV;
|
||||
|
||||
public FieldItemManager(MainSave sav)
|
||||
{
|
||||
Layer1 = new FieldItemLayer(layer1);
|
||||
Layer2 = new FieldItemLayer(layer2);
|
||||
Layer1 = new FieldItemLayer(sav.GetFieldItemLayer1());
|
||||
Layer2 = new FieldItemLayer(sav.GetFieldItemLayer2());
|
||||
SAV = sav;
|
||||
}
|
||||
|
||||
public FieldItemManager(FieldItem[] items, int layers = 2) // Two halves; split and assign.
|
||||
: this(items.Slice(0, items.Length / 2), items.SliceEnd(items.Length / 2))
|
||||
public void Save()
|
||||
{
|
||||
if (layers != 2)
|
||||
throw new ArgumentOutOfRangeException(nameof(layers));
|
||||
SAV.SetFieldItemLayer1(Layer1.Tiles);
|
||||
SAV.SetFieldItemLayer2(Layer2.Tiles);
|
||||
|
||||
SetTileActiveFlags(Layer1, SAV.FieldItemFlag1);
|
||||
SetTileActiveFlags(Layer2, SAV.FieldItemFlag2);
|
||||
}
|
||||
|
||||
public FieldItem GetTile(int layer, int x, int y) => GetLayer(layer).GetTile(x, y);
|
||||
public FieldItem GetTile(int layer, int acreX, int acreY, int gridX, int gridY) => GetLayer(layer).GetTile(acreX, acreY, gridX, gridY);
|
||||
public FieldItem GetAcreTile(int layer, int acreIndex, int tileIndex) => GetLayer(layer).GetAcreTile(acreIndex, tileIndex);
|
||||
|
||||
public FieldItemLayer GetLayer(int layer)
|
||||
public List<string> GetUnsupportedTiles()
|
||||
{
|
||||
if ((uint) layer >= 2)
|
||||
throw new ArgumentOutOfRangeException(nameof(layer));
|
||||
return layer == 0 ? Layer1 : Layer2;
|
||||
var result = new List<string>();
|
||||
for (int x = 0; x < 224; x++)
|
||||
{
|
||||
for (int y = 0; y < 192; y++)
|
||||
{
|
||||
var tile = Layer2.GetTile(x, y);
|
||||
if (tile.IsNone)
|
||||
continue;
|
||||
|
||||
var support = Layer1.GetTile(x, y);
|
||||
if (!support.IsNone)
|
||||
continue; // dunno how to check if the tile can actually have an item put on top of it...
|
||||
|
||||
result.Add($"{x:000},{y:000}");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SetTileActiveFlags(FieldItemLayer tiles, int ofs)
|
||||
{
|
||||
// Although the Tiles are arranged y-column (y-x) based, the 'isActive' flags are arranged x-row (x-y) based.
|
||||
// We can turn the isActive flag off if the item is not a root or the item cannot be animated.
|
||||
for (int x = 0; x < 224; x++)
|
||||
{
|
||||
for (int y = 0; y < 192; y++)
|
||||
{
|
||||
var tile = tiles.GetTile(x, y);
|
||||
var isActive = IsActive(ofs, x, y);
|
||||
if (!isActive)
|
||||
continue;
|
||||
|
||||
bool empty = tile.IsNone;
|
||||
if (empty)
|
||||
Debug.WriteLine($"Flag at ({x},{y}) is not a root object.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsActive(bool baseLayer, int x, int y) => IsActive(baseLayer ? SAV.FieldItemFlag1 : SAV.FieldItemFlag2, x, y);
|
||||
private bool IsActive(int ofs, int x, int y) => FlagUtil.GetFlag(SAV.Data, ofs, (y * 224) + x);
|
||||
public bool IsOccupied(int x, int y) => !Layer1.GetTile(x, y).IsNone || !Layer2.GetTile(x, y).IsNone;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public class MapManager : MapTerrainStructure
|
|||
|
||||
public MapManager(MainSave sav) : base(sav)
|
||||
{
|
||||
Items = new FieldItemManager(sav.GetFieldItems());
|
||||
Items = new FieldItemManager(sav);
|
||||
}
|
||||
|
||||
public FieldItemLayer CurrentLayer => MapLayer == 0 ? Items.Layer1 : Items.Layer2;
|
||||
|
|
|
|||
|
|
@ -176,12 +176,13 @@ private void PB_Acre_MouseMove(object sender, MouseEventArgs e)
|
|||
{
|
||||
var l = Map.CurrentLayer;
|
||||
var oldTile = l.GetTile(View.X + HoverX, View.Y + HoverY);
|
||||
var tile = GetTile(l, e, out _, out _);
|
||||
var tile = GetTile(l, e, out var x, out var y);
|
||||
if (tile == oldTile)
|
||||
return;
|
||||
var str = GameInfo.Strings;
|
||||
var name = str.GetItemName(tile);
|
||||
TT_Hover.SetToolTip(PB_Acre, name);
|
||||
SetCoordinateText(x, y);
|
||||
}
|
||||
|
||||
private void ViewTile(FieldItem tile)
|
||||
|
|
@ -251,8 +252,17 @@ private void DeleteTile(TerrainTile tile)
|
|||
|
||||
private void B_Save_Click(object sender, EventArgs e)
|
||||
{
|
||||
var all = ArrayUtil.ConcatAll(Map.Items.Layer1.Tiles, Map.Items.Layer2.Tiles);
|
||||
SAV.SetFieldItems(all);
|
||||
var unsupported = Map.Items.GetUnsupportedTiles();
|
||||
if (unsupported.Count != 0)
|
||||
{
|
||||
var err = MessageStrings.MsgFieldItemUnsupportedLayer2Tile;
|
||||
var ask = MessageStrings.MsgAskContinue;
|
||||
var prompt = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, err, ask);
|
||||
if (prompt != DialogResult.Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
Map.Items.Save();
|
||||
SAV.SetTerrainTiles(Map.Terrain.Tiles);
|
||||
SAV.Buildings = Map.Buildings;
|
||||
SAV.PlazaX = Map.PlazaX;
|
||||
|
|
@ -468,10 +478,12 @@ private void PB_Map_MouseMove(object sender, MouseEventArgs e)
|
|||
else
|
||||
{
|
||||
View.GetCursorCoordinates(e.X, e.Y, out var x, out var y);
|
||||
L_Coordinates.Text = $"({x:000},{y:000}) = (0x{x:X2},0x{y:X2})";
|
||||
SetCoordinateText(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCoordinateText(int x, int y) => L_Coordinates.Text = $"({x:000},{y:000}) = (0x{x:X2},0x{y:X2})";
|
||||
|
||||
private void NUD_Layer_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
Map.MapLayer = (int) NUD_Layer.Value - 1;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public static class MessageStrings
|
|||
public static string MsgFieldItemRemoveAsk { get; set; } = "Are you sure you want to remove {0}?";
|
||||
public static string MsgFieldItemRemoveNone { get; set; } = "Nothing removed (none found).";
|
||||
public static string MsgFieldItemRemoveCount { get; set; } = "Removed {0} from the map.";
|
||||
public static string MsgFieldItemUnsupportedLayer2Tile { get; set; } = "Unsupported Layer2 items detected.";
|
||||
|
||||
public static string MsgSysBotInfo { get; set; } = "This SysBot reads and writes RAM directly to your game when called to Read/Write.";
|
||||
public static string MsgSysBotRequired { get; set; } = "Using this functionality requires the sys-botbase sysmodule running on the console. Your console must be on the same network as the PC running this program.";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user