working vital meter for tool durability

This commit is contained in:
Song Minjae
2017-04-21 18:11:30 +09:00
parent c6e42ffbbe
commit b342e7d042
35 changed files with 338 additions and 185 deletions

View File

@@ -2,7 +2,7 @@ package net.torvald.aa
import net.torvald.point.Point2d import net.torvald.point.Point2d
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gameactors.sqr import net.torvald.terrarum.gameactors.sqr
import java.util.* import java.util.*
@@ -23,7 +23,7 @@ class KDHeapifiedTree() {
private val dimension = 2 private val dimension = 2
private val initialSize = 128 private val initialSize = 128
private val nodes = Array<ActorWithSprite?>(initialSize, { null }) private val nodes = Array<ActorWithPhysics?>(initialSize, { null })
private val root: Int = 0 private val root: Int = 0
@@ -34,13 +34,13 @@ class KDHeapifiedTree() {
private fun Int.getActor() = nodes[this] private fun Int.getActor() = nodes[this]
private fun Int.getLeft() = this * 2 + 1 private fun Int.getLeft() = this * 2 + 1
private fun Int.getRight() = this * 2 + 2 private fun Int.getRight() = this * 2 + 2
private fun Int.set(value: ActorWithSprite?) { nodes[this] = value } private fun Int.set(value: ActorWithPhysics?) { nodes[this] = value }
private fun Int.setLeftChild(value: ActorWithSprite?) { nodes[this.getLeft()] = value } private fun Int.setLeftChild(value: ActorWithPhysics?) { nodes[this.getLeft()] = value }
private fun Int.setRightChild(value: ActorWithSprite?) { nodes[this.getRight()] = value } private fun Int.setRightChild(value: ActorWithPhysics?) { nodes[this.getRight()] = value }
private val zeroPoint = Point2d(0.0, 0.0) private val zeroPoint = Point2d(0.0, 0.0)
private fun create(points: List<ActorWithSprite?>, depth: Int, index: Int): ActorWithSprite? { private fun create(points: List<ActorWithPhysics?>, depth: Int, index: Int): ActorWithPhysics? {
if (points.isEmpty()) { if (points.isEmpty()) {
index.set(null) index.set(null)
@@ -91,7 +91,7 @@ class KDHeapifiedTree() {
private fun expandArray() { private fun expandArray() {
val prevNodes = nodes.copyOf() val prevNodes = nodes.copyOf()
Array<ActorWithSprite?>(prevNodes.size * 2, { null }) Array<ActorWithPhysics?>(prevNodes.size * 2, { null })
create(prevNodes.toList(), 0, 0) create(prevNodes.toList(), 0, 0)
} }

View File

@@ -0,0 +1,88 @@
package net.torvald.dataclass
import kotlin.experimental.or
/**
* https://stackoverflow.com/questions/6162651/half-precision-floating-point-in-java#6162687
*
* Created by SKYHi14 on 2017-04-21.
*/
typealias Float16Bits = Short
class Float16() {
var bits = 0.toShort()
private set
constructor(fval: Float) : this() {
fromFloat(fval)
}
fun toFloat() = Float16.toFloat(bits)
fun fromFloat(fval: Float) {
bits = Float16.fromFloat(fval)
}
companion object {
fun toFloat(hbits: Short): Float {
val hbits = hbits.toInt().and(0xFFFF)
var mant = hbits and 0x03ff // 10 bits mantissa
var exp = hbits and 0x7c00 // 5 bits exponent
if (exp == 0x7c00)
// NaN/Inf
exp = 0x3fc00 // -> NaN/Inf
else if (exp != 0)
// normalized value
{
exp += 0x1c000 // exp - 15 + 127
if (mant == 0 && exp > 0x1c400)
// smooth transition
return java.lang.Float.intBitsToFloat(hbits and 0x8000 shl 16 or (exp shl 13) or 0x3ff)
}
else if (mant != 0)
// && exp==0 -> subnormal
{
exp = 0x1c400 // make it normal
do {
mant = mant shl 1 // mantissa * 2
exp -= 0x400 // decrease exp by 1
} while (mant and 0x400 == 0) // while not normal
mant = mant and 0x3ff // discard subnormal bit
} // else +/-0 -> +/-0
return java.lang.Float.intBitsToFloat(// combine all parts
hbits and 0x8000 shl 16 or (exp or mant shl 13)) // value << ( 23 - 10 )
}
fun fromFloat(fval: Float): Short {
val fbits = java.lang.Float.floatToIntBits(fval)
val sign = fbits.ushr(16).and(0x8000).toShort() // sign only
var `val` = (fbits and 0x7fffffff) + 0x1000 // rounded value
if (`val` >= 0x47800000)
// might be or become NaN/Inf
{ // avoid Inf due to rounding
if (fbits and 0x7fffffff >= 0x47800000) { // is or must become NaN/Inf
if (`val` < 0x7f800000)
// was value but too large
return sign or 0x7c00 // make it +/-Inf
return sign or 0x7c00 or // remains +/-Inf or NaN
(fbits and 0x007fffff).ushr(13).toShort() // keep NaN (and Inf) bits
}
return sign or 0x7bff.toShort() // unrounded not quite Inf
}
if (`val` >= 0x38800000)
// remains normalized value
return sign or (`val` - 0x38000000).ushr(13).toShort() // exp - 127 + 15
if (`val` < 0x33000000)
// too small for subnormal
return sign // becomes +/-0
`val` = (fbits and 0x7fffffff).ushr(23) // tmp exp for subnormal calc
return sign or ((fbits and 0x7fffff or 0x800000) // add subnormal bit
+ 0x800000.ushr(`val` - 102) // round depending on cut off
).ushr(126 - `val`) // div by 2^(1-(exp-127+15)) and >> 13 | exp=0
.toShort()
}
}
}

View File

@@ -1,4 +1,4 @@
package net.torvald.gadgets package net.torvald.dataclass
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer

View File

@@ -65,7 +65,6 @@ open class GameFontBase(val noShadow: Boolean) : Font {
private fun isCyrilic(c: Char) = c.toInt() in 0x400..0x45F private fun isCyrilic(c: Char) = c.toInt() in 0x400..0x45F
private fun isFullwidthUni(c: Char) = c.toInt() in 0xFF00..0xFF1F private fun isFullwidthUni(c: Char) = c.toInt() in 0xFF00..0xFF1F
private fun isUniPunct(c: Char) = c.toInt() in 0x2000..0x206F private fun isUniPunct(c: Char) = c.toInt() in 0x2000..0x206F
private fun isWenQuanYi(c: Char) = c.toInt() in 0x3400..0x9FFF
private fun isGreek(c: Char) = c.toInt() in 0x370..0x3CE private fun isGreek(c: Char) = c.toInt() in 0x370..0x3CE
private fun isThai(c: Char) = c.toInt() in 0xE00..0xE7F private fun isThai(c: Char) = c.toInt() in 0xE00..0xE7F
private fun isThaiDiacritics(c: Char) = c.toInt() in 0xE34..0xE3A private fun isThaiDiacritics(c: Char) = c.toInt() in 0xE34..0xE3A
@@ -91,9 +90,6 @@ open class GameFontBase(val noShadow: Boolean) : Font {
private fun cjkPunctIndexX(c: Char) = (c.toInt() - 0x3000) % 16 private fun cjkPunctIndexX(c: Char) = (c.toInt() - 0x3000) % 16
private fun cjkPunctIndexY(c: Char) = (c.toInt() - 0x3000) / 16 private fun cjkPunctIndexY(c: Char) = (c.toInt() - 0x3000) / 16
private fun uniHanIndexX(c: Char) = (c.toInt() - 0x3400) % 256
private fun uniHanIndexY(c: Char) = (c.toInt() - 0x3400) / 256
private fun cyrilicIndexX(c: Char) = (c.toInt() - 0x400) % 16 private fun cyrilicIndexX(c: Char) = (c.toInt() - 0x400) % 16
private fun cyrilicIndexY(c: Char) = (c.toInt() - 0x400) / 16 private fun cyrilicIndexY(c: Char) = (c.toInt() - 0x400) / 16
@@ -103,8 +99,8 @@ open class GameFontBase(val noShadow: Boolean) : Font {
private fun uniPunctIndexX(c: Char) = (c.toInt() - 0x2000) % 16 private fun uniPunctIndexX(c: Char) = (c.toInt() - 0x2000) % 16
private fun uniPunctIndexY(c: Char) = (c.toInt() - 0x2000) / 16 private fun uniPunctIndexY(c: Char) = (c.toInt() - 0x2000) / 16
private fun wenQuanYiIndexX(c: Char) = (c.toInt() - 0x3400) % 256 private fun unihanIndexX(c: Char) = (c.toInt() - 0x3400) % 256
private fun wenQuanYiIndexY(c: Char) = (c.toInt() - 0x3400) / 256 private fun unihanIndexY(c: Char) = (c.toInt() - 0x3400) / 256
private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16 private fun greekIndexX(c: Char) = (c.toInt() - 0x370) % 16
private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16 private fun greekIndexY(c: Char) = (c.toInt() - 0x370) / 16
@@ -121,7 +117,7 @@ open class GameFontBase(val noShadow: Boolean) : Font {
private val unihanWidthSheets = arrayOf( private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN, SHEET_UNIHAN,
SHEET_FW_UNI, SHEET_FW_UNI,
SHEET_WENQUANYI SHEET_UNIHAN
) )
private val zeroWidthSheets = arrayOf( private val zeroWidthSheets = arrayOf(
SHEET_COLOURCODE SHEET_COLOURCODE
@@ -231,28 +227,8 @@ open class GameFontBase(val noShadow: Boolean) : Font {
} }
//hangulSheet.endUse() //hangulSheet.endUse()
// unihan fonts // WenQuanYi
/*uniHan.startUse(); //uniHan.startUse()
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (isUniHan(ch)) {
int glyphW = getWidth("" + ch);
uniHan.renderInUse(
Math.round(x
+ getWidthSubstr(s, i + 1) - glyphW
)
, Math.round((H - H_UNIHAN) / 2 + y)
, uniHanIndexX(ch)
, uniHanIndexY(ch)
);
}
}
uniHan.endUse();*/
// WenQuanYi 1
//wenQuanYi_1.startUse()
for (i in 0..s.length - 1) { for (i in 0..s.length - 1) {
val ch = s[i] val ch = s[i]
@@ -262,9 +238,9 @@ open class GameFontBase(val noShadow: Boolean) : Font {
continue continue
} }
if (isWenQuanYi(ch)) { if (isUniHan(ch)) {
val glyphW = getWidth("" + ch) val glyphW = getWidth("" + ch)
wenQuanYi.getSubImage(wenQuanYiIndexX(ch), wenQuanYiIndexY(ch)).drawWithShadow( uniHan.getSubImage(unihanIndexX(ch), unihanIndexY(ch)).drawWithShadow(
Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(), Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(),
Math.round((H - H_UNIHAN) / 2 + y).toFloat(), Math.round((H - H_UNIHAN) / 2 + y).toFloat(),
scale.toFloat(), thisCol, noShadow scale.toFloat(), thisCol, noShadow
@@ -272,7 +248,7 @@ open class GameFontBase(val noShadow: Boolean) : Font {
} }
} }
//wenQuanYi_1.endUse() //uniHan.endUse()
// regular fonts // regular fonts
var prevInstance = -1 var prevInstance = -1
@@ -405,8 +381,6 @@ open class GameFontBase(val noShadow: Boolean) : Font {
return SHEET_GREEK_VARW return SHEET_GREEK_VARW
else if (isThai(c)) else if (isThai(c))
return SHEET_THAI_WIDE return SHEET_THAI_WIDE
else if (isWenQuanYi(c))
return SHEET_WENQUANYI
else if (c.isColourCode()) else if (c.isColourCode())
return SHEET_COLOURCODE return SHEET_COLOURCODE
else if (isKeycap(c)) else if (isKeycap(c))
@@ -479,11 +453,10 @@ open class GameFontBase(val noShadow: Boolean) : Font {
lateinit internal var extBSheet: SpriteSheet lateinit internal var extBSheet: SpriteSheet
lateinit internal var kanaSheet: SpriteSheet lateinit internal var kanaSheet: SpriteSheet
lateinit internal var cjkPunct: SpriteSheet lateinit internal var cjkPunct: SpriteSheet
// static SpriteSheet uniHan; lateinit internal var uniHan: SpriteSheet
lateinit internal var cyrilic: SpriteSheet lateinit internal var cyrilic: SpriteSheet
lateinit internal var fullwidthForms: SpriteSheet lateinit internal var fullwidthForms: SpriteSheet
lateinit internal var uniPunct: SpriteSheet lateinit internal var uniPunct: SpriteSheet
lateinit internal var wenQuanYi: SpriteSheet
lateinit internal var greekSheet: SpriteSheet lateinit internal var greekSheet: SpriteSheet
lateinit internal var thaiSheet: SpriteSheet lateinit internal var thaiSheet: SpriteSheet
lateinit internal var keycapSheet: SpriteSheet lateinit internal var keycapSheet: SpriteSheet
@@ -513,11 +486,10 @@ open class GameFontBase(val noShadow: Boolean) : Font {
internal val SHEET_CYRILIC_VARW = 8 internal val SHEET_CYRILIC_VARW = 8
internal val SHEET_FW_UNI = 9 internal val SHEET_FW_UNI = 9
internal val SHEET_UNI_PUNCT = 10 internal val SHEET_UNI_PUNCT = 10
internal val SHEET_WENQUANYI = 11 internal val SHEET_GREEK_VARW = 11
internal val SHEET_GREEK_VARW = 12 internal val SHEET_THAI_WIDE = 12
internal val SHEET_THAI_WIDE = 13 internal val SHEET_THAI_NARROW = 13
internal val SHEET_THAI_NARROW = 14 internal val SHEET_KEYCAP = 14
internal val SHEET_KEYCAP = 15
internal val SHEET_UNKNOWN = 254 internal val SHEET_UNKNOWN = 254
internal val SHEET_COLOURCODE = 255 internal val SHEET_COLOURCODE = 255

View File

@@ -24,13 +24,6 @@ class GameFontImpl(noShadow: Boolean = false) : GameFontBase(noShadow = noShadow
"./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H) "./assets/graphics/fonts/kana.tga", GameFontBase.W_KANA, GameFontBase.H)
GameFontBase.cjkPunct = SpriteSheet( GameFontBase.cjkPunct = SpriteSheet(
"./assets/graphics/fonts/cjkpunct.tga", GameFontBase.W_ASIAN_PUNCT, GameFontBase.H) "./assets/graphics/fonts/cjkpunct.tga", GameFontBase.W_ASIAN_PUNCT, GameFontBase.H)
/*uniHan = new SpriteSheet(
"./assets/graphics/fonts/unifont_unihan"
+ ((!terrarum.gameLocale.contains("zh"))
? "_ja" : "")
+".tga"
, W_UNIHAN, H_UNIHAN
);*/
GameFontBase.cyrilic = SpriteSheet( GameFontBase.cyrilic = SpriteSheet(
when (Terrarum.gameLocale.substring(0..1)) { when (Terrarum.gameLocale.substring(0..1)) {
"bg" -> "./assets/graphics/fonts/cyrilic_bulgarian_variable.tga" "bg" -> "./assets/graphics/fonts/cyrilic_bulgarian_variable.tga"
@@ -41,7 +34,7 @@ class GameFontImpl(noShadow: Boolean = false) : GameFontBase(noShadow = noShadow
"./assets/graphics/fonts/fullwidth_forms.tga", GameFontBase.W_UNIHAN, GameFontBase.H_UNIHAN) "./assets/graphics/fonts/fullwidth_forms.tga", GameFontBase.W_UNIHAN, GameFontBase.H_UNIHAN)
GameFontBase.uniPunct = SpriteSheet( GameFontBase.uniPunct = SpriteSheet(
"./assets/graphics/fonts/unipunct.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H) "./assets/graphics/fonts/unipunct.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H)
GameFontBase.wenQuanYi = SpriteSheet( GameFontBase.uniHan = SpriteSheet(
"./assets/graphics/fonts/wenquanyi.tga.gz", 16, 16) "./assets/graphics/fonts/wenquanyi.tga.gz", 16, 16)
GameFontBase.greekSheet = SpriteSheet( GameFontBase.greekSheet = SpriteSheet(
"./assets/graphics/fonts/greek_variable.tga", 15, 19, 1) "./assets/graphics/fonts/greek_variable.tga", 15, 19, 1)
@@ -58,11 +51,10 @@ class GameFontImpl(noShadow: Boolean = false) : GameFontBase(noShadow = noShadow
GameFontBase.extBSheet, GameFontBase.extBSheet,
GameFontBase.kanaSheet, GameFontBase.kanaSheet,
GameFontBase.cjkPunct, GameFontBase.cjkPunct,
null, // Full unihan, filler because we're using WenQuanYi GameFontBase.uniHan,
GameFontBase.cyrilic, GameFontBase.cyrilic,
GameFontBase.fullwidthForms, GameFontBase.fullwidthForms,
GameFontBase.uniPunct, GameFontBase.uniPunct,
GameFontBase.wenQuanYi,
GameFontBase.greekSheet, GameFontBase.greekSheet,
GameFontBase.thaiSheet, GameFontBase.thaiSheet,
null, // Thai EF, filler because not being used right now null, // Thai EF, filler because not being used right now

View File

@@ -5,13 +5,13 @@
package net.torvald.spriteanimation package net.torvald.spriteanimation
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import org.newdawn.slick.Graphics import org.newdawn.slick.Graphics
import org.newdawn.slick.Image import org.newdawn.slick.Image
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import org.newdawn.slick.SpriteSheet import org.newdawn.slick.SpriteSheet
class SpriteAnimation(val parentActor: ActorWithSprite, val cellWidth: Int, val cellHeight: Int) { class SpriteAnimation(val parentActor: ActorWithPhysics, val cellWidth: Int, val cellHeight: Int) {
private var spriteImage: SpriteSheet? = null private var spriteImage: SpriteSheet? = null
var currentFrame = 0 var currentFrame = 0

View File

@@ -0,0 +1,36 @@
package net.torvald.terrarum
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.ui.UIVitalMetre
/**
* Created by SKYHi14 on 2017-04-21.
*/
object AmmoMeterProxy {
operator fun invoke(actor: ActorHumanoid, meter: UIVitalMetre) {
val currentItem = actor.inventory.itemEquipped[InventoryItem.EquipPosition.HAND_GRIP]
if (currentItem == null) {
meter.vitalGetterMax = { null }
meter.vitalGetterVal = { null }
}
else {
meter.vitalGetterVal = {
if (ItemCodex[currentItem.id].consumable)
actor.inventory.getByID(currentItem.id)!!.amount.toFloat()
else
actor.inventory.getByID(currentItem.id)!!.item.durability
}
meter.vitalGetterMax = {
if (ItemCodex[currentItem.id].consumable)
500f
else
actor.inventory.getByID(currentItem.id)!!.item.maxDurability.toFloat()
}
}
}
}

View File

@@ -72,7 +72,8 @@ class StateInGame : BasicGameState() {
lateinit var notifier: UIHandler lateinit var notifier: UIHandler
private var playableActorDelegate: PlayableActorDelegate? = null // DO NOT LATEINIT! var playableActorDelegate: PlayableActorDelegate? = null // DO NOT LATEINIT!
private set
internal val player: ActorHumanoid? // currently POSSESSED actor :) internal val player: ActorHumanoid? // currently POSSESSED actor :)
get() = playableActorDelegate?.actor get() = playableActorDelegate?.actor
@@ -95,21 +96,20 @@ class StateInGame : BasicGameState() {
val KEY_LIGHTMAP_SMOOTH = Key.F8 val KEY_LIGHTMAP_SMOOTH = Key.F8
// UI aliases (no pause) // UI aliases (no pause)
val uiAliases = HashMap<String, UIHandler>() lateinit var uiPieMenu: UIHandler
val UI_PIE_MENU = "uiPieMenu" lateinit var uiQuickBar: UIHandler
val UI_QUICK_BAR = "uiQuickBar" lateinit var uiInventoryPlayer: UIHandler
val UI_INVENTORY_PLAYER = "uiInventoryPlayer" lateinit var uiInventoryContainer: UIHandler
val UI_INVENTORY_CONTAINER = "uiInventoryContainer" lateinit var uiVitalPrimary: UIHandler
val UI_VITAL_PRIMARY = "uiVital1" lateinit var uiVitalSecondary: UIHandler
val UI_VITAL_SECONDARY = "uiVital2" lateinit var uiVitalItem: UIHandler // itemcount/durability of held block or active ammo of held gun. As for the block, max value is 500.
val UI_VITAL_ITEM = "uiVital3" // itemcount/durability of held block or active ammo of held gun. As for the block, max value is 500. lateinit var uiAliases: Array<UIHandler>
val UI_CONSOLE = "uiConsole"
// UI aliases (pause) // UI aliases (pause)
val uiAlasesPausing = HashMap<String, UIHandler>() val uiAlasesPausing = ArrayList<UIHandler>()
var paused: Boolean = false var paused: Boolean = false
get() = uiAlasesPausing.map { if (it.value.isOpened) 1 else 0 }.sum() > 0 get() = uiAlasesPausing.map { if (it.isOpened) 1 else 0 }.sum() > 0
/** /**
* Set to false if UI is opened; set to true if UI is closed. * Set to false if UI is opened; set to true if UI is closed.
*/ */
@@ -155,7 +155,6 @@ class StateInGame : BasicGameState() {
// init console window // init console window
consoleHandler = UIHandler(ConsoleWindow()) consoleHandler = UIHandler(ConsoleWindow())
consoleHandler.setPosition(0, 0) consoleHandler.setPosition(0, 0)
uiAlasesPausing[UI_CONSOLE] = consoleHandler
// init debug window // init debug window
@@ -175,7 +174,7 @@ class StateInGame : BasicGameState() {
// >- queue up game UIs that should pause the world -< // >- queue up game UIs that should pause the world -<
// inventory // inventory
uiAlasesPausing[UI_INVENTORY_PLAYER] = UIHandler( uiInventoryPlayer = UIHandler(
UIInventory(player, UIInventory(player,
width = 840, width = 840,
height = Terrarum.HEIGHT - 160, height = Terrarum.HEIGHT - 160,
@@ -183,42 +182,48 @@ class StateInGame : BasicGameState() {
), ),
toggleKey = Terrarum.getConfigInt("keyinventory") toggleKey = Terrarum.getConfigInt("keyinventory")
) )
uiAlasesPausing[UI_INVENTORY_PLAYER]!!.setPosition( uiInventoryPlayer.setPosition(
-uiAlasesPausing[UI_INVENTORY_PLAYER]!!.UI.width, -uiInventoryPlayer.UI.width,
70 70
) )
// >- lesser UIs -< // >- lesser UIs -<
// quick bar // quick bar
uiAliases[UI_QUICK_BAR] = UIHandler(UIQuickBar()) uiQuickBar = UIHandler(UIQuickBar())
uiAliases[UI_QUICK_BAR]!!.isVisible = true uiQuickBar.isVisible = true
uiAliases[UI_QUICK_BAR]!!.setPosition(0, 0) uiQuickBar.setPosition(0, 0)
// pie menu // pie menu
uiAliases[UI_PIE_MENU] = UIHandler(UIPieMenu()) uiPieMenu = UIHandler(UIPieMenu())
uiAliases[UI_PIE_MENU]!!.setPosition( uiPieMenu.setPosition(
(Terrarum.WIDTH - uiAliases[UI_PIE_MENU]!!.UI.width) / 2, (Terrarum.WIDTH - uiPieMenu.UI.width) / 2,
(Terrarum.HEIGHT - uiAliases[UI_PIE_MENU]!!.UI.height) / 2 (Terrarum.HEIGHT - uiPieMenu.UI.height) / 2
) )
// vital metre // vital metre
// fill in getter functions by // fill in getter functions by
// (uiAliases[UI_QUICK_BAR]!!.UI as UIVitalMetre).vitalGetterMax = { some_function } // (uiAliases[UI_QUICK_BAR]!!.UI as UIVitalMetre).vitalGetterMax = { some_function }
uiAliases[UI_VITAL_PRIMARY] = UIHandler(UIVitalMetre(player, { 80f }, { 100f }, Color.red, 0), customPositioning = true) uiVitalPrimary = UIHandler(UIVitalMetre(player, { 80f }, { 100f }, Color.red, 2), customPositioning = true)
uiAliases[UI_VITAL_PRIMARY]!!.setAsAlwaysVisible() uiVitalPrimary.setAsAlwaysVisible()
uiAliases[UI_VITAL_SECONDARY] = UIHandler(UIVitalMetre(player, { 73f }, { 100f }, Color(0x00dfff), 1), customPositioning = true) uiVitalSecondary = UIHandler(UIVitalMetre(player, { 73f }, { 100f }, Color(0x00dfff), 1), customPositioning = true)
uiAliases[UI_VITAL_SECONDARY]!!.setAsAlwaysVisible() uiVitalSecondary.setAsAlwaysVisible()
uiAliases[UI_VITAL_ITEM] = UIHandler(UIVitalMetre(player, { 32f }, { 100f }, Color(0xffcc00), 2), customPositioning = true) uiVitalItem = UIHandler(UIVitalMetre(player, { null }, { null }, Color(0xffcc00), 0), customPositioning = true)
uiAliases[UI_VITAL_ITEM]!!.setAsAlwaysVisible() uiVitalItem.setAsAlwaysVisible()
// batch-process uiAliases // batch-process uiAliases
uiAlasesPausing.forEach { _, uiHandler -> uiAliases = arrayOf(
uiContainer.add(uiHandler) // put them all to the UIContainer uiPieMenu,
} uiQuickBar,
uiAliases.forEach { _, uiHandler -> uiInventoryPlayer,
uiContainer.add(uiHandler) // put them all to the UIContainer //uiInventoryContainer,
} uiVitalPrimary,
uiVitalSecondary,
uiVitalItem
)
uiAlasesPausing.forEach { uiContainer.add(it) } // put them all to the UIContainer
uiAliases.forEach { uiContainer.add(it) } // put them all to the UIContainer
@@ -346,7 +351,7 @@ class StateInGame : BasicGameState() {
playableActorDelegate!!.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE playableActorDelegate!!.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE
// accept new delegate // accept new delegate
playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid) playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid)
playableActorDelegate!!.actor.collisionType = ActorWithSprite.COLLISION_KINEMATIC playableActorDelegate!!.actor.collisionType = ActorWithPhysics.COLLISION_KINEMATIC
WorldSimulator(player, UPDATE_DELTA) WorldSimulator(player, UPDATE_DELTA)
} }
@@ -446,7 +451,7 @@ class StateInGame : BasicGameState() {
// debug physics // debug physics
if (KeyToggler.isOn(Key.F11)) { if (KeyToggler.isOn(Key.F11)) {
actorContainer.forEachIndexed { i, actor -> actorContainer.forEachIndexed { i, actor ->
if (actor is ActorWithSprite) { if (actor is ActorWithPhysics) {
worldG.color = Color(1f, 0f, 1f, 1f) worldG.color = Color(1f, 0f, 1f, 1f)
worldG.font = Terrarum.fontSmallNumbers worldG.font = Terrarum.fontSmallNumbers
worldG.lineWidth = 1f worldG.lineWidth = 1f
@@ -527,8 +532,8 @@ class StateInGame : BasicGameState() {
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key) if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) { || key == Terrarum.getConfigInt("keyquicksel")) {
uiAliases[UI_PIE_MENU]!!.setAsOpen() uiPieMenu.setAsOpen()
uiAliases[UI_QUICK_BAR]!!.setAsClose() uiQuickBar.setAsClose()
} }
uiContainer.forEach { it.keyPressed(key, c) } // for KeyboardControlled UIcanvases uiContainer.forEach { it.keyPressed(key, c) } // for KeyboardControlled UIcanvases
@@ -539,8 +544,8 @@ class StateInGame : BasicGameState() {
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key) if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) { || key == Terrarum.getConfigInt("keyquicksel")) {
uiAliases[UI_PIE_MENU]!!.setAsClose() uiPieMenu.setAsClose()
uiAliases[UI_QUICK_BAR]!!.setAsOpen() uiQuickBar.setAsOpen()
} }
uiContainer.forEach { it.keyReleased(key, c) } // for KeyboardControlled UIcanvases uiContainer.forEach { it.keyReleased(key, c) } // for KeyboardControlled UIcanvases
@@ -679,6 +684,7 @@ class StateInGame : BasicGameState() {
} }
} }
} }
AmmoMeterProxy(player!!, uiVitalItem.UI as UIVitalMetre)
} }
} }

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.console package net.torvald.terrarum.console
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
/** /**
* Created by minjaesong on 2017-01-20. * Created by minjaesong on 2017-01-20.
@@ -15,8 +15,8 @@ object SetScale : ConsoleCommand {
val target = Terrarum.ingame!!.getActorByID(targetID) val target = Terrarum.ingame!!.getActorByID(targetID)
if (target !is ActorWithSprite) { if (target !is ActorWithPhysics) {
EchoError("Target is not ActorWithSprite") EchoError("Target is not ActorWithPhysics")
} }
else { else {
target.scale = scale target.scale = scale

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.console package net.torvald.terrarum.console
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gameactors.PhysTestBall import net.torvald.terrarum.gameactors.PhysTestBall
import net.torvald.terrarum.mapdrawer.TilesDrawer import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum

View File

@@ -3,7 +3,7 @@ package net.torvald.terrarum.console
import net.torvald.terrarum.StateInGame import net.torvald.terrarum.StateInGame
import net.torvald.terrarum.mapdrawer.FeaturesDrawer import net.torvald.terrarum.mapdrawer.FeaturesDrawer
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
/** /**
* Created by minjaesong on 16-01-24. * Created by minjaesong on 16-01-24.
@@ -31,8 +31,8 @@ internal object Teleport : ConsoleCommand {
EchoError("missing 'to' on teleport command") EchoError("missing 'to' on teleport command")
return return
} }
val fromActor: ActorWithSprite val fromActor: ActorWithPhysics
val targetActor: ActorWithSprite val targetActor: ActorWithPhysics
try { try {
val fromActorID = args[1].toInt() val fromActorID = args[1].toInt()
val targetActorID = if (args[3].toLowerCase() == "player") val targetActorID = if (args[3].toLowerCase() == "player")
@@ -43,13 +43,13 @@ internal object Teleport : ConsoleCommand {
// if from == target, ignore the action // if from == target, ignore the action
if (fromActorID == targetActorID) return if (fromActorID == targetActorID) return
if (Terrarum.ingame!!.getActorByID(fromActorID) !is ActorWithSprite || if (Terrarum.ingame!!.getActorByID(fromActorID) !is ActorWithPhysics ||
Terrarum.ingame!!.getActorByID(targetActorID) !is ActorWithSprite) { Terrarum.ingame!!.getActorByID(targetActorID) !is ActorWithPhysics) {
throw IllegalArgumentException() throw IllegalArgumentException()
} }
else { else {
fromActor = Terrarum.ingame!!.getActorByID(fromActorID) as ActorWithSprite fromActor = Terrarum.ingame!!.getActorByID(fromActorID) as ActorWithPhysics
targetActor = Terrarum.ingame!!.getActorByID(targetActorID) as ActorWithSprite targetActor = Terrarum.ingame!!.getActorByID(targetActorID) as ActorWithPhysics
} }
} }
catch (e: NumberFormatException) { catch (e: NumberFormatException) {
@@ -72,7 +72,7 @@ internal object Teleport : ConsoleCommand {
return return
} }
val actor: ActorWithSprite val actor: ActorWithPhysics
val x: Int val x: Int
val y: Int val y: Int
try { try {
@@ -80,11 +80,11 @@ internal object Teleport : ConsoleCommand {
y = args[4].toInt() * FeaturesDrawer.TILE_SIZE + FeaturesDrawer.TILE_SIZE / 2 y = args[4].toInt() * FeaturesDrawer.TILE_SIZE + FeaturesDrawer.TILE_SIZE / 2
val actorID = args[1].toInt() val actorID = args[1].toInt()
if (Terrarum.ingame!!.getActorByID(actorID) !is ActorWithSprite) { if (Terrarum.ingame!!.getActorByID(actorID) !is ActorWithPhysics) {
throw IllegalArgumentException() throw IllegalArgumentException()
} }
else { else {
actor = Terrarum.ingame!!.getActorByID(actorID) as ActorWithSprite actor = Terrarum.ingame!!.getActorByID(actorID) as ActorWithPhysics
} }
} }
catch (e: NumberFormatException) { catch (e: NumberFormatException) {

View File

@@ -5,7 +5,7 @@ import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.Echo import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.console.SetAV import net.torvald.terrarum.console.SetAV
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.mapdrawer.FeaturesDrawer import net.torvald.terrarum.mapdrawer.FeaturesDrawer
import java.awt.BorderLayout import java.awt.BorderLayout
import java.awt.GridLayout import java.awt.GridLayout
@@ -28,7 +28,7 @@ class ActorValueTracker constructor() : JFrame() {
private val avPosArea = JTextArea() private val avPosArea = JTextArea()
private val avPosScroller = JScrollPane(avPosArea) private val avPosScroller = JScrollPane(avPosArea)
private var actor: ActorWithSprite? = null private var actor: ActorWithPhysics? = null
private var actorValue: ActorValue? = null private var actorValue: ActorValue? = null
private val modavInputKey = JTextField() private val modavInputKey = JTextField()
@@ -87,7 +87,7 @@ class ActorValueTracker constructor() : JFrame() {
actorValue = actor!!.actorValue actorValue = actor!!.actorValue
} }
else if (actorIDField.text.isNotBlank()) { else if (actorIDField.text.isNotBlank()) {
actor = Terrarum.ingame!!.getActorByID(actorIDField.text.toInt()) as ActorWithSprite actor = Terrarum.ingame!!.getActorByID(actorIDField.text.toInt()) as ActorWithPhysics
actorValue = actor!!.actorValue actorValue = actor!!.actorValue
} }
} }
@@ -151,7 +151,7 @@ class ActorValueTracker constructor() : JFrame() {
this.title = "AVTracker — $actor" this.title = "AVTracker — $actor"
if (actor is ActorWithSprite) { if (actor is ActorWithPhysics) {
this.actor = actor this.actor = actor
} }

View File

@@ -344,7 +344,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* this code base, ACCELERATION must be changed (in other words, we must deal with JERK) accordingly * this code base, ACCELERATION must be changed (in other words, we must deal with JERK) accordingly
* to the FRICTION. * to the FRICTION.
* *
* So I'm adding walkX/Y and getting the ActorWithSprite.setNewNextHitbox to use the velocity value of * So I'm adding walkX/Y and getting the ActorWithPhysics.setNewNextHitbox to use the velocity value of
* walkX/Y + velocity, which is stored in variable moveDelta. * walkX/Y + velocity, which is stored in variable moveDelta.
* *
* Be warned. * Be warned.

View File

@@ -26,7 +26,7 @@ import java.util.*
* *
* Created by minjaesong on 16-01-13. * Created by minjaesong on 16-01-13.
*/ */
open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean = false, physics: Boolean = true) : ActorVisible(renderOrder) { open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean = false, physics: Boolean = true) : ActorVisible(renderOrder) {
/** !! ActorValue macros are on the very bottom of the source !! **/ /** !! ActorValue macros are on the very bottom of the source !! **/
@@ -113,7 +113,7 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
if (value <= 0) if (value <= 0)
throw IllegalArgumentException("mass cannot be less than or equal to zero.") throw IllegalArgumentException("mass cannot be less than or equal to zero.")
else if (value < MASS_LOWEST) { else if (value < MASS_LOWEST) {
println("[ActorWithSprite] input too small; using $MASS_LOWEST instead.") println("[ActorWithPhysics] input too small; using $MASS_LOWEST instead.")
actorValue[AVKey.BASEMASS] = MASS_LOWEST actorValue[AVKey.BASEMASS] = MASS_LOWEST
} }
@@ -126,7 +126,7 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
if (value < 0) if (value < 0)
throw IllegalArgumentException("invalid elasticity value $value; valid elasticity value is [0, 1].") throw IllegalArgumentException("invalid elasticity value $value; valid elasticity value is [0, 1].")
else if (value >= ELASTICITY_MAX) { else if (value >= ELASTICITY_MAX) {
println("[ActorWithSprite] Elasticity were capped to $ELASTICITY_MAX.") println("[ActorWithPhysics] Elasticity were capped to $ELASTICITY_MAX.")
field = ELASTICITY_MAX field = ELASTICITY_MAX
} }
else else
@@ -150,7 +150,7 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
var density = 1000.0 var density = 1000.0
set(value) { set(value) {
if (value < 0) if (value < 0)
throw IllegalArgumentException("[ActorWithSprite] $value: density cannot be negative.") throw IllegalArgumentException("[ActorWithPhysics] $value: density cannot be negative.")
field = value field = value
} }
@@ -190,7 +190,7 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT get() = actorValue.getAsDouble(AVKey.DRAGCOEFF) ?: DRAG_COEFF_DEFAULT
set(value) { set(value) {
if (value < 0) if (value < 0)
throw IllegalArgumentException("[ActorWithSprite] drag coefficient cannot be negative.") throw IllegalArgumentException("[ActorWithPhysics] drag coefficient cannot be negative.")
actorValue[AVKey.DRAGCOEFF] = value actorValue[AVKey.DRAGCOEFF] = value
} }
@@ -272,8 +272,8 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
* @param h * @param h
* @param tx positive: translate sprite to LEFT. * @param tx positive: translate sprite to LEFT.
* @param ty positive: translate sprite to DOWN. * @param ty positive: translate sprite to DOWN.
* @see ActorWithSprite.drawBody * @see ActorWithPhysics.drawBody
* @see ActorWithSprite.drawGlow * @see ActorWithPhysics.drawGlow
*/ */
fun setHitboxDimension(w: Int, h: Int, tx: Int, ty: Int) { fun setHitboxDimension(w: Int, h: Int, tx: Int, ty: Int) {
baseHitboxH = h baseHitboxH = h
@@ -1166,9 +1166,9 @@ open class ActorWithSprite(renderOrder: RenderOrder, val immobileBody: Boolean =
// warnings // warnings
if (sprite == null && isVisible) if (sprite == null && isVisible)
println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.") println("[ActorWithPhysics] Caution: actor ${this.javaClass.simpleName} is echo but the sprite was not set.")
else if (sprite != null && !isVisible) else if (sprite != null && !isVisible)
println("[ActorWithSprite] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.") println("[ActorWithPhysics] Caution: actor ${this.javaClass.simpleName} is invisible but the sprite was given.")
assertPrinted = true assertPrinted = true
} }

View File

@@ -18,8 +18,8 @@ object CreatureBuilder {
* @Param jsonFileName with extension * @Param jsonFileName with extension
*/ */
@Throws(IOException::class, SlickException::class) @Throws(IOException::class, SlickException::class)
operator fun invoke(module: String, jsonFileName: String): ActorWithSprite { operator fun invoke(module: String, jsonFileName: String): ActorWithPhysics {
val actor = ActorWithSprite(Actor.RenderOrder.MIDDLE) val actor = ActorWithPhysics(Actor.RenderOrder.MIDDLE)
InjectCreatureRaw(actor.actorValue, module, jsonFileName) InjectCreatureRaw(actor.actorValue, module, jsonFileName)

View File

@@ -9,7 +9,7 @@ import org.newdawn.slick.Graphics
/** /**
* Created by minjaesong on 16-03-15. * Created by minjaesong on 16-03-15.
*/ */
class DroppedItem(private val item: InventoryItem) : ActorWithSprite(Actor.RenderOrder.MIDTOP) { class DroppedItem(private val item: InventoryItem) : ActorWithPhysics(Actor.RenderOrder.MIDTOP) {
init { init {
if (item.id >= ItemCodex.ACTOR_ID_MIN) if (item.id >= ItemCodex.ACTOR_ID_MIN)

View File

@@ -6,7 +6,7 @@ import net.torvald.spriteanimation.SpriteAnimation
* Created by minjaesong on 16-06-17. * Created by minjaesong on 16-06-17.
*/ */
open class FixtureBase(physics: Boolean = true) : open class FixtureBase(physics: Boolean = true) :
ActorWithSprite(Actor.RenderOrder.BEHIND, immobileBody = true, physics = physics) { ActorWithPhysics(Actor.RenderOrder.BEHIND, immobileBody = true, physics = physics) {
/** /**
* 0: Open * 0: Open
* 1: Blocked * 1: Blocked

View File

@@ -13,7 +13,7 @@ typealias AnyPlayer = HistoricalFigure
* *
* Created by minjaesong on 16-10-10. * Created by minjaesong on 16-10-10.
*/ */
open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null, realAirFriction: Boolean = false) : ActorWithSprite(Actor.RenderOrder.MIDDLE, realAirFriction) { open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null, realAirFriction: Boolean = false) : ActorWithPhysics(Actor.RenderOrder.MIDDLE, realAirFriction) {
init { init {
this.actorValue["_bornyear"] = born.year this.actorValue["_bornyear"] = born.year

View File

@@ -34,7 +34,7 @@ open class HumanoidNPC(
} }
companion object { companion object {
val DEFAULT_COLLISION_TYPE = ActorWithSprite.COLLISION_DYNAMIC val DEFAULT_COLLISION_TYPE = ActorWithPhysics.COLLISION_DYNAMIC
} }
init { init {

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithSprite.Companion.SI_TO_GAME_ACC import net.torvald.terrarum.gameactors.ActorWithPhysics.Companion.SI_TO_GAME_ACC
import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE
import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.tileproperties.TileCodex import net.torvald.terrarum.tileproperties.TileCodex

View File

@@ -10,7 +10,7 @@ import org.newdawn.slick.Graphics
/** /**
* Created by minjaesong on 16-03-05. * Created by minjaesong on 16-03-05.
*/ */
class PhysTestBall : ActorWithSprite(Actor.RenderOrder.MIDDLE, immobileBody = true) { class PhysTestBall : ActorWithPhysics(Actor.RenderOrder.MIDDLE, immobileBody = true) {
private var color = Color.orange private var color = Color.orange

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.terrarum.AmmoMeterProxy
import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.ActorHumanoid
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input import org.newdawn.slick.Input
@@ -17,12 +18,4 @@ class PlayableActorDelegate(val actor: ActorHumanoid) {
throw IllegalArgumentException("Player must be 'Controllable'!") throw IllegalArgumentException("Player must be 'Controllable'!")
} }
fun processInput(gc: GameContainer, delta: Int, input: Input) {
(actor as Controllable).processInput(gc, delta, input)
}
fun keyPressed(key: Int, c: Char) {
(actor as Controllable).keyPressed(key, c)
}
} }

View File

@@ -11,7 +11,7 @@ import net.torvald.terrarum.mapdrawer.FeaturesDrawer
*/ */
object PlayerBuilderCynthia { object PlayerBuilderCynthia {
operator fun invoke(): ActorWithSprite { operator fun invoke(): ActorWithPhysics {
//val p: Player = Player(GameDate(100, 143)) // random value thrown //val p: Player = Player(GameDate(100, 143)) // random value thrown
val p: HumanoidNPC = HumanoidNPC( val p: HumanoidNPC = HumanoidNPC(
LuaAIWrapper("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua"), LuaAIWrapper("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua"),

View File

@@ -23,7 +23,7 @@ open class ProjectileSimple(
private val type: Int, private val type: Int,
fromPoint: Vector2, // projected coord fromPoint: Vector2, // projected coord
toPoint: Vector2 // arriving coord toPoint: Vector2 // arriving coord
) : ActorWithSprite(Actor.RenderOrder.MIDTOP), Luminous, Projectile { ) : ActorWithPhysics(Actor.RenderOrder.MIDTOP), Luminous, Projectile {
val damage: Int val damage: Int
val displayColour: Color val displayColour: Color

View File

@@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors
/** /**
* Created by minjaesong on 16-04-26. * Created by minjaesong on 16-04-26.
*/ */
class WeaponSwung(val itemID: Int) : ActorWithSprite(Actor.RenderOrder.MIDTOP), Luminous { class WeaponSwung(val itemID: Int) : ActorWithPhysics(Actor.RenderOrder.MIDTOP), Luminous {
// just let the solver use AABB; it's cheap but works just enough // just let the solver use AABB; it's cheap but works just enough
/** /**

View File

@@ -3,7 +3,7 @@ package net.torvald.terrarum.gameactors.ai
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AIControlled import net.torvald.terrarum.gameactors.AIControlled
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.mapdrawer.LightmapRenderer import net.torvald.terrarum.mapdrawer.LightmapRenderer
import net.torvald.terrarum.tileproperties.Tile import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.tileproperties.TileCodex import net.torvald.terrarum.tileproperties.TileCodex
@@ -14,7 +14,7 @@ import org.luaj.vm2.lib.ZeroArgFunction
/** /**
* Created by minjaesong on 16-10-24. * Created by minjaesong on 16-10-24.
*/ */
internal class AILuaAPI(g: Globals, actor: ActorWithSprite) { internal class AILuaAPI(g: Globals, actor: ActorWithPhysics) {
// FIXME when actor jumps, the actor releases left/right stick // FIXME when actor jumps, the actor releases left/right stick
@@ -51,9 +51,9 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
companion object { companion object {
/** /**
* Reads arbitrary ActorWithSprite and returns its information as Lua table * Reads arbitrary ActorWithPhysics and returns its information as Lua table
*/ */
fun composeActorObject(actor: ActorWithSprite): LuaTable { fun composeActorObject(actor: ActorWithPhysics): LuaTable {
val t: LuaTable = LuaTable() val t: LuaTable = LuaTable()
t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua() t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua()
@@ -87,7 +87,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
operator fun LuaTable.set(index: Int, value: Int) { this[index] = value.toLua() } operator fun LuaTable.set(index: Int, value: Int) { this[index] = value.toLua() }
} }
class GetSelfActorInfo(val actor: ActorWithSprite) : ZeroArgFunction() { class GetSelfActorInfo(val actor: ActorWithPhysics) : ZeroArgFunction() {
override fun call(): LuaValue { override fun call(): LuaValue {
return composeActorObject(actor) return composeActorObject(actor)
} }
@@ -123,13 +123,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
} }
} }
class GetX(val actor: ActorWithSprite) : ZeroArgFunction() { class GetX(val actor: ActorWithPhysics) : ZeroArgFunction() {
override fun call(): LuaValue { override fun call(): LuaValue {
return LuaValue.valueOf(actor.hitbox.centeredX) return LuaValue.valueOf(actor.hitbox.centeredX)
} }
} }
class GetY(val actor: ActorWithSprite) : ZeroArgFunction() { class GetY(val actor: ActorWithPhysics) : ZeroArgFunction() {
override fun call(): LuaValue { override fun call(): LuaValue {
return LuaValue.valueOf(actor.hitbox.centeredY) return LuaValue.valueOf(actor.hitbox.centeredY)
} }
@@ -212,7 +212,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
} }
} }
class GetNearbyTiles(val actor: ActorWithSprite) : OneArgFunction() { class GetNearbyTiles(val actor: ActorWithPhysics) : OneArgFunction() {
/** @param radius /** @param radius
* *
* 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3
@@ -254,7 +254,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
} }
} }
class GetFloorsHeight(val actor: ActorWithSprite) : OneArgFunction() { class GetFloorsHeight(val actor: ActorWithPhysics) : OneArgFunction() {
/** @param radius /** @param radius
* *
* 3 will return len:7 array, 0 will return len:1, 1 will return len:3 * 3 will return len:7 array, 0 will return len:1, 1 will return len:3
@@ -297,7 +297,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
} }
} }
class GetCeilingsHeight(val actor: ActorWithSprite) : OneArgFunction() { class GetCeilingsHeight(val actor: ActorWithPhysics) : OneArgFunction() {
/** @param arg radius /** @param arg radius
* *
* 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3
@@ -340,7 +340,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithSprite) {
} }
} }
class GetLedgesHeight(val actor: ActorWithSprite) : OneArgFunction() { class GetLedgesHeight(val actor: ActorWithPhysics) : OneArgFunction() {
/** @param arg radius /** @param arg radius
* == * ==
* <- (non-solid found) * <- (non-solid found)

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.gameactors.ai package net.torvald.terrarum.gameactors.ai
import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import org.luaj.vm2.Globals import org.luaj.vm2.Globals
import org.luaj.vm2.LuaError import org.luaj.vm2.LuaError
import org.luaj.vm2.LuaInteger import org.luaj.vm2.LuaInteger
@@ -25,14 +25,14 @@ class LuaAIWrapper(private val scriptPath: String) : ActorAI {
private lateinit var aiLuaAPI: AILuaAPI private lateinit var aiLuaAPI: AILuaAPI
private lateinit var targetActor: ActorWithSprite private lateinit var targetActor: ActorWithPhysics
/** /**
* The initialiser * The initialiser
* *
* Use ```(p.ai as LuaAIWrapper).attachActor(p)``` * Use ```(p.ai as LuaAIWrapper).attachActor(p)```
*/ */
fun attachActor(actor: ActorWithSprite) { fun attachActor(actor: ActorWithPhysics) {
targetActor = actor targetActor = actor
luag["io"] = LuaValue.NIL luag["io"] = LuaValue.NIL

View File

@@ -2,7 +2,7 @@ package net.torvald.terrarum.gameactors.physicssolver
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import java.util.* import java.util.*
/** /**
@@ -20,9 +20,9 @@ object CollisionSolver {
private val collListX = ArrayList<CollisionMarkings>(COLL_LIST_SIZE) private val collListX = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
private val collListY = ArrayList<CollisionMarkings>(COLL_LIST_SIZE) private val collListY = ArrayList<CollisionMarkings>(COLL_LIST_SIZE)
private val collCandidateX = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_CANDIDATES_SIZE) private val collCandidateX = ArrayList<Pair<ActorWithPhysics, ActorWithPhysics>>(COLL_CANDIDATES_SIZE)
private val collCandidateY = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_CANDIDATES_SIZE) private val collCandidateY = ArrayList<Pair<ActorWithPhysics, ActorWithPhysics>>(COLL_CANDIDATES_SIZE)
private var collCandidates = ArrayList<Pair<ActorWithSprite, ActorWithSprite>>(COLL_FINAL_CANDIDATES_SIZE) private var collCandidates = ArrayList<Pair<ActorWithPhysics, ActorWithPhysics>>(COLL_FINAL_CANDIDATES_SIZE)
private val collCandidateStack = Stack<CollisionMarkings>() private val collCandidateStack = Stack<CollisionMarkings>()
@@ -40,7 +40,7 @@ object CollisionSolver {
// mark list x // mark list x
Terrarum.ingame!!.actorContainer.forEach { it -> Terrarum.ingame!!.actorContainer.forEach { it ->
if (it is ActorWithSprite) { if (it is ActorWithPhysics) {
collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it)) collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it))
collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it)) collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it))
} }
@@ -73,7 +73,7 @@ object CollisionSolver {
// mark list y // mark list y
Terrarum.ingame!!.actorContainer.forEach { it -> Terrarum.ingame!!.actorContainer.forEach { it ->
if (it is ActorWithSprite) { if (it is ActorWithPhysics) {
collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it)) collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it))
collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it)) collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it))
} }
@@ -89,7 +89,7 @@ object CollisionSolver {
else if (it.kind == ENDPOINT) { else if (it.kind == ENDPOINT) {
val mark_this = it val mark_this = it
val mark_other = collCandidateStack.pop() val mark_other = collCandidateStack.pop()
val collCandidate: Pair<ActorWithSprite, ActorWithSprite> val collCandidate: Pair<ActorWithPhysics, ActorWithPhysics>
// make sure actor with lower ID comes first // make sure actor with lower ID comes first
if (mark_this.actor < mark_other.actor) if (mark_this.actor < mark_other.actor)
collCandidate = Pair(mark_this.actor, mark_other.actor) collCandidate = Pair(mark_this.actor, mark_other.actor)
@@ -137,7 +137,7 @@ object CollisionSolver {
return indexOfEqFn(this, other) >= 0 return indexOfEqFn(this, other) >= 0
} }
private fun solveCollision(a: ActorWithSprite, b: ActorWithSprite) { private fun solveCollision(a: ActorWithPhysics, b: ActorWithPhysics) {
// some of the Pair(a, b) are either duplicates or erroneously reported. // some of the Pair(a, b) are either duplicates or erroneously reported.
// e.g. (A, B), (B, C) and then (A, C); // e.g. (A, B), (B, C) and then (A, C);
// in some situation (A, C) will not making any contact with each other // in some situation (A, C) will not making any contact with each other
@@ -170,11 +170,11 @@ object CollisionSolver {
} }
} }
private infix fun ActorWithSprite.makesCollisionWith(other: ActorWithSprite) = private infix fun ActorWithPhysics.makesCollisionWith(other: ActorWithPhysics) =
this.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE && this.collisionType != ActorWithPhysics.COLLISION_NOCOLLIDE &&
other.collisionType != ActorWithSprite.COLLISION_NOCOLLIDE other.collisionType != ActorWithPhysics.COLLISION_NOCOLLIDE
private infix fun ActorWithSprite.isCollidingWith(other: ActorWithSprite): Boolean { private infix fun ActorWithPhysics.isCollidingWith(other: ActorWithPhysics): Boolean {
val ax = this.hitbox.centeredX val ax = this.hitbox.centeredX
val ay = this.hitbox.centeredY val ay = this.hitbox.centeredY
val bx = other.hitbox.centeredX val bx = other.hitbox.centeredX
@@ -205,7 +205,7 @@ object CollisionSolver {
data class CollisionMarkings( data class CollisionMarkings(
val pos: Double, val pos: Double,
val kind: Int, val kind: Int,
val actor: ActorWithSprite val actor: ActorWithPhysics
) )
/** /**

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.gameactors.physicssolver package net.torvald.terrarum.gameactors.physicssolver
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
/** /**
* Created by minjaesong on 16-05-01. * Created by minjaesong on 16-05-01.
@@ -11,7 +11,7 @@ object VelocitySolver {
} }
private fun applyGravity(actor: ActorWithSprite) { private fun applyGravity(actor: ActorWithPhysics) {
} }

View File

@@ -115,6 +115,7 @@ object GameController {
fun mouseReleased(button: Int, x: Int, y: Int) { fun mouseReleased(button: Int, x: Int, y: Int) {
if (Terrarum.ingame != null) { if (Terrarum.ingame != null) {
val ingame = Terrarum.ingame!! val ingame = Terrarum.ingame!!
// don't separate Player from this! Physics will break, esp. airborne manoeuvre
if (ingame.player != null && ingame.canPlayerControl) { if (ingame.player != null && ingame.canPlayerControl) {
val itemOnGrip = ingame.player!!.inventory.itemEquipped[InventoryItem.EquipPosition.HAND_GRIP] val itemOnGrip = ingame.player!!.inventory.itemEquipped[InventoryItem.EquipPosition.HAND_GRIP]

View File

@@ -20,6 +20,8 @@ class GameWorld(val width: Int, val height: Int) {
val layerWallLowBits: PairedMapLayer val layerWallLowBits: PairedMapLayer
val layerTerrainLowBits: PairedMapLayer val layerTerrainLowBits: PairedMapLayer
val layerThermal: MapLayerFloat // in Kelvins
val spawnX: Int val spawnX: Int
val spawnY: Int val spawnY: Int
@@ -46,6 +48,9 @@ class GameWorld(val width: Int, val height: Int) {
layerTerrainLowBits = PairedMapLayer(width, height) layerTerrainLowBits = PairedMapLayer(width, height)
layerWallLowBits = PairedMapLayer(width, height) layerWallLowBits = PairedMapLayer(width, height)
layerThermal = MapLayerFloat(width / 2, height / 2)
time = WorldTime( time = WorldTime(
71 * WorldTime.DAY_LENGTH + 71 * WorldTime.DAY_LENGTH +
7 * WorldTime.HOUR_SEC + 7 * WorldTime.HOUR_SEC +

View File

@@ -0,0 +1,60 @@
package net.torvald.terrarum.gameworld
import net.torvald.dataclass.Float16
import net.torvald.dataclass.Float16Bits
/**
* MapLayer that contains raw Float16 values
*
* Created by SKYHi14 on 2017-04-21.
*/
class MapLayerFloat(val width: Int, val height: Int) : Iterable<Float16Bits> {
internal @Volatile var data: Array<Array<Float16Bits>> // in parallel programming: do not trust your register; always read freshly from RAM!
init {
data = Array(height) { Array(width, { 0.toShort() }) }
}
/**
* Returns an iterator over elements of type `T`.
* @return an Iterator.
*/
override fun iterator(): Iterator<Float16Bits> {
return object : Iterator<Float16Bits> {
private var iteratorCount = 0
override fun hasNext(): Boolean {
return iteratorCount < width * height
}
override fun next(): Float16Bits {
val y = iteratorCount / width
val x = iteratorCount % width
// advance counter
iteratorCount += 1
return data[y][x]
}
}
}
internal fun getValue(x: Int, y: Int): Float? {
return if (x !in 0..width - 1 || y !in 0..height - 1)
null
else
data[y][x].toFloat()
}
internal fun setValue(x: Int, y: Int, value: Float) {
data[y][x] = Float16.fromFloat(value)
}
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
companion object {
@Transient const val SIZEOF: Byte = 2 // 1 for 8-bit, 2 for 16-bit, ...
}
}

View File

@@ -6,7 +6,7 @@ import net.torvald.terrarum.gameactors.CanBeAnItem
import net.torvald.terrarum.itemproperties.InventoryItem import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gamecontroller.mouseTileX import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY import net.torvald.terrarum.gamecontroller.mouseTileY
import net.torvald.terrarum.itemproperties.IVKey import net.torvald.terrarum.itemproperties.IVKey
@@ -71,7 +71,7 @@ object ItemCodex {
val mousePoint = Point2d(gc.mouseTileX.toDouble(), gc.mouseTileY.toDouble()) val mousePoint = Point2d(gc.mouseTileX.toDouble(), gc.mouseTileY.toDouble())
// linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox)
Terrarum.ingame!!.actorContainer.forEach { Terrarum.ingame!!.actorContainer.forEach {
if (it is ActorWithSprite && it.tilewiseHitbox.intersects(mousePoint)) if (it is ActorWithPhysics && it.tilewiseHitbox.intersects(mousePoint))
return false return false
} }
@@ -109,7 +109,7 @@ object ItemCodex {
override var baseMass = 10.0 override var baseMass = 10.0
override var baseToolSize: Double? = 10.0 override var baseToolSize: Double? = 10.0
override var consumable = false override var consumable = false
override var maxDurability = 606 // this much tiles before breaking override var maxDurability = 147//606 // this much tiles before breaking
override var durability = maxDurability.toFloat() override var durability = maxDurability.toFloat()
override var equipPosition = EquipPosition.HAND_GRIP override var equipPosition = EquipPosition.HAND_GRIP
override var inventoryCategory = Category.TOOL override var inventoryCategory = Category.TOOL
@@ -132,7 +132,7 @@ object ItemCodex {
// linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox)
Terrarum.ingame!!.actorContainer.forEach { Terrarum.ingame!!.actorContainer.forEach {
if (it is ActorWithSprite && it.tilewiseHitbox.intersects(mousePoint)) if (it is ActorWithPhysics && it.tilewiseHitbox.intersects(mousePoint))
return false return false
} }

View File

@@ -7,7 +7,7 @@ import com.jme3.math.FastMath
import net.torvald.colourutil.RGB import net.torvald.colourutil.RGB
import net.torvald.colourutil.CIELuvUtil.additiveLuv import net.torvald.colourutil.CIELuvUtil.additiveLuv
import net.torvald.terrarum.concurrent.ThreadParallel import net.torvald.terrarum.concurrent.ThreadParallel
import net.torvald.terrarum.gameactors.ActorWithSprite import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gameactors.abs import net.torvald.terrarum.gameactors.abs
import net.torvald.terrarum.gameactors.roundInt import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.gameworld.GameWorld
@@ -217,7 +217,7 @@ object LightmapRenderer {
private fun buildLanternmap() { private fun buildLanternmap() {
lanternMap.clear() lanternMap.clear()
Terrarum.ingame!!.actorContainer.forEach { it -> Terrarum.ingame!!.actorContainer.forEach { it ->
if (it is Luminous && it is ActorWithSprite) { 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.posX + lightBox.posX

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.ui package net.torvald.terrarum.ui
import net.torvald.gadgets.HistoryArray import net.torvald.dataclass.HistoryArray
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.Authenticator import net.torvald.terrarum.console.Authenticator