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 110a79e2..c64f8f80 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java
@@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
import de.steamwar.bausystem.utils.ItemUtils;
+import de.steamwar.bausystem.utils.RayTraceUtils;
import org.bukkit.Bukkit;
import org.bukkit.FluidCollisionMode;
import org.bukkit.GameMode;
@@ -56,41 +57,7 @@ public class TNTSimulatorListener implements Listener {
}
static RayTraceResult trace(Player player, Location to, TNTSimulator simulator) {
- if (player.getGameMode() == GameMode.SPECTATOR) {
- return null;
- }
-
- Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0);
- Vector direction = to.getDirection();
- RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true);
-
- Entity nearestHitEntity = null;
- RayTraceResult nearestHitResult = null;
- double nearestDistanceSq = Double.MAX_VALUE;
- for (Entity entity : simulator.getEntities()) {
- BoundingBox boundingBox = entity.getBoundingBox();
- RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0);
- if (hitResult != null) {
- double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition());
- if (distanceSq < nearestDistanceSq) {
- nearestHitEntity = entity;
- nearestHitResult = hitResult;
- nearestDistanceSq = distanceSq;
- }
- }
- }
- RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace());
-
- if (blocks == null) {
- return entities;
- } else if (entities == null) {
- return blocks;
- } else {
- Vector startVec = startPos.toVector();
- double blockHitDistance = startVec.distance(blocks.getHitPosition());
- double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition());
- return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks;
- }
+ return RayTraceUtils.trace(player, to, simulator.getEntities());
}
@EventHandler
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java
index 980f511b..ef0df4aa 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/AbstractTraceEntity.java
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.shared.AbstractEntity;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public interface AbstractTraceEntity extends AbstractEntity {
@@ -27,4 +28,6 @@ public interface AbstractTraceEntity extends AbstractEntity {
void display(Player player, boolean exploded, int ticks);
boolean hide(Player player, boolean always);
+
+ Entity getBukkitEntity();
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceTNTClickListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceTNTClickListener.java
new file mode 100644
index 00000000..6a9b885e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceTNTClickListener.java
@@ -0,0 +1,66 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 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;
+
+import com.comphenix.tinyprotocol.Reflection;
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.features.tracer.show.TraceShowManager;
+import de.steamwar.bausystem.linkage.LinkageType;
+import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.bausystem.utils.ProtocolAPI;
+import de.steamwar.bausystem.utils.RayTraceUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.util.RayTraceResult;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Linked(LinkageType.PLAIN)
+public class TraceTNTClickListener {
+
+ private static final Class> useEntity = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity");
+
+ {
+ Set playerSet = new HashSet<>();
+
+ ProtocolAPI.setIncomingHandler(useEntity, (player, o) -> {
+ if (!playerSet.add(player)) return o;
+ Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
+ RayTraceResult rayTraceResult = RayTraceUtils.trace(player, player.getLocation(), TraceShowManager.getEntities(player));
+ if (rayTraceResult == null) return;
+ if (rayTraceResult.getHitEntity() == null) return;
+ TNTPosition tntPosition = TraceShowManager.getTNTPosition(player, rayTraceResult.getHitEntity());
+ if (tntPosition == null) return;
+
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player);
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", player, tntPosition.getFuseTicks());
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", player, tntPosition.getLocation().getX() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", player, tntPosition.getLocation().getY() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", player, tntPosition.getLocation().getZ() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", player, tntPosition.getVelocity().getX() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", player, tntPosition.getVelocity().getY() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", player, tntPosition.getVelocity().getZ() + "");
+ playerSet.remove(player);
+ }, 1);
+ return o;
+ });
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityTraceShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityTraceShowMode.java
new file mode 100644
index 00000000..2b73a40b
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/EntityTraceShowMode.java
@@ -0,0 +1,31 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 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;
+
+import de.steamwar.bausystem.features.tracer.TNTPosition;
+import de.steamwar.bausystem.shared.ShowMode;
+import org.bukkit.entity.Entity;
+
+import java.util.List;
+
+public interface EntityTraceShowMode extends ShowMode {
+ List getEntities();
+ TNTPosition getTNTPosition(Entity entity);
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
index 3f93a0cb..cdb176cf 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/TraceShowManager.java
@@ -4,12 +4,15 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.shared.ShowMode;
import org.bukkit.Bukkit;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class TraceShowManager implements Listener {
@@ -31,6 +34,28 @@ public class TraceShowManager implements Listener {
traceShowMode.hide();
}
+ public static List getEntities(Player player) {
+ ShowMode showMode = showModes.get(player);
+ if (showMode == null) {
+ return Collections.emptyList();
+ }
+ if (showMode instanceof EntityTraceShowMode) {
+ return ((EntityTraceShowMode) showMode).getEntities();
+ }
+ return Collections.emptyList();
+ }
+
+ public static TNTPosition getTNTPosition(Player player, Entity entity) {
+ ShowMode showMode = showModes.get(player);
+ if (showMode == null) {
+ return null;
+ }
+ if (showMode instanceof EntityTraceShowMode) {
+ return ((EntityTraceShowMode) showMode).getTNTPosition(entity);
+ }
+ return null;
+ }
+
public static void reshow() {
Map> current = new HashMap<>(showModes);
current.forEach(TraceShowManager::show);
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
index 2a819e8c..523fc92d 100644
--- 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
@@ -21,19 +21,22 @@ 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.show.EntityTraceShowMode;
import de.steamwar.bausystem.features.tracer.show.ShowModeParameter;
import de.steamwar.bausystem.shared.RoundedPosition;
-import de.steamwar.bausystem.shared.ShowMode;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.NMSWrapper;
+import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Consumer;
import org.bukkit.util.Vector;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-public abstract class FactoredEntityShowMode implements ShowMode {
+public abstract class FactoredEntityShowMode implements EntityTraceShowMode {
private int factor;
@@ -42,6 +45,7 @@ public abstract class FactoredEntityShowMode implements ShowMode {
private final Map tntEntityMap = new HashMap<>();
private final Map updateEntityMap = new HashMap<>();
+ private final Map tntPositionMap = new HashMap<>();
protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) {
this.player = player;
@@ -57,6 +61,7 @@ public abstract class FactoredEntityShowMode implements ShowMode {
}
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
+ tntPositionMap.put(entity.getBukkitEntity(), position);
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
return;
}
@@ -81,6 +86,7 @@ public abstract class FactoredEntityShowMode implements ShowMode {
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
+ tntPositionMap.put(entity.getBukkitEntity(), position);
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
applyOnPosition(position, updatePointPosition -> {
@@ -120,9 +126,20 @@ public abstract class FactoredEntityShowMode implements ShowMode {
@Override
public void hide() {
+ tntPositionMap.clear();
tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
tntEntityMap.clear();
updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
updateEntityMap.clear();
}
+
+ @Override
+ public List getEntities() {
+ return new ArrayList<>(tntPositionMap.keySet());
+ }
+
+ @Override
+ public TNTPosition getTNTPosition(Entity entity) {
+ return tntPositionMap.get(entity);
+ }
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java
index 9c69b022..7a2f0a67 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java
@@ -49,8 +49,8 @@ public class TNTClickListener implements Listener {
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", event.getPlayer(), tntPrimed.getLocation().getY() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", event.getPlayer(), tntPrimed.getLocation().getZ() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
- BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
- BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", event.getPlayer(), tntPrimed.getVelocity().getY() + "");
+ BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getZ() + "");
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + "");
}
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/RayTraceUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/RayTraceUtils.java
new file mode 100644
index 00000000..2145e442
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/RayTraceUtils.java
@@ -0,0 +1,74 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 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.utils;
+
+import lombok.experimental.UtilityClass;
+import org.bukkit.FluidCollisionMode;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.BoundingBox;
+import org.bukkit.util.RayTraceResult;
+import org.bukkit.util.Vector;
+
+import java.util.List;
+
+@UtilityClass
+public class RayTraceUtils {
+
+ public static RayTraceResult trace(Player player, Location to, List entityList) {
+ if (player.getGameMode() == GameMode.SPECTATOR) {
+ return null;
+ }
+
+ Location startPos = to.clone().add(0.0, player.getEyeHeight(), 0.0);
+ Vector direction = to.getDirection();
+ RayTraceResult blocks = player.getWorld().rayTraceBlocks(startPos, direction, 10.0, FluidCollisionMode.NEVER, true);
+
+ Entity nearestHitEntity = null;
+ RayTraceResult nearestHitResult = null;
+ double nearestDistanceSq = Double.MAX_VALUE;
+ for (Entity entity : entityList) {
+ BoundingBox boundingBox = entity.getBoundingBox();
+ RayTraceResult hitResult = boundingBox.rayTrace(startPos.toVector(), direction, 10.0);
+ if (hitResult != null) {
+ double distanceSq = startPos.toVector().distanceSquared(hitResult.getHitPosition());
+ if (distanceSq < nearestDistanceSq) {
+ nearestHitEntity = entity;
+ nearestHitResult = hitResult;
+ nearestDistanceSq = distanceSq;
+ }
+ }
+ }
+ RayTraceResult entities = nearestHitEntity == null ? null : new RayTraceResult(nearestHitResult.getHitPosition(), nearestHitEntity, nearestHitResult.getHitBlockFace());
+
+ if (blocks == null) {
+ return entities;
+ } else if (entities == null) {
+ return blocks;
+ } else {
+ Vector startVec = startPos.toVector();
+ double blockHitDistance = startVec.distance(blocks.getHitPosition());
+ double entityHitDistanceSquared = startVec.distanceSquared(entities.getHitPosition());
+ return entityHitDistanceSquared < blockHitDistance * blockHitDistance ? entities : blocks;
+ }
+ }
+}