Add team system and team-based win condition
Introduce a full in-memory team system and integrate it into gameplay and UI. - Add Team, TeamManager, TeamListener and TeamCommand to manage teams, invites, accept/deny, leave, kick and info. TeamManager stores teams and pending invites (INVITE_TTL_MS) using concurrent maps and exposes helper/query methods (areInSameTeam, allAliveInSameTeam, getInviterFor, cleanExpiredInvites, reset). - Wire TeamManager into SpeedHG: initialize, schedule periodic invite cleanup, register command and listener, and reset teams on plugin disable. - Update GameManager to consider teams for win conditions, build team winner names, exclude teammates from random teleport/compass logic, and credit all winning team members for stats/ranking. - Move ability charge feedback out of individual kits into KitEventDispatcher: remove per-kit onFullyCharged overrides and add centralized ActionBar/sound feedback (sendChargeUpdateActionBar/sendChargeReadyActionBar). ActiveAbility no longer defines onFullyCharged. - Make OraclePerk ignore teammates when finding nearest enemy. - Add config entries for teams and corresponding language strings; tweak some default values in CustomGameSettings (gladiator arena radius/height and minor formatting changes). These changes enable 2-player teams (configurable), friendly-fire prevention, invite lifecycle handling, and team-aware endgame logic.
This commit is contained in:
@@ -274,15 +274,27 @@ class GameManager(
|
||||
checkWin()
|
||||
}
|
||||
|
||||
private fun checkWin()
|
||||
{
|
||||
if ( currentState != GameState.INGAME && currentState != GameState.INVINCIBILITY ) return
|
||||
private fun checkWin() {
|
||||
if (currentState != GameState.INGAME && currentState != GameState.INVINCIBILITY) return
|
||||
|
||||
if ( alivePlayers.size <= 1 )
|
||||
{
|
||||
val teamManager = plugin.teamManager
|
||||
|
||||
val roundOver = when {
|
||||
// Nur noch 0 oder 1 Spieler übrig → immer Ende
|
||||
alivePlayers.size <= 1 -> true
|
||||
|
||||
// Teams aktiv: Alle Überlebenden im selben Team → Team gewinnt
|
||||
teamManager.isEnabled && teamManager.allAliveInSameTeam(alivePlayers) -> true
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (roundOver) {
|
||||
val winnerUUID = alivePlayers.firstOrNull()
|
||||
val winnerName = if ( winnerUUID != null ) Bukkit.getPlayer( winnerUUID )?.name ?: "N/A" else "N/A"
|
||||
endGame( winnerName )
|
||||
// Den sichtbaren Gewinner-Namen ermitteln:
|
||||
// Bei Team-Sieg alle Mitglieder des Gewinner-Teams anzeigen.
|
||||
val winnerName = buildWinnerName(winnerUUID)
|
||||
endGame(winnerName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,18 +308,18 @@ class GameManager(
|
||||
|
||||
val winnerUUID = alivePlayers.firstOrNull()
|
||||
|
||||
val winnerTeam = if ( plugin.teamManager.isEnabled && winnerUUID != null )
|
||||
plugin.teamManager.getTeam( winnerUUID ) else null
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach { p ->
|
||||
if ( p.uniqueId == winnerUUID )
|
||||
val isWinner = winnerTeam?.contains( p.uniqueId ) ?: ( p.uniqueId == winnerUUID )
|
||||
|
||||
if ( isWinner )
|
||||
{
|
||||
plugin.statsManager.addWin( p.uniqueId )
|
||||
plugin.rankingManager.onPlayerResult( p, isWinner = true )
|
||||
}
|
||||
}
|
||||
|
||||
plugin.kitManager.clearAll()
|
||||
plugin.perkManager.removeAllActivePerks()
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach { p ->
|
||||
p.showTitle(Title.title(
|
||||
p.trans( "title.win-main", "winner" to winnerName ),
|
||||
p.trans( "title.win-sub" )
|
||||
@@ -315,6 +327,9 @@ class GameManager(
|
||||
p.sendMsg( "game.win-chat", "winner" to winnerName )
|
||||
}
|
||||
|
||||
plugin.kitManager.clearAll()
|
||||
plugin.perkManager.removeAllActivePerks()
|
||||
|
||||
plugin.discordWebhookManager.broadcastEmbed(
|
||||
title = "🏆 Spiel beendet!",
|
||||
description = "**$winnerName** hat das Spiel gewonnen! GG!",
|
||||
@@ -328,6 +343,25 @@ class GameManager(
|
||||
|
||||
// --- Helfer Methoden ---
|
||||
|
||||
private fun buildWinnerName(anyAliveUUID: UUID?): String {
|
||||
anyAliveUUID ?: return "N/A"
|
||||
|
||||
val teamManager = plugin.teamManager
|
||||
if (!teamManager.isEnabled) {
|
||||
return Bukkit.getPlayer(anyAliveUUID)?.name ?: "N/A"
|
||||
}
|
||||
|
||||
val winnerTeam = teamManager.getTeam(anyAliveUUID)
|
||||
return if (winnerTeam != null && winnerTeam.size > 1) {
|
||||
// "PlayerA & PlayerB" als Team-Gewinner-String
|
||||
winnerTeam.members
|
||||
.mapNotNull { Bukkit.getPlayer(it)?.name }
|
||||
.joinToString(" & ")
|
||||
} else {
|
||||
Bukkit.getPlayer(anyAliveUUID)?.name ?: "N/A"
|
||||
}
|
||||
}
|
||||
|
||||
private fun teleportRandomly(
|
||||
player: Player,
|
||||
world: World,
|
||||
@@ -368,6 +402,10 @@ class GameManager(
|
||||
{
|
||||
if ( p == target ) continue
|
||||
|
||||
if ( plugin.teamManager.isEnabled &&
|
||||
plugin.teamManager.areInSameTeam( p, target ))
|
||||
continue
|
||||
|
||||
val dist = p.location.distanceSquared( target.location )
|
||||
if ( dist < minDistance )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user