diff --git a/res/locales/devmsg.csv b/res/locales/devmsg.csv index 8ba27b812..03f13b02a 100644 --- a/res/locales/devmsg.csv +++ b/res/locales/devmsg.csv @@ -8,6 +8,6 @@ "DEV_COLOUR_LEGEND_ORANGE";;"ORANGE";"ORANGE";;;;;;;;;;;;;;;"黄";;;"황";;;;;;;"オレンジ";"rauðugulur" "DEV_COLOUR_LEGEND_RED";;" RED";" ROUGE";;;;;;;;;;;;;;;"赤";;;"적";;;;;;;"  あか";"rauður" -"DEV_MESSAGE_CONSOLE_CODEX";;"Type “codex” for available commands.";"Tapez « codex » pour commandes disponibles.";;;;;;;;;;;;;;;"使用可能な命令語の目録は「codex」を入力して下さい。";;;"사용 가능한 명령어 목록을 보려면 ‘codex’를 입력해 주십시오.";;;;;;;"しよう かのうな めいれいごの もくろくは 「codex」を にゅうりょく して ください。";"Skrifa „codex“ fyrir tiltækilegum skipunum." +"DEV_MESSAGE_CONSOLE_CODEX";;"Type “codex” for available commands.";"Tapez « codex » pour commandes disponibles.";;;;;;;;;;;;;;;"使用可能な命令語の目録は「codex」を入力してください。";;;"사용 가능한 명령어 목록을 보려면 ‘codex’를 입력해 주십시오.";;;;;;;"しようかのうな めいれいごのもくろくは 「codex」を にゅうりょくしてください。";"Skrifa „codex“ fyrir tiltækilegum skipunum." "DEV_MESSAGE_CONSOLE_AVAILABLE_COMMANDS";;"Available commends:";"Commandes disponibles :";;;;;;;;;;;;;;;"命令語の目録:";;;"명령어 목록:";;;;;;;"めいれいごの もくろく:";"Listi skipana :" "DEV_MESSAGE_CONSOLE_COMMAND_UNKNOWN";;"“%1$s”: Unknown command";"« %1$s » : Commande inconnue";;;;;;;;;;;;;;;"「%1$s」: 不明な命令語";;;"‘%1$s’: 알 수 없는 명령어";;;;;;;"「%1$s」: ふめいな めいれいご";"„%1$s“ : óþekkt skipunin" \ No newline at end of file diff --git a/res/locales/helpOnTheFly.csv b/res/locales/helpOnTheFly.csv index 786a079b8..6451a9938 100644 --- a/res/locales/helpOnTheFly.csv +++ b/res/locales/helpOnTheFly.csv @@ -1,14 +1,14 @@ "STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC" "HELP_OTF_MAIN_1";;"Type “help slow” for the ways to make the game run faster.";"Tapez « help slow » si votre jeu fonctionne lentement.";;;;;;;;;;;;;;;;;;"게임이 느리게 돌아간다면 “help slow”를 입력해 보세요." -"HELP_OTF_MAIN_2";;"Press PageUp/PageDown to scroll the messages.";"Appuyez sur PageUp/Pagedown pour faire défiler les messages.";;;;;;;;;;;;;;;;;;"PageUp/PageDown 키를 사용해 메시지를 스크롤할 수 있습니다." +"HELP_OTF_MAIN_2";;"Press PageUp/PageDown to scroll the messages.";"Appuyez sur PageUp/PageDown pour faire défiler les messages.";;;;;;;;;;;;;;;;;;"PageUp/PageDown 키를 사용해 메시지를 스크롤할 수 있습니다." "HELP_OTF_MAIN_3";;"Utility keys:";"Touches utilitaires:";;;;;;;;;;;;;;;;;;"기능 키:" "HELP_OTF_MAIN_4";;"• F3: basic information";"• F3: informations de base";;;;;;;;;;;;;;;;;;"• F3: 기본 정보" "HELP_OTF_MAIN_5";;"• F7: (debug) toggle light blending";"• F7: (déboguer) basculer fusion de lumière";;;;;;;;;;;;;;;;;;"• F7: (디버그용) 광원 블렌딩 켜고 끄기" "HELP_OTF_MAIN_6";;"• F8: toggle smooth lighting";"• F8: basculer éclairage lisse";;;;;;;;;;;;;;;;;;"• F8: 부드러운 광원 켜고 끄기" -"HELP_OTF_SLOW_1";;"To make your game run faster:";"Pour rendre votre jeu courir plus vite :";;;;;;;;;;;;;;;;;;"게임을 빠르게 하려면" -"HELP_OTF_SLOW_IF_ZOOM";;"• Reset screen zoom to 1.";"• Réinitialisez le zoom de l‘écran à 1.";;;;;;;;;;;;;;;;;;"• 화면 줌을 1로 돌려주세요. " -"HELP_OTF_SLOW_IF_F3";;"• Turn off the basic information window.";"• Désactivez la fenêtre d‘informations.";;;;;;;;;;;;;;;;;;"• 기본 정보 창을 꺼 주세요." -"HELP_OTF_SLOW_1";;"• Turn off smooth lighting. You can do it now by pressing F8.";"• Désactivez éclairage lisse en utilisant 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로 돌려주세요. " +"HELP_OTF_SLOW_3";;"• Turn off the basic information window.";"• Désactivez la fenêtre d‘informations.";;;;;;;;;;;;;;;;;;"• 기본 정보 창을 꺼 주세요." +"HELP_OTF_SLOW_4";;"• Turn off smooth lighting. You can do it now by pressing F8.";"• Désactivez éclairage lisse en utilisant F8.";;;;;;;;;;;;;;;;;;"• 부드러운 광원 효과를 꺼 주세요. F8을 사용할 수 있습니다." diff --git a/res/locales/usermsg.csv b/res/locales/usermsg.csv index 34ebe030d..c52c71d49 100644 --- a/res/locales/usermsg.csv +++ b/res/locales/usermsg.csv @@ -1,6 +1,6 @@ "STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC" -"APP_CALIBRATE_YOUR_MONITOR";;"Best player experience can be achieved with properly calibrated monitor. If you have not, please do it before you play.";"Meilleure expérience de joueur peut être réalisé avec écran correctement calibré. Si vous ne l'avez pas, s.v.p. le calibrez avant de jouer.";;;;;;;;;;;;;;;"このゲームは、適切に調整したモニターから最高のプレイができます。調整していなかったら、プレイする前に調整して下さい。";;;"본 게임은 적절히 보정된 모니터에서 최상으로 즐길 수 있습니다. 보정하지 않았다면 플레이하기 전에 보정해 주십시오.";;;;;;;"このゲームは てきせつに ちょうせいしたモニターから さいこうのプレイができます。ちょうせいして いなかったら プレイするまえに ちょうせいしてください。";"Best leikmaður reynsla er getur náðist með rétt kvarðaður skjárinn. Ef þú ekki gerðir, gerðu svo vel að kvarða áður en þú leikur." +"APP_CALIBRATE_YOUR_MONITOR";;"Best player experience can be achieved with properly calibrated monitor. If you have not, please do it before you play.";"Meilleure expérience de joueur peut être réalisé avec écran correctement calibré. Si vous ne l'avez pas, s.v.p. le calibrez avant de jouer.";;;;;;;;;;;;;;;"このゲームは、適切に調整したモニターから最高のプレイができます。調整していなかったら、プレイする前に調整してください。";;;"본 게임은 적절히 보정된 모니터에서 최상으로 즐길 수 있습니다. 보정하지 않았다면 플레이하기 전에 보정해 주십시오.";;;;;;;"このゲームは、てきせつにちょうせいした モニターからさいこうのプレイができます。ちょうせいして いなかったら、プレイするまえにちょうせいしてください。";"Best leikmaður reynsla er getur náðist með rétt kvarðaður skjárinn. Ef þú ekki gerðir, gerðu svo vel að kvarða áður en þú leikur." "COPYRIGHT_MSG";;"All rights reserved.";"Tous les droits sont réservés.";;;;;;;;;;;;;;;"全著作権所有。";;;"모든 권리 보유.";;;;;;;"ぜん ちょさくけん しょゆう。";"Allur réttur áskilinn." -"MENU_LABEL_NEW_WORLD";"";"New world";"Nouveau monde";"Nuevo mundo";"Neue Welt";"Nuovo mondo";"Novo mundo";"Novo mundo";"Новый мир";"Νέο κόσμο";"Yeni Dünya";"Ny verden";"Ny verden";"Ny värld";"Nieuwe wereld";"Nowy Świat";"Uusi maailma";"新しい世界";"新世界";"新世界";"새 세계";"Nový svět";"Új világ";"Lume noua";"โลกใหม่";"Нов свят";"עולם חדש";"あたらしいせかい";"Nýr heimur" +"MENU_LABEL_NEW_WORLD";"";"New world";"Nouveau monde";"Nuevo mundo";"Neue Welt";"Nuovo mondo";"Novo mundo";"Novo mundo";"Новый мир";"Νέο κόσμο";"Yeni Dünya";"Ny verden";"Ny verden";"Ny värld";"Nieuwe wereld";"Nowy Świat";"Uusi maailma";"新しい世界";"新世界";"新世界";"새 세계";"Nový svět";"Új világ";"Lume noua";"โลกใหม่";"Нов свят";"עולם חדש";"あたらしい せかい";"Nýr heimur" diff --git a/src/com/Torvald/ImageFont/GameFontBase.kt b/src/com/Torvald/ImageFont/GameFontBase.kt index 743ba71c1..734fcf453 100644 --- a/src/com/Torvald/ImageFont/GameFontBase.kt +++ b/src/com/Torvald/ImageFont/GameFontBase.kt @@ -315,9 +315,13 @@ constructor() : Font { val glyphW = getWidth("" + ch) sheetKey[prevInstance].renderInUse( Math.round(x + getWidthSubstr(s, i + 1) - glyphW) // Interchar: pull punct right next to hangul to the left - + if (i > 0 && isHangul(s[i - 1])) -3 else 0, Math.round(y) + if (prevInstance == SHEET_CJK_PUNCT) - -1 - else if (prevInstance == SHEET_FW_UNI) (H - H_HANGUL) / 2 else 0, sheetX, sheetY) + + if (i > 0 && isHangul(s[i - 1])) -3 else 0, Math.round(y) + + if (prevInstance == SHEET_CJK_PUNCT) + -1 + else if (prevInstance == SHEET_FW_UNI) + (H - H_HANGUL) / 2 + else 0, + sheetX, sheetY) } diff --git a/src/com/Torvald/Terrarum/Game.kt b/src/com/Torvald/Terrarum/Game.kt index 78c925202..f44cd1026 100644 --- a/src/com/Torvald/Terrarum/Game.kt +++ b/src/com/Torvald/Terrarum/Game.kt @@ -175,6 +175,8 @@ constructor() : BasicGameState() { } override fun render(gc: GameContainer, sbg: StateBasedGame, g: Graphics) { + setBlendModeNormal() + Terrarum.gameConfig["smoothlighting"] = KeyToggler.isOn(KEY_LIGHTMAP_SMOOTH) if (!g.isAntiAlias) g.isAntiAlias = true @@ -284,16 +286,6 @@ constructor() : BasicGameState() { g.fill(skyBox, skyColourFill) } - private fun setBlendModeMul() { - GL11.glEnable(GL11.GL_BLEND) - GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA) - } - - private fun setBlendModeNormal() { - GL11.glDisable(GL11.GL_BLEND) - Terrarum.appgc.graphics.setDrawMode(Graphics.MODE_NORMAL) - } - fun sendNotification(msg: Array) { (notifinator.UI as Notification).sendNotification(Terrarum.appgc, update_delta, msg) notifinator.setAsOpening() diff --git a/src/com/Torvald/Terrarum/GameMap/GameMap.kt b/src/com/Torvald/Terrarum/GameMap/GameMap.kt index 3325c6101..e4d0620dc 100644 --- a/src/com/Torvald/Terrarum/GameMap/GameMap.kt +++ b/src/com/Torvald/Terrarum/GameMap/GameMap.kt @@ -167,6 +167,48 @@ constructor(//properties worldTime.update(delta) } + fun terrainIterator(): Iterator { + return object : Iterator { + + private var iteratorCount = 0 + + override fun hasNext(): Boolean { + return iteratorCount < width * height + } + + override fun next(): Int { + val y = iteratorCount / width + val x = iteratorCount % width + // advance counter + iteratorCount += 1 + + return getTileFromTerrain(x, y)!! + } + + } + } + + fun wallIterator(): Iterator { + return object : Iterator { + + private var iteratorCount = 0 + + override fun hasNext(): Boolean { + return iteratorCount < width * height + } + + override fun next(): Int { + val y = iteratorCount / width + val x = iteratorCount % width + // advance counter + iteratorCount += 1 + + return getTileFromWall(x, y)!! + } + + } + } + companion object { @Transient val WALL = 0 diff --git a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt index d846cc82f..3b9d985be 100644 --- a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt +++ b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt @@ -6,6 +6,8 @@ import com.torvald.terrarum.Terrarum import com.torvald.terrarum.tileproperties.TileNameCode import com.torvald.terrarum.tileproperties.TilePropCodex import com.jme3.math.FastMath +import com.torvald.terrarum.setBlendModeMul +import com.torvald.terrarum.setBlendModeNormal import org.lwjgl.opengl.GL11 import org.newdawn.slick.GameContainer import org.newdawn.slick.Graphics @@ -455,13 +457,4 @@ object MapCamera { private fun isBlendMul(b: Int?): Boolean = TILES_BLEND_MUL.contains(b) - private fun setBlendModeMul() { - GL11.glEnable(GL11.GL_BLEND) - GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA) - } - - private fun setBlendModeNormal() { - GL11.glDisable(GL11.GL_BLEND) - Terrarum.appgc.graphics.setDrawMode(Graphics.MODE_NORMAL) - } } \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.kt b/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.kt index 69984f887..35e50bf4d 100644 --- a/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.kt +++ b/src/com/Torvald/Terrarum/MapGenerator/MapGenerator.kt @@ -14,25 +14,24 @@ object MapGenerator { private lateinit var random: Random //private static float[] noiseArray; private var SEED: Long = 0 - private var WIDTH: Int = 0 - private var HEIGHT: Int = 0 + var WIDTH: Int = 0 + var HEIGHT: Int = 0 //private lateinit var heightMap: IntArray private lateinit var terrainMap: Array - private var DIRT_LAYER_DEPTH: Int = 0 - private var TERRAIN_AVERAGE_HEIGHT: Int = 0 + var DIRT_LAYER_DEPTH: Int = 0 + var TERRAIN_AVERAGE_HEIGHT: Int = 0 private var minimumFloatingIsleHeight: Int = 0 private val noiseGradientStart = 0.67f private val noiseGradientEnd = 0.56f - private val noiseGrdCaveEnd = 0.54f private val HILL_WIDTH = 256 // power of two! //private val MAX_HILL_HEIGHT = 100 private val TERRAIN_UNDULATION = 250 - private val CAVE_LARGEST_FEATURE = 200 + private val SIMPLEXGEN_LARGEST_FEATURE = 200 private var OCEAN_WIDTH = 400 private var SHORE_WIDTH = 120 @@ -41,14 +40,9 @@ object MapGenerator { private var GLACIER_MOUNTAIN_WIDTH = 900 private val GLACIER_MOUNTAIN_HEIGHT = 300 - private val CAVEGEN_PERTURB_RATE = 0.37f - private val CAVEGEN_PERTURB2_RATE = 0.25f - - private val CAVEGEN_THRE_START = 0.87f + private val CAVEGEN_THRE_START = 0.95f private val CAVEGEN_THRE_END = 0.67f - private val CAVEGEN_LARGEST_FEATURE = 256 - private val CAVEGEN_LARGEST_FEATURE_PERTURB = 128 private var worldOceanPosition: Int = -1 private val TYPE_OCEAN_LEFT = 0 @@ -58,7 +52,9 @@ object MapGenerator { private val GRASSCUR_RIGHT = 1 private val GRASSCUR_DOWN = 2 private val GRASSCUR_LEFT = 3 - + + private val TILE_MACRO_ALL = -1 + fun attachMap(map: GameMap) { this.map = map WIDTH = map.width @@ -97,87 +93,62 @@ object MapGenerator { terrainMap = raise3() - terrainMapToObjectMap() + fillMapByNoiseMap() /** * Done: more perturbed overworld (harder to supra-navigate) * Todo: veined ore distribution (metals) -- use veined simplex noise - * Todo: clustered gem distribution (Groups: [Ruby, Sapphire], Amethyst, Yellow topaz, emerald, diamond) -- use regular simplex noise + * Todo: clustered gem distribution (clusters: [Ruby, Sapphire], Amethyst, Yellow topaz, emerald, diamond) -- use regular simplex noise * Todo: Lakes! Aquifers! Lava chambers! * Todo: deserts (variants: SAND_DESERT, SAND_RED) * Todo: volcano(es?) * Done: variants of beach (SAND, SAND_BEACH, SAND_BLACK, SAND_GREEN) */ - carveCave( - caveGen(1.4f, 1.7f), TileNameCode.AIR, "Carving out cave...") + 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) - fillByMapNoFilterUnderground( - generate2DSimplexNoiseWorldSize(1f, 1f), 0.9f, TileNameCode.AIR, TileNameCode.STONE, "Collapsing caves...") + // random stone patches on grounds + //TaggedJoise(noiseBlobs(0.25f, 0.25f), 1.02f, TileNameCode.DIRT, TileNameCode.STONE, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart), + // random dirt spots in caves + //TaggedJoise(noiseBlobs(2.5f, 2.5f), 0.98f, TileNameCode.STONE, TileNameCode.DIRT, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart), + // random gravels in caves + //TaggedJoise(noiseBlobs(2.5f, 2.5f), 0.98f, TileNameCode.STONE, TileNameCode.GRAVEL, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart), - /*fillByMapInverseGradFilter( - generate2DSimplexNoiseWorldSize(2.5f, 2.5f) - , 1.02f - , TileNameCode.DIRT - , TileNameCode.STONE - , "Planting stones on dirt layers..." - ); - fillByMapInverseGradFilter( - generate2DSimplexNoiseWorldSize(2.5f, 2.5f) - , 0.98f - , TileNameCode.STONE - , TileNameCode.DIRT - , "Planting dirts..." - ); - fillByMapInverseGradFilter( - generate2DSimplexNoiseWorldSize(2.5f, 2.5f) - , 0.92f - , TileNameCode.STONE - , GRAVEL - , "Planting gravels..." - );*/ + // copper veins + //TaggedJoise(noiseRidged(2.2f, 2.2f), 1.67f, TileNameCode.STONE, TileNameCode.ORE_COPPER), + // separate copper veins + //TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_COPPER, TileNameCode.STONE), - /** - * Plant ores - */ - /*fillByMap( - generate2DSimplexNoiseWorldSize(5, 5) - , 0.78f - , TileNameCode.STONE - , DIAMOND - , "Planting diamonds..." - ); + // iron veins + //TaggedJoise(noiseRidged(2.2f, 2.2f), 1.69f, TileNameCode.STONE, TileNameCode.ORE_IRON), + // separate iron veins + //TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_IRON, TileNameCode.STONE), - byte[] berylsArray = {RUBY, EMERALD, SAPPHIRE, TOPAZ, AMETHYST}; - fillByMap( - generate2DSimplexNoiseWorldSize(5, 5) - , 0.8f - , TileNameCode.STONE - , berylsArray - , "Planting beryls..." - ); + // silver veins + //TaggedJoise(noiseRidged(2.2f, 2.2f), 1.70f, TileNameCode.STONE, TileNameCode.ORE_SILVER), + // separate silver veins + //TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_SILVER, TileNameCode.STONE), - fillByMap( - generate2DSimplexNoiseWorldSize(5, 5) - , 0.80f - , TileNameCode.STONE - , GOLD - , "Planting golds..." - ); - fillByMap( - generate2DSimplexNoiseWorldSize(5, 5) - , 0.866f - , TileNameCode.STONE - , IRON - , "Planting irons..." - ); - fillByMap( - generate2DSimplexNoiseWorldSize(5, 5) - , 0.88f - , TileNameCode.STONE - , COPPER - , "Planting coppers..." - );*/ + // gold veins + //TaggedJoise(noiseRidged(2.2f, 2.2f), 1.71f, TileNameCode.STONE, TileNameCode.ORE_GOLD), + // separate gold veins + //TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_GOLD, TileNameCode.STONE), + + // topaz + //TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_TOPAZ), + // ruby/sapphire + //TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, intArrayOf(TileNameCode.RAW_RUBY, TileNameCode.RAW_SAPPHIRE)), + // emerald + //TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_EMERALD), + // diamond + //TaggedJoise(noiseBlobs(1.45f, 1.45f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_DIAMOND), + // amethyst + //TaggedJoise(noiseBlobs(1.45f, 1.45f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_AMETHYST) + ) + + processNoiseLayers(noiseArray) /** TODO Cobaltite, Ilmenite, Aurichalcum (and possibly pitchblende?) */ @@ -202,128 +173,40 @@ object MapGenerator { /* 1. Raise */ - /** - * Ridged 2D simplex noise with some perturbing - * @param xStretch - * * - * @param yStretch - * * - * @return - */ - private fun caveGen(xStretch: Float, yStretch: Float): Array { - val noiseMap = Array(HEIGHT) { FloatArray(WIDTH) } + private fun noiseRidged(xStretch: Float, yStretch: Float): Joise { + val ridged = ModuleFractal() + ridged.setType(ModuleFractal.FractalType.RIDGEMULTI) + ridged.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC) + ridged.setNumOctaves(4) + ridged.setFrequency(1.0) + ridged.seed = SEED xor random.nextLong() - val simplexNoise = SimplexNoise(CAVEGEN_LARGEST_FEATURE, CAVEGEN_PERTURB_RATE, SEED) - val simplexNoisePerturbMap = SimplexNoise(CAVEGEN_LARGEST_FEATURE_PERTURB, 0.5f, SEED xor random.nextLong()) + val ridged_autocorrect = ModuleAutoCorrect() + ridged_autocorrect.setRange(0.0, 1.0) + ridged_autocorrect.setSource(ridged) - val xEnd = WIDTH * yStretch - val yEnd = HEIGHT * xStretch + val ridged_scale = ModuleScaleDomain() + ridged_scale.setScaleX(xStretch.toDouble()) + ridged_scale.setScaleY(yStretch.toDouble()) + ridged_scale.setSource(ridged_autocorrect) - var lowestNoiseVal = 10000f - var highestNoiseVal = -10000f - - for (y in 0..HEIGHT - 1) { - for (x in 0..WIDTH - 1) { - val ny = (y * (xEnd / WIDTH)).toInt() - val nx = (x * (yEnd / HEIGHT)).toInt() - - val noiseInit = simplexNoise.getNoise(nx, ny) // [-1 , 1] - val perturbInit = simplexNoisePerturbMap.getNoise(nx, ny) * 0.5f + 0.5f // [0 , 1] - - /** Ridging part ! */ - val noiseFin = 1f - Math.abs(noiseInit) // [0 , 1] - - val perturb = 1 - perturbInit * CAVEGEN_PERTURB2_RATE // [1 , 1-0.25] - val noisePerturbed = noiseFin * perturb // [0 , 1] - - if (noisePerturbed < lowestNoiseVal) lowestNoiseVal = noisePerturbed - if (noisePerturbed > highestNoiseVal) highestNoiseVal = noisePerturbed - noiseMap[y][x] = noisePerturbed - } - } - - // Auto-scaling noise - - for (y in 0..HEIGHT - 1) { - for (x in 0..WIDTH - 1) { - val noiseInit = noiseMap[y][x] - lowestNoiseVal - - val noiseFin = noiseInit * (1f / (highestNoiseVal - lowestNoiseVal)) - - val noiseThresholded = (if (noiseFin > gradientSqrt(y, CAVEGEN_THRE_START, - CAVEGEN_THRE_END)) - 1 - else - 0).toFloat() - - noiseMap[y][x] = noiseThresholded - } - } - - return noiseMap + return Joise(ridged_scale) } - private fun generate2DSimplexNoiseWorldSize(xStretch: Float, yStretch: Float): Array { - return generate2DSimplexNoise(WIDTH, HEIGHT, xStretch, yStretch) + private fun noiseBlobs(xStretch: Float, yStretch: Float): Joise { + val gradval = ModuleBasisFunction() + gradval.seed = SEED + gradval.setType(ModuleBasisFunction.BasisType.GRADVAL) + gradval.setInterpolation(ModuleBasisFunction.InterpolationType.QUINTIC) + + val gradval_scale = ModuleScaleDomain() + gradval_scale.setScaleX(1.0 / xStretch) + gradval_scale.setScaleY(1.0 / yStretch) + gradval_scale.setSource(gradval) + + return Joise(gradval_scale) } - /** - * Generate 2D array of simplex noise. - * @param sizeX - * * - * @param sizeY - * * - * @param xStretch - * * - * @param yStretch - * * - * @return matrix in ![x][y]! - */ - private fun generate2DSimplexNoise(sizeX: Int, sizeY: Int, xStretch: Float, yStretch: Float): Array { - val simplexNoise = SimplexNoise(CAVE_LARGEST_FEATURE, 0.1f, SEED xor random.nextLong()) - - val xStart = 0f - val yStart = 0f - - /** higher = denser. - * Recommended: (width or height) * 3 - */ - val xEnd = WIDTH * yStretch - val yEnd = HEIGHT * xStretch - - var lowestNoiseVal = 10000f - var highestNoiseVal = -10000f - - val result = Array(sizeY) { FloatArray(sizeX) } - - for (i in 0..sizeY - 1) { - for (j in 0..sizeX - 1) { - val x = (xStart + i * ((xEnd - xStart) / sizeX)).toInt() - val y = (yStart + j * ((yEnd - yStart) / sizeY)).toInt() - - val noiseValue = (0.5 * (1 + simplexNoise.getNoise(x, y))).toFloat() - - if (noiseValue < lowestNoiseVal) lowestNoiseVal = noiseValue - if (noiseValue > highestNoiseVal) highestNoiseVal = noiseValue - - result[i][j] = noiseValue - } - } - - // Auto-scaling noise - - for (y in 0..HEIGHT - 1) { - for (x in 0..WIDTH - 1) { - val noiseInit = result[y][x] - lowestNoiseVal - - val noiseFin = noiseInit * (1f / (highestNoiseVal - lowestNoiseVal)) - - result[y][x] = noiseFin - } - } - - return result - } private fun generateOcean(noiseArrayLocal: IntArray): IntArray { val oceanLeftP1 = noiseArrayLocal[OCEAN_WIDTH] @@ -333,13 +216,13 @@ object MapGenerator { * Add ocean so that: * +1| - - - * 0| - -- ... + * 0| - -- ... * -1|______ - * interpolated to * +1| - - - * 0| _--- -- ... + * 0| _--- -- ... * -1|__- - * ↑-- Rough, white noise @@ -388,8 +271,7 @@ object MapGenerator { //println(lowland_shape_fractal.seed) val lowland_autocorrect = ModuleAutoCorrect() - lowland_autocorrect.setLow(0.0) - lowland_autocorrect.setHigh(1.0) + lowland_autocorrect.setRange(0.0, 1.0) lowland_autocorrect.setSource(lowland_shape_fractal) val lowland_scale = ModuleScaleOffset() @@ -418,8 +300,7 @@ object MapGenerator { val highland_autocorrect = ModuleAutoCorrect() highland_autocorrect.setSource(highland_shape_fractal) - highland_autocorrect.setLow(0.0) - highland_autocorrect.setHigh(1.0) + highland_autocorrect.setRange(0.0, 1.0) val highland_scale = ModuleScaleOffset() highland_scale.setSource(highland_autocorrect) @@ -447,8 +328,7 @@ object MapGenerator { val mountain_autocorrect = ModuleAutoCorrect() mountain_autocorrect.setSource(mountain_shape_fractal) - mountain_autocorrect.setLow(0.0) - mountain_autocorrect.setHigh(1.0) + mountain_autocorrect.setRange(0.0, 1.0) val mountain_scale = ModuleScaleOffset() mountain_scale.setSource(mountain_autocorrect) @@ -476,8 +356,7 @@ object MapGenerator { val terrain_autocorrect = ModuleAutoCorrect() terrain_autocorrect.setSource(terrain_type_fractal) - terrain_autocorrect.setLow(0.0) - terrain_autocorrect.setHigh(1.0) + terrain_autocorrect.setRange(0.0, 1.0) val terrain_type_scale = ModuleScaleDomain() terrain_type_scale.setScaleY(0.33) @@ -508,7 +387,9 @@ object MapGenerator { ground_select.setControlSource(highland_lowland_select) val joise = Joise(ground_select) + // fill the area as Joise map + println("[mapgenerator] Raising and eroding terrain...") for (y in 0..(TERRAIN_UNDULATION - 1)) { for (x in 0..WIDTH) { val map: Boolean = ( @@ -606,8 +487,8 @@ object MapGenerator { } } - private fun terrainMapToObjectMap() { - println("[mapgenerator] Shaping world as processed...") + private fun fillMapByNoiseMap() { + println("[mapgenerator] Shaping world...") // generate dirt-stone transition line // use catmull spline val dirtStoneLine = IntArray(WIDTH) @@ -620,12 +501,12 @@ object MapGenerator { splineControlPoints[x] = Pair(x * POINTS_GAP, y) if (terrainMap[y].get(splineControlPoints[x].first)) break } - println("Spline[$x] x: ${splineControlPoints[x].first}, " + - "y: ${splineControlPoints[x].second}") + // println("Spline[$x] x: ${splineControlPoints[x].first}, " + + // "y: ${splineControlPoints[x].second}") } // do interpolation - for (x in 0..dirtStoneLine.size) { + for (x in 0..dirtStoneLine.size - 1) { val x_1 = x / POINTS_GAP val splineX0 = splineControlPoints[ clamp(x_1 - 1, 0, dirtStoneLine.size / POINTS_GAP) ].first @@ -641,7 +522,7 @@ object MapGenerator { if (x in POINTS_GAP - 1..WIDTH - 2 * POINTS_GAP) { dirtStoneLine[x] = Math.round(FastMath.interpolateCatmullRom( (x - splineX1) / POINTS_GAP.toFloat(), - 0.01f, + -0.3f,//0.01f, splineP0, splineP1, splineP2, @@ -649,11 +530,14 @@ object MapGenerator { )) } else { - interpolateCosine( + dirtStoneLine[x] = Math.round(FastMath.interpolateCatmullRom( (x - splineX1) / POINTS_GAP.toFloat(), + -0.3f,//0.01f, + splineP0, splineP1, - splineP2 - ) + splineP2, + splineP3 + )) } } @@ -675,283 +559,138 @@ object MapGenerator { /* 2. Carve */ - private fun carveCave(noisemap: Array, tile: Int, message: String) { - println("[mapgenerator] " + message) - - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > 0.9) { - map.setTileTerrain(j, i, tile) - } - } - } - } - /** - * Carve (place air block) by noisemap, inversed gradation filter applied. + * Carve (place specified block) by noisemap, inversed gradation filter applied. * @param map noisemap * * - * @param scarcity higher = larger blob - * * + * @param scarcity higher == rarer + * * 1.0 is a default value. This value works as a multiplier to the gradient filter. * @param tile * * * @param message */ - private fun carveByMap(noisemap: Array, scarcity: Float, tile: Int, message: String) { + private fun carveByMap(noisemap: Any, scarcity: Float, tile: Int, message: String, + filter: NoiseFilter = NoiseFilterQuadratic, + filterStart: Float = noiseGradientStart, + filterEnd: Float = noiseGradientEnd) { println("[mapgenerator] " + message) - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > gradientQuadratic(i, noiseGradientStart, noiseGrdCaveEnd) * scarcity) { - map.setTileTerrain(j, i, tile) + for (y in 0..HEIGHT - 1) { + for (x in 0..WIDTH - 1) { + val noise: Float = when (noisemap) { + is Joise -> + noisemap.get( + x.toDouble() / 48.0, // 48: Fixed value + y.toDouble() / 48.0 + ).toFloat() + + is TaggedSimplexNoise -> noisemap.noiseModule.getNoise( + Math.round(x / noisemap.xStretch), + Math.round(y / noisemap.yStretch) + ) + + else -> throw(IllegalArgumentException("[mapgenerator] Unknown noise module type '${noisemap.javaClass.simpleName}': Only the 'Joise' or 'TaggedSimplexNoise' is valid.")) + } + + if (noise > filter.getGrad(y, filterStart, filterEnd) * scarcity) { + map.setTileTerrain(x, y, tile) } } } } - /** - * Fill by noisemap, gradation filter applied. - * @param map noisemap - * * - * @param scarcity higher = larger blob - * * - * @param replaceFrom - * * - * @param tile - * * - * @param message - */ - private fun fillByMap(noisemap: Array, scarcity: Float, replaceFrom: Int, tile: Int, message: String) { + private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, replaceTo: Int, message: String, + filter: NoiseFilter = NoiseFilterQuadratic, + filterStart: Float = noiseGradientStart, + filterEnd: Float = noiseGradientEnd) { println("[mapgenerator] " + message) - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > getNoiseGradient(i, noiseGradientStart, noiseGradientEnd) * scarcity && map.getTileFromTerrain(j, i) == replaceFrom) { - map.setTileTerrain(j, i, tile) + for (y in 0..HEIGHT - 1) { + for (x in 0..WIDTH - 1) { + val noise: Float = when (noisemap) { + is Joise -> + noisemap.get( + x.toDouble() / 48.0, // 48: Fixed value + y.toDouble() / 48.0 + ).toFloat() + + is TaggedSimplexNoise -> noisemap.noiseModule.getNoise( + Math.round(x / noisemap.xStretch), + Math.round(y / noisemap.yStretch) + ) + + else -> throw(IllegalArgumentException("[mapgenerator] Unknown noise module type '${noisemap.javaClass.simpleName}': Only the 'Joise' or 'TaggedSimplexNoise' is valid.")) + } + + if (noise > filter.getGrad(y, filterStart, filterEnd) * scarcity + && map.getTileFromTerrain(x, y) == replaceFrom) { + map.setTileTerrain(x, y, replaceTo) } } } } - /** - * Fill by noisemap, inversed gradation filter applied. - * @param map noisemap - * * - * @param scarcity higher = larger blob - * * - * @param replaceFrom - * * - * @param tile - * * - * @param message - */ - private fun fillByMapInverseGradFilter(noisemap: Array, scarcity: Float, replaceFrom: Int, tile: Int, message: String) { + private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, tile: IntArray, message: String, + filter: NoiseFilter = NoiseFilterQuadratic, + filterStart: Float = noiseGradientStart, + filterEnd: Float = noiseGradientEnd) { println("[mapgenerator] " + message) - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > getNoiseGradientInversed(i, noiseGradientEnd, noiseGradientStart) * scarcity - && map.getTileFromTerrain(j, i) == replaceFrom) { - map.setTileTerrain(j, i, tile) + for (y in 0..HEIGHT - 1) { + for (x in 0..WIDTH - 1) { + val noise: Float = when (noisemap) { + is Joise -> + noisemap.get( + x.toDouble() / 48.0, // 48: Fixed value + y.toDouble() / 48.0 + ).toFloat() + + is TaggedSimplexNoise -> noisemap.noiseModule.getNoise( + Math.round(x / noisemap.xStretch), + Math.round(y / noisemap.yStretch) + ) + + else -> throw(IllegalArgumentException("[mapgenerator] Unknown noise module type '${noisemap.javaClass.simpleName}': Only the 'Joise' or 'TaggedSimplexNoise' is valid.")) + } + + if (noise > filter.getGrad(y, filterStart, filterEnd) * scarcity && map.getTileFromTerrain(x, y) == replaceFrom) { + map.setTileTerrain(x, y, tile[random.nextInt(tile.size)]) } } } } - /** - * Fill by noisemap, no filter applied. Takes - * - * noiseGradientStart / scarcity - * as carving threshold. - * @param map noisemap - * * - * @param scarcity higher = larger blob - * * - * @param replaceFrom - * * - * @param tile - * * - * @param message - */ - private fun fillByMapNoFilter(noisemap: Array, scarcity: Float, replaceFrom: Int, tile: Int, message: String) { - println("[mapgenerator] " + message) + private fun processNoiseLayers(noiseRecords: Array) { + for (record in noiseRecords) { + println("[mapgenerator] ${record.message}...") + for (y in 0..HEIGHT - 1) { + for (x in 0..WIDTH - 1) { + val noise: Float = record.noiseModule.get( + x.toDouble() / 48.0, // 48: Fixed value + y.toDouble() / 48.0 + ).toFloat() - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > noiseGradientStart * scarcity && map.getTileFromTerrain(j, i) == replaceFrom) { - map.setTileTerrain(j, i, tile) + val fromTerr = record.replaceFromTerrain + val fromWall = record.replaceFromWall + val to: Int = when(record.replaceTo) { + is Int -> record.replaceTo as Int + is IntArray -> (record.replaceTo as IntArray)[random.nextInt((record.replaceTo as IntArray).size)] + else -> throw IllegalArgumentException("[mapgenerator] Unknown replaceTo tile type '${record.replaceTo.javaClass.canonicalName}': Only 'kotlin.Int' and 'kotlin.IntArray' is valid.") + } + if (to == TILE_MACRO_ALL) throw IllegalArgumentException("[mapgenerator] Invalid replaceTo: TILE_MACRO_ALL") + val threshold = record.filter.getGrad(y, record.filterArg1, record.filterArg2) + + if (noise > threshold * record.scarcity) { + if ((map.getTileFromTerrain(x, y) == fromTerr || fromTerr == TILE_MACRO_ALL) + && (map.getTileFromWall(x, y) == fromWall || fromWall == TILE_MACRO_ALL)) { + map.setTileTerrain(x, y, to) + } + } } } } } - private fun fillByMapNoFilterUnderground(noisemap: Array, scarcity: Float, replaceFrom: Int, replaceTo: Int, message: String) { - println("[mapgenerator] " + message) - - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > noiseGradientStart * scarcity - && map.getTileFromTerrain(j, i) ?: 0 == replaceFrom - && map.getTileFromWall(j, i) ?: 0 == replaceTo - ) { - map.setTileTerrain(j, i, replaceTo) - } - } - } - } - - private fun fillByMap(noisemap: Array, scarcity: Float, replaceFrom: Int, tile: IntArray, message: String) { - println("[mapgenerator] " + message) - - for (i in 0..HEIGHT - 1) { - for (j in 0..WIDTH - 1) { - if (noisemap[i][j] > getNoiseGradient(i, noiseGradientStart, noiseGradientEnd) * scarcity && map.getTileFromTerrain(j, i) == replaceFrom) { - map.setTileTerrain(j, i, tile[random.nextInt(tile.size)]) - } - } - } - } - - private fun getNoiseGradient(x: Int, start: Float, end: Float): Float { - return gradientQuadratic(x, start, end) - } - - private fun getNoiseGradientInversed(x: Int, start: Float, end: Float): Float { - return gradientMinusQuadratic(x, start, end) - } - - private fun gradientSqrt(func_argX: Int, start: Float, end: Float): Float { - val graph_gradient = (end - start) / FastMath.sqrt((HEIGHT - TERRAIN_AVERAGE_HEIGHT).toFloat()) * FastMath.sqrt((func_argX - TERRAIN_AVERAGE_HEIGHT).toFloat()) + start - - if (func_argX < TERRAIN_AVERAGE_HEIGHT) { - return start - } else if (func_argX >= HEIGHT) { - return end - } else { - return graph_gradient - } - } - - /** - * Quadratic polynomial - * (16/9) * (start-end)/height^2 * (x-height)^2 + end - * 16/9: terrain is formed from 1/4 of height. - * 1 - (1/4) = 3/4, reverse it and square it. - * That makes 16/9. - - * Shape: - - * cavity - - * small - * - - * - - * -- - * ---- - * cavity -------- - * large ---------------- - - * @param func_argX - * * - * @param start - * * - * @param end - * * - * @return - */ - private fun gradientQuadratic(func_argX: Int, start: Float, end: Float): Float { - val graph_gradient = FastMath.pow(FastMath.sqr((1 - TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 - (start - end) / FastMath.sqr(HEIGHT.toFloat()) * - FastMath.sqr((func_argX - HEIGHT).toFloat()) + end - - if (func_argX < TERRAIN_AVERAGE_HEIGHT) { - return start - } else if (func_argX >= HEIGHT) { - return end - } else { - return graph_gradient - } - } - - /** - * Double Quadratic polynomial - * (16/9) * (start-end)/height^2 * (x-height)^2 + end - * 16/9: terrain is formed from 1/4 of height. - * 1 - (1/4) = 3/4, reverse it and square it. - * That makes 16/9. - - * Shape: - - * cavity - - * small - * - - * - - * -- - * ---- - * cavity -------- - * large ---------------- - - * @param func_argX - * * - * @param start - * * - * @param end - * * - * @return - */ - private fun gradientCubic(func_argX: Int, start: Float, end: Float): Float { - val graph_gradient = -FastMath.pow(FastMath.pow((1 - TERRAIN_AVERAGE_HEIGHT).toFloat(), 3f), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 - (start - end) / FastMath.pow(HEIGHT.toFloat(), 3f) * - FastMath.pow((func_argX - HEIGHT).toFloat(), 3f) + end - - if (func_argX < TERRAIN_AVERAGE_HEIGHT) { - return start - } else if (func_argX >= HEIGHT) { - return end - } else { - return graph_gradient - } - } - - /** - * Quadratic polynomial - * -(16/9) * (start-end)/height^2 * (x - 0.25 * height)^2 + start - * 16/9: terrain is formed from 1/4 of height. - * 1 - (1/4) = 3/4, reverse it and square it. - * That makes 16/9. - - * Shape: - - * cavity _ - * small - * _ - * _ - * __ - * ____ - * cavity ________ - * large ________________ - - * @param func_argX - * * - * @param start - * * - * @param end - * * - * @return - */ - private fun gradientMinusQuadratic(func_argX: Int, start: Float, end: Float): Float { - val graph_gradient = -FastMath.pow(FastMath.sqr((1 - TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 - (start - end) / FastMath.sqr(HEIGHT.toFloat()) * - FastMath.sqr((func_argX - TERRAIN_AVERAGE_HEIGHT).toFloat()) + start - - if (func_argX < TERRAIN_AVERAGE_HEIGHT) { - return start - } else if (func_argX >= HEIGHT) { - return end - } else { - return graph_gradient - } - } - private fun generateFloatingIslands() { println("[mapgenerator] Placing floating islands...") @@ -1197,4 +936,13 @@ object MapGenerator { private fun clamp(x: Int, min: Int, max: Int): Int = if (x < min) min else if (x > max) max else x + 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 replaceFromTerrain: Int, var replaceFromWall: Int, + var replaceTo: Any, + var filter: NoiseFilter = NoiseFilterQuadratic, + var filterArg1: Float = noiseGradientStart, + var filterArg2: Float = noiseGradientEnd) } \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/Terrarum.kt b/src/com/Torvald/Terrarum/Terrarum.kt index aa64541c8..49c9f5278 100644 --- a/src/com/Torvald/Terrarum/Terrarum.kt +++ b/src/com/Torvald/Terrarum/Terrarum.kt @@ -5,6 +5,7 @@ import com.torvald.JsonFetcher import com.torvald.JsonWriter import com.torvald.terrarum.langpack.Lang import org.lwjgl.input.Controllers +import org.lwjgl.opengl.GL11 import org.newdawn.slick.AppGameContainer import org.newdawn.slick.Font import org.newdawn.slick.GameContainer @@ -329,4 +330,14 @@ constructor(gamename: String) : StateBasedGame(gamename) { } } -fun main(args: Array) = Terrarum.main(args) \ No newline at end of file +fun main(args: Array) = Terrarum.main(args) + +fun setBlendModeMul() { + GL11.glEnable(GL11.GL_BLEND) + GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA) +} + +fun setBlendModeNormal() { + GL11.glEnable(GL11.GL_BLEND) + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA) +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/MECHNANICS.md b/src/com/torvald/terrarum/MECHNANICS.md index bb9712dff..cd22863fa 100644 --- a/src/com/torvald/terrarum/MECHNANICS.md +++ b/src/com/torvald/terrarum/MECHNANICS.md @@ -90,12 +90,6 @@ Magical/Surreal: Use 24 Bits * Base mass: 60 kg -## Custom pattern making ## - -- Players can create their own décors (hang on wall), dresses. -- Two looms (216 colour mode, 4096 colour mode) - - ## Food/Potion dose ## Scale ^ 3 ^ (3/4) == (ThisWgt / TargetWgt) ^ (3/4) diff --git a/src/com/torvald/terrarum/MISC_FEATURES.md b/src/com/torvald/terrarum/MISC_FEATURES.md new file mode 100644 index 000000000..ab0cb318c --- /dev/null +++ b/src/com/torvald/terrarum/MISC_FEATURES.md @@ -0,0 +1,19 @@ +## Gadgets ## + +### Looms for custom pattern ### + +- Players can create their own décors (hang on wall), dresses. +- Two looms (216 colour mode, 4096 colour mode) + + +### Music making ### + +- Automated glockenspiel thingy +- Single tile can hold 48 notes, single track +- Work like Modtracker, incl. physical arrangements + + Arrangements in the map + Time →→→→ + voice 1 → # # # # # # # + voice 2 → # # # # # # # + ↑ played simultaneously along the X-axis \ No newline at end of file diff --git a/src/com/torvald/terrarum/SAVE_FORMAT.md b/src/com/torvald/terrarum/SAVE_FORMAT.md index 080b4d9dd..2c4efc757 100644 --- a/src/com/torvald/terrarum/SAVE_FORMAT.md +++ b/src/com/torvald/terrarum/SAVE_FORMAT.md @@ -1,7 +1,7 @@ ## Format ## * Save meta - - Binary (for more security) + - GZip'd binary (for more security) - Filename : world (with no extension) |Type |Mnemonic |Description | @@ -11,10 +11,10 @@ |Byte |NULL |String terminator | |Byte[8] |terraseed |Terrain seed | |Byte[8] |rogueseed |Randomiser seed | - |Byte[32] |hash1 |SHA-256 hash of worldinfo1 being stored| - |Byte[32] |hash2 |SHA-256 hash of worldinfo2 being stored| - |Byte[32] |hash3 |SHA-256 hash of worldinfo3 being stored| - |Byte[32] |hash4 |SHA-256 hash of worldinfo4 being stored| + |Byte[32] |hash1 |SHA-256 hash of worldinfo1 being stored (when not zipped)| + |Byte[32] |hash2 |SHA-256 hash of worldinfo2 being stored (when not zipped)| + |Byte[32] |hash3 |SHA-256 hash of worldinfo3 being stored (when not zipped)| + |Byte[32] |hash4 |SHA-256 hash of worldinfo4 being stored (when not zipped)| Endianness: Big @@ -25,10 +25,10 @@ * Prop data - GZip'd CSV - - Filename : worldinfo2 -- tileprop.csv - worldinfo3 -- itemprop.csv - worldinfo4 -- materialprop.csv - (with no extension) + - Filename : (with no extension) + worldinfo2 -- tileprop + worldinfo3 -- itemprop + worldinfo4 -- materialprop * Human-readable @@ -39,8 +39,7 @@ ## How it works ## -* If hash discrepancy has detected, (hash of csv in save dir != stored hash || hash of TEMD != stored hash) - printout "Save file corrupted. Continue?" with prompt "Yes/No" +* If hash discrepancy has detected, (hash of csv in save dir != stored hash || hash of TEMD != stored hash), printout "Save file corrupted. Continue?" with prompt "Yes/No" Directory: @@ -48,10 +47,10 @@ Directory: --- 2a93bc5fd...f823 Actor/Faction/etc. data --- 423bdc838...93bd Actor/Faction/etc. data --- Items_list.txt Human-readable - --- Materials_list.txt Human-redable + --- Materials_list.txt Human-readable --- Tiles_list.txt Human-readable - --- world save meta (binary) - --- worldinfo1 TEMD (binary) - --- worldinfo2 tileprop - --- worldinfo3 itemprop - --- worldinfo4 materialprop + --- world save meta (binary, GZip) + --- worldinfo1 TEMD (binary, GZip) + --- worldinfo2 tileprop (GZip) + --- worldinfo3 itemprop (GZip) + --- worldinfo4 materialprop (GZip) diff --git a/src/com/torvald/terrarum/console/ExportMap.kt b/src/com/torvald/terrarum/console/ExportMap.kt index 8b9e65e8b..0703df24c 100644 --- a/src/com/torvald/terrarum/console/ExportMap.kt +++ b/src/com/torvald/terrarum/console/ExportMap.kt @@ -3,6 +3,7 @@ package com.torvald.terrarum.console import com.torvald.colourutil.Col4096 import com.torvald.RasterWriter import com.torvald.terrarum.Terrarum +import com.torvald.terrarum.tileproperties.TileNameCode import java.io.* import java.util.HashMap @@ -15,7 +16,7 @@ class ExportMap : ConsoleCommand { //private var mapData: ByteArray? = null // private var mapDataPointer = 0 - private val colorTable = HashMap() + private val colorTable = HashMap() override fun execute(args: Array) { if (args.size == 2) { @@ -24,8 +25,8 @@ class ExportMap : ConsoleCommand { var mapData = ByteArray(Terrarum.game.map.width * Terrarum.game.map.height * 3) var mapDataPointer = 0 - for (tile in Terrarum.game.map.layerTerrain) { - val colArray = (colorTable as Map) + for (tile in Terrarum.game.map.terrainIterator()) { + val colArray = (colorTable as Map) .getOrElse(tile, { Col4096(0xFFF) }).toByteArray() for (i in 0..2) { @@ -71,222 +72,45 @@ class ExportMap : ConsoleCommand { } private fun buildColorTable() { - colorTable.put(AIR, Col4096(0xCEF)) - colorTable.put(STONE, Col4096(0x887)) - colorTable.put(DIRT, Col4096(0x763)) - colorTable.put(GRASS, Col4096(0x251)) + colorTable.put(TileNameCode.AIR, Col4096(0xCEF)) + colorTable.put(TileNameCode.STONE, Col4096(0x888)) + colorTable.put(TileNameCode.DIRT, Col4096(0x753)) + colorTable.put(TileNameCode.GRASS, Col4096(0x472)) - colorTable.put(COPPER, Col4096(0x6A8)) - colorTable.put(IRON, Col4096(0xC75)) - colorTable.put(GOLD, Col4096(0xCB6)) - colorTable.put(ILMENITE, Col4096(0x8AB)) - colorTable.put(AURICHALCUM, Col4096(0xD92)) - colorTable.put(SILVER, Col4096(0xDDD)) + colorTable.put(TileNameCode.ORE_COPPER, Col4096(0x6A8)) + colorTable.put(TileNameCode.ORE_IRON, Col4096(0xC75)) + colorTable.put(TileNameCode.ORE_GOLD, Col4096(0xA87)) + colorTable.put(TileNameCode.ORE_ILMENITE, Col4096(0x8AB)) + colorTable.put(TileNameCode.ORE_AURICHALCUM, Col4096(0xD92)) + colorTable.put(TileNameCode.ORE_SILVER, Col4096(0xDDD)) - colorTable.put(DIAMOND, Col4096(0x9CE)) - colorTable.put(RUBY, Col4096(0xB10)) - colorTable.put(EMERALD, Col4096(0x0B1)) - colorTable.put(SAPPHIRE, Col4096(0x01B)) - colorTable.put(TOPAZ, Col4096(0xC70)) - colorTable.put(AMETHYST, Col4096(0x70C)) + colorTable.put(TileNameCode.RAW_DIAMOND, Col4096(0x2BF)) + colorTable.put(TileNameCode.RAW_RUBY, Col4096(0xB10)) + colorTable.put(TileNameCode.RAW_EMERALD, Col4096(0x0B1)) + colorTable.put(TileNameCode.RAW_SAPPHIRE, Col4096(0x01B)) + colorTable.put(TileNameCode.RAW_TOPAZ, Col4096(0xC70)) + colorTable.put(TileNameCode.RAW_AMETHYST, Col4096(0x70C)) - colorTable.put(WATER, Col4096(0x038)) - colorTable.put(LAVA, Col4096(0xF50)) + colorTable.put(TileNameCode.WATER, Col4096(0x038)) + colorTable.put(TileNameCode.LAVA, Col4096(0xF50)) - colorTable.put(SAND, Col4096(0xDCA)) - colorTable.put(GRAVEL, Col4096(0x664)) + colorTable.put(TileNameCode.SAND, Col4096(0xDDB)) + colorTable.put(TileNameCode.SAND_WHITE, Col4096(0xFFD)) + colorTable.put(TileNameCode.SAND_RED, Col4096(0xA32)) + colorTable.put(TileNameCode.SAND_DESERT, Col4096(0xEDB)) + colorTable.put(TileNameCode.SAND_BLACK, Col4096(0x444)) + colorTable.put(TileNameCode.SAND_GREEN, Col4096(0x9A6)) - colorTable.put(ICE_NATURAL, Col4096(0x9AB)) - colorTable.put(ICE_MAGICAL, Col4096(0x7AC)) - colorTable.put(ICE_FRAGILE, Col4096(0x6AF)) - colorTable.put(SNOW, Col4096(0xCDE)) + colorTable.put(TileNameCode.GRAVEL, Col4096(0x664)) + colorTable.put(TileNameCode.GRAVEL_GREY, Col4096(0x999)) + + colorTable.put(TileNameCode.ICE_NATURAL, Col4096(0x9AB)) + colorTable.put(TileNameCode.ICE_MAGICAL, Col4096(0x7AC)) + colorTable.put(TileNameCode.ICE_FRAGILE, Col4096(0x6AF)) + colorTable.put(TileNameCode.SNOW, Col4096(0xCDE)) } - - companion object { - - private val AIR: Byte = 0 - - private val STONE: Byte = 1 - private val DIRT: Byte = 2 - private val GRASS: Byte = 3 - - private val SAND: Byte = 13 - private val GRAVEL: Byte = 14 - - private val COPPER: Byte = 15 - private val IRON: Byte = 16 - private val GOLD: Byte = 17 - private val SILVER: Byte = 18 - private val ILMENITE: Byte = 19 - private val AURICHALCUM: Byte = 20 - - private val DIAMOND: Byte = 25 - private val RUBY: Byte = 21 - private val EMERALD: Byte = 22 - private val SAPPHIRE: Byte = 23 - private val TOPAZ: Byte = 24 - private val AMETHYST: Byte = 26 - - private val SNOW: Byte = 27 - private val ICE_FRAGILE: Byte = 28 - private val ICE_NATURAL: Byte = 29 - private val ICE_MAGICAL: Byte = 30 - - private val WATER = 239.toByte() - private val LAVA = 255.toByte() - } - } -/* -package com.torvald.terrarum.console; - -import com.torvald.colourutil.Col4096; -import com.torvald.RasterWriter; -import com.torvald.terrarum.terrarum; - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.color.ColorSpace; -import java.awt.image.*; -import java.io.*; -import java.util.Hashtable; - -/** - * Created by minjaesong on 16-01-17. - */ -public class ExportMap implements console { - - private byte[] mapData; - private int mapDataPointer = 0; - - private static final byte AIR = 0; - - private static final byte STONE = 1; - private static final byte DIRT = 2; - private static final byte GRASS = 3; - - private static final byte SAND = 13; - private static final byte GRAVEL = 14; - - private static final byte COPPER = 15; - private static final byte IRON = 16; - private static final byte GOLD = 17; - private static final byte SILVER = 18; - private static final byte ILMENITE = 19; - private static final byte AURICHALCUM = 20; - - private static final byte DIAMOND = 25; - private static final byte RUBY = 21; - private static final byte EMERALD = 22; - private static final byte SAPPHIRE = 23; - private static final byte TOPAZ = 24; - private static final byte AMETHYST = 26; - - private static final byte SNOW = 27; - private static final byte ICE_FRAGILE = 28; - private static final byte ICE_NATURAL = 29; - private static final byte ICE_MAGICAL = 30; - - private static final byte WATER = (byte) 239; - private static final byte LAVA = (byte) 255; - - private Hashtable colorTable = new Hashtable<>(); - - @Override - public void execute(String[] args) { - if (args.length == 2) { - buildColorTable(); - - mapData = new byte[terrarum.game.map.getWidth() * terrarum.game.map.getHeight() * 3]; - - for (byte tile : terrarum.game.map.getLayerTerrain()) { - byte[] colArray = colorTable.getOrDefault(tile, new Col4096(0xFFF)) - .toByteArray(); - - for (int i = 0; i < 3; i++) { - mapData[mapDataPointer + i] = colArray[i]; - } - - mapDataPointer += 3; - } - - String dir = terrarum.defaultDir + "/Exports/"; - File dirAsFile = new File(dir); - if (!dirAsFile.exists()) { - dirAsFile.mkdir(); - } - - try { - RasterWriter.INSTANCE.writePNG_RGB( - terrarum.game.map.getWidth() - , terrarum.game.map.getHeight() - , mapData - , dir + args[1] + ".png" - ); - new Echo().execute("ExportMap: exported to " + args[1] + ".png"); - - } catch (IOException e) { - new Echo().execute("ExportMap: IOException raised."); - e.printStackTrace(); - } - - mapData = null; - mapDataPointer = 0; - - // Free up some memory - System.gc(); - } - else{ - printUsage(); - } - } - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Usage: export "); - echo.execute("Exports current map into visible image."); - echo.execute("The image can be found at %adddata%/terrarum/Exports"); - } - - private void buildColorTable() { - colorTable.put(AIR, new Col4096(0xCEF)); - colorTable.put(STONE, new Col4096(0x887)); - colorTable.put(DIRT, new Col4096(0x763)); - colorTable.put(GRASS, new Col4096(0x251)); - - colorTable.put(COPPER, new Col4096(0x6A8)); - colorTable.put(IRON, new Col4096(0xC75)); - colorTable.put(GOLD, new Col4096(0xCB6)); - colorTable.put(ILMENITE, new Col4096(0x8AB)); - colorTable.put(AURICHALCUM, new Col4096(0xD92)); - colorTable.put(SILVER, new Col4096(0xDDD)); - - colorTable.put(DIAMOND, new Col4096(0x9CE)); - colorTable.put(RUBY, new Col4096(0xB10)); - colorTable.put(EMERALD, new Col4096(0x0B1)); - colorTable.put(SAPPHIRE, new Col4096(0x01B)); - colorTable.put(TOPAZ, new Col4096(0xC70)); - colorTable.put(AMETHYST, new Col4096(0x70C)); - - colorTable.put(WATER, new Col4096(0x038)); - colorTable.put(LAVA, new Col4096(0xF50)); - - colorTable.put(SAND, new Col4096(0xDCA)); - colorTable.put(GRAVEL, new Col4096(0x664)); - - colorTable.put(ICE_NATURAL, new Col4096(0x9AB)); - colorTable.put(ICE_MAGICAL, new Col4096(0x7AC)); - colorTable.put(ICE_FRAGILE, new Col4096(0x6AF)); - colorTable.put(SNOW, new Col4096(0xCDE)); - - - } - -} - - */ \ No newline at end of file diff --git a/src/com/torvald/terrarum/console/Help.kt b/src/com/torvald/terrarum/console/Help.kt index e262852a1..368ee0f47 100644 --- a/src/com/torvald/terrarum/console/Help.kt +++ b/src/com/torvald/terrarum/console/Help.kt @@ -10,16 +10,10 @@ class Help : ConsoleCommand { override fun execute(args: Array) { val echo = Echo() if (args.size == 1) { - for (i in 1..6) echo.execute(Lang["HELP_OTF_TEXT_$i"]) + for (i in 1..6) echo.execute(Lang["HELP_OTF_MAIN_$i"]) } else if (args[1].toLowerCase() == "slow") { - if (Terrarum.game.screenZoom < 1) - echo.execute(Lang["HELP_OTF_SLOW_IF_ZOOM"]) - - if (Terrarum.game.debugWindow.isVisible) - echo.execute(Lang["HELP_OTF_SLOW_IF_F3"]) - - for (i in 1..1) echo.execute(Lang["HELP_OTF_SLOW_$i"]) + for (i in 1..4) echo.execute(Lang["HELP_OTF_SLOW_$i"]) } else { for (i in 1..6) echo.execute(Lang["HELP_OTF_MAIN_$i"]) diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilter.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilter.kt new file mode 100644 index 000000000..80c7ddb34 --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilter.kt @@ -0,0 +1,8 @@ +package com.torvald.terrarum.mapgenerator + +/** + * Created by minjaesong on 16-03-31. + */ +interface NoiseFilter { + fun getGrad(func_argX: Int, start: Float, end: Float): Float +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt new file mode 100644 index 000000000..3b4d7ecd7 --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt @@ -0,0 +1,46 @@ +package com.torvald.terrarum.mapgenerator + +import com.jme3.math.FastMath + +/** + * Double Quadratic polynomial + * (16/9) * (start-end)/height^2 * (x-height)^2 + end + * 16/9: terrain is formed from 1/4 of height. + * 1 - (1/4) = 3/4, reverse it and square it. + * That makes 16/9. + + * Shape: + + * cavity - + * small + * - + * - + * -- + * ---- + * cavity -------- + * large ---------------- + + * @param func_argX + * * + * @param start + * * + * @param end + * * + * @return + * Created by minjaesong on 16-03-31. + */ +object NoiseFilterCubic : NoiseFilter { + override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + val graph_gradient = -FastMath.pow(FastMath.pow((1 - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat(), 3f), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 + (start - end) / FastMath.pow(MapGenerator.HEIGHT.toFloat(), 3f) * + FastMath.pow((func_argX - MapGenerator.HEIGHT).toFloat(), 3f) + end + + if (func_argX < MapGenerator.TERRAIN_AVERAGE_HEIGHT) { + return start + } else if (func_argX >= MapGenerator.HEIGHT) { + return end + } else { + return graph_gradient + } + } +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt new file mode 100644 index 000000000..a7b7c783c --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilterMinusQuadratic.kt @@ -0,0 +1,46 @@ +package com.torvald.terrarum.mapgenerator + +import com.jme3.math.FastMath + +/** + * Quadratic polynomial + * -(16/9) * (start-end)/height^2 * (x - 0.25 * height)^2 + start + * 16/9: terrain is formed from 1/4 of height. + * 1 - (1/4) = 3/4, reverse it and square it. + * That makes 16/9. + + * Shape: + + * cavity _ + * small + * _ + * _ + * __ + * ____ + * cavity ________ + * large ________________ + + * @param func_argX + * * + * @param start + * * + * @param end + * * + * @return + * Created by minjaesong on 16-03-31. + */ +object NoiseFilterMinusQuadratic : NoiseFilter { + override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + val graph_gradient = -FastMath.pow(FastMath.sqr((1 - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 + (start - end) / FastMath.sqr(MapGenerator.HEIGHT.toFloat()) * + FastMath.sqr((func_argX - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start + + if (func_argX < MapGenerator.TERRAIN_AVERAGE_HEIGHT) { + return start + } else if (func_argX >= MapGenerator.HEIGHT) { + return end + } else { + return graph_gradient + } + } +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt new file mode 100644 index 000000000..058b22d1a --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilterQuadratic.kt @@ -0,0 +1,47 @@ +package com.torvald.terrarum.mapgenerator + +import com.jme3.math.FastMath + +/** + * Quadratic polynomial + * (16/9) * (start-end)/height^2 * (x-height)^2 + end + * 16/9: terrain is formed from 1/4 of height. + * 1 - (1/4) = 3/4, reverse it and square it. + * That makes 16/9. + + * Shape: + + * cavity - + * small + * - + * - + * -- + * ---- + * cavity -------- + * large ---------------- + + * @param func_argX + * * + * @param start + * * + * @param end + * * + * @return + * + * Created by minjaesong on 16-03-31. + */ +object NoiseFilterQuadratic : NoiseFilter { + override fun getGrad(func_argX: Int, start: Float, end: Float): Float { + val graph_gradient = FastMath.pow(FastMath.sqr((1 - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9 + (start - end) / FastMath.sqr(MapGenerator.HEIGHT.toFloat()) * + FastMath.sqr((func_argX - MapGenerator.HEIGHT).toFloat()) + end + + if (func_argX < MapGenerator.TERRAIN_AVERAGE_HEIGHT) { + return start + } else if (func_argX >= MapGenerator.HEIGHT) { + return end + } else { + return graph_gradient + } + } +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt new file mode 100644 index 000000000..8eb9d7779 --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt @@ -0,0 +1,20 @@ +package com.torvald.terrarum.mapgenerator + +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 { + val graph_gradient = (end - start) / FastMath.sqrt((MapGenerator.HEIGHT - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) * FastMath.sqrt((func_argX - MapGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start + + if (func_argX < MapGenerator.TERRAIN_AVERAGE_HEIGHT) { + return start + } else if (func_argX >= MapGenerator.HEIGHT) { + return end + } else { + return graph_gradient + } + } +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt b/src/com/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt new file mode 100644 index 000000000..f72802b6e --- /dev/null +++ b/src/com/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt @@ -0,0 +1,10 @@ +package com.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 + } +} \ No newline at end of file diff --git a/src/com/torvald/terrarum/ui/ConsoleWindow.kt b/src/com/torvald/terrarum/ui/ConsoleWindow.kt index d0afa35c6..0cc94922c 100644 --- a/src/com/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/com/torvald/terrarum/ui/ConsoleWindow.kt @@ -60,7 +60,7 @@ class ConsoleWindow : UICanvas, UITypable { // text and cursor g.color = Color.white g.drawString(input, 1f + drawOffX, drawOffY) - g.fillRect(inputDrawWidth.toFloat() + drawOffX, drawOffY, 2f, inputDrawHeight.toFloat()) + g.fillRect(inputDrawWidth.toFloat() + drawOffX + 1, drawOffY, 2f, inputDrawHeight.toFloat()) // messages for (i in 0..MESSAGES_DISPLAY_COUNT - 1) { diff --git a/src/com/torvald/terrarum/ui/MessageWindow.kt b/src/com/torvald/terrarum/ui/MessageWindow.kt index d3a4e0a56..64225cd0a 100644 --- a/src/com/torvald/terrarum/ui/MessageWindow.kt +++ b/src/com/torvald/terrarum/ui/MessageWindow.kt @@ -116,6 +116,6 @@ constructor(override var width: Int, isBlackVariant: Boolean) : UICanvas { companion object { // private int messagesShowingIndex = 0; val MESSAGES_DISPLAY = 2 - val OPEN_CLOSE_TIME = 200 + val OPEN_CLOSE_TIME = 160 } }