And update CmdSpin.

This commit is contained in:
UnknownShadow200 2015-12-04 21:29:17 +11:00
parent c2cb1ac0c0
commit 26550adc9b
3 changed files with 167 additions and 138 deletions

View File

@ -205,7 +205,7 @@ namespace MCGalaxy.Commands
using (FileStream fs = new FileStream(path, FileMode.Open)) using (FileStream fs = new FileStream(path, FileMode.Open))
using(GZipStream gs = new GZipStream(fs, CompressionMode.Decompress)) using(GZipStream gs = new GZipStream(fs, CompressionMode.Decompress))
{ {
CopyState state = new CopyState(); CopyState state = new CopyState(0, 0, 0, 0, 0, 0, null);
state.LoadFrom(gs); state.LoadFrom(gs);
p.CopyBuffer = state; p.CopyBuffer = state;
} }

View File

@ -14,114 +14,151 @@
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using MCGalaxy.Drawing; using MCGalaxy.Drawing;
namespace MCGalaxy.Commands namespace MCGalaxy.Commands
{ {
public sealed class CmdSpin : Command public sealed class CmdSpin : Command
{ {
public override string name { get { return "spin"; } } public override string name { get { return "spin"; } }
public override string shortcut { get { return ""; } } public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Building; } } public override string type { get { return CommandTypes.Building; } }
public override bool museumUsable { get { return false; } } public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
public CmdSpin() { } public CmdSpin() { }
public override void Use(Player p, string message) public override void Use(Player p, string message)
{ {
if (message.Split(' ').Length > 1) { Help(p); return; } if (message.Split(' ').Length > 1) { Help(p); return; }
if (message == "") message = "y"; if (message == "") message = "y";
List<Player.CopyPos> newBuffer = new List<Player.CopyPos>(); switch (message)
int TotalLoop = 0; ushort temp; {
newBuffer.Clear(); case "90":
case "y":
p.CopyBuffer = RotateY(p.CopyBuffer);
goto case "m";
case "180":
FlipDiagonal(p.CopyBuffer); break;
case "upsidedown":
case "u":
FlipY(p.CopyBuffer); break;
case "mirror":
case "m":
FlipX(p.CopyBuffer); break;
case "z":
p.CopyBuffer = RotateZ(p.CopyBuffer); break;
case "x":
p.CopyBuffer = RotateX(p.CopyBuffer); break;
switch (message) default:
{ Player.SendMessage(p, "Incorrect syntax");
case "90": Help(p); return;
case "y": }
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos) Player.SendMessage(p, "Spun: &b" + message);
{ }
temp = Pos.z; Pos.z = Pos.x; Pos.x = temp;
p.CopyBuffer[TotalLoop] = Pos; CopyState RotateX(CopyState state) {
TotalLoop += 1; CopyState newState = new CopyState(state.X, state.Y, state.Z,
}); state.Width, state.Length, state.Height);
goto case "m"; byte[] blocks = state.Blocks;
case "180":
TotalLoop = p.CopyBuffer.Count; for (int i = 0; i < blocks.Length; i++) {
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos) ushort x, y, z;
{ state.GetCoords(i, out x, out y, out z);
TotalLoop -= 1; newState.Set(x, z, y, blocks[i]);
Pos.x = p.CopyBuffer[TotalLoop].x; }
Pos.z = p.CopyBuffer[TotalLoop].z; return newState;
newBuffer.Add(Pos); }
});
p.CopyBuffer.Clear(); CopyState RotateY(CopyState state) {
p.CopyBuffer = newBuffer; CopyState newState = new CopyState(state.X, state.Y, state.Z,
break; state.Length, state.Height, state.Width);
case "upsidedown": byte[] blocks = state.Blocks;
case "u":
TotalLoop = p.CopyBuffer.Count; for (int i = 0; i < blocks.Length; i++) {
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos) ushort x, y, z;
{ state.GetCoords(i, out x, out y, out z);
TotalLoop -= 1; newState.Set(z, y, x, blocks[i]);
Pos.y = p.CopyBuffer[TotalLoop].y; }
newBuffer.Add(Pos); return newState;
}); }
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer; CopyState RotateZ(CopyState state) {
break; CopyState newState = new CopyState(state.X, state.Y, state.Z,
case "mirror": state.Height, state.Width, state.Length);
case "m": byte[] blocks = state.Blocks;
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos) for (int i = 0; i < blocks.Length; i++) {
{ ushort x, y, z;
TotalLoop -= 1; state.GetCoords(i, out x, out y, out z);
Pos.x = p.CopyBuffer[TotalLoop].x; newState.Set(y, x, z, blocks[i]);
newBuffer.Add(Pos); }
}); return newState;
p.CopyBuffer.Clear(); }
p.CopyBuffer = newBuffer;
break; void FlipX(CopyState state) {
case "z": int midX = state.Width / 2, maxX = state.Width - 1;
TotalLoop = p.CopyBuffer.Count; byte[] blocks = state.Blocks;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{ for (int y = 0; y < state.Height; y++) {
TotalLoop -= 1; for (int z = 0; z < state.Length; z++) {
Pos.x = (ushort)(p.CopyBuffer[TotalLoop].y - (2 * p.CopyBuffer[TotalLoop].y)); for (int x = 0; x < midX; x++) {
Pos.y = p.CopyBuffer[TotalLoop].x; int endX = maxX - x;
newBuffer.Add(Pos); int start = state.GetIndex(x, y, z);
}); int end = state.GetIndex(endX, y, z);
p.CopyBuffer.Clear(); Swap(blocks, start, end);
p.CopyBuffer = newBuffer; }
break; }
case "x": }
TotalLoop = p.CopyBuffer.Count; }
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{ void FlipY(CopyState state) {
TotalLoop -= 1; int midY = state.Height / 2, maxY = state.Height - 1;
Pos.z = (ushort)(p.CopyBuffer[TotalLoop].y - (2 * p.CopyBuffer[TotalLoop].y)); byte[] blocks = state.Blocks;
Pos.y = p.CopyBuffer[TotalLoop].z;
newBuffer.Add(Pos); for (int y = 0; y < midY; y++) {
}); int endY = maxY - y;
p.CopyBuffer.Clear(); int start = state.GetIndex(0, y, 0);
p.CopyBuffer = newBuffer; int end = state.GetIndex(0, endY, 0);
break;
for (int z = 0; z < state.Length; z++) {
default: for (int x = 0; x < state.Width; x++) {
Player.SendMessage(p, "Incorrect syntax"); Help(p); Swap(blocks, start, end);
return; start++; end++;
} }
}
Player.SendMessage(p, "Spun: &b" + message); }
} }
public override void Help(Player p) void FlipDiagonal(CopyState state) {
{ int midX = state.Width / 2, maxX = state.Width - 1;
Player.SendMessage(p, "/spin <y/180/mirror/upsidedown> - Spins the copied object."); int midZ = state.Length / 2, maxZ = state.Length - 1;
Player.SendMessage(p, "Shotcuts: m for mirror, u for upside down, x for spin 90 on x, y for spin 90 on y, z for spin 90 on z."); byte[] blocks = state.Blocks;
}
} for (int y = 0; y < state.Height; y++) {
for (int z = 0; z < midZ; z++) {
int endZ = maxZ - 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, endZ);
Swap(blocks, start, end);
}
}
}
}
static void Swap( byte[] b, int start, int end ) {
byte a = b[start]; b[start] = b[end]; b[end] = a;
}
public override void Help(Player p)
{
Player.SendMessage(p, "/spin <y/180/mirror/upsidedown> - Spins the copied object.");
Player.SendMessage(p, "Shotcuts: m for mirror, u for upside down, x for spin 90 on x, y for spin 90 on y, z for spin 90 on z.");
}
}
} }

View File

@ -22,57 +22,53 @@ namespace MCGalaxy.Drawing {
public sealed class CopyState { public sealed class CopyState {
public ushort[] MinCoords;
public ushort[] MaxCoords;
public byte[] Blocks; public byte[] Blocks;
public int X, Y, Z;
public int Width, Height, Length;
int width, height, length;
const int identifier = 0x434F5059; // 'COPY' const int identifier = 0x434F5059; // 'COPY'
public int Volume { public int Volume {
get { return width * height * length; } get { return Width * Height * Length; }
} }
public CopyState() { } public CopyState(int x, int y, int z, int width, int height, int length, byte[] blocks) {
X = x; Y = y; Z = z;
Width = width; Height = height; Length = length;
Blocks = blocks;
}
public CopyState(ushort minX, ushort minY, ushort minZ, public CopyState(int x, int y, int z, int width, int height, int length)
ushort maxX, ushort maxY, ushort maxZ) { : this(x, y, z, width, height, length, null) {
SetBounds(minX, minY, minZ, maxX, maxY, maxZ);
width = maxX - minX + 1;
height = maxY - minY + 1;
length = maxZ - minZ + 1;
Blocks = new byte[width * height * length]; Blocks = new byte[width * height * length];
} }
public void SetBounds(ushort minX, ushort minY, ushort minZ,
ushort maxX, ushort maxY, ushort maxZ) {
MinCoords = new [] { minX, minY, minZ };
MaxCoords = new [] { maxX, maxY, maxZ };
}
public void Clear() { public void Clear() {
Blocks = null; Blocks = null;
MinCoords = null;
MaxCoords = null;
} }
public void GetCoords(int index, out ushort x, out ushort y, out ushort z) { public void GetCoords(int index, out ushort x, out ushort y, out ushort z) {
y = (ushort)(index / width / length); y = (ushort)(index / Width / Length);
index -= y * width * length; index -= y * Width * Length;
z = (ushort)(index / width); z = (ushort)(index / Width);
index -= z * width; index -= z * Width;
x = (ushort)index; x = (ushort)index;
} }
public int GetIndex(int x, int y, int z) {
return (y * Length + z) * Width + x;
}
public void Set(int x, int y, int z, byte block) {
Blocks[(y * Length + z) * Width + x] = block;
}
public void SaveTo(Stream stream) { public void SaveTo(Stream stream) {
BinaryWriter w = new BinaryWriter(stream); BinaryWriter w = new BinaryWriter(stream);
w.Write(identifier); w.Write(identifier);
w.Write(MinCoords[0]); w.Write(MinCoords[1]); w.Write(MinCoords[2]);
w.Write(MaxCoords[0]); w.Write(MaxCoords[1]); w.Write(MaxCoords[2]);
w.Write(width); w.Write(X); w.Write(Y); w.Write(Z);
w.Write(height); w.Write(Width); w.Write(Height); w.Write(Length);
w.Write(length);
w.Write(Blocks); w.Write(Blocks);
} }
@ -80,14 +76,10 @@ namespace MCGalaxy.Drawing {
BinaryReader r = new BinaryReader(stream); BinaryReader r = new BinaryReader(stream);
if (r.ReadInt32() != identifier) if (r.ReadInt32() != identifier)
throw new InvalidDataException("invalid identifier"); throw new InvalidDataException("invalid identifier");
ushort minX = r.ReadUInt16(), minY = r.ReadUInt16(), minZ = r.ReadUInt16();
ushort maxX = r.ReadUInt16(), maxY = r.ReadUInt16(), maxZ = r.ReadUInt16();
SetBounds( minX, minY, minZ, maxX, maxY, maxZ );
width = r.ReadInt32(); X = r.ReadInt32(); Y = r.ReadInt32(); Z = r.ReadInt32();
height = r.ReadInt32(); Width = r.ReadInt32(); Height = r.ReadInt32(); Length = r.ReadInt32();
length = r.ReadInt32(); Blocks = r.ReadBytes(Width * Height * Length);
Blocks = r.ReadBytes(width * height * length);
} }
} }
} }