mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
18 Commits
inventory-
...
newlight2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49f055ca27 | ||
|
|
b7f7589990 | ||
|
|
a7ef6b1f53 | ||
|
|
f857d49d82 | ||
|
|
503229675f | ||
|
|
ead33aeb7a | ||
|
|
feb2becbc2 | ||
|
|
01e10824f7 | ||
|
|
cc0646ffc9 | ||
|
|
fdb258f578 | ||
|
|
c8235aa57a | ||
|
|
d22959e993 | ||
|
|
cbf0064e13 | ||
|
|
50b98d565a | ||
|
|
216bc299a8 | ||
|
|
ddebb65362 | ||
|
|
0d8c93d18e | ||
|
|
14eb765670 |
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#version 120
|
#version 130
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Binary file not shown.
@@ -44,7 +44,7 @@ internal object UnsafeHelper {
|
|||||||
*
|
*
|
||||||
* @return offset from the array's base memory address (aka pointer) that the actual data begins.
|
* @return offset from the array's base memory address (aka pointer) that the actual data begins.
|
||||||
*/
|
*/
|
||||||
fun getArrayOffset(obj: Any) = unsafe.arrayBaseOffset(obj.javaClass)
|
fun getArrayOffset(obj: Any) = unsafe.arrayBaseOffset(obj.javaClass).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ import com.badlogic.gdx.utils.NumberUtils
|
|||||||
class Cvec {
|
class Cvec {
|
||||||
|
|
||||||
/** the red, green, blue and alpha components */
|
/** the red, green, blue and alpha components */
|
||||||
var r: Float = 0.toFloat()
|
var r: Float = 0f
|
||||||
var g: Float = 0.toFloat()
|
var g: Float = 0f
|
||||||
var b: Float = 0.toFloat()
|
var b: Float = 0f
|
||||||
var a: Float = 0.toFloat()
|
var a: Float = 0f
|
||||||
|
|
||||||
/** Constructs a new Cvec with all components set to 0. */
|
/** Constructs a new Cvec with all components set to 0. */
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ internal object AssembleFrameBase {
|
|||||||
transforms.forEach { transform ->
|
transforms.forEach { transform ->
|
||||||
if (transform.joint.name == ADProperties.ALL_JOINT_SELECT_KEY) {
|
if (transform.joint.name == ADProperties.ALL_JOINT_SELECT_KEY) {
|
||||||
// transform applies to all joints
|
// transform applies to all joints
|
||||||
for (c in 0 until out.size) {
|
for (c in out.indices) {
|
||||||
out[c] = out[c].first to (out[c].second + transform.translate)
|
out[c] = out[c].first to (out[c].second + transform.translate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,7 +346,9 @@ public class AppLoader implements ApplicationListener {
|
|||||||
// safe area box
|
// safe area box
|
||||||
//KeyToggler.INSTANCE.forceSet(Input.Keys.F11, true);
|
//KeyToggler.INSTANCE.forceSet(Input.Keys.F11, true);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
System.err.println("Game not started using DEBUG MODE -- current build of the game will display black screen without debug mode");
|
||||||
|
}
|
||||||
// set some more configuration vars
|
// set some more configuration vars
|
||||||
MULTITHREAD = ThreadParallel.INSTANCE.getThreadCount() >= 3 && getConfigBoolean("multithread");
|
MULTITHREAD = ThreadParallel.INSTANCE.getThreadCount() >= 3 && getConfigBoolean("multithread");
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,13 @@ data class Point2d(var x: Double, var y: Double) : Cloneable {
|
|||||||
|
|
||||||
fun toDoubleArray() = doubleArrayOf(x, y)
|
fun toDoubleArray() = doubleArrayOf(x, y)
|
||||||
|
|
||||||
|
fun apply(transformation: (Double, Double) -> Pair<Double, Double>): Point2d {
|
||||||
|
val translation = transformation(x, y)
|
||||||
|
this.x = translation.first
|
||||||
|
this.y = translation.second
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Point2i(var x: Int, var y: Int) {
|
data class Point2i(var x: Int, var y: Int) {
|
||||||
@@ -79,4 +86,12 @@ data class Point2i(var x: Int, var y: Int) {
|
|||||||
operator fun minus(other: Point2i): Point2i {
|
operator fun minus(other: Point2i): Point2i {
|
||||||
return Point2i(other.x - this.x, other.y - this.y)
|
return Point2i(other.x - this.x, other.y - this.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun apply(transformation: (Int, Int) -> Pair<Int, Int>): Point2i {
|
||||||
|
val translation = transformation(x, y)
|
||||||
|
this.x = translation.first
|
||||||
|
this.y = translation.second
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.blockstats
|
package net.torvald.terrarum.blockstats
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
@@ -73,8 +74,8 @@ object MinimapComposer : Disposable {
|
|||||||
fun update() {
|
fun update() {
|
||||||
// make the queueing work
|
// make the queueing work
|
||||||
// enqueue first
|
// enqueue first
|
||||||
for (y in 0 until tilemap.size) {
|
for (y in tilemap.indices) {
|
||||||
for (x in 0 until tilemap[0].size) {
|
for (x in tilemap[0].indices) {
|
||||||
if (liveTilesMeta[tilemap[y][x]].revalidate) {
|
if (liveTilesMeta[tilemap[y][x]].revalidate) {
|
||||||
liveTilesMeta[tilemap[y][x]].revalidate = false
|
liveTilesMeta[tilemap[y][x]].revalidate = false
|
||||||
updaterQueue.addLast(createUpdater(x, y))
|
updaterQueue.addLast(createUpdater(x, y))
|
||||||
@@ -83,7 +84,7 @@ object MinimapComposer : Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// consume the queue
|
// consume the queue
|
||||||
for (k in 0 until currentThreads.size) {
|
for (k in currentThreads.indices) {
|
||||||
if (currentThreads[k].state == Thread.State.TERMINATED && !updaterQueue.isEmpty) {
|
if (currentThreads[k].state == Thread.State.TERMINATED && !updaterQueue.isEmpty) {
|
||||||
currentThreads[k] = Thread(updaterQueue.removeFirst(), "MinimapLivetilePainter")
|
currentThreads[k] = Thread(updaterQueue.removeFirst(), "MinimapLivetilePainter")
|
||||||
printdbg(this, "Consuming from queue; queue size now: ${updaterQueue.size}")
|
printdbg(this, "Consuming from queue; queue size now: ${updaterQueue.size}")
|
||||||
@@ -139,11 +140,11 @@ object MinimapComposer : Disposable {
|
|||||||
val colTerr = CreateTileAtlas.terrainTileColourMap.get(tileTerr % 16, tileTerr / 16)
|
val colTerr = CreateTileAtlas.terrainTileColourMap.get(tileTerr % 16, tileTerr / 16)
|
||||||
val colWall = CreateTileAtlas.terrainTileColourMap.get(wallTerr % 16, wallTerr / 16).mul(BlocksDrawer.wallOverlayColour)
|
val colWall = CreateTileAtlas.terrainTileColourMap.get(wallTerr % 16, wallTerr / 16).mul(BlocksDrawer.wallOverlayColour)
|
||||||
|
|
||||||
if (colTerr.a < 1f) {
|
val outCol = if (colTerr.a > 0.1f) colTerr else colWall
|
||||||
pixmap.setColor(colWall)
|
|
||||||
pixmap.drawPixel(x - topLeftX, y - topLeftY)
|
pixmap.blending = Pixmap.Blending.None
|
||||||
}
|
pixmap.setColor(outCol)
|
||||||
pixmap.setColor(colTerr)
|
//pixmap.setColor(Color.CORAL)
|
||||||
pixmap.drawPixel(x - topLeftX, y - topLeftY)
|
pixmap.drawPixel(x - topLeftX, y - topLeftY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package net.torvald.terrarum.concurrent
|
package net.torvald.terrarum.concurrent
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.*
|
||||||
import java.util.concurrent.Executors
|
|
||||||
import java.util.concurrent.Future
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
typealias RunnableFun = () -> Unit
|
typealias RunnableFun = () -> Unit
|
||||||
@@ -14,32 +11,58 @@ typealias ThreadableFun = (Int) -> Unit
|
|||||||
object ThreadExecutor {
|
object ThreadExecutor {
|
||||||
val threadCount = Runtime.getRuntime().availableProcessors() // not using (logicalCores + 1) method; it's often better idea to reserve one extra thread for other jobs in the app
|
val threadCount = Runtime.getRuntime().availableProcessors() // not using (logicalCores + 1) method; it's often better idea to reserve one extra thread for other jobs in the app
|
||||||
private lateinit var executor: ExecutorService// = Executors.newFixedThreadPool(threadCount)
|
private lateinit var executor: ExecutorService// = Executors.newFixedThreadPool(threadCount)
|
||||||
|
val futures = ArrayList<Future<*>>()
|
||||||
|
private var isOpen = true
|
||||||
|
|
||||||
private fun checkShutdown() {
|
private fun checkShutdown() {
|
||||||
try {
|
try {
|
||||||
if (executor.isTerminated)
|
if (executor.isTerminated)
|
||||||
throw IllegalStateException("Executor terminated, renew the executor service.")
|
throw IllegalStateException("Executor terminated, renew the executor service.")
|
||||||
if (executor.isShutdown)
|
if (!isOpen || executor.isShutdown)
|
||||||
throw IllegalStateException("Pool is closed, come back when all the threads are terminated.")
|
throw IllegalStateException("Pool is closed, come back when all the threads are terminated.")
|
||||||
}
|
}
|
||||||
catch (e: UninitializedPropertyAccessException) {}
|
catch (e: UninitializedPropertyAccessException) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renew() {
|
fun renew() {
|
||||||
|
try {
|
||||||
|
if (!executor.isTerminated && !executor.isShutdown) throw IllegalStateException("Pool is still running")
|
||||||
|
}
|
||||||
|
catch (_: UninitializedPropertyAccessException) {}
|
||||||
|
|
||||||
executor = Executors.newFixedThreadPool(threadCount)
|
executor = Executors.newFixedThreadPool(threadCount)
|
||||||
|
futures.clear()
|
||||||
|
isOpen = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submit(t: Runnable): Future<*> {
|
/*fun invokeAll(ts: List<Callable<Unit>>) {
|
||||||
checkShutdown()
|
checkShutdown()
|
||||||
return executor.submit(t)
|
executor.invokeAll(ts)
|
||||||
}
|
}*/
|
||||||
fun submit(f: RunnableFun): Future<*> {
|
|
||||||
checkShutdown()
|
|
||||||
return executor.submit { f() }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fun submit(t: Callable<Unit>) {
|
||||||
|
checkShutdown()
|
||||||
|
val fut = executor.submit(t)
|
||||||
|
futures.add(fut)
|
||||||
|
}
|
||||||
|
/*fun submit(f: RunnableFun) {
|
||||||
|
checkShutdown()
|
||||||
|
val fut = executor.submit { f() }
|
||||||
|
futures.add(fut)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/28818494/threads-stopping-prematurely-for-certain-values
|
||||||
fun join() {
|
fun join() {
|
||||||
println("ThreadExecutor.join")
|
println("ThreadExecutor.join")
|
||||||
|
isOpen = false
|
||||||
|
futures.forEach {
|
||||||
|
try {
|
||||||
|
it.get()
|
||||||
|
}
|
||||||
|
catch (e: ExecutionException) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
executor.shutdown() // thread status of completed ones will be WAIT instead of TERMINATED without this line...
|
executor.shutdown() // thread status of completed ones will be WAIT instead of TERMINATED without this line...
|
||||||
executor.awaitTermination(24L, TimeUnit.HOURS)
|
executor.awaitTermination(24L, TimeUnit.HOURS)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
// scan for the one with non-null UI.
|
// scan for the one with non-null UI.
|
||||||
// what if there's multiple of such fixtures? whatever, you are supposed to DISALLOW such situation.
|
// what if there's multiple of such fixtures? whatever, you are supposed to DISALLOW such situation.
|
||||||
for (kk in 0 until actorsUnderMouse.size) {
|
for (kk in actorsUnderMouse.indices) {
|
||||||
actorsUnderMouse[kk].mainUI?.let {
|
actorsUnderMouse[kk].mainUI?.let {
|
||||||
uiOpened = true
|
uiOpened = true
|
||||||
|
|
||||||
|
|||||||
@@ -378,8 +378,8 @@ object WorldSimulator {
|
|||||||
private val FALLABLE_MAX_FALL_SPEED = 2
|
private val FALLABLE_MAX_FALL_SPEED = 2
|
||||||
|
|
||||||
private fun monitorIllegalFluidSetup() {
|
private fun monitorIllegalFluidSetup() {
|
||||||
for (y in 0 until fluidMap.size) {
|
for (y in fluidMap.indices) {
|
||||||
for (x in 0 until fluidMap[0].size) {
|
for (x in fluidMap[0].indices) {
|
||||||
val fluidData = world.getFluid(x + updateXFrom, y + updateYFrom)
|
val fluidData = world.getFluid(x + updateXFrom, y + updateYFrom)
|
||||||
if (fluidData.amount < 0f) {
|
if (fluidData.amount < 0f) {
|
||||||
throw InternalError("Negative amount of fluid at (${x + updateXFrom},${y + updateYFrom}): $fluidData")
|
throw InternalError("Negative amount of fluid at (${x + updateXFrom},${y + updateYFrom}): $fluidData")
|
||||||
@@ -391,8 +391,8 @@ object WorldSimulator {
|
|||||||
private fun makeFluidMapFromWorld() {
|
private fun makeFluidMapFromWorld() {
|
||||||
//printdbg(this, "Scan area: ($updateXFrom,$updateYFrom)..(${updateXFrom + fluidMap[0].size},${updateYFrom + fluidMap.size})")
|
//printdbg(this, "Scan area: ($updateXFrom,$updateYFrom)..(${updateXFrom + fluidMap[0].size},${updateYFrom + fluidMap.size})")
|
||||||
|
|
||||||
for (y in 0 until fluidMap.size) {
|
for (y in fluidMap.indices) {
|
||||||
for (x in 0 until fluidMap[0].size) {
|
for (x in fluidMap[0].indices) {
|
||||||
val fluidData = world.getFluid(x + updateXFrom, y + updateYFrom)
|
val fluidData = world.getFluid(x + updateXFrom, y + updateYFrom)
|
||||||
fluidMap[y][x] = fluidData.amount
|
fluidMap[y][x] = fluidData.amount
|
||||||
fluidTypeMap[y][x] = fluidData.type
|
fluidTypeMap[y][x] = fluidData.type
|
||||||
@@ -407,8 +407,8 @@ object WorldSimulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fluidmapToWorld() {
|
private fun fluidmapToWorld() {
|
||||||
for (y in 0 until fluidMap.size) {
|
for (y in fluidMap.indices) {
|
||||||
for (x in 0 until fluidMap[0].size) {
|
for (x in fluidMap[0].indices) {
|
||||||
world.setFluid(x + updateXFrom, y + updateYFrom, fluidNewTypeMap[y][x], fluidNewMap[y][x])
|
world.setFluid(x + updateXFrom, y + updateYFrom, fluidNewTypeMap[y][x], fluidNewMap[y][x])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,20 +96,20 @@ class WorldTime(initTime: Long = 0L) {
|
|||||||
|
|
||||||
|
|
||||||
// these functions won't need inlining for performance
|
// these functions won't need inlining for performance
|
||||||
val yearlyDays: Int // 0 - 119
|
val ordinalDay: Int // 0 - 119
|
||||||
get() = (TIME_T.div(DAY_LENGTH) fmod YEAR_DAYS.toLong()).toInt()
|
get() = (TIME_T.div(DAY_LENGTH) fmod YEAR_DAYS.toLong()).toInt()
|
||||||
val days: Int // 1 - 30 fixed
|
val calendarDay: Int // 1 - 30 fixed
|
||||||
get() = (yearlyDays % MONTH_LENGTH) + 1
|
get() = (ordinalDay % MONTH_LENGTH) + 1
|
||||||
val months: Int // 1 - 4
|
val calendarMonth: Int // 1 - 4
|
||||||
get() = (yearlyDays / MONTH_LENGTH) + 1
|
get() = (ordinalDay / MONTH_LENGTH) + 1
|
||||||
val years: Int
|
val years: Int
|
||||||
get() = TIME_T.div(YEAR_DAYS * DAY_LENGTH).abs().toInt() + EPOCH_YEAR
|
get() = TIME_T.div(YEAR_DAYS * DAY_LENGTH).abs().toInt() + EPOCH_YEAR
|
||||||
|
|
||||||
val quarter = months - 1 // 0 - 3
|
val quarter = calendarMonth - 1 // 0 - 3
|
||||||
|
|
||||||
|
|
||||||
val dayOfWeek: Int //0: Mondag-The first day of weekday (0 - 7)
|
val dayOfWeek: Int //0: Mondag-The first day of weekday (0 - 7)
|
||||||
get() = if (yearlyDays == YEAR_DAYS - 1) 7 else yearlyDays % 7
|
get() = if (ordinalDay == YEAR_DAYS - 1) 7 else ordinalDay % 7
|
||||||
|
|
||||||
var timeDelta: Int = 1
|
var timeDelta: Int = 1
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -206,17 +206,17 @@ class WorldTime(initTime: Long = 0L) {
|
|||||||
fun getFormattedTime() = "${getDayNameShort()}, " +
|
fun getFormattedTime() = "${getDayNameShort()}, " +
|
||||||
"$years " +
|
"$years " +
|
||||||
"${getMonthNameFull()} " +
|
"${getMonthNameFull()} " +
|
||||||
"$days " +
|
"$calendarDay " +
|
||||||
"${String.format("%02d", hours)}:" +
|
"${String.format("%02d", hours)}:" +
|
||||||
"${String.format("%02d", minutes)}:" +
|
"${String.format("%02d", minutes)}:" +
|
||||||
"${String.format("%02d", seconds)}"
|
"${String.format("%02d", seconds)}"
|
||||||
fun getShortTime() = "${years.toString().padStart(4, '0')}-${getMonthNameShort()}-${days.toString().padStart(2, '0')}"
|
fun getShortTime() = "${years.toString().padStart(4, '0')}-${getMonthNameShort()}-${calendarDay.toString().padStart(2, '0')}"
|
||||||
fun getFilenameTime() = "${years.toString().padStart(4, '0')}${months.toString().padStart(2, '0')}${days.toString().padStart(2, '0')}"
|
fun getFilenameTime() = "${years.toString().padStart(4, '0')}${calendarMonth.toString().padStart(2, '0')}${calendarDay.toString().padStart(2, '0')}"
|
||||||
|
|
||||||
fun getDayNameFull() = DAY_NAMES[dayOfWeek]
|
fun getDayNameFull() = DAY_NAMES[dayOfWeek]
|
||||||
fun getDayNameShort() = DAY_NAMES_SHORT[dayOfWeek]
|
fun getDayNameShort() = DAY_NAMES_SHORT[dayOfWeek]
|
||||||
fun getMonthNameFull() = MONTH_NAMES[months - 1]
|
fun getMonthNameFull() = MONTH_NAMES[calendarMonth - 1]
|
||||||
fun getMonthNameShort() = MONTH_NAMES_SHORT[months - 1]
|
fun getMonthNameShort() = MONTH_NAMES_SHORT[calendarMonth - 1]
|
||||||
|
|
||||||
override fun toString() = getFormattedTime()
|
override fun toString() = getFormattedTime()
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ package net.torvald.terrarum.modulebasegame.ui
|
|||||||
inventorySortList.sortBy { it.item.name }
|
inventorySortList.sortBy { it.item.name }
|
||||||
|
|
||||||
// map sortList to item list
|
// map sortList to item list
|
||||||
for (k in 0 until items.size) {
|
for (k in items.indices) {
|
||||||
// we have an item
|
// we have an item
|
||||||
try {
|
try {
|
||||||
val sortListItem = inventorySortList[k + itemPage * items.size]
|
val sortListItem = inventorySortList[k + itemPage * items.size]
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ internal class UIInventoryCells(
|
|||||||
UIItemInventoryDynamicList(
|
UIItemInventoryDynamicList(
|
||||||
full,
|
full,
|
||||||
full.actor.inventory,
|
full.actor.inventory,
|
||||||
0 + (AppLoader.screenW - full.internalWidth) / 2,
|
full.INVENTORY_CELLS_OFFSET_X,
|
||||||
107 + (AppLoader.screenH - full.internalHeight) / 2,
|
full.INVENTORY_CELLS_OFFSET_Y,
|
||||||
full.CELLS_HOR, full.CELLS_VRT
|
full.CELLS_HOR, full.CELLS_VRT
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ internal class UIInventoryCells(
|
|||||||
full.actor.inventory,
|
full.actor.inventory,
|
||||||
full.actor as ActorWithBody,
|
full.actor as ActorWithBody,
|
||||||
full.internalWidth - UIItemInventoryEquippedView.WIDTH + (AppLoader.screenW - full.internalWidth) / 2,
|
full.internalWidth - UIItemInventoryEquippedView.WIDTH + (AppLoader.screenW - full.internalWidth) / 2,
|
||||||
107 + (AppLoader.screenH - full.internalHeight) / 2
|
full.INVENTORY_CELLS_OFFSET_Y
|
||||||
)
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.graphics.Camera
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import net.torvald.terrarum.AppLoader
|
||||||
|
import net.torvald.terrarum.TitleScreen
|
||||||
|
import net.torvald.terrarum.blendNormal
|
||||||
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
|
import net.torvald.terrarum.ui.UIItemTextButtonList
|
||||||
|
import net.torvald.terrarum.ui.UIItemTextButtonList.Companion.DEFAULT_LINE_HEIGHT
|
||||||
|
|
||||||
|
class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() {
|
||||||
|
|
||||||
|
override var width: Int = AppLoader.screenW
|
||||||
|
override var height: Int = AppLoader.screenH
|
||||||
|
override var openCloseTime = 0.0f
|
||||||
|
|
||||||
|
private val gameMenu = arrayOf("MENU_LABEL_MAINMENU", "MENU_LABEL_DESKTOP", "MENU_OPTIONS_CONTROLS", "MENU_OPTIONS_SOUND", "MENU_LABEL_GRAPHICS")
|
||||||
|
private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size
|
||||||
|
private val gameMenuListWidth = 400
|
||||||
|
private val gameMenuButtons = UIItemTextButtonList(
|
||||||
|
this, gameMenu,
|
||||||
|
(AppLoader.screenW - gameMenuListWidth) / 2,
|
||||||
|
full.INVENTORY_CELLS_OFFSET_Y + (full.INVENTORY_CELLS_UI_HEIGHT - gameMenuListHeight) / 2,
|
||||||
|
gameMenuListWidth, gameMenuListHeight,
|
||||||
|
readFromLang = true,
|
||||||
|
textAreaWidth = gameMenuListWidth,
|
||||||
|
activeBackCol = Color(0),
|
||||||
|
highlightBackCol = Color(0),
|
||||||
|
backgroundCol = Color(0),
|
||||||
|
inactiveCol = Color.WHITE,
|
||||||
|
defaultSelection = null
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
uiItems.add(gameMenuButtons)
|
||||||
|
|
||||||
|
gameMenuButtons.selectionChangeListener = { _, new ->
|
||||||
|
when (new) {
|
||||||
|
0 -> AppLoader.setScreen(TitleScreen(AppLoader.batch))
|
||||||
|
1 -> Gdx.app.exit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateUI(delta: Float) {
|
||||||
|
gameMenuButtons.update(delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
|
// control hints
|
||||||
|
blendNormal(batch)
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
AppLoader.fontGame.draw(batch, full.gameMenuControlHelp, full.offsetX, full.yEnd - 20)
|
||||||
|
|
||||||
|
// text buttons
|
||||||
|
gameMenuButtons.render(batch, camera)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doOpening(delta: Float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doClosing(delta: Float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun endOpening(delta: Float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun endClosing(delta: Float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,8 +29,6 @@ class UIInventoryFull(
|
|||||||
doNotWarnConstant: Boolean = false
|
doNotWarnConstant: Boolean = false
|
||||||
) : UICanvas(toggleKeyLiteral, toggleButtonLiteral, customPositioning, doNotWarnConstant) {
|
) : UICanvas(toggleKeyLiteral, toggleButtonLiteral, customPositioning, doNotWarnConstant) {
|
||||||
|
|
||||||
private val debugvals = true
|
|
||||||
|
|
||||||
override var width: Int = AppLoader.screenW
|
override var width: Int = AppLoader.screenW
|
||||||
override var height: Int = AppLoader.screenH
|
override var height: Int = AppLoader.screenH
|
||||||
override var openCloseTime: Second = 0.0f
|
override var openCloseTime: Second = 0.0f
|
||||||
@@ -48,6 +46,10 @@ class UIInventoryFull(
|
|||||||
|
|
||||||
val itemListHeight: Int = CELLS_VRT * UIItemInventoryElemSimple.height + (CELLS_VRT - 1) * net.torvald.terrarum.modulebasegame.ui.UIItemInventoryDynamicList.Companion.listGap
|
val itemListHeight: Int = CELLS_VRT * UIItemInventoryElemSimple.height + (CELLS_VRT - 1) * net.torvald.terrarum.modulebasegame.ui.UIItemInventoryDynamicList.Companion.listGap
|
||||||
|
|
||||||
|
val INVENTORY_CELLS_UI_HEIGHT = CELLS_VRT * UIItemInventoryElemSimple.height + (CELLS_VRT - 1) * UIItemInventoryDynamicList.listGap
|
||||||
|
val INVENTORY_CELLS_OFFSET_X = 0 + (AppLoader.screenW - internalWidth) / 2
|
||||||
|
val INVENTORY_CELLS_OFFSET_Y = 107 + (AppLoader.screenH - internalHeight) / 2
|
||||||
|
|
||||||
init {
|
init {
|
||||||
handler.allowESCtoClose = true
|
handler.allowESCtoClose = true
|
||||||
CommonResourcePool.addToLoadingList("inventory_caticons") {
|
CommonResourcePool.addToLoadingList("inventory_caticons") {
|
||||||
@@ -111,13 +113,13 @@ class UIInventoryFull(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private val transitionalMinimap = UIInventoryCells(this) // PLACEHOLDER
|
private val transitionalMinimap = UIInventoryMinimap(this) // PLACEHOLDER
|
||||||
private val transitionalItemCells = UIInventoryCells(this)
|
private val transitionalItemCells = UIInventoryCells(this)
|
||||||
private val transitionalEscMenu = UIInventoryCells(this) // PLACEHOLDER
|
private val transitionalEscMenu = UIInventoryEscMenu(this)
|
||||||
private val transitionPanel = UIItemHorizontalFadeSlide(
|
private val transitionPanel = UIItemHorizontalFadeSlide(
|
||||||
this,
|
this,
|
||||||
(AppLoader.screenW - internalWidth) / 2,
|
(AppLoader.screenW - internalWidth) / 2,
|
||||||
107 + (AppLoader.screenH - internalHeight) / 2,
|
INVENTORY_CELLS_OFFSET_Y,
|
||||||
AppLoader.screenW,
|
AppLoader.screenW,
|
||||||
AppLoader.screenH,
|
AppLoader.screenH,
|
||||||
1f,
|
1f,
|
||||||
@@ -125,36 +127,9 @@ class UIInventoryFull(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private val gameMenu = arrayOf("MENU_LABEL_MAINMENU", "MENU_LABEL_DESKTOP", "MENU_OPTIONS_CONTROLS", "MENU_OPTIONS_SOUND", "MENU_LABEL_GRAPHICS")
|
|
||||||
private val gameMenuListHeight = DEFAULT_LINE_HEIGHT * gameMenu.size
|
|
||||||
private val gameMenuListWidth = 400
|
|
||||||
private val gameMenuButtons = UIItemTextButtonList(
|
|
||||||
this, gameMenu,
|
|
||||||
(AppLoader.screenW - gameMenuListWidth) / 2,
|
|
||||||
(transitionalItemCells.itemList.height - gameMenuListHeight) / 2 + transitionalItemCells.itemList.posY,
|
|
||||||
gameMenuListWidth, gameMenuListHeight,
|
|
||||||
readFromLang = true,
|
|
||||||
textAreaWidth = gameMenuListWidth,
|
|
||||||
activeBackCol = Color(0),
|
|
||||||
highlightBackCol = Color(0),
|
|
||||||
backgroundCol = Color(0),
|
|
||||||
inactiveCol = Color.WHITE,
|
|
||||||
defaultSelection = null
|
|
||||||
)
|
|
||||||
|
|
||||||
private val SCREEN_MINIMAP = 0f
|
|
||||||
private val SCREEN_INVENTORY = 1f
|
|
||||||
private val SCREEN_MENU = 2f
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addUIitem(categoryBar)
|
addUIitem(categoryBar)
|
||||||
addUIitem(transitionPanel)
|
addUIitem(transitionPanel)
|
||||||
//itemList.let { addUIitem(it) }
|
|
||||||
//equipped.let { addUIitem(it) }
|
|
||||||
|
|
||||||
|
|
||||||
categoryBar.selectionChangeListener = { old, new ->
|
categoryBar.selectionChangeListener = { old, new ->
|
||||||
rebuildList()
|
rebuildList()
|
||||||
@@ -164,15 +139,6 @@ class UIInventoryFull(
|
|||||||
|
|
||||||
rebuildList()
|
rebuildList()
|
||||||
|
|
||||||
// make gameMenuButtons work
|
|
||||||
gameMenuButtons.selectionChangeListener = { old, new ->
|
|
||||||
if (new == 0) {
|
|
||||||
AppLoader.setScreen(TitleScreen(AppLoader.batch))
|
|
||||||
}
|
|
||||||
else if (new == 1) {
|
|
||||||
Gdx.app.exit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,29 +154,8 @@ class UIInventoryFull(
|
|||||||
rebuildList()
|
rebuildList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
categoryBar.update(delta)
|
categoryBar.update(delta)
|
||||||
transitionPanel.update(delta)
|
transitionPanel.update(delta)
|
||||||
|
|
||||||
|
|
||||||
// update map while visible
|
|
||||||
/*if (currentScreenTransition > 1f + epsilon) {
|
|
||||||
MinimapComposer.setWorld(Terrarum.ingame!!.world)
|
|
||||||
MinimapComposer.update()
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// update inventory while visible
|
|
||||||
/*if (currentScreenTransition in epsilon..2f - epsilon) {
|
|
||||||
itemList.update(delta)
|
|
||||||
equipped.update(delta)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// update menu while visible
|
|
||||||
/*if (currentScreenTransition < 1f - epsilon) {
|
|
||||||
gameMenuButtons.update(delta)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
minimapRerenderTimer += Gdx.graphics.rawDeltaTime
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gradStartCol = Color(0x404040_60)
|
private val gradStartCol = Color(0x404040_60)
|
||||||
@@ -223,18 +168,6 @@ class UIInventoryFull(
|
|||||||
internal var yEnd = (AppLoader.screenH + internalHeight).div(2).toFloat()
|
internal var yEnd = (AppLoader.screenH + internalHeight).div(2).toFloat()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private var minimapRerenderTimer = 0f
|
|
||||||
private val minimapRerenderInterval = .5f
|
|
||||||
|
|
||||||
// TODO implemented on UIItemTransitionContainer
|
|
||||||
/*fun requestTransition(target: Int) {
|
|
||||||
if (!transitionOngoing) {
|
|
||||||
transitionRequested = true
|
|
||||||
transitionReqSource = currentScreenTransition.round()
|
|
||||||
transitionReqTarget = target.toFloat()
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
|
|
||||||
|
|
||||||
@@ -262,252 +195,8 @@ class UIInventoryFull(
|
|||||||
// UI items
|
// UI items
|
||||||
categoryBar.render(batch, camera)
|
categoryBar.render(batch, camera)
|
||||||
transitionPanel.render(batch, camera)
|
transitionPanel.render(batch, camera)
|
||||||
|
|
||||||
// render map while visible
|
|
||||||
/*if (currentScreenTransition > 1f + epsilon) {
|
|
||||||
renderScreenMinimap(batch, camera)
|
|
||||||
|
|
||||||
if (debugvals) {
|
|
||||||
batch.color = Color.CORAL
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "Map", 300f, 10f)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// render inventory while visible
|
|
||||||
/*if (currentScreenTransition in epsilon..2f - epsilon) {
|
|
||||||
renderScreenInventory(batch, camera)
|
|
||||||
|
|
||||||
if (debugvals) {
|
|
||||||
batch.color = Color.CHARTREUSE
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "Inv", 350f, 10f)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// render menu while visible
|
|
||||||
/*if (currentScreenTransition < 1f - epsilon) {
|
|
||||||
renderScreenGamemenu(batch, camera)
|
|
||||||
|
|
||||||
if (debugvals) {
|
|
||||||
batch.color = Color.SKY
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "Men", 400f, 10f)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*if (debugvals) {
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "minimap:$minimapScrOffX", 500f, 0f)
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "inven:$inventoryScrOffX", 500f, 10f)
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "menu:$menuScrOffX", 500f, 20f)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val epsilon = 0.001f
|
|
||||||
|
|
||||||
/**
|
|
||||||
* - 0 on inventory screen
|
|
||||||
* - +WIDTH on minimap screen
|
|
||||||
* - -WIDTH on gamemenu screen
|
|
||||||
*/
|
|
||||||
/*private val minimapScrOffX: Float
|
|
||||||
get() = (currentScreenTransition - 2f) * AppLoader.screenW / 2f
|
|
||||||
private val inventoryScrOffX: Float
|
|
||||||
get() = (currentScreenTransition - 1f) * AppLoader.screenW / 2f
|
|
||||||
private val menuScrOffX: Float
|
|
||||||
get() = (currentScreenTransition - 0f) * AppLoader.screenW / 2f
|
|
||||||
|
|
||||||
private val minimapScrOpacity: Float
|
|
||||||
get() = (currentScreenTransition - 2f).coerceIn(0f, 1f)
|
|
||||||
private val inventoryScrOpacity: Float
|
|
||||||
get() = (currentScreenTransition - 1f).coerceIn(0f, 1f)
|
|
||||||
private val menuScrOpacity: Float
|
|
||||||
get() = (currentScreenTransition - 0f).coerceIn(0f, 1f)*/
|
|
||||||
|
|
||||||
//private val MINIMAP_WIDTH = 800f
|
|
||||||
//private val MINIMAP_HEIGHT = itemList.height.toFloat()
|
|
||||||
//private val MINIMAP_SKYCOL = Color(0x88bbddff.toInt())
|
|
||||||
//private var minimapZoom = 1f
|
|
||||||
//private var minimapPanX = -MinimapComposer.totalWidth / 2f
|
|
||||||
//private var minimapPanY = -MinimapComposer.totalHeight / 2f
|
|
||||||
//private val MINIMAP_ZOOM_MIN = 0.5f
|
|
||||||
//private val MINIMAP_ZOOM_MAX = 8f
|
|
||||||
//private val minimapFBO = FrameBuffer(Pixmap.Format.RGBA8888, MINIMAP_WIDTH.toInt(), MINIMAP_HEIGHT.toInt(), false)
|
|
||||||
//private val minimapCamera = OrthographicCamera(MINIMAP_WIDTH, MINIMAP_HEIGHT)
|
|
||||||
|
|
||||||
|
|
||||||
// TODO put 3 bare sub-UIs into proper UIcanvas to handle the motherfucking opacity
|
|
||||||
|
|
||||||
// TODO not yet refactored
|
|
||||||
/*private fun renderScreenMinimap(batch: SpriteBatch, camera: Camera) {
|
|
||||||
blendNormal(batch)
|
|
||||||
|
|
||||||
// update map panning
|
|
||||||
if (currentScreenTransition >= 2f - epsilon) {
|
|
||||||
// if left click is down and cursor is in the map area
|
|
||||||
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) &&
|
|
||||||
Terrarum.mouseScreenY in itemList.posY..itemList.posY + itemList.height) {
|
|
||||||
minimapPanX += Terrarum.mouseDeltaX / minimapZoom
|
|
||||||
minimapPanY += Terrarum.mouseDeltaY / minimapZoom
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (Gdx.input.isKeyPressed(Input.Keys.NUM_1)) {
|
|
||||||
minimapZoom *= (1f / 1.02f)
|
|
||||||
}
|
|
||||||
if (Gdx.input.isKeyPressed(Input.Keys.NUM_2)) {
|
|
||||||
minimapZoom *= 1.02f
|
|
||||||
}
|
|
||||||
if (Gdx.input.isKeyPressed(Input.Keys.NUM_3)) {
|
|
||||||
minimapZoom = 1f
|
|
||||||
minimapPanX = -MinimapComposer.totalWidth / 2f
|
|
||||||
minimapPanY = -MinimapComposer.totalHeight / 2f
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
//minimapPanX = minimapPanX.coerceIn(-(MinimapComposer.totalWidth * minimapZoom) + MINIMAP_WIDTH, 0f) // un-comment this line to constain the panning over x-axis
|
|
||||||
} catch (e: IllegalArgumentException) { }
|
|
||||||
try {
|
|
||||||
//minimapPanY = minimapPanY.coerceIn(-(MinimapComposer.totalHeight * minimapZoom) + MINIMAP_HEIGHT, 0f)
|
|
||||||
} catch (e: IllegalArgumentException) { }
|
|
||||||
minimapZoom = minimapZoom.coerceIn(MINIMAP_ZOOM_MIN, MINIMAP_ZOOM_MAX)
|
|
||||||
|
|
||||||
|
|
||||||
// make image to roll over for x-axis. This is for the ROUNDWORLD implementation, feel free to remove below.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// render minimap
|
|
||||||
batch.end()
|
|
||||||
|
|
||||||
if (minimapRerenderTimer >= minimapRerenderInterval) {
|
|
||||||
minimapRerenderTimer = 0f
|
|
||||||
MinimapComposer.requestRender()
|
|
||||||
}
|
|
||||||
|
|
||||||
MinimapComposer.renderToBackground()
|
|
||||||
|
|
||||||
minimapFBO.inAction(minimapCamera, batch) {
|
|
||||||
// whatever.
|
|
||||||
MinimapComposer.tempTex.dispose()
|
|
||||||
MinimapComposer.tempTex = Texture(MinimapComposer.minimap)
|
|
||||||
MinimapComposer.tempTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest)
|
|
||||||
|
|
||||||
batch.inUse {
|
|
||||||
|
|
||||||
// [ 1 0 0 ] [ s 0 0 ] [ s 0 0 ]
|
|
||||||
// [ 0 1 0 ] x [ 0 s 0 ] = [ 0 s 0 ]
|
|
||||||
// [ px py 1 ] [ w/2 h/2 1 ] [ tx ty 1 ]
|
|
||||||
//
|
|
||||||
// https://www.wolframalpha.com/input/?i=%7B%7B1,0,0%7D,%7B0,1,0%7D,%7Bp_x,p_y,1%7D%7D+*+%7B%7Bs,0,0%7D,%7B0,s,0%7D,%7Bw%2F2,h%2F2,1%7D%7D
|
|
||||||
|
|
||||||
val tx = minimapPanX * minimapZoom + 0.5f * MINIMAP_WIDTH
|
|
||||||
val ty = minimapPanY * minimapZoom + 0.5f * MINIMAP_HEIGHT
|
|
||||||
|
|
||||||
// sky background
|
|
||||||
batch.color = MINIMAP_SKYCOL
|
|
||||||
batch.fillRect(0f, 0f, MINIMAP_WIDTH, MINIMAP_HEIGHT)
|
|
||||||
// the actual image
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
batch.draw(MinimapComposer.tempTex, tx, ty + MinimapComposer.totalHeight * minimapZoom, MinimapComposer.totalWidth * minimapZoom, -MinimapComposer.totalHeight * minimapZoom)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
batch.begin()
|
|
||||||
|
|
||||||
if (debugvals) {
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", minimapScrOffX + (AppLoader.screenW - MINIMAP_WIDTH) / 2, -10f + itemList.posY)
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.projectionMatrix = camera.combined
|
|
||||||
// 1px stroke
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
batch.fillRect(-1 + minimapScrOffX + (AppLoader.screenW - MINIMAP_WIDTH) / 2, -1 + itemList.posY.toFloat(), 2 + MINIMAP_WIDTH, 2 + MINIMAP_HEIGHT)
|
|
||||||
|
|
||||||
// control hints
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
AppLoader.fontGame.draw(batch, minimapControlHelp, offsetX + minimapScrOffX, yEnd - 20)
|
|
||||||
|
|
||||||
// the minimap
|
|
||||||
batch.draw(minimapFBO.colorBufferTexture, minimapScrOffX + (AppLoader.screenW - MINIMAP_WIDTH) / 2, itemList.posY.toFloat())
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// TODO not yet refactored
|
|
||||||
/*private fun renderScreenGamemenu(batch: SpriteBatch, camera: Camera) {
|
|
||||||
// control hints
|
|
||||||
blendNormal(batch)
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
AppLoader.fontGame.draw(batch, gameMenuControlHelp, offsetX + menuScrOffX, yEnd - 20)
|
|
||||||
|
|
||||||
// text buttons
|
|
||||||
gameMenuButtons.posX = gameMenuButtons.initialX + menuScrOffX.roundToInt()
|
|
||||||
gameMenuButtons.render(batch, camera)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// TODO refactoring wip
|
|
||||||
/*private fun renderScreenInventory(batch: SpriteBatch, camera: Camera) {
|
|
||||||
itemList.posX = itemList.initialX + inventoryScrOffX.roundToInt()
|
|
||||||
itemList.render(batch, camera)
|
|
||||||
equipped.posX = equipped.initialX + inventoryScrOffX.roundToInt()
|
|
||||||
equipped.render(batch, camera)
|
|
||||||
|
|
||||||
|
|
||||||
// control hints
|
|
||||||
val controlHintXPos = offsetX + inventoryScrOffX
|
|
||||||
blendNormal(batch)
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
AppLoader.fontGame.draw(batch, listControlHelp, controlHintXPos, yEnd - 20)
|
|
||||||
|
|
||||||
|
|
||||||
// encumbrance meter
|
|
||||||
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
|
|
||||||
// encumbrance bar will go one row down if control help message is too long
|
|
||||||
val encumbBarXPos = xEnd - weightBarWidth + inventoryScrOffX
|
|
||||||
val encumbBarTextXPos = encumbBarXPos - 6 - AppLoader.fontGame.getWidth(encumbranceText)
|
|
||||||
val encumbBarYPos = yEnd-20 + 3f +
|
|
||||||
if (AppLoader.fontGame.getWidth(listControlHelp) + 2 + controlHintXPos >= encumbBarTextXPos)
|
|
||||||
AppLoader.fontGame.lineHeight
|
|
||||||
else 0f
|
|
||||||
|
|
||||||
AppLoader.fontGame.draw(batch,
|
|
||||||
encumbranceText,
|
|
||||||
encumbBarTextXPos,
|
|
||||||
encumbBarYPos - 3f
|
|
||||||
)
|
|
||||||
|
|
||||||
// encumbrance bar background
|
|
||||||
blendNormal(batch)
|
|
||||||
val encumbCol = UIItemInventoryCellCommonRes.getHealthMeterColour(1f - encumbrancePerc, 0f, 1f)
|
|
||||||
val encumbBack = encumbCol mul UIItemInventoryCellCommonRes.meterBackDarkening
|
|
||||||
batch.color = encumbBack
|
|
||||||
batch.fillRect(
|
|
||||||
encumbBarXPos, encumbBarYPos,
|
|
||||||
weightBarWidth, controlHelpHeight - 6f
|
|
||||||
)
|
|
||||||
// encumbrance bar
|
|
||||||
batch.color = encumbCol
|
|
||||||
batch.fillRect(
|
|
||||||
encumbBarXPos, encumbBarYPos,
|
|
||||||
if (actor.inventory.capacityMode == CAPACITY_MODE_NO_ENCUMBER)
|
|
||||||
1f
|
|
||||||
else // make sure 1px is always be seen
|
|
||||||
minOf(weightBarWidth, maxOf(1f, weightBarWidth * encumbrancePerc)),
|
|
||||||
controlHelpHeight - 6f
|
|
||||||
)
|
|
||||||
// debug text
|
|
||||||
batch.color = Color.LIGHT_GRAY
|
|
||||||
if (IS_DEVELOPMENT_BUILD) {
|
|
||||||
AppLoader.fontSmallNumbers.draw(batch,
|
|
||||||
"${actor.inventory.capacity}/${actor.inventory.maxCapacity}",
|
|
||||||
encumbBarTextXPos,
|
|
||||||
encumbBarYPos + controlHelpHeight - 4f
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
fun rebuildList() {
|
fun rebuildList() {
|
||||||
transitionalItemCells.rebuildList()
|
transitionalItemCells.rebuildList()
|
||||||
}
|
}
|
||||||
|
|||||||
146
src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt
Normal file
146
src/net/torvald/terrarum/modulebasegame/ui/UIInventoryMinimap.kt
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.Input
|
||||||
|
import com.badlogic.gdx.graphics.*
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.blockstats.MinimapComposer
|
||||||
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
|
|
||||||
|
class UIInventoryMinimap(val full: UIInventoryFull) : UICanvas() {
|
||||||
|
|
||||||
|
private val debugvals = true
|
||||||
|
|
||||||
|
override var width: Int = AppLoader.screenW
|
||||||
|
override var height: Int = AppLoader.screenH
|
||||||
|
override var openCloseTime = 0.0f
|
||||||
|
|
||||||
|
private val MINIMAP_WIDTH = 800f
|
||||||
|
private val MINIMAP_HEIGHT = full.INVENTORY_CELLS_UI_HEIGHT.toFloat()
|
||||||
|
private val MINIMAP_SKYCOL = Color(0x88bbddff.toInt())
|
||||||
|
private var minimapZoom = 1f
|
||||||
|
private var minimapPanX = -MinimapComposer.totalWidth / 2f
|
||||||
|
private var minimapPanY = -MinimapComposer.totalHeight / 2f
|
||||||
|
private val MINIMAP_ZOOM_MIN = 0.5f
|
||||||
|
private val MINIMAP_ZOOM_MAX = 8f
|
||||||
|
private val minimapFBO = FrameBuffer(Pixmap.Format.RGBA8888, MINIMAP_WIDTH.toInt(), MINIMAP_HEIGHT.toInt(), false)
|
||||||
|
private val minimapCamera = OrthographicCamera(MINIMAP_WIDTH, MINIMAP_HEIGHT)
|
||||||
|
|
||||||
|
private var minimapRerenderTimer = 0f
|
||||||
|
private val minimapRerenderInterval = .5f
|
||||||
|
|
||||||
|
override fun updateUI(delta: Float) {
|
||||||
|
MinimapComposer.setWorld(Terrarum.ingame!!.world)
|
||||||
|
MinimapComposer.update()
|
||||||
|
minimapRerenderTimer += Gdx.graphics.rawDeltaTime
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
|
blendNormal(batch)
|
||||||
|
|
||||||
|
// update map panning
|
||||||
|
// if left click is down and cursor is in the map area
|
||||||
|
if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) &&
|
||||||
|
Terrarum.mouseScreenY in full.INVENTORY_CELLS_OFFSET_Y..full.INVENTORY_CELLS_OFFSET_Y + full.INVENTORY_CELLS_UI_HEIGHT) {
|
||||||
|
minimapPanX += Terrarum.mouseDeltaX * 2f / minimapZoom
|
||||||
|
minimapPanY += Terrarum.mouseDeltaY * 2f / minimapZoom
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Gdx.input.isKeyPressed(Input.Keys.NUM_1)) {
|
||||||
|
minimapZoom *= (1f / 1.02f)
|
||||||
|
}
|
||||||
|
if (Gdx.input.isKeyPressed(Input.Keys.NUM_2)) {
|
||||||
|
minimapZoom *= 1.02f
|
||||||
|
}
|
||||||
|
if (Gdx.input.isKeyPressed(Input.Keys.NUM_3)) {
|
||||||
|
minimapZoom = 1f
|
||||||
|
minimapPanX = -MinimapComposer.totalWidth / 2f
|
||||||
|
minimapPanY = -MinimapComposer.totalHeight / 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
//minimapPanX = minimapPanX.coerceIn(-(MinimapComposer.totalWidth * minimapZoom) + MINIMAP_WIDTH, 0f) // un-comment this line to constain the panning over x-axis
|
||||||
|
} catch (e: IllegalArgumentException) { }
|
||||||
|
try {
|
||||||
|
//minimapPanY = minimapPanY.coerceIn(-(MinimapComposer.totalHeight * minimapZoom) + MINIMAP_HEIGHT, 0f)
|
||||||
|
} catch (e: IllegalArgumentException) { }
|
||||||
|
minimapZoom = minimapZoom.coerceIn(MINIMAP_ZOOM_MIN, MINIMAP_ZOOM_MAX)
|
||||||
|
|
||||||
|
|
||||||
|
// make image to roll over for x-axis. This is for the ROUNDWORLD implementation, feel free to remove below.
|
||||||
|
|
||||||
|
|
||||||
|
// render minimap
|
||||||
|
batch.end()
|
||||||
|
|
||||||
|
if (minimapRerenderTimer >= minimapRerenderInterval) {
|
||||||
|
minimapRerenderTimer = 0f
|
||||||
|
MinimapComposer.requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
MinimapComposer.renderToBackground()
|
||||||
|
|
||||||
|
minimapFBO.inAction(minimapCamera, batch) {
|
||||||
|
// whatever.
|
||||||
|
MinimapComposer.tempTex.dispose()
|
||||||
|
MinimapComposer.tempTex = Texture(MinimapComposer.minimap)
|
||||||
|
MinimapComposer.tempTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Nearest)
|
||||||
|
|
||||||
|
batch.inUse {
|
||||||
|
|
||||||
|
// [ 1 0 0 ] [ s 0 0 ] [ s 0 0 ]
|
||||||
|
// [ 0 1 0 ] x [ 0 s 0 ] = [ 0 s 0 ]
|
||||||
|
// [ px py 1 ] [ w/2 h/2 1 ] [ tx ty 1 ]
|
||||||
|
//
|
||||||
|
// https://www.wolframalpha.com/input/?i=%7B%7B1,0,0%7D,%7B0,1,0%7D,%7Bp_x,p_y,1%7D%7D+*+%7B%7Bs,0,0%7D,%7B0,s,0%7D,%7Bw%2F2,h%2F2,1%7D%7D
|
||||||
|
|
||||||
|
val tx = minimapPanX * minimapZoom + 0.5f * MINIMAP_WIDTH
|
||||||
|
val ty = minimapPanY * minimapZoom + 0.5f * MINIMAP_HEIGHT
|
||||||
|
|
||||||
|
// sky background
|
||||||
|
batch.color = MINIMAP_SKYCOL
|
||||||
|
batch.fillRect(0f, 0f, MINIMAP_WIDTH, MINIMAP_HEIGHT)
|
||||||
|
// the actual image
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
batch.draw(MinimapComposer.tempTex, tx, ty + MinimapComposer.totalHeight * minimapZoom, MinimapComposer.totalWidth * minimapZoom, -MinimapComposer.totalHeight * minimapZoom)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
batch.begin()
|
||||||
|
|
||||||
|
if (debugvals) {
|
||||||
|
AppLoader.fontSmallNumbers.draw(batch, "$minimapPanX, $minimapPanY; x$minimapZoom", (AppLoader.screenW - MINIMAP_WIDTH) / 2, -10f + full.INVENTORY_CELLS_OFFSET_Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
// 1px stroke
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
batch.fillRect((AppLoader.screenW - MINIMAP_WIDTH) / 2, -1 + full.INVENTORY_CELLS_OFFSET_Y.toFloat(), MINIMAP_WIDTH, 1f)
|
||||||
|
batch.fillRect((AppLoader.screenW - MINIMAP_WIDTH) / 2, full.INVENTORY_CELLS_OFFSET_Y + MINIMAP_HEIGHT, MINIMAP_WIDTH, 1f)
|
||||||
|
batch.fillRect(-1 + (AppLoader.screenW - MINIMAP_WIDTH) / 2, full.INVENTORY_CELLS_OFFSET_Y.toFloat(), 1f, MINIMAP_HEIGHT)
|
||||||
|
batch.fillRect((AppLoader.screenW - MINIMAP_WIDTH) / 2 + MINIMAP_WIDTH, full.INVENTORY_CELLS_OFFSET_Y.toFloat(), 1f, MINIMAP_HEIGHT)
|
||||||
|
|
||||||
|
// control hints
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
AppLoader.fontGame.draw(batch, full.minimapControlHelp, full.offsetX, full.yEnd - 20)
|
||||||
|
|
||||||
|
// the minimap
|
||||||
|
batch.draw(minimapFBO.colorBufferTexture, (AppLoader.screenW - MINIMAP_WIDTH) / 2, full.INVENTORY_CELLS_OFFSET_Y.toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doOpening(delta: Float) {}
|
||||||
|
|
||||||
|
override fun doClosing(delta: Float) {}
|
||||||
|
|
||||||
|
override fun endOpening(delta: Float) {}
|
||||||
|
|
||||||
|
override fun endClosing(delta: Float) {}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
minimapFBO.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -353,7 +353,7 @@ class UIItemInventoryDynamicList(
|
|||||||
inventorySortList.sortBy { ItemCodex[it.item]!!.name }
|
inventorySortList.sortBy { ItemCodex[it.item]!!.name }
|
||||||
|
|
||||||
// map sortList to item list
|
// map sortList to item list
|
||||||
for (k in 0 until items.size) {
|
for (k in items.indices) {
|
||||||
// we have an item
|
// we have an item
|
||||||
try {
|
try {
|
||||||
val sortListItem = inventorySortList[k + itemPage * items.size]
|
val sortListItem = inventorySortList[k + itemPage * items.size]
|
||||||
@@ -372,7 +372,7 @@ class UIItemInventoryDynamicList(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set equippedslot number
|
// set equippedslot number
|
||||||
for (eq in 0 until inventory.itemEquipped.size) {
|
for (eq in inventory.itemEquipped.indices) {
|
||||||
if (eq < inventory.itemEquipped.size) {
|
if (eq < inventory.itemEquipped.size) {
|
||||||
if (inventory.itemEquipped[eq] == items[k].item?.dynamicID) {
|
if (inventory.itemEquipped[eq] == items[k].item?.dynamicID) {
|
||||||
items[k].equippedSlot = eq
|
items[k].equippedSlot = eq
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class UIItemInventoryEquippedView(
|
|||||||
// sort by equip position
|
// sort by equip position
|
||||||
|
|
||||||
// fill the grid from fastest index, make no gap in-between of slots
|
// fill the grid from fastest index, make no gap in-between of slots
|
||||||
for (k in 0 until itemGrid.size) {
|
for (k in itemGrid.indices) {
|
||||||
val item = inventory.itemEquipped[k]
|
val item = inventory.itemEquipped[k]
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas() {
|
|||||||
watchFont.draw(batch, worldTime.getDayNameShort().toUpperCase(), 73f, 7f)
|
watchFont.draw(batch, worldTime.getDayNameShort().toUpperCase(), 73f, 7f)
|
||||||
|
|
||||||
// day
|
// day
|
||||||
watchFont.draw(batch, worldTime.days.toString().padStart(2, '@'), 107f, 7f)
|
watchFont.draw(batch, worldTime.calendarDay.toString().padStart(2, '@'), 107f, 7f)
|
||||||
|
|
||||||
// hour
|
// hour
|
||||||
watchFont.draw(batch, worldTime.hours.toString().padStart(2, '@'), 27f, 7f)
|
watchFont.draw(batch, worldTime.hours.toString().padStart(2, '@'), 27f, 7f)
|
||||||
@@ -84,7 +84,7 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas() {
|
|||||||
watchFont.draw(batch, worldTime.minutes.toString().padStart(2, '0'), 49f, 7f)
|
watchFont.draw(batch, worldTime.minutes.toString().padStart(2, '0'), 49f, 7f)
|
||||||
|
|
||||||
// season marker
|
// season marker
|
||||||
batch.draw(atlas.get(1, worldTime.months - 1), 0f, 0f)
|
batch.draw(atlas.get(1, worldTime.calendarMonth - 1), 0f, 0f)
|
||||||
|
|
||||||
|
|
||||||
// moon dial
|
// moon dial
|
||||||
|
|||||||
@@ -300,13 +300,13 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
var mixFrom: String?
|
var mixFrom: String?
|
||||||
try { mixFrom = JSON.get("mixFrom").asJsonPrimitive.asString }
|
try { mixFrom = JSON.get("mixFrom").asJsonPrimitive.asString }
|
||||||
catch (e: IllegalStateException) { mixFrom = null }
|
catch (e: NullPointerException) { mixFrom = null }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var mixPercentage: Double?
|
var mixPercentage: Double?
|
||||||
try { mixPercentage = JSON.get("mixPercentage").asJsonPrimitive.asDouble }
|
try { mixPercentage = JSON.get("mixPercentage").asJsonPrimitive.asDouble }
|
||||||
catch (e: IllegalStateException) { mixPercentage = null }
|
catch (e: NullPointerException) { mixPercentage = null }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,21 +23,13 @@ class Biomegen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
|
|||||||
|
|
||||||
private val genSlices = maxOf(ThreadExecutor.threadCount, world.width / 8)
|
private val genSlices = maxOf(ThreadExecutor.threadCount, world.width / 8)
|
||||||
|
|
||||||
private var genFutures: Array<Future<*>?> = arrayOfNulls(genSlices)
|
|
||||||
override var generationStarted: Boolean = false
|
|
||||||
override val generationDone: Boolean
|
|
||||||
get() = generationStarted && genFutures.fold(true) { acc, f -> acc and (f?.isDone ?: true) }
|
|
||||||
|
|
||||||
private val YHEIGHT_MAGIC = 2800.0 / 3.0
|
private val YHEIGHT_MAGIC = 2800.0 / 3.0
|
||||||
private val YHEIGHT_DIVISOR = 2.0 / 7.0
|
private val YHEIGHT_DIVISOR = 2.0 / 7.0
|
||||||
|
|
||||||
override fun run() {
|
override fun getDone() {
|
||||||
|
|
||||||
generationStarted = true
|
|
||||||
|
|
||||||
ThreadExecutor.renew()
|
ThreadExecutor.renew()
|
||||||
(0 until world.width).sliceEvenly(genSlices).mapIndexed { i, xs ->
|
(0 until world.width).sliceEvenly(genSlices).map { xs ->
|
||||||
genFutures[i] = ThreadExecutor.submit {
|
ThreadExecutor.submit {
|
||||||
val localJoise = getGenerator(seed, params as BiomegenParams)
|
val localJoise = getGenerator(seed, params as BiomegenParams)
|
||||||
for (x in xs) {
|
for (x in xs) {
|
||||||
for (y in 0 until world.height) {
|
for (y in 0 until world.height) {
|
||||||
|
|||||||
@@ -20,33 +20,28 @@ class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
|
|||||||
|
|
||||||
private val genSlices = maxOf(ThreadExecutor.threadCount, world.width / 8)
|
private val genSlices = maxOf(ThreadExecutor.threadCount, world.width / 8)
|
||||||
|
|
||||||
private var genFutures: Array<Future<*>?> = arrayOfNulls(genSlices)
|
|
||||||
override var generationStarted: Boolean = false
|
|
||||||
override val generationDone: Boolean
|
|
||||||
get() = generationStarted && genFutures.fold(true) { acc, f -> acc and (f?.isDone ?: true) }
|
|
||||||
|
|
||||||
private val YHEIGHT_MAGIC = 2800.0 / 3.0
|
private val YHEIGHT_MAGIC = 2800.0 / 3.0
|
||||||
private val YHEIGHT_DIVISOR = 2.0 / 7.0
|
private val YHEIGHT_DIVISOR = 2.0 / 7.0
|
||||||
|
|
||||||
override fun run() {
|
override fun getDone() {
|
||||||
|
|
||||||
generationStarted = true
|
|
||||||
|
|
||||||
ThreadExecutor.renew()
|
ThreadExecutor.renew()
|
||||||
(0 until world.width).sliceEvenly(genSlices).mapIndexed { i, xs ->
|
(0 until world.width).sliceEvenly(genSlices).mapIndexed { i, xs ->
|
||||||
genFutures[i] = ThreadExecutor.submit {
|
ThreadExecutor.submit {
|
||||||
val localJoise = getGenerator(seed, params as TerragenParams)
|
val localJoise = getGenerator(seed, params as TerragenParams)
|
||||||
for (x in xs) {
|
val localLock = java.lang.Object() // in an attempt to fix the "premature exit" issue of a thread run
|
||||||
for (y in 0 until world.height) {
|
synchronized(localLock) { // also see: https://stackoverflow.com/questions/28818494/threads-stopping-prematurely-for-certain-values
|
||||||
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
for (x in xs) {
|
||||||
val sampleOffset = world.width / 8.0
|
for (y in 0 until world.height) {
|
||||||
val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
|
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||||
val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
|
val sampleOffset = world.width / 8.0
|
||||||
val sampleY = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
|
||||||
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
|
||||||
val noise = localJoise.map { it.get(sampleX, sampleY, sampleZ) }
|
val sampleY = y - (world.height - YHEIGHT_MAGIC) * YHEIGHT_DIVISOR // Q&D offsetting to make ratio of sky:ground to be constant
|
||||||
|
// DEBUG NOTE: it is the OFFSET FROM THE IDEAL VALUE (observed land height - (HEIGHT * DIVISOR)) that must be constant
|
||||||
|
val noise = localJoise.map { it.get(sampleX, sampleY, sampleZ) }
|
||||||
|
|
||||||
draw(x, y, noise, world)
|
draw(x, y, noise, world)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.worldgenerator
|
|||||||
import net.torvald.terrarum.AppLoader
|
import net.torvald.terrarum.AppLoader
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New world generator.
|
* New world generator.
|
||||||
@@ -34,7 +35,7 @@ object Worldgen {
|
|||||||
val it = jobs[i]
|
val it = jobs[i]
|
||||||
|
|
||||||
AppLoader.getLoadScreen().addMessage(it.loadingScreenName)
|
AppLoader.getLoadScreen().addMessage(it.loadingScreenName)
|
||||||
it.theWork.run()
|
it.theWork.getDone()
|
||||||
}
|
}
|
||||||
|
|
||||||
printdbg(this, "Generation job finished")
|
printdbg(this, "Generation job finished")
|
||||||
@@ -46,9 +47,7 @@ object Worldgen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class Gen(val world: GameWorld, val seed: Long, val params: Any) {
|
abstract class Gen(val world: GameWorld, val seed: Long, val params: Any) {
|
||||||
abstract var generationStarted: Boolean
|
open fun getDone() { } // trying to use different name so that it won't be confused with Runnable or Callable
|
||||||
abstract val generationDone: Boolean
|
|
||||||
open fun run() { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class WorldgenParams(
|
data class WorldgenParams(
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ internal object ReadLayerDataLzma {
|
|||||||
val fluidFills = HashMap<BlockAddress, Float>()
|
val fluidFills = HashMap<BlockAddress, Float>()
|
||||||
|
|
||||||
// parse terrain damages
|
// parse terrain damages
|
||||||
for (c in 0 until payloadBytes["TdMG"]!!.size step 10) {
|
for (c in payloadBytes["TdMG"]!!.indices step 10) {
|
||||||
val bytes = payloadBytes["TdMG"]!!
|
val bytes = payloadBytes["TdMG"]!!
|
||||||
|
|
||||||
val tileAddr = bytes.sliceArray(c..c+5)
|
val tileAddr = bytes.sliceArray(c..c+5)
|
||||||
@@ -164,7 +164,7 @@ internal object ReadLayerDataLzma {
|
|||||||
|
|
||||||
|
|
||||||
// parse wall damages
|
// parse wall damages
|
||||||
for (c in 0 until payloadBytes["WdMG"]!!.size step 10) {
|
for (c in payloadBytes["WdMG"]!!.indices step 10) {
|
||||||
val bytes = payloadBytes["WdMG"]!!
|
val bytes = payloadBytes["WdMG"]!!
|
||||||
|
|
||||||
val tileAddr = bytes.sliceArray(c..c+5)
|
val tileAddr = bytes.sliceArray(c..c+5)
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ internal object ReadLayerDataZip {
|
|||||||
val fluidFills = HashMap<BlockAddress, Float>()
|
val fluidFills = HashMap<BlockAddress, Float>()
|
||||||
|
|
||||||
// parse terrain damages
|
// parse terrain damages
|
||||||
for (c in 0 until payloadBytes["TdMG"]!!.size step 10) {
|
for (c in payloadBytes["TdMG"]!!.indices step 10) {
|
||||||
val bytes = payloadBytes["TdMG"]!!
|
val bytes = payloadBytes["TdMG"]!!
|
||||||
|
|
||||||
val tileAddr = bytes.sliceArray(c..c+5)
|
val tileAddr = bytes.sliceArray(c..c+5)
|
||||||
@@ -165,7 +165,7 @@ internal object ReadLayerDataZip {
|
|||||||
|
|
||||||
|
|
||||||
// parse wall damages
|
// parse wall damages
|
||||||
for (c in 0 until payloadBytes["WdMG"]!!.size step 10) {
|
for (c in payloadBytes["WdMG"]!!.indices step 10) {
|
||||||
val bytes = payloadBytes["WdMG"]!!
|
val bytes = payloadBytes["WdMG"]!!
|
||||||
|
|
||||||
val tileAddr = bytes.sliceArray(c..c+5)
|
val tileAddr = bytes.sliceArray(c..c+5)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class RGBtoXYZBenchmark {
|
|||||||
|
|
||||||
// print out captured data
|
// print out captured data
|
||||||
println("with LUT\tno LUT\tmult")
|
println("with LUT\tno LUT\tmult")
|
||||||
for (i in 0 until timer1.size) {
|
for (i in timer1.indices) {
|
||||||
println("${timer1[i]}\t${timer2[i]}\t${timer1[i].toFloat() / timer2[i]}")
|
println("${timer1[i]}\t${timer2[i]}\t${timer1[i].toFloat() / timer2[i]}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void main() {
|
|||||||
|
|
||||||
val mouseUp: Boolean
|
val mouseUp: Boolean
|
||||||
get() {
|
get() {
|
||||||
for (k in 0 until subUIs.size) {
|
for (k in subUIs.indices) {
|
||||||
val ret2 = subUIs[k].mouseUp
|
val ret2 = subUIs[k].mouseUp
|
||||||
if (ret2) return true
|
if (ret2) return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ internal object BlocksDrawer {
|
|||||||
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
||||||
|
|
||||||
var ret = 0
|
var ret = 0
|
||||||
for (i in 0 until nearbyTiles.size) {
|
for (i in nearbyTiles.indices) {
|
||||||
if (nearbyTiles[i] == mark) {
|
if (nearbyTiles[i] == mark) {
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ internal object BlocksDrawer {
|
|||||||
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getWiringBlocks(it.x, it.y).and(drawWires).toBitOrd() * 16 }
|
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getWiringBlocks(it.x, it.y).and(drawWires).toBitOrd() * 16 }
|
||||||
|
|
||||||
var ret = 0
|
var ret = 0
|
||||||
for (i in 0 until nearbyTiles.size) {
|
for (i in nearbyTiles.indices) {
|
||||||
if (nearbyTiles[i] == wire) {
|
if (nearbyTiles[i] == wire) {
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
}
|
}
|
||||||
@@ -442,7 +442,7 @@ internal object BlocksDrawer {
|
|||||||
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
val nearbyTiles = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) ?: Block.NULL }
|
||||||
|
|
||||||
var ret = 0
|
var ret = 0
|
||||||
for (i in 0 until nearbyTiles.size) {
|
for (i in nearbyTiles.indices) {
|
||||||
if (BlockCodex[nearbyTiles[i]].isSolid) {
|
if (BlockCodex[nearbyTiles[i]].isSolid) {
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
}
|
}
|
||||||
@@ -459,7 +459,7 @@ internal object BlocksDrawer {
|
|||||||
val nearbyTiles = nearbyPos.map { world.getTileFromTerrain(it.x, it.y) ?: Block.NULL }
|
val nearbyTiles = nearbyPos.map { world.getTileFromTerrain(it.x, it.y) ?: Block.NULL }
|
||||||
|
|
||||||
var ret = 0
|
var ret = 0
|
||||||
for (i in 0 until nearbyTiles.size) {
|
for (i in nearbyTiles.indices) {
|
||||||
val fluid = world.getFluid(nearbyPos[i].x, nearbyPos[i].y)
|
val fluid = world.getFluid(nearbyPos[i].x, nearbyPos[i].y)
|
||||||
if (BlockCodex[nearbyTiles[i]].isSolid || (fluid.isFluid() && 0 < CreateTileAtlas.fluidFillToTileLevel(fluid.amount))) {
|
if (BlockCodex[nearbyTiles[i]].isSolid || (fluid.isFluid() && 0 < CreateTileAtlas.fluidFillToTileLevel(fluid.amount))) {
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wipe out lightmap
|
// wipe out lightmap
|
||||||
AppLoader.measureDebugTime("Renderer.Light0") {
|
AppLoader.measureDebugTime("Renderer.LightPrecalc") {
|
||||||
// when disabled, light will "decay out" instead of "instantly out", which can have a cool effect
|
// when disabled, light will "decay out" instead of "instantly out", which can have a cool effect
|
||||||
// but the performance boost is measly 0.1 ms on 6700K
|
// but the performance boost is measly 0.1 ms on 6700K
|
||||||
lightmap.zerofill()
|
lightmap.zerofill()
|
||||||
@@ -224,10 +224,10 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// O((5*9)n) == O(n) where n is a size of the map.
|
// O((5*9)n where n is a size of the map.
|
||||||
// Because of inevitable overlaps on the area, it only works with MAX blend
|
// Because of inevitable overlaps on the area, it only works with MAX blend
|
||||||
|
|
||||||
fun r1() {
|
/*fun or1() {
|
||||||
// Round 1
|
// Round 1
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
for (y in for_y_start - overscan_open..for_y_end) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
for (x in for_x_start - overscan_open..for_x_end) {
|
||||||
@@ -235,7 +235,7 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun r2() {
|
fun or2() {
|
||||||
// Round 2
|
// Round 2
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
for (x in for_x_start - overscan_open..for_x_end) {
|
||||||
@@ -243,7 +243,7 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun r3() {
|
fun or3() {
|
||||||
// Round 3
|
// Round 3
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
for (x in for_x_end + overscan_open downTo for_x_start) {
|
||||||
@@ -251,13 +251,109 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun r4() {
|
fun or4() {
|
||||||
// Round 4
|
// Round 4
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
for (y in for_y_start - overscan_open..for_y_end) {
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
for (x in for_x_end + overscan_open downTo for_x_start) {
|
||||||
calculateAndAssign(lightmap, x, y)
|
calculateAndAssign(lightmap, x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// O((8*2)n) where n is a size of the map.
|
||||||
|
fun r1() {
|
||||||
|
// TODO test non-parallel
|
||||||
|
swipeDiag = false
|
||||||
|
for (line in 1 until LIGHTMAP_HEIGHT - 1) {
|
||||||
|
swipeLight(
|
||||||
|
1, line,
|
||||||
|
LIGHTMAP_WIDTH - 2, line,
|
||||||
|
1, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun r2() {
|
||||||
|
// TODO test non-parallel
|
||||||
|
swipeDiag = false
|
||||||
|
for (line in 1 until LIGHTMAP_WIDTH - 1) {
|
||||||
|
swipeLight(
|
||||||
|
line, 1,
|
||||||
|
line, LIGHTMAP_HEIGHT - 2,
|
||||||
|
0, 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun r3() {
|
||||||
|
// TODO test non-parallel
|
||||||
|
swipeDiag = true
|
||||||
|
/* construct indices such that:
|
||||||
|
56789ABC
|
||||||
|
4 1 w-2
|
||||||
|
3 \---\---+
|
||||||
|
2 \\···\··|
|
||||||
|
1 \\\···\·|
|
||||||
|
0 \\\\···\|
|
||||||
|
h-2 \\\\\---\
|
||||||
|
|
||||||
|
0 (1, h-2) -> (1, h-2)
|
||||||
|
1 (1, h-2-1) -> (2, h-2)
|
||||||
|
2 (1, h-2-2) -> (3, h-2)
|
||||||
|
3 (1, h-2-3) -> (4, h-2)
|
||||||
|
4 (1, 1) -> (5, h-2)
|
||||||
|
|
||||||
|
5 (2, 1) -> (6, h-2)
|
||||||
|
6 (3, 1) -> (7, h-2)
|
||||||
|
7 (4, 1) -> (8, h-2)
|
||||||
|
8 (5, 1) -> (w-2, h-2)
|
||||||
|
|
||||||
|
9 (6, 1) -> (w-2, h-2-1)
|
||||||
|
10 (7, 1) -> (w-2, h-2-2)
|
||||||
|
11 (8, 1) -> (w-2, h-2-3)
|
||||||
|
12 (w-2, 1) -> (w-2, 1)
|
||||||
|
|
||||||
|
number of indices: internal_width + internal_height - 1
|
||||||
|
*/
|
||||||
|
for (i in 0 until LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 5) {
|
||||||
|
swipeLight(
|
||||||
|
maxOf(1, i - LIGHTMAP_HEIGHT + 4), maxOf(1, LIGHTMAP_HEIGHT - 2 - i),
|
||||||
|
minOf(LIGHTMAP_WIDTH - 2, i + 1), minOf(LIGHTMAP_HEIGHT - 2, (LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 5) - i),
|
||||||
|
1, 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun r4() {
|
||||||
|
// TODO test non-parallel
|
||||||
|
swipeDiag = true
|
||||||
|
/*
|
||||||
|
1 w-2
|
||||||
|
/////---/
|
||||||
|
////···/|
|
||||||
|
///···/·|
|
||||||
|
//···/··|
|
||||||
|
h-2 /---/---+
|
||||||
|
d:(1,-1)
|
||||||
|
|
||||||
|
0 (1, 1) -> (1, 1)
|
||||||
|
1 (1, 2) -> (2, 1)
|
||||||
|
2 (1, 3) -> (3, 1)
|
||||||
|
3 (1, 4) -> (4, 1)
|
||||||
|
4 (1, h-2) -> (5, 1)
|
||||||
|
5 (2, h-2) -> (6, 1)
|
||||||
|
6 (3, h-2) -> (7, 1)
|
||||||
|
7 (4, h-2) -> (8, 1)
|
||||||
|
8 (5, h-2) -> (w-2, 1)
|
||||||
|
9 (6, h-2) -> (w-2, 2)
|
||||||
|
10 (7, h-2) -> (w-2, 3)
|
||||||
|
11 (8, h-2) -> (w-2, 4)
|
||||||
|
12 (w-2, h-2) -> (w-2, h-2)
|
||||||
|
*/
|
||||||
|
for (i in 0 until LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 5) {
|
||||||
|
swipeLight(
|
||||||
|
maxOf(1, i - LIGHTMAP_HEIGHT + 4), minOf(LIGHTMAP_HEIGHT - 2, i + 1),
|
||||||
|
minOf(LIGHTMAP_WIDTH - 2, i + 1), maxOf(1, (LIGHTMAP_HEIGHT - 2) - (LIGHTMAP_WIDTH + LIGHTMAP_HEIGHT - 6) + i),
|
||||||
|
1, -1
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -266,7 +362,7 @@ object LightmapRenderer {
|
|||||||
// I was able to pull out 3.5..5.5 ms! With abhorrently many occurrences of segfaults I had to track down...
|
// I was able to pull out 3.5..5.5 ms! With abhorrently many occurrences of segfaults I had to track down...
|
||||||
|
|
||||||
if (!AppLoader.getConfigBoolean("multithreadedlight")) {
|
if (!AppLoader.getConfigBoolean("multithreadedlight")) {
|
||||||
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
AppLoader.measureDebugTime("Renderer.LightRuns") {
|
||||||
|
|
||||||
// To save you from pains:
|
// To save you from pains:
|
||||||
// - Per-channel light updating is actually slower
|
// - Per-channel light updating is actually slower
|
||||||
@@ -275,11 +371,15 @@ object LightmapRenderer {
|
|||||||
// - Multithreading? I have absolutely no idea.
|
// - Multithreading? I have absolutely no idea.
|
||||||
// - If you naively slice the screen (job area) to multithread, the seam will appear.
|
// - If you naively slice the screen (job area) to multithread, the seam will appear.
|
||||||
|
|
||||||
r3();r4();r1();r2();r3();
|
//r3();r4();r1();r2();r3();
|
||||||
|
|
||||||
|
r1();r2();r3();r4()
|
||||||
|
r1();r2();r3();r4()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
||||||
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
AppLoader.measureDebugTime("Renderer.LightRuns") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -522,6 +622,57 @@ object LightmapRenderer {
|
|||||||
// you're doing it wrong, the IF and return statements must be inclusive.
|
// you're doing it wrong, the IF and return statements must be inclusive.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var swipeX = -1
|
||||||
|
private var swipeY = -1
|
||||||
|
private var swipeDiag = false
|
||||||
|
private fun _swipeTask(x: Int, y: Int, x2: Int, y2: Int) {
|
||||||
|
if (x2 < 0 || y2 < 0 || x2 >= LIGHTMAP_WIDTH || y2 >= LIGHTMAP_HEIGHT) return
|
||||||
|
|
||||||
|
_ambientAccumulator.r = _mapLightLevelThis.getR(x, y)
|
||||||
|
_ambientAccumulator.g = _mapLightLevelThis.getG(x, y)
|
||||||
|
_ambientAccumulator.b = _mapLightLevelThis.getB(x, y)
|
||||||
|
_ambientAccumulator.a = _mapLightLevelThis.getA(x, y)
|
||||||
|
|
||||||
|
if (!swipeDiag) {
|
||||||
|
_thisTileOpacity.r = _mapThisTileOpacity.getR(x, y)
|
||||||
|
_thisTileOpacity.g = _mapThisTileOpacity.getG(x, y)
|
||||||
|
_thisTileOpacity.b = _mapThisTileOpacity.getB(x, y)
|
||||||
|
_thisTileOpacity.a = _mapThisTileOpacity.getA(x, y)
|
||||||
|
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_thisTileOpacity2.r = _mapThisTileOpacity2.getR(x, y)
|
||||||
|
_thisTileOpacity2.g = _mapThisTileOpacity2.getG(x, y)
|
||||||
|
_thisTileOpacity2.b = _mapThisTileOpacity2.getB(x, y)
|
||||||
|
_thisTileOpacity2.a = _mapThisTileOpacity2.getA(x, y)
|
||||||
|
_ambientAccumulator.maxAndAssign(darkenColoured(x2, y2, _thisTileOpacity2))
|
||||||
|
}
|
||||||
|
|
||||||
|
_mapLightLevelThis.setVec(x, y, _ambientAccumulator)
|
||||||
|
lightmap.setVec(x, y, _ambientAccumulator)
|
||||||
|
}
|
||||||
|
private fun swipeLight(sx: Int, sy: Int, ex: Int, ey: Int, dx: Int, dy: Int) {
|
||||||
|
swipeX = sx; swipeY = sy
|
||||||
|
while (swipeX*dx <= ex*dx && swipeY*dy <= ey*dy) {
|
||||||
|
// conduct the task #1
|
||||||
|
// spread towards the end
|
||||||
|
_swipeTask(swipeX, swipeY, swipeX-dx, swipeY-dy)
|
||||||
|
|
||||||
|
swipeX += dx
|
||||||
|
swipeY += dy
|
||||||
|
}
|
||||||
|
|
||||||
|
swipeX = ex; swipeY = ey
|
||||||
|
while (swipeX*dx >= sx*dx && swipeY*dy >= sy*dy) {
|
||||||
|
// conduct the task #2
|
||||||
|
// spread towards the start
|
||||||
|
_swipeTask(swipeX, swipeY, swipeX+dx, swipeY+dy)
|
||||||
|
|
||||||
|
swipeX -= dx
|
||||||
|
swipeY -= dy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the light simulation, using main lightmap as one of the input.
|
* Calculates the light simulation, using main lightmap as one of the input.
|
||||||
*/
|
*/
|
||||||
|
|||||||
BIN
work_files/yet_another_lighting.kra
LFS
Normal file
BIN
work_files/yet_another_lighting.kra
LFS
Normal file
Binary file not shown.
BIN
work_files/yet_another_lighting.png
LFS
Normal file
BIN
work_files/yet_another_lighting.png
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user