package club.mcscrims.speedhg.kit import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.kit.charge.PlayerChargeData import org.bukkit.entity.Player import java.util.UUID import java.util.concurrent.ConcurrentHashMap /** * Manages kit registration, player selections, and the charge state for all online players. * * ## Typical usage flow * ``` * // During plugin startup * kitManager.registerKit(WarriorKit()) * kitManager.registerKit(ArcherKit()) * * // During lobby (e.g. GUI click) * kitManager.selectKit(player, kitManager.getKit("warrior")!!) * kitManager.selectPlaystyle(player, Playstyle.AGGRESSIVE) * * // When the game round starts (replace the TODO in GameManager.startGame) * kitManager.applyKit(player) // gives items, runs onAssign / passive.onActivate * * // When the round ends * kitManager.clearAll() // runs onRemove / passive.onDeactivate for every player * ``` */ class KitManager( private val plugin: SpeedHG ) { // All kits available this session, keyed by Kit.id private val registeredKits = ConcurrentHashMap() // Lobby selections — set before the round starts private val selectedKits = ConcurrentHashMap() private val selectedPlaystyles = ConcurrentHashMap() // Live charge state — populated by applyKit, cleared by removeKit/clearAll private val chargeData = ConcurrentHashMap() // ------------------------------------------------------------------------- // Kit registration // ------------------------------------------------------------------------- fun registerKit( kit: Kit ) { registeredKits[kit.id] = kit plugin.logger.info("[KitManager] Registered kit: ${kit.id}") } fun getRegisteredKits(): Collection = registeredKits.values fun getKit( id: String ): Kit? = registeredKits[id] // ------------------------------------------------------------------------- // Player selections (lobby phase) // ------------------------------------------------------------------------- fun selectKit( player: Player, kit: Kit ) { selectedKits[player.uniqueId] = kit } /** * Set the playstyle for a player. * Defaults to [Playstyle.DEFENSIVE] if never called. */ fun selectPlaystyle( player: Player, playstyle: Playstyle ) { selectedPlaystyles[player.uniqueId] = playstyle } fun getSelectedKit( player: Player ): Kit? = selectedKits[player.uniqueId] fun getSelectedPlaystyle( player: Player ): Playstyle = selectedPlaystyles[player.uniqueId] ?: Playstyle.DEFENSIVE // ------------------------------------------------------------------------- // Game lifecycle // ------------------------------------------------------------------------- /** * Apply the player's selected kit at game start. * * Call this from [GameManager.startGame] for every online player, **after** teleportation. * If the player has not selected a kit, this is a no-op. */ fun applyKit( player: Player ) { val kit = selectedKits[player.uniqueId] ?: return val playstyle = getSelectedPlaystyle( player ) val active = kit.getActiveAbility( playstyle ) chargeData[player.uniqueId] = PlayerChargeData( active.hitsRequired ) kit.onAssign( player, playstyle ) kit.getPassiveAbility( playstyle ).onActivate( player ) kit.giveItems( player, playstyle ) } /** * Remove and clean up a player's kit (round over, player eliminated, etc.). * Safe to call even if the player has no kit assigned. */ fun removeKit( player: Player ) { val kit = selectedKits[player.uniqueId] ?: return val playstyle = getSelectedPlaystyle( player ) kit.getPassiveAbility( playstyle ).onDeactivate( player ) kit.onRemove( player ) chargeData.remove( player.uniqueId ) } /** * Remove all kits and clear every selection. * Call this at the end of each round, **before** resetting other game state. */ fun clearAll() { selectedKits.keys.toList().forEach { uuid -> val player = plugin.server.getPlayer( uuid ) if ( player != null ) removeKit( player ) else { // Daten bereinigen ohne Lifecycle-Hooks (Spieler ist offline) chargeData.remove( uuid ) // Hinweis: onDeactivate/onRemove können nicht aufgerufen werden // → Kits müssen in onActivate gestartete Tasks UUID-basiert führen } } selectedKits.clear() selectedPlaystyles.clear() chargeData.clear() } // ------------------------------------------------------------------------- // Charge access (used by KitEventDispatcher) // ------------------------------------------------------------------------- fun getChargeData( player: Player ): PlayerChargeData? = chargeData[player.uniqueId] }