diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index a7288ed97..545e0429b 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -122,7 +122,7 @@ constructor() : BasicGameState() { // add new player and put it to actorContainer - playerWrapper = AnyPlayer(PBSigrid.create()) + playerWrapper = AnyPlayer(PlayerBuilderSigrid.create()) //player = PBCynthia.create() //player.setNoClip(true); addActor(player) diff --git a/src/net/torvald/terrarum/gameactors/AIControlled.kt b/src/net/torvald/terrarum/gameactors/AIControlled.kt index deff1bb25..46310adf9 100644 --- a/src/net/torvald/terrarum/gameactors/AIControlled.kt +++ b/src/net/torvald/terrarum/gameactors/AIControlled.kt @@ -1,12 +1,21 @@ 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. + * Created by minjaesong on 16-01-31. */ interface AIControlled { val scriptPath: String + + fun moveLeft() + fun moveRight() + fun moveUp() + fun moveDown() + fun moveJump() + + /** fly toward arbitrary angle WARNING: the map is looped! */ + fun moveTo(bearing: Double) + /** fly toward arbitrary coord WARNING: the map is looped! */ + fun moveTo(toX: Double, toY: Double) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/console/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt similarity index 81% rename from src/net/torvald/terrarum/console/ActorHumanoid.kt rename to src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index f901d2d91..e9f073b7f 100644 --- a/src/net/torvald/terrarum/console/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -1,4 +1,4 @@ -package net.torvald.terrarum.console +package net.torvald.terrarum.gameactors import com.jme3.math.FastMath import net.torvald.terrarum.Terrarum @@ -120,16 +120,46 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) @Transient private val AXIS_POSMAX = 1.0f @Transient private val GAMEPAD_JUMP = 7 + protected var isUpDown = false + protected var isDownDown = false + protected var isLeftDown = false + protected var isRightDown = false + protected var isJumpDown = false + protected val isGamer: Boolean + get() = this is Player + override fun update(gc: GameContainer, delta: Int) { super.update(gc, delta) + // don't put this into keyPressed; execution order is important! + updateGamerControlBox(gc.input) + updateMovementControl() updateSprite(delta) if (noClip) { grounded = true } + + // reset control box of AI + if (!isGamer) { + isUpDown = false + isDownDown = false + isLeftDown = false + isRightDown = false + isJumpDown = false + } + } + + 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) + } } private fun updateMovementControl() { @@ -145,7 +175,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) } override fun processInput(input: Input) { - if (Terrarum.hasController) { + if (isGamer && Terrarum.hasController) { gamepad = Controllers.getController(0) axisX = gamepad!!.getAxisValue(0) axisY = gamepad!!.getAxisValue(1) @@ -162,29 +192,27 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) /** * L-R stop */ - if (Terrarum.hasController && !isWalkingH) { + if (isGamer && Terrarum.hasController && !isWalkingH) { if (axisX == 0f) { walkHStop() } } // ↑F, ↑S - if (isWalkingH && !isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) { + if (isWalkingH && !isLeftDown && !isRightDown) { walkHStop() prevHMoveKey = KEY_NULL } /** * U-D stop */ - if (Terrarum.hasController) { + if (isGamer && Terrarum.hasController) { if (axisY == 0f) { walkVStop() } } // ↑E // ↑D - if (isNoClip() - && !isFuncDown(input, EnumKeyFunc.MOVE_UP) - && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) { + if (isNoClip() && !isUpDown && !isDownDown) { walkVStop() prevVMoveKey = KEY_NULL } @@ -193,21 +221,21 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * Left/Right movement */ - if (Terrarum.hasController) { + if (isGamer && Terrarum.hasController) { if (axisX != 0f) { walkHorizontal(axisX < 0f, axisX.abs()) } } // ↑F, ↓S - if (isFuncDown(input, EnumKeyFunc.MOVE_RIGHT) && !isFuncDown(input, EnumKeyFunc.MOVE_LEFT)) { + if (isRightDown && !isLeftDown) { walkHorizontal(false, AXIS_POSMAX) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) } // ↓F, ↑S - else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) { + else if (isLeftDown && !isRightDown) { walkHorizontal(true, AXIS_POSMAX) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT) } // ↓F, ↓S - /*else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) { + /*else if (isLeftDown && isRightDown) { if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) { walkHorizontal(false, AXIS_POSMAX) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) @@ -221,21 +249,21 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * Up/Down movement */ if (noClip) { - if (Terrarum.hasController) { + if (isGamer && Terrarum.hasController) { if (axisY != 0f) { walkVertical(axisY < 0, axisY.abs()) } } // ↑E, ↓D - if (isFuncDown(input, EnumKeyFunc.MOVE_DOWN) && !isFuncDown(input, EnumKeyFunc.MOVE_UP)) { + if (isDownDown && !isUpDown) { walkVertical(false, AXIS_POSMAX) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) } // ↓E, ↑D - else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) { + else if (isUpDown && !isDownDown) { walkVertical(true, AXIS_POSMAX) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP) } // ↓E, ↓D - /*else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) { + /*else if (isUpDown && isDownDown) { if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) { walkVertical(false, AXIS_POSMAX) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) @@ -249,7 +277,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) /** * Jump control */ - if (isFuncDown(input, EnumKeyFunc.JUMP) || Terrarum.hasController && gamepad!!.isButtonPressed(GAMEPAD_JUMP)) { + if (isJumpDown || isGamer && Terrarum.hasController && gamepad!!.isButtonPressed(GAMEPAD_JUMP)) { if (!noClip) { if (grounded) { jumping = true @@ -365,53 +393,12 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) // stops; let the friction kick in by doing nothing to the velocity here private fun walkHStop() { - /*if (veloX > 0) { - veloX -= actorValue.getAsDouble(AVKey.ACCEL)!! * - actorValue.getAsDouble(AVKey.ACCELMULT)!! * - Math.sqrt(scale) - - // compensate overshoot - if (veloX < 0) veloX = 0f - } else if (veloX < 0) { - veloX += actorValue.getAsDouble(AVKey.ACCEL)!! * - actorValue.getAsDouble(AVKey.ACCELMULT)!! * - Math.sqrt(scale) - - // compensate overshoot - if (veloX > 0) veloX = 0f - } else { - veloX = 0f - }*/ - - //veloX = 0f - walkCounterX = 0 isWalkingH = false } // stops; let the friction kick in by doing nothing to the velocity here private fun walkVStop() { - /*if (veloY > 0) { - veloY -= WALK_STOP_ACCEL * - actorValue.getAsDouble(AVKey.ACCELMULT)!! * - Math.sqrt(scale) - - // compensate overshoot - if (veloY < 0) - veloY = 0f - } else if (veloY < 0) { - veloY += WALK_STOP_ACCEL * - actorValue.getAsDouble(AVKey.ACCELMULT)!! * - Math.sqrt(scale) - - // compensate overshoot - if (veloY > 0) veloY = 0f - } else { - veloY = 0f - }*/ - - ///veloY = 0f - walkCounterY = 0 isWalkingV = false } @@ -436,27 +423,27 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) } if (jumping) { - // increment jump counter - if (jumpCounter < len) jumpCounter += 1 + if (isGamer) { // jump power increases as the gamer hits JUMP longer time + // increment jump counter + if (jumpCounter < len) jumpCounter += 1 - // linear time mode - val init = (len + 1) / 2.0 - var timedJumpCharge = init - init / len * jumpCounter - if (timedJumpCharge < 0) timedJumpCharge = 0.0 + // linear time mode + val init = (len + 1) / 2.0 + var timedJumpCharge = init - init / len * jumpCounter + if (timedJumpCharge < 0) timedJumpCharge = 0.0 - // one that uses jumpFunc(x) - //val timedJumpCharge = jumpFunc(jumpCounter) + // one that uses jumpFunc(x) + //val timedJumpCharge = jumpFunc(jumpCounter) - jumpAcc = -pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value + jumpAcc = -pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * Math.sqrt(scale) // positive value - applyForce(Vector2(0.0, jumpAcc)) + applyForce(Vector2(0.0, jumpAcc)) + } + else { // no such minute control for AIs + //veloY -= pwr * Math.sqrt(scale) + jumpAcc = -pwr * Math.sqrt(scale) + } } - - // for mob ai: - //super.setVeloY(veloY - // - - // pwr * Math.sqrt(scale) - //); } private fun isFuncDown(input: Input, fn: EnumKeyFunc): Boolean { diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index a548f8692..6cd9c2407 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -51,10 +51,10 @@ open class ActorWithBody : Actor(), Visible { internal val velocity = Vector2(0.0, 0.0) var veloX: Double get() = velocity.x - private set(value) { velocity.x = value } + protected set(value) { velocity.x = value } var veloY: Double get() = velocity.y - private set(value) { velocity.y = value } + protected set(value) { velocity.y = value } val moveDelta = Vector2(0.0, 0.0) @Transient private val VELO_HARD_LIMIT = 100.0 @@ -65,10 +65,10 @@ open class ActorWithBody : Actor(), Visible { var controllerVel: Vector2? = if (this is Controllable) Vector2() else null var walkX: Double get() = controllerVel!!.x - internal set(value) { controllerVel!!.x = value } + protected set(value) { controllerVel!!.x = value } var walkY: Double get() = controllerVel!!.y - internal set(value) { controllerVel!!.y = value } + protected set(value) { controllerVel!!.y = value } /** * Physical properties. diff --git a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt index b4e6d2ec9..23f466b5f 100644 --- a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt @@ -106,6 +106,38 @@ open class HumanoidNPC(aiFile: String, born: GameDate) : ActorHumanoid(born), AI } + override fun moveLeft() { // hit the buttons on the controller box + isLeftDown = true + } + + override fun moveRight() { // hit the buttons on the controller box + isRightDown = true + } + + override fun moveUp() { // hit the buttons on the controller box + isUpDown = true + } + + override fun moveDown() { // hit the buttons on the controller box + isDownDown = true + } + + override fun moveJump() { // hit the buttons on the controller box + isJumpDown = true + } + + /** fly toward arbitrary angle WARNING: the map is looped! */ + override fun moveTo(bearing: Double) { + // if your NPC should fly, override this + throw UnsupportedOperationException("Humans cannot fly :p") + } + + /** fly toward arbitrary coord WARNING: the map is looped! */ + override fun moveTo(toX: Double, toY: Double) { + // if your NPC should fly, override this + throw UnsupportedOperationException("Humans cannot fly :p") + } + var currentExecutionThread = Thread() var threadRun = false diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index c5adf8030..172f798db 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -29,7 +29,7 @@ class Player(born: GameDate) : ActorHumanoid(born) { internal val quickBarRegistration = IntArray(UIQuickBar.SLOT_COUNT, { -1 }) companion object { - @Transient const val PLAYER_REF_ID: Int = 0x51621D + @Transient const val PLAYER_REF_ID: Int = 0x91A7E2 } /** diff --git a/src/net/torvald/terrarum/gameactors/PBCynthia.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt similarity index 97% rename from src/net/torvald/terrarum/gameactors/PBCynthia.kt rename to src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt index a6b26d91a..44647b8b9 100644 --- a/src/net/torvald/terrarum/gameactors/PBCynthia.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt @@ -7,7 +7,7 @@ import net.torvald.terrarum.mapdrawer.MapDrawer /** * Created by minjaesong on 16-03-25. */ -object PBCynthia { +object PlayerBuilderCynthia { fun create(): Player { val p: Player = Player(GameDate(100, 143)) // random value thrown diff --git a/src/net/torvald/terrarum/gameactors/PBSigrid.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt similarity index 96% rename from src/net/torvald/terrarum/gameactors/PBSigrid.kt rename to src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt index 6b99ca640..33e1c5b52 100644 --- a/src/net/torvald/terrarum/gameactors/PBSigrid.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderSigrid.kt @@ -14,11 +14,13 @@ import java.io.IOException * Created by minjaesong on 16-03-14. */ -object PBSigrid { +object PlayerBuilderSigrid { fun create(): Player { val p = Player(GameDate(-2147483648, 0)) // XD + p.referenceID = 0x51621D // the only constant of this procedural universe + p.sprite = SpriteAnimation() p.sprite!!.setDimension(28, 51) p.sprite!!.setSpriteImage("assets/graphics/sprites/test_player.png") diff --git a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt index 470ce84f0..e1b8803ee 100644 --- a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt @@ -1,9 +1,6 @@ package net.torvald.terrarum.gameactors.ai -import net.torvald.colourutil.CIELab -import net.torvald.colourutil.CIELabUtil -import net.torvald.colourutil.RGB -import net.torvald.colourutil.toLab +import net.torvald.terrarum.gameactors.AIControlled import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.mapdrawer.LightmapRenderer @@ -19,12 +16,20 @@ import org.luaj.vm2.lib.ZeroArgFunction internal class AILuaAPI(g: Globals, actor: ActorWithBody) { init { + if (actor !is AIControlled) throw IllegalArgumentException("The actor is not AIControlled! $actor") + // load things. WARNING: THIS IS MANUAL! g["ai"] = LuaValue.tableOf() g["ai"]["getNearestActor"] = GetNearestActor() g["ai"]["getNearestPlayer"] = GetNearestPlayer() g["ai"]["getX"] = GetX(actor) g["ai"]["getY"] = GetY(actor) + g["ai"]["moveUp"] = MoveUp(actor) + g["ai"]["moveDown"] = MoveDown(actor) + g["ai"]["moveLeft"] = MoveLeft(actor) + g["ai"]["moveRight"] = MoveRight(actor) + g["ai"]["moveTo"] = MoveTo(actor) + } companion object { @@ -42,12 +47,13 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { t["height"] = actor.hitbox.height val lumrgb: Int = actor.actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0 + val MUL_2 = LightmapRenderer.MUL_2 + val MUL = LightmapRenderer.MUL + val CHMAX = LightmapRenderer.CHANNEL_MAX t["luminosity_rgb"] = lumrgb - t["luminosity"] = RGB( // perceived luminosity - lumrgb.div(LightmapRenderer.MUL_2).mod(LightmapRenderer.MUL) / LightmapRenderer.CHANNEL_MAX_FLOAT, - lumrgb.div(LightmapRenderer.MUL_2).mod(LightmapRenderer.MUL) / LightmapRenderer.CHANNEL_MAX_FLOAT, - lumrgb.div(LightmapRenderer.MUL_2).mod(LightmapRenderer.MUL) / LightmapRenderer.CHANNEL_MAX_FLOAT - ).toLab().L.div(100.0) + t["luminosity"] = (lumrgb.div(MUL_2).and(CHMAX).times(3) + + lumrgb.div(MUL).and(CHMAX).times(4) + + lumrgb.and(1023)) / 8 return t } @@ -95,4 +101,44 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } + class MoveLeft(val actor: AIControlled) : ZeroArgFunction() { + override fun call(): LuaValue { + actor.moveLeft() + return LuaValue.NONE + } + } + + class MoveRight(val actor: AIControlled) : ZeroArgFunction() { + override fun call(): LuaValue { + actor.moveRight() + return LuaValue.NONE + } + } + + class MoveUp(val actor: AIControlled) : ZeroArgFunction() { + override fun call(): LuaValue { + actor.moveUp() + return LuaValue.NONE + } + } + + class MoveDown(val actor: AIControlled) : ZeroArgFunction() { + override fun call(): LuaValue { + actor.moveDown() + return LuaValue.NONE + } + } + + class MoveTo(val actor: AIControlled) : LuaFunction() { + override fun call(bearing: LuaValue): LuaValue { + actor.moveTo(bearing.checkdouble()) + return LuaValue.NONE + } + + override fun call(toX: LuaValue, toY: LuaValue): LuaValue { + actor.moveTo(toX.checkdouble(), toY.checkdouble()) + return LuaValue.NONE + } + } + } \ No newline at end of file