Use Vector2 for structures, move rotation stuff to new util class

This commit is contained in:
dfsek
2020-10-05 01:25:53 -07:00
parent 96d293eec5
commit 0e760ec87e
6 changed files with 189 additions and 178 deletions

View File

@@ -0,0 +1,168 @@
package com.dfsek.terra.util.structure;
import com.dfsek.terra.procgen.math.Vector2;
import com.dfsek.terra.structure.GaeaStructure;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Rail;
import java.util.Arrays;
public class RotationUtil {
/**
* Rotate and mirror a coordinate pair.
* @param arr Array containing X and Z coordinates.
* @param r Rotation
* @return Rotated coordinate pair
*/
public static Vector2 getRotatedCoords(Vector2 orig, GaeaStructure.Rotation r) {
Vector2 copy = orig.clone();
switch(r) {
case CW_90:
copy.setX(orig.getZ()).setZ(-orig.getX());
break;
case CCW_90:
copy.setX(-orig.getZ()).setZ(orig.getX());
break;
case CW_180:
copy.multiply(-1);
break;
}
return copy;
}
/**
* Get the BlockFace with rotation and mirrors applied to it
* @param f BlockFace to apply rotation to
* @param r Rotation
* @return Rotated BlockFace
*/
public static BlockFace getRotatedFace(BlockFace f, GaeaStructure.Rotation r) {
BlockFace n = f;
int rotateNum = r.getDegrees()/90;
int rn = faceRotation(f);
if(rn >= 0) {
n = fromRotation(faceRotation(n) + 4*rotateNum);
}
return n;
}
public static org.bukkit.Axis getRotatedAxis(org.bukkit.Axis orig, GaeaStructure.Rotation r) {
org.bukkit.Axis other = orig;
final boolean shouldSwitch = r.equals(GaeaStructure.Rotation.CW_90) || r.equals(GaeaStructure.Rotation.CCW_90);
switch(orig) {
case X:
if(shouldSwitch) other = org.bukkit.Axis.Z;
break;
case Z:
if(shouldSwitch) other = org.bukkit.Axis.X;
break;
}
return other;
}
/**
* Method to rotate the incredibly obnoxious Rail.Shape enum
* @param orig Original shape
* @param r Rotate
* @return Rotated/mirrored shape
*/
public static Rail.Shape getRotatedRail(Rail.Shape orig, GaeaStructure.Rotation r) {
switch(r) {
case CCW_90:
switch(orig) {
case NORTH_WEST: return Rail.Shape.SOUTH_WEST;
case NORTH_SOUTH: return Rail.Shape.EAST_WEST;
case SOUTH_WEST: return Rail.Shape.SOUTH_EAST;
case SOUTH_EAST: return Rail.Shape.NORTH_EAST;
case EAST_WEST: return Rail.Shape.NORTH_SOUTH;
case NORTH_EAST: return Rail.Shape.NORTH_WEST;
case ASCENDING_EAST: return Rail.Shape.ASCENDING_NORTH;
case ASCENDING_WEST: return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_NORTH: return Rail.Shape.ASCENDING_WEST;
case ASCENDING_SOUTH: return Rail.Shape.ASCENDING_EAST;
}
case CW_90:
switch(orig) {
case NORTH_WEST: return Rail.Shape.NORTH_EAST;
case NORTH_SOUTH: return Rail.Shape.EAST_WEST;
case SOUTH_WEST: return Rail.Shape.NORTH_WEST;
case SOUTH_EAST: return Rail.Shape.SOUTH_WEST;
case EAST_WEST: return Rail.Shape.NORTH_SOUTH;
case NORTH_EAST: return Rail.Shape.SOUTH_EAST;
case ASCENDING_EAST: return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_WEST: return Rail.Shape.ASCENDING_NORTH;
case ASCENDING_NORTH: return Rail.Shape.ASCENDING_EAST;
case ASCENDING_SOUTH: return Rail.Shape.ASCENDING_WEST;
}
case CW_180:
switch(orig) {
case NORTH_WEST: return Rail.Shape.SOUTH_EAST;
case NORTH_SOUTH: return Rail.Shape.NORTH_SOUTH;
case SOUTH_WEST: return Rail.Shape.NORTH_EAST;
case SOUTH_EAST: return Rail.Shape.NORTH_WEST;
case EAST_WEST: return Rail.Shape.EAST_WEST;
case NORTH_EAST: return Rail.Shape.SOUTH_WEST;
case ASCENDING_EAST: return Rail.Shape.ASCENDING_WEST;
case ASCENDING_WEST: return Rail.Shape.ASCENDING_EAST;
case ASCENDING_NORTH: return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_SOUTH: return Rail.Shape.ASCENDING_NORTH;
}
}
return orig;
}
/**
* Get an integer representation of a BlockFace, to perform math on.
* @param f BlockFace to get integer for
* @return integer representation of BlockFace
*/
public static int faceRotation(BlockFace f) {
switch(f) {
case NORTH: return 0;
case NORTH_NORTH_EAST: return 1;
case NORTH_EAST: return 2;
case EAST_NORTH_EAST: return 3;
case EAST: return 4;
case EAST_SOUTH_EAST: return 5;
case SOUTH_EAST: return 6;
case SOUTH_SOUTH_EAST: return 7;
case SOUTH: return 8;
case SOUTH_SOUTH_WEST: return 9;
case SOUTH_WEST: return 10;
case WEST_SOUTH_WEST: return 11;
case WEST: return 12;
case WEST_NORTH_WEST: return 13;
case NORTH_WEST: return 14;
case NORTH_NORTH_WEST: return 15;
default: return -1;
}
}
/**
* Convert integer to BlockFace representation
* @param r integer to get BlockFace for
* @return BlockFace represented by integer.
*/
public static BlockFace fromRotation(int r) {
switch(Math.floorMod(r, 16)) {
case 0: return BlockFace.NORTH;
case 1: return BlockFace.NORTH_NORTH_EAST;
case 2: return BlockFace.NORTH_EAST;
case 3: return BlockFace.EAST_NORTH_EAST;
case 4: return BlockFace.EAST;
case 5: return BlockFace.EAST_SOUTH_EAST;
case 6: return BlockFace.SOUTH_EAST;
case 7: return BlockFace.SOUTH_SOUTH_EAST;
case 8: return BlockFace.SOUTH;
case 9: return BlockFace.SOUTH_SOUTH_WEST;
case 10: return BlockFace.SOUTH_WEST;
case 11: return BlockFace.WEST_SOUTH_WEST;
case 12: return BlockFace.WEST;
case 13: return BlockFace.WEST_NORTH_WEST;
case 14: return BlockFace.NORTH_WEST;
case 15: return BlockFace.NORTH_NORTH_WEST;
default: throw new IllegalArgumentException();
}
}
}

View File

@@ -0,0 +1,67 @@
package com.dfsek.terra.util.structure;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class WorldEditUtil {
public static WorldEditPlugin getWorldEdit() {
Plugin p = Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
if (p instanceof WorldEditPlugin) return (WorldEditPlugin) p;
Bukkit.getLogger().severe("[Terra] a command requiring WorldEdit was executed, but WorldEdit was not detected!");
return null;
}
public static Location[] getSelectionLocations(Player sender) {
WorldEditPlugin we = WorldEditUtil.getWorldEdit();
if(we == null) {
sender.sendMessage("WorldEdit is not installed! Please install WorldEdit before attempting to export structures.");
return null;
}
Region selection;
try {
selection = we.getSession(sender).getSelection(BukkitAdapter.adapt(sender.getWorld()));
} catch(IncompleteRegionException |ClassCastException e) {
sender.sendMessage("Invalid/incomplete selection!");
return null;
}
if(selection == null) {
sender.sendMessage("Please make a selection before attempting to export!");
return null;
}
BlockVector3 min = selection.getMinimumPoint();
BlockVector3 max = selection.getMaximumPoint();
Location l1 = new Location(sender.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
Location l2 = new Location(sender.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
return new Location[] {l1, l2};
}
public static Location[] getSelectionPositions(Player sender) {
WorldEditPlugin we = WorldEditUtil.getWorldEdit();
if(we == null) {
sender.sendMessage("WorldEdit is not installed! Please install WorldEdit before attempting to export structures.");
return null;
}
CuboidRegion selection;
try {
selection = (CuboidRegion) we.getSession(sender).getSelection(BukkitAdapter.adapt(sender.getWorld()));
} catch(IncompleteRegionException |ClassCastException e) {
sender.sendMessage("Invalid/incomplete selection!");
return null;
}
if(selection == null) {
sender.sendMessage("Please make a selection before attempting to export!");
return null;
}
BlockVector3 min = selection.getPos1();
BlockVector3 max = selection.getPos2();
Location l1 = new Location(sender.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
Location l2 = new Location(sender.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
return new Location[] {l1, l2};
}
}