diff --git a/src/net/torvald/terrarum/Principii.java b/src/net/torvald/terrarum/Principii.java index 73503b968..3d40fe41c 100644 --- a/src/net/torvald/terrarum/Principii.java +++ b/src/net/torvald/terrarum/Principii.java @@ -78,7 +78,7 @@ public class Principii { if (OS.contains("WIN")) { runtimeRoot = "runtime-windows-" + runtimeArch; } - else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", even on Big Sur and beyond + else if (OS.contains("OS X") || OS.contains("MACOS")) { // OpenJDK for mac will still report "Mac OS X" with version number "10.16", "11.x", "12.x", "13.x", ... runtimeRoot = "runtime-osx-" + runtimeArch; extracmd0 += " -XstartOnFirstThread"; } diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 4f4d876e6..ad3d4e0ef 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -101,8 +101,6 @@ object WorldSimulator { fun buryGrassImmediately() { - //val grassPlacedByPlayer = ArrayList() - ingame.terrainChangeQueue.forEach { if (BlockCodex[it.new].isSolid) { if (world.getTileFromTerrain(it.posX, it.posY + 1) == Block.GRASS) { @@ -111,39 +109,10 @@ object WorldSimulator { } } } - - // kill grasses surrounded by dirts in cruciform formation - // NOPE this part would not work; environment-depending degrassing must be done by the "grass spread simulator" - /*val for_y_start = (WorldCamera.y.toFloat() / TILE_SIZE).floorToInt() - val for_y_end = for_y_start + BlocksDrawer.tilesInVertical - 1 - - val for_x_start = (WorldCamera.x.toFloat() / TILE_SIZE).floorToInt() - val for_x_end = for_x_start + BlocksDrawer.tilesInHorizontal - 1 - for (y in for_y_start..for_y_end) { - for (x in for_x_start..for_x_end) { - // do not de-grass ones placed by player - var nogo = false - grassPlacedByPlayer.forEach { - if (x == it.posX && y == it.posY) nogo = true - } - - if (!nogo) { - val tile = world.getTileFromTerrain(x, y) - if (tile == Block.GRASS) { - if (world.getTileFromTerrain(x - 1, y) != Block.GRASS && - world.getTileFromTerrain(x + 1, y) != Block.GRASS && - world.getTileFromTerrain(x, y - 1) != Block.GRASS && - world.getTileFromTerrain(x, y + 1) != Block.GRASS) { - world.setTileTerrain(x, y, Block.DIRT, true) - } - } - } - } - }*/ } fun growOrKillGrass() { - repeat(2) { + repeat(2 * world.worldTime.timeDelta) { val rx = rng.nextInt(updateXFrom, updateXTo + 1) val ry = rng.nextInt(updateYFrom, updateYTo + 1) val tile = world.getTileFromTerrain(rx, ry) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UITitleWallOfText.kt b/src/net/torvald/terrarum/modulebasegame/ui/UITitleWallOfText.kt index 6579c3fcb..469b86413 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UITitleWallOfText.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UITitleWallOfText.kt @@ -6,9 +6,8 @@ import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.App import net.torvald.terrarum.CreditSingleton -import net.torvald.terrarum.ui.Toolkit -import net.torvald.terrarum.ui.UICanvas -import net.torvald.terrarum.ui.UIItemTextArea +import net.torvald.terrarum.ceilToInt +import net.torvald.terrarum.ui.* import java.util.TreeMap open class UITitleWallOfText(private val text: List) : UICanvas() { @@ -17,30 +16,56 @@ open class UITitleWallOfText(private val text: List) : UICanvas() { private val textAreaHMargin = 48 override var width = 600 override var height = App.scr.height - textAreaHMargin * 2 - private val textArea = UIItemTextArea(this, - (App.scr.width - width) / 2, textAreaHMargin, - width, height - ) + private val textArea: UIItemTextArea = UIItemTextArea( + this, + (App.scr.width - width) / 2 + 32, textAreaHMargin, + width, height + ).also { + it.setWallOfText(text) + it.scrolledListener = { x, y -> + scrollbar?.scrolledForce(5*x, 5*y) + } + } + + private val scrollbar: UIItemVertSlider? = if (true) { + UIItemVertSlider( + this, + (App.scr.width - width) / 2 - 16, textAreaHMargin, + 0.0, 0.0, text.size - textArea.lineCount.toDouble(), + height, ((textArea.lineCount.toDouble() / text.size) * height).ceilToInt() + ).also { + it.selectionChangeListener = { value -> + textArea.scrollPos = value.toInt() + } + } + } + else null init { - uiItems.add(textArea) - - textArea.setWallOfText(text) } override fun updateUI(delta: Float) { textArea.update(delta) + scrollbar?.update(delta) } override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) { batch.color = Color.WHITE textArea.render(batch, camera) + scrollbar?.render(batch, camera) //AppLoader.printdbg(this, "Rendering texts of length ${text.size}") } + override fun scrolled(amountX: Float, amountY: Float): Boolean { + textArea.scrolled(amountX, amountY) + return true + } + override fun dispose() { + textArea.dispose() + scrollbar?.dispose() } } diff --git a/src/net/torvald/terrarum/ui/UIItemHorzSlider.kt b/src/net/torvald/terrarum/ui/UIItemHorzSlider.kt index 042490967..c9f32636e 100644 --- a/src/net/torvald/terrarum/ui/UIItemHorzSlider.kt +++ b/src/net/torvald/terrarum/ui/UIItemHorzSlider.kt @@ -106,5 +106,16 @@ class UIItemHorzSlider( if (disposeTexture) backgroundTexture?.texture?.tryDispose() } + fun scrolledForce(amountX: Float, amountY: Float): Boolean { + val scroll = if (amountY == 0f) amountX else if (amountX == 0f) amountY else (amountX + amountY) / 2f + val move = Math.round(scroll) + val newValue = (value + move).coerceIn(min, max) + + handlePos = interpolateLinear(newValue / max, 0.0, handleTravelDist.toDouble()) + value = newValue + selectionChangeListener(value) + + return true + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/ui/UIItemVertSlider.kt b/src/net/torvald/terrarum/ui/UIItemVertSlider.kt new file mode 100644 index 000000000..9692a0b97 --- /dev/null +++ b/src/net/torvald/terrarum/ui/UIItemVertSlider.kt @@ -0,0 +1,113 @@ +package net.torvald.terrarum.ui + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.g2d.TextureRegion +import net.torvald.terrarum.* +import net.torvald.terrarum.App.printdbg +import kotlin.math.roundToInt + +/** + * Created by minjaesong on 2023-09-17. + */ +class UIItemVertSlider( + parentUI: UICanvas, + initialX: Int, initialY: Int, + private var initialValue: Double, + val min: Double, + val max: Double, + override val height: Int, + val handleHeight: Int = 12, + private val backgroundTexture: TextureRegion? = null, + private val disposeTexture: Boolean = false +) : UIItem(parentUI, initialX, initialY) { + + override val width = 16 + private var mouseOnHandle = false + + private val handleTravelDist = height - handleHeight + private var handlePos = (initialValue / max).times(handleTravelDist).coerceIn(0.0, handleTravelDist.toDouble()) + + var value: Double = initialValue; private set + var selectionChangeListener: (Double) -> Unit = {} + + init { + printdbg(this, "slider max=$max") + } + + override fun update(delta: Float) { + super.update(delta) + + mouseOnHandle = itemRelativeMouseY in handlePos.roundToInt() until handlePos.roundToInt() + handleHeight && itemRelativeMouseX in 0 until width + + // update handle position and value + if (mouseUp && Terrarum.mouseDown || mouseLatched) { + mouseLatched = true + handlePos = (itemRelativeMouseY - handleHeight/2.0).coerceIn(0.0, handleTravelDist.toDouble()) + value = interpolateLinear(handlePos / handleTravelDist, min, max) + selectionChangeListener(value) + } + + if (!Terrarum.mouseDown) { + mouseLatched = false + } + } + + val troughBorderCol: Color; get() = if (mouseUp || mouseLatched) Toolkit.Theme.COL_MOUSE_UP else Toolkit.Theme.COL_INACTIVE + val handleCol: Color; get() = if (mouseOnHandle && mousePushed || mouseLatched) Toolkit.Theme.COL_SELECTED + else if (mouseOnHandle) Toolkit.Theme.COL_MOUSE_UP else Color.WHITE + + private val renderJobs = arrayOf( + // trough fill + { batch: SpriteBatch -> + if (backgroundTexture != null) { + batch.color = Color.WHITE + batch.draw(backgroundTexture, posX.toFloat(), posY.toFloat(), width.toFloat(), height.toFloat()) + } + else { + batch.color = UIItemTextLineInput.TEXTINPUT_COL_BACKGROUND + Toolkit.fillArea(batch, posX, posY, width, height) + } + }, + // trough border + { batch: SpriteBatch -> + batch.color = troughBorderCol + Toolkit.drawBoxBorder(batch, posX - 1, posY - 1, width + 2, height + 2) + }, + // handle fill + { batch: SpriteBatch -> + batch.color = handleCol.cpy().mul(Color.LIGHT_GRAY) + Toolkit.fillArea(batch, posX, posY + handlePos.roundToInt(), width, handleHeight) + }, + // handle border + { batch: SpriteBatch -> + batch.color = handleCol + Toolkit.drawBoxBorder(batch, posX - 1, posY + handlePos.roundToInt() - 1, width + 2, handleHeight + 2) + }, + ) + + private val renderOrderMouseUp = arrayOf(0,2,3,1).map { renderJobs[it] } + + override fun render(batch: SpriteBatch, camera: OrthographicCamera) { + blendNormalStraightAlpha(batch) + renderOrderMouseUp.forEach { it(batch) } + + super.render(batch, camera) + } + + override fun dispose() { + if (disposeTexture) backgroundTexture?.texture?.tryDispose() + } + + fun scrolledForce(amountX: Float, amountY: Float): Boolean { + val move = Math.round(amountY) + val newValue = (value + move).coerceIn(min, max) + + handlePos = interpolateLinear(newValue / max, 0.0, handleTravelDist.toDouble()) + value = newValue + selectionChangeListener(value) + + return true + } +} \ No newline at end of file