From c4ad69525bee778d136f74a7807e39586f8c2453 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Fri, 17 Jun 2016 01:39:55 +0900 Subject: [PATCH] TilePropCodex is now object, torch flicker (WIP as all the torches are in unison) Former-commit-id: df9c0e3a9ace2ba976da5e81f1f2d2217db541a0 Former-commit-id: 81a25a938023f318937e1f4ded15e6047fdf8864 --- res/locales/helpOnTheFly.csv | 6 +- src/net/torvald/random/HQRNG.java | 59 ------- src/net/torvald/random/HQRNG.kt | 57 +++++++ src/net/torvald/terrarum/DefaultConfig.kt | 4 +- src/net/torvald/terrarum/Game.kt | 3 - .../torvald/terrarum/concurrent/ThreadPool.kt | 24 ++- .../torvald/terrarum/console/CommandDict.kt | 1 + src/net/torvald/terrarum/console/Seed.kt | 23 +++ .../terrarum/gameactors/ActorWithBody.kt | 8 +- .../gameactors/faction/FactionCodex.kt | 4 +- src/net/torvald/terrarum/gamemap/GameMap.kt | 2 + .../terrarum/itemproperties/ItemPropCodex.kt | 2 +- .../terrarum/mapdrawer/LightmapRenderer.kt | 69 +++++--- .../terrarum/mapgenerator/MapGenerator.kt | 43 ++--- .../mapgenerator/ThreadProcessNoiseLayers.kt | 12 +- .../terrarum/tileproperties/TileProp.kt | 5 +- .../terrarum/tileproperties/TilePropCodex.kt | 149 +++++++++--------- .../terrarum/tileproperties/TilePropUtil.kt | 57 +++++++ .../terrarum/tileproperties/tileprop.csv | 6 +- .../terrarum/ui/BasicDebugInfoWindow.kt | 19 +-- 20 files changed, 347 insertions(+), 206 deletions(-) delete mode 100644 src/net/torvald/random/HQRNG.java create mode 100644 src/net/torvald/random/HQRNG.kt create mode 100644 src/net/torvald/terrarum/console/Seed.kt create mode 100644 src/net/torvald/terrarum/tileproperties/TilePropUtil.kt diff --git a/res/locales/helpOnTheFly.csv b/res/locales/helpOnTheFly.csv index 9f1ef04cd..dd4f246c4 100644 --- a/res/locales/helpOnTheFly.csv +++ b/res/locales/helpOnTheFly.csv @@ -4,9 +4,9 @@ "HELP_OTF_MAIN_2";;"Press PageUp/PageDown to scroll the messages.";"Appuyez sur PageUp/PageDown pour faire défiler les messages.";;;;;;;;;;;;;;;"PageUp/PageDownキーを使ってメッセージのスクロールができます。";;;"PageUp/PageDown 키를 사용해 메시지를 스크롤할 수 있습니다.";;;;;;"PageUp/PageDownキーをつかって メッセージのスクロールができます。" "HELP_OTF_MAIN_3";;"Utility keys:";"Touches utilitaires:";;;;;;;;;;;;;;;"技能キー";;;"기능 키:" "HELP_OTF_MAIN_4";;"• F3: (debug) basic information";"• F3: (déboguer) informations de base";;;;;;;;;;;;;;;"• F3: (デバッグ)基本的な情報を見る";;;"• F3: (디버그) 기본 정보";;;;;;"• F3: (デバッグ)きほんてきな じょうほうを みる" -"HELP_OTF_MAIN_5";;"• F7: (debug) toggle light blending";"• F7: (déboguer) basculer fusion de lumière";;;;;;;;;;;;;;;"• F7: (デバッグ)光源のブレンドをオン・オフする";;;"• F7: (디버그) 광원 블렌딩 켜고 끄기";;;;;;"• F7: (デバッグ)こうげんのブレンドを オン・オフする" -"HELP_OTF_MAIN_6";;"• F8: toggle smooth lighting effect";"• F8: basculer effet éclairage lisse";;;;;;;;;;;;;;;"• F8: すべすべの光源効果をオン・オフする";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: すべすべのこうげん こうかを オン・オフする" -"HELP_OTF_MAIN_JP_1";;"• F4: toggle Kana/Kanji mode";;;;;;;;;;;;;;;;"• F8: 【日本語】かな・漢字モードを変換する";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: 【日本語】かな・かんじモードを" +"HELP_OTF_MAIN_5";;"• F7: (debug) toggle light blending";"• F7: (déboguer) basculer fusion de lumière";;;;;;;;;;;;;;;"• F7: (デバッグ)光源のブレンド オン・オフ";;;"• F7: (디버그) 광원 블렌딩 켜고 끄기";;;;;;"• F7: (デバッグ)こうげんのブレンド オン・オフ" +"HELP_OTF_MAIN_6";;"• F8: toggle smooth lighting effect";"• F8: basculer effet éclairage lisse";;;;;;;;;;;;;;;"• F8: すべすべの光源効果 オン・オフ";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: すべすべのこうげん こうか オン・オフ" +"HELP_OTF_MAIN_JP_1";;"• F4: toggle Kana/Kanji mode";;;;;;;;;;;;;;;;"• F8: 【日本語】かな・漢字モード変換";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: 【日本語】かな・かんじモードを" "HELP_OTF_SLOW_1";;"If your game runs slowly:";"Si votre jeu tourne lentement :";;;;;;;;;;;;;;;"ゲームの実行がおそければ";;;"게임이 느리게 돌아간다면";;;;;;"ゲームのじっこうが おそければ" "HELP_OTF_SLOW_2";;"• Reset screen zoom to 1.";"• Réinitialisez le zoom de l‘écran à 1.";;;;;;;;;;;;;;;"• スクリーンのズームを1倍にリセットしてください。";;;"• 화면 줌을 1로 돌려주세요. ";;;;;;"• スクリーンのズームを 1にリセットしてください。" diff --git a/src/net/torvald/random/HQRNG.java b/src/net/torvald/random/HQRNG.java deleted file mode 100644 index 539be8491..000000000 --- a/src/net/torvald/random/HQRNG.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.torvald.random; - -import java.util.Random; -//import java.util.concurrent.locks.*; - -/** - * This class implements a better random number generator than the standard LCG that is implemented in java.util.Random. - * It is based on Numerical Recipes: The Art of Scientific Computing, - * and gives a good compromise between quality and speed. It is a combined generator: two XORShift generators are combined with an LCG and a multiply with carry generator. - * (Without going into all the details here, notice the two blocks of three shifts each, which are the XORShifts; the first line which is the LCG, similar to the standard - * Java Random algorithm, and the line between the two XORShifts, which is a multiply with carry generator.) - * Note that this version is not thread-safe. In order to make it thread-safe, uncomment the lock-related lines. It is also not cryptographically secure, like the java.security.SecureRandom class. - * @author Numerical Recipes - */ - -public class HQRNG extends Random { - - //private Lock l = new ReentrantLock(); - private long u; - private long v = 4101842887655102017L; - private long w = 1; - - public HQRNG() { - this(System.nanoTime()); - } - public HQRNG(long seed) { - //l.lock(); - u = seed ^ v; - nextLong(); - v = u; - nextLong(); - w = v; - nextLong(); - //l.unlock(); - } - - public long nextLong() { - // l.lock(); - try { - u = u * 2862933555777941757L + 7046029254386353087L; - v ^= v >>> 17; - v ^= v << 31; - v ^= v >>> 8; - w = 4294957665L * (w & 0xffffffff) + (w >>> 32); - long x = u ^ (u << 21); - x ^= x >>> 35; - x ^= x << 4; - long ret = (x + v) ^ w; - return ret; - } finally { - //l.unlock(); - } - } - - protected int next(int bits) { - return (int) (nextLong() >>> (64-bits)); - } - -} \ No newline at end of file diff --git a/src/net/torvald/random/HQRNG.kt b/src/net/torvald/random/HQRNG.kt new file mode 100644 index 000000000..e981694b3 --- /dev/null +++ b/src/net/torvald/random/HQRNG.kt @@ -0,0 +1,57 @@ +package net.torvald.random + +import java.util.Random + +//import java.util.concurrent.locks.*; + +/** + * This class implements a better random number generator than the standard LCG that is implemented in java.util.Random. + * It is based on [Numerical Recipes: The Art of Scientific Computing](http://www.amazon.com/gp/product/0521880688?ie=UTF8&tag=javamex-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0521880688), + * and gives a good compromise between quality and speed. It is a combined generator: two XORShift generators are combined with an LCG and a multiply with carry generator. + * (Without going into all the details here, notice the two blocks of three shifts each, which are the XORShifts; the first line which is the LCG, similar to the standard + * Java Random algorithm, and the line between the two XORShifts, which is a multiply with carry generator.) + * Note that this version is **not** thread-safe. In order to make it thread-safe, uncomment the lock-related lines. It is also **not** cryptographically secure, like the java.security.SecureRandom class. + * @author Numerical Recipes + */ + +class HQRNG @JvmOverloads constructor(seed: Long = System.nanoTime()) : Random() { + + //private Lock l = new ReentrantLock(); + private var u: Long = 0 + private var v = 4101842887655102017L + private var w: Long = 1 + + init { + //l.lock(); + u = seed xor v + nextLong() + v = u + nextLong() + w = v + nextLong() + //l.unlock(); + } + + override fun nextLong(): Long { + // l.lock(); + try { + u = u * 2862933555777941757L + 7046029254386353087L + v = v xor v.ushr(17) + v = v xor v.shl(31) + v = v xor v.ushr(8) + w = 4294957665L * w.and(0xffffffffL) + w.ushr(32) + var x = u xor u.shl(21) + x = x xor x.ushr(35) + x = x xor x.shl(4) + return x + v xor w + } + finally { + //l.unlock(); + } + } + + override fun next(bits: Int): Int { + return nextLong().ushr(64 - bits).toInt() + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index 046ab5005..c73fa35aa 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -10,10 +10,10 @@ object DefaultConfig { val jsonObject = JsonObject() jsonObject.addProperty("smoothlighting", true) - jsonObject.addProperty("imtooyoungtodie", false) + jsonObject.addProperty("imtooyoungtodie", false) // perma-death jsonObject.addProperty("language", Terrarum.sysLang) jsonObject.addProperty("notificationshowuptime", 6500) - jsonObject.addProperty("multithread", false) // experimental! + jsonObject.addProperty("multithread", true) // experimental! return jsonObject } diff --git a/src/net/torvald/terrarum/Game.kt b/src/net/torvald/terrarum/Game.kt index 61384a8b0..4b876aeaa 100644 --- a/src/net/torvald/terrarum/Game.kt +++ b/src/net/torvald/terrarum/Game.kt @@ -99,9 +99,6 @@ constructor() : BasicGameState() { GRADIENT_IMAGE = Image("res/graphics/colourmap/sky_colour.png") skyBox = Rectangle(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat()) - TilePropCodex() - // new ItemPropCodex() -- This is kotlin object and already initialised. - map = GameMap(8192, 2048) MapGenerator.attachMap(map) diff --git a/src/net/torvald/terrarum/concurrent/ThreadPool.kt b/src/net/torvald/terrarum/concurrent/ThreadPool.kt index a0e7768df..84358509f 100644 --- a/src/net/torvald/terrarum/concurrent/ThreadPool.kt +++ b/src/net/torvald/terrarum/concurrent/ThreadPool.kt @@ -7,15 +7,17 @@ import java.util.* * Created by minjaesong on 16-05-25. */ object ThreadPool { - private val pool = Array(Terrarum.CORES, { Thread() }) - val POOL_SIZE = Terrarum.CORES + val POOL_SIZE = Terrarum.CORES + 1 + + private val pool: Array = Array(POOL_SIZE, { null }) /** + * Map array of Runnable objects to thread pool. * @param prefix : will name each thread as "Foo-1" * @param runnables : vararg */ - fun mapAll(prefix: String, vararg runnables: Runnable) { - if (runnables.size != Terrarum.CORES) + fun mapAll(prefix: String, runnables: Array) { + if (runnables.size != POOL_SIZE) throw RuntimeException("Thread pool argument size mismatch. If you have four cores, you must use four runnables.") for (i in 0..runnables.size) @@ -23,6 +25,7 @@ object ThreadPool { } /** + * Map Runnable object to certain index of the thread pool. * @param index of the runnable * @param runnable * @param prefix Will name each thread like "Foo-1", "Foo-2", etc. @@ -31,7 +34,18 @@ object ThreadPool { pool[index] = Thread(runnable, "$prefix-$index") } + /** + * Fill the thread pool with NULL value. + */ + fun purge() { + for (i in 0..POOL_SIZE) + pool[i] = null + } + + /** + * Start all thread in the pool. If the thread in the pool is NULL, it will simply ignored. + */ fun startAll() { - pool.forEach { it.start() } + pool.forEach { it?.start() } } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 2b84daf9a..da4aa5bda 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -37,6 +37,7 @@ object CommandDict { Pair("settimedelta", SetTimeDelta()), Pair("help", Help()), Pair("version", Version()), + Pair("seed", Seed()), // Test codes Pair("bulletintest", SetBulletin()), diff --git a/src/net/torvald/terrarum/console/Seed.kt b/src/net/torvald/terrarum/console/Seed.kt new file mode 100644 index 000000000..12f508375 --- /dev/null +++ b/src/net/torvald/terrarum/console/Seed.kt @@ -0,0 +1,23 @@ +package net.torvald.terrarum.console + +import net.torvald.imagefont.GameFontBase +import net.torvald.terrarum.Terrarum + +/** + * Created by minjaesong on 16-06-16. + */ +class Seed : ConsoleCommand { + val ccG = GameFontBase.colToCode["g"] + val ccW = GameFontBase.colToCode["w"] + val ccY = GameFontBase.colToCode["y"] + // tsalagi + + override fun execute(args: Array) { + Echo().execute("${ccY}Map$ccW: $ccG${Terrarum.game.map.generatorSeed}") + // TODO display randomiser seed + } + + override fun printUsage() { + Echo().execute("prints out the generator seed of the current game.") + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index e4f2f36d3..1055543eb 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -546,13 +546,17 @@ open class ActorWithBody constructor() : Actor(), Visible { if (!isNoCollideWorld){ val delta: Vector2 = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place val ccdDelta = delta.setMagnitude(CCD_TICK) + val ccdTryMax = 400 + var ccdCount = 0 //if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation // CCD to delta while still colliding - while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT) - || isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM) + while ((isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT) + || isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)) + && ccdCount < ccdTryMax ) { nextHitbox.translate(ccdDelta) + ccdCount += 1 } //} /*else { // stuck while standing still diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt b/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt index 166efdb59..f5160b256 100644 --- a/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt +++ b/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt @@ -33,9 +33,9 @@ object FactionCodex { } private fun insertionSortLastElem(arr: ArrayList) { - var x: Faction + val x: Faction var j: Int - var index: Int = arr.size - 1 + val index: Int = arr.size - 1 x = arr[index] j = index - 1 while (j > 0 && arr[j] > x) { diff --git a/src/net/torvald/terrarum/gamemap/GameMap.kt b/src/net/torvald/terrarum/gamemap/GameMap.kt index 236c439b2..f3ff5dae5 100644 --- a/src/net/torvald/terrarum/gamemap/GameMap.kt +++ b/src/net/torvald/terrarum/gamemap/GameMap.kt @@ -38,6 +38,8 @@ constructor(//properties var globalLight: Int = 0 val worldTime: WorldTime + var generatorSeed: Long = 0 + init { this.spawnX = width / 2 this.spawnY = 200 diff --git a/src/net/torvald/terrarum/itemproperties/ItemPropCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemPropCodex.kt index 732f2af2d..20b3faa01 100644 --- a/src/net/torvald/terrarum/itemproperties/ItemPropCodex.kt +++ b/src/net/torvald/terrarum/itemproperties/ItemPropCodex.kt @@ -21,7 +21,7 @@ object ItemPropCodex { const val ITEM_UNIQUE_MAX = 32768 - fun buildItemProp() { + init { itemCodex = arrayOf() // read prop in csv diff --git a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt index eab6e4201..68fde40df 100644 --- a/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt +++ b/src/net/torvald/terrarum/mapdrawer/LightmapRenderer.kt @@ -7,6 +7,7 @@ import net.torvald.terrarum.tileproperties.TilePropCodex import com.jme3.math.FastMath import net.torvald.terrarum.gameactors.Visible import net.torvald.terrarum.tileproperties.TileNameCode +import net.torvald.terrarum.tileproperties.TilePropUtil import org.newdawn.slick.Color import org.newdawn.slick.Graphics import java.util.* @@ -40,6 +41,7 @@ object LightmapRenderer { // color model related constants const val MUL = 1024 // modify this to 1024 to implement 30-bit RGB + const val CHANNEL_MAX_DECIMAL = 4f const val MUL_2 = MUL * MUL const val CHANNEL_MAX = MUL - 1 const val CHANNEL_MAX_FLOAT = CHANNEL_MAX.toFloat() @@ -206,6 +208,8 @@ object LightmapRenderer { setLight(x, y, calculate(x, y)) } } + + TilePropUtil.torchFlickerTickClock() } catch (e: ArrayIndexOutOfBoundsException) { } @@ -422,33 +426,44 @@ object LightmapRenderer { /** * Subtract each channel's RGB value. * - * It works like: - * - * f(data, darken) = RGB(data.r - darken.r, data.g - darken.g, data.b - darken.b) - * - * @param data Raw channel value (0-39) per channel - * @param darken (0-39) per channel - * @return darkened data (0-39) per channel + * @param data Raw channel value (0-255) per channel + * @param darken (0-255) per channel + * @return darkened data (0-255) per channel */ fun darkenColoured(data: Int, darken: Int): Int { if (darken.toInt() < 0 || darken.toInt() >= COLOUR_RANGE_SIZE) throw IllegalArgumentException("darken: out of range ($darken)") - var r = data.r() * (1f - darken.r() * 6) // 6: Arbitrary value - var g = data.g() * (1f - darken.g() * 6) // TODO gamma correction? - var b = data.b() * (1f - darken.b() * 6) + val r = data.r() * (1f - darken.r() * 6) // 6: Arbitrary value + val g = data.g() * (1f - darken.g() * 6) // TODO gamma correction? + val b = data.b() * (1f - darken.b() * 6) return constructRGBFromFloat(r.clampZero(), g.clampZero(), b.clampZero()) } + /** + * Add each channel's RGB value. + * + * @param data Raw channel value (0-255) per channel + * @param brighten (0-255) per channel + * @return brightened data (0-255) per channel + */ + fun brightenColoured(data: Int, brighten: Int): Int { + if (brighten.toInt() < 0 || brighten.toInt() >= COLOUR_RANGE_SIZE) + throw IllegalArgumentException("brighten: out of range ($brighten)") + + val r = data.r() * (1f + brighten.r() * 6) // 6: Arbitrary value + val g = data.g() * (1f + brighten.g() * 6) // TODO gamma correction? + val b = data.b() * (1f + brighten.b() * 6) + + return constructRGBFromFloat(r.clampChannel(), g.clampChannel(), b.clampChannel()) + } + /** * Darken each channel by 'darken' argument * - * It works like: - * - * f(data, darken) = RGB(data.r - darken, data.g - darken, data.b - darken) - * @param data (0-39) per channel - * @param darken (0-39) + * @param data Raw channel value (0-255) per channel + * @param darken (0-255) * @return */ fun darkenUniformInt(data: Int, darken: Int): Int { @@ -459,11 +474,27 @@ object LightmapRenderer { return darkenColoured(data, darkenColoured) } + /** + * Darken or brighten colour by 'brighten' argument + * + * @param data Raw channel value (0-255) per channel + * @param brighten (-1.0 - 1.0) negative means darkening + * @return processed colour + */ + fun brightenUniform(data: Int, brighten: Float): Int { + val modifier = if (brighten < 0) + constructRGBFromFloat(-brighten, -brighten, -brighten) + else + constructRGBFromFloat(brighten, brighten, brighten) + return if (brighten < 0) + darkenColoured(data, modifier) + else + brightenColoured(data, modifier) + } + /** Get each channel from two RGB values, return new RGB that has max value of each channel * @param rgb - * * * @param rgb2 - * * * @return */ private fun maximiseRGB(rgb: Int, rgb2: Int): Int { @@ -505,9 +536,7 @@ object LightmapRenderer { /** * @param RGB - * * * @param offset 2 = R, 1 = G, 0 = B - * * * @return */ fun getRaw(RGB: Int, offset: Int): Int { @@ -559,6 +588,8 @@ object LightmapRenderer { private fun Float.clampOne() = if (this < 0) 0f else if (this > 1) 1f else this + private fun Float.clampChannel() = if (this > CHANNEL_MAX_DECIMAL) CHANNEL_MAX_DECIMAL else this + fun getValueFromMap(x: Int, y: Int): Int? = getLight(x, y) private fun purgeLightmap() { diff --git a/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt b/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt index 1ca88f9a8..136eb87e6 100644 --- a/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt +++ b/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt @@ -17,6 +17,10 @@ object MapGenerator { internal lateinit var random: Random //private static float[] noiseArray; var SEED: Long = 0 + set(value) { + field = value + map.generatorSeed = value + } var WIDTH: Int = 0 var HEIGHT: Int = 0 @@ -107,36 +111,35 @@ object MapGenerator { * Done: variants of beach (SAND, SAND_BEACH, SAND_BLACK, SAND_GREEN) */ - val noiseArray = arrayOf( - TaggedJoise("Carving caves", noiseRidged(1.7f, 1.4f), 1f, TILE_MACRO_ALL, TILE_MACRO_ALL, TileNameCode.AIR, NoiseFilterSqrt, CAVEGEN_THRE_START, CAVEGEN_THRE_END) - , TaggedJoise("Collapsing caves", noiseBlobs(0.5f, 0.5f), 0.3f, TileNameCode.AIR, TileNameCode.STONE, TileNameCode.STONE, NoiseFilterUniform) - - //, TaggedJoise("Putting stone patches on the ground", noiseBlobs(0.8f, 0.8f), 1.02f, TileNameCode.DIRT, TileNameCode.DIRT, TileNameCode.STONE, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart) - //, TaggedJoise("Placing dirt spots in the cave", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.DIRT, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart) - //, TaggedJoise("Quarrying some stone into gravels", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.GRAVEL, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart) - + //val noiseArray = arrayOf( + // TaggedJoise("Carving caves", noiseRidged(1.7f, 1.4f), 1f, TILE_MACRO_ALL, TILE_MACRO_ALL, TileNameCode.AIR, NoiseFilterSqrt, CAVEGEN_THRE_START, CAVEGEN_THRE_END) + //, TaggedJoise("Collapsing caves", noiseBlobs(0.5f, 0.5f), 0.3f, TileNameCode.AIR, TileNameCode.STONE, TileNameCode.STONE, NoiseFilterUniform) +// + //, TaggedJoise("Putting stone patches on the ground", noiseBlobs(0.8f, 0.8f), 1.02f, intArrayOf(TileNameCode.DIRT, TileNameCode.GRASS), TileNameCode.DIRT, TileNameCode.STONE, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) + //, TaggedJoise("Placing dirt spots in the cave", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.DIRT, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) + //, TaggedJoise("Quarrying some stone into gravels", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.GRAVEL, NoiseFilterQuadratic, NOISE_GRAD_END, NOISE_GRAD_START) +// //, TaggedJoise("Growing copper veins", noiseRidged(1.7f, 1.7f), 1.68f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_COPPER) //, TaggedJoise("Cutting copper veins", noiseBlobs(0.4f, 0.4f), 0.26f, TileNameCode.ORE_COPPER, TileNameCode.STONE, TileNameCode.STONE) - +// //, TaggedJoise("Growing iron veins", noiseRidged(1.7f, 1.7f), 1.68f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_IRON) //, TaggedJoise("Cutting iron veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_IRON, TileNameCode.STONE, TileNameCode.STONE) - +// //, TaggedJoise("Growing silver veins", noiseRidged(1.7f, 1.7f), 1.71f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_SILVER) //, TaggedJoise("Cutting silver veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_SILVER, TileNameCode.STONE, TileNameCode.STONE) - +// //, TaggedJoise("Growing gold veins", noiseRidged(1.7f, 1.7f), 1.73f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_GOLD) //, TaggedJoise("Cutting gold veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_GOLD, TileNameCode.STONE, TileNameCode.STONE) - - ////, TaggedJoise("Growing topaz clusters", noiseBlobs(0.9f, 0.9f), 2f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_TOPAZ) +// // FIXME gem clusters are too large + //, TaggedJoise("Growing topaz clusters", noiseBlobs(0.9f, 0.9f), 2f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_TOPAZ) //, TaggedJoise("Growing aluminium oxide clusters", noiseBlobs(0.9f, 0.9f), 1.7f, TileNameCode.STONE, TileNameCode.STONE, intArrayOf(TileNameCode.RAW_RUBY, TileNameCode.RAW_SAPPHIRE)) - //, TaggedJoise("Growing emerald clusters", noiseBlobs(0.9f, 0.9f), 1,7f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_EMERALD) + //, TaggedJoise("Growing emerald clusters", noiseBlobs(0.9f, 0.9f), 1.7f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_EMERALD) //, TaggedJoise("Growing hearts of white", noiseBlobs(0.9f, 0.9f), 1.83f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_DIAMOND) - //, TaggedJoise("Growing hearts of violet", noiseRidged(2.5f, 2.5f), 1.75f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_AMETHYST) +// //, TaggedJoise("Cutting over-grown hearts", noiseBlobs(0.7f, 0.7f), 0.17f, TileNameCode.RAW_AMETHYST, TileNameCode.STONE, TileNameCode.STONE) - ) - - processNoiseLayers(noiseArray) + //) + //processNoiseLayers(noiseArray) /** TODO Cobaltite, Ilmenite, Aurichalcum (and possibly pitchblende?) */ @@ -670,7 +673,7 @@ object MapGenerator { private fun processNoiseLayers(noiseRecords: Array) { if (Terrarum.MULTITHREAD) { // set up indices - for (i in 0..ThreadPool.POOL_SIZE - 1) { + for (i in 0..Terrarum.CORES - 1) { ThreadPool.map( i, ThreadProcessNoiseLayers( @@ -960,7 +963,7 @@ object MapGenerator { data class TaggedJoise(var message: String, var noiseModule: Joise, var scarcity: Float, - var replaceFromTerrain: Int, var replaceFromWall: Int, + var replaceFromTerrain: Any, var replaceFromWall: Int, var replaceTo: Any, var filter: NoiseFilter = NoiseFilterQuadratic, var filterArg1: Float = NOISE_GRAD_START, diff --git a/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt b/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt index c4fcfa028..87139689b 100644 --- a/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt +++ b/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt @@ -34,7 +34,17 @@ class ThreadProcessNoiseLayers(val startIndex: Int, val endIndex: Int, val threshold = record.filter.getGrad(y, record.filterArg1, record.filterArg2) if (noise > threshold * record.scarcity) { - if ((MapGenerator.map.getTileFromTerrain(x, y) == fromTerr || fromTerr == MapGenerator.TILE_MACRO_ALL) + if (fromTerr is IntArray) { + for (i in 0..fromTerr.size - 1) { + val fromTerrVariable = fromTerr[i] + + if ((MapGenerator.map.getTileFromTerrain(x, y) == fromTerrVariable || fromTerrVariable == MapGenerator.TILE_MACRO_ALL) + && (MapGenerator.map.getTileFromWall(x, y) == fromWall || fromWall == MapGenerator.TILE_MACRO_ALL)) { + MapGenerator.map.setTileTerrain(x, y, to) + } + } + } + else if ((MapGenerator.map.getTileFromTerrain(x, y) == fromTerr || fromTerr == MapGenerator.TILE_MACRO_ALL) && (MapGenerator.map.getTileFromWall(x, y) == fromWall || fromWall == MapGenerator.TILE_MACRO_ALL)) { MapGenerator.map.setTileTerrain(x, y, to) } diff --git a/src/net/torvald/terrarum/tileproperties/TileProp.kt b/src/net/torvald/terrarum/tileproperties/TileProp.kt index ece5730d1..d4ea2791e 100644 --- a/src/net/torvald/terrarum/tileproperties/TileProp.kt +++ b/src/net/torvald/terrarum/tileproperties/TileProp.kt @@ -36,10 +36,13 @@ class TileProp { set(value) { realLum = value } - get() = if (id == TileNameCode.SUNSTONE) + get() = // specify special tiles; else return real luminosity recorded in CSV + if (id == TileNameCode.SUNSTONE) Terrarum.game.map.globalLight else if (id == TileNameCode.DAYLIGHT_CAPACITOR) Terrarum.game.globalLightByTime(WorldTime.DAY_LENGTH / 2) + else if (id == TileNameCode.TORCH) + TilePropUtil.getTorchFlicker(realLum) else realLum diff --git a/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt b/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt index 95f93a87c..821d863fc 100644 --- a/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt +++ b/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt @@ -10,7 +10,13 @@ import java.io.IOException /** * Created by minjaesong on 16-02-16. */ -class TilePropCodex { +object TilePropCodex { + + private lateinit var tileProps: Array + + val CSV_PATH = "./src/net/torvald/terrarum/tileproperties/tileprop.csv" + + const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE init { tileProps = Array(TILE_UNIQUE_MAX + 1, @@ -38,82 +44,73 @@ class TilePropCodex { } - companion object { - - private lateinit var tileProps: Array - - val CSV_PATH = "./src/net/torvald/terrarum/tileproperties/tileprop.csv" - - const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE - - fun getProp(index: Int, damage: Int): TileProp { - try { - tileProps[idDamageToIndex(index, damage)].id - } - catch (e: NullPointerException) { - throw NullPointerException("Tile prop with id $index and damage $damage does not exist.") - } - - return tileProps[idDamageToIndex(index, damage)] + fun getProp(index: Int, damage: Int): TileProp { + try { + tileProps[idDamageToIndex(index, damage)].id + } + catch (e: NullPointerException) { + throw NullPointerException("Tile prop with id $index and damage $damage does not exist.") } - fun getProp(rawIndex: Int?): TileProp { - try { - tileProps[rawIndex ?: TileNameCode.NULL].id - } - catch (e: NullPointerException) { - throw NullPointerException("Tile prop with raw id $rawIndex does not exist.") - } - - return tileProps[rawIndex ?: TileNameCode.NULL] - } - - private fun setProp(prop: TileProp, record: CSVRecord) { - prop.nameKey = record.get("name") - - prop.id = idDamageToIndex(intVal(record, "id"), intVal(record, "dmg")) - - prop.opacity = intVal(record, "opacity") - prop.strength = intVal(record, "strength") - prop.density = intVal(record, "dsty") - prop.luminosity = intVal(record, "lumcolor") - prop.drop = intVal(record, "drop") - prop.dropDamage = intVal(record, "ddmg") - prop.friction = intVal(record, "friction") - - prop.isFluid = boolVal(record, "fluid") - prop.isSolid = boolVal(record, "solid") - prop.isWallable = boolVal(record, "wall") - prop.isFallable = boolVal(record, "fall") - - print(formatNum3(intVal(record, "id")) + ":" + formatNum2(intVal(record, "dmg"))) - println("\t" + prop.nameKey) - } - - private fun intVal(rec: CSVRecord, s: String): Int { - var ret = -1 - try { - ret = Integer.decode(rec.get(s))!! - } - catch (e: NullPointerException) { - } - - return ret - } - - private fun boolVal(rec: CSVRecord, s: String) = intVal(rec, s) != 0 - - fun idDamageToIndex(index: Int, damage: Int) = index * PairedMapLayer.RANGE + damage - - private fun formatNum3(i: Int): String { - if (i < 10) - return "00" + i - else if (i < 100) - return "0" + i - else - return i.toString() - } - - private fun formatNum2(i: Int) = if (i < 10) "0" + i else i.toString() + return tileProps[idDamageToIndex(index, damage)] } + + fun getProp(rawIndex: Int?): TileProp { + try { + tileProps[rawIndex ?: TileNameCode.NULL].id + } + catch (e: NullPointerException) { + throw NullPointerException("Tile prop with raw id $rawIndex does not exist.") + } + + return tileProps[rawIndex ?: TileNameCode.NULL] + } + + private fun setProp(prop: TileProp, record: CSVRecord) { + prop.nameKey = record.get("name") + + prop.id = idDamageToIndex(intVal(record, "id"), intVal(record, "dmg")) + + prop.opacity = intVal(record, "opacity") + prop.strength = intVal(record, "strength") + prop.density = intVal(record, "dsty") + prop.luminosity = intVal(record, "lumcolor") + prop.drop = intVal(record, "drop") + prop.dropDamage = intVal(record, "ddmg") + prop.friction = intVal(record, "friction") + + prop.isFluid = boolVal(record, "fluid") + prop.isSolid = boolVal(record, "solid") + prop.isWallable = boolVal(record, "wall") + prop.isFallable = boolVal(record, "fall") + + print(formatNum3(intVal(record, "id")) + ":" + formatNum2(intVal(record, "dmg"))) + println("\t" + prop.nameKey) + } + + private fun intVal(rec: CSVRecord, s: String): Int { + var ret = -1 + try { + ret = Integer.decode(rec.get(s))!! + } + catch (e: NullPointerException) { + } + + return ret + } + + private fun boolVal(rec: CSVRecord, s: String) = intVal(rec, s) != 0 + + fun idDamageToIndex(index: Int, damage: Int) = index * PairedMapLayer.RANGE + damage + + private fun formatNum3(i: Int): String { + if (i < 10) + return "00" + i + else if (i < 100) + return "0" + i + else + return i.toString() + } + + private fun formatNum2(i: Int) = if (i < 10) "0" + i else i.toString() } diff --git a/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt new file mode 100644 index 000000000..fe5d3957e --- /dev/null +++ b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt @@ -0,0 +1,57 @@ +package net.torvald.terrarum.tileproperties + +import com.jme3.math.FastMath +import net.torvald.random.HQRNG +import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.mapdrawer.LightmapRenderer + +/** + * Created by minjaesong on 16-06-16. + */ +object TilePropUtil { + var flickerFuncX = 0 // in milliseconds; saves current status of func + val flickerFuncDomain = 50 // time between two noise sample, in milliseconds + val flickerFuncRange = 0.012f // intensity [0, 1] + //val torchIntensityOffset = -0.04f + + val random = HQRNG(); + var funcY = 0f + + var patternThis = getNewPattern() + var patternNext = getNewPattern() + + init { + + } + + fun getTorchFlicker(baseLum: Int): Int { + funcY = linearInterpolation1D(patternThis, patternNext, + flickerFuncX.toFloat() / flickerFuncDomain + ) + + return LightmapRenderer.brightenUniform(baseLum, funcY) + } + + fun torchFlickerTickClock() { + flickerFuncX += Terrarum.game.DELTA_T + + if (flickerFuncX > flickerFuncDomain) { + flickerFuncX -= flickerFuncDomain + + patternThis = patternNext + patternNext = getNewPattern() + } + } + + private fun getNewPattern(): Float = random.nextFloat().times(2).minus(1f) * flickerFuncRange + + private fun cosineInterpolation1D(a: Float, b: Float, x: Float): Float{ + val ft: Float = x * FastMath.PI; + val f: Float = (1 - FastMath.cos(ft)) * 0.5f; + + return a * (1 - f) + b * f; + } + + private fun linearInterpolation1D(a: Float, b: Float, x: Float) = + a * (1 - x) + b * x; +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/tileproperties/tileprop.csv b/src/net/torvald/terrarum/tileproperties/tileprop.csv index 27b1a77d2..763c41ad4 100644 --- a/src/net/torvald/terrarum/tileproperties/tileprop.csv +++ b/src/net/torvald/terrarum/tileproperties/tileprop.csv @@ -41,7 +41,7 @@ "10"; "2";"TILE_PLATFORM_EBONY" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "2"; "0";"16" "10"; "3";"TILE_PLATFORM_BIRCH" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "3"; "0";"16" "10"; "4";"TILE_PLATFORM_BLOODROSE" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "4"; "0";"16" - "11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "267518016"; "11"; "0"; "0";"16" + "11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "266453040"; "11"; "0"; "0";"16" "11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16" "12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16" "12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16" @@ -122,7 +122,7 @@ ## Notes ## # Friction: 0: frictionless, <16: slippery, 16: regular, >16: sticky -# Opacity/Lumcolor: 40-step RGB +# Opacity/Lumcolor: 30-bit RGB # Solid: whether the tile has full collision # movr: Movement resistance, (walkspeedmax) / (1 + (n/16)), 16 halves movement speed # dsty: density. As we are putting water an 1000, it is identical to specific gravity. [g/l] @@ -131,7 +131,7 @@ ## Illuminators ## # Illuminator white: RGB(228,238,234), simulation of a halophosphate FL lamp (If you want high CRI lamp, collect a daylight!) -# Defalut torch : L 70 a 51 b 59; real candlelight colour taken from properly configured camera. +# Defalut torch : L 64 a 51 b 59; real candlelight colour taken from properly configured camera. # Sunstone: Artificial sunlight, change colour over time in sync with sunlight. The light is set by game's code. # Sunlight capacitor: daylight at noon. Set by game's code. diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 4d7bb8a88..bfbd1a5fe 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -72,6 +72,10 @@ class BasicDebugInfoWindow:UICanvas { val hitbox = player.hitbox val nextHitbox = player.nextHitbox + /** + * First column + */ + printLine(g, 1, "posX " + ccG + "${hitbox.pointedX.toString()}" @@ -95,21 +99,18 @@ class BasicDebugInfoWindow:UICanvas { printLine(g, 6, "noClip $ccG${player.noClip}") val lightVal: String - var mtX = mouseTileX.toString() - var mtY = mouseTileY.toString() + val mtX = mouseTileX.toString() + val mtY = mouseTileY.toString() val valRaw = LightmapRenderer.getValueFromMap(mouseTileX, mouseTileY) ?: -1 val rawR = valRaw.rawR() val rawG = valRaw.rawG() val rawB = valRaw.rawB() - lightVal = if (valRaw == -1) - "—" - else - valRaw.toInt().toString() + " (" + + + lightVal = if (valRaw == -1) "—" + else valRaw.toInt().toString() + " (" + rawR.toString() + " " + rawG.toString() + " " + rawB.toString() + ")" - - printLine(g, 7, "light@cursor $ccG$lightVal") val tileNo: String @@ -142,7 +143,7 @@ class BasicDebugInfoWindow:UICanvas { g.color = GameFontBase.codeToCol["y"] g.drawString("${ccY}MEM ", (Terrarum.WIDTH - 15 * 8 - 2).toFloat(), 2f) //g.drawString("${ccY}FPS $ccG${Terrarum.appgc.fps}", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f) - g.drawString("${ccY}CPUs ${if (Terrarum.getConfigBoolean("multithread")) ccG else ccR}${Terrarum.CORES}", + g.drawString("${ccY}CPUs ${if (Terrarum.MULTITHREAD) ccG else ccR}${Terrarum.CORES}", (Terrarum.WIDTH - 2 - 6*8).toFloat(), 10f) g.color = GameFontBase.codeToCol["g"]