various patches and renaming; thai-variable font sheet

This commit is contained in:
minjaesong
2017-05-27 20:05:12 +09:00
parent d5bf9b8279
commit 225a18619b
22 changed files with 861 additions and 137 deletions

1
.gitignore vendored
View File

@@ -3,5 +3,4 @@ bin/*
hs_err_pid* hs_err_pid*
Thumbs.db Thumbs.db
.DS_Store .DS_Store
/.idea/workspace.xml
~$* ~$*

View File

@@ -3,7 +3,6 @@
<component name="ProjectCodeStyleSettingsManager"> <component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS"> <option name="PER_PROJECT_SETTINGS">
<value> <value>
<option name="RIGHT_MARGIN" value="100" />
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" /> <option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
</JetCodeStyleSettings> </JetCodeStyleSettings>

Binary file not shown.

Binary file not shown.

View File

@@ -39,7 +39,7 @@ class GameFontImpl(noShadow: Boolean = false) : GameFontBase(noShadow = noShadow
GameFontBase.greekSheet = SpriteSheet( GameFontBase.greekSheet = SpriteSheet(
"./assets/graphics/fonts/greek_variable.tga", 15, 19, 1) "./assets/graphics/fonts/greek_variable.tga", 15, 19, 1)
GameFontBase.thaiSheet = SpriteSheet( GameFontBase.thaiSheet = SpriteSheet(
"./assets/graphics/fonts/thai_wide.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H) "./assets/graphics/fonts/thai_variable.tga",15, 19, 1)
GameFontBase.keycapSheet = SpriteSheet( GameFontBase.keycapSheet = SpriteSheet(
"./assets/graphics/fonts/puae000-e0ff.tga", GameFontBase.SIZE_KEYCAP, GameFontBase.SIZE_KEYCAP) "./assets/graphics/fonts/puae000-e0ff.tga", GameFontBase.SIZE_KEYCAP, GameFontBase.SIZE_KEYCAP)

View File

@@ -14,6 +14,10 @@ object DefaultConfig {
fun fetch(): JsonObject { fun fetch(): JsonObject {
val jsonObject = JsonObject() val jsonObject = JsonObject()
jsonObject.addProperty("displayfps", 60)
jsonObject.addProperty("usevsync", true)
jsonObject.addProperty("smoothlighting", true) jsonObject.addProperty("smoothlighting", true)
jsonObject.addProperty("imtooyoungtodie", false) // perma-death jsonObject.addProperty("imtooyoungtodie", false) // perma-death
jsonObject.addProperty("language", Terrarum.sysLang) jsonObject.addProperty("language", Terrarum.sysLang)

View File

@@ -86,7 +86,8 @@ nopqrstuvwxyz
"Pijamalı hasta yağız şoföre çabucak güvendi", "Pijamalı hasta yağız şoföre çabucak güvendi",
"Also supports: Unicode „quotation marks“—dashes…「括弧」‼", "Also supports: Unicode „quotation marks“—dashes…「括弧」‼",
"ASCII Latin-1 Latin_Ext-A Latin_Ext-B Greek Cyrillic CJK-Ideo Kana Hangul_Syllables", "ASCII Latin-1 Latin_Ext-A Latin_Ext-B Greek Cyrillic CJK-Ideo Kana Hangul_Syllables",
"" "",
"…not seeing your language/writing system? Let me know on the Issue Tracker!"
) )
val SP = "${0x3000.toChar()}${0x3000.toChar()}" val SP = "${0x3000.toChar()}${0x3000.toChar()}"

View File

@@ -435,8 +435,8 @@ class StateInGame : BasicGameState() {
worldG.font = Terrarum.fontSmallNumbers worldG.font = Terrarum.fontSmallNumbers
worldG.drawString( worldG.drawString(
actor.referenceID.toString(), actor.referenceID.toString(),
actor.hitbox.posX.toFloat(), actor.hitbox.startX.toFloat(),
actor.hitbox.pointedY.toFloat() + 4 actor.hitbox.canonicalY.toFloat() + 4
) )
} }
} }
@@ -449,8 +449,8 @@ class StateInGame : BasicGameState() {
worldG.font = Terrarum.fontSmallNumbers worldG.font = Terrarum.fontSmallNumbers
worldG.lineWidth = 1f worldG.lineWidth = 1f
worldG.drawRect( worldG.drawRect(
actor.hitbox.posX.toFloat(), actor.hitbox.startX.toFloat(),
actor.hitbox.posY.toFloat(), actor.hitbox.startY.toFloat(),
actor.hitbox.width.toFloat(), actor.hitbox.width.toFloat(),
actor.hitbox.height.toFloat() actor.hitbox.height.toFloat()
) )
@@ -459,13 +459,13 @@ class StateInGame : BasicGameState() {
worldG.color = GameFontBase.codeToCol["g"] worldG.color = GameFontBase.codeToCol["g"]
worldG.drawString( worldG.drawString(
"${0x7F.toChar()}X ${actor.externalForce.x}", "${0x7F.toChar()}X ${actor.externalForce.x}",
actor.hitbox.posX.toFloat(), actor.hitbox.startX.toFloat(),
actor.hitbox.pointedY.toFloat() + 4 + 8 actor.hitbox.canonicalY.toFloat() + 4 + 8
) )
worldG.drawString( worldG.drawString(
"${0x7F.toChar()}Y ${actor.externalForce.y}", "${0x7F.toChar()}Y ${actor.externalForce.y}",
actor.hitbox.posX.toFloat(), actor.hitbox.startX.toFloat(),
actor.hitbox.pointedY.toFloat() + 4 + 8 * 2 actor.hitbox.canonicalY.toFloat() + 4 + 8 * 2
) )
} }
} }
@@ -501,7 +501,6 @@ class StateInGame : BasicGameState() {
backG.flush() backG.flush()
gwin.drawImage(backDrawFrameBuffer, 0f, 0f) gwin.drawImage(backDrawFrameBuffer, 0f, 0f)
// centre marker // centre marker
/*gwin.color = Color(0x00FFFF) /*gwin.color = Color(0x00FFFF)
gwin.lineWidth = 1f gwin.lineWidth = 1f
@@ -639,12 +638,12 @@ class StateInGame : BasicGameState() {
) )
private fun distToCameraSqr(a: ActorWithBody) = private fun distToCameraSqr(a: ActorWithBody) =
min( min(
(a.hitbox.posX - WorldCamera.x).sqr() + (a.hitbox.startX - WorldCamera.x).sqr() +
(a.hitbox.posY - WorldCamera.y).sqr(), (a.hitbox.startY - WorldCamera.y).sqr(),
(a.hitbox.posX - WorldCamera.x + world.width * TILE_SIZE).sqr() + (a.hitbox.startX - WorldCamera.x + world.width * TILE_SIZE).sqr() +
(a.hitbox.posY - WorldCamera.y).sqr(), (a.hitbox.startY - WorldCamera.y).sqr(),
(a.hitbox.posX - WorldCamera.x - world.width * TILE_SIZE).sqr() + (a.hitbox.startX - WorldCamera.x - world.width * TILE_SIZE).sqr() +
(a.hitbox.posY - WorldCamera.y).sqr() (a.hitbox.startY - WorldCamera.y).sqr()
) )
/** whether the actor is within screen */ /** whether the actor is within screen */

View File

@@ -34,13 +34,17 @@ typealias Millisec = Int
*/ */
object Terrarum : StateBasedGame(GAME_NAME) { object Terrarum : StateBasedGame(GAME_NAME) {
////////////////////////////// //////////////////////////////
// GLOBAL IMMUTABLE CONFIGS // // GLOBAL IMMUTABLE CONFIGS //
////////////////////////////// //////////////////////////////
var WIDTH = 1072 var WIDTH = 1072
var HEIGHT = 742 // IMAX ratio var HEIGHT = 742 // IMAX ratio
var VSYNC = true val RENDER_FPS = getConfigInt("displayfps")
val USE_VSYNC = getConfigBoolean("usevsync")
var VSYNC = USE_VSYNC
val VSYNC_TRIGGER_THRESHOLD = 56 val VSYNC_TRIGGER_THRESHOLD = 56
val HALFW: Int val HALFW: Int
@@ -516,8 +520,10 @@ fun main(args: Array<String>) {
Terrarum.appgc = AppGameContainer(Terrarum) Terrarum.appgc = AppGameContainer(Terrarum)
Terrarum.appgc.setDisplayMode(Terrarum.WIDTH, Terrarum.HEIGHT, false) Terrarum.appgc.setDisplayMode(Terrarum.WIDTH, Terrarum.HEIGHT, false)
Terrarum.appgc.setTargetFrameRate(Terrarum.TARGET_INTERNAL_FPS) if (Terrarum.RENDER_FPS > 0) {
Terrarum.appgc.setVSync(Terrarum.VSYNC) Terrarum.appgc.setTargetFrameRate(Terrarum.RENDER_FPS)
}
//Terrarum.appgc.setVSync(Terrarum.VSYNC)
Terrarum.appgc.setMaximumLogicUpdateInterval(1000 / Terrarum.TARGET_INTERNAL_FPS) // 10 ms Terrarum.appgc.setMaximumLogicUpdateInterval(1000 / Terrarum.TARGET_INTERNAL_FPS) // 10 ms
Terrarum.appgc.setMinimumLogicUpdateInterval(1000 / Terrarum.TARGET_INTERNAL_FPS - 1) // 9 ms Terrarum.appgc.setMinimumLogicUpdateInterval(1000 / Terrarum.TARGET_INTERNAL_FPS - 1) // 9 ms

View File

@@ -162,8 +162,8 @@ class ActorValueTracker constructor() : JFrame() {
if (actor != null) { if (actor != null) {
sb.append("toString: ${actor!!}\n") sb.append("toString: ${actor!!}\n")
sb.append("X: ${actor!!.hitbox.pointedX} (${(actor!!.hitbox.pointedX / FeaturesDrawer.TILE_SIZE).toInt()})\n") sb.append("X: ${actor!!.hitbox.canonicalX} (${(actor!!.hitbox.canonicalX / FeaturesDrawer.TILE_SIZE).toInt()})\n")
sb.append("Y: ${actor!!.hitbox.pointedY} (${(actor!!.hitbox.pointedY / FeaturesDrawer.TILE_SIZE).toInt()})") sb.append("Y: ${actor!!.hitbox.canonicalY} (${(actor!!.hitbox.canonicalY / FeaturesDrawer.TILE_SIZE).toInt()})")
avPosArea.text = "$sb" avPosArea.text = "$sb"
sb.setLength(0) // clear stringbuffer sb.setLength(0) // clear stringbuffer

View File

@@ -71,7 +71,8 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* (Use ArrayList for normal circumstances) * (Use ArrayList for normal circumstances)
*/ */
override val lightBoxList: List<Hitbox> override val lightBoxList: List<Hitbox>
get() = arrayOf(Hitbox(0.0, 0.0, hitbox.width, hitbox.height)).toList() // use getter; dimension of the player may change by time. get() = arrayOf(Hitbox(2.0, 2.0, hitbox.width - 3, hitbox.height - 3)).toList() // things are asymmetric!!
// use getter; dimension of the player may change by time.
@Transient val BASE_DENSITY = 980.0 @Transient val BASE_DENSITY = 980.0
@@ -156,7 +157,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (vehicleRiding is Player) if (vehicleRiding is Player)
throw Error("Attempted to 'ride' player object. ($vehicleRiding)") throw Error("Attempted to 'ride' player object. ($vehicleRiding)")
if (vehicleRiding != null && (vehicleRiding == this)) if (vehicleRiding != null && vehicleRiding == this)
throw Error("Attempted to 'ride' itself. ($vehicleRiding)") throw Error("Attempted to 'ride' itself. ($vehicleRiding)")
@@ -167,7 +168,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
updateSprite(delta) updateSprite(delta)
if (noClip) { if (noClip) {
grounded = true //grounded = true
} }
// reset control box of AI // reset control box of AI
@@ -370,9 +371,9 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
avAcceleration * (if (left) -1f else 1f) * absAxisVal avAcceleration * (if (left) -1f else 1f) * absAxisVal
if (absAxisVal != AXIS_KEYBOARD) if (absAxisVal != AXIS_KEYBOARD)
walkX = walkX.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) }
else else
walkX = walkX.plus(readonly_totalX).bipolarClamp(avSpeedCap) controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap) }
if (absAxisVal == AXIS_KEYBOARD) { if (absAxisVal == AXIS_KEYBOARD) {
walkCounterX += 1 walkCounterX += 1
@@ -399,9 +400,9 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
avAcceleration * (if (up) -1f else 1f) * absAxisVal avAcceleration * (if (up) -1f else 1f) * absAxisVal
if (absAxisVal != AXIS_KEYBOARD) if (absAxisVal != AXIS_KEYBOARD)
walkY = walkY.plus(readonly_totalY).bipolarClamp(avSpeedCap * absAxisVal) controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) }
else else
walkY = walkY.plus(readonly_totalY).bipolarClamp(avSpeedCap) controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalX).bipolarClamp(avSpeedCap) }
if (absAxisVal == AXIS_KEYBOARD) { if (absAxisVal == AXIS_KEYBOARD) {
walkCounterY += 1 walkCounterY += 1
@@ -459,7 +460,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value
walkY -= jumpAcc // feed negative value to the vector controllerMoveDelta?.y?.let { controllerMoveDelta!!.y -= jumpAcc } // feed negative value to the vector
// do not think of resetting this to zero when counter hit the ceiling; that's HOW NOT // do not think of resetting this to zero when counter hit the ceiling; that's HOW NOT
// newtonian physics work, stupid myself :( // newtonian physics work, stupid myself :(

View File

@@ -44,8 +44,8 @@ open class ParticleBase(renderOrder: Actor.RenderOrder, maxLifeTime: Int? = null
if (velocity.isZero || lifetimeCounter >= lifetimeMax || if (velocity.isZero || lifetimeCounter >= lifetimeMax ||
// simple stuck check // simple stuck check
BlockCodex[Terrarum.ingame!!.world.getTileFromTerrain( BlockCodex[Terrarum.ingame!!.world.getTileFromTerrain(
hitbox.pointedX.div(TILE_SIZE).floorInt(), hitbox.canonicalX.div(TILE_SIZE).floorInt(),
hitbox.pointedY.div(TILE_SIZE).floorInt() hitbox.canonicalY.div(TILE_SIZE).floorInt()
) ?: Block.STONE].isSolid) { ) ?: Block.STONE].isSolid) {
flagDespawn = true flagDespawn = true
} }

View File

@@ -24,20 +24,20 @@ class PhysTestBall : ActorWithPhysics(Actor.RenderOrder.MIDDLE, immobileBody = t
override fun drawBody(g: Graphics) { override fun drawBody(g: Graphics) {
g.color = color g.color = color
g.fillOval( g.fillOval(
hitbox.posX.toFloat(), hitbox.startX.toFloat() - 1f,
hitbox.posY.toFloat(), hitbox.startY.toFloat() - 1f,
hitbox.width.toFloat(), hitbox.width.toFloat(),
hitbox.height.toFloat()) hitbox.height.toFloat())
g.fillOval( g.fillOval(
hitbox.posX.toFloat() + Terrarum.ingame!!.world.width * TILE_SIZE, hitbox.startX.toFloat() + Terrarum.ingame!!.world.width * TILE_SIZE - 1f,
hitbox.posY.toFloat(), hitbox.startY.toFloat() - 1f,
hitbox.width.toFloat(), hitbox.width.toFloat(),
hitbox.height.toFloat()) hitbox.height.toFloat())
g.fillOval( g.fillOval(
hitbox.posX.toFloat() - Terrarum.ingame!!.world.width * TILE_SIZE, hitbox.startX.toFloat() - Terrarum.ingame!!.world.width * TILE_SIZE - 1f,
hitbox.posY.toFloat(), hitbox.startY.toFloat() - 1f,
hitbox.width.toFloat(), hitbox.width.toFloat(),
hitbox.height.toFloat()) hitbox.height.toFloat())

View File

@@ -49,8 +49,8 @@ object PlayerBuilderSigrid {
p.actorValue[AVKey.INTELLIGENT] = true p.actorValue[AVKey.INTELLIGENT] = true
p.actorValue[AVKey.LUMINOSITY] = Color(0x434aff).to10bit() //p.actorValue[AVKey.LUMINOSITY] = Color(0x434aff).to10bit()
//p.actorValue[AVKey.LUMINOSITY] = 214127943 // bright purple p.actorValue[AVKey.LUMINOSITY] = 214127943 // bright purple
p.actorValue[AVKey.BASEDEFENCE] = 141 p.actorValue[AVKey.BASEDEFENCE] = 141

View File

@@ -58,8 +58,8 @@ internal class AILuaAPI(g: Globals, actor: ActorWithPhysics) {
val moveDelta = actor.externalForce + actor.controllerMoveDelta val moveDelta = actor.externalForce + actor.controllerMoveDelta
t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua() t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua()
t["posX"] = actor.hitbox.centeredX.toLua() t["startX"] = actor.hitbox.centeredX.toLua()
t["posY"] = actor.hitbox.centeredY.toLua() t["startY"] = actor.hitbox.centeredY.toLua()
t["veloX"] = moveDelta.x.toLua() t["veloX"] = moveDelta.x.toLua()
t["veloY"] = moveDelta.y.toLua() t["veloY"] = moveDelta.y.toLua()

View File

@@ -2,13 +2,11 @@ package net.torvald.terrarum.ui
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.imagefont.GameFontBase import net.torvald.imagefont.GameFontBase
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.worlddrawer.LightmapRenderer import net.torvald.terrarum.worlddrawer.LightmapRenderer
import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.worlddrawer.FeaturesDrawer
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blendNormal import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.blendScreen import net.torvald.terrarum.blendScreen
import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.terrarum.worlddrawer.WorldCamera
import org.newdawn.slick.Color import org.newdawn.slick.Color
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
@@ -47,11 +45,11 @@ class BasicDebugInfoWindow : UICanvas {
val player = Terrarum.ingame!!.player!! val player = Terrarum.ingame!!.player!!
val hitbox = player.hitbox val hitbox = player.hitbox
xdelta = hitbox.pointedX - prevPlayerX xdelta = hitbox.canonicalX - prevPlayerX
ydelta = hitbox.pointedY - prevPlayerY ydelta = hitbox.canonicalY - prevPlayerY
prevPlayerX = hitbox.pointedX prevPlayerX = hitbox.canonicalX
prevPlayerY = hitbox.pointedY prevPlayerY = hitbox.canonicalY
} }
override fun render(gc: GameContainer, g: Graphics) { override fun render(gc: GameContainer, g: Graphics) {
@@ -73,34 +71,46 @@ class BasicDebugInfoWindow : UICanvas {
* First column * First column
*/ */
printLine(g, 1, "pointedX " printLineColumn(g, 1, 1, "startX "
+ ccG + ccG
+ "${hitbox?.pointedX}" + "${hitbox?.startX}"
+ " (" + " ("
+ "${(hitbox?.pointedX?.div(FeaturesDrawer.TILE_SIZE))?.toInt()}" + "${(hitbox?.startX?.div(FeaturesDrawer.TILE_SIZE))?.toInt()}"
+ ")") + ")")
printLine(g, 2, "endY " printLineColumn(g, 2, 1, "endX "
+ ccG + ccG
+ hitbox?.endPointY.toString() + "${hitbox?.endX}"
+ " (" + " ("
+ (hitbox?.endPointY?.div(FeaturesDrawer.TILE_SIZE))?.toInt().toString() + "${(hitbox?.endX?.div(FeaturesDrawer.TILE_SIZE))?.toInt()}"
+ ")") + ")")
printLineColumn(g, 1, 2, "startY "
+ ccG
+ "${hitbox?.startY}"
+ " ("
+ "${(hitbox?.startY?.div(FeaturesDrawer.TILE_SIZE))?.toInt()}"
+ ")")
printLineColumn(g, 2, 2, "endY "
+ ccG
+ "${hitbox?.endY}"
+ " ("
+ "${(hitbox?.endY?.div(FeaturesDrawer.TILE_SIZE))?.toInt()}"
+ ")")
printLine(g, 3, "veloX reported $ccG${player?.externalForce?.x} ${player?.controllerMoveDelta?.x}") printLine(g, 3, "veloX reported $ccG${player?.externalForce?.x}")
printLine(g, 4, "veloY reported $ccG${player?.externalForce?.y} ${player?.controllerMoveDelta?.y}") printLine(g, 4, "veloY reported $ccG${player?.externalForce?.y}")
printLine(g, 5, "p_WalkX $ccG${player?.controllerMoveDelta?.x}")
printLine(g, 6, "p_WalkY $ccG${player?.controllerMoveDelta?.y}")
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}") printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}") printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
printLine(g, 5, "grounded $ccG${player?.grounded}")
printLine(g, 6, "noClip $ccG${player?.noClip}")
if (player != null) { if (player != null) {
printLine(g, 7, printLineColumn(g, 1, 7,
"walled ${if (player.walledLeft) "$ccR" else "$ccG"}L" + "walled " +
"${if (player.walledTop) "$ccR" else "$ccG"}${0x1E.toChar()}" + "${if (player.walledLeft) "$ccR" else "$ccG"}L" +
"${if (player.walledBottom) "$ccR" else "$ccG"}${0x1F.toChar()}" + "${if (player.walledBottom) "$ccR" else "$ccG"}${0x1F.toChar()}" +
"${if (player.walledTop) "$ccR" else "$ccG"}${0x1E.toChar()}" +
"${if (player.walledRight) "$ccR" else "$ccG"}R" "${if (player.walledRight) "$ccR" else "$ccG"}R"
) )
} }
@@ -132,14 +142,15 @@ class BasicDebugInfoWindow : UICanvas {
* Second column * Second column
*/ */
printLineColumn(g, 2, 1, "VSync $ccG" + Terrarum.appgc.isVSyncRequested) //printLineColumn(g, 2, 1, "VSync $ccG" + Terrarum.appgc.isVSyncRequested)
printLineColumn(g, 2, 2, "Env colour temp $ccG" + FeaturesDrawer.colTemp) //printLineColumn(g, 2, 2, "Env colour temp $ccG" + FeaturesDrawer.colTemp)
printLineColumn(g, 2, 5, "Time $ccG${Terrarum.ingame!!.world.time.todaySeconds.toString().padStart(5, '0')}" + printLineColumn(g, 2, 5, "Time $ccG${Terrarum.ingame!!.world.time.todaySeconds.toString().padStart(5, '0')}" +
" (${Terrarum.ingame!!.world.time.getFormattedTime()})") " (${Terrarum.ingame!!.world.time.getFormattedTime()})")
printLineColumn(g, 2, 6, "Mass $ccG${player?.mass}") printLineColumn(g, 2, 6, "Mass $ccG${player?.mass}")
printLineColumn(g, 2, 7, "p_WalkX $ccG${player?.walkX}") printLineColumn(g, 2, 7, "grounded $ccG${player?.grounded}")
printLineColumn(g, 2, 8, "p_WalkY $ccG${player?.walkY}") printLineColumn(g, 2, 8, "noClip $ccG${player?.noClip}")
drawHistogram(g, LightmapRenderer.histogram, drawHistogram(g, LightmapRenderer.histogram,

View File

@@ -38,13 +38,13 @@ import kotlin.collections.HashMap
*/ */
class TerrarumComputer(peripheralSlots: Int) { class TerrarumComputer(peripheralSlots: Int) {
var maxPeripherals: Int = peripheralSlots
private set
val DEBUG_UNLIMITED_MEM = false val DEBUG_UNLIMITED_MEM = false
val DEBUG = true val DEBUG = true
val maxPeripherals: Int = if (DEBUG) 32 else peripheralSlots
lateinit var luaJ_globals: Globals lateinit var luaJ_globals: Globals
private set private set
@@ -80,7 +80,7 @@ class TerrarumComputer(peripheralSlots: Int) {
lateinit var term: Teletype lateinit var term: Teletype
private set private set
val peripheralTable = ArrayList<Peripheral>() val peripheralTable = Array<Peripheral?>(peripheralSlots, { null }) // index == slot number
var stdinInput: Int = -1 var stdinInput: Int = -1
private set private set
@@ -139,26 +139,55 @@ class TerrarumComputer(peripheralSlots: Int) {
fun getPeripheral(tableName: String): Peripheral? { fun getPeripheral(tableName: String): Peripheral? {
peripheralTable.forEach { peripheralTable.forEach {
if (it.tableName == tableName) if (it?.tableName == tableName)
return it return it
} }
return null return null
} }
fun attachPeripheral(peri: Peripheral) { fun getPeripheralSlot(tableName: String): Int? {
if (peripheralTable.size < maxPeripherals) { peripheralTable.forEachIndexed { index, peri ->
peripheralTable.add(peri) if (peri?.tableName == tableName)
return index
}
return null
}
/** @return installed slot */
fun attachPeripheral(peri: Peripheral): Int {
(0..maxPeripherals - 1).forEach {
try {
attachPeripheralTo(peri, it)
return it
}
catch (tryNext: RuntimeException) { }
}
throw RuntimeException("No vacant peripheral slot")
}
fun attachPeripheralTo(peri: Peripheral, slot: Int) {
if (peripheralTable[slot] == null) {
peripheralTable[slot] = peri
peri.loadLib(luaJ_globals) peri.loadLib(luaJ_globals)
println("[TerrarumComputer] loading peripheral $peri") println("[TerrarumComputer] loading peripheral $peri")
} }
else { else {
throw Error("No vacant peripheral slot") throw RuntimeException("Peripheral slot is already taken by: ${peripheralTable[slot]?.tableName}")
} }
} }
fun detachPeripheral(peri: Peripheral) { fun detachPeripheral(peri: Peripheral) {
if (peripheralTable.contains(peri)) { // search for the peripheral
peripheralTable.remove(peri) var found = -1
for (i in 0..maxPeripherals - 1) {
if (peripheralTable[i] == peri) {
found = i
break
}
}
if (found >= 0) {
peripheralTable[found] = null
println("[TerrarumComputer] unloading peripheral $peri") println("[TerrarumComputer] unloading peripheral $peri")
} }
else { else {
@@ -213,7 +242,6 @@ class TerrarumComputer(peripheralSlots: Int) {
// load every peripheral if we're in DEBUG // load every peripheral if we're in DEBUG
if (DEBUG) { if (DEBUG) {
maxPeripherals = 32
attachPeripheral(PeripheralInternet(this)) attachPeripheral(PeripheralInternet(this))
attachPeripheral(PeripheralPSG(this)) attachPeripheral(PeripheralPSG(this))
// ... // ...

View File

@@ -126,9 +126,9 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
return "$base$local".replace("//", "/") return "$base$local".replace("//", "/")
} }
private fun tryBool(action: (Unit) -> Unit): LuaValue { private fun tryBool(action: () -> Unit): LuaValue {
try { try {
action(Unit) action()
return LuaValue.valueOf(true) return LuaValue.valueOf(true)
} }
catch (gottaCatchemAll: Exception) { catch (gottaCatchemAll: Exception) {

View File

@@ -13,26 +13,32 @@ import net.torvald.terrarum.worlddrawer.WorldCamera.y
import net.torvald.terrarum.worlddrawer.WorldCamera.height import net.torvald.terrarum.worlddrawer.WorldCamera.height
import net.torvald.terrarum.worlddrawer.WorldCamera.width import net.torvald.terrarum.worlddrawer.WorldCamera.width
import org.lwjgl.BufferUtils import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.*
import org.lwjgl.opengl.GL15
import org.newdawn.slick.* import org.newdawn.slick.*
import java.nio.ByteBuffer
import java.nio.FloatBuffer import java.nio.FloatBuffer
/** /**
* Created by minjaesong on 16-01-19. * Created by minjaesong on 16-01-19.
*/ */
object BlocksDrawer { object BlocksDrawer_NEW {
private val world: GameWorld = Terrarum.ingame!!.world private val world: GameWorld = Terrarum.ingame!!.world
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat() private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat()
// TODO modular // TODO modular
val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/terrain.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/test.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB
val terrainHorizontalTiles = tilesTerrain.horizontalCount val terrainHorizontalTiles = tilesTerrain.horizontalCount
val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB
val wireHorizontalTiles = tilesWire.horizontalCount val wireHorizontalTiles = tilesWire.horizontalCount
val tilesTerrainTexBuffer: ByteBuffer = BufferUtils.createByteBuffer(tilesTerrain.texture.textureData.size)
init {
tilesTerrainTexBuffer.put(tilesTerrain.texture.textureData)
tilesTerrainTexBuffer.rewind()
}
val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
@@ -57,8 +63,8 @@ object BlocksDrawer {
val VBO_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH).div(TILE_SIZE).ceil() + 2 val VBO_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH).div(TILE_SIZE).ceil() + 3
val VBO_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT).div(TILE_SIZE).ceil() + 2 val VBO_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT).div(TILE_SIZE).ceil() + 3
val cameraTileX: Int val cameraTileX: Int
get() = WorldCamera.x.div(TILE_SIZE) get() = WorldCamera.x.div(TILE_SIZE)
val cameraTileY: Int val cameraTileY: Int
@@ -108,18 +114,22 @@ object BlocksDrawer {
// generate VBO // generate VBO
worldVBOTexture = BufferUtils.createFloatBuffer(12 * VBO_WIDTH * VBO_HEIGHT) worldVBOTexture = BufferUtils.createFloatBuffer(8 * VBO_WIDTH * VBO_HEIGHT)
worldVBOVertex = BufferUtils.createFloatBuffer(12 * VBO_WIDTH * VBO_HEIGHT) worldVBOVertex = BufferUtils.createFloatBuffer(8 * VBO_WIDTH * VBO_HEIGHT)
for (y in 0..VBO_HEIGHT - 1) { for (y in 0..VBO_HEIGHT - 1) {
for (x in 0..VBO_WIDTH - 1) { for (x in 0..VBO_WIDTH - 1) {
val x = x * TILE_SIZEF val x = x * TILE_SIZEF
val y = y * TILE_SIZEF val y = y * TILE_SIZEF
worldVBOVertex.put(floatArrayOf( worldVBOVertex.put(floatArrayOf( // fixed points (triangles); won't need to be re-assigned
//x , y ,
//x + TILE_SIZEF, y ,
//x , y + TILE_SIZEF,
//x + TILE_SIZEF, y ,
//x + TILE_SIZEF, y + TILE_SIZEF,
//x , y + TILE_SIZEF
x, y, x, y,
x + TILE_SIZEF, y, x + TILE_SIZEF, y,
x, y + TILE_SIZEF,
x + TILE_SIZEF, y,
x + TILE_SIZEF, y + TILE_SIZEF, x + TILE_SIZEF, y + TILE_SIZEF,
x, y + TILE_SIZEF x, y + TILE_SIZEF
)) ))
@@ -129,7 +139,7 @@ object BlocksDrawer {
worldVBOVertexID = GL15.glGenBuffers() worldVBOVertexID = GL15.glGenBuffers()
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID) //Bind buffer (also specifies type of buffer) GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID) //Bind buffer (also specifies type of buffer)
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, worldVBOVertex, GL15.GL_DYNAMIC_DRAW) //Send up the data and specify usage hint. GL15.glBufferData(GL15.GL_ARRAY_BUFFER, worldVBOVertex, GL15.GL_STATIC_DRAW) //Send up the data and specify usage hint.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0) GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
worldVBOTextureID = GL15.glGenBuffers() worldVBOTextureID = GL15.glGenBuffers()
@@ -494,7 +504,7 @@ object BlocksDrawer {
} }
// draw a breakage // draw a breakage
if (mode == TERRAIN || mode == WALL) { /*if (mode == TERRAIN || mode == WALL) {
val breakage = if (mode == TERRAIN) world.getTerrainDamage(x, y) else world.getWallDamage(x, y) val breakage = if (mode == TERRAIN) world.getTerrainDamage(x, y) else world.getWallDamage(x, y)
val maxHealth = BlockCodex[world.getTileFromTerrain(x, y)].strength val maxHealth = BlockCodex[world.getTileFromTerrain(x, y)].strength
val stage = (breakage / maxHealth).times(breakAnimSteps).roundInt() val stage = (breakage / maxHealth).times(breakAnimSteps).roundInt()
@@ -503,7 +513,7 @@ object BlocksDrawer {
// alpha blending works, but no GL blend func... // alpha blending works, but no GL blend func...
drawTile(mode, x, y, 5 + stage, 0) drawTile(mode, x, y, 5 + stage, 0)
} }
} }*/
} // end if (is illuminated) } // end if (is illuminated)
@@ -534,44 +544,55 @@ object BlocksDrawer {
} }
// draw - fill up the VBO buffer // draw - fill up the VBO buffer
worldVBOTexture.rewind()
for (y in 0..VBO_HEIGHT - 1) { for (y in 0..VBO_HEIGHT - 1) {
for (x in 0..VBO_WIDTH - 1) { for (x in 0..VBO_WIDTH - 1) {
val vx = x * TILE_SIZEF
val vy = y * TILE_SIZEF
val tileID = regionBuffer[y][x] val tileID = regionBuffer[y][x]
val tileX = (tileID % terrainHorizontalTiles) * TILE_SIZEF val tileX = (tileID % terrainHorizontalTiles) * TILE_SIZEF
val tileY = (tileID / terrainHorizontalTiles) * TILE_SIZEF val tileY = (tileID / terrainHorizontalTiles) * TILE_SIZEF
worldVBOTexture.put(floatArrayOf( // feed GL_TRIANGLE data
tileX, tileY, worldVBOTexture.put(floatArrayOf( // feed GL_TRIANGLE data (note: bottom-left is zero)
tileX + TILE_SIZEF, tileY, Math.random().toFloat(), Math.random().toFloat(),
tileX, tileY + TILE_SIZEF, Math.random().toFloat(), Math.random().toFloat(),
tileX + TILE_SIZEF, tileY, Math.random().toFloat(), Math.random().toFloat(),
tileX + TILE_SIZEF, tileY + TILE_SIZEF, Math.random().toFloat(), Math.random().toFloat()
tileX, tileY + TILE_SIZEF //Math.random().toFloat() * 4096f, Math.random().toFloat() * 4096f,
)) //Math.random().toFloat() * 4096f, Math.random().toFloat() * 4096f
)) // FIXME texCoords are wrong?!
} }
} }
worldVBOTexture.rewind()
// draw - render the VBO // draw - render the VBO
GL11.glBindTexture(GL11.GL_TEXTURE_2D, when (mode) { val texToBind = when (mode) {
TERRAIN, WALL -> tilesTerrain TERRAIN, WALL -> tilesTerrain
WIRE -> tilesWire WIRE -> tilesWire
else -> throw Error("mode not TERRAIN/WALL/WIRE") else -> throw Error("mode not TERRAIN/WALL/WIRE")
}.texture.textureID) }.texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texToBind.textureID)
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT)
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT)
//inGLMatrixStack { // disabled for debugging: won't hotswap //inGLMatrixStack { // disabled for debugging: won't hotswap
GL11.glPushMatrix() GL11.glPushMatrix()
GL11.glTranslatef(WorldCamera.x.clampTileSize().toFloat() - TILE_SIZEF, WorldCamera.y.clampTileSize().toFloat(), 0f) GL11.glTranslatef(WorldCamera.x.clampTileSize().toFloat() - TILE_SIZEF, WorldCamera.y.clampTileSize().toFloat(), 0f)
//GL11.glTranslatef(0f, 0f, 0f)
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID)
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0)
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOTextureID) GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOTextureID)
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0) GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0)
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6 * VBO_WIDTH * VBO_HEIGHT) // for some reason, using 2 VBOs are faster -- presumably because you must fill EVERY ELEMENT when you're using java.nio.Buffer
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID)
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0)
GL11.glDrawArrays(GL11.GL_QUADS, 0, 4 * VBO_WIDTH * VBO_HEIGHT)
GL11.glPopMatrix() GL11.glPopMatrix()
//} //}

View File

@@ -0,0 +1,657 @@
package net.torvald.terrarum.worlddrawer
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import com.jme3.math.FastMath
import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.itemproperties.ItemCodex.ITEM_TILES
import net.torvald.terrarum.worlddrawer.WorldCamera.x
import net.torvald.terrarum.worlddrawer.WorldCamera.y
import net.torvald.terrarum.worlddrawer.WorldCamera.height
import net.torvald.terrarum.worlddrawer.WorldCamera.width
import org.lwjgl.opengl.GL11
import org.newdawn.slick.*
import org.newdawn.slick.imageout.ImageOut
/**
* Created by minjaesong on 16-01-19.
*/
object BlocksDrawer {
private val world: GameWorld = Terrarum.ingame!!.world
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat()
// TODO modular
val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/terrain.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB
val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB
val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
val wallOverlayColour = Color(2f/3f, 2f/3f, 2f/3f, 1f)
val breakAnimSteps = 10
val WALL = GameWorld.WALL
val TERRAIN = GameWorld.TERRAIN
val WIRE = GameWorld.WIRE
private val NEARBY_TILE_KEY_UP = 0
private val NEARBY_TILE_KEY_RIGHT = 1
private val NEARBY_TILE_KEY_DOWN = 2
private val NEARBY_TILE_KEY_LEFT = 3
private val NEARBY_TILE_CODE_UP = 1
private val NEARBY_TILE_CODE_RIGHT = 2
private val NEARBY_TILE_CODE_DOWN = 4
private val NEARBY_TILE_CODE_LEFT = 8
init {
val tg = tileItemWall.graphics
// initialise item_wall images
(ITEM_TILES).forEach {
tg.drawImage(
tilesTerrain.getSubImage(
(it % 16) * 16,
(it / 16)
),
(it % 16) * TILE_SIZE.toFloat(),
(it / 16) * TILE_SIZE.toFloat(),
wallOverlayColour
)
}
//tg.flush()
//ImageOut.write(tileItemWall, "./tileitemwalltest.png")
tg.destroy()
}
/**
* Connectivity group 01 : artificial tiles
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
* These are the tiles that only connects to itself, will not connect to colour variants
*/
private val TILES_CONNECT_SELF = hashSetOf(
Block.GLASS_CRUDE,
Block.GLASS_CLEAN,
Block.ILLUMINATOR_BLACK,
Block.ILLUMINATOR_BLUE,
Block.ILLUMINATOR_BROWN,
Block.ILLUMINATOR_CYAN,
Block.ILLUMINATOR_FUCHSIA,
Block.ILLUMINATOR_GREEN,
Block.ILLUMINATOR_GREEN_DARK,
Block.ILLUMINATOR_GREY_DARK,
Block.ILLUMINATOR_GREY_LIGHT,
Block.ILLUMINATOR_GREY_MED,
Block.ILLUMINATOR_ORANGE,
Block.ILLUMINATOR_PURPLE,
Block.ILLUMINATOR_RED,
Block.ILLUMINATOR_TAN,
Block.ILLUMINATOR_WHITE,
Block.ILLUMINATOR_YELLOW,
Block.ILLUMINATOR_BLACK_OFF,
Block.ILLUMINATOR_BLUE_OFF,
Block.ILLUMINATOR_BROWN_OFF,
Block.ILLUMINATOR_CYAN_OFF,
Block.ILLUMINATOR_FUCHSIA_OFF,
Block.ILLUMINATOR_GREEN_OFF,
Block.ILLUMINATOR_GREEN_DARK_OFF,
Block.ILLUMINATOR_GREY_DARK_OFF,
Block.ILLUMINATOR_GREY_LIGHT_OFF,
Block.ILLUMINATOR_GREY_MED_OFF,
Block.ILLUMINATOR_ORANGE_OFF,
Block.ILLUMINATOR_PURPLE_OFF,
Block.ILLUMINATOR_RED_OFF,
Block.ILLUMINATOR_TAN_OFF,
Block.ILLUMINATOR_WHITE_OFF,
Block.ILLUMINATOR_YELLOW,
Block.DAYLIGHT_CAPACITOR
)
/**
* To interact with external modules
*/
@JvmStatic fun addConnectSelf(blockID: Int): Boolean {
return TILES_CONNECT_SELF.add(blockID)
}
/**
* Connectivity group 02 : natural tiles
* It holds different shading rule to discriminate with group 01, index 0 is middle tile.
*/
private val TILES_CONNECT_MUTUAL = hashSetOf(
Block.STONE,
Block.STONE_QUARRIED,
Block.STONE_TILE_WHITE,
Block.STONE_BRICKS,
Block.DIRT,
Block.GRASS,
Block.GRASSWALL,
Block.PLANK_BIRCH,
Block.PLANK_BLOODROSE,
Block.PLANK_EBONY,
Block.PLANK_NORMAL,
Block.SAND,
Block.SAND_WHITE,
Block.SAND_RED,
Block.SAND_DESERT,
Block.SAND_BLACK,
Block.SAND_GREEN,
Block.GRAVEL,
Block.GRAVEL_GREY,
Block.SNOW,
Block.ICE_NATURAL,
Block.ICE_MAGICAL,
Block.ORE_COPPER,
Block.ORE_IRON,
Block.ORE_GOLD,
Block.ORE_SILVER,
Block.ORE_ILMENITE,
Block.ORE_AURICHALCUM,
Block.SANDSTONE,
Block.SANDSTONE_BLACK,
Block.SANDSTONE_DESERT,
Block.SANDSTONE_RED,
Block.SANDSTONE_WHITE,
Block.SANDSTONE_GREEN,
Block.WATER,
Block.WATER_1,
Block.WATER_2,
Block.WATER_3,
Block.WATER_4,
Block.WATER_5,
Block.WATER_6,
Block.WATER_7,
Block.WATER_8,
Block.WATER_9,
Block.WATER_10,
Block.WATER_11,
Block.WATER_12,
Block.WATER_13,
Block.WATER_14,
Block.WATER_15,
Block.LAVA,
Block.LAVA_1,
Block.LAVA_2,
Block.LAVA_3,
Block.LAVA_4,
Block.LAVA_5,
Block.LAVA_6,
Block.LAVA_7,
Block.LAVA_8,
Block.LAVA_9,
Block.LAVA_10,
Block.LAVA_11,
Block.LAVA_12,
Block.LAVA_13,
Block.LAVA_14,
Block.LAVA_15
)
/**
* To interact with external modules
*/
@JvmStatic fun addConnectMutual(blockID: Int): Boolean {
return TILES_CONNECT_MUTUAL.add(blockID)
}
/**
* Torches, levers, switches, ...
*/
private val TILES_WALL_STICKER = hashSetOf(
Block.TORCH,
Block.TORCH_FROST,
Block.TORCH_OFF,
Block.TORCH_FROST_OFF
)
/**
* To interact with external modules
*/
@JvmStatic fun addWallSticker(blockID: Int): Boolean {
return TILES_WALL_STICKER.add(blockID)
}
/**
* platforms, ...
*/
private val TILES_WALL_STICKER_CONNECT_SELF = hashSetOf(
Block.PLATFORM_BIRCH,
Block.PLATFORM_BLOODROSE,
Block.PLATFORM_EBONY,
Block.PLATFORM_STONE,
Block.PLATFORM_WOODEN
)
/**
* To interact with external modules
*/
@JvmStatic fun addWallStickerConnectSelf(blockID: Int): Boolean {
return TILES_WALL_STICKER_CONNECT_SELF.add(blockID)
}
/**
* Tiles that half-transparent and has hue
* will blend colour using colour multiplication
* i.e. red hues get lost if you dive into the water
*/
private val TILES_BLEND_MUL = hashSetOf(
Block.WATER,
Block.WATER_1,
Block.WATER_2,
Block.WATER_3,
Block.WATER_4,
Block.WATER_5,
Block.WATER_6,
Block.WATER_7,
Block.WATER_8,
Block.WATER_9,
Block.WATER_10,
Block.WATER_11,
Block.WATER_12,
Block.WATER_13,
Block.WATER_14,
Block.WATER_15,
Block.LAVA,
Block.LAVA_1,
Block.LAVA_2,
Block.LAVA_3,
Block.LAVA_4,
Block.LAVA_5,
Block.LAVA_6,
Block.LAVA_7,
Block.LAVA_8,
Block.LAVA_9,
Block.LAVA_10,
Block.LAVA_11,
Block.LAVA_12,
Block.LAVA_13,
Block.LAVA_14,
Block.LAVA_15
)
/**
* To interact with external modules
*/
@JvmStatic fun addBlendMul(blockID: Int): Boolean {
return TILES_BLEND_MUL.add(blockID)
}
fun renderWall(g: Graphics) {
/**
* render to camera
*/
blendNormal()
tilesTerrain.startUse()
drawTiles(g, WALL, false)
tilesTerrain.endUse()
blendMul()
g.color = wallOverlayColour
g.fillRect(WorldCamera.x.toFloat(), WorldCamera.y.toFloat(),
WorldCamera.width.toFloat() + 1, WorldCamera.height.toFloat() + 1
)
blendNormal()
}
fun renderTerrain(g: Graphics) {
/**
* render to camera
*/
blendNormal()
tilesTerrain.startUse()
drawTiles(g, TERRAIN, false) // regular tiles
tilesTerrain.endUse()
}
fun renderFront(g: Graphics, drawWires: Boolean) {
/**
* render to camera
*/
blendMul()
tilesTerrain.startUse()
drawTiles(g, TERRAIN, true) // blendmul tiles
tilesTerrain.endUse()
if (drawWires) {
tilesWire.startUse()
drawTiles(g, WIRE, false)
tilesWire.endUse()
}
blendNormal()
}
private val tileDrawLightThreshold = 2
private fun drawTiles(g: Graphics, mode: Int, drawModeTilesBlendMul: Boolean) {
val for_y_start = y / TILE_SIZE
val for_y_end = BlocksDrawer.clampHTile(for_y_start + (height / TILE_SIZE) + 2)
val for_x_start = x / TILE_SIZE - 1
val for_x_end = for_x_start + (width / TILE_SIZE) + 3
var zeroTileCounter = 0
// loop
for (y in for_y_start..for_y_end) {
for (x in for_x_start..for_x_end - 1) {
val thisTile: Int?
if (mode % 3 == WALL)
thisTile = world.getTileFromWall(x, y)
else if (mode % 3 == TERRAIN)
thisTile = world.getTileFromTerrain(x, y)
else if (mode % 3 == WIRE)
thisTile = world.getTileFromWire(x, y)
else
throw IllegalArgumentException()
val noDamageLayer = mode % 3 == WIRE
// draw a tile, but only when illuminated
try {
if ((mode == WALL || mode == TERRAIN) && // not an air tile
(thisTile ?: 0) != Block.AIR) {
// check if light level of nearby or this tile is illuminated
if ( LightmapRenderer.getHighestRGB(x, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x, y + 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y + 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y + 1) ?: 0 >= tileDrawLightThreshold) {
// blackness
if (zeroTileCounter > 0) {
/* unable to do anything */
zeroTileCounter = 0
}
val nearbyTilesInfo: Int
if (isPlatform(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoPlatform(x, y)
}
else if (isWallSticker(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoWallSticker(x, y)
}
else if (isConnectMutual(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoNonSolid(x, y, mode)
}
else if (isConnectSelf(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile)
}
else {
nearbyTilesInfo = 0
}
val thisTileX = if (!noDamageLayer)
PairedMapLayer.RANGE * ((thisTile ?: 0) % PairedMapLayer.RANGE) + nearbyTilesInfo
else
nearbyTilesInfo
val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE
// draw a tile
if (drawModeTilesBlendMul) {
if (BlocksDrawer.isBlendMul(thisTile)) {
drawTile(mode, x, y, thisTileX, thisTileY)
}
}
else {
// do NOT add "if (!isBlendMul(thisTile))"!
// or else they will not look like they should be when backed with wall
drawTile(mode, x, y, thisTileX, thisTileY)
}
// draw a breakage
if (mode == TERRAIN || mode == WALL) {
val breakage = if (mode == TERRAIN) world.getTerrainDamage(x, y) else world.getWallDamage(x, y)
val maxHealth = BlockCodex[world.getTileFromTerrain(x, y)].strength
val stage = (breakage / maxHealth).times(breakAnimSteps).roundInt()
// actual drawing
if (stage > 0) {
// alpha blending works, but no GL blend func...
drawTile(mode, x, y, 5 + stage, 0)
}
}
} // end if (is illuminated)
// draw black patch
else {
zeroTileCounter++ // unused for now
GL11.glColor4f(0f, 0f, 0f, 1f)
GL11.glTexCoord2f(0f, 0f)
GL11.glVertex3f(x * TILE_SIZE.toFloat(), y * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f, 0f + TILE_SIZE)
GL11.glVertex3f(x * TILE_SIZE.toFloat(), (y + 1) * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f + TILE_SIZE, 0f + TILE_SIZE)
GL11.glVertex3f((x + 1) * TILE_SIZE.toFloat(), (y + 1) * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f + TILE_SIZE, 0f)
GL11.glVertex3f((x + 1) * TILE_SIZE.toFloat(), y * TILE_SIZE.toFloat(), 0f)
GL11.glColor4f(1f, 1f, 1f, 1f)
}
} // end if (not an air)
} catch (e: NullPointerException) {
// do nothing. WARNING: This exception handling may hide erratic behaviour completely.
}
}
}
}
/**
* @param x
* *
* @param y
* *
* @return binary [0-15] 1: up, 2: right, 4: down, 8: left
*/
fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(mode, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(mode, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_UP] = world.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(mode, x , y + 1) ?: Block.NULL
// try for
var ret = 0
for (i in 0..3) {
if (nearbyTiles[i] == mark) {
ret += 1 shl i // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
}
return ret
}
fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(mode, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(mode, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_UP] = world.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(mode, x , y + 1) ?: Block.NULL
// try for
var ret = 0
for (i in 0..3) {
try {
if (!BlockCodex[nearbyTiles[i]].isSolid &&
!BlockCodex[nearbyTiles[i]].isFluid) {
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
} catch (e: ArrayIndexOutOfBoundsException) {
}
}
return ret
}
fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int {
val nearbyTiles = IntArray(4)
val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(TERRAIN, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(TERRAIN, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(TERRAIN, x , y + 1) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_BACK] = world.getTileFrom(WALL, x , y) ?: Block.NULL
try {
if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_DOWN]].isSolid)
// has tile on the bottom
return 3
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid
&& BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid)
// has tile on both sides
return 0
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid)
// has tile on the right
return 2
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid)
// has tile on the left
return 1
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_BACK]].isSolid)
// has tile on the back
return 0
else
return 3
} catch (e: ArrayIndexOutOfBoundsException) {
return if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_DOWN]].isSolid)
// has tile on the bottom
3 else 0
}
}
fun getNearbyTilesInfoPlatform(x: Int, y: Int): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(TERRAIN, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(TERRAIN, x + 1, y) ?: Block.NULL
if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid) ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT]) &&
isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // LR solid || LR platform
return 0
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT]) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // L solid and not platform && R not solid and not platform
return 4
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT]) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // R solid and not platform && L not solid and nto platform
return 6
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // L solid && L not platform
return 3
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // R solid && R not platform
return 5
else if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // L solid or platform && R not solid and not platform
return 1
else if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // R solid or platform && L not solid and not platform
return 2
else
return 7
}
private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
if (mode == TERRAIN || mode == WALL)
tilesTerrain.renderInUse(
FastMath.floor((tilewisePosX * TILE_SIZE).toFloat()),
FastMath.floor((tilewisePosY * TILE_SIZE).toFloat()),
sheetX, sheetY
)
else if (mode == WIRE)
tilesWire.renderInUse(
FastMath.floor((tilewisePosX * TILE_SIZE).toFloat()),
FastMath.floor((tilewisePosY * TILE_SIZE).toFloat()),
sheetX, sheetY
)
else
throw IllegalArgumentException()
}
fun clampH(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.height * TILE_SIZE) {
return world.height * TILE_SIZE
} else {
return x
}
}
fun clampWTile(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.width) {
return world.width
} else {
return x
}
}
fun clampHTile(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.height) {
return world.height
} else {
return x
}
}
fun getRenderStartX(): Int = x / TILE_SIZE
fun getRenderStartY(): Int = y / TILE_SIZE
fun getRenderEndX(): Int = clampWTile(getRenderStartX() + (width / TILE_SIZE) + 2)
fun getRenderEndY(): Int = clampHTile(getRenderStartY() + (height / TILE_SIZE) + 2)
fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b)
fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b)
fun isWallSticker(b: Int?): Boolean = TILES_WALL_STICKER.contains(b)
fun isPlatform(b: Int?): Boolean = TILES_WALL_STICKER_CONNECT_SELF.contains(b)
fun isBlendMul(b: Int?): Boolean = TILES_BLEND_MUL.contains(b)
fun tileInCamera(x: Int, y: Int) =
x >= WorldCamera.x.div(TILE_SIZE) && y >= WorldCamera.y.div(TILE_SIZE) &&
x <= WorldCamera.x.plus(width).div(TILE_SIZE) && y <= WorldCamera.y.plus(width).div(TILE_SIZE)
}

View File

@@ -7,8 +7,6 @@ import com.jme3.math.FastMath
import net.torvald.terrarum.gameactors.ActorWithPhysics import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyToggler
import org.newdawn.slick.Color import org.newdawn.slick.Color
import org.newdawn.slick.Graphics import org.newdawn.slick.Graphics
import java.util.* import java.util.*
@@ -20,12 +18,15 @@ import java.util.*
object LightmapRenderer { object LightmapRenderer {
private val world: GameWorld = Terrarum.ingame!!.world private val world: GameWorld = Terrarum.ingame!!.world
// TODO if (VBO works on BlocksDrawer) THEN overscan of 256, utilise same technique in here
val overscan_open: Int = Math.min(32, 256f.div(BlockCodex[Block.AIR].opacity and 0xFF).ceil()) val overscan_open: Int = Math.min(32, 256f.div(BlockCodex[Block.AIR].opacity and 0xFF).ceil())
val overscan_opaque: Int = Math.min(8, 256f.div(BlockCodex[Block.STONE].opacity and 0xFF).ceil()) val overscan_opaque: Int = Math.min(8, 256f.div(BlockCodex[Block.STONE].opacity and 0xFF).ceil())
private val LIGHTMAP_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH) val LIGHTMAP_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH)
.div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3 .div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3
private val LIGHTMAP_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT) val LIGHTMAP_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT)
.div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3 .div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3
/** /**
@@ -215,8 +216,8 @@ object LightmapRenderer {
if (it is Luminous && it is ActorWithPhysics) { if (it is Luminous && it is ActorWithPhysics) {
// put lanterns to the area the luminantBox is occupying // put lanterns to the area the luminantBox is occupying
for (lightBox in it.lightBoxList) { for (lightBox in it.lightBoxList) {
val lightBoxX = it.hitbox.posX + lightBox.posX val lightBoxX = it.hitbox.startX + lightBox.startX
val lightBoxY = it.hitbox.posY + lightBox.posY val lightBoxY = it.hitbox.startY + lightBox.startY
val lightBoxW = lightBox.width val lightBoxW = lightBox.width
val lightBoxH = lightBox.height val lightBoxH = lightBox.height
for (y in lightBoxY.div(TILE_SIZE).floorInt() for (y in lightBoxY.div(TILE_SIZE).floorInt()
@@ -364,10 +365,7 @@ object LightmapRenderer {
for (iy in 0..1) { for (iy in 0..1) {
for (ix in 0..1) { for (ix in 0..1) {
g.color = if (KeyToggler.isOn(Key.F9)) g.color = colourMapItoL[iy * 2 + ix].normaliseToColourHDR()
colourMapItoL[iy * 2 + ix].normaliseToColourHDR()
else
colourMapItoL[iy * 2 + ix].normaliseToColour()
g.fillRect( g.fillRect(
@@ -395,10 +393,7 @@ object LightmapRenderer {
if (x + sameLevelCounter >= this_x_end) break if (x + sameLevelCounter >= this_x_end) break
} }
g.color = if (KeyToggler.isOn(Key.F9)) g.color = (getLight(x, y) ?: 0).normaliseToColourHDR()
(getLight(x, y) ?: 0).normaliseToColourHDR()
else
(getLight(x, y) ?: 0).normaliseToColour()
g.fillRect( g.fillRect(
(x.toFloat() * TILE_SIZE).round().toFloat(), (x.toFloat() * TILE_SIZE).round().toFloat(),

Binary file not shown.