From 4acc797feefcd48e94d46b368b2d47bcf297b526 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Sat, 21 Jan 2017 16:52:16 +0900 Subject: [PATCH] actorwithbody splitted in favour of new particle type Former-commit-id: 121bd069d0a9eeef60f5ecb085a11a93c4b4a84d Former-commit-id: 539b4b6916e808c01298190cf347e928f61fe62e --- ENVIRON.md | 12 +- src/net/torvald/aa/KDHeapifiedTree.kt | 14 +- .../spriteanimation/SpriteAnimation.kt | 30 +- src/net/torvald/terrarum/StateInGame.kt | 125 ++++++--- src/net/torvald/terrarum/StateNoiseTexGen.kt | 32 ++- src/net/torvald/terrarum/Terrarum.kt | 36 ++- .../torvald/terrarum/console/CommandDict.kt | 1 + src/net/torvald/terrarum/console/SetScale.kt | 35 +++ .../terrarum/console/SpawnPhysTestBall.kt | 2 +- .../torvald/terrarum/console/SpawnTapestry.kt | 2 +- src/net/torvald/terrarum/console/Teleport.kt | 20 +- .../terrarum/debuggerapp/ActorValueTracker.kt | 8 +- src/net/torvald/terrarum/gameactors/Actor.kt | 7 +- .../terrarum/gameactors/ActorHumanoid.kt | 2 +- .../terrarum/gameactors/ActorVisible.kt | 14 + .../{ActorWithBody.kt => ActorWithSprite.kt} | 160 +++++++---- .../terrarum/gameactors/CreatureBuilder.kt | 4 +- .../terrarum/gameactors/DroppedItem.kt | 2 +- .../terrarum/gameactors/FixtureBase.kt | 2 +- .../terrarum/gameactors/FixtureTikiTorch.kt | 3 +- .../terrarum/gameactors/HistoricalFigure.kt | 2 +- .../terrarum/gameactors/HumanoidNPC.kt | 2 +- .../terrarum/gameactors/ParticleBase.kt | 68 +++++ .../terrarum/gameactors/ParticleTestRain.kt | 24 ++ .../terrarum/gameactors/PhysTestBall.kt | 2 +- .../gameactors/PlayerBuilderCynthia.kt | 5 +- .../gameactors/PlayerBuilderSigrid.kt | 8 +- .../terrarum/gameactors/ProjectileSimple.kt | 13 +- .../terrarum/gameactors/TapestryObject.kt | 9 +- .../terrarum/gameactors/WeaponSwung.kt | 2 +- .../terrarum/gameactors/ai/AILuaAPI.kt | 66 ++++- .../gameactors/ai/scripts/PokemonNPCAI.lua | 6 +- .../physicssolver/CollisionSolver.kt | 26 +- .../physicssolver/VelocitySolver.kt | 4 +- .../terrarum/gameworld/WorldSimulator.kt | 46 +-- .../terrarum/itemproperties/ItemCodex.kt | 4 +- .../terrarum/mapdrawer/LightmapRenderer.kt | 9 +- .../terrarum/mapgenerator/NoiseFilter.kt | 2 +- .../terrarum/mapgenerator/NoiseFilterCubic.kt | 2 +- .../mapgenerator/NoiseFilterMinusQuadratic.kt | 2 +- .../mapgenerator/NoiseFilterQuadratic.kt | 2 +- .../terrarum/mapgenerator/NoiseFilterSqrt.kt | 2 +- .../mapgenerator/NoiseFilterUniform.kt | 4 +- .../terrarum/mapgenerator/WorldGenerator.kt | 65 +++-- .../terrarum/tileproperties/TileCodex.kt | 7 +- .../terrarum/tileproperties/TileProp.kt | 1 + .../terrarum/tileproperties/TilePropCSV.kt | 264 +++++++++--------- src/net/torvald/terrarum/ui/ConsoleWindow.kt | 9 +- .../torvald/terrarum/weather/WeatherMixer.kt | 13 + 49 files changed, 752 insertions(+), 428 deletions(-) create mode 100644 src/net/torvald/terrarum/console/SetScale.kt create mode 100644 src/net/torvald/terrarum/gameactors/ActorVisible.kt rename src/net/torvald/terrarum/gameactors/{ActorWithBody.kt => ActorWithSprite.kt} (89%) create mode 100644 src/net/torvald/terrarum/gameactors/ParticleBase.kt create mode 100644 src/net/torvald/terrarum/gameactors/ParticleTestRain.kt diff --git a/ENVIRON.md b/ENVIRON.md index fc39ecfd0..2ddf6e0ad 100644 --- a/ENVIRON.md +++ b/ENVIRON.md @@ -19,4 +19,14 @@ Colour overlay is set to 6 500 K as untouched. The value must be ## Sunlight ## -Sunlight of the midday must have colour temperature of 5 700 K. \ No newline at end of file +Sunlight of the midday must have colour temperature of 5 700 K. + + +## Weather effects ## + +* Wind + - Blows away sands/snows + - Tilts raindrops/snowfall + +* Precipitation + - Rain, snow \ No newline at end of file diff --git a/src/net/torvald/aa/KDHeapifiedTree.kt b/src/net/torvald/aa/KDHeapifiedTree.kt index 552f54062..fd853adbc 100644 --- a/src/net/torvald/aa/KDHeapifiedTree.kt +++ b/src/net/torvald/aa/KDHeapifiedTree.kt @@ -2,7 +2,7 @@ package net.torvald.aa import net.torvald.point.Point2d import net.torvald.terrarum.gameactors.Actor -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.sqr import java.util.* @@ -23,7 +23,7 @@ class KDHeapifiedTree() { private val dimension = 2 private val initialSize = 128 - private val nodes = Array(initialSize, { null }) + private val nodes = Array(initialSize, { null }) private val root: Int = 0 @@ -34,13 +34,13 @@ class KDHeapifiedTree() { private fun Int.getActor() = nodes[this] private fun Int.getLeft() = this * 2 + 1 private fun Int.getRight() = this * 2 + 2 - private fun Int.set(value: ActorWithBody?) { nodes[this] = value } - private fun Int.setLeftChild(value: ActorWithBody?) { nodes[this.getLeft()] = value } - private fun Int.setRightChild(value: ActorWithBody?) { nodes[this.getRight()] = value } + private fun Int.set(value: ActorWithSprite?) { nodes[this] = value } + private fun Int.setLeftChild(value: ActorWithSprite?) { nodes[this.getLeft()] = value } + private fun Int.setRightChild(value: ActorWithSprite?) { nodes[this.getRight()] = value } private val zeroPoint = Point2d(0.0, 0.0) - private fun create(points: List, depth: Int, index: Int): ActorWithBody? { + private fun create(points: List, depth: Int, index: Int): ActorWithSprite? { if (points.isEmpty()) { index.set(null) @@ -91,7 +91,7 @@ class KDHeapifiedTree() { private fun expandArray() { val prevNodes = nodes.copyOf() - Array(prevNodes.size * 2, { null }) + Array(prevNodes.size * 2, { null }) create(prevNodes.toList(), 0, 0) } diff --git a/src/net/torvald/spriteanimation/SpriteAnimation.kt b/src/net/torvald/spriteanimation/SpriteAnimation.kt index e7c1e070a..f0561525e 100644 --- a/src/net/torvald/spriteanimation/SpriteAnimation.kt +++ b/src/net/torvald/spriteanimation/SpriteAnimation.kt @@ -7,19 +7,15 @@ package net.torvald.spriteanimation import net.torvald.terrarum.StateInGame import net.torvald.terrarum.Terrarum import com.jme3.math.FastMath -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import org.newdawn.slick.Graphics import org.newdawn.slick.Image import org.newdawn.slick.SlickException import org.newdawn.slick.SpriteSheet -class SpriteAnimation(val parentActor: ActorWithBody) { +class SpriteAnimation(val parentActor: ActorWithSprite, val cellWidth: Int, val cellHeight: Int) { private var spriteImage: SpriteSheet? = null - var height: Int = 0 - private set - var width: Int = 0 - private set private var currentFrame = 1 // one-based! private var currentRow = 1 // one-based! private var nFrames: Int = 1 @@ -47,11 +43,11 @@ class SpriteAnimation(val parentActor: ActorWithBody) { * @throws SlickException */ fun setSpriteImage(imagePath: String) { - spriteImage = SpriteSheet(imagePath, this.width, this.height) + spriteImage = SpriteSheet(imagePath, cellWidth, cellHeight) } fun setSpriteImage(image: Image) { - spriteImage = SpriteSheet(image, this.width, this.height) + spriteImage = SpriteSheet(image, cellWidth, cellHeight) } /** @@ -62,16 +58,6 @@ class SpriteAnimation(val parentActor: ActorWithBody) { this.delay = delay } - /** - * Sets sprite dimension. This is necessary for this to work. - * @param w width of the animation frame - * @param h height of the animation frame - */ - fun setDimension(w: Int, h: Int) { - width = w - height = h - } - /** * Sets sheet rows and animation frames. Will default to * 1, 1 (still image of top left from the sheet) if not called. @@ -115,6 +101,10 @@ class SpriteAnimation(val parentActor: ActorWithBody) { * @param scale */ @JvmOverloads fun render(g: Graphics, posX: Float, posY: Float, scale: Float = 1f) { + if (cellWidth == 0 || cellHeight == 0) { + throw Error("Sprite width or height is set to zero! ($cellWidth, $cellHeight); master: $parentActor") + } + // Null checking if (currentImage == null) { currentImage = getScaledSprite(scale) @@ -131,8 +121,8 @@ class SpriteAnimation(val parentActor: ActorWithBody) { flippedImage.draw( Math.round(posX).toFloat(), FastMath.floor(posY).toFloat(), - FastMath.floor(width * scale).toFloat(), - FastMath.floor(height * scale).toFloat() + FastMath.floor(cellWidth * scale).toFloat(), + FastMath.floor(cellHeight * scale).toFloat() ) } } diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index e5c5a3a04..6d4f292bd 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -24,6 +24,7 @@ import net.torvald.terrarum.mapdrawer.MapCamera import net.torvald.terrarum.mapgenerator.WorldGenerator import net.torvald.terrarum.mapgenerator.RoguelikeRandomiser import net.torvald.terrarum.tileproperties.TileCodex +import net.torvald.terrarum.tileproperties.TilePropUtil import net.torvald.terrarum.tilestats.TileStats import net.torvald.terrarum.ui.* import net.torvald.terrarum.weather.WeatherMixer @@ -36,6 +37,8 @@ import org.newdawn.slick.state.StateBasedGame import shader.Shader import java.lang.management.ManagementFactory import java.util.* +import java.util.concurrent.locks.Lock +import java.util.concurrent.locks.ReentrantLock /** * Created by minjaesong on 15-12-30. @@ -56,10 +59,10 @@ constructor() : BasicGameState() { val actorContainerInactive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) val uiContainer = ArrayList() - private val actorsRenderBehind = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderMiddle = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderMidTop = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - private val actorsRenderFront = ArrayList(ACTORCONTAINER_INITIAL_SIZE) + private val actorsRenderBehind = ArrayList(ACTORCONTAINER_INITIAL_SIZE) + private val actorsRenderMiddle = ArrayList(ACTORCONTAINER_INITIAL_SIZE) + private val actorsRenderMidTop = ArrayList(ACTORCONTAINER_INITIAL_SIZE) + private val actorsRenderFront = ArrayList(ACTORCONTAINER_INITIAL_SIZE) lateinit var consoleHandler: UIHandler lateinit var debugWindow: UIHandler @@ -127,8 +130,6 @@ constructor() : BasicGameState() { // add new player and put it to actorContainer playableActorDelegate = PlayableActorDelegate(PlayerBuilderSigrid()) - //player = PBCynthia.create() - //player.setNoClip(true); addActor(player) @@ -185,8 +186,9 @@ constructor() : BasicGameState() { /////////////////////////// // world-related updates // /////////////////////////// + TilePropUtil.dynamicLumFuncTickClock() world.updateWorldTime(delta) - WorldSimulator(world, player, delta) + WorldSimulator(player, delta) WeatherMixer.update(gc, delta) TileStats.update() if (!(CommandDict["setgl"] as SetGlobalLightOverride).lightOverride) @@ -255,9 +257,13 @@ constructor() : BasicGameState() { private fun repossessActor() { // check if currently pocessed actor is removed from game - if (!hasActor(player)) - // re-possess canonical player - changePossession(Player.PLAYER_REF_ID) // TODO completely other behaviour? + if (!hasActor(player)) { + // re-possess canonical player + if (hasActor(Player.PLAYER_REF_ID)) + changePossession(Player.PLAYER_REF_ID) + else + changePossession(0x51621D) // FIXME fallback debug mode (FIXME is there for a reminder visible in ya IDE) + } } private fun changePossession(newActor: PlayableActorDelegate) { @@ -266,7 +272,7 @@ constructor() : BasicGameState() { } playableActorDelegate = newActor - WorldSimulator(world, player, UPDATE_DELTA) + WorldSimulator(player, UPDATE_DELTA) } private fun changePossession(refid: Int) { @@ -280,8 +286,8 @@ constructor() : BasicGameState() { 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) + playableActorDelegate!!.actor.collisionType = ActorWithSprite.COLLISION_KINEMATIC + WorldSimulator(player, UPDATE_DELTA) } private fun setAppTitle() { @@ -325,7 +331,7 @@ constructor() : BasicGameState() { actorsRenderMidTop.forEach { actor -> actor.drawBody(worldG) } player.drawBody(worldG) actorsRenderFront.forEach { actor -> actor.drawBody(worldG) } - // --> Change of blend mode <-- introduced by ActorWithBody // + // --> Change of blend mode <-- introduced by ActorVisible // ///////////////////////////// @@ -352,7 +358,7 @@ constructor() : BasicGameState() { actorsRenderMidTop.forEach { actor -> actor.drawGlow(worldG) } player.drawGlow(worldG) actorsRenderFront.forEach { actor -> actor.drawGlow(worldG) } - // --> blendLightenOnly() <-- introduced by ActorWithBody // + // --> blendLightenOnly() <-- introduced by ActorVisible // //////////////////////// @@ -362,7 +368,7 @@ constructor() : BasicGameState() { // draw reference ID if debugWindow is open if (debugWindow.isVisible) { actorContainer.forEachIndexed { i, actor -> - if (actor is ActorWithBody) { + if (actor is ActorVisible) { worldG.color = Color.white worldG.font = Terrarum.fontSmallNumbers worldG.drawString( @@ -401,6 +407,13 @@ constructor() : BasicGameState() { ///////////////// gwin.drawImage(worldDrawFrameBuffer.getScaledCopy(screenZoom), 0f, 0f) gwin.drawImage(uisDrawFrameBuffer, 0f, 0f) + + + // centre marker + /*gwin.color = Color(0x00FFFF) + gwin.lineWidth = 1f + gwin.drawLine(Terrarum.WIDTH / 2f, 0f, Terrarum.WIDTH / 2f, Terrarum.HEIGHT.toFloat()) + gwin.drawLine(0f, Terrarum.HEIGHT / 2f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT / 2f)*/ } override fun keyPressed(key: Int, c: Char) { @@ -484,7 +497,7 @@ constructor() : BasicGameState() { while (i < actorContainerSize) { // loop through actorContainerInactive val actor = actorContainerInactive[i] val actorIndex = i - if (actor is ActorWithBody && actor.inUpdateRange()) { + if (actor is ActorVisible && actor.inUpdateRange()) { addActor(actor) // duplicates are checked here actorContainerInactive.removeAt(actorIndex) actorContainerSize -= 1 @@ -507,12 +520,12 @@ constructor() : BasicGameState() { val actorIndex = i // kill actors flagged to despawn if (actor.flagDespawn) { - actorContainer.removeAt(actorIndex) + removeActor(actor) actorContainerSize -= 1 i-- // array removed 1 elem, so we also decrement counter by 1 } // inactivate distant actors - else if (actor is ActorWithBody && !actor.inUpdateRange()) { + else if (actor is ActorVisible && !actor.inUpdateRange()) { if (actor !is Projectile) { // if it's a projectile, don't inactivate it; just kill it. actorContainerInactive.add(actor) // naïve add; duplicates are checked when the actor is re-activated } @@ -559,7 +572,7 @@ constructor() : BasicGameState() { d.forEach { if (it < ret) ret = it } return ret } - private fun distToActorSqr(a: ActorWithBody, p: ActorWithBody) = + private fun distToActorSqr(a: ActorVisible, p: ActorVisible) = min(// take min of normal position and wrapped (x < 0) position (a.hitbox.centeredX - p.hitbox.centeredX).sqr() + (a.hitbox.centeredY - p.hitbox.centeredY).sqr(), @@ -568,7 +581,7 @@ constructor() : BasicGameState() { (a.hitbox.centeredX - p.hitbox.centeredX - world.width * TILE_SIZE).sqr() + (a.hitbox.centeredY - p.hitbox.centeredY).sqr() ) - private fun distToCameraSqr(a: ActorWithBody) = + private fun distToCameraSqr(a: ActorVisible) = min( (a.hitbox.posX - MapCamera.x).sqr() + (a.hitbox.posY - MapCamera.y).sqr(), @@ -579,14 +592,14 @@ constructor() : BasicGameState() { ) /** whether the actor is within screen */ - private fun ActorWithBody.inScreen() = + private fun ActorVisible.inScreen() = distToCameraSqr(this) <= (Terrarum.WIDTH.plus(this.hitbox.width.div(2)).times(1 / Terrarum.ingame.screenZoom).sqr() + Terrarum.HEIGHT.plus(this.hitbox.height.div(2)).times(1 / Terrarum.ingame.screenZoom).sqr()) /** whether the actor is within update range */ - private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr() + private fun ActorVisible.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr() /** * actorContainer extensions @@ -596,8 +609,21 @@ constructor() : BasicGameState() { fun hasActor(ID: Int): Boolean = if (actorContainer.size == 0) false - else - actorContainer.binarySearch(ID) >= 0 + else { + // TODO cherche for inactive + val binsearch = actorContainer.binarySearch(ID) + if (binsearch < 0) { + if (actorContainerInactive.size == 0) false + else { + val binsearch2 = actorContainerInactive.binarySearch(ID) + + binsearch2 >= 0 + } + } + else { + true + } + } fun removeActor(ID: Int) = removeActor(getActorByID(ID)) /** @@ -616,7 +642,7 @@ constructor() : BasicGameState() { // indexToDelete >= 0 means that the actor certainly exists in the game // which means we don't need to check if i >= 0 again - if (actor is ActorWithBody) { + if (actor is ActorVisible) { when (actor.renderOrder) { ActorOrder.BEHIND -> { val i = actorsRenderBehind.binarySearch(actor.referenceID) @@ -648,12 +674,12 @@ constructor() : BasicGameState() { actorContainer.add(actor) insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor - if (actor is ActorWithBody) { + if (actor is ActorVisible) { when (actor.renderOrder) { - ActorOrder.BEHIND -> actorsRenderBehind.add(actor) - ActorOrder.MIDDLE -> actorsRenderMiddle.add(actor) - ActorOrder.MIDTOP -> actorsRenderMidTop.add(actor) - ActorOrder.FRONT -> actorsRenderFront.add(actor) + 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 ) } } } } @@ -681,15 +707,26 @@ constructor() : BasicGameState() { } private fun insertionSortLastElem(arr: ArrayList) { - var j: Int - val index: Int = arr.size - 1 - val x = arr[index] - j = index - 1 - while (j > 0 && arr[j] > x) { - arr[j + 1] = arr[j] - j -= 1 + lock(ReentrantLock()) { + var j = arr.lastIndex - 1 + val x = arr.last() + while (j >= 0 && arr[j] > x) { + arr[j + 1] = arr[j] + j -= 1 + } + arr[j + 1] = x + } + } + private fun insertionSortLastElemAV(arr: ArrayList) { // out-projection doesn't work, duh + lock(ReentrantLock()) { + var j = arr.lastIndex - 1 + val x = arr.last() + while (j >= 0 && arr[j] > x) { + arr[j + 1] = arr[j] + j -= 1 + } + arr[j + 1] = x } - arr[j + 1] = x } private fun ArrayList.binarySearch(actor: Actor) = this.binarySearch(actor.referenceID) @@ -712,6 +749,16 @@ constructor() : BasicGameState() { } return -(low + 1) // key not found } + + inline fun lock(lock: Lock, body: () -> Unit) { + lock.lock() + try { + body() + } + finally { + lock.unlock() + } + } } fun Color.toInt() = redByte.shl(16) or greenByte.shl(8) or blueByte diff --git a/src/net/torvald/terrarum/StateNoiseTexGen.kt b/src/net/torvald/terrarum/StateNoiseTexGen.kt index bcee4d08e..80e69308c 100644 --- a/src/net/torvald/terrarum/StateNoiseTexGen.kt +++ b/src/net/torvald/terrarum/StateNoiseTexGen.kt @@ -55,6 +55,23 @@ class StateNoiseTexGen : BasicGameState() { return Joise(ridged_autocorrect) } + private fun noiseBrownianGranite(): Joise { + val ridged = ModuleFractal() + ridged.setType(ModuleFractal.FractalType.FBM) + ridged.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC) + ridged.setNumOctaves(2) + ridged.setFrequency(16.0) + ridged.seed = Random().nextLong() + + val brownian_select = ModuleSelect() + brownian_select.setControlSource(ridged) + brownian_select.setThreshold(0.8) + brownian_select.setLowSource(0.0) + brownian_select.setHighSource(1.0) + + return Joise(brownian_select) + } + private fun noiseBillowFractal(): Joise { val ridged = ModuleFractal() ridged.setType(ModuleFractal.FractalType.BILLOW) @@ -70,19 +87,6 @@ class StateNoiseTexGen : BasicGameState() { return Joise(ridged_autocorrect) } - private fun noiseBlobs(): Joise { - val gradval = ModuleBasisFunction() - gradval.seed = Random().nextLong() - gradval.setType(ModuleBasisFunction.BasisType.GRADVAL) - gradval.setInterpolation(ModuleBasisFunction.InterpolationType.QUINTIC) - - val gradval_autocorrect = ModuleAutoCorrect() - gradval_autocorrect.setRange(0.0, 1.0) - gradval_autocorrect.setSource(gradval) - - return Joise(gradval_autocorrect) - } - private fun noiseSimplex(): Joise { val simplex = ModuleFractal() simplex.seed = Random().nextLong() @@ -114,7 +118,7 @@ class StateNoiseTexGen : BasicGameState() { } fun generateNoiseImage() { - val noiseModule = noiseBrownian() // change noise function here + val noiseModule = noiseBrownianGranite() // change noise function here for (y in 0..imagesize - 1) { for (x in 0..imagesize - 1) { diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 3a50502da..f582b670a 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -33,8 +33,16 @@ constructor(gamename: String) : StateBasedGame(gamename) { var previousState: Int? = null // to be used with temporary states like StateMonitorCheck + val systemArch = System.getProperty("os.arch") + + private val thirtyTwoBitArchs = arrayOf("i386", "i686", "ppc", "x86", "x86_32") // I know I should Write Once, Run Everywhere; but just in case :) + val is32Bit = thirtyTwoBitArchs.contains(systemArch) + init { + // just in case + println("[Terrarum] os.arch = $systemArch") + gameConfig = GameConfig() joypadLabelStart = when (getConfigString("joypadlabelstyle")) { @@ -67,7 +75,7 @@ constructor(gamename: String) : StateBasedGame(gamename) { else gameLocale = gameLocaleFromConfig - println("[terrarum] Locale: " + gameLocale) + println("[Terrarum] Locale: " + gameLocale) try { Controllers.getController(0) @@ -127,6 +135,12 @@ constructor(gamename: String) : StateBasedGame(gamename) { ingame = StateInGame() addState(ingame) + + + // foolproof + if (stateCount < 1) { + throw Error("Please add or un-comment addState statements") + } } companion object { @@ -158,16 +172,18 @@ constructor(gamename: String) : StateBasedGame(gamename) { var HEIGHT = 742 // IMAX ratio var VSYNC = true val VSYNC_TRIGGER_THRESHOLD = 56 + val HALFW: Int + get() = WIDTH.ushr(1) + val HALFH: Int + get() = HEIGHT.ushr(1) var gameStarted = false lateinit var ingame: StateInGame lateinit var gameConfig: GameConfig - lateinit var OSName: String // System.getProperty("os.name") - private set - lateinit var OSVersion: String // System.getProperty("os.version") - private set + val OSName = System.getProperty("os.name") + val OSVersion = System.getProperty("os.version") lateinit var OperationSystem: String // all caps "WINDOWS, "OSX", "LINUX", "SOLARIS", "UNKNOWN" private set val isWin81: Boolean @@ -268,7 +284,8 @@ constructor(gamename: String) : StateBasedGame(gamename) { appgc.setVSync(VSYNC) appgc.setMaximumLogicUpdateInterval(1000 / TARGET_INTERNAL_FPS) // 10 ms appgc.setMinimumLogicUpdateInterval(1000 / TARGET_INTERNAL_FPS - 1) // 9 ms - appgc.setMultiSample(4) + + appgc.setMultiSample(0) appgc.setShowFPS(false) @@ -299,9 +316,6 @@ constructor(gamename: String) : StateBasedGame(gamename) { } private fun getDefaultDirectory() { - OSName = System.getProperty("os.name") - OSVersion = System.getProperty("os.version") - val OS = System.getProperty("os.name").toUpperCase() if (OS.contains("WIN")) { OperationSystem = "WINDOWS" @@ -327,8 +341,8 @@ constructor(gamename: String) : StateBasedGame(gamename) { defaultSaveDir = defaultDir + "/Saves" configDir = defaultDir + "/config.json" - println("os.name: '$OSName'") - println("os.version: '$OSVersion'") + println("[Terrarum] os.name = $OSName") + println("[Terrarum] os.version = $OSVersion") } private fun createDirs() { diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 972743440..43332d8b0 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -41,6 +41,7 @@ object CommandDict { Pair("inventory", Inventory), Pair("avtracker", AVTracker), Pair("actorslist", ActorsList), + Pair("setscale", SetScale), // Test codes Pair("bulletintest", SetBulletin), diff --git a/src/net/torvald/terrarum/console/SetScale.kt b/src/net/torvald/terrarum/console/SetScale.kt new file mode 100644 index 000000000..63a0c3314 --- /dev/null +++ b/src/net/torvald/terrarum/console/SetScale.kt @@ -0,0 +1,35 @@ +package net.torvald.terrarum.console + +import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.gameactors.ActorWithSprite + +/** + * Created by SKYHi14 on 2017-01-20. + */ +object SetScale : ConsoleCommand { + override fun execute(args: Array) { + if (args.size == 2 || args.size == 3) { + try { + val targetID = if (args.size == 3) args[1].toInt() else Terrarum.ingame.player.referenceID + val scale = args[if (args.size == 3) 2 else 1].toDouble() + + val target = Terrarum.ingame.getActorByID(targetID) + + if (target !is ActorWithSprite) { + EchoError("Target is not ActorWithSprite") + } + else { + target.scale = scale + } + } + catch (e: NumberFormatException) { + EchoError("Wrong number input") + } + } + else printUsage() + } + + override fun printUsage() { + Echo("Usage: setscale scale | setscale actorID scale") + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt b/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt index d5f4494d9..1c993d625 100644 --- a/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt +++ b/src/net/torvald/terrarum/console/SpawnPhysTestBall.kt @@ -1,7 +1,7 @@ package net.torvald.terrarum.console import net.torvald.terrarum.gameactors.Actor -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.PhysTestBall import net.torvald.terrarum.mapdrawer.TilesDrawer import net.torvald.terrarum.Terrarum diff --git a/src/net/torvald/terrarum/console/SpawnTapestry.kt b/src/net/torvald/terrarum/console/SpawnTapestry.kt index 7b9a0c7e0..2ac07d142 100644 --- a/src/net/torvald/terrarum/console/SpawnTapestry.kt +++ b/src/net/torvald/terrarum/console/SpawnTapestry.kt @@ -20,6 +20,6 @@ object SpawnTapestry : ConsoleCommand { } override fun printUsage() { - println("Usage: spawntapestry ") + Echo("Usage: spawntapestry ") } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/console/Teleport.kt b/src/net/torvald/terrarum/console/Teleport.kt index 9fc51a2fe..e935b9c3a 100644 --- a/src/net/torvald/terrarum/console/Teleport.kt +++ b/src/net/torvald/terrarum/console/Teleport.kt @@ -3,7 +3,7 @@ package net.torvald.terrarum.console import net.torvald.terrarum.StateInGame import net.torvald.terrarum.mapdrawer.FeaturesDrawer import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite /** * Created by minjaesong on 16-01-24. @@ -31,8 +31,8 @@ internal object Teleport : ConsoleCommand { EchoError("missing 'to' on teleport command") return } - val fromActor: ActorWithBody - val targetActor: ActorWithBody + val fromActor: ActorWithSprite + val targetActor: ActorWithSprite try { val fromActorID = args[1].toInt() val targetActorID = if (args[3].toLowerCase() == "player") @@ -43,13 +43,13 @@ internal object Teleport : ConsoleCommand { // if from == target, ignore the action if (fromActorID == targetActorID) return - if (Terrarum.ingame.getActorByID(fromActorID) !is ActorWithBody || - Terrarum.ingame.getActorByID(targetActorID) !is ActorWithBody) { + if (Terrarum.ingame.getActorByID(fromActorID) !is ActorWithSprite || + Terrarum.ingame.getActorByID(targetActorID) !is ActorWithSprite) { throw IllegalArgumentException() } else { - fromActor = Terrarum.ingame.getActorByID(fromActorID) as ActorWithBody - targetActor = Terrarum.ingame.getActorByID(targetActorID) as ActorWithBody + fromActor = Terrarum.ingame.getActorByID(fromActorID) as ActorWithSprite + targetActor = Terrarum.ingame.getActorByID(targetActorID) as ActorWithSprite } } catch (e: NumberFormatException) { @@ -72,7 +72,7 @@ internal object Teleport : ConsoleCommand { return } - val actor: ActorWithBody + val actor: ActorWithSprite val x: Int val y: Int try { @@ -80,11 +80,11 @@ internal object Teleport : ConsoleCommand { y = args[4].toInt() * FeaturesDrawer.TILE_SIZE + FeaturesDrawer.TILE_SIZE / 2 val actorID = args[1].toInt() - if (Terrarum.ingame.getActorByID(actorID) !is ActorWithBody) { + if (Terrarum.ingame.getActorByID(actorID) !is ActorWithSprite) { throw IllegalArgumentException() } else { - actor = Terrarum.ingame.getActorByID(actorID) as ActorWithBody + actor = Terrarum.ingame.getActorByID(actorID) as ActorWithSprite } } catch (e: NumberFormatException) { diff --git a/src/net/torvald/terrarum/debuggerapp/ActorValueTracker.kt b/src/net/torvald/terrarum/debuggerapp/ActorValueTracker.kt index 8c23eb1f7..3b993c3bd 100644 --- a/src/net/torvald/terrarum/debuggerapp/ActorValueTracker.kt +++ b/src/net/torvald/terrarum/debuggerapp/ActorValueTracker.kt @@ -6,7 +6,7 @@ import net.torvald.terrarum.console.SetAV import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.ActorValue -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.mapdrawer.FeaturesDrawer import java.awt.BorderLayout import java.awt.Color @@ -30,7 +30,7 @@ class ActorValueTracker constructor() : JFrame() { private val avPosArea = JTextArea() private val avPosScroller = JScrollPane(avPosArea) - private var actor: ActorWithBody? = null + private var actor: ActorWithSprite? = null private var actorValue: ActorValue? = null private val modavInputKey = JTextField() @@ -101,7 +101,7 @@ class ActorValueTracker constructor() : JFrame() { actorValue = actor!!.actorValue } else if (actorIDField.text.isNotBlank()) { - actor = Terrarum.ingame.getActorByID(actorIDField.text.toInt()) as ActorWithBody + actor = Terrarum.ingame.getActorByID(actorIDField.text.toInt()) as ActorWithSprite actorValue = actor!!.actorValue } } @@ -165,7 +165,7 @@ class ActorValueTracker constructor() : JFrame() { this.title = "AVTracker — $actor" - if (actor is ActorWithBody) { + if (actor is ActorWithSprite) { this.actor = actor } diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index bc99696e6..6f80946a7 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -64,4 +64,9 @@ abstract class Actor(val renderOrder: ActorOrder) : Comparable, Runnable } -enum class ActorOrder { BEHIND, MIDDLE, MIDTOP, FRONT } \ No newline at end of file +enum class ActorOrder { + BEHIND, // tapestries, some particles (obstructed by terrain) + MIDDLE, // actors + MIDTOP, // bullets, thrown items + FRONT // fake tiles +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index 284567e60..2a9aaaf7b 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -361,7 +361,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * this code base, ACCELERATION must be changed (in other words, we must deal with JERK) accordingly * to the FRICTION. * - * So I'm adding walkX/Y and getting the ActorWithBody.setNewNextHitbox to use the velocity value of + * So I'm adding walkX/Y and getting the ActorWithSprite.setNewNextHitbox to use the velocity value of * walkX/Y + velocity, which is stored in variable moveDelta. * * Be warned. diff --git a/src/net/torvald/terrarum/gameactors/ActorVisible.kt b/src/net/torvald/terrarum/gameactors/ActorVisible.kt new file mode 100644 index 000000000..c4bf707a4 --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/ActorVisible.kt @@ -0,0 +1,14 @@ +package net.torvald.terrarum.gameactors + +import org.newdawn.slick.GameContainer +import org.newdawn.slick.Graphics + +/** + * Created by SKYHi14 on 2017-01-21. + */ +abstract class ActorVisible(renderOrder: ActorOrder) : Actor(renderOrder) { + open val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) + override abstract fun update(gc: GameContainer, delta: Int) + abstract fun drawBody(g: Graphics) + abstract fun drawGlow(g: Graphics) +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt similarity index 89% rename from src/net/torvald/terrarum/gameactors/ActorWithBody.kt rename to src/net/torvald/terrarum/gameactors/ActorWithSprite.kt index 8b85982ef..02773933e 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithSprite.kt @@ -7,21 +7,29 @@ import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.mapdrawer.FeaturesDrawer import net.torvald.terrarum.tileproperties.TileCodex 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.tileproperties.Tile import net.torvald.terrarum.tileproperties.TileProp import org.dyn4j.Epsilon import org.dyn4j.geometry.Vector2 +import org.newdawn.slick.Color import org.newdawn.slick.GameContainer import org.newdawn.slick.Graphics +import org.newdawn.slick.Image import java.util.* /** - * Base class for every actor that has physical (or echo) body. This includes furnishings, paintings, gadgets, etc. + * 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 * * Created by minjaesong on 16-01-13. */ -open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { +open class ActorWithSprite(renderOrder: ActorOrder, physics: Boolean = true) : ActorVisible(renderOrder) { /** !! ActorValue macros are on the very bottom of the source !! **/ @@ -38,14 +46,12 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { protected var hitboxTranslateY: Double = 0.0// relative to spritePosY protected var baseHitboxW: Int = 0 protected var baseHitboxH: Int = 0 - protected var baseSpriteWidth: Int = 0 - protected var baseSpriteHeight: Int = 0 /** * * Position: top-left point * * Unit: pixel * !! external class should not hitbox.set(); use setHitboxDimension() and setPosition() */ - val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double; + override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double; @Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // 52 mantissas ought to be enough for anybody... val tilewiseHitbox: Hitbox @@ -100,7 +106,10 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { get() = (actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) * (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0) set(value) { + val scaleDelta = value - scale actorValue[AVKey.SCALE] = value / (actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0) + // reposition + translatePosition(-baseHitboxW * scaleDelta / 2, -baseHitboxH * scaleDelta) } @Transient val MASS_LOWEST = 0.1 // Kilograms /** Apparent mass. Use "avBaseMass" for base mass */ @@ -110,7 +119,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { if (value <= 0) throw IllegalArgumentException("mass cannot be less than or equal to zero.") else if (value < MASS_LOWEST) { - println("[ActorWithBody] input too small; using $MASS_LOWEST instead.") + println("[ActorWithSprite] input too small; using $MASS_LOWEST instead.") actorValue[AVKey.BASEMASS] = MASS_LOWEST } @@ -123,7 +132,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { if (value < 0) throw IllegalArgumentException("invalid elasticity value $value; valid elasticity value is [0, 1].") else if (value >= ELASTICITY_MAX) { - println("[ActorWithBody] Elasticity were capped to $ELASTICITY_MAX.") + println("[ActorWithSprite] Elasticity were capped to $ELASTICITY_MAX.") field = ELASTICITY_MAX } else @@ -149,7 +158,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { var density = 1000.0 set(value) { if (value < 0) - throw IllegalArgumentException("[ActorWithBody] $value: density cannot be negative.") + throw IllegalArgumentException("[ActorWithSprite] $value: density cannot be negative.") field = value } @@ -164,7 +173,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { /** Default to 'true' */ var isVisible = true /** Default to 'true' */ - var isUpdate = true + var isUpdate = physics var isNoSubjectToGrav = false var isNoCollideWorld = false var isNoSubjectToFluidResistance = false @@ -177,19 +186,6 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { */ @Volatile var isChronostasis = false - /** - * Constants - */ - - @Transient private val METER = 24.0 - /** - * [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2] - */ - @Transient private val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble() - /** - * [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame] - */ - @Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS /** * Gravitational Constant G. Load from gameworld. * [m / s^2] @@ -203,7 +199,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT set(value) { if (value < 0) - throw IllegalArgumentException("[ActorWithBody] drag coefficient cannot be negative.") + throw IllegalArgumentException("[ActorWithSprite] drag coefficient cannot be negative.") actorValue[AVKey.DRAGCOEFF] = value } @@ -260,23 +256,33 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { // some initialiser goes here... } - fun makeNewSprite(w: Int, h: Int) { - sprite = SpriteAnimation(this) - sprite!!.setDimension(w, h) + fun makeNewSprite(w: Int, h: Int, image: Image) { + sprite = SpriteAnimation(this, w, h) + sprite!!.setSpriteImage(image) } - fun makeNewSpriteGlow(w: Int, h: Int) { - spriteGlow = SpriteAnimation(this) - spriteGlow!!.setDimension(w, h) + fun makeNewSprite(w: Int, h: Int, imageref: String) { + sprite = SpriteAnimation(this, w, h) + sprite!!.setSpriteImage(imageref) + } + + fun makeNewSpriteGlow(w: Int, h: Int, image: Image) { + spriteGlow = SpriteAnimation(this, w, h) + spriteGlow!!.setSpriteImage(image) + } + + fun makeNewSpriteGlow(w: Int, h: Int, imageref: String) { + spriteGlow = SpriteAnimation(this, w, h) + spriteGlow!!.setSpriteImage(imageref) } /** * @param w * @param h - * @param tx positive: translate drawn sprite to LEFT. - * @param ty positive: translate drawn sprite to DOWN. - * @see ActorWithBody.drawBody - * @see ActorWithBody.drawGlow + * @param tx positive: translate sprite to LEFT. + * @param ty positive: translate sprite to DOWN. + * @see ActorWithSprite.drawBody + * @see ActorWithSprite.drawGlow */ fun setHitboxDimension(w: Int, h: Int, tx: Int, ty: Int) { baseHitboxH = h @@ -296,18 +302,23 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { */ fun setPosition(x: Double, y: Double) { hitbox.setFromWidthHeight( - x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale), - y - (baseHitboxH - hitboxTranslateY) * (1 - scale), + x - (baseHitboxW / 2 - hitboxTranslateX) * scale, + y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, baseHitboxH * scale) nextHitbox.setFromWidthHeight( - x - (baseHitboxW / 2 - hitboxTranslateX) * (1 - scale), - y - (baseHitboxH - hitboxTranslateY) * (1 - scale), + x - (baseHitboxW / 2 - hitboxTranslateX) * scale, + y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, baseHitboxH * scale) } + private fun translatePosition(dx: Double, dy: Double) { + hitbox.translate(dx, dy) + nextHitbox.translate(dx, dy) + } + val centrePosVector: Vector2 get() = Vector2(hitbox.centeredX, hitbox.centeredY) val centrePosPoint: Point2d @@ -344,12 +355,6 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { isNoSubjectToFluidResistance = isPlayerNoClip } - // set sprite dimension vars if there IS sprite for the actor - if (sprite != null) { - baseSpriteHeight = sprite!!.height - baseSpriteWidth = sprite!!.width - } - /** * Actual physics thing (altering velocity) starts from here */ @@ -987,50 +992,64 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { private fun updateHitbox() = hitbox.reassign(nextHitbox) - open fun drawGlow(g: Graphics) { + override open fun drawGlow(g: Graphics) { if (isVisible && spriteGlow != null) { blendLightenOnly() if (!sprite!!.flippedHorizontal()) { spriteGlow!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat(), - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) // Q&D fix for Roundworld anomaly spriteGlow!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) spriteGlow!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat() - world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) } else { spriteGlow!!.render(g, (hitbox.posX - scale).toFloat(), - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) // Q&D fix for Roundworld anomaly spriteGlow!!.render(g, (hitbox.posX - scale).toFloat() + world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) spriteGlow!!.render(g, (hitbox.posX - scale).toFloat() - world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) } } + + + // 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() + ) + } } - open fun drawBody(g: Graphics) { + override open fun drawBody(g: Graphics) { if (isVisible && sprite != null) { @@ -1043,36 +1062,36 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { if (!sprite!!.flippedHorizontal()) { sprite!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat(), - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) // Q&D fix for Roundworld anomaly sprite!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) sprite!!.render(g, (hitbox.posX - hitboxTranslateX * scale).toFloat() - world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) } else { sprite!!.render(g, (hitbox.posX - scale).toFloat(), - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) // Q&D fix for Roundworld anomaly sprite!!.render(g, (hitbox.posX - scale).toFloat() + world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) sprite!!.render(g, (hitbox.posX - scale).toFloat() - world.width * TILE_SIZE, - (hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(), + (hitbox.posY + hitboxTranslateY * scale).toFloat(), (scale).toFloat() ) } @@ -1129,9 +1148,9 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { // warnings if (sprite == null && isVisible) - println("[ActorWithBody] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.") + println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.") else if (sprite != null && !isVisible) - println("[ActorWithBody] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.") + println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.") assertPrinted = true } @@ -1190,13 +1209,30 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) { companion object { + /** + * Constants + */ + + @Transient private val METER = 24.0 + /** + * [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2] + */ + @Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble() + /** + * [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame] + */ + @Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS + /** * Enumerations that exported to JSON */ @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 (e.g. nonmoving static obj) + /** does not displaced by external forces when collided, but it still can move (e.g. player, elevator) */ + @Transient const val COLLISION_KINEMATIC = 1 + /** displaced by external forces */ + @Transient const val COLLISION_DYNAMIC = 2 + /** does not displaced by external forces, target of collision (e.g. nonmoving static obj) */ + @Transient const val COLLISION_STATIC = 3 @Transient const val COLLISION_KNOCKBACK_GIVER = 4 // mobs @Transient const val COLLISION_KNOCKBACK_TAKER = 5 // benevolent NPCs @Transient const val BLEND_NORMAL = 4 diff --git a/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt b/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt index 14d04ec18..3e10f78d3 100644 --- a/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt +++ b/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt @@ -18,8 +18,8 @@ object CreatureBuilder { * @Param jsonFileName with extension */ @Throws(IOException::class, SlickException::class) - operator fun invoke(jsonFileName: String): ActorWithBody { - val actor = ActorWithBody(ActorOrder.MIDDLE) + operator fun invoke(jsonFileName: String): ActorWithSprite { + val actor = ActorWithSprite(ActorOrder.MIDDLE) InjectCreatureRaw(actor.actorValue, jsonFileName) return actor diff --git a/src/net/torvald/terrarum/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/gameactors/DroppedItem.kt index 4b5e3b7f9..5631d3210 100644 --- a/src/net/torvald/terrarum/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/gameactors/DroppedItem.kt @@ -9,7 +9,7 @@ import org.newdawn.slick.Graphics /** * Created by minjaesong on 16-03-15. */ -class DroppedItem(private val item: InventoryItem) : ActorWithBody(ActorOrder.MIDTOP) { +class DroppedItem(private val item: InventoryItem) : ActorWithSprite(ActorOrder.MIDTOP) { init { if (item.id >= ItemCodex.ITEM_COUNT_MAX) diff --git a/src/net/torvald/terrarum/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/gameactors/FixtureBase.kt index 6d08d8449..04fa21e7e 100644 --- a/src/net/torvald/terrarum/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/gameactors/FixtureBase.kt @@ -5,7 +5,7 @@ import net.torvald.spriteanimation.SpriteAnimation /** * Created by minjaesong on 16-06-17. */ -open class FixtureBase : ActorWithBody(ActorOrder.BEHIND) { +open class FixtureBase(physics: Boolean = true) : ActorWithSprite(ActorOrder.BEHIND, physics) { /** * 0: Open * 1: Blocked diff --git a/src/net/torvald/terrarum/gameactors/FixtureTikiTorch.kt b/src/net/torvald/terrarum/gameactors/FixtureTikiTorch.kt index e5094d3fa..97cef64f1 100644 --- a/src/net/torvald/terrarum/gameactors/FixtureTikiTorch.kt +++ b/src/net/torvald/terrarum/gameactors/FixtureTikiTorch.kt @@ -25,8 +25,7 @@ class FixtureTikiTorch : FixtureBase(), Luminous { lightBoxList = ArrayList(1) lightBoxList.add(Hitbox(3.0, 0.0, 4.0, 3.0)) - makeNewSprite(10, 27) - sprite!!.setSpriteImage("assets/graphics/sprites/fixtures/tiki_torch.tga") + makeNewSprite(10, 27, "assets/graphics/sprites/fixtures/tiki_torch.tga") sprite!!.setDelay(200) sprite!!.setRowsAndFrames(1, 1) diff --git a/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt b/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt index 8a50e3fc6..4ddee190b 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) : ActorWithBody(ActorOrder.MIDDLE) { +open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null) : ActorWithSprite(ActorOrder.MIDDLE) { init { this.actorValue["_bornyear"] = born.year diff --git a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt index 35ee3d3ea..456c9e405 100644 --- a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt @@ -31,7 +31,7 @@ open class HumanoidNPC(override val scriptPath: String, born: GameDate) : ActorH private val aiLuaAPI: AILuaAPI companion object { - val DEFAULT_COLLISION_TYPE = ActorWithBody.COLLISION_DYNAMIC + val DEFAULT_COLLISION_TYPE = ActorWithSprite.COLLISION_DYNAMIC } init { diff --git a/src/net/torvald/terrarum/gameactors/ParticleBase.kt b/src/net/torvald/terrarum/gameactors/ParticleBase.kt new file mode 100644 index 000000000..00ba1e3d6 --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/ParticleBase.kt @@ -0,0 +1,68 @@ +package net.torvald.terrarum.gameactors + +import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.gameactors.ActorWithSprite.Companion.SI_TO_GAME_ACC +import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE +import net.torvald.terrarum.tileproperties.Tile +import net.torvald.terrarum.tileproperties.TileCodex +import org.dyn4j.geometry.Vector2 +import org.newdawn.slick.GameContainer +import org.newdawn.slick.Graphics +import org.newdawn.slick.Image + +/** + * Actors with static sprites and very simple physics + * + * Created by SKYHi14 on 2017-01-20. + */ +open class ParticleBase(renderOrder: ActorOrder, maxLifeTime: Int? = null) : ActorVisible(renderOrder), Projectile { + + override var actorValue = ActorValue() + override @Volatile var flagDespawn = false + + override fun run() { + TODO("not implemented") + } + + var isNoSubjectToGrav = false + var dragCoefficient = 3.0 + + private val lifetimeMax = maxLifeTime ?: 5000 + private var lifetimeCounter = 0 + + open val velocity = Vector2(0.0, 0.0) + + open lateinit var image: Image + + init { + + } + + override fun update(gc: GameContainer, delta: Int) { + lifetimeCounter += delta + if (velocity.isZero || lifetimeCounter >= lifetimeMax || + // simple stuck check + TileCodex[Terrarum.ingame.world.getTileFromTerrain( + hitbox.pointedX.div(TILE_SIZE).floorInt(), + hitbox.pointedY.div(TILE_SIZE).floorInt() + ) ?: Tile.STONE].isSolid) { + flagDespawn = true + } + + // gravity, winds, etc. (external forces) + if (!isNoSubjectToGrav) { + velocity += Terrarum.ingame.world.gravitation / dragCoefficient * SI_TO_GAME_ACC + } + + + // combine external forces + hitbox.translate(velocity) + } + + override fun drawBody(g: Graphics) { + g.drawImage(image, hitbox.centeredX.toFloat(), hitbox.centeredY.toFloat()) + } + + override fun drawGlow(g: Graphics) { + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ParticleTestRain.kt b/src/net/torvald/terrarum/gameactors/ParticleTestRain.kt new file mode 100644 index 000000000..77dcb82dd --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/ParticleTestRain.kt @@ -0,0 +1,24 @@ +package net.torvald.terrarum.gameactors + +import org.dyn4j.geometry.Vector2 +import org.newdawn.slick.Image + +/** + * Created by SKYHi14 on 2017-01-20. + */ +class ParticleTestRain(posX: Double, posY: Double) : ParticleBase(ActorOrder.BEHIND, 6000) { + + init { + image = Image("./assets/graphics/weathers/raindrop.tga") + val w = image.width.toDouble() + val h = image.height.toDouble() + hitbox.setFromWidthHeight( + posX - w.times(0.5), + posY - h.times(0.5), + w, h + ) + + velocity.y = 16.0 + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/PhysTestBall.kt b/src/net/torvald/terrarum/gameactors/PhysTestBall.kt index 6d5003af0..8fd1cf40a 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 : ActorWithBody(ActorOrder.MIDDLE) { +class PhysTestBall : ActorWithSprite(ActorOrder.MIDDLE) { private var color = Color.orange diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt index f4b1d9910..428f03eca 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt @@ -9,7 +9,7 @@ import net.torvald.terrarum.mapdrawer.FeaturesDrawer */ object PlayerBuilderCynthia { - operator fun invoke(): ActorWithBody { + operator fun invoke(): ActorWithSprite { //val p: Player = Player(GameDate(100, 143)) // random value thrown val p: HumanoidNPC = HumanoidNPC("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua", GameDate(100, 143)) // random value thrown @@ -19,8 +19,7 @@ object PlayerBuilderCynthia { p.actorValue[AVKey.NAME] = "Cynthia" - p.makeNewSprite(26, 42) - p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player_2.tga") + p.makeNewSprite(26, 42, "assets/graphics/sprites/test_player_2.tga") p.sprite!!.setDelay(200) p.sprite!!.setRowsAndFrames(1, 1) diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt index ec4419913..e8505fd7b 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt @@ -26,13 +26,11 @@ object PlayerBuilderSigrid { p.referenceID = 0x51621D // the only constant of this procedural universe - p.makeNewSprite(28, 51) - p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player.tga") + p.makeNewSprite(28, 51, "assets/graphics/sprites/test_player.tga") p.sprite!!.setDelay(200) p.sprite!!.setRowsAndFrames(1, 1) - p.makeNewSpriteGlow(28, 51) - p.spriteGlow!!.setSpriteImage("assets/graphics/sprites/test_player_glow.tga") + p.makeNewSpriteGlow(28, 51, "assets/graphics/sprites/test_player_glow.tga") p.spriteGlow!!.setDelay(200) p.spriteGlow!!.setRowsAndFrames(1, 1) @@ -66,7 +64,7 @@ object PlayerBuilderSigrid { //p.actorValue["__selectedtile"] = 147 // test code; replace with .primaryUse(gc, delta) p.actorValue["__aimhelper"] = true // TODO when you'll gonna implement it? - p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 10, 0) + p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 11, -2) // FIXME offsetY of -2: Have no idea about the error; it's just supposed to be zero p.inventory = ActorInventory(0x7FFFFFFF, true) diff --git a/src/net/torvald/terrarum/gameactors/ProjectileSimple.kt b/src/net/torvald/terrarum/gameactors/ProjectileSimple.kt index 435e7b380..201d42027 100644 --- a/src/net/torvald/terrarum/gameactors/ProjectileSimple.kt +++ b/src/net/torvald/terrarum/gameactors/ProjectileSimple.kt @@ -4,6 +4,8 @@ import net.torvald.colourutil.CIELabUtil.darkerLab import net.torvald.point.Point2d import net.torvald.spriteanimation.SpriteAnimation import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.tileproperties.Tile +import net.torvald.terrarum.tileproperties.TileCodex import org.dyn4j.geometry.Vector2 import org.newdawn.slick.Color import org.newdawn.slick.GameContainer @@ -15,11 +17,13 @@ import java.util.* * * Created by minjaesong on 16-08-29. */ + +// TODO simplified, lightweight physics (does not call PhysicsSolver) open class ProjectileSimple( private val type: Int, fromPoint: Vector2, // projected coord toPoint: Vector2 // arriving coord - ) : ActorWithBody(ActorOrder.MIDTOP), Luminous, Projectile { + ) : ActorWithSprite(ActorOrder.MIDTOP), Luminous, Projectile { val damage: Int val displayColour: Color @@ -69,7 +73,12 @@ open class ProjectileSimple( override fun update(gc: GameContainer, delta: Int) { // hit something and despawn lifetimeCounter += delta - if ((ccdCollided || grounded) || lifetimeCounter >= lifetimeMax) flagDespawn() + if (ccdCollided || grounded || lifetimeCounter >= lifetimeMax || + // stuck check + TileCodex[Terrarum.ingame.world.getTileFromTerrain(feetPosTile[0], feetPosTile[1]) ?: Tile.STONE].isSolid + ) { + flagDespawn() + } posPre.set(centrePosPoint) diff --git a/src/net/torvald/terrarum/gameactors/TapestryObject.kt b/src/net/torvald/terrarum/gameactors/TapestryObject.kt index 918eb7bf9..4ddbd305d 100644 --- a/src/net/torvald/terrarum/gameactors/TapestryObject.kt +++ b/src/net/torvald/terrarum/gameactors/TapestryObject.kt @@ -10,13 +10,14 @@ import org.newdawn.slick.Image /** * Created by SKYHi14 on 2017-01-07. */ -class TapestryObject(val image: Image, val artName: String, val artAuthor: String) : FixtureBase() { +class TapestryObject(val image: Image, val artName: String, val artAuthor: String) : FixtureBase(physics = false) { + + // physics = false only speeds up for ~2 frames with 50 tapestries init { - makeNewSprite(image.width, image.height) + image.filter = Image.FILTER_NEAREST + makeNewSprite(image.width, image.height, image) setHitboxDimension(image.width, image.height, 0, 0) - sprite!!.setSpriteImage(image) - isNoSubjectToGrav = true setPosition(Terrarum.appgc.mouseX, Terrarum.appgc.mouseY) } diff --git a/src/net/torvald/terrarum/gameactors/WeaponSwung.kt b/src/net/torvald/terrarum/gameactors/WeaponSwung.kt index 886f2d9ea..ccf082437 100644 --- a/src/net/torvald/terrarum/gameactors/WeaponSwung.kt +++ b/src/net/torvald/terrarum/gameactors/WeaponSwung.kt @@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors /** * Created by minjaesong on 16-04-26. */ -class WeaponSwung(val itemID: Int) : ActorWithBody(ActorOrder.MIDTOP), Luminous { +class WeaponSwung(val itemID: Int) : ActorWithSprite(ActorOrder.MIDTOP), Luminous { // just let the solver use AABB; it's cheap but works just enough /** diff --git a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt index d62fc4ecd..04345f729 100644 --- a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt @@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors.ai import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameactors.AIControlled import net.torvald.terrarum.gameactors.AVKey -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.mapdrawer.LightmapRenderer import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.TileCodex @@ -14,7 +14,7 @@ import org.luaj.vm2.lib.ZeroArgFunction /** * Created by minjaesong on 16-10-24. */ -internal class AILuaAPI(g: Globals, actor: ActorWithBody) { +internal class AILuaAPI(g: Globals, actor: ActorWithSprite) { // FIXME when actor jumps, the actor releases left/right stick @@ -42,6 +42,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { g["ai"]["getNearbyTiles"] = GetNearbyTiles(actor) g["ai"]["getFloorsHeight"] = GetFloorsHeight(actor) g["ai"]["getCeilingsHeight"] = GetCeilingsHeight(actor) + g["ai"]["getLedgesHeight"] = GetLedgesHeight(actor) g["game"] = LuaValue.tableOf() g["game"]["version"] = GameVersion() @@ -50,9 +51,9 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { companion object { /** - * Reads arbitrary ActorWithBody and returns its information as Lua table + * Reads arbitrary ActorWithSprite and returns its information as Lua table */ - fun composeActorObject(actor: ActorWithBody): LuaTable { + fun composeActorObject(actor: ActorWithSprite): LuaTable { val t: LuaTable = LuaTable() t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua() @@ -94,7 +95,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { operator fun LuaTable.set(index: Int, value: Int) { this[index] = value.toLua() } } - class GetSelfActorInfo(val actor: ActorWithBody) : ZeroArgFunction() { + class GetSelfActorInfo(val actor: ActorWithSprite) : ZeroArgFunction() { override fun call(): LuaValue { return composeActorObject(actor) } @@ -130,13 +131,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } - class GetX(val actor: ActorWithBody) : ZeroArgFunction() { + class GetX(val actor: ActorWithSprite) : ZeroArgFunction() { override fun call(): LuaValue { return LuaValue.valueOf(actor.hitbox.centeredX) } } - class GetY(val actor: ActorWithBody) : ZeroArgFunction() { + class GetY(val actor: ActorWithSprite) : ZeroArgFunction() { override fun call(): LuaValue { return LuaValue.valueOf(actor.hitbox.centeredY) } @@ -219,7 +220,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } - class GetNearbyTiles(val actor: ActorWithBody) : OneArgFunction() { + class GetNearbyTiles(val actor: ActorWithSprite) : OneArgFunction() { /** @param radius * * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 @@ -261,7 +262,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } - class GetFloorsHeight(val actor: ActorWithBody) : OneArgFunction() { + class GetFloorsHeight(val actor: ActorWithSprite) : OneArgFunction() { /** @param radius * * 3 will return len:7 array, 0 will return len:1, 1 will return len:3 @@ -304,14 +305,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } - class GetCeilingsHeight(val actor: ActorWithBody) : OneArgFunction() { - /** @param radius + class GetCeilingsHeight(val actor: ActorWithSprite) : OneArgFunction() { + /** @param arg 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 @@ -348,6 +348,48 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } + class GetLedgesHeight(val actor: ActorWithSprite) : OneArgFunction() { + /** @param arg radius + * == + * <- (non-solid found) + * == + * == + * == + * == @ -> ledge height: 4 + * ================= + */ + 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++ + } + } + + return luatable + } + } + } + diff --git a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua index 6eedcb355..235208264 100644 --- a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua +++ b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua @@ -20,11 +20,11 @@ function generateCountMax() end function moveToDirection(delta) - local tiles = ai.getNearbyTiles(1) + local pits = ai.getFloorsHeight(2) local ledges = ai.getLedgesHeight(1) if moveMode == "left" then - if bit32.band(bit32.bor(tiles[0][-1], tiles[-1][-1]), 1) == 1 then + if pits[-1] == 1 then ai.moveLeft(0.8) if ledges[-1] <= jumpheight then -- no futile jumps ai.jump() @@ -33,7 +33,7 @@ function moveToDirection(delta) ai.moveLeft(0.5) end elseif moveMode == "right" then - if bit32.band(bit32.bor(tiles[0][1], tiles[-1][1]), 1) == 1 then + if pits[1] == 1 then ai.moveRight(0.8) if ledges[1] <= jumpheight then -- no futile jumps ai.jump() diff --git a/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt b/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt index 7ad0160fe..9b81a67c4 100644 --- a/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt +++ b/src/net/torvald/terrarum/gameactors/physicssolver/CollisionSolver.kt @@ -2,7 +2,7 @@ package net.torvald.terrarum.gameactors.physicssolver import com.jme3.math.FastMath import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import java.util.* /** @@ -20,9 +20,9 @@ object CollisionSolver { private val collListX = ArrayList(COLL_LIST_SIZE) private val collListY = ArrayList(COLL_LIST_SIZE) - private val collCandidateX = ArrayList>(COLL_CANDIDATES_SIZE) - private val collCandidateY = ArrayList>(COLL_CANDIDATES_SIZE) - private var collCandidates = ArrayList>(COLL_FINAL_CANDIDATES_SIZE) + private val collCandidateX = ArrayList>(COLL_CANDIDATES_SIZE) + private val collCandidateY = ArrayList>(COLL_CANDIDATES_SIZE) + private var collCandidates = ArrayList>(COLL_FINAL_CANDIDATES_SIZE) private val collCandidateStack = Stack() @@ -40,7 +40,7 @@ object CollisionSolver { // mark list x Terrarum.ingame.actorContainer.forEach { it -> - if (it is ActorWithBody) { + if (it is ActorWithSprite) { collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it)) collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it)) } @@ -73,7 +73,7 @@ object CollisionSolver { // mark list y Terrarum.ingame.actorContainer.forEach { it -> - if (it is ActorWithBody) { + if (it is ActorWithSprite) { collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it)) collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it)) } @@ -89,7 +89,7 @@ object CollisionSolver { else if (it.kind == ENDPOINT) { val mark_this = it val mark_other = collCandidateStack.pop() - val collCandidate: Pair + val collCandidate: Pair // make sure actor with lower ID comes first if (mark_this.actor < mark_other.actor) collCandidate = Pair(mark_this.actor, mark_other.actor) @@ -137,7 +137,7 @@ object CollisionSolver { return indexOfEqFn(this, other) >= 0 } - private fun solveCollision(a: ActorWithBody, b: ActorWithBody) { + private fun solveCollision(a: ActorWithSprite, b: ActorWithSprite) { // some of the Pair(a, b) are either duplicates or erroneously reported. // e.g. (A, B), (B, C) and then (A, C); // in some situation (A, C) will not making any contact with each other @@ -170,11 +170,11 @@ object CollisionSolver { } } - private infix fun ActorWithBody.makesCollisionWith(other: ActorWithBody) = - this.collisionType != ActorWithBody.COLLISION_NOCOLLIDE && - other.collisionType != ActorWithBody.COLLISION_NOCOLLIDE + private infix fun ActorWithSprite.makesCollisionWith(other: ActorWithSprite) = + this.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE && + other.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE - private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean { + private infix fun ActorWithSprite.isCollidingWith(other: ActorWithSprite): Boolean { val ax = this.hitbox.centeredX val ay = this.hitbox.centeredY val bx = other.hitbox.centeredX @@ -205,7 +205,7 @@ object CollisionSolver { data class CollisionMarkings( val pos: Double, val kind: Int, - val actor: ActorWithBody + val actor: ActorWithSprite ) /** diff --git a/src/net/torvald/terrarum/gameactors/physicssolver/VelocitySolver.kt b/src/net/torvald/terrarum/gameactors/physicssolver/VelocitySolver.kt index 651f7dd9e..6f01f74dc 100644 --- a/src/net/torvald/terrarum/gameactors/physicssolver/VelocitySolver.kt +++ b/src/net/torvald/terrarum/gameactors/physicssolver/VelocitySolver.kt @@ -1,6 +1,6 @@ package net.torvald.terrarum.gameactors.physicssolver -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite /** * Created by minjaesong on 16-05-01. @@ -11,7 +11,7 @@ object VelocitySolver { } - private fun applyGravity(actor: ActorWithBody) { + private fun applyGravity(actor: ActorWithSprite) { } diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 322aed4cb..b9cef00c2 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -24,7 +24,7 @@ object WorldSimulator { const val FLUID_UPDATING_SQUARE_RADIUS = 64 // larger value will have dramatic impact on performance const private val DOUBLE_RADIUS = FLUID_UPDATING_SQUARE_RADIUS * 2 - private val fluidMap = Array(DOUBLE_RADIUS, { IntArray(DOUBLE_RADIUS) }) + private val fluidMap = Array(DOUBLE_RADIUS, { ByteArray(DOUBLE_RADIUS) }) private val fluidTypeMap = Array(DOUBLE_RADIUS, { ByteArray(DOUBLE_RADIUS) }) const val DISPLACE_CAP = 4 @@ -38,23 +38,28 @@ object WorldSimulator { val colourNone = Color(0x808080) val colourWater = Color(0x66BBFF) + private val world = Terrarum.ingame.world + // TODO future Kotlin feature -- typealias AnyPlayer: HistoricalFigure - operator fun invoke(world: GameWorld, p: HistoricalFigure, delta: Int) { + operator fun invoke(p: HistoricalFigure, delta: Int) { updateXFrom = p.hitbox.centeredX.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt() updateYFrom = p.hitbox.centeredY.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt() updateXTo = updateXFrom + DOUBLE_RADIUS updateYTo = updateYFrom + DOUBLE_RADIUS - moveFluids(world, delta) - displaceFallables(world, delta) + moveFluids(delta) + displaceFallables(delta) } /** * displace fluids. Note that the code assumes the gravity pulls things downward ONLY, * which means you'll need to modify the code A LOT if you're going to implement zero- or * reverse-gravity. + * + * Procedure: CP world fluidmap -> sim on fluidmap -> CP fluidmap world + * TODO multithread */ - fun moveFluids(world: GameWorld, delta: Int) { + fun moveFluids(delta: Int) { //////////////////// // build fluidmap // //////////////////// @@ -74,7 +79,7 @@ object WorldSimulator { if (tile.isFluid()) { // move down if not obstructed - if (!tileBottom.isSolid()) { + /*if (!tileBottom.isSolid()) { val drainage = drain(world, x, y, DISPLACE_CAP) pour(world, x, y + 1, drainage) } @@ -106,7 +111,11 @@ object WorldSimulator { // nowhere open; do default (fill top) else { pour(world, x, y - 1, DISPLACE_CAP) + }*/ + if (!tileBottom.isSolid()) { + pour(x, y + 1, drain(x, y, FLUID_MAX)) } + } } } @@ -123,7 +132,7 @@ object WorldSimulator { * displace fallable tiles. It is scanned bottom-left first. To achieve the sens ofreal * falling, each tiles are displaced by ONLY ONE TILE below. */ - fun displaceFallables(world: GameWorld, delta: Int) { + fun displaceFallables(delta: Int) { for (y in updateYFrom..updateYTo) { for (x in updateXFrom..updateXTo) { val tile = world.getTileFromTerrain(x, y) ?: Tile.STONE @@ -135,7 +144,7 @@ object WorldSimulator { // remove tileThis to create air pocket world.setTileTerrain(x, y, Tile.AIR) - pour(world, x, y, drain(world, x, y, tileBelow.fluidLevel())) + pour(x, y, drain(x, y, tileBelow.fluidLevel().toInt())) // place our tile world.setTileTerrain(x, y + 1, tile) } @@ -156,7 +165,7 @@ object WorldSimulator { for (x in 0..fluidMap[0].size - 1) { val data = fluidMap[y][x] if (TilesDrawer.tileInCamera(x + updateXFrom, y + updateYFrom)) { - if (data == 0) + if (data == 0.toByte()) g.color = colourNone else g.color = colourWater @@ -188,7 +197,7 @@ object WorldSimulator { for (x in updateXFrom..updateXTo) { val tile = world.getTileFromTerrain(x, y) ?: Tile.STONE if (tile.isFluid()) { - fluidMap[y - updateYFrom][x - updateXFrom] = tile.fluidLevel() + fluidMap[y - updateYFrom][x - updateXFrom] = tile.fluidLevel().toByte() fluidTypeMap[y - updateYFrom][x - updateXFrom] = tile.fluidType().toByte() } } @@ -209,8 +218,8 @@ object WorldSimulator { fun Int.isFluid() = TileCodex[this].isFluid fun Int.isSolid() = this.fluidLevel() == FLUID_MAX || TileCodex[this].isSolid //fun Int.viscosity() = TileCodex[this]. - fun Int.fluidLevel() = if (!this.isFluid()) 0 else (this % FLUID_MAX) + 1 - fun Int.fluidType() = this / FLUID_MAX + fun Int.fluidLevel() = if (!this.isFluid()) 0 else (this % FLUID_MAX).plus(1) + fun Int.fluidType() = (this / 16) // 0 - 255, 255 being water, 254 being lava fun Int.isEven() = (this and 0x01) == 0 fun Int.isFallable() = TileCodex[this].isFallable @@ -231,10 +240,11 @@ object WorldSimulator { * (intended drainage - this) will give you how much fluid is not yet drained. * TODO add fluidType support */ - private fun drain(world: GameWorld, x: Int, y: Int, amount: Int): Int { - val displacement = Math.min(fluidMap[y - updateYFrom][x - updateXFrom], amount) + private fun drain(x: Int, y: Int, amount: Int): Int { + val displacement = Math.min(fluidMap[y - updateYFrom][x - updateXFrom].toInt(), amount) - fluidMap[y - updateYFrom][x - updateXFrom] -= displacement + fluidMap[y - updateYFrom][x - updateXFrom] = + (fluidMap[y - updateYFrom][x - updateXFrom] - displacement).toByte() return displacement } @@ -243,7 +253,7 @@ object WorldSimulator { * @param x and y: world tile coord * TODO add fluidType support */ - private fun pour(world: GameWorld, x: Int, y: Int, amount: Int) { + private fun pour(x: Int, y: Int, amount: Int) { /** * @param x and y: world tile coord * @return spillage @@ -256,10 +266,10 @@ object WorldSimulator { val addrY = worldYPos - updateYFrom if (addrX >= 0 && addrY >= 0 && addrX < DOUBLE_RADIUS && addrY < DOUBLE_RADIUS) { - fluidMap[addrY][addrX] += volume + fluidMap[addrY][addrX] = (fluidMap[addrY][addrX] + volume).toByte() if (fluidMap[addrY][addrX] > FLUID_MAX) { spil = fluidMap[addrY][addrX] - FLUID_MAX - fluidMap[addrY][addrX] = FLUID_MAX + fluidMap[addrY][addrX] = FLUID_MAX.toByte() } } diff --git a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt index e4ceabdee..1a226b0a9 100644 --- a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt +++ b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt @@ -5,7 +5,7 @@ import net.torvald.terrarum.KVHashMap import net.torvald.terrarum.gameactors.CanBeAnItem import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gamecontroller.mouseTileX import net.torvald.terrarum.gamecontroller.mouseTileY import net.torvald.terrarum.gameitem.EquipPosition @@ -50,7 +50,7 @@ object ItemCodex { val mousePoint = Point2d(gc.mouseTileX.toDouble(), gc.mouseTileY.toDouble()) // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) Terrarum.ingame.actorContainer.forEach { - if (it is ActorWithBody && it.tilewiseHitbox.intersects(mousePoint)) + if (it is ActorWithSprite && it.tilewiseHitbox.intersects(mousePoint)) return } // filter passed, do the job diff --git a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt index cc5121f77..d19f07912 100644 --- a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt @@ -7,7 +7,7 @@ import com.jme3.math.FastMath import net.torvald.colourutil.RGB import net.torvald.colourutil.CIELuvUtil.additiveLuv import net.torvald.terrarum.concurrent.ThreadParallel -import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.abs import net.torvald.terrarum.gameactors.roundInt import net.torvald.terrarum.gameworld.GameWorld @@ -217,7 +217,7 @@ object LightmapRenderer { private fun buildLanternmap() { lanternMap.clear() Terrarum.ingame.actorContainer.forEach { it -> - if (it is Luminous && it is ActorWithBody) { + if (it is Luminous && it is ActorWithSprite) { // put lanterns to the area the luminantBox is occupying for (lightBox in it.lightBoxList) { val lightBoxX = it.hitbox.posX + lightBox.posX @@ -267,11 +267,6 @@ object LightmapRenderer { } // END MIX TILE - // mix luminous actor - /*for ((posX, posY, luminosity) in lanternMap) { - if (posX == x && posY == y) - lightLevelThis = lightLevelThis maxBlend luminosity // maximise to not exceed 1.0 with normal (<= 1.0) light - }*/ for (i in 0..lanternMap.size - 1) { val lmap = lanternMap[i] if (lmap.posX == x && lmap.posY == y) diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilter.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilter.kt index 60bc280ee..9d26f93df 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilter.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilter.kt @@ -4,5 +4,5 @@ package net.torvald.terrarum.mapgenerator * Created by minjaesong on 16-03-31. */ interface NoiseFilter { - fun getGrad(func_argX: Int, start: Float, end: Float): Float + fun getGrad(func_argX: Int, start: Double, end: Double): Double } \ No newline at end of file diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt index bec042a76..515659446 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt @@ -30,7 +30,7 @@ import com.jme3.math.FastMath * Created by minjaesong on 16-03-31. */ object NoiseFilterCubic : NoiseFilter { - override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + override fun getGrad(func_argX: Int, start: Double, end: Double): Double { val graph_gradient = -FastMath.pow(FastMath.pow((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat(), 3f), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 (start - end) / FastMath.pow(WorldGenerator.HEIGHT.toFloat(), 3f) * FastMath.pow((func_argX - WorldGenerator.HEIGHT).toFloat(), 3f) + end diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt index cd01f4736..cdefeaa8c 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt @@ -30,7 +30,7 @@ import com.jme3.math.FastMath * Created by minjaesong on 16-03-31. */ object NoiseFilterMinusQuadratic : NoiseFilter { - override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + override fun getGrad(func_argX: Int, start: Double, end: Double): Double { val graph_gradient = -FastMath.pow(FastMath.sqr((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 (start - end) / FastMath.sqr(WorldGenerator.HEIGHT.toFloat()) * FastMath.sqr((func_argX - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt index 1616755b8..a2d2223e6 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt @@ -31,7 +31,7 @@ import com.jme3.math.FastMath * Created by minjaesong on 16-03-31. */ object NoiseFilterQuadratic : NoiseFilter { - override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + override fun getGrad(func_argX: Int, start: Double, end: Double): Double { val graph_gradient = FastMath.pow(FastMath.sqr((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 (start - end) / FastMath.sqr(WorldGenerator.HEIGHT.toFloat()) * FastMath.sqr((func_argX - WorldGenerator.HEIGHT).toFloat()) + end diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt index fd58f03d4..5a85fedc7 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt @@ -6,7 +6,7 @@ import com.jme3.math.FastMath * Created by minjaesong on 16-03-31. */ object NoiseFilterSqrt : NoiseFilter { - override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + override fun getGrad(func_argX: Int, start: Double, end: Double): Double { val graph_gradient = (end - start) / FastMath.sqrt((WorldGenerator.HEIGHT - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) * FastMath.sqrt((func_argX - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start if (func_argX < WorldGenerator.TERRAIN_AVERAGE_HEIGHT) { diff --git a/src/net/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt b/src/net/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt index e71bca803..97b371654 100644 --- a/src/net/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt +++ b/src/net/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt @@ -4,7 +4,7 @@ package net.torvald.terrarum.mapgenerator * Created by minjaesong on 16-03-31. */ object NoiseFilterUniform : NoiseFilter { - override fun getGrad(func_argX: Int, start: Float, end: Float): Float { - return 1f + override fun getGrad(func_argX: Int, start: Double, end: Double): Double { + return 1.0 } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt b/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt index 6c533020b..b2daecf0b 100644 --- a/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt +++ b/src/net/torvald/terrarum/mapgenerator/WorldGenerator.kt @@ -32,11 +32,11 @@ object WorldGenerator { var TERRAIN_AVERAGE_HEIGHT: Int = 0 private var minimumFloatingIsleHeight: Int = 0 - private val NOISE_GRAD_START = 0.67f - private val NOISE_GRAD_END = 0.56f + private val NOISE_GRAD_START = 0.67 + private val NOISE_GRAD_END = 0.56 - private val NOISE_SIMPLEX_ORE_START = 1.42f - private val NOISE_SIMPLEX_ORE_END = 1.28f + private val NOISE_SIMPLEX_ORE_START = 1.42 + private val NOISE_SIMPLEX_ORE_END = 1.28 private val HILL_WIDTH = 256 // power of two! //private val MAX_HILL_HEIGHT = 100 @@ -51,8 +51,8 @@ object WorldGenerator { private var GLACIER_MOUNTAIN_WIDTH = 900 private val GLACIER_MOUNTAIN_HEIGHT = 300 - private val CAVEGEN_THRE_START = 0.95f - private val CAVEGEN_THRE_END = 0.67f + private val CAVEGEN_THRE_START = 0.95 + private val CAVEGEN_THRE_END = 0.67 private var worldOceanPosition: Int = -1 @@ -113,12 +113,12 @@ object WorldGenerator { */ val noiseArray = arrayOf( - TaggedJoise("Carving caves", noiseRidged(1.7f, 1.4f), 1f, TILE_MACRO_ALL, TILE_MACRO_ALL, Tile.AIR, NoiseFilterSqrt, CAVEGEN_THRE_START, CAVEGEN_THRE_END) - , TaggedJoise("Collapsing caves", noiseBlobs(0.5f, 0.5f), 0.3f, Tile.AIR, Tile.STONE, Tile.STONE, NoiseFilterUniform) + TaggedJoise("Carving caves", noiseRidged(1.7, 1.4), 1.0, TILE_MACRO_ALL, TILE_MACRO_ALL, Tile.AIR, NoiseFilterSqrt, CAVEGEN_THRE_START, CAVEGEN_THRE_END) + , TaggedJoise("Collapsing caves", noiseBlobs(0.5), 0.3, Tile.AIR, Tile.STONE, Tile.STONE, NoiseFilterUniform) // - //, TaggedJoise("Putting stone patches on the ground", noiseBlobs(0.8f, 0.8f), 1.02f, intArrayOf(Tile.DIRT, Tile.GRASS), Tile.DIRT, Tile.STONE, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) - //, TaggedJoise("Placing dirt spots in the cave", noiseBlobs(0.5f, 0.5f), 0.98f, Tile.STONE, Tile.STONE, Tile.DIRT, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) - //, TaggedJoise("Quarrying some stone into gravels", noiseBlobs(0.5f, 0.5f), 0.98f, Tile.STONE, Tile.STONE, Tile.GRAVEL, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) + //, TaggedJoise("Putting stone patches on the ground", noiseBlobs(0.8), 1.02f, intArrayOf(Tile.DIRT, Tile.GRASS), Tile.DIRT, Tile.STONE, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) + //, TaggedJoise("Placing dirt spots in the cave", noiseBlobs(0.5), 0.98f, Tile.STONE, Tile.STONE, Tile.DIRT, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) + //, TaggedJoise("Quarrying some stone into gravels", noiseBlobs(0.5), 0.98f, Tile.STONE, Tile.STONE, Tile.GRAVEL, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) // //, TaggedJoise("Growing copper veins", noiseRidged(1.7f, 1.7f), 1.68f, Tile.STONE, Tile.STONE, Tile.ORE_COPPER) //, TaggedJoise("Cutting copper veins", noiseBlobs(0.4f, 0.4f), 0.26f, Tile.ORE_COPPER, Tile.STONE, Tile.STONE) @@ -165,7 +165,7 @@ object WorldGenerator { /* 1. Raise */ - private fun noiseRidged(xStretch: Float, yStretch: Float): Joise { + private fun noiseRidged(xStretch: Double, yStretch: Double): Joise { val ridged = ModuleFractal() ridged.setType(ModuleFractal.FractalType.RIDGEMULTI) ridged.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC) @@ -185,18 +185,21 @@ object WorldGenerator { return Joise(ridged_scale) } - private fun noiseBlobs(xStretch: Float, yStretch: Float): Joise { - val gradval = ModuleBasisFunction() - gradval.seed = SEED xor random.nextLong() - gradval.setType(ModuleBasisFunction.BasisType.GRADVAL) - gradval.setInterpolation(ModuleBasisFunction.InterpolationType.QUINTIC) + private fun noiseBlobs(frequency: Double): Joise { + val ridged = ModuleFractal() + ridged.setType(ModuleFractal.FractalType.FBM) + ridged.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC) + ridged.setNumOctaves(2) + ridged.setFrequency(frequency) + ridged.seed = Random().nextLong() - val gradval_scale = ModuleScaleDomain() - gradval_scale.setScaleX(1.0 / xStretch) - gradval_scale.setScaleY(1.0 / yStretch) - gradval_scale.setSource(gradval) + val brownian_select = ModuleSelect() + brownian_select.setControlSource(ridged) + brownian_select.setThreshold(0.8) + brownian_select.setLowSource(0.0) + brownian_select.setHighSource(1.0) - return Joise(gradval_scale) + return Joise(ridged) } /** @@ -596,8 +599,8 @@ object WorldGenerator { */ private fun carveByMap(noisemap: Any, scarcity: Float, tile: Int, message: String, filter: NoiseFilter = NoiseFilterQuadratic, - filterStart: Float = NOISE_GRAD_START, - filterEnd: Float = NOISE_GRAD_END) { + filterStart: Double = NOISE_GRAD_START, + filterEnd: Double = NOISE_GRAD_END) { println("[mapgenerator] " + message) for (y in 0..HEIGHT - 1) { @@ -626,8 +629,8 @@ object WorldGenerator { private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, replaceTo: Int, message: String, filter: NoiseFilter = NoiseFilterQuadratic, - filterStart: Float = NOISE_GRAD_START, - filterEnd: Float = NOISE_GRAD_END) { + filterStart: Double = NOISE_GRAD_START, + filterEnd: Double = NOISE_GRAD_END) { println("[mapgenerator] " + message) for (y in 0..HEIGHT - 1) { @@ -657,8 +660,8 @@ object WorldGenerator { private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, tile: IntArray, message: String, filter: NoiseFilter = NoiseFilterQuadratic, - filterStart: Float = NOISE_GRAD_START, - filterEnd: Float = NOISE_GRAD_END) { + filterStart: Double = NOISE_GRAD_START, + filterEnd: Double = NOISE_GRAD_END) { println("[mapgenerator] " + message) for (y in 0..HEIGHT - 1) { @@ -953,10 +956,10 @@ object WorldGenerator { data class TaggedSimplexNoise(var noiseModule: SimplexNoise, var xStretch: Float, var yStretch: Float) data class TaggedJoise(var message: String, - var noiseModule: Joise, var scarcity: Float, + var noiseModule: Joise, var scarcity: Double, var replaceFromTerrain: Any, var replaceFromWall: Int, var replaceTo: Any, var filter: NoiseFilter = NoiseFilterQuadratic, - var filterArg1: Float = NOISE_GRAD_START, - var filterArg2: Float = NOISE_GRAD_END) + var filterArg1: Double = NOISE_GRAD_START, + var filterArg2: Double = NOISE_GRAD_END) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/tileproperties/TileCodex.kt b/src/net/torvald/terrarum/tileproperties/TileCodex.kt index 62e2f4fcc..ac9cd5700 100644 --- a/src/net/torvald/terrarum/tileproperties/TileCodex.kt +++ b/src/net/torvald/terrarum/tileproperties/TileCodex.kt @@ -12,16 +12,14 @@ import java.io.IOException */ object TileCodex { - private lateinit var tileProps: Array + private var tileProps: Array val CSV_PATH = "/net/torvald/terrarum/tileproperties/tileprop.csv" const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE init { - tileProps = Array(TILE_UNIQUE_MAX + 1, - {i -> TileProp() } - ) + tileProps = Array(TILE_UNIQUE_MAX + 1, { i -> TileProp() }) for (i in tileProps.indices) { tileProps[i] = TileProp() @@ -83,6 +81,7 @@ object TileCodex { prop.isSolid = boolVal(record, "solid") prop.isWallable = boolVal(record, "wall") prop.isFallable = boolVal(record, "fall") + prop.isVertFriction = boolVal(record, "fv") prop.dynamicLuminosityFunction = intVal(record, "dlfn") diff --git a/src/net/torvald/terrarum/tileproperties/TileProp.kt b/src/net/torvald/terrarum/tileproperties/TileProp.kt index 8631e5091..d8c1c6b5f 100644 --- a/src/net/torvald/terrarum/tileproperties/TileProp.kt +++ b/src/net/torvald/terrarum/tileproperties/TileProp.kt @@ -24,6 +24,7 @@ class TileProp { var isFluid: Boolean = false var isSolid: Boolean = false var isWallable: Boolean = false + var isVertFriction: Boolean = false /** * @param luminosity Raw RGB value, without alpha diff --git a/src/net/torvald/terrarum/tileproperties/TilePropCSV.kt b/src/net/torvald/terrarum/tileproperties/TilePropCSV.kt index d8fdd890e..649e742c2 100644 --- a/src/net/torvald/terrarum/tileproperties/TilePropCSV.kt +++ b/src/net/torvald/terrarum/tileproperties/TilePropCSV.kt @@ -5,137 +5,137 @@ package net.torvald.terrarum.tileproperties */ object TilePropCSV { operator fun invoke() = """ - "id";"dmg";"name" ; "opacity";"strength";"dsty";"mate";"fluid";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"dlfn";"vscs";"friction" - "0"; "0";"TILE_AIR" ; "8396808"; "0"; "1";"null"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"N/A";"4" - "1"; "0";"TILE_STONE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "0"; "0"; "0";"N/A";"16" - "1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "1"; "0"; "0";"N/A";"16" - "1"; "2";"TILE_STONE_TILE_WHITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "2"; "0"; "0";"N/A";"16" - "1"; "3";"TILE_STONE_BRICKS" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "3"; "0"; "0";"N/A";"16" - "2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400";"dirt"; "0"; "1"; "1"; "0"; "2"; "0"; "0"; "0";"N/A";"16" - "2"; "1";"TILE_GRASS" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "1"; "0"; "0";"N/A";"16" - "2"; "2";"TILE_FOLIAGE_GREEN" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "2"; "0"; "0";"N/A";"16" - "2"; "3";"TILE_FOLIAGE_LIME" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "3"; "0"; "0";"N/A";"16" - "2"; "4";"TILE_FOLIAGE_GOLD" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "4"; "0"; "0";"N/A";"16" - "2"; "5";"TILE_FOLIAGE_RED" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "5"; "0"; "0";"N/A";"16" - "2"; "6";"TILE_FOLIAGE_ICEBLUE" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "6"; "0"; "0";"N/A";"16" - "2"; "7";"TILE_FOLIAGE_PURPLE" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "7"; "0"; "0";"N/A";"16" - "3"; "0";"TILE_PLANK_NORMAL" ; "33587232"; "12"; "740";"wood"; "0"; "1"; "1"; "0"; "3"; "0"; "0"; "0";"N/A";"16" - "3"; "1";"TILE_PLANK_EBONY" ; "33587232"; "12";"1200";"wood"; "0"; "1"; "1"; "0"; "3"; "1"; "0"; "0";"N/A";"16" - "3"; "2";"TILE_PLANK_BIRCH" ; "33587232"; "12"; "670";"wood"; "0"; "1"; "1"; "0"; "3"; "2"; "0"; "0";"N/A";"16" - "3"; "3";"TILE_PLANK_BLOODROSE" ; "33587232"; "12"; "900";"wood"; "0"; "1"; "1"; "0"; "3"; "3"; "0"; "0";"N/A";"16" - "4"; "0";"TILE_TRUNK_NORMAL" ; "33587232"; "12"; "740";"wood"; "0"; "1"; "0"; "0"; "3"; "0"; "0"; "0";"N/A";"16" - "4"; "1";"TILE_TRUNK_EBONY" ; "33587232"; "12";"1200";"wood"; "0"; "1"; "0"; "0"; "3"; "1"; "0"; "0";"N/A";"16" - "4"; "2";"TILE_TRUNK_BIRCH" ; "33587232"; "12"; "670";"wood"; "0"; "1"; "0"; "0"; "3"; "2"; "0"; "0";"N/A";"16" - "4"; "3";"TILE_TRUNK_BLOODROSE" ; "33587232"; "12"; "900";"wood"; "0"; "1"; "0"; "0"; "3"; "3"; "0"; "0";"N/A";"16" - "5"; "0";"TILE_SAND" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "0"; "1"; "0";"N/A";"16" - "5"; "1";"TILE_SAND_WHITE" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "1"; "1"; "0";"N/A";"16" - "5"; "2";"TILE_SAND_RED" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "2"; "1"; "0";"N/A";"16" - "5"; "3";"TILE_SAND_DESERT" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "3"; "1"; "0";"N/A";"16" - "5"; "4";"TILE_SAND_BLACK" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "4"; "1"; "0";"N/A";"16" - "5"; "5";"TILE_SAND_GREEN" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "5"; "1"; "0";"N/A";"16" - "6"; "0";"TILE_GRAVEL" ; "33587232"; "6";"2400";"grvl"; "0"; "1"; "0"; "0"; "6"; "0"; "1"; "0";"N/A";"16" - "6"; "1";"TILE_GRAVEL_GREY" ; "33587232"; "6";"2400";"grvl"; "0"; "1"; "0"; "0"; "6"; "1"; "1"; "0";"N/A";"16" - "7"; "0";"TILE_ORE_MALACHITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "0"; "0"; "0";"N/A";"16" - "7"; "1";"TILE_ORE_HEMATITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "1"; "0"; "0";"N/A";"16" - "7"; "2";"TILE_ORE_NATURAL_GOLD" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "2"; "0"; "0";"N/A";"16" - "7"; "3";"TILE_ORE_NATURAL_SILVER" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "3"; "0"; "0";"N/A";"16" - "7"; "4";"TILE_ORE_RUTILE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "4"; "0"; "0";"N/A";"16" - "7"; "5";"TILE_ORE_AURICHALCUMITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "5"; "0"; "0";"N/A";"16" - "8"; "0";"TILE_GEM_RUBY" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "0"; "0"; "0";"N/A";"16" - "8"; "1";"TILE_GEM_EMERALD" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "1"; "0"; "0";"N/A";"16" - "8"; "2";"TILE_GEM_SAPPHIRE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "2"; "0"; "0";"N/A";"16" - "8"; "3";"TILE_GEM_TOPAZ" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "3"; "0"; "0";"N/A";"16" - "8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "4"; "0"; "0";"N/A";"16" - "8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "5"; "0"; "0";"N/A";"16" - "9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500";"snow"; "0"; "1"; "1"; "0"; "9"; "0"; "0"; "0";"N/A";"16" - "9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930";"icei"; "0"; "1"; "0"; "0"; "9"; "1"; "0"; "0";"N/A";"16" - "9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930";"icei"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "0";"N/A"; "4" - "9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720";"icex"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "0";"N/A"; "4" - "9"; "4";"TILE_GLASS_CRUDE" ; "3146755"; "1";"2500";"glas"; "0"; "1"; "1"; "0"; "9"; "4"; "0"; "0";"N/A";"16" - "9"; "5";"TILE_GLASS_CLEAN" ; "1049601"; "1";"2203";"glas"; "0"; "1"; "1"; "0"; "9"; "5"; "0"; "0";"N/A";"16" - "10"; "0";"TILE_PLATFORM_STONE" ; "8396808"; "1"; "N/A";"rock"; "0"; "0"; "0"; "0"; "10"; "0"; "0"; "0";"N/A";"16" - "10"; "1";"TILE_PLATFORM_WOODEN" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "1"; "0"; "0";"N/A";"16" - "10"; "2";"TILE_PLATFORM_EBONY" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "2"; "0"; "0";"N/A";"16" - "10"; "3";"TILE_PLATFORM_BIRCH" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "3"; "0"; "0";"N/A";"16" - "10"; "4";"TILE_PLATFORM_BLOODROSE" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "4"; "0"; "0";"N/A";"16" - "11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "267553792"; "11"; "0"; "0"; "1";"N/A";"16" - "11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0"; "1";"N/A";"16" - "12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "0"; "11"; "0"; "0"; "0";"N/A";"16" - "12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "0"; "11"; "1"; "0"; "0";"N/A";"16" - "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "239319274"; "13"; "0"; "0"; "0";"N/A";"16" - "13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "267607040"; "13"; "1"; "0"; "0";"N/A";"16" - "13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "267546624"; "13"; "2"; "0"; "0";"N/A";"16" - "13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0"; "0";"N/A";"16" - "13"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "246415543"; "13"; "4"; "0"; "0";"N/A";"16" - "13"; "5";"TILE_ILLUMINATOR_PURPLE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "191889643"; "13"; "5"; "0"; "0";"N/A";"16" - "13"; "6";"TILE_ILLUMINATOR_BLUE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "52479"; "13"; "6"; "0"; "0";"N/A";"16" - "13"; "7";"TILE_ILLUMINATOR_CYAN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "219391"; "13"; "7"; "0"; "0";"N/A";"16" - "13"; "8";"TILE_ILLUMINATOR_GREEN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "56884224"; "13"; "8"; "0"; "0";"N/A";"16" - "13"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "33660928"; "13"; "9"; "0"; "0";"N/A";"16" - "13"; "10";"TILE_ILLUMINATOR_BROWN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "89161728"; "13"; "10"; "0"; "0";"N/A";"16" - "13"; "11";"TILE_ILLUMINATOR_TAN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "157392948"; "13"; "11"; "0"; "0";"N/A";"16" - "13"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "198374589"; "13"; "12"; "0"; "0";"N/A";"16" - "13"; "13";"TILE_ILLUMINATOR_GREY_MED"; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "122803317"; "13"; "13"; "0"; "0";"N/A";"16" - "13"; "14";"TILE_ILLUMINATOR_GREY_DARK"; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "68224065"; "13"; "14"; "0"; "0";"N/A";"16" - "13"; "15";"TILE_ILLUMINATOR_BLACK" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "116392191"; "13"; "15"; "0"; "0";"N/A";"16" - "14"; "0";"TILE_ILLUMINATOR_WHITE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "0"; "0"; "0";"N/A";"16" - "14"; "1";"TILE_ILLUMINATOR_YELLOW" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "1"; "0"; "0";"N/A";"16" - "14"; "2";"TILE_ILLUMINATOR_ORANGE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "2"; "0"; "0";"N/A";"16" - "14"; "3";"TILE_ILLUMINATOR_RED" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "3"; "0"; "0";"N/A";"16" - "14"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "4"; "0"; "0";"N/A";"16" - "14"; "5";"TILE_ILLUMINATOR_PURPLE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "5"; "0"; "0";"N/A";"16" - "14"; "6";"TILE_ILLUMINATOR_BLUE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "6"; "0"; "0";"N/A";"16" - "14"; "7";"TILE_ILLUMINATOR_CYAN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "7"; "0"; "0";"N/A";"16" - "14"; "8";"TILE_ILLUMINATOR_GREEN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "8"; "0"; "0";"N/A";"16" - "14"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "9"; "0"; "0";"N/A";"16" - "14"; "10";"TILE_ILLUMINATOR_BROWN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "10"; "0"; "0";"N/A";"16" - "14"; "11";"TILE_ILLUMINATOR_TAN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "11"; "0"; "0";"N/A";"16" - "14"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "12"; "0"; "0";"N/A";"16" - "14"; "13";"TILE_ILLUMINATOR_GREY_MED"; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "13"; "0"; "0";"N/A";"16" - "14"; "14";"TILE_ILLUMINATOR_GREY_DARK";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "14"; "0"; "0";"N/A";"16" - "14"; "15";"TILE_ILLUMINATOR_BLACK" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "15"; "0"; "0";"N/A";"16" - "15"; "0";"TILE_SANDSTONE" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "0"; "0"; "0";"N/A";"16" - "15"; "1";"TILE_SANDSTONE_WHITE" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "1"; "0"; "0";"N/A";"16" - "15"; "2";"TILE_SANDSTONE_RED" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "2"; "0"; "0";"N/A";"16" - "15"; "3";"TILE_SANDSTONE_DESERT" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "3"; "0"; "0";"N/A";"16" - "15"; "4";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "4"; "0"; "0";"N/A";"16" - "15"; "5";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "5"; "0"; "0";"N/A";"16" - "16"; "0";"TILE_LANTERN_IRON_REGULAR"; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "266453040"; "16"; "0"; "0"; "0";"N/A";"16" - "16"; "1";"TILE_SUNSTONE" ; "33587232"; "0"; "N/A";"rock"; "0"; "1"; "0"; "0"; "16"; "1"; "0"; "2";"N/A";"16" - "16"; "2";"TILE_DAYLIGHT_CAPACITOR" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "0"; "0"; "16"; "2"; "0"; "3";"N/A";"16" -"254"; "0";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "1";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "2";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "3";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "4";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "5";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "6";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "7";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "8";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "9";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "10";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "11";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "12";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "13";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "14";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"254"; "15";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32";"16" -"255"; "0";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "1";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "2";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "3";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "4";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "5";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "6";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "7";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "8";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "9";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "10";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "11";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "12";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "13";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "14";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"255"; "15";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16";"16" -"256"; "0";"TILE_NULL" ; "0"; "-1";"2600";"null"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0";"N/A";"16" + "id";"dmg";"name" ; "opacity";"strength";"dsty";"mate";"fluid";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"dlfn";"vscs";"fv";"friction" + "0"; "0";"TILE_AIR" ; "8396808"; "0"; "1";"null"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "N/A"; "0";"4" + "1"; "0";"TILE_STONE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "0"; "0"; "0"; "N/A"; "0";"16" + "1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "1"; "0"; "0"; "N/A"; "0";"16" + "1"; "2";"TILE_STONE_TILE_WHITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "2"; "0"; "0"; "N/A"; "0";"16" + "1"; "3";"TILE_STONE_BRICKS" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "1"; "0"; "1"; "3"; "0"; "0"; "N/A"; "0";"16" + "2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400";"dirt"; "0"; "1"; "1"; "0"; "2"; "0"; "0"; "0"; "N/A"; "0";"16" + "2"; "1";"TILE_GRASS" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "1"; "0"; "0"; "N/A"; "0";"16" + "2"; "2";"TILE_FOLIAGE_GREEN" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "2"; "0"; "0"; "N/A"; "0";"16" + "2"; "3";"TILE_FOLIAGE_LIME" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "3"; "0"; "0"; "N/A"; "0";"16" + "2"; "4";"TILE_FOLIAGE_GOLD" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "4"; "0"; "0"; "N/A"; "0";"16" + "2"; "5";"TILE_FOLIAGE_RED" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "5"; "0"; "0"; "N/A"; "0";"16" + "2"; "6";"TILE_FOLIAGE_ICEBLUE" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "6"; "0"; "0"; "N/A"; "0";"16" + "2"; "7";"TILE_FOLIAGE_PURPLE" ; "33587232"; "6";"1400";"grss"; "0"; "1"; "1"; "0"; "2"; "7"; "0"; "0"; "N/A"; "0";"16" + "3"; "0";"TILE_PLANK_NORMAL" ; "33587232"; "12"; "740";"wood"; "0"; "1"; "1"; "0"; "3"; "0"; "0"; "0"; "N/A"; "0";"16" + "3"; "1";"TILE_PLANK_EBONY" ; "33587232"; "12";"1200";"wood"; "0"; "1"; "1"; "0"; "3"; "1"; "0"; "0"; "N/A"; "0";"16" + "3"; "2";"TILE_PLANK_BIRCH" ; "33587232"; "12"; "670";"wood"; "0"; "1"; "1"; "0"; "3"; "2"; "0"; "0"; "N/A"; "0";"16" + "3"; "3";"TILE_PLANK_BLOODROSE" ; "33587232"; "12"; "900";"wood"; "0"; "1"; "1"; "0"; "3"; "3"; "0"; "0"; "N/A"; "0";"16" + "4"; "0";"TILE_TRUNK_NORMAL" ; "33587232"; "12"; "740";"wood"; "0"; "1"; "0"; "0"; "3"; "0"; "0"; "0"; "N/A"; "0";"16" + "4"; "1";"TILE_TRUNK_EBONY" ; "33587232"; "12";"1200";"wood"; "0"; "1"; "0"; "0"; "3"; "1"; "0"; "0"; "N/A"; "0";"16" + "4"; "2";"TILE_TRUNK_BIRCH" ; "33587232"; "12"; "670";"wood"; "0"; "1"; "0"; "0"; "3"; "2"; "0"; "0"; "N/A"; "0";"16" + "4"; "3";"TILE_TRUNK_BLOODROSE" ; "33587232"; "12"; "900";"wood"; "0"; "1"; "0"; "0"; "3"; "3"; "0"; "0"; "N/A"; "0";"16" + "5"; "0";"TILE_SAND" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "0"; "1"; "0"; "N/A"; "0";"16" + "5"; "1";"TILE_SAND_WHITE" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "1"; "1"; "0"; "N/A"; "0";"16" + "5"; "2";"TILE_SAND_RED" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "2"; "1"; "0"; "N/A"; "0";"16" + "5"; "3";"TILE_SAND_DESERT" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "3"; "1"; "0"; "N/A"; "0";"16" + "5"; "4";"TILE_SAND_BLACK" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "4"; "1"; "0"; "N/A"; "0";"16" + "5"; "5";"TILE_SAND_GREEN" ; "33587232"; "6";"2400";"sand"; "0"; "1"; "0"; "0"; "5"; "5"; "1"; "0"; "N/A"; "0";"16" + "6"; "0";"TILE_GRAVEL" ; "33587232"; "6";"2400";"grvl"; "0"; "1"; "0"; "0"; "6"; "0"; "1"; "0"; "N/A"; "0";"16" + "6"; "1";"TILE_GRAVEL_GREY" ; "33587232"; "6";"2400";"grvl"; "0"; "1"; "0"; "0"; "6"; "1"; "1"; "0"; "N/A"; "0";"16" + "7"; "0";"TILE_ORE_MALACHITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "0"; "0"; "0"; "N/A"; "0";"16" + "7"; "1";"TILE_ORE_HEMATITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "1"; "0"; "0"; "N/A"; "0";"16" + "7"; "2";"TILE_ORE_NATURAL_GOLD" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "2"; "0"; "0"; "N/A"; "0";"16" + "7"; "3";"TILE_ORE_NATURAL_SILVER" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "3"; "0"; "0"; "N/A"; "0";"16" + "7"; "4";"TILE_ORE_RUTILE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "4"; "0"; "0"; "N/A"; "0";"16" + "7"; "5";"TILE_ORE_AURICHALCUMITE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "7"; "5"; "0"; "0"; "N/A"; "0";"16" + "8"; "0";"TILE_GEM_RUBY" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "0"; "0"; "0"; "N/A"; "0";"16" + "8"; "1";"TILE_GEM_EMERALD" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "1"; "0"; "0"; "N/A"; "0";"16" + "8"; "2";"TILE_GEM_SAPPHIRE" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "2"; "0"; "0"; "N/A"; "0";"16" + "8"; "3";"TILE_GEM_TOPAZ" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "3"; "0"; "0"; "N/A"; "0";"16" + "8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "4"; "0"; "0"; "N/A"; "0";"16" + "8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400";"rock"; "0"; "1"; "0"; "0"; "8"; "5"; "0"; "0"; "N/A"; "0";"16" + "9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500";"snow"; "0"; "1"; "1"; "0"; "9"; "0"; "0"; "0"; "N/A"; "0";"16" + "9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930";"icei"; "0"; "1"; "0"; "0"; "9"; "1"; "0"; "0"; "N/A"; "0";"16" + "9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930";"icei"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "0"; "N/A"; "0"; "4" + "9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720";"icex"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "0"; "N/A"; "0"; "4" + "9"; "4";"TILE_GLASS_CRUDE" ; "3146755"; "1";"2500";"glas"; "0"; "1"; "1"; "0"; "9"; "4"; "0"; "0"; "N/A"; "0";"16" + "9"; "5";"TILE_GLASS_CLEAN" ; "1049601"; "1";"2203";"glas"; "0"; "1"; "1"; "0"; "9"; "5"; "0"; "0"; "N/A"; "0";"16" + "10"; "0";"TILE_PLATFORM_STONE" ; "8396808"; "1"; "N/A";"rock"; "0"; "0"; "0"; "0"; "10"; "0"; "0"; "0"; "N/A"; "0";"16" + "10"; "1";"TILE_PLATFORM_WOODEN" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "1"; "0"; "0"; "N/A"; "0";"16" + "10"; "2";"TILE_PLATFORM_EBONY" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "2"; "0"; "0"; "N/A"; "0";"16" + "10"; "3";"TILE_PLATFORM_BIRCH" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "3"; "0"; "0"; "N/A"; "0";"16" + "10"; "4";"TILE_PLATFORM_BLOODROSE" ; "8396808"; "1"; "N/A";"wood"; "0"; "0"; "0"; "0"; "10"; "4"; "0"; "0"; "N/A"; "0";"16" + "11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "267553792"; "11"; "0"; "0"; "1"; "N/A"; "0";"16" + "11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0"; "1"; "N/A"; "0";"16" + "12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "0"; "11"; "0"; "0"; "0"; "N/A"; "0";"16" + "12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "0"; "11"; "1"; "0"; "0"; "N/A"; "0";"16" + "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "239319274"; "13"; "0"; "0"; "0"; "N/A"; "0";"16" + "13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "267607040"; "13"; "1"; "0"; "0"; "N/A"; "0";"16" + "13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "267546624"; "13"; "2"; "0"; "0"; "N/A"; "0";"16" + "13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0"; "0"; "N/A"; "0";"16" + "13"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "246415543"; "13"; "4"; "0"; "0"; "N/A"; "0";"16" + "13"; "5";"TILE_ILLUMINATOR_PURPLE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "191889643"; "13"; "5"; "0"; "0"; "N/A"; "0";"16" + "13"; "6";"TILE_ILLUMINATOR_BLUE" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "52479"; "13"; "6"; "0"; "0"; "N/A"; "0";"16" + "13"; "7";"TILE_ILLUMINATOR_CYAN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "219391"; "13"; "7"; "0"; "0"; "N/A"; "0";"16" + "13"; "8";"TILE_ILLUMINATOR_GREEN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "56884224"; "13"; "8"; "0"; "0"; "N/A"; "0";"16" + "13"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "33660928"; "13"; "9"; "0"; "0"; "N/A"; "0";"16" + "13"; "10";"TILE_ILLUMINATOR_BROWN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "89161728"; "13"; "10"; "0"; "0"; "N/A"; "0";"16" + "13"; "11";"TILE_ILLUMINATOR_TAN" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "157392948"; "13"; "11"; "0"; "0"; "N/A"; "0";"16" + "13"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "198374589"; "13"; "12"; "0"; "0"; "N/A"; "0";"16" + "13"; "13";"TILE_ILLUMINATOR_GREY_MED"; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "122803317"; "13"; "13"; "0"; "0"; "N/A"; "0";"16" + "13"; "14";"TILE_ILLUMINATOR_GREY_DARK"; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "68224065"; "13"; "14"; "0"; "0"; "N/A"; "0";"16" + "13"; "15";"TILE_ILLUMINATOR_BLACK" ; "8396808"; "0"; "N/A";"glas"; "0"; "1"; "1"; "116392191"; "13"; "15"; "0"; "0"; "N/A"; "0";"16" + "14"; "0";"TILE_ILLUMINATOR_WHITE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "0"; "0"; "0"; "N/A"; "0";"16" + "14"; "1";"TILE_ILLUMINATOR_YELLOW" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "1"; "0"; "0"; "N/A"; "0";"16" + "14"; "2";"TILE_ILLUMINATOR_ORANGE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "2"; "0"; "0"; "N/A"; "0";"16" + "14"; "3";"TILE_ILLUMINATOR_RED" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "3"; "0"; "0"; "N/A"; "0";"16" + "14"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "4"; "0"; "0"; "N/A"; "0";"16" + "14"; "5";"TILE_ILLUMINATOR_PURPLE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "5"; "0"; "0"; "N/A"; "0";"16" + "14"; "6";"TILE_ILLUMINATOR_BLUE" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "6"; "0"; "0"; "N/A"; "0";"16" + "14"; "7";"TILE_ILLUMINATOR_CYAN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "7"; "0"; "0"; "N/A"; "0";"16" + "14"; "8";"TILE_ILLUMINATOR_GREEN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "8"; "0"; "0"; "N/A"; "0";"16" + "14"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "9"; "0"; "0"; "N/A"; "0";"16" + "14"; "10";"TILE_ILLUMINATOR_BROWN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "10"; "0"; "0"; "N/A"; "0";"16" + "14"; "11";"TILE_ILLUMINATOR_TAN" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "11"; "0"; "0"; "N/A"; "0";"16" + "14"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "12"; "0"; "0"; "N/A"; "0";"16" + "14"; "13";"TILE_ILLUMINATOR_GREY_MED"; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "13"; "0"; "0"; "N/A"; "0";"16" + "14"; "14";"TILE_ILLUMINATOR_GREY_DARK";"33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "14"; "0"; "0"; "N/A"; "0";"16" + "14"; "15";"TILE_ILLUMINATOR_BLACK" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "1"; "0"; "13"; "15"; "0"; "0"; "N/A"; "0";"16" + "15"; "0";"TILE_SANDSTONE" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "0"; "0"; "0"; "N/A"; "0";"16" + "15"; "1";"TILE_SANDSTONE_WHITE" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "1"; "0"; "0"; "N/A"; "0";"16" + "15"; "2";"TILE_SANDSTONE_RED" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "2"; "0"; "0"; "N/A"; "0";"16" + "15"; "3";"TILE_SANDSTONE_DESERT" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "3"; "0"; "0"; "N/A"; "0";"16" + "15"; "4";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "4"; "0"; "0"; "N/A"; "0";"16" + "15"; "5";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900";"rock"; "0"; "1"; "1"; "0"; "15"; "5"; "0"; "0"; "N/A"; "0";"16" + "16"; "0";"TILE_LANTERN_IRON_REGULAR"; "8396808"; "0"; "N/A";"fxtr"; "0"; "0"; "0"; "266453040"; "16"; "0"; "0"; "0"; "N/A"; "0";"16" + "16"; "1";"TILE_SUNSTONE" ; "33587232"; "0"; "N/A";"rock"; "0"; "1"; "0"; "0"; "16"; "1"; "0"; "2"; "N/A"; "0";"16" + "16"; "2";"TILE_DAYLIGHT_CAPACITOR" ; "33587232"; "0"; "N/A";"glas"; "0"; "1"; "0"; "0"; "16"; "2"; "0"; "3"; "N/A"; "0";"16" +"254"; "0";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "1";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "2";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "3";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "4";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "5";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "6";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "7";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "8";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "9";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "10";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "11";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "12";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "13";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "14";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"254"; "15";"TILE_LAVA" ;"260301048"; "100";"2600";"rock"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0"; "0"; "32"; "0";"16" +"255"; "0";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "1";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "2";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "3";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "4";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "5";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "6";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "7";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "8";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "9";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "10";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "11";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "12";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "13";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "14";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"255"; "15";"TILE_WATER" ; "27282445"; "100";"1000";"watr"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "16"; "0";"16" +"256"; "0";"TILE_NULL" ; "0"; "-1";"2600";"null"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0"; "0"; "N/A"; "0";"16" ## Notes ## @@ -155,6 +155,8 @@ object TilePropCSV { # mate: material, four-letter code +# fv: vertical friction (boolean) + ## Illuminators ## diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index 6670350b1..bc73e1e90 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -65,7 +65,12 @@ class ConsoleWindow : UICanvas, KeyboardControlled { // text and cursor g.color = Color.white g.drawString(input, 1f + drawOffX, drawOffY) + + g.color = Color(0x7f7f7f) g.fillRect(inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 2f, inputDrawHeight.toFloat()) + g.color = Color.white + g.fillRect(inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 1f, inputDrawHeight.toFloat() - 1) + // messages for (i in 0..MESSAGES_DISPLAY_COUNT - 1) { @@ -85,13 +90,13 @@ class ConsoleWindow : UICanvas, KeyboardControlled { historyIndex = -1 // execute - if (key == Key.RETURN && commandInputPool!!.length > 0) { + if (key == Key.RETURN && commandInputPool!!.isNotEmpty()) { commandHistory.add(commandInputPool!!.toString()) executeCommand() commandInputPool = StringBuilder() } // erase last letter - else if (key == Key.BACKSPACE && commandInputPool!!.length > 0) { + else if (key == Key.BACKSPACE && commandInputPool!!.isNotEmpty()) { commandInputPool!!.deleteCharAt(commandInputPool!!.length - 1) } // append acceptable letter diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 3b8ad28d0..39f702fb7 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -7,6 +7,9 @@ import net.torvald.random.HQRNG import net.torvald.terrarum.Terrarum import net.torvald.terrarum.blendMul import net.torvald.terrarum.blendNormal +import net.torvald.terrarum.gameactors.ParticleTestRain +import net.torvald.terrarum.gamecontroller.Key +import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gameworld.WorldTime import net.torvald.terrarum.getPixel import org.newdawn.slick.Color @@ -76,6 +79,16 @@ object WeatherMixer { fun update(gc: GameContainer, delta: Int) { currentWeather = weatherList[WEATHER_GENERIC]!![0] + // test rain toggled by F2 + + if (KeyToggler.isOn(Key.F2)) { + val playerPos = Terrarum.ingame.player.centrePosPoint + val rainParticle = ParticleTestRain( + playerPos.x + HQRNG().nextInt(Terrarum.WIDTH) - Terrarum.HALFW, + playerPos.y - Terrarum.HALFH + ) + Terrarum.ingame.addActor(rainParticle) + } } fun render(g: Graphics) {