static CopyState Rotate(CopyState state, CopyState flipped, int[] m) { byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; for (int i = 0; i < blocks.Length; i++) { ushort x, y, z; state.GetCoords(i, out x, out y, out z); flipped.Set(blocks[i], extBlocks[i], Rotate(m[0], x, y, z, state), Rotate(m[1], x, y, z, state), Rotate(m[2], x, y, z, state)); } int oX = state.OriginX - state.X, oY = state.OriginY - state.Y, oZ = state.OriginZ - state.Z; flipped.OriginX = state.X + Rotate(m[0], oX, oY, oZ, state); flipped.OriginY = state.Y + Rotate(m[1], oX, oY, oZ, state); flipped.OriginZ = state.Z + Rotate(m[2], oX, oY, oZ, state); // Offset is relative to Origin oX += state.Offset.X; oY += state.Offset.Y; oZ += state.Offset.Z; flipped.Offset.X = state.X + Rotate(m[0], oX, oY, oZ, state) - flipped.OriginX; flipped.Offset.Y = state.Y + Rotate(m[1], oX, oY, oZ, state) - flipped.OriginY; flipped.Offset.Z = state.Z + Rotate(m[2], oX, oY, oZ, state) - flipped.OriginZ; return(flipped); }
public static CopyState RotateZ(CopyState state, int angle, BlockDefinition[] defs) { CopyState newState = Clone(state); newState.Width = angle == 180 ? state.Width : state.Height; newState.Height = angle == 180 ? state.Height : state.Width; ExtBlock[] transform; if (angle == 90 || angle == 270) { transform = Transform(defs, rotZ_90_270, null); } else if (angle == 180) { transform = Transform(defs, rotZ_180, null); } else { transform = Transform(defs, null, null); } int[] m = new int[] { posY, negX, posZ }; if (angle == 180) { m[0] = negX; m[1] = negY; } if (angle == 270) { m[0] = negY; m[1] = posX; } return(Rotate(state, newState, m, transform)); }
public static void MirrorY(CopyState state, BlockDefinition[] defs) { int midY = (state.Height + 1) / 2, maxY = state.Height - 1; state.OriginY = state.OppositeOriginY; state.Offset.Y = -state.Offset.Y; BlockID[] transform = Transform(defs, mirrorY, null); for (int y = 0; y < midY; y++) { int endY = maxY - y; int beg = state.GetIndex(0, y, 0); int end = state.GetIndex(0, endY, 0); for (int z = 0; z < state.Length; z++) { for (int x = 0; x < state.Width; x++) { BlockID blockA = transform[state.Get(beg)]; BlockID blockB = transform[state.Get(end)]; state.Set(blockB, beg); state.Set(blockA, end); beg++; end++; } } } }
static CopyState Rotate(CopyState state, CopyState flipped, int[] m, BlockID[] transform) { int volume = state.Volume; for (int i = 0; i < volume; i++) { ushort x, y, z; state.GetCoords(i, out x, out y, out z); BlockID block = transform[state.Get(i)]; flipped.Set(block, Rotate(m[0], x, y, z, state), Rotate(m[1], x, y, z, state), Rotate(m[2], x, y, z, state)); } int oX = state.OriginX - state.X, oY = state.OriginY - state.Y, oZ = state.OriginZ - state.Z; flipped.OriginX = state.X + Rotate(m[0], oX, oY, oZ, state); flipped.OriginY = state.Y + Rotate(m[1], oX, oY, oZ, state); flipped.OriginZ = state.Z + Rotate(m[2], oX, oY, oZ, state); // Offset is relative to Origin oX += state.Offset.X; oY += state.Offset.Y; oZ += state.Offset.Z; flipped.Offset.X = state.X + Rotate(m[0], oX, oY, oZ, state) - flipped.OriginX; flipped.Offset.Y = state.Y + Rotate(m[1], oX, oY, oZ, state) - flipped.OriginY; flipped.Offset.Z = state.Z + Rotate(m[2], oX, oY, oZ, state) - flipped.OriginZ; return(flipped); }
public static void MirrorX(CopyState state, BlockDefinition[] defs) { // ceiling division by 2, because for odd length, we still want to // mirror the middle row to rotate directional blocks int midX = (state.Width + 1) / 2, maxX = state.Width - 1; state.OriginX = state.OppositeOriginX; state.Offset.X = -state.Offset.X; BlockID[] transform = Transform(defs, mirrorX, null); for (int y = 0; y < state.Height; y++) { for (int z = 0; z < state.Length; z++) { for (int x = 0; x < midX; x++) { int endX = maxX - x; int beg = state.GetIndex(x, y, z); int end = state.GetIndex(endX, y, z); BlockID blockA = transform[state.Get(beg)]; BlockID blockB = transform[state.Get(end)]; state.Set(blockB, beg); state.Set(blockA, end); } } } }
public static void MirrorZ(CopyState state, BlockDefinition[] defs) { int midX = (state.Width + 1) / 2, maxX = state.Width - 1; state.OriginX = state.OppositeOriginX; state.Offset.X = -state.Offset.X; BlockID[] transform = Transform(defs, mirrorZ, null); for (int y = 0; y < state.Height; y++) { for (int z = 0; z < state.Length; z++) { for (int x = 0; x < midX; x++) { int endX = maxX - x; int start = state.GetIndex(x, y, z); int end = state.GetIndex(endX, y, z); BlockID blockA = transform[state.Get(start)]; BlockID blockB = transform[state.Get(end)]; state.Set(blockB, start); state.Set(blockA, end); } } } }
public static CopyState RotateX(CopyState state, int angle, BlockDefinition[] defs) { CopyState newState = Clone(state); newState.Height = angle == 180 ? state.Height : state.Length; newState.Length = angle == 180 ? state.Length : state.Height; BlockID[] transform; if (angle == 90 || angle == 270) { transform = Transform(defs, rotX_90_270, null); } else if (angle == 180) { transform = Transform(defs, rotX_180, null); } else { transform = Transform(defs, null, null); } int[] m = new int[] { posX, negZ, posY }; if (angle == 180) { m[1] = negY; m[2] = negZ; } if (angle == 270) { m[1] = posZ; m[2] = negY; } return(Rotate(state, newState, m, transform)); }
public static void MirrorX(CopyState state, BlockDefinition[] defs) { // ceiling division by 2, because for odd length, we still want to // mirror the middle row to rotate directional blocks int midZ = (state.Length + 1) / 2, maxZ = state.Length - 1; state.OriginZ = state.OppositeOriginZ; state.Offset.Z = -state.Offset.Z; BlockID[] transform = Transform(defs, mirrorX, null); for (int y = 0; y < state.Height; y++) { for (int z = 0; z < midZ; z++) { int endZ = maxZ - z; int start = state.GetIndex(0, y, z); int end = state.GetIndex(0, y, endZ); for (int x = 0; x < state.Width; x++) { BlockID blockA = transform[state.Get(start)]; BlockID blockB = transform[state.Get(end)]; state.Set(blockB, start); state.Set(blockA, end); start++; end++; } } } }
public static void MirrorZ(CopyState state, BlockDefinition[] defs) { int midZ = (state.Length + 1) / 2, maxZ = state.Length - 1; state.OriginZ = state.OppositeOriginZ; state.Offset.Z = -state.Offset.Z; BlockID[] transform = Transform(defs, mirrorZ, null); for (int y = 0; y < state.Height; y++) { for (int z = 0; z < midZ; z++) { int endZ = maxZ - z; int beg = state.GetIndex(0, y, z); int end = state.GetIndex(0, y, endZ); for (int x = 0; x < state.Width; x++) { BlockID blockA = transform[state.Get(beg)]; BlockID blockB = transform[state.Get(end)]; state.Set(blockB, beg); state.Set(blockA, end); beg++; end++; } } } }
static CopyState Clone(CopyState state) { CopyState newState = new CopyState(state.X, state.Y, state.Z, state.Width, state.Height, state.Length); newState.UsedBlocks = state.UsedBlocks; newState.PasteAir = state.PasteAir; return(newState); }
CopyState RotateY(CopyState state) { CopyState newState = new CopyState(state.X, state.Y, state.Z, state.Length, state.Height, state.Width); byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; for (int i = 0; i < blocks.Length; i++) { ushort x, y, z; state.GetCoords(i, out x, out y, out z); newState.Set(z, y, x, blocks[i], extBlocks[i]); } newState.SetOrigin(state.OriginX, state.OriginY, state.OriginZ); return newState; }
public static CopyState RotateY(CopyState state, int angle) { CopyState newState = Clone(state); newState.Width = angle == 180 ? state.Width : state.Length; newState.Length = angle == 180 ? state.Length : state.Width; int[] m = { negZ, posY, posX }; if (angle == 180) { m[0] = negX; m[2] = negZ; } if (angle == 270) { m[0] = posZ; m[2] = negX; } return(Rotate(state, newState, m)); }
public static CopyState RotateX(CopyState state, int angle) { CopyState newState = Clone(state); newState.Height = angle == 180 ? state.Height : state.Length; newState.Length = angle == 180 ? state.Length : state.Height; int[] m = { posX, negZ, posY }; if (angle == 180) { m[1] = negY; m[2] = negZ; } if (angle == 270) { m[1] = posZ; m[2] = negY; } return(Rotate(state, newState, m)); }
static int Rotate(int row, int x, int y, int z, CopyState state) { switch (row) { case posX: return(x); case negX: return(state.Width - 1 - x); case posY: return(y); case negY: return(state.Height - 1 - y); case posZ: return(z); case negZ: return(state.Length - 1 - z); } return(0); }
public static CopyState RotateZ(CopyState state, int angle) { CopyState newState = Clone(state); newState.Width = angle == 180 ? state.Width : state.Height; newState.Height = angle == 180 ? state.Height : state.Width; int[] m = { posY, negX, posZ }; if (angle == 180) { m[0] = negX; m[1] = negY; } if (angle == 270) { m[0] = negY; m[1] = posX; } return(Rotate(state, newState, m)); }
public static void MirrorZ(CopyState state) { int midX = state.Width / 2, maxX = state.Width - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; state.OriginX = state.OppositeOriginX; state.Offset.X = -state.Offset.X; for (int y = 0; y < state.Height; y++) { for (int z = 0; z < state.Length; z++) { for (int x = 0; x < midX; x++) { int endX = maxX - x; int start = state.GetIndex(x, y, z); int end = state.GetIndex(endX, y, z); Swap(blocks, extBlocks, start, end); } } } }
public static void MirrorX(CopyState state) { int midZ = state.Length / 2, maxZ = state.Length - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; state.OriginZ = state.OppositeOriginZ; state.Offset.Z = -state.Offset.Z; for (int y = 0; y < state.Height; y++) { for (int z = 0; z < midZ; z++) { int endZ = maxZ - z; int start = state.GetIndex(0, y, z); int end = state.GetIndex(0, y, endZ); for (int x = 0; x < state.Width; x++) { Swap(blocks, extBlocks, start, end); start++; end++; } } } }
public static void MirrorY(CopyState state) { int midY = state.Height / 2, maxY = state.Height - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; state.OriginY = state.OppositeOriginY; state.Offset.Y = -state.Offset.Y; for (int y = 0; y < midY; y++) { int endY = maxY - y; int start = state.GetIndex(0, y, 0); int end = state.GetIndex(0, endY, 0); for (int z = 0; z < state.Length; z++) { for (int x = 0; x < state.Width; x++) { Swap(blocks, extBlocks, start, end); start++; end++; } } } }
public static CopyState RotateY(CopyState state, int angle, BlockDefinition[] defs) { CopyState newState = Clone(state); newState.Width = angle == 180 ? state.Width : state.Length; newState.Length = angle == 180 ? state.Length : state.Width; BlockID[] transform; if (angle == 90) { transform = Transform(defs, null, rotY_90); } else if (angle == 180) { transform = Transform(defs, rotY_180, null); } else if (angle == 270) { transform = Transform(defs, null, rotY_270); } else { transform = Transform(defs, null, null); } int[] m = new int[] { negZ, posY, posX }; if (angle == 180) { m[0] = negX; m[2] = negZ; } if (angle == 270) { m[0] = posZ; m[2] = negX; } return(Rotate(state, newState, m, transform)); }
void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { RevertAndClearState(p, x, y, z); CatchPos cpos = (CatchPos)p.blockchangeObject; ushort minX = (ushort)Math.Min(x, cpos.x), minY = (ushort)Math.Min(y, cpos.y); ushort minZ = (ushort)Math.Min(z, cpos.z), maxX = (ushort)Math.Max(x, cpos.x); ushort maxY = (ushort)Math.Max(y, cpos.y), maxZ = (ushort)Math.Max(z, cpos.z); CopyState state = new CopyState(minX, minY, minZ, maxX - minX + 1, maxY - minY + 1, maxZ - minZ + 1); state.SetOrigin(cpos.x, cpos.y, cpos.z); int totalAir = 0, index = 0; p.copyAir = cpos.type == 2; for (ushort yy = minY; yy <= maxY; ++yy) for (ushort zz = minZ; zz <= maxZ; ++zz) for (ushort xx = minX; xx <= maxX; ++xx) { byte b = p.level.GetTile(xx, yy, zz); if (!Block.canPlace(p, b)) { index++; continue; } if (b == Block.air && cpos.type != 2 || cpos.ignoreTypes.Contains(b)) totalAir++; if (!cpos.ignoreTypes.Contains(b)) { state.Blocks[index] = b; if (b == Block.custom_block) state.ExtBlocks[index] = p.level.GetExtTile(xx, yy, zz); } index++; } p.CopyBuffer = state; if ((state.Volume - totalAir) > p.group.maxBlocks) { Player.SendMessage(p, "You tried to copy " + state.Volume + " blocks."); Player.SendMessage(p, "You cannot copy more than " + p.group.maxBlocks + "."); p.CopyBuffer = null; return; } if (cpos.type == 1) for (ushort yy = minY; yy <= maxY; ++yy) for (ushort zz = minZ; zz <= maxZ; ++zz) for (ushort xx = minX; xx <= maxX; ++xx) { byte b = p.level.GetTile(xx, yy, zz); if (b != Block.air && Block.canPlace(p, b)) p.level.Blockchange(p, xx, yy, zz, Block.air); } Player.SendMessage(p, (state.Volume - totalAir) + " blocks copied."); if (allowoffset != -1) { Player.SendMessage(p, "Place a block to determine where to paste from"); p.Blockchange += new Player.BlockchangeEventHandler(Blockchange3); } }
void LoadCopy(Player p, string file) { string path = "extra/savecopy/" + p.name + "/" + file; bool existsNew = File.Exists(path + ".cpb"); bool existsOld = File.Exists(path + ".cpy"); if (!existsNew && !existsOld) { Player.SendMessage(p, "No such copy exists"); return; } path = existsNew ? path + ".cpb" : path + ".cpy"; using (FileStream fs = new FileStream(path, FileMode.Open)) using(GZipStream gs = new GZipStream(fs, CompressionMode.Decompress)) { CopyState state = new CopyState(0, 0, 0, 0, 0, 0, null, null); if (existsNew) state.LoadFrom(gs); else state.LoadFromOld(gs, fs); p.CopyBuffer = state; } Player.SendMessage(p, "Loaded copy as " + file); }
void FlipX(CopyState state) { int midX = state.Width / 2, maxX = state.Width - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; for (int y = 0; y < state.Height; y++) { for (int z = 0; z < state.Length; z++) { for (int x = 0; x < midX; x++) { int endX = maxX - x; int start = state.GetIndex(x, y, z); int end = state.GetIndex(endX, y, z); Swap(blocks, extBlocks, start, end); } } } }
void FlipY(CopyState state) { int midY = state.Height / 2, maxY = state.Height - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; for (int y = 0; y < midY; y++) { int endY = maxY - y; int start = state.GetIndex(0, y, 0); int end = state.GetIndex(0, endY, 0); for (int z = 0; z < state.Length; z++) { for (int x = 0; x < state.Width; x++) { Swap(blocks, extBlocks, start, end); start++; end++; } } } }
void FlipZ(CopyState state) { int midZ = state.Width / 2, maxZ = state.Length - 1; byte[] blocks = state.Blocks, extBlocks = state.ExtBlocks; for (int y = 0; y < state.Height; y++) { for (int z = 0; z < midZ; z++) { int endZ = maxZ - z; int start = state.GetIndex(0, y, z); int end = state.GetIndex(0, y, endZ); for (int x = 0; x < state.Width; x++) { Swap(blocks, extBlocks, start, end); start++; end++; } } } }