diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index ed83c048a..fc213576e 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -58,7 +58,9 @@ constructor() : BasicGameState() { lateinit var debugWindow: UIHandler lateinit var notifier: UIHandler - lateinit internal var player: Player + lateinit internal var playerWrapper: AnyPlayer + internal val player: HistoricalFigure // currently POSSESSED actor :) + get() = playerWrapper.actor //private var GRADIENT_IMAGE: Image? = null //private var skyBox: Rectangle? = null @@ -119,7 +121,7 @@ constructor() : BasicGameState() { // add new player and put it to actorContainer - player = PBSigrid.create() + playerWrapper = AnyPlayer(PBSigrid.create()) //player = PBCynthia.create() //player.setNoClip(true); addActor(player) @@ -199,6 +201,8 @@ constructor() : BasicGameState() { /////////////////////////// // actor-related updates // /////////////////////////// + repossessActor() + // determine whether the inactive actor should be re-active wakeDormantActors() // determine whether the actor should be active or dormant @@ -226,6 +230,31 @@ constructor() : BasicGameState() { Terrarum.gameConfig["smoothlighting"] = KeyToggler.isOn(KEY_LIGHTMAP_SMOOTH) } + private fun repossessActor() { + // check if currently pocessed actor is removed from game + if (!hasActor(player)) + // re-possess canonical player + changePossession(Player.PLAYER_REF_ID) // TODO completely other behaviour? + } + + private fun changePossession(newActor: AnyPlayer) { + if (!hasActor(player)) { + throw IllegalArgumentException("No such actor in actorContainer: $newActor") + } + + playerWrapper = newActor + WorldSimulator(world, player, UPDATE_DELTA) + } + + private fun changePossession(refid: Int) { + if (!hasActor(refid)) { + throw IllegalArgumentException("No such actor in actorContainer: $refid") + } + + playerWrapper = AnyPlayer(getActorByID(refid) as HistoricalFigure) + WorldSimulator(world, player, UPDATE_DELTA) + } + private fun setAppTitle() { Terrarum.appgc.setTitle( "${Terrarum.NAME}" + @@ -319,7 +348,7 @@ constructor() : BasicGameState() { } // fluidmap debug if (KeyToggler.isOn(Key.F4)) - WorldSimulator.drawFluidMapDebug(player, g) + WorldSimulator.drawFluidMapDebug(g) ////////////// @@ -482,7 +511,7 @@ constructor() : BasicGameState() { fun Double.sqr() = this * this fun Int.sqr() = this * this - private fun distToActorSqr(a: Visible, p: Player): Double = + private fun distToActorSqr(a: Visible, p: ActorWithBody): Double = (a.hitbox.centeredX - p.hitbox.centeredX).sqr() + (a.hitbox.centeredY - p.hitbox.centeredY).sqr() /** whether the actor is within screen */ private fun Visible.inScreen() = distToActorSqr(this, player) <= diff --git a/src/net/torvald/terrarum/gameactors/AIControlled.kt b/src/net/torvald/terrarum/gameactors/AIControlled.kt index c39a7fb5e..27792ee7d 100644 --- a/src/net/torvald/terrarum/gameactors/AIControlled.kt +++ b/src/net/torvald/terrarum/gameactors/AIControlled.kt @@ -3,6 +3,8 @@ package net.torvald.terrarum.gameactors import net.torvald.terrarum.gameactors.ai.ActorAI /** + * Note: AI-controlled actor must be 'Controllable' + * * Created by minjaesong on 16-03-14. */ interface AIControlled { diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 44d256546..a548f8692 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -443,8 +443,7 @@ open class ActorWithBody : Actor(), Visible { else if (moveDelta.y < 0.0) { // or was moving upward? grounded = false if (isTouchingSide(nextHitbox, COLLIDING_TOP)) { // actor hit something on its top - //hitAndForciblyReflectY() - hitAndReflectY() + hitAndForciblyReflectY() // prevents sticking to the ceiling } else { // the actor is not grounded at all } @@ -507,7 +506,9 @@ open class ActorWithBody : Actor(), Visible { } } - @Deprecated("it's no use!") + /** + * prevents sticking to the ceiling + */ private fun hitAndForciblyReflectY() { if (veloY.abs() * CEILING_HIT_ELASTICITY > A_PIXEL) veloY = -veloY * CEILING_HIT_ELASTICITY @@ -965,7 +966,7 @@ open class ActorWithBody : Actor(), Visible { private fun assertInit() { // errors if (baseHitboxW == 0 || baseHitboxH == 0) - throw RuntimeException("Hitbox dimension was not set.") + throw Error("Hitbox dimension was not set.") // warnings if (sprite == null && isVisible) diff --git a/src/net/torvald/terrarum/gameactors/AnyPlayer.kt b/src/net/torvald/terrarum/gameactors/AnyPlayer.kt new file mode 100644 index 000000000..3ea7a7108 --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/AnyPlayer.kt @@ -0,0 +1,23 @@ +package net.torvald.terrarum.gameactors + +import org.newdawn.slick.Input + +/** + * Created by minjaesong on 16-10-23. + */ +class AnyPlayer(val actor: HistoricalFigure) { + + init { + if (actor !is Controllable) + throw IllegalArgumentException("Player must be 'Controllable'!") + } + + fun processInput(input: Input) { + (actor as Controllable).processInput(input) + } + + fun keyPressed(key: Int, c: Char) { + (actor as Controllable).keyPressed(key, c) + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt b/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt index 877f5f33e..9253c2e01 100644 --- a/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt +++ b/src/net/torvald/terrarum/gameactors/HistoricalFigure.kt @@ -1,14 +1,17 @@ package net.torvald.terrarum.gameactors import net.torvald.terrarum.gameworld.WorldTime +import org.newdawn.slick.Input /** * An actor (NPC) which has life and death, * though death might not exist if it has achieved immortality :) * + * NOTE: all canonical NPCs are must be HistoricalFigure!! (double excl mark, bitch) + * * Created by minjaesong on 16-10-10. */ -open class HistoricalFigure(born: GameDate, dead: GameDate? = null) : ActorWithBody() { +open class HistoricalFigure(val born: GameDate, val dead: GameDate? = null) : ActorWithBody(), Controllable { init { this.actorValue["_bornyear"] = born.year @@ -20,6 +23,21 @@ open class HistoricalFigure(born: GameDate, dead: GameDate? = null) : ActorWithB } } + override fun processInput(input: Input) { + // let out children play + } + + override fun keyPressed(key: Int, c: Char) { + // let out children play + } + + open internal var noClip = false + + open fun isNoClip() = noClip + + open fun setNoClip(b: Boolean) { + noClip = b + } } data class GameDate(val year: Int, val yearlyDay: Int) { diff --git a/src/net/torvald/terrarum/gameactors/PBSigrid.kt b/src/net/torvald/terrarum/gameactors/PBSigrid.kt index 0bb5ae414..8e6667274 100644 --- a/src/net/torvald/terrarum/gameactors/PBSigrid.kt +++ b/src/net/torvald/terrarum/gameactors/PBSigrid.kt @@ -46,7 +46,7 @@ object PBSigrid { * fixed value, or 'base value', from creature strength of Dwarf Fortress. * Human race uses 1000. (see CreatureHuman.json) */ - p.actorValue[AVKey.STRENGTH] = 1414 + p.actorValue[AVKey.STRENGTH] = 1414 // this is test character, after all. p.actorValue[AVKey.ENCUMBRANCE] = 1000 p.actorValue[AVKey.BASEHEIGHT] = 46 @@ -59,8 +59,8 @@ object PBSigrid { p.actorValue[AVKey.BASEDEFENCE] = 141 p.actorValue[AVKey.__PLAYER_QUICKBARSEL] = 0 - p.actorValue["__selectedtile"] = 16 // test code; replace with .primaryUse(gc, delta) - p.actorValue["__aimhelper"] = true + p.actorValue["__selectedtile"] = 147 // test code; replace with .primaryUse(gc, delta) + p.actorValue["__aimhelper"] = true // TODO when you'll gonna implement it? p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 10, 0) diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index 79c323274..8a1b6d1d1 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -16,6 +16,8 @@ import org.newdawn.slick.SlickException import java.util.* /** + * Game player (YOU!) + * * Created by minjaesong on 16-03-14. */ @@ -53,7 +55,7 @@ class Player(born: GameDate) : HistoricalFigure(born), Controllable, Pocketed, F @Transient private var prevHMoveKey = KEY_NULL @Transient private var prevVMoveKey = KEY_NULL - internal var noClip = false + override internal var noClip = false @Transient private val AXIS_POSMAX = 1.0f @Transient private val GAMEPAD_JUMP = 7 @@ -491,11 +493,11 @@ class Player(born: GameDate) : HistoricalFigure(born), Controllable, Pocketed, F } } - fun isNoClip(): Boolean { + override fun isNoClip(): Boolean { return noClip } - fun setNoClip(b: Boolean) { + override fun setNoClip(b: Boolean) { noClip = b } diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilder.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilder.kt index 77f6161ad..eba8c93cb 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilder.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilder.kt @@ -11,9 +11,8 @@ object PlayerBuilder { private val JSONPATH = "./assets/raw/" private val jsonString = String() - @Throws(IOException::class, SlickException::class) - fun create(): Player { - val p: Player = Player(Terrarum.ingame.world.time.currentTimeAsGameDate) + fun create(): Actor { + val p: Actor = Player(Terrarum.ingame.world.time.currentTimeAsGameDate) CreatureRawInjector.inject(p.actorValue, "CreatureHuman.json") // attach sprite diff --git a/src/net/torvald/terrarum/gamecontroller/GameController.kt b/src/net/torvald/terrarum/gamecontroller/GameController.kt index 54758a3a2..46b75e131 100644 --- a/src/net/torvald/terrarum/gamecontroller/GameController.kt +++ b/src/net/torvald/terrarum/gamecontroller/GameController.kt @@ -32,8 +32,8 @@ object GameController { if (!Terrarum.ingame.consoleHandler.isTakingControl) { - if (Terrarum.ingame.player.vehicleRiding != null) { - Terrarum.ingame.player.vehicleRiding!!.processInput(input) + if (Terrarum.ingame.player is Player && (Terrarum.ingame.player as Player).vehicleRiding != null) { + (Terrarum.ingame.player as Player).vehicleRiding!!.processInput(input) } Terrarum.ingame.player.processInput(input) @@ -83,8 +83,8 @@ object GameController { if (!Terrarum.ingame.consoleHandler.isTakingControl) { - if (Terrarum.ingame.player.vehicleRiding != null) { - Terrarum.ingame.player.vehicleRiding!!.keyPressed(key, c) + if (Terrarum.ingame.player is Player && (Terrarum.ingame.player as Player).vehicleRiding != null) { + (Terrarum.ingame.player as Player).vehicleRiding!!.keyPressed(key, c) } Terrarum.ingame.player.keyPressed(key, c) diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 0751dea06..431a51b7e 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.gameworld import net.torvald.random.HQRNG import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.gameactors.HistoricalFigure import net.torvald.terrarum.gameactors.Player import net.torvald.terrarum.gameactors.roundInt import net.torvald.terrarum.gameworld.WorldSimulator.isSolid @@ -37,14 +38,15 @@ object WorldSimulator { val colourNone = Color(0x808080) val colourWater = Color(0x66BBFF) - operator fun invoke(world: GameWorld, p: Player, delta: Int) { + // TODO future Kotlin feature -- typealias AnyPlayer: HistoricalFigure + operator fun invoke(world: GameWorld, p: HistoricalFigure, delta: Int) { updateXFrom = p.hitbox.centeredX.div(MapDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt() updateYFrom = p.hitbox.centeredY.div(MapDrawer.TILE_SIZE).minus(FLUID_UPDATING_SQUARE_RADIUS).roundInt() updateXTo = updateXFrom + DOUBLE_RADIUS updateYTo = updateYFrom + DOUBLE_RADIUS - moveFluids(world, p, delta) - displaceFallables(world, p, delta) + moveFluids(world, delta) + displaceFallables(world, delta) } /** @@ -52,7 +54,7 @@ object WorldSimulator { * which means you'll need to modify the code A LOT if you're going to implement zero- or * reverse-gravity. */ - fun moveFluids(world: GameWorld, p: Player, delta: Int) { + fun moveFluids(world: GameWorld, delta: Int) { //////////////////// // build fluidmap // //////////////////// @@ -121,7 +123,7 @@ object WorldSimulator { * displace fallable tiles. It is scanned bottom-left first. To achieve the sens ofreal * falling, each tiles are displaced by ONLY ONE TILE below. */ - fun displaceFallables(world: GameWorld, p: Player, delta: Int) { + fun displaceFallables(world: GameWorld, delta: Int) { for (y in updateYFrom..updateYTo) { for (x in updateXFrom..updateXTo) { val tile = world.getTileFromTerrain(x, y) ?: TileNameCode.STONE @@ -146,7 +148,7 @@ object WorldSimulator { } } - fun drawFluidMapDebug(p: Player, g: Graphics) { + fun drawFluidMapDebug(g: Graphics) { g.font = Terrarum.fontSmallNumbers g.color = colourWater diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 9ed2f5ed7..041335c75 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -100,7 +100,7 @@ class BasicDebugInfoWindow : UICanvas { printLine(g, 5, "grounded $ccG${player.grounded}") printLine(g, 6, "noClip $ccG${player.noClip}") - printLine(g, 7, "jump $ccG${player.jumpAcc}") + //printLine(g, 7, "jump $ccG${player.jumpAcc}") val lightVal: String val mtX = mouseTileX.toString() diff --git a/src/net/torvald/terrarum/ui/UIQuickBar.kt b/src/net/torvald/terrarum/ui/UIQuickBar.kt index 6eb790a15..2bacc54d9 100644 --- a/src/net/torvald/terrarum/ui/UIQuickBar.kt +++ b/src/net/torvald/terrarum/ui/UIQuickBar.kt @@ -24,7 +24,7 @@ class UIQuickBar : UICanvas, MouseControlled { override var handler: UIHandler? = null private var selection: Int - get() = Terrarum.ingame.player.actorValue.getAsInt(AVKey.__PLAYER_QUICKBARSEL)!! + get() = Terrarum.ingame.player.actorValue.getAsInt(AVKey.__PLAYER_QUICKBARSEL) ?: 0 set(value) { Terrarum.ingame.player.actorValue[AVKey.__PLAYER_QUICKBARSEL] = value } override fun update(gc: GameContainer, delta: Int) {