Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
3be33adb00
Commit
b22fabe8cd
@ -25,6 +25,7 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
|
|||||||
import de.steamwar.bausystem.linkage.LinkageType;
|
import de.steamwar.bausystem.linkage.LinkageType;
|
||||||
import de.steamwar.bausystem.linkage.Linked;
|
import de.steamwar.bausystem.linkage.Linked;
|
||||||
import de.steamwar.bausystem.utils.ItemUtils;
|
import de.steamwar.bausystem.utils.ItemUtils;
|
||||||
|
import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.FluidCollisionMode;
|
import org.bukkit.FluidCollisionMode;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
@ -56,41 +57,7 @@ public class TNTSimulatorListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RayTraceResult trace(Player player, Location to, TNTSimulator simulator) {
|
static RayTraceResult trace(Player player, Location to, TNTSimulator simulator) {
|
||||||
if (player.getGameMode() == GameMode.SPECTATOR) {
|
return RayTraceUtils.trace(player, to, simulator.getEntities());
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.bausystem.features.tracer;
|
package de.steamwar.bausystem.features.tracer;
|
||||||
|
|
||||||
import de.steamwar.bausystem.shared.AbstractEntity;
|
import de.steamwar.bausystem.shared.AbstractEntity;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface AbstractTraceEntity extends AbstractEntity {
|
public interface AbstractTraceEntity extends AbstractEntity {
|
||||||
@ -27,4 +28,6 @@ public interface AbstractTraceEntity extends AbstractEntity {
|
|||||||
void display(Player player, boolean exploded, int ticks);
|
void display(Player player, boolean exploded, int ticks);
|
||||||
|
|
||||||
boolean hide(Player player, boolean always);
|
boolean hide(Player player, boolean always);
|
||||||
|
|
||||||
|
Entity getBukkitEntity();
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<Player> 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<TNTPosition> {
|
||||||
|
List<Entity> getEntities();
|
||||||
|
TNTPosition getTNTPosition(Entity entity);
|
||||||
|
}
|
@ -4,12 +4,15 @@ import de.steamwar.bausystem.BauSystem;
|
|||||||
import de.steamwar.bausystem.features.tracer.TNTPosition;
|
import de.steamwar.bausystem.features.tracer.TNTPosition;
|
||||||
import de.steamwar.bausystem.shared.ShowMode;
|
import de.steamwar.bausystem.shared.ShowMode;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TraceShowManager implements Listener {
|
public class TraceShowManager implements Listener {
|
||||||
@ -31,6 +34,28 @@ public class TraceShowManager implements Listener {
|
|||||||
traceShowMode.hide();
|
traceShowMode.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Entity> getEntities(Player player) {
|
||||||
|
ShowMode<TNTPosition> 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<TNTPosition> showMode = showModes.get(player);
|
||||||
|
if (showMode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (showMode instanceof EntityTraceShowMode) {
|
||||||
|
return ((EntityTraceShowMode) showMode).getTNTPosition(entity);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void reshow() {
|
public static void reshow() {
|
||||||
Map<Player, ShowMode<TNTPosition>> current = new HashMap<>(showModes);
|
Map<Player, ShowMode<TNTPosition>> current = new HashMap<>(showModes);
|
||||||
current.forEach(TraceShowManager::show);
|
current.forEach(TraceShowManager::show);
|
||||||
|
@ -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.AbstractTraceEntity;
|
||||||
import de.steamwar.bausystem.features.tracer.TNTPosition;
|
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.features.tracer.show.ShowModeParameter;
|
||||||
import de.steamwar.bausystem.shared.RoundedPosition;
|
import de.steamwar.bausystem.shared.RoundedPosition;
|
||||||
import de.steamwar.bausystem.shared.ShowMode;
|
|
||||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Consumer;
|
import org.bukkit.util.Consumer;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
|
public abstract class FactoredEntityShowMode implements EntityTraceShowMode {
|
||||||
|
|
||||||
private int factor;
|
private int factor;
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
|
|||||||
|
|
||||||
private final Map<RoundedPosition, AbstractTraceEntity> tntEntityMap = new HashMap<>();
|
private final Map<RoundedPosition, AbstractTraceEntity> tntEntityMap = new HashMap<>();
|
||||||
private final Map<RoundedPosition, AbstractTraceEntity> updateEntityMap = new HashMap<>();
|
private final Map<RoundedPosition, AbstractTraceEntity> updateEntityMap = new HashMap<>();
|
||||||
|
private final Map<Entity, TNTPosition> tntPositionMap = new HashMap<>();
|
||||||
|
|
||||||
protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) {
|
protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -57,6 +61,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
|
|||||||
}
|
}
|
||||||
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
|
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
|
||||||
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
|
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);
|
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,6 +86,7 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
|
|||||||
|
|
||||||
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
|
RoundedPosition roundedPosition = new RoundedPosition(position, factor);
|
||||||
AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true));
|
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);
|
entity.display(player, position.isExploded(), showModeParameter.isTicks() ? position.getFuseTicks() : -1);
|
||||||
|
|
||||||
applyOnPosition(position, updatePointPosition -> {
|
applyOnPosition(position, updatePointPosition -> {
|
||||||
@ -120,9 +126,20 @@ public abstract class FactoredEntityShowMode implements ShowMode<TNTPosition> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
tntPositionMap.clear();
|
||||||
tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
|
tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
|
||||||
tntEntityMap.clear();
|
tntEntityMap.clear();
|
||||||
updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
|
updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true));
|
||||||
updateEntityMap.clear();
|
updateEntityMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Entity> getEntities() {
|
||||||
|
return new ArrayList<>(tntPositionMap.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TNTPosition getTNTPosition(Entity entity) {
|
||||||
|
return tntPositionMap.get(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_Y", event.getPlayer(), tntPrimed.getLocation().getY() + "");
|
||||||
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", event.getPlayer(), tntPrimed.getLocation().getZ() + "");
|
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_X", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
|
||||||
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", 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().getX() + "");
|
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getZ() + "");
|
||||||
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + "");
|
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
BauSystem_Main/src/de/steamwar/bausystem/utils/RayTraceUtils.java
Normale Datei
74
BauSystem_Main/src/de/steamwar/bausystem/utils/RayTraceUtils.java
Normale Datei
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<Entity> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren