diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index 0e6a7d982..ad47a9f54 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -17,6 +17,7 @@ import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer +import net.torvald.terrarum.modulebasegame.ui.Noticelet import net.torvald.terrarum.modulebasegame.ui.Notification import net.torvald.terrarum.modulebasegame.ui.UITooltip import net.torvald.terrarum.realestate.LandUtil @@ -86,6 +87,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo /** For in-world text overlays? e.g. cursor on the ore block and tooltip will say "Malachite" or something */ open var uiTooltip: UITooltip = UITooltip() open var notifier: Notification = Notification() + open var noticelet: Noticelet = Noticelet() val deltaTeeBenchmarks = CircularArray(App.getConfigInt("debug_deltat_benchmark_sample_sizes"), true) @@ -97,6 +99,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo (Toolkit.drawWidth - notifier.width) / 2, App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight ) + noticelet.setPosition(0, 0) printdbg(this, "New ingame instance ${this.hashCode()}, called from") printStackTrace(this) @@ -559,6 +562,10 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo fun onConfigChange() { } + fun sendItemPickupNoticelet(itemID: ItemID, itemCount: Long) { + noticelet.sendNotification(itemID, itemCount) + } + open val musicGovernor: MusicGovernor = MusicGovernor() } diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index d4c2f2c98..7bed16252 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -149,9 +149,7 @@ object WorldSimulator { val pickupDistSqr = w*w + h*h// TODO refer to the actorValue // println("${result.distance}\pickupDistSqr") if (result.distance < pickupDistSqr) { - droppedItem.flagDespawn = true - (actor as Pocketed).inventory.add(droppedItem.itemID, droppedItem.itemCount) - ItemCodex[droppedItem.itemID]!!.effectOnPickup(actor) + droppedItem.onItemPickup(actor) break } } diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 106afcda2..fb5ed2b74 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -657,6 +657,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { } // these need to appear on top of any others + uiContainer.add(noticelet) uiContainer.add(notifier) App.setDebugTime("Ingame.UpdateCounter", 0) @@ -1615,6 +1616,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { (Toolkit.drawWidth - notifier.width) / 2, App.scr.height - notifier.height - App.scr.tvSafeGraphicsHeight ) + noticelet.setPosition(0, 0) uiQuickBar.setPosition((drawWidth - uiQuickBar.width) / 2, App.scr.tvSafeGraphicsHeight) // inventory diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt index 7ab30d429..6915107d9 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt @@ -8,6 +8,7 @@ import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.BlockCodex import net.torvald.terrarum.INGAME import net.torvald.terrarum.ItemCodex +import net.torvald.terrarum.Terrarum import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.gameactors.* @@ -157,4 +158,11 @@ open class DroppedItem : ActorWithBody { } } } + + fun onItemPickup(actor: ActorWithBody) { + flagDespawn = true + (actor as Pocketed).inventory.add(itemID, itemCount) + Terrarum.ingame!!.sendItemPickupNoticelet(itemID, itemCount) + ItemCodex[itemID]!!.effectOnPickup(actor) + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/Noticelet.kt b/src/net/torvald/terrarum/modulebasegame/ui/Noticelet.kt new file mode 100644 index 000000000..e1824bbdc --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ui/Noticelet.kt @@ -0,0 +1,122 @@ +package net.torvald.terrarum.modulebasegame.ui + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.utils.Queue +import net.torvald.terrarum.* +import net.torvald.terrarum.App.printdbg +import net.torvald.terrarum.gameitems.ItemID +import net.torvald.terrarum.ui.Toolkit +import net.torvald.terrarum.ui.UICanvas + +/** + * Smaller notification for item pickup notice + * + * Created by minjaesong on 2024-01-22. + */ +class Noticelet : UICanvas() { + + data class Notice( + var timeAddedMS: Long, + val item: ItemID, + var amount: Long, + var akku: Float = 0f + ) + + private var fontCol: Color = Color.WHITE // assuming alpha of 1.0 + + override var openCloseTime: Second = Notification.OPEN_CLOSE_TIME + private val visibleTime = 5f + + private val LRmargin = 0f // there's "base value" of 8 px for LR (width of segment tile) + + + + override var width: Int = 500 + + override var height: Int = 0 + + + internal val messageQueue = ArrayList() + + private val timeGaugeCol = Color(0x707070ff) + + init { + handler.alwaysUpdate = true + setAsAlwaysVisible() + } + + override fun updateUI(delta: Float) { + // update timer and animation + messageQueue.forEach { + it.akku += delta + if (it.akku > despawnTime) toDelete.add(it) + } + + toDelete.forEach { + messageQueue.remove(it) + } + toDelete.clear() + } + + private val h = 24f + private val gap = 8f + + private val toDelete = ArrayList() + + override fun renderUI(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { + val px = Toolkit.drawWidthf + val py = App.scr.halfhf + 100f + + messageQueue.forEachIndexed { index, notice -> + drawNoticelet(batch, px, py + (h + gap) * index, notice) + } + } + + override fun dispose() { + } + + private val despawnTime = openCloseTime + visibleTime + openCloseTime + + /** + * @param x center point + * @param y up point + */ + private fun drawNoticelet(batch: SpriteBatch, x: Float, y: Float, notice: Notice) { + val prop = ItemCodex[notice.item]!! + val str = "${prop.name} (${notice.amount})" + val strLen = App.fontGame.getWidth(str) + val icon = ItemCodex.getItemImage(notice.item) ?: CommonResourcePool.getAsTextureRegion("itemplaceholder_16") + val width = 4f + icon.regionWidth + 4 + strLen + 4 + val dx = ((x - width) / 2).floorToFloat() + val dy = y + + val opacity = if (notice.akku < openCloseTime) + notice.akku / openCloseTime + else if (notice.akku < openCloseTime + visibleTime) + 1f + else + 1f - (notice.akku - visibleTime - openCloseTime) / openCloseTime + + Toolkit.drawBaloon(batch, dx, dy + 2, width, h - 4, opacity.coerceIn(0f, 1f)) + batch.draw(icon, dx + 4f, dy + ((h - icon.regionHeight) / 2).floorToFloat()) + App.fontGame.draw(batch, str, dx + 4f + icon.regionWidth + 4, dy) + } + + fun sendNotification(item: ItemID, amount: Long) { +// printdbg(this, "Picked up $item ($amount)") + messageQueue.find { it.item == item }.let { + if (it != null) { + it.timeAddedMS = System.currentTimeMillis() + it.amount += amount + it.akku = openCloseTime + } + else { + messageQueue.add(Notice(System.currentTimeMillis(), item, amount)) + } + } + } + + +} \ No newline at end of file