forked from SteamWar/SteamWar
Move a lot more logic into component
This commit is contained in:
+207
-135
@@ -70,10 +70,20 @@ import java.util.stream.Collectors;
|
|||||||
public class SimulatorCursorManager implements Listener {
|
public class SimulatorCursorManager implements Listener {
|
||||||
|
|
||||||
private static class SimulatorCursorComponent implements SWPlayer.Component {
|
private static class SimulatorCursorComponent implements SWPlayer.Component {
|
||||||
|
private Player player;
|
||||||
|
private Cursor cursor;
|
||||||
private CursorType cursorType = CursorType.TNT;
|
private CursorType cursorType = CursorType.TNT;
|
||||||
private REntityServer emptyTargetServer;
|
private REntityServer emptyTargetServer;
|
||||||
|
private REntityServer currentTargetServer;
|
||||||
private long lastSneakMillis;
|
private long lastSneakMillis;
|
||||||
|
|
||||||
|
private SimulatorCursorComponent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimulatorCursorComponent(CursorType cursorType) {
|
||||||
|
this.cursorType = cursorType;
|
||||||
|
}
|
||||||
|
|
||||||
private REntityServer getOrCreateEmptyTargetServer() {
|
private REntityServer getOrCreateEmptyTargetServer() {
|
||||||
if (emptyTargetServer == null) {
|
if (emptyTargetServer == null) {
|
||||||
emptyTargetServer = new REntityServer();
|
emptyTargetServer = new REntityServer();
|
||||||
@@ -81,158 +91,85 @@ public class SimulatorCursorManager implements Listener {
|
|||||||
return emptyTargetServer;
|
return emptyTargetServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDoubleSneak() {
|
private boolean handleSneak(long now) {
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
boolean doubleSneak = now - lastSneakMillis <= 200;
|
boolean doubleSneak = now - lastSneakMillis <= 200;
|
||||||
lastSneakMillis = doubleSneak ? 0 : now;
|
lastSneakMillis = doubleSneak ? 0 : now;
|
||||||
return doubleSneak;
|
return doubleSneak;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private CursorType getCursorType() {
|
||||||
public void onUnmount(SWPlayer player) {
|
return cursorType;
|
||||||
player.removeComponent(Cursor.class);
|
|
||||||
if (emptyTargetServer != null) {
|
|
||||||
emptyTargetServer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSimulatorItem(ItemStack itemStack) {
|
private void setCursorType(CursorType cursorType) {
|
||||||
return ItemUtils.isItem(itemStack, "simulator");
|
this.cursorType = cursorType;
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasSimulatorItem(Player player) {
|
private void switchCursorMode() {
|
||||||
return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand());
|
cursorType = cursorType == CursorType.TNT ? CursorType.REDSTONE_BLOCK : CursorType.TNT;
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
private void refresh() {
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> calcCursor(event.getPlayer()), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
|
||||||
calcCursor(event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (!Permission.BUILD.hasPermission(player)) return;
|
|
||||||
|
|
||||||
boolean hasSimulatorInNewMainHand = isSimulatorItem(player.getInventory().getItem(event.getNewSlot()));
|
|
||||||
boolean hasSimulatorInOffHand = isSimulatorItem(player.getInventory().getItemInOffHand());
|
|
||||||
if (!hasSimulatorInNewMainHand && !hasSimulatorInOffHand) {
|
|
||||||
if (deactivateCursor(player) || SimulatorWatcher.show(null, player)) {
|
|
||||||
SWUtils.sendToActionbar(player, "");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> calcCursor(player), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
|
||||||
event.getChanged().forEach(SimulatorCursorManager::calcCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
|
||||||
deactivateCursor(event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
|
||||||
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
|
|
||||||
if (!event.isSneaking()) return;
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (!hasSimulatorItem(player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SimulatorCursorComponent component = getOrCreateComponent(player);
|
|
||||||
if (component.isDoubleSneak()) {
|
|
||||||
component.cursorType = component.cursorType == CursorType.TNT ? CursorType.REDSTONE_BLOCK : CursorType.TNT;
|
|
||||||
calcCursor(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CursorType getCursorType(Player player) {
|
|
||||||
return SWPlayer.of(player).getComponent(SimulatorCursorComponent.class)
|
|
||||||
.map(component -> component.cursorType)
|
|
||||||
.orElse(CursorType.TNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setCursorType(Player player, CursorType cursorType) {
|
|
||||||
getOrCreateComponent(player).cursorType = cursorType;
|
|
||||||
calcCursor(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void calcCursor(Player player) {
|
|
||||||
if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) {
|
if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) {
|
||||||
if (deactivateCursor(player) || SimulatorWatcher.show(null, player)) {
|
deactivateCursor(player);
|
||||||
SWUtils.sendToActionbar(player, "");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Simulator simulator = SimulatorStorage.getSimulator(player);
|
Simulator simulator = SimulatorStorage.getSimulator(player);
|
||||||
if (simulator != null && simulator.getStabGenerator() != null) {
|
if (simulator != null && simulator.getStabGenerator() != null) {
|
||||||
deactivateCursor(player);
|
removeGenericCursor();
|
||||||
SimulatorWatcher.show(null, player);
|
boolean watcherRemoved = SimulatorWatcher.show(null, player);
|
||||||
|
if (watcherRemoved) {
|
||||||
|
SWUtils.sendToActionbar(player, "");
|
||||||
|
}
|
||||||
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorCursorComponent component = getOrCreateComponent(player);
|
|
||||||
SimulatorWatcher.show(simulator, player);
|
SimulatorWatcher.show(simulator, player);
|
||||||
Cursor cursor = getOrCreateCursor(player, simulator, component);
|
REntityServer targetServer = simulator == null ? getOrCreateEmptyTargetServer() : SimulatorWatcher.getEntityServerOfSimulator(simulator);
|
||||||
cursor.renderDeduplicated();
|
if (cursor == null || currentTargetServer != targetServer) {
|
||||||
}
|
removeGenericCursor();
|
||||||
|
currentTargetServer = targetServer;
|
||||||
private static SimulatorCursorComponent getOrCreateComponent(Player player) {
|
|
||||||
return SWPlayer.of(player).getComponentOrDefault(SimulatorCursorComponent.class, SimulatorCursorComponent::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Cursor getOrCreateCursor(Player player, Simulator simulator, SimulatorCursorComponent component) {
|
|
||||||
REntityServer targetServer = simulator == null ? component.getOrCreateEmptyTargetServer() : SimulatorWatcher.getEntityServerOfSimulator(simulator);
|
|
||||||
SWPlayer swPlayer = SWPlayer.of(player);
|
|
||||||
Optional<Cursor> activeCursor = swPlayer.getComponent(Cursor.class);
|
|
||||||
CursorType type = component.cursorType;
|
|
||||||
|
|
||||||
Cursor cursor = activeCursor.orElse(null);
|
|
||||||
if (cursor == null || cursor.getTargetServer() != targetServer) {
|
|
||||||
swPlayer.removeComponent(Cursor.class);
|
|
||||||
cursor = new Cursor(
|
cursor = new Cursor(
|
||||||
targetServer,
|
targetServer,
|
||||||
player,
|
player,
|
||||||
Material.GLASS,
|
Material.GLASS,
|
||||||
type.material,
|
cursorType.material,
|
||||||
type.cursorModes,
|
cursorType.cursorModes,
|
||||||
(location, hitEntity, action) -> handlePlayerClick(player, location, hitEntity, action),
|
this::handlePlayerClick,
|
||||||
(location, hitEntity) -> sendCursorActionbar(player, component, SimulatorStorage.getSimulator(player), location != null, hitEntity.isPresent())
|
(location, hitEntity) -> sendCursorActionbar(simulator, location != null, hitEntity.isPresent())
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
cursor.setCursorMaterial(type.material);
|
cursor.setCursorMaterial(cursorType.material);
|
||||||
cursor.setAllowedCursorModes(type.cursorModes);
|
cursor.setAllowedCursorModes(cursorType.cursorModes);
|
||||||
|
}
|
||||||
|
cursor.renderDeduplicated();
|
||||||
}
|
}
|
||||||
|
|
||||||
return cursor;
|
private void removeGenericCursor() {
|
||||||
|
if (cursor == null && !SWPlayer.of(player).hasComponent(Cursor.class)) {
|
||||||
|
currentTargetServer = null;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean deactivateCursor(Player player) {
|
SWPlayer.of(player).removeComponent(Cursor.class);
|
||||||
SWPlayer swPlayer = SWPlayer.of(player);
|
cursor = null;
|
||||||
boolean hadSimulatorCursor = swPlayer.hasComponent(SimulatorCursorComponent.class);
|
currentTargetServer = null;
|
||||||
boolean hadCursor = swPlayer.hasComponent(Cursor.class);
|
|
||||||
swPlayer.removeComponent(SimulatorCursorComponent.class);
|
|
||||||
if (!hadSimulatorCursor) {
|
|
||||||
swPlayer.removeComponent(Cursor.class);
|
|
||||||
}
|
|
||||||
return hadSimulatorCursor || hadCursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendCursorActionbar(Player player, SimulatorCursorComponent component, Simulator simulator, boolean hasCursorLocation, boolean hasHitEntity) {
|
private void closeEmptyTargetServer() {
|
||||||
|
if (emptyTargetServer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyTargetServer.close();
|
||||||
|
emptyTargetServer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendCursorActionbar(Simulator simulator, boolean hasCursorLocation, boolean hasHitEntity) {
|
||||||
if (!hasCursorLocation) {
|
if (!hasCursorLocation) {
|
||||||
SWUtils.sendToActionbar(player, simulator == null ? "§eSelect Simulator" : "§eOpen Simulator");
|
SWUtils.sendToActionbar(player, simulator == null ? "§eSelect Simulator" : "§eOpen Simulator");
|
||||||
} else if (simulator == null) {
|
} else if (simulator == null) {
|
||||||
@@ -240,26 +177,11 @@ public class SimulatorCursorManager implements Listener {
|
|||||||
} else if (hasHitEntity) {
|
} else if (hasHitEntity) {
|
||||||
SWUtils.sendToActionbar(player, "§eEdit Position");
|
SWUtils.sendToActionbar(player, "§eEdit Position");
|
||||||
} else {
|
} else {
|
||||||
SWUtils.sendToActionbar(player, "§eAdd new " + component.cursorType.name);
|
SWUtils.sendToActionbar(player, "§eAdd new " + cursorType.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
private void handlePlayerClick(Location cursorLocation, Optional<REntity> hitEntity, Action action) {
|
||||||
@AllArgsConstructor
|
|
||||||
public enum CursorType {
|
|
||||||
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, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
|
|
||||||
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 nonSelectedMaterial;
|
|
||||||
public final List<Cursor.CursorMode> cursorModes;
|
|
||||||
public final String name;
|
|
||||||
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handlePlayerClick(Player player, Location cursorLocation, Optional<REntity> hitEntity, Action action) {
|
|
||||||
if (!Permission.BUILD.hasPermission(player)) return;
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
if (!hasSimulatorItem(player)) {
|
if (!hasSimulatorItem(player)) {
|
||||||
return;
|
return;
|
||||||
@@ -317,6 +239,156 @@ public class SimulatorCursorManager implements Listener {
|
|||||||
createElement(player, cursorLocation, simulator);
|
createElement(player, cursorLocation, simulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMount(SWPlayer player) {
|
||||||
|
this.player = player.getPlayer();
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnmount(SWPlayer player) {
|
||||||
|
boolean hadCursor = cursor != null || player.hasComponent(Cursor.class);
|
||||||
|
removeGenericCursor();
|
||||||
|
closeEmptyTargetServer();
|
||||||
|
boolean watcherRemoved = SimulatorWatcher.show(null, this.player);
|
||||||
|
if (hadCursor || watcherRemoved) {
|
||||||
|
SWUtils.sendToActionbar(this.player, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSimulatorItem(ItemStack itemStack) {
|
||||||
|
return ItemUtils.isItem(itemStack, "simulator");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasSimulatorItem(Player player) {
|
||||||
|
return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||||
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
|
calcCursor(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
|
|
||||||
|
boolean hasSimulatorInNewMainHand = isSimulatorItem(player.getInventory().getItem(event.getNewSlot()));
|
||||||
|
boolean hasSimulatorInOffHand = isSimulatorItem(player.getInventory().getItemInOffHand());
|
||||||
|
if (!hasSimulatorInNewMainHand && !hasSimulatorInOffHand) {
|
||||||
|
boolean cursorRemoved = deactivateCursor(player);
|
||||||
|
boolean watcherRemoved = SimulatorWatcher.show(null, player);
|
||||||
|
if (cursorRemoved || watcherRemoved) {
|
||||||
|
SWUtils.sendToActionbar(player, "");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> calcCursor(player), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
||||||
|
event.getChanged().forEach(SimulatorCursorManager::calcCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
deactivateCursor(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
|
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
|
||||||
|
if (!event.isSneaking()) return;
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!hasSimulatorItem(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SimulatorCursorComponent component = activateOrRefresh(player);
|
||||||
|
if (component == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean shouldSwitch = component.handleSneak(System.currentTimeMillis());
|
||||||
|
if (shouldSwitch) {
|
||||||
|
component.switchCursorMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CursorType getCursorType(Player player) {
|
||||||
|
return SWPlayer.of(player).getComponent(SimulatorCursorComponent.class)
|
||||||
|
.map(SimulatorCursorComponent::getCursorType)
|
||||||
|
.orElse(CursorType.TNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCursorType(Player player, CursorType cursorType) {
|
||||||
|
Optional<SimulatorCursorComponent> component = SWPlayer.of(player).getComponent(SimulatorCursorComponent.class);
|
||||||
|
if (component.isPresent()) {
|
||||||
|
component.get().setCursorType(cursorType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SWPlayer.of(player).setComponent(new SimulatorCursorComponent(cursorType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void calcCursor(Player player) {
|
||||||
|
activateOrRefresh(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimulatorCursorComponent activateOrRefresh(Player player) {
|
||||||
|
if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) {
|
||||||
|
boolean cursorRemoved = deactivateCursor(player);
|
||||||
|
boolean watcherRemoved = SimulatorWatcher.show(null, player);
|
||||||
|
if (cursorRemoved || watcherRemoved) {
|
||||||
|
SWUtils.sendToActionbar(player, "");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWPlayer swPlayer = SWPlayer.of(player);
|
||||||
|
Optional<SimulatorCursorComponent> existingComponent = swPlayer.getComponent(SimulatorCursorComponent.class);
|
||||||
|
if (existingComponent.isPresent()) {
|
||||||
|
SimulatorCursorComponent component = existingComponent.get();
|
||||||
|
component.refresh();
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimulatorCursorComponent component = new SimulatorCursorComponent();
|
||||||
|
swPlayer.setComponent(component);
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized boolean deactivateCursor(Player player) {
|
||||||
|
SWPlayer swPlayer = SWPlayer.of(player);
|
||||||
|
boolean hadSimulatorCursor = swPlayer.hasComponent(SimulatorCursorComponent.class);
|
||||||
|
boolean hadCursor = swPlayer.hasComponent(Cursor.class);
|
||||||
|
swPlayer.removeComponent(SimulatorCursorComponent.class);
|
||||||
|
if (!hadSimulatorCursor) {
|
||||||
|
swPlayer.removeComponent(Cursor.class);
|
||||||
|
}
|
||||||
|
return hadSimulatorCursor || hadCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CursorType {
|
||||||
|
TNT(Material.TNT, Material.GUNPOWDER, List.of(Cursor.CursorMode.SURFACE_ALIGNED, Cursor.CursorMode.FREE), "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
|
||||||
|
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, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
|
||||||
|
;
|
||||||
|
|
||||||
|
public final Material material;
|
||||||
|
public final Material nonSelectedMaterial;
|
||||||
|
public final List<Cursor.CursorMode> cursorModes;
|
||||||
|
public final String name;
|
||||||
|
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
||||||
|
}
|
||||||
|
|
||||||
private static void openElement(Player player, Simulator simulator, REntity hitEntity) {
|
private static void openElement(Player player, Simulator simulator, REntity hitEntity) {
|
||||||
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
||||||
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user