diff --git a/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java b/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java new file mode 100644 index 0000000..099c96f --- /dev/null +++ b/BauSystem_12/src/de/steamwar/bausystem/world/TNTSimulator_12.java @@ -0,0 +1,34 @@ +/* + * 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 new file mode 100644 index 0000000..8fea70d --- /dev/null +++ b/BauSystem_15/src/de/steamwar/bausystem/world/TNTSimulator_15.java @@ -0,0 +1,35 @@ +/* + * + * 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_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index cef05e9..dd1817f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -97,6 +97,8 @@ public class BauSystem extends JavaPlugin implements Listener { getCommand("detonator").setExecutor(new CommandDetonator()); getCommand("detonator").setTabCompleter(new CommandDetonatorTabCompleter()); getCommand("script").setExecutor(new CommandScript()); + getCommand("simulator").setExecutor(new CommandSimulator()); + getCommand("simulator").setTabCompleter(new CommandSimulatorTabCompleter()); getCommand("gui").setExecutor(new CommandGUI()); Bukkit.getPluginManager().registerEvents(this, this); @@ -104,6 +106,7 @@ 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); new AFKStopper(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java index be01a34..5576d67 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandGUI.java @@ -55,8 +55,6 @@ public class CommandGUI implements CommandExecutor, Listener { inv.setItem(37, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { }); - inv.setItem(38, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { - }); inv.setItem(43, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { }); inv.setItem(42, Material.NETHER_STAR, "§7Bau GUI Item", Arrays.asList("§7Du kannst dieses Item zum Öffnen der BauGUI nutzen", "§7oder Doppel F (Swap hands) drücken."), false, clickType -> { @@ -64,14 +62,7 @@ public class CommandGUI implements CommandExecutor, Listener { player.performCommand("gui item"); }); - ItemStack dtWand = Detonator.WAND.clone(); - ItemMeta meta = dtWand.getItemMeta(); - List lore = meta.getLore(); - lore.add("§8/§7dt wand"); - if (Welt.noPermission(player, Permission.world)) - lore.add("§cDu hast keine Worldrechte"); - meta.setLore(lore); - dtWand.setItemMeta(meta); + ItemStack dtWand = wand(player, Detonator.WAND, "§8/§7dt wand", Permission.world, "§cDu hast keine Worldrechte"); inv.setItem(39, dtWand, clickType -> { if (Welt.noPermission(player, Permission.world)) return; @@ -79,6 +70,14 @@ public class CommandGUI implements CommandExecutor, Listener { player.performCommand("dt wand"); }); + ItemStack simWand = wand(player, TNTSimulator.WAND, "§8/§7sim wand", Permission.world, "§cDu hast keine Worldrechte"); + inv.setItem(38, simWand, clickType -> { + if (Welt.noPermission(player, Permission.world)) + return; + player.closeInventory(); + player.performCommand("sim wand"); + }); + inv.setItem(40, getMaterial("WOODEN_AXE", "WOOD_AXE"), "§eWorldedit Axt", getNoPermsLore(Arrays.asList("§8//§7wand"), player, "§cDu hast keine Worldeditrechte", Permission.worldedit), false, clickType -> { if (Welt.noPermission(player, Permission.world)) return; @@ -567,6 +566,18 @@ public class CommandGUI implements CommandExecutor, Listener { return null; } + private static ItemStack wand(Player player, ItemStack base, String command, Permission permission, String noPermissionMessage) { + base = base.clone(); + ItemMeta meta = base.getItemMeta(); + List lore = meta.getLore(); + lore.add(command); + if (Welt.noPermission(player, permission)) + lore.add(noPermissionMessage); + meta.setLore(lore); + base.setItemMeta(meta); + return base; + } + @Override public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { if (!(commandSender instanceof Player)) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java new file mode 100644 index 0000000..325f1a3 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java @@ -0,0 +1,79 @@ +/* + * + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.PlayerUtils; +import de.steamwar.bausystem.world.TNTSimulator; +import de.steamwar.bausystem.world.Welt; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class CommandSimulator implements CommandExecutor { + + private void help(Player player) { + player.sendMessage("§8/§esimulator §8- §7Öffnet die Simulations GUI"); + player.sendMessage("§8/§esimulator start §8- §7Startet die Simulation"); + player.sendMessage("§8/§esimulator wand §8- §7Legt dir den Simulatorstab ins Inventar"); + player.sendMessage("§8/§esimulator delete §8- §7Löscht alle TNT"); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.world)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Simulator nutzen"); + return false; + } + return true; + } + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { + if (!(commandSender instanceof Player)) + return false; + Player player = (Player) commandSender; + if (!permissionCheck(player)) { + return false; + } + + if (args.length == 1) { + switch (args[0].toLowerCase()) { + case "wand": + PlayerUtils.giveItemToPlayer(player, TNTSimulator.WAND); + break; + case "start": + TNTSimulator.get(player).start(); + break; + case "delete": + TNTSimulator.get(player).delete(); + default: + help(player); + break; + } + return false; + } + TNTSimulator.openSimulator(player); + return false; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulatorTabCompleter.java b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulatorTabCompleter.java new file mode 100644 index 0000000..0103d30 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulatorTabCompleter.java @@ -0,0 +1,60 @@ +/* + * + * 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.commands; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class CommandSimulatorTabCompleter implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + if(!(sender instanceof Player)) return new ArrayList<>(); + return simulatorTabComplete((Player) sender, args); + } + + private List simulatorTabComplete(Player player, String[] args) { + List tabComplete = new ArrayList<>(); + tabComplete.add("wand"); + tabComplete.add("start"); + tabComplete.add("delete"); + + if (args.length >= 2) { + return new ArrayList<>(); + } + return manageList(tabComplete, args, 0); + } + + private List manageList(List strings, String[] args, int index) { + for (int i = strings.size() - 1; i >= 0; i--) { + if (!strings.get(i).startsWith(args[index])) { + strings.remove(i); + } + } + return strings; + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java new file mode 100644 index 0000000..7a9fb2d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulator.java @@ -0,0 +1,441 @@ +/* + * + * 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 de.steamwar.bausystem.BauSystem; +import de.steamwar.core.VersionedCallable; +import de.steamwar.inventory.SWAnvilInv; +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import de.steamwar.inventory.SWListInv; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Consumer; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +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 List EMPTY = new ArrayList<>(); + + 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(); + + 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()); + swListEntryList.add(new SWListInv.SWListEntry<>(new SWItem(Material.TNT, "§eTNT", lore, false, null), 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); + })); + swInventory.setItem(19, 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)); + })); + 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); + })); + swInventory.setItem(20, 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)); + })); + 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); + })); + swInventory.setItem(21, 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)); + })); + 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; + } + + public void delete() { + TNT_SPAWNS.clear(); + } + + public void start() { + Map> first = new HashMap<>(); + 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++) { + list.computeIfAbsent(tntSpawn.getTickOffset(), integer -> new ArrayList<>()).add(tntSpawn); + } + if (lastTick < tntSpawn.getTickOffset()) { + lastTick = tntSpawn.getTickOffset(); + } + } + int finalLastTick = lastTick; + + AtomicInteger currentTick = new AtomicInteger(0); + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), bukkitTask -> { + int tick = currentTick.get(); + spawnRandomList(first.getOrDefault(tick, EMPTY)); + spawnRandomList(second.getOrDefault(tick, EMPTY)); + if (tick > finalLastTick) bukkitTask.cancel(); + currentTick.incrementAndGet(); + }, 1, 1); + } + + private void spawnRandomList(List tntSpawns) { + if (tntSpawns.isEmpty()) return; + Collections.shuffle(tntSpawns); + for (TNTSpawn tntSpawn : tntSpawns) { + tntSpawn.spawn(); + } + } + + public static class TNTSpawn implements Comparable { + + private static final World WORLD = Bukkit.getWorlds().get(0); + + 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 comparator = false; + + public TNTSpawn(Vector position) { + this.position = position; + } + + public void spawn() { + WORLD.spawn(position.toLocation(WORLD), TNTPrimed.class, tntPrimed -> { + tntPrimed.setFuseTicks(fuseTicks); + if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0)); + if (!yVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setY(0)); + if (!zVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setZ(0)); + }); + } + + public Vector getPosition() { + return position; + } + + public int getFuseTicks() { + return fuseTicks; + } + + public void setFuseTicks(int fuseTicks) { + this.fuseTicks = fuseTicks; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getTickOffset() { + return tickOffset; + } + + public void setTickOffset(int tickOffset) { + 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); + } + + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java new file mode 100644 index 0000000..e0af211 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/world/TNTSimulatorListener.java @@ -0,0 +1,84 @@ +/* + * + * 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 de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +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.PlayerQuitEvent; +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"); + return false; + } + return true; + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getItem() == null) { + return; + } + if (!event.getItem().isSimilar(WAND)) { + return; + } + event.setCancelled(true); + if (!permissionCheck(event.getPlayer())) { + return; + } + + switch (event.getAction()) { + case LEFT_CLICK_BLOCK: + case LEFT_CLICK_AIR: + startSimulation(event.getPlayer()); + break; + case RIGHT_CLICK_BLOCK: + Vector location = event.getClickedBlock().getLocation().toVector().add(event.getBlockFace().getDirection()).add(HALF); + TNTSpawn tntSpawn = new TNTSpawn(location); + addTNT(event.getPlayer(), tntSpawn); + editTNT(event.getPlayer(), tntSpawn); + break; + case RIGHT_CLICK_AIR: + openSimulator(event.getPlayer()); + break; + default: + break; + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + TNT_SIMULATOR_MAP.remove(event.getPlayer()); + } + +} diff --git a/BauSystem_Main/src/plugin.yml b/BauSystem_Main/src/plugin.yml index 8ac3fdc..113cb9a 100644 --- a/BauSystem_Main/src/plugin.yml +++ b/BauSystem_Main/src/plugin.yml @@ -36,4 +36,6 @@ commands: detonator: aliases: dt script: + simulator: + aliases: sim gui: \ No newline at end of file