diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a03a380 --- /dev/null +++ b/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + com.allocinit + SkyJot + 1.0.0-SNAPSHOT + BlockHunt + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + + org.bukkit + bukkit + 1.8.8-R0.1-SNAPSHOT + + + + + + + . + true + ${basedir}/src/main/resources + + plugin.yml + + + + + src + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + + + + + diff --git a/src/main/java/com/allocinit/skyjot/Character.java b/src/main/java/com/allocinit/skyjot/Character.java new file mode 100644 index 0000000..bfbea62 --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/Character.java @@ -0,0 +1,39 @@ +package com.allocinit.skyjot; + +import java.util.ArrayList; +import java.util.List; + + +public class Character +{ + private List path = new ArrayList<>(); + private int width = 0; + + public Character(String... rows) + { + for (int i = 0; i < rows.length; i++) + { + String row = rows [rows.length - i - 1]; + + for (int j = 0; j < row.length(); j++) + { + if (j >= width) + width = j + 1; + + char dot = row.charAt(j); + if (dot != ' ') + path.add(new Integer [] { j, i }); + } + } + } + + public int getWidth() + { + return width; + } + + public List getPath() + { + return path; + } +} diff --git a/src/main/java/com/allocinit/skyjot/DirectionHelper.java b/src/main/java/com/allocinit/skyjot/DirectionHelper.java new file mode 100644 index 0000000..893ec0f --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/DirectionHelper.java @@ -0,0 +1,40 @@ +package com.allocinit.skyjot; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +class DirectionHelper +{ + private double xAdd; + private double zAdd; + + public DirectionHelper() + { + } + + public void setFromPlayerView(Player player) + { + Vector direction = player.getLocation().getDirection(); + + direction.setY(0); + + if (Math.abs(direction.getX()) < Math.abs(direction.getZ())) + { + xAdd = direction.getZ() > 0 ? -1 : 1; + zAdd = 0; + } + else + { + zAdd = direction.getX() < 0 ? -1 : 1; + xAdd = 0; + } + } + + public void move(Location loc, int xoff, int yoff) + { + loc.setX(loc.getX() + xoff * xAdd); + loc.setZ(loc.getZ() + xoff * zAdd); + loc.setY(loc.getY() + yoff); + } +} \ No newline at end of file diff --git a/src/main/java/com/allocinit/skyjot/Font.java b/src/main/java/com/allocinit/skyjot/Font.java new file mode 100644 index 0000000..0976d73 --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/Font.java @@ -0,0 +1,322 @@ +package com.allocinit.skyjot; + +import java.util.HashMap; +import java.util.Map; + + +public class Font +{ + private Character SPACE = new Character() + { + @Override + public int getWidth() + { + return 2; + } + }; + + private Character A = new Character(// + "XXX", // + "X X", // + "XXX", // + "X X", // + "X X"); + + private Character B = new Character(// + "XXX", // + "X X", // + "XXX", // + "X X", // + "XXX"); + + private Character C = new Character(// + "XXX", // + "X", // + "X", // + "X", // + "XXX"); + + private Character D = new Character(// + "XXX", // + "X X", // + "X X", // + "X X", // + "XXX"); + + private Character E = new Character(// + "XXX", // + "X", // + "XX", // + "X", // + "XXX"); + + private Character F = new Character(// + "XXX", // + "X", // + "XX", // + "X", // + "X"); + + private Character G = new Character(// + "XXX", // + "X", // + "X", // + "X X", // + "XXX"); + + private Character H = new Character(// + "X X", // + "X X", // + "XXX", // + "X X", // + "X X"); + + private Character I = new Character(// + "XXX", // + " X", // + " X", // + " X", // + "XXX"); + + private Character J = new Character(// + "XXXX", // + " X", // + " X", // + " X", // + "XXX"); + + private Character K = new Character(// + "X X", // + "X X", // + "XX", // + "X X", // + "X X"); + + private Character L = new Character(// + "X", // + "X", // + "X", // + "X", // + "XXX"); + + private Character M = new Character(// + "XX XX", // + "X X X", // + "X X X", // + "X X", // + "X X"); + + private Character N = new Character(// + "X X", // + "XX X", // + "X X X", // + "X XX", // + "X X"); + + private Character O = new Character(// + " XX ", // + "X X", // + "X X", // + "X X", // + " XX"); + + private Character P = new Character(// + "XXX", // + "X X", // + "XXX", // + "X", // + "X"); + + private Character Q = new Character(// + " XXX ", // + "X X", // + "X X X", // + "X XX", // + " XXX"); + + private Character R = new Character(// + "XXX", // + "X X", // + "XX", // + "X X", // + "X X"); + + private Character S = new Character(// + "XXX", // + "X", // + "XXX", // + " X", // + "XXX"); + + private Character T = new Character(// + "XXX", // + " X", // + " X", // + " X", // + " X"); + + private Character U = new Character(// + "X X", // + "X X", // + "X X", // + "X X", // + " XX"); + + private Character V = new Character(// + "X X", // + "X X", // + " X X", // + " X X", // + " X"); + + private Character W = new Character(// + "X X", // + "X X", // + "X X X", // + "X X X", // + " X X"); + + private Character X = new Character(// + "X X", // + "X X", // + " X", // + "X X", // + "X X"); + + private Character Y = new Character(// + "X X", // + "X X", // + " X", // + " X", // + " X"); + + private Character Z = new Character(// + "XXX", // + " X", // + " X", // + "X", // + "XXX"); + + private Character N1 = new Character(// + "XX", // + " X", // + " X", // + " X", // + "XXX"); + + private Character N2 = new Character(// + "XXX", // + " X", // + "XXX", // + "X", // + "XXX"); + + private Character N3 = new Character(// + "XXX", // + " X", // + "XXX", // + " X", // + "XXX"); + + private Character N4 = new Character(// + "X X", // + "X X", // + "XXX", // + " X", // + " X"); + + private Character N5 = new Character(// + "XXX", // + "X", // + "XXX", // + " X", // + "XXX"); + + private Character N6 = new Character(// + "XXX", // + "X", // + "XXX", // + "X X", // + "XXX"); + + private Character N7 = new Character(// + "XXX", // + " X", // + " X", // + " X", // + " X"); + + private Character N8 = new Character(// + "XXX", // + "X X", // + "XXX", // + "X X", // + "XXX"); + + private Character N9 = new Character(// + "XXX", // + "X X", // + "XXX", // + " X", // + " X"); + + private Character N0 = new Character(// + "XXX", // + "X X", // + "X X", // + "X X", // + "XXX"); + + private Map font = new HashMap<>(); + + public Font() + { + font.put(" ", SPACE); + font.put("A", A); + font.put("B", B); + font.put("C", C); + font.put("D", D); + font.put("E", E); + font.put("F", F); + font.put("G", G); + font.put("H", H); + font.put("I", I); + font.put("J", J); + font.put("K", K); + font.put("L", L); + font.put("M", M); + font.put("N", N); + font.put("O", O); + font.put("P", P); + font.put("Q", Q); + font.put("R", R); + font.put("S", S); + font.put("T", T); + font.put("U", U); + font.put("V", V); + font.put("W", W); + font.put("X", X); + font.put("Y", Y); + font.put("Z", Z); + font.put("0", N0); + font.put("1", N1); + font.put("2", N2); + font.put("3", N3); + font.put("4", N4); + font.put("5", N5); + font.put("6", N6); + font.put("7", N7); + font.put("8", N8); + font.put("9", N9); + } + + public int getHeight() + { + return 5; + } + + public Character get(String c) + { + return font.get(c); + } +} diff --git a/src/main/java/com/allocinit/skyjot/SkyJot.java b/src/main/java/com/allocinit/skyjot/SkyJot.java new file mode 100644 index 0000000..a1fadec --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/SkyJot.java @@ -0,0 +1,75 @@ +package com.allocinit.skyjot; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + + +public class SkyJot extends JavaPlugin +{ + private Map playerState = new HashMap<>(); + private SubCommand writeCommand = new WriteCommand(this); + private SubCommand undoCommand = new UndoCommand(this); + + @Override + public void onEnable() + { + this.getCommand("skyjot").setExecutor(new CommandExecutor() + { + @Override + public boolean onCommand(CommandSender sender, Command cmd, + String label, String [] args) + { + Player player = (Player) sender; + + if (!player.hasPermission("skyjot")) + { + player.sendMessage("&cPermission Denied"); + return true; + } + + if (args.length < 1) + { + writeUsage(player); + return true; + } + + String subCmd = args [0]; + + args = Arrays.copyOfRange(args, 1, args.length); + + if ("write".equals(subCmd)) + writeCommand.doCommand(sender, args); + else if ("undo".equals(subCmd)) + undoCommand.doCommand(sender, args); + else + writeUsage(player); + + return true; + } + }); + + } + + private void writeUsage(Player player) + { + writeCommand.writeUsage(player); + undoCommand.writeUsage(player); + } + + @Override + public void onDisable() + { + } + + public Map getPlayerState() + { + return playerState; + } +} \ No newline at end of file diff --git a/src/main/java/com/allocinit/skyjot/SubCommand.java b/src/main/java/com/allocinit/skyjot/SubCommand.java new file mode 100644 index 0000000..059895a --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/SubCommand.java @@ -0,0 +1,12 @@ +package com.allocinit.skyjot; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public interface SubCommand +{ + public void doCommand(CommandSender sender, String [] args); + + public void writeUsage(Player player); +} diff --git a/src/main/java/com/allocinit/skyjot/Undo.java b/src/main/java/com/allocinit/skyjot/Undo.java new file mode 100644 index 0000000..10e3464 --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/Undo.java @@ -0,0 +1,38 @@ +package com.allocinit.skyjot; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.material.MaterialData; + + +public class Undo +{ + private Map undoMap = new HashMap<>(); + + public Undo() + { + } + + public void saveLocation(Location where) + { + MaterialData what = where.getBlock().getState().getData(); + undoMap.put(where, what); + } + + public void undo() + { + for (Map.Entry entry : undoMap.entrySet()) + { + MaterialData data = entry.getValue(); + + Block block = entry.getKey().getBlock(); + block.setType(data.getItemType()); + block.setData(data.getData()); + } + + undoMap.clear(); + } +} diff --git a/src/main/java/com/allocinit/skyjot/UndoCommand.java b/src/main/java/com/allocinit/skyjot/UndoCommand.java new file mode 100644 index 0000000..6f5e5f1 --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/UndoCommand.java @@ -0,0 +1,30 @@ +package com.allocinit.skyjot; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public class UndoCommand implements SubCommand +{ + private SkyJot skyjot; + + public UndoCommand(SkyJot skyjot) + { + this.skyjot = skyjot; + } + + public void doCommand(CommandSender sender, String [] args) + { + Player player = (Player) sender; + + Undo undo = skyjot.getPlayerState().get(player.getName()); + + if (undo != null) + undo.undo(); + } + + public void writeUsage(Player player) + { + player.sendMessage("skyjot undo"); + } +} diff --git a/src/main/java/com/allocinit/skyjot/WriteCommand.java b/src/main/java/com/allocinit/skyjot/WriteCommand.java new file mode 100644 index 0000000..024d54f --- /dev/null +++ b/src/main/java/com/allocinit/skyjot/WriteCommand.java @@ -0,0 +1,168 @@ +package com.allocinit.skyjot; + +import java.util.Arrays; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.material.MaterialData; + + +public class WriteCommand implements SubCommand +{ + private SkyJot skyjot; + private Font font = new Font(); + + public WriteCommand(SkyJot skyjot) + { + this.skyjot = skyjot; + } + + public void doCommand(CommandSender sender, String [] args) + { + Player player = (Player) sender; + + char justification = 'c'; + DirectionHelper dirHelper = new DirectionHelper(); + MaterialData material = new MaterialData(Material.STONE); + dirHelper.setFromPlayerView(player); + + // write [b:block type] [j:left|right|center] text ... + + while (args.length > 4) + { + String arg = args [0]; + + if (arg.startsWith("j:")) + { + justification = arg.charAt(2); + } + else if (arg.startsWith("b:")) + { + String val = arg.substring(2); + material = parseMaterial(val); + } + else + break; + + args = Arrays.copyOfRange(args, 1, args.length); + } + + if (args.length < 4) + { + writeUsage(player); + return; + } + + Location where = player.getLocation(); + where.setX(parseCoord(where.getX(), args [0])); + where.setY(parseCoord(where.getY(), args [1])); + where.setZ(parseCoord(where.getZ(), args [2])); + + Undo undo = new Undo(); + skyjot.getPlayerState().put(player.getName(), undo); + + Location cursor = where.clone(); + + String complete = ""; + for (int i = 3; i < args.length; i++) + complete += args [i] + " "; + + // For now + complete = complete.toUpperCase(); + + String [] lines = complete.split("\\\\N"); + + for (String line : lines) + { + if (justification == 'c' || justification == 'r') + { + // Get a total width + int width = 0; + + int letterCnt = 0; + for (int j = 0; j < line.length(); j++) + { + String letter = line.substring(j, j + 1); + Character c = font.get(letter); + if (c != null) + { + letterCnt++; + width += c.getWidth(); + } + } + + // The gap between letters + width += letterCnt - 1; + + if (justification == 'c') + dirHelper.move(cursor, -width / 2, 0); + else if (justification == 'r') + dirHelper.move(cursor, -width, 0); + } + + for (int j = 0; j < line.length(); j++) + { + String letter = line.substring(j, j + 1); + + Character c = font.get(letter); + + if (c == null) + continue; + + for (Integer [] offset : c.getPath()) + { + Location blockLoc = cursor.clone(); + + dirHelper.move(blockLoc, offset [0], offset [1]); + + undo.saveLocation(blockLoc); + + Block block = blockLoc.getBlock(); + block.setType(material.getItemType()); + block.setData(material.getData()); + } + + dirHelper.move(cursor, c.getWidth() + 1, 0); + } + + // New line + cursor.setX(where.getX()); + cursor.setZ(where.getZ()); + cursor.setY(cursor.getY() - font.getHeight() - 2); + } + } + + private MaterialData parseMaterial(String val) + { + byte data = 0; + + String [] parts = val.split(":", 2); + Material material = Material.matchMaterial(parts [0]); + if (parts.length > 1) + data = (byte) Integer.parseInt(parts [1]); + + return new MaterialData(material, data); + } + + private double parseCoord(double d, String coord) + { + if (coord.startsWith("~")) + { + if (coord.length() > 1) + d += Integer.parseInt(coord.substring(1)); + return d; + } + + return Integer.parseInt(coord); + } + + public void writeUsage(Player player) + { + player.sendMessage( + "skyjot write [b:block type] [a:left|right|center] text ..."); + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..f7351cf --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,11 @@ +name: RW +main: com.allocinit.skyjot.SkyJot +version: 1.0.0-SNAPSHOT + +commands: + skyjot: + +permissions: + skyjot: + default: op + \ No newline at end of file