Refactored cursor manager for new simulator cursor and adappted usage

This commit is contained in:
D4rkr34lm
2025-11-06 02:43:37 +01:00
parent 4c82469171
commit d66f3fe89f
4 changed files with 57 additions and 127 deletions
@@ -22,6 +22,7 @@ import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.display.SimulatorCursor;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
import de.steamwar.bausystem.features.simulator.SimulatorCursorManager;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
@@ -39,7 +40,7 @@ import java.util.Collection;
public class SimulatorCommand extends SWCommand {
@LinkedInstance
public SimulatorCursor simulatorCursor;
public SimulatorCursorManager cursorManager;
public SimulatorCommand() {
super("sim", "simulator");
@@ -48,7 +49,7 @@ public class SimulatorCommand extends SWCommand {
@Register(description = "SIMULATOR_HELP")
public void genericCommand(@Validator Player p) {
SWUtils.giveItemToPlayer(p, SimulatorStorage.getWand(p));
// TODO simulatorCursor.calcCursor(p);
cursorManager.showCursor(p, null);
}
@Register(value = "change", description = "SIMULATOR_CHANGE_HELP")
@@ -17,152 +17,84 @@
package de.steamwar.bausystem.features.simulator;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement;
import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator.display.EmptySimulatorCursor;
import de.steamwar.bausystem.features.simulator.display.SimulatorCursor;
import de.steamwar.bausystem.features.simulator.display.SimulatorRenderer;
import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor;
import de.steamwar.bausystem.features.simulator.gui.SimulatorGroupGui;
import de.steamwar.bausystem.features.simulator.gui.SimulatorGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.bausystem.utils.RayTraceUtils;
import de.steamwar.bausystem.features.simulator.display.SimulatorCursorMode;
import de.steamwar.bausystem.utils.cursor.Cursor;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.var;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
@Linked
@MinVersion(19)
public class SimulatorCursorManager implements Listener {
enum SimulatorCursorMode {
TNT, REDSTONE_BLOCK, OBSERVER
}
private final Map<Player, Map<Simulator, Cursor>> activeCursorsByPlayerBySimulator = new HashMap<>();
@EventHandler
public void onPlayerItemEquip(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
// Show simulator cursor for newly held simulator item and trigger simulator display
Simulator heldSimulator = SimulatorStorage.getSimulator(player.getInventory().getItem(event.getNewSlot()));
if (heldSimulator != null) {
Map<Simulator, Cursor> cursorsBySimulator = activeCursorsByPlayerBySimulator.getOrDefault(player, new HashMap<>());
Cursor cursor = cursorsBySimulator.get(heldSimulator);
if (cursor == null) {
REntityServer simulatorServer = SimulatorRenderer.show(heldSimulator, player);
cursor = new Cursor(simulatorServer, player, Material.GLASS, Material.TNT,
Arrays.asList(Cursor.CursorMode.BLOCK_ALIGNED, Cursor.CursorMode.FREE), (clickedLocation, clickedOnEntity, clickAction) -> {
});
cursorsBySimulator.put(heldSimulator, cursor);
activeCursorsByPlayerBySimulator.put(player, cursorsBySimulator);
cursor.show();
}
cursor.show();
ItemStack oldItem = event.getPlayer().getInventory().getItem(event.getPreviousSlot());
if (SimulatorUtils.isSimulatorItem(oldItem)) {
Simulator simulator = SimulatorStorage.getSimulator(oldItem);
hideCursor(event.getPlayer(), simulator);
}
// Hide simulator cursor for previously held simulator item
Simulator previousSimulator = SimulatorStorage.getSimulator(player.getInventory().getItem(event.getPreviousSlot()));
if (previousSimulator != null) {
Map<Simulator, Cursor> cursorsBySimulator = activeCursorsByPlayerBySimulator.getOrDefault(player, new HashMap<>());
Cursor cursor = cursorsBySimulator.get(previousSimulator);
if (cursor != null) {
cursor.hide();
}
ItemStack newItem = event.getPlayer().getInventory().getItem(event.getNewSlot());
if (SimulatorUtils.isSimulatorItem(newItem)) {
Simulator simulator = SimulatorStorage.getSimulator(newItem);
showCursor(event.getPlayer(), simulator);
}
}
private synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, boolean hasSimulatorSelected) {
REntityServer entityServer = cursors.computeIfAbsent(player, __ -> {
REntityServer rEntityServer = new REntityServer();
rEntityServer.addPlayer(player);
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");
/**
* Shows the cursor for the given simulator to the given player. Shows an empty cursor if the
* simulator is null.
*/
public void showCursor(Player player, Simulator simulator) {
var cursorsBySimulator = activeCursorsByPlayerBySimulator.computeIfAbsent(player, __ -> new HashMap<>());
var cursor = cursorsBySimulator.get(simulator);
if (cursor == null) {
if (simulator == null) {
Cursor emptyCursor = new EmptySimulatorCursor(player);
cursorsBySimulator.put(simulator, emptyCursor);
cursor = emptyCursor;
} else {
SWUtils.sendToActionbar(player, "§eAdd new " + type.name);
Cursor newCursor = new SimulatorCursor(simulator, player, SimulatorCursorMode.TNT);
cursorsBySimulator.put(simulator, newCursor);
cursor = newCursor;
}
} else {
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
}
cursor.show();
}
public void hideCursor(Player player, Simulator simulator) {
var cursorsBySimulator = activeCursorsByPlayerBySimulator.get(player);
if (cursorsBySimulator == null) {
return;
}
var cursor = cursorsBySimulator.remove(simulator);
if (cursor != null) {
cursor.hide();
}
}
@Getter
@AllArgsConstructor
public enum CursorType {
}
private void createElement(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, Simulator simulator) {
}
}
@@ -2,7 +2,6 @@ package de.steamwar.bausystem.features.simulator.display;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -18,7 +17,6 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorGroupGui;
import de.steamwar.bausystem.features.simulator.gui.SimulatorGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.utils.cursor.Cursor;
import de.steamwar.entity.REntityServer;
public class SimulatorCursor extends Cursor {
private final Simulator simulator;
@@ -66,9 +64,8 @@ public class SimulatorCursor extends Cursor {
new SimulatorGui(owner, simulator);
} else {
Vector vector = clickedLocation.get().toVector();
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());
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream)
.filter(element -> element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0)).toList();
switch (elements.size()) {
case 0:
@@ -84,7 +81,7 @@ public class SimulatorCursor extends Cursor {
element.open(owner, simulator, group1, back);
break;
default:
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().toList();
if (parents.size() == 1) {
// Open multi element present in Simulator in existing group
SimulatorGui simulatorGui = new SimulatorGui(owner, simulator);
@@ -60,8 +60,8 @@ public class SimulatorRenderer implements Listener {
server.getEntities().forEach(REntity::die);
Map<Vector, Set<Class<?>>> positionCache = new HashMap<>();
simulator.getGroups().stream().map(group -> group.getElements().stream().map(element -> new Pair<>(group, element)).collect(Collectors.toList()))
.flatMap(List::stream).forEach(pair -> {
simulator.getGroups().stream().map(group -> group.getElements().stream().map(element -> new Pair<>(group, element)).toList()).flatMap(List::stream)
.forEach(pair -> {
SimulatorGroup group = pair.getKey();
SimulatorElement<?> element = pair.getValue();