mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-12 22:56:06 +09:00
cavegen renewed (WIP)
Former-commit-id: c29114d50d7d86ef903aa2215b5603a01547999a Former-commit-id: 1099816bc5fd8998cbd538a855c9986bc6b1b983
This commit is contained in:
@@ -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"
|
||||
|
@@ -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을 사용할 수 있습니다."
|
||||
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String>) {
|
||||
(notifinator.UI as Notification).sendNotification(Terrarum.appgc, update_delta, msg)
|
||||
notifinator.setAsOpening()
|
||||
|
||||
@@ -167,6 +167,48 @@ constructor(//properties
|
||||
worldTime.update(delta)
|
||||
}
|
||||
|
||||
fun terrainIterator(): Iterator<Int> {
|
||||
return object : Iterator<Int> {
|
||||
|
||||
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<Int> {
|
||||
return object : Iterator<Int> {
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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<BitSet>
|
||||
|
||||
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<FloatArray> {
|
||||
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<FloatArray> {
|
||||
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<FloatArray> {
|
||||
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<FloatArray>, 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<FloatArray>, 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<FloatArray>, 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<FloatArray>, 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<FloatArray>, scarcity: Float, replaceFrom: Int, tile: Int, message: String) {
|
||||
println("[mapgenerator] " + message)
|
||||
private fun processNoiseLayers(noiseRecords: Array<TaggedJoise>) {
|
||||
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<FloatArray>, 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<FloatArray>, 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)
|
||||
}
|
||||
@@ -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<String>) = Terrarum.main(args)
|
||||
fun main(args: Array<String>) = 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)
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
19
src/com/torvald/terrarum/MISC_FEATURES.md
Normal file
19
src/com/torvald/terrarum/MISC_FEATURES.md
Normal file
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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<Byte, Col4096>()
|
||||
private val colorTable = HashMap<Int, Col4096>()
|
||||
|
||||
override fun execute(args: Array<String>) {
|
||||
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<Byte, Col4096>)
|
||||
for (tile in Terrarum.game.map.terrainIterator()) {
|
||||
val colArray = (colorTable as Map<Int, Col4096>)
|
||||
.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<Byte, Col4096> 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 <name>");
|
||||
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));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -10,16 +10,10 @@ class Help : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
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"])
|
||||
|
||||
8
src/com/torvald/terrarum/mapgenerator/NoiseFilter.kt
Normal file
8
src/com/torvald/terrarum/mapgenerator/NoiseFilter.kt
Normal file
@@ -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
|
||||
}
|
||||
46
src/com/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt
Normal file
46
src/com/torvald/terrarum/mapgenerator/NoiseFilterCubic.kt
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/com/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt
Normal file
20
src/com/torvald/terrarum/mapgenerator/NoiseFilterSqrt.kt
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/com/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt
Normal file
10
src/com/torvald/terrarum/mapgenerator/NoiseFilterUniform.kt
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user