Update from Git Manager GUI
This commit is contained in:
49
src/main/java/de/mviper/elevator/DatabaseManager.java
Normal file
49
src/main/java/de/mviper/elevator/DatabaseManager.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DatabaseManager {
|
||||||
|
private File localFile;
|
||||||
|
private FileConfiguration localConfig;
|
||||||
|
|
||||||
|
public DatabaseManager() { setupLocalFile(); }
|
||||||
|
|
||||||
|
private void setupLocalFile() {
|
||||||
|
localFile = new File(Elevator.getInstance().getDataFolder(), "elevators.yml");
|
||||||
|
if (!localFile.exists()) {
|
||||||
|
try {
|
||||||
|
Elevator.getInstance().getDataFolder().mkdirs();
|
||||||
|
localFile.createNewFile();
|
||||||
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
}
|
||||||
|
localConfig = YamlConfiguration.loadConfiguration(localFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addElevator(Location loc, UUID owner) {
|
||||||
|
String key = locToKey(loc);
|
||||||
|
localConfig.set(key + ".owner", owner.toString());
|
||||||
|
localConfig.set(key + ".name", "Etage");
|
||||||
|
localConfig.set(key + ".public", true);
|
||||||
|
saveLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeElevator(Location loc) { localConfig.set(locToKey(loc), null); saveLocal(); }
|
||||||
|
public boolean isElevator(Location loc) { return localConfig.contains(locToKey(loc)); }
|
||||||
|
public String getFloorCustomName(Location loc) { return localConfig.getString(locToKey(loc) + ".name", "Etage"); }
|
||||||
|
public void setFloorName(Location loc, String name) { localConfig.set(locToKey(loc) + ".name", name); saveLocal(); }
|
||||||
|
|
||||||
|
public UUID getOwner(Location loc) {
|
||||||
|
String s = localConfig.getString(locToKey(loc) + ".owner");
|
||||||
|
return s != null ? UUID.fromString(s) : UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPublic(Location loc) { return localConfig.getBoolean(locToKey(loc) + ".public", true); }
|
||||||
|
public void setPublic(Location loc, boolean status) { localConfig.set(locToKey(loc) + ".public", status); saveLocal(); }
|
||||||
|
private String locToKey(Location l) { return "data." + l.getWorld().getName() + "_" + l.getBlockX() + "_" + l.getBlockY() + "_" + l.getBlockZ(); }
|
||||||
|
private void saveLocal() { try { localConfig.save(localFile); } catch (IOException e) { e.printStackTrace(); } }
|
||||||
|
}
|
||||||
51
src/main/java/de/mviper/elevator/Elevator.java
Normal file
51
src/main/java/de/mviper/elevator/Elevator.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemFlag;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.ShapedRecipe;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class Elevator extends JavaPlugin {
|
||||||
|
private static Elevator instance;
|
||||||
|
private DatabaseManager databaseManager;
|
||||||
|
private HologramManager hologramManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
saveDefaultConfig();
|
||||||
|
this.databaseManager = new DatabaseManager();
|
||||||
|
this.hologramManager = new HologramManager();
|
||||||
|
hologramManager.purgeAllHolograms();
|
||||||
|
|
||||||
|
getServer().getPluginManager().registerEvents(new ElevatorListener(), this);
|
||||||
|
getCommand("elevator").setExecutor(new ElevatorCommand());
|
||||||
|
registerElevatorRecipe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerElevatorRecipe() {
|
||||||
|
ItemStack item = new ItemStack(Material.DAYLIGHT_DETECTOR);
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
if (meta != null) {
|
||||||
|
meta.setDisplayName("§b§lAufzug-Modul");
|
||||||
|
meta.setLore(Arrays.asList("§7Platziere dies als Etage.", "§eRechtsklick: §fMenü öffnen", "§eSpringen/Sneaken: §fReisen"));
|
||||||
|
meta.addEnchant(Enchantment.LUCK, 1, true);
|
||||||
|
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
ShapedRecipe recipe = new ShapedRecipe(new NamespacedKey(this, "elevator_module"), item);
|
||||||
|
recipe.shape("S.S", ".I.", "S.S");
|
||||||
|
recipe.setIngredient('S', Material.DAYLIGHT_DETECTOR);
|
||||||
|
recipe.setIngredient('I', Material.IRON_BLOCK);
|
||||||
|
getServer().addRecipe(recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Elevator getInstance() { return instance; }
|
||||||
|
public DatabaseManager getDatabaseManager() { return databaseManager; }
|
||||||
|
public HologramManager getHologramManager() { return hologramManager; }
|
||||||
|
}
|
||||||
83
src/main/java/de/mviper/elevator/ElevatorCommand.java
Normal file
83
src/main/java/de/mviper/elevator/ElevatorCommand.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class ElevatorCommand implements CommandExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) return true;
|
||||||
|
Player p = (Player) sender;
|
||||||
|
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
Block moduleBlock = null;
|
||||||
|
|
||||||
|
// GROBE ERKENNUNG:
|
||||||
|
// Wir prüfen einen kleinen Radius (0.5 Blöcke) um den Spieler und 1.2 Blöcke nach unten.
|
||||||
|
// Das stellt sicher, dass man nicht pixelgenau in der Mitte stehen muss.
|
||||||
|
Location pLoc = p.getLocation();
|
||||||
|
|
||||||
|
outerLoop:
|
||||||
|
for (double x = -0.5; x <= 0.5; x += 0.5) {
|
||||||
|
for (double z = -0.5; z <= 0.5; z += 0.5) {
|
||||||
|
for (double y = -1.2; y <= 0.2; y += 0.4) {
|
||||||
|
Block check = pLoc.clone().add(x, y, z).getBlock();
|
||||||
|
if (check.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(check.getLocation())) {
|
||||||
|
moduleBlock = check;
|
||||||
|
break outerLoop; // Modul gefunden, Suche beenden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moduleBlock == null) {
|
||||||
|
p.sendMessage("§8[§bElevator§8] §cKein Aufzug-Modul in deiner Nähe gefunden!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Berechtigungs-Check (Besitzer oder Admin)
|
||||||
|
if (!db.getOwner(moduleBlock.getLocation()).equals(p.getUniqueId()) && !p.hasPermission("elevator.admin")) {
|
||||||
|
p.sendMessage("§8[§bElevator§8] §cDies ist nicht dein Aufzug!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Befehl: /elevator name <Text>
|
||||||
|
if (args.length >= 2 && args[0].equalsIgnoreCase("name")) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 1; i < args.length; i++) sb.append(args[i]).append(" ");
|
||||||
|
String newName = ChatColor.translateAlternateColorCodes('&', sb.toString().trim());
|
||||||
|
|
||||||
|
db.setFloorName(moduleBlock.getLocation(), newName);
|
||||||
|
p.sendMessage("§8[§bElevator§8] §aEtage benannt: " + newName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Befehle: /elevator private | public
|
||||||
|
if (args.length == 1) {
|
||||||
|
if (args[0].equalsIgnoreCase("private")) {
|
||||||
|
db.setPublic(moduleBlock.getLocation(), false);
|
||||||
|
p.sendMessage("§8[§bElevator§8] §7Status: §cPrivat");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args[0].equalsIgnoreCase("public")) {
|
||||||
|
db.setPublic(moduleBlock.getLocation(), true);
|
||||||
|
p.sendMessage("§8[§bElevator§8] §7Status: §aÖffentlich");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hilfe-Anzeige
|
||||||
|
p.sendMessage("§b--- Elevator Hilfe ---");
|
||||||
|
p.sendMessage("§e/elevator name <Text> §7- Namen der Etage ändern");
|
||||||
|
p.sendMessage("§e/elevator private §7- Zugriff nur für dich");
|
||||||
|
p.sendMessage("§e/elevator public §7- Zugriff für alle");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
337
src/main/java/de/mviper/elevator/ElevatorListener.java
Normal file
337
src/main/java/de/mviper/elevator/ElevatorListener.java
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.Sign;
|
||||||
|
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.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.block.SignChangeEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ElevatorListener implements Listener {
|
||||||
|
|
||||||
|
private final String SKULL_URL =
|
||||||
|
"http://textures.minecraft.net/texture/be8440e9d54ec7630b3e387f84e19e15f0b09d438a6bd784305df5d7608e6903";
|
||||||
|
|
||||||
|
private final Map<UUID, Long> cooldowns = new HashMap<>();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInteract(PlayerInteractEvent e) {
|
||||||
|
if (e.getAction() != Action.RIGHT_CLICK_BLOCK || e.getClickedBlock() == null) return;
|
||||||
|
|
||||||
|
Block block = e.getClickedBlock();
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
Location elevatorLoc = null;
|
||||||
|
|
||||||
|
if (block.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(block.getLocation())) {
|
||||||
|
elevatorLoc = block.getLocation();
|
||||||
|
} else if (block.getType().name().contains("SIGN")) {
|
||||||
|
Sign sign = (Sign) block.getState();
|
||||||
|
if (sign.getLine(0).equalsIgnoreCase("[Elevator]") || sign.getLine(1).contains("AUFZUG")) {
|
||||||
|
elevatorLoc = findModuleNearby(block.getLocation(), 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elevatorLoc != null) {
|
||||||
|
if (!db.isPublic(elevatorLoc)
|
||||||
|
&& !db.getOwner(elevatorLoc).equals(e.getPlayer().getUniqueId())
|
||||||
|
&& !e.getPlayer().hasPermission("elevator.admin")) {
|
||||||
|
e.getPlayer().sendMessage("§cDieser Aufzug ist privat!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.setCancelled(true);
|
||||||
|
openGUI(e.getPlayer(), elevatorLoc.getBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onSignChange(SignChangeEvent e) {
|
||||||
|
if (!e.getLine(0).equalsIgnoreCase("[Elevator]")) return;
|
||||||
|
|
||||||
|
Location loc = findModuleNearby(e.getBlock().getLocation(), 3);
|
||||||
|
|
||||||
|
e.setLine(0, "§7§m--§b §l● §7§m--");
|
||||||
|
e.setLine(1, "§b§lAUFZUG");
|
||||||
|
|
||||||
|
if (loc != null) {
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
String customName = db.getFloorCustomName(loc);
|
||||||
|
|
||||||
|
if (customName != null && !customName.isEmpty()) {
|
||||||
|
e.setLine(2, "§f" + customName);
|
||||||
|
} else {
|
||||||
|
List<Block> floors = findFloorsInColumn(loc.getBlock());
|
||||||
|
floors.sort(Comparator.comparingInt(Block::getY));
|
||||||
|
|
||||||
|
int floorIndex = -1;
|
||||||
|
for (int i = 0; i < floors.size(); i++) {
|
||||||
|
if (floors.get(i).getY() == loc.getBlockY()) {
|
||||||
|
floorIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String label = (floorIndex <= 0) ? "Erdgeschoss" : "Etage " + floorIndex;
|
||||||
|
e.setLine(2, "§f" + label);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.setLine(2, "§8(Bereit)");
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setLine(3, "§7§m--§b §l● §7§m--");
|
||||||
|
e.getPlayer().sendMessage("§aAufzug-Schild wurde schick gemacht!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Location findModuleNearby(Location loc, int radius) {
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
for (int x = -radius; x <= radius; x++) {
|
||||||
|
for (int y = -radius; y <= radius; y++) {
|
||||||
|
for (int z = -radius; z <= radius; z++) {
|
||||||
|
Location check = loc.clone().add(x, y, z);
|
||||||
|
if (check.getBlock().getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(check)) {
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openGUI(Player p, Block clickedBlock) {
|
||||||
|
List<Block> floors = findFloorsInColumn(clickedBlock);
|
||||||
|
floors.sort(Comparator.comparingInt(Block::getY));
|
||||||
|
|
||||||
|
Inventory inv = Bukkit.createInventory(null, 27, "§8» §bAufzug-Menü");
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
|
||||||
|
for (int i = 0; i < floors.size(); i++) {
|
||||||
|
Block f = floors.get(i);
|
||||||
|
boolean isCurrent = f.getY() == clickedBlock.getY();
|
||||||
|
|
||||||
|
ItemStack item = isCurrent ? new ItemStack(Material.BEACON) : SkullCreator.getCustomSkull(SKULL_URL);
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
|
||||||
|
String floorLabel = (i == 0) ? "Erdgeschoss" : "Etage " + i;
|
||||||
|
meta.setDisplayName((isCurrent ? "§a● " : "§b○ ") + "§l" + floorLabel);
|
||||||
|
|
||||||
|
// Lore ohne sichtbare Koordinaten, aber mit versteckter ID am Ende
|
||||||
|
String customName = db.getFloorCustomName(f.getLocation());
|
||||||
|
meta.setLore(Arrays.asList(
|
||||||
|
"§7Name: §f" + (customName != null ? customName : floorLabel),
|
||||||
|
"",
|
||||||
|
isCurrent ? "§7(Diese Etage)" : "§e➤ Klicken zum Reisen",
|
||||||
|
"§0HIDDEN:" + f.getY() // Versteckte Zeile (Schwarz auf Schwarz/Unsichtbar)
|
||||||
|
));
|
||||||
|
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
inv.addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.openInventory(inv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent e) {
|
||||||
|
if (!e.getView().getTitle().equals("§8» §bAufzug-Menü")) return;
|
||||||
|
|
||||||
|
e.setCancelled(true);
|
||||||
|
Player p = (Player) e.getWhoClicked();
|
||||||
|
|
||||||
|
if (e.getCurrentItem() == null || !e.getCurrentItem().hasItemMeta()) return;
|
||||||
|
if (e.getCurrentItem().getType() == Material.BEACON) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<String> lore = e.getCurrentItem().getItemMeta().getLore();
|
||||||
|
// Die versteckte Koordinate steht in der letzten Zeile (Index 3)
|
||||||
|
int targetY = Integer.parseInt(lore.get(3).replace("§0HIDDEN:", ""));
|
||||||
|
p.closeInventory();
|
||||||
|
|
||||||
|
// Prüfe grob, ob der Spieler auf dem Modul steht
|
||||||
|
Block module = findModuleUnderPlayer(p);
|
||||||
|
|
||||||
|
if (module != null) {
|
||||||
|
performTeleport(p, targetY);
|
||||||
|
} else {
|
||||||
|
p.sendMessage("§eBitte stelle dich innerhalb von 5 Sekunden auf das Aufzug-Modul...");
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int timer = 0;
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!p.isOnline()) { cancel(); return; }
|
||||||
|
Block current = findModuleUnderPlayer(p);
|
||||||
|
if (current != null) {
|
||||||
|
performTeleport(p, targetY);
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
timer++;
|
||||||
|
if (timer >= 100) {
|
||||||
|
p.sendMessage("§cVorgang abgebrochen: Du hast das Modul nicht rechtzeitig betreten.");
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskTimer(Elevator.getInstance(), 0L, 1L);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
p.sendMessage("§cFehler beim Verarbeiten der Reisedaten.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performTeleport(Player p, int targetY) {
|
||||||
|
Location targetLoc = p.getLocation().clone();
|
||||||
|
targetLoc.setY(targetY + 1.1);
|
||||||
|
p.teleport(targetLoc);
|
||||||
|
p.playSound(p.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1.2f);
|
||||||
|
p.sendMessage("§6Abfahrt!");
|
||||||
|
showVisualFeedback(p, p.getWorld().getBlockAt(p.getLocation().getBlockX(), targetY, p.getLocation().getBlockZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
|
public void onJump(PlayerMoveEvent e) {
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
if (e.getTo().getY() <= e.getFrom().getY()) return;
|
||||||
|
|
||||||
|
if (cooldowns.containsKey(p.getUniqueId()) && System.currentTimeMillis() - cooldowns.get(p.getUniqueId()) < 300) return;
|
||||||
|
|
||||||
|
Block b = findModuleUnderPlayer(p);
|
||||||
|
if (b != null) {
|
||||||
|
cooldowns.put(p.getUniqueId(), System.currentTimeMillis());
|
||||||
|
handleQuickMove(p, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onSneak(PlayerToggleSneakEvent e) {
|
||||||
|
if (!e.isSneaking()) return;
|
||||||
|
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
if (cooldowns.containsKey(p.getUniqueId()) && System.currentTimeMillis() - cooldowns.get(p.getUniqueId()) < 300) return;
|
||||||
|
|
||||||
|
Block b = findModuleUnderPlayer(p);
|
||||||
|
if (b != null) {
|
||||||
|
cooldowns.put(p.getUniqueId(), System.currentTimeMillis());
|
||||||
|
handleQuickMove(p, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hilfsmethode für grobe Erkennung (überall im Listener genutzt)
|
||||||
|
private Block findModuleUnderPlayer(Player p) {
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
Location l = p.getLocation();
|
||||||
|
// Check Fußblock und Block darunter
|
||||||
|
Block feet = l.getBlock();
|
||||||
|
if (feet.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(feet.getLocation())) return feet;
|
||||||
|
Block below = feet.getRelative(0, -1, 0);
|
||||||
|
if (below.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(below.getLocation())) return below;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isElevatorModule(Block b) {
|
||||||
|
if (b == null) return false;
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
return b.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(b.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleQuickMove(Player p, int dir) {
|
||||||
|
Block b = findModuleUnderPlayer(p);
|
||||||
|
if (b == null) return;
|
||||||
|
|
||||||
|
List<Block> floors = findFloorsInColumn(b);
|
||||||
|
floors.sort(Comparator.comparingInt(Block::getY));
|
||||||
|
|
||||||
|
int currentIdx = -1;
|
||||||
|
for (int i = 0; i < floors.size(); i++) {
|
||||||
|
if (floors.get(i).getY() == b.getY()) {
|
||||||
|
currentIdx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextIdx = currentIdx + dir;
|
||||||
|
if (nextIdx >= 0 && nextIdx < floors.size()) {
|
||||||
|
Block targetBlock = floors.get(nextIdx);
|
||||||
|
Location loc = targetBlock.getLocation().add(0.5, 1.1, 0.5);
|
||||||
|
loc.setYaw(p.getLocation().getYaw());
|
||||||
|
loc.setPitch(p.getLocation().getPitch());
|
||||||
|
|
||||||
|
p.setVelocity(new Vector(0, 0, 0));
|
||||||
|
p.teleport(loc);
|
||||||
|
p.playSound(loc, Sound.BLOCK_IRON_DOOR_OPEN, 0.5f, 1.5f);
|
||||||
|
showVisualFeedback(p, targetBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Block> findFloorsInColumn(Block b) {
|
||||||
|
List<Block> floors = new ArrayList<>();
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
|
||||||
|
for (int y = b.getWorld().getMinHeight(); y < b.getWorld().getMaxHeight(); y++) {
|
||||||
|
Block check = b.getWorld().getBlockAt(b.getX(), y, b.getZ());
|
||||||
|
if (check.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(check.getLocation())) {
|
||||||
|
floors.add(check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return floors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showVisualFeedback(Player p, Block targetBlock) {
|
||||||
|
List<Block> floors = findFloorsInColumn(targetBlock);
|
||||||
|
floors.sort(Comparator.comparingInt(Block::getY));
|
||||||
|
|
||||||
|
int floorIndex = -1;
|
||||||
|
for (int i = 0; i < floors.size(); i++) {
|
||||||
|
if (floors.get(i).getY() == targetBlock.getY()) {
|
||||||
|
floorIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String label = (floorIndex <= 0) ? "Erdgeschoss" : "Etage " + floorIndex;
|
||||||
|
p.sendTitle("", "§b" + label, 5, 25, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlace(BlockPlaceEvent e) {
|
||||||
|
if (e.getItemInHand() != null
|
||||||
|
&& e.getItemInHand().hasItemMeta()
|
||||||
|
&& e.getItemInHand().getItemMeta().getDisplayName().contains("Aufzug-Modul")) {
|
||||||
|
|
||||||
|
Elevator.getInstance().getDatabaseManager()
|
||||||
|
.addElevator(e.getBlockPlaced().getLocation(), e.getPlayer().getUniqueId());
|
||||||
|
|
||||||
|
e.getPlayer().sendMessage("§8[§bElevator§8] §aModul erfolgreich registriert!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBreak(BlockBreakEvent e) {
|
||||||
|
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||||
|
if (!db.isElevator(e.getBlock().getLocation())) return;
|
||||||
|
|
||||||
|
if (!e.getPlayer().getUniqueId().equals(db.getOwner(e.getBlock().getLocation()))
|
||||||
|
&& !e.getPlayer().hasPermission("elevator.admin")) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
e.getPlayer().sendMessage("§cDas ist nicht dein Aufzug!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.removeElevator(e.getBlock().getLocation());
|
||||||
|
e.getPlayer().sendMessage("§eAufzug-Modul entfernt.");
|
||||||
|
}
|
||||||
|
}
|
||||||
50
src/main/java/de/mviper/elevator/HologramManager.java
Normal file
50
src/main/java/de/mviper/elevator/HologramManager.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.entity.Display;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.TextDisplay;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.util.Transformation;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
public class HologramManager {
|
||||||
|
|
||||||
|
public void spawnElevatorHolo(Location loc, String floorLabel) {
|
||||||
|
// Holen des benutzerdefinierten Namens für den Block unter den Füßen
|
||||||
|
String name = Elevator.getInstance().getDatabaseManager().getFloorCustomName(loc.clone().add(0, -1.1, 0).getBlock().getLocation());
|
||||||
|
|
||||||
|
TextDisplay display = loc.getWorld().spawn(loc.clone().add(0, 1.5, 0), TextDisplay.class, d -> {
|
||||||
|
d.setText("§b" + name + "\n§8» §f" + floorLabel + " §8«");
|
||||||
|
d.setBillboard(Display.Billboard.CENTER);
|
||||||
|
d.setShadowed(true);
|
||||||
|
d.setBackgroundColor(Color.fromARGB(120, 0, 0, 0));
|
||||||
|
d.addScoreboardTag("ElevatorHolo");
|
||||||
|
|
||||||
|
Transformation trans = d.getTransformation();
|
||||||
|
trans.getScale().set(new Vector3f(1.4f, 1.4f, 1.4f));
|
||||||
|
d.setTransformation(trans);
|
||||||
|
});
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
int ticks = 0;
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (ticks++ > 40 || !display.isValid()) {
|
||||||
|
display.remove();
|
||||||
|
this.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
display.teleport(display.getLocation().add(0, 0.015, 0));
|
||||||
|
}
|
||||||
|
}.runTaskTimer(Elevator.getInstance(), 0L, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void purgeAllHolograms() {
|
||||||
|
for (World w : Bukkit.getWorlds()) {
|
||||||
|
for (Entity e : w.getEntities()) {
|
||||||
|
if (e instanceof TextDisplay && e.getScoreboardTags().contains("ElevatorHolo")) e.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/main/java/de/mviper/elevator/SkullCreator.java
Normal file
46
src/main/java/de/mviper/elevator/SkullCreator.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package de.mviper.elevator;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
import org.bukkit.profile.PlayerProfile;
|
||||||
|
import org.bukkit.profile.PlayerTextures;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class SkullCreator {
|
||||||
|
public static ItemStack getCustomSkull(String urlString) {
|
||||||
|
ItemStack item = new ItemStack(Material.PLAYER_HEAD);
|
||||||
|
if (urlString == null || urlString.isEmpty()) return item;
|
||||||
|
|
||||||
|
SkullMeta meta = (SkullMeta) item.getItemMeta();
|
||||||
|
if (meta == null) return item;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Erstellt ein neues, leeres Profil mit einer zufälligen UUID
|
||||||
|
PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), "Elevator");
|
||||||
|
PlayerTextures textures = profile.getTextures();
|
||||||
|
|
||||||
|
// Setzt die URL für die Textur
|
||||||
|
URL url = new URL(urlString);
|
||||||
|
textures.setSkin(url);
|
||||||
|
|
||||||
|
// Wichtig: Texturen zurück ins Profil schreiben
|
||||||
|
profile.setTextures(textures);
|
||||||
|
|
||||||
|
// Profil in die SkullMeta setzen (Offizielle API!)
|
||||||
|
meta.setOwnerProfile(profile);
|
||||||
|
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
Bukkit.getLogger().warning("Ungültige Skull-URL: " + urlString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/main/resources/config.yml
Normal file
38
src/main/resources/config.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Elevator Config by mviper
|
||||||
|
mysql:
|
||||||
|
enable: false
|
||||||
|
host: "localhost"
|
||||||
|
port: 3306
|
||||||
|
database: "minecraft"
|
||||||
|
user: "root"
|
||||||
|
password: ""
|
||||||
|
|
||||||
|
settings:
|
||||||
|
max-distance: 64
|
||||||
|
hologram-duration: 45
|
||||||
|
cooldown: 500
|
||||||
|
|
||||||
|
visuals:
|
||||||
|
enable-particles: true
|
||||||
|
particle-type: "FIREWORKS_SPARK"
|
||||||
|
# Nutze HIER nur das & Zeichen für Farben!
|
||||||
|
hologram-text: "&8&l» &b&lEtage %floor% &8&l«"
|
||||||
|
hologram-height-offset: 2.2
|
||||||
|
hologram-scale: 1.5
|
||||||
|
actionbar-text: "&fTransport: &b&lEtage %floor%"
|
||||||
|
hologram-background-color:
|
||||||
|
alpha: 120
|
||||||
|
red: 0
|
||||||
|
green: 0
|
||||||
|
blue: 0
|
||||||
|
|
||||||
|
sounds:
|
||||||
|
enable: true
|
||||||
|
type: "BLOCK_NOTE_BLOCK_CHIME"
|
||||||
|
volume: 1.0
|
||||||
|
pitch: 1.5
|
||||||
|
|
||||||
|
messages:
|
||||||
|
prefix: "&8[&bElevator&8] "
|
||||||
|
registered: "&aModul erfolgreich registriert!"
|
||||||
|
no-target: "&cKeine weitere Etage gefunden."
|
||||||
9
src/main/resources/plugin.yml
Normal file
9
src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name: Elevator
|
||||||
|
version: 1.0
|
||||||
|
main: de.mviper.elevator.Elevator
|
||||||
|
api-version: 1.20
|
||||||
|
author: mviper
|
||||||
|
commands:
|
||||||
|
elevator:
|
||||||
|
description: Verwalte deinen Aufzug.
|
||||||
|
permission: elevator.use
|
||||||
Reference in New Issue
Block a user