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(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);
p.CopyBuffer = state;
}

View File

@ -14,114 +14,151 @@
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
*/
using System.Collections.Generic;
using MCGalaxy.Drawing;
namespace MCGalaxy.Commands
{
public sealed class CmdSpin : Command
{
public override string name { get { return "spin"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Building; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
public CmdSpin() { }
public sealed class CmdSpin : Command
{
public override string name { get { return "spin"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Building; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
public CmdSpin() { }
public override void Use(Player p, string message)
{
if (message.Split(' ').Length > 1) { Help(p); return; }
if (message == "") message = "y";
public override void Use(Player p, string message)
{
if (message.Split(' ').Length > 1) { Help(p); return; }
if (message == "") message = "y";
List<Player.CopyPos> newBuffer = new List<Player.CopyPos>();
int TotalLoop = 0; ushort temp;
newBuffer.Clear();
switch (message)
{
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)
{
case "90":
case "y":
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
temp = Pos.z; Pos.z = Pos.x; Pos.x = temp;
p.CopyBuffer[TotalLoop] = Pos;
TotalLoop += 1;
});
goto case "m";
case "180":
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
TotalLoop -= 1;
Pos.x = p.CopyBuffer[TotalLoop].x;
Pos.z = p.CopyBuffer[TotalLoop].z;
newBuffer.Add(Pos);
});
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer;
break;
case "upsidedown":
case "u":
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
TotalLoop -= 1;
Pos.y = p.CopyBuffer[TotalLoop].y;
newBuffer.Add(Pos);
});
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer;
break;
case "mirror":
case "m":
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
TotalLoop -= 1;
Pos.x = p.CopyBuffer[TotalLoop].x;
newBuffer.Add(Pos);
});
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer;
break;
case "z":
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
TotalLoop -= 1;
Pos.x = (ushort)(p.CopyBuffer[TotalLoop].y - (2 * p.CopyBuffer[TotalLoop].y));
Pos.y = p.CopyBuffer[TotalLoop].x;
newBuffer.Add(Pos);
});
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer;
break;
case "x":
TotalLoop = p.CopyBuffer.Count;
p.CopyBuffer.ForEach(delegate(Player.CopyPos Pos)
{
TotalLoop -= 1;
Pos.z = (ushort)(p.CopyBuffer[TotalLoop].y - (2 * p.CopyBuffer[TotalLoop].y));
Pos.y = p.CopyBuffer[TotalLoop].z;
newBuffer.Add(Pos);
});
p.CopyBuffer.Clear();
p.CopyBuffer = newBuffer;
break;
default:
Player.SendMessage(p, "Incorrect syntax"); Help(p);
return;
}
Player.SendMessage(p, "Spun: &b" + message);
}
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.");
}
}
default:
Player.SendMessage(p, "Incorrect syntax");
Help(p); return;
}
Player.SendMessage(p, "Spun: &b" + message);
}
CopyState RotateX(CopyState state) {
CopyState newState = new CopyState(state.X, state.Y, state.Z,
state.Width, state.Length, state.Height);
byte[] blocks = state.Blocks;
for (int i = 0; i < blocks.Length; i++) {
ushort x, y, z;
state.GetCoords(i, out x, out y, out z);
newState.Set(x, z, y, blocks[i]);
}
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;
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]);
}
return newState;
}
CopyState RotateZ(CopyState state) {
CopyState newState = new CopyState(state.X, state.Y, state.Z,
state.Height, state.Width, state.Length);
byte[] blocks = state.Blocks;
for (int i = 0; i < blocks.Length; i++) {
ushort x, y, z;
state.GetCoords(i, out x, out y, out z);
newState.Set(y, x, z, blocks[i]);
}
return newState;
}
void FlipX(CopyState state) {
int midX = state.Width / 2, maxX = state.Width - 1;
byte[] blocks = state.Blocks;
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, start, end);
}
}
}
}
void FlipY(CopyState state) {
int midY = state.Height / 2, maxY = state.Height - 1;
byte[] blocks = state.Blocks;
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, start, end);
start++; end++;
}
}
}
}
void FlipDiagonal(CopyState state) {
int midX = state.Width / 2, maxX = state.Width - 1;
int midZ = state.Length / 2, maxZ = state.Length - 1;
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 ushort[] MinCoords;
public ushort[] MaxCoords;
public byte[] Blocks;
public int X, Y, Z;
public int Width, Height, Length;
int width, height, length;
const int identifier = 0x434F5059; // 'COPY'
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,
ushort maxX, ushort maxY, ushort maxZ) {
SetBounds(minX, minY, minZ, maxX, maxY, maxZ);
width = maxX - minX + 1;
height = maxY - minY + 1;
length = maxZ - minZ + 1;
public CopyState(int x, int y, int z, int width, int height, int length)
: this(x, y, z, width, height, length, null) {
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() {
Blocks = null;
MinCoords = null;
MaxCoords = null;
}
public void GetCoords(int index, out ushort x, out ushort y, out ushort z) {
y = (ushort)(index / width / length);
index -= y * width * length;
z = (ushort)(index / width);
index -= z * width;
y = (ushort)(index / Width / Length);
index -= y * Width * Length;
z = (ushort)(index / Width);
index -= z * Width;
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) {
BinaryWriter w = new BinaryWriter(stream);
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(height);
w.Write(length);
w.Write(X); w.Write(Y); w.Write(Z);
w.Write(Width); w.Write(Height); w.Write(Length);
w.Write(Blocks);
}
@ -80,14 +76,10 @@ namespace MCGalaxy.Drawing {
BinaryReader r = new BinaryReader(stream);
if (r.ReadInt32() != 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();
height = r.ReadInt32();
length = r.ReadInt32();
Blocks = r.ReadBytes(width * height * length);
X = r.ReadInt32(); Y = r.ReadInt32(); Z = r.ReadInt32();
Width = r.ReadInt32(); Height = r.ReadInt32(); Length = r.ReadInt32();
Blocks = r.ReadBytes(Width * Height * Length);
}
}
}