diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index f6494be4c..79ddc34ba 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -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() 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() 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) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 456b3e08c..f4ab7e655 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -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() diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index 116fc1964..a43014901 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -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.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 } diff --git a/src/net/torvald/terrarum/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/gameactors/ActorInventory.kt index fd9b38635..dc60a424d 100644 --- a/src/net/torvald/terrarum/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/gameactors/ActorInventory.kt @@ -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.") diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index 288b4db0f..eb2b33b2b 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -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) } diff --git a/src/net/torvald/terrarum/gamecontroller/GameController.kt b/src/net/torvald/terrarum/gamecontroller/GameController.kt index fa02b3ae4..4028112e5 100644 --- a/src/net/torvald/terrarum/gamecontroller/GameController.kt +++ b/src/net/torvald/terrarum/gamecontroller/GameController.kt @@ -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) */ diff --git a/src/net/torvald/terrarum/gamecontroller/KeyMap.kt b/src/net/torvald/terrarum/gamecontroller/KeyMap.kt deleted file mode 100644 index 01600638c..000000000 --- a/src/net/torvald/terrarum/gamecontroller/KeyMap.kt +++ /dev/null @@ -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() - - 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) - } - -} diff --git a/src/net/torvald/terrarum/gamecontroller/KeyToggler.kt b/src/net/torvald/terrarum/gamecontroller/KeyToggler.kt index ee80671cd..0e5a60fd2 100644 --- a/src/net/torvald/terrarum/gamecontroller/KeyToggler.kt +++ b/src/net/torvald/terrarum/gamecontroller/KeyToggler.kt @@ -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 } } } diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index b3a2e434a..cf2d5fa4e 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -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) diff --git a/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt index 310b6fe94..69ca8a19e 100644 --- a/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt +++ b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt @@ -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) { diff --git a/src/net/torvald/terrarum/ui/UICanvas.kt b/src/net/torvald/terrarum/ui/UICanvas.kt index 880f4ebe0..be3591270 100644 --- a/src/net/torvald/terrarum/ui/UICanvas.kt +++ b/src/net/torvald/terrarum/ui/UICanvas.kt @@ -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?) { diff --git a/src/net/torvald/terrarum/ui/UIHandler.kt b/src/net/torvald/terrarum/ui/UIHandler.kt index 8f19dc362..d87612f29 100644 --- a/src/net/torvald/terrarum/ui/UIHandler.kt +++ b/src/net/torvald/terrarum/ui/UIHandler.kt @@ -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) } diff --git a/src/net/torvald/terrarum/ui/UIInventory.kt b/src/net/torvald/terrarum/ui/UIInventory.kt index 7cc8a7318..c9aed2e25 100644 --- a/src/net/torvald/terrarum/ui/UIInventory.kt +++ b/src/net/torvald/terrarum/ui/UIInventory.kt @@ -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() - - // 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() - // 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 } } diff --git a/src/net/torvald/terrarum/ui/UIQuickBar.kt b/src/net/torvald/terrarum/ui/UIQuickBar.kt index bfca2cdad..fa5399e32 100644 --- a/src/net/torvald/terrarum/ui/UIQuickBar.kt +++ b/src/net/torvald/terrarum/ui/UIQuickBar.kt @@ -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 } diff --git a/src/net/torvald/terrarum/ui/UIVitalMetre.kt b/src/net/torvald/terrarum/ui/UIVitalMetre.kt index 406ece1d7..1ab0e66db 100644 --- a/src/net/torvald/terrarum/ui/UIVitalMetre.kt +++ b/src/net/torvald/terrarum/ui/UIVitalMetre.kt @@ -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 diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/FilesystemTEVD.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/FilesystemTEVD.kt index 87edc08af..6ba61f20e 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/FilesystemTEVD.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/FilesystemTEVD.kt @@ -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)) -} diff --git a/src/net/torvald/terrarum/virtualcomputer/luaapi/WorldInformationProvider.kt b/src/net/torvald/terrarum/virtualcomputer/luaapi/WorldInformationProvider.kt index 2fe641682..1dc1d900c 100644 --- a/src/net/torvald/terrarum/virtualcomputer/luaapi/WorldInformationProvider.kt +++ b/src/net/torvald/terrarum/virtualcomputer/luaapi/WorldInformationProvider.kt @@ -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() diff --git a/src/net/torvald/terrarum/virtualcomputer/tvd/VDUtil.kt b/src/net/torvald/terrarum/virtualcomputer/tvd/VDUtil.kt index 2363e3436..273bf7ac8 100644 --- a/src/net/torvald/terrarum/virtualcomputer/tvd/VDUtil.kt +++ b/src/net/torvald/terrarum/virtualcomputer/tvd/VDUtil.kt @@ -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 { - if (entry.contents !is EntryDirectory) + fun getDirectoryEntries(disk: VirtualDisk, dirToSearch: DiskEntry): Array { + if (dirToSearch.contents !is EntryDirectory) throw IllegalArgumentException("The entry is not directory") val entriesList = ArrayList() - 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) } /** diff --git a/src/net/torvald/terrarum/virtualcomputer/tvd/VirtualDisk.kt b/src/net/torvald/terrarum/virtualcomputer/tvd/VirtualDisk.kt index 885f08568..4e1ac2dd6 100644 --- a/src/net/torvald/terrarum/virtualcomputer/tvd/VirtualDisk.kt +++ b/src/net/torvald/terrarum/virtualcomputer/tvd/VirtualDisk.kt @@ -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 diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 0d89202d0..ff1101e4b 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -32,10 +32,10 @@ import java.util.* * Created by minjaesong on 16-07-11. */ object WeatherMixer { - lateinit var weatherList: HashMap> + var weatherList: HashMap> - lateinit var currentWeather: BaseModularWeather - lateinit var nextWeather: BaseModularWeather + var currentWeather: BaseModularWeather + var nextWeather: BaseModularWeather lateinit var mixedWeather: BaseModularWeather