Update from Git Manager GUI
This commit is contained in:
@@ -44,6 +44,9 @@ public class VelocityFall extends JavaPlugin {
|
|||||||
private Stats stats;
|
private Stats stats;
|
||||||
private DisableReset disablereset;
|
private DisableReset disablereset;
|
||||||
|
|
||||||
|
// Listener-Referenzen (für GameManager-Zugriff)
|
||||||
|
private FloorLoseListener floorLoseListener;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
@@ -75,8 +78,13 @@ public class VelocityFall extends JavaPlugin {
|
|||||||
|
|
||||||
getCommand("velocityfall").setExecutor(new VelocityCommand(this));
|
getCommand("velocityfall").setExecutor(new VelocityCommand(this));
|
||||||
|
|
||||||
|
// Listener registrieren
|
||||||
Bukkit.getPluginManager().registerEvents(new FloorListener(this), this);
|
Bukkit.getPluginManager().registerEvents(new FloorListener(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new FloorLoseListener(this), this);
|
|
||||||
|
// FloorLoseListener mit Referenz speichern (für GameManager)
|
||||||
|
this.floorLoseListener = new FloorLoseListener(this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(floorLoseListener, this);
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(new GameListener(this), this);
|
Bukkit.getPluginManager().registerEvents(new GameListener(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new SetupListener(this), this);
|
Bukkit.getPluginManager().registerEvents(new SetupListener(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new SignListener(this), this);
|
Bukkit.getPluginManager().registerEvents(new SignListener(this), this);
|
||||||
@@ -133,6 +141,7 @@ public class VelocityFall extends JavaPlugin {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manager-Getter
|
||||||
public ArenaManager getArenaManager() { return arenaManager; }
|
public ArenaManager getArenaManager() { return arenaManager; }
|
||||||
public JoinManager getJoinManager() { return joinManager; }
|
public JoinManager getJoinManager() { return joinManager; }
|
||||||
public SignManager getSignManager() { return signManager; }
|
public SignManager getSignManager() { return signManager; }
|
||||||
@@ -141,6 +150,10 @@ public class VelocityFall extends JavaPlugin {
|
|||||||
public Messages getMessages() { return messages; }
|
public Messages getMessages() { return messages; }
|
||||||
public Stats getStats() { return stats; }
|
public Stats getStats() { return stats; }
|
||||||
|
|
||||||
|
// Listener-Getter (für GameManager)
|
||||||
|
public FloorLoseListener getFloorLoseListener() { return floorLoseListener; }
|
||||||
|
|
||||||
|
// Map-Getter
|
||||||
public HashMap<Player, String> getPlayerArenaMap() { return playerArena; }
|
public HashMap<Player, String> getPlayerArenaMap() { return playerArena; }
|
||||||
public HashMap<String, Integer> getArenaPlayersCountMap() { return arenaPlayersCount; }
|
public HashMap<String, Integer> getArenaPlayersCountMap() { return arenaPlayersCount; }
|
||||||
public HashMap<String, Boolean> getGameStartedMap() { return gameStarted; }
|
public HashMap<String, Boolean> getGameStartedMap() { return gameStarted; }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import de.velocityfall.utils.ScoreboardHelper;
|
|||||||
import de.velocityfall.utils.StatsHandler;
|
import de.velocityfall.utils.StatsHandler;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -15,10 +16,14 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class FloorLoseListener implements Listener {
|
public class FloorLoseListener implements Listener {
|
||||||
|
|
||||||
private final VelocityFall plugin;
|
private final VelocityFall plugin;
|
||||||
|
// Tracking: welche Spieler bereits als "verloren" markiert wurden
|
||||||
|
private final Set<Player> alreadyLost = new HashSet<>();
|
||||||
|
|
||||||
public FloorLoseListener(VelocityFall plugin) {
|
public FloorLoseListener(VelocityFall plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@@ -32,70 +37,78 @@ public class FloorLoseListener implements Listener {
|
|||||||
String arena = VelocityFall.getArena(p);
|
String arena = VelocityFall.getArena(p);
|
||||||
if (arena == null) return;
|
if (arena == null) return;
|
||||||
|
|
||||||
|
// Wenn Spieler bereits verloren hat, nicht nochmal verarbeiten
|
||||||
|
if (alreadyLost.contains(p)) return;
|
||||||
|
|
||||||
Location loc = p.getLocation();
|
Location loc = p.getLocation();
|
||||||
double minY = plugin.getArenaManager().getMinY(arena);
|
double minY = plugin.getArenaManager().getMinY(arena);
|
||||||
double buffer = 5.0; // Puffer für mehrstöckige Arenen
|
double buffer = 5.0; // Puffer für mehrstöckige Arenen
|
||||||
|
|
||||||
// Verlierer nur, wenn wirklich unter der Arena + Puffer
|
// Verlierer nur, wenn wirklich unter der Arena + Puffer
|
||||||
if (loc.getY() < minY - buffer) {
|
if (loc.getY() < minY - buffer) {
|
||||||
removePlayerFromGame(p, arena);
|
markPlayerAsLost(p, arena);
|
||||||
GameManager.checkForWinner(arena);
|
GameManager.checkForWinner(arena);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional: Wenn außerhalb der Region und unter MinY
|
// Optional: Wenn außerhalb der Region und unter MinY
|
||||||
if (!plugin.getArenaManager().isInArenaRegion(arena, loc) && loc.getY() < minY) {
|
if (!plugin.getArenaManager().isInArenaRegion(arena, loc) && loc.getY() < minY) {
|
||||||
removePlayerFromGame(p, arena);
|
markPlayerAsLost(p, arena);
|
||||||
GameManager.checkForWinner(arena);
|
GameManager.checkForWinner(arena);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removePlayerFromGame(Player p, String arena) {
|
/**
|
||||||
var playerArenaMap = plugin.getPlayerArenaMap();
|
* Markiert Spieler als "verloren" - reduziert nur den Counter, entfernt ihn aber
|
||||||
|
* NICHT aus playerArenaMap oder ingamePlayers (das macht später der GameManager)
|
||||||
|
*/
|
||||||
|
private void markPlayerAsLost(Player p, String arena) {
|
||||||
|
// Verhindere Mehrfach-Verarbeitung
|
||||||
|
if (alreadyLost.contains(p)) return;
|
||||||
|
alreadyLost.add(p);
|
||||||
|
|
||||||
var arenaPlayersCountMap = plugin.getArenaPlayersCountMap();
|
var arenaPlayersCountMap = plugin.getArenaPlayersCountMap();
|
||||||
|
|
||||||
// Potions entfernen (falls du eine Methode hast)
|
// Lose-Nachricht
|
||||||
// methodes.removepotions(p);
|
|
||||||
|
|
||||||
if (plugin.getConfig().getBoolean("SaveInv", false)) {
|
|
||||||
try {
|
|
||||||
// methodes.restore(p);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p.getInventory().clear();
|
|
||||||
p.getInventory().setArmorContents(null);
|
|
||||||
|
|
||||||
String uuid = p.getUniqueId().toString();
|
|
||||||
var saveFile = plugin.getConfigs().getSaveConfig();
|
|
||||||
double x = saveFile.getDouble(uuid + ".NoSave.X", p.getWorld().getSpawnLocation().getX());
|
|
||||||
double y = saveFile.getDouble(uuid + ".NoSave.Y", p.getWorld().getSpawnLocation().getY());
|
|
||||||
double z = saveFile.getDouble(uuid + ".NoSave.Z", p.getWorld().getSpawnLocation().getZ());
|
|
||||||
String worldName = saveFile.getString(uuid + ".NoSave.World", p.getWorld().getName());
|
|
||||||
|
|
||||||
World w = Bukkit.getWorld(worldName);
|
|
||||||
if (w != null) {
|
|
||||||
p.teleport(new Location(w, x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
saveFile.set(uuid, null);
|
|
||||||
try {
|
|
||||||
saveFile.save(plugin.getConfigs().getSaveFile());
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&',
|
p.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&',
|
||||||
plugin.getMessages().getMessagesConfig().getString("LoseMessage", "&cDu bist rausgefallen!")));
|
plugin.getMessages().getMessagesConfig().getString("LoseMessage", "&cDu bist rausgefallen!")));
|
||||||
|
|
||||||
arenaPlayersCountMap.compute(arena, (k, v) -> (v == null ? 0 : v) - 1);
|
// Setze Spieler sofort in Spectator, damit er nicht weiter interagieren kann
|
||||||
plugin.ingamePlayers.remove(p);
|
p.setGameMode(GameMode.SPECTATOR);
|
||||||
playerArenaMap.remove(p);
|
|
||||||
p.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
|
|
||||||
|
|
||||||
|
// Counter reduzieren (wichtig für checkForWinner)
|
||||||
|
arenaPlayersCountMap.compute(arena, (k, v) -> Math.max(0, (v == null ? 0 : v) - 1));
|
||||||
|
|
||||||
|
// Scoreboard leeren
|
||||||
|
try {
|
||||||
|
p.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Scoreboard für andere updaten
|
||||||
|
try {
|
||||||
ScoreboardHelper.updateAllInArena(arena, true);
|
ScoreboardHelper.updateAllInArena(arena, true);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Sign updaten
|
||||||
|
try {
|
||||||
plugin.getSignManager().updateSign(arena);
|
plugin.getSignManager().updateSign(arena);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// WICHTIG: Spieler bleibt in ingamePlayers und playerArenaMap!
|
||||||
|
// Er wird erst in performSafeResetAndLobbyTeleport entfernt
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup-Methode für den GameManager - wird nach Arena-Reset aufgerufen
|
||||||
|
*/
|
||||||
|
public void clearLostPlayers() {
|
||||||
|
alreadyLost.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Menge der verlorenen Spieler zurück (für GameManager)
|
||||||
|
*/
|
||||||
|
public Set<Player> getAlreadyLost() {
|
||||||
|
return new HashSet<>(alreadyLost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,13 +8,25 @@ import org.bukkit.GameMode;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Firework;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.meta.FireworkMeta;
|
||||||
|
import org.bukkit.FireworkEffect;
|
||||||
|
import org.bukkit.Color;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class GameManager {
|
public class GameManager {
|
||||||
|
|
||||||
|
/* ---------------------------------------------------
|
||||||
|
* GAME START COUNTDOWN
|
||||||
|
* --------------------------------------------------- */
|
||||||
public static void startArenaCountdown(String arenaName) {
|
public static void startArenaCountdown(String arenaName) {
|
||||||
VelocityFall plugin = VelocityFall.getInstance();
|
final VelocityFall plugin = VelocityFall.getInstance();
|
||||||
if (plugin.getGameStartedMap().getOrDefault(arenaName, false)) return;
|
if (plugin.getGameStartedMap().getOrDefault(arenaName, false)) return;
|
||||||
|
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
@@ -22,7 +34,8 @@ public class GameManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int playerCount = (int) plugin.getPlayerArenaMap().values().stream().filter(arenaName::equals).count();
|
int playerCount = (int) plugin.getPlayerArenaMap().values()
|
||||||
|
.stream().filter(arenaName::equals).count();
|
||||||
|
|
||||||
if (playerCount < 1) {
|
if (playerCount < 1) {
|
||||||
cancel();
|
cancel();
|
||||||
@@ -38,10 +51,10 @@ public class GameManager {
|
|||||||
plugin.getArenaPlayersCountMap().put(arenaName, playerCount);
|
plugin.getArenaPlayersCountMap().put(arenaName, playerCount);
|
||||||
|
|
||||||
plugin.getSignManager().updateSign(arenaName);
|
plugin.getSignManager().updateSign(arenaName);
|
||||||
|
|
||||||
broadcast(arenaName, "§6§lDAS SPIEL BEGINNT!");
|
broadcast(arenaName, "§6§lDAS SPIEL BEGINNT!");
|
||||||
|
|
||||||
Location spawn = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Spawn");
|
Location spawn = plugin.getArenaManager()
|
||||||
|
.getArenaConfig().getLocation("Arenas." + arenaName + ".Spawn");
|
||||||
|
|
||||||
plugin.getPlayerArenaMap().forEach((p, a) -> {
|
plugin.getPlayerArenaMap().forEach((p, a) -> {
|
||||||
if (arenaName.equals(a)) {
|
if (arenaName.equals(a)) {
|
||||||
@@ -62,65 +75,324 @@ public class GameManager {
|
|||||||
startArenaCountdown(arenaName);
|
startArenaCountdown(arenaName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------
|
||||||
|
* WIN HANDLING
|
||||||
|
* --------------------------------------------------- */
|
||||||
public static void checkForWinner(String arenaName) {
|
public static void checkForWinner(String arenaName) {
|
||||||
VelocityFall plugin = VelocityFall.getInstance();
|
final VelocityFall plugin = VelocityFall.getInstance();
|
||||||
var countMap = plugin.getArenaPlayersCountMap();
|
int remaining = plugin.getArenaPlayersCountMap().getOrDefault(arenaName, 0);
|
||||||
int remaining = countMap.getOrDefault(arenaName, 0);
|
|
||||||
|
|
||||||
if (remaining != 1) return;
|
if (remaining != 1) return;
|
||||||
|
|
||||||
var arenaPlayers = VelocityFall.getArenaPlayers(arenaName);
|
// 1) Versuche Gewinner zuverlässig über playerArenaMap (Single source)
|
||||||
if (arenaPlayers.isEmpty()) return;
|
Player winner = plugin.getPlayerArenaMap().entrySet().stream()
|
||||||
|
.filter(e -> arenaName.equals(e.getValue()))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.filter(p -> p.getGameMode() != GameMode.SPECTATOR) // Nicht-Spectator = Gewinner
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
Player winner = arenaPlayers.get(0);
|
// 2) Fallback: VelocityFall.getArenaPlayers(arenaName)
|
||||||
|
if (winner == null) {
|
||||||
winner.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&',
|
List<Player> arenaPlayers = VelocityFall.getArenaPlayers(arenaName);
|
||||||
plugin.getMessages().getMessagesConfig().getString("WinMessage", "&aDu hast gewonnen!")));
|
for (Player p : arenaPlayers) {
|
||||||
|
if (p != null && p.getGameMode() != GameMode.SPECTATOR) {
|
||||||
StatsHandler.addWin(winner.getUniqueId().toString());
|
winner = p;
|
||||||
|
break;
|
||||||
plugin.ingameArenas.remove(arenaName);
|
}
|
||||||
plugin.ingamePlayers.remove(winner);
|
}
|
||||||
plugin.getPlayerArenaMap().remove(winner);
|
|
||||||
countMap.remove(arenaName);
|
|
||||||
plugin.getGameStartedMap().remove(arenaName);
|
|
||||||
winner.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
|
|
||||||
|
|
||||||
resetArena(arenaName);
|
|
||||||
|
|
||||||
plugin.getSignManager().updateSign(arenaName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void resetArena(String arenaName) {
|
if (winner == null) return; // kein Gewinner auffindbar → exit
|
||||||
VelocityFall plugin = VelocityFall.getInstance();
|
|
||||||
|
|
||||||
plugin.getArenaBlocksMap().forEach((block, matName) -> block.setType(Material.valueOf(matName)));
|
final Player finalWinner = winner;
|
||||||
|
|
||||||
|
// Nachricht + Stats + Scoreboard
|
||||||
|
try {
|
||||||
|
finalWinner.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&',
|
||||||
|
plugin.getMessages().getMessagesConfig()
|
||||||
|
.getString("WinMessage", "&aDu hast gewonnen!")));
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
try {
|
||||||
|
StatsHandler.addWin(finalWinner.getUniqueId().toString());
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
try {
|
||||||
|
finalWinner.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Lose-Location: mehrere mögliche Keys supporten + YLose fallback
|
||||||
|
Location loseLocation = plugin.getArenaManager()
|
||||||
|
.getArenaConfig().getLocation("Arenas." + arenaName + ".Lose");
|
||||||
|
if (loseLocation == null) loseLocation = plugin.getArenaManager()
|
||||||
|
.getArenaConfig().getLocation("Arenas." + arenaName + ".LoseLocation");
|
||||||
|
if (loseLocation == null) loseLocation = plugin.getArenaManager()
|
||||||
|
.getArenaConfig().getLocation("Arenas." + arenaName + ".LosePoint");
|
||||||
|
if (loseLocation == null) loseLocation = plugin.getArenaManager()
|
||||||
|
.getArenaConfig().getLocation("Arenas." + arenaName + ".SetLose");
|
||||||
|
|
||||||
|
// Spezial-Fallback: YLose vorhanden? Dann baue Location auf Basis von Spawn oder Lobby X/Z
|
||||||
|
if (loseLocation == null) {
|
||||||
|
Double yLose = plugin.getArenaManager().getArenaConfig().getDouble("Arenas." + arenaName + ".YLose", Double.NaN);
|
||||||
|
if (!yLose.isNaN()) {
|
||||||
|
// Priorität: Spawn -> Lobby -> arena center (Pos1/Pos2 midpoint)
|
||||||
|
Location spawn = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Spawn");
|
||||||
|
Location lobby = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Lobby");
|
||||||
|
if (spawn != null) {
|
||||||
|
loseLocation = spawn.clone();
|
||||||
|
loseLocation.setY(yLose);
|
||||||
|
} else if (lobby != null) {
|
||||||
|
loseLocation = lobby.clone();
|
||||||
|
loseLocation.setY(yLose);
|
||||||
|
} else {
|
||||||
|
// midpoint of Pos1 and Pos2 if available
|
||||||
|
Location pos1 = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Pos1");
|
||||||
|
Location pos2 = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Pos2");
|
||||||
|
if (pos1 != null && pos2 != null && pos1.getWorld() != null && pos1.getWorld().equals(pos2.getWorld())) {
|
||||||
|
double midX = (pos1.getX() + pos2.getX()) / 2.0;
|
||||||
|
double midZ = (pos1.getZ() + pos2.getZ()) / 2.0;
|
||||||
|
loseLocation = new Location(pos1.getWorld(), midX, yLose, midZ, 0f, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Location finalLoseLocation = loseLocation; // final für Lambdas
|
||||||
|
|
||||||
|
// Ermittlung der Verlierer: alle Spectator-Spieler in dieser Arena
|
||||||
|
List<Player> losers = new ArrayList<>();
|
||||||
|
|
||||||
|
// Strategie A: playerArenaMap - alle Spectators sind Verlierer
|
||||||
|
plugin.getPlayerArenaMap().forEach((p, a) -> {
|
||||||
|
if (arenaName.equals(a) && !p.equals(finalWinner) && p.getGameMode() == GameMode.SPECTATOR) {
|
||||||
|
losers.add(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Strategie B: Falls keine Verlierer gefunden -> ingamePlayers Liste
|
||||||
|
if (losers.isEmpty()) {
|
||||||
|
try {
|
||||||
|
for (Player p : plugin.ingamePlayers) {
|
||||||
|
if (p != null && !p.equals(finalWinner) && p.getGameMode() == GameMode.SPECTATOR) {
|
||||||
|
losers.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategie C: VelocityFall.getArenaPlayers(arenaName)
|
||||||
|
if (losers.isEmpty()) {
|
||||||
|
List<Player> arenaPlayers = VelocityFall.getArenaPlayers(arenaName);
|
||||||
|
if (!arenaPlayers.isEmpty()) {
|
||||||
|
for (Player p : arenaPlayers) {
|
||||||
|
if (p != null && !p.equals(finalWinner) && p.getGameMode() == GameMode.SPECTATOR) {
|
||||||
|
losers.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erstelle finale Liste der Verlierer (damit sie auch nach Delays verfügbar ist)
|
||||||
|
final List<Player> finalLosers = new ArrayList<>(losers);
|
||||||
|
|
||||||
|
// Teleportiere Verlierer SOFORT zum Lose-Punkt (sie sind bereits in GM3 durch FloorLoseListener)
|
||||||
|
for (Player loser : finalLosers) {
|
||||||
|
try {
|
||||||
|
// Sicherstellen, dass Spectator-Modus gesetzt ist
|
||||||
|
if (loser.getGameMode() != GameMode.SPECTATOR) {
|
||||||
|
loser.setGameMode(GameMode.SPECTATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (finalLoseLocation != null) {
|
||||||
|
loser.teleport(finalLoseLocation);
|
||||||
|
} else {
|
||||||
|
// fallback: direkt neben Gewinner
|
||||||
|
Location fallback = finalWinner.getLocation().clone().add(1.0, 0.0, 0.0);
|
||||||
|
loser.teleport(fallback);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Falls Teleport fehlschlägt, loggen wir es serverseitig
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay 3-5 Sekunden (konfigurierbar)
|
||||||
|
int delaySeconds = plugin.getConfig().getInt("PostWinDelay", 4);
|
||||||
|
delaySeconds = Math.min(5, Math.max(3, delaySeconds));
|
||||||
|
final long delayTicks = delaySeconds * 20L;
|
||||||
|
|
||||||
|
// Nach Delay: Feuerwerk beim Gewinner und dann Arena resetten / Lobby teleport
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
spawnFireworks(finalWinner.getLocation(), 2);
|
||||||
|
finalWinner.playSound(finalWinner.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// 1 Sekunde später: Reset & Teleport aller zur Lobby (GM1)
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
// Robustes Reset: teleportiere Gewinner + finale Verlierer-Liste zur Lobby
|
||||||
|
performSafeResetAndLobbyTeleport(arenaName, finalWinner, finalLosers);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Aufräumen maps / Signs
|
||||||
|
try {
|
||||||
|
plugin.ingameArenas.remove(arenaName);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
try {
|
||||||
|
plugin.getSignManager().updateSign(arenaName);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
}.runTaskLater(plugin, 20L); // 1 Sekunde nach Feuerwerk
|
||||||
|
}
|
||||||
|
}.runTaskLater(plugin, delayTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------
|
||||||
|
* SAFE RESET & LOBBY TELEPORT (robust)
|
||||||
|
* --------------------------------------------------- */
|
||||||
|
private static void performSafeResetAndLobbyTeleport(String arenaName, Player winner, List<Player> losers) {
|
||||||
|
final VelocityFall plugin = VelocityFall.getInstance();
|
||||||
|
|
||||||
|
// Blöcke zurücksetzen
|
||||||
|
plugin.getArenaBlocksMap().forEach((block, matName) -> {
|
||||||
|
try {
|
||||||
|
block.setType(Material.valueOf(matName));
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
});
|
||||||
plugin.getArenaBlocksMap().clear();
|
plugin.getArenaBlocksMap().clear();
|
||||||
|
|
||||||
|
// Spielzustand zurücksetzen
|
||||||
plugin.getGameStartedMap().put(arenaName, false);
|
plugin.getGameStartedMap().put(arenaName, false);
|
||||||
plugin.getArenaPlayersCountMap().remove(arenaName);
|
plugin.getArenaPlayersCountMap().remove(arenaName);
|
||||||
|
|
||||||
|
// Lobby-Location (kann null sein)
|
||||||
Location lobby = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Lobby");
|
Location lobby = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Lobby");
|
||||||
|
|
||||||
plugin.getPlayerArenaMap().entrySet().removeIf(e -> {
|
// Sammle alle Spieler, die teleportiert werden müssen
|
||||||
if (arenaName.equals(e.getValue())) {
|
List<Player> toHandle = new ArrayList<>();
|
||||||
Player p = e.getKey();
|
|
||||||
p.setGameMode(GameMode.SURVIVAL);
|
// Gewinner hinzufügen
|
||||||
|
if (winner != null) {
|
||||||
|
toHandle.add(winner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verlierer hinzufügen (bereits als finale Liste übergeben)
|
||||||
|
for (Player loser : losers) {
|
||||||
|
if (loser != null && !toHandle.contains(loser)) {
|
||||||
|
toHandle.add(loser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zusätzlich: alle restlichen Spieler aus playerArenaMap (Sicherheit)
|
||||||
|
plugin.getPlayerArenaMap().forEach((p, a) -> {
|
||||||
|
if (arenaName.equals(a) && !toHandle.contains(p)) {
|
||||||
|
toHandle.add(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fallback: ingamePlayers
|
||||||
|
try {
|
||||||
|
for (Player p : new ArrayList<>(plugin.ingamePlayers)) {
|
||||||
|
if (p != null && !toHandle.contains(p)) {
|
||||||
|
// Prüfe ob Spieler möglicherweise zu dieser Arena gehört
|
||||||
|
String playerArena = plugin.getPlayerArenaMap().get(p);
|
||||||
|
if (arenaName.equals(playerArena)) {
|
||||||
|
toHandle.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Fallback: VelocityFall.getArenaPlayers
|
||||||
|
try {
|
||||||
|
List<Player> arenaPlayers = VelocityFall.getArenaPlayers(arenaName);
|
||||||
|
for (Player p : arenaPlayers) {
|
||||||
|
if (p != null && !toHandle.contains(p)) toHandle.add(p);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Verarbeite alle gesammelten Spieler: GM1 (SURVIVAL), Inventar clear, teleport zur Lobby, entferne aus Maps
|
||||||
|
for (Player p : toHandle) {
|
||||||
|
try {
|
||||||
|
p.setGameMode(GameMode.SURVIVAL); // GM1
|
||||||
p.getInventory().clear();
|
p.getInventory().clear();
|
||||||
if (lobby != null) p.teleport(lobby);
|
p.getInventory().setArmorContents(null);
|
||||||
|
p.setHealth(20.0);
|
||||||
|
p.setFoodLevel(20);
|
||||||
|
|
||||||
|
if (lobby != null) {
|
||||||
|
p.teleport(lobby);
|
||||||
|
} else {
|
||||||
|
// Fallback: Spawn-Location oder World-Spawn
|
||||||
|
Location spawn = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Spawn");
|
||||||
|
if (spawn != null) {
|
||||||
|
p.teleport(spawn);
|
||||||
|
} else if (p.getWorld() != null) {
|
||||||
|
p.teleport(p.getWorld().getSpawnLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jetzt erst aus den Maps entfernen
|
||||||
plugin.ingamePlayers.remove(p);
|
plugin.ingamePlayers.remove(p);
|
||||||
return true;
|
plugin.getPlayerArenaMap().remove(p);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// FloorLoseListener cleanup
|
||||||
|
try {
|
||||||
|
if (plugin.getFloorLoseListener() != null) {
|
||||||
|
plugin.getFloorLoseListener().clearLostPlayers();
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// Signs updaten
|
||||||
|
try {
|
||||||
plugin.getSignManager().updateSign(arenaName);
|
plugin.getSignManager().updateSign(arenaName);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------
|
||||||
|
* FIREWORKS
|
||||||
|
* --------------------------------------------------- */
|
||||||
|
private static void spawnFireworks(Location loc, int count) {
|
||||||
|
if (loc == null || loc.getWorld() == null) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.max(1, count); i++) {
|
||||||
|
try {
|
||||||
|
Firework fw = loc.getWorld().spawn(loc.clone().add(0, 1 + i * 0.5, 0), Firework.class);
|
||||||
|
FireworkMeta meta = fw.getFireworkMeta();
|
||||||
|
|
||||||
|
FireworkEffect effect = FireworkEffect.builder()
|
||||||
|
.with(FireworkEffect.Type.BALL_LARGE)
|
||||||
|
.withColor(Color.LIME, Color.YELLOW)
|
||||||
|
.withFade(Color.WHITE)
|
||||||
|
.trail(true)
|
||||||
|
.flicker(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
meta.addEffect(effect);
|
||||||
|
meta.setPower(1);
|
||||||
|
fw.setFireworkMeta(meta);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------
|
||||||
|
* BROADCAST
|
||||||
|
* --------------------------------------------------- */
|
||||||
private static void broadcast(String arena, String msg) {
|
private static void broadcast(String arena, String msg) {
|
||||||
VelocityFall plugin = VelocityFall.getInstance();
|
final VelocityFall plugin = VelocityFall.getInstance();
|
||||||
plugin.getPlayerArenaMap().forEach((player, a) -> {
|
plugin.getPlayerArenaMap().forEach((player, a) -> {
|
||||||
if (arena.equals(a)) player.sendMessage(VelocityFall.prefix + msg);
|
if (arena.equals(a)) {
|
||||||
|
player.sendMessage(VelocityFall.prefix + msg);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ Prefix: '&c[VelocityFall] '
|
|||||||
BeforeGameCD: 15
|
BeforeGameCD: 15
|
||||||
CountdownSound: ENTITY_EXPERIENCE_ORB_PICKUP
|
CountdownSound: ENTITY_EXPERIENCE_ORB_PICKUP
|
||||||
SaveInv: true
|
SaveInv: true
|
||||||
|
PostWinDelay: 4
|
||||||
WinCommands:
|
WinCommands:
|
||||||
- eco give %player% 10
|
- eco give %player% 10
|
||||||
- msg %player% Du hast gewonnen!
|
- msg %player% Du hast gewonnen!
|
||||||
|
|||||||
Reference in New Issue
Block a user