mostly working jukebox ui

This commit is contained in:
minjaesong
2024-01-13 22:03:35 +09:00
parent ab171fe9b3
commit 3c3e650a97
6 changed files with 146 additions and 79 deletions

View File

@@ -157,7 +157,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
@Transient var mainUIopenFun: ((UICanvas) -> Unit)? = null @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() : super(RenderOrder.BEHIND, PhysProperties.IMMOBILE, null)
protected constructor(renderOrder: RenderOrder, physProp: PhysProperties, id: ActorID?) : super(renderOrder, physProp, id) protected constructor(renderOrder: RenderOrder, physProp: PhysProperties, id: ActorID?) : super(renderOrder, physProp, id)

View File

@@ -4,27 +4,25 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.spriteanimation.SheetSpriteAnimation import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg 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.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.audio.AudioMixer
import net.torvald.terrarum.audio.AudioMixer.DEFAULT_FADEOUT_LEN import net.torvald.terrarum.audio.AudioMixer.DEFAULT_FADEOUT_LEN
import net.torvald.terrarum.audio.dsp.Convolv import net.torvald.terrarum.audio.dsp.Convolv
import net.torvald.terrarum.audio.dsp.NullFilter 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.gameactors.AVKey
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.MusicContainer import net.torvald.terrarum.modulebasegame.MusicContainer
import net.torvald.terrarum.modulebasegame.TerrarumMusicGovernor import net.torvald.terrarum.modulebasegame.TerrarumMusicGovernor
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase 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
import net.torvald.terrarum.modulebasegame.ui.UIJukebox.Companion.SLOT_SIZE import net.torvald.terrarum.modulebasegame.ui.UIJukebox.Companion.SLOT_SIZE
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
@@ -39,22 +37,16 @@ class FixtureJukebox : Electric {
mainUI = UIJukebox() mainUI = UIJukebox()
) )
@Transient private var discCurrentlyPlaying: Int? = null @Transient var discCurrentlyPlaying: Int? = null; private set
@Transient private var musicNowPlaying: MusicContainer? = null @Transient var musicNowPlaying: MusicContainer? = null; private set
@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 private val backLamp: SheetSpriteAnimation @Transient private val backLamp: SheetSpriteAnimation
internal val discInventory = arrayOfNulls<ItemID>(SLOT_SIZE) internal val discInventory = arrayOfNulls<ItemID>(SLOT_SIZE)
val musicIsPlaying: Boolean
get() = musicNowPlaying != null
init { init {
(mainUI as UIJukebox).parent = this (mainUI as UIJukebox).parent = this
@@ -84,36 +76,64 @@ class FixtureJukebox : Electric {
override fun update(delta: Float) { override fun update(delta: Float) {
super.update(delta) super.update(delta)
if (discCurrentlyPlaying == null) { // supress the normal background music playback
// wait 3 seconds if (musicIsPlaying && !flagDespawn) {
if (waitAkku >= 3f) {
discCurrentlyPlaying = 0
playDisc(discCurrentlyPlaying!!)
waitAkku = 0f
}
waitAkku += delta
}
else if (!flagDespawn) {
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic() (INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic()
} }
} }
private fun playDisc(index: Int) { fun playDisc(index: Int) {
printdbg(this, "Play disc $index!") 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) { if (musicFile != null) {
startAudio(musicNowPlaying!!) { val musicdbFile = musicFile.sibling("_musicdb.json")
it.filters[2] = Convolv(ModMgr.getFile("basegame", "audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin"), 0f, 5f / 16f) 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 @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) { override fun drawBody(frameDelta: Float, batch: SpriteBatch) {
blendNormalStraightAlpha(batch) blendNormalStraightAlpha(batch)
super.drawBody(frameDelta, batch) super.drawBody(frameDelta, batch)
@@ -130,7 +150,7 @@ class FixtureJukebox : Electric {
} }
} }
private fun forceStop() { private fun stopDiscPlayback() {
musicNowPlaying?.let { musicNowPlaying?.let {
stopAudio(it) stopAudio(it)
unloadConvolver(it) unloadConvolver(it)
@@ -145,10 +165,7 @@ class FixtureJukebox : Electric {
} }
} }
@Transient override var despawnHook: (FixtureBase) -> Unit = { @Transient override var despawnHook: (FixtureBase) -> Unit = { stopGracefully() }
forceStop()
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f)
}
override fun reload() { override fun reload() {
super.reload() super.reload()

View File

@@ -1,5 +1,8 @@
package net.torvald.terrarum.modulebasegame.gameitems 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.GameItem
import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.ItemID
import java.io.File import java.io.File
@@ -63,4 +66,14 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) {
override val isDynamic = false override val isDynamic = false
override val materialId = "" override val materialId = ""
override var equipPosition = EquipPosition.HAND_GRIP 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)
} }

View File

@@ -20,19 +20,19 @@ import kotlin.math.roundToInt
* Created by minjaesong on 2017-10-22. * Created by minjaesong on 2017-10-22.
*/ */
abstract class UIItemInventoryCellBase( abstract class UIItemInventoryCellBase(
parentUI: UICanvas, parentUI: UICanvas,
initialX: Int, initialX: Int,
initialY: Int, initialY: Int,
open var item: GameItem?, open var item: GameItem?,
open var amount: Long, open var amount: Long,
open var itemImage: TextureRegion?, open var itemImage: TextureRegion?,
open var quickslot: Int? = null, open var quickslot: Int? = null,
open var equippedSlot: Int? = null, open var equippedSlot: Int? = null,
val keyDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Keycode, extra info, self var 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 var touchDownFun: (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit, // Item, Amount, Button, extra info, self
open var extraInfo: Any?, open var extraInfo: Any?,
open protected val highlightEquippedItem: Boolean = true, // for some UIs that only cares about getting equipped slot number but not highlighting 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 var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme
) : UIItem(parentUI, initialX, initialY) { ) : UIItem(parentUI, initialX, initialY) {
abstract override fun update(delta: Float) abstract override fun update(delta: Float)
abstract override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) abstract override fun render(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera)

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.*
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.GameItem
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory 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.gameactors.InventoryPair
import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef import net.torvald.terrarum.modulebasegame.gameitems.ItemFileRef
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.defaultInventoryCellTheme 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 thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset
private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y() private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y()
private var currentFreeSlot = 0 // private var currentFreeSlot: Int
private val playerInventory: ActorInventory private val playerInventory: ActorInventory
get() = INGAME.actorNowPlaying!!.inventory get() = INGAME.actorNowPlaying!!.inventory
@@ -36,9 +37,28 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() {
thisOffsetX, thisOffsetY + (UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) * index, thisOffsetX, thisOffsetY + (UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap) * index,
6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap, 6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap,
keyDownFun = { _, _, _, _, _ -> Unit }, keyDownFun = { _, _, _, _, _ -> Unit },
touchDownFun = { gameItem, amount, mouseButton, _, _ -> touchDownFun = { _, _, _, _, _ -> Unit },
if (mouseButton == App.getConfigInt("config_mouseprimary")) { )
}.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 (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 parent.discInventory[index] = null
playerInventory.add(gameItem) playerInventory.add(gameItem)
@@ -51,28 +71,29 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() {
rebuild() rebuild()
} }
} }
}, }
)
}.toTypedArray() addUIitem(thisButton)
}
}
private val playerInventoryUI = UITemplateHalfInventory(this, false).also { private val playerInventoryUI = UITemplateHalfInventory(this, false).also {
it.itemListTouchDownFun = { gameItem, _, _, _, _ -> 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].item = gameItem
fixtureDiscCell[currentFreeSlot].itemImage = gameItem.itemImage
parent.discInventory[currentFreeSlot] = gameItem.dynamicID
playerInventory.remove(gameItem) playerInventory.remove(gameItem)
currentFreeSlot += 1
rebuild() rebuild()
} }
} }
addUIitem(it)
} }
init {
fixtureDiscCell.forEach { thisButton ->
addUIitem(thisButton)
}
addUIitem(playerInventoryUI)
}
private val playerInventoryFilterFun = { (itm, _): InventoryPair -> private val playerInventoryFilterFun = { (itm, _): InventoryPair ->
ItemCodex[itm].let { 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 thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + UIItemInventoryItemGrid.listGap - halfSlotOffset
private val thisOffsetX2 = thisOffsetX + (UIItemInventoryItemGrid.listGap + UIItemInventoryElemWide.height) * 7 private val thisOffsetX2 = thisOffsetX + (UIItemInventoryItemGrid.listGap + UIItemInventoryElemWide.height) * 7
private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y()
private val songButtonColourTheme = defaultInventoryCellTheme.copy( private val songButtonColourTheme = defaultInventoryCellTheme.copy(
cellHighlightNormalCol = Color(0xfec753c8.toInt()), cellHighlightNormalCol = Color(0xfec753c8.toInt()),
@@ -134,22 +154,24 @@ class UIJukeboxSonglistPanel(val parent: UIJukebox) : UICanvas() {
if (index % 2 == 0) thisOffsetX else thisOffsetX2, if (index % 2 == 0) thisOffsetX else thisOffsetX2,
ys[index.shr(1)], ys[index.shr(1)],
6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap, 6 * UIItemInventoryElemSimple.height + 5 * UIItemInventoryItemGrid.listGap,
index = index,
colourTheme = songButtonColourTheme, colourTheme = songButtonColourTheme,
keyDownFun = { _, _, _, _, _ -> Unit }, keyDownFun = { _, _, _ -> Unit },
touchDownFun = { gameItem, amount, button, _, _ -> touchDownFun = { index, button, _ ->
if (button == App.getConfigInt("config_mouseprimary")) { if (button == App.getConfigInt("config_mouseprimary") && !parent.parent.musicIsPlaying) {
parent.parent.playDisc(index)
} }
} }
) )
}.toTypedArray() }.toTypedArray()
fun rebuild() { fun rebuild() {
jukeboxPlayButtons.forEachIndexed { index, button -> jukeboxPlayButtons.forEachIndexed { index, button ->
parent.discInventory[index].let { parent.discInventory[index].let {
val item = ItemCodex[it] as? ItemFileRef val item = ItemCodex[it] as? ItemFileRef
button.title = "${index+1} ${item?.name}"// ?: "" button.title = item?.name ?: ""
button.artist = "${index+1} ${item?.author}"// ?: "" button.artist = item?.author ?: ""
} }
} }
} }
@@ -185,11 +207,12 @@ class UIItemJukeboxSonglist(
initialX: Int, initialX: Int,
initialY: Int, initialY: Int,
override val width: Int, override val width: Int,
val index: Int,
var title: String = "", var title: String = "",
var artist: String = "", var artist: String = "",
var keyDownFun: (GameItem?, Long, Int, Any?, UIItemJukeboxSonglist) -> Unit, // Item, Amount, Keycode, extra info, self var keyDownFun: (Int, Int, UIItemJukeboxSonglist) -> Unit, // Index, Keycode, self
var touchDownFun: (GameItem?, Long, Int, Any?, UIItemJukeboxSonglist) -> Unit, // Item, Amount, Button, extra info, self var touchDownFun: (Int, Int, UIItemJukeboxSonglist) -> Unit, // Index, Button, self
var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme var colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme
) : UIItem(parentUI, initialX, initialY) { ) : UIItem(parentUI, initialX, initialY) {
@@ -200,8 +223,8 @@ class UIItemJukeboxSonglist(
override val height = Companion.height override val height = Companion.height
private val textOffsetX = 50f private val textOffsetX = 6
private val textOffsetY = 8f private val textOffsetY = 1
/** Custom highlight rule to highlight tihs button to primary accent colour (blue by default). /** Custom highlight rule to highlight tihs button to primary accent colour (blue by default).
@@ -215,6 +238,19 @@ class UIItemJukeboxSonglist(
var forceHighlighted = false 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 private var highlightToMainCol = false
@@ -250,9 +286,10 @@ class UIItemJukeboxSonglist(
else colourTheme.textHighlightNormalCol else colourTheme.textHighlightNormalCol
// draw title // draw title
App.fontGame.draw(batch, title, posX + textOffsetX, posY + textOffsetY) Toolkit.drawTextCentered(batch, App.fontGame, title, width, posX, posY + textOffsetY)
// draw artist // 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? // see IFs above?