Update from Git Manager GUI
This commit is contained in:
@@ -129,7 +129,7 @@ public class Ball {
|
|||||||
if (entity == null || entity.isDead() || !active) return;
|
if (entity == null || entity.isDead() || !active) return;
|
||||||
Location ballLoc = entity.getLocation();
|
Location ballLoc = entity.getLocation();
|
||||||
Vector dir = blendDirection(player, 0.65);
|
Vector dir = blendDirection(player, 0.65);
|
||||||
double power = cfg("ball.header-power", 1.3);
|
double power = cfg("gameplay.header-power", 1.3);
|
||||||
dir.setY(Math.max(dir.getY(), -0.05));
|
dir.setY(Math.max(dir.getY(), -0.05));
|
||||||
dir.multiply(power);
|
dir.multiply(power);
|
||||||
applyKick(dir, ballLoc, 0.85f);
|
applyKick(dir, ballLoc, 0.85f);
|
||||||
|
|||||||
@@ -352,6 +352,9 @@ public class Game {
|
|||||||
state = GameState.RUNNING;
|
state = GameState.RUNNING;
|
||||||
secondHalf = true;
|
secondHalf = true;
|
||||||
timeLeft = arena.getGameDuration() / 2;
|
timeLeft = arena.getGameDuration() / 2;
|
||||||
|
// Nachspielzeit der 1. Halbzeit zurücksetzen
|
||||||
|
injuryTimeBuffer = 0;
|
||||||
|
inInjuryTime = false;
|
||||||
|
|
||||||
// Seitenwechsel: Rotes Team → BlueSpawn, Blaues Team → RedSpawn
|
// Seitenwechsel: Rotes Team → BlueSpawn, Blaues Team → RedSpawn
|
||||||
for (UUID uuid : redTeam) { Player p = Bukkit.getPlayer(uuid); if (p != null) p.teleport(arena.getBlueSpawn()); }
|
for (UUID uuid : redTeam) { Player p = Bukkit.getPlayer(uuid); if (p != null) p.teleport(arena.getBlueSpawn()); }
|
||||||
@@ -572,6 +575,7 @@ public class Game {
|
|||||||
// ════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
private void startGameLoop() {
|
private void startGameLoop() {
|
||||||
|
if (gameTask != null) { gameTask.cancel(); gameTask = null; }
|
||||||
gameTask = new BukkitRunnable() {
|
gameTask = new BukkitRunnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (state != GameState.RUNNING && state != GameState.OVERTIME) return;
|
if (state != GameState.RUNNING && state != GameState.OVERTIME) return;
|
||||||
@@ -841,21 +845,32 @@ public class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkPlayerBallInteraction() {
|
private void checkPlayerBallInteraction() {
|
||||||
if (ball == null || !ball.isActive()) return;
|
if (ball == null || !ball.isActive() || ball.isHeld()) return;
|
||||||
for (UUID uuid : allPlayers) {
|
for (UUID uuid : allPlayers) {
|
||||||
Player p = Bukkit.getPlayer(uuid);
|
Player p = Bukkit.getPlayer(uuid);
|
||||||
if (p == null) continue;
|
if (p == null) continue;
|
||||||
if (ball.getDistanceTo(p) < 1.5) {
|
if (ball.getDistanceTo(p) >= 1.5) continue;
|
||||||
if (throwInTeam != null && getTeam(p) != throwInTeam) continue;
|
if (throwInTeam != null && getTeam(p) != throwInTeam) continue;
|
||||||
lastKicker = p.getUniqueId();
|
|
||||||
lastTouchTeam = getTeam(p);
|
// ── Rückpass-Regel für Torwarte ──────────────────────────────────
|
||||||
kicks.merge(p.getUniqueId(), 1, Integer::sum);
|
// Torwart im Auto-Kick: falls Ball vom Mitspieler per Fuß zugespielt → überspringen
|
||||||
throwInTeam = null;
|
if (isGoalkeeper(p) && isInOwnHalf(p)) {
|
||||||
ball.kick(p);
|
UUID prev = lastKicker;
|
||||||
|
if (prev != null && !prev.equals(uuid)) {
|
||||||
|
Player prevPlayer = Bukkit.getPlayer(prev);
|
||||||
|
if (prevPlayer != null && getTeam(prevPlayer) == getTeam(p) && !lastKickWasHeader) {
|
||||||
|
continue; // Rückpass – auto-kick nicht ausführen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throwInTeam = null;
|
||||||
|
setLastKicker(uuid); // korrekt: nutzt setLastKicker statt direktem Feldzugriff
|
||||||
|
ball.kick(p);
|
||||||
|
break; // pro Tick max. 1 Auto-Kick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
// TOR
|
// TOR
|
||||||
// ════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════
|
||||||
@@ -1452,12 +1467,20 @@ public class Game {
|
|||||||
if (ball != null) ball.remove();
|
if (ball != null) ball.remove();
|
||||||
if (bossBar != null) { bossBar.removeAll(); bossBar = null; }
|
if (bossBar != null) { bossBar.removeAll(); bossBar = null; }
|
||||||
outOfBoundsCountdown.clear();
|
outOfBoundsCountdown.clear();
|
||||||
|
headerCooldowns.clear();
|
||||||
freekickLocation = null;
|
freekickLocation = null;
|
||||||
freekickTicks = 0;
|
freekickTicks = 0;
|
||||||
throwInTeam = null;
|
throwInTeam = null;
|
||||||
|
injuryTimeBuffer = 0;
|
||||||
|
inInjuryTime = false;
|
||||||
|
lastKicker = null;
|
||||||
|
secondLastKicker = null;
|
||||||
|
lastKickWasHeader = false;
|
||||||
|
|
||||||
// Persistente Statistiken speichern
|
// Persistente Statistiken speichern
|
||||||
boolean draw = winner == null || redScore == blueScore;
|
// BUG FIX: nach Elfmeter kann redScore == blueScore true sein obwohl ein Gewinner existiert.
|
||||||
|
// Einzig korrekte Quelle der Wahrheit ist das übergebene winner-Argument.
|
||||||
|
boolean draw = (winner == null);
|
||||||
Map<UUID, String> names = new HashMap<>();
|
Map<UUID, String> names = new HashMap<>();
|
||||||
for (UUID uuid : allPlayers) { Player p = Bukkit.getPlayer(uuid); if (p != null) names.put(uuid, p.getName()); }
|
for (UUID uuid : allPlayers) { Player p = Bukkit.getPlayer(uuid); if (p != null) names.put(uuid, p.getName()); }
|
||||||
plugin.getStatsManager().flushKicks(kicks, names);
|
plugin.getStatsManager().flushKicks(kicks, names);
|
||||||
@@ -1693,6 +1716,8 @@ public class Game {
|
|||||||
public Map<UUID, Integer> getGoals() { return goals; }
|
public Map<UUID, Integer> getGoals() { return goals; }
|
||||||
public Map<UUID, Integer> getKicks() { return kicks; }
|
public Map<UUID, Integer> getKicks() { return kicks; }
|
||||||
public boolean isSecondHalf() { return secondHalf; }
|
public boolean isSecondHalf() { return secondHalf; }
|
||||||
|
public boolean isInInjuryTime() { return inInjuryTime; }
|
||||||
|
public int getInjuryTimeBuffer() { return injuryTimeBuffer; }
|
||||||
public int getPenaltyRedGoals() { return penaltyRedGoals; }
|
public int getPenaltyRedGoals() { return penaltyRedGoals; }
|
||||||
public int getPenaltyBlueGoals() { return penaltyBlueGoals; }
|
public int getPenaltyBlueGoals() { return penaltyBlueGoals; }
|
||||||
/** Gibt zurück welches Team gerade Einwurf/Ecke/Abstoß hat (null = jeder darf) */
|
/** Gibt zurück welches Team gerade Einwurf/Ecke/Abstoß hat (null = jeder darf) */
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import org.bukkit.entity.Player;
|
|||||||
*
|
*
|
||||||
* Verfügbare Platzhalter:
|
* Verfügbare Platzhalter:
|
||||||
* %fussball_goals% - Tore des Spielers (gesamt)
|
* %fussball_goals% - Tore des Spielers (gesamt)
|
||||||
|
* %fussball_owngoals% - Eigentore des Spielers
|
||||||
|
* %fussball_assists% - Vorlagen des Spielers
|
||||||
* %fussball_kicks% - Schüsse des Spielers (gesamt)
|
* %fussball_kicks% - Schüsse des Spielers (gesamt)
|
||||||
* %fussball_wins% - Siege des Spielers
|
* %fussball_wins% - Siege des Spielers
|
||||||
* %fussball_losses% - Niederlagen des Spielers
|
* %fussball_losses% - Niederlagen des Spielers
|
||||||
@@ -19,6 +21,8 @@ import org.bukkit.entity.Player;
|
|||||||
* %fussball_ingame% - "true" / "false" – ob Spieler gerade im Spiel ist
|
* %fussball_ingame% - "true" / "false" – ob Spieler gerade im Spiel ist
|
||||||
* %fussball_arena% - Name der aktuellen Arena (oder "–")
|
* %fussball_arena% - Name der aktuellen Arena (oder "–")
|
||||||
* %fussball_score% - Aktueller Spielstand (z.B. "2 : 1") oder "–"
|
* %fussball_score% - Aktueller Spielstand (z.B. "2 : 1") oder "–"
|
||||||
|
* %fussball_team% - Team des Spielers im aktuellen Spiel ("Rot"/"Blau"/"–")
|
||||||
|
* %fussball_injurytime% - Aktuelle Nachspielzeit in Sekunden (0 wenn keine)
|
||||||
*/
|
*/
|
||||||
public class FussballPlaceholders extends PlaceholderExpansion {
|
public class FussballPlaceholders extends PlaceholderExpansion {
|
||||||
|
|
||||||
@@ -28,17 +32,10 @@ public class FussballPlaceholders extends PlaceholderExpansion {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public String getIdentifier() { return "fussball"; }
|
||||||
public String getIdentifier() { return "fussball"; }
|
@Override public String getAuthor() { return "M_Viper"; }
|
||||||
|
@Override public String getVersion() { return plugin.getDescription().getVersion(); }
|
||||||
@Override
|
@Override public boolean persist() { return true; }
|
||||||
public String getAuthor() { return "M_Viper"; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersion() { return plugin.getDescription().getVersion(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean persist() { return true; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String onPlaceholderRequest(Player player, String identifier) {
|
public String onPlaceholderRequest(Player player, String identifier) {
|
||||||
@@ -48,6 +45,8 @@ public class FussballPlaceholders extends PlaceholderExpansion {
|
|||||||
|
|
||||||
return switch (identifier.toLowerCase()) {
|
return switch (identifier.toLowerCase()) {
|
||||||
case "goals" -> String.valueOf(s.goals);
|
case "goals" -> String.valueOf(s.goals);
|
||||||
|
case "owngoals" -> String.valueOf(s.ownGoals);
|
||||||
|
case "assists" -> String.valueOf(s.assists);
|
||||||
case "kicks" -> String.valueOf(s.kicks);
|
case "kicks" -> String.valueOf(s.kicks);
|
||||||
case "wins" -> String.valueOf(s.wins);
|
case "wins" -> String.valueOf(s.wins);
|
||||||
case "losses" -> String.valueOf(s.losses);
|
case "losses" -> String.valueOf(s.losses);
|
||||||
@@ -63,6 +62,17 @@ public class FussballPlaceholders extends PlaceholderExpansion {
|
|||||||
var game = plugin.getGameManager().getPlayerGame(player);
|
var game = plugin.getGameManager().getPlayerGame(player);
|
||||||
yield game != null ? game.getRedScore() + " : " + game.getBlueScore() : "–";
|
yield game != null ? game.getRedScore() + " : " + game.getBlueScore() : "–";
|
||||||
}
|
}
|
||||||
|
case "team" -> {
|
||||||
|
var game = plugin.getGameManager().getPlayerGame(player);
|
||||||
|
if (game == null) yield "–";
|
||||||
|
de.fussball.plugin.game.Team t = game.getTeam(player);
|
||||||
|
yield t != null ? t.getDisplayName() : "–";
|
||||||
|
}
|
||||||
|
case "injurytime" -> {
|
||||||
|
var game = plugin.getGameManager().getPlayerGame(player);
|
||||||
|
yield (game != null && game.isInInjuryTime())
|
||||||
|
? String.valueOf(game.getInjuryTimeBuffer()) : "0";
|
||||||
|
}
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,15 +64,25 @@ public class FussballScoreboard {
|
|||||||
// Zeit / Status-Zeile
|
// Zeit / Status-Zeile
|
||||||
switch (game.getState()) {
|
switch (game.getState()) {
|
||||||
case RUNNING, GOAL -> {
|
case RUNNING, GOAL -> {
|
||||||
int m = game.getTimeLeft() / 60, s = game.getTimeLeft() % 60;
|
|
||||||
String half = game.isSecondHalf() ? "§72. HZ" : "§71. HZ";
|
String half = game.isSecondHalf() ? "§72. HZ" : "§71. HZ";
|
||||||
|
if (game.isInInjuryTime()) {
|
||||||
|
int injMins = (int) Math.ceil(game.getInjuryTimeBuffer() / 60.0);
|
||||||
|
set(obj, "§c⏱ +" + injMins + "' §7Nachsp. " + half, l--);
|
||||||
|
} else {
|
||||||
|
int m = game.getTimeLeft() / 60, s = game.getTimeLeft() % 60;
|
||||||
set(obj, "§e⏱ " + String.format("%02d:%02d", m, s) + " " + half, l--);
|
set(obj, "§e⏱ " + String.format("%02d:%02d", m, s) + " " + half, l--);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case HALFTIME -> set(obj, "§6⏸ HALBZEIT", l--);
|
case HALFTIME -> set(obj, "§6⏸ HALBZEIT", l--);
|
||||||
case OVERTIME -> {
|
case OVERTIME -> {
|
||||||
|
if (game.isInInjuryTime()) {
|
||||||
|
int injMins = (int) Math.ceil(game.getInjuryTimeBuffer() / 60.0);
|
||||||
|
set(obj, "§c⏱ +" + injMins + "' §6VL Nachsp.", l--);
|
||||||
|
} else {
|
||||||
int m = game.getTimeLeft() / 60, s = game.getTimeLeft() % 60;
|
int m = game.getTimeLeft() / 60, s = game.getTimeLeft() % 60;
|
||||||
set(obj, "§e⏱ " + String.format("%02d:%02d", m, s) + " §6VL", l--);
|
set(obj, "§e⏱ " + String.format("%02d:%02d", m, s) + " §6VL", l--);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case PENALTY -> set(obj, "§c⚽ ELFMETER R" + game.getPenaltyRedGoals() + ":B" + game.getPenaltyBlueGoals(), l--);
|
case PENALTY -> set(obj, "§c⚽ ELFMETER R" + game.getPenaltyRedGoals() + ":B" + game.getPenaltyBlueGoals(), l--);
|
||||||
case STARTING -> set(obj, "§e⏱ §6Startet gleich...", l--);
|
case STARTING -> set(obj, "§e⏱ §6Startet gleich...", l--);
|
||||||
default -> set(obj, "§7⏳ Warte auf Spieler...", l--);
|
default -> set(obj, "§7⏳ Warte auf Spieler...", l--);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Fussball
|
name: Fussball
|
||||||
version: 2.0.0
|
version: 1.0.0
|
||||||
main: de.fussball.plugin.Fussball
|
main: de.fussball.plugin.Fussball
|
||||||
api-version: 1.21
|
api-version: 1.21
|
||||||
author: M_Viper
|
author: M_Viper
|
||||||
|
|||||||
Reference in New Issue
Block a user