Inventory UI on ingame

This commit is contained in:
Song Minjae
2017-04-09 03:35:18 +09:00
parent c5367f8f1c
commit 671048e1e1
20 changed files with 245 additions and 267 deletions

View File

@@ -11,7 +11,6 @@ import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameactors.physicssolver.CollisionSolver
import net.torvald.terrarum.gamecontroller.GameController
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldSimulator
@@ -40,6 +39,7 @@ import java.lang.management.ManagementFactory
import java.util.*
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import kotlin.collections.HashMap
/**
* Created by minjaesong on 15-12-30.
@@ -70,9 +70,9 @@ class StateInGame : BasicGameState() {
lateinit var debugWindow: UIHandler
lateinit var notifier: UIHandler
internal var playableActorDelegate: PlayableActorDelegate? = null
private lateinit var playableActorDelegate: PlayableActorDelegate // player is necessity in this engine, even if the player is just a camera
internal val player: ActorHumanoid // currently POSSESSED actor :)
get() = playableActorDelegate!!.actor
get() = playableActorDelegate.actor
var screenZoom = 1.0f
val ZOOM_MAX = 2.0f
@@ -92,24 +92,32 @@ class StateInGame : BasicGameState() {
val KEY_LIGHTMAP_RENDER = Key.F7
val KEY_LIGHTMAP_SMOOTH = Key.F8
// UI aliases
// UI aliases (no pause)
val uiAliases = HashMap<String, UIHandler>()
private val UI_PIE_MENU = "uiPieMenu"
private val UI_QUICK_BAR = "uiQuickBar"
private val UI_INVENTORY_PLAYER = "uiInventoryPlayer"
private val UI_INVENTORY_ANON = "uiInventoryAnon"
private val UI_INVENTORY_CONTAINER = "uiInventoryContainer"
private val UI_VITAL1 = "uiVital1"
private val UI_VITAL2 = "uiVital2"
private val UI_VITAL3 = "uiVital3"
private val UI_CONSOLE = "uiConsole"
// UI aliases (pause)
val uiAlasesPausing = HashMap<String, UIHandler>()
var paused: Boolean = false
get() = consoleHandler.isOpened
get() = uiAlasesPausing.map { if (it.value.isOpened) 1 else 0 }.sum() > 0
/**
* Set to false if UI is opened; set to true if UI is closed.
*/
var canPlayerMove: Boolean = false
get() = !paused // FIXME temporary behab (block movement if the game is paused or paused by UIs)
@Throws(SlickException::class)
override fun init(gameContainer: GameContainer, stateBasedGame: StateBasedGame) {
// state init code. Executed before the game goes into any "state" in states in StateBasedGame.java
Terrarum.gameStarted = true
}
override fun enter(gc: GameContainer, sbg: StateBasedGame) {
@@ -145,6 +153,8 @@ class StateInGame : BasicGameState() {
// init console window
consoleHandler = UIHandler(ConsoleWindow())
consoleHandler.setPosition(0, 0)
uiAlasesPausing[UI_CONSOLE] = consoleHandler
// init debug window
debugWindow = UIHandler(BasicDebugInfoWindow())
@@ -161,8 +171,18 @@ class StateInGame : BasicGameState() {
// queue up game UIs
// lesser UIs
// >- queue up game UIs that should pause the world -<
// inventory
uiAlasesPausing[UI_INVENTORY_PLAYER] = UIHandler(
UIInventory(player, 800, Terrarum.HEIGHT - 160),
toggleKey = Terrarum.getConfigInt("keyinventory")
)
uiAlasesPausing[UI_INVENTORY_PLAYER]!!.setPosition(
-uiAlasesPausing[UI_INVENTORY_PLAYER]!!.UI.width,
70
)
// >- lesser UIs -<
// quick bar
uiAliases[UI_QUICK_BAR] = UIHandler(UIQuickBar())
uiAliases[UI_QUICK_BAR]!!.isVisible = true
@@ -187,6 +207,9 @@ class StateInGame : BasicGameState() {
// batch-process uiAliases
uiAlasesPausing.forEach { _, uiHandler ->
uiContainer.add(uiHandler) // put them all to the UIContainer
}
uiAliases.forEach { _, uiHandler ->
uiContainer.add(uiHandler) // put them all to the UIContainer
}
@@ -208,6 +231,10 @@ class StateInGame : BasicGameState() {
setAppTitle()
KeyToggler.update(gc.input)
GameController.processInput(gc, delta, gc.input)
if (!paused) {
///////////////////////////
@@ -229,7 +256,6 @@ class StateInGame : BasicGameState() {
///////////////////////////
// input-related updates //
///////////////////////////
GameController.processInput(gc, delta, gc.input)
uiContainer.forEach { it.processInput(gc, delta, gc.input) }
@@ -261,7 +287,6 @@ class StateInGame : BasicGameState() {
// ui-related updates //
////////////////////////
uiContainer.forEach { it.update(gc, delta) }
consoleHandler.update(gc, delta)
debugWindow.update(gc, delta)
notifier.update(gc, delta)
@@ -272,6 +297,7 @@ class StateInGame : BasicGameState() {
}
/////////////////////////
// app-related updates //
/////////////////////////
@@ -311,10 +337,10 @@ class StateInGame : BasicGameState() {
}
// take care of old delegate
playableActorDelegate!!.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE
playableActorDelegate.actor.collisionType = HumanoidNPC.DEFAULT_COLLISION_TYPE
// accept new delegate
playableActorDelegate = PlayableActorDelegate(getActorByID(refid) as ActorHumanoid)
playableActorDelegate!!.actor.collisionType = ActorWithSprite.COLLISION_KINEMATIC
playableActorDelegate.actor.collisionType = ActorWithSprite.COLLISION_KINEMATIC
WorldSimulator(player, UPDATE_DELTA)
}
@@ -327,6 +353,8 @@ class StateInGame : BasicGameState() {
}
override fun render(gc: GameContainer, sbg: StateBasedGame, gwin: Graphics) {
Terrarum.GLOBAL_RENDER_TIMER += 1
// clean the shit beforehand
worldG.clear()
uiG.clear()
@@ -447,8 +475,9 @@ class StateInGame : BasicGameState() {
//////////////
// draw UIs //
//////////////
uiContainer.forEach { it.render(gc, sbg, uiG) }
uiContainer.forEach { if (it != consoleHandler) it.render(gc, sbg, uiG) }
debugWindow.render(gc, sbg, uiG)
// make sure console draws on top of other UIs
consoleHandler.render(gc, sbg, uiG)
notifier.render(gc, sbg, uiG)
@@ -468,8 +497,19 @@ class StateInGame : BasicGameState() {
}
override fun keyPressed(key: Int, c: Char) {
if (key == Key.GRAVE) {
consoleHandler.toggleOpening()
}
else if (key == Key.F3) {
debugWindow.toggleOpening()
}
GameController.keyPressed(key, c)
if (canPlayerMove) {
player.keyPressed(key, c)
}
if (Terrarum.getConfigIntArray("keyquickselalt").contains(key)
|| key == Terrarum.getConfigInt("keyquicksel")) {
uiAliases[UI_PIE_MENU]!!.setAsOpen()
@@ -653,7 +693,7 @@ class StateInGame : BasicGameState() {
/**
* actorContainer extensions
*/
fun theGameHasActor(actor: Actor) = theGameHasActor(actor.referenceID)
fun theGameHasActor(actor: Actor?) = if (actor == null) false else theGameHasActor(actor.referenceID)
fun theGameHasActor(ID: Int): Boolean =
isActive(ID) || isInactive(ID)

View File

@@ -63,6 +63,11 @@ object Terrarum : StateBasedGame(GAME_NAME) {
*/
val TARGET_INTERNAL_FPS = 100
/**
* For the events depends on rendering frame (e.g. flicker on post-hit invincibility)
*/
var GLOBAL_RENDER_TIMER = Random().nextInt(1020) + 1
@@ -78,8 +83,6 @@ object Terrarum : StateBasedGame(GAME_NAME) {
lateinit var appgc: AppGameContainer
var gameStarted = false
var ingame: StateInGame? = null
private val gameConfig = GameConfig()
@@ -650,6 +653,6 @@ operator fun Color.minus(other: Color) = Color(
this.a - other.a
)
fun Int.toHex() = this.toString(16)
fun Int.toHex() = this.toLong().and(0xFFFFFFFF).toString(16).padStart(8, '0').toUpperCase()

View File

@@ -4,7 +4,6 @@ import com.jme3.math.FastMath
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gamecontroller.EnumKeyFunc
import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.realestate.RealEstateUtility
import org.newdawn.slick.GameContainer
@@ -20,6 +19,9 @@ import java.util.*
open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
: HistoricalFigure(birth, death), Controllable, Pocketed, Factionable, Luminous, LandHolder {
var vehicleRiding: Controllable? = null // usually player only
/** Must be set by PlayerFactory */
override var inventory: ActorInventory = ActorInventory()
override val itemEquipped = Array<InventoryItem?>(InventoryItem.EquipPosition.INDEX_MAX + 1, { null })
@@ -144,6 +146,13 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
override fun update(gc: GameContainer, delta: Int) {
super.update(gc, delta)
if (vehicleRiding is Player)
throw Error("Attempted to 'ride' player object. ($vehicleRiding)")
if (vehicleRiding != null && (vehicleRiding == this))
throw Error("Attempted to 'ride' itself. ($vehicleRiding)")
// don't put this into keyPressed; execution order is important!
updateGamerControlBox(gc.input)
@@ -196,11 +205,11 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
private fun updateGamerControlBox(input: Input) {
if (isGamer) {
isUpDown = isFuncDown(input, EnumKeyFunc.MOVE_UP)
isLeftDown = isFuncDown(input, EnumKeyFunc.MOVE_LEFT)
isDownDown = isFuncDown(input, EnumKeyFunc.MOVE_DOWN)
isRightDown = isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)
isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP)
isUpDown = input.isKeyDown(Terrarum.getConfigInt("keyup"))
isLeftDown = input.isKeyDown(Terrarum.getConfigInt("keyleft"))
isDownDown = input.isKeyDown(Terrarum.getConfigInt("keydown"))
isRightDown = input.isKeyDown(Terrarum.getConfigInt("keyright"))
isJumpDown = input.isKeyDown(Terrarum.getConfigInt("keyjump"))
if (Terrarum.controller != null) {
axisX = Terrarum.controller!!.getAxisValue(Terrarum.getConfigInt("joypadlstickx"))
@@ -214,7 +223,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0f
if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0f
isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP) ||
isJumpDown = input.isKeyDown(Terrarum.getConfigInt("keyjump")) ||
Terrarum.controller!!.isButtonPressed(GAMEPAD_JUMP)
}
}
@@ -233,12 +242,12 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* Primary Use
*/
// Left mouse
if (isGamer && isFuncDown(input, EnumKeyFunc.HAND_PRIMARY)) {
if (isGamer && input.isKeyDown(Terrarum.getConfigInt("mouseprimary"))) {
(itemEquipped[InventoryItem.EquipPosition.HAND_GRIP] ?: nullItem).primaryUse(gc, delta)
}
// Right mouse
if (isGamer && isFuncDown(input, EnumKeyFunc.HAND_SECONDARY)) {
if (isGamer && input.isKeyDown(Terrarum.getConfigInt("mouseprimary"))) {
(itemEquipped[InventoryItem.EquipPosition.HAND_GRIP] ?: nullItem).secondaryUse(gc, delta)
}
@@ -282,11 +291,11 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
// ↑F, ↓S
if (isRightDown && !isLeftDown) {
walkHorizontal(false, AXIS_KEYBOARD)
prevHMoveKey = KeyMap[EnumKeyFunc.MOVE_RIGHT]
prevHMoveKey = Terrarum.getConfigInt("keyright")
} // ↓F, ↑S
else if (isLeftDown && !isRightDown) {
walkHorizontal(true, AXIS_KEYBOARD)
prevHMoveKey = KeyMap[EnumKeyFunc.MOVE_LEFT]
prevHMoveKey = Terrarum.getConfigInt("keyleft")
} // ↓F, ↓S
/*else if (isLeftDown && isRightDown) {
if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) {
@@ -310,11 +319,11 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
// ↑E, ↓D
if (isDownDown && !isUpDown) {
walkVertical(false, AXIS_KEYBOARD)
prevVMoveKey = KeyMap[EnumKeyFunc.MOVE_DOWN]
prevVMoveKey = Terrarum.getConfigInt("keydown")
} // ↓E, ↑D
else if (isUpDown && !isDownDown) {
walkVertical(true, AXIS_KEYBOARD)
prevVMoveKey = KeyMap[EnumKeyFunc.MOVE_UP]
prevVMoveKey = Terrarum.getConfigInt("keyup")
} // ↓E, ↓D
/*else if (isUpDown && isDownDown) {
if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) {
@@ -488,13 +497,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
}
}
private fun isFuncDown(input: Input, fn: EnumKeyFunc): Boolean {
return if (fn == EnumKeyFunc.HAND_PRIMARY || fn == EnumKeyFunc.HAND_SECONDARY)
input.isMouseButtonDown(KeyMap[fn])
else
input.isKeyDown(KeyMap[fn])
}
fun isNoClip(): Boolean {
return noClip
}

View File

@@ -58,7 +58,6 @@ class ActorInventory() {
if (item.id == Player.PLAYER_REF_ID)
throw IllegalArgumentException("Attempted to put human player into the inventory.")
if (Terrarum.ingame != null &&
Terrarum.ingame!!.playableActorDelegate != null &&
item.id == Terrarum.ingame!!.player.referenceID)
throw IllegalArgumentException("Attempted to put active player into the inventory.")

View File

@@ -1,20 +1,7 @@
package net.torvald.terrarum.gameactors
import com.jme3.math.FastMath
import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gamecontroller.EnumKeyFunc
import net.torvald.terrarum.gamecontroller.KeyMap
import net.torvald.terrarum.mapdrawer.FeaturesDrawer
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.ui.UIQuickBar
import org.dyn4j.geometry.Vector2
import org.lwjgl.input.Controller
import org.lwjgl.input.Controllers
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input
import org.newdawn.slick.SlickException
import java.util.*
/**
* Game player (YOU!)
@@ -24,8 +11,6 @@ import java.util.*
class Player(born: GameDate) : ActorHumanoid(born) {
var vehicleRiding: Controllable? = null
internal val quickBarRegistration = IntArray(UIQuickBar.SLOT_COUNT, { -1 })
companion object {
@@ -46,11 +31,6 @@ class Player(born: GameDate) : ActorHumanoid(born) {
}
override fun update(gc: GameContainer, delta: Int) {
if (vehicleRiding is Player)
throw Error("Attempted to 'ride' player object. ($vehicleRiding)")
if (vehicleRiding != null && (vehicleRiding == this))
throw Error("Attempted to 'ride' itself. ($vehicleRiding)")
super.update(gc, delta)
}

View File

@@ -1,12 +1,9 @@
package net.torvald.terrarum.gamecontroller
import net.torvald.terrarum.gameactors.Controllable
import net.torvald.terrarum.gameactors.Player
import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.mapdrawer.FeaturesDrawer
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ProjectileSimple
import net.torvald.terrarum.gameactors.floorInt
import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.mapdrawer.MapCamera
import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.tileproperties.TileCodex
@@ -24,37 +21,42 @@ object GameController {
// e.g. gc.mouseTileX
/** position of the mouse (pixelwise) relative to the world (also, currently pointing world-wise coordinate, if the world coordinate is pixel-wise) */
internal val mouseX: Float
val mouseX: Float
get() = (MapCamera.x + Terrarum.appgc.input.mouseX / (Terrarum.ingame?.screenZoom ?: 1f))
/** position of the mouse (pixelwise) relative to the world (also, currently pointing world-wise coordinate, if the world coordinate is pixel-wise)*/
internal val mouseY: Float
val mouseY: Float
get() = (MapCamera.y + Terrarum.appgc.input.mouseY / (Terrarum.ingame?.screenZoom ?: 1f))
/** currently pointing tile coordinate */
internal val mouseTileX: Int
val mouseTileX: Int
get() = (mouseX / FeaturesDrawer.TILE_SIZE).floorInt()
/** currently pointing tile coordinate */
internal val mouseTileY: Int
val mouseTileY: Int
get() = (mouseY / FeaturesDrawer.TILE_SIZE).floorInt()
fun processInput(gc: GameContainer, delta: Int, input: Input) {
KeyToggler.update(input)
if (Terrarum.ingame != null) {
val ingame = Terrarum.ingame!!
if (!ingame.consoleHandler.isTakingControl) {
if (ingame.player is Player && (ingame.player as Player).vehicleRiding != null) {
(ingame.player as Player).vehicleRiding!!.processInput(gc, delta, input)
if (ingame.canPlayerMove) {
ingame.actorContainer.forEach {
if (it is Controllable) {
// disable control of actor if the actor is riding something?
if ((it as ActorHumanoid).vehicleRiding != null) {
it.vehicleRiding!!.processInput(gc, delta, input)
}
else {
it.processInput(gc, delta, input)
}
}
}
}
ingame.actorContainer.forEach {
if (it is Controllable) it.processInput(gc, delta, input)
}
ingame.uiContainer.forEach {
it.processInput(gc, delta, input)
else {
ingame.uiContainer.forEach {
it.processInput(gc, delta, input)
}
}
}
else {
@@ -75,33 +77,7 @@ object GameController {
}
fun keyPressed(key: Int, c: Char) {
if (Terrarum.ingame != null) {
val ingame = Terrarum.ingame!!
if (keyPressedByCode(key, EnumKeyFunc.UI_CONSOLE)) {
ingame.consoleHandler.toggleOpening()
}
else if (keyPressedByCode(key, EnumKeyFunc.UI_BASIC_INFO)) {
ingame.debugWindow.toggleOpening()
}
if (!ingame.consoleHandler.isTakingControl) {
if (ingame.player is Player && (ingame.player as Player).vehicleRiding != null) {
(ingame.player as Player).vehicleRiding!!.keyPressed(key, c)
}
ingame.player.keyPressed(key, c)
}
else {
ingame.consoleHandler.keyPressed(key, c)
}
//System.out.println(String.valueOf(key) + ", " + String.valueOf(c));
}
}
fun keyReleased(key: Int, c: Char) {
@@ -117,14 +93,7 @@ object GameController {
}
fun mousePressed(button: Int, x: Int, y: Int) {
// bullet test
/*if (button == 0) {
Terrarum.ingame!!.addActor(ProjectileSimple(
0,
Terrarum.ingame!!.player.centrePosVector,
Vector2(mouseX.toDouble(), mouseY.toDouble())
))
}*/
}
fun mouseReleased(button: Int, x: Int, y: Int) {
@@ -142,10 +111,6 @@ object GameController {
fun controllerButtonReleased(controller: Int, button: Int) {
}
private fun keyPressedByCode(key: Int, fn: EnumKeyFunc): Boolean {
return KeyMap[fn] == key
}
}
/** position of the mouse (pixelwise) relative to the world (also, currently pointing world-wise coordinate, if the world coordinate is pixel-wise) */

View File

@@ -1,33 +0,0 @@
package net.torvald.terrarum.gamecontroller
import net.torvald.terrarum.Terrarum
import java.util.Hashtable
/**
* Created by minjaesong on 15-12-31.
*/
object KeyMap {
var map_code = Hashtable<EnumKeyFunc, Int>()
init {
map_code.put(EnumKeyFunc.MOVE_UP, Terrarum.getConfigInt("keyup"))
map_code.put(EnumKeyFunc.MOVE_LEFT, Terrarum.getConfigInt("keyleft"))
map_code.put(EnumKeyFunc.MOVE_DOWN, Terrarum.getConfigInt("keydown"))
map_code.put(EnumKeyFunc.MOVE_RIGHT, Terrarum.getConfigInt("keyright"))
map_code.put(EnumKeyFunc.JUMP, Terrarum.getConfigInt("keyjump"))
map_code.put(EnumKeyFunc.UI_CONSOLE, Key.GRAVE)
map_code.put(EnumKeyFunc.UI_BASIC_INFO, Key.F3)
map_code.put(EnumKeyFunc.HAND_PRIMARY, Terrarum.getConfigInt("mousePrimary"))
map_code.put(EnumKeyFunc.HAND_SECONDARY, Terrarum.getConfigInt("mouseSecondary"))
}
operator fun get(fn: EnumKeyFunc): Int {
return map_code[fn]!!
}
operator fun set(func: EnumKeyFunc, key: Int) {
map_code.put(func, key)
}
}

View File

@@ -15,27 +15,20 @@ object KeyToggler {
}
fun update(input: Input) {
for (i in 0..255) {
if (input.isKeyDown(i)) {
isPressed[i] = true
}
else {
isPressed[i] = false
}
}
(0..255).forEach {
isPressed[it] = input.isKeyDown(it)
for (i in 0..255) {
if (isPressed[i] && !currentState[i] && !isToggled[i]) {
currentState[i] = true
isToggled[i] = true
if (isPressed[it] && !currentState[it] && !isToggled[it]) {
currentState[it] = true
isToggled[it] = true
}
else if (isPressed[i] && currentState[i] && !isToggled[i]) {
currentState[i] = false
isToggled[i] = true
else if (isPressed[it] && currentState[it] && !isToggled[it]) {
currentState[it] = false
isToggled[it] = true
}
if (!isPressed[i] && isToggled[i]) {
isToggled[i] = false
if (!isPressed[it] && isToggled[it]) {
isToggled[it] = false
}
}
}

View File

@@ -41,11 +41,13 @@ object WorldSimulator {
private val world = Terrarum.ingame!!.world
// TODO future Kotlin feature -- typealias AnyPlayer: HistoricalFigure
operator fun invoke(p: HistoricalFigure, delta: Int) {
updateXFrom = p.hitbox.centeredX.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
updateYFrom = p.hitbox.centeredY.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
updateXTo = updateXFrom + DOUBLE_RADIUS
updateYTo = updateYFrom + DOUBLE_RADIUS
operator fun invoke(p: HistoricalFigure?, delta: Int) {
if (p != null) {
updateXFrom = p.hitbox.centeredX.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
updateYFrom = p.hitbox.centeredY.div(FeaturesDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt()
updateXTo = updateXFrom + DOUBLE_RADIUS
updateYTo = updateYFrom + DOUBLE_RADIUS
}
moveFluids(delta)
displaceFallables(delta)

View File

@@ -57,6 +57,9 @@ object TilePropUtil {
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
}
/**
* Using our own timer so that they flickers for same duration regardless of game's FPS
*/
internal fun dynamicLumFuncTickClock() {
// FPS-time compensation
if (Terrarum.appgc.fps > 0) {

View File

@@ -55,11 +55,11 @@ interface UICanvas {
const val OPENCLOSE_GENERIC = 200
fun doOpeningFade(handler: UIHandler?, openCloseTime: Int) {
handler!!.opacity = handler!!.openCloseCounter.toFloat() / openCloseTime
handler!!.opacity = handler.openCloseCounter.toFloat() / openCloseTime
}
fun doClosingFade(handler: UIHandler?, openCloseTime: Int) {
handler!!.opacity = (openCloseTime - handler!!.openCloseCounter.toFloat()) / openCloseTime
handler!!.opacity = (openCloseTime - handler.openCloseCounter.toFloat()) / openCloseTime
}
fun endOpeningFade(handler: UIHandler?) {

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.ui
import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.Terrarum
import com.jme3.math.FastMath
import net.torvald.terrarum.gamecontroller.KeyToggler
import org.lwjgl.opengl.GL11
import org.newdawn.slick.*
import org.newdawn.slick.state.StateBasedGame
@@ -16,7 +17,9 @@ import org.newdawn.slick.state.StateBasedGame
*
* Created by minjaesong on 15-12-31.
*/
class UIHandler(val UI: UICanvas) {
class UIHandler(val UI: UICanvas,
val toggleKey: Int? = null, val toggleButton: Int? = null
) {
// X/Y Position to the game window.
var posX: Int = 0
@@ -62,6 +65,18 @@ class UIHandler(val UI: UICanvas) {
fun update(gc: GameContainer, delta: Int) {
// open/close UI by key pressed
if (toggleKey != null) {
if (KeyToggler.isOn(toggleKey)) {
setAsOpen()
}
else {
setAsClose()
}
}
if (isVisible || alwaysVisible) {
UI.update(gc, delta)
}

View File

@@ -11,18 +11,18 @@ import java.util.*
* Created by SKYHi14 on 2017-03-13.
*/
class UIInventory(
val actor: Pocketed,
var actor: Pocketed?,
override var width: Int,
override var height: Int
) : UICanvas {
val inventory: ActorInventory
get() = actor.inventory
val inventory: ActorInventory?
get() = actor?.inventory
val actorValue: ActorValue
get() = (actor as Actor).actorValue
override var handler: UIHandler? = null
override var openCloseTime: Int = UICanvas.OPENCLOSE_GENERIC
override var openCloseTime: Int = 120
val itemImagePlaceholder = Image("./assets/item_kari_24.tga")
@@ -104,68 +104,68 @@ class UIInventory(
private var oldCatSelect = -1
override fun update(gc: GameContainer, delta: Int) {
Terrarum.gameLocale = "koKR" // hot swap this to test
catButtons.update(gc, delta)
// monitor and check if category selection has been changed
if (oldCatSelect != catButtons.selectedIndex) {
rebuildList = true
}
if (rebuildList) {
val filter = catButtonsToCatIdent[catButtons.selectedButton.labelText]
inventorySortList = ArrayList<InventoryPair>()
// filter items
inventory.forEach {
if (it.item.category == filter || filter == "__all__")
inventorySortList.add(it)
if (actor != null && inventory != null) {
// monitor and check if category selection has been changed
if (oldCatSelect != catButtons.selectedIndex) {
rebuildList = true
}
rebuildList = false
// sort if needed
// test sort by name
inventorySortList.sortBy { it.item.name }
if (rebuildList) {
val filter = catButtonsToCatIdent[catButtons.selectedButton.labelText]
// map sortList to item list
for (k in 0..items.size - 1) {
try {
val sortListItem = inventorySortList[k + itemsScrollOffset]
items[k].item = sortListItem.item
items[k].amount = sortListItem.amount
items[k].itemImage = itemImagePlaceholder
inventorySortList = ArrayList<InventoryPair>()
// set quickslot number
for (qs in 1..QUICKSLOT_MAX) {
if (-sortListItem.item.id == actorValue.getAsInt(AVKey.__PLAYER_QSPREFIX + qs)) {
items[k].quickslot = qs % 10 // 10 -> 0, 1..9 -> 1..9
break
}
else
items[k].quickslot = null
}
// filter items
inventory?.forEach {
if (it.item.category == filter || filter == "__all__")
inventorySortList.add(it)
}
for (eq in 0..actor.itemEquipped.size - 1) {
if (eq < actor.itemEquipped.size) {
if (actor.itemEquipped[eq] == items[k].item) {
items[k].equippedSlot = eq
rebuildList = false
// sort if needed
// test sort by name
inventorySortList.sortBy { it.item.name }
// map sortList to item list
for (k in 0..items.size - 1) {
try {
val sortListItem = inventorySortList[k + itemsScrollOffset]
items[k].item = sortListItem.item
items[k].amount = sortListItem.amount
items[k].itemImage = itemImagePlaceholder
// set quickslot number
for (qs in 1..QUICKSLOT_MAX) {
if (-sortListItem.item.id == actorValue.getAsInt(AVKey.__PLAYER_QSPREFIX + qs)) {
items[k].quickslot = qs % 10 // 10 -> 0, 1..9 -> 1..9
break
}
else
items[k].equippedSlot = null
items[k].quickslot = null
}
for (eq in 0..actor!!.itemEquipped.size - 1) {
if (eq < actor!!.itemEquipped.size) {
if (actor!!.itemEquipped[eq] == items[k].item) {
items[k].equippedSlot = eq
break
}
else
items[k].equippedSlot = null
}
}
}
}
catch (e: IndexOutOfBoundsException) {
items[k].item = null
items[k].amount = 0
items[k].itemImage = null
items[k].quickslot = null
catch (e: IndexOutOfBoundsException) {
items[k].item = null
items[k].amount = 0
items[k].itemImage = null
items[k].quickslot = null
}
}
}
}
@@ -190,18 +190,26 @@ class UIInventory(
}
override fun doOpening(gc: GameContainer, delta: Int) {
UICanvas.doOpeningFade(handler, openCloseTime)
handler!!.posX = Movement.fastPullOut(
handler!!.openCloseCounter.toFloat() / openCloseTime,
-width.toFloat(),
0f
).roundInt()
}
override fun doClosing(gc: GameContainer, delta: Int) {
UICanvas.doClosingFade(handler, openCloseTime)
handler!!.posX = Movement.fastPullOut(
handler!!.openCloseCounter.toFloat() / openCloseTime,
0f,
-width.toFloat()
).roundInt()
}
override fun endOpening(gc: GameContainer, delta: Int) {
UICanvas.endOpeningFade(handler)
handler!!.posX = 0
}
override fun endClosing(gc: GameContainer, delta: Int) {
UICanvas.endClosingFade(handler)
handler!!.posX = -width
}
}

View File

@@ -13,7 +13,7 @@ import org.newdawn.slick.Input
class UIQuickBar : UICanvas, MouseControlled {
private val gutter = 8
override var width: Int = (ItemSlotImageBuilder.slotImageSize + gutter) * SLOT_COUNT
override var height: Int = ItemSlotImageBuilder.slotImageSize + 4 + Terrarum.fontGame!!.lineHeight
override var height: Int = ItemSlotImageBuilder.slotImageSize + 4 + Terrarum.fontGame.lineHeight
/**
* In milliseconds
*/
@@ -84,7 +84,7 @@ class UIQuickBar : UICanvas, MouseControlled {
}
override fun mouseWheelMoved(change: Int) {
selection = selection.plus(if (change > 1) 1 else if (change < -1) -1 else 0).mod(SLOT_COUNT)
selection = selection.plus(if (change > 1) 1 else if (change < -1) -1 else 0).rem(SLOT_COUNT)
if (selection < 0) selection += SLOT_COUNT
}

View File

@@ -14,7 +14,7 @@ import org.newdawn.slick.Input
* Created by SKYHi14 on 2017-03-03.
*/
class UIVitalMetre(
var player: ActorHumanoid,
var player: ActorHumanoid?,
var vitalGetterVal: () -> Float?,
var vitalGetterMax: () -> Float?,
var color: Color?,
@@ -25,13 +25,13 @@ class UIVitalMetre(
private val gap = 4f
override var width: Int = 80 + 2 * margin; set(value) { throw Error("operation not permitted") }
override var height: Int; get() = player.baseHitboxH * 3 + margin; set(value) { throw Error("operation not permitted") }
override var height: Int; get() = player?.baseHitboxH ?: 0 * 3 + margin; set(value) { throw Error("operation not permitted") }
override var handler: UIHandler? = null
override var openCloseTime: Int = 50
private val relativePX = width / 2f
private val relativePY: Float; get() = player.baseHitboxH * 1.5f
private val circleRadius: Float; get() = player.baseHitboxH * 3f
private val relativePY: Float; get() = (player?.baseHitboxH ?: 0) * 1.5f
private val circleRadius: Float; get() = (player?.baseHitboxH ?: 0) * 3f
private val theta = 33f
private val halfTheta = theta / 2f

View File

@@ -75,7 +75,7 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
* return value is there for chaining only.
*/
fun VDPath.dropMount(): VDPath {
if (this.hierarchy.size >= 2 && this[0].toCanonicalString() == "media") {
if (this.hierarchy.size >= 2 && this[0].toCanonicalString(sysCharset) == "media") {
this.hierarchy.removeAt(0) // drop "media"
this.hierarchy.removeAt(0) // drop whatever mount symbol
}
@@ -105,7 +105,7 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
fun TerrarumComputer.getTargetDisk(path: VDPath) : VirtualDisk? {
if (path.hierarchy.size >= 2 &&
Arrays.equals(path[0], "media".toEntryName(DiskEntry.NAME_LENGTH, sysCharset))) {
val diskName = path[1].toCanonicalString()
val diskName = path[1].toCanonicalString(sysCharset)
val disk = this.diskRack[diskName]
return disk
@@ -149,8 +149,9 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
val table = LuaTable()
try {
val directoryContents = computer.getDirectoryEntries(path)!!
println("[Filesystem] directoryContents size: ${directoryContents.size}")
directoryContents.forEachIndexed { index, diskEntry ->
table.insert(index + 1, LuaValue.valueOf(diskEntry.filename.toCanonicalString()))
table.insert(index + 1, LuaValue.valueOf(diskEntry.filename.toCanonicalString(sysCharset)))
}
}
catch (e: KotlinNullPointerException) {}
@@ -219,8 +220,22 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
return tryBool {
val path = VDPath(path.checkPath(), sysCharset)
val disk = computer.getTargetDisk(path)!!
val dirList = computer.getDirectoryEntries(path.getParent())
var makeNew = true
VDUtil.addDir(disk, path.getParent(), path.last())
// check dupes
if (dirList != null) {
for (entry in dirList) {
if (Arrays.equals(path.last(), entry.filename)) {
makeNew = false
break
}
}
}
if (makeNew) {
VDUtil.addDir(disk, path.getParent(), path.last())
}
}
}
}
@@ -497,17 +512,3 @@ internal class Filesystem(globals: Globals, computer: TerrarumComputer) {
}
}
}
/**
* drops appended NULs and return resulting ByteArray as String
*/
private fun ByteArray.toCanonicalString(): String {
var lastIndexOfRealStr = 0
for (i in this.lastIndex downTo 0) {
if (this[i] != 0.toByte()) {
lastIndexOfRealStr = i
break
}
}
return String(this.sliceArray(0..lastIndexOfRealStr))
}

View File

@@ -24,7 +24,7 @@ class WorldInformationProvider(globals: Globals) {
companion object {
fun getWorldTimeInLuaFormat() : LuaTable {
val t = LuaTable()
val time = if (Terrarum.gameStarted) Terrarum.ingame!!.world.time else WorldTime()
val time = if (Terrarum.ingame != null) Terrarum.ingame!!.world.time else WorldTime()
// int Terrarum World Time format
t["hour"] = time.hours
@@ -43,7 +43,7 @@ class WorldInformationProvider(globals: Globals) {
/** evaluate single C date format */
fun String.evalAsDate(): String {
val time = if (Terrarum.gameStarted) Terrarum.ingame!!.world.time else WorldTime()
val time = if (Terrarum.ingame != null) Terrarum.ingame!!.world.time else WorldTime()
return when (this) {
"%a" -> time.getDayNameShort()
"%A" -> time.getDayNameFull()

View File

@@ -56,12 +56,12 @@ object VDUtil {
override fun toString(): String {
val sb = StringBuilder()
if (hierarchy.size > 0) {
sb.append(hierarchy[0].toCanonicalString())
sb.append(hierarchy[0].toCanonicalString(Charsets.UTF_8))
}
if (hierarchy.size > 1) {
(1..hierarchy.lastIndex).forEach {
sb.append('/')
sb.append(hierarchy[it].toCanonicalString())
sb.append(hierarchy[it].toCanonicalString(Charsets.UTF_8))
}
}
@@ -209,12 +209,12 @@ object VDUtil {
/**
* Get list of entries of directory.
*/
fun getDirectoryEntries(disk: VirtualDisk, entry: DiskEntry): Array<DiskEntry> {
if (entry.contents !is EntryDirectory)
fun getDirectoryEntries(disk: VirtualDisk, dirToSearch: DiskEntry): Array<DiskEntry> {
if (dirToSearch.contents !is EntryDirectory)
throw IllegalArgumentException("The entry is not directory")
val entriesList = ArrayList<DiskEntry>()
entry.contents.entries.forEach {
dirToSearch.contents.entries.forEach {
val entry = disk.entries[it]
if (entry != null) entriesList.add(entry)
}
@@ -697,7 +697,7 @@ fun String.toEntryName(length: Int, charset: Charset): ByteArray {
buffer.put(stringByteArray.sliceArray(0..minOf(length, stringByteArray.size) - 1))
return buffer.array
}
fun ByteArray.toCanonicalString(): String {
fun ByteArray.toCanonicalString(charset: Charset): String {
var lastIndexOfRealStr = 0
for (i in this.lastIndex downTo 0) {
if (this[i] != 0.toByte()) {
@@ -705,7 +705,7 @@ fun ByteArray.toCanonicalString(): String {
break
}
}
return String(this.sliceArray(0..lastIndexOfRealStr))
return String(this.sliceArray(0..lastIndexOfRealStr), charset)
}
/**

View File

@@ -102,7 +102,7 @@ class DiskEntry(
// content
val contents: DiskEntryContent
) {
fun getFilenameString(charset: Charset) = if (entryID == 0) ROOTNAME else String(filename, charset)
fun getFilenameString(charset: Charset) = if (entryID == 0) ROOTNAME else filename.toCanonicalString(charset)
val serialisedSize: Int
get() = contents.getSizeEntry() + HEADER_SIZE

View File

@@ -32,10 +32,10 @@ import java.util.*
* Created by minjaesong on 16-07-11.
*/
object WeatherMixer {
lateinit var weatherList: HashMap<String, ArrayList<BaseModularWeather>>
var weatherList: HashMap<String, ArrayList<BaseModularWeather>>
lateinit var currentWeather: BaseModularWeather
lateinit var nextWeather: BaseModularWeather
var currentWeather: BaseModularWeather
var nextWeather: BaseModularWeather
lateinit var mixedWeather: BaseModularWeather