From 0e3577063e37e64e9c49927c8f09ebcb416946a8 Mon Sep 17 00:00:00 2001 From: dfsek Date: Mon, 9 Nov 2020 00:39:09 -0700 Subject: [PATCH] Move Rotation stuff for Structures to separate class --- .../terra/async/AsyncStructureFinder.java | 3 +- .../terra/command/structure/LoadCommand.java | 5 +- .../terra/config/genconfig/TreeConfig.java | 3 +- .../terra/population/StructurePopulator.java | 3 +- .../com/dfsek/terra/structure/Rotation.java | 48 ++++++++ .../com/dfsek/terra/structure/Structure.java | 111 +++--------------- .../terra/util/structure/RotationUtil.java | 55 ++++++++- 7 files changed, 121 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/dfsek/terra/structure/Rotation.java diff --git a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java index 04dd0a576..5a0191bc8 100644 --- a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java +++ b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java @@ -4,6 +4,7 @@ import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.genconfig.structure.StructureConfig; +import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Structure; import org.bukkit.Location; import org.bukkit.World; @@ -36,7 +37,7 @@ public class AsyncStructureFinder extends AsyncFeatureFinder { return false; Random r2 = new Random(spawn.hashCode()); Structure struc = target.getStructure(r2); - Structure.Rotation rotation = Structure.Rotation.fromDegrees(r2.nextInt(4) * 90); + Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90); for(int y = target.getSearchStart().get(r2); y > 0; y--) { if(!target.getBound().isInRange(y)) return false; spawn.setY(y); diff --git a/src/main/java/com/dfsek/terra/command/structure/LoadCommand.java b/src/main/java/com/dfsek/terra/command/structure/LoadCommand.java index d12aa1910..51e327f6d 100644 --- a/src/main/java/com/dfsek/terra/command/structure/LoadCommand.java +++ b/src/main/java/com/dfsek/terra/command/structure/LoadCommand.java @@ -2,6 +2,7 @@ package com.dfsek.terra.command.structure; import com.dfsek.terra.Terra; import com.dfsek.terra.config.lang.LangUtil; +import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Structure; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -23,9 +24,9 @@ public class LoadCommand extends PlayerCommand implements DebugCommand { @Override public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { try { - Structure.Rotation r; + Rotation r; try { - r = Structure.Rotation.fromDegrees(Integer.parseInt(args[1])); + r = Rotation.fromDegrees(Integer.parseInt(args[1])); } catch(NumberFormatException e) { LangUtil.send("command.structure.invalid-rotation", sender, args[1]); return true; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/TreeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/TreeConfig.java index 1ee3c9c93..56732b4b6 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/TreeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/TreeConfig.java @@ -6,6 +6,7 @@ import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.exception.ConfigException; import com.dfsek.terra.config.exception.NotFoundException; +import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Structure; import org.bukkit.Location; import org.bukkit.Material; @@ -67,7 +68,7 @@ public class TreeConfig extends TerraConfig implements Tree { Location mut = location.clone().subtract(0, yOffset, 0); if(!spawnable.contains(location.getBlock().getType())) return false; Structure struc = structure.get(random); - Structure.Rotation rotation = Structure.Rotation.fromDegrees(random.nextInt(4) * 90); + Rotation rotation = Rotation.fromDegrees(random.nextInt(4) * 90); if(!struc.checkSpawns(mut, rotation)) return false; struc.paste(mut, rotation); return true; diff --git a/src/main/java/com/dfsek/terra/population/StructurePopulator.java b/src/main/java/com/dfsek/terra/population/StructurePopulator.java index 816af7527..844941596 100644 --- a/src/main/java/com/dfsek/terra/population/StructurePopulator.java +++ b/src/main/java/com/dfsek/terra/population/StructurePopulator.java @@ -8,6 +8,7 @@ import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.genconfig.structure.StructureConfig; import com.dfsek.terra.procgen.math.Vector2; +import com.dfsek.terra.structure.Rotation; import com.dfsek.terra.structure.Structure; import com.dfsek.terra.structure.StructureContainedInventory; import com.dfsek.terra.structure.features.Feature; @@ -41,7 +42,7 @@ public class StructurePopulator extends BlockPopulator { if(!config.getBiome((UserDefinedBiome) grid.getBiome(spawn)).getStructures().contains(conf)) continue; Random r2 = new Random(spawn.hashCode()); Structure struc = conf.getStructure(r2); - Structure.Rotation rotation = Structure.Rotation.fromDegrees(r2.nextInt(4) * 90); + Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90); for(int y = conf.getSearchStart().get(r2); y > 0; y--) { if(!conf.getBound().isInRange(y)) continue structure; spawn.setY(y); diff --git a/src/main/java/com/dfsek/terra/structure/Rotation.java b/src/main/java/com/dfsek/terra/structure/Rotation.java new file mode 100644 index 000000000..f1a91d212 --- /dev/null +++ b/src/main/java/com/dfsek/terra/structure/Rotation.java @@ -0,0 +1,48 @@ +package com.dfsek.terra.structure; + +public enum Rotation { + CW_90(90), CW_180(180), CCW_90(270), NONE(0); + private final int degrees; + + Rotation(int degrees) { + this.degrees = degrees; + } + + public static Rotation fromDegrees(int deg) { + switch(Math.floorMod(deg, 360)) { + case 0: + return Rotation.NONE; + case 90: + return Rotation.CW_90; + case 180: + return Rotation.CW_180; + case 270: + return Rotation.CCW_90; + default: + throw new IllegalArgumentException(); + } + } + + public int getDegrees() { + return degrees; + } + + public Rotation inverse() { + switch(this) { + case NONE: + return NONE; + case CCW_90: + return CW_90; + case CW_90: + return CCW_90; + case CW_180: + return CW_180; + default: + throw new IllegalArgumentException(); + } + } + + public enum Axis { + X, Y, Z + } +} diff --git a/src/main/java/com/dfsek/terra/structure/Structure.java b/src/main/java/com/dfsek/terra/structure/Structure.java index fd21dcf8d..e7d041e60 100644 --- a/src/main/java/com/dfsek/terra/structure/Structure.java +++ b/src/main/java/com/dfsek/terra/structure/Structure.java @@ -2,6 +2,7 @@ package com.dfsek.terra.structure; import com.dfsek.terra.Debug; import com.dfsek.terra.procgen.math.Vector2; +import com.dfsek.terra.util.structure.RotationUtil; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; @@ -11,12 +12,6 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Directional; -import org.bukkit.block.data.MultipleFacing; -import org.bukkit.block.data.Orientable; -import org.bukkit.block.data.Rail; -import org.bukkit.block.data.Rotatable; -import org.bukkit.block.data.type.RedstoneWire; import org.bukkit.inventory.BlockInventoryHolder; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.math.Range; @@ -29,14 +24,12 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Objects; import java.util.UUID; import java.util.function.Consumer; -import static com.dfsek.terra.util.structure.RotationUtil.*; +import static com.dfsek.terra.util.structure.RotationUtil.getRotatedCoords; @SuppressWarnings("unused") public class Structure implements Serializable { @@ -158,9 +151,9 @@ public class Structure implements Serializable { * @param r Rotation */ public void paste(@NotNull Location origin, Rotation r) { - Range xRange = getRange(Axis.X, r); - Range zRange = getRange(Axis.Z, r); - this.executeForBlocksInRange(xRange, getRange(Axis.Y, r), zRange, block -> pasteBlock(block, origin, r), r); + Range xRange = getRange(Rotation.Axis.X, r); + Range zRange = getRange(Rotation.Axis.Z, r); + this.executeForBlocksInRange(xRange, getRange(Rotation.Axis.Y, r), zRange, block -> pasteBlock(block, origin, r), r); } /** @@ -176,6 +169,7 @@ public class Structure implements Serializable { Location loc = origin.clone().add(block.getX(), block.getY(), block.getZ()); Block worldBlock = loc.getBlock(); + main: while(worldBlock.isEmpty()) { if(loc.getBlockY() > 255 || loc.getBlockY() < 0) return; @@ -196,37 +190,8 @@ public class Structure implements Serializable { if(offset != 0) worldBlock = worldBlock.getRelative((offset > 0) ? BlockFace.UP : BlockFace.DOWN, Math.abs(offset)); - if(data instanceof Rotatable) { - BlockFace rt = getRotatedFace(((Rotatable) data).getRotation(), r); - ((Rotatable) data).setRotation(rt); - } else if(data instanceof Directional) { - BlockFace rt = getRotatedFace(((Directional) data).getFacing(), r); - ((Directional) data).setFacing(rt); - } else if(data instanceof MultipleFacing) { - MultipleFacing mfData = (MultipleFacing) data; - Map faces = new HashMap<>(); - for(BlockFace f : mfData.getAllowedFaces()) { - faces.put(f, mfData.hasFace(f)); - } - for(Map.Entry face : faces.entrySet()) { - mfData.setFace(getRotatedFace(face.getKey(), r), face.getValue()); - } - } else if(data instanceof Rail) { - Rail.Shape newShape = getRotatedRail(((Rail) data).getShape(), r); - ((Rail) data).setShape(newShape); - } else if(data instanceof Orientable) { - org.bukkit.Axis newAxis = getRotatedAxis(((Orientable) data).getAxis(), r); - ((Orientable) data).setAxis(newAxis); - } else if(data instanceof RedstoneWire) { - Map connections = new HashMap<>(); - RedstoneWire rData = (RedstoneWire) data; - for(BlockFace f : rData.getAllowedFaces()) { - connections.put(f, rData.getFace(f)); - } - for(Map.Entry e : connections.entrySet()) { - rData.setFace(getRotatedFace(e.getKey(), r), e.getValue()); - } - } + RotationUtil.rotateBlockData(data, r); + worldBlock.setBlockData(data, false); if(block.getState() != null) { block.getState().getState(worldBlock.getState()).update(true, false); @@ -281,22 +246,22 @@ public class Structure implements Serializable { } @NotNull - public Range getRange(@NotNull Axis a, @NotNull Rotation r) { - if(a.equals(Axis.Y)) return getRawRange(a); + public Range getRange(@NotNull Rotation.Axis a, @NotNull Rotation r) { + if(a.equals(Rotation.Axis.Y)) return getRawRange(a); Vector2 center = new Vector2(structureInfo.getCenterX(), structureInfo.getCenterZ()); - Range x = getRawRange(Axis.X); - Range z = getRawRange(Axis.Z); + Range x = getRawRange(Rotation.Axis.X); + Range z = getRawRange(Rotation.Axis.Z); Vector2 min = getRotatedCoords(new Vector2(x.getMin(), z.getMin()).subtract(center), r.inverse()).add(center); Vector2 max = getRotatedCoords(new Vector2(x.getMax(), z.getMax()).subtract(center), r.inverse()).add(center); - if(a.equals(Axis.X)) + if(a.equals(Rotation.Axis.X)) return new Range((int) Math.floor(Math.min(min.getX(), max.getX())), (int) Math.ceil(Math.max(min.getX(), max.getX())) + 1); else return new Range((int) Math.floor(Math.min(min.getZ(), max.getZ())), (int) Math.ceil(Math.max(min.getZ(), max.getZ())) + 1); } @NotNull - private Range getRawRange(@NotNull Axis a) { + private Range getRawRange(@NotNull Rotation.Axis a) { switch(a) { case X: return new Range(0, structureInfo.getSizeX()); @@ -335,7 +300,7 @@ public class Structure implements Serializable { Range intersectX = new Range(xOr, xOr + 16).sub(origin.getBlockX() - structureInfo.getCenterX()); Range intersectZ = new Range(zOr, zOr + 16).sub(origin.getBlockZ() - structureInfo.getCenterZ()); if(intersectX == null || intersectZ == null) return; - executeForBlocksInRange(intersectX, getRange(Axis.Y, r), intersectZ, block -> pasteBlock(block, origin, r), r); + executeForBlocksInRange(intersectX, getRange(Rotation.Axis.Y, r), intersectZ, block -> pasteBlock(block, origin, r), r); Debug.info(intersectX.toString() + " : " + intersectZ.toString()); } @@ -375,50 +340,4 @@ public class Structure implements Serializable { return uuid; } - public enum Axis { - X, Y, Z - } - - public enum Rotation { - CW_90(90), CW_180(180), CCW_90(270), NONE(0); - private final int degrees; - - Rotation(int degrees) { - this.degrees = degrees; - } - - public static Rotation fromDegrees(int deg) { - switch(Math.floorMod(deg, 360)) { - case 0: - return Rotation.NONE; - case 90: - return Rotation.CW_90; - case 180: - return Rotation.CW_180; - case 270: - return Rotation.CCW_90; - default: - throw new IllegalArgumentException(); - } - } - - public int getDegrees() { - return degrees; - } - - public Rotation inverse() { - switch(this) { - case NONE: - return NONE; - case CCW_90: - return CW_90; - case CW_90: - return CCW_90; - case CW_180: - return CW_180; - default: - throw new IllegalArgumentException(); - } - } - } } diff --git a/src/main/java/com/dfsek/terra/util/structure/RotationUtil.java b/src/main/java/com/dfsek/terra/util/structure/RotationUtil.java index 4fc7f4797..9a97c0aa0 100644 --- a/src/main/java/com/dfsek/terra/util/structure/RotationUtil.java +++ b/src/main/java/com/dfsek/terra/util/structure/RotationUtil.java @@ -1,9 +1,18 @@ package com.dfsek.terra.util.structure; import com.dfsek.terra.procgen.math.Vector2; -import com.dfsek.terra.structure.Structure; +import com.dfsek.terra.structure.Rotation; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.MultipleFacing; +import org.bukkit.block.data.Orientable; import org.bukkit.block.data.Rail; +import org.bukkit.block.data.Rotatable; +import org.bukkit.block.data.type.RedstoneWire; + +import java.util.HashMap; +import java.util.Map; public final class RotationUtil { /** @@ -13,7 +22,7 @@ public final class RotationUtil { * @param r Rotation * @return Rotated coordinate pair */ - public static Vector2 getRotatedCoords(Vector2 orig, Structure.Rotation r) { + public static Vector2 getRotatedCoords(Vector2 orig, Rotation r) { Vector2 copy = orig.clone(); switch(r) { case CW_90: @@ -36,7 +45,7 @@ public final class RotationUtil { * @param r Rotation * @return Rotated BlockFace */ - public static BlockFace getRotatedFace(BlockFace f, Structure.Rotation r) { + public static BlockFace getRotatedFace(BlockFace f, Rotation r) { BlockFace n = f; int rotateNum = r.getDegrees() / 90; int rn = faceRotation(f); @@ -136,9 +145,9 @@ public final class RotationUtil { } } - public static org.bukkit.Axis getRotatedAxis(org.bukkit.Axis orig, Structure.Rotation r) { + public static org.bukkit.Axis getRotatedAxis(org.bukkit.Axis orig, Rotation r) { org.bukkit.Axis other = orig; - final boolean shouldSwitch = r.equals(Structure.Rotation.CW_90) || r.equals(Structure.Rotation.CCW_90); + final boolean shouldSwitch = r.equals(Rotation.CW_90) || r.equals(Rotation.CCW_90); switch(orig) { case X: if(shouldSwitch) other = org.bukkit.Axis.Z; @@ -158,7 +167,7 @@ public final class RotationUtil { * @return Rotated/mirrored shape */ @SuppressWarnings("fallthrough") - public static Rail.Shape getRotatedRail(Rail.Shape orig, Structure.Rotation r) { + public static Rail.Shape getRotatedRail(Rail.Shape orig, Rotation r) { switch(r) { case CCW_90: switch(orig) { @@ -232,4 +241,38 @@ public final class RotationUtil { } return orig; } + + public static void rotateBlockData(BlockData data, Rotation r) { + if(data instanceof Rotatable) { + BlockFace rt = getRotatedFace(((Rotatable) data).getRotation(), r); + ((Rotatable) data).setRotation(rt); + } else if(data instanceof Directional) { + BlockFace rt = getRotatedFace(((Directional) data).getFacing(), r); + ((Directional) data).setFacing(rt); + } else if(data instanceof MultipleFacing) { + MultipleFacing mfData = (MultipleFacing) data; + Map faces = new HashMap<>(); + for(BlockFace f : mfData.getAllowedFaces()) { + faces.put(f, mfData.hasFace(f)); + } + for(Map.Entry face : faces.entrySet()) { + mfData.setFace(getRotatedFace(face.getKey(), r), face.getValue()); + } + } else if(data instanceof Rail) { + Rail.Shape newShape = getRotatedRail(((Rail) data).getShape(), r); + ((Rail) data).setShape(newShape); + } else if(data instanceof Orientable) { + org.bukkit.Axis newAxis = getRotatedAxis(((Orientable) data).getAxis(), r); + ((Orientable) data).setAxis(newAxis); + } else if(data instanceof RedstoneWire) { + Map connections = new HashMap<>(); + RedstoneWire rData = (RedstoneWire) data; + for(BlockFace f : rData.getAllowedFaces()) { + connections.put(f, rData.getFace(f)); + } + for(Map.Entry e : connections.entrySet()) { + rData.setFace(getRotatedFace(e.getKey(), r), e.getValue()); + } + } + } }