From ea4c4bdb2bfc431b4229c6b65ff0a0fa82c3e7b5 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Tue, 17 Jan 2017 23:42:25 +0900 Subject: [PATCH] new sunlight and skybox colouring collected from real world measurements (reports TBA) Former-commit-id: 6abaa1e16d0fd7a71f95bd0265809aad9e34a425 Former-commit-id: bb871bd87072f27b9cc29594f9eed615351df5f8 --- src/net/torvald/point/Point2d.kt | 2 + src/net/torvald/terrarum/StateInGame.kt | 14 ++- src/net/torvald/terrarum/StateNoiseTexGen.kt | 4 +- src/net/torvald/terrarum/console/ExportMap.kt | 4 +- .../terrarum/gameactors/ActorWithBody.kt | 23 ++-- .../terrarum/gameactors/HumanoidNPC.kt | 6 + .../gameactors/PlayerBuilderSigrid.kt | 2 +- .../terrarum/gameactors/ai/AILuaAPI.kt | 104 ++++++++++++++++-- .../physicssolver/CollisionSolver.kt | 73 ++++++++---- .../terrarum/mapgenerator/WorldGenerator.kt | 34 +----- .../torvald/terrarum/weather/WeatherMixer.kt | 32 +++--- 11 files changed, 210 insertions(+), 88 deletions(-) diff --git a/src/net/torvald/point/Point2d.kt b/src/net/torvald/point/Point2d.kt index e90f2cefa..0bdfddfba 100644 --- a/src/net/torvald/point/Point2d.kt +++ b/src/net/torvald/point/Point2d.kt @@ -49,6 +49,8 @@ class Point2d(var x: Double, var y: Double) : Cloneable { fun toVector() = Vector2(x, y) + fun copy() = Point2d(x, y) + fun length(other: Point2d) = distSqr(other).sqrt() fun distSqr(other: Point2d) = ((this.x - other.x).sqr() + (this.y - other.y).sqr()) } diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index 8a55a2cf7..e5c5a3a04 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -69,9 +69,6 @@ constructor() : BasicGameState() { internal val player: ActorHumanoid // currently POSSESSED actor :) get() = playableActorDelegate!!.actor - //private var GRADIENT_IMAGE: Image? = null - //private var skyBox: Rectangle? = null - var screenZoom = 1.0f val ZOOM_MAX = 2.0f val ZOOM_MIN = 0.5f @@ -99,7 +96,7 @@ constructor() : BasicGameState() { private val UI_INVENTORY_PLAYER = "uiInventoryPlayer" private val UI_INVENTORY_ANON = "uiInventoryAnon" - val paused: Boolean + var paused: Boolean = false get() = consoleHandler.isOpened @Throws(SlickException::class) @@ -279,7 +276,11 @@ constructor() : BasicGameState() { throw IllegalArgumentException("No such actor in actorContainer: $refid") } + // take care of old delegate + playableActorDelegate!!.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE + // accept new delegate playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid) + playableActorDelegate!!.actor.collisionType = ActorWithBody.COLLISION_KINEMATIC WorldSimulator(world, player, UPDATE_DELTA) } @@ -298,7 +299,8 @@ constructor() : BasicGameState() { blendNormal() - drawSkybox(gwin) + drawSkybox(gwin) // drawing to gwin so that any lights from lamp wont "leak" to the skybox + // e.g. Bright blue light on sunset // make camara work // @@ -306,6 +308,8 @@ constructor() : BasicGameState() { worldG.translate(-MapCamera.x.toFloat(), -MapCamera.y.toFloat()) + blendNormal() + ///////////////////////////// // draw map related stuffs // ///////////////////////////// diff --git a/src/net/torvald/terrarum/StateNoiseTexGen.kt b/src/net/torvald/terrarum/StateNoiseTexGen.kt index 330412ea2..bcee4d08e 100644 --- a/src/net/torvald/terrarum/StateNoiseTexGen.kt +++ b/src/net/torvald/terrarum/StateNoiseTexGen.kt @@ -40,7 +40,7 @@ class StateNoiseTexGen : BasicGameState() { return Joise(ridged_autocorrect) } - private fun noiseSmokyFractal(): Joise { + private fun noiseBrownian(): Joise { val ridged = ModuleFractal() ridged.setType(ModuleFractal.FractalType.FBM) ridged.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC) @@ -114,7 +114,7 @@ class StateNoiseTexGen : BasicGameState() { } fun generateNoiseImage() { - val noiseModule = noiseBillowFractal() // change noise function here + val noiseModule = noiseBrownian() // change noise function here for (y in 0..imagesize - 1) { for (x in 0..imagesize - 1) { diff --git a/src/net/torvald/terrarum/console/ExportMap.kt b/src/net/torvald/terrarum/console/ExportMap.kt index f41a0df28..652e580b3 100644 --- a/src/net/torvald/terrarum/console/ExportMap.kt +++ b/src/net/torvald/terrarum/console/ExportMap.kt @@ -82,8 +82,8 @@ internal object ExportMap : ConsoleCommand { try { RasterWriter.writePNG_RGB( - Terrarum.ingame.world.width, Terrarum.ingame.world.height, mapData, dir + args[1] + ".tga") - Echo("ExportMap: exported to " + args[1] + ".tga") + Terrarum.ingame.world.width, Terrarum.ingame.world.height, mapData, dir + args[1] + ".png") + Echo("ExportMap: exported to " + args[1] + ".png") } catch (e: IOException) { diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index cbdf7b6b4..96712d203 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -100,7 +100,9 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { var scale: Double get() = (actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) * (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0) - set(value) = actorValue.set(AVKey.SCALE, value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)) + set(value) { + actorValue[AVKey.SCALE] = value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0) + } @Transient val MASS_LOWEST = 0.1 // Kilograms /** Apparent mass. Use "avBaseMass" for base mass */ var mass: Double @@ -284,6 +286,10 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { hitboxTranslateY = ty.toDouble() } + fun setPosition(pos: Point2d) = setPosition(pos.x, pos.y) + fun setPosition(pos: Vector2) = setPosition(pos.x, pos.y) + + /** * Set hitbox position from bottom-center point * @param x @@ -291,14 +297,14 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { */ fun setPosition(x: Double, y: Double) { hitbox.setFromWidthHeight( - x - (baseHitboxW / 2 - hitboxTranslateX) * scale, - y - (baseHitboxH - hitboxTranslateY) * scale, + x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale), + y - (baseHitboxH - hitboxTranslateY) * (1 - scale), baseHitboxW * scale, baseHitboxH * scale) nextHitbox.setFromWidthHeight( - x - (baseHitboxW / 2 - hitboxTranslateX) * scale, - y - (baseHitboxH - hitboxTranslateY) * scale, + x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale), + y - (baseHitboxH - hitboxTranslateY) * (1 - scale), baseHitboxW * scale, baseHitboxH * scale) } @@ -1113,9 +1119,12 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { /** * Enumerations that exported to JSON */ - @Transient const val COLLISION_KINEMATIC = 1 // does not displaced by external forces + @Transient const val COLLISION_NOCOLLIDE = 0 + @Transient const val COLLISION_KINEMATIC = 1 // does not displaced by external forces when collided, but it still can move (e.g. player, elevator) @Transient const val COLLISION_DYNAMIC = 2 // displaced by external forces - @Transient const val COLLISION_STATIC = 3 // does not displaced by external forces, target of collision + @Transient const val COLLISION_STATIC = 3 // does not displaced by external forces, target of collision (e.g. nonmoving static obj) + @Transient const val COLLISION_KNOCKBACK_GIVER = 4 // mobs + @Transient const val COLLISION_KNOCKBACK_TAKER = 5 // benevolent NPCs @Transient const val BLEND_NORMAL = 4 @Transient const val BLEND_SCREEN = 5 @Transient const val BLEND_MULTIPLY = 6 diff --git a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt index c31fa8393..35ee3d3ea 100644 --- a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt @@ -30,7 +30,13 @@ open class HumanoidNPC(override val scriptPath: String, born: GameDate) : ActorH private val aiLuaAPI: AILuaAPI + companion object { + val DEFAULT_COLLISION_TYPE = ActorWithBody.COLLISION_DYNAMIC + } + init { + collisionType = DEFAULT_COLLISION_TYPE + luag["io"] = LuaValue.NIL luag["os"] = LuaValue.NIL luag["luajava"] = LuaValue.NIL diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt index addd6ffdb..ec4419913 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt @@ -58,7 +58,7 @@ object PlayerBuilderSigrid { p.actorValue[AVKey.INTELLIGENT] = true - p.actorValue[AVKey.LUMINOSITY] = Color(0x434aff).to10bit() + //p.actorValue[AVKey.LUMINOSITY] = Color(0x434aff).to10bit() p.actorValue[AVKey.BASEDEFENCE] = 141 diff --git a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt index 1bfb16b4d..d62fc4ecd 100644 --- a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt @@ -5,6 +5,7 @@ import net.torvald.terrarum.gameactors.AIControlled import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.mapdrawer.LightmapRenderer +import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.TileCodex import org.luaj.vm2.* import org.luaj.vm2.lib.OneArgFunction @@ -39,6 +40,8 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { g["ai"]["jump"] = Jump(actor) g["ai"]["getNearbyTiles"] = GetNearbyTiles(actor) + g["ai"]["getFloorsHeight"] = GetFloorsHeight(actor) + g["ai"]["getCeilingsHeight"] = GetCeilingsHeight(actor) g["game"] = LuaValue.tableOf() g["game"]["version"] = GameVersion() @@ -87,6 +90,8 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { fun Int?.toLua() = if (this == null) LuaValue.NIL else this.toLua() fun String?.toLua() = if (this == null) LuaValue.NIL else this.toLua() fun Boolean.toInt() = if (this) 1 else 0 + + operator fun LuaTable.set(index: Int, value: Int) { this[index] = value.toLua() } } class GetSelfActorInfo(val actor: ActorWithBody) : ZeroArgFunction() { @@ -215,19 +220,18 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } class GetNearbyTiles(val actor: ActorWithBody) : OneArgFunction() { - - /** @param radius: lookahead + /** @param radius * * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 * - * Index: [-3: y][-3: x] ... [0: y][0: x] ... [3: y][3: x] + * Index: [-3: y][-3: x] ... [0: y][0: x] ... [3: y][3: x] for radius 3 * Return value: bitset (int 0-7) * 1 -- solidity * 2 -- liquidity * 3 -- gravity */ - override fun call(radius: LuaValue): LuaValue { - val radius = radius.checkint() + override fun call(arg: LuaValue): LuaValue { + val radius = arg.checkint() if (radius < 0) { return LuaValue.NONE @@ -248,8 +252,94 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { val gravity = tile.isFallable.toInt() val tileFlag: Int = gravity.shl(2) + liquidity.shl(1) + solidity - luatable[y - feetTilePos[1]][x - feetTilePos[0]] = - LuaInteger.valueOf(tileFlag) + luatable[y - feetTilePos[1]][x - feetTilePos[0]] = tileFlag.toLua() + } + } + + return luatable + } + } + } + + class GetFloorsHeight(val actor: ActorWithBody) : OneArgFunction() { + /** @param radius + * + * 3 will return len:7 array, 0 will return len:1, 1 will return len:3 + * + * Index: [-3] .. [0] .. [3] for radius + * Return value: floor height + * 0: body tile (legs area) + * 1: tile you can stand on + * 2+: tiles down there + */ + override fun call(arg: LuaValue): LuaValue { + val radius = arg.checkint() + + val searchDownLimit = 12 + + if (radius < 0) { + return LuaValue.NONE + } + else if (radius > 8) { + throw IllegalArgumentException("Radius too large -- must be 8 or less") + } + else { + val luatable = LuaTable() + val feetTilePos = actor.feetPosTile + for (x in feetTilePos[0] - radius..feetTilePos[0] + radius) { + // search down + var searchDownCounter = 0 + while (true) { + val tile = Terrarum.ingame.world.getTileFromTerrain(x, feetTilePos[1] + searchDownCounter) ?: Tile.STONE + if (TileCodex[tile].isSolid || searchDownCounter >= searchDownLimit) { + luatable[x - feetTilePos[0]] = searchDownCounter + break + } + searchDownCounter++ + } + } + + return luatable + } + } + } + + class GetCeilingsHeight(val actor: ActorWithBody) : OneArgFunction() { + /** @param radius + * + * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 + * + * Index: [-3] .. [0] .. [3] for radius + * Return value: floor height + * (-1): tile you can stand on + * 0: body tile (legs area) + * 1: body tile (may be vary depend on the size of the actor) + * 2+: tiles up there + */ + override fun call(arg: LuaValue): LuaValue { + val radius = arg.checkint() + + val searchUpLimit = 12 + + if (radius < 0) { + return LuaValue.NONE + } + else if (radius > 8) { + throw IllegalArgumentException("Radius too large -- must be 8 or less") + } + else { + val luatable = LuaTable() + val feetTilePos = actor.feetPosTile + for (x in feetTilePos[0] - radius..feetTilePos[0] + radius) { + // search up + var searchUpCounter = 0 + while (true) { + val tile = Terrarum.ingame.world.getTileFromTerrain(x, feetTilePos[1] - searchUpCounter) ?: Tile.STONE + if (TileCodex[tile].isSolid || searchUpCounter >= searchUpLimit) { + luatable[x - feetTilePos[0]] = searchUpCounter + break + } + searchUpCounter++ } } diff --git a/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt b/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt index 6e5398834..7ad0160fe 100644 --- a/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt +++ b/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt @@ -49,22 +49,26 @@ object CollisionSolver { collListX.sortBy { it.pos } // set candidateX - for (it in collListX) { + collListX.forEach { if (it.kind == STARTPOINT) { collCandidateStack.push(it) } else if (it.kind == ENDPOINT) { val mark_this = it val mark_other = collCandidateStack.pop() - val collCandidate: Pair - if (mark_this < mark_other) // make sure actor with lower pos comes left - collCandidate = Pair(mark_this.actor, mark_other.actor) + // make sure actor with lower ID comes first + val collCandidate = if (mark_this.actor < mark_other.actor) + Pair(mark_this.actor, mark_other.actor) else - collCandidate = Pair(mark_other.actor, mark_this.actor) + Pair(mark_other.actor, mark_this.actor) - collCandidateX.add(collCandidate) + // filter out Pair(E, E); Pair(A, B) if Pair(B, A) exists + if (mark_this.actor != mark_other.actor) { + collCandidateX.add(collCandidate) + } } } + collCandidateStack.clear() // mark list y @@ -78,7 +82,7 @@ object CollisionSolver { collListY.sortBy { it.pos } // set candidateY - for (it in collListY) { + collListY.forEach { if (it.kind == STARTPOINT) { collCandidateStack.push(it) } @@ -86,12 +90,16 @@ object CollisionSolver { val mark_this = it val mark_other = collCandidateStack.pop() val collCandidate: Pair - if (mark_this < mark_other) // make sure actor with lower pos comes left + // make sure actor with lower ID comes first + if (mark_this.actor < mark_other.actor) collCandidate = Pair(mark_this.actor, mark_other.actor) else collCandidate = Pair(mark_other.actor, mark_this.actor) - collCandidateY.add(collCandidate) + // filter out Pair(E, E); Pair(A, B) if Pair(B, A) exists + if (mark_this.actor != mark_other.actor) { + collCandidateY.add(collCandidate) + } } } // look for overlaps in candidate X/Y and put them into collCandidates @@ -99,10 +107,36 @@ object CollisionSolver { collCandidateY.retainAll(collCandidateX) // list Y will have intersection of X and Y now collCandidates = collCandidateY // renaming. X and Y won't be used anyway. + //collCandidates.forEach { println(it) } + //println("-----------------------") + // solve collision for actors in collCandidates collCandidates.forEach { solveCollision(it.first, it.second) } } + private fun pairEqv(a: Pair, b: Pair) = + (a.first == b.first && a.second == b.second) || + (a.first == b.second && a.second == b.first) + + /** Mimics java's original behaviour, with user-defined equals function */ + fun ArrayList.containsByFunc(other: Any?, equalsFun: (a: Any?, b: Any?) -> Boolean): Boolean { + fun indexOfEqFn(arrayList: ArrayList, o: Any?): Int { + if (o == null) { + for (i in 0..size - 1) + if (arrayList[i] == null) + return i + } + else { + for (i in 0..size - 1) + if (equalsFun(o, arrayList[i])) + return i + } + return -1 + } + + return indexOfEqFn(this, other) >= 0 + } + private fun solveCollision(a: ActorWithBody, b: ActorWithBody) { // some of the Pair(a, b) are either duplicates or erroneously reported. // e.g. (A, B), (B, C) and then (A, C); @@ -110,12 +144,12 @@ object CollisionSolver { // we are going to filter them if (a isCollidingWith b) { // notify collision, but not solve it yet - // (e.g. player vs mob, will pass by but still takes damage) + //println("Collision: $a <-> $b") + // FIXME does work but has duplication // if they actually makes collision (e.g. player vs ball), solve it if (a makesCollisionWith b) { - // assuming perfect elastic collision; ignoring 'var elasticity' val ux_1 = a.veloX val ux_2 = b.veloX val uy_1 = a.veloY @@ -136,10 +170,10 @@ object CollisionSolver { } } - private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody): Boolean { - return true - } - + private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody) = + this.collisionType != ActorWithBody.COLLISION_NOCOLLIDE && + other.collisionType != ActorWithBody.COLLISION_NOCOLLIDE + private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean { val ax = this.hitbox.centeredX val ay = this.hitbox.centeredY @@ -168,16 +202,11 @@ object CollisionSolver { fun Double.abs() = if (this < 0) -this else this fun Double.sqr() = this * this - class CollisionMarkings( + data class CollisionMarkings( val pos: Double, val kind: Int, val actor: ActorWithBody - ) : Comparable { - override fun compareTo(other: CollisionMarkings): Int = - if (this.pos > other.pos) 1 - else if (this.pos < other.pos) -1 - else 0 - } + ) /** * === Some useful physics knowledge === diff --git a/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt b/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt index 0b79eb9f1..6c533020b 100644 --- a/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt +++ b/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt @@ -700,45 +700,21 @@ object WorldGenerator { ) } - ThreadParallel.startAll() - // FIXME game starts prematurely - /* Console: - [mapgenerator] Seed: 85336530 - [mapgenerator] Raising and eroding terrain... - [mapgenerator] Shaping world... - [mapgenerator] Carving caves... - [mapgenerator] Carving caves... - [mapgenerator] Carving caves... - [mapgenerator] Flooding bottom lava... - [mapgenerator] Carving caves... - [mapgenerator] Planting grass... - [mapgenerator] Placing floating islands... - [UIHandler] Creating UI 'ConsoleWindow' - Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false - Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 2048x256 - [UIHandler] Creating UI 'BasicDebugInfoWindow' - Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false - Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 2048x1024 - [UIHandler] Creating UI 'Notification' - Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false - Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 512x64 - [mapgenerator] Collapsing caves... - [mapgenerator] Collapsing caves... - [mapgenerator] Collapsing caves... - [mapgenerator] Collapsing caves... - */ + ThreadParallel.startAllWaitForDie() } else { ThreadProcessNoiseLayers(0, HEIGHT - 1, noiseRecords).run() } } + private val islandSpacing = 1024 + private fun generateFloatingIslands() { println("[mapgenerator] Placing floating islands...") val nIslandsMax = Math.round(world.width * 6f / 8192f) val nIslandsMin = Math.max(2, Math.round(world.width * 4f / 8192f)) - val nIslands = random.nextInt(nIslandsMax - nIslandsMin) + nIslandsMin + val nIslands = random.nextInt(Math.max(1, nIslandsMax - nIslandsMin)) + nIslandsMin val prevIndex = -1 val tiles = intArrayOf(Tile.AIR, Tile.STONE, Tile.DIRT, Tile.GRASS) @@ -750,7 +726,7 @@ object WorldGenerator { } val island = FloatingIslandsPreset.generatePreset(currentIndex, random) - val startingPosX = random.nextInt(world.width - 2048) + 1024 + val startingPosX = random.nextInt(islandSpacing) + islandSpacing * i val startingPosY = minimumFloatingIsleHeight + random.nextInt(minimumFloatingIsleHeight) for (j in island.indices) { diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index f5d0b20fd..6efe02529 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -7,6 +7,8 @@ import net.torvald.colourutil.CIEXYZUtil import net.torvald.colourutil.ColourUtil import net.torvald.random.HQRNG import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.blendMul +import net.torvald.terrarum.blendNormal import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.getPixel import org.newdawn.slick.Color @@ -85,26 +87,30 @@ object WeatherMixer { val skyboxColourMap = currentWeather.skyboxGradColourMap val lightColourMap = currentWeather.globalLightColourMap - // draw skybox to provided (should be main) graphics instance - val skyColourFill = GradientFill( - 0f, 0f, - getGradientColour(skyboxColourMap, 0, timeNow), - 0f, Terrarum.HEIGHT.toFloat(),// / Terrarum.ingame.screenZoom, - getGradientColour(skyboxColourMap, 1, timeNow) - ) - g.fill(Rectangle( - 0f, 0f, - Terrarum.WIDTH.toFloat(),// / Terrarum.ingame.screenZoom, - Terrarum.HEIGHT.toFloat()// / Terrarum.ingame.screenZoom - ),skyColourFill) - // calculate global light val gradCol = getGradientColour(lightColourMap, 0, timeNow) globalLightNow.r = gradCol.r globalLightNow.g = gradCol.g globalLightNow.b = gradCol.b + + // draw skybox to provided (should be main) graphics instance + val skyColourFill = GradientFill( + 0f, 0f, + getGradientColour(skyboxColourMap, 0, timeNow) * gradCol, // mul with globallight + 0f, Terrarum.HEIGHT.toFloat(),// / Terrarum.ingame.screenZoom, + getGradientColour(skyboxColourMap, 1, timeNow) * gradCol // mul with globallight + ) + + blendNormal() + g.fill(Rectangle( + 0f, 0f, + Terrarum.WIDTH.toFloat(),// / Terrarum.ingame.screenZoom, + Terrarum.HEIGHT.toFloat()// / Terrarum.ingame.screenZoom + ), skyColourFill) } + operator fun Color.times(other: Color) = Color(this.r * other.r, this.g * other.g, this.b * other.b, 1f) + /** * Get a GL of specific time */