From 1b83e7deb724ab61c152e0d5c69b1d7ea2c5dacb Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Mon, 23 Jan 2017 19:06:12 +0900 Subject: [PATCH] tiles with light level <= 1 will be rendered as black square, phys support for non-self-moving bodies (e.g. balls) Former-commit-id: 5611e2d89f4601e57d014c45f0479600778217f6 Former-commit-id: d900c0733a6d1dcbd9aaed8e9f7f1671c3866624 --- src/com/jme3/math/FastMath.java | 12 ++ src/net/torvald/imagefont/GameFontBase.kt | 2 +- src/net/torvald/terrarum/StateInGame.kt | 77 ++++++++---- .../terrarum/console/SpawnPhysTestBall.kt | 25 +++- .../terrarum/gameactors/ActorHumanoid.kt | 1 + .../terrarum/gameactors/ActorWithSprite.kt | 95 ++++++++------- .../terrarum/gameactors/FixtureBase.kt | 3 +- .../terrarum/gameactors/HistoricalFigure.kt | 2 +- .../terrarum/gameactors/PhysTestBall.kt | 2 +- .../terrarum/mapdrawer/LightmapRenderer.kt | 22 ++-- .../torvald/terrarum/mapdrawer/MapCamera.kt | 8 +- .../torvald/terrarum/mapdrawer/TilesDrawer.kt | 115 ++++++++++-------- .../torvald/terrarum/weather/WeatherMixer.kt | 9 ++ 13 files changed, 236 insertions(+), 137 deletions(-) diff --git a/src/com/jme3/math/FastMath.java b/src/com/jme3/math/FastMath.java index 56b708d49..a0c14659d 100644 --- a/src/com/jme3/math/FastMath.java +++ b/src/com/jme3/math/FastMath.java @@ -851,4 +851,16 @@ final public class FastMath { for (int i = 1; i < f.length; i++) max = (f[i] > max) ? f[i] : max; return max; } + + public static int min(int... f) { + int min = f[0]; + for (int i = 1; i < f.length; i++) min = (f[i] < min) ? f[i] : min; + return min; + } + + public static int max(int... f) { + int max = f[0]; + for (int i = 1; i < f.length; i++) max = (f[i] > max) ? f[i] : max; + return max; + } } diff --git a/src/net/torvald/imagefont/GameFontBase.kt b/src/net/torvald/imagefont/GameFontBase.kt index 2cc7388db..d90bcc0ed 100644 --- a/src/net/torvald/imagefont/GameFontBase.kt +++ b/src/net/torvald/imagefont/GameFontBase.kt @@ -703,7 +703,7 @@ constructor() : Font { Pair(0x14.toChar(), Color(0xFFA0E0)), //f uchsia Pair(0x15.toChar(), Color(0xE0A0FF)), //*m agenta (purple) Pair(0x16.toChar(), Color(0x8080FF)), //*b lue - Pair(0x17.toChar(), Color(0xFF80FF)), //c yan + Pair(0x17.toChar(), Color(0x80FFFF)), //c yan Pair(0x18.toChar(), Color(0x80FF80)), //*g reen Pair(0x19.toChar(), Color(0x008000)), //v iridian Pair(0x1A.toChar(), Color(0x805030)), //x (khaki) diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index dabb4b2ac..75ebdfaf3 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -381,15 +381,35 @@ constructor() : BasicGameState() { actor.hitbox.posX.toFloat(), actor.hitbox.pointedY.toFloat() + 4 ) + } + } + } + // debug physics + if (KeyToggler.isOn(Key.F11)) { + actorContainer.forEachIndexed { i, actor -> + if (actor is ActorWithSprite) { + worldG.color = Color(1f, 0f, 1f, 1f) + worldG.font = Terrarum.fontSmallNumbers + worldG.lineWidth = 1f + worldG.drawRect( + actor.hitbox.posX.toFloat(), + actor.hitbox.posY.toFloat(), + actor.hitbox.width.toFloat(), + actor.hitbox.height.toFloat() + ) - if (DEBUG_ARRAY) { - worldG.color = GameFontBase.codeToCol["g"] - worldG.drawString( - i.toString(), - actor.hitbox.posX.toFloat(), - actor.hitbox.pointedY.toFloat() + 4 + 10 - ) - } + // velocity + worldG.color = Color(0x80FFFF) + worldG.drawString( + "vX ${actor.velocity.x}", // doesn't work for NPCs/Player + actor.hitbox.posX.toFloat(), + actor.hitbox.pointedY.toFloat() + 4 + 8 + ) + worldG.drawString( + "vY ${actor.velocity.y}", + actor.hitbox.posX.toFloat(), + actor.hitbox.pointedY.toFloat() + 4 + 8 * 2 + ) } } } @@ -674,17 +694,30 @@ constructor() : BasicGameState() { * Check for duplicates, append actor and sort the list */ fun addActor(actor: Actor) { - if (hasActor(actor.referenceID)) - throw RuntimeException("Actor with ID ${actor.referenceID} already exists.") - actorContainer.add(actor) - insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor + if (hasActor(actor.referenceID)) { + println("[StateInGame] Replacing actor $actor") + removeActor(actor) + addActor(actor) + } + else { + actorContainer.add(actor) + insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor - if (actor is ActorVisible) { - when (actor.renderOrder) { - ActorOrder.BEHIND -> { actorsRenderBehind.add(actor); insertionSortLastElemAV(actorsRenderBehind) } - ActorOrder.MIDDLE -> { actorsRenderMiddle.add(actor); insertionSortLastElemAV(actorsRenderMiddle) } - ActorOrder.MIDTOP -> { actorsRenderMidTop.add(actor); insertionSortLastElemAV(actorsRenderMidTop) } - ActorOrder.FRONT -> { actorsRenderFront .add(actor); insertionSortLastElemAV(actorsRenderFront ) } + if (actor is ActorVisible) { + when (actor.renderOrder) { + ActorOrder.BEHIND -> { + actorsRenderBehind.add(actor); insertionSortLastElemAV(actorsRenderBehind) + } + ActorOrder.MIDDLE -> { + actorsRenderMiddle.add(actor); insertionSortLastElemAV(actorsRenderMiddle) + } + ActorOrder.MIDTOP -> { + actorsRenderMidTop.add(actor); insertionSortLastElemAV(actorsRenderMidTop) + } + ActorOrder.FRONT -> { + actorsRenderFront.add(actor); insertionSortLastElemAV(actorsRenderFront) + } + } } } } @@ -693,11 +726,6 @@ constructor() : BasicGameState() { particlesContainer.add(particle) } - /** - * Whether the game should display actorContainer elem number when F3 is on - */ - val DEBUG_ARRAY = false - fun getActorByID(ID: Int): Actor { if (actorContainer.size == 0 && actorContainerInactive.size == 0) throw IllegalArgumentException("Actor with ID $ID does not exist.") @@ -743,10 +771,11 @@ constructor() : BasicGameState() { private fun ArrayList.binarySearch(ID: Int): Int { // code from collections/Collections.kt var low = 0 - var high = actorContainer.size - 1 + var high = this.size - 1 while (low <= high) { val mid = (low + high).ushr(1) // safe from overflows + val midVal = get(mid) if (ID > midVal.referenceID) diff --git a/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt b/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt index 1c993d625..4e5ec4afe 100644 --- a/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt +++ b/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt @@ -6,6 +6,7 @@ import net.torvald.terrarum.gameactors.PhysTestBall import net.torvald.terrarum.mapdrawer.TilesDrawer import net.torvald.terrarum.Terrarum import net.torvald.terrarum.mapdrawer.MapCamera +import org.dyn4j.geometry.Vector2 /** * Created by minjaesong on 16-03-05. @@ -13,10 +14,26 @@ import net.torvald.terrarum.mapdrawer.MapCamera internal object SpawnPhysTestBall : ConsoleCommand { @Throws(Exception::class) override fun execute(args: Array) { - if (args.size == 2) { - val mouseX = Terrarum.appgc.input.mouseX - val mouseY = Terrarum.appgc.input.mouseY + val mouseX = Terrarum.appgc.input.mouseX + val mouseY = Terrarum.appgc.input.mouseY + if (args.size >= 3) { + val elasticity = args[1].toDouble() + + val xvel = args[2].toDouble() + val yvel = if (args.size >= 4) args[3].toDouble() else 0.0 + + val ball = PhysTestBall() + ball.setPosition( + (mouseX + MapCamera.x).toDouble(), + (mouseY + MapCamera.y).toDouble() + ) + ball.elasticity = elasticity + ball.applyForce(Vector2(xvel, yvel)) + + Terrarum.ingame.addActor(ball) + } + else if (args.size == 2) { val elasticity = args[1].toDouble() val ball = PhysTestBall() @@ -34,6 +51,6 @@ internal object SpawnPhysTestBall : ConsoleCommand { } override fun printUsage() { - Echo("usage: spawnball [elasticity]") + Echo("usage: spawnball elasticity [x velocity] [y velocity]") } } diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index 2a9aaaf7b..6a658a8f8 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -16,6 +16,7 @@ import java.util.* /** * Humanoid actor class to provide same controlling function (such as work, jump) + * Also applies unreal air friction for movement control * * Created by minjaesong on 16-10-24. */ diff --git a/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt b/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt index 20b84af9d..eee44a3e2 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt @@ -10,6 +10,7 @@ import net.torvald.spriteanimation.SpriteAnimation import net.torvald.terrarum.gamecontroller.Key import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE +import net.torvald.terrarum.mapdrawer.MapCamera import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.TileProp import org.dyn4j.Epsilon @@ -19,17 +20,19 @@ import org.newdawn.slick.GameContainer import org.newdawn.slick.Graphics import org.newdawn.slick.Image import java.util.* +import kotlin.reflect.jvm.internal.impl.resolve.constants.DoubleValue /** * Base class for every actor that has animated sprites. This includes furnishings, paintings, gadgets, etc. * Also has all the physics * * @param renderOrder Rendering order (BEHIND, MIDDLE, MIDTOP, FRONT) - * @param physics + * @param immobileBody use realistic air friction (1/1000 of "unrealistic" canonical setup) + * @param physics use physics simulation * * Created by minjaesong on 16-01-13. */ -open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : ActorVisible(renderOrder) { +open class ActorWithSprite(renderOrder: ActorOrder, val immobileBody: Boolean = false, physics: Boolean = true) : ActorVisible(renderOrder) { /** !! ActorValue macros are on the very bottom of the source !! **/ @@ -343,6 +346,8 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A velocity += acc.times(speedMultByTile) } + private val bounceDampenVelThreshold = 0.5 + override fun update(gc: GameContainer, delta: Int) { if (isUpdate && !flagDespawn) { @@ -388,7 +393,7 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A } setHorizontalFriction() - if (isPlayerNoClip) { // TODO also hanging on the rope, etc. + if (immobileBody || isPlayerNoClip) { // TODO also hanging on the rope, etc. setVerticalFriction() } @@ -424,28 +429,28 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A // decide whether to ignore walkX if (!(isCollidingSide(hitbox, COLLIDING_LEFT) && walkX < 0) || !(isCollidingSide(hitbox, COLLIDING_RIGHT) && walkX > 0) - ) { + ) { moveDelta.x = veloX + walkX } // decide whether to ignore walkY if (!(isCollidingSide(hitbox, COLLIDING_TOP) && walkY < 0) || !(isCollidingSide(hitbox, COLLIDING_BOTTOM) && walkY > 0) - ) { + ) { moveDelta.y = veloY + walkY } } else { if (!isCollidingSide(hitbox, COLLIDING_LEFT) || !isCollidingSide(hitbox, COLLIDING_RIGHT) - ) { + ) { moveDelta.x = veloX } // decide whether to ignore walkY if (!isCollidingSide(hitbox, COLLIDING_TOP) || !isCollidingSide(hitbox, COLLIDING_BOTTOM) - ) { + ) { moveDelta.y = veloY } } @@ -771,6 +776,13 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A return contactAreaCounter } + private fun getTileFriction(tile: Int) = + if (immobileBody && tile == Tile.AIR) + TileCodex[Tile.AIR].friction.frictionToMult().div(1000) + .times(if (!grounded) elasticity else 1.0) + else + TileCodex[tile].friction.frictionToMult() + /** about stopping * for about get moving, see updateMovementControl */ private fun setHorizontalFriction() { @@ -778,7 +790,7 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A BASE_FRICTION * TileCodex[Tile.STONE].friction.frictionToMult() else { // TODO status quo if !submerged else linearBlend(feetFriction, bodyFriction, submergedRatio) - BASE_FRICTION * (if (grounded) feetFriction else bodyFriction).frictionToMult() + BASE_FRICTION * if (grounded) feetFriction else bodyFriction } if (veloX < 0) { @@ -806,7 +818,7 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A val friction = if (isPlayerNoClip) BASE_FRICTION * TileCodex[Tile.STONE].friction.frictionToMult() else - BASE_FRICTION * bodyFriction.frictionToMult() + BASE_FRICTION * bodyFriction if (veloY < 0) { veloY += friction @@ -859,22 +871,24 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A ).toDouble() - internal val bodyFriction: Int + internal val bodyFriction: Double get() { - var friction = 0 - forEachOccupyingTile { // get max friction - if (it?.friction ?: TileCodex[Tile.AIR].friction > friction) - friction = it?.friction ?: TileCodex[Tile.AIR].friction + var friction = 0.0 + forEachOccupyingTileNum { + // get max friction + if (getTileFriction(it ?: Tile.AIR) > friction) + friction = getTileFriction(it ?: Tile.AIR) } return friction } - internal val feetFriction: Int + internal val feetFriction: Double get() { - var friction = 0 - forEachFeetTile { // get max friction - if (it?.friction ?: TileCodex[Tile.AIR].friction > friction) - friction = it?.friction ?: TileCodex[Tile.AIR].friction + var friction = 0.0 + forEachFeetTileNum { + // get max friction + if (getTileFriction(it ?: Tile.AIR) > friction) + friction = getTileFriction(it ?: Tile.AIR) } return friction @@ -885,7 +899,8 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A internal val bodyViscosity: Int get() { var viscosity = 0 - forEachOccupyingTile { // get max viscosity + forEachOccupyingTile { + // get max viscosity if (it?.viscosity ?: 0 > viscosity) viscosity = it?.viscosity ?: 0 } @@ -895,7 +910,8 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A internal val feetViscosity: Int get() { var viscosity = 0 - forEachFeetTile { // get max viscosity + forEachFeetTile { + // get max viscosity if (it?.viscosity ?: 0 > viscosity) viscosity = it?.viscosity ?: 0 } @@ -921,9 +937,9 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A get() { if (!isPlayerNoClip) { val notSubmergedAccel = if (grounded) - feetFriction.frictionToMult() + feetFriction else - bodyFriction.frictionToMult() + bodyFriction val normalisedViscocity = bodyViscosity.viscosityToMult() return interpolateLinear(submergedRatio, notSubmergedAccel, normalisedViscocity) @@ -992,7 +1008,7 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A private fun updateHitbox() = hitbox.reassign(nextHitbox) - override open fun drawGlow(g: Graphics) { + override fun drawGlow(g: Graphics) { if (isVisible && spriteGlow != null) { blendLightenOnly() @@ -1033,25 +1049,12 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A ) } } - - - // debug hitbox - if (KeyToggler.isOn(Key.F11)) { - g.color = Color(1f, 0f, 1f, 1f) - blendNormal() - g.lineWidth = 1f - g.drawRect( - hitbox.posX.toFloat(), - hitbox.posY.toFloat(), - hitbox.width.toFloat(), - hitbox.height.toFloat() - ) - } } - override open fun drawBody(g: Graphics) { - if (isVisible && sprite != null) { + private val halfWorldW = world.width.times(TILE_SIZE).ushr(1) + override fun drawBody(g: Graphics) { + if (isVisible && sprite != null) { when (drawMode) { BLEND_NORMAL -> blendNormal() @@ -1282,7 +1285,9 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A var avBaseScale: Double // use canonical "scale" for apparent scale (base * buff) get() = actorValue.getAsDouble(AVKey.SCALE) ?: 1.0 - set(value) { actorValue[AVKey.SCALE] = value } + set(value) { + actorValue[AVKey.SCALE] = value + } /** Apparent strength */ var avStrength: Double get() = (actorValue.getAsDouble(AVKey.STRENGTH) ?: 0.0) * @@ -1294,10 +1299,14 @@ open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : A } var avBaseStrength: Double? get() = actorValue.getAsDouble(AVKey.STRENGTH) - set(value) { actorValue[AVKey.STRENGTH] = value!! } + set(value) { + actorValue[AVKey.STRENGTH] = value!! + } var avBaseMass: Double get() = actorValue.getAsDouble(AVKey.BASEMASS) ?: MASS_DEFAULT - set(value) { actorValue[AVKey.BASEMASS] = value } + set(value) { + actorValue[AVKey.BASEMASS] = value + } val avAcceleration: Double get() = actorValue.getAsDouble(AVKey.ACCEL)!! * actorValue.getAsDouble(AVKey.ACCELBUFF)!! * diff --git a/src/net/torvald/terrarum/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/gameactors/FixtureBase.kt index 04fa21e7e..69815f6ef 100644 --- a/src/net/torvald/terrarum/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/gameactors/FixtureBase.kt @@ -5,7 +5,8 @@ import net.torvald.spriteanimation.SpriteAnimation /** * Created by minjaesong on 16-06-17. */ -open class FixtureBase(physics: Boolean = true) : ActorWithSprite(ActorOrder.BEHIND, physics) { +open class FixtureBase(physics: Boolean = true) : + ActorWithSprite(ActorOrder.BEHIND, immobileBody = true, physics = physics) { /** * 0: Open * 1: Blocked diff --git a/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt b/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt index 4ddee190b..2f4124b97 100644 --- a/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt +++ b/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt @@ -11,7 +11,7 @@ import org.newdawn.slick.Input * * Created by minjaesong on 16-10-10. */ -open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null) : ActorWithSprite(ActorOrder.MIDDLE) { +open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null, realAirFriction: Boolean = false) : ActorWithSprite(ActorOrder.MIDDLE, realAirFriction) { init { this.actorValue["_bornyear"] = born.year diff --git a/src/net/torvald/terrarum/gameactors/PhysTestBall.kt b/src/net/torvald/terrarum/gameactors/PhysTestBall.kt index 8fd1cf40a..003ed0174 100644 --- a/src/net/torvald/terrarum/gameactors/PhysTestBall.kt +++ b/src/net/torvald/terrarum/gameactors/PhysTestBall.kt @@ -10,7 +10,7 @@ import org.newdawn.slick.Graphics /** * Created by minjaesong on 16-03-05. */ -class PhysTestBall : ActorWithSprite(ActorOrder.MIDDLE) { +class PhysTestBall : ActorWithSprite(ActorOrder.MIDDLE, immobileBody = true) { private var color = Color.orange diff --git a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt index d19f07912..ccd416ce5 100644 --- a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt @@ -432,17 +432,12 @@ object LightmapRenderer { if (darken < 0 || darken >= COLOUR_RANGE_SIZE) throw IllegalArgumentException("darken: out of range ($darken)") - // use equation with magic number 6.5: - // =>> val r = data.r() * (1f + brighten.r() * 6.5f) <<= - // gives 8-visible-tile penetration of sunlight, fairly smooth, - // DOES NOT GO BELOW (2,2,2) + // use equation with magic number 9.0 + // smooooooth - val r = data.r() * (1f - darken.r() * 6.5f) - val g = data.g() * (1f - darken.g() * 6.5f) - val b = data.b() * (1f - darken.b() * 6.5f) - //val r = data.r() - darken.r() - //val g = data.g() - darken.g() - //val b = data.b() - darken.b() + val r = data.r() * (1f - darken.r() * 9.0f) + val g = data.g() * (1f - darken.g() * 9.0f) + val b = data.b() * (1f - darken.b() * 9.0f) return constructRGBFromFloat(r.clampZero(), g.clampZero(), b.clampZero()) } @@ -629,6 +624,13 @@ object LightmapRenderer { private fun Float.clampChannel() = if (this > CHANNEL_MAX_DECIMAL) CHANNEL_MAX_DECIMAL else this fun getValueFromMap(x: Int, y: Int): Int? = getLight(x, y) + fun getLowestRGB(x: Int, y: Int): Int? { + val value = getLight(x, y) + if (value == null) + return null + else + return FastMath.min(value.rawR(), value.rawG(), value.rawB()) + } private fun purgeLightmap() { for (y in 0..LIGHTMAP_HEIGHT - 1) { diff --git a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt index 70f0898fc..941e7f100 100644 --- a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt +++ b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt @@ -11,14 +11,18 @@ object MapCamera { private val world: GameWorld = Terrarum.ingame.world private val TILE_SIZE = FeaturesDrawer.TILE_SIZE - var x = 0 + var x: Int = 0 private set - var y = 0 + var y: Int = 0 private set var width: Int = 0 private set var height: Int = 0 private set + val xCentre: Int + get() = x + width.ushr(1) + val yCentre: Int + get() = y + height.ushr(1) fun update() { val player = Terrarum.ingame.player diff --git a/src/net/torvald/terrarum/mapdrawer/TilesDrawer.kt b/src/net/torvald/terrarum/mapdrawer/TilesDrawer.kt index f45823107..0ef3a6ae6 100644 --- a/src/net/torvald/terrarum/mapdrawer/TilesDrawer.kt +++ b/src/net/torvald/terrarum/mapdrawer/TilesDrawer.kt @@ -278,6 +278,8 @@ object TilesDrawer { blendNormal() } + private val tileDrawLightThreshold = 2 + private fun drawTiles(g: Graphics, mode: Int, drawModeTilesBlendMul: Boolean) { val for_y_start = y / TILE_SIZE val for_y_end = TilesDrawer.clampHTile(for_y_start + (height / TILE_SIZE) + 2) @@ -305,59 +307,72 @@ object TilesDrawer { // draw try { - if ( - (mode == WALL || mode == TERRAIN) && // not an air tile - (thisTile ?: 0) > 0) //&& // commented out: meh + if ((mode == WALL || mode == TERRAIN) && // not an air tile + (thisTile ?: 0) != Tile.AIR) { // check if light level of nearby or this tile is illuminated - /*( LightmapRenderer.getValueFromMap(x, y) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x - 1, y) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x + 1, y) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x, y - 1) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x, y + 1) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x - 1, y - 1) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x + 1, y + 1) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x + 1, y - 1) ?: 0 > 0 || - LightmapRenderer.getValueFromMap(x - 1, y + 1) ?: 0 > 0) - )*/ { - val nearbyTilesInfo: Int - if (isPlatform(thisTile)) { - nearbyTilesInfo = getNearbyTilesInfoPlatform(x, y) - } - else if (isWallSticker(thisTile)) { - nearbyTilesInfo = getNearbyTilesInfoWallSticker(x, y) - } - else if (isConnectMutual(thisTile)) { - nearbyTilesInfo = getNearbyTilesInfoNonSolid(x, y, mode) - } - else if (isConnectSelf(thisTile)) { - nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile) - } + if ( LightmapRenderer.getLowestRGB(x, y) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x - 1, y) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x + 1, y) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x, y - 1) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x, y + 1) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x - 1, y - 1) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x + 1, y + 1) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x + 1, y - 1) ?: 0 >= tileDrawLightThreshold || + LightmapRenderer.getLowestRGB(x - 1, y + 1) ?: 0 >= tileDrawLightThreshold) { + // blackness + /*if (zeroTileCounter > 0) { + g.color = Color.black + g.fillRect( + (x - zeroTileCounter) * TILE_SIZE.toFloat(), y * TILE_SIZE.toFloat(), + zeroTileCounter * TILE_SIZE.toFloat(), TILE_SIZE.toFloat() + ) + g.color = Color.white + zeroTileCounter = 0 + }*/ + + + val nearbyTilesInfo: Int + if (isPlatform(thisTile)) { + nearbyTilesInfo = getNearbyTilesInfoPlatform(x, y) + } + else if (isWallSticker(thisTile)) { + nearbyTilesInfo = getNearbyTilesInfoWallSticker(x, y) + } + else if (isConnectMutual(thisTile)) { + nearbyTilesInfo = getNearbyTilesInfoNonSolid(x, y, mode) + } + else if (isConnectSelf(thisTile)) { + nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile) + } + else { + nearbyTilesInfo = 0 + } + + + val thisTileX: Int + if (!noDamageLayer) + thisTileX = PairedMapLayer.RANGE * ((thisTile ?: 0) % PairedMapLayer.RANGE) + nearbyTilesInfo + else + thisTileX = nearbyTilesInfo + + val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE + + if (drawModeTilesBlendMul) { + if (TilesDrawer.isBlendMul(thisTile)) { + drawTile(mode, x, y, thisTileX, thisTileY) + } + } + else { + // do NOT add "if (!isBlendMul(thisTile))"! + // or else they will not look like they should be when backed with wall + drawTile(mode, x, y, thisTileX, thisTileY) + } + } // end if (is illuminated) else { - nearbyTilesInfo = 0 + zeroTileCounter++ + drawTile(mode, x, y, 1, 0) // black patch } - - - val thisTileX: Int - if (!noDamageLayer) - thisTileX = PairedMapLayer.RANGE * ((thisTile ?: 0) % PairedMapLayer.RANGE) + nearbyTilesInfo - else - thisTileX = nearbyTilesInfo - - val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE - - if (drawModeTilesBlendMul) { - if (TilesDrawer.isBlendMul(thisTile)) { - drawTile(mode, x, y, thisTileX, thisTileY) - } - } else { - // do NOT add "if (!isBlendMul(thisTile))"! - // or else they will not look like they should be when backed with wall - drawTile(mode, x, y, thisTileX, thisTileY) - } - } // end if (not an air and is illuminated) - else { - zeroTileCounter++ - } + } // end if (not an air) } catch (e: NullPointerException) { // do nothing. WARNING: This exception handling may hide erratic behaviour completely. } diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 9aa5041b3..4acf33d46 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -40,6 +40,7 @@ object WeatherMixer { lateinit var mixedWeather: BaseModularWeather val globalLightNow = Color(0) + private val world = Terrarum.ingame.world // Weather indices const val WEATHER_GENERIC = "generic" @@ -90,9 +91,17 @@ object WeatherMixer { ) Terrarum.ingame.addParticle(rainParticle) } + globalLightNow.set(getGlobalLightOfTime(world.time.elapsedSeconds).darker(0.3f)) } } + private fun Color.set(other: Color) { + this.r = other.r + this.g = other.g + this.b = other.b + this.a = other.a + } + fun render(g: Graphics) { // we will not care for nextSkybox for now