new noisegen for ores/gems, need some test, error-proof ActorValue addressing, more comments for ActorWithBody.kt

Former-commit-id: a3441e31f11fa89283babee4c9749680495af923
Former-commit-id: 4092ed362f4f8c28685f82a70ee49e0bee0f0a13
This commit is contained in:
Song Minjae
2016-04-04 23:55:00 +09:00
parent 1573851130
commit bad4afe247
20 changed files with 349 additions and 227 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -56,7 +56,7 @@ class Col216 : LimitedColours {
} }
private fun assertRaw(i: Int) { private fun assertRaw(i: Int) {
if (i >= COLOUR_DOMAIN_SIZE || i < 0) { if (i >= COLOUR_RANGE_SIZE || i < 0) {
println("i: " + i.toString()) println("i: " + i.toString())
throw IllegalArgumentException() throw IllegalArgumentException()
} }
@@ -77,6 +77,6 @@ class Col216 : LimitedColours {
const val MUL = 6 const val MUL = 6
const val MUL_2 = MUL * MUL const val MUL_2 = MUL * MUL
const val MAX_STEP = MUL - 1 const val MAX_STEP = MUL - 1
const val COLOUR_DOMAIN_SIZE = MUL_2 * MUL const val COLOUR_RANGE_SIZE = MUL_2 * MUL
} }
} }

View File

@@ -7,7 +7,6 @@ import org.newdawn.slick.Color
*/ */
interface LimitedColours { interface LimitedColours {
fun createSlickColor(raw: Int): Color fun createSlickColor(raw: Int): Color
fun createSlickColor(r: Int, g: Int, b: Int): Color fun createSlickColor(r: Int, g: Int, b: Int): Color

View File

@@ -180,13 +180,13 @@ constructor() : Font {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
// chosung // initials
hangulSheet.renderInUse( hangulSheet.renderInUse(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexCho, choRow) Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexCho, choRow)
// jungseong // medials
hangulSheet.renderInUse( hangulSheet.renderInUse(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexJung, jungRow) Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexJung, jungRow)
// jongseong // finals
hangulSheet.renderInUse( hangulSheet.renderInUse(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexJong, jongRow) Math.round(x + getWidthSubstr(s, i + 1) - glyphW), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), indexJong, jongRow)
} }
@@ -231,6 +231,7 @@ constructor() : Font {
} }
wenQuanYi_1.endUse() wenQuanYi_1.endUse()
// WenQuanYi 2
wenQuanYi_2.startUse() wenQuanYi_2.startUse()
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
@@ -249,7 +250,7 @@ constructor() : Font {
wenQuanYi_2.endUse() wenQuanYi_2.endUse()
//ascii fonts // regular fonts
var prevInstance = -1 var prevInstance = -1
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
@@ -313,16 +314,20 @@ constructor() : Font {
} }
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
sheetKey[prevInstance].renderInUse( try {
Math.round(x + getWidthSubstr(s, i + 1) - glyphW) // Interchar: pull punct right next to hangul to the left sheetKey[prevInstance].renderInUse(
+ if (i > 0 && isHangul(s[i - 1])) -3 else 0, Math.round(y) + Math.round(x + getWidthSubstr(s, i + 1) - glyphW) // Interchar: pull punct right next to hangul to the left
if (prevInstance == SHEET_CJK_PUNCT) + if (i > 0 && isHangul(s[i - 1])) -3 else 0, Math.round(y) +
-1 if (prevInstance == SHEET_CJK_PUNCT)
else if (prevInstance == SHEET_FW_UNI) -1
(H - H_HANGUL) / 2 else if (prevInstance == SHEET_FW_UNI)
else 0, (H - H_HANGUL) / 2
sheetX, sheetY) else 0,
sheetX, sheetY)
}
catch (e: ArrayIndexOutOfBoundsException) {
// character that does not exist in the sheet. No render, pass.
}
} }
} }

View File

@@ -1,6 +1,6 @@
package com.torvald.terrarum.itemproperties package com.torvald.terrarum.itemproperties
import com.torvald.terrarum.gameactors.CanBeStoredAsItem import com.torvald.terrarum.gameactors.CanBeAnItem
import com.torvald.terrarum.gameitem.InventoryItem import com.torvald.terrarum.gameitem.InventoryItem
import com.torvald.terrarum.Terrarum import com.torvald.terrarum.Terrarum
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
@@ -34,7 +34,7 @@ object ItemPropCodex {
return itemCodex[(code and 0xFFFFFFFF).toInt()] return itemCodex[(code and 0xFFFFFFFF).toInt()]
else { else {
for (actor in Terrarum.game.actorContainer) { for (actor in Terrarum.game.actorContainer) {
if (actor is CanBeStoredAsItem && actor.referenceID.equals(code)) if (actor is CanBeAnItem && actor.referenceID.equals(code))
return actor.itemData return actor.itemData
} }

View File

@@ -39,26 +39,51 @@ open class KVHashMap {
} }
fun getAsInt(key: String): Int? { fun getAsInt(key: String): Int? {
val value = get(key)
if (value is JsonPrimitive)
return value.asInt
return get(key) as Int? return get(key) as Int?
} }
fun getAsFloat(key: String): Float? { fun getAsFloat(key: String): Float? {
val value = get(key) val value = get(key)
if (value is Int) if (value is Int)
return value.toFloat() return value.toFloat()
else if (value is JsonPrimitive) return value.asFloat else if (value is JsonPrimitive)
return value.asFloat
return value as Float? return value as Float?
} }
fun getAsDouble(key: String): Double? {
val value = get(key)
if (value is Int)
return value.toDouble()
else if (value is JsonPrimitive)
return value.asDouble
return value as Double?
}
fun getAsString(key: String): String? { fun getAsString(key: String): String? {
val value = get(key) val value = get(key)
if (value is JsonPrimitive) return value.asString
if (value is JsonPrimitive)
return value.asString
return value as String? return value as String?
} }
fun getAsBoolean(key: String): Boolean? { fun getAsBoolean(key: String): Boolean? {
val value = get(key) val value = get(key)
if (value is JsonPrimitive) return value.asBoolean
if (value is JsonPrimitive)
return value.asBoolean
return value as Boolean? return value as Boolean?
} }

View File

@@ -35,18 +35,18 @@ object LightmapRenderer {
private val OFFSET_G = 1 private val OFFSET_G = 1
private val OFFSET_B = 0 private val OFFSET_B = 0
private val TSIZE = MapDrawer.TILE_SIZE private const val TSIZE = MapDrawer.TILE_SIZE
// color model related vars // color model related constants
const val MUL = 256 // modify this to 1024 to implement 30-bit RGB const val MUL = 256 // modify this to 1024 to implement 30-bit RGB
const val MUL_2 = MUL * MUL const val MUL_2 = MUL * MUL
const val CHANNEL_MAX = MUL - 1 const val CHANNEL_MAX = MUL - 1
const val CHANNEL_MAX_FLOAT = CHANNEL_MAX.toFloat() const val CHANNEL_MAX_FLOAT = CHANNEL_MAX.toFloat()
const val COLOUR_DOMAIN_SIZE = MUL * MUL_2 const val COLOUR_RANGE_SIZE = MUL * MUL_2
private const val deprecatedFeatureDebatable = "The usage of this feature is debatable. Do not use it yet." private const val deprecatedFeatureDebatable = "The usage of this feature is debatable. Do not use it yet."
@Deprecated(deprecatedFeatureDebatable) @Deprecated(deprecatedFeatureDebatable)
fun addLantern(x: Int, y: Int, intensity: Int) { fun addLantern(x: Int, y: Int, intensity: Int) {
val thisLantern = LightmapLantern(x, y, intensity) val thisLantern = LightmapLantern(x, y, intensity)
@@ -77,6 +77,7 @@ object LightmapRenderer {
fun getLight(x: Int, y: Int): Int? = fun getLight(x: Int, y: Int): Int? =
if (x !in 0..Terrarum.game.map.width - 1 || y !in 0..Terrarum.game.map.height - 1) if (x !in 0..Terrarum.game.map.width - 1 || y !in 0..Terrarum.game.map.height - 1)
// if out of range then
null null
else else
java.lang.Byte.toUnsignedInt(lightMapLSB!![y][x]) or (lightMapMSB!![y][x].toInt() shl 8) java.lang.Byte.toUnsignedInt(lightMapLSB!![y][x]) or (lightMapMSB!![y][x].toInt() shl 8)
@@ -336,7 +337,7 @@ object LightmapRenderer {
// calculate ambient // calculate ambient
var ambient: Int = 0 var ambient: Int = 0
var nearby: Int = 0 var nearby: Int = 0
findNearbyBrightest@ for (yoff in -1..1) { for (yoff in -1..1) {
for (xoff in -1..1) { for (xoff in -1..1) {
/** /**
* filter for 'v's as: * filter for 'v's as:
@@ -393,9 +394,8 @@ object LightmapRenderer {
* @return darkened data (0-39) per channel * @return darkened data (0-39) per channel
*/ */
fun darkenColoured(data: Int, darken: Int): Int { fun darkenColoured(data: Int, darken: Int): Int {
if (darken.toInt() < 0 || darken.toInt() >= COLOUR_DOMAIN_SIZE) { if (darken.toInt() < 0 || darken.toInt() >= COLOUR_RANGE_SIZE)
throw IllegalArgumentException("darken: out of " + "range") throw IllegalArgumentException("darken: out of range ($darken)")
}
val r = clampZero(getR(data) - getR(darken)) val r = clampZero(getR(data) - getR(darken))
val g = clampZero(getG(data) - getG(darken)) val g = clampZero(getG(data) - getG(darken))
@@ -416,9 +416,8 @@ object LightmapRenderer {
* @return * @return
*/ */
fun darkenUniformFloat(data: Int, darken: Float): Int { fun darkenUniformFloat(data: Int, darken: Float): Int {
if (darken < 0 || darken > 1f) { if (darken < 0 || darken > 1f)
throw IllegalArgumentException("darken: out of " + "range") throw IllegalArgumentException("darken: out of range ($darken)")
}
val r = clampZero(getR(data) - darken) val r = clampZero(getR(data) - darken)
val g = clampZero(getG(data) - darken) val g = clampZero(getG(data) - darken)
@@ -438,9 +437,8 @@ object LightmapRenderer {
* @return * @return
*/ */
fun darkenUniformInt(data: Int, darken: Int): Int { fun darkenUniformInt(data: Int, darken: Int): Int {
if (darken < 0 || darken > CHANNEL_MAX) { if (darken < 0 || darken > CHANNEL_MAX)
throw IllegalArgumentException("darken: out of " + "range") throw IllegalArgumentException("darken: out of range ($darken)")
}
val r = clampZero(getRawR(data) - darken) val r = clampZero(getRawR(data) - darken)
val g = clampZero(getRawG(data) - darken) val g = clampZero(getRawG(data) - darken)
@@ -463,9 +461,8 @@ object LightmapRenderer {
* @return brightened data [0-39] per channel * @return brightened data [0-39] per channel
*/ */
private fun brightenColoured(data: Int, brighten: Int): Int { private fun brightenColoured(data: Int, brighten: Int): Int {
if (brighten.toInt() < 0 || brighten.toInt() >= COLOUR_DOMAIN_SIZE) { if (brighten.toInt() < 0 || brighten.toInt() >= COLOUR_RANGE_SIZE)
throw IllegalArgumentException("brighten: out of " + "range") throw IllegalArgumentException("brighten: out of range ($brighten)")
}
val r = clampFloat(getR(data) + getR(brighten)) val r = clampFloat(getR(data) + getR(brighten))
val g = clampFloat(getG(data) + getG(brighten)) val g = clampFloat(getG(data) + getG(brighten))
@@ -530,12 +527,10 @@ object LightmapRenderer {
* @return * @return
*/ */
fun getRaw(RGB: Int, offset: Int): Int { fun getRaw(RGB: Int, offset: Int): Int {
if (offset == OFFSET_R) return getRawR(RGB) if (offset == OFFSET_R) return getRawR(RGB)
if (offset == OFFSET_G) return getRawG(RGB) else if (offset == OFFSET_G) return getRawG(RGB)
if (offset == OFFSET_B) else if (offset == OFFSET_B) return getRawB(RGB)
return getRawB(RGB) else throw IllegalArgumentException("Channel offset out of range")
else
throw IllegalArgumentException("Channel offset out of range")
} }
private fun getR(rgb: Int): Float { private fun getR(rgb: Int): Float {
@@ -559,28 +554,16 @@ object LightmapRenderer {
} }
fun constructRGBFromInt(r: Int, g: Int, b: Int): Int { fun constructRGBFromInt(r: Int, g: Int, b: Int): Int {
if (r < 0 || r > CHANNEL_MAX) { if (r !in 0..CHANNEL_MAX) throw IllegalArgumentException("Red: out of range")
throw IllegalArgumentException("Red: out of range") if (g !in 0..CHANNEL_MAX) throw IllegalArgumentException("Green: out of range")
} if (b !in 0..CHANNEL_MAX) throw IllegalArgumentException("Blue: out of range")
if (g < 0 || g > CHANNEL_MAX) {
throw IllegalArgumentException("Green: out of range")
}
if (b < 0 || b > CHANNEL_MAX) {
throw IllegalArgumentException("Blue: out of range")
}
return (r * MUL_2 + g * MUL + b) return (r * MUL_2 + g * MUL + b)
} }
fun constructRGBFromFloat(r: Float, g: Float, b: Float): Int { fun constructRGBFromFloat(r: Float, g: Float, b: Float): Int {
if (r < 0 || r > 1.0f) { if (r < 0 || r > 1.0f) throw IllegalArgumentException("Red: out of range")
throw IllegalArgumentException("Red: out of range") if (g < 0 || g > 1.0f) throw IllegalArgumentException("Green: out of range")
} if (b < 0 || b > 1.0f) throw IllegalArgumentException("Blue: out of range")
if (g < 0 || g > 1.0f) {
throw IllegalArgumentException("Green: out of range")
}
if (b < 0 || b > 1.0f) {
throw IllegalArgumentException("Blue: out of range")
}
val intR = Math.round(r * CHANNEL_MAX) val intR = Math.round(r * CHANNEL_MAX)
val intG = Math.round(g * CHANNEL_MAX) val intG = Math.round(g * CHANNEL_MAX)
@@ -622,10 +605,10 @@ object LightmapRenderer {
} }
private fun outOfBounds(x: Int, y: Int): Boolean = private fun outOfBounds(x: Int, y: Int): Boolean =
x < 0 || y < 0 || x >= Terrarum.game.map.width || y >= Terrarum.game.map.height x !in 0..Terrarum.game.map.width - 1 || y !in 0..Terrarum.game.map.height - 1
private fun outOfMapBounds(x: Int, y: Int): Boolean = private fun outOfMapBounds(x: Int, y: Int): Boolean =
x < 0 || y < 0 || x >= lightMapMSB!![0].size || y >= lightMapMSB!!.size x !in 0..lightMapMSB!![0].size - 1 || y !in 0..lightMapMSB!!.size - 1
private fun clampZero(i: Int): Int = if (i < 0) 0 else i private fun clampZero(i: Int): Int = if (i < 0) 0 else i

View File

@@ -11,14 +11,14 @@ import org.newdawn.slick.*
* Created by minjaesong on 15-12-31. * Created by minjaesong on 15-12-31.
*/ */
object MapDrawer { object MapDrawer {
@JvmStatic val TILE_SIZE = 16 const val TILE_SIZE = 16
private var envOverlayColourmap: Image = Image("./res/graphics/black_body_col_1000_40000_K.png") private var envOverlayColourmap: Image = Image("./res/graphics/black_body_col_1000_40000_K.png")
@JvmStatic private val ENV_COLTEMP_LOWEST = 5500 private val ENV_COLTEMP_LOWEST = 5500
@JvmStatic private val ENV_COLTEMP_HIGHEST = 7500 private val ENV_COLTEMP_HIGHEST = 7500
@JvmStatic val ENV_COLTEMP_NOON = 6500 val ENV_COLTEMP_NOON = 6500
private var colTemp: Int = 0 private var colTemp: Int = 0

View File

@@ -24,8 +24,11 @@ object MapGenerator {
var TERRAIN_AVERAGE_HEIGHT: Int = 0 var TERRAIN_AVERAGE_HEIGHT: Int = 0
private var minimumFloatingIsleHeight: Int = 0 private var minimumFloatingIsleHeight: Int = 0
private val noiseGradientStart = 0.67f private val NOISE_GRAD_START = 0.67f
private val noiseGradientEnd = 0.56f private val NOISE_GRAD_END = 0.56f
private val NOISE_SIMPLEX_ORE_START = 1.42f
private val NOISE_SIMPLEX_ORE_END = 1.28f
private val HILL_WIDTH = 256 // power of two! private val HILL_WIDTH = 256 // power of two!
//private val MAX_HILL_HEIGHT = 100 //private val MAX_HILL_HEIGHT = 100
@@ -106,46 +109,32 @@ object MapGenerator {
*/ */
val noiseArray = arrayOf( 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("Carving caves", noiseRidged(1.7f, 1.4f), 1f, TILE_MACRO_ALL, TILE_MACRO_ALL, TileNameCode.AIR, NoiseFilterSqrt, CAVEGEN_THRE_START, CAVEGEN_THRE_END)
TaggedJoise("Collapsing caves", noiseBlobs(0.5f, 0.5f), 0.3f, TileNameCode.AIR, TileNameCode.STONE, TileNameCode.STONE, NoiseFilterUniform) , TaggedJoise("Collapsing caves", noiseBlobs(0.5f, 0.5f), 0.3f, TileNameCode.AIR, TileNameCode.STONE, TileNameCode.STONE, NoiseFilterUniform)
// random stone patches on grounds //, TaggedJoise("Putting stone patches on the ground", noiseBlobs(0.8f, 0.8f), 1.02f, TileNameCode.DIRT, TileNameCode.DIRT, TileNameCode.STONE, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart)
//TaggedJoise(noiseBlobs(0.25f, 0.25f), 1.02f, TileNameCode.DIRT, TileNameCode.STONE, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart), //, TaggedJoise("Placing dirt spots in the cave", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.DIRT, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart)
// random dirt spots in caves //, TaggedJoise("Quarrying some stone into gravels", noiseBlobs(0.5f, 0.5f), 0.98f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.GRAVEL, NoiseFilterQuadratic, noiseGradientEnd, noiseGradientStart)
//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),
// copper veins //, TaggedJoise("Growing copper veins", noiseRidged(1.7f, 1.7f), 1.68f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_COPPER)
//TaggedJoise(noiseRidged(2.2f, 2.2f), 1.67f, TileNameCode.STONE, TileNameCode.ORE_COPPER), //, TaggedJoise("Cutting copper veins", noiseBlobs(0.4f, 0.4f), 0.26f, TileNameCode.ORE_COPPER, TileNameCode.STONE, TileNameCode.STONE)
// separate copper veins
//TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_COPPER, TileNameCode.STONE),
// iron veins //, TaggedJoise("Growing iron veins", noiseRidged(1.7f, 1.7f), 1.68f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_IRON)
//TaggedJoise(noiseRidged(2.2f, 2.2f), 1.69f, TileNameCode.STONE, TileNameCode.ORE_IRON), //, TaggedJoise("Cutting iron veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_IRON, TileNameCode.STONE, TileNameCode.STONE)
// separate iron veins
//TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_IRON, TileNameCode.STONE),
// silver veins //, TaggedJoise("Growing silver veins", noiseRidged(1.7f, 1.7f), 1.71f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_SILVER)
//TaggedJoise(noiseRidged(2.2f, 2.2f), 1.70f, TileNameCode.STONE, TileNameCode.ORE_SILVER), //, TaggedJoise("Cutting silver veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_SILVER, TileNameCode.STONE, TileNameCode.STONE)
// separate silver veins
//TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_SILVER, TileNameCode.STONE),
// gold veins //, TaggedJoise("Growing gold veins", noiseRidged(1.7f, 1.7f), 1.73f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.ORE_GOLD)
//TaggedJoise(noiseRidged(2.2f, 2.2f), 1.71f, TileNameCode.STONE, TileNameCode.ORE_GOLD), //, TaggedJoise("Cutting gold veins", noiseBlobs(0.7f, 0.7f), 0.26f, TileNameCode.ORE_GOLD, TileNameCode.STONE, TileNameCode.STONE)
// separate gold veins
//TaggedJoise(noiseBlobs(1.3f, 1.3f), 0.75f, TileNameCode.ORE_GOLD, TileNameCode.STONE),
// topaz ////, TaggedJoise("Growing topaz clusters", noiseBlobs(0.9f, 0.9f), 2f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_TOPAZ)
//TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_TOPAZ), //, TaggedJoise("Growing aluminium oxide clusters", noiseBlobs(0.9f, 0.9f), 1.7f, TileNameCode.STONE, TileNameCode.STONE, intArrayOf(TileNameCode.RAW_RUBY, TileNameCode.RAW_SAPPHIRE))
// ruby/sapphire //, TaggedJoise("Growing emerald clusters", noiseBlobs(0.9f, 0.9f), 1,7f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_EMERALD)
//TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, intArrayOf(TileNameCode.RAW_RUBY, TileNameCode.RAW_SAPPHIRE)), //, TaggedJoise("Growing hearts of white", noiseBlobs(0.9f, 0.9f), 1.83f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_DIAMOND)
// emerald
//TaggedJoise(noiseBlobs(1.55f, 1.55f), 1.5f, TileNameCode.STONE, TileNameCode.RAW_EMERALD), //, TaggedJoise("Growing hearts of violet", noiseRidged(2.5f, 2.5f), 1.75f, TileNameCode.STONE, TileNameCode.STONE, TileNameCode.RAW_AMETHYST)
// diamond //, TaggedJoise("Cutting over-grown hearts", noiseBlobs(0.7f, 0.7f), 0.17f, TileNameCode.RAW_AMETHYST, TileNameCode.STONE, TileNameCode.STONE)
//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) processNoiseLayers(noiseArray)
@@ -195,7 +184,7 @@ object MapGenerator {
private fun noiseBlobs(xStretch: Float, yStretch: Float): Joise { private fun noiseBlobs(xStretch: Float, yStretch: Float): Joise {
val gradval = ModuleBasisFunction() val gradval = ModuleBasisFunction()
gradval.seed = SEED gradval.seed = SEED xor random.nextLong()
gradval.setType(ModuleBasisFunction.BasisType.GRADVAL) gradval.setType(ModuleBasisFunction.BasisType.GRADVAL)
gradval.setInterpolation(ModuleBasisFunction.InterpolationType.QUINTIC) gradval.setInterpolation(ModuleBasisFunction.InterpolationType.QUINTIC)
@@ -207,6 +196,25 @@ object MapGenerator {
return Joise(gradval_scale) return Joise(gradval_scale)
} }
/**
* Note:
* * Threshold 1.4 for rarer gem clusters, 1.35 for ores
*/
private fun noiseSimplex(xStretch: Float, yStretch: Float): Joise {
val simplex = ModuleFractal()
simplex.seed = SEED
simplex.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.SIMPLEX)
simplex.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.LINEAR)
simplex.setNumOctaves(2)
simplex.setFrequency(1.0)
val simplex_scale = ModuleScaleDomain()
simplex_scale.setScaleX(1.0 / xStretch)
simplex_scale.setScaleY(1.0 / yStretch)
simplex_scale.setSource(simplex)
return Joise(simplex_scale)
}
private fun generateOcean(noiseArrayLocal: IntArray): IntArray { private fun generateOcean(noiseArrayLocal: IntArray): IntArray {
val oceanLeftP1 = noiseArrayLocal[OCEAN_WIDTH] val oceanLeftP1 = noiseArrayLocal[OCEAN_WIDTH]
@@ -571,8 +579,8 @@ object MapGenerator {
*/ */
private fun carveByMap(noisemap: Any, scarcity: Float, tile: Int, message: String, private fun carveByMap(noisemap: Any, scarcity: Float, tile: Int, message: String,
filter: NoiseFilter = NoiseFilterQuadratic, filter: NoiseFilter = NoiseFilterQuadratic,
filterStart: Float = noiseGradientStart, filterStart: Float = NOISE_GRAD_START,
filterEnd: Float = noiseGradientEnd) { filterEnd: Float = NOISE_GRAD_END) {
println("[mapgenerator] " + message) println("[mapgenerator] " + message)
for (y in 0..HEIGHT - 1) { for (y in 0..HEIGHT - 1) {
@@ -601,8 +609,8 @@ object MapGenerator {
private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, replaceTo: Int, message: String, private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, replaceTo: Int, message: String,
filter: NoiseFilter = NoiseFilterQuadratic, filter: NoiseFilter = NoiseFilterQuadratic,
filterStart: Float = noiseGradientStart, filterStart: Float = NOISE_GRAD_START,
filterEnd: Float = noiseGradientEnd) { filterEnd: Float = NOISE_GRAD_END) {
println("[mapgenerator] " + message) println("[mapgenerator] " + message)
for (y in 0..HEIGHT - 1) { for (y in 0..HEIGHT - 1) {
@@ -632,8 +640,8 @@ object MapGenerator {
private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, tile: IntArray, message: String, private fun fillByMap(noisemap: Any, scarcity: Float, replaceFrom: Int, tile: IntArray, message: String,
filter: NoiseFilter = NoiseFilterQuadratic, filter: NoiseFilter = NoiseFilterQuadratic,
filterStart: Float = noiseGradientStart, filterStart: Float = NOISE_GRAD_START,
filterEnd: Float = noiseGradientEnd) { filterEnd: Float = NOISE_GRAD_END) {
println("[mapgenerator] " + message) println("[mapgenerator] " + message)
for (y in 0..HEIGHT - 1) { for (y in 0..HEIGHT - 1) {
@@ -943,6 +951,6 @@ object MapGenerator {
var replaceFromTerrain: Int, var replaceFromWall: Int, var replaceFromTerrain: Int, var replaceFromWall: Int,
var replaceTo: Any, var replaceTo: Any,
var filter: NoiseFilter = NoiseFilterQuadratic, var filter: NoiseFilter = NoiseFilterQuadratic,
var filterArg1: Float = noiseGradientStart, var filterArg1: Float = NOISE_GRAD_START,
var filterArg2: Float = noiseGradientEnd) var filterArg2: Float = NOISE_GRAD_END)
} }

View File

@@ -12,9 +12,14 @@ import org.newdawn.slick.GameContainer
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import org.newdawn.slick.state.StateBasedGame import org.newdawn.slick.state.StateBasedGame
import java.io.File import java.io.File
import java.io.FileWriter
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import java.util.logging.FileHandler
import java.util.logging.Level import java.util.logging.Level
import java.util.logging.Logger import java.util.logging.Logger
import java.util.logging.SimpleFormatter
/** /**
* Created by minjaesong on 15-12-30. * Created by minjaesong on 15-12-30.
@@ -120,7 +125,22 @@ constructor(gamename: String) : StateBasedGame(gamename) {
appgc.start() appgc.start()
} }
catch (ex: SlickException) { catch (ex: SlickException) {
Logger.getLogger(Terrarum::class.java.name).log(Level.SEVERE, null, ex) val logger = Logger.getLogger(Terrarum::class.java.name)
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
val calendar = Calendar.getInstance()
val filepath = "$defaultDir/crashlog-${dateFormat.format(calendar.time)}.txt"
val fileHandler = FileHandler(filepath)
logger.addHandler(fileHandler)
val formatter = SimpleFormatter()
fileHandler.formatter = formatter
//logger.info()
println("The game has been crashed!")
println("Crash log were saved to $filepath.")
println("================================================================================")
logger.log(Level.SEVERE, null, ex)
} }
} }

View File

@@ -133,6 +133,8 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
@Transient private val map: GameMap @Transient private val map: GameMap
@Transient private val MASS_DEFAULT = 60f
init { init {
// referenceID = HQRNG().nextLong() // renew ID just in case // referenceID = HQRNG().nextLong() // renew ID just in case
map = Terrarum.game.map map = Terrarum.game.map
@@ -172,25 +174,41 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
x - (baseHitboxW / 2 - hitboxTranslateX) * scale, y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, baseHitboxH * scale) x - (baseHitboxW / 2 - hitboxTranslateX) * scale, y - (baseHitboxH - hitboxTranslateY) * scale, baseHitboxW * scale, baseHitboxH * scale)
} }
private fun updatePhysicalInfos() {
scale = actorValue.getAsFloat(AVKey.SCALE) ?: 1f
mass = (actorValue.getAsFloat(AVKey.BASEMASS) ?: MASS_DEFAULT) * FastMath.pow(scale, 3f)
if (elasticity != 0f) elasticity = 0f
}
override fun update(gc: GameContainer, delta_t: Int) { override fun update(gc: GameContainer, delta_t: Int) {
if (isUpdate) { if (isUpdate) {
updatePhysicalInfos()
/** /**
* Update variables * Update variables
*/ */
// make NoClip work for player
if (this is Player) { if (this is Player) {
isNoSubjectToGrav = isPlayerNoClip isNoSubjectToGrav = isPlayerNoClip
isNoCollideWorld = isPlayerNoClip isNoCollideWorld = isPlayerNoClip
isNoSubjectToFluidResistance = isPlayerNoClip isNoSubjectToFluidResistance = isPlayerNoClip
} }
if (mass < MASS_LOWEST) mass = MASS_LOWEST // clamp to minimum possible mass // clamp to the minimum possible mass
if (mass < MASS_LOWEST) mass = MASS_LOWEST
// set sprite dimension vars if there IS sprite for the actor
if (sprite != null) { if (sprite != null) {
baseSpriteHeight = sprite!!.height baseSpriteHeight = sprite!!.height
baseSpriteWidth = sprite!!.width baseSpriteWidth = sprite!!.width
} }
// copy gravitational constant from the map the actor is in
gravitation = map.gravitation gravitation = map.gravitation
// Auto climb rate. Clamp to TSIZE
AUTO_CLIMB_RATE = Math.min(TSIZE / 8 * FastMath.sqrt(scale), TSIZE.toFloat()).toInt() AUTO_CLIMB_RATE = Math.min(TSIZE / 8 * FastMath.sqrt(scale), TSIZE.toFloat()).toInt()
// Actors are subject to the gravity and the buoyancy if they are not levitating
if (!isNoSubjectToGrav) { if (!isNoSubjectToGrav) {
applyGravitation() applyGravitation()
applyBuoyancy() applyBuoyancy()
@@ -207,7 +225,7 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
//} //}
// Set 'next' positions to fiddle with // Set 'next' position (hitbox) to fiddle with
updateNextHitboxFromVelo() updateNextHitboxFromVelo()
@@ -217,15 +235,16 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
// updateHorizontalPos(); // updateHorizontalPos();
//} //}
//else { //else {
// compensate for colliding
updateHorizontalPos() updateHorizontalPos()
updateVerticalPos() updateVerticalPos()
//} //}
// apply our compensation to actual hitbox
updateHitboxX() updateHitboxX()
updateHitboxY() updateHitboxY()
// make sure the actor does not go out of the map
clampNextHitbox() clampNextHitbox()
clampHitbox() clampHitbox()
} }
@@ -259,29 +278,30 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
private fun updateVerticalPos() { private fun updateVerticalPos() {
if (!isNoCollideWorld) { if (!isNoCollideWorld) {
// check downward if (veloY >= 0) { // check downward
if (veloY >= 0) { if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_BOTTOM)) {
adjustHitBottom() adjustHitBottom()
elasticReflectY() elasticReflectY()
grounded = true grounded = true
} else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { }
else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is standing ON the ground
elasticReflectY() elasticReflectY()
grounded = true grounded = true
} else { }
else { // the actor is not grounded at all
grounded = false grounded = false
} }
} else if (veloY < 0) { }
else if (veloY < 0) { // check upward
grounded = false grounded = false
if (isColliding(CONTACT_AREA_TOP)) { // the ceiling has dug into the body
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_TOP)) {
adjustHitTop() adjustHitTop()
elasticReflectY() elasticReflectY()
} else if (isColliding(CONTACT_AREA_TOP, 0, -1)) { }
elasticReflectY() // for reversed gravity else if (isColliding(CONTACT_AREA_TOP, 0, -1)) { // the actor is touching the ceiling
} else { elasticReflectY() // reflect on ceiling, for reversed gravity
}
else { // the actor is not grounded at all
} }
} }
} }
@@ -294,6 +314,7 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
var newYOff = 0 // always positive var newYOff = 0 // always positive
// count up Y offset until the actor is not touching the ground
var colliding: Boolean var colliding: Boolean
do { do {
newYOff += 1 newYOff += 1
@@ -311,6 +332,7 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
var newYOff = 0 // always positive var newYOff = 0 // always positive
// count up Y offset until the actor is not touching the ceiling
var colliding: Boolean var colliding: Boolean
do { do {
newYOff += 1 newYOff += 1
@@ -323,49 +345,57 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
private fun updateHorizontalPos() { private fun updateHorizontalPos() {
if (!isNoCollideWorld) { if (!isNoCollideWorld) {
// check right if (veloX >= 0.5) { // check right
if (veloX >= 0.5) {
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) { if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) {
// the actor is embedded to the wall
adjustHitRight() adjustHitRight()
elasticReflectX() elasticReflectX()
} else if (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, -1, 0)) {
elasticReflectX()
} else {
} }
} else if (veloX <= -0.5) { else if (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, -1, 0)) {
// the actor is touching the wall
elasticReflectX()
}
else {
}
}
else if (veloX <= -0.5) { // check left
// System.out.println("collidingleft"); // System.out.println("collidingleft");
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) { if (isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) {
// the actor is embedded to the wall
adjustHitLeft() adjustHitLeft()
elasticReflectX() elasticReflectX()
} else if (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0)) {
elasticReflectX()
} else {
} }
} else { else if (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0)) {
// the actor is touching the wall
elasticReflectX()
}
else {
}
}
else { // check both sides?
// System.out.println("updatehorizontal - |velo| < 0.5"); // System.out.println("updatehorizontal - |velo| < 0.5");
if (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)) { //if (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)) {
elasticReflectX() // elasticReflectX()
} //}
} }
} }
} }
private fun adjustHitRight() { private fun adjustHitRight() {
val newY = nextHitbox!!.posY // look carefully, getPos or getPointed val newY = nextHitbox!!.posY // look carefully, posY or pointedY
// int-ify posY of nextHitbox // int-ify posY of nextHitbox
nextHitbox!!.setPositionX(FastMath.floor(nextHitbox!!.posX + nextHitbox!!.width) - nextHitbox!!.width) nextHitbox!!.setPositionX(FastMath.floor(nextHitbox!!.posX + nextHitbox!!.width) - nextHitbox!!.width)
var newXOff = 0 // always positive var newXOff = 0 // always positive
// count up Y offset until the actor is not touching the wall
var colliding: Boolean var colliding: Boolean
do { do {
newXOff += 1 newXOff += 1
colliding = isColliding(CONTACT_AREA_BOTTOM, -newXOff, 0) colliding = isColliding(CONTACT_AREA_BOTTOM, -newXOff, 0)
} while (newXOff < TSIZE && colliding) } while (newXOff < TSIZE && colliding)
val newX = nextHitbox!!.posX - newXOff val newX = nextHitbox!!.posX - newXOff -1 // -1: Q&D way to prevent the actor sticking to the wall and won't detach
nextHitbox!!.setPosition(newX, newY) nextHitbox!!.setPosition(newX, newY)
} }
@@ -376,14 +406,15 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
var newXOff = 0 // always positive var newXOff = 0 // always positive
// count up Y offset until the actor is not touching the wall
var colliding: Boolean var colliding: Boolean
do { do {
newXOff += 1 newXOff += 1
colliding = isColliding(CONTACT_AREA_TOP, newXOff, 0) colliding = isColliding(CONTACT_AREA_TOP, newXOff, 0)
} while (newXOff < TSIZE && colliding) } while (newXOff < TSIZE && colliding)
val newX = nextHitbox!!.posX + newXOff val newX = nextHitbox!!.posX + newXOff +1 // +1: Q&D way to prevent the actor sticking to the wall and won't detach
nextHitbox!!.setPosition(newX, newY) // + 1; float-point rounding compensation (i think...) nextHitbox!!.setPosition(newX, newY)
} }
private fun elasticReflectX() { private fun elasticReflectX() {
@@ -394,9 +425,7 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
if (veloY != 0f) veloY = -veloY * elasticity if (veloY != 0f) veloY = -veloY * elasticity
} }
private fun isColliding(side: Int, tx: Int = 0, ty: Int = 0): Boolean { private fun isColliding(side: Int, tx: Int = 0, ty: Int = 0): Boolean = getContactingArea(side, tx, ty) > 1
return getContactingArea(side, tx, ty) > 1
}
private fun getContactingArea(side: Int, translateX: Int = 0, translateY: Int = 0): Int { private fun getContactingArea(side: Int, translateX: Int = 0, translateY: Int = 0): Int {
var contactAreaCounter = 0 var contactAreaCounter = 0
@@ -408,19 +437,23 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x)
+ i + translateX) + i + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxEnd.y) + translateY) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxEnd.y) + translateY)
} else if (side == CONTACT_AREA_TOP) { }
else if (side == CONTACT_AREA_TOP) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x)
+ i + translateX) + i + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) + translateY) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) + translateY)
} else if (side == CONTACT_AREA_RIGHT) { }
else if (side == CONTACT_AREA_RIGHT) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxEnd.x) + translateX) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxEnd.x) + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y)
+ i + translateY) + i + translateY)
} else if (side == CONTACT_AREA_LEFT) { }
else if (side == CONTACT_AREA_LEFT) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) + translateX) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y)
+ i + translateY) + i + translateY)
} else { }
else {
throw IllegalArgumentException(side.toString() + ": Wrong side input") throw IllegalArgumentException(side.toString() + ": Wrong side input")
} }
@@ -443,19 +476,23 @@ open class ActorWithBody constructor() : Actor, Visible, Glowing {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x)
+ i + translateX) + i + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxEnd.y) + translateY) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxEnd.y) + translateY)
} else if (side == CONTACT_AREA_TOP) { }
else if (side == CONTACT_AREA_TOP) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x)
+ i + translateX) + i + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) + translateY) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) + translateY)
} else if (side == CONTACT_AREA_RIGHT) { }
else if (side == CONTACT_AREA_RIGHT) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxEnd.x) + translateX) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxEnd.x) + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y)
+ i + translateY) + i + translateY)
} else if (side == CONTACT_AREA_LEFT) { }
else if (side == CONTACT_AREA_LEFT) {
tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) + translateX) tileX = div16TruncateToMapWidth(Math.round(nextHitbox!!.hitboxStart.x) + translateX)
tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y) tileY = div16TruncateToMapHeight(Math.round(nextHitbox!!.hitboxStart.y)
+ i + translateY) + i + translateY)
} else { }
else {
throw IllegalArgumentException(side.toString() + ": Wrong side input") throw IllegalArgumentException(side.toString() + ": Wrong side input")
} }

View File

@@ -2,11 +2,11 @@ package com.torvald.terrarum.gameactors
import com.torvald.JsonFetcher import com.torvald.JsonFetcher
import com.torvald.random.Fudge3 import com.torvald.random.Fudge3
import com.torvald.random.HQRNG
import com.torvald.terrarum.langpack.Lang import com.torvald.terrarum.langpack.Lang
import com.google.gson.JsonObject import com.google.gson.JsonObject
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import java.io.IOException import java.io.IOException
import java.security.SecureRandom
/** /**
* Created by minjaesong on 16-03-25. * Created by minjaesong on 16-03-25.
@@ -14,7 +14,7 @@ import java.io.IOException
object CreatureRawInjector { object CreatureRawInjector {
const val JSONPATH = "./res/raw/creatures/" const val JSONPATH = "./res/raw/creatures/"
private const val MULTIPLIER_RAW_ELEM_SUFFIX = "mult" private const val MULTIPLIER_RAW_ELEM_SUFFIX = AVKey.MULTIPLIER_SUFFIX
/** /**
* 'Injects' creature raw ActorValue to the ActorValue reference provided. * 'Injects' creature raw ActorValue to the ActorValue reference provided.
@@ -26,10 +26,10 @@ object CreatureRawInjector {
fun inject(actorValueRef: ActorValue, jsonFileName: String) { fun inject(actorValueRef: ActorValue, jsonFileName: String) {
val jsonObj = JsonFetcher.readJson(JSONPATH + jsonFileName) val jsonObj = JsonFetcher.readJson(JSONPATH + jsonFileName)
val elementsString = arrayOf("racename", "racenameplural") val elementsString = arrayOf(AVKey.RACENAME, AVKey.RACENAMEPLURAL)
val elementsFloat = arrayOf("baseheight", "basemass", "accel", "toolsize", "encumbrance") val elementsFloat = arrayOf(AVKey.BASEHEIGHT, AVKey.BASEMASS, AVKey.ACCEL, AVKey.TOOLSIZE, AVKey.ENCUMBRANCE)
val elementsFloatVariable = arrayOf("strength", "speed", "jumppower", "scale", "speed") val elementsFloatVariable = arrayOf(AVKey.STRENGTH, AVKey.SPEED, AVKey.JUMPPOWER, AVKey.SCALE, AVKey.SPEED)
val elementsBoolean = arrayOf("intelligent") val elementsBoolean = arrayOf(AVKey.INTELLIGENT)
// val elementsMultiplyFromOne = arrayOf() // val elementsMultiplyFromOne = arrayOf()
setAVStrings(actorValueRef, elementsString, jsonObj) setAVStrings(actorValueRef, elementsString, jsonObj)
@@ -38,8 +38,8 @@ object CreatureRawInjector {
// setAVMultiplyFromOne(actorValueRef, elementsMultiplyFromOne, jsonObj) // setAVMultiplyFromOne(actorValueRef, elementsMultiplyFromOne, jsonObj)
setAVBooleans(actorValueRef, elementsBoolean, jsonObj) setAVBooleans(actorValueRef, elementsBoolean, jsonObj)
actorValueRef["accel"] = Player.WALK_ACCEL_BASE actorValueRef[AVKey.ACCEL] = Player.WALK_ACCEL_BASE
actorValueRef["accelmult"] = 1f actorValueRef[AVKey.ACCELMULT] = 1f
} }
/** /**
@@ -54,7 +54,7 @@ object CreatureRawInjector {
for (s in elemSet) { for (s in elemSet) {
val baseValue = jsonObject.get(s).asFloat val baseValue = jsonObject.get(s).asFloat
// roll fudge dice and get value [-3, 3] as [0, 6] // roll fudge dice and get value [-3, 3] as [0, 6]
val varSelected = Fudge3(HQRNG()).rollForArray() val varSelected = Fudge3(SecureRandom()).rollForArray()
// get multiplier from json. Assuming percentile // get multiplier from json. Assuming percentile
val multiplier = jsonObject.get(s + MULTIPLIER_RAW_ELEM_SUFFIX).asJsonArray.get(varSelected).asInt val multiplier = jsonObject.get(s + MULTIPLIER_RAW_ELEM_SUFFIX).asJsonArray.get(varSelected).asInt
val realValue = baseValue * multiplier / 100f val realValue = baseValue * multiplier / 100f
@@ -106,7 +106,7 @@ object CreatureRawInjector {
for (s in elemSet) { for (s in elemSet) {
val baseValue = 1f val baseValue = 1f
// roll fudge dice and get value [-3, 3] as [0, 6] // roll fudge dice and get value [-3, 3] as [0, 6]
val varSelected = Fudge3(HQRNG()).rollForArray() val varSelected = Fudge3(SecureRandom()).rollForArray()
// get multiplier from json. Assuming percentile // get multiplier from json. Assuming percentile
val multiplier = jsonObject.get(s).asJsonArray.get(varSelected).asInt val multiplier = jsonObject.get(s).asJsonArray.get(varSelected).asInt
val realValue = baseValue * multiplier / 100f val realValue = baseValue * multiplier / 100f

View File

@@ -12,7 +12,7 @@ import java.util.*
* Created by minjaesong on 16-03-14. * Created by minjaesong on 16-03-14.
*/ */
open class NPCIntelligentBase : ActorWithBody() open class NPCIntelligentBase : ActorWithBody()
, AIControlled, Pocketed, CanBeStoredAsItem, Factionable, LandHolder { , AIControlled, Pocketed, CanBeAnItem, Factionable, LandHolder {
override var itemData: InventoryItem = object : InventoryItem { override var itemData: InventoryItem = object : InventoryItem {
override var itemID = HQRNG().nextLong() override var itemID = HQRNG().nextLong()

View File

@@ -1,6 +1,7 @@
package com.torvald.terrarum.gameactors package com.torvald.terrarum.gameactors
import com.torvald.spriteanimation.SpriteAnimation import com.torvald.spriteanimation.SpriteAnimation
import com.torvald.terrarum.mapdrawer.MapDrawer
/** /**
* Created by minjaesong on 16-03-25. * Created by minjaesong on 16-03-25.
@@ -20,9 +21,9 @@ object PFCynthia {
p.sprite!!.setRowsAndFrames(1, 1) p.sprite!!.setRowsAndFrames(1, 1)
p.sprite!!.setAsVisible() p.sprite!!.setAsVisible()
p.setHitboxDimension(15, 40, 9, 0) p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: Player.BASE_HEIGHT, 9, 0)
p.setPosition((4096 * 16).toFloat(), (300 * 16).toFloat()) p.setPosition((4096 * MapDrawer.TILE_SIZE).toFloat(), (300 * 16).toFloat())
return p return p
} }

View File

@@ -5,6 +5,7 @@ import com.torvald.terrarum.gameactors.faction.Faction
import com.torvald.spriteanimation.SpriteAnimation import com.torvald.spriteanimation.SpriteAnimation
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.torvald.terrarum.gameactors.faction.FactionFactory import com.torvald.terrarum.gameactors.faction.FactionFactory
import com.torvald.terrarum.mapdrawer.MapDrawer
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import java.io.IOException import java.io.IOException
@@ -32,38 +33,36 @@ object PFSigrid {
p.spriteGlow!!.setAsVisible() p.spriteGlow!!.setAsVisible()
p.actorValue = ActorValue() p.actorValue = ActorValue()
p.actorValue["scale"] = 1.0f p.actorValue[AVKey.SCALE] = 1.0f
p.actorValue["speed"] = 4.0f p.actorValue[AVKey.SPEED] = 4.0f
p.actorValue["speedmult"] = 1.0f p.actorValue[AVKey.SPEEDMULT] = 1.0f
p.actorValue["accel"] = Player.WALK_ACCEL_BASE p.actorValue[AVKey.ACCEL] = Player.WALK_ACCEL_BASE
p.actorValue["accelmult"] = 1.0f p.actorValue[AVKey.ACCELMULT] = 1.0f
p.actorValue[AVKey.JUMPPOWER] = 5f
p.actorValue["jumppower"] = 5f p.actorValue[AVKey.BASEMASS] = 80f
p.actorValue[AVKey.PHYSIQUEMULT] = 1 // Constant 1.0 for player, meant to be used by random mobs
p.actorValue["basemass"] = 80f
p.actorValue["physiquemult"] = 1 // Constant 1.0 for player, meant to be used by random mobs
/** /**
* fixed value, or 'base value', from creature strength of Dwarf Fortress. * fixed value, or 'base value', from creature strength of Dwarf Fortress.
* Human race uses 1000. (see CreatureHuman.json) * Human race uses 1000. (see CreatureHuman.json)
*/ */
p.actorValue["strength"] = 1414 p.actorValue[AVKey.STRENGTH] = 1414
p.actorValue["encumbrance"] = 1000 p.actorValue[AVKey.ENCUMBRANCE] = 1000
p.actorValue[AVKey.BASEHEIGHT] = 46
p.actorValue["name"] = "Sigrid" p.actorValue[AVKey.NAME] = "Sigrid"
p.actorValue["intelligent"] = true p.actorValue[AVKey.INTELLIGENT] = true
p.actorValue["luminosity"] = 5980540 p.actorValue[AVKey.LUMINOSITY] = 5980540
p.actorValue["selectedtile"] = 16 p.actorValue["selectedtile"] = 16
//p.setHitboxDimension(18, 46, 8, 0) p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 10, 0)
p.setHitboxDimension(15, 46, 10, 0)
p.inventory = ActorInventory(0x7FFFFFFF, true) p.inventory = ActorInventory(0x7FFFFFFF, true)
p.setPosition((4096 * 16).toFloat(), (300 * 16).toFloat()) p.setPosition((4096 * MapDrawer.TILE_SIZE).toFloat(), (300 * 16).toFloat())
p.faction.add(FactionFactory.create("FactionSigrid.json")) p.faction.add(FactionFactory.create("FactionSigrid.json"))

View File

@@ -69,9 +69,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
override var houseDesignation: ArrayList<Int>? = null override var houseDesignation: ArrayList<Int>? = null
override var luminosity: Int override var luminosity: Int
get() = actorValue.getAsInt("luminosity") ?: 0 get() = actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
set(value) { set(value) {
actorValue["luminosity"] = value actorValue[AVKey.LUMINOSITY] = value
} }
companion object { companion object {
@@ -79,7 +79,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
@Transient internal const val WALK_STOP_ACCEL = 0.32f @Transient internal const val WALK_STOP_ACCEL = 0.32f
@Transient internal const val WALK_ACCEL_BASE = 0.32f @Transient internal const val WALK_ACCEL_BASE = 0.32f
@Transient val PLAYER_REF_ID: Long = 0x51621D @Transient const val PLAYER_REF_ID: Long = 0x51621D
@Transient const val BASE_HEIGHT = 40
} }
/** /**
@@ -100,7 +101,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
if (vehicleRiding is Player) if (vehicleRiding is Player)
throw RuntimeException("Attempted to 'ride' " + "player object.") throw RuntimeException("Attempted to 'ride' " + "player object.")
updatePhysicalInfos()
super.update(gc, delta_t) super.update(gc, delta_t)
updateSprite(delta_t) updateSprite(delta_t)
@@ -113,12 +113,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
} }
private fun updatePhysicalInfos() {
scale = actorValue.getAsFloat("scale")!!
mass = actorValue.getAsFloat("basemass")!! * FastMath.pow(scale, 3f)
if (elasticity != 0f) elasticity = 0f
}
/** /**
* @param left (even if the game is joypad controlled, you must give valid value) * @param left (even if the game is joypad controlled, you must give valid value)
@@ -128,8 +122,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun walkHorizontal(left: Boolean, absAxisVal: Float) { private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
//if ((!super.isWalledLeft() && left) || (!super.isWalledRight() && !left)) { //if ((!super.isWalledLeft() && left) || (!super.isWalledRight() && !left)) {
readonly_totalX = veloX + readonly_totalX = veloX +
actorValue.getAsFloat("accel")!! * actorValue.getAsFloat(AVKey.ACCEL)!! *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) * FastMath.sqrt(scale) *
applyAccelRealism(walkPowerCounter) * applyAccelRealism(walkPowerCounter) *
(if (left) -1 else 1).toFloat() * (if (left) -1 else 1).toFloat() *
@@ -142,8 +136,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
} }
// Clamp veloX // Clamp veloX
veloX = absClamp(veloX, actorValue.getAsFloat("speed")!! veloX = absClamp(veloX, actorValue.getAsFloat(AVKey.SPEED)!!
* actorValue.getAsFloat("speedmult")!! * actorValue.getAsFloat(AVKey.SPEEDMULT)!!
* FastMath.sqrt(scale)) * FastMath.sqrt(scale))
// Heading flag // Heading flag
@@ -162,8 +156,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
*/ */
private fun walkVertical(up: Boolean, absAxisVal: Float) { private fun walkVertical(up: Boolean, absAxisVal: Float) {
readonly_totalY = veloY + readonly_totalY = veloY +
actorValue.getAsFloat("accel")!! * actorValue.getAsFloat(AVKey.ACCEL)!! *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) * FastMath.sqrt(scale) *
applyAccelRealism(walkPowerCounter) * applyAccelRealism(walkPowerCounter) *
(if (up) -1 else 1).toFloat() * (if (up) -1 else 1).toFloat() *
@@ -176,8 +170,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
} }
// Clamp veloX // Clamp veloX
veloY = absClamp(veloY, actorValue.getAsFloat("speed")!! veloY = absClamp(veloY, actorValue.getAsFloat(AVKey.SPEED)!!
* actorValue.getAsFloat("speedmult")!! * actorValue.getAsFloat(AVKey.SPEEDMULT)!!
* FastMath.sqrt(scale)) * FastMath.sqrt(scale))
} }
@@ -210,15 +204,15 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun walkHStop() { private fun walkHStop() {
if (veloX > 0) { if (veloX > 0) {
veloX -= actorValue.getAsFloat("accel")!! * veloX -= actorValue.getAsFloat(AVKey.ACCEL)!! *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) FastMath.sqrt(scale)
// compensate overshoot // compensate overshoot
if (veloX < 0) veloX = 0f if (veloX < 0) veloX = 0f
} else if (veloX < 0) { } else if (veloX < 0) {
veloX += actorValue.getAsFloat("accel")!! * veloX += actorValue.getAsFloat(AVKey.ACCEL)!! *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) FastMath.sqrt(scale)
// compensate overshoot // compensate overshoot
@@ -233,7 +227,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun walkVStop() { private fun walkVStop() {
if (veloY > 0) { if (veloY > 0) {
veloY -= WALK_STOP_ACCEL * veloY -= WALK_STOP_ACCEL *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) FastMath.sqrt(scale)
// compensate overshoot // compensate overshoot
@@ -241,7 +235,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
veloY = 0f veloY = 0f
} else if (veloY < 0) { } else if (veloY < 0) {
veloY += WALK_STOP_ACCEL * veloY += WALK_STOP_ACCEL *
actorValue.getAsFloat("accelmult")!! * actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale) FastMath.sqrt(scale)
// compensate overshoot // compensate overshoot
@@ -256,12 +250,12 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun updateMovementControl() { private fun updateMovementControl() {
if (!noClip) { if (!noClip) {
if (grounded) { if (grounded) {
actorValue.set("accelmult", 1f) actorValue.set(AVKey.ACCELMULT, 1f)
} else { } else {
actorValue.set("accelmult", ACCEL_MULT_IN_FLIGHT) actorValue.set(AVKey.ACCELMULT, ACCEL_MULT_IN_FLIGHT)
} }
} else { } else {
actorValue.set("accelmult", 1f) actorValue.set(AVKey.ACCELMULT, 1f)
} }
} }
@@ -405,7 +399,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun jump() { private fun jump() {
if (jumping) { if (jumping) {
val len = MAX_JUMP_LENGTH.toFloat() val len = MAX_JUMP_LENGTH.toFloat()
val pwr = actorValue.getAsFloat("jumppower")!! val pwr = actorValue.getAsFloat(AVKey.JUMPPOWER)!! * (actorValue.getAsFloat(AVKey.JUMPPOWERMULT) ?: 1f)
// increment jump counter // increment jump counter
if (jumpCounter < len) jumpCounter += 1 if (jumpCounter < len) jumpCounter += 1

View File

@@ -14,6 +14,27 @@
Arrangements in the map Arrangements in the map
Time →→→→ Time →→→→
voice 1 → # # # # # # # voice 1 → □□□□□□□□□□□□□□□□...
voice 2 → # # # # # # # voice 2 → □□□□□□□□□□□□□□□□...
↑ played simultaneously along the X-axis ↑ played simultaneously along the X-axis
- Each tracker head and body are connected by placing tracks adjacent to each other or connecting them with wire.
Connect two or more tracker head to play the array of trackers play simultaneously (multi-tracking)
- Serialisation
<actorid>.json
{
0 = [long],
1 = [long],
...
47 = [long],
speed = 120
}
*long: array of bits that indicates the note is stricken (1) or not (0)
0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000
↑G5 ↑C5 ↑C4 ↑C3 ↑C2 ↑C1 E0↑
(Assuming C3 (32nd bit) as middle 'C')
*speed: in BPM

View File

@@ -29,8 +29,8 @@ class SetGlobalLightLevel : ConsoleCommand {
try { try {
val GL = args[1].toInt() val GL = args[1].toInt()
if (GL.toInt() < 0 || GL.toInt() >= LightmapRenderer.COLOUR_DOMAIN_SIZE) { if (GL.toInt() < 0 || GL.toInt() >= LightmapRenderer.COLOUR_RANGE_SIZE) {
Echo().execute("Range: 0-" + (LightmapRenderer.COLOUR_DOMAIN_SIZE - 1)) Echo().execute("Range: 0-" + (LightmapRenderer.COLOUR_RANGE_SIZE - 1))
} }
else { else {
Terrarum.game.map.globalLight = GL Terrarum.game.map.globalLight = GL

View File

@@ -0,0 +1,30 @@
package com.torvald.terrarum.gameactors
/**
* Created by minjaesong on 16-04-02.
*/
object AVKey {
const val MULTIPLIER_SUFFIX = "mult"
const val SPEED = "speed"
const val SPEEDMULT = "speed$MULTIPLIER_SUFFIX"
const val ACCEL = "accel"
const val ACCELMULT = "accel$MULTIPLIER_SUFFIX"
const val SCALE = "scale"
const val BASEHEIGHT = "baseheight"
const val BASEMASS = "basemass"
const val JUMPPOWER = "jumppower"
const val JUMPPOWERMULT = "jumppower$MULTIPLIER_SUFFIX"
const val STRENGTH = "strength"
const val ENCUMBRANCE = "encumbrance"
const val LUMINOSITY = "luminosity"
const val PHYSIQUEMULT = "physique$MULTIPLIER_SUFFIX"
const val NAME = "name"
const val RACENAME = "racename"
const val RACENAMEPLURAL = "racenameplural"
const val TOOLSIZE = "toolsize"
const val INTELLIGENT = "intelligent"
}

View File

@@ -5,7 +5,7 @@ import com.torvald.terrarum.gameitem.InventoryItem
/** /**
* Created by minjaesong on 16-03-14. * Created by minjaesong on 16-03-14.
*/ */
interface CanBeStoredAsItem { interface CanBeAnItem {
fun attachItemData() fun attachItemData()