diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 7fc13eb9..19fd2479 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -41,6 +41,7 @@ SCOREBOARD_REGION = Region SCOREBOARD_TRACE = Trace SCOREBOARD_LOADER = Loader SCOREBOARD_TPS = TPS +SCOREBOARD_TPS_FROZEN = §e Eingefroren SCOREBOARD_TRACE_TICKS = Ticks @@ -519,20 +520,45 @@ BLOCK_COUNTER_MESSAGE = §e{0} §7Blöcke §e{1} §7TNT §e{2} §7Blöcke/TNT BLOCK_COUNTER_ENABLE = §7BlockCounter angemacht BLOCK_COUNTER_DISABLE = §7BlockCounter ausgemacht +# TPSLimit +TICK_STEP_HELP = §8/§etick step §8<§7Ticks§8> §8- §7Spule n Ticks vor +TICK_STEP_SINGLE_HELP = §8/§etick step §8- §7Spule einen Ticks vor +TICK_WARP_HELP = §8/§etick warp §8<§7Ticks§8> §8- §7Warpe n Ticks vor +TICK_CANCEL_HELP = §8/§etick cancel §8- §7Cancelt den Tick Warp oder Step +TICK_ERROR = §cDu kannst keinen weiteren §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c anmachen +TICK_CANCEL_ERROR = §cDu hast keinen §8'§e/tick step§8'§c oder §8'§e/tick warp§8'§c aktiv +TICK_STEP = §eSpult {0} Ticks vor +TICK_STEP_LEFT = §eSpult noch {0} Ticks vor +TICK_WARP = §eWarpe {0} Ticks vor +TICK_WARP_LEFT = §eWarpe noch {0} Ticks vor +TICK_CANCEL = §eWarps und Steps abgebrochen +TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter +TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0} +TPSLIMIT_ANVIL_GUI = Neues TPS Limit +TPSLIMIT_HELP = §8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Setzte die TPS auf dem Bau +TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0} +TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen +TPSLIMIT_SET = §eTPS limit auf {0} gesetzt. +TPSLIMIT_FROZEN = §eTPS eingefroren. +TPSLIMIT_INVALID = §cNur Zahlen zwischen 0,5 und {0}, und 'default'{1} erlaubt. +TPSLIMIT_INVALID_FROZEN = §c und '0' + # Trace TRACE_RECORD=§aan TRACE_RECORD-AUTO=§aan +TRACE_RECORD-SINGLE=§aan TRACE_IDLE=§caus TRACE_IDLE-AUTO=§eauto +TRACE_IDLE-SINGLE=§esingle TRACE_MESSAGE-AUTO_RECORD=§cTNT-Tracer muss gestoppt werden TRACE_MESSAGE-AUTO_RECORD-AUTO=§cTNT-Tracer darf nicht aufnehmen TRACE_MESSAGE-AUTO_IDLE=§cAuto-Tracer gestoppt TRACE_MESSAGE-AUTO_IDLE-AUTO = §aAuto-Tracer gestartet TRACE_MESSAGE_START = §aTNT-Tracer gestartet +TRACE_MESSAGE_SINGLE = §aSingle-Tracer gestartet TRACE_MESSAGE_STOP = §cTNT-Tracer gestoppt TRACE_MESSAGE_DELETE = §cAlle TNT-Positionen gelöscht TRACE_MESSAGE_SHOW = §aAlle TNT-Positionen angezeigt -TRACE_MESSAGE_SHOW_UNKNOWN = §cUnbekannter Show Mode TRACE_MESSAGE_HIDE = §cAlle TNT-Positionen ausgeblendet TRACE_MESSAGE_DISALLOWED = §cDu darfst hier nicht den TNT-Tracer nutzen diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java index ce085b38..7b16da9d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java @@ -110,5 +110,4 @@ public class AutostartListener implements Listener { RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT3"); }); } - } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java index fe9f9b44..a5b0bb4c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracer.java @@ -117,6 +117,8 @@ public class ObserverTracer { } private void calculateObserver(Block block) { + // TODO: Implement single Repeater, single Redstone, DetectorRail, PoweredRail, Diagonal Piston + Observer observer = (Observer) block.getBlockData(); for (BlockFace blockFace : ALLOWED) { Location location = block.getLocation().add(blockFace.getModX(), blockFace.getModY(), blockFace.getModZ()); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java index 27995703..66e916b5 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java @@ -40,12 +40,20 @@ public class TimeCommand extends SWCommand { addDefaultHelpMessage("OTHER_TIME_HELP"); } + // TODO: Add set as OptionalValue @Register public void genericCommand(@Guard Player p, Time time) { Bukkit.getWorlds().get(0).setTime(time.getValue()); BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p); } + @Register + public void genericCommand(@Guard Player p, @StaticValue(value = "set") String set, Time time) { + Bukkit.getWorlds().get(0).setTime(time.getValue()); + BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p); + } + + // TODO: Add set as OptionalValue @Register public void genericCommand(@Guard Player p, int time) { if (time < 0 || time > 24000) { @@ -56,6 +64,16 @@ public class TimeCommand extends SWCommand { BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p); } + @Register + public void genericCommand(@Guard Player p, @StaticValue(value = "set") String set, int time) { + if (time < 0 || time > 24000) { + BauSystem.MESSAGE.send("OTHER_TIME_INVALID", p); + return; + } + Bukkit.getWorlds().get(0).setTime(time); + BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p); + } + @ClassMapper(value = int.class, local = true) public TypeMapper intTypeMapper() { return SWCommandUtils.createMapper(s -> { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/OtherListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/OtherListener.java new file mode 100644 index 00000000..d55e3986 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/OtherListener.java @@ -0,0 +1,46 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.region; + +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; + +@Linked(LinkageType.LISTENER) +public class OtherListener implements Listener { + + @EventHandler + public void onBlockForm(BlockFormEvent event) { + if (event.getBlock().getType() == Material.SNOW_BLOCK || event.getBlock().getType() == Material.SNOW) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockFade(BlockFadeEvent event) { + if (event.getBlock().getType() == Material.SNOW_BLOCK || event.getBlock().getType() == Material.SNOW) { + event.setCancelled(true); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java index c718d6c8..cdcaec09 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java @@ -26,9 +26,14 @@ import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.config.ColorConfig; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.worlddata.SimulatorData; import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeMapper; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.List; + @Linked(LinkageType.COMMAND) public class SimulatorCommand extends SWCommand { @@ -42,6 +47,10 @@ public class SimulatorCommand extends SWCommand { p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator start" + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Startet die Simulation"); p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator gui" + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Öffnet die GUI"); p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator delete" + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Löscht alle TNT"); + p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator save " + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Speichert den Simulator"); + p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator load " + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Lädt den Simulator"); + p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator list" + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Listet alle gespeicherten Simulator"); + p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator remove " + ColorConfig.OTHER + " - " + ColorConfig.BASE + "Löscht den Simulator"); } @Register @@ -66,6 +75,44 @@ public class SimulatorCommand extends SWCommand { public void deleteCommand(Player p) { if (cannotUse(p)) return; TNTSimulator.get(p).delete(); + p.sendMessage(ColorConfig.BASE + "Alle TNT wurden gelöscht"); + } + + @Register({"save"}) + public void saveCommand(Player p, String name) { + if (cannotUse(p)) return; + TNTSimulator.get(p).save(); + SimulatorData.saveSimulator(p, name); + p.sendMessage(ColorConfig.BASE + "Simulator " + ColorConfig.HIGHLIGHT + name + ColorConfig.BASE + " wurde gespeichert"); + } + + @Register({"load"}) + public void loadCommand(Player p, @Mapper("SavedSimulators") String name) { + if (cannotUse(p)) return; + TNTSimulator.get(p).delete(); + SimulatorData.loadSimulator(p, name); + p.sendMessage(ColorConfig.BASE + "Simulator " + ColorConfig.HIGHLIGHT + name + ColorConfig.BASE + " wurde geladen"); + } + + @Register({"remove"}) + public void removeCommand(Player p, @Mapper("SavedSimulators") String name) { + if (cannotUse(p)) return; + SimulatorData.removeSimulator(p, name); + p.sendMessage(ColorConfig.BASE + "Simulator " + ColorConfig.HIGHLIGHT + name + ColorConfig.BASE + " wurde gelöscht"); + } + + @Register({"list"}) + public void listCommand(Player p) { + if (cannotUse(p)) return; + List sims = SimulatorData.listSimulator(p); + if (sims.isEmpty()) { + p.sendMessage(ColorConfig.BASE + "Keine gespeicherten Simulatoren"); + return; + } + p.sendMessage(ColorConfig.BASE + "Gespeicherte Simulatoren:"); + for (String s : sims) { + p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "simulator load " + s); + } } private boolean cannotUse(Player player) { @@ -76,4 +123,21 @@ public class SimulatorCommand extends SWCommand { return false; } + @Mapper(value = "SavedSimulators", local = true) + public TypeMapper simulatorListTypeMapper() { + return new TypeMapper() { + @Override + public String map(CommandSender commandSender, String[] previousArguments, String s) { + if (SimulatorData.listSimulator(((Player) commandSender)).contains(s)) { + return s; + } + return null; + } + + @Override + public List tabCompletes(CommandSender commandSender, String[] strings, String s) { + return SimulatorData.listSimulator(((Player) commandSender)); + } + }; + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java index 78f38475..1907dee0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java @@ -24,14 +24,14 @@ package de.steamwar.bausystem.features.simulator; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.config.ColorConfig; +import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.simulator.show.SimulatorEntityShowMode; +import de.steamwar.bausystem.features.tracer.record.RecordStateMachine; import de.steamwar.bausystem.worlddata.SimulatorData; -import de.steamwar.bausystem.worlddata.WorldData; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import de.steamwar.inventory.SWListInv; -import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; @@ -56,6 +56,10 @@ public class TNTSimulator { private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0); private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625); + private static final Vector FX_VECTOR = new Vector(1, 0, 0); + private static final Vector FY_VECTOR = new Vector(0, 1, 0); + private static final Vector FZ_VECTOR = new Vector(0, 0, 1); + 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<>(); @@ -82,22 +86,18 @@ public class TNTSimulator { simulator.spawns.forEach(tntSpawn -> { yapionArray.add(tntSpawn.output()); }); - if (yapionArray.isEmpty()) { - SimulatorData.removeSimulator(player); - } else { - SimulatorData.saveSimulator(player, new YAPIONObject().add("", yapionArray)); - } + SimulatorData.saveSimulator(player, yapionArray); simulator.hide(); } - public void saveAndDelete() { - save(); - TNT_SIMULATOR_MAP.remove(player); - } - public void delete() { TNTSimulator simulator = TNT_SIMULATOR_MAP.remove(player); - SimulatorData.removeSimulator(player); + SimulatorData.removeSimulator(player, ""); + simulator.hide(); + } + + public void remove() { + TNTSimulator simulator = TNT_SIMULATOR_MAP.remove(player); simulator.hide(); } @@ -155,7 +155,7 @@ public class TNTSimulator { return; } if (tntSpawns.size() == 1) { - tntSpawns.get(0).editTNT(); + tntSpawns.get(0).editTNT(spawns); } else { showGUI(new HashSet<>(tntSpawns)); } @@ -177,6 +177,12 @@ public class TNTSimulator { } public void start() { + boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false); + if (simulatorAutoTrace) { + RecordStateMachine.commandSingle(); + player.performCommand("trace show"); + } + Map> first = new HashMap<>(); Map> second = new HashMap<>(); int lastTick = 0; @@ -211,7 +217,6 @@ public class TNTSimulator { 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()); @@ -221,7 +226,9 @@ public class TNTSimulator { 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 swListInv = new SWListInv<>(player, "Kanonensimulator", false, swListEntryList, (clickType, spawn) -> { + spawn.editTNT(tntSpawns); + }); swListInv.setItem(51, new SWItem(Material.BARRIER, "§cTNT löschen", clickType -> { delete(); player.closeInventory(); @@ -230,9 +237,72 @@ public class TNTSimulator { start(); player.closeInventory(); })); + boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false); + swListInv.setItem(48, new SWItem(simulatorAutoTrace ? Material.CHAIN_COMMAND_BLOCK : Material.COMMAND_BLOCK, "§eAutoTrace§8: §7" + simulatorAutoTrace, clickType -> { + Config.getInstance().get(player).put("simulatorAutoTrace", !simulatorAutoTrace); + showGUI(tntSpawns); + })); + swListInv.setItem(49, new SWItem(Material.MAGENTA_GLAZED_TERRACOTTA, "§eAlle Verschieben", clickType -> { + move(tntSpawns); + })); swListInv.open(); } + private void move(Set tntSpawns) { + SWInventory swInventory = new SWInventory(player, 54, "TNT Verschieben"); + + // Position Settings + // X Position + swInventory.setItem(12, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.add(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR)); + move(tntSpawns); + })); + swInventory.setItem(21, new SWItem(Material.PAPER, "§7x-Position", clickType -> { + })); + swInventory.setItem(30, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.subtract(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR)); + move(tntSpawns); + })); + + // Y Position + swInventory.setItem(13, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.add(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR)); + move(tntSpawns); + })); + swInventory.setItem(22, new SWItem(Material.PAPER, "§7y-Position", clickType -> { + })); + swInventory.setItem(31, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.subtract(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR)); + move(tntSpawns); + })); + + // Z Position + swInventory.setItem(14, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.add(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR)); + move(tntSpawns); + })); + swInventory.setItem(23, new SWItem(Material.PAPER, "§7z-Position", clickType -> { + })); + swInventory.setItem(32, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + updatePosition(tntSpawns, vector -> vector.subtract(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR)); + move(tntSpawns); + })); + + swInventory.setItem(53, new SWItem(Material.ARROW, "§eZurück", clickType -> { + showGUI(tntSpawns); + })); + swInventory.open(); + } + + private void updatePosition(Set tntSpawns, Consumer positionChanger) { + Set vectors = new HashSet<>(); + for (TNTSpawn tntSpawn : tntSpawns) { + if (vectors.add(tntSpawn.position)) { + positionChanger.accept(tntSpawn.position); + } + } + } + private List getEntity(Entity entity) { List tntSpawns = new ArrayList<>(); for (TNTSpawn spawn : spawns) { @@ -297,7 +367,7 @@ public class TNTSimulator { } } - if (player.isSneaking()) { + if (!player.isSneaking()) { pos.setX(pos.getBlockX() + 0.5); if (face == null || face.getModY() == 0) pos.setY(pos.getBlockY() + 0.0); @@ -325,13 +395,13 @@ public class TNTSimulator { this.position = position; this.entity = entity; show(); - editTNT(); + editTNT(spawns); } private TNTSpawn(YAPIONObject yapionObject) { this.position = new Vector(yapionObject.getPlainValueOrDefault("positionX", 0.0), yapionObject.getPlainValueOrDefault("positionY", 0.0), yapionObject.getPlainValueOrDefault("positionZ", 0.0)); this.entity = SimulatorEntityShowMode.createEntity(player, position, false); - this.fuseTicks = yapionObject.getPlainValue("fuseTicks"); + this.fuseTicks = yapionObject.getPlainValueOrDefault("fuseTicks", 80); this.count = yapionObject.getPlainValue("count"); this.tickOffset = yapionObject.getPlainValue("tickOffset"); this.xVelocity = yapionObject.getPlainValue("xVelocity"); @@ -405,137 +475,147 @@ public class TNTSimulator { return -Integer.compare(tickOffset, tntSpawn.tickOffset); } - private void editTNT() { + private void editTNT(Set tntSpawns) { hide(); entity.setPosition(position); show(); SWInventory swInventory = new SWInventory(player, 54, "TNT konfigurieren"); // Change Count of spawned TNT - swInventory.setItem(1, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - setCount(count + 1); - editTNT(); + swInventory.setItem(1, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+5"), false, clickType -> { + setCount(count + (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); 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)); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns))); countItem.getItemStack().setAmount(count); swInventory.setItem(10, countItem); - swInventory.setItem(19, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - setCount(count - 1); - editTNT(); + swInventory.setItem(19, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-5"), false, clickType -> { + setCount(count - (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); // Change TickOffset - swInventory.setItem(2, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - setTickOffset(tickOffset + 1); - editTNT(); + swInventory.setItem(2, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+5"), false, clickType -> { + setTickOffset(tickOffset + (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); 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)); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns))); tickItem.getItemStack().setAmount(Math.max(tickOffset, 1)); swInventory.setItem(11, tickItem); - swInventory.setItem(20, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - setTickOffset(tickOffset - 1); - editTNT(); + swInventory.setItem(20, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-5"), false, clickType -> { + setTickOffset(tickOffset - (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); // Change FuseTicks - swInventory.setItem(3, new SWItem(SWItem.getDye(10), "§7+1", clickType -> { - setFuseTicks(fuseTicks + 1); - editTNT(); + swInventory.setItem(3, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+5"), false, clickType -> { + setFuseTicks(fuseTicks + (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); SWItem fuseTickItem = new SWItem(Material.CLOCK, "§7Lebensdauer §8- §e" + fuseTicks, LORE, false, clickType -> changeCount(player, "Fuse-Ticks", fuseTicks, tick -> { setFuseTicks(tick); - editTNT(); - }, this::editTNT)); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns))); fuseTickItem.getItemStack().setAmount(Math.max(fuseTicks, 1)); swInventory.setItem(12, fuseTickItem); - swInventory.setItem(21, new SWItem(SWItem.getDye(1), "§7-1", clickType -> { - setFuseTicks(fuseTicks - 1); - editTNT(); + swInventory.setItem(21, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-5"), false, clickType -> { + setFuseTicks(fuseTicks - (clickType.isShiftClick() ? 5 : 1)); + editTNT(tntSpawns); })); // Velocity Settings - swInventory.setItem(38, Material.TNT, "TNT", clickType -> { + swInventory.setItem(38, Material.TNT, "§7TNT", clickType -> { + if (xVelocity || yVelocity || zVelocity) { + xVelocity = false; + yVelocity = false; + zVelocity = false; + } else { + xVelocity = true; + yVelocity = true; + zVelocity = true; + } + editTNT(tntSpawns); }); swInventory.setItem(46, new SWItem(getWool(xVelocity), getColor(xVelocity), "§7TNT §eSprung X §8- " + active(xVelocity), clickType -> { xVelocity = !xVelocity; - editTNT(); + editTNT(tntSpawns); })); swInventory.setItem(29, new SWItem(getWool(yVelocity), getColor(yVelocity), "§7TNT §eSprung Y §8- " + active(yVelocity), clickType -> { yVelocity = !yVelocity; - editTNT(); + editTNT(tntSpawns); })); swInventory.setItem(48, new SWItem(getWool(zVelocity), getColor(zVelocity), "§7TNT §eSprung Z §8- " + active(zVelocity), clickType -> { zVelocity = !zVelocity; - editTNT(); + editTNT(tntSpawns); })); // Position Settings // X Position - swInventory.setItem(5, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - position.add(X_VECTOR); - editTNT(); + swInventory.setItem(5, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + position.add(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); + editTNT(tntSpawns); })); swInventory.setItem(14, new SWItem(Material.PAPER, "§7x-Position §8- §e" + position.getX(), LORE, false, clickType -> { changePosition(player, position.getX(), x -> { position.setX(clamp(x)); - editTNT(); - }, this::editTNT); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns)); })); - swInventory.setItem(23, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - position.subtract(X_VECTOR); - editTNT(); + swInventory.setItem(23, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + position.subtract(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); + editTNT(tntSpawns); })); // Y Position - swInventory.setItem(6, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - position.add(Y_VECTOR); - editTNT(); + swInventory.setItem(6, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + position.add(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); + editTNT(tntSpawns); })); swInventory.setItem(15, new SWItem(Material.PAPER, "§7y-Position §8- §e" + position.getY(), LORE, false, clickType -> { changePosition(player, position.getY(), y -> { position.setY(clamp(y)); - editTNT(); - }, this::editTNT); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns)); })); - swInventory.setItem(24, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - position.subtract(Y_VECTOR); - editTNT(); + swInventory.setItem(24, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + position.subtract(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); + editTNT(tntSpawns); })); // Z Position - swInventory.setItem(7, new SWItem(SWItem.getDye(10), "§7+0,0625", clickType -> { - position.add(Z_VECTOR); - editTNT(); + swInventory.setItem(7, new SWItem(SWItem.getDye(10), "§7+1", Arrays.asList("§eShift §7Click für §e+0,0625"), false, clickType -> { + position.add(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); + editTNT(tntSpawns); })); swInventory.setItem(16, new SWItem(Material.PAPER, "§7z-Position §8- §e" + position.getZ(), LORE, false, clickType -> { changePosition(player, position.getZ(), z -> { position.setZ(clamp(z)); - editTNT(); - }, this::editTNT); + editTNT(tntSpawns); + }, () -> editTNT(tntSpawns)); })); - swInventory.setItem(25, new SWItem(SWItem.getDye(1), "§7-0,0625", clickType -> { - position.subtract(Z_VECTOR); - editTNT(); + swInventory.setItem(25, new SWItem(SWItem.getDye(1), "§7-1", Arrays.asList("§eShift §7Click für §e-0,0625"), false, clickType -> { + position.subtract(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); + editTNT(tntSpawns); })); // Repeater before Comparator - swInventory.setItem(41, new SWItem(comparator ? SWItem.getMaterial("REDSTONE_COMPARATOR_OFF") : SWItem.getMaterial("DIODE"), "§7Gezündet durch §8- §e" + (comparator ? "Comparator" : "Repeater"), clickType -> { + swInventory.setItem(42, new SWItem(comparator ? SWItem.getMaterial("REDSTONE_COMPARATOR_OFF") : SWItem.getMaterial("DIODE"), "§7Gezündet durch §8- §e" + (comparator ? "Comparator" : "Repeater"), clickType -> { comparator = !comparator; - editTNT(); + editTNT(tntSpawns); })); swInventory.setItem(33, new SWItem(Material.TNT, "§eZündphase hinzufügen", clickType -> { spawns.add(new TNTSpawn(position, entity)); })); - swInventory.setItem(42, new SWItem(Material.ARROW, "§eZurück", clickType -> { - showGUI(); + swInventory.setItem(53, new SWItem(Material.ARROW, "§eZurück", clickType -> { + showGUI(tntSpawns); })); swInventory.setItem(51, new SWItem(Material.DISPENSER, "§eTNT hinzufügen", clickType -> { @@ -544,7 +624,7 @@ public class TNTSimulator { })); // Delete tnt - swInventory.setItem(43, new SWItem(Material.BARRIER, "§cEntfernen", clickType -> { + swInventory.setItem(44, new SWItem(Material.BARRIER, "§cEntfernen", clickType -> { hide(); spawns.remove(this); player.closeInventory(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorDisable.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorDisable.java deleted file mode 100644 index 4c7e3e24..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorDisable.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.steamwar.bausystem.features.simulator; - -import de.steamwar.bausystem.linkage.Disable; -import de.steamwar.bausystem.linkage.LinkageType; -import de.steamwar.bausystem.linkage.Linked; - -@Linked(LinkageType.DISABLE_LINK) -public class TNTSimulatorDisable implements Disable { - - @Override - public void disable() { - for (TNTSimulator simulator : TNTSimulator.TNT_SIMULATOR_MAP.values()) { - simulator.save(); - } - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java index f2743fb8..4e0359df 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java @@ -23,6 +23,7 @@ package de.steamwar.bausystem.features.simulator; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.linkage.Disable; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import org.bukkit.FluidCollisionMode; @@ -47,7 +48,8 @@ import static de.steamwar.bausystem.features.simulator.TNTSimulator.WAND; import static de.steamwar.bausystem.features.simulator.TNTSimulator.get; @Linked(LinkageType.LISTENER) -public class TNTSimulatorListener implements Listener { +@Linked(LinkageType.DISABLE_LINK) +public class TNTSimulatorListener implements Listener, Disable { private boolean permissionCheck(Player player) { if (!Permission.hasPermission(player, Permission.WORLD)) { @@ -117,7 +119,6 @@ public class TNTSimulatorListener implements Listener { if (event.getItem() == null || !event.getItem().isSimilar(WAND)) { return; } - System.out.println(event); event.setCancelled(true); if (!permissionCheck(event.getPlayer())) { @@ -140,6 +141,14 @@ public class TNTSimulatorListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - get(event.getPlayer()).saveAndDelete(); + get(event.getPlayer()).save(); + get(event.getPlayer()).remove(); + } + + @Override + public void disable() { + for (TNTSimulator simulator : TNTSimulator.TNT_SIMULATOR_MAP.values()) { + simulator.save(); + } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/algorithms/PowerableActivation.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/algorithms/PowerableActivation.java index 121e97c4..1fa366b1 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/algorithms/PowerableActivation.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/algorithms/PowerableActivation.java @@ -52,7 +52,15 @@ public class PowerableActivation implements PanzernAlgorithm { if (block.getType() == Material.TNT) { powerable++; } - if (blockFace == BlockFace.DOWN || blockFace == BlockFace.UP) { + if (blockFace == BlockFace.DOWN) { + for (BlockFace otherBlockFace : HORIZONTAL_FACES) { + Block otherBlock = block.getRelative(otherBlockFace); + if (otherBlock.getType() == Material.PISTON) { + powered++; + } + } + } + if (blockFace == BlockFace.UP) { continue; } switch (block.getType()) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java new file mode 100644 index 00000000..19ca8d0d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceBehaviour.java @@ -0,0 +1,45 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.smartplace; + +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public interface SmartPlaceBehaviour { + + enum SmartPlaceResult { + APPLIED, + IGNORED + } + + enum SmartPlaceType { + PLACE, + INTERACT_DIRECT, // Before checking if block is interacteable + INTERACT_INDIRECT, // After checking if block is interacteable + } + + SmartPlaceType getType(); + default SmartPlaceResult place(BlockPlaceEvent event) { + return SmartPlaceResult.IGNORED; + } + default SmartPlaceResult interact(PlayerInteractEvent event) { + return SmartPlaceResult.IGNORED; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index 74adbee9..b63abbb0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -23,41 +23,39 @@ import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.block.data.Rotatable; -import org.bukkit.block.data.type.Repeater; -import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.InventoryHolder; + +import java.util.ArrayList; +import java.util.List; @Linked(LinkageType.LISTENER) public class SmartPlaceListener implements Listener { + private static List smartPlaceBehaviours = new ArrayList<>(); + + public static void add(SmartPlaceBehaviour smartPlaceBehaviour) { + smartPlaceBehaviours.add(smartPlaceBehaviour); + } + @EventHandler public void onBlockPlace(BlockPlaceEvent event) { if (event.getPlayer().isSneaking() && Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) { - Block block = event.getBlockPlaced(); - BlockData blockData = block.getBlockData(); - if (blockData instanceof Directional) { - Directional directional = (Directional) blockData; - BlockFace blockFace = directional.getFacing().getOppositeFace(); - if (directional.getFaces().contains(blockFace)) { - directional.setFacing(blockFace); + SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED; + for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) { + if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.PLACE) { + smartPlaceBehaviour.place(event); + } + if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) { + break; } - } else if (blockData instanceof Rotatable) { - Rotatable rotatable = (Rotatable) blockData; - rotatable.setRotation(rotatable.getRotation()); } - block.setBlockData(blockData); } } @@ -67,20 +65,14 @@ public class SmartPlaceListener implements Listener { if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return; if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return; - // Reverse repeater - if (event.getPlayer().isSneaking()) { - if (event.getClickedBlock().getType() == Material.REPEATER) { - if (event.getItem() != null && event.getMaterial() != Material.REPEATER) { - return; - } - Repeater repeater = (Repeater) event.getClickedBlock().getBlockData(); - int i = repeater.getDelay() - 1; - if (i <= 0) i += 4; - repeater.setDelay(i); - event.getClickedBlock().setBlockData(repeater); - event.setCancelled(true); + for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) { + SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED; + if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.INTERACT_DIRECT) { + smartPlaceResult = smartPlaceBehaviour.interact(event); + } + if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) { + return; } - return; } if (!event.getClickedBlock().getType().isInteractable()) return; @@ -95,38 +87,14 @@ public class SmartPlaceListener implements Listener { return; } - if (event.getClickedBlock().getType() == event.getMaterial() || event.getMaterial() == Material.HOPPER) { - if (!(event.getClickedBlock().getState() instanceof InventoryHolder)) { - return; + for (SmartPlaceBehaviour smartPlaceBehaviour : smartPlaceBehaviours) { + SmartPlaceBehaviour.SmartPlaceResult smartPlaceResult = SmartPlaceBehaviour.SmartPlaceResult.IGNORED; + if (smartPlaceBehaviour.getType() == SmartPlaceBehaviour.SmartPlaceType.INTERACT_INDIRECT) { + smartPlaceResult = smartPlaceBehaviour.interact(event); } - } else { - BlockData blockData = event.getMaterial().createBlockData(); - if (blockData instanceof Directional) { - return; - } - if (blockData instanceof Rotatable) { + if (smartPlaceResult == SmartPlaceBehaviour.SmartPlaceResult.APPLIED) { return; } } - - // TODO: Fix block setting - event.setUseInteractedBlock(Event.Result.DENY); - World world = event.getPlayer().getWorld(); - Block block = world.getBlockAt(event.getClickedBlock().getX() + event.getBlockFace().getModX(), event.getClickedBlock().getY() + event.getBlockFace().getModY(), event.getClickedBlock().getZ() + event.getBlockFace().getModZ()); - block.setType(event.getMaterial()); - BlockData blockData = event.getItem().getType().createBlockData(); - BlockFace blockFace = event.getBlockFace(); - if (block.getType() == Material.HOPPER || block.getType() == Material.OBSERVER) { - blockFace = blockFace.getOppositeFace(); - } - if (blockData instanceof Directional) { - Directional directional = (Directional) blockData; - if (directional.getFaces().contains(blockFace)) { - directional.setFacing(blockFace); - } - } else if (blockData instanceof Rotatable) { - ((Rotatable) blockData).setRotation(blockFace); - } - block.setBlockData(blockData); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java new file mode 100644 index 00000000..5474561c --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockPlaceBehaviour.java @@ -0,0 +1,64 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.smartplace.behaviour; + +import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; +import org.bukkit.event.block.BlockPlaceEvent; + +@Linked(LinkageType.SMART_PLACE) +public class BlockPlaceBehaviour implements SmartPlaceBehaviour { + + @Override + public SmartPlaceType getType() { + return SmartPlaceType.PLACE; + } + + @Override + public SmartPlaceResult place(BlockPlaceEvent event) { + if (event.getBlockAgainst().getType().isInteractable()) { + return SmartPlaceResult.IGNORED; + } + + SmartPlaceResult smartPlaceResult = SmartPlaceResult.IGNORED; + Block block = event.getBlockPlaced(); + BlockData blockData = block.getBlockData(); + if (blockData instanceof Directional) { + Directional directional = (Directional) blockData; + BlockFace blockFace = directional.getFacing().getOppositeFace(); + if (directional.getFaces().contains(blockFace)) { + directional.setFacing(blockFace); + } + smartPlaceResult = SmartPlaceResult.APPLIED; + } else if (blockData instanceof Rotatable) { + Rotatable rotatable = (Rotatable) blockData; + rotatable.setRotation(rotatable.getRotation()); + smartPlaceResult = SmartPlaceResult.APPLIED; + } + block.setBlockData(blockData); + return smartPlaceResult; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java new file mode 100644 index 00000000..29071148 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/BlockRotatingBehaviour.java @@ -0,0 +1,81 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.smartplace.behaviour; + +import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.InventoryHolder; + +@Linked(LinkageType.SMART_PLACE) +public class BlockRotatingBehaviour implements SmartPlaceBehaviour { + + @Override + public SmartPlaceType getType() { + return SmartPlaceType.INTERACT_INDIRECT; + } + + @Override + public SmartPlaceResult interact(PlayerInteractEvent event) { + if (event.getClickedBlock().getType() == event.getMaterial() || event.getMaterial() == Material.HOPPER) { + if (!(event.getClickedBlock().getState() instanceof InventoryHolder)) { + return SmartPlaceResult.IGNORED; + } + } else { + BlockData blockData = event.getMaterial().createBlockData(); + if (blockData instanceof Directional) { + return SmartPlaceResult.IGNORED; + } + if (blockData instanceof Rotatable) { + return SmartPlaceResult.IGNORED; + } + } + + // TODO: Fix block setting + event.setUseInteractedBlock(Event.Result.DENY); + World world = event.getPlayer().getWorld(); + Block block = world.getBlockAt(event.getClickedBlock().getX() + event.getBlockFace().getModX(), event.getClickedBlock().getY() + event.getBlockFace().getModY(), event.getClickedBlock().getZ() + event.getBlockFace().getModZ()); + block.setType(event.getMaterial()); + BlockData blockData = event.getItem().getType().createBlockData(); + BlockFace blockFace = event.getBlockFace(); + if (block.getType() == Material.HOPPER || block.getType() == Material.OBSERVER) { + blockFace = blockFace.getOppositeFace(); + } + if (blockData instanceof Directional) { + Directional directional = (Directional) blockData; + if (directional.getFaces().contains(blockFace)) { + directional.setFacing(blockFace); + } + } else if (blockData instanceof Rotatable) { + ((Rotatable) blockData).setRotation(blockFace); + } + block.setBlockData(blockData); + return SmartPlaceResult.APPLIED; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java new file mode 100644 index 00000000..2c4a071a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/behaviour/ReverseRepeaterBehaviour.java @@ -0,0 +1,55 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.smartplace.behaviour; + +import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import org.bukkit.Material; +import org.bukkit.block.data.type.Repeater; +import org.bukkit.event.player.PlayerInteractEvent; + +@Linked(LinkageType.SMART_PLACE) +public class ReverseRepeaterBehaviour implements SmartPlaceBehaviour { + + @Override + public SmartPlaceType getType() { + return SmartPlaceType.INTERACT_DIRECT; + } + + @Override + public SmartPlaceResult interact(PlayerInteractEvent event) { + if (event.getPlayer().isSneaking()) { + if (event.getClickedBlock().getType() == Material.REPEATER) { + if (event.getItem() != null && event.getMaterial() != Material.REPEATER) { + return SmartPlaceResult.APPLIED; + } + Repeater repeater = (Repeater) event.getClickedBlock().getBlockData(); + int i = repeater.getDelay() - 1; + if (i <= 0) i += 4; + repeater.setDelay(i); + event.getClickedBlock().setBlockData(repeater); + event.setCancelled(true); + } + return SmartPlaceResult.APPLIED; + } + return SmartPlaceResult.IGNORED; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounterListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounterListener.java index d4ab3412..f910f935 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounterListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounterListener.java @@ -38,6 +38,9 @@ public class BlockCounterListener implements Listener { @EventHandler public void onEntityExplode(EntityExplodeEvent event) { Region region = Region.getRegion(event.getLocation()); + if (region.isGlobal()) { + return; + } List blockList = event.blockList(); blockList = blockList.stream().filter(block -> region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)).collect(Collectors.toList()); if (blockList.isEmpty()) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java new file mode 100644 index 00000000..e0d5804d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/FreezeUtils.java @@ -0,0 +1,72 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.tpslimit; + +import lombok.Getter; +import lombok.experimental.UtilityClass; +import net.minecraft.server.v1_15_R1.WorldServer; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; +import yapion.utils.ReflectionsUtils; + +import java.lang.reflect.Field; + +@UtilityClass +public class FreezeUtils { + + private static final Field field; + public static final boolean freezeEnabled; + + @Getter + private static boolean frozen = false; + + private static final World world; + + static { + field = ReflectionsUtils.getField(WorldServer.class, "freezed"); + if (field != null) field.setAccessible(true); + freezeEnabled = field != null; + world = Bukkit.getWorlds().get(0); + } + + public static void freeze() { + setFreeze(world, true); + } + + public static void unfreeze() { + setFreeze(world, false); + } + + public static boolean frozen() { + return freezeEnabled && frozen; + } + + private void setFreeze(World world, boolean state) { + if (freezeEnabled) { + try { + field.set(((CraftWorld) world).getHandle(), state); + frozen = state; + } catch (IllegalAccessException e) { + // Ignored; + } + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitBauGuiItem.java index bf72ef38..8451bf5a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitBauGuiItem.java @@ -19,11 +19,11 @@ package de.steamwar.bausystem.features.tpslimit; +import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.config.ColorConfig; -import de.steamwar.bausystem.linkage.specific.BauGuiItem; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.linkage.specific.BauGuiItem; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWItem; import org.bukkit.Material; @@ -42,14 +42,14 @@ public class TPSLimitBauGuiItem extends BauGuiItem { @Override public ItemStack getItem(Player player) { - return new SWItem(Material.CLOCK, ColorConfig.HIGHLIGHT + "TPS Limiter", Arrays.asList(ColorConfig.BASE + "Aktuell: " + ColorConfig.HIGHLIGHT + TPSLimitUtils.getCurrentTPSLimit()), false, clickType -> { + return new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("TPSLIMIT_GUI_ITEM_LORE", player, TPSLimitUtils.getCurrentTPSLimit())), false, clickType -> { }).getItemStack(); } @Override public boolean click(ClickType click, Player p) { p.closeInventory(); - SWAnvilInv inv = new SWAnvilInv(p, "Neues TPS Limit"); + SWAnvilInv inv = new SWAnvilInv(p, BauSystem.MESSAGE.parse("TPSLIMIT_ANVIL_GUI", p)); inv.setItem(Material.CLOCK); inv.setCallback(s -> p.performCommand("tpslimit " + s)); inv.open(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitCommand.java index 7a56e37f..7950e401 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitCommand.java @@ -21,15 +21,13 @@ package de.steamwar.bausystem.features.tpslimit; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.config.ColorConfig; +import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.linkage.Enable; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommandUtils; import de.steamwar.command.TypeMapper; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -50,6 +48,10 @@ public class TPSLimitCommand extends SWCommand implements Enable { tabCompletions.add(i + ""); } } + if (FreezeUtils.freezeEnabled) { + tabCompletions.add("0"); + } + addDefaultHelpMessage("TPSLIMIT_HELP"); } @Override @@ -57,57 +59,70 @@ public class TPSLimitCommand extends SWCommand implements Enable { TPSWarpUtils.init(); } - @Register(help = true) - public void genericHelp(Player p, String... args) { - p.sendMessage(BauSystem.PREFIX + "Jetziges TPS limit: " + TPSLimitUtils.currentTPSLimit); - p.sendMessage(ColorConfig.OTHER + "/" + ColorConfig.HIGHLIGHT + "tpslimit " + ColorConfig.OTHER + "[" + ColorConfig.BASE + "TPS" + ColorConfig.OTHER + "|" + ColorConfig.HIGHLIGHT + "default" + ColorConfig.OTHER + "] - " + ColorConfig.BASE + "Setzte die TPS auf dem Bau"); + @Register + public void checkCommand(Player p) { + if (!permissionCheck(p)) return; + BauSystem.MESSAGE.send("TPSLIMIT_CURRENT", p, TPSLimitUtils.currentTPSLimit); } @Register({"default"}) public void defaultCommand(Player p) { if (!permissionCheck(p)) return; - TPSLimitUtils.currentTPSLimit = 20; - TPSLimitUtils.tpsLimiter(); - sendNewTPSLimitMessage(); + valueCommand(p, 20D); } @Register public void valueCommand(Player p, /*@DoubleRange(min = 0.5, max = 60)*/ double tpsLimitDouble) { if (!permissionCheck(p)) return; + if (FreezeUtils.freezeEnabled && tpsLimitDouble == 0) { + FreezeUtils.freeze(); + TPSLimitUtils.currentTPSLimit = 20; + TPSLimitUtils.tpsLimiter(); + sendNewTPSLimitMessage(true); + return; + } if (tpsLimitDouble < 0.5 || tpsLimitDouble > (TPSWarpUtils.isWarpAllowed() ? 60 : 20)) { sendInvalidArgumentMessage(p); return; } + FreezeUtils.unfreeze(); TPSLimitUtils.currentTPSLimit = tpsLimitDouble; TPSLimitUtils.tpsLimiter(); - sendNewTPSLimitMessage(); + sendNewTPSLimitMessage(false); } @ClassMapper(value = double.class, local = true) public TypeMapper doubleTypeMapper() { return SWCommandUtils.createMapper(s -> { + if (s.equalsIgnoreCase("nan")) return -1D; try { return Double.parseDouble(s.replace(',', '.')); } catch (NumberFormatException e) { - return 0D; + return -1D; } }, s -> tabCompletions); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") - private boolean permissionCheck(Player player) { + protected static boolean permissionCheck(Player player) { if (!Permission.hasPermission(player, Permission.WORLD)) { - player.sendMessage(BauSystem.PREFIX + ColorConfig.DISABLE + "Du darfst hier nicht den TPS-Limiter nutzen"); + BauSystem.MESSAGE.send("TPSLIMIT_NO_PERMS", player); return false; } return true; } - private void sendNewTPSLimitMessage() { - Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(ColorConfig.HIGHLIGHT + "TPS limit auf " + TPSLimitUtils.currentTPSLimit + " gesetzt."))); + private void sendNewTPSLimitMessage(boolean frozen) { + Bukkit.getOnlinePlayers().forEach(player -> { + if (frozen) { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_FROZEN", player)); + } else { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TPSLIMIT_SET", player, TPSLimitUtils.currentTPSLimit)); + } + }); } private void sendInvalidArgumentMessage(Player player) { - player.sendMessage(BauSystem.PREFIX + ColorConfig.DISABLE + "Nur Zahlen zwischen 0,5 und " + (TPSWarpUtils.isWarpAllowed() ? 60 : 20) + ", und 'default' erlaubt."); + BauSystem.MESSAGE.send("TPSLIMIT_INVALID", player, TPSWarpUtils.isWarpAllowed() ? 60 : 20, FreezeUtils.freezeEnabled ? BauSystem.MESSAGE.parse("TPSLIMIT_INVALID_FROZEN", player) : ""); } } \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitUtils.java index a7952d08..7d4d6e9b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSLimitUtils.java @@ -86,5 +86,4 @@ public class TPSLimitUtils { currentTPSLimit = d; tpsLimiter(); } - } \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSUtils.java index 0ea3903f..7a2e3a0e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSUtils.java @@ -34,5 +34,4 @@ public class TPSUtils { static { Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> ticksSinceServerStart++, 1, 1); } - } \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSWarpUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSWarpUtils.java index 997ae238..28fbbc02 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSWarpUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSWarpUtils.java @@ -44,7 +44,7 @@ public class TPSWarpUtils { public static void setTPS(double tps) { double d = 50 - (50 / (tps / 20.0)); - nanoDOffset = Math.max(0, Math.min((long) (d * 1000000), 37500000)); + nanoDOffset = Math.max(0, Math.min((long) (d * 1000000), 375000000)); if (Core.getVersion() != 15) { return; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TickCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TickCommand.java new file mode 100644 index 00000000..8e4b7c86 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TickCommand.java @@ -0,0 +1,130 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.tpslimit; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.command.SWCommand; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +@Linked(LinkageType.COMMAND) +public class TickCommand extends SWCommand { + + private AtomicInteger ticksLeft = null; + private Runnable disableTask = null; + private Consumer ticksLeftActionBar = null; + + public TickCommand() { + super("tick"); + if (!FreezeUtils.freezeEnabled) { + unregister(); + return; + } + + new BukkitRunnable() { + @Override + public void run() { + if (ticksLeft == null) { + return; + } + + if (ticksLeft.getAndDecrement() <= 0) { + disableTask.run(); + disableTask = null; + ticksLeft = null; + } + if (ticksLeftActionBar != null && ticksLeft != null) { + ticksLeftActionBar.accept(ticksLeft.get()); + } + } + }.runTaskTimer(BauSystem.getInstance(), 0L, 1L); + } + + @Register(value = {"step"}, description = {"TICK_STEP_SINGLE_HELP", "TICK_STEP_HELP"}) + public void stepCommand(Player p, @OptionalValue("1") int ticks) { + if (!TPSLimitCommand.permissionCheck(p)) return; + if (ticksLeft != null) { + BauSystem.MESSAGE.send("TICK_ERROR", p); + return; + } + Bukkit.getOnlinePlayers().forEach(player -> { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_STEP", player, ticks)); + }); + FreezeUtils.unfreeze(); + ticksLeft = new AtomicInteger(ticks); + disableTask = FreezeUtils::freeze; + ticksLeftActionBar = currentTicksLeft -> { + Bukkit.getOnlinePlayers().forEach(player -> { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_STEP_LEFT", player, currentTicksLeft)); + }); + }; + } + + @Register(value = {"warp"}, description = "TICK_WARP_HELP") + public void warpCommand(Player p, int ticks) { + if (!TPSLimitCommand.permissionCheck(p)) return; + if (ticksLeft != null) { + BauSystem.MESSAGE.send("TICK_ERROR", p); + return; + } + Bukkit.getOnlinePlayers().forEach(player -> { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_WARP", player, ticks)); + }); + boolean frozen = FreezeUtils.frozen(); + double currentTPSLimit = TPSLimitUtils.currentTPSLimit; + TPSLimitUtils.currentTPSLimit = 240; + TPSLimitUtils.tpsLimiter(); + + FreezeUtils.unfreeze(); + ticksLeft = new AtomicInteger(ticks); + disableTask = () -> { + if (frozen) { + FreezeUtils.freeze(); + } + TPSLimitUtils.currentTPSLimit = currentTPSLimit; + TPSLimitUtils.tpsLimiter(); + }; + ticksLeftActionBar = currentTicksLeft -> { + Bukkit.getOnlinePlayers().forEach(player -> { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_WARP_LEFT", player, currentTicksLeft)); + }); + }; + } + + @Register(value = {"cancel"}, description = "TICK_CANCEL_HELP") + public void cancelCommand(Player p) { + if (!TPSLimitCommand.permissionCheck(p)) return; + if (ticksLeft == null) { + BauSystem.MESSAGE.send("TICK_CANCEL_ERROR", p); + return; + } + ticksLeft.set(0); + Bukkit.getOnlinePlayers().forEach(player -> { + SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("TICK_CANCEL", player)); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java index 74a957db..ce66267a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -28,22 +28,28 @@ import de.steamwar.bausystem.features.tracer.show.Record; import de.steamwar.bausystem.features.tracer.show.*; import de.steamwar.bausystem.features.tracer.show.mode.BlockShowMode; import de.steamwar.bausystem.features.tracer.show.mode.ParticleShowMode; +import de.steamwar.bausystem.features.tracer.show.mode.RawEntityShowMode; import de.steamwar.bausystem.features.tracer.show.mode.TraceEntityShowMode; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.shared.ShowMode; import de.steamwar.bausystem.utils.ListChatView; import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommandUtils; import de.steamwar.command.TypeMapper; +import lombok.AllArgsConstructor; import lombok.NonNull; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; @Linked(LinkageType.COMMAND) public class TraceCommand extends SWCommand { @@ -114,8 +120,8 @@ public class TraceCommand extends SWCommand { listCommand(p, 0); } - @Register({"record", "list"}) - @Register({"list"}) + @Register(value = {"record", "list"}, noTabComplete = true) + @Register(value = {"list"}, noTabComplete = true) public void listCommand(Player player, int page) { if (!permissionCheck(player)) return; ListChatView.chatView(player, StoredRecords.getRecords(), page, record -> { @@ -139,19 +145,19 @@ public class TraceCommand extends SWCommand { }); } - @Register({"record", "delete"}) + @Register(value = {"record", "delete"}, noTabComplete = true) public void recordDelete(Player p, int id) { if (!permissionCheck(p)) return; StoredRecords.remove(id); BauSystem.MESSAGE.send("TRACE_RECORD_DELETE", p); } - @Register("record") + @Register(value = "record", noTabComplete = true) public void recordList(Player p, int record) { recordList(p, record, 0); } - @Register("record") + @Register(value = "record", noTabComplete = true) public void recordList(Player player, int recordID, int page) { if (!permissionCheck(player)) return; Record traceRecord = StoredRecords.get(recordID); @@ -180,7 +186,7 @@ public class TraceCommand extends SWCommand { }); } - @Register({"record", "tnt", "delete"}) + @Register(value = {"record", "tnt", "delete"}, noTabComplete = true) public void deleteRecordTNT(Player player, int recordID, int tntID) { if (!permissionCheck(player)) return; Record record = StoredRecords.get(recordID); @@ -192,13 +198,13 @@ public class TraceCommand extends SWCommand { BauSystem.MESSAGE.send("TRACE_TNT_DELETE", player); } - @Register("record") - public void recordTNTPositions(Player player, int recordID, @Mapper("tnt") String tnt, int tntID) { + @Register(value = "record", noTabComplete = true) + public void recordTNTPositions(Player player, int recordID, @StaticValue("tnt") String tnt, int tntID) { recordTNTPositions(player, recordID, tnt, tntID, 0); } - @Register("record") - public void recordTNTPositions(Player player, int recordID, @Mapper("tnt") String tnt, int tntID, int page) { + @Register(value = "record", noTabComplete = true) + public void recordTNTPositions(Player player, int recordID, @StaticValue("tnt") String tnt, int tntID, int page) { if (!permissionCheck(player)) return; Record record = StoredRecords.get(recordID); if (record == null) { @@ -225,8 +231,8 @@ public class TraceCommand extends SWCommand { }); } - @Register("record") - public void recordTNTPositions(Player player, int recordID, @Mapper("tnt") String tnt, int tntID, @Mapper("fuse") String fuse, int fuseTicks) { + @Register(value = "record", noTabComplete = true) + public void recordTNTPositions(Player player, int recordID, @StaticValue("tnt") String tnt, int tntID, @StaticValue("fuse") String fuse, int fuseTicks) { if (!permissionCheck(player)) return; Record record = StoredRecords.get(recordID); if (record == null) { @@ -257,6 +263,13 @@ public class TraceCommand extends SWCommand { BauSystem.MESSAGE.send("TRACE_MESSAGE_START", p); } + @Register({"single"}) + public void singleCommand(Player p) { + if (!permissionCheck(p)) return; + RecordStateMachine.commandSingle(); + BauSystem.MESSAGE.send("TRACE_MESSAGE_SINGLE", p); + } + @Register({"stop"}) public void stopCommand(Player p) { if (!permissionCheck(p)) return; @@ -264,12 +277,8 @@ public class TraceCommand extends SWCommand { BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", p); } - @Register({"toggleauto"}) - public void toggleAutoCommand(Player p) { - autoCommand(p); - } - @Register({"auto"}) + @Register({"toggleauto"}) public void autoCommand(Player p) { if (!permissionCheck(p)) return; RecordStateMachine.commandAuto(); @@ -311,10 +320,19 @@ public class TraceCommand extends SWCommand { internalShow(p, ShowModeType.PARTICLE, showModeParameterTypes); } + @Register({"show", "raw"}) + public void rawShowEntityCommand(Player p, ShowModeParameterType... showModeParameterTypes) { + internalShow(p, ShowModeType.RAW_ENTITY, showModeParameterTypes); + } + + @AllArgsConstructor private enum ShowModeType { - ENTITY, - PARTICLE, - BLOCK + ENTITY(TraceEntityShowMode::new), + RAW_ENTITY(RawEntityShowMode::new), + PARTICLE(ParticleShowMode::new), + BLOCK(BlockShowMode::new); + + private BiFunction> showModeBiFunction; } private void internalShow(Player p, @NonNull ShowModeType showModeType, ShowModeParameterType... showModeParameterTypes) { @@ -323,20 +341,7 @@ public class TraceCommand extends SWCommand { for (ShowModeParameterType showModeParameterType : showModeParameterTypes) { showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter); } - switch (showModeType) { - case BLOCK: - TraceShowManager.show(p, new BlockShowMode(p, showModeParameter)); - break; - case PARTICLE: - TraceShowManager.show(p, new ParticleShowMode(p, showModeParameter)); - break; - case ENTITY: - TraceShowManager.show(p, new TraceEntityShowMode(p, showModeParameter)); - break; - default: - BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_UNKNOWN", p); - return; - } + TraceShowManager.show(p, showModeType.showModeBiFunction.apply(p, showModeParameter)); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", p); } @@ -361,40 +366,4 @@ public class TraceCommand extends SWCommand { } return true; } - - @Mapper(value = "tnt", local = true) - public TypeMapper tntTypeMapper() { - return new TypeMapper() { - @Override - public String map(CommandSender commandSender, String[] previousArguments, String s) { - if (s.equals("tnt")) { - return "tnt"; - } - return null; - } - - @Override - public List tabCompletes(CommandSender commandSender, String[] strings, String s) { - return Collections.singletonList("tnt"); - } - }; - } - - @Mapper(value = "fuse", local = true) - public TypeMapper fuseTypeMapper() { - return new TypeMapper() { - @Override - public String map(CommandSender commandSender, String[] previousArguments, String s) { - if (s.equals("fuse")) { - return "fuse"; - } - return null; - } - - @Override - public List tabCompletes(CommandSender commandSender, String[] strings, String s) { - return Collections.singletonList("fuse"); - } - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStateMachine.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStateMachine.java index 8cb5e245..d83ab71d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStateMachine.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStateMachine.java @@ -19,10 +19,10 @@ package de.steamwar.bausystem.features.tracer.record; -public class RecordStateMachine { - private RecordStateMachine() { - } +import lombok.experimental.UtilityClass; +@UtilityClass +public class RecordStateMachine { private static final TraceAutoHandler autoHandler = new TraceAutoHandler(); private static RecordStatus recordStatus = RecordStatus.IDLE; @@ -53,14 +53,32 @@ public class RecordStateMachine { } } + public static void commandSingle() { + if (recordStatus.isTracing()) + return; + + if (recordStatus != RecordStatus.IDLE_SINGLE) { + recordStatus = RecordStatus.IDLE_SINGLE; + autoHandler.enable(); + } + } + static void autoRecord() { recordStart(); - recordStatus = RecordStatus.RECORD_AUTO; + if (recordStatus == RecordStatus.IDLE_AUTO) { + recordStatus = RecordStatus.RECORD_AUTO; + } else { + recordStatus = RecordStatus.RECORD_SINGLE; + } } static void autoIdle() { recordStop(); - recordStatus = RecordStatus.IDLE_AUTO; + if (recordStatus == RecordStatus.RECORD_AUTO) { + recordStatus = RecordStatus.IDLE_AUTO; + } else { + recordStatus = RecordStatus.IDLE; + } } private static void recordStart() { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStatus.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStatus.java index f5d37e2e..e1198b11 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStatus.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/RecordStatus.java @@ -23,8 +23,10 @@ public enum RecordStatus { RECORD("TRACE_RECORD", true, "TRACE_MESSAGE-AUTO_RECORD"), RECORD_AUTO("TRACE_RECORD-AUTO", true, "TRACE_MESSAGE-AUTO_RECORD-AUTO"), + RECORD_SINGLE("TRACE_RECORD-SINGLE", true, ""), IDLE("TRACE_IDLE", false, "TRACE_MESSAGE-AUTO_IDLE"), - IDLE_AUTO("TRACE_IDLE-AUTO", false, "TRACE_MESSAGE-AUTO_IDLE-AUTO"); + IDLE_AUTO("TRACE_IDLE-AUTO", false, "TRACE_MESSAGE-AUTO_IDLE-AUTO"), + IDLE_SINGLE("TRACE_IDLE-SINGLE", false, ""); String name; boolean tracing; @@ -51,5 +53,4 @@ public enum RecordStatus { public String getAutoMessage() { return autoMessage; } - } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceAutoHandler.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceAutoHandler.java index f95a75a4..298dde87 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceAutoHandler.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/record/TraceAutoHandler.java @@ -63,8 +63,10 @@ public class TraceAutoHandler implements Listener { if (lastExplosion > 80) { RecordStateMachine.autoIdle(); - task.cancel(); - task = null; + if (task != null) { + task.cancel(); + task = null; + } } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java index b7ad90ec..c01ce31d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/Record.java @@ -61,14 +61,14 @@ public class Record { tnt.clear(); } - public TNTRecord get(int id) { + public TNTRecord get(long id) { for (TNTRecord record : tnt) { if (record.getId() == id) return record; } return null; } - public void remove(int id) { + public void remove(long id) { tnt.removeIf(record -> record.getId() == id); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java index de516128..beaf1c1e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/StoredRecords.java @@ -40,11 +40,11 @@ public class StoredRecords { records.remove(record); } - public static void remove(int id) { + public static void remove(long id) { records.removeIf(record -> record.getId() == id); } - public static Record get(int id) { + public static Record get(long id) { for (Record record : records) { if (record.getId() == id) return record; } @@ -60,5 +60,4 @@ public class StoredRecords { TraceShowManager.clear(); RecordStateMachine.postClear(); } - } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java new file mode 100644 index 00000000..ed03c9d8 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java @@ -0,0 +1,129 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 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.features.tracer.show.mode; + +import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; +import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.features.tracer.TNTTracer_15; +import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; +import de.steamwar.bausystem.shared.RoundedPosition; +import de.steamwar.bausystem.shared.ShowMode; +import de.steamwar.core.VersionedCallable; +import org.bukkit.entity.Player; +import org.bukkit.util.Consumer; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.Map; + +public abstract class FactoredEntityShowMode implements ShowMode { + + private int factor; + + protected final Player player; + protected final ShowModeParameter showModeParameter; + + private final Map tntEntityMap = new HashMap<>(); + private final Map updateEntityMap = new HashMap<>(); + + protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) { + this.player = player; + this.showModeParameter = showModeParameter; + this.factor = factor; + } + + @Override + public void show(TNTPosition position) { + if (showModeParameter.isExplodeOnly()) { + if (!position.isExploded()) { + return; + } + RoundedPosition roundedPosition = new RoundedPosition(position, factor); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player, position.isExploded()); + return; + } + if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { + // Basic + for (TNTPosition pos : position.getRecord().getPositions()) { + RoundedPosition roundedPosition = new RoundedPosition(pos, factor); + tntEntityMap.computeIfPresent(roundedPosition, (p, tnt) -> { + return tnt.hide(player, false) ? null : tnt; + }); + } + // Advanced + for (TNTPosition pos : position.getRecord().getPositions()) { + applyOnPosition(pos, updatePointPosition -> { + updateEntityMap.computeIfPresent(new RoundedPosition(updatePointPosition, factor), (p, point) -> { + return point.hide(player, false) ? null : point; + }); + }); + } + return; + } + + RoundedPosition roundedPosition = new RoundedPosition(position, factor); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player, position.isExploded()); + + applyOnPosition(position, updatePointPosition -> { + updateEntityMap.computeIfAbsent(new RoundedPosition(updatePointPosition, factor), pos -> { + return createEntity(player, updatePointPosition, false); + }).display(player, false); + }); + } + + private boolean checkWater(Vector position) { + return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.inWater(player.getWorld(), position), 15)); + } + + public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { + return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.create(player.getWorld(), position, tnt), 15)); + } + + private void applyOnPosition(TNTPosition position, Consumer function) { + if (position.getPreviousLocation() == null) return; + + if (showModeParameter.isInterpolate_Y()) { + Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); + if (!position.getLocation().equals(updatePointY)) { + function.accept(updatePointY); + } + } + + if (showModeParameter.isInterpolate_XZ()) { + Vector movement = position.getLocation().clone().subtract(position.getPreviousLocation()); + Vector updatePointXZ = Math.abs(movement.getX()) > Math.abs(movement.getZ()) + ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) + : position.getLocation().clone().setX(position.getPreviousLocation().getX()); + if (!position.getLocation().equals(updatePointXZ)) { + function.accept(updatePointXZ); + } + } + } + + @Override + public void hide() { + tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + tntEntityMap.clear(); + updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + updateEntityMap.clear(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java new file mode 100644 index 00000000..22952c0d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java @@ -0,0 +1,32 @@ +/* + * + * 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.features.tracer.show.mode; + +import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; +import org.bukkit.entity.Player; + +public class RawEntityShowMode extends FactoredEntityShowMode { + + public RawEntityShowMode(Player player, ShowModeParameter showModeParameter) { + super(player, showModeParameter, -1); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java index 6e7801ac..a5decb5c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java @@ -21,108 +21,12 @@ package de.steamwar.bausystem.features.tracer.show.mode; -import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; -import de.steamwar.bausystem.features.tracer.TNTPosition; -import de.steamwar.bausystem.features.tracer.TNTTracer_15; import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; -import de.steamwar.bausystem.shared.RoundedPosition; -import de.steamwar.bausystem.shared.ShowMode; -import de.steamwar.core.VersionedCallable; import org.bukkit.entity.Player; -import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; -import java.util.HashMap; -import java.util.Map; - -public class TraceEntityShowMode implements ShowMode { - - protected final Player player; - protected final ShowModeParameter showModeParameter; - - private final Map tntEntityMap = new HashMap<>(); - private final Map updateEntityMap = new HashMap<>(); +public class TraceEntityShowMode extends FactoredEntityShowMode { public TraceEntityShowMode(Player player, ShowModeParameter showModeParameter) { - this.player = player; - this.showModeParameter = showModeParameter; - } - - @Override - public void show(TNTPosition position) { - if (showModeParameter.isExplodeOnly()) { - if (!position.isExploded()) { - return; - } - RoundedPosition roundedPosition = new RoundedPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); - entity.display(player, position.isExploded()); - return; - } - if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { - // Basic - for (TNTPosition pos : position.getRecord().getPositions()) { - RoundedPosition roundedPosition = new RoundedPosition(pos); - tntEntityMap.computeIfPresent(roundedPosition, (p, tnt) -> { - return tnt.hide(player, false) ? null : tnt; - }); - } - // Advanced - for (TNTPosition pos : position.getRecord().getPositions()) { - applyOnPosition(pos, updatePointPosition -> { - updateEntityMap.computeIfPresent(new RoundedPosition(updatePointPosition), (p, point) -> { - return point.hide(player, false) ? null : point; - }); - }); - } - return; - } - - RoundedPosition roundedPosition = new RoundedPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); - entity.display(player, position.isExploded()); - - applyOnPosition(position, updatePointPosition -> { - updateEntityMap.computeIfAbsent(new RoundedPosition(updatePointPosition), pos -> { - return createEntity(player, updatePointPosition, false); - }).display(player, false); - }); - } - - private boolean checkWater(Vector position) { - return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.inWater(player.getWorld(), position), 15)); - } - - public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { - return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.create(player.getWorld(), position, tnt), 15)); - } - - private void applyOnPosition(TNTPosition position, Consumer function) { - if (position.getPreviousLocation() == null) return; - - if (showModeParameter.isInterpolate_Y()) { - Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); - if (!position.getLocation().equals(updatePointY)) { - function.accept(updatePointY); - } - } - - if (showModeParameter.isInterpolate_XZ()) { - Vector movement = position.getLocation().clone().subtract(position.getPreviousLocation()); - Vector updatePointXZ = Math.abs(movement.getX()) > Math.abs(movement.getZ()) - ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) - : position.getLocation().clone().setX(position.getPreviousLocation().getX()); - if (!position.getLocation().equals(updatePointXZ)) { - function.accept(updatePointXZ); - } - } - } - - @Override - public void hide() { - tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); - tntEntityMap.clear(); - updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); - updateEntityMap.clear(); + super(player, showModeParameter, 10); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java index 17865922..eb3144d2 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java @@ -2,6 +2,7 @@ package de.steamwar.bausystem.features.world; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.loader.Loader; +import de.steamwar.bausystem.features.tpslimit.FreezeUtils; import de.steamwar.bausystem.features.tpslimit.TPSLimitUtils; import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.features.tpslimit.TPSWarpUtils; @@ -85,7 +86,11 @@ public class BauScoreboard implements Listener { strings.add(colorCode + BauSystem.MESSAGE.parse("SCOREBOARD_LOADER", p) + "§8: " + BauSystem.MESSAGE.parse(loader != null ? loader.getStage().getChatValue() : "LOADER_OFF", p)); strings.add("§5"); - strings.add(colorCode + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8 " + tpsColor() + TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit()); + if (FreezeUtils.frozen()) { + strings.add(colorCode + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p)); + } else { + strings.add(colorCode + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8 " + tpsColor() + TPSWarpUtils.getTps(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit()); + } int i = strings.size(); HashMap result = new HashMap<>(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageType.java b/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageType.java index 9b501472..ab9f6be6 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageType.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageType.java @@ -20,13 +20,15 @@ package de.steamwar.bausystem.linkage; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.configplayer.ConfigConverter; import de.steamwar.bausystem.configplayer.Config; +import de.steamwar.bausystem.configplayer.ConfigConverter; import de.steamwar.bausystem.features.gui.BauGUI; -import de.steamwar.bausystem.features.slaves.panzern.Panzern; -import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm; import de.steamwar.bausystem.features.script.ScriptExecutor; import de.steamwar.bausystem.features.script.SpecialCommand; +import de.steamwar.bausystem.features.slaves.panzern.Panzern; +import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm; +import de.steamwar.bausystem.features.smartplace.SmartPlaceBehaviour; +import de.steamwar.bausystem.features.smartplace.SmartPlaceListener; import de.steamwar.bausystem.linkage.specific.BauGuiItem; import de.steamwar.bausystem.linkage.specific.ScoreboardItem; import de.steamwar.command.SWCommand; @@ -58,7 +60,8 @@ public enum LinkageType { SCRIPT_COMMAND(4, false, SpecialCommand.class::isAssignableFrom, o -> ScriptExecutor.SPECIAL_COMMANDS.add((SpecialCommand) o)), CONFIG_CONVERTER(5, false, ConfigConverter.class::isAssignableFrom, o -> Config.addConfigConverter((ConfigConverter) o)), SCOREBOARD(6, false, ScoreboardItem.class::isAssignableFrom, o -> {}), - PANZERN(7, false, PanzernAlgorithm.class::isAssignableFrom, o -> Panzern.add((PanzernAlgorithm) o)); + PANZERN(7, false, PanzernAlgorithm.class::isAssignableFrom, o -> Panzern.add((PanzernAlgorithm) o)), + SMART_PLACE(8, false, SmartPlaceBehaviour.class::isAssignableFrom, o -> SmartPlaceListener.add((SmartPlaceBehaviour) o)); private final int order; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageUtils.java index 429d96cc..85f41d5a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/linkage/LinkageUtils.java @@ -41,12 +41,10 @@ public class LinkageUtils { public void link() { internalLinkOrUnlink(false, Linked.class); - internalLinkOrUnlink(false, Linked.Linkages.class); internalLinkFields(); } public void unlink() { - internalLinkOrUnlink(true, Linked.Linkages.class); internalLinkOrUnlink(true, Linked.class); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/linkage/Linked.java b/BauSystem_Main/src/de/steamwar/bausystem/linkage/Linked.java index ff447ed0..2096d1ac 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/linkage/Linked.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/linkage/Linked.java @@ -30,7 +30,6 @@ import java.lang.annotation.*; public @interface Linked { LinkageType value(); - @IndexAnnotated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @interface Linkages { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java b/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java index 5116d48f..5401ee4b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/region/Region.java @@ -434,7 +434,7 @@ public class Region { int dz = Math.abs(clipboard.getOrigin().getZ() - clipboard.getMinimumPoint().getZ()); if (dz < 2 || dz > prototype.getTestblock().getSizeZ()) { pastePoint = pastePoint.add(0, 0, prototype.getTestblock().getSizeZ() / 2); - } else if (clipboard.getDimensions().getZ() < prototype.getTestblock().getSizeZ()) { + } else if (clipboard.getDimensions().getZ() != prototype.getTestblock().getSizeZ()) { pastePoint = pastePoint.add(0, 0, clipboard.getDimensions().getZ() / 2 - (clipboard.getOrigin().getZ() - clipboard.getMinimumPoint().getZ()) - 1); } else { pastePoint = pastePoint.add(0, 0, prototype.getTestblock().getSizeZ() / 2); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java b/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java index ef2a65f7..4d3b9a2c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/region/flags/Flag.java @@ -36,7 +36,7 @@ public enum Flag implements EnumDisplay { FIRE("FLAG_FIRE", FireMode.class, FireMode.ALLOW, region -> true), DAMAGE("FLAG_DAMAGE", DamageMode.class, DamageMode.ALLOW, region -> false), FREEZE("FLAG_FREEZE", FreezeMode.class, FreezeMode.INACTIVE, region -> true), - PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.INACTIVE, region -> region.getFloorLevel() != 0); + PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.ACTIVE, region -> region.getFloorLevel() != 0); @Getter private static final Set flags; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java index 55e791d3..23aed77f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java @@ -25,24 +25,44 @@ import java.util.Objects; public class RoundedPosition { - private static final int factor = 10; + private static final long factor = 10; - private int x; - private int y; - private int z; + private long x; + private long y; + private long z; public RoundedPosition(Position position) { this(position.getLocation().getX(), position.getLocation().getY(), position.getLocation().getZ()); } + public RoundedPosition(Position position, int factor) { + this(position.getLocation().getX(), position.getLocation().getY(), position.getLocation().getZ(), factor); + } + public RoundedPosition(Vector vector) { this(vector.getX(), vector.getY(), vector.getZ()); } + public RoundedPosition(Vector vector, int factor) { + this(vector.getX(), vector.getY(), vector.getZ(), factor); + } + public RoundedPosition(double x, double y, double z) { - this.x = (int) (x * factor); - this.y = (int) (y * factor); - this.z = (int) (z * factor); + this.x = (long) (x * factor); + this.y = (long) (y * factor); + this.z = (long) (z * factor); + } + + public RoundedPosition(double x, double y, double z, long factor) { + if (factor == -1) { + this.x = Double.doubleToLongBits(x); + this.y = Double.doubleToLongBits(y); + this.z = Double.doubleToLongBits(z); + } else { + this.x = (long) (x * factor); + this.y = (long) (y * factor); + this.z = (long) (z * factor); + } } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/worlddata/SimulatorData.java b/BauSystem_Main/src/de/steamwar/bausystem/worlddata/SimulatorData.java index dc2695e3..e9ef8f5b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/worlddata/SimulatorData.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/worlddata/SimulatorData.java @@ -25,10 +25,12 @@ import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import yapion.hierarchy.output.FileOutput; +import yapion.hierarchy.types.YAPIONArray; import yapion.hierarchy.types.YAPIONObject; import yapion.parser.YAPIONParser; import java.io.File; +import java.util.List; @UtilityClass public class SimulatorData { @@ -49,7 +51,7 @@ public class SimulatorData { } @SneakyThrows - public void saveSimulator(Player player, YAPIONObject yapionObject) { + private void internalSaveSimulator(Player player, YAPIONObject yapionObject) { File file = getFile(player); yapionObject.toYAPION(new FileOutput(file)).close(); } @@ -60,11 +62,34 @@ public class SimulatorData { yapionObject.toYAPION(new FileOutput(file)).close(); } - public void removeSimulator(Player player) { - File file = getFile(player); - if (file.exists()) { - file.delete(); - } + public List listSimulator(Player player) { + List strings = getSimulator(player).getKeys(); + strings.remove(""); + return strings; + } + + public void saveSimulator(Player player, String name) { + YAPIONObject yapionObject = getSimulator(player); + yapionObject.put(name, yapionObject.getArray("").copy()); + internalSaveSimulator(player, yapionObject); + } + + public void saveSimulator(Player player, YAPIONArray simulator) { + YAPIONObject yapionObject = getSimulator(player); + yapionObject.put("", simulator); + internalSaveSimulator(player, yapionObject); + } + + public void loadSimulator(Player player, String name) { + YAPIONObject yapionObject = getSimulator(player); + yapionObject.put("", yapionObject.getArray(name).copy()); + internalSaveSimulator(player, yapionObject); + } + + public void removeSimulator(Player player, String name) { + YAPIONObject yapionObject = getSimulator(player); + yapionObject.remove(name); + internalSaveSimulator(player, yapionObject); } private File getFile(Player player) { diff --git a/yapion/prototypes3.yapion b/yapion/prototypes3.yapion index 38c4ecb2..37bf6f2d 100644 --- a/yapion/prototypes3.yapion +++ b/yapion/prototypes3.yapion @@ -21,6 +21,7 @@ sizeX(63) sizeY(256) sizeZ(120) + floorOffset(45) testblock{ offsetX(13) offsetY(44) @@ -37,6 +38,7 @@ sizeX(133) sizeY(255) sizeZ(214) + floorOffset(45) testblock{ offsetX(33) offsetY(44)