static void Read2DArray(BinBuffer bb, ModIdMap map, int xLen, int yLen, Action <int, int, int> setElemV, Action <int, int, ObjectRef> setElemM) { var dictPos = bb.ReadInt32(); var dataStart = bb.Position; bb.Position = dictPos; map.ReadDictionary(bb); var endOfStream = bb.Position; bb.Position = dataStart; int amt = 0; bool isM = false; ObjectRef curM = ObjectRef.Null; int curV = 0; for (int y = 0; y < yLen; y++) { for (int x = 0; x < xLen; x++) { if (amt == 0) { map.GetRef(bb.ReadUInt32(), oid => { curV = oid; isM = false; setElemV(x, y, curV); // amt == 0 -> one element }, or => { curM = or; isM = true; setElemM(x, y, curM); // amt == 0 -> one element }); amt = bb.ReadUInt16(); } else { if (isM) { setElemM(x, y, curM); } else { setElemV(x, y, curV); } amt--; } } } bb.Position = endOfStream; }
static void SaveWallTypes(BinBuffer bb) { var map = new ModIdMap(WallID.Count, or => WallDef.Defs[or].Type, id => Handler.WallDef.DefsByType[id]); Write2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y) => Main.tile[x, y] == null || Main.tile[x, y].wall <= 0, (x, y) => Main.tile[x, y].wall >= WallID.Count ? 0 : Main.tile[x, y].wall, (x, y) => Main.tile[x, y].wall < WallID.Count || !Handler.WallDef.DefsByType.ContainsKey(Main.tile[x, y].wall) ? ObjectRef.Null : Handler.WallDef.DefsByType[Main.tile[x, y].wall]); }
static void SaveTileTypes(BinBuffer bb) { var map = new ModIdMap(TileID.Count, or => TileDef.Defs[or].Type, id => Handler.TileDef.DefsByType[id]); Write2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y) => Main.tile[x, y] == null || Main.tile[x, y].type <= 0, // 0 -> dirt wall, but this works here, too (x, y) => Main.tile[x, y].type >= TileID.Count ? 0 : Main.tile[x, y].type, (x, y) => Main.tile[x, y].type < TileID.Count || !Handler.TileDef.DefsByType.ContainsKey(Main.tile[x, y].type) ? ObjectRef.Null : Handler.TileDef.DefsByType[Main.tile[x, y].type]); }
static void SaveTileTypes(BinBuffer bb) { // don't write anything for now, custom tiles aren't implemented return; #pragma warning disable 162 var map = new ModIdMap(TileID.Count, or => new TileRef(or).Resolve().Type, id => new TileRef(id)); #pragma warning restore 162 int ot = 0; int amt = 0; bool once = true; int op = bb.Position; bb.Write(0); for (int y = 0; y < Main.maxTilesY; y++) { for (int x = 0; x < Main.maxTilesX; x++) { int t = Main.tile[x, y] == null || !Main.tile[x, y].active() ? 0 : Main.tile[x, y].type; if (once) { ot = t; bb.Write(map.Register(new TileRef(t))); once = false; continue; } if (t == ot && amt < UInt16.MaxValue) { amt++; } else { bb.Write((ushort)amt); // write the amount of successing tiles of the same type, // instead of the type over and over again, to save some space amt = 0; ot = t; bb.Write(map.Register(new TileRef(t))); } } } bb.Write((ushort)amt); var p = bb.Position; bb.Position = op; bb.Write(p - op); // dictionary offset bb.Position = p; map.WriteDictionary(bb); }
static void LoadWallTypes(BinBuffer bb, int v) { if (v < 1) // custom walls introduced in v1 { return; } var map = new ModIdMap(WallID.Count, or => WallDef.Defs[or].Type, id => Handler.WallDef.DefsByType[id]); Read2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y, id) => Main.tile[x, y].wall = (ushort)id, (x, y, or) => Main.tile[x, y].wall = (ushort)WallDef.Defs[or].Type); }
static void LoadTileTypes(BinBuffer bb, int v) { if (v < 2 /* v2: added tile support */) { return; } var map = new ModIdMap(TileID.Count, or => TileDef.Defs[or].Type, id => Handler.TileDef.DefsByType[id]); Read2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y, id) => Main.tile[x, y].type = (ushort)id, (x, y, or) => Main.tile[x, y].type = (ushort)TileDef.Defs[or].Type); }
static void LoadTileTypes(BinBuffer bb, int v) { // don't read anything for now, custom tiles aren't implemented return; #pragma warning disable 162 // to be used in future versions if (v == 0) { return; } #pragma warning restore 162 var map = new ModIdMap(TileID.Count, or => new TileRef(or).Resolve().Type, id => new TileRef(id)); var tp = bb.Position; var dictOffset = bb.ReadInt32(); bb.Position += dictOffset; map.ReadDictionary(bb); var end = bb.Position; bb.Position = tp; int amt = 0; for (int y = 0; y < Main.maxTilesY; y++) { for (int x = 0; x < Main.maxTilesX; x++) { if (amt == 0) { var t = bb.ReadUInt32(); Main.tile[x, y].type = (ushort)new TileRef(map.GetRef(t)).Resolve().Type; amt = bb.ReadUInt16(); } else { amt--; } } } bb.Position = end; }
//TODO: make these faster (especially write) static void Write2DArray(BinBuffer bb, ModIdMap map, int xLen, int yLen, Func <int, int, bool> isEmpty, Func <int, int, int> getElemV, Func <int, int, ObjectRef> getElemM) { var ov = 0; var ot = ObjectRef.Null; bool isOV = true; int amt = 0; bool once = true; int dictOffsetPosition = bb.Position; bb.Write(0); // dictionary position for (int y = 0; y < yLen; y++) { for (int x = 0; x < xLen; x++) { var e = isEmpty(x, y); var v = e ? 0 : getElemV(x, y); var t = ObjectRef.Null; var isV = e || v > 0; if (!e && v == 0) { t = getElemM(x, y); isV = false; } if (once) { if (isV) { ov = v; } else { ot = t; } isOV = isV; bb.Write((uint)(isV ? map.Register(v) : map.Register(t))); once = false; } else if (isV == isOV && (isV ? v == ov : t == ot) && amt < UInt16.MaxValue) { amt++; } else { bb.Write((ushort)amt); // write the amount of successing elements of the same type, // instead of the type over and over again, to save some space amt = 0; // amt == 0 -> one element if (isV) { ov = v; } else { ot = t; } isOV = isV; bb.Write((uint)(isV ? map.Register(v) : map.Register(t))); } } } bb.Write((ushort)amt); // write final amt var afterData = bb.Position; bb.Position = dictOffsetPosition; bb.Write(afterData); // dictionary position bb.Position = afterData; map.WriteDictionary(bb); }
//TODO: make these faster (especially write) static void Write2DArray(BinBuffer bb, ModIdMap map, int xLen, int yLen, Func <int, int, bool> isEmpty , Func <int, int, int > getElemV, Func<int, int, ObjectRef> getElemM) { var ov = 0; var ot = ObjectRef.Null; bool isOV = true; int amt = 0; bool once = true; int dictOffsetPosition = bb.Position; bb.Write(0); // dictionary position for (int y = 0; y < yLen; y++) for (int x = 0; x < xLen; x++) { var e = isEmpty(x, y); var v = e ? 0 : getElemV(x, y); var t = ObjectRef.Null; var isV = e || v > 0; if (!e && v == 0) { t = getElemM(x, y); isV = false; } if (once) { if (isV) ov = v; else ot = t; isOV = isV; bb.Write((uint)(isV ? map.Register(v) : map.Register(t))); once = false; } else if (isV == isOV && (isV ? v == ov : t == ot) && amt < UInt16.MaxValue) amt++; else { bb.Write((ushort)amt); // write the amount of successing elements of the same type, // instead of the type over and over again, to save some space amt = 0; // amt == 0 -> one element if (isV) ov = v; else ot = t; isOV = isV; bb.Write((uint)(isV ? map.Register(v) : map.Register(t))); } } bb.Write((ushort)amt); // write final amt var afterData = bb.Position; bb.Position = dictOffsetPosition; bb.Write(afterData); // dictionary position bb.Position = afterData; map.WriteDictionary(bb); }
static void Read2DArray(BinBuffer bb, ModIdMap map, int xLen, int yLen, Action<int, int, int > setElemV, Action<int, int, ObjectRef> setElemM) { var dictPos = bb.ReadInt32(); var dataStart = bb.Position; bb.Position = dictPos; map.ReadDictionary(bb); var endOfStream = bb.Position; bb.Position = dataStart; int amt = 0; bool isM = false; ObjectRef curM = ObjectRef.Null; int curV = 0; for (int y = 0; y < yLen; y++) for (int x = 0; x < xLen; x++) if (amt == 0) { map.GetRef(bb.ReadUInt32(), oid => { curV = oid; isM = false; setElemV(x, y, curV); // amt == 0 -> one element }, or => { curM = or; isM = true; setElemM(x, y, curM); // amt == 0 -> one element }); amt = bb.ReadUInt16(); } else { if (isM) setElemM(x, y, curM); else setElemV(x, y, curV); amt--; } bb.Position = endOfStream; }
static void LoadWallTypes(BinBuffer bb, int v) { if (v < 1) // custom walls introduced in v1 return; var map = new ModIdMap(WallID.Count, or => WallDef.Defs[or].Type, id => Handler.WallDef.DefsByType[id]); Read2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y, id) => Main.tile[x, y].wall = (ushort)id, (x, y, or) => Main.tile[x, y].wall = (ushort)WallDef.Defs[or].Type); }
static void LoadTileTypes(BinBuffer bb, int v) { if (v < 2 /* v2: added tile support */) return; var map = new ModIdMap(TileID.Count, or => TileDef.Defs[or].Type, id => Handler.TileDef.DefsByType[id]); Read2DArray(bb, map, Main.maxTilesX, Main.maxTilesY, (x, y, id) => Main.tile[x, y].type = (ushort)id, (x, y, or) => Main.tile[x, y].type = (ushort)TileDef.Defs[or].Type); }
static void SaveTileTypes(BinBuffer bb) { // don't write anything for now, custom tiles aren't implemented return; #pragma warning disable 162 var map = new ModIdMap(TileID.Count, or => new TileRef(or).Resolve().Type, id => new TileRef(id)); #pragma warning restore 162 int ot = 0; int amt = 0; bool once = true; int op = bb.Position; bb.Write(0); for (int y = 0; y < Main.maxTilesY; y++) for (int x = 0; x < Main.maxTilesX; x++) { int t = Main.tile[x, y] == null || !Main.tile[x, y].active() ? 0 : Main.tile[x, y].type; if (once) { ot = t; bb.Write(map.Register(new TileRef(t))); once = false; continue; } if (t == ot && amt < UInt16.MaxValue) amt++; else { bb.Write((ushort)amt); // write the amount of successing tiles of the same type, // instead of the type over and over again, to save some space amt = 0; ot = t; bb.Write(map.Register(new TileRef(t))); } } bb.Write((ushort)amt); var p = bb.Position; bb.Position = op; bb.Write(p - op); // dictionary offset bb.Position = p; map.WriteDictionary(bb); }
static void LoadTileTypes(BinBuffer bb, int v) { // don't read anything for now, custom tiles aren't implemented return; #pragma warning disable 162 // to be used in future versions if (v == 0) return; #pragma warning restore 162 var map = new ModIdMap(TileID.Count, or => new TileRef(or).Resolve().Type, id => new TileRef(id)); var tp = bb.Position; var dictOffset = bb.ReadInt32(); bb.Position += dictOffset; map.ReadDictionary(bb); var end = bb.Position; bb.Position = tp; int amt = 0; for (int y = 0; y < Main.maxTilesY; y++) for (int x = 0; x < Main.maxTilesX; x++) { if (amt == 0) { var t = bb.ReadUInt32(); Main.tile[x, y].type = (ushort)new TileRef(map.GetRef(t)).Resolve().Type; amt = bb.ReadUInt16(); } else amt--; } bb.Position = end; }