diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java
new file mode 100644
index 00000000..485bcd83
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/SimulatorCursor.java
@@ -0,0 +1,199 @@
+/*
+ * 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.simulator2;
+
+import com.comphenix.tinyprotocol.Reflection;
+import com.comphenix.tinyprotocol.TinyProtocol;
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.SWUtils;
+import de.steamwar.bausystem.utils.ItemUtils;
+import de.steamwar.bausystem.utils.RayTraceUtils;
+import de.steamwar.entity.REntity;
+import de.steamwar.entity.REntityServer;
+import de.steamwar.entity.RFallingBlockEntity;
+import de.steamwar.linkage.Linked;
+import de.steamwar.linkage.api.Plain;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.BlockFace;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerItemHeldEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+@Linked
+public class SimulatorCursor implements Plain, Listener {
+
+ private final World WORLD = Bukkit.getWorlds().get(0);
+ private Class> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
+ private Class> look = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInLook");
+ private Class> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
+
+ private Map cursors = new HashMap<>();
+
+ public static boolean isSimulatorItem(ItemStack itemStack) {
+ return ItemUtils.isItem(itemStack, "simulator");
+ }
+
+ public SimulatorCursor() {
+ BiFunction function = (player, object) -> {
+ if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
+ removeCursor(player);
+ return object;
+ }
+ RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>());
+ if (rayTraceResult == null) {
+ removeCursor(player);
+ return object;
+ }
+
+ showCursor(player, rayTraceResult);
+ return object;
+ };
+ TinyProtocol.instance.addFilter(position, function);
+ TinyProtocol.instance.addFilter(look, function);
+ TinyProtocol.instance.addFilter(positionLook, function);
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+ if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
+ return;
+ }
+ RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>());
+ if (rayTraceResult == null) {
+ return;
+ }
+
+ showCursor(player, rayTraceResult);
+ }
+
+ @EventHandler
+ public void onPlayerDropItem(PlayerDropItemEvent event) {
+ Player player = event.getPlayer();
+ if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
+ removeCursor(player);
+ return;
+ }
+ RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>());
+ if (rayTraceResult == null) {
+ removeCursor(player);
+ return;
+ }
+
+ showCursor(player, rayTraceResult);
+ }
+
+ @EventHandler
+ public void onPlayerItemHeld(PlayerItemHeldEvent event) {
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ Player player = event.getPlayer();
+ if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
+ removeCursor(player);
+ return;
+ }
+ RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), new ArrayList<>());
+ if (rayTraceResult == null) {
+ removeCursor(player);
+ return;
+ }
+
+ showCursor(player, rayTraceResult);
+ }, 1);
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ cursors.remove(event.getPlayer());
+ }
+
+ private void removeCursor(Player player) {
+ cursors.computeIfPresent(player, (player1, rEntityServer) -> {
+ rEntityServer.close();
+ return null;
+ });
+ }
+
+ private void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult) {
+ REntityServer entityServer = cursors.computeIfAbsent(player, __ -> {
+ REntityServer rEntityServer = new REntityServer();
+ rEntityServer.addPlayer(player);
+ RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(rEntityServer, new Location(WORLD, 0, 0, 0, 0, 0), Material.GLASS);
+ rFallingBlockEntity.setNoGravity(true);
+ return rEntityServer;
+ });
+ entityServer.getEntities().forEach(rEntity -> {
+ rEntity.move(getPos(player, rayTraceResult).toLocation(WORLD));
+ });
+ }
+
+ public static Vector getPos(Player player, RayTraceUtils.RRayTraceResult result) {
+ Vector pos = result.getHitPosition();
+
+ BlockFace face = result.getHitBlockFace();
+ if (face != null) {
+ switch (face) {
+ case DOWN:
+ pos.setY(pos.getY() - 0.98);
+ break;
+ case EAST:
+ pos.setX(pos.getX() + 0.49);
+ break;
+ case WEST:
+ pos.setX(pos.getX() - 0.49);
+ break;
+ case NORTH:
+ pos.setZ(pos.getZ() - 0.49);
+ break;
+ case SOUTH:
+ pos.setZ(pos.getZ() + 0.49);
+ break;
+ default:
+ break;
+ }
+
+ if (face.getModY() == 0 && player.isSneaking()) {
+ pos.setY(pos.getY() - 0.49);
+ }
+ }
+
+ if (!player.isSneaking()) {
+ pos.setX(pos.getBlockX() + 0.5);
+ if (face == null || face.getModY() == 0)
+ pos.setY(pos.getBlockY() + 0.0);
+ pos.setZ(pos.getBlockZ() + 0.5);
+ }
+
+ return pos;
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupGui.java
index 2cab54cc..f1bce0f2 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupGui.java
@@ -27,7 +27,6 @@ import de.steamwar.bausystem.features.simulator2.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorPageGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupSettingsGui.java
index df5b06fe..6f945bdf 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGroupSettingsGui.java
@@ -23,7 +23,6 @@ import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
import de.steamwar.bausystem.features.simulator2.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGui.java
index 757918a3..d2e5ce95 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorGui.java
@@ -25,7 +25,6 @@ import de.steamwar.bausystem.features.simulator2.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator2.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorPageGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/utils/SimulatorMaterialGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorMaterialGui.java
similarity index 97%
rename from BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/utils/SimulatorMaterialGui.java
rename to BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorMaterialGui.java
index 95d321a7..9e8e6081 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/utils/SimulatorMaterialGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorMaterialGui.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package de.steamwar.bausystem.features.simulator2.gui.utils;
+package de.steamwar.bausystem.features.simulator2.gui;
import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneGui.java
index efb64277..27222540 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneGui.java
@@ -26,15 +26,12 @@ import de.steamwar.bausystem.features.simulator2.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator2.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorScrollGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
public class SimulatorRedstoneGui extends SimulatorScrollGui {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstonePhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstonePhaseSettingsGui.java
index 7835261d..7b93f595 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstonePhaseSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstonePhaseSettingsGui.java
@@ -21,11 +21,9 @@ package de.steamwar.bausystem.features.simulator2.gui;
import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
-import de.steamwar.bausystem.features.simulator2.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator2.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator2.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneSettingsGui.java
index 7152cc6f..ed4a99cb 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorRedstoneSettingsGui.java
@@ -23,14 +23,11 @@ import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
import de.steamwar.bausystem.features.simulator2.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
private final RedstoneElement redstone;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorSettingsGui.java
index b9e75a5e..8ed72b0e 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorSettingsGui.java
@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.simulator2.gui;
import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTGui.java
index 34906cd0..a21cf414 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTGui.java
@@ -26,17 +26,12 @@ import de.steamwar.bausystem.features.simulator2.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorScrollGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
-import de.steamwar.bausystem.features.simulator2.gui.SimulatorTNTPhaseSettingsGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
public class SimulatorTNTGui extends SimulatorScrollGui {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTPhaseSettingsGui.java
index 4e68d0dd..fffb767a 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTPhaseSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTPhaseSettingsGui.java
@@ -25,7 +25,6 @@ import de.steamwar.bausystem.features.simulator2.data.SimulatorPhase;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTSettingsGui.java
index 074e86c4..f93cc648 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTSettingsGui.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator2/gui/SimulatorTNTSettingsGui.java
@@ -23,7 +23,6 @@ import de.steamwar.bausystem.features.simulator2.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator2.data.Simulator;
import de.steamwar.bausystem.features.simulator2.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator2.gui.base.SimulatorBaseGui;
-import de.steamwar.bausystem.features.simulator2.gui.utils.SimulatorMaterialGui;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;