From e9dbb1549fdf0ecc192374d6c4b0fb5d155a78f9 Mon Sep 17 00:00:00 2001 From: Andrew121410 Date: Thu, 5 Sep 2024 22:58:20 -0400 Subject: [PATCH] Add a way to re-align an elevator. --- .../mc/world16elevators/Elevator.java | 100 ++++++++++++++++++ .../commands/ElevatorCMD.java | 96 ++++++++++++++++- .../commands/tabcomplete/ElevatorTab.java | 9 ++ 3 files changed, 203 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/andrew121410/mc/world16elevators/Elevator.java b/src/main/java/com/andrew121410/mc/world16elevators/Elevator.java index bd9f8be..17dadd5 100644 --- a/src/main/java/com/andrew121410/mc/world16elevators/Elevator.java +++ b/src/main/java/com/andrew121410/mc/world16elevators/Elevator.java @@ -358,6 +358,106 @@ public void run() { }.runTaskTimer(plugin, 40L, 40L); } + /** + * This function will fix the elevator if it becomes unaligned. + * Meaning if the elevator thinks it's on a floor, but it's not. + * Like sometimes If I call the elevator to go to my floor 1 and then when the elevator comes to my floor the door opens to nothing. + * Because the elevator bounding box is not aligned with the elevator anymore? + * I still don't know why this happens. + * + * @param player the player who is trying to fix the elevator + * @param confirmChange if true, the elevator will be re-aligned to the floor it's on. If false, the function will show where the elevator thinks it's at. + * @return a map of the blocks that were changed to diamond blocks to show where this function thinks the elevator is at. + */ + + // So extremely cursed + public Map fixUnalignedElevator(Player player, boolean confirmChange) { + if (this.floorsMap == null || this.floorsMap.isEmpty()) { + Bukkit.broadcastMessage("No floors found in elevator: " + this.elevatorName); + return null; + } + + ElevatorFloor lowestFloor = this.floorsMap.values().stream().min(Comparator.comparingInt(ElevatorFloor::getFloor)).orElse(null); + ElevatorFloor topFloor = this.floorsMap.values().stream().max(Comparator.comparingInt(ElevatorFloor::getFloor)).orElse(null); + + int startY = lowestFloor.getBlockUnderMainDoor().getBlockY(); + int endY = topFloor.getBlockUnderMainDoor().getBlockY(); + + // Iterate from the lowest possible floor to the highest possible floor + for (int y = startY; y <= endY; y++) { + // Create a bounding box for the current floor level + BoundingBox floorBoundingBox = new BoundingBox( + this.elevatorMovement.getBoundingBox().getMinX(), + y, + this.elevatorMovement.getBoundingBox().getMinZ(), + this.elevatorMovement.getBoundingBox().getMaxX(), + y, + this.elevatorMovement.getBoundingBox().getMaxZ() + ); + + // Check if the bounding box contains any non-air blocks + boolean foundNonAirBlock = false; + for (int x = (int) floorBoundingBox.getMinX(); x <= floorBoundingBox.getMaxX(); x++) { + for (int z = (int) floorBoundingBox.getMinZ(); z <= floorBoundingBox.getMaxZ(); z++) { + Block block = getBukkitWorld().getBlockAt(x, y, z); + if (block.getType() != Material.AIR) { + foundNonAirBlock = true; + break; + } + } + if (foundNonAirBlock) break; + } + + // If a non-air block is found, re-align the elevator's bounding box and set the elevator to that floor + if (foundNonAirBlock) { + if (confirmChange) { + // Calculate the shift amount + double shiftAmount = y - this.elevatorMovement.getAtDoor().getY(); + + // Shift the elevator bounding box to where the function thinks the elevator is at + this.elevatorMovement.getBoundingBox().shift(0, shiftAmount, 0); + this.boundingBoxExpanded.shift(0, shiftAmount, 0); + + // Update the Y position of the door + this.elevatorMovement.getAtDoor().setY(y); + + // What floor number are we on? + for (ElevatorFloor elevatorFloor : this.floorsMap.values()) { + if (elevatorFloor.getBlockUnderMainDoor().getBlockY() == y) { + this.elevatorMovement.setFloor(elevatorFloor.getFloor()); + break; + } + } + + player.sendMessage(Translate.miniMessage("Fixed elevator alignment to floor: " + this.elevatorMovement.getFloor())); + break; + } else { // Show where the elevator is at. + BoundingBox finalFloorBoundingBox = this.elevatorMovement.getBoundingBox().clone().shift(0, y - this.elevatorMovement.getAtDoor().getY(), 0); + + Location atDoor = this.elevatorMovement.getAtDoor().clone(); + atDoor.setY(y); + Location minX = new Location(getBukkitWorld(), finalFloorBoundingBox.getMinX(), finalFloorBoundingBox.getMinY(), finalFloorBoundingBox.getMinZ()); + Location maxX = new Location(getBukkitWorld(), finalFloorBoundingBox.getMaxX(), finalFloorBoundingBox.getMaxY(), finalFloorBoundingBox.getMaxZ()); + + Map blocksToChangeBack = new HashMap<>(); + + blocksToChangeBack.put(atDoor, atDoor.getBlock().getType()); + blocksToChangeBack.put(minX, minX.getBlock().getType()); + blocksToChangeBack.put(maxX, maxX.getBlock().getType()); + + // Set the blocks to diamond blocks + minX.getBlock().setType(Material.DIAMOND_BLOCK); + maxX.getBlock().setType(Material.DIAMOND_BLOCK); + atDoor.getBlock().setType(Material.OBSIDIAN); + + return blocksToChangeBack; + } + } + } + + return null; + } + /** * Finds floors, and adds them to the elevator * diff --git a/src/main/java/com/andrew121410/mc/world16elevators/commands/ElevatorCMD.java b/src/main/java/com/andrew121410/mc/world16elevators/commands/ElevatorCMD.java index f16d782..30ae17a 100644 --- a/src/main/java/com/andrew121410/mc/world16elevators/commands/ElevatorCMD.java +++ b/src/main/java/com/andrew121410/mc/world16elevators/commands/ElevatorCMD.java @@ -7,6 +7,7 @@ import com.andrew121410.mc.world16elevators.enums.ElevatorStatus; import com.andrew121410.mc.world16elevators.enums.ElevatorWho; import com.andrew121410.mc.world16elevators.storage.ElevatorManager; +import com.andrew121410.mc.world16utils.chat.ChatClickCallbackManager; import com.andrew121410.mc.world16utils.chat.Translate; import com.andrew121410.mc.world16utils.player.PlayerUtils; import com.andrew121410.mc.world16utils.utils.Utils; @@ -17,6 +18,7 @@ import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.CommandBlock; @@ -30,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; public class ElevatorCMD implements CommandExecutor { @@ -153,8 +156,7 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String return true; } return true; - //Create elevator - } else if (args[0].equalsIgnoreCase("create")) { + } else if (args[0].equalsIgnoreCase("create")) { // /elevator create if (!p.hasPermission("world16elevators.create")) { p.sendMessage(Translate.color("&bYou don't have permission to use this command.")); return true; @@ -791,6 +793,96 @@ public void run() { } else { p.sendMessage(Translate.chat("&6/elevator teleport &e &9")); } + } else if (args[0].equalsIgnoreCase("realign")) { // /elevator realign + if (!p.hasPermission("world16elevators.realign")) { + p.sendMessage(Translate.color("&bYou don't have permission to use this command.")); + return true; + } + if (args.length == 3) { + ElevatorArguments elevatorArguments = getElevatorArguments(args, 2); + ElevatorController elevatorController = elevatorArguments.getElevatorController(); + if (elevatorController == null) { + p.sendMessage("Elevator controller was not found."); + return true; + } + Elevator elevator = elevatorArguments.getElevator(); + if (elevator == null) { + p.sendMessage("Elevator was not found."); + return true; + } + + ChatClickCallbackManager chatClickCallbackManager = this.plugin.getOtherPlugins().getWorld16Utils().getChatClickCallbackManager(); + Map blockMap = elevator.fixUnalignedElevator(p, false); + + p.sendMessage(Translate.miniMessage("PLEASE go check to see if the elevator is aligned correctly. Look for diamond blocks.")); + p.sendMessage(Translate.miniMessage("Click here to undo the diamond block changes.").clickEvent(chatClickCallbackManager.create(p, p1 -> { + blockMap.forEach((location, material) -> location.getBlock().setType(material)); + p1.sendMessage(Translate.miniMessage("The original blocks have been restored.")); + }))); + p.sendMessage(Translate.miniMessage("CLICK HERE TO CONFIRM THE CHANGES.").clickEvent(chatClickCallbackManager.create(p, p1 -> { + elevator.fixUnalignedElevator(p, true); + blockMap.forEach((location, material) -> location.getBlock().setType(material)); + p1.sendMessage(Translate.miniMessage("The changes have been confirmed.")); + }))); + return true; + } else { + p.sendMessage(Translate.chat("&6/elevator realign &e &9")); + } + } else if (args[0].equalsIgnoreCase("show-boundingbox")) { // /elevator show-boundingbox + if (!p.hasPermission("world16elevators.show-boundingbox")) { + p.sendMessage(Translate.color("&bYou don't have permission to use this command.")); + return true; + } + if (args.length == 3) { + ElevatorArguments elevatorArguments = getElevatorArguments(args, 2); + ElevatorController elevatorController = elevatorArguments.getElevatorController(); + if (elevatorController == null) { + p.sendMessage("Elevator controller was not found."); + return true; + } + Elevator elevator = elevatorArguments.getElevator(); + if (elevator == null) { + p.sendMessage("Elevator was not found."); + return true; + } + + ChatClickCallbackManager chatClickCallbackManager = this.plugin.getOtherPlugins().getWorld16Utils().getChatClickCallbackManager(); + + Location atDoor = elevator.getElevatorMovement().getAtDoor().clone(); + BoundingBox boundingBox = elevator.getElevatorMovement().getBoundingBox().clone(); + BoundingBox expandedBoundingBox = elevator.getBoundingBoxExpanded().clone(); + + Map blockMap = new HashMap<>(); + + Location minX = new Location(p.getWorld(), boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ()); + Location maxX = new Location(p.getWorld(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ()); + + Location expandedMinX = new Location(p.getWorld(), expandedBoundingBox.getMinX(), expandedBoundingBox.getMinY(), expandedBoundingBox.getMinZ()); + Location expandedMaxX = new Location(p.getWorld(), expandedBoundingBox.getMaxX(), expandedBoundingBox.getMaxY(), expandedBoundingBox.getMaxZ()); + + // Save the blocks. + blockMap.put(atDoor, atDoor.getBlock().getType()); + blockMap.put(minX, minX.getBlock().getType()); + blockMap.put(maxX, maxX.getBlock().getType()); + blockMap.put(expandedMinX, expandedMinX.getBlock().getType()); + blockMap.put(expandedMaxX, expandedMaxX.getBlock().getType()); + + minX.getBlock().setType(Material.DIAMOND_BLOCK); + maxX.getBlock().setType(Material.DIAMOND_BLOCK); + expandedMinX.getBlock().setType(Material.REDSTONE_BLOCK); + expandedMaxX.getBlock().setType(Material.REDSTONE_BLOCK); + atDoor.getBlock().setType(Material.OBSIDIAN); + + p.sendMessage(Translate.miniMessage("Click here to undo the block changes").clickEvent(chatClickCallbackManager.create(p, p1 -> { + blockMap.forEach((location, material) -> location.getBlock().setType(material)); + p1.sendMessage(Translate.miniMessage("The original blocks have been restored.")); + }))); + + p.sendMessage(Translate.miniMessage("The normal bounding box is the diamond blocks, and the expanded bounding box is the redstone blocks.")); + return true; + } else { + p.sendMessage(Translate.chat("&6/elevator realign &e &9")); + } } return true; } diff --git a/src/main/java/com/andrew121410/mc/world16elevators/commands/tabcomplete/ElevatorTab.java b/src/main/java/com/andrew121410/mc/world16elevators/commands/tabcomplete/ElevatorTab.java index fd1089f..7b96f8d 100644 --- a/src/main/java/com/andrew121410/mc/world16elevators/commands/tabcomplete/ElevatorTab.java +++ b/src/main/java/com/andrew121410/mc/world16elevators/commands/tabcomplete/ElevatorTab.java @@ -44,6 +44,8 @@ public ElevatorTab(World16Elevators plugin) { tabCompleteList.add("copysettingsfrom"); tabCompleteList.add("tostring"); tabCompleteList.add("teleport"); + tabCompleteList.add("realign"); + tabCompleteList.add("show-boundingbox"); this.elevatorControllerMap = this.plugin.getMemoryHolder().getElevatorControllerMap(); this.soundList = new ArrayList<>(); for (Sound value : Sound.values()) { @@ -189,6 +191,13 @@ public List onTabComplete(CommandSender sender, Command cmd, String aile return this.elevatorControllerMap.containsKey(args[1]) ? new ArrayList<>(this.elevatorControllerMap.get(args[1]).getElevatorsMap().keySet()) : null; } return null; + } else if (args[0].equalsIgnoreCase("realign") || args[0].equalsIgnoreCase("show-boundingbox")) { + if (args.length == 2) { + return getContainsString(args[1], controllerList); + } else if (args.length == 3) { + return this.elevatorControllerMap.containsKey(args[1]) ? new ArrayList<>(this.elevatorControllerMap.get(args[1]).getElevatorsMap().keySet()) : null; + } + return null; } return null; }