font bug sorta fixed, new splash: warning health and safety

Former-commit-id: f79503873f57e781480fa742ed1a058becb6c7a1
Former-commit-id: daeeed816b339958786746c3717670c724676a44
This commit is contained in:
Song Minjae
2016-08-05 01:59:43 +09:00
parent 17c39c1824
commit fa5e95a89d
38 changed files with 483 additions and 82 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,10 @@
{
"globalLight": "generic_light.png",
"skyboxGradColourMap": "generic_skybox.png",
"classification": "genericrain",
"extraImages": [
"raindrop.png"
],
"mixFrom": "__CURRENTWEATHER",
"mixPercentage": 80.0
}

1
assets/sounds/test/.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.{psd,tga,ogg} filter=lfs diff=lfs merge=lfs -text

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/sounds/test/bb.xm Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -154,11 +154,6 @@ constructor() : Font {
private val zeroWidthSheets = arrayOf(
SHEET_COLOURCODE
)
private val cjkWidthSheets = arrayOf(
SHEET_KANA,
SHEET_HANGUL,
SHEET_CJK_PUNCT
)
override fun getWidth(s: String) = getWidthSubstr(s, s.length)
@@ -168,8 +163,8 @@ constructor() : Font {
for (i in 0..endIndex - 1) {
val ctype = getSheetType(s[i])
if (i > 0 && s[i].toInt() > 0x20) {
// Unihan-hangul Kerning
/*if (i > 0 && s[i].toInt() > 0x20) {
// inter-Unihan-hangul Kerning
val cpre = getSheetType(s[i - 1])
if ((unihanWidthSheets.contains(cpre) || cpre == SHEET_HANGUL) && !(unihanWidthSheets.contains(ctype) || ctype == SHEET_HANGUL)
@@ -182,18 +177,22 @@ constructor() : Font {
len += 1
}
}
}*/
if (zeroWidthSheets.contains(ctype))
len += 0
else if (narrowWidthSheets.contains(ctype))
len += W_LATIN_NARROW
else if (cjkWidthSheets.contains(ctype))
len += W_CJK
else if (ctype == SHEET_CJK_PUNCT)
len += W_ASIAN_PUNCT
else if (ctype == SHEET_HANGUL)
len += W_HANGUL
else if (ctype == SHEET_KANA)
len += W_KANA
else if (unihanWidthSheets.contains(ctype))
len += W_UNIHAN
else if (isThaiDiacritics(s[i]))
len = len // set width of the glyph as -W_LATIN_WIDE
len += 0 // set width of the glyph as -W_LATIN_WIDE
else
len += W_LATIN_WIDE
@@ -237,7 +236,7 @@ constructor() : Font {
val jungRow = getHanMedialRow(hIndex)
val jongRow = getHanFinalRow(hIndex)
val glyphW = getWidth("" + ch)
val glyphW = getWidth(ch.toString())
/*// initials
hangulSheet.renderInUse(
@@ -453,11 +452,11 @@ constructor() : Font {
sheetX, sheetY
)*/
sheetKey[prevInstance]!!.getSubImage(sheetX, sheetY).draw(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat() // Interchar: pull punct right next to hangul to the left
+ if (i > 0 && isHangul(s[i - 1])) -3f
else 0f,
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
// to deal with the height difference of the sheets
Math.round(y).toFloat() + (if (prevInstance == SHEET_CJK_PUNCT) -1
else if (prevInstance == SHEET_FW_UNI) (H - H_HANGUL) / 2
else 0).toFloat(),
@@ -589,10 +588,13 @@ constructor() : Font {
internal val JUNG_COUNT = 21
internal val JONG_COUNT = 28
internal val W_CJK = 10
internal val W_ASIAN_PUNCT = 10
internal val W_HANGUL = 11
internal val W_KANA = 12
internal val W_UNIHAN = 16
internal val W_LATIN_WIDE = 9 // width of regular letters, including m
internal val W_LATIN_NARROW = 5 // width of letter f, t, i, l
internal val H = 20
internal val H_HANGUL = 16
internal val H_UNIHAN = 16

View File

@@ -12,7 +12,7 @@ constructor() : GameFontBase() {
init {
GameFontBase.hangulSheet = SpriteSheet(
"./assets/graphics/fonts/han_johab.png", GameFontBase.W_CJK, GameFontBase.H_HANGUL)
"./assets/graphics/fonts/han_johab.png", GameFontBase.W_HANGUL, GameFontBase.H_HANGUL)
GameFontBase.asciiSheet = SpriteSheet(
"./assets/graphics/fonts/ascii_fullwidth.png", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.asciiSheetEF = SpriteSheet(
@@ -24,9 +24,9 @@ constructor() : GameFontBase() {
GameFontBase.extASheetEF = SpriteSheet(
"./assets/graphics/fonts/LatinExtA_ef.png", GameFontBase.W_LATIN_NARROW, GameFontBase.H)
GameFontBase.kanaSheet = SpriteSheet(
"./assets/graphics/fonts/kana.png", GameFontBase.W_CJK, GameFontBase.H_KANA)
"./assets/graphics/fonts/kana.png", GameFontBase.W_KANA, GameFontBase.H_KANA)
GameFontBase.cjkPunct = SpriteSheet(
"./assets/graphics/fonts/cjkpunct.png", GameFontBase.W_CJK, GameFontBase.H_KANA)
"./assets/graphics/fonts/cjkpunct.png", GameFontBase.W_ASIAN_PUNCT, GameFontBase.H_KANA)
/*uniHan = new SpriteSheet(
"./assets/graphics/fonts/unifont_unihan"
+ ((!terrarum.gameLocale.contains("zh"))

View File

@@ -58,6 +58,8 @@ object DefaultConfig {
jsonObject.addProperty("pcgamepadenv", "console")
jsonObject.addProperty("safetywarning", true)
return jsonObject
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum
import net.torvald.imagefont.GameFontWhite
import net.torvald.terrarum.langpack.Lang
import org.newdawn.slick.Font
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
@@ -20,6 +21,8 @@ class StateFontTester : BasicGameState() {
canvas = Graphics(1024, 1024)
gameFont = GameFontWhite()
Terrarum.gameLocale = "fiFI"
}
override fun update(gc: GameContainer, game: StateBasedGame, delta: Int) {
@@ -28,7 +31,21 @@ class StateFontTester : BasicGameState() {
override fun render(gc: GameContainer, game: StateBasedGame, g: Graphics) {
g.font = gameFont
g.drawString(textToPrint, 10f, 10f)
val text = arrayOf(
Lang["APP_WARNING_HEALTH_AND_SAFETY"],
"",
"90 10 20” 50 cm",
"",
"",
Lang["MENU_LABEL_PRESS_ANYKEY_CONTINUE"],
"DGB금융지주의 자회사. 대구광역시에서 쓰는 교통카드인 원패스와 탑패스 그리고 만악의 근원 대경교통카드를 판매 및 정산하고 있다. 본사는",
"Atlantic Records, it features production from Nick Hexum of 311, Tony Kanal of No Doubt, and Sublime producer Paul Leary."
)
for (i in 0..text.size - 1) {
g.drawString(text[i], 10f, 10f + (g.font.lineHeight * i))
}
}
override fun getID(): Int = Terrarum.SCENE_ID_TEST_FONT

View File

@@ -11,6 +11,7 @@ import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gamemap.GameWorld
import net.torvald.terrarum.gamemap.WorldSimulator
import net.torvald.terrarum.gamemap.WorldTime
import net.torvald.terrarum.mapdrawer.LightmapRenderer
import net.torvald.terrarum.mapdrawer.MapCamera
@@ -161,38 +162,56 @@ constructor() : BasicGameState() {
setAppTitle()
///////////////////////////
// world-related updates //
///////////////////////////
world.updateWorldTime(delta)
WorldSimulator(world, player, delta)
WeatherMixer.update(gc, delta)
world.globalLight = globalLightByTime.toInt()
///////////////////////////
// input-related updates //
///////////////////////////
GameController.processInput(gc.input)
uiContainer.forEach { it.processInput(gc.input) }
TileStats.update()
////////////////////////////
// camera-related updates //
////////////////////////////
MapDrawer.update(gc, delta)
MapCamera.update(gc, delta)
///////////////////////////
// actor-related updates //
///////////////////////////
// determine whether the inactive actor should be re-active
wakeDormantActors()
// determine whether the actor should be active or dormant
InactivateDistantActors()
updateActors(gc, delta)
// TODO thread pool(?)
CollisionSolver.process()
////////////////////////
// ui-related updates //
////////////////////////
uiContainer.forEach { ui -> ui.update(gc, delta) }
consoleHandler.update(gc, delta)
debugWindow.update(gc, delta)
notifier.update(gc, delta)
/////////////////////////
// app-related updates //
/////////////////////////
Terrarum.appgc.setVSync(Terrarum.appgc.fps >= Terrarum.VSYNC_TRIGGER_THRESHOLD)
}
@@ -204,8 +223,6 @@ constructor() : BasicGameState() {
}
override fun render(gc: GameContainer, sbg: StateBasedGame, g: Graphics) {
g.setAntiAlias(true)
setBlendNormal()
// determine if lightmap blending should be done

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Typesetter
import net.torvald.terrarum.ui.Typography
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIHandler
import net.torvald.terrarum.ui.KeyboardControlled
@@ -113,24 +113,24 @@ class StateMonitorCheck : BasicGameState() {
// labels
g.color = Color.white
Typesetter.printCentered(
Lang["MENU_MONITOR_CALI_TITLE"],
Typography.printCentered(
g, Lang["MENU_MONITOR_CALI_TITLE"],
titleY,
this, g
this
)
(1..12).forEach {
Typesetter.printCentered(
Lang["MENU_MONITOR_CALI_LABEL_$it"],
Typography.printCentered(
g, Lang["MENU_MONITOR_CALI_LABEL_$it"],
instructionY + it.minus(2).times(g.font.lineHeight),
this, g
this
)
}
Typesetter.printCentered(
Lang["MENU_LABEL_PRESS_ANYKEY_CONTINUE"],
Typography.printCentered(
g, Lang["MENU_LABEL_PRESS_ANYKEY_CONTINUE"],
anykeyY,
this, g
this
)
}

View File

@@ -0,0 +1,139 @@
package net.torvald.terrarum
import com.jme3.math.FastMath
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.DrawUtil
import net.torvald.terrarum.ui.Typography
import org.newdawn.slick.Color
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
import org.newdawn.slick.Image
import org.newdawn.slick.state.BasicGameState
import org.newdawn.slick.state.StateBasedGame
import java.util.*
/**
* Created by minjaesong on 16-08-04.
*/
class StateSplash : BasicGameState() {
val pictogramCollection = ArrayList<Image>()
val virtualImageHeight = 100
var imageBoardHeight = 0
var imageBoardOffset = 0
lateinit var fadeSheet: Image
lateinit var thisG: Graphics
var opacity = 0f
val fadeTime = 500
var fadeTimer = 0
var anykey_hit = false
val backgroundColour = Color(0x303030)
var delta = 0
val deltathre = 500
val auto_dismiss = 5000
var opened = false
override fun init(container: GameContainer?, game: StateBasedGame?) {
// pre-load lang
Lang["MENU_LANGUAGE_THIS"]
pictogramCollection.add(Image("./assets/graphics/gui/health_take_a_break.png"))
pictogramCollection.add(Image("./assets/graphics/gui/health_distance.png"))
fadeSheet = Image(Terrarum.WIDTH, Terrarum.HEIGHT)
thisG = fadeSheet.graphics
thisG.font = Terrarum.gameFont
}
override fun update(container: GameContainer, game: StateBasedGame, delta: Int) {
this.delta = delta
// next splash or load next scene
if (anykey_hit && opacity == 0f) {
System.exit(0)
}
// fade-in
if (delta < deltathre) {
if (opacity < 1f && !anykey_hit) {
opacity = FastMath.interpolateLinear(
fadeTimer.toFloat() / fadeTime, 0f, 1f
)
}
else if (opacity > 0f && anykey_hit) {
opacity = FastMath.interpolateLinear(
fadeTimer.toFloat() / fadeTime, 1f, 0f
)
}
if (!opened && fadeTimer >= fadeTime && !anykey_hit) {
fadeTimer = 0
opened = true
}
}
// auto dismiss
if (opened && fadeTimer >= auto_dismiss)
doAnykeyThingy()
fadeTimer += delta
}
override fun getID(): Int = Terrarum.SCENE_ID_SPLASH
override fun render(container: GameContainer?, game: StateBasedGame?, g: Graphics) {
imageBoardHeight = Terrarum.HEIGHT - thisG.font.lineHeight.times(6)
imageBoardOffset = thisG.font.lineHeight.times(3)
thisG.color = backgroundColour
thisG.fillRect(0f, 0f, fadeSheet.width.toFloat(), fadeSheet.height.toFloat())
thisG.color = Color.white
Typography.printCentered(thisG, Lang["APP_WARNING_HEALTH_AND_SAFETY"],
thisG.font.lineHeight * 2)
Typography.printCentered(thisG, Lang["MENU_LABEL_PRESS_ANYKEY_CONTINUE"],
Terrarum.HEIGHT - thisG.font.lineHeight.times(3))
pictogramCollection.forEachIndexed { i, image ->
DrawUtil.drawCentered(thisG, image, knowYourPlace(i) + imageBoardOffset)
}
g.drawImage(fadeSheet, 0f, 0f, Color(1f, 1f, 1f, opacity))
}
private fun knowYourPlace(i: Int): Int {
val gutter = (imageBoardHeight - virtualImageHeight.times(pictogramCollection.size)).toFloat().div(
pictogramCollection.size + 1f
)
return (gutter * i.plus(1) + virtualImageHeight * i).roundInt()
}
override fun keyPressed(key: Int, c: Char) {
doAnykeyThingy()
}
override fun controllerButtonPressed(controller: Int, button: Int) {
doAnykeyThingy()
}
private fun doAnykeyThingy() {
if (delta < deltathre && !anykey_hit) {
anykey_hit = true
fadeTimer = 0
}
}
}

View File

@@ -73,9 +73,13 @@ constructor(gamename: String) : StateBasedGame(gamename) {
}
}
gc.graphics.clear() // clean up any 'dust' in the buffer
ingame = StateInGame()
//addState(ingame)
addState(StateMonitorCheck())
//addState(StateMonitorCheck())
//addState(StateFontTester())
addState(StateSplash())
}
companion object {
@@ -103,8 +107,8 @@ constructor(gamename: String) : StateBasedGame(gamename) {
lateinit var appgc: AppGameContainer
val WIDTH = 1072
val HEIGHT = 742 // IMAX ratio
var WIDTH = 1072
var HEIGHT = 742 // IMAX ratio
var VSYNC = true
val VSYNC_TRIGGER_THRESHOLD = 56
@@ -141,6 +145,7 @@ constructor(gamename: String) : StateBasedGame(gamename) {
// 0x0 - 0xF: Game-related
// 0x10 - 0x1F: Config
// 0x100 and onward: unit tests for dev
val SCENE_ID_SPLASH = 0x0
val SCENE_ID_HOME = 0x1
val SCENE_ID_GAME = 0x3
val SCENE_ID_CONFIG_CALIBRATE = 0x11
@@ -362,7 +367,7 @@ fun main(args: Array<String>) = Terrarum.main(args)
fun setBlendMul() {
GL11.glEnable(GL11.GL_BLEND)
GL11.glColorMask(true, true, true, true)
GL11.glColorMask(true, true, true, false)
GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA)
}

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.gameactors
import com.jme3.math.FastMath
import net.torvald.terrarum.*
import net.torvald.terrarum.gamemap.GameWorld
import net.torvald.terrarum.mapdrawer.MapDrawer
@@ -971,10 +972,12 @@ open class ActorWithBody : Actor(), Visible {
}
fun Double.floorInt() = Math.floor(this).toInt()
fun Float.floorInt() = FastMath.floor(this).toInt()
fun Double.round() = Math.round(this).toDouble()
fun Double.floor() = Math.floor(this)
fun Double.ceil() = this.floor() + 1.0
fun Double.roundInt(): Int = Math.round(this).toInt()
fun Float.roundInt(): Int = Math.round(this).toInt()
fun Double.abs() = Math.abs(this)
fun Double.sqr() = this * this
fun Int.abs() = if (this < 0) -this else this

View File

@@ -46,27 +46,6 @@ class MDLInterpreterState {
// push, pop, +, -, *, /, %, dup, swap, drop
}
class MagicOrInt() {
private var magic: MagicWords? = null
private var number: Int? = null
constructor(kynngi: MagicWords): this() {
magic = kynngi
}
constructor(integer: Int) : this() {
number = integer
}
fun toMagic() = if (magic != null) magic!! else throw TypeCastException("$this: cannot be cast to MagicWord")
fun toInt() = if (number != null) number!! else throw TypeCastException("$this: cannot be cast to MagicWord")
fun isMagic() = (magic != null)
fun isInt() = (number != null)
override fun toString(): String = if (magic != null && number == null) "$magic" else if (magic == null && number != null) "$number" else "INVALID"
}
class MagicArrayStack {
/**
* Number of elements in the stack
@@ -81,28 +60,28 @@ class MDLInterpreterState {
else deflate(data.size - newSize)
}
private lateinit var data: Array<MagicOrInt?>
private lateinit var data: Array<Int?>
constructor(stackSize: Int) {
data = Array(stackSize, { null })
}
constructor(arr: Array<MagicOrInt?>) {
constructor(arr: Array<Int?>) {
data = arr.copyOf()
depth = size
}
fun push(v: MagicOrInt) {
fun push(v: Int) {
if (depth >= data.size) throw StackOverflowError()
data[depth++] = v
}
fun pop(): MagicOrInt {
fun pop(): Int {
if (depth == 0) throw EmptyStackException()
return data[--depth]!!
}
fun peek(): MagicOrInt? {
fun peek(): Int? {
if (depth == 0) return null
return data[depth - 1]
}
@@ -126,7 +105,7 @@ class MDLInterpreterState {
--depth
}
fun defineFromArray(arr: Array<MagicOrInt?>) { data = arr.copyOf() }
fun defineFromArray(arr: Array<Int?>) { data = arr.copyOf() }
/**
* Increase the stack size by a factor.
@@ -157,10 +136,10 @@ class MDLInterpreterState {
fun equalTo(other: MagicArrayStack) = (this.asArray() == other.asArray())
fun plus() { if (data[depth - 2]!!.isInt() && peek()!!.isInt()) data[depth - 2] = MagicOrInt(data[depth - 2]!!.toInt() + (pop().toInt())) else throw RuntimeException("${data[depth - 2]}: Cannot do arithmetic operation on non-numeric type.") }
fun minus() { if (data[depth - 2]!!.isInt() && peek()!!.isInt()) data[depth - 2] = MagicOrInt(data[depth - 2]!!.toInt() - (pop().toInt())) else throw RuntimeException("${data[depth - 2]}: Cannot do arithmetic operation on non-numeric type.") }
fun times() { if (data[depth - 2]!!.isInt() && peek()!!.isInt()) data[depth - 2] = MagicOrInt(data[depth - 2]!!.toInt() * (pop().toInt())) else throw RuntimeException("${data[depth - 2]}: Cannot do arithmetic operation on non-numeric type.") }
fun div() { if (data[depth - 2]!!.isInt() && peek()!!.isInt()) data[depth - 2] = MagicOrInt(data[depth - 2]!!.toInt() / (pop().toInt())) else throw RuntimeException("${data[depth - 2]}: Cannot do arithmetic operation on non-numeric type.") }
fun mod() { if (data[depth - 2]!!.isInt() && peek()!!.isInt()) data[depth - 2] = MagicOrInt(data[depth - 2]!!.toInt() % (pop().toInt())) else throw RuntimeException("${data[depth - 2]}: Cannot do arithmetic operation on non-numeric type.") }
fun plus() { data[depth - 2] = data[depth - 2]!! + (pop().toInt()) }
fun minus() { data[depth - 2] = data[depth - 2]!! - (pop().toInt()) }
fun times() { data[depth - 2] = data[depth - 2]!! * (pop().toInt()) }
fun div() { data[depth - 2] = data[depth - 2]!! / (pop().toInt()) }
fun mod() { data[depth - 2] = data[depth - 2]!! % (pop().toInt()) }
}
}

View File

@@ -1,6 +1,9 @@
package net.torvald.terrarum.gamemap
import net.torvald.terrarum.gameactors.Player
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.mapdrawer.MapDrawer
import org.dyn4j.geometry.Vector2
import org.newdawn.slick.SlickException

View File

@@ -47,6 +47,8 @@ class MapLayer(var width: Int, var height: Int) : Iterable<Byte> {
data[y][x] = tile
}
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x)
companion object {

View File

@@ -0,0 +1,188 @@
package net.torvald.terrarum.gamemap
import net.torvald.random.HQRNG
import net.torvald.terrarum.gameactors.Player
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.mapdrawer.MapDrawer
import net.torvald.terrarum.tileproperties.TileNameCode
import net.torvald.terrarum.tileproperties.TilePropCodex
import org.newdawn.slick.Graphics
/**
* Created by minjaesong on 16-08-03.
*/
object WorldSimulator {
/**
* In tiles;
* square width/height = field * 2
*/
const val FLUID_UPDATING_SQUARE_RADIUS = 128
const private val DOUBLE_RADIUS = FLUID_UPDATING_SQUARE_RADIUS * 2
private val fluidMap = Array<IntArray>(DOUBLE_RADIUS, { IntArray(DOUBLE_RADIUS) })
const val DISPLACE_CAP = 4
const val FLUID_MAX = 16
operator fun invoke(world: GameWorld, p: Player, delta: Int) {
moveFluids(world, p, delta)
}
/**
* displace fluids. Note that the code assumes the gravity pulls things downward ONLY,
* which means you'll need to modify the code A LOT if you're going to implement zero- or
* reverse-gravity.
*/
fun moveFluids(world: GameWorld, p: Player, delta: Int) {
val updateXFrom = p.hitbox.centeredX.div(MapDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
val updateYFrom = p.hitbox.centeredY.div(MapDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
val updateXTo = updateXFrom + 1 * FLUID_UPDATING_SQUARE_RADIUS
val updateYTo = updateYFrom + 1 * FLUID_UPDATING_SQUARE_RADIUS
/**
* @return amount of fluid actually drained.
* (intended drainage - this) will give you how much fluid is not yet drained.
*/
fun drain(x: Int, y: Int, amount: Int): Int {
val displacement = Math.min(fluidMap[y - updateYFrom][x - updateXFrom], amount)
fluidMap[y - updateYFrom][x - updateXFrom] -= displacement
return displacement
}
fun pour(x: Int, y: Int, amount: Int) {
fun pourInternal(xpos: Int, ypos: Int, volume: Int): Int {
var spil = 0
val addrX = xpos - updateXFrom
val addrY = ypos - updateYFrom
if (addrX >= 0 && addrY >= 0 && addrX < DOUBLE_RADIUS && addrY < DOUBLE_RADIUS) {
fluidMap[addrY][addrX] += volume
if (fluidMap[addrY][addrX] > FLUID_MAX) {
spil = fluidMap[addrY][addrX] - FLUID_MAX
fluidMap[addrY][addrX] = FLUID_MAX
}
}
return spil
}
// pour the fluid
var spillage = pourInternal(x, y, amount)
if (spillage == 0) return
// deal with the spillage
val tileUp = world.getTileFromTerrain(x - updateXFrom, y - updateYFrom - 1)
val tileDown = world.getTileFromTerrain(x - updateXFrom, y - updateYFrom + 1)
// try to fill downward
if (tileDown != null && !tileDown.isSolid()) {
spillage = pourInternal(x, y + 1, spillage)
}
// else, try to fill upward. if there is no space, just discard
if (tileUp != null && !tileUp.isSolid()) {
pourInternal(x, y - 1, spillage)
}
}
purgeFluidMap()
/////////////////////////////////////////////////////////////
// displace fluids. Record displacements into the fluidMap //
/////////////////////////////////////////////////////////////
for (y in updateYFrom..updateYTo) {
for (x in updateXFrom..updateXTo) {
val tile = world.getTileFromTerrain(x, y)
val tileBottom = world.getTileFromTerrain(x, y + 1)
val tileLeft = world.getTileFromTerrain(x - 1, y)
val tileRight = world.getTileFromTerrain(x + 1, y)
if (tile != null && tile.isFluid()) {
// move down if not obstructed
if (tileBottom != null && !tileBottom.isSolid()) {
val drainage = drain(x, y, DISPLACE_CAP)
pour(x, y + 1, drainage)
}
// left and right both open (null is considered as open)
else if ((tileLeft != null && tileRight != null && !tileLeft.isSolid() && !tileRight.isSolid()) ||
tileLeft == null && tileRight == null) {
// half-breaker
val moreToTheRight = HQRNG().nextBoolean()
val displacement = drain(x, y, DISPLACE_CAP)
if (displacement.isEven()) {
pour(x - 1, y, displacement shr 1)
pour(x + 1, y, displacement shr 1)
}
else {
pour(x - 1, y, (displacement shr 1) + if (moreToTheRight) 0 else 1)
pour(x + 1, y, (displacement shr 1) + if (moreToTheRight) 1 else 0)
}
}
// left open (null is considered as open)
else if ((tileLeft != null && !tileLeft.isSolid()) || tileLeft == null) {
val displacement = drain(x, y, DISPLACE_CAP)
pour(x - 1, y, displacement)
}
// right open (null is considered as open)
else if ((tileRight != null && !tileRight.isSolid()) || tileRight == null) {
val displacement = drain(x, y, DISPLACE_CAP)
pour(x + 1, y, displacement)
}
// nowhere open; do default (fill top)
else {
pour(x, y - 1, DISPLACE_CAP)
}
}
}
}
/////////////////////////////////////////////////////
// replace fluids in the map according to fluidMap //
/////////////////////////////////////////////////////
for (y in 0..fluidMap.size - 1) {
for (x in 0..fluidMap[0].size - 1) {
placeFluid(world, updateXFrom + x, updateYFrom + y, WATER, fluidMap[y][x].minus(1))
// FIXME test code: deals with water only!
}
}
}
fun drawFluidMapDebug(p: Player, g: Graphics) {
for (y in 0..fluidMap.size - 1) {
for (x in 0..fluidMap[0].size - 1) {
}
}
}
private fun purgeFluidMap() {
for (y in 1..DOUBLE_RADIUS)
for (x in 1..DOUBLE_RADIUS)
fluidMap[y - 1][x - 1] = 0
}
fun Int.isFluid() = TilePropCodex.getProp(this).isFluid
fun Int.isSolid() = TilePropCodex.getProp(this).isSolid
//fun Int.viscosity() = TilePropCodex.getProp(this).
fun Int.fluidLevel() = this % FLUID_MAX
fun Int.isEven() = (this and 0x01) == 0
private fun placeFluid(world: GameWorld, x: Int, y: Int, tileFluid: Int, amount: Int) {
if (world.layerTerrain.isInBound(x, y)) {
if (amount > 0 && !world.getTileFromTerrain(x, y)!!.isSolid()) {
world.setTileTerrain(x, y, amount.minus(1).plus(tileFluid))
}
else if (amount == 0 && world.getTileFromTerrain(x, y)!!.isFluid()) {
world.setTileTerrain(x, y, TileNameCode.AIR)
}
}
}
val LAVA = TileNameCode.LAVA_1
val WATER = TileNameCode.WATER_1
}

View File

@@ -381,7 +381,8 @@ object MapCamera {
var ret = 0
for (i in 0..3) {
try {
if (!TilePropCodex.getProp(nearbyTiles[i]).isSolid) {
if (!TilePropCodex.getProp(nearbyTiles[i]).isSolid &&
!TilePropCodex.getProp(nearbyTiles[i]).isFluid) {
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
} catch (e: ArrayIndexOutOfBoundsException) {

View File

@@ -1,5 +1,5 @@
"id";"dmg";"name" ; "opacity";"strength";"dsty";"fluid";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"dlfn";"friction"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"4"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"4"
"1"; "0";"TILE_STONE" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "0"; "0"; "0";"16"
"1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "1"; "0"; "0";"16"
"1"; "2";"TILE_STONE_TILE_WHITE" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "2"; "0"; "0";"16"
Can't render this file because it contains an unexpected character in line 1 and column 18.

View File

@@ -0,0 +1,17 @@
package net.torvald.terrarum.ui
import net.torvald.terrarum.Terrarum
import org.newdawn.slick.Graphics
import org.newdawn.slick.Image
/**
* Created by minjaesong on 16-08-04.
*/
object DrawUtil {
fun drawCentered(g: Graphics, image: Image, screenPosY: Int, ui: UICanvas? = null) {
val imageW = image.width
val targetW = if (ui == null) Terrarum.WIDTH else ui.width
g.drawImage(image, targetW.minus(imageW).ushr(1).toFloat(), screenPosY.toFloat())
}
}

View File

@@ -1,14 +1,15 @@
package net.torvald.terrarum.ui
import net.torvald.terrarum.Terrarum
import org.newdawn.slick.Graphics
/**
* Created by minjaesong on 16-07-06.
*/
object Typesetter {
fun printCentered(string: String, screenPosY: Int, ui: UICanvas, g: Graphics) {
object Typography {
fun printCentered(g: Graphics, string: String, screenPosY: Int, ui: UICanvas? = null) {
val stringW = g.font.getWidth(string)
val targetW = ui.width
val targetW = if (ui == null) Terrarum.WIDTH else ui.width
g.drawString(string, targetW.minus(stringW).ushr(1).toFloat(), screenPosY.toFloat())
}

View File

@@ -14,5 +14,7 @@ data class BaseModularWeather(
val globalLightColourMap: Image,
var skyboxGradColourMap: Image,
val classification: String,
var extraImages: ArrayList<Image>
var extraImages: ArrayList<Image>,
val mixFrom: String? = null,
val mixPercentage: Double? = null
)

View File

@@ -27,12 +27,15 @@ object WeatherMixer {
lateinit var currentWeather: BaseModularWeather
lateinit var nextWeather: BaseModularWeather
lateinit var mixedWeather: BaseModularWeather
private var skyBoxCurrent = Rectangle(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
private var skyBoxNext = Rectangle(0f, 0f, Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
val globalLightNow = Light10B(0)
// Weather indices
const val WEATHER_GENERIC = "generic"
const val WEATHER_GENERIC_RAIN = "genericrain"
// TODO add weather classification indices manually
const val RAW_DIR = "./assets/raw/weathers"
@@ -169,6 +172,12 @@ object WeatherMixer {
val skybox: Image
val extraImages = ArrayList<Image>()
val classification = JSON.get("classification").asJsonPrimitive.asString
val mixFrom: String?
try { mixFrom = JSON.get("mixFrom").asJsonPrimitive.asString }
catch (e: NullPointerException) { mixFrom = null }
val mixPercentage: Double?
try { mixPercentage = JSON.get("mixPercentage").asJsonPrimitive.asDouble }
catch (e: NullPointerException) { mixPercentage = null }
// parse globalLight
if (globalLightInJson.isString)
@@ -196,7 +205,10 @@ object WeatherMixer {
// get extra images
for (i in extraImagesPath)
extraImages.add(Image("$pathToImage/$i"))
extraImages.add(Image("$pathToImage/${i.asString}"))
// get mix from
return BaseModularWeather(globalLight, skybox, classification, extraImages)
}

Binary file not shown.