using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace WOMGeneral { public class CellBase { public const int CELL_WIDTH = 8; public const int CELL_HEIGHT = 8; public const int CELL_PIXELWIDTH = 128; public const int CELL_PIXELHEIGHT = 128; public int x = 0; public int y = 0; public TileBase[,] tiles = new TileBase[CELL_WIDTH, CELL_HEIGHT]; public CellBase() { Initialize(); } public CellBase(byte[] serialized) { Deserialize(serialized); } public void Initialize() where T : TileBase, new() { for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { tiles[ix, iy] = new T(); AdjustTilePosition(ix, iy); } } } public void Deserialize(byte[] serialized) where T : TileBase, new() { MemoryStream ms = new MemoryStream(serialized); int serializeVersion = ms.ReadByte(); switch (serializeVersion) { case 1: //Location, followed by full serialized tiles preceded by 2-byte lengths this.x = UtilBase.ReadTwoBytes(ms.ReadByte(), ms.ReadByte()); this.y = UtilBase.ReadTwoBytes(ms.ReadByte(), ms.ReadByte()); for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { int tileLength = UtilBase.ReadTwoBytes(ms.ReadByte(), ms.ReadByte()); byte[] serializedTile = new byte[tileLength]; ms.Read(serializedTile, 0, tileLength); tiles[ix, iy] = new T(); tiles[ix, iy].Deserialize(serializedTile); AdjustTilePosition(ix, iy); } } break; case 2: //Location, but the cell is completely empty this.x = UtilBase.ReadTwoBytes(ms.ReadByte(), ms.ReadByte()); this.y = UtilBase.ReadTwoBytes(ms.ReadByte(), ms.ReadByte()); for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { tiles[ix, iy] = new T(); AdjustTilePosition(ix, iy); } } break; } ms.Close(); } public virtual byte[] Serialize(int specifiedVersion = -1) { //Store byte arrays rather than separate bytes to avoid using a bazillion slow List.Add calls List toReturn = new List(); if (specifiedVersion == -1) //Default; choose which to use { specifiedVersion = 1; } toReturn.Add(new byte[] { (byte)specifiedVersion }); switch (specifiedVersion) { case 1: toReturn.Add(UtilBase.WriteTwoBytes(x)); toReturn.Add(UtilBase.WriteTwoBytes(y)); for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { byte[] serializedTile = tiles[ix, iy].Serialize(); toReturn.Add(UtilBase.WriteTwoBytes(serializedTile.Length)); toReturn.Add(serializedTile); } } break; case 2: toReturn.Add(UtilBase.WriteTwoBytes(x)); toReturn.Add(UtilBase.WriteTwoBytes(y)); break; } //Finally, convert the thing to a byte array //1. Count the combined length of the byte arrays int arrayLength = 0; for (int i = 0; i < toReturn.Count; i++) { arrayLength += toReturn[i].Length; } //2. Merge into one array byte[] returnArray = new byte[arrayLength]; long currentPosition = 0; for (int i = 0; i < toReturn.Count; i++) { byte[] relevantArray = toReturn[i]; for (int ii = 0; ii < relevantArray.Length; ii++) { returnArray[currentPosition] = relevantArray[ii]; currentPosition++; } } return returnArray; } public virtual void Move(int offsetX, int offsetY) { for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { tiles[ix, iy].Move(offsetX, offsetY); } } } public virtual void EraseCell() { for (int iy = 0; iy < CELL_HEIGHT; iy++) { for (int ix = 0; ix < CELL_WIDTH; ix++) { tiles[ix, iy].EraseTile(); } } } //Allow program to move sprite to proper position public virtual void AdjustTilePosition(int x, int y) { } } }