diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
index ffea7e4f..95fa92b6 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java
@@ -26,7 +26,7 @@ import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
-@Linked
+// @Linked
public class LoaderCommand extends SWCommand {
public LoaderCommand() {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/Loader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/Loader.java
new file mode 100644
index 00000000..01d56d04
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/Loader.java
@@ -0,0 +1,130 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.loadern.elements.LoaderElement;
+import de.steamwar.inventory.SWListInv;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Loader implements Listener {
+
+ private static final Map LOADER_MAP = new HashMap<>();
+
+ public static Loader getLoader(Player player) {
+ return LOADER_MAP.get(player);
+ }
+
+ public static void newLoader(Player player) {
+ LOADER_MAP.put(player, new Loader(player));
+ }
+
+ private final Player p;
+
+ private Stage stage = Stage.SETUP;
+ private LoaderRecorder recorder;
+
+ private List elements = new ArrayList<>();
+ private int currentElement = 0;
+
+ public Loader(Player p) {
+ this.p = p;
+ this.recorder = new LoaderRecorder(p, elements);
+ Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
+ }
+
+ private void next() {
+ currentElement++;
+ if (currentElement >= elements.size()) {
+ currentElement = 0;
+ }
+ if (stage == Stage.RUNNING) {
+ elements.get(currentElement).execute(this::next);
+ }
+ }
+
+ public void start() {
+ if (stage == Stage.END) return;
+ if (stage == Stage.RUNNING) return;
+ stage = Stage.RUNNING;
+ if (recorder != null) {
+ recorder.stop();
+ recorder = null;
+ }
+ if (elements.isEmpty()) {
+ p.sendMessage("§cEs wurden keine Elemente aufgenommen!");
+ stop();
+ return;
+ }
+ elements.get(currentElement).execute(this::next);
+ }
+
+ public void pause() {
+ if (stage == Stage.END) return;
+ if (stage == Stage.PAUSE) return;
+ stage = Stage.PAUSE;
+ if (recorder != null) {
+ recorder.stop();
+ recorder = null;
+ }
+ }
+
+ public void stop() {
+ stage = Stage.END;
+ if (recorder != null) {
+ recorder.stop();
+ recorder = null;
+ }
+ elements.clear();
+ LOADER_MAP.remove(p);
+ }
+
+ public void settings() {
+ List> list = new ArrayList<>();
+ for (LoaderElement element : elements) {
+ list.add(new SWListInv.SWListEntry<>(element.menu(p), element));
+ }
+ new SWListInv<>(p, "Loader Settings", false, list, (clickType, entry) -> {
+ entry.click(p, this::settings);
+ }).open();
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ if (event.getPlayer() != p) return;
+ stop();
+ }
+
+ public enum Stage {
+ SETUP,
+ RUNNING,
+ PAUSE,
+ END
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderCommand.java
new file mode 100644
index 00000000..6539d16a
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderCommand.java
@@ -0,0 +1,92 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+import de.steamwar.command.SWCommand;
+import de.steamwar.command.TypeValidator;
+import de.steamwar.linkage.Linked;
+import org.bukkit.entity.Player;
+
+@Linked
+public class LoaderCommand extends SWCommand {
+
+ public LoaderCommand() {
+ super("loader");
+ }
+
+ private boolean loaderNullCheck(Loader loader, Player p) {
+ if (loader == null) {
+ BauSystem.MESSAGE.send("LOADER_NO_LOADER", p);
+ return true;
+ }
+ return false;
+ }
+
+ @Register(value = "setup", description = "LOADER_HELP_SETUP")
+ public void setupLoader(@Validator Player player) {
+ if (Loader.getLoader(player) != null) {
+ player.sendMessage("Please stop the current loader first!");
+ return;
+ }
+ Loader.newLoader(player);
+ BauSystem.MESSAGE.send("LOADER_NEW", player);
+ BauSystem.MESSAGE.send("LOADER_HOW_TO_START", player);
+ }
+
+ @Register(value = "start", description = "LOADER_HELP_START")
+ public void startLoader(@Validator Player player) {
+ Loader loader = Loader.getLoader(player);
+ if (loaderNullCheck(loader, player)) return;
+ loader.start();
+ BauSystem.MESSAGE.send("LOADER_ACTIVE", player);
+ }
+
+ @Register(value = "stop", description = "LOADER_HELP_STOP")
+ public void stopLoader(@Validator Player player) {
+ Loader loader = Loader.getLoader(player);
+ if (loaderNullCheck(loader, player)) return;
+ loader.stop();
+ BauSystem.MESSAGE.send("LOADER_STOP", player);
+ }
+
+ @Register(value = "pause", description = "LOADER_HELP_PAUSE")
+ public void pauseLoader(@Validator Player player) {
+ Loader loader = Loader.getLoader(player);
+ if (loaderNullCheck(loader, player)) return;
+ loader.pause();
+ BauSystem.MESSAGE.send("LOADER_PAUSED", player);
+ }
+
+ @Register(value = "settings", description = "LOADER_HELP_PAUSE")
+ public void settingsLoader(@Validator Player player) {
+ Loader loader = Loader.getLoader(player);
+ if (loaderNullCheck(loader, player)) return;
+ loader.settings();
+ }
+
+ @ClassValidator(value = Player.class, local = true)
+ public TypeValidator loaderValidator() {
+ return (commandSender, player, messageSender) -> {
+ return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "LOADER_PERMS");
+ };
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java
new file mode 100644
index 00000000..4bc9f071
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/LoaderRecorder.java
@@ -0,0 +1,187 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.loadern.elements.LoaderElement;
+import de.steamwar.bausystem.features.loadern.elements.impl.*;
+import de.steamwar.bausystem.features.tpslimit.TPSUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.HandlerList;
+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.event.player.PlayerMoveEvent;
+import org.bukkit.inventory.EquipmentSlot;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class LoaderRecorder implements Listener {
+
+ private Player player;
+ private List loaderElementList;
+ private Set blockSet = new HashSet<>();
+ private long lastInteraction = TPSUtils.currentTick.get();
+
+ public LoaderRecorder(Player player, List loaderElementList) {
+ this.player = player;
+ this.loaderElementList = loaderElementList;
+ Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
+ }
+
+ public void stop() {
+ addWaitTime(true);
+ HandlerList.unregisterAll(this);
+ player = null;
+ blockSet.clear();
+ }
+
+ private void addWaitTime(boolean last) {
+ if (loaderElementList.isEmpty()) {
+ lastInteraction = TPSUtils.currentTick.get();
+ return;
+ }
+ if (loaderElementList.get(loaderElementList.size() - 1) instanceof LoaderWait) {
+ return;
+ }
+ long diff = TPSUtils.currentTick.get() - lastInteraction;
+ if (last && diff > 160) diff = 160;
+ lastInteraction = TPSUtils.currentTick.get();
+ loaderElementList.add(new LoaderWait(diff));
+ }
+
+ @EventHandler
+ public void onBlockPlace(BlockPlaceEvent event) {
+ if (event.getPlayer() != player) return;
+ if (event.getBlock().getType() != Material.TNT) return;
+
+ addWaitTime(false);
+ loaderElementList.add(new LoaderTNT(event.getBlock().getLocation()));
+ }
+
+ @EventHandler
+ public void onPlayerInteractEntity(PlayerInteractEvent event) {
+ if (event.getPlayer() != player) return;
+ if (player.isSneaking()) return;
+ if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) return;
+ if (event.getClickedBlock().getType() == Material.OBSERVER) return;
+ if (event.getHand() == EquipmentSlot.OFF_HAND) return;
+
+ addWaitTime(false);
+ Block block = event.getClickedBlock();
+ Material type = block.getType();
+ switch (type) {
+ case COMPARATOR:
+ loaderElementList.add(new LoaderComparator(block.getLocation()));
+ break;
+ case REPEATER:
+ loaderElementList.add(new LoaderRepeater(block.getLocation()));
+ break;
+ case NOTE_BLOCK:
+ loaderElementList.add(new LoaderNoteBlock(block.getLocation()));
+ break;
+ case LEVER:
+ loaderElementList.add(new LoaderLever(block.getLocation()));
+ break;
+ case DAYLIGHT_DETECTOR:
+ loaderElementList.add(new LoaderDaylightDetector(block.getLocation()));
+ break;
+ case LECTERN:
+ loaderElementList.add(new LoaderLectern(block.getLocation()));
+ break;
+ case IRON_TRAPDOOR:
+ break;
+ default:
+ if (type.name().endsWith("_TRAPDOOR")) {
+ loaderElementList.add(new LoaderOpenable(block.getLocation(), "Trapdoor", type));
+ } else if (type.name().endsWith("_DOOR")) {
+ loaderElementList.add(new LoaderOpenable(block.getLocation(), "Door", type));
+ } else if (type.name().endsWith("FENCE_GATE")) {
+ loaderElementList.add(new LoaderOpenable(block.getLocation(), "Fencegate", type));
+ } else if (type.name().endsWith("STONE_BUTTON")) {
+ loaderElementList.add(new LoaderTicks(block.getLocation(), "Stone Button", type, 20));
+ } else if (type.name().endsWith("BUTTON")) {
+ loaderElementList.add(new LoaderTicks(block.getLocation(), "Wooden Button", type, 30));
+ }
+ break;
+ }
+ }
+
+ @EventHandler
+ public void onPlayerMove(PlayerMoveEvent event) {
+ if (event.getPlayer() != player) return;
+
+ Block fromBlock = event.getTo().getBlock();
+ Block toBlock = event.getTo().getBlock();
+ if (!blockSet.contains(toBlock.getLocation())) {
+ blockSet.remove(fromBlock.getLocation());
+ blockSet.add(toBlock.getLocation());
+
+ addWaitTime(false);
+ Material type = toBlock.getType();
+ switch (type) {
+ case TRIPWIRE:
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Tripwire", Material.STRING, 30));
+ break;
+ case LIGHT_WEIGHTED_PRESSURE_PLATE:
+ case HEAVY_WEIGHTED_PRESSURE_PLATE:
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Weighted Pressure Plate", type, 20));
+ break;
+ default:
+ if (type.name().endsWith("PRESSURE_PLATE")) {
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Pressure Plate", type, 30));
+ }
+ break;
+ }
+ }
+
+ fromBlock = fromBlock.getRelative(0, 1, 0);
+ toBlock = toBlock.getRelative(0, 1, 0);
+ if (!blockSet.contains(toBlock.getLocation())) {
+ blockSet.remove(fromBlock.getLocation());
+ blockSet.add(toBlock.getLocation());
+
+ addWaitTime(false);
+ Material type = toBlock.getType();
+ switch (type) {
+ case TRIPWIRE:
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Tripwire", Material.STRING, 30));
+ break;
+ case LIGHT_WEIGHTED_PRESSURE_PLATE:
+ case HEAVY_WEIGHTED_PRESSURE_PLATE:
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Weighted Pressure Plate", type, 20));
+ break;
+ default:
+ if (type.name().endsWith("PRESSURE_PLATE")) {
+ loaderElementList.add(new LoaderTicks(toBlock.getLocation(), "Pressure Plate", type, 30));
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/ElementSettings.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/ElementSettings.java
new file mode 100644
index 00000000..5142e8cf
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/ElementSettings.java
@@ -0,0 +1,31 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements;
+
+import de.steamwar.inventory.SWItem;
+import org.bukkit.entity.Player;
+
+public interface ElementSettings {
+ SWItem menu(Player player);
+ void execute(Runnable nextAction);
+ void click(Player player, Runnable backAction, Runnable deleteAction);
+
+ default void playerInteract() {}
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderElement.java
new file mode 100644
index 00000000..4b1734bd
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderElement.java
@@ -0,0 +1,29 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements;
+
+import de.steamwar.inventory.SWItem;
+import org.bukkit.entity.Player;
+
+public interface LoaderElement {
+ SWItem menu(Player player);
+ void execute(Runnable nextAction);
+ void click(Player player, Runnable backAction);
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderInteractionElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderInteractionElement.java
new file mode 100644
index 00000000..7785f07b
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/LoaderInteractionElement.java
@@ -0,0 +1,116 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements;
+
+import de.steamwar.bausystem.features.loader.LoaderButton;
+import de.steamwar.inventory.SWItem;
+import de.steamwar.inventory.SWListInv;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.block.data.FaceAttachable;
+import org.bukkit.block.data.type.Switch;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class LoaderInteractionElement implements LoaderElement {
+
+ protected final Location location;
+ protected int currentShot = 0;
+ protected List elements = new ArrayList<>();
+
+ protected LoaderInteractionElement(Location location) {
+ this.location = location;
+
+ T element = createNewElement();
+ element.playerInteract();
+ elements.add(element);
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ if (currentShot >= elements.size()) currentShot = 0;
+ elements.get(currentShot).execute(nextAction);
+ currentShot++;
+ if (currentShot >= elements.size()) currentShot = 0;
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction) {
+ List> entries = new ArrayList<>();
+ for (T element : elements) {
+ entries.add(new SWListInv.SWListEntry<>(element.menu(player), element));
+ }
+
+ SWListInv listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {
+ entry.click(player, () -> {
+ click(player, backAction);
+ }, () -> {
+ if (elements.size() == 1) return;
+ elements.remove(entry);
+ click(player, backAction);
+ });
+ });
+ listInv.setItem(48, new SWItem(Material.ARROW, "§7Back", clickType -> {
+ backAction.run();
+ }));
+ listInv.setItem(50, new SWItem(Material.GHAST_SPAWN_EGG, "§7Insert another", clickType -> {
+ T element = createNewElement();
+ elements.add(element);
+ element.click(player, () -> click(player, backAction), () -> {
+ if (elements.size() == 1) return;
+ elements.remove(element);
+ click(player, backAction);
+ });
+ }));
+ listInv.open();
+ }
+
+ protected void update(Block block) {
+ Material material = block.getType();
+ if (block.getBlockData() instanceof Switch) {
+ Switch sw = (Switch) block.getBlockData();
+ FaceAttachable.AttachedFace face = sw.getAttachedFace();
+ if (face == FaceAttachable.AttachedFace.FLOOR) {
+ updateBlock(block.getRelative(BlockFace.DOWN));
+ } else if (face == FaceAttachable.AttachedFace.CEILING) {
+ updateBlock(block.getRelative(BlockFace.UP));
+ } else {
+ updateBlock(block.getRelative(sw.getFacing().getOppositeFace()));
+ }
+ } else if (material == Material.TRIPWIRE) {
+ updateBlock(block);
+ } else if (material.name().endsWith("_PLATE")) {
+ updateBlock(block.getRelative(BlockFace.DOWN));
+ }
+ }
+
+ protected void updateBlock(Block block) {
+ BlockData data = block.getBlockData();
+ block.setType(Material.BARRIER, true);
+ block.setBlockData(data, true);
+ }
+
+ public abstract T createNewElement();
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderComparator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderComparator.java
new file mode 100644
index 00000000..d92ea4ad
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderComparator.java
@@ -0,0 +1,135 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.type.Comparator;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderComparator extends LoaderInteractionElement {
+
+ public LoaderComparator(Location location) {
+ super(location);
+ }
+
+ public class ComparatorSettings implements ElementSettings {
+
+ private boolean interact = false;
+ private Comparator.Mode mode = Comparator.Mode.COMPARE;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, interact, mode);
+ }
+
+ private SWItem menu(Player player, boolean interact, Comparator.Mode mode) {
+ SWItem swItem;
+ if (interact) {
+ swItem = new SWItem(Material.STICK, "§7Comparator§8: §eInteract");
+ } else if (mode == null) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Comparator§8: §eNOOP");
+ } else {
+ swItem = new SWItem(Material.COMPARATOR, "§7Comparator§8: §e" + mode.name());
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.COMPARATOR) return;
+ Comparator comparator = (Comparator) location.getBlock().getBlockData();
+ if (interact) {
+ comparator.setMode(comparator.getMode() == Comparator.Mode.COMPARE ? Comparator.Mode.SUBTRACT : Comparator.Mode.COMPARE);
+ } else if (mode == null) {
+ return;
+ } else {
+ comparator.setMode(mode);
+ }
+ location.getBlock().setBlockData(comparator, true);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 18, "Settings");
+ for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(2, item(player, true, null).getItemStack(), clickType -> {
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(3, item(player, false, null).getItemStack(), clickType -> {
+ interact = false;
+ mode = null;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, Comparator.Mode.COMPARE).getItemStack(), clickType -> {
+ interact = false;
+ mode = Comparator.Mode.COMPARE;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, Comparator.Mode.SUBTRACT).getItemStack(), clickType -> {
+ interact = false;
+ mode = Comparator.Mode.SUBTRACT;
+ click(player, backAction, deleteAction);
+ });
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean interact, Comparator.Mode mode) {
+ SWItem swItem = menu(player, interact, mode);
+ if (swItem.getItemStack().equals(menu(player, this.interact, this.mode).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+
+ @Override
+ public void playerInteract() {
+ interact = true;
+ mode = null;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.COMPARATOR, "§7Comparator");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public ComparatorSettings createNewElement() {
+ return new ComparatorSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderDaylightDetector.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderDaylightDetector.java
new file mode 100644
index 00000000..cbdcc7dc
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderDaylightDetector.java
@@ -0,0 +1,159 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.type.DaylightDetector;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderDaylightDetector extends LoaderInteractionElement {
+
+ public LoaderDaylightDetector(Location location) {
+ super(location);
+ }
+
+ public class DaylightDetectorSettings implements ElementSettings {
+
+ private boolean noop = false;
+ private boolean interact = false;
+ private boolean inverted = true;
+ private int power = 0;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, noop, interact, inverted);
+ }
+
+ private SWItem menu(Player player, boolean noop, boolean interact, boolean powered) {
+ SWItem swItem;
+ if (noop) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Daylight Detector§8: §eNOOP");
+ } else if (interact) {
+ swItem = new SWItem(Material.STICK, "§7Daylight Detector§8: §eInteract");
+ } else {
+ swItem = new SWItem(Material.DAYLIGHT_DETECTOR, "§7Daylight Detector§8: §e" + (powered ? "Powered" : "Unpowered"));
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.DAYLIGHT_DETECTOR) return;
+ DaylightDetector daylightDetector = (DaylightDetector) location.getBlock().getBlockData();
+ if (noop) {
+ return;
+ } else if (interact) {
+ daylightDetector.setInverted(!daylightDetector.isInverted());
+ } else {
+ daylightDetector.setInverted(inverted);
+ }
+ daylightDetector.setPower(daylightDetector.isInverted() ? 15 - power : power);
+ location.getBlock().setBlockData(daylightDetector);
+ update(location.getBlock().getRelative(0, -1, 0));
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 36, "Settings");
+ for (int i = 27; i < 35; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(27, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(35, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
+ noop = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ inverted = false;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ inverted = true;
+ click(player, backAction, deleteAction);
+ });
+
+ for (int i = 0; i < 16; i++) {
+ int finalI = i;
+ int finalI2 = i;
+ if (i >= 9) finalI2++;
+ swInventory.setItem(finalI2 + 9, item(player, finalI).getItemStack(), clickType -> {
+ power = finalI;
+ click(player, backAction, deleteAction);
+ });
+ }
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean noop, boolean interact, boolean inverted) {
+ SWItem swItem = menu(player, noop, interact, inverted);
+ if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.inverted).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+
+ private SWItem item(Player player, int power) {
+ SWItem swItem = new SWItem(power == 0 ? Material.GUNPOWDER : Material.REDSTONE, "§7Power §8:§e " + power);
+ swItem.getItemStack().setAmount(power == 0 ? 1 : power);
+ if (!this.noop && this.power == power) swItem.setEnchanted(true);
+ return swItem;
+ }
+
+ @Override
+ public void playerInteract() {
+ noop = false;
+ interact = true;
+ inverted = false;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.DAYLIGHT_DETECTOR, "§7Daylight Detector");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public DaylightDetectorSettings createNewElement() {
+ return new DaylightDetectorSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLectern.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLectern.java
new file mode 100644
index 00000000..033d936a
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLectern.java
@@ -0,0 +1,155 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Lectern;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.meta.BookMeta;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderLectern extends LoaderInteractionElement {
+
+
+ public LoaderLectern(Location location) {
+ super(location);
+ }
+
+ public class LecternSettings implements ElementSettings {
+
+ private boolean noop = true;
+ private LecternAction action = LecternAction.PAGE_NEXT;
+ private int page = 0;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, noop, action, page);
+ }
+
+ private SWItem menu(Player player, boolean noop, LecternAction action, int page) {
+ SWItem swItem;
+ if (noop) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Lectern§8: §eNOOP");
+ } else if (action == LecternAction.PAGE_PREV) {
+ swItem = new SWItem(Material.STICK, "§7Lectern§8: §ePage Prev");
+ } else if (action == LecternAction.PAGE_NEXT) {
+ swItem = new SWItem(Material.STICK, "§7Lectern§8: §ePage Next");
+ } else {
+ swItem = new SWItem(Material.LECTERN, "§7Lectern§8: §ePage " + page);
+ swItem.getItemStack().setAmount(page);
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.LECTERN) return;
+ Lectern lectern = (Lectern) location.getBlock().getState();
+ if (!((org.bukkit.block.data.type.Lectern) lectern.getBlockData()).hasBook()) return;
+ int pages = ((BookMeta) lectern.getInventory().getItem(0).getItemMeta()).getPages().size();
+ if (noop) {
+ return;
+ } else if (action == LecternAction.PAGE_PREV) {
+ int page = lectern.getPage();
+ if (page > 1) lectern.setPage(page - 1);
+ } else if (action == LecternAction.PAGE_NEXT) {
+ int page = lectern.getPage();
+ if (page < pages) lectern.setPage(page + 1);
+ } else if (action == LecternAction.PAGE_SET) {
+ if (page <= pages) lectern.setPage(page);
+ }
+ lectern.update(false, true);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 36, "Settings");
+ for (int i = 27; i < 35; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(27, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(35, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(3, item(player, true, LecternAction.PAGE_SET, 0).getItemStack(), clickType -> {
+ noop = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, LecternAction.PAGE_PREV, 0).getItemStack(), clickType -> {
+ noop = false;
+ action = LecternAction.PAGE_PREV;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, LecternAction.PAGE_NEXT, 0).getItemStack(), clickType -> {
+ noop = false;
+ action = LecternAction.PAGE_NEXT;
+ click(player, backAction, deleteAction);
+ });
+
+ for (int i = 0; i < 15; i++) {
+ int finalI = i;
+ int finalI2 = i;
+ if (i >= 9) finalI2++;
+ if (i >= 12) finalI2++;
+ swInventory.setItem(finalI2 + 9, item(player, false, LecternAction.PAGE_SET, finalI + 1).getItemStack(), clickType -> {
+ noop = false;
+ action = LecternAction.PAGE_SET;
+ page = finalI + 1;
+ click(player, backAction, deleteAction);
+ });
+ }
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean noop, LecternAction action, int page) {
+ SWItem swItem = menu(player, noop, action, page);
+ if (swItem.getItemStack().equals(menu(player, this.noop, this.action, this.page).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+ }
+
+ public enum LecternAction {
+ PAGE_NEXT,
+ PAGE_PREV,
+ PAGE_SET
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.LECTERN, "§7Lectern");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public LecternSettings createNewElement() {
+ return new LecternSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLever.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLever.java
new file mode 100644
index 00000000..8bd0d7b0
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderLever.java
@@ -0,0 +1,132 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.type.Switch;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderLever extends LoaderInteractionElement {
+
+ public LoaderLever(Location location) {
+ super(location);
+ }
+
+ public class LeverSettings implements ElementSettings {
+
+ private boolean noop = false;
+ private boolean interact = false;
+ private boolean power = false;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, noop, interact, power);
+ }
+
+ private SWItem menu(Player player, boolean noop, boolean interact, boolean power) {
+ SWItem swItem;
+ if (noop) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Lever§8: §eNOOP");
+ } else if (interact) {
+ swItem = new SWItem(Material.STICK, "§7Lever§8: §eInteract");
+ } else {
+ swItem = new SWItem(Material.LEVER, "§7Lever§8: §e" + (power ? "Active" : "Inactive"));
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.LEVER) return;
+ if (noop) return;
+
+ Switch lever = (Switch) location.getBlock().getBlockData();
+ if (interact) {
+ lever.setPowered(!lever.isPowered());
+ } else {
+ lever.setPowered(power);
+ }
+ location.getBlock().setBlockData(lever);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 18, "Settings");
+ for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
+ noop = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ power = false;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ power = true;
+ click(player, backAction, deleteAction);
+ });
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean noop, boolean interact, boolean power) {
+ SWItem swItem = menu(player, noop, interact, power);
+ if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.power).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.LEVER, "§7Lever");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public LeverSettings createNewElement() {
+ return new LeverSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderNoteBlock.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderNoteBlock.java
new file mode 100644
index 00000000..5f062f87
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderNoteBlock.java
@@ -0,0 +1,115 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Instrument;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.type.NoteBlock;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderNoteBlock extends LoaderInteractionElement {
+
+ public LoaderNoteBlock(Location location) {
+ super(location);
+ }
+
+ public class NoteBlockSettings implements ElementSettings {
+
+ private boolean interact = true;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, interact);
+ }
+
+ private SWItem menu(Player player, boolean interact) {
+ SWItem swItem;
+ if (interact) {
+ swItem = new SWItem(Material.NOTE_BLOCK, "§7Note Block§8: §eInteract");
+ } else {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Note Block§8: §eNOOP");
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.NOTE_BLOCK) return;
+ NoteBlock noteBlock = (NoteBlock) location.getBlock().getBlockData();
+ if (interact) {
+ if (noteBlock.getInstrument() == Instrument.BANJO) noteBlock.setInstrument(Instrument.BIT);
+ else noteBlock.setInstrument(Instrument.BANJO);
+ } else {
+ return;
+ }
+ location.getBlock().setBlockData(noteBlock);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 18, "Settings");
+ for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(3, item(player, false).getItemStack(), clickType -> {
+ interact = false;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, true).getItemStack(), clickType -> {
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean interact) {
+ SWItem swItem = menu(player, interact);
+ if (swItem.getItemStack().equals(menu(player, this.interact).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.NOTE_BLOCK, "§7Note Block");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public NoteBlockSettings createNewElement() {
+ return new NoteBlockSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderOpenable.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderOpenable.java
new file mode 100644
index 00000000..1fc45d69
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderOpenable.java
@@ -0,0 +1,138 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.Openable;
+import org.bukkit.block.data.type.TrapDoor;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderOpenable extends LoaderInteractionElement {
+
+ private String name;
+ private Material material;
+
+ public LoaderOpenable(Location location, String name, Material material) {
+ super(location);
+ this.name = name;
+ this.material = material;
+ }
+
+ public class TrapdoorSettings implements ElementSettings {
+
+ private boolean noop = false;
+ private boolean interact = true;
+ private boolean open = false;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, noop, interact, open);
+ }
+
+ private SWItem menu(Player player, boolean noop, boolean interact, boolean powered) {
+ SWItem swItem;
+ if (noop) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7" + name +"§8: §eNOOP");
+ } else if (interact) {
+ swItem = new SWItem(Material.STICK, "§7" + name + "§8: §eInteract");
+ } else {
+ swItem = new SWItem(material, "§7" + name + "§8: §e" + (powered ? "Open" : "Closed"));
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != material) return;
+ Openable openable = (Openable) location.getBlock().getBlockData();
+ if (noop) {
+ return;
+ } else if (interact) {
+ openable.setOpen(!openable.isOpen());
+ } else {
+ openable.setOpen(open);
+ }
+ location.getBlock().setBlockData(openable);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 18, "Settings");
+ for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(2, item(player, true, false, false).getItemStack(), clickType -> {
+ noop = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(3, item(player, false, true, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, false, false).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ open = false;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, false, true).getItemStack(), clickType -> {
+ noop = false;
+ interact = false;
+ open = true;
+ click(player, backAction, deleteAction);
+ });
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean noop, boolean interact, boolean open) {
+ SWItem swItem = menu(player, noop, interact, open);
+ if (swItem.getItemStack().equals(menu(player, this.noop, this.interact, this.open).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(material, "§7" + name);
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public TrapdoorSettings createNewElement() {
+ return new TrapdoorSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderRepeater.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderRepeater.java
new file mode 100644
index 00000000..a0e50e48
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderRepeater.java
@@ -0,0 +1,149 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.type.Repeater;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderRepeater extends LoaderInteractionElement {
+
+ public LoaderRepeater(Location location) {
+ super(location);
+ }
+
+ public class RepeaterSettings implements ElementSettings {
+
+ private boolean interact = false;
+ private int delay = 1;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, interact, delay);
+ }
+
+ private SWItem menu(Player player, boolean interact, int delay) {
+ SWItem swItem;
+ if (interact) {
+ swItem = new SWItem(Material.STICK, "§7Repeater§8: §eInteract");
+ } else if (delay == 0) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7Repeater§8: §eNOOP");
+ } else {
+ swItem = new SWItem(Material.REPEATER, "§7Repeater§8: §e" + delay);
+ swItem.getItemStack().setAmount(delay);
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ nextAction.run();
+ if (location.getBlock().getType() != Material.REPEATER) return;
+ Repeater repeater = (Repeater) location.getBlock().getBlockData();
+ if (interact) {
+ int delay = repeater.getDelay();
+ delay++;
+ if (delay > 4) delay = 1;
+ repeater.setDelay(delay);
+ } else if (delay == 0) {
+ return;
+ } else {
+ repeater.setDelay(delay);
+ }
+ location.getBlock().setBlockData(repeater, true);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, 18, "Settings");
+ for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(1, item(player, true, -1).getItemStack(), clickType -> {
+ interact = true;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(2, item(player, false, 0).getItemStack(), clickType -> {
+ interact = false;
+ delay = 0;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(4, item(player, false, 1).getItemStack(), clickType -> {
+ interact = false;
+ delay = 1;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(5, item(player, false, 2).getItemStack(), clickType -> {
+ interact = false;
+ delay = 2;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, 3).getItemStack(), clickType -> {
+ interact = false;
+ delay = 3;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(7, item(player, false, 4).getItemStack(), clickType -> {
+ interact = false;
+ delay = 4;
+ click(player, backAction, deleteAction);
+ });
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean interact, int delay) {
+ SWItem swItem = menu(player, interact, delay);
+ if (swItem.getItemStack().equals(menu(player, this.interact, this.delay).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+
+ @Override
+ public void playerInteract() {
+ interact = true;
+ delay = 0;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.REPEATER, "§7Repeater");
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public RepeaterSettings createNewElement() {
+ return new RepeaterSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTNT.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTNT.java
new file mode 100644
index 00000000..92c2bd4e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTNT.java
@@ -0,0 +1,63 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.loadern.elements.LoaderElement;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+
+public class LoaderTNT implements LoaderElement {
+
+ private Location location;
+
+ public LoaderTNT(Location location) {
+ this.location = location;
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem item = new SWItem(Material.TNT, "§cTNT");
+ item.setLore(Arrays.asList("§7X§8: " + location.getBlockX(), "§7Y§8: " + location.getBlockY(), "§7Z§8: " + location.getBlockZ()));
+ return item;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ Block block = location.getBlock();
+ if (block.getType() != Material.AIR && block.getType() != Material.WATER) {
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> execute(nextAction), 1);
+ return;
+ }
+
+ block.setType(Material.TNT, true);
+ nextAction.run();
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction) {
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java
new file mode 100644
index 00000000..54e63d34
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderTicks.java
@@ -0,0 +1,191 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.loadern.elements.ElementSettings;
+import de.steamwar.bausystem.features.loadern.elements.LoaderInteractionElement;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.AnaloguePowerable;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.block.data.Powerable;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoaderTicks extends LoaderInteractionElement {
+
+ protected String name;
+ protected Material material;
+ protected boolean analogue;
+ protected int ticks;
+
+ public LoaderTicks(Location location, String name, Material material, int ticks) {
+ super(location);
+ this.name = name;
+ this.material = material;
+ this.analogue = location.getBlock().getBlockData() instanceof AnaloguePowerable;
+ this.ticks = ticks;
+ }
+
+ public class StoneButtonSettings implements ElementSettings {
+
+ private boolean noop = false;
+ private boolean waitFor = true;
+ private int power = 0;
+
+ @Override
+ public SWItem menu(Player player) {
+ return menu(player, noop, waitFor);
+ }
+
+ private SWItem menu(Player player, boolean noop, boolean waitFor) {
+ SWItem swItem;
+ if (noop) {
+ swItem = new SWItem(Material.STRUCTURE_VOID, "§7" + name + "§8: §eNOOP");
+ } else if (waitFor) {
+ swItem = new SWItem(material, "§7" + name + "§8: §eWaitFor");
+ } else {
+ swItem = new SWItem(material, "§7" + name + "§8: §eNoWaitFor");
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ if (location.getBlock().getType() != material) {
+ nextAction.run();
+ return;
+ }
+ if (noop) {
+ nextAction.run();
+ return;
+ }
+
+ BlockData blockData = location.getBlock().getBlockData();
+ if (blockData instanceof AnaloguePowerable) {
+ AnaloguePowerable analoguePowerable = (AnaloguePowerable) location.getBlock().getBlockData();
+ analoguePowerable.setPower(power);
+ } else if (blockData instanceof Powerable) {
+ Powerable powerable = (Powerable) location.getBlock().getBlockData();
+ if (ticks < 0) {
+ powerable.setPowered(power > 0);
+ } else {
+ powerable.setPowered(true);
+ }
+ }
+
+ location.getBlock().setBlockData(blockData);
+ update(location.getBlock());
+ if (ticks >= 0) {
+ boolean finalWaitFor = waitFor;
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ if (blockData instanceof AnaloguePowerable) {
+ ((AnaloguePowerable) blockData).setPower(0);
+ } else {
+ ((Powerable) blockData).setPowered(false);
+ }
+ location.getBlock().setBlockData(blockData);
+ update(location.getBlock());
+ if (finalWaitFor) {
+ nextAction.run();
+ }
+ }, ticks);
+ if (!finalWaitFor) {
+ nextAction.run();
+ }
+ }
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction, Runnable deleteAction) {
+ SWInventory swInventory = new SWInventory(player, analogue ? 36 : 18, "Settings");
+ for (int i = analogue ? 27 : 9; i < (analogue ? 35 : 18); i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
+ swInventory.setItem(analogue ? 27 : 9, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+ swInventory.setItem(analogue ? 35 : 17, new SWItem(Material.BARRIER, "§cDelete").getItemStack(), clickType -> deleteAction.run());
+
+ swInventory.setItem(3, item(player, true, false).getItemStack(), clickType -> {
+ noop = true;
+ click(player, backAction, deleteAction);
+ });
+ if (ticks >= 0) {
+ swInventory.setItem(5, item(player, false, false).getItemStack(), clickType -> {
+ noop = false;
+ waitFor = false;
+ click(player, backAction, deleteAction);
+ });
+ swInventory.setItem(6, item(player, false, true).getItemStack(), clickType -> {
+ noop = false;
+ waitFor = true;
+ click(player, backAction, deleteAction);
+ });
+ }
+
+ if (analogue) {
+ for (int i = 0; i < 16; i++) {
+ int finalI = i;
+ int finalI2 = i;
+ if (i >= 9) finalI2++;
+ swInventory.setItem(finalI2 + 9, item(player, finalI).getItemStack(), clickType -> {
+ power = finalI;
+ click(player, backAction, deleteAction);
+ });
+ }
+ }
+
+ swInventory.open();
+ }
+
+ private SWItem item(Player player, boolean noop, boolean waitFor) {
+ SWItem swItem = menu(player, noop, waitFor);
+ if (swItem.getItemStack().equals(menu(player, this.noop, this.waitFor).getItemStack())) {
+ swItem.setEnchanted(true);
+ }
+ swItem.setLore(Collections.emptyList());
+ return swItem;
+ }
+
+ private SWItem item(Player player, int power) {
+ SWItem swItem = new SWItem(power == 0 ? Material.GUNPOWDER : Material.REDSTONE, "§7Power §8:§e " + power);
+ swItem.getItemStack().setAmount(power == 0 ? 1 : power);
+ if (!this.noop && this.power == power) swItem.setEnchanted(true);
+ return swItem;
+ }
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(material, "§7" + name);
+ swItem.setLore(Arrays.asList("§7Modes§8: §e" + elements.size(), "§8", "§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public StoneButtonSettings createNewElement() {
+ return new StoneButtonSettings();
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderWait.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderWait.java
new file mode 100644
index 00000000..5b263af9
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadern/elements/impl/LoaderWait.java
@@ -0,0 +1,88 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 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.loadern.elements.impl;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.loadern.elements.LoaderElement;
+import de.steamwar.inventory.SWAnvilInv;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+
+import java.util.Arrays;
+
+public class LoaderWait implements LoaderElement, Listener {
+
+ private long delay;
+
+ public LoaderWait(long delay) {
+ this.delay = delay;
+ }
+
+ @Override
+ public SWItem menu(Player player) {
+ SWItem swItem = new SWItem(Material.CLOCK, "§7Wartezeit: §e" + delay + " Ticks");
+ swItem.getItemStack().setAmount((int) Math.max(Math.min(delay, 64), 1));
+ if (delay == 0) swItem.setEnchanted(true);
+ swItem.setLore(Arrays.asList("§7Click to edit"));
+ return swItem;
+ }
+
+ @Override
+ public void execute(Runnable nextAction) {
+ if (delay == 0) {
+ nextAction.run();
+ return;
+ }
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), nextAction, delay);
+ }
+
+ @Override
+ public void click(Player player, Runnable backAction) {
+ SWInventory swInventory = new SWInventory(player, 9, "Wartezeit");
+ swInventory.setItem(0, new SWItem(Material.ARROW, "§8Back").getItemStack(), clickType -> backAction.run());
+
+ swInventory.setItem(3, new SWItem(SWItem.getDye(1), "§c-1").getItemStack(), clickType -> {
+ delay -= clickType.isShiftClick() ? 5 : 1;
+ if (delay < 0) delay = 0;
+ swInventory.setItem(4, menu(player));
+ });
+ swInventory.setItem(4, menu(player).getItemStack(), clickType -> {
+ SWAnvilInv swAnvilInv = new SWAnvilInv(player, "§7Wartezeit", delay + "");
+ swAnvilInv.setCallback(s -> {
+ try {
+ delay = Long.parseLong(s);
+ } catch (NumberFormatException ignored) {
+ }
+ click(player, backAction);
+ });
+ swAnvilInv.open();
+ });
+ swInventory.setItem(5, new SWItem(SWItem.getDye(10), "§a+1").getItemStack(), clickType -> {
+ delay += clickType.isShiftClick() ? 5 : 1;
+ swInventory.setItem(4, menu(player));
+ });
+
+ swInventory.open();
+ }
+}