Migrate FightSystem modes and countdowns to GameCore

- Move shared arena-mode abstractions into GameCore
- Adapt fight countdowns and APIs to the shared model
- Add SteamWar issue audit workflow and SQL language settings
This commit is contained in:
2026-07-24 12:18:49 +02:00
parent badff1c70f
commit 867ca6f5dc
133 changed files with 2155 additions and 1076 deletions
@@ -19,6 +19,8 @@
package de.steamwar.misslewars;
import de.steamwar.gamecore.ArenaMode;
import de.steamwar.gamecore.config.GameRuntimeProperties;
import de.steamwar.sql.Event;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.Team;
@@ -36,6 +38,9 @@ public class Config {
private Config() {
}
public static final GameRuntimeProperties RuntimeProperties = GameRuntimeProperties.load();
public static final ArenaMode mode = ArenaMode.from(RuntimeProperties);
public static final int ArenaMinX;
public static final int ArenaMaxX;
public static final int ArenaMinY;
@@ -108,17 +113,13 @@ public class Config {
BluePortalZ = blue.getInt("PortalZ");
BlueSpawn = new Location(Bukkit.getWorlds().get(0), blue.getDouble("SpawnX"), blue.getDouble("SpawnY"), blue.getDouble("SpawnZ"), (float) blue.getDouble("SpawnYaw"), (float) blue.getDouble("SpawnPitch"));
String blueLeader = System.getProperty("blueLeader", null);
String redLeader = System.getProperty("redLeader", null);
if (blueLeader != null) BlueLeader = UUID.fromString(blueLeader);
else BlueLeader = null;
if (redLeader != null) RedLeader = UUID.fromString(redLeader);
else RedLeader = null;
BlueLeader = RuntimeProperties.getBlueLeader();
RedLeader = RuntimeProperties.getRedLeader();
Barrier = config.getBoolean("Barrier", false);
Space = config.getBoolean("Space", false);
EventKampfID = Integer.parseInt(System.getProperty("fightID", "0"));
EventKampfID = RuntimeProperties.getFightId();
if (EventKampfID >= 1) {
EventKampf = EventFight.byId(EventKampfID);
if (EventKampf == null) {
@@ -163,7 +164,7 @@ public class Config {
}
public static boolean isEvent() {
return EventKampfID >= 1;
return mode == ArenaMode.EVENT;
}
public static boolean isChallenge() {
@@ -171,6 +172,6 @@ public class Config {
}
public static boolean test() {
return EventKampfID == -1;
return mode == ArenaMode.TEST;
}
}
@@ -1,26 +1,11 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.misslewars;
import de.steamwar.gamecore.state.GameStateMachine;
public enum FightState {
WAITING, // waiting for at least 2 players
FIGHTING, // no one has won
END // fight ended for some reason
WAITING,
FIGHTING,
END;
public static final GameStateMachine<FightState> lifecycle = new GameStateMachine<>(WAITING);
}
@@ -34,7 +34,7 @@ import org.bukkit.scoreboard.Team;
import java.util.*;
public class MWTeam {
public class MWTeam implements de.steamwar.gamecore.team.GameTeam<Player> {
public static final ItemStack bow = new ItemStack(Material.BOW);
static {
@@ -226,8 +226,7 @@ public class MWTeam {
}
private MWTeam enemy() {
if (this == MissileWars.getRedTeam()) return MissileWars.getBlueTeam();
return MissileWars.getRedTeam();
return MissileWars.getOpposite(this);
}
public String getColorCode() {
@@ -246,6 +245,26 @@ public class MWTeam {
return color + teamName;
}
@Override
public String teamId() {
return teamName;
}
@Override
public Collection<Player> members() {
return Collections.unmodifiableList(players);
}
@Override
public Player leader() {
return players.peekFirst();
}
@Override
public boolean contains(Player member) {
return hasPlayer(member);
}
public static void removeInvitations(Player p) {
MissileWars.getRedTeam().openInvitations.remove(p);
MissileWars.getBlueTeam().openInvitations.remove(p);
@@ -21,6 +21,7 @@ package de.steamwar.misslewars;
import de.steamwar.linkage.AbstractLinker;
import de.steamwar.linkage.SpigotLinker;
import de.steamwar.gamecore.team.TeamRegistry;
import de.steamwar.misslewars.items.CustomItem;
import de.steamwar.misslewars.items.Missile;
import de.steamwar.misslewars.slowmo.SlowMoRunner;
@@ -33,6 +34,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Set;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -40,7 +42,7 @@ public class MissileWars extends JavaPlugin {
private static MissileWars plugin;
private static MWTeam redTeam; //red has South side -> spawns missles towards north
private static MWTeam blueTeam;
private static FightState fightState;
private static TeamRegistry<MWTeam, Player> teams;
/**
* create teams, ect
@@ -48,13 +50,14 @@ public class MissileWars extends JavaPlugin {
@Override
public void onLoad() {
plugin = this;
fightState = FightState.WAITING;
FightState.lifecycle.reset(FightState.WAITING);
}
@Override
public void onEnable() {
redTeam = new MWTeam(Config.TeamRedColor, Config.RedSpawn, Config.TeamRedName, Config.RedPortalZ);
blueTeam = new MWTeam(Config.TeamBlueColor, Config.BlueSpawn, Config.TeamBlueName, Config.BluePortalZ);
teams = new TeamRegistry<>(List.of(redTeam, blueTeam));
SpigotLinker spigotLinker = new SpigotLinker(this, null) {
@Override
@@ -73,8 +76,6 @@ public class MissileWars extends JavaPlugin {
Missile.init();
CustomItem.init();
StateDependent.setupState(fightState);
Bukkit.getScheduler().runTaskTimer(this, new FightInfoPacketSender(), 20, 20);
Bukkit.getWorlds().forEach(world -> {
@@ -87,9 +88,8 @@ public class MissileWars extends JavaPlugin {
}
public static void waiting() {
if (fightState == FightState.END) {
fightState = FightState.WAITING;
StateDependent.setupState(fightState);
if (FightState.lifecycle.getCurrentState() == FightState.END) {
StateDependent.setupState(FightState.WAITING);
SlowMoRunner.resetSlowMoTime();
@@ -108,10 +108,9 @@ public class MissileWars extends JavaPlugin {
* call to change fightstate from WAITING to INGAME
*/
static void startRound() {
if (fightState != FightState.WAITING) // anti dual-call
if (FightState.lifecycle.getCurrentState() != FightState.WAITING) // anti dual-call
return;
fightState = FightState.FIGHTING;
StateDependent.setupState(fightState);
StateDependent.setupState(FightState.FIGHTING);
}
/**
@@ -121,10 +120,9 @@ public class MissileWars extends JavaPlugin {
* @param winner Gewinner (oder null)
*/
public static void end(WinReasons reason, MWTeam winner) {
if (fightState == FightState.END) //verhindern dass es mehrfach gecallt wird
if (FightState.lifecycle.getCurrentState() == FightState.END) //verhindern dass es mehrfach gecallt wird
return;
fightState = FightState.END;
StateDependent.setupState(fightState);
StateDependent.setupState(FightState.END);
for (Player player : Bukkit.getOnlinePlayers()) {
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_DEATH, 100f, 1f);
@@ -156,7 +154,7 @@ public class MissileWars extends JavaPlugin {
}
public static FightState getFightState() {
return fightState;
return FightState.lifecycle.getCurrentState();
}
public static MWTeam getRedTeam() {
@@ -168,9 +166,11 @@ public class MissileWars extends JavaPlugin {
}
public static MWTeam getTeam(Player p) {
if (blueTeam.hasPlayer(p)) return blueTeam;
if (redTeam.hasPlayer(p)) return redTeam;
return null;
return teams.findTeam(p);
}
public static MWTeam getOpposite(MWTeam team) {
return teams.opposite(team);
}
public static MWTeam getInvitation(Player p) {
@@ -19,37 +19,18 @@
package de.steamwar.misslewars;
import java.util.HashSet;
import java.util.Set;
public abstract class StateDependent {
private static Set<StateDependent> listeners = new HashSet<>();
private final Set<FightState> active;
private boolean running;
public abstract class StateDependent extends de.steamwar.gamecore.state.StateDependent<FightState> {
public StateDependent(final Set<FightState> active) {
this.active = active;
running = false;
listeners.add(this);
super(FightState.lifecycle, true, active);
register();
}
public abstract void enable();
public abstract void disable();
static void setupState(FightState state) {
if (state == FightState.FIGHTING) {
FightScoreboard.startTime();
}
for (StateDependent listener : listeners) {
if (listener.running && !listener.active.contains(state)) {
listener.disable();
listener.running = false;
} else if (!listener.running && listener.active.contains(state)) {
listener.enable();
listener.running = true;
}
}
FightState.lifecycle.transitionTo(state);
}
}
@@ -22,14 +22,13 @@ package de.steamwar.misslewars.countdowns;
import de.steamwar.linkage.Linked;
import de.steamwar.misslewars.*;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import java.util.EnumSet;
@Linked
public class EndCountdown extends StateDependent {
private BukkitTask task;
private de.steamwar.gamecore.countdown.Countdown countdown;
public EndCountdown() {
super(EnumSet.of(FightState.END));
@@ -37,11 +36,20 @@ public class EndCountdown extends StateDependent {
@Override
public void enable() {
if (Config.isEvent()) {
task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::stop, 200);
} else {
task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::restart, Config.EndTime);
}
long delay = Config.isEvent() ? 200 : Config.EndTime;
countdown = new de.steamwar.gamecore.countdown.Countdown(
MissileWars.getPlugin(), 1, delay, 1, false
) {
@Override
protected void onFinished() {
if (Config.isEvent()) {
stop();
} else {
restart();
}
}
};
countdown.enable();
}
private void restart() {
@@ -62,6 +70,6 @@ public class EndCountdown extends StateDependent {
@Override
public void disable() {
if (task != null && !task.isCancelled()) task.cancel();
if (countdown != null) countdown.disable();
}
}
@@ -25,14 +25,13 @@ import de.steamwar.misslewars.FightState;
import de.steamwar.misslewars.MissileWars;
import de.steamwar.misslewars.StateDependent;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import java.util.EnumSet;
@Linked
public class WaitingCountdown extends StateDependent {
private BukkitTask task;
private de.steamwar.gamecore.countdown.Countdown countdown;
public WaitingCountdown() {
super(EnumSet.of(FightState.WAITING));
@@ -40,15 +39,21 @@ public class WaitingCountdown extends StateDependent {
@Override
public void enable() {
task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> {
if (Bukkit.getOnlinePlayers().isEmpty()) {
Bukkit.shutdown();
countdown = new de.steamwar.gamecore.countdown.Countdown(
MissileWars.getPlugin(), 1, Config.WaitingTime, 1, false
) {
@Override
protected void onFinished() {
if (Bukkit.getOnlinePlayers().isEmpty()) {
Bukkit.shutdown();
}
}
}, Config.WaitingTime);
};
countdown.enable();
}
@Override
public void disable() {
if (task != null && !task.isCancelled()) task.cancel();
if (countdown != null) countdown.disable();
}
}
+2 -1
View File
@@ -8,10 +8,11 @@ authors:
version: "1.0"
api-version: "1.13"
depend:
- GameCore
- WorldEdit
- SpigotCore
commands:
spectate:
invite:
accept:
decline:
decline: