219 lines
8.0 KiB
Java
219 lines
8.0 KiB
Java
package de.nexuslobby.modules.intro;
|
|
|
|
import de.nexuslobby.NexusLobby;
|
|
import de.nexuslobby.api.Module;
|
|
import net.md_5.bungee.api.ChatMessageType;
|
|
import net.md_5.bungee.api.chat.TextComponent;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.GameMode;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.command.Command;
|
|
import org.bukkit.command.CommandExecutor;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.configuration.file.FileConfiguration;
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
|
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.*;
|
|
|
|
public class IntroModule implements Module, Listener, CommandExecutor {
|
|
|
|
private final Set<UUID> activeIntro = new HashSet<>();
|
|
private final List<Location> points = new ArrayList<>();
|
|
private File configFile;
|
|
private FileConfiguration config;
|
|
|
|
// --- Einstellungen ---
|
|
private final int TICKS_FLUG = 70; // Dauer der Fahrt zwischen zwei Punkten (3.5 Sek)
|
|
private final int TICKS_PAUSE = 30; // Standzeit an jedem Punkt (1.5 Sek)
|
|
|
|
@Override
|
|
public String getName() { return "Intro"; }
|
|
|
|
@Override
|
|
public void onEnable() {
|
|
Bukkit.getPluginManager().registerEvents(this, NexusLobby.getInstance());
|
|
if (NexusLobby.getInstance().getCommand("intro") != null) {
|
|
NexusLobby.getInstance().getCommand("intro").setExecutor(this);
|
|
}
|
|
loadPoints();
|
|
}
|
|
|
|
@Override
|
|
public void onDisable() {
|
|
activeIntro.clear();
|
|
}
|
|
|
|
private void loadPoints() {
|
|
points.clear();
|
|
configFile = new File(NexusLobby.getInstance().getDataFolder(), "intro.yml");
|
|
if (!configFile.exists()) {
|
|
try { configFile.createNewFile(); } catch (IOException ignored) {}
|
|
}
|
|
config = YamlConfiguration.loadConfiguration(configFile);
|
|
List<?> list = config.getList("points");
|
|
if (list != null) {
|
|
for (Object obj : list) {
|
|
if (obj instanceof Location loc) points.add(loc);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void savePoints() {
|
|
config.set("points", points);
|
|
try { config.save(configFile); } catch (IOException e) { e.printStackTrace(); }
|
|
}
|
|
|
|
@EventHandler
|
|
public void onJoin(PlayerJoinEvent event) {
|
|
if (!event.getPlayer().hasPlayedBefore() && points.size() >= 2) {
|
|
startIntro(event.getPlayer());
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void onSneak(PlayerToggleSneakEvent event) {
|
|
if (activeIntro.contains(event.getPlayer().getUniqueId()) && event.isSneaking()) {
|
|
stopIntro(event.getPlayer(), true);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
|
if (!(sender instanceof Player p)) return true;
|
|
if (!p.hasPermission("nexuslobby.admin")) return true;
|
|
|
|
if (args.length == 0) {
|
|
p.sendMessage("§8§m------------------------------------");
|
|
p.sendMessage("§6§lNexus Intro System (Cinematic)");
|
|
p.sendMessage("§e/intro add §7- Punkt hinzufügen");
|
|
p.sendMessage("§e/intro clear §7- Alle Punkte löschen");
|
|
p.sendMessage("§e/intro start §7- Teste die Fahrt");
|
|
p.sendMessage("§8§m------------------------------------");
|
|
return true;
|
|
}
|
|
|
|
switch (args[0].toLowerCase()) {
|
|
case "add" -> {
|
|
points.add(p.getLocation());
|
|
savePoints();
|
|
p.sendMessage("§8[§6Nexus§8] §aPunkt #" + points.size() + " wurde gesetzt!");
|
|
}
|
|
case "clear" -> {
|
|
points.clear();
|
|
savePoints();
|
|
p.sendMessage("§8[§6Nexus§8] §cAlle Intro-Punkte wurden gelöscht.");
|
|
}
|
|
case "start" -> {
|
|
if (points.size() < 2) {
|
|
p.sendMessage("§8[§6Nexus§8] §cDu brauchst mindestens 2 Punkte für eine Fahrt.");
|
|
} else {
|
|
startIntro(p);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void startIntro(Player player) {
|
|
activeIntro.add(player.getUniqueId());
|
|
player.setGameMode(GameMode.SPECTATOR);
|
|
|
|
new BukkitRunnable() {
|
|
int currentSegment = 0;
|
|
int tickInSegment = 0;
|
|
boolean isPausing = true;
|
|
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
if (!player.isOnline() || !activeIntro.contains(player.getUniqueId())) {
|
|
this.cancel();
|
|
return;
|
|
}
|
|
|
|
if (currentSegment >= points.size() - 1) {
|
|
stopIntro(player, false);
|
|
this.cancel();
|
|
return;
|
|
}
|
|
|
|
Location start = points.get(currentSegment);
|
|
Location end = points.get(currentSegment + 1);
|
|
|
|
if (isPausing) {
|
|
// Kamera steht am aktuellen Punkt
|
|
player.teleport(start);
|
|
tickInSegment++;
|
|
if (tickInSegment >= TICKS_PAUSE) {
|
|
isPausing = false;
|
|
tickInSegment = 0;
|
|
}
|
|
} else {
|
|
// Kamera fliegt zum nächsten Punkt
|
|
double progress = (double) tickInSegment / (double) TICKS_FLUG;
|
|
|
|
// "Smooth Step" für flüssigeres Beschleunigen/Bremsen
|
|
double smoothT = progress * progress * (3 - 2 * progress);
|
|
|
|
Location nextLoc = interpolate(start, end, smoothT);
|
|
player.teleport(nextLoc);
|
|
|
|
tickInSegment++;
|
|
if (tickInSegment >= TICKS_FLUG) {
|
|
isPausing = true;
|
|
tickInSegment = 0;
|
|
currentSegment++;
|
|
}
|
|
}
|
|
|
|
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
|
|
new TextComponent("§6§lINTRO-TOUR §8| §ePunkt " + (currentSegment + 1) + " §8| §7Sneak zum Abbrechen"));
|
|
|
|
} catch (Exception e) {
|
|
this.cancel();
|
|
stopIntro(player, true);
|
|
}
|
|
}
|
|
}.runTaskTimer(NexusLobby.getInstance(), 0L, 1L);
|
|
}
|
|
|
|
private Location interpolate(Location start, Location end, double t) {
|
|
double x = start.getX() + (end.getX() - start.getX()) * t;
|
|
double y = start.getY() + (end.getY() - start.getY()) * t;
|
|
double z = start.getZ() + (end.getZ() - start.getZ()) * t;
|
|
|
|
// Sanfte Drehung
|
|
float startYaw = start.getYaw();
|
|
float endYaw = end.getYaw();
|
|
// Verhindert ruckartige 360-Grad Dreher
|
|
float diff = (endYaw - startYaw) % 360;
|
|
if (diff > 180) diff -= 360;
|
|
if (diff < -180) diff += 360;
|
|
float yaw = startYaw + diff * (float)t;
|
|
|
|
float pitch = (float) (start.getPitch() + (end.getPitch() - start.getPitch()) * t);
|
|
|
|
return new Location(start.getWorld(), x, y, z, yaw, pitch);
|
|
}
|
|
|
|
private void stopIntro(Player player, boolean canceled) {
|
|
activeIntro.remove(player.getUniqueId());
|
|
player.setGameMode(GameMode.ADVENTURE);
|
|
player.teleport(player.getWorld().getSpawnLocation());
|
|
|
|
if (canceled) {
|
|
player.sendMessage("§8[§6Nexus§8] §cIntro abgebrochen.");
|
|
} else {
|
|
player.sendMessage("§8[§6Nexus§8] §aWillkommen auf dem Netzwerk!");
|
|
}
|
|
}
|
|
} |