diff --git a/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java b/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java deleted file mode 100644 index 099c96f..0000000 --- a/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.world; - -import org.bukkit.Material; - -public class TNTSimulator_12 { - - public static Material active() { - return Material.CONCRETE; - } - - public static Material notActive() { - return Material.CONCRETE; - } - -} diff --git a/BauSystem_15/src/de/steamwar/bausystem/world/TNTSimulator_15.java b/BauSystem_15/src/de/steamwar/bausystem/world/TNTSimulator_15.java deleted file mode 100644 index 8fea70d..0000000 --- a/BauSystem_15/src/de/steamwar/bausystem/world/TNTSimulator_15.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bausystem.world; - -import org.bukkit.Material; - -public class TNTSimulator_15 { - - public static Material active() { - return Material.LIME_CONCRETE; - } - - public static Material notActive() { - return Material.RED_CONCRETE; - } - -} diff --git a/BauSystem_API/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java b/BauSystem_API/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java index dcad8cc..1df4d96 100644 --- a/BauSystem_API/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java +++ b/BauSystem_API/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.tracer; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public interface AbstractTraceEntity { @@ -27,4 +28,7 @@ public interface AbstractTraceEntity { boolean hide(Player player, boolean always); + int getId(); + + Entity getBukkitEntity(); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index 829132c..30672b8 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -107,11 +107,13 @@ public class BauSystem extends JavaPlugin implements Listener { Bukkit.getPluginManager().registerEvents(new ScriptListener(), this); Bukkit.getPluginManager().registerEvents(new BauScoreboard(), this); Bukkit.getPluginManager().registerEvents(new ClipboardListener(), this); - Bukkit.getPluginManager().registerEvents(new TNTSimulatorListener(), this); Bukkit.getPluginManager().registerEvents(new CommandGUI(), this); Bukkit.getPluginManager().registerEvents(new DetonatorListener(), this); Bukkit.getPluginManager().registerEvents(new ItemFrameListener(), this); - VersionedRunnable.call(new VersionedRunnable(() -> Bukkit.getPluginManager().registerEvents(new RedstoneListener(), this), 15)); + VersionedRunnable.call(new VersionedRunnable(() -> { + Bukkit.getPluginManager().registerEvents(new RedstoneListener(), this); + Bukkit.getPluginManager().registerEvents(new TNTSimulatorListener(), this); + }, 15)); new AFKStopper(); autoShutdown = Bukkit.getScheduler().runTaskLater(this, Bukkit::shutdown, 1200); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java index 17947a5..601ec3b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java @@ -26,52 +26,54 @@ import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.world.TNTSimulator; import de.steamwar.bausystem.world.Welt; import de.steamwar.command.SWCommand; +import de.steamwar.core.Core; import org.bukkit.entity.Player; public class CommandSimulator extends SWCommand { public CommandSimulator() { super("simulator", "sim"); + if(Core.getVersion() < 15) + unregister(); } @Register(help = true) public void genericHelp(Player p, String... args) { - p.sendMessage("§8/§esimulator §8- §7Öffnet die Simulations GUI"); + p.sendMessage("§8/§esimulator §8- §7Legt dir den Simulatorstab ins Inventar"); p.sendMessage("§8/§esimulator start §8- §7Startet die Simulation"); - p.sendMessage("§8/§esimulator wand §8- §7Legt dir den Simulatorstab ins Inventar"); p.sendMessage("§8/§esimulator delete §8- §7Löscht alle TNT"); } @Register public void genericCommand(Player p) { - if (!permissionCheck(p)) return; - TNTSimulator.openSimulator(p); - } - - @Register({"wand"}) - public void wandCommand(Player p) { - if (!permissionCheck(p)) return; + if (cannotUse(p)) return; SWUtils.giveItemToPlayer(p, TNTSimulator.WAND); } @Register({"start"}) public void startCommand(Player p) { - if (!permissionCheck(p)) return; + if (cannotUse(p)) return; TNTSimulator.get(p).start(); } + @Register({"gui"}) + public void guiCommand(Player p) { + if (cannotUse(p)) return; + TNTSimulator.get(p).showGUI(); + } + @Register({"delete"}) public void deleteCommand(Player p) { - if (!permissionCheck(p)) return; + if (cannotUse(p)) return; TNTSimulator.get(p).delete(); } - private boolean permissionCheck(Player player) { + private boolean cannotUse(Player player) { if (Welt.noPermission(player, Permission.WORLD)) { player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Simulator nutzen"); - return false; + return true; } - return true; + return false; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java index bd7e8d7..892a776 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java @@ -67,12 +67,12 @@ public class EntityShowMode implements ShowMode { } RoundedTNTPosition roundedTNTPosition = new RoundedTNTPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedTNTPosition, pos -> createEntity(position.getLocation(), true)); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedTNTPosition, pos -> createEntity(player, position.getLocation(), true)); entity.display(player, position.isExploded()); applyOnPosition(position, updatePointPosition -> { updateEntityMap.computeIfAbsent(new RoundedTNTPosition(updatePointPosition), pos -> { - return createEntity(updatePointPosition, false); + return createEntity(player, updatePointPosition, false); }).display(player, position.isExploded()); }); } @@ -82,7 +82,7 @@ public class EntityShowMode implements ShowMode { new VersionedCallable<>(() -> TNTTracer_15.inWater(player.getWorld(), position), 14)); } - private AbstractTraceEntity createEntity(Vector position, boolean tnt) { + public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_12.create(player.getWorld(), position, tnt), 8), new VersionedCallable<>(() -> TNTTracer_15.create(player.getWorld(), position, tnt), 14)); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java index 1eaa634..0b5ed01 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java @@ -22,301 +22,114 @@ package de.steamwar.bausystem.world; import de.steamwar.bausystem.BauSystem; -import de.steamwar.core.VersionedCallable; +import de.steamwar.bausystem.tracer.AbstractTraceEntity; +import de.steamwar.bausystem.tracer.show.mode.EntityShowMode; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import de.steamwar.inventory.SWListInv; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Consumer; +import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class TNTSimulator { - private static final Vector X_VECTOR = new Vector(0.0625, 0, 0); - private static final Vector NX_VECTOR = new Vector(-0.0625, 0, 0); - private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0); - private static final Vector NY_VECTOR = new Vector(0, -0.0625, 0); - private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625); - private static final Vector NZ_VECTOR = new Vector(0, 0, -0.0625); - private static final List LORE = Collections.singletonList("§eZum ändern klicken"); + private static final World WORLD = Bukkit.getWorlds().get(0); + private static final List LORE = Collections.singletonList("§eZum Ändern klicken"); private static final List EMPTY = new ArrayList<>(); + public static final ItemStack WAND = new SWItem(Material.BLAZE_ROD, "§eKanonensimulator", Arrays.asList("§eRechtsklick §8- §7Füge eine Position hinzu", "§eSneaken §8- §7Auf den Block zentrieren", "§eLinksklick §8- §7Starte die Simulation", "§eRechtsklick Luft §8- §7Öffne die GUI"), false, null).getItemStack(); - static final Map TNT_SIMULATOR_MAP = new HashMap<>(); - private final Set TNT_SPAWNS = new HashSet<>(); - - public static final ItemStack WAND = new SWItem(Material.BLAZE_ROD, "§eKanonensimulator", Arrays.asList("§eRechtsklick Block §8- §7Füge einen TNT hinzu", "§eRechtsklick Luft §8- §7Öffne den Simulator", "§eLinksklick §8- §7Starte die Simulation"), false, null).getItemStack(); + private static final Map TNT_SIMULATOR_MAP = new HashMap<>(); public static TNTSimulator get(Player player) { - return TNT_SIMULATOR_MAP.computeIfAbsent(player, p -> new TNTSimulator()); - } - - public static void openSimulator(Player player) { - TNTSimulator tntSimulator = get(player); - - List> swListEntryList = new ArrayList<>(); - tntSimulator.TNT_SPAWNS.forEach(tntSpawn -> { - List lore = new ArrayList<>(); - lore.add("§7Klicken zum Konfigurieren"); - lore.add(""); - lore.add("§7TNT-Anzahl§8: §e" + tntSpawn.getCount()); - lore.add("§7Tick§8: §e" + tntSpawn.getTickOffset()); - lore.add("§7Fuse-Tick§8: §e" + tntSpawn.getFuseTicks()); - lore.add(""); - lore.add("§7X§8: §e" + tntSpawn.getPosition().getX()); - lore.add("§7Y§8: §e" + tntSpawn.getPosition().getY()); - lore.add("§7Z§8: §e" + tntSpawn.getPosition().getZ()); - SWItem swItem = new SWItem(Material.TNT, "§eTNT", lore, false, null); - swItem.getItemStack().setAmount(tntSpawn.count); - swListEntryList.add(new SWListInv.SWListEntry<>(swItem, tntSpawn)); - }); - swListEntryList.sort(Comparator.comparing(SWListInv.SWListEntry::getObject)); - - SWListInv swListInv = new SWListInv<>(player, "Kanonensimulator", false, swListEntryList, (clickType, tntSpawn) -> { - editTNT(player, tntSpawn); - }); - swListInv.setItem(51, new SWItem(Material.BARRIER, "§cTNT löschen", clickType -> { - tntSimulator.TNT_SPAWNS.clear(); - openSimulator(player); - })); - swListInv.setItem(47, new SWItem(Material.FLINT_AND_STEEL, "§eStarten", clickType -> { - player.closeInventory(); - startSimulation(player); - })); - swListInv.open(); - } - - static void editTNT(Player player, TNTSpawn tntSpawn) { - TNTSimulator tntSimulator = get(player); - - SWInventory swInventory = new SWInventory(player, 54, "TNT"); - swInventory.setItem(49, new SWItem(Material.REDSTONE_BLOCK, "§cZurück", clickType -> { - openSimulator(player); - })); - - // Delete tnt - swInventory.setItem(53, new SWItem(Material.BARRIER, "§cEntfernen", clickType -> { - tntSimulator.TNT_SPAWNS.remove(tntSpawn); - openSimulator(player); - })); - - // Change Count of spawned TNT - swInventory.setItem(10, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - tntSpawn.setCount(tntSpawn.getCount() + 1); - if (tntSpawn.getCount() > 400) { - tntSpawn.setCount(400); - } - editTNT(player, tntSpawn); - })); - SWItem countItem = new SWItem(Material.TNT, "§7Anzahl §8- §e" + tntSpawn.getCount(), LORE, false, clickType -> { - changeCount(player, "Anzahl TNT", tntSpawn.getCount(), count -> { - if (count < 1) count = 1; - if (count > 400) count = 400; - tntSpawn.setCount(count); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - }); - countItem.getItemStack().setAmount(tntSpawn.getCount()); - swInventory.setItem(19, countItem); - swInventory.setItem(28, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - tntSpawn.setCount(tntSpawn.getCount() - 1); - if (tntSpawn.getCount() < 1) { - tntSpawn.setCount(1); - } - editTNT(player, tntSpawn); - })); - - // Change TickOffset - swInventory.setItem(11, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - tntSpawn.setTickOffset(tntSpawn.getTickOffset() + 1); - if (tntSpawn.getTickOffset() > 8000) { - tntSpawn.setTickOffset(8000); - } - editTNT(player, tntSpawn); - })); - SWItem tickItem = new SWItem(Material.CLOCK, "§7Tick §8- §e" + tntSpawn.getTickOffset(), LORE, false, clickType -> { - changeCount(player, "Tick Offset", tntSpawn.getTickOffset(), tick -> { - if (tick < 0) tick = 0; - if (tick > 8000) tick = 8000; - tntSpawn.setTickOffset(tick); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - }); - tickItem.getItemStack().setAmount(Math.max(tntSpawn.getTickOffset(), 1)); - swInventory.setItem(20, tickItem); - swInventory.setItem(29, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - tntSpawn.setTickOffset(tntSpawn.getTickOffset() - 1); - if (tntSpawn.getTickOffset() < 0) { - tntSpawn.setTickOffset(0); - } - editTNT(player, tntSpawn); - })); - - // Change FuseTicks - swInventory.setItem(12, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - tntSpawn.setFuseTicks(tntSpawn.getFuseTicks() + 1); - if (tntSpawn.getFuseTicks() > 80) { - tntSpawn.setFuseTicks(80); - } - editTNT(player, tntSpawn); - })); - SWItem fuseTickItem = new SWItem(Material.CLOCK, "§7Fuse-Ticks §8- §e" + tntSpawn.getFuseTicks(), LORE, false, clickType -> { - changeCount(player, "Fuse-Ticks", tntSpawn.getFuseTicks(), tick -> { - if (tick < 0) tick = 0; - if (tick > 80) tick = 80; - tntSpawn.setFuseTicks(tick); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - }); - fuseTickItem.getItemStack().setAmount(Math.max(tntSpawn.getFuseTicks(), 1)); - swInventory.setItem(21, fuseTickItem); - swInventory.setItem(30, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - tntSpawn.setFuseTicks(tntSpawn.getFuseTicks() - 1); - if (tntSpawn.getFuseTicks() < 1) { - tntSpawn.setFuseTicks(1); - } - editTNT(player, tntSpawn); - })); - - // Repeater before Comparator - swInventory.setItem(4, new SWItem(comparatorOrNot(tntSpawn.isComparator()), "§7Gezündet durch §8- §e" + (tntSpawn.isComparator() ? "Comparator" : "Repeater"), clickType -> { - tntSpawn.setComparator(!tntSpawn.isComparator()); - editTNT(player, tntSpawn); - })); - - // Velocity Settings - swInventory.setItem(13, new SWItem(activeOrNot(tntSpawn.isxVelocity()), "§7TNT §eSprung X §8- " + active(tntSpawn.isxVelocity()), clickType -> { - tntSpawn.setxVelocity(!tntSpawn.isxVelocity()); - editTNT(player, tntSpawn); - })); - swInventory.setItem(22, new SWItem(activeOrNot(tntSpawn.isyVelocity()), "§7TNT §eSprung Y §8- " + active(tntSpawn.isyVelocity()), clickType -> { - tntSpawn.setyVelocity(!tntSpawn.isyVelocity()); - editTNT(player, tntSpawn); - })); - swInventory.setItem(31, new SWItem(activeOrNot(tntSpawn.iszVelocity()), "§7TNT §eSprung Z §8- " + active(tntSpawn.iszVelocity()), clickType -> { - tntSpawn.setzVelocity(!tntSpawn.iszVelocity()); - editTNT(player, tntSpawn); - })); - - // X Position - swInventory.setItem(14, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - tntSpawn.getPosition().add(X_VECTOR); - editTNT(player, tntSpawn); - })); - swInventory.setItem(23, new SWItem(Material.PAPER, "§7x-Position §8- §e" + tntSpawn.getPosition().getX(), LORE, false, clickType -> { - changePosition(player, tntSpawn.getPosition().getX(), x -> { - tntSpawn.getPosition().setX(clamp(x)); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - })); - swInventory.setItem(32, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - tntSpawn.getPosition().add(NX_VECTOR); - editTNT(player, tntSpawn); - })); - - // Y Position - swInventory.setItem(15, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - tntSpawn.getPosition().add(Y_VECTOR); - editTNT(player, tntSpawn); - })); - swInventory.setItem(24, new SWItem(Material.PAPER, "§7y-Position §8- §e" + tntSpawn.getPosition().getY(), LORE, false, clickType -> { - changePosition(player, tntSpawn.getPosition().getY(), y -> { - tntSpawn.getPosition().setY(clamp(y)); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - })); - swInventory.setItem(33, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - tntSpawn.getPosition().add(NY_VECTOR); - editTNT(player, tntSpawn); - })); - - // Z Position - swInventory.setItem(16, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - tntSpawn.getPosition().add(Z_VECTOR); - editTNT(player, tntSpawn); - })); - swInventory.setItem(25, new SWItem(Material.PAPER, "§7z-Position §8- §e" + tntSpawn.getPosition().getZ(), LORE, false, clickType -> { - changePosition(player, tntSpawn.getPosition().getZ(), z -> { - tntSpawn.getPosition().setZ(clamp(z)); - editTNT(player, tntSpawn); - }, () -> editTNT(player, tntSpawn)); - })); - swInventory.setItem(34, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - tntSpawn.getPosition().add(NZ_VECTOR); - editTNT(player, tntSpawn); - })); - swInventory.open(); - } - - static void startSimulation(Player player) { - TNT_SIMULATOR_MAP.getOrDefault(player, new TNTSimulator()).start(); - } - - static void addTNT(Player player, TNTSpawn tntSpawn) { - TNTSimulator tntSimulator = TNT_SIMULATOR_MAP.computeIfAbsent(player, player1 -> new TNTSimulator()); - tntSimulator.TNT_SPAWNS.add(tntSpawn); - } - - private static Material comparatorOrNot(boolean b) { - if (b) { - return SWItem.getMaterial("REDSTONE_COMPARATOR"); - } else { - return SWItem.getMaterial("DIODE"); - } - } - - private static Material activeOrNot(boolean b) { - if (b) { - return VersionedCallable.call(new VersionedCallable<>(TNTSimulator_12::active, 8), new VersionedCallable<>(TNTSimulator_15::active, 14)); - } else { - return VersionedCallable.call(new VersionedCallable<>(TNTSimulator_12::notActive, 8), new VersionedCallable<>(TNTSimulator_15::notActive, 14)); - } - } - - private static String active(boolean b) { - return b ? "§aan" : "§caus"; - } - - private static void changeCount(Player player, String name, int defaultValue, Consumer result, Runnable failure) { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - try { - result.accept(Integer.parseInt(s)); - } catch (NumberFormatException e) { - failure.run(); - } - }); - swAnvilInv.open(); - } - - private static void changePosition(Player player, double defaultValue, Consumer result, Runnable failure) { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Position", defaultValue + ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - try { - result.accept(Double.parseDouble(s.replace(',', '.'))); - } catch (NumberFormatException e) { - failure.run(); - } - }); - swAnvilInv.open(); - } - - private static double clamp(double d) { - return (int) (d * 10000) * 0.0001; + return TNT_SIMULATOR_MAP.computeIfAbsent(player, p -> new TNTSimulator(player)); } public void delete() { - TNT_SPAWNS.clear(); + TNTSimulator simulator = TNT_SIMULATOR_MAP.remove(player); + simulator.hide(); + } + + private final Set spawns = new HashSet<>(); + private final Player player; + + private AbstractTraceEntity cursor = null; + private boolean printed = false; + + private TNTSimulator(Player player){ + this.player = player; + } + + public List getEntities(){ + return spawns.stream().map(spawn -> spawn.entity.getBukkitEntity()).collect(Collectors.toList()); + } + + public void show(RayTraceResult result){ + printed = true; + + if(cursor != null) + cursor.hide(player, false); + + spawns.forEach(TNTSpawn::show); + + if(result == null) + return; + + if(result.getHitEntity() != null){ + TNTSpawn entity = getEntity(result.getHitEntity()); + entity.hide(); + + cursor = EntityShowMode.createEntity(player, entity.position, false); + cursor.display(player, false); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§ePosition bearbeiten")); + return; + } + + cursor = EntityShowMode.createEntity(player, getPos(result), true); + cursor.display(player, false); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§ePosition setzen")); + } + + public void edit(RayTraceResult result){ + if(result == null) { + showGUI(); + return; + } + + show(result); + + if(result.getHitEntity() != null){ + TNTSpawn entity = getEntity(result.getHitEntity()); + entity.editTNT(); + return; + } + + spawns.add(new TNTSpawn(getPos(result), cursor)); + } + + public void hide(){ + if(!printed) + return; + + printed = false; + if(cursor != null) + cursor.hide(player, true); + cursor = null; + spawns.forEach(TNTSpawn::hide); } public void start() { @@ -324,9 +137,9 @@ public class TNTSimulator { Map> second = new HashMap<>(); int lastTick = 0; - for (TNTSpawn tntSpawn : TNT_SPAWNS) { - Map> list = tntSpawn.isComparator() ? second : first; - for (int i = 0; i < tntSpawn.getCount(); i++) { + for (TNTSpawn tntSpawn : spawns) { + Map> list = tntSpawn.comparator ? second : first; + for (int i = 0; i < tntSpawn.count; i++) { list.computeIfAbsent(tntSpawn.getTickOffset(), integer -> new ArrayList<>()).add(tntSpawn); } if (lastTick < tntSpawn.getTickOffset()) { @@ -345,6 +158,41 @@ public class TNTSimulator { }, 1, 1); } + public void showGUI() { + List> swListEntryList = spawns.stream().map(spawn -> { + List lore = new ArrayList<>(); + lore.add("§7TNT-Anzahl§8: §e" + spawn.count); + lore.add("§7Tick§8: §e" + spawn.tickOffset); + lore.add("§7Fuse-Tick§8: §e" + spawn.fuseTicks); + lore.add(""); + lore.add("§7x§8: §e" + spawn.position.getX()); + lore.add("§7y§8: §e" + spawn.position.getY()); + lore.add("§7z§8: §e" + spawn.position.getZ()); + SWItem swItem = new SWItem(Material.TNT, "§eTNT", lore, false, null); + swItem.getItemStack().setAmount(spawn.count); + return new SWListInv.SWListEntry<>(swItem, spawn); + }).sorted(Comparator.comparing(SWListInv.SWListEntry::getObject)).collect(Collectors.toList()); + + SWListInv swListInv = new SWListInv<>(player, "Kanonensimulator", false, swListEntryList, (clickType, spawn) -> spawn.editTNT()); + swListInv.setItem(51, new SWItem(Material.BARRIER, "§cTNT löschen", clickType -> { + delete(); + player.closeInventory(); + })); + swListInv.setItem(47, new SWItem(Material.FLINT_AND_STEEL, "§eStarten", clickType -> { + start(); + player.closeInventory(); + })); + swListInv.open(); + } + + private TNTSpawn getEntity(Entity entity){ + for(TNTSpawn spawn : spawns){ + if(spawn.entity.getId() == entity.getEntityId()) + return spawn; + } + throw new IllegalStateException(); + } + private void spawnRandomList(List tntSpawns) { if (tntSpawns.isEmpty()) return; Collections.shuffle(tntSpawns); @@ -353,24 +201,82 @@ public class TNTSimulator { } } - public static class TNTSpawn implements Comparable { + private Vector getPos(RayTraceResult result){ + Vector pos = result.getHitPosition(); - private static final World WORLD = Bukkit.getWorlds().get(0); + BlockFace face = result.getHitBlockFace(); + if(face != null){ + switch (face) { + case DOWN: + pos.setY(pos.getY() - 0.98); + break; + case EAST: + pos.setX(pos.getX() + 0.49); + break; + case WEST: + pos.setX(pos.getX() - 0.49); + break; + case NORTH: + pos.setZ(pos.getZ() - 0.49); + break; + case SOUTH: + pos.setZ(pos.getZ() + 0.49); + break; + default: + break; + } + + if(face.getModY() == 0 && !player.isSneaking()){ + pos.setY(pos.getY() - 0.49); + } + } + + if(player.isSneaking()){ + pos.setX(pos.getBlockX() + 0.5); + if(face == null || face.getModY() == 0) + pos.setY(pos.getBlockY() + 0.0); + pos.setZ(pos.getBlockZ() + 0.5); + } + + return pos; + } + + private class TNTSpawn implements Comparable { + + private final AbstractTraceEntity entity; + private boolean printed = false; private final Vector position; private int fuseTicks = 80; private int count = 1; private int tickOffset = 0; - private boolean xVelocity = true; - private boolean yVelocity = true; - private boolean zVelocity = true; + private boolean xVelocity = false; + private boolean yVelocity = false; + private boolean zVelocity = false; private boolean comparator = false; - public TNTSpawn(Vector position) { + private TNTSpawn(Vector position, AbstractTraceEntity entity) { this.position = position; + this.entity = entity; + show(); + editTNT(); } - public void spawn() { + private void show(){ + if(printed) + return; + printed = true; + entity.display(player, false); + } + + private void hide(){ + if(!printed) + return; + printed = false; + entity.hide(player, false); + } + + private void spawn() { WORLD.spawn(position.toLocation(WORLD), TNTPrimed.class, tntPrimed -> { tntPrimed.setFuseTicks(fuseTicks); if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0)); @@ -379,71 +285,144 @@ public class TNTSimulator { }); } - public Vector getPosition() { - return position; - } - - public int getFuseTicks() { - return fuseTicks; - } - - public void setFuseTicks(int fuseTicks) { + private void setFuseTicks(int fuseTicks) { + if (fuseTicks < 0) + fuseTicks = 0; + if (fuseTicks > 80) + fuseTicks = 80; this.fuseTicks = fuseTicks; } - public int getCount() { - return count; - } - - public void setCount(int count) { + private void setCount(int count) { + if(count < 1) + count = 1; + if(count > 400) + count = 400; this.count = count; } - public int getTickOffset() { + private int getTickOffset() { return tickOffset; } - public void setTickOffset(int tickOffset) { + private void setTickOffset(int tickOffset) { + if(tickOffset < 0) + tickOffset = 0; + if(tickOffset > 400) + tickOffset = 400; this.tickOffset = tickOffset; } - public boolean isxVelocity() { - return xVelocity; - } - - public void setxVelocity(boolean xVelocity) { - this.xVelocity = xVelocity; - } - - public boolean isyVelocity() { - return yVelocity; - } - - public void setyVelocity(boolean yVelocity) { - this.yVelocity = yVelocity; - } - - public boolean iszVelocity() { - return zVelocity; - } - - public void setzVelocity(boolean zVelocity) { - this.zVelocity = zVelocity; - } - - public boolean isComparator() { - return comparator; - } - - public void setComparator(boolean comparator) { - this.comparator = comparator; - } - @Override public int compareTo(TNTSpawn tntSpawn) { return -Integer.compare(tickOffset, tntSpawn.tickOffset); } - } + private void editTNT() { + SWInventory swInventory = new SWInventory(player, 27, "TNT konfigurieren"); + // Change Count of spawned TNT + swInventory.setItem(0, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setCount(count + 1); + editTNT(); + })); + SWItem countItem = new SWItem(Material.TNT, "§7TNT-Anzahl §8- §e" + count, LORE, false, clickType -> changeCount(player, "Anzahl TNT", count, c -> { + setCount(c); + editTNT(); + }, this::editTNT)); + countItem.getItemStack().setAmount(count); + swInventory.setItem(9, countItem); + swInventory.setItem(18, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setCount(count - 1); + editTNT(); + })); + + // Change TickOffset + swInventory.setItem(1, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setTickOffset(tickOffset + 1); + editTNT(); + })); + SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), "§7Tick §8- §e" + tickOffset, LORE, false, clickType -> changeCount(player, "Tick Offset", tickOffset, tick -> { + setTickOffset(tick); + editTNT(); + }, this::editTNT)); + tickItem.getItemStack().setAmount(Math.max(tickOffset, 1)); + swInventory.setItem(10, tickItem); + swInventory.setItem(19, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setTickOffset(tickOffset - 1); + editTNT(); + })); + + // Change FuseTicks + swInventory.setItem(2, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { + setFuseTicks(fuseTicks + 1); + editTNT(); + })); + SWItem fuseTickItem = new SWItem(Material.CLOCK, "§7Lebensdauer §8- §e" + fuseTicks, LORE, false, clickType -> changeCount(player, "Fuse-Ticks", fuseTicks, tick -> { + setFuseTicks(tick); + editTNT(); + }, this::editTNT)); + fuseTickItem.getItemStack().setAmount(Math.max(fuseTicks, 1)); + swInventory.setItem(11, fuseTickItem); + swInventory.setItem(20, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { + setFuseTicks(fuseTicks - 1); + editTNT(); + })); + + // Velocity Settings + swInventory.setItem(14, Material.TNT, "TNT", clickType -> {}); + swInventory.setItem(22, new SWItem(getDye(xVelocity), getColor(xVelocity), "§7TNT §eSprung X §8- " + active(xVelocity), clickType -> { + xVelocity = !xVelocity; + editTNT(); + })); + swInventory.setItem(5, new SWItem(getDye(yVelocity), getColor(yVelocity), "§7TNT §eSprung Y §8- " + active(yVelocity), clickType -> { + yVelocity = !yVelocity; + editTNT(); + })); + swInventory.setItem(24, new SWItem(getDye(zVelocity), getColor(zVelocity), "§7TNT §eSprung Z §8- " + active(zVelocity), clickType -> { + zVelocity = !zVelocity; + editTNT(); + })); + + // Repeater before Comparator + swInventory.setItem(8, new SWItem(comparator ? SWItem.getMaterial("REDSTONE_COMPARATOR_OFF") : SWItem.getMaterial("DIODE"), "§7Gezündet durch §8- §e" + (comparator ? "Comparator" : "Repeater"), clickType -> { + comparator = !comparator; + editTNT(); + })); + + // Delete tnt + swInventory.setItem(26, new SWItem(Material.BARRIER, "§cEntfernen", clickType -> { + hide(); + spawns.remove(this); + player.closeInventory(); + })); + + swInventory.open(); + } + + private void changeCount(Player player, String name, int defaultValue, Consumer result, Runnable failure) { + SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + ""); + swAnvilInv.setItem(Material.PAPER); + swAnvilInv.setCallback(s -> { + try { + result.accept(Integer.parseInt(s)); + } catch (NumberFormatException e) { + failure.run(); + } + }); + swAnvilInv.open(); + } + + private Material getDye(boolean b) { + return SWItem.getDye(getColor(b)); + } + + private byte getColor(boolean b) { + return (byte) (b ? 10 : 1); + } + + private String active(boolean b) { + return b ? "§aan" : "§caus"; + } + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java index 2a11d53..7250035 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java @@ -23,20 +23,23 @@ package de.steamwar.bausystem.world; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; -import org.bukkit.block.BlockFace; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; import static de.steamwar.bausystem.world.TNTSimulator.*; public class TNTSimulatorListener implements Listener { - private static final Vector HALF = new Vector(0.5, 0, 0.5); - private boolean permissionCheck(Player player) { if (Welt.noPermission(player, Permission.WORLD)) { player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Simulator nutzen"); @@ -45,14 +48,58 @@ public class TNTSimulatorListener implements Listener { return true; } + private RayTraceResult trace(Player player, Location to){ + Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0); + Vector direction = to.getDirection(); + RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true); + + Entity nearestHitEntity = null; + RayTraceResult nearestHitResult = null; + double nearestDistanceSq = Double.MAX_VALUE; + for(Entity entity : get(player).getEntities()) { + BoundingBox boundingBox = entity.getBoundingBox(); + RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0); + if (hitResult != null) { + double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition()); + if (distanceSq < nearestDistanceSq) { + nearestHitEntity = entity; + nearestHitResult = hitResult; + nearestDistanceSq = distanceSq; + } + } + } + RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace()); + + if (blocks == null) { + return entities; + } else if (entities == null) { + return blocks; + } else { + Vector startVec = startPos.toVector(); + double blockHitDistance = startVec.distance(blocks.getHitPosition()); + double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition()); + return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks; + } + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent e){ + Player player = e.getPlayer(); + TNTSimulator simulator = get(player); + if(!player.getInventory().getItemInMainHand().isSimilar(WAND)){ + simulator.hide(); + return; + } + + simulator.show(trace(player, e.getTo())); + } + @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getItem() == null) { - return; - } - if (!event.getItem().isSimilar(WAND)) { + if (event.getItem() == null || !event.getItem().isSimilar(WAND)) { return; } + event.setCancelled(true); if (!permissionCheck(event.getPlayer())) { return; @@ -61,21 +108,11 @@ public class TNTSimulatorListener implements Listener { switch (event.getAction()) { case LEFT_CLICK_BLOCK: case LEFT_CLICK_AIR: - startSimulation(event.getPlayer()); + get(event.getPlayer()).start(); break; case RIGHT_CLICK_BLOCK: - BlockFace blockFace = event.getBlockFace(); - Vector direction = new Vector(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ()); - if (blockFace.getModX() != 0 || blockFace.getModY() != 0 || blockFace.getModZ() != 0) { - direction.normalize(); - } - Vector location = event.getClickedBlock().getLocation().toVector().add(direction).add(HALF); - TNTSpawn tntSpawn = new TNTSpawn(location); - addTNT(event.getPlayer(), tntSpawn); - editTNT(event.getPlayer(), tntSpawn); - break; case RIGHT_CLICK_AIR: - openSimulator(event.getPlayer()); + get(event.getPlayer()).edit(trace(event.getPlayer(), event.getPlayer().getLocation())); break; default: break; @@ -84,7 +121,7 @@ public class TNTSimulatorListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - TNT_SIMULATOR_MAP.remove(event.getPlayer()); + get(event.getPlayer()).delete(); } }