Allow rotating 180, 270 degrees in a call to /spin.

This commit is contained in:
UnknownShadow200 2016-05-28 12:42:50 +10:00
parent 9d1b23519e
commit 08d8fe88bf
3 changed files with 67 additions and 36 deletions

View File

@ -35,7 +35,7 @@ namespace MCGalaxy.Commands.Building {
if (p.CopyBuffer == null) {
Player.Message(p, "You haven't copied anything yet"); return;
}
string opt = opt.ToLower();
string opt = message.ToLower();
// Mirroring
if (opt == "mirrorx" || opt == "mirror x") {
@ -48,24 +48,36 @@ namespace MCGalaxy.Commands.Building {
Flip.MirrorZ(p.CopyBuffer);
Player.Message(p, "Flipped copy across the Z (north/south) axis.");
} else {
// Rotating
switch (opt) {
case "90":
case "y":
p.CopyBuffer = Flip.RotateY(p.CopyBuffer, 90); break;
case "180":
Flip.MirrorX(p.CopyBuffer); Flip.MirrorZ(p.CopyBuffer); break;
case "z":
p.CopyBuffer = Flip.RotateZ(p.CopyBuffer, 90); break;
case "x":
p.CopyBuffer = Flip.RotateX(p.CopyBuffer, 90); break;
string[] args = opt.Split(' ');
char axis = 'Y';
int angle = 90;
if (!Handle(ref axis, ref angle, args[0])) { Help(p); return; }
if (args.Length > 1 && !Handle(ref axis, ref angle, args[1])) { Help(p); return; }
default:
Player.Message(p, "Incorrect syntax");
Help(p); return;
Player.Message(p, "Spun: &b" + opt);
if (angle == 0) {
} else if (axis == 'X') {
p.CopyBuffer = Flip.RotateX(p.CopyBuffer, angle);
} else if (axis == 'Y') {
p.CopyBuffer = Flip.RotateY(p.CopyBuffer, angle);
} else if (axis == 'Z') {
p.CopyBuffer = Flip.RotateZ(p.CopyBuffer, angle);
}
Player.Message(p, "Rotated copy {0} degrees around the {1} axis", angle, axis);
}
}
bool Handle(ref char axis, ref int angle, string arg) {
int value;
if (arg == "x" || arg == "y" || arg == "z") {
axis = char.ToUpper(arg[0]); return true;
} else if (int.TryParse(arg, out value)) {
// Clamp to [0, 360)
value %= 360;
if (value < 0) value += 360;
angle = value;
return angle == 0 || angle == 90 || angle == 180 || angle == 270;
}
return false;
}
public override void Help(Player p) {

View File

@ -19,27 +19,38 @@ using System;
using System.IO;
namespace MCGalaxy.Drawing {
public static class Flip {
public static CopyState RotateX(CopyState state, int angle) {
CopyState newState = new CopyState(state.X, state.Y, state.Z,
state.Width, state.Length, state.Height);
int[] m = { 0x100, 0x002, 0x010 };
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);
}
public static CopyState RotateY(CopyState state, int angle) {
CopyState newState = new CopyState(state.X, state.Y, state.Z,
state.Length, state.Height, state.Width);
int[] m = { 0x002, 0x010, 0x100 };
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 RotateZ(CopyState state, int angle) {
CopyState newState = new CopyState(state.X, state.Y, state.Z,
state.Height, state.Width, state.Length);
int[] m = { 0x010, 0x200, 0x001 };
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);
}
@ -59,21 +70,29 @@ namespace MCGalaxy.Drawing {
state.X + Rotate(m[0], oX, oY, oZ, state),
state.Y + Rotate(m[1], oX, oY, oZ, state),
state.Z + Rotate(m[2], oX, oY, oZ, state));
return newState;
}
const int posX = 0x100, negX = 0x200, posY = 0x010, negY = 0x020, posZ = 0x001, negZ = 0x002;
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;
}
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;
return newState;
}
static int Rotate(int row, int x, int y, int z, CopyState state) {
switch (row) {
case 0x100: return x;
case 0x200: return (state.Width - 1 - x);
case 0x010: return y;
case 0x020: return (state.Height - 1 - y);
case 0x001: return z;
case 0x002: return (state.Length - 1 - z);
}
return 0;
}
public static void MirrorX(CopyState state) {
int midZ = state.Length / 2, maxZ = state.Length - 1;