From 3c3e650a9739fa6ecefe58cd699465acf5ed884f Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 13 Jan 2024 22:03:35 +0900 Subject: [PATCH] mostly working jukebox ui --- assets/mods/basegame/gui/jukebox_caticons.tga | 2 +- .../modulebasegame/gameactors/FixtureBase.kt | 2 +- .../gameactors/FixtureJukebox.kt | 91 +++++++++++-------- .../modulebasegame/gameitems/ItemFileRef.kt | 13 +++ .../ui/UIItemInventoryCellBase.kt | 26 +++--- .../modulebasegame/ui/UIJukeboxInventory.kt | 91 +++++++++++++------ 6 files changed, 146 insertions(+), 79 deletions(-) diff --git a/assets/mods/basegame/gui/jukebox_caticons.tga b/assets/mods/basegame/gui/jukebox_caticons.tga index 6ebe9c8f5..e5a78785f 100644 --- a/assets/mods/basegame/gui/jukebox_caticons.tga +++ b/assets/mods/basegame/gui/jukebox_caticons.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4282512c65c0d1d845709dde7d2018e87601e27762b89e089a303e44f90efa74 +oid sha256:dac8ce21e6f695304e0b5866e8e03e0bea91209555982786782ba2d0c761bc3c size 3218 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index d75c37c75..7870b267a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -157,7 +157,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { @Transient var mainUIopenFun: ((UICanvas) -> Unit)? = null - protected var actorThatInstalledThisFixture: UUID? = null + internal var actorThatInstalledThisFixture: UUID? = null protected constructor() : super(RenderOrder.BEHIND, PhysProperties.IMMOBILE, null) protected constructor(renderOrder: RenderOrder, physProp: PhysProperties, id: ActorID?) : super(renderOrder, physProp, id) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt index ef3e8a2c9..8943a30d8 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt @@ -4,27 +4,25 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.g2d.TextureRegion import com.jme3.math.FastMath import net.torvald.spriteanimation.SheetSpriteAnimation +import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg -import net.torvald.terrarum.INGAME -import net.torvald.terrarum.ModMgr import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.audio.AudioMixer.DEFAULT_FADEOUT_LEN import net.torvald.terrarum.audio.dsp.Convolv import net.torvald.terrarum.audio.dsp.NullFilter -import net.torvald.terrarum.blendNormalStraightAlpha -import net.torvald.terrarum.blendScreen import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.MusicContainer import net.torvald.terrarum.modulebasegame.TerrarumMusicGovernor import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase +import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef import net.torvald.terrarum.modulebasegame.ui.UIJukebox import net.torvald.terrarum.modulebasegame.ui.UIJukebox.Companion.SLOT_SIZE +import net.torvald.terrarum.utils.JsonFetcher import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import org.dyn4j.geometry.Vector2 @@ -39,22 +37,16 @@ class FixtureJukebox : Electric { mainUI = UIJukebox() ) - @Transient private var discCurrentlyPlaying: Int? = null - @Transient private var musicNowPlaying: MusicContainer? = null - - @Transient private val testMusic = ModMgr.getGdxFile("basegame", "audio/music/discs/01 Thousands of Shards.ogg").let { - MusicContainer("Thousands of Shards", it.file(), Gdx.audio.newMusic(it)) { - unloadConvolver(musicNowPlaying) - discCurrentlyPlaying = null - musicNowPlaying = null - (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f) - } - } + @Transient var discCurrentlyPlaying: Int? = null; private set + @Transient var musicNowPlaying: MusicContainer? = null; private set @Transient private val backLamp: SheetSpriteAnimation internal val discInventory = arrayOfNulls(SLOT_SIZE) + val musicIsPlaying: Boolean + get() = musicNowPlaying != null + init { (mainUI as UIJukebox).parent = this @@ -84,36 +76,64 @@ class FixtureJukebox : Electric { override fun update(delta: Float) { super.update(delta) - if (discCurrentlyPlaying == null) { - // wait 3 seconds - if (waitAkku >= 3f) { - discCurrentlyPlaying = 0 - playDisc(discCurrentlyPlaying!!) - waitAkku = 0f - } - - waitAkku += delta - } - else if (!flagDespawn) { + // supress the normal background music playback + if (musicIsPlaying && !flagDespawn) { (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic() } } - private fun playDisc(index: Int) { + fun playDisc(index: Int) { printdbg(this, "Play disc $index!") - musicNowPlaying = testMusic // todo use index + val disc = discInventory[index] + val musicFile = (ItemCodex[disc] as? ItemFileRef)?.getAsGdxFile() - AudioMixer.requestFadeOut(AudioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) { - startAudio(musicNowPlaying!!) { - it.filters[2] = Convolv(ModMgr.getFile("basegame", "audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin"), 0f, 5f / 16f) + if (musicFile != null) { + val musicdbFile = musicFile.sibling("_musicdb.json") + val musicdb = JsonFetcher.invoke(musicdbFile.file()) + val propForThisFile = musicdb.get(musicFile.name()) + + val artist = propForThisFile.get("artist").asString() + val title = propForThisFile.get("title").asString() + + printdbg(this, "Title: $title, artist: $artist") + + + musicNowPlaying = MusicContainer(title, musicFile.file(), Gdx.audio.newMusic(musicFile)) { + unloadConvolver(musicNowPlaying) + discCurrentlyPlaying = null + musicNowPlaying?.gdxMusic?.tryDispose() + musicNowPlaying = null + (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f) + } + + discCurrentlyPlaying = index + + AudioMixer.requestFadeOut(AudioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) { + startAudio(musicNowPlaying!!) { + it.filters[2] = Convolv( + ModMgr.getFile( + "basegame", + "audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin" + ), 0f, 5f / 16f + ) + } } } + } @Transient private var lampDecay = 0f + /** + * Try to stop the disc being played, and reset the background music cue + */ + fun stopGracefully() { + stopDiscPlayback() + (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f) + } + override fun drawBody(frameDelta: Float, batch: SpriteBatch) { blendNormalStraightAlpha(batch) super.drawBody(frameDelta, batch) @@ -130,7 +150,7 @@ class FixtureJukebox : Electric { } } - private fun forceStop() { + private fun stopDiscPlayback() { musicNowPlaying?.let { stopAudio(it) unloadConvolver(it) @@ -145,10 +165,7 @@ class FixtureJukebox : Electric { } } - @Transient override var despawnHook: (FixtureBase) -> Unit = { - forceStop() - (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f) - } + @Transient override var despawnHook: (FixtureBase) -> Unit = { stopGracefully() } override fun reload() { super.reload() diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt index d538cd6fa..03b815f73 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt @@ -1,5 +1,8 @@ package net.torvald.terrarum.modulebasegame.gameitems +import com.badlogic.gdx.Gdx +import net.torvald.terrarum.App +import net.torvald.terrarum.ModMgr import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID import java.io.File @@ -63,4 +66,14 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { override val isDynamic = false override val materialId = "" override var equipPosition = EquipPosition.HAND_GRIP + + fun getAsGdxFile() = if (refIsShared) + Gdx.files.external(App.saveSharedDir + "/$refPath") + else + ModMgr.getGdxFile(refModuleName, refPath) + + fun getAsFile() = if (refIsShared) + File(App.saveSharedDir + "/$refPath") + else + ModMgr.getFile(refModuleName, refPath) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt index 2e90410b6..7f9b6bb9d 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryCellBase.kt @@ -20,19 +20,19 @@ import kotlin.math.roundToInt * Created by minjaesong on 2017-10-22. */ abstract class UIItemInventoryCellBase( - parentUI: UICanvas, - initialX: Int, - initialY: Int, - open var item: GameItem?, - open var amount: Long, - open var itemImage: TextureRegion?, - open var quickslot: Int? = null, - open var equippedSlot: Int? = null, - val keyDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Keycode, extra info, self - val touchDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Button, extra info, self - open var extraInfo: Any?, - open protected val highlightEquippedItem: Boolean = true, // for some UIs that only cares about getting equipped slot number but not highlighting - var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme + parentUI: UICanvas, + initialX: Int, + initialY: Int, + open var item: GameItem?, + open var amount: Long, + open var itemImage: TextureRegion?, + open var quickslot: Int? = null, + open var equippedSlot: Int? = null, + var keyDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Keycode, extra info, self + var touchDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Button, extra info, self + open var extraInfo: Any?, + open protected val highlightEquippedItem: Boolean = true, // for some UIs that only cares about getting equipped slot number but not highlighting + var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme ) : UIItem(parentUI, initialX, initialY) { abstract override fun update(delta: Float) abstract override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt index 82be33b7c..da7dd3ab3 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.defaultInventoryCellTheme @@ -26,7 +27,7 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() { private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y() - private var currentFreeSlot = 0 +// private var currentFreeSlot: Int private val playerInventory: ActorInventory get() = INGAME.actorNowPlaying!!.inventory @@ -36,9 +37,28 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() { thisOffsetX, thisOffsetY + (UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) * index, 6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap, keyDownFun = { _, _, _, _, _ -> Unit }, - touchDownFun = { gameItem, amount, mouseButton, _, _ -> - if (mouseButton == App.getConfigInt("config_mouseprimary")) { + touchDownFun = { _, _, _, _, _ -> Unit }, + ) + }.toTypedArray() + + private val operatedByTheInstaller: Boolean + get() = true/*if (parent.parent.actorThatInstalledThisFixture == null) true + else if (parent.parent.actorThatInstalledThisFixture != null && INGAME.actorNowPlaying is IngamePlayer) + (parent.parent.actorThatInstalledThisFixture == (INGAME.actorNowPlaying as IngamePlayer).uuid) + else false*/ + + init { + fixtureDiscCell.forEachIndexed { index, thisButton -> + thisButton.touchDownFun = { gameItem, amount, mouseButton, _, _ -> + if (operatedByTheInstaller && mouseButton == App.getConfigInt("config_mouseprimary")) { if (gameItem != null) { + // if the disc being removed is the same disc being played, stop the playback + if (index == parent.parent.discCurrentlyPlaying) { + parent.parent.stopGracefully() + } + + // remove the disc + fixtureDiscCell[index].item = null parent.discInventory[index] = null playerInventory.add(gameItem) @@ -51,28 +71,29 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() { rebuild() } } - }, - ) - }.toTypedArray() + } + + addUIitem(thisButton) + } + } private val playerInventoryUI = UITemplateHalfInventory(this, false).also { it.itemListTouchDownFun = { gameItem, _, _, _, _ -> - if (currentFreeSlot < SLOT_SIZE && gameItem != null) { + val currentFreeSlot = parent.discInventory.filterNotNull().size + + if (operatedByTheInstaller && currentFreeSlot < SLOT_SIZE && gameItem != null) { fixtureDiscCell[currentFreeSlot].item = gameItem + fixtureDiscCell[currentFreeSlot].itemImage = gameItem.itemImage + parent.discInventory[currentFreeSlot] = gameItem.dynamicID playerInventory.remove(gameItem) - currentFreeSlot += 1 rebuild() } } + + addUIitem(it) } - init { - fixtureDiscCell.forEach { thisButton -> - addUIitem(thisButton) - } - addUIitem(playerInventoryUI) - } private val playerInventoryFilterFun = { (itm, _): InventoryPair -> ItemCodex[itm].let { @@ -113,7 +134,6 @@ class UIJukeboxSonglistPanel(val parent: UIJukebox) : UICanvas() { private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset private val thisOffsetX2 = thisOffsetX + (UIItemInventoryItemGrid.listGap + UIItemInventoryElemWide.height) * 7 - private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y() private val songButtonColourTheme = defaultInventoryCellTheme.copy( cellHighlightNormalCol = Color(0xfec753c8.toInt()), @@ -134,22 +154,24 @@ class UIJukeboxSonglistPanel(val parent: UIJukebox) : UICanvas() { if (index % 2 == 0) thisOffsetX else thisOffsetX2, ys[index.shr(1)], 6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap, + index = index, colourTheme = songButtonColourTheme, - keyDownFun = { _, _, _, _, _ -> Unit }, - touchDownFun = { gameItem, amount, button, _, _ -> - if (button == App.getConfigInt("config_mouseprimary")) { - + keyDownFun = { _, _, _ -> Unit }, + touchDownFun = { index, button, _ -> + if (button == App.getConfigInt("config_mouseprimary") && !parent.parent.musicIsPlaying) { + parent.parent.playDisc(index) } } ) }.toTypedArray() fun rebuild() { + jukeboxPlayButtons.forEachIndexed { index, button -> parent.discInventory[index].let { val item = ItemCodex[it] as? ItemFileRef - button.title = "${index+1} ${item?.name}"// ?: "" - button.artist = "${index+1} ${item?.author}"// ?: "" + button.title = item?.name ?: "" + button.artist = item?.author ?: "" } } } @@ -185,11 +207,12 @@ class UIItemJukeboxSonglist( initialX: Int, initialY: Int, override val width: Int, + val index: Int, var title: String = "", var artist: String = "", - var keyDownFun: (GameItem?, Long, Int, Any?, UIItemJukeboxSonglist) -> Unit, // Item, Amount, Keycode, extra info, self - var touchDownFun: (GameItem?, Long, Int, Any?, UIItemJukeboxSonglist) -> Unit, // Item, Amount, Button, extra info, self + var keyDownFun: (Int, Int, UIItemJukeboxSonglist) -> Unit, // Index, Keycode, self + var touchDownFun: (Int, Int, UIItemJukeboxSonglist) -> Unit, // Index, Button, self var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme ) : UIItem(parentUI, initialX, initialY) { @@ -200,8 +223,8 @@ class UIItemJukeboxSonglist( override val height = Companion.height - private val textOffsetX = 50f - private val textOffsetY = 8f + private val textOffsetX = 6 + private val textOffsetY = 1 /** Custom highlight rule to highlight tihs button to primary accent colour (blue by default). @@ -215,6 +238,19 @@ class UIItemJukeboxSonglist( var forceHighlighted = false + override fun keyDown(keycode: Int): Boolean { + keyDownFun(index, keycode, this) + super.keyDown(keycode) + return true + } + + override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { + if (mouseUp) { + touchDownFun(index, button, this) + super.touchDown(screenX, screenY, pointer, button) + } + return true + } private var highlightToMainCol = false @@ -250,9 +286,10 @@ class UIItemJukeboxSonglist( else colourTheme.textHighlightNormalCol // draw title - App.fontGame.draw(batch, title, posX + textOffsetX, posY + textOffsetY) + Toolkit.drawTextCentered(batch, App.fontGame, title, width, posX, posY + textOffsetY) // draw artist - App.fontGame.draw(batch, artist, posX + textOffsetX, posY + textOffsetY + 24f) + batch.color = batch.color.cpy().mul(0.75f, 0.75f, 0.75f, 1f) + Toolkit.drawTextCentered(batch, App.fontGame, artist, width, posX, posY + App.fontGame.lineHeight.toInt() - 2*textOffsetY) } // see IFs above?