Files
GameModes-SpeedHG/src/main/kotlin/club/mcscrims/speedhg/command/TeamCommand.kt
TDSTOS 4a28c58d2e Add /help command and various gameplay fixes
Introduce a HelpCommand (/help) and register it in SpeedHG; add its localized help text and plugin.yml entry. Prevent kit ability use while in gladiator by checking metadata in KitEventDispatcher and add a matching translation key. Early-return in KitCommand during ENDING state. Fix English message in TeamCommand and adjust spacing in LeaderboardMenu lore. Remove an unused import in SpeedHG and add necessary imports.
2026-04-12 07:20:20 +02:00

232 lines
8.4 KiB
Kotlin

package club.mcscrims.speedhg.command
import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.game.GameState
import club.mcscrims.speedhg.team.TeamManager
import club.mcscrims.speedhg.util.sendMsg
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter
import org.bukkit.entity.Player
class TeamCommand : CommandExecutor, TabCompleter {
private val plugin get() = SpeedHG.instance
// ── Guard: Teams nur in Lobby-Phasen ändern ──────────────────────────────
private fun isLobbyPhase(): Boolean = when (plugin.gameManager.currentState) {
GameState.LOBBY, GameState.STARTING -> true
else -> false
}
// =========================================================================
// onCommand dispatch
// =========================================================================
override fun onCommand(
sender: CommandSender,
command: Command,
label: String,
args: Array<out String>
): Boolean {
val player = sender as? Player ?: run {
sender.sendMessage("§cOnly players can use this command.")
return true
}
if (!plugin.teamManager.isEnabled) {
player.sendMsg("team.disabled")
return true
}
when (args.firstOrNull()?.lowercase()) {
"invite" -> handleInvite(player, args)
"accept" -> handleAccept(player, args)
"deny" -> handleDeny(player, args)
"leave" -> handleLeave(player)
"kick" -> handleKick(player, args)
"info" -> handleInfo(player)
else -> player.sendMsg("team.usage")
}
return true
}
// =========================================================================
// Subcommand Handlers
// =========================================================================
private fun handleInvite(player: Player, args: Array<out String>) {
if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return }
val targetName = args.getOrNull(1) ?: run { player.sendMsg("team.invite.usage"); return }
val target = plugin.server.getPlayerExact(targetName) ?: run {
player.sendMsg("team.player_not_found", "name" to targetName); return
}
when (plugin.teamManager.invite(player, target)) {
is TeamManager.InviteResult.Success -> {
player.sendMsg("team.invite.sent", "name" to target.name)
target.sendMsg("team.invite.received",
"name" to player.name,
"time" to (TeamManager.INVITE_TTL_MS / 1000).toString()
)
}
is TeamManager.InviteResult.TeamsDisabled -> player.sendMsg("team.disabled")
is TeamManager.InviteResult.InvitedSelf -> player.sendMsg("team.invite.self")
is TeamManager.InviteResult.AlreadyInSameTeam -> player.sendMsg("team.invite.already_teammate")
is TeamManager.InviteResult.TargetAlreadyInTeam -> player.sendMsg("team.invite.target_has_team", "name" to target.name)
is TeamManager.InviteResult.SenderAlreadyInFullTeam -> player.sendMsg("team.invite.team_full")
is TeamManager.InviteResult.InviteAlreadyPending -> player.sendMsg("team.invite.already_pending", "name" to target.name)
}
}
private fun handleAccept(player: Player, args: Array<out String>) {
if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return }
val inviterName = args.getOrNull(1) ?: run { player.sendMsg("team.accept.usage"); return }
val inviter = plugin.server.getPlayerExact(inviterName) ?: run {
player.sendMsg("team.player_not_found", "name" to inviterName); return
}
when (val result = plugin.teamManager.accept(player, inviter.uniqueId)) {
is TeamManager.AcceptResult.Success -> {
val memberNames = result.team.members
.mapNotNull { plugin.server.getPlayer(it)?.name }
.joinToString(", ")
// Alle Teammitglieder benachrichtigen
result.team.members.forEach { uuid ->
plugin.server.getPlayer(uuid)?.sendMsg(
"team.accept.joined",
"name" to player.name,
"members" to memberNames
)
}
}
is TeamManager.AcceptResult.TeamsDisabled -> player.sendMsg("team.disabled")
is TeamManager.AcceptResult.NoInvite -> player.sendMsg("team.accept.no_invite", "name" to inviterName)
is TeamManager.AcceptResult.WrongInviter -> player.sendMsg("team.accept.no_invite", "name" to inviterName)
is TeamManager.AcceptResult.InviteExpired -> player.sendMsg("team.accept.expired", "name" to inviterName)
is TeamManager.AcceptResult.AlreadyInTeam -> player.sendMsg("team.already_in_team")
is TeamManager.AcceptResult.TeamFull -> player.sendMsg("team.invite.team_full")
is TeamManager.AcceptResult.InviterNotFound -> player.sendMsg("team.player_not_found", "name" to inviterName)
}
}
private fun handleDeny(player: Player, args: Array<out String>) {
if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return }
val inviterName = args.getOrNull(1) ?: run { player.sendMsg("team.deny.usage"); return }
val inviter = plugin.server.getPlayerExact(inviterName) ?: run {
player.sendMsg("team.player_not_found", "name" to inviterName); return
}
if (plugin.teamManager.deny(player, inviter.uniqueId)) {
player.sendMsg("team.deny.success", "name" to inviterName)
inviter.sendMsg("team.deny.received", "name" to player.name)
} else {
player.sendMsg("team.accept.no_invite", "name" to inviterName)
}
}
private fun handleLeave(player: Player) {
if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return }
val team = plugin.teamManager.getTeam(player)
when (plugin.teamManager.leave(player)) {
is TeamManager.LeaveResult.NotInTeam -> {
player.sendMsg("team.not_in_team")
}
is TeamManager.LeaveResult.TeamDisbanded -> {
// Alle Ex-Mitglieder (außer dem Verlassenden) benachrichtigen
team?.members?.forEach { uuid ->
plugin.server.getPlayer(uuid)?.sendMsg("team.leave.disbanded")
}
player.sendMsg("team.leave.disbanded")
}
is TeamManager.LeaveResult.Success -> {
player.sendMsg("team.leave.success")
// Verbleibende Mitglieder informieren
team?.members?.forEach { uuid ->
plugin.server.getPlayer(uuid)?.sendMsg(
"team.leave.member_left", "name" to player.name
)
}
}
}
}
private fun handleKick(player: Player, args: Array<out String>) {
if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return }
val targetName = args.getOrNull(1) ?: run { player.sendMsg("team.kick.usage"); return }
val target = plugin.server.getPlayerExact(targetName) ?: run {
player.sendMsg("team.player_not_found", "name" to targetName); return
}
when (plugin.teamManager.kick(player, target)) {
is TeamManager.KickResult.Success -> {
player.sendMsg("team.kick.success", "name" to target.name)
target.sendMsg("team.kick.received", "name" to player.name)
}
is TeamManager.KickResult.NotInTeam -> player.sendMsg("team.not_in_team")
is TeamManager.KickResult.NotLeader -> player.sendMsg("team.kick.not_leader")
is TeamManager.KickResult.TargetNotInTeam -> player.sendMsg("team.kick.not_in_your_team", "name" to targetName)
is TeamManager.KickResult.CannotKickSelf -> player.sendMsg("team.kick.self")
}
}
private fun handleInfo(player: Player) {
val team = plugin.teamManager.getTeam(player) ?: run {
player.sendMsg("team.not_in_team"); return
}
player.sendMsg("team.info.header")
team.members.forEachIndexed { i, uuid ->
val name = plugin.server.getPlayer(uuid)?.name ?: uuid.toString().take(8)
val isLeader = team.isLeader(uuid)
player.sendMsg(
"team.info.member",
"index" to (i + 1).toString(),
"name" to name,
"leader" to if (isLeader) "" else ""
)
}
player.sendMsg("team.info.footer", "size" to team.size.toString(), "max" to plugin.teamManager.maxTeamSize.toString())
}
// =========================================================================
// Tab Completion
// =========================================================================
override fun onTabComplete(
sender: CommandSender,
command: Command,
label: String,
args: Array<out String>
): List<String> {
if (sender !is Player) return emptyList()
if (args.size == 1) {
return listOf("invite", "accept", "deny", "leave", "kick", "info")
.filter { it.startsWith(args[0], ignoreCase = true) }
}
if (args.size == 2) {
return when (args[0].lowercase()) {
"invite", "accept", "deny", "kick" ->
plugin.server.onlinePlayers
.filter { it != sender }
.map { it.name }
.filter { it.startsWith(args[1], ignoreCase = true) }
else -> emptyList()
}
}
return emptyList()
}
}