diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index 9a7276b..0d92386 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -96,6 +96,7 @@ 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()); Bukkit.getPluginManager().registerEvents(this, this); Bukkit.getPluginManager().registerEvents(new RegionListener(), this); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSimulator.java new file mode 100644 index 0000000..5a51c5b --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSimulator.java @@ -0,0 +1,251 @@ +/* + * + * 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.canonsimulator; + +import de.steamwar.bausystem.BauSystem; +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.entity.Player; +import org.bukkit.util.Consumer; +import org.bukkit.util.Vector; + +import java.util.*; + +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 Map tntSimulatorMap = new HashMap<>(); + + public static void openSimulator(Player player) { + if (!tntSimulatorMap.containsKey(player)) { + tntSimulatorMap.put(player, new TNTSimulator()); + } + TNTSimulator tntSimulator = tntSimulatorMap.get(player); + + List> swListEntryList = new ArrayList<>(); + tntSimulator.tntSpawns.forEach(tntSpawn -> { + List lore = new ArrayList<>(); + lore.add("§eTNT-Anzahl§8: §7" + tntSpawn.getCount()); + lore.add("§eTick§8: §7" + tntSpawn.getTickOffset()); + lore.add(""); + lore.add("§eX§8: §7" + tntSpawn.getPosition().getX()); + lore.add("§eY§8: §7" + tntSpawn.getPosition().getY()); + lore.add("§eZ§8: §7" + tntSpawn.getPosition().getZ()); + swListEntryList.add(new SWListInv.SWListEntry<>(new SWItem(Material.TNT, "§eTNT", lore, false, null), tntSpawn)); + }); + SWListInv swListInv = new SWListInv<>(player, "Kanonen Simulator", false, swListEntryList, (clickType, tntSpawn) -> { + editTNT(player, tntSpawn); + }); + swListInv.setItem(48, new SWItem(Material.BARRIER, "§cLösche alle TNT", clickType -> { + tntSimulator.tntSpawns.clear(); + openSimulator(player); + })); + swListInv.setItem(49, new SWItem(Material.TNT, "§aNeues TNT", clickType -> { + Vector vector = player.getLocation().toVector().multiply(16); + vector.setX((int) vector.getX()); + vector.setY((int) vector.getY()); + vector.setZ((int) vector.getZ()); + vector.multiply(0.0625); + + TNTSpawn tntSpawn = new TNTSpawn(vector); + if (tntSimulator.tntSpawns.contains(tntSpawn)) { + return; + } + tntSimulator.tntSpawns.add(tntSpawn); + editTNT(player, tntSpawn); + })); + swListInv.setItem(50, new SWItem(Material.FLINT_AND_STEEL, "§eSimulation Starten", clickType -> { + tntSimulator.start(); + player.closeInventory(); + })); + swListInv.open(); + } + + private static void editTNT(Player player, TNTSpawn tntSpawn) { + SWInventory swInventory = new SWInventory(player, 45, "TNT"); + swInventory.setItem(44, new SWItem(Material.REDSTONE_BLOCK, "§cZurück", clickType -> { + openSimulator(player); + })); + + // Change Count of spawned TNT + swInventory.setItem(10, new SWItem(SWItem.getDye(10), "§a+1", clickType -> { + tntSpawn.setCount(tntSpawn.getCount() + 1); + editTNT(player, tntSpawn); + })); + swInventory.setItem(19, new SWItem(Material.TNT, "§eAnzahl §8- §7" + tntSpawn.getCount(), clickType -> { + changeCount(player, count -> { + if (count < 1) count = 1; + tntSpawn.setCount(count); + editTNT(player, tntSpawn); + }, () -> editTNT(player, tntSpawn)); + })); + swInventory.setItem(28, new SWItem(SWItem.getDye(1), "§c-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), "§a+1", clickType -> { + tntSpawn.setTickOffset(tntSpawn.getTickOffset() + 1); + editTNT(player, tntSpawn); + })); + swInventory.setItem(20, new SWItem(Material.CLOCK, "§eTick §8- §7" + tntSpawn.getTickOffset(), clickType -> { + changeCount(player, tick -> { + if (tick < 0) tick = 0; + tntSpawn.setTickOffset(tick); + editTNT(player, tntSpawn); + }, () -> editTNT(player, tntSpawn)); + })); + swInventory.setItem(29, new SWItem(SWItem.getDye(1), "§c-1", clickType -> { + tntSpawn.setTickOffset(tntSpawn.getTickOffset() - 1); + if (tntSpawn.getTickOffset() < 0) { + tntSpawn.setTickOffset(0); + } + editTNT(player, tntSpawn); + })); + + // Delete icon + swInventory.setItem(21, new SWItem(Material.BARRIER, "§cDelete", clickType -> { + tntSimulatorMap.get(player).tntSpawns.remove(tntSpawn); + openSimulator(player); + })); + + // Velocity Settings + swInventory.setItem(13, new SWItem(tntSpawn.isxVelocity() ? Material.LIME_WOOL : Material.RED_WOOL, "§eVelocity-X §8- §7" + active(tntSpawn.isxVelocity()), clickType -> { + tntSpawn.setxVelocity(!tntSpawn.isxVelocity()); + editTNT(player, tntSpawn); + })); + swInventory.setItem(22, new SWItem(tntSpawn.isyVelocity() ? Material.LIME_WOOL : Material.RED_WOOL, "§eVelocity-Y §8- §7" + active(tntSpawn.isyVelocity()), clickType -> { + tntSpawn.setyVelocity(!tntSpawn.isyVelocity()); + editTNT(player, tntSpawn); + })); + swInventory.setItem(31, new SWItem(tntSpawn.iszVelocity() ? Material.LIME_WOOL : Material.RED_WOOL, "§eVelocity-Z §8- §7" + active(tntSpawn.iszVelocity()), clickType -> { + tntSpawn.setzVelocity(!tntSpawn.iszVelocity()); + editTNT(player, tntSpawn); + })); + + // X Position + swInventory.setItem(14, new SWItem(SWItem.getDye(10), "§a+0,0625", clickType -> { + tntSpawn.getPosition().add(X_VECTOR); + editTNT(player, tntSpawn); + })); + swInventory.setItem(23, new SWItem(Material.PAPER, "§ePosition-X §8- §7" + tntSpawn.getPosition().getX(), clickType -> { + changePosition(player, x -> { + tntSpawn.getPosition().setX(clamp(x)); + editTNT(player, tntSpawn); + }, () -> editTNT(player, tntSpawn)); + })); + swInventory.setItem(32, new SWItem(SWItem.getDye(1), "§c-0,0625", clickType -> { + tntSpawn.getPosition().add(NX_VECTOR); + editTNT(player, tntSpawn); + })); + + // Y Position + swInventory.setItem(15, new SWItem(SWItem.getDye(10), "§a+0,0625", clickType -> { + tntSpawn.getPosition().add(Y_VECTOR); + editTNT(player, tntSpawn); + })); + swInventory.setItem(24, new SWItem(Material.PAPER, "§ePosition-Y §8- §7" + tntSpawn.getPosition().getY(), clickType -> { + changePosition(player, y -> { + tntSpawn.getPosition().setY(clamp(y)); + editTNT(player, tntSpawn); + }, () -> editTNT(player, tntSpawn)); + })); + swInventory.setItem(33, new SWItem(SWItem.getDye(1), "§c-0,0625", clickType -> { + tntSpawn.getPosition().add(NY_VECTOR); + editTNT(player, tntSpawn); + })); + + // Z Position + swInventory.setItem(16, new SWItem(SWItem.getDye(10), "§a+0,0625", clickType -> { + tntSpawn.getPosition().add(Z_VECTOR); + editTNT(player, tntSpawn); + })); + swInventory.setItem(25, new SWItem(Material.PAPER, "§ePosition-Z §8- §7" + tntSpawn.getPosition().getZ(), clickType -> { + changePosition(player, z -> { + tntSpawn.getPosition().setZ(clamp(z)); + editTNT(player, tntSpawn); + }, () -> editTNT(player, tntSpawn)); + })); + swInventory.setItem(34, new SWItem(SWItem.getDye(1), "§c-0,0625", clickType -> { + tntSpawn.getPosition().add(NZ_VECTOR); + editTNT(player, tntSpawn); + })); + swInventory.open(); + } + + private static String active(boolean b) { + return b ? "§aan" : "§caus"; + } + + private static void changeCount(Player player, Consumer result, Runnable failure) { + SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Zahl"); + 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, Consumer result, Runnable failure) { + SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Position"); + 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 * 100) * 0.01; + } + + private Set tntSpawns = new TreeSet<>(); + + public void start() { + tntSpawns.forEach(tntSpawn -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), tntSpawn::spawn, tntSpawn.getTickOffset() + 1L); + }); + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSpawn.java b/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSpawn.java new file mode 100644 index 0000000..cb93471 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/canonsimulator/TNTSpawn.java @@ -0,0 +1,127 @@ +/* + * + * 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.canonsimulator; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; + +import java.util.Objects; + +public class TNTSpawn implements Comparable { + + private static final World WORLD = Bukkit.getWorlds().get(0); + + private Vector position; + private int count = 1; + private int tickOffset = 0; + private boolean xVelocity = true; + private boolean yVelocity = true; + private boolean zVelocity = true; + + public TNTSpawn(Vector position) { + this.position = position; + } + + public void spawn() { + for (int i = 0; i < count; i++) { + WORLD.spawn(position.toLocation(WORLD), TNTPrimed.class, tntPrimed -> { + 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 void setPosition(Vector position) { + this.position = position; + } + + 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; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TNTSpawn)) return false; + TNTSpawn tntSpawn = (TNTSpawn) o; + return count == tntSpawn.count && + tickOffset == tntSpawn.tickOffset && + xVelocity == tntSpawn.xVelocity && + yVelocity == tntSpawn.yVelocity && + zVelocity == tntSpawn.zVelocity && + position.equals(tntSpawn.position); + } + + @Override + public int hashCode() { + return Objects.hash(position, count, tickOffset, xVelocity, yVelocity, zVelocity); + } + + @Override + public int compareTo(TNTSpawn tntSpawn) { + return -Integer.compare(tickOffset, tntSpawn.tickOffset); + } + +} 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..5c48636 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/commands/CommandSimulator.java @@ -0,0 +1,41 @@ +/* + * + * 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.canonsimulator.TNTSimulator; +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 { + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { + if(!(commandSender instanceof Player)) + return false; + Player p = (Player) commandSender; + TNTSimulator.openSimulator(p); + return false; + } + +} diff --git a/BauSystem_Main/src/plugin.yml b/BauSystem_Main/src/plugin.yml index bc85fb9..200cb28 100644 --- a/BauSystem_Main/src/plugin.yml +++ b/BauSystem_Main/src/plugin.yml @@ -33,4 +33,6 @@ commands: lockschem: detonator: aliases: dt - script: \ No newline at end of file + script: + simulator: + aliases: sim \ No newline at end of file