Aller au contenu principal

open_audio_settings

Open Audio Settings Menu — misc entry.

Entry Information

PropertyValue
Entry IDopen_audio_settings
TypeMisc
ColorCyan
Iconfa6-solid:sliders

Description

Opens the Audio Settings menu for a player. Shows per-layer volume controls as clickable items. Supported button types: AUDIO_VOLUME_UP, AUDIO_VOLUME_DOWN, AUDIO_LAYER_MUTE, AUDIO_CLOSE / @Entry("audio_settings_menu", "Audio Settings Menu", Colors.CYAN, "fa6-solid:volume-high") @Tags("audio_settings_menu", "action") class AudioSettingsMenuEntry( override val id: String = "", override val name: String = "", override val criteria: List<Criteria> = emptyList(), override val modifiers: List<Modifier> = emptyList(), override val triggers: List<Ref<TriggerableEntry>> = emptyList(), @Help("Title of the inventory") val inventoryTitle: Var<String> = ConstVar("<gradient:#0ABAB5:#3366CC>Audio Settings</gradient>"), @Help("Number of rows (1-6)") val inventoryRows: Int = 4, @Help("GUI type to use (CUSTOM, BOOK, FURNACE, etc.)") val guiType: GuiType = GuiType.CUSTOM, @Help("Pool of layout definitions.") val layoutPool: List<LayoutData> = emptyList(), @Help("ID of the main layout to display from the pool.") val mainLayoutId: String? = null, @Help("Audio configuration for the GUI.") val audio: GuiAudioData = GuiAudioData(), ) : ActionEntry { companion object { private val LAYER_DISPLAY_NAMES = mapOf( AudioLayer.MASTER to "<white>Master", AudioLayer.MUSIC to "<aqua>Music", AudioLayer.AMBIENT to "<green>Ambient", AudioLayer.SFX to "<yellow>SFX", AudioLayer.VOICE to "<light_purple>Voice" ) private val LAYER_MATERIALS = mapOf( AudioLayer.MASTER to Material.NETHER_STAR, AudioLayer.MUSIC to Material.MUSIC_DISC_CAT, AudioLayer.AMBIENT to Material.GRASS_BLOCK, AudioLayer.SFX to Material.ANVIL, AudioLayer.VOICE to Material.PLAYER_HEAD ) } override fun ActionTrigger.execute() { CoroutineScope(Dispatchers.Default).launch { openForPlayer(player) } } suspend fun openForPlayer(player: Player) { val ctx = context {} val rawTitleString = inventoryTitle.get(player, ctx).parsePlaceholders(player) val componentTitle = try { MiniMessage.miniMessage().deserialize(rawTitleString) } catch (: Exception) { net.kyori.adventure.text.Component.text(rawTitleString) } val rows = inventoryRows.coerceIn(1, 6) val resolvedSize = InventorySize.entries.getOrNull(rows - 1) ?: InventorySize.SIZE_36 val totalSize = resolvedSize.slots val pool = layoutPool.filterNotNull().associateBy { it.id } val mainLayout = mainLayoutId?.let { pool[it] } val baseLayout: MenuLayout = mainLayout?.let { LayoutParser.parse(player, ctx, guiType, totalSize, pool, it) } ?: EmptyLayout val finalLayout: MenuLayout = AudioButtonResolverLayout( inner = baseLayout, resolver = { type: String, p: Player, slot: GuiSlot -> resolveButton(p, type, slot) } ) val definition = MenuDefinition( id = "audio_settings${player.uniqueId}", type = guiType, title = componentTitle, rawTitle = rawTitleString, size = resolvedSize, layout = finalLayout, audio = MenuAudioConfig( onOpen = audio.onOpen, onClose = audio.onClose, onScroll = audio.onScroll, onClick = audio.onClick ) ) MenuSessionService.register(player, definition) } private fun resolveButton(player: Player, type: String, slot: GuiSlot): GuiSlot? { val buttonType = try { AudioButtonType.valueOf(type) } catch (: IllegalArgumentException) { return null } val mixerService: AudioMixerService = org.koin.java.KoinJavaComponent.get(AudioMixerService::class.java) return when (buttonType) { AudioButtonType.AUDIO_VOLUME_UP -> { val layer = getLayerFromSlot(slot) ?: return slot val currentVol = mixerService.getLayerVolume(player, layer) val newVol = (currentVol + 0.1f).coerceAtMost(1.0f) mixerService.setLayerVolume(player, layer, newVol) buildLayerSlot(player, layer, newVol) } AudioButtonType.AUDIO_VOLUME_DOWN -> { val layer = getLayerFromSlot(slot) ?: return slot val currentVol = mixerService.getLayerVolume(player, layer) val newVol = (currentVol - 0.1f).coerceAtLeast(0.0f) mixerService.setLayerVolume(player, layer, newVol) buildLayerSlot(player, layer, newVol) } AudioButtonType.AUDIO_LAYER_MUTE -> { val layer = getLayerFromSlot(slot) ?: return slot val currentVol = mixerService.getLayerVolume(player, layer) val newVol = if (currentVol > 0.0f) 0.0f else 1.0f mixerService.setLayerVolume(player, layer, newVol) buildLayerSlot(player, layer, newVol) } AudioButtonType.AUDIO_CLOSE -> { player.closeInventory() null } } } private fun getLayerFromSlot(slot: GuiSlot): AudioLayer? { val tag = slot.tag ?: return null val layerName = tag.removePrefix("audio_layer:") return try { AudioLayer.valueOf(layerName) } catch (: Exception) { null } } private fun buildLayerSlot( player: Player, layer: AudioLayer, volume: Float ): GuiSlot { val material = LAYER_MATERIALS[layer] ?: Material.PAPER val displayName = LAYER_DISPLAY_NAMES[layer] ?: layer.name val percent = (volume * 100).toInt() val filledBars = (volume * 10).toInt() val emptyBars = 10 - filledBars val bar = "<dark_gray>[<green>${"▬".repeat(filledBars)}<gray>${"▬".repeat(emptyBars)}</dark_gray>]" val item = ItemStack(material) val meta = item.itemMeta if (meta != null) { meta.displayName(MiniMessage.miniMessage().deserialize("<white>$displayName <gray>$percent%")) meta.lore(listOf( MiniMessage.miniMessage().deserialize("<gray>$bar"), MiniMessage.miniMessage().deserialize(""), MiniMessage.miniMessage().deserialize("<yellow>Left-Click <gray>▸ <green>+10%"), MiniMessage.miniMessage().deserialize("<yellow>Right-Click <gray>▸ <red>-10%"), MiniMessage.miniMessage().deserialize("<yellow>Shift-Click <gray>▸ <aqua>Toggle Mute") )) item.itemMeta = meta } return GuiSlot( x = 0, y = 0, item = item, allowPickup = false, tag = "audio_layer:${layer.name}", interactions = mapOf( InteractionType.LEFT_CLICK to GuiSlotInteraction( commands = listOf("audio_button AUDIO_VOLUME_UP ${player.name} ${layer.name}") ), InteractionType.RIGHT_CLICK to GuiSlotInteraction( commands = listOf("audio_button AUDIO_VOLUME_DOWN ${player.name} ${layer.name}") ), InteractionType.SHIFT_LEFT_CLICK to GuiSlotInteraction( commands = listOf("audio_button AUDIO_LAYER_MUTE ${player.name} ${layer.name}") ) ) ) } } /** Action entry to open the audio settings menu.

Fields

FieldTypeDescription
menuRef<AudioSettingsMenuEntry>The audio settings menu entry to open

Usage Example

- entry: open_audio_settings
name: "Open Audio Settings Menu"
menu: ""