diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursor.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursor.java index bae58778..f4ec7cd0 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursor.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursor.java @@ -4,35 +4,44 @@ import de.steamwar.bausystem.utils.RayTraceUtils; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import java.util.function.BiFunction; + @Getter public class RCursor { - private final REntityServer targetServer; - private final Player owner; private final Material highlightMaterial; + @Setter private Material cursorMaterial; + @Setter + private CursorMode cursorMode; + private boolean visible = true; private RFallingBlockEntity cursorEntity; - public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial) { + public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, CursorMode cursorMode) { this.targetServer = targetServer; this.owner = owner; this.highlightMaterial = highlightMaterial; this.cursorMaterial = cursorMaterial; + this.cursorMode = cursorMode; RCursorManager.getInstance().registerCursor(this); } public void render() { + if (!visible) return; + RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities()); if (rayTraceResult == null) { cursorEntity.die(); @@ -43,7 +52,7 @@ public class RCursor { Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial; - Location activeCursorLocation = hitEntity == null ? rayTraceResult.getHitPosition().toLocation(owner.getWorld()) + Location activeCursorLocation = hitEntity == null ? cursorMode.positionTransform.apply(owner, rayTraceResult).toLocation(owner.getWorld()) : new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(owner.getWorld()); if (cursorEntity == null) { @@ -59,8 +68,94 @@ public class RCursor { } public void hide() { + visible = false; if (cursorEntity != null) { cursorEntity.die(); } } + + public void show() { + visible = true; + } + + @AllArgsConstructor + public enum CursorMode { + FREE((player, rayTraceResult) -> { + Vector pos = rayTraceResult.getHitPosition(); + + BlockFace face = rayTraceResult.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; + }), + BLOCK_ALIGNED((player, rayTraceResult) -> { + Vector pos = rayTraceResult.getHitPosition(); + + BlockFace face = rayTraceResult.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; + } + } + + pos.setX(pos.getBlockX() + 0.5); + if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) { + pos.setY(pos.getBlockY() + 1.0); + } else { + pos.setY(pos.getBlockY()); + } + pos.setZ(pos.getBlockZ() + 0.5); + return pos; + }); + + + private final BiFunction positionTransform; + } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursorManager.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursorManager.java index 82554406..b72e00b7 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursorManager.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/cursor/RCursorManager.java @@ -53,6 +53,10 @@ public class RCursorManager { } private void updateCursor(Player player) { + if (!activeCursors.containsKey(player)) { + return; + } + synchronized (calculationActive) { if (calculationActive.contains(player)) { return; @@ -62,6 +66,7 @@ public class RCursorManager { } SoftReference cursorRef = activeCursors.get(player); + RCursor cursor = cursorRef.get(); if (cursor == null) { @@ -74,4 +79,5 @@ public class RCursorManager { calculationActive.remove(player); } } + }