forked from SteamWar/SteamWar
Refactor simulation cursor to use new generic cursor
This commit is contained in:
+103
-238
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.simulator;
|
package de.steamwar.bausystem.features.simulator;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.SWUtils;
|
import de.steamwar.bausystem.SWUtils;
|
||||||
@@ -38,63 +37,52 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorGui;
|
|||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||||
import de.steamwar.bausystem.utils.ItemUtils;
|
import de.steamwar.bausystem.utils.ItemUtils;
|
||||||
import de.steamwar.cursor.RayTraceUtils;
|
import de.steamwar.core.SWPlayer;
|
||||||
|
import de.steamwar.cursor.Cursor;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
|
||||||
import de.steamwar.inventory.SWAnvilInv;
|
import de.steamwar.inventory.SWAnvilInv;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.*;
|
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.event.player.PlayerToggleSneakEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
import java.util.function.BiFunction;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class SimulatorCursor implements Listener {
|
public class SimulatorCursor implements Listener {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static final Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
private static final Map<Player, REntityServer> emptyTargetServers = Collections.synchronizedMap(new HashMap<>());
|
||||||
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
private static final Set<Player> calculating = new HashSet<>();
|
|
||||||
|
|
||||||
public static boolean isSimulatorItem(ItemStack itemStack) {
|
public static boolean isSimulatorItem(ItemStack itemStack) {
|
||||||
return ItemUtils.isItem(itemStack, "simulator");
|
return ItemUtils.isItem(itemStack, "simulator");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimulatorCursor() {
|
|
||||||
BiFunction<Player, ServerboundMovePlayerPacket, Object> function = (player, object) -> {
|
|
||||||
calcCursor(player);
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, function);
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Rot.class, function);
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> calcCursor(event.getPlayer()), 0);
|
||||||
calcCursor(event.getPlayer());
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -106,9 +94,7 @@ public class SimulatorCursor implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> calcCursor(event.getPlayer()), 1);
|
||||||
calcCursor(event.getPlayer());
|
|
||||||
}, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -119,10 +105,7 @@ public class SimulatorCursor implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
cursorType.remove(event.getPlayer());
|
cursorType.remove(event.getPlayer());
|
||||||
cursors.remove(event.getPlayer());
|
removeCursor(event.getPlayer());
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(event.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
|
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
|
||||||
@@ -164,17 +147,10 @@ public class SimulatorCursor implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void calcCursor(Player player) {
|
public static void calcCursor(Player player) {
|
||||||
synchronized (calculating) {
|
|
||||||
if (calculating.contains(player)) return;
|
|
||||||
calculating.add(player);
|
|
||||||
}
|
|
||||||
if (!Permission.BUILD.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) {
|
if (!Permission.BUILD.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) {
|
||||||
if (removeCursor(player) || SimulatorWatcher.show(null, player)) {
|
if (removeCursor(player) || SimulatorWatcher.show(null, player)) {
|
||||||
SWUtils.sendToActionbar(player, "");
|
SWUtils.sendToActionbar(player, "");
|
||||||
}
|
}
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(player);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,203 +159,93 @@ public class SimulatorCursor implements Listener {
|
|||||||
removeCursor(player);
|
removeCursor(player);
|
||||||
SimulatorWatcher.show(null, player);
|
SimulatorWatcher.show(null, player);
|
||||||
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(player);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorWatcher.show(simulator, player);
|
SimulatorWatcher.show(simulator, player);
|
||||||
List<REntity> entities = SimulatorWatcher.getEntitiesOfSimulator(simulator);
|
REntityServer targetServer = simulator == null ? emptyTargetServers.computeIfAbsent(player, __ -> new REntityServer()) : SimulatorWatcher.getEntityServerOfSimulator(simulator);
|
||||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities);
|
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
||||||
if (rayTraceResult == null) {
|
SWPlayer swPlayer = SWPlayer.of(player);
|
||||||
removeCursor(player);
|
Optional<Cursor> currentCursor = swPlayer.getComponent(Cursor.class);
|
||||||
if (simulator == null) {
|
Cursor cursor;
|
||||||
SWUtils.sendToActionbar(player, "§eSelect Simulator");
|
if (currentCursor.isEmpty() || currentCursor.get().getTargetServer() != targetServer) {
|
||||||
} else {
|
swPlayer.removeComponent(Cursor.class);
|
||||||
SWUtils.sendToActionbar(player, "§eOpen Simulator");
|
cursor = new Cursor(
|
||||||
}
|
targetServer,
|
||||||
synchronized (calculating) {
|
player,
|
||||||
calculating.remove(player);
|
Material.GLASS,
|
||||||
}
|
type.material,
|
||||||
return;
|
type.cursorModes,
|
||||||
}
|
(location, hitEntity, action) -> handlePlayerClick(player, location, hitEntity, action),
|
||||||
|
(location, hitEntity) -> sendCursorActionbar(player, SimulatorStorage.getSimulator(player), location != null, hitEntity.isPresent())
|
||||||
showCursor(player, rayTraceResult, simulator != null);
|
);
|
||||||
synchronized (calculating) {
|
} else {
|
||||||
calculating.remove(player);
|
cursor = currentCursor.get();
|
||||||
|
cursor.setCursorMaterial(type.material);
|
||||||
|
cursor.setAllowedCursorModes(type.cursorModes);
|
||||||
}
|
}
|
||||||
|
cursor.renderDeduplicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean removeCursor(Player player) {
|
private static synchronized boolean removeCursor(Player player) {
|
||||||
REntityServer entityServer = cursors.get(player);
|
Optional<Cursor> cursor = SWPlayer.of(player).getComponent(Cursor.class);
|
||||||
boolean hadCursor = entityServer != null && !entityServer.getEntities().isEmpty();
|
cursor.ifPresent(__ -> SWPlayer.of(player).removeComponent(Cursor.class));
|
||||||
if (entityServer != null) {
|
REntityServer emptyTargetServer = emptyTargetServers.remove(player);
|
||||||
entityServer.getEntities().forEach(REntity::die);
|
if (emptyTargetServer != null) {
|
||||||
|
emptyTargetServer.close();
|
||||||
}
|
}
|
||||||
return hadCursor;
|
return cursor.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, boolean hasSimulatorSelected) {
|
private static void sendCursorActionbar(Player player, Simulator simulator, boolean hasCursorLocation, boolean hasHitEntity) {
|
||||||
REntityServer entityServer = cursors.computeIfAbsent(player, __ -> {
|
if (!hasCursorLocation) {
|
||||||
REntityServer rEntityServer = new REntityServer();
|
SWUtils.sendToActionbar(player, simulator == null ? "§eSelect Simulator" : "§eOpen Simulator");
|
||||||
rEntityServer.addPlayer(player);
|
} else if (simulator == null) {
|
||||||
return rEntityServer;
|
|
||||||
});
|
|
||||||
|
|
||||||
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
|
||||||
REntity hitEntity = rayTraceResult.getHitEntity();
|
|
||||||
Location location = hitEntity != null ? new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD) :
|
|
||||||
type.position.apply(player, rayTraceResult).toLocation(WORLD);
|
|
||||||
|
|
||||||
Material material = hitEntity != null ? Material.GLASS : type.getMaterial();
|
|
||||||
List<RFallingBlockEntity> entities = entityServer.getEntitiesByType(RFallingBlockEntity.class);
|
|
||||||
entities.removeIf(rFallingBlockEntity -> {
|
|
||||||
if (rFallingBlockEntity.getMaterial() != material) {
|
|
||||||
rFallingBlockEntity.die();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
rFallingBlockEntity.move(location);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
if (entities.isEmpty()) {
|
|
||||||
RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, location, material);
|
|
||||||
rFallingBlockEntity.setNoGravity(true);
|
|
||||||
if (material == Material.GLASS) {
|
|
||||||
rFallingBlockEntity.setGlowing(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSimulatorSelected) {
|
|
||||||
if (hitEntity != null) {
|
|
||||||
SWUtils.sendToActionbar(player, "§eEdit Position");
|
|
||||||
} else {
|
|
||||||
SWUtils.sendToActionbar(player, "§eAdd new " + type.name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
|
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
|
||||||
}
|
} else if (hasHitEntity) {
|
||||||
}
|
SWUtils.sendToActionbar(player, "§eEdit Position");
|
||||||
|
|
||||||
public static Vector getPosFree(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Vector getPosBlockAligned(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.setX(pos.getBlockX() + 0.5);
|
|
||||||
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
|
|
||||||
pos.setY(pos.getBlockY() + 1.0);
|
|
||||||
} else {
|
} else {
|
||||||
pos.setY(pos.getBlockY());
|
SWUtils.sendToActionbar(player, "§eAdd new " + cursorType.getOrDefault(player, CursorType.TNT).name);
|
||||||
}
|
}
|
||||||
pos.setZ(pos.getBlockZ() + 0.5);
|
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum CursorType {
|
public enum CursorType {
|
||||||
TNT(Material.TNT, Material.GUNPOWDER, SimulatorCursor::getPosFree, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
|
TNT(Material.TNT, Material.GUNPOWDER, List.of(Cursor.CursorMode.FREE), "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
|
||||||
REDSTONE_BLOCK(Material.REDSTONE_BLOCK, Material.REDSTONE, SimulatorCursor::getPosBlockAligned, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
|
REDSTONE_BLOCK(Material.REDSTONE_BLOCK, Material.REDSTONE, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
|
||||||
OBSERVER(Material.OBSERVER, Material.QUARTZ, SimulatorCursor::getPosBlockAligned, "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
|
OBSERVER(Material.OBSERVER, Material.QUARTZ, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
|
||||||
;
|
;
|
||||||
|
|
||||||
public final Material material;
|
public final Material material;
|
||||||
public final Material nonSelectedMaterial;
|
public final Material nonSelectedMaterial;
|
||||||
public final BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> position;
|
public final List<Cursor.CursorMode> cursorModes;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
private static void handlePlayerClick(Player player, Location cursorLocation, Optional<REntity> hitEntity, Action action) {
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
|
||||||
if (!ItemUtils.isItem(event.getItem(), "simulator")) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
Simulator simulator = SimulatorStorage.getSimulator(player);
|
Simulator simulator = SimulatorStorage.getSimulator(player);
|
||||||
|
|
||||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
|
if (action == Action.LEFT_CLICK_BLOCK || action == Action.LEFT_CLICK_AIR) {
|
||||||
if (simulator == null) {
|
if (simulator == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SimulatorExecutor.run(event.getPlayer(), simulator, null);
|
SimulatorExecutor.run(player, simulator, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) {
|
if (action != Action.RIGHT_CLICK_BLOCK && action != Action.RIGHT_CLICK_AIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), SimulatorWatcher.getEntitiesOfSimulator(simulator));
|
|
||||||
if (simulator == null) {
|
if (simulator == null) {
|
||||||
if (rayTraceResult == null) {
|
if (cursorLocation == null) {
|
||||||
SimulatorStorage.openSimulatorSelector(player);
|
SimulatorStorage.openSimulatorSelector(player);
|
||||||
} else {
|
} else {
|
||||||
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
|
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
|
||||||
@@ -395,7 +261,7 @@ public class SimulatorCursor implements Listener {
|
|||||||
}
|
}
|
||||||
sim = new Simulator(s);
|
sim = new Simulator(s);
|
||||||
SimulatorStorage.addSimulator(s, sim);
|
SimulatorStorage.addSimulator(s, sim);
|
||||||
createElement(player, rayTraceResult, sim);
|
createElement(player, cursorLocation, sim);
|
||||||
SimulatorStorage.setSimulator(player, sim);
|
SimulatorStorage.setSimulator(player, sim);
|
||||||
});
|
});
|
||||||
anvilInv.open();
|
anvilInv.open();
|
||||||
@@ -403,57 +269,56 @@ public class SimulatorCursor implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayTraceResult == null) {
|
if (cursorLocation == null) {
|
||||||
new SimulatorGui(player, simulator).open();
|
new SimulatorGui(player, simulator).open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayTraceResult.getHitEntity() != null) {
|
if (hitEntity.isPresent()) {
|
||||||
REntity hitEntity = rayTraceResult.getHitEntity();
|
openElement(player, simulator, hitEntity.get());
|
||||||
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
|
||||||
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
|
||||||
return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0);
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
|
|
||||||
switch (elements.size()) {
|
|
||||||
case 0:
|
|
||||||
return;
|
|
||||||
case 1:
|
|
||||||
// Open single element present in Simulator
|
|
||||||
SimulatorElement<?> element = elements.get(0);
|
|
||||||
SimulatorGroup group1 = element.getGroup(simulator);
|
|
||||||
SimulatorBaseGui back = new SimulatorGui(player, simulator);
|
|
||||||
if (group1.getElements().size() > 1) {
|
|
||||||
back = new SimulatorGroupGui(player, simulator, group1, back);
|
|
||||||
}
|
|
||||||
element.open(player, simulator, group1, back);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
|
|
||||||
if (parents.size() == 1) {
|
|
||||||
// Open multi element present in Simulator in existing group
|
|
||||||
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
|
||||||
new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open();
|
|
||||||
} else {
|
|
||||||
// Open multi element present in Simulator in implicit group
|
|
||||||
SimulatorGroup group2 = new SimulatorGroup();
|
|
||||||
group2.setMaterial(null);
|
|
||||||
group2.getElements().addAll(elements);
|
|
||||||
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
|
||||||
new SimulatorGroupGui(player, simulator, group2, simulatorGui).open();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new Element to current simulator
|
createElement(player, cursorLocation, simulator);
|
||||||
createElement(player, rayTraceResult, simulator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createElement(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, Simulator simulator) {
|
private static void openElement(Player player, Simulator simulator, REntity hitEntity) {
|
||||||
|
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
||||||
|
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
||||||
|
return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
switch (elements.size()) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
SimulatorElement<?> element = elements.get(0);
|
||||||
|
SimulatorGroup group1 = element.getGroup(simulator);
|
||||||
|
SimulatorBaseGui back = new SimulatorGui(player, simulator);
|
||||||
|
if (group1.getElements().size() > 1) {
|
||||||
|
back = new SimulatorGroupGui(player, simulator, group1, back);
|
||||||
|
}
|
||||||
|
element.open(player, simulator, group1, back);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
|
||||||
|
if (parents.size() == 1) {
|
||||||
|
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
||||||
|
new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open();
|
||||||
|
} else {
|
||||||
|
SimulatorGroup group2 = new SimulatorGroup();
|
||||||
|
group2.setMaterial(null);
|
||||||
|
group2.getElements().addAll(elements);
|
||||||
|
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
||||||
|
new SimulatorGroupGui(player, simulator, group2, simulatorGui).open();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createElement(Player player, Location cursorLocation, Simulator simulator) {
|
||||||
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
||||||
Vector vector = type.position.apply(player, rayTraceResult);
|
Vector vector = cursorLocation.toVector();
|
||||||
if (type == CursorType.REDSTONE_BLOCK) {
|
if (type == CursorType.REDSTONE_BLOCK) {
|
||||||
vector.subtract(new Vector(0.5, 0, 0.5));
|
vector.subtract(new Vector(0.5, 0, 0.5));
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -124,4 +124,11 @@ public class SimulatorWatcher {
|
|||||||
}
|
}
|
||||||
return entityServer.getEntities();
|
return entityServer.getEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized REntityServer getEntityServerOfSimulator(Simulator simulator) {
|
||||||
|
if (simulator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entityServers.computeIfAbsent(simulator, __ -> createSim(new REntityServer(), simulator));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@@ -44,14 +45,22 @@ public class Cursor implements SWPlayer.Component {
|
|||||||
private List<CursorMode> allowedCursorModes;
|
private List<CursorMode> allowedCursorModes;
|
||||||
private final Material highlightMaterial;
|
private final Material highlightMaterial;
|
||||||
private final TriConsumer<Location, Optional<REntity>, Action> onClick;
|
private final TriConsumer<Location, Optional<REntity>, Action> onClick;
|
||||||
|
private final BiConsumer<Location, Optional<REntity>> onRender;
|
||||||
|
|
||||||
|
|
||||||
public Cursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, List<CursorMode> allowedModes, TriConsumer<Location, Optional<REntity>, Action> onClick) {
|
public Cursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, List<CursorMode> allowedModes, TriConsumer<Location, Optional<REntity>, Action> onClick) {
|
||||||
|
this(targetServer, owner, highlightMaterial, cursorMaterial, allowedModes, onClick, (location, hitEntity) -> {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, List<CursorMode> allowedModes, TriConsumer<Location, Optional<REntity>, Action> onClick, BiConsumer<Location, Optional<REntity>> onRender) {
|
||||||
this.targetServer = targetServer;
|
this.targetServer = targetServer;
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.highlightMaterial = highlightMaterial;
|
this.highlightMaterial = highlightMaterial;
|
||||||
this.cursorMaterial = cursorMaterial;
|
this.cursorMaterial = cursorMaterial;
|
||||||
|
this.allowedCursorModes = allowedModes;
|
||||||
this.onClick = onClick;
|
this.onClick = onClick;
|
||||||
|
this.onRender = onRender;
|
||||||
|
|
||||||
cursorServer = new REntityServer();
|
cursorServer = new REntityServer();
|
||||||
cursorServer.addPlayer(owner);
|
cursorServer.addPlayer(owner);
|
||||||
@@ -72,6 +81,9 @@ public class Cursor implements SWPlayer.Component {
|
|||||||
if (cursorEntity != null)
|
if (cursorEntity != null)
|
||||||
cursorEntity.die();
|
cursorEntity.die();
|
||||||
cursorEntity = null;
|
cursorEntity = null;
|
||||||
|
cursorLocation = null;
|
||||||
|
hitEntity = null;
|
||||||
|
onRender.accept(null, Optional.empty());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,14 +113,12 @@ public class Cursor implements SWPlayer.Component {
|
|||||||
cursorEntity.setGlowing(true);
|
cursorEntity.setGlowing(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onRender.accept(cursorLocation, Optional.ofNullable(hitEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handlePlayerClick(Action clickAction) {
|
protected void handlePlayerClick(Action clickAction) {
|
||||||
renderDeduplicated();
|
renderDeduplicated();
|
||||||
|
onClick.accept(this.cursorLocation, Optional.ofNullable(this.hitEntity), clickAction);
|
||||||
if(cursorLocation != null) {
|
|
||||||
onClick.accept(this.cursorLocation, Optional.ofNullable(this.hitEntity), clickAction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user