- Added proper block flipping code for all blocks with proper rotation code except sign posts

- Fixed block rotation code for some blocks and cleaned it up a lot
- Added block rotation code for powered rails and detector rails
- //flip now flips all blocks, not just half of them
This commit is contained in:
TomyLobo 2011-08-26 12:41:31 +02:00
parent 2281684f20
commit 8e84e7ae18
3 changed files with 390 additions and 192 deletions

View File

@ -182,14 +182,22 @@ public class CuboidClipboard {
switch (dir) { switch (dir) {
case NORTH_SOUTH: case NORTH_SOUTH:
int wid = (int)Math.floor(width / 2); int wid = (int)Math.ceil(width / 2);
for (int xs = 0; xs < wid; ++xs) { for (int xs = 0; xs < wid; ++xs) {
for (int z = 0; z < length; ++z) { for (int z = 0; z < length; ++z) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
BaseBlock old = data[xs][y][z]; BaseBlock a = data[xs][y][z];
old.flip(); //System.out.println(xs+"/"+y+"/"+z+": "+a.getType());
data[xs][y][z] = data[width - xs - 1][y][z]; a.flip(dir);
data[width - xs - 1][y][z] = old;
if (xs == width - xs - 1)
continue;
BaseBlock b = data[width - xs - 1][y][z];
b.flip(dir);
data[xs][y][z] = b;
data[width - xs - 1][y][z] = a;
} }
} }
} }
@ -200,14 +208,21 @@ public class CuboidClipboard {
break; break;
case WEST_EAST: case WEST_EAST:
int len = (int)Math.floor(length / 2); int len = (int)Math.ceil(length / 2);
for (int zs = 0; zs < len; ++zs) { for (int zs = 0; zs < len; ++zs) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
BaseBlock old = data[x][y][zs]; BaseBlock a = data[x][y][zs];
old.flip(); a.flip(dir);
data[x][y][zs] = data[x][y][length - zs - 1];
data[x][y][length - zs - 1] = old; if (zs == length - zs - 1)
continue;
BaseBlock b = data[x][y][length - zs - 1];
b.flip(dir);
data[x][y][zs] = b;
data[x][y][length - zs - 1] = a;
} }
} }
} }
@ -218,13 +233,21 @@ public class CuboidClipboard {
break; break;
case UP_DOWN: case UP_DOWN:
int hei = (int)Math.floor(height / 2); int hei = (int)Math.ceil(height / 2);
for (int ys = 0; ys < hei; ++ys) { for (int ys = 0; ys < hei; ++ys) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
for (int z = 0; z < length; ++z) { for (int z = 0; z < length; ++z) {
BaseBlock old = data[x][ys][z]; BaseBlock a = data[x][ys][z];
data[x][ys][z] = data[x][height - ys - 1][z]; a.flip(dir);
data[x][height - ys - 1][z] = old;
if (ys == height - ys - 1)
continue;
BaseBlock b = data[x][height - ys - 1][z];
b.flip(dir);
data[x][ys][z] = b;
data[x][height - ys - 1][z] = a;
} }
} }
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.blocks; package com.sk89q.worldedit.blocks;
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
import com.sk89q.worldedit.data.BlockData; import com.sk89q.worldedit.data.BlockData;
/** /**
@ -109,8 +110,9 @@ public class BaseBlock {
/** /**
* Flip this block. * Flip this block.
* @param direction
*/ */
public void flip() { public void flip(FlipDirection direction) {
data = (char)BlockData.flip(type, data); data = (char)BlockData.flip(type, data, direction);
} }
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.data; package com.sk89q.worldedit.data;
import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockID;
/** /**
@ -35,116 +36,134 @@ public final class BlockData {
* @return * @return
*/ */
public static int rotate90(int type, int data) { public static int rotate90(int type, int data) {
if (type == BlockID.TORCH switch (type) {
|| type == BlockID.REDSTONE_TORCH_OFF case BlockID.TORCH:
|| type == BlockID.REDSTONE_TORCH_ON) { case BlockID.REDSTONE_TORCH_OFF:
case BlockID.REDSTONE_TORCH_ON:
switch (data) { switch (data) {
case 1: return 3; case 1: return 3;
case 2: return 4; case 2: return 4;
case 3: return 2; case 3: return 2;
case 4: return 1; case 4: return 1;
} }
} else if (type == BlockID.MINECART_TRACKS) { break;
case BlockID.MINECART_TRACKS:
switch (data) { switch (data) {
case 0: return 1; case 6: return 7;
case 1: return 0; case 7: return 8;
case 2: return 5; case 8: return 9;
case 3: return 4; case 9: return 6;
case 4: return 2;
case 5: return 3;
case 6: return 7;
case 7: return 8;
case 8: return 9;
case 9: return 6;
} }
} else if (type == BlockID.WOODEN_STAIRS /* FALL-THROUGH */
|| type == BlockID.COBBLESTONE_STAIRS) {
case BlockID.POWERED_RAIL:
case BlockID.DETECTOR_RAIL:
switch (data & 0x7) {
case 0: return 1;
case 1: return 0;
case 2: return 5;
case 3: return 4;
case 4: return 2;
case 5: return 3;
}
break;
case BlockID.WOODEN_STAIRS:
case BlockID.COBBLESTONE_STAIRS:
switch (data) { switch (data) {
case 0: return 2; case 0: return 2;
case 1: return 3; case 1: return 3;
case 2: return 1; case 2: return 1;
case 3: return 0; case 3: return 0;
} }
} else if (type == BlockID.LEVER) { break;
case BlockID.LEVER:
case BlockID.STONE_BUTTON:
int thrown = data & 0x8; int thrown = data & 0x8;
int withoutThrown = data ^ 0x8; int withoutThrown = data & ~0x8;
switch (withoutThrown) { switch (withoutThrown) {
case 1: return 3 | thrown; case 1: return 3 | thrown;
case 2: return 4 | thrown; case 2: return 4 | thrown;
case 3: return 2 | thrown; case 3: return 2 | thrown;
case 4: return 1 | thrown; case 4: return 1 | thrown;
} }
} else if (type == BlockID.WOODEN_DOOR break;
|| type == BlockID.IRON_DOOR) {
case BlockID.WOODEN_DOOR:
case BlockID.IRON_DOOR:
int topHalf = data & 0x8; int topHalf = data & 0x8;
int swung = data & 0x4; int swung = data & 0x4;
int withoutFlags = data ^ (0x8 | 0x4); int withoutFlags = data & ~(0x8 | 0x4);
switch (withoutFlags) { switch (withoutFlags) {
case 0: return 1 | topHalf | swung; case 0: return 1 | topHalf | swung;
case 1: return 2 | topHalf | swung; case 1: return 2 | topHalf | swung;
case 2: return 3 | topHalf | swung; case 2: return 3 | topHalf | swung;
case 3: return 0 | topHalf | swung; case 3: return 0 | topHalf | swung;
} }
} else if (type == BlockID.STONE_BUTTON) { break;
int thrown = data & 0x8;
int withoutThrown = data ^ 0x8; case BlockID.SIGN_POST:
switch (withoutThrown) {
case 1: return 3 | thrown;
case 2: return 4 | thrown;
case 3: return 2 | thrown;
case 4: return 1 | thrown;
}
} else if (type == BlockID.SIGN_POST) {
return (data + 4) % 16; return (data + 4) % 16;
} else if (type == BlockID.LADDER
|| type == BlockID.WALL_SIGN case BlockID.LADDER:
|| type == BlockID.FURNACE case BlockID.WALL_SIGN:
|| type == BlockID.BURNING_FURNACE case BlockID.FURNACE:
|| type == BlockID.DISPENSER) { case BlockID.BURNING_FURNACE:
case BlockID.DISPENSER:
switch (data) { switch (data) {
case 2: return 5; case 2: return 5;
case 3: return 4; case 3: return 4;
case 4: return 2; case 4: return 2;
case 5: return 3; case 5: return 3;
} }
} else if (type == BlockID.PUMPKIN break;
|| type == BlockID.JACKOLANTERN) {
case BlockID.PUMPKIN:
case BlockID.JACKOLANTERN:
switch (data) { switch (data) {
case 0: return 1; case 0: return 1;
case 1: return 2; case 1: return 2;
case 2: return 3; case 2: return 3;
case 3: return 0; case 3: return 0;
} }
} else if (type == BlockID.REDSTONE_REPEATER_OFF break;
|| type == BlockID.REDSTONE_REPEATER_ON) {
case BlockID.REDSTONE_REPEATER_OFF:
case BlockID.REDSTONE_REPEATER_ON:
int dir = data & 0x03; int dir = data & 0x03;
int delay = data - dir; int delay = data - dir;
switch (dir) { switch (dir) {
case 0: return 1 | delay; case 0: return 1 | delay;
case 1: return 2 | delay; case 1: return 2 | delay;
case 2: return 3 | delay; case 2: return 3 | delay;
case 3: return 0 | delay; case 3: return 0 | delay;
} }
} else if (type == BlockID.TRAP_DOOR) { break;
case BlockID.TRAP_DOOR:
int open = data & 0x4; int open = data & 0x4;
int withoutOpen = data ^ 0x4; int withoutOpen = data & ~0x4;
switch (withoutOpen) { switch (withoutOpen) {
case 0: return 3 | open; case 0: return 3 | open;
case 1: return 2 | open; case 1: return 2 | open;
case 2: return 0 | open; case 2: return 0 | open;
case 3: return 1 | open; case 3: return 1 | open;
} }
} else if (type == BlockID.PISTON_BASE || type == BlockID.PISTON_STICKY_BASE || type == BlockID.PISTON_EXTENSION) { case BlockID.PISTON_BASE:
case BlockID.PISTON_STICKY_BASE:
case BlockID.PISTON_EXTENSION:
switch(data) { switch(data) {
case 0: return 0; case 0: return 0;
case 1: return 1; case 1: return 1;
case 2: return 5; case 2: return 5;
case 3: return 4; case 3: return 4;
case 4: return 2; case 4: return 2;
case 5: return 3; case 5: return 3;
} }
} }
return data; return data;
} }
@ -157,122 +176,135 @@ public final class BlockData {
*/ */
public static int rotate90Reverse(int type, int data) { public static int rotate90Reverse(int type, int data) {
// case ([0-9]+): return ([0-9]+) -> case \2: return \1 // case ([0-9]+): return ([0-9]+) -> case \2: return \1
if (type == BlockID.TORCH switch (type) {
|| type == BlockID.REDSTONE_TORCH_OFF case BlockID.TORCH:
|| type == BlockID.REDSTONE_TORCH_ON) { case BlockID.REDSTONE_TORCH_OFF:
case BlockID.REDSTONE_TORCH_ON:
switch (data) { switch (data) {
case 3: return 1; case 3: return 1;
case 4: return 2; case 4: return 2;
case 2: return 3; case 2: return 3;
case 1: return 4; case 1: return 4;
} }
} else if (type == BlockID.MINECART_TRACKS) { break;
case BlockID.MINECART_TRACKS:
switch (data) { switch (data) {
case 1: return 0; case 7: return 6;
case 0: return 1; case 8: return 7;
case 5: return 2; case 9: return 8;
case 4: return 3; case 6: return 9;
case 2: return 4;
case 3: return 5;
case 7: return 6;
case 8: return 7;
case 9: return 8;
case 6: return 9;
} }
} else if (type == BlockID.WOODEN_STAIRS /* FALL-THROUGH */
|| type == BlockID.COBBLESTONE_STAIRS) {
case BlockID.POWERED_RAIL:
case BlockID.DETECTOR_RAIL:
switch (data & 0x7) {
case 1: return 0;
case 0: return 1;
case 5: return 2;
case 4: return 3;
case 2: return 4;
case 3: return 5;
}
break;
case BlockID.WOODEN_STAIRS:
case BlockID.COBBLESTONE_STAIRS:
switch (data) { switch (data) {
case 2: return 0; case 2: return 0;
case 3: return 1; case 3: return 1;
case 1: return 2; case 1: return 2;
case 0: return 3; case 0: return 3;
} }
} else if (type == BlockID.LEVER) { break;
case BlockID.LEVER:
case BlockID.STONE_BUTTON:
int thrown = data & 0x8; int thrown = data & 0x8;
int withoutThrown = data ^ 0x8; int withoutThrown = data & ~0x8;
switch (withoutThrown) { switch (withoutThrown) {
case 3: return 1 | thrown; case 3: return 1 | thrown;
case 4: return 2 | thrown; case 4: return 2 | thrown;
case 2: return 3 | thrown; case 2: return 3 | thrown;
case 1: return 4 | thrown; case 1: return 4 | thrown;
} }
} else if (type == BlockID.WOODEN_DOOR break;
|| type == BlockID.IRON_DOOR) {
case BlockID.WOODEN_DOOR:
case BlockID.IRON_DOOR:
int topHalf = data & 0x8; int topHalf = data & 0x8;
int swung = data & 0x4; int swung = data & 0x4;
int withoutFlags = data ^ (0x8 | 0x4); int withoutFlags = data & ~(0x8 | 0x4);
switch (withoutFlags) { switch (withoutFlags) {
case 1: return 0 | topHalf | swung; case 1: return 0 | topHalf | swung;
case 2: return 1 | topHalf | swung; case 2: return 1 | topHalf | swung;
case 3: return 2 | topHalf | swung; case 3: return 2 | topHalf | swung;
case 0: return 3 | topHalf | swung; case 0: return 3 | topHalf | swung;
} }
} else if (type == BlockID.STONE_BUTTON) { break;
int thrown = data & 0x8;
int withoutThrown = data ^ 0x8; case BlockID.SIGN_POST:
switch (withoutThrown) { return (data + 12) % 16;
case 3: return 1 | thrown;
case 4: return 2 | thrown; case BlockID.LADDER:
case 2: return 3 | thrown; case BlockID.WALL_SIGN:
case 1: return 4 | thrown; case BlockID.FURNACE:
} case BlockID.BURNING_FURNACE:
} else if (type == BlockID.SIGN_POST) { case BlockID.DISPENSER:
int newData = (data - 4);
if (newData < 0) {
newData += 16;
}
return newData;
} else if (type == BlockID.LADDER
|| type == BlockID.WALL_SIGN
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.DISPENSER) {
switch (data) { switch (data) {
case 5: return 2; case 5: return 2;
case 4: return 3; case 4: return 3;
case 2: return 4; case 2: return 4;
case 3: return 5; case 3: return 5;
} }
} else if (type == BlockID.PUMPKIN break;
|| type == BlockID.JACKOLANTERN) {
case BlockID.PUMPKIN:
case BlockID.JACKOLANTERN:
switch (data) { switch (data) {
case 1: return 0; case 1: return 0;
case 2: return 1; case 2: return 1;
case 3: return 2; case 3: return 2;
case 0: return 3; case 0: return 3;
} }
} else if (type == BlockID.REDSTONE_REPEATER_OFF break;
|| type == BlockID.REDSTONE_REPEATER_ON) {
case BlockID.REDSTONE_REPEATER_OFF:
case BlockID.REDSTONE_REPEATER_ON:
int dir = data & 0x03; int dir = data & 0x03;
int delay = data ^ 0x03; int delay = data - dir;
switch (dir) { switch (dir) {
case 1: return 0 | delay; case 1: return 0 | delay;
case 2: return 1 | delay; case 2: return 1 | delay;
case 3: return 2 | delay; case 3: return 2 | delay;
case 0: return 3 | delay; case 0: return 3 | delay;
} }
} else if (type == BlockID.TRAP_DOOR) { break;
case BlockID.TRAP_DOOR:
int open = data & 0x4; int open = data & 0x4;
int withoutOpen = data ^ 0x4; int withoutOpen = data & ~0x4;
switch (withoutOpen) { switch (withoutOpen) {
case 3: return 0 | open; case 3: return 0 | open;
case 2: return 1 | open; case 2: return 1 | open;
case 0: return 2 | open; case 0: return 2 | open;
case 1: return 3 | open; case 1: return 3 | open;
}
case BlockID.PISTON_BASE:
case BlockID.PISTON_STICKY_BASE:
case BlockID.PISTON_EXTENSION:
switch(data) {
case 0: return 0;
case 1: return 1;
case 5: return 2;
case 4: return 3;
case 2: return 4;
case 3: return 5;
} }
} else if (type == BlockID.PISTON_BASE || type == BlockID.PISTON_STICKY_BASE || type == BlockID.PISTON_EXTENSION) {
int dir = data & 0x8;
switch(dir) {
case 0: return 0;
case 1: return 1;
case 2: return 4;
case 3: return 5;
case 4: return 3;
case 5: return 2;
}
} }
return data; return data;
} }
@ -281,9 +313,150 @@ public final class BlockData {
* *
* @param type * @param type
* @param data * @param data
* @param direction
* @return * @return
*/ */
public static int flip(int type, int data) { public static int flip(int type, int data, FlipDirection direction) {
return rotate90(type, rotate90(type, data)); int flipX = 0;
int flipY = 0;
int flipZ = 0;
switch (direction) {
case NORTH_SOUTH:
flipX = 1;
break;
case WEST_EAST:
flipY = 1;
break;
case UP_DOWN:
flipZ = 1;
break;
}
switch (type) {
case BlockID.TORCH:
case BlockID.REDSTONE_TORCH_OFF:
case BlockID.REDSTONE_TORCH_ON:
case BlockID.LEVER:
case BlockID.STONE_BUTTON:
switch (data & ~0x8) {
case 1: return data + flipX;
case 2: return data - flipX;
case 3: return data + flipY;
case 4: return data - flipY;
}
break;
case BlockID.MINECART_TRACKS:
switch (data) {
case 6: return data + flipX + 3*flipY;
case 7: return data - flipX + flipY;
case 8: return data + flipX - flipY;
case 9: return data - flipX - 3*flipY;
}
/* FALL-THROUGH */
case BlockID.POWERED_RAIL:
case BlockID.DETECTOR_RAIL:
switch (data & 0x7) {
case 0:
case 1:
return data;
case 2:
case 3:
return data ^ flipX;
case 4:
case 5:
return data ^ flipY;
}
break;
case BlockID.WOODEN_STAIRS:
case BlockID.COBBLESTONE_STAIRS:
switch (data) {
case 0:
case 1:
return data ^ flipX;
case 2:
case 3:
return data ^ flipY;
}
break;
case BlockID.WOODEN_DOOR:
case BlockID.IRON_DOOR:
switch (data & 0x3) {
case 0: return data + flipX + 3*flipY;
case 1: return data - flipX + flipY;
case 2: return data + flipX - flipY;
case 3: return data - flipX - 3*flipY;
}
break;
case BlockID.SIGN_POST:
return (data + 8) % 16; // broken!
case BlockID.LADDER:
case BlockID.WALL_SIGN:
case BlockID.FURNACE:
case BlockID.BURNING_FURNACE:
case BlockID.DISPENSER:
switch (data) {
case 2:
case 3:
return data ^ flipY;
case 4:
case 5:
return data ^ flipX;
}
break;
case BlockID.PUMPKIN:
case BlockID.JACKOLANTERN:
case BlockID.REDSTONE_REPEATER_OFF:
case BlockID.REDSTONE_REPEATER_ON:
switch (data & 0x3) {
case 0:
case 2:
return data ^ (flipY<<1);
case 1:
case 3:
return data ^ (flipX<<1);
}
break;
case BlockID.TRAP_DOOR:
switch (data & 0x3) {
case 0:
case 1:
return data ^ flipY;
case 2:
case 3:
return data ^ flipX;
}
break;
case BlockID.PISTON_BASE:
case BlockID.PISTON_STICKY_BASE:
case BlockID.PISTON_EXTENSION:
switch(data & ~0x8) {
case 0:
case 1:
return data ^ flipZ;
case 2:
case 3:
return data ^ flipY;
case 4:
case 5:
return data ^ flipX;
}
}
return data;
} }
} }