From 273f7c7a7366396234319fee2af038608bea3746 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Mon, 24 Aug 2020 08:03:05 -0400 Subject: [PATCH] GUI & Tasking utils --- src/main/java/com/volmit/iris/Iris.java | 6 +- .../com/volmit/iris/StructureManager.java | 55 + .../java/com/volmit/iris/WandManager.java | 11 +- .../com/volmit/iris/command/CommandIris.java | 3 + .../command/CommandIrisObjectContract.java | 8 +- .../iris/command/CommandIrisObjectExpand.java | 8 +- .../iris/command/CommandIrisObjectP1.java | 10 +- .../iris/command/CommandIrisObjectP2.java | 10 +- .../iris/command/CommandIrisObjectPaste.java | 8 +- .../iris/command/CommandIrisObjectSave.java | 4 +- .../iris/command/CommandIrisObjectShift.java | 8 +- .../iris/command/CommandIrisObjectWand.java | 4 +- .../iris/command/CommandIrisObjectXAY.java | 8 +- .../iris/command/CommandIrisObjectXPY.java | 8 +- .../iris/command/CommandIrisStructure.java | 46 + .../command/CommandIrisStructureClose.java | 49 + .../command/CommandIrisStructureCreate.java | 52 + .../command/CommandIrisStructureExpand.java | 49 + .../command/CommandIrisStructureMore.java | 49 + .../command/CommandIrisStructureSave.java | 49 + .../iris/command/CommandIrisStudio.java | 14 +- .../iris/object/IrisAxisRotationClamp.java | 5 + .../com/volmit/iris/object/IrisObject.java | 22 + .../iris/object/IrisObjectRotation.java | 33 +- .../volmit/iris/object/IrisStructureTile.java | 6 +- src/main/java/com/volmit/iris/util/A.java | 9 + src/main/java/com/volmit/iris/util/AR.java | 27 + .../java/com/volmit/iris/util/Callback.java | 15 + .../com/volmit/iris/util/CancellableTask.java | 6 + .../com/volmit/iris/util/ChronoLatch.java | 18 +- .../java/com/volmit/iris/util/Element.java | 55 + .../com/volmit/iris/util/ElementEvent.java | 17 + .../com/volmit/iris/util/FinalInteger.java | 36 + src/main/java/com/volmit/iris/util/J.java | 227 ++++ src/main/java/com/volmit/iris/util/S.java | 14 + src/main/java/com/volmit/iris/util/SR.java | 27 + .../volmit/iris/util/StructureTemplate.java | 973 ++++++++++++++++++ .../java/com/volmit/iris/util/Wrapper.java | 72 ++ .../com/volmit/iris/util/inventory/C.java | 787 ++++++++++++++ .../volmit/iris/util/inventory/Callback.java | 21 + .../volmit/iris/util/inventory/Element.java | 56 + .../iris/util/inventory/ElementEvent.java | 17 + .../iris/util/inventory/MaterialBlock.java | 136 +++ .../volmit/iris/util/inventory/UIElement.java | 259 +++++ .../util/inventory/UIStaticDecorator.java | 19 + .../iris/util/inventory/UIVoidDecorator.java | 11 + .../volmit/iris/util/inventory/UIWindow.java | 545 ++++++++++ .../volmit/iris/util/inventory/Window.java | 73 ++ .../iris/util/inventory/WindowDecorator.java | 6 + .../iris/util/inventory/WindowResolution.java | 41 + 50 files changed, 3937 insertions(+), 55 deletions(-) create mode 100644 src/main/java/com/volmit/iris/StructureManager.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructure.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructureClose.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructureCreate.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructureExpand.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructureMore.java create mode 100644 src/main/java/com/volmit/iris/command/CommandIrisStructureSave.java create mode 100644 src/main/java/com/volmit/iris/util/A.java create mode 100644 src/main/java/com/volmit/iris/util/AR.java create mode 100644 src/main/java/com/volmit/iris/util/CancellableTask.java create mode 100644 src/main/java/com/volmit/iris/util/Element.java create mode 100644 src/main/java/com/volmit/iris/util/ElementEvent.java create mode 100644 src/main/java/com/volmit/iris/util/FinalInteger.java create mode 100644 src/main/java/com/volmit/iris/util/S.java create mode 100644 src/main/java/com/volmit/iris/util/SR.java create mode 100644 src/main/java/com/volmit/iris/util/StructureTemplate.java create mode 100644 src/main/java/com/volmit/iris/util/Wrapper.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/C.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/Callback.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/Element.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/ElementEvent.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/MaterialBlock.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/UIElement.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/UIStaticDecorator.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/UIVoidDecorator.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/UIWindow.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/Window.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/WindowDecorator.java create mode 100644 src/main/java/com/volmit/iris/util/inventory/WindowResolution.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index d1ee2711a..e602b6d77 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -48,7 +48,8 @@ public class Iris extends MortarPlugin implements BoardProvider public static IrisDataManager globaldata; public static ProjectManager proj; public static IrisHotloadManager hotloader; - public static WandController wand; + public static WandManager wand; + public static StructureManager struct; private BoardManager manager; private String mem = "..."; private ChronoLatch cl = new ChronoLatch(1000); @@ -94,7 +95,8 @@ public class Iris extends MortarPlugin implements BoardProvider instance = this; hotloader = new IrisHotloadManager(); globaldata = new IrisDataManager(getDataFolder()); - wand = new WandController(); + wand = new WandManager(); + struct = new StructureManager(); postProcessors = loadPostProcessors(); proj = new ProjectManager(); manager = new BoardManager(this, BoardSettings.builder().boardProvider(this).scoreDirection(ScoreDirection.UP).build()); diff --git a/src/main/java/com/volmit/iris/StructureManager.java b/src/main/java/com/volmit/iris/StructureManager.java new file mode 100644 index 000000000..3fb14351b --- /dev/null +++ b/src/main/java/com/volmit/iris/StructureManager.java @@ -0,0 +1,55 @@ +package com.volmit.iris; + +import org.bukkit.entity.Player; + +import com.volmit.iris.util.KList; +import com.volmit.iris.util.StructureTemplate; + +public class StructureManager +{ + private KList openEditors; + + public StructureManager() + { + this.openEditors = new KList<>(); + } + + public void closeall() + { + for(StructureTemplate i : openEditors.copy()) + { + i.close(); + } + } + + public void open(StructureTemplate t) + { + for(StructureTemplate i : openEditors.copy()) + { + if(t.getWorker().equals(i.getWorker())) + { + i.close(); + } + } + + openEditors.add(t); + } + + public void remove(StructureTemplate s) + { + openEditors.remove(s); + } + + public StructureTemplate get(Player p) + { + for(StructureTemplate i : openEditors) + { + if(i.getWorker().equals(p)) + { + return i; + } + } + + return null; + } +} diff --git a/src/main/java/com/volmit/iris/WandManager.java b/src/main/java/com/volmit/iris/WandManager.java index 466074d46..0c20d3001 100644 --- a/src/main/java/com/volmit/iris/WandManager.java +++ b/src/main/java/com/volmit/iris/WandManager.java @@ -28,9 +28,9 @@ import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.KList; import com.volmit.iris.util.M; -public class WandController implements Listener +public class WandManager implements Listener { - public WandController() + public WandManager() { Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, () -> { @@ -38,7 +38,7 @@ public class WandController implements Listener { tick(i); } - }, 0, 0); + }, 0, 5); Bukkit.getPluginManager().registerEvents(this, Iris.instance); } @@ -59,6 +59,11 @@ public class WandController implements Listener } } + public void draw(Cuboid d, Player p) + { + draw(new Location[] {d.getLowerNE(), d.getUpperSW()}, p); + } + public void draw(Location[] d, Player p) { Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65); diff --git a/src/main/java/com/volmit/iris/command/CommandIris.java b/src/main/java/com/volmit/iris/command/CommandIris.java index 6964acd94..d089c0cdf 100644 --- a/src/main/java/com/volmit/iris/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/command/CommandIris.java @@ -18,6 +18,9 @@ public class CommandIris extends MortarCommand @Command private CommandIrisObject object; + + @Command + private CommandIrisStructure structure; @Command private CommandIrisCreate create; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectContract.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectContract.java index cd7ce449a..bcf0cc0ff 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectContract.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectContract.java @@ -5,7 +5,7 @@ import org.bukkit.Sound; import org.bukkit.entity.Player; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.Direction; import com.volmit.iris.util.MortarCommand; @@ -32,14 +32,14 @@ public class CommandIrisObjectContract extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; } int amt = Integer.valueOf(args[0]); - Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand()); + Location[] b = WandManager.getCuboid(p.getInventory().getItemInMainHand()); Location a1 = b[0].clone(); Location a2 = b[1].clone(); Cuboid cursor = new Cuboid(a1, a2); @@ -47,7 +47,7 @@ public class CommandIrisObjectContract extends MortarCommand cursor = cursor.expand(d, -amt); b[0] = cursor.getLowerNE(); b[1] = cursor.getUpperSW(); - p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1])); + p.getInventory().setItemInMainHand(WandManager.createWand(b[0], b[1])); p.updateInventory(); p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectExpand.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectExpand.java index 27c3286c8..3f5aa0bcb 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectExpand.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectExpand.java @@ -5,7 +5,7 @@ import org.bukkit.Sound; import org.bukkit.entity.Player; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.Direction; import com.volmit.iris.util.MortarCommand; @@ -32,14 +32,14 @@ public class CommandIrisObjectExpand extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; } int amt = Integer.valueOf(args[0]); - Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand()); + Location[] b = WandManager.getCuboid(p.getInventory().getItemInMainHand()); Location a1 = b[0].clone(); Location a2 = b[1].clone(); Cuboid cursor = new Cuboid(a1, a2); @@ -47,7 +47,7 @@ public class CommandIrisObjectExpand extends MortarCommand cursor = cursor.expand(d, amt); b[0] = cursor.getLowerNE(); b[1] = cursor.getUpperSW(); - p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1])); + p.getInventory().setItemInMainHand(WandManager.createWand(b[0], b[1])); p.updateInventory(); p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectP1.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectP1.java index 0356a4788..4c5284c45 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectP1.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectP1.java @@ -8,7 +8,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -34,7 +34,7 @@ public class CommandIrisObjectP1 extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; @@ -42,9 +42,9 @@ public class CommandIrisObjectP1 extends MortarCommand ItemStack wand = p.getInventory().getItemInMainHand(); - if(WandController.isWand(wand)) + if(WandManager.isWand(wand)) { - Location[] g = WandController.getCuboid(wand); + Location[] g = WandManager.getCuboid(wand); g[0] = p.getLocation().getBlock().getLocation().clone().add(0, -1, 0); if(args.length == 1 && args[0].equals("-l")) @@ -52,7 +52,7 @@ public class CommandIrisObjectP1 extends MortarCommand g[0] = p.getTargetBlock((Set) null, 256).getLocation().clone(); } - p.setItemInHand(WandController.createWand(g[0], g[1])); + p.setItemInHand(WandManager.createWand(g[0], g[1])); } return true; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectP2.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectP2.java index 69a957d8e..7c4b466fd 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectP2.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectP2.java @@ -8,7 +8,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -34,7 +34,7 @@ public class CommandIrisObjectP2 extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; @@ -42,9 +42,9 @@ public class CommandIrisObjectP2 extends MortarCommand ItemStack wand = p.getInventory().getItemInMainHand(); - if(WandController.isWand(wand)) + if(WandManager.isWand(wand)) { - Location[] g = WandController.getCuboid(wand); + Location[] g = WandManager.getCuboid(wand); g[1] = p.getLocation().getBlock().getLocation().clone().add(0, -1, 0); if(args.length == 1 && args[0].equals("-l")) @@ -52,7 +52,7 @@ public class CommandIrisObjectP2 extends MortarCommand g[1] = p.getTargetBlock((Set) null, 256).getLocation().clone(); } - p.setItemInHand(WandController.createWand(g[0], g[1])); + p.setItemInHand(WandManager.createWand(g[0], g[1])); } return true; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectPaste.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectPaste.java index 24324e465..408ee212b 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectPaste.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectPaste.java @@ -10,7 +10,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.object.IrisObject; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -64,14 +64,14 @@ public class CommandIrisObjectPaste extends MortarCommand sender.player().getWorld().playSound(sender.player().getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.5f); Location block = sender.player().getTargetBlock((Set) null, 256).getLocation().clone().add(0, 1, 0); - if(intoWand && WandController.isWand(wand)) + if(intoWand && WandManager.isWand(wand)) { - wand = WandController.createWand(block.clone().subtract(o.getCenter()).add(o.getW() - 1, o.getH(), o.getD() - 1), block.clone().subtract(o.getCenter())); + wand = WandManager.createWand(block.clone().subtract(o.getCenter()).add(o.getW() - 1, o.getH(), o.getD() - 1), block.clone().subtract(o.getCenter())); p.getInventory().setItemInMainHand(wand); sender.sendMessage("Updated wand for " + "objects/" + args[0] + ".iob"); } - WandController.pasteSchematic(o, block); + WandManager.pasteSchematic(o, block); sender.sendMessage("Placed " + "objects/" + args[0] + ".iob"); return true; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectSave.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectSave.java index cef4bfcb6..20361da94 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectSave.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectSave.java @@ -7,7 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.object.IrisObject; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -52,7 +52,7 @@ public class CommandIrisObjectSave extends MortarCommand Player p = sender.player(); ItemStack wand = p.getInventory().getItemInMainHand(); - IrisObject o = WandController.createSchematic(wand); + IrisObject o = WandManager.createSchematic(wand); File file = Iris.instance.getDataFile("packs", args[0], "objects", args[1] + ".iob"); if(file.exists()) diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectShift.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectShift.java index 8ceb703c4..07c8ae9d9 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectShift.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectShift.java @@ -5,7 +5,7 @@ import org.bukkit.Sound; import org.bukkit.entity.Player; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.Direction; import com.volmit.iris.util.MortarCommand; @@ -32,14 +32,14 @@ public class CommandIrisObjectShift extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; } int amt = Integer.valueOf(args[0]); - Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand()); + Location[] b = WandManager.getCuboid(p.getInventory().getItemInMainHand()); Location a1 = b[0].clone(); Location a2 = b[1].clone(); Direction d = Direction.closest(p.getLocation().getDirection()).reverse(); @@ -48,7 +48,7 @@ public class CommandIrisObjectShift extends MortarCommand Cuboid cursor = new Cuboid(a1, a2); b[0] = cursor.getLowerNE(); b[1] = cursor.getUpperSW(); - p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1])); + p.getInventory().setItemInMainHand(WandManager.createWand(b[0], b[1])); p.updateInventory(); p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectWand.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectWand.java index 2b3731db2..87cae2cd4 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectWand.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectWand.java @@ -3,7 +3,7 @@ package com.volmit.iris.command; import org.bukkit.Sound; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -26,7 +26,7 @@ public class CommandIrisObjectWand extends MortarCommand return true; } - sender.player().getInventory().addItem(WandController.createWand()); + sender.player().getInventory().addItem(WandManager.createWand()); sender.player().playSound(sender.player().getLocation(), Sound.ITEM_ARMOR_EQUIP_NETHERITE, 1f, 1.5f); return true; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectXAY.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectXAY.java index 413b184a4..7f316f688 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectXAY.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectXAY.java @@ -7,7 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -34,13 +34,13 @@ public class CommandIrisObjectXAY extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; } - Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand()); + Location[] b = WandManager.getCuboid(p.getInventory().getItemInMainHand()); Location a1 = b[0].clone(); Location a2 = b[1].clone(); Location a1x = b[0].clone(); @@ -76,7 +76,7 @@ public class CommandIrisObjectXAY extends MortarCommand cursor = cursor.contract(CuboidDirection.West); b[0] = cursor.getLowerNE(); b[1] = cursor.getUpperSW(); - p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1])); + p.getInventory().setItemInMainHand(WandManager.createWand(b[0], b[1])); p.updateInventory(); p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisObjectXPY.java b/src/main/java/com/volmit/iris/command/CommandIrisObjectXPY.java index 86efe0f7a..5346df2f1 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisObjectXPY.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisObjectXPY.java @@ -7,7 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import com.volmit.iris.Iris; -import com.volmit.iris.WandController; +import com.volmit.iris.WandManager; import com.volmit.iris.util.Cuboid; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -34,12 +34,12 @@ public class CommandIrisObjectXPY extends MortarCommand Player p = sender.player(); - if(!WandController.isWand(p)) + if(!WandManager.isWand(p)) { sender.sendMessage("Ready your Wand."); return true; } - Location[] b = WandController.getCuboid(p.getInventory().getItemInMainHand()); + Location[] b = WandManager.getCuboid(p.getInventory().getItemInMainHand()); b[0].add(new Vector(0, 1, 0)); b[1].add(new Vector(0, 1, 0)); Location a1 = b[0].clone(); @@ -64,7 +64,7 @@ public class CommandIrisObjectXPY extends MortarCommand cursor = cursor.contract(CuboidDirection.West); b[0] = cursor.getLowerNE(); b[1] = cursor.getUpperSW(); - p.getInventory().setItemInMainHand(WandController.createWand(b[0], b[1])); + p.getInventory().setItemInMainHand(WandManager.createWand(b[0], b[1])); p.updateInventory(); p.playSound(p.getLocation(), Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructure.java b/src/main/java/com/volmit/iris/command/CommandIrisStructure.java new file mode 100644 index 000000000..14258ba5e --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructure.java @@ -0,0 +1,46 @@ +package com.volmit.iris.command; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.Command; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; + +public class CommandIrisStructure extends MortarCommand +{ + @Command + private CommandIrisStructureCreate create; + + @Command + private CommandIrisStructureSave save; + + @Command + private CommandIrisStructureMore more; + + @Command + private CommandIrisStructureExpand expand; + + @Command + private CommandIrisStructureClose close; + + public CommandIrisStructure() + { + super("structure", "struct", "str"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Structure Commands"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + sender.sendMessage("Iris Structure Commands"); + printHelp(sender); + return true; + } + + @Override + protected String getArgsUsage() + { + return "[subcommand]"; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructureClose.java b/src/main/java/com/volmit/iris/command/CommandIrisStructureClose.java new file mode 100644 index 000000000..fdc9eaec1 --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructureClose.java @@ -0,0 +1,49 @@ +package com.volmit.iris.command; + +import org.bukkit.entity.Player; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; +import com.volmit.iris.util.StructureTemplate; + +public class CommandIrisStructureClose extends MortarCommand +{ + public CommandIrisStructureClose() + { + super("close", "x"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Close a structure"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(!sender.isPlayer()) + { + sender.sendMessage("You don't have a wand"); + return true; + } + + Player p = sender.player(); + StructureTemplate m = Iris.struct.get(p); + + if(m == null) + { + sender.sendMessage("You do not have an open structure"); + return true; + } + + m.close(); + sender.sendMessage("Saved & Closed!"); + + return true; + } + + @Override + protected String getArgsUsage() + { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructureCreate.java b/src/main/java/com/volmit/iris/command/CommandIrisStructureCreate.java new file mode 100644 index 000000000..4cf1ff86f --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructureCreate.java @@ -0,0 +1,52 @@ +package com.volmit.iris.command; + +import org.bukkit.entity.Player; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; +import com.volmit.iris.util.StructureTemplate; + +public class CommandIrisStructureCreate extends MortarCommand +{ + public CommandIrisStructureCreate() + { + super("new", "create", "+"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Create a structure"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(!sender.isPlayer()) + { + sender.sendMessage("You don't have a wand"); + return true; + } + + Player p = sender.player(); + + boolean d3 = false; + + for(String i : args) + { + if(i.equalsIgnoreCase("-3d")) + { + d3 = true; + } + } + + sender.sendMessage("Creating new Structure"); + new StructureTemplate(args[0], args[1], p, p.getLocation(), 5, Integer.valueOf(args[2]), Integer.valueOf(args[3]), d3); + + return true; + } + + @Override + protected String getArgsUsage() + { + return " [-3d]"; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructureExpand.java b/src/main/java/com/volmit/iris/command/CommandIrisStructureExpand.java new file mode 100644 index 000000000..8705542c0 --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructureExpand.java @@ -0,0 +1,49 @@ +package com.volmit.iris.command; + +import org.bukkit.entity.Player; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; +import com.volmit.iris.util.StructureTemplate; + +public class CommandIrisStructureExpand extends MortarCommand +{ + public CommandIrisStructureExpand() + { + super("expand", "+++"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Expand out more of the structure"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(!sender.isPlayer()) + { + sender.sendMessage("You don't have a wand"); + return true; + } + + Player p = sender.player(); + StructureTemplate m = Iris.struct.get(p); + + if(m == null) + { + sender.sendMessage("You do not have an open structure"); + return true; + } + + m.expand(); + sender.sendMessage("Loading More!"); + + return true; + } + + @Override + protected String getArgsUsage() + { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructureMore.java b/src/main/java/com/volmit/iris/command/CommandIrisStructureMore.java new file mode 100644 index 000000000..cd65cced5 --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructureMore.java @@ -0,0 +1,49 @@ +package com.volmit.iris.command; + +import org.bukkit.entity.Player; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; +import com.volmit.iris.util.StructureTemplate; + +public class CommandIrisStructureMore extends MortarCommand +{ + public CommandIrisStructureMore() + { + super("more", "++"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Load more of the structure"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(!sender.isPlayer()) + { + sender.sendMessage("You don't have a wand"); + return true; + } + + Player p = sender.player(); + StructureTemplate m = Iris.struct.get(p); + + if(m == null) + { + sender.sendMessage("You do not have an open structure"); + return true; + } + + m.more(); + sender.sendMessage("Loading More!"); + + return true; + } + + @Override + protected String getArgsUsage() + { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStructureSave.java b/src/main/java/com/volmit/iris/command/CommandIrisStructureSave.java new file mode 100644 index 000000000..8dbd39e2a --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStructureSave.java @@ -0,0 +1,49 @@ +package com.volmit.iris.command; + +import org.bukkit.entity.Player; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; +import com.volmit.iris.util.StructureTemplate; + +public class CommandIrisStructureSave extends MortarCommand +{ + public CommandIrisStructureSave() + { + super("save", "s"); + requiresPermission(Iris.perm); + setCategory("Structure"); + setDescription("Save a structure"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(!sender.isPlayer()) + { + sender.sendMessage("You don't have a wand"); + return true; + } + + Player p = sender.player(); + StructureTemplate m = Iris.struct.get(p); + + if(m == null) + { + sender.sendMessage("You do not have an open structure"); + return true; + } + + m.saveStructure(); + sender.sendMessage("Saved!"); + + return true; + } + + @Override + protected String getArgsUsage() + { + return ""; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStudio.java b/src/main/java/com/volmit/iris/command/CommandIrisStudio.java index 6ba5753e6..d2fe75fd9 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisStudio.java @@ -5,7 +5,8 @@ import com.volmit.iris.util.Command; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; -public class CommandIrisStudio extends MortarCommand { +public class CommandIrisStudio extends MortarCommand +{ @Command private CommandIrisStudioCreate create; @@ -23,28 +24,31 @@ public class CommandIrisStudio extends MortarCommand { @Command private CommandIrisStudioUpdate update; - + @Command private CommandIrisMap map; @Command private CommandIrisStudioList list; - public CommandIrisStudio() { + public CommandIrisStudio() + { super("studio", "std"); requiresPermission(Iris.perm.studio); setCategory("Studio"); } @Override - public boolean handle(MortarSender sender, String[] args) { + public boolean handle(MortarSender sender, String[] args) + { sender.sendMessage("Iris Studio Commands"); printHelp(sender); return true; } @Override - protected String getArgsUsage() { + protected String getArgsUsage() + { return "[subcommand]"; } } diff --git a/src/main/java/com/volmit/iris/object/IrisAxisRotationClamp.java b/src/main/java/com/volmit/iris/object/IrisAxisRotationClamp.java index 7292883f9..d551fc56c 100644 --- a/src/main/java/com/volmit/iris/object/IrisAxisRotationClamp.java +++ b/src/main/java/com/volmit/iris/object/IrisAxisRotationClamp.java @@ -60,6 +60,11 @@ public class IrisAxisRotationClamp return min == max && min == 0; } + public boolean isLocked() + { + return min == max && !isUnlimited(); + } + public double getRadians(int rng) { if(isUnlimited()) diff --git a/src/main/java/com/volmit/iris/object/IrisObject.java b/src/main/java/com/volmit/iris/object/IrisObject.java index ba14c1a35..8cafd639a 100644 --- a/src/main/java/com/volmit/iris/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/object/IrisObject.java @@ -104,6 +104,17 @@ public class IrisObject extends IrisRegistrant } } + public void clean() + { + KMap d = blocks.copy(); + blocks.clear(); + + for(BlockVector i : d.k()) + { + blocks.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), d.get(i)); + } + } + public void setUnsigned(int x, int y, int z, BlockData block) { if(x >= w || y >= h || z >= d) @@ -370,6 +381,17 @@ public class IrisObject extends IrisRegistrant return y; } + + public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) + { + KMap v = blocks.copy(); + blocks.clear(); + + for(BlockVector i : v.keySet()) + { + blocks.put(r.rotate(i.clone(), spinx, spiny, spinz), r.rotate(v.get(i).clone(), spinx, spiny, spinz)); + } + } public void place(Location at) { diff --git a/src/main/java/com/volmit/iris/object/IrisObjectRotation.java b/src/main/java/com/volmit/iris/object/IrisObjectRotation.java index 3f4240eda..4dd2bcdde 100644 --- a/src/main/java/com/volmit/iris/object/IrisObjectRotation.java +++ b/src/main/java/com/volmit/iris/object/IrisObjectRotation.java @@ -201,7 +201,38 @@ public class IrisObjectRotation if(canRotateY()) { - v.rotateAroundY(getYRotation(spiny)); + if(getYAxis().isLocked()) + { + if(Math.abs(getYAxis().getMax()) == 180D) + { + v.setX(-v.getX()); + v.setZ(-v.getZ()); + } + + else if(getYAxis().getMax() == 90D || getYAxis().getMax() == -270D) + { + double x = v.getX(); + v.setX(v.getZ()); + v.setZ(-x); + } + + else if(getYAxis().getMax() == -90D || getYAxis().getMax() == 270D) + { + double x = v.getX(); + v.setX(-v.getZ()); + v.setZ(x); + } + + else + { + v.rotateAroundY(getYRotation(spiny)); + } + } + + else + { + v.rotateAroundY(getYRotation(spiny)); + } } return v; diff --git a/src/main/java/com/volmit/iris/object/IrisStructureTile.java b/src/main/java/com/volmit/iris/object/IrisStructureTile.java index 79565a310..7f594dd06 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructureTile.java +++ b/src/main/java/com/volmit/iris/object/IrisStructureTile.java @@ -62,14 +62,16 @@ public class IrisStructureTile @Desc("List of objects to place centered in this tile") private KList objects = new KList<>(); + private transient IrisObject forceObject; + @RegistryListObject @ArrayType(min = 1, type = IrisRareObject.class) @DontObfuscate @Desc("List of objects to place centered in this tile but with rarity. These items only place some of the time so specify objects for common stuff too.") private KList rareObjects = new KList<>(); - private AtomicCache minFaces = new AtomicCache<>(); - private AtomicCache maxFaces = new AtomicCache<>(); + private transient AtomicCache minFaces = new AtomicCache<>(); + private transient AtomicCache maxFaces = new AtomicCache<>(); public IrisStructureTile() { diff --git a/src/main/java/com/volmit/iris/util/A.java b/src/main/java/com/volmit/iris/util/A.java new file mode 100644 index 000000000..8d3912ca0 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/A.java @@ -0,0 +1,9 @@ +package com.volmit.iris.util; + +public abstract class A implements Runnable +{ + public A() + { + J.a(this); + } +} diff --git a/src/main/java/com/volmit/iris/util/AR.java b/src/main/java/com/volmit/iris/util/AR.java new file mode 100644 index 000000000..74bb12d6a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/AR.java @@ -0,0 +1,27 @@ +package com.volmit.iris.util; + +public abstract class AR implements Runnable, CancellableTask +{ + private int id = 0; + + public AR() + { + this(0); + } + + public AR(int interval) + { + id = J.ar(this, interval); + } + + @Override + public void cancel() + { + J.car(id); + } + + public int getId() + { + return id; + } +} diff --git a/src/main/java/com/volmit/iris/util/Callback.java b/src/main/java/com/volmit/iris/util/Callback.java index d8eab4929..b4b0b3bfb 100644 --- a/src/main/java/com/volmit/iris/util/Callback.java +++ b/src/main/java/com/volmit/iris/util/Callback.java @@ -1,6 +1,21 @@ package com.volmit.iris.util; +/** + * Callback for async workers + * + * @author cyberpwn + * + * @param + * the type of object to be returned in the runnable + */ +@FunctionalInterface public interface Callback { + /** + * Called when the callback calls back... + * + * @param t + * the object to be called back + */ public void run(T t); } diff --git a/src/main/java/com/volmit/iris/util/CancellableTask.java b/src/main/java/com/volmit/iris/util/CancellableTask.java new file mode 100644 index 000000000..33c37a2f1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/CancellableTask.java @@ -0,0 +1,6 @@ +package com.volmit.iris.util; + +public interface CancellableTask +{ + public void cancel(); +} diff --git a/src/main/java/com/volmit/iris/util/ChronoLatch.java b/src/main/java/com/volmit/iris/util/ChronoLatch.java index f468f1ff9..791bdc6d4 100644 --- a/src/main/java/com/volmit/iris/util/ChronoLatch.java +++ b/src/main/java/com/volmit/iris/util/ChronoLatch.java @@ -4,18 +4,28 @@ public class ChronoLatch { private long interval; private long since; - + public ChronoLatch(long interval, boolean openedAtStart) { this.interval = interval; since = System.currentTimeMillis() - (openedAtStart ? interval * 2 : 0); } - + public ChronoLatch(long interval) { this(interval, true); } - + + public void flipDown() + { + since = System.currentTimeMillis(); + } + + public boolean couldFlip() + { + return System.currentTimeMillis() - since > interval; + } + public boolean flip() { if(System.currentTimeMillis() - since > interval) @@ -23,7 +33,7 @@ public class ChronoLatch since = System.currentTimeMillis(); return true; } - + return false; } } diff --git a/src/main/java/com/volmit/iris/util/Element.java b/src/main/java/com/volmit/iris/util/Element.java new file mode 100644 index 000000000..b02d4549b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/Element.java @@ -0,0 +1,55 @@ +package com.volmit.iris.util; + +import org.bukkit.block.data.BlockData; +import org.bukkit.inventory.ItemStack; + +public interface Element +{ + public BlockData getMaterial(); + + public Element setMaterial(BlockData b); + + public boolean isEnchanted(); + + public Element setEnchanted(boolean enchanted); + + public String getId(); + + public String getName(); + + public Element setProgress(double progress); + + public double getProgress(); + + public short getEffectiveDurability(); + + public Element setCount(int c); + + public int getCount(); + + public ItemStack computeItemStack(); + + public Element setBackground(boolean bg); + + public boolean isBackgrond(); + + public Element setName(String name); + + public Element addLore(String loreLine); + + public KList getLore(); + + public Element call(ElementEvent event, Element context); + + public Element onLeftClick(Callback clicked); + + public Element onRightClick(Callback clicked); + + public Element onShiftLeftClick(Callback clicked); + + public Element onShiftRightClick(Callback clicked); + + public Element onDraggedInto(Callback into); + + public Element onOtherDraggedInto(Callback other); +} diff --git a/src/main/java/com/volmit/iris/util/ElementEvent.java b/src/main/java/com/volmit/iris/util/ElementEvent.java new file mode 100644 index 000000000..2208c1344 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/ElementEvent.java @@ -0,0 +1,17 @@ +package com.volmit.iris.util; + +/** + * Element Event. + * + * @author cyberpwn + * + */ +public enum ElementEvent +{ + LEFT, + RIGHT, + SHIFT_LEFT, + SHIFT_RIGHT, + DRAG_INTO, + OTHER_DRAG_INTO; +} diff --git a/src/main/java/com/volmit/iris/util/FinalInteger.java b/src/main/java/com/volmit/iris/util/FinalInteger.java new file mode 100644 index 000000000..e4fe46488 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/FinalInteger.java @@ -0,0 +1,36 @@ +package com.volmit.iris.util; + +/** + * Represents a number that can be finalized and be changed + * + * @author cyberpwn + */ +public class FinalInteger extends Wrapper +{ + public FinalInteger(Integer t) + { + super(t); + } + + /** + * Add to this value + * + * @param i + * the number to add to this value (value = value + i) + */ + public void add(int i) + { + set(get() + i); + } + + /** + * Subtract from this value + * + * @param i + * the number to subtract from this value (value = value - i) + */ + public void sub(int i) + { + set(get() - i); + } +} diff --git a/src/main/java/com/volmit/iris/util/J.java b/src/main/java/com/volmit/iris/util/J.java index d730e27fe..84b638774 100644 --- a/src/main/java/com/volmit/iris/util/J.java +++ b/src/main/java/com/volmit/iris/util/J.java @@ -9,6 +9,8 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.bukkit.Bukkit; + import com.volmit.iris.Iris; public class J @@ -134,4 +136,229 @@ public class J return i; } } + + private static KList afterStartup = new KList<>(); + private static KList afterStartupAsync = new KList<>(); + private static boolean started = false; + + /** + * Dont call this unless you know what you are doing! + */ + public static void executeAfterStartupQueue() + { + if(started) + { + return; + } + + started = true; + + for(Runnable r : afterStartup) + { + s(r); + } + + for(Runnable r : afterStartupAsync) + { + a(r); + } + + afterStartup = null; + afterStartupAsync = null; + } + + /** + * Schedule a sync task to be run right after startup. If the server has already + * started ticking, it will simply run it in a sync task. + * + * If you dont know if you should queue this or not, do so, it's pretty + * forgiving. + * + * @param r + * the runnable + */ + public static void ass(Runnable r) + { + if(started) + { + s(r); + } + + else + { + afterStartup.add(r); + } + } + + /** + * Schedule an async task to be run right after startup. If the server has + * already started ticking, it will simply run it in an async task. + * + * If you dont know if you should queue this or not, do so, it's pretty + * forgiving. + * + * @param r + * the runnable + */ + public static void asa(Runnable r) + { + if(started) + { + a(r); + } + + else + { + afterStartupAsync.add(r); + } + } + + /** + * Queue a sync task + * + * @param r + * the runnable + */ + public static void s(Runnable r) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r); + } + + /** + * Queue a sync task + * + * @param r + * the runnable + * @param delay + * the delay to wait in ticks before running + */ + public static void s(Runnable r, int delay) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r, delay); + } + + /** + * Cancel a sync repeating task + * + * @param id + * the task id + */ + public static void csr(int id) + { + Bukkit.getScheduler().cancelTask(id); + } + + /** + * Start a sync repeating task + * + * @param r + * the runnable + * @param interval + * the interval + * @return the task id + */ + public static int sr(Runnable r, int interval) + { + return Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, r, 0, interval); + } + + /** + * Start a sync repeating task for a limited amount of ticks + * + * @param r + * the runnable + * @param interval + * the interval in ticks + * @param intervals + * the maximum amount of intervals to run + */ + public static void sr(Runnable r, int interval, int intervals) + { + FinalInteger fi = new FinalInteger(0); + + new SR() + { + @Override + public void run() + { + fi.add(1); + r.run(); + + if(fi.get() >= intervals) + { + cancel(); + } + } + }; + } + + /** + * Call an async task dealyed + * + * @param r + * the runnable + * @param delay + * the delay to wait before running + */ + @SuppressWarnings("deprecation") + public static void a(Runnable r, int delay) + { + Bukkit.getScheduler().scheduleAsyncDelayedTask(Iris.instance, r, delay); + } + + /** + * Cancel an async repeat task + * + * @param id + * the id + */ + public static void car(int id) + { + Bukkit.getScheduler().cancelTask(id); + } + + /** + * Start an async repeat task + * + * @param r + * the runnable + * @param interval + * the interval in ticks + * @return the task id + */ + @SuppressWarnings("deprecation") + public static int ar(Runnable r, int interval) + { + return Bukkit.getScheduler().scheduleAsyncRepeatingTask(Iris.instance, r, 0, interval); + } + + /** + * Start an async repeating task for a limited time + * + * @param r + * the runnable + * @param interval + * the interval + * @param intervals + * the intervals to run + */ + public static void ar(Runnable r, int interval, int intervals) + { + FinalInteger fi = new FinalInteger(0); + + new AR() + { + @Override + public void run() + { + fi.add(1); + r.run(); + + if(fi.get() >= intervals) + { + cancel(); + } + } + }; + } } diff --git a/src/main/java/com/volmit/iris/util/S.java b/src/main/java/com/volmit/iris/util/S.java new file mode 100644 index 000000000..2199339d2 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/S.java @@ -0,0 +1,14 @@ +package com.volmit.iris.util; + +public abstract class S implements Runnable +{ + public S() + { + J.s(this); + } + + public S(int delay) + { + J.s(this, delay); + } +} diff --git a/src/main/java/com/volmit/iris/util/SR.java b/src/main/java/com/volmit/iris/util/SR.java new file mode 100644 index 000000000..453977ddc --- /dev/null +++ b/src/main/java/com/volmit/iris/util/SR.java @@ -0,0 +1,27 @@ +package com.volmit.iris.util; + +public abstract class SR implements Runnable, CancellableTask +{ + private int id = 0; + + public SR() + { + this(0); + } + + public SR(int interval) + { + id = J.sr(this, interval); + } + + @Override + public void cancel() + { + J.csr(id); + } + + public int getId() + { + return id; + } +} diff --git a/src/main/java/com/volmit/iris/util/StructureTemplate.java b/src/main/java/com/volmit/iris/util/StructureTemplate.java new file mode 100644 index 000000000..4de5f1a5f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/StructureTemplate.java @@ -0,0 +1,973 @@ +package com.volmit.iris.util; + +import java.io.File; +import java.util.Iterator; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockCookEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFertilizeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.util.BlockVector; + +import com.google.gson.Gson; +import com.volmit.iris.Iris; +import com.volmit.iris.object.IrisObject; +import com.volmit.iris.object.IrisStructure; +import com.volmit.iris.object.IrisStructureTile; +import com.volmit.iris.object.StructureTileCondition; +import com.volmit.iris.object.TileResult; + +import lombok.Data; + +@Data +public class StructureTemplate implements Listener, IObjectPlacer +{ + private int w; + private int h; + private boolean use3d; + private IrisStructure structure; + private RNG rng; + private int size; + private Location center; + private ChronoLatch u = new ChronoLatch(50); + private World world; + private static final BlockData STONE = B.get("STONE"); + private static final BlockData RED = B.get("RED_STAINED_GLASS"); + private static final BlockData GREEN = B.get("LIME_STAINED_GLASS"); + private int task; + private ChronoLatch dirtyLatch; + private ChronoLatch gLatch; + private Location focus; + private Player worker; + private KMap updates = new KMap<>(); + private File folder; + + public StructureTemplate(String name, String dimension, Player worker, Location c, int size, int w, int h, boolean use3d) + { + this.worker = worker; + rng = new RNG(); + folder = Iris.instance.getDataFolder("packs", dimension); + gLatch = new ChronoLatch(250); + focus = center; + dirtyLatch = new ChronoLatch(2350); + task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::tick, 0, 0); + this.world = c.getWorld(); + this.center = c.clone(); + this.size = size; + this.use3d = use3d; + this.w = w; + this.h = h; + Iris.instance.registerListener(this); + structure = new IrisStructure(); + structure.setGridSize(w); + structure.setGridHeight(h); + structure.setMaxLayers(use3d ? size : 1); + structure.setBore(true); + structure.setLoadKey(name); + structure.setName(Form.capitalizeWords(name.replaceAll("\\Q-\\E", " "))); + structure.setWallChance(0.35); + defineStructures(); + updateTiles(center, null, null); + Iris.struct.open(this); + } + + public void saveStructure() + { + try + { + File structureFile = new File(folder, "structures/" + structure.getLoadKey() + ".json"); + + for(IrisStructureTile i : structure.getTiles()) + { + File objectFile = new File(folder, "objects/structure/" + structure.getLoadKey() + "/" + i.getForceObject().getLoadKey() + ".iob"); + Iris.verbose("Saving " + objectFile.getPath()); + i.getForceObject().write(objectFile); + } + + Iris.verbose("Saving " + structureFile.getPath()); + IO.writeAll(structureFile, new JSONObject(new Gson().toJson(structure)).toString(4)); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + + public void setWallChance(double w) + { + structure.setWallChance(w); + regenerate(); + } + + public void regenerate() + { + rng = new RNG(); + updateTiles(center, null, null); + } + + public void queue(Location l, Runnable r) + { + if(updates.containsKey(l)) + { + return; + } + + updates.put(l, r); + } + + public void tick() + { + try + { + Location m = worker.getTargetBlockExact(64).getLocation(); + + if(isWithinBounds(m) && u.flip()) + { + focus = m.clone(); + Cuboid b = getTileBounds(m); + if(gLatch.flip()) + { + highlightTile(b); + } + } + } + + catch(Throwable ef) + { + + } + + if(dirtyLatch.couldFlip()) + { + int u = 3; + while(updates.size() > 0 && u-- > 0) + { + runClosestTo(); + } + } + } + + private void runClosestTo() + { + if(focus == null) + { + focus = center; + } + + Location g = null; + double v = Double.MAX_VALUE; + + for(Location l : updates.keySet()) + { + double d = l.distanceSquared(focus); + if(d < v) + { + v = d; + g = l; + } + } + + updates.remove(g).run(); + } + + private void mod(Location l) + { + if(!isWithinBounds(l)) + { + return; + } + + focus = l.clone(); + Cuboid cuboid = getTileBounds(l); + Location center = cuboid.getCenter(); + TileResult r = structure.getTile(rng, center.getX(), center.getY(), center.getZ()); + + if(r == null) + { + return; + } + + IrisObject o = r.getTile().getForceObject(); + double yrot = r.getPlacement().getRotation().getYAxis().getMax(); + double trot = -yrot; + r.getPlacement().getRotation().getYAxis().setMin(trot); + r.getPlacement().getRotation().getYAxis().setMax(trot); + + Location min = cuboid.getLowerNE(); + Iterator bit = cuboid.iterator(); + + while(bit.hasNext()) + { + Block b = bit.next(); + Location loc = new Location(world, b.getX(), b.getY(), b.getZ()); + BlockVector v = loc.clone().subtract(min).subtract(o.getCenter()).toVector().toBlockVector(); + v = r.getPlacement().getRotation().rotate(v, 0, 0, 0); + BlockData next = r.getPlacement().getRotation().rotate(b.getBlockData(), 0, 0, 0); + + o.getBlocks().put(v, next); + } + + r.getPlacement().getRotation().getYAxis().setMin(yrot); + r.getPlacement().getRotation().getYAxis().setMax(yrot); + dirtyLatch.flipDown(); + updateTiles(l, r.getTile(), getTileBounds(l)); + } + + public void highlightTile(Cuboid b) + { + Iris.wand.draw(b, worker); + Location center = b.getCenter(); + TileResult r = structure.getTile(rng, center.getX(), center.getY(), center.getZ()); + worker.sendTitle("", r.getTile().getForceObject().getLoadKey() + " " + r.getPlacement().getRotation().getYAxis().getMax() + "°", 0, 20, 40); + } + + public void updateTiles(Location from, IrisStructureTile tileType, Cuboid ignore) + { + Cuboid bounds = getBounds(); + + for(int i = bounds.getLowerX(); i < bounds.getUpperX(); i += w) + { + for(int j = bounds.getLowerZ(); j < bounds.getUpperZ(); j += w) + { + for(int hh = bounds.getLowerY(); hh < bounds.getUpperY(); hh += h) + { + Location l = new Location(world, i, hh, j); + + if(ignore != null && ignore.contains(l)) + { + continue; + } + + if(tileType != null) + { + Location center = getTileBounds(l).getCenter(); + TileResult r = structure.getTile(rng, center.getX(), center.getY(), center.getZ()); + + if(r == null || !r.getTile().getForceObject().getLoadKey().equals(tileType.getForceObject().getLoadKey())) + { + continue; + } + } + + if(isWithinBounds(l)) + { + queue(l, () -> updateTile(getTileBounds(l))); + } + } + } + } + } + + public void deleteTile(Cuboid from) + { + Location center = from.getCenter(); + from.iterator().forEachRemaining((b) -> b.setType(Material.AIR, false)); + center.getWorld().playSound(center, Sound.BLOCK_ANCIENT_DEBRIS_BREAK, 1f, 0.1f); + center.getWorld().spawnParticle(Particle.EXPLOSION_HUGE, center.getX(), center.getY(), center.getZ(), 1); + } + + public void updateTile(Cuboid c) + { + Location center = c.getCenter(); + Location bottomCenter = c.getCenter(); + bottomCenter.setY(c.getLowerY()); + TileResult r = structure.getTile(rng, center.getX(), center.getY(), center.getZ()); + + if(r == null) + { + return; + } + + r.getTile().getForceObject().place(bottomCenter.getBlockX(), bottomCenter.getBlockY(), bottomCenter.getBlockZ(), this, r.getPlacement(), rng); + center.getWorld().playSound(center, Sound.BLOCK_ANCIENT_DEBRIS_BREAK, 1f, 0.35f); + center.getWorld().spawnParticle(Particle.FLASH, center.getX(), center.getY(), center.getZ(), 1); + } + + public boolean isWithinBounds(Location l) + { + return getBounds().contains(l); + } + + public void close() + { + worker.sendMessage(Iris.instance.getTag() + "Saving Structure: " + getStructure().getName()); + Iris.instance.unregisterListener(this); + Bukkit.getScheduler().cancelTask(task); + saveStructure(); + Iris.struct.remove(this); + } + + public TileResult getTile(int x, int y, int z) + { + return structure.getTile(rng, x, y, z); + } + + public Cuboid getBounds() + { + return getBounds(center); + } + + public Cuboid getBounds(Location center) + { + //@builder + return new Cuboid( + getTileBounds(center.clone().add( + ((size / 2) * w) + 1, + !use3d ? 0 : (((size / 2) * h) + 1), + ((size / 2) * w) + 1) + ).getUpperSW(), + getTileBounds(center.clone().subtract( + ((size / 2) * w) + 1, + !use3d ? 0 : (((size / 2) * h) + 1), + ((size / 2) * w) + 1) + ).getLowerNE()); + //@done + } + + public Cuboid getTileBounds(Location l) + { + //@builder + return new Cuboid( + new Location(l.getWorld(), + Math.floorDiv(l.getBlockX(), w) * w, + Math.floorDiv(l.getBlockY(), h) * h, + Math.floorDiv(l.getBlockZ(), w) * w), + new Location(l.getWorld(), + ((Math.floorDiv(l.getBlockX(), w)+1) * w)-1, + ((Math.floorDiv(l.getBlockY(), h)+1) * h)-1, + ((Math.floorDiv(l.getBlockZ(), w)+1) * w)-1)); + //@done + } + + public IrisStructureTile tileFor(String name, StructureTileCondition f, StructureTileCondition c, StructureTileCondition n, StructureTileCondition e, StructureTileCondition w, StructureTileCondition s) + { + IrisObject o = new IrisObject(this.w, this.h, this.w); + o.setLoadKey(name.toLowerCase().replaceAll("\\Q \\E", "-")); + IrisStructureTile t = new IrisStructureTile(); + t.setForceObject(o); + t.setObjects(new KList<>("structure/" + this.structure.getLoadKey() + "/" + o.getLoadKey())); + t.setFloor(f); + t.setCeiling(c); + t.setNorth(n); + t.setEast(e); + t.setSouth(s); + t.setWest(w); + + int minX = 0; + int maxX = this.w - 1; + int minZ = 0; + int maxZ = this.w - 1; + int minY = 0; + int maxY = this.h - 1; + + if(use3d) + { + if(f.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minZ; j <= maxZ; j++) + { + o.setUnsigned(i, minY, j, STONE); + } + } + } + + if(c.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minZ; j <= maxZ; j++) + { + o.setUnsigned(i, maxY, j, STONE); + } + } + } + + if(n.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minY; j <= maxY; j++) + { + o.setUnsigned(i, j, minZ, STONE); + } + } + } + + if(s.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minY; j <= maxY; j++) + { + o.setUnsigned(i, j, maxZ, STONE); + } + } + } + + if(w.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minZ; i <= maxZ; i++) + { + for(int j = minY; j <= maxY; j++) + { + o.setUnsigned(minX, j, i, STONE); + } + } + } + + if(e.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minZ; i <= maxZ; i++) + { + for(int j = minY; j <= maxY; j++) + { + o.setUnsigned(maxX, j, i, STONE); + } + } + } + } + + else + { + if(f.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minZ; j <= maxZ; j++) + { + o.setUnsigned(i, minY, j, GREEN); + } + } + } + + if(c.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + for(int j = minZ; j <= maxZ; j++) + { + o.setUnsigned(i, maxY, j, GREEN); + } + } + } + + if(n.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + o.setUnsigned(i, minY, minZ, RED); + } + } + + if(s.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minX; i <= maxX; i++) + { + o.setUnsigned(i, minY, maxZ, RED); + } + } + + if(w.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minZ; i <= maxZ; i++) + { + o.setUnsigned(minX, minY, i, RED); + } + } + + if(e.equals(StructureTileCondition.REQUIRED)) + { + for(int i = minZ; i <= maxZ; i++) + { + o.setUnsigned(maxX, minY, i, RED); + } + } + } + + return t; + } + + @Override + public int getHighest(int x, int z) + { + return 0; + } + + @Override + public int getHighest(int x, int z, boolean ignoreFluid) + { + return 0; + } + + @Override + public void set(int x, int y, int z, BlockData d) + { + if(get(x, y, z).equals(d)) + { + return; + } + + world.getBlockAt(x, y, z).setBlockData(d, false); + } + + @Override + public BlockData get(int x, int y, int z) + { + return world.getBlockAt(x, y, z).getBlockData(); + } + + @Override + public boolean isPreventingDecay() + { + return true; + } + + @Override + public boolean isSolid(int x, int y, int z) + { + return get(x, y, z).getMaterial().isSolid(); + } + + @Override + public boolean isUnderwater(int x, int z) + { + return false; + } + + @Override + public int getFluidHeight() + { + return 0; + } + + private void defineStructures() + { + if(use3d) + { + //@builder + structure.getTiles().add(tileFor("Cross Floor", + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("T-Connect Floor", + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Hall Floor", + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED + )); + structure.getTiles().add(tileFor("Corner Floor", + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Room Floor", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Walled Room Floor", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED + )); + + structure.getTiles().add(tileFor("Cross Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("T-Connect Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Hall Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED + )); + structure.getTiles().add(tileFor("Corner Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Room Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Walled Room Ceiling", + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED + )); + + structure.getTiles().add(tileFor("Cross Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("T-Connect Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Hall Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED + )); + structure.getTiles().add(tileFor("Corner Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Room Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Walled Room Opening", + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED + )); + + structure.getTiles().add(tileFor("Cross Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("T-Connect Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Hall Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED + )); + structure.getTiles().add(tileFor("Corner Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Room Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Walled Room Encased", + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED + )); + //@done + } + + else + { + //@builder + structure.getTiles().add(tileFor("Cross", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("T-Connect", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Hall", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER, + StructureTileCondition.REQUIRED + )); + structure.getTiles().add(tileFor("Corner", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Room", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.NEVER + )); + structure.getTiles().add(tileFor("Walled Room", + StructureTileCondition.REQUIRED, + StructureTileCondition.AGNOSTIC, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED, + StructureTileCondition.REQUIRED + )); + //@done + } + } + + @EventHandler + public void on(BlockBreakEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockIgniteEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockFormEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockFromToEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockFadeEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockPhysicsEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockFertilizeEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockGrowEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockSpreadEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockBurnEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockCookEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + @EventHandler + public void on(BlockPlaceEvent e) + { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> mod(e.getBlock().getLocation()), 5); + } + + public void more() + { + Location center = worker.getLocation().clone(); + + if(!use3d) + { + center.setY(this.center.getY()); + } + + Cuboid bounds = getBounds(); + Cuboid newBounds = getBounds(center); + Cuboid total = bounds.getBoundingCuboid(newBounds); + + for(int i = bounds.getLowerX(); i < bounds.getUpperX(); i += w) + { + for(int j = bounds.getLowerZ(); j < bounds.getUpperZ(); j += w) + { + for(int hh = bounds.getLowerY(); hh < bounds.getUpperY(); hh += h) + { + Location l = new Location(world, i, hh, j); + if(!total.contains(l)) + { + continue; + } + boolean o = bounds.contains(l); + boolean n = newBounds.contains(l); + + if(o && !n) + { + deleteTile(getTileBounds(l)); + } + } + } + } + + this.center = center; + updateTiles(focus, null, null); + } + + public void expand() + { + Location center = worker.getLocation().clone(); + + if(!use3d) + { + center.setY(this.center.getY()); + } + + Cuboid bounds = getBounds(); + Cuboid newBounds = getBounds(center); + Cuboid total = bounds.getBoundingCuboid(newBounds); + + for(int i = bounds.getLowerX(); i < bounds.getUpperX(); i += w) + { + for(int j = bounds.getLowerZ(); j < bounds.getUpperZ(); j += w) + { + for(int hh = bounds.getLowerY(); hh < bounds.getUpperY(); hh += h) + { + Location l = new Location(world, i, hh, j); + if(!total.contains(l)) + { + continue; + } + boolean o = bounds.contains(l); + boolean n = newBounds.contains(l); + + if(o && !n) + { + deleteTile(getTileBounds(l)); + } + } + } + } + + size += 2; + this.center = center; + updateTiles(focus, null, null); + } +} diff --git a/src/main/java/com/volmit/iris/util/Wrapper.java b/src/main/java/com/volmit/iris/util/Wrapper.java new file mode 100644 index 000000000..53353ed5a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/Wrapper.java @@ -0,0 +1,72 @@ +package com.volmit.iris.util; + +public class Wrapper +{ + private T t; + + public Wrapper(T t) + { + set(t); + } + + public void set(T t) + { + this.t = t; + } + + public T get() + { + return t; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((t == null) ? 0 : t.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if(this == obj) + { + return true; + } + if(obj == null) + { + return false; + } + if(!(obj instanceof Wrapper)) + { + return false; + } + + Wrapper other = (Wrapper) obj; + if(t == null) + { + if(other.t != null) + { + return false; + } + } + else if(!t.equals(other.t)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + if(t != null) + { + return get().toString(); + } + + return super.toString() + " (null)"; + } +} diff --git a/src/main/java/com/volmit/iris/util/inventory/C.java b/src/main/java/com/volmit/iris/util/inventory/C.java new file mode 100644 index 000000000..843c61b0c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/C.java @@ -0,0 +1,787 @@ +package com.volmit.iris.util.inventory; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.DyeColor; + +/** + * Colors + * + * @author cyberpwn + */ +public enum C +{ + /** + * Represents black + */ + BLACK('0', 0x00) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.BLACK; + } + }, + /** + * Represents dark blue + */ + DARK_BLUE('1', 0x1) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_BLUE; + } + }, + /** + * Represents dark green + */ + DARK_GREEN('2', 0x2) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_GREEN; + } + }, + /** + * Represents dark blue (aqua) + */ + DARK_AQUA('3', 0x3) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_AQUA; + } + }, + /** + * Represents dark red + */ + DARK_RED('4', 0x4) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_RED; + } + }, + /** + * Represents dark purple + */ + DARK_PURPLE('5', 0x5) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_PURPLE; + } + }, + /** + * Represents gold + */ + GOLD('6', 0x6) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.GOLD; + } + }, + /** + * Represents gray + */ + GRAY('7', 0x7) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.GRAY; + } + }, + /** + * Represents dark gray + */ + DARK_GRAY('8', 0x8) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.DARK_GRAY; + } + }, + /** + * Represents blue + */ + BLUE('9', 0x9) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.BLUE; + } + }, + /** + * Represents green + */ + GREEN('a', 0xA) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.GREEN; + } + }, + /** + * Represents aqua + */ + AQUA('b', 0xB) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.AQUA; + } + }, + /** + * Represents red + */ + RED('c', 0xC) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.RED; + } + }, + /** + * Represents light purple + */ + LIGHT_PURPLE('d', 0xD) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.LIGHT_PURPLE; + } + }, + /** + * Represents yellow + */ + YELLOW('e', 0xE) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.YELLOW; + } + }, + /** + * Represents white + */ + WHITE('f', 0xF) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.WHITE; + } + }, + /** + * Represents magical characters that change around randomly + */ + MAGIC('k', 0x10, true) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.MAGIC; + } + }, + /** + * Makes the text bold. + */ + BOLD('l', 0x11, true) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.BOLD; + } + }, + /** + * Makes a line appear through the text. + */ + STRIKETHROUGH('m', 0x12, true) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.STRIKETHROUGH; + } + }, + /** + * Makes the text appear underlined. + */ + UNDERLINE('n', 0x13, true) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.UNDERLINE; + } + }, + /** + * Makes the text italic. + */ + ITALIC('o', 0x14, true) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.ITALIC; + } + }, + + /** + * Resets all previous chat colors or formats. + */ + RESET('r', 0x15) + { + @Override + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.RESET; + } + }; + + /** + * The special character which prefixes all chat colour codes. Use this if you + * need to dynamically convert colour codes from your custom format. + */ + public static final char COLOR_CHAR = '\u00A7'; + private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]"); + public final static C[] COLORCYCLE = new C[] {C.GOLD, C.YELLOW, C.GREEN, C.AQUA, C.LIGHT_PURPLE, C.AQUA, C.GREEN, C.YELLOW, C.GOLD, C.RED}; + private final static C[] COLORS = new C[] {C.BLACK, C.DARK_BLUE, C.DARK_GREEN, C.DARK_AQUA, C.DARK_RED, C.DARK_PURPLE, C.GOLD, C.GRAY, C.DARK_GRAY, C.BLUE, C.GREEN, C.AQUA, C.RED, C.LIGHT_PURPLE, C.YELLOW, C.WHITE}; + private final int intCode; + private final char code; + private final boolean isFormat; + private final String toString; + private final static Map BY_ID = new HashMap(); + private final static Map BY_CHAR = new HashMap(); + private final static Map dyeChatMap = new HashMap(); + private final static Map chatHexMap = new HashMap(); + private final static Map dyeHexMap = new HashMap(); + + static + { + chatHexMap.put(C.BLACK, "#000"); + chatHexMap.put(C.DARK_BLUE, "#00a"); + chatHexMap.put(C.DARK_GREEN, "#0a0"); + chatHexMap.put(C.DARK_AQUA, "#0aa"); + chatHexMap.put(C.DARK_RED, "#a00"); + chatHexMap.put(C.DARK_PURPLE, "#a0a"); + chatHexMap.put(C.GOLD, "#fa0"); + chatHexMap.put(C.GRAY, "#999"); + chatHexMap.put(C.DARK_GRAY, "#555"); + chatHexMap.put(C.BLUE, "#55f"); + chatHexMap.put(C.GREEN, "#5c5"); + chatHexMap.put(C.AQUA, "#5cc"); + chatHexMap.put(C.RED, "#f55"); + chatHexMap.put(C.LIGHT_PURPLE, "#f5f"); + chatHexMap.put(C.YELLOW, "#cc5"); + chatHexMap.put(C.WHITE, "#aaa"); + dyeChatMap.put(DyeColor.BLACK, C.DARK_GRAY); + dyeChatMap.put(DyeColor.BLUE, C.DARK_BLUE); + dyeChatMap.put(DyeColor.BROWN, C.GOLD); + dyeChatMap.put(DyeColor.CYAN, C.AQUA); + dyeChatMap.put(DyeColor.GRAY, C.GRAY); + dyeChatMap.put(DyeColor.GREEN, C.DARK_GREEN); + dyeChatMap.put(DyeColor.LIGHT_BLUE, C.BLUE); + dyeChatMap.put(DyeColor.LIME, C.GREEN); + dyeChatMap.put(DyeColor.MAGENTA, C.LIGHT_PURPLE); + dyeChatMap.put(DyeColor.ORANGE, C.GOLD); + dyeChatMap.put(DyeColor.PINK, C.LIGHT_PURPLE); + dyeChatMap.put(DyeColor.PURPLE, C.DARK_PURPLE); + dyeChatMap.put(DyeColor.RED, C.RED); + dyeChatMap.put(DyeColor.LIGHT_GRAY, C.GRAY); + dyeChatMap.put(DyeColor.WHITE, C.WHITE); + dyeChatMap.put(DyeColor.YELLOW, C.YELLOW); + dyeHexMap.put(DyeColor.BLACK, "#181414"); + dyeHexMap.put(DyeColor.BLUE, "#253193"); + dyeHexMap.put(DyeColor.BROWN, "#56331c"); + dyeHexMap.put(DyeColor.CYAN, "#267191"); + dyeHexMap.put(DyeColor.GRAY, "#414141"); + dyeHexMap.put(DyeColor.GREEN, "#364b18"); + dyeHexMap.put(DyeColor.LIGHT_BLUE, "#6387d2"); + dyeHexMap.put(DyeColor.LIME, "#39ba2e"); + dyeHexMap.put(DyeColor.MAGENTA, "#be49c9"); + dyeHexMap.put(DyeColor.ORANGE, "#ea7e35"); + dyeHexMap.put(DyeColor.PINK, "#d98199"); + dyeHexMap.put(DyeColor.PURPLE, "#7e34bf"); + dyeHexMap.put(DyeColor.RED, "#9e2b27"); + dyeHexMap.put(DyeColor.LIGHT_GRAY, "#a0a7a7"); + dyeHexMap.put(DyeColor.WHITE, "#a4a4a4"); + dyeHexMap.put(DyeColor.YELLOW, "#c2b51c"); + } + + private C(char code, int intCode) + { + this(code, intCode, false); + } + + private C(char code, int intCode, boolean isFormat) + { + this.code = code; + this.intCode = intCode; + this.isFormat = isFormat; + this.toString = new String(new char[] {COLOR_CHAR, code}); + } + + public net.md_5.bungee.api.ChatColor asBungee() + { + return net.md_5.bungee.api.ChatColor.RESET; + }; + + /** + * Gets the char value associated with this color + * + * @return A char value of this color code + */ + public char getChar() + { + return code; + } + + @Override + public String toString() + { + return toString; + } + + /** + * get the dye color for the chatcolor + * + * @return + */ + public DyeColor dye() + { + return chatToDye(chatColor()); + } + + public String hex() + { + return chatToHex(chatColor()); + } + + /** + * Checks if this code is a format code as opposed to a color code. + * + * @return whether this ChatColor is a format code + */ + public boolean isFormat() + { + return isFormat; + } + + /** + * Checks if this code is a color code as opposed to a format code. + * + * @return whether this ChatColor is a color code + */ + public boolean isColor() + { + return !isFormat && this != RESET; + } + + /** + * Gets the color represented by the specified color code + * + * @param code + * Code to check + * @return Associative {@link org.bukkit.ChatColor} with the given code, or null + * if it doesn't exist + */ + public static C getByChar(char code) + { + try + { + return BY_CHAR.get(code); + } + + catch(Exception e) + { + return C.WHITE; + } + } + + /** + * Gets the color represented by the specified color code + * + * @param code + * Code to check + * @return Associative {@link org.bukkit.ChatColor} with the given code, or null + * if it doesn't exist + */ + public static C getByChar(String code) + { + try + { + Validate.notNull(code, "Code cannot be null"); + Validate.isTrue(code.length() > 0, "Code must have at least one char"); + + return BY_CHAR.get(code.charAt(0)); + } + + catch(Exception e) + { + return C.WHITE; + } + } + + /** + * Strips the given message of all color codes + * + * @param input + * String to strip of color + * @return A copy of the input string, without any coloring + */ + public static String stripColor(final String input) + { + if(input == null) + { + return null; + } + + return STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); + } + + /** + * DyeColor to ChatColor + * + * @param dclr + * the dye color + * @return the color + */ + public static C dyeToChat(DyeColor dclr) + { + if(dyeChatMap.containsKey(dclr)) + { + return dyeChatMap.get(dclr); + } + + return C.MAGIC; + } + + public static DyeColor chatToDye(ChatColor color) + { + for(DyeColor i : dyeChatMap.keySet()) + { + if(dyeChatMap.get(i).toString().equals(color.toString())) + { + return i; + } + } + + return DyeColor.BLACK; + } + + @SuppressWarnings("unlikely-arg-type") + public static String chatToHex(ChatColor clr) + { + if(chatHexMap.containsKey(clr)) + { + return chatHexMap.get(clr); + } + + return "#000"; + } + + public static String dyeToHex(DyeColor clr) + { + if(dyeHexMap.containsKey(clr)) + { + return dyeHexMap.get(clr); + } + + return "#000"; + } + + public static Color hexToColor(String hex) + { + if(hex.startsWith("#")) + { + hex = hex.substring(1); + } + + if(hex.indexOf("x") != -1) + { + hex = hex.substring(hex.indexOf("x")); + } + + if(hex.length() != 6 && hex.length() != 3) + { + return null; + } + int sz = hex.length() / 3, mult = 1 << ((2 - sz) * 4), x = 0; + + for(int i = 0, z = 0; z < hex.length(); ++i, z += sz) + { + x |= (mult * Integer.parseInt(hex.substring(z, z + sz), 16)) << (i * 8); + } + + return Color.fromBGR(x & 0xffffff); + } + + public static Color rgbToColor(String rgb) + { + String parts[] = rgb.split("[^0-9]+"); + if(parts.length < 3) + { + return null; + } + + int x = 0, i; + + for(i = 0; i < 3; ++i) + { + x |= Integer.parseInt(parts[i]) << (i * 8); + } + + return Color.fromBGR(x & 0xffffff); + } + + public static String generateColorTable() + { + StringBuilder str = new StringBuilder(); + + str.append(""); + + for(Map.Entry e : chatHexMap.entrySet()) + { + str.append(String.format("" + "", e.getKey().name(), e.getValue())); + } + + str.append("
Chat ColorColor
%1$sTest String
"); + str.append(""); + for(Map.Entry e : dyeHexMap.entrySet()) + { + str.append(String.format("" + "", e.getKey().name(), e.getValue())); + } + + str.append("
Dye ColorColor
%1$sTest String
"); + + return str.toString(); + } + + /** + * Get the ChatColor enum instance instead of C + * + * @return + */ + public ChatColor chatColor() + { + return ChatColor.getByChar(code); + } + + /** + * Translates a string using an alternate color code character into a string + * that uses the internal ChatColor.COLOR_CODE color code character. The + * alternate color code character will only be replaced if it is immediately + * followed by 0-9, A-F, a-f, K-O, k-o, R or r. + * + * @param altColorChar + * The alternate color code character to replace. Ex: {@literal &} + * @param textToTranslate + * Text containing the alternate color code character. + * @return Text containing the ChatColor.COLOR_CODE color code character. + */ + public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) + { + char[] b = textToTranslate.toCharArray(); + for(int i = 0; i < b.length - 1; i++) + { + if(b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) + { + b[i] = C.COLOR_CHAR; + b[i + 1] = Character.toLowerCase(b[i + 1]); + } + } + return new String(b); + } + + public static C fromItemMeta(byte c) + { + for(C i : C.values()) + { + if(i.getItemMeta() == c) + { + return i; + } + } + + return null; + } + + public byte getMeta() + { + switch(this) + { + case AQUA: + return 11; + case BLACK: + return 0; + case BLUE: + return 9; + case BOLD: + return -1; + case DARK_AQUA: + return 9; + case DARK_BLUE: + return 1; + case DARK_GRAY: + return 8; + case DARK_GREEN: + return 2; + case DARK_PURPLE: + return 5; + case DARK_RED: + return 4; + case GOLD: + return 6; + case GRAY: + return 7; + case GREEN: + return 10; + case ITALIC: + return -1; + case LIGHT_PURPLE: + return 13; + case MAGIC: + return -1; + case RED: + return 12; + case RESET: + return -1; + case STRIKETHROUGH: + return -1; + case UNDERLINE: + return -1; + case WHITE: + return 15; + case YELLOW: + return 14; + default: + return -1; + } + } + + public byte getItemMeta() + { + switch(this) + { + case AQUA: + return 9; + case BLACK: + return 15; + case BLUE: + return 3; + case BOLD: + return -1; + case DARK_AQUA: + return 9; + case DARK_BLUE: + return 11; + case DARK_GRAY: + return 7; + case DARK_GREEN: + return 13; + case DARK_PURPLE: + return 10; + case DARK_RED: + return 14; + case GOLD: + return 4; + case GRAY: + return 8; + case GREEN: + return 5; + case ITALIC: + return -1; + case LIGHT_PURPLE: + return 2; + case MAGIC: + return -1; + case RED: + return 14; + case RESET: + return -1; + case STRIKETHROUGH: + return -1; + case UNDERLINE: + return -1; + case WHITE: + return 0; + case YELLOW: + return 4; + default: + return -1; + } + } + + public static C randomColor() + { + return COLORS[(int) (Math.random() * (COLORS.length - 1))]; + } + + /** + * Gets the ChatColors used at the end of the given input string. + * + * @param input + * Input string to retrieve the colors from. + * @return Any remaining ChatColors to pass onto the next line. + */ + public static String getLastColors(String input) + { + String result = ""; + int length = input.length(); + + // Search backwards from the end as it is faster + for(int index = length - 1; index > -1; index--) + { + char section = input.charAt(index); + if(section == COLOR_CHAR && index < length - 1) + { + char c = input.charAt(index + 1); + C color = getByChar(c); + + if(color != null) + { + result = color.toString() + result; + + // Once we find a color or reset we can stop searching + if(color.isColor() || color.equals(RESET)) + { + break; + } + } + } + } + + return result; + } + + static + { + for(C color : values()) + { + BY_ID.put(color.intCode, color); + BY_CHAR.put(color.code, color); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/inventory/Callback.java b/src/main/java/com/volmit/iris/util/inventory/Callback.java new file mode 100644 index 000000000..321b184bb --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/Callback.java @@ -0,0 +1,21 @@ +package com.volmit.iris.util.inventory; + +/** + * Callback for async workers + * + * @author cyberpwn + * + * @param + * the type of object to be returned in the runnable + */ +@FunctionalInterface +public interface Callback +{ + /** + * Called when the callback calls back... + * + * @param t + * the object to be called back + */ + public void run(T t); +} diff --git a/src/main/java/com/volmit/iris/util/inventory/Element.java b/src/main/java/com/volmit/iris/util/inventory/Element.java new file mode 100644 index 000000000..a8e451b8b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/Element.java @@ -0,0 +1,56 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.inventory.ItemStack; + +import com.volmit.iris.util.KList; + +public interface Element +{ + public MaterialBlock getMaterial(); + + public Element setMaterial(MaterialBlock b); + + public boolean isEnchanted(); + + public Element setEnchanted(boolean enchanted); + + public String getId(); + + public String getName(); + + public Element setProgress(double progress); + + public double getProgress(); + + public short getEffectiveDurability(); + + public Element setCount(int c); + + public int getCount(); + + public ItemStack computeItemStack(); + + public Element setBackground(boolean bg); + + public boolean isBackgrond(); + + public Element setName(String name); + + public Element addLore(String loreLine); + + public KList getLore(); + + public Element call(ElementEvent event, Element context); + + public Element onLeftClick(Callback clicked); + + public Element onRightClick(Callback clicked); + + public Element onShiftLeftClick(Callback clicked); + + public Element onShiftRightClick(Callback clicked); + + public Element onDraggedInto(Callback into); + + public Element onOtherDraggedInto(Callback other); +} diff --git a/src/main/java/com/volmit/iris/util/inventory/ElementEvent.java b/src/main/java/com/volmit/iris/util/inventory/ElementEvent.java new file mode 100644 index 000000000..642d4c23b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/ElementEvent.java @@ -0,0 +1,17 @@ +package com.volmit.iris.util.inventory; + +/** + * Element Event. + * + * @author cyberpwn + * + */ +public enum ElementEvent +{ + LEFT, + RIGHT, + SHIFT_LEFT, + SHIFT_RIGHT, + DRAG_INTO, + OTHER_DRAG_INTO; +} diff --git a/src/main/java/com/volmit/iris/util/inventory/MaterialBlock.java b/src/main/java/com/volmit/iris/util/inventory/MaterialBlock.java new file mode 100644 index 000000000..4c21deea6 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/MaterialBlock.java @@ -0,0 +1,136 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; + +/** + * Material blocks + * + * @author cyberpwn + */ +@SuppressWarnings("deprecation") +public class MaterialBlock +{ + private Material material; + private Byte data; + + /** + * Create a materialblock + * + * @param material + * the material + * @param data + * the data + */ + public MaterialBlock(Material material, Byte data) + { + this.material = material; + this.data = data; + } + + public MaterialBlock(Material material) + { + this.material = material; + data = 0; + } + + public MaterialBlock(Location location) + { + this(location.getBlock()); + } + + public MaterialBlock(BlockState state) + { + material = state.getType(); + data = state.getData().getData(); + } + + public MaterialBlock(Block block) + { + material = block.getType(); + data = block.getData(); + } + + public MaterialBlock() + { + material = Material.AIR; + data = 0; + } + + public Material getMaterial() + { + return material; + } + + public void setMaterial(Material material) + { + this.material = material; + } + + public Byte getData() + { + return data; + } + + public void setData(Byte data) + { + this.data = data; + } + + @Override + public String toString() + { + if(getData() == 0) + { + return getMaterial().toString(); + } + + return getMaterial().toString() + ":" + getData(); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((data == null) ? 0 : data.hashCode()); + result = prime * result + ((material == null) ? 0 : material.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if(this == obj) + { + return true; + } + if(obj == null) + { + return false; + } + if(getClass() != obj.getClass()) + { + return false; + } + MaterialBlock other = (MaterialBlock) obj; + if(data == null) + { + if(other.data != null) + { + return false; + } + } + else if(!data.equals(other.data)) + { + return false; + } + if(material != other.material) + { + return false; + } + return true; + } +} diff --git a/src/main/java/com/volmit/iris/util/inventory/UIElement.java b/src/main/java/com/volmit/iris/util/inventory/UIElement.java new file mode 100644 index 000000000..578d2d15f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/UIElement.java @@ -0,0 +1,259 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.volmit.iris.util.KList; +import com.volmit.iris.util.M; + +public class UIElement implements Element +{ + private MaterialBlock material; + private boolean enchanted; + private final String id; + private String name; + private double progress; + private boolean bg; + private final KList lore; + private Callback eLeft; + private Callback eRight; + private Callback eShiftLeft; + private Callback eShiftRight; + private Callback eDraggedInto; + private Callback eOtherDraggedInto; + private int count; + + public UIElement(String id) + { + this.id = id; + lore = new KList<>(); + enchanted = false; + count = 1; + material = new MaterialBlock(Material.AIR); + } + + @Override + public MaterialBlock getMaterial() + { + return material; + } + + @Override + public UIElement setMaterial(MaterialBlock material) + { + this.material = material; + return this; + } + + @Override + public boolean isEnchanted() + { + return enchanted; + } + + @Override + public UIElement setEnchanted(boolean enchanted) + { + this.enchanted = enchanted; + return this; + } + + @Override + public String getId() + { + return id; + } + + @Override + public String getName() + { + return name; + } + + @Override + public UIElement setName(String name) + { + this.name = name; + return this; + } + + @Override + public KList getLore() + { + return lore; + } + + @Override + public UIElement onLeftClick(Callback clicked) + { + eLeft = clicked; + return this; + } + + @Override + public UIElement onRightClick(Callback clicked) + { + eRight = clicked; + return this; + } + + @Override + public UIElement onShiftLeftClick(Callback clicked) + { + eShiftLeft = clicked; + return this; + } + + @Override + public UIElement onShiftRightClick(Callback clicked) + { + eShiftRight = clicked; + return this; + } + + @Override + public UIElement onDraggedInto(Callback into) + { + eDraggedInto = into; + return this; + } + + @Override + public UIElement onOtherDraggedInto(Callback other) + { + eOtherDraggedInto = other; + return this; + } + + @Override + public Element call(ElementEvent event, Element context) + { + try + { + switch(event) + { + case DRAG_INTO: + eDraggedInto.run(context); + return this; + case LEFT: + eLeft.run(context); + return this; + case OTHER_DRAG_INTO: + eOtherDraggedInto.run(context); + return this; + case RIGHT: + eRight.run(context); + return this; + case SHIFT_LEFT: + eShiftLeft.run(context); + return this; + case SHIFT_RIGHT: + eShiftRight.run(context); + return this; + } + } + + catch(NullPointerException e) + { + + } + + catch(Throwable e) + { + e.printStackTrace(); + } + + return this; + } + + @Override + public Element addLore(String loreLine) + { + getLore().add(loreLine); + return this; + } + + @Override + public Element setBackground(boolean bg) + { + this.bg = bg; + return this; + } + + @Override + public boolean isBackgrond() + { + return bg; + } + + @Override + public Element setCount(int c) + { + count = (int) M.clip(c, 1, 64); + return this; + } + + @Override + public int getCount() + { + return count; + } + + @SuppressWarnings("deprecation") + @Override + public ItemStack computeItemStack() + { + try + { + ItemStack is = new ItemStack(getMaterial().getMaterial(), getCount(), getEffectiveDurability(), getMaterial().getData()); + ItemMeta im = is.getItemMeta(); + im.setDisplayName(getName()); + im.setLore(getLore().copy()); + + if(isEnchanted()) + { + im.addEnchant(Enchantment.DURABILITY, 1, true); + } + + is.setItemMeta(im); + return is; + } + + catch(Throwable e) + { + e.printStackTrace(); + } + + return null; + } + + @Override + public Element setProgress(double progress) + { + this.progress = M.clip(progress, 0D, 1D); + return this; + } + + @Override + public double getProgress() + { + return progress; + } + + @Override + public short getEffectiveDurability() + { + if(getMaterial().getMaterial().getMaxDurability() == 0) + { + return 0; + } + + else + { + int prog = (int) ((double) getMaterial().getMaterial().getMaxDurability() * (1D - getProgress())); + return M.clip(prog, 1, (getMaterial().getMaterial().getMaxDurability() - 1)).shortValue(); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/inventory/UIStaticDecorator.java b/src/main/java/com/volmit/iris/util/inventory/UIStaticDecorator.java new file mode 100644 index 000000000..c146b87e6 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/UIStaticDecorator.java @@ -0,0 +1,19 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.Material; + +public class UIStaticDecorator implements WindowDecorator +{ + private Element element; + + public UIStaticDecorator(Element element) + { + this.element = element == null ? new UIElement("bg").setMaterial(new MaterialBlock(Material.AIR)) : element; + } + + @Override + public Element onDecorateBackground(Window window, int position, int row) + { + return element; + } +} diff --git a/src/main/java/com/volmit/iris/util/inventory/UIVoidDecorator.java b/src/main/java/com/volmit/iris/util/inventory/UIVoidDecorator.java new file mode 100644 index 000000000..f84b1e250 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/UIVoidDecorator.java @@ -0,0 +1,11 @@ +package com.volmit.iris.util.inventory; + +public class UIVoidDecorator implements WindowDecorator +{ + @Override + public Element onDecorateBackground(Window window, int position, int row) + { + return null; + } +} + diff --git a/src/main/java/com/volmit/iris/util/inventory/UIWindow.java b/src/main/java/com/volmit/iris/util/inventory/UIWindow.java new file mode 100644 index 000000000..117ca7901 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/UIWindow.java @@ -0,0 +1,545 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.J; +import com.volmit.iris.util.KMap; +import com.volmit.iris.util.KSet; +import com.volmit.iris.util.M; + +public class UIWindow implements Window, Listener +{ + private WindowDecorator decorator; + private final Player viewer; + private Callback eClose; + private WindowResolution resolution; + private KMap elements; + private String title; + private boolean visible; + private int viewportPosition; + private int viewportSize; + private int highestRow; + private Inventory inventory; + private int clickcheck; + private boolean doubleclicked; + + public UIWindow(Player viewer) + { + clickcheck = 0; + doubleclicked = false; + this.viewer = viewer; + this.elements = new KMap<>(); + setTitle(""); + setDecorator(new UIVoidDecorator()); + setResolution(WindowResolution.W9_H6); + setViewportHeight((int) M.clip(3, 1, getResolution().getMaxHeight()).intValue()); + setViewportPosition(0); + } + + @EventHandler + public void on(InventoryClickEvent e) + { + if(!e.getWhoClicked().equals(viewer)) + { + return; + } + + if(!isVisible()) + { + return; + } + + // 1.14 bukkit api change, removed getTitle() and getName() from Inventory.class + if(!viewer.getOpenInventory().getTitle().equals(title)) + { + return; + } + + if(e.getClickedInventory() == null) + { + return; + } + + if(!e.getView().getType().equals(getResolution().getType())) + { + return; + } + + if(e.getClickedInventory().getType().equals(getResolution().getType())) + { + Element element = getElement(getLayoutPosition(e.getSlot()), getLayoutRow(e.getSlot())); + + switch(e.getAction()) + { + case CLONE_STACK: + break; + case COLLECT_TO_CURSOR: + break; + case DROP_ALL_CURSOR: + break; + case DROP_ALL_SLOT: + break; + case DROP_ONE_CURSOR: + break; + case DROP_ONE_SLOT: + break; + case HOTBAR_MOVE_AND_READD: + break; + case HOTBAR_SWAP: + break; + case MOVE_TO_OTHER_INVENTORY: + break; + case NOTHING: + break; + case PICKUP_ALL: + break; + case PICKUP_HALF: + break; + case PICKUP_ONE: + break; + case PICKUP_SOME: + break; + case PLACE_ALL: + break; + case PLACE_ONE: + break; + case PLACE_SOME: + break; + case SWAP_WITH_CURSOR: + break; + case UNKNOWN: + break; + } + + switch(e.getClick()) + { + case CONTROL_DROP: + break; + case CREATIVE: + break; + case DOUBLE_CLICK: + doubleclicked = true; + break; + case DROP: + break; + case LEFT: + + clickcheck++; + + if(clickcheck == 1) + { + J.s(() -> + { + if(clickcheck == 1) + { + clickcheck = 0; + + if(element != null) + { + element.call(ElementEvent.LEFT, element); + } + } + }); + } + + else if(clickcheck == 2) + { + J.s(() -> + { + if(doubleclicked) + { + doubleclicked = false; + } + + else + { + scroll(1); + } + + clickcheck = 0; + }); + } + + break; + case MIDDLE: + break; + case NUMBER_KEY: + break; + case RIGHT: + if(element != null) + { + element.call(ElementEvent.RIGHT, element); + } + + else + { + scroll(-1); + } + break; + case SHIFT_LEFT: + if(element != null) + { + element.call(ElementEvent.SHIFT_LEFT, element); + } + break; + case SHIFT_RIGHT: + if(element != null) + { + element.call(ElementEvent.SHIFT_RIGHT, element); + } + break; + case WINDOW_BORDER_LEFT: + break; + case WINDOW_BORDER_RIGHT: + break; + case UNKNOWN: + break; + case SWAP_OFFHAND: + break; + default: + break; + } + } + + e.setCancelled(true); + + } + + @EventHandler + public void on(InventoryCloseEvent e) + { + if(!e.getPlayer().equals(viewer)) + { + return; + } + + if(!e.getPlayer().getOpenInventory().getTitle().equals(title)) + { + return; + } + + if(isVisible()) + { + close(); + callClosed(); + } + } + + @Override + public UIWindow setDecorator(WindowDecorator decorator) + { + this.decorator = decorator; + return this; + } + + @Override + public WindowDecorator getDecorator() + { + return decorator; + } + + @Override + public UIWindow close() + { + setVisible(false); + return this; + } + + @Override + public UIWindow open() + { + setVisible(true); + return this; + } + + @Override + public UIWindow setVisible(boolean visible) + { + if(isVisible() == visible) + { + return this; + } + + if(visible) + { + Bukkit.getPluginManager().registerEvents(this, Iris.instance); + + if(getResolution().getType().equals(InventoryType.CHEST)) + { + inventory = Bukkit.createInventory(null, getViewportHeight() * 9, getTitle()); + } + + else + { + inventory = Bukkit.createInventory(null, getResolution().getType(), getTitle()); + } + + viewer.openInventory(inventory); + this.visible = visible; + updateInventory(); + } + + else + { + this.visible = visible; + HandlerList.unregisterAll(this); + viewer.closeInventory(); + } + + this.visible = visible; + return this; + } + + @Override + public boolean isVisible() + { + return visible; + } + + @Override + public int getViewportPosition() + { + return viewportPosition; + } + + @Override + public UIWindow setViewportPosition(int viewportPosition) + { + this.viewportPosition = viewportPosition; + scroll(0); + updateInventory(); + + return this; + } + + @Override + public int getMaxViewportPosition() + { + return Math.max(0, highestRow - getViewportHeight()); + } + + @Override + public UIWindow scroll(int direction) + { + viewportPosition = (int) M.clip(viewportPosition + direction, 0, getMaxViewportPosition()); + updateInventory(); + + return this; + } + + @Override + public int getViewportHeight() + { + return viewportSize; + } + + @Override + public UIWindow setViewportHeight(int height) + { + viewportSize = (int) M.clip(height, 1, getResolution().getMaxHeight()); + + if(isVisible()) + { + reopen(); + } + + return this; + } + + @Override + public String getTitle() + { + return title; + } + + @Override + public UIWindow setTitle(String title) + { + this.title = title; + + if(isVisible()) + { + reopen(); + } + + return this; + } + + @Override + public UIWindow setElement(int position, int row, Element e) + { + if(row > highestRow) + { + highestRow = row; + } + + elements.put(getRealPosition((int) M.clip(position, -getResolution().getMaxWidthOffset(), getResolution().getMaxWidthOffset()), row), e); + updateInventory(); + return this; + } + + @Override + public Element getElement(int position, int row) + { + return elements.get(getRealPosition((int) M.clip(position, -getResolution().getMaxWidthOffset(), getResolution().getMaxWidthOffset()), row)); + } + + @Override + public Player getViewer() + { + return viewer; + } + + @Override + public UIWindow onClosed(Callback window) + { + eClose = window; + return this; + } + + @Override + public int getViewportSlots() + { + return getViewportHeight() * getResolution().getWidth(); + } + + @Override + public int getLayoutRow(int viewportSlottedPosition) + { + return getRow(getRealLayoutPosition(viewportSlottedPosition)); + } + + @Override + public int getLayoutPosition(int viewportSlottedPosition) + { + return getPosition(viewportSlottedPosition); + } + + @Override + public int getRealLayoutPosition(int viewportSlottedPosition) + { + return getRealPosition(getPosition(viewportSlottedPosition), getRow(viewportSlottedPosition) + getViewportPosition()); + } + + @Override + public int getRealPosition(int position, int row) + { + return (int) (((row * getResolution().getWidth()) + getResolution().getMaxWidthOffset()) + M.clip(position, -getResolution().getMaxWidthOffset(), getResolution().getMaxWidthOffset())); + } + + @Override + public int getRow(int realPosition) + { + return realPosition / getResolution().getWidth(); + } + + @Override + public int getPosition(int realPosition) + { + return (realPosition % getResolution().getWidth()) - getResolution().getMaxWidthOffset(); + } + + @Override + public Window callClosed() + { + if(eClose != null) + { + eClose.run(this); + } + + return this; + } + + @Override + public boolean hasElement(int position, int row) + { + return getElement(position, row) != null; + } + + @Override + public WindowResolution getResolution() + { + return resolution; + } + + @Override + public Window setResolution(WindowResolution resolution) + { + close(); + this.resolution = resolution; + setViewportHeight((int) M.clip(getViewportHeight(), 1, getResolution().getMaxHeight())); + return this; + } + + @Override + public Window clearElements() + { + highestRow = 0; + elements.clear(); + updateInventory(); + return this; + } + + @Override + public Window updateInventory() + { + if(isVisible()) + { + ItemStack[] is = inventory.getContents(); + KSet isf = new KSet(); + + for(int i = 0; i < is.length; i++) + { + ItemStack isc = is[i]; + ItemStack isx = computeItemStack(i); + int layoutRow = getLayoutRow(i); + int layoutPosition = getLayoutPosition(i); + + if(isx != null && !hasElement(layoutPosition, layoutRow)) + { + ItemStack gg = isx.clone(); + gg.setAmount(gg.getAmount() + 1); + isf.add(gg); + } + + if(((isc == null) != (isx == null)) || isx != null && isc != null && !isc.equals(isx)) + { + inventory.setItem(i, isx); + } + } + } + + return this; + } + + @Override + public ItemStack computeItemStack(int viewportSlot) + { + int layoutRow = getLayoutRow(viewportSlot); + int layoutPosition = getLayoutPosition(viewportSlot); + Element e = hasElement(layoutPosition, layoutRow) ? getElement(layoutPosition, layoutRow) : getDecorator().onDecorateBackground(this, layoutPosition, layoutRow); + + if(e != null) + { + return e.computeItemStack(); + } + + return null; + } + + @Override + public Window reopen() + { + return this.close().open(); + } +} diff --git a/src/main/java/com/volmit/iris/util/inventory/Window.java b/src/main/java/com/volmit/iris/util/inventory/Window.java new file mode 100644 index 000000000..8352d4f13 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/Window.java @@ -0,0 +1,73 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public interface Window +{ + public Window setDecorator(WindowDecorator decorator); + + public WindowDecorator getDecorator(); + + public WindowResolution getResolution(); + + public Window setResolution(WindowResolution resolution); + + public Window clearElements(); + + public Window close(); + + public Window open(); + + public Window callClosed(); + + public Window updateInventory(); + + public Window setVisible(boolean visible); + + public ItemStack computeItemStack(int viewportSlot); + + public int getLayoutRow(int viewportSlottedPosition); + + public int getLayoutPosition(int viewportSlottedPosition); + + public int getRealLayoutPosition(int viewportSlottedPosition); + + public int getRealPosition(int position, int row); + + public int getRow(int realPosition); + + public int getPosition(int realPosition); + + public boolean isVisible(); + + public int getViewportPosition(); + + public int getViewportSlots(); + + public Window setViewportPosition(int position); + + public int getMaxViewportPosition(); + + public Window scroll(int direction); + + public int getViewportHeight(); + + public Window setViewportHeight(int height); + + public String getTitle(); + + public Window setTitle(String title); + + public boolean hasElement(int position, int row); + + public Window setElement(int position, int row, Element e); + + public Element getElement(int position, int row); + + public Player getViewer(); + + public Window reopen(); + + public Window onClosed(Callback window); +} diff --git a/src/main/java/com/volmit/iris/util/inventory/WindowDecorator.java b/src/main/java/com/volmit/iris/util/inventory/WindowDecorator.java new file mode 100644 index 000000000..85981dd66 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/WindowDecorator.java @@ -0,0 +1,6 @@ +package com.volmit.iris.util.inventory; + +public interface WindowDecorator +{ + public Element onDecorateBackground(Window window, int position, int row); +} diff --git a/src/main/java/com/volmit/iris/util/inventory/WindowResolution.java b/src/main/java/com/volmit/iris/util/inventory/WindowResolution.java new file mode 100644 index 000000000..b5bf1f991 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/inventory/WindowResolution.java @@ -0,0 +1,41 @@ +package com.volmit.iris.util.inventory; + +import org.bukkit.event.inventory.InventoryType; + +public enum WindowResolution +{ + W9_H6(9, 6, InventoryType.CHEST), + W5_H1(5, 1, InventoryType.HOPPER), + W3_H3(3, 3, InventoryType.DROPPER); + + private int width; + private int maxHeight; + private InventoryType type; + + private WindowResolution(int w, int h, InventoryType type) + { + this.width = w; + this.maxHeight = h; + this.type = type; + } + + public int getMaxWidthOffset() + { + return (getWidth() - 1) / 2; + } + + public int getWidth() + { + return width; + } + + public int getMaxHeight() + { + return maxHeight; + } + + public InventoryType getType() + { + return type; + } +}