From 8e84e7ae18fa85ff97060ad6a7b37e66d7e8e499 Mon Sep 17 00:00:00 2001 From: TomyLobo Date: Fri, 26 Aug 2011 12:41:31 +0200 Subject: [PATCH] - 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 --- .../com/sk89q/worldedit/CuboidClipboard.java | 51 +- .../com/sk89q/worldedit/blocks/BaseBlock.java | 6 +- .../com/sk89q/worldedit/data/BlockData.java | 525 ++++++++++++------ 3 files changed, 390 insertions(+), 192 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/CuboidClipboard.java b/src/main/java/com/sk89q/worldedit/CuboidClipboard.java index f03f1e33a..fe95913f2 100644 --- a/src/main/java/com/sk89q/worldedit/CuboidClipboard.java +++ b/src/main/java/com/sk89q/worldedit/CuboidClipboard.java @@ -182,14 +182,22 @@ public class CuboidClipboard { switch (dir) { 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 z = 0; z < length; ++z) { for (int y = 0; y < height; ++y) { - BaseBlock old = data[xs][y][z]; - old.flip(); - data[xs][y][z] = data[width - xs - 1][y][z]; - data[width - xs - 1][y][z] = old; + BaseBlock a = data[xs][y][z]; + //System.out.println(xs+"/"+y+"/"+z+": "+a.getType()); + a.flip(dir); + + 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; 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 x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { - BaseBlock old = data[x][y][zs]; - old.flip(); - data[x][y][zs] = data[x][y][length - zs - 1]; - data[x][y][length - zs - 1] = old; + BaseBlock a = data[x][y][zs]; + a.flip(dir); + + 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; 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 x = 0; x < width; ++x) { for (int z = 0; z < length; ++z) { - BaseBlock old = data[x][ys][z]; - data[x][ys][z] = data[x][height - ys - 1][z]; - data[x][height - ys - 1][z] = old; + BaseBlock a = data[x][ys][z]; + a.flip(dir); + + 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; } } } diff --git a/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java b/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java index 33120bd4a..920508409 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java +++ b/src/main/java/com/sk89q/worldedit/blocks/BaseBlock.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.blocks; +import com.sk89q.worldedit.CuboidClipboard.FlipDirection; import com.sk89q.worldedit.data.BlockData; /** @@ -109,8 +110,9 @@ public class BaseBlock { /** * Flip this block. + * @param direction */ - public void flip() { - data = (char)BlockData.flip(type, data); + public void flip(FlipDirection direction) { + data = (char)BlockData.flip(type, data, direction); } } diff --git a/src/main/java/com/sk89q/worldedit/data/BlockData.java b/src/main/java/com/sk89q/worldedit/data/BlockData.java index 89569ead3..1c5648b63 100644 --- a/src/main/java/com/sk89q/worldedit/data/BlockData.java +++ b/src/main/java/com/sk89q/worldedit/data/BlockData.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.data; +import com.sk89q.worldedit.CuboidClipboard.FlipDirection; import com.sk89q.worldedit.blocks.BlockID; /** @@ -35,116 +36,134 @@ public final class BlockData { * @return */ public static int rotate90(int type, int data) { - if (type == BlockID.TORCH - || type == BlockID.REDSTONE_TORCH_OFF - || type == BlockID.REDSTONE_TORCH_ON) { + switch (type) { + case BlockID.TORCH: + case BlockID.REDSTONE_TORCH_OFF: + case BlockID.REDSTONE_TORCH_ON: switch (data) { - case 1: return 3; - case 2: return 4; - case 3: return 2; - case 4: return 1; + case 1: return 3; + case 2: return 4; + case 3: return 2; + case 4: return 1; } - } else if (type == BlockID.MINECART_TRACKS) { + break; + + case BlockID.MINECART_TRACKS: switch (data) { - case 0: return 1; - case 1: return 0; - case 2: return 5; - case 3: return 4; - case 4: return 2; - case 5: return 3; - case 6: return 7; - case 7: return 8; - case 8: return 9; - case 9: return 6; + case 6: return 7; + case 7: return 8; + case 8: return 9; + case 9: return 6; } - } else if (type == BlockID.WOODEN_STAIRS - || type == BlockID.COBBLESTONE_STAIRS) { + /* FALL-THROUGH */ + + 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) { - case 0: return 2; - case 1: return 3; - case 2: return 1; - case 3: return 0; + case 0: return 2; + case 1: return 3; + case 2: return 1; + case 3: return 0; } - } else if (type == BlockID.LEVER) { + break; + + case BlockID.LEVER: + case BlockID.STONE_BUTTON: int thrown = data & 0x8; - int withoutThrown = data ^ 0x8; + int withoutThrown = data & ~0x8; switch (withoutThrown) { - case 1: return 3 | thrown; - case 2: return 4 | thrown; - case 3: return 2 | thrown; - case 4: return 1 | thrown; + case 1: return 3 | thrown; + case 2: return 4 | thrown; + case 3: return 2 | thrown; + case 4: return 1 | thrown; } - } else if (type == BlockID.WOODEN_DOOR - || type == BlockID.IRON_DOOR) { + break; + + case BlockID.WOODEN_DOOR: + case BlockID.IRON_DOOR: int topHalf = data & 0x8; int swung = data & 0x4; - int withoutFlags = data ^ (0x8 | 0x4); + int withoutFlags = data & ~(0x8 | 0x4); switch (withoutFlags) { - case 0: return 1 | topHalf | swung; - case 1: return 2 | topHalf | swung; - case 2: return 3 | topHalf | swung; - case 3: return 0 | topHalf | swung; + case 0: return 1 | topHalf | swung; + case 1: return 2 | topHalf | swung; + case 2: return 3 | topHalf | swung; + case 3: return 0 | topHalf | swung; } - } else if (type == BlockID.STONE_BUTTON) { - int thrown = data & 0x8; - int withoutThrown = data ^ 0x8; - 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) { + break; + + case BlockID.SIGN_POST: return (data + 4) % 16; - } else if (type == BlockID.LADDER - || type == BlockID.WALL_SIGN - || type == BlockID.FURNACE - || type == BlockID.BURNING_FURNACE - || type == BlockID.DISPENSER) { + + case BlockID.LADDER: + case BlockID.WALL_SIGN: + case BlockID.FURNACE: + case BlockID.BURNING_FURNACE: + case BlockID.DISPENSER: switch (data) { - case 2: return 5; - case 3: return 4; - case 4: return 2; - case 5: return 3; + case 2: return 5; + case 3: return 4; + case 4: return 2; + case 5: return 3; } - } else if (type == BlockID.PUMPKIN - || type == BlockID.JACKOLANTERN) { + break; + + case BlockID.PUMPKIN: + case BlockID.JACKOLANTERN: switch (data) { - case 0: return 1; - case 1: return 2; - case 2: return 3; - case 3: return 0; + case 0: return 1; + case 1: return 2; + case 2: return 3; + case 3: return 0; } - } else if (type == BlockID.REDSTONE_REPEATER_OFF - || type == BlockID.REDSTONE_REPEATER_ON) { + break; + + case BlockID.REDSTONE_REPEATER_OFF: + case BlockID.REDSTONE_REPEATER_ON: int dir = data & 0x03; int delay = data - dir; switch (dir) { - case 0: return 1 | delay; - case 1: return 2 | delay; - case 2: return 3 | delay; - case 3: return 0 | delay; + case 0: return 1 | delay; + case 1: return 2 | delay; + case 2: return 3 | delay; + case 3: return 0 | delay; } - } else if (type == BlockID.TRAP_DOOR) { + break; + + case BlockID.TRAP_DOOR: int open = data & 0x4; - int withoutOpen = data ^ 0x4; + int withoutOpen = data & ~0x4; switch (withoutOpen) { - case 0: return 3 | open; - case 1: return 2 | open; - case 2: return 0 | open; - case 3: return 1 | open; + case 0: return 3 | open; + case 1: return 2 | open; + case 2: return 0 | 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) { - case 0: return 0; - case 1: return 1; - case 2: return 5; - case 3: return 4; - case 4: return 2; - case 5: return 3; + case 0: return 0; + case 1: return 1; + case 2: return 5; + case 3: return 4; + case 4: return 2; + case 5: return 3; } } - + return data; } @@ -157,122 +176,135 @@ public final class BlockData { */ public static int rotate90Reverse(int type, int data) { // case ([0-9]+): return ([0-9]+) -> case \2: return \1 - - if (type == BlockID.TORCH - || type == BlockID.REDSTONE_TORCH_OFF - || type == BlockID.REDSTONE_TORCH_ON) { + + switch (type) { + case BlockID.TORCH: + case BlockID.REDSTONE_TORCH_OFF: + case BlockID.REDSTONE_TORCH_ON: switch (data) { - case 3: return 1; - case 4: return 2; - case 2: return 3; - case 1: return 4; + case 3: return 1; + case 4: return 2; + case 2: return 3; + case 1: return 4; } - } else if (type == BlockID.MINECART_TRACKS) { + break; + + case BlockID.MINECART_TRACKS: switch (data) { - case 1: return 0; - case 0: return 1; - case 5: return 2; - case 4: return 3; - case 2: return 4; - case 3: return 5; - case 7: return 6; - case 8: return 7; - case 9: return 8; - case 6: return 9; + case 7: return 6; + case 8: return 7; + case 9: return 8; + case 6: return 9; } - } else if (type == BlockID.WOODEN_STAIRS - || type == BlockID.COBBLESTONE_STAIRS) { + /* FALL-THROUGH */ + + 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) { - case 2: return 0; - case 3: return 1; - case 1: return 2; - case 0: return 3; + case 2: return 0; + case 3: return 1; + case 1: return 2; + case 0: return 3; } - } else if (type == BlockID.LEVER) { + break; + + case BlockID.LEVER: + case BlockID.STONE_BUTTON: int thrown = data & 0x8; - int withoutThrown = data ^ 0x8; + int withoutThrown = data & ~0x8; switch (withoutThrown) { - case 3: return 1 | thrown; - case 4: return 2 | thrown; - case 2: return 3 | thrown; - case 1: return 4 | thrown; + case 3: return 1 | thrown; + case 4: return 2 | thrown; + case 2: return 3 | thrown; + case 1: return 4 | thrown; } - } else if (type == BlockID.WOODEN_DOOR - || type == BlockID.IRON_DOOR) { + break; + + case BlockID.WOODEN_DOOR: + case BlockID.IRON_DOOR: int topHalf = data & 0x8; int swung = data & 0x4; - int withoutFlags = data ^ (0x8 | 0x4); + int withoutFlags = data & ~(0x8 | 0x4); switch (withoutFlags) { - case 1: return 0 | topHalf | swung; - case 2: return 1 | topHalf | swung; - case 3: return 2 | topHalf | swung; - case 0: return 3 | topHalf | swung; + case 1: return 0 | topHalf | swung; + case 2: return 1 | topHalf | swung; + case 3: return 2 | topHalf | swung; + case 0: return 3 | topHalf | swung; } - } else if (type == BlockID.STONE_BUTTON) { - int thrown = data & 0x8; - int withoutThrown = data ^ 0x8; - switch (withoutThrown) { - case 3: return 1 | thrown; - case 4: return 2 | thrown; - case 2: return 3 | thrown; - case 1: return 4 | thrown; - } - } else if (type == BlockID.SIGN_POST) { - 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) { + break; + + case BlockID.SIGN_POST: + return (data + 12) % 16; + + case BlockID.LADDER: + case BlockID.WALL_SIGN: + case BlockID.FURNACE: + case BlockID.BURNING_FURNACE: + case BlockID.DISPENSER: switch (data) { - case 5: return 2; - case 4: return 3; - case 2: return 4; - case 3: return 5; + case 5: return 2; + case 4: return 3; + case 2: return 4; + case 3: return 5; } - } else if (type == BlockID.PUMPKIN - || type == BlockID.JACKOLANTERN) { + break; + + case BlockID.PUMPKIN: + case BlockID.JACKOLANTERN: switch (data) { - case 1: return 0; - case 2: return 1; - case 3: return 2; - case 0: return 3; + case 1: return 0; + case 2: return 1; + case 3: return 2; + case 0: return 3; } - } else if (type == BlockID.REDSTONE_REPEATER_OFF - || type == BlockID.REDSTONE_REPEATER_ON) { + break; + + case BlockID.REDSTONE_REPEATER_OFF: + case BlockID.REDSTONE_REPEATER_ON: int dir = data & 0x03; - int delay = data ^ 0x03; + int delay = data - dir; switch (dir) { - case 1: return 0 | delay; - case 2: return 1 | delay; - case 3: return 2 | delay; - case 0: return 3 | delay; + case 1: return 0 | delay; + case 2: return 1 | delay; + case 3: return 2 | delay; + case 0: return 3 | delay; } - } else if (type == BlockID.TRAP_DOOR) { + break; + + case BlockID.TRAP_DOOR: int open = data & 0x4; - int withoutOpen = data ^ 0x4; + int withoutOpen = data & ~0x4; switch (withoutOpen) { - case 3: return 0 | open; - case 2: return 1 | open; - case 0: return 2 | open; - case 1: return 3 | open; + case 3: return 0 | open; + case 2: return 1 | open; + case 0: return 2 | 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; } @@ -281,9 +313,150 @@ public final class BlockData { * * @param type * @param data + * @param direction * @return */ - public static int flip(int type, int data) { - return rotate90(type, rotate90(type, data)); + public static int flip(int type, int data, FlipDirection direction) { + 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; } }