From 13faeb2947687f9379891a7ac9ed6acff066f50e Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Wed, 28 Dec 2016 00:17:52 +0900 Subject: [PATCH] ActorAI's walk speed can be adjusted now Former-commit-id: 556677bddf9cc29358471c81f7febc40e8e6cc7d Former-commit-id: 35b994001dd034e166ba6c6709cb92fd5dca073e --- src/net/torvald/terrarum/Terrarum.kt | 33 ++++--- .../terrarum/gameactors/AIControlled.kt | 10 +-- .../terrarum/gameactors/ActorHumanoid.kt | 88 ++++++++++++------- .../terrarum/gameactors/HumanoidNPC.kt | 18 ++-- src/net/torvald/terrarum/gameactors/Player.kt | 7 -- .../terrarum/gameactors/ai/AILuaAPI.kt | 52 ++++++++--- .../gameactors/ai/scripts/PokemonNPCAI.kt | 4 +- 7 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 3995aeab9..d4431b648 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -86,21 +86,30 @@ constructor(gamename: String) : StateBasedGame(gamename) { fontGame = GameFontWhite() fontSmallNumbers = TinyAlphNum() + // search for real controller + // exclude controllers with name "Mouse", "keyboard" + val notControllerRegex = Regex("mouse|keyboard") try { - hasController = gc.input.controllerCount > 0 + // gc.input.controllerCount is unreliable + for (i in 0..255) { + val controllerInQuo = Controllers.getController(i) - if (hasController) { - // check if the first controller is actually available - Controllers.getController(0).getAxisValue(0) + println("Controller $i: ${controllerInQuo.name}") + + // check the name + if (!controllerInQuo.name.toLowerCase().contains(notControllerRegex)) { + controller = controllerInQuo + println("Controller $i selected: ${controller!!.name}") + break + } } } - catch (e: ArrayIndexOutOfBoundsException) { - hasController = false + catch (e: IndexOutOfBoundsException) { } - if (hasController) { - for (c in 0..Controllers.getController(0).axisCount - 1) { - Controllers.getController(0).setDeadZone(c, CONTROLLER_DEADZONE) + if (controller != null) { + for (c in 0..controller!!.axisCount - 1) { + controller!!.setDeadZone(c, CONTROLLER_DEADZONE) } } @@ -215,8 +224,10 @@ constructor(gamename: String) : StateBasedGame(gamename) { val STATE_ID_TOOL_NOISEGEN = 0x200 - var hasController = false - val CONTROLLER_DEADZONE = 0.1f + //var hasController = false + var controller: org.lwjgl.input.Controller? = null + private set + val CONTROLLER_DEADZONE = 0.2f /** Available CPU threads */ val THREADS = Runtime.getRuntime().availableProcessors() diff --git a/src/net/torvald/terrarum/gameactors/AIControlled.kt b/src/net/torvald/terrarum/gameactors/AIControlled.kt index 46310adf9..3ac7536c5 100644 --- a/src/net/torvald/terrarum/gameactors/AIControlled.kt +++ b/src/net/torvald/terrarum/gameactors/AIControlled.kt @@ -8,11 +8,11 @@ package net.torvald.terrarum.gameactors interface AIControlled { val scriptPath: String - fun moveLeft() - fun moveRight() - fun moveUp() - fun moveDown() - fun moveJump() + fun moveLeft(amount: Float = 1f) + fun moveRight(amount: Float = 1f) + fun moveUp(amount: Float = 1f) + fun moveDown(amount: Float = 1f) + fun moveJump(amount: Float = 1f) /** fly toward arbitrary angle WARNING: the map is looped! */ fun moveTo(bearing: Double) diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index b34218ef3..7475cab35 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.gameactors import com.jme3.math.FastMath import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.faction.Faction import net.torvald.terrarum.gamecontroller.EnumKeyFunc import net.torvald.terrarum.gamecontroller.KeyMap @@ -11,7 +10,6 @@ import net.torvald.terrarum.gameitem.InventoryItem import net.torvald.terrarum.realestate.RealEstateUtility 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 java.util.* @@ -86,7 +84,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) // MOVEMENT RELATED FUNCTIONS // //////////////////////////////// - var gamepad: Controller? = null var axisX = 0f var axisY = 0f var axisRX = 0f @@ -121,7 +118,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) internal var noClip = false - @Transient private val AXIS_POSMAX = 1.0f + @Transient private val AXIS_KEYBOARD = -13372f // leetz @Transient private val GAMEPAD_JUMP = 7 protected var isUpDown = false @@ -160,6 +157,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) isLeftDown = false isRightDown = false isJumpDown = false + axisX = 0f + axisY = 0f + axisRX = 0f + axisRY = 0f } // update inventory items @@ -198,12 +199,11 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) isRightDown = isFuncDown(input, EnumKeyFunc.MOVE_RIGHT) isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP) - if (Terrarum.hasController) { - gamepad = Controllers.getController(0) - axisX = gamepad!!.getAxisValue(0) - axisY = gamepad!!.getAxisValue(1) - axisRX = gamepad!!.getAxisValue(2) - axisRY = gamepad!!.getAxisValue(3) + if (Terrarum.controller != null) { + axisX = Terrarum.controller!!.getAxisValue(3) + axisY = Terrarum.controller!!.getAxisValue(2) + axisRX = Terrarum.controller!!.getAxisValue(1) + axisRY = Terrarum.controller!!.getAxisValue(0) // deadzonning if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0f @@ -211,7 +211,8 @@ 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 - gamepad!!.isButtonPressed(GAMEPAD_JUMP) + isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP) || + Terrarum.controller!!.isButtonPressed(GAMEPAD_JUMP) } } } @@ -230,6 +231,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) } } + private val hasController: Boolean + get() = if (isGamer) Terrarum.controller != null + else true + override fun processInput(gc: GameContainer, delta: Int, input: Input) { /////////////////// // MOUSE CONTROL // @@ -252,7 +257,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) /** * L-R stop */ - if (isGamer && Terrarum.hasController && !isWalkingH) { + if (hasController && !isWalkingH) { if (axisX == 0f) { walkHStop() } @@ -265,7 +270,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) /** * U-D stop */ - if (isGamer && Terrarum.hasController) { + if (hasController) { if (axisY == 0f) { walkVStop() } @@ -281,26 +286,26 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * Left/Right movement */ - if (isGamer && Terrarum.hasController) { + if (hasController) { if (axisX != 0f) { walkHorizontal(axisX < 0f, axisX.abs()) } } // ↑F, ↓S if (isRightDown && !isLeftDown) { - walkHorizontal(false, AXIS_POSMAX) + walkHorizontal(false, AXIS_KEYBOARD) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) } // ↓F, ↑S else if (isLeftDown && !isRightDown) { - walkHorizontal(true, AXIS_POSMAX) + walkHorizontal(true, AXIS_KEYBOARD) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT) } // ↓F, ↓S /*else if (isLeftDown && isRightDown) { if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) { - walkHorizontal(false, AXIS_POSMAX) + walkHorizontal(false, AXIS_KEYBOARD) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) } else if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)) { - walkHorizontal(true, AXIS_POSMAX) + walkHorizontal(true, AXIS_KEYBOARD) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT) } }*/ @@ -309,26 +314,26 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * Up/Down movement */ if (noClip) { - if (isGamer && Terrarum.hasController) { + if (hasController) { if (axisY != 0f) { walkVertical(axisY < 0, axisY.abs()) } } // ↑E, ↓D if (isDownDown && !isUpDown) { - walkVertical(false, AXIS_POSMAX) + walkVertical(false, AXIS_KEYBOARD) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) } // ↓E, ↑D else if (isUpDown && !isDownDown) { - walkVertical(true, AXIS_POSMAX) + walkVertical(true, AXIS_KEYBOARD) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP) } // ↓E, ↓D /*else if (isUpDown && isDownDown) { if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) { - walkVertical(false, AXIS_POSMAX) + walkVertical(false, AXIS_KEYBOARD) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) } else if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)) { - walkVertical(true, AXIS_POSMAX) + walkVertical(true, AXIS_KEYBOARD) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP) } }*/ @@ -345,7 +350,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) jump() } else { - walkVertical(true, AXIS_POSMAX) + walkVertical(true, AXIS_KEYBOARD) } } else { @@ -376,23 +381,33 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * Be warned. * * @param left (even if the game is joypad controlled, you must give valid value) - * @param absAxisVal (set AXIS_POSMAX if keyboard controlled) + * @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled) * @author minjaesong */ private fun walkHorizontal(left: Boolean, absAxisVal: Float) { if ((!walledLeft && left) || (!walledRight && !left)) { readonly_totalX = absMax( // keyboard - avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f), + if (absAxisVal == AXIS_KEYBOARD) + avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f) + else + 0.0 + , // gamepad - avAcceleration * (if (left) -1f else 1f) * absAxisVal + if (absAxisVal != AXIS_KEYBOARD) + avAcceleration * (if (left) -1f else 1f) * absAxisVal + else + 0.0 ) //applyForce(Vector2(readonly_totalX, 0.0)) walkX += readonly_totalX + walkX = readonly_totalX walkX = walkX.bipolarClamp(avSpeedCap) - walkCounterX += 1 + if (absAxisVal == AXIS_KEYBOARD) { + walkCounterX += 1 + } isWalkingH = true } @@ -408,20 +423,29 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) * @param up (even if the game is joypad controlled, you must give valid value) * * - * @param absAxisVal (set AXIS_POSMAX if keyboard controlled) + * @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled) */ private fun walkVertical(up: Boolean, absAxisVal: Float) { readonly_totalY = absMax( // keyboard - avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f), + if (absAxisVal == AXIS_KEYBOARD) + avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f) + else + 0.0 + , // gamepad - avAcceleration * (if (up) -1f else 1f) * absAxisVal + if (absAxisVal != AXIS_KEYBOARD) + avAcceleration * (if (up) -1f else 1f) * absAxisVal + else + 0.0 ) walkY += readonly_totalY walkY = walkY.bipolarClamp(avSpeedCap) - walkCounterY += 1 + if (absAxisVal == AXIS_KEYBOARD) { + walkCounterY += 1 + } isWalkingV = true } diff --git a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt index fe136bf94..5b3d1fa9d 100644 --- a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt @@ -84,23 +84,23 @@ open class HumanoidNPC(val luaScript: String, born: GameDate) : ActorHumanoid(bo //moveRight() } - override fun moveLeft() { // hit the buttons on the controller box - isLeftDown = true + override fun moveLeft(amount: Float) { // hit the buttons on the controller box + axisX = -amount } - override fun moveRight() { // hit the buttons on the controller box - isRightDown = true + override fun moveRight(amount: Float) { // hit the buttons on the controller box + axisX = amount } - override fun moveUp() { // hit the buttons on the controller box - isUpDown = true + override fun moveUp(amount: Float) { // hit the buttons on the controller box + axisY = -amount } - override fun moveDown() { // hit the buttons on the controller box - isDownDown = true + override fun moveDown(amount: Float) { // hit the buttons on the controller box + axisY = amount } - override fun moveJump() { // hit the buttons on the controller box + override fun moveJump(amount: Float) { // hit the buttons on the controller box isJumpDown = true } diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index d5af49107..fed14b80d 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -43,13 +43,6 @@ class Player(born: GameDate) : ActorHumanoid(born) { referenceID = PLAYER_REF_ID // forcibly set ID density = BASE_DENSITY collisionType = COLLISION_KINEMATIC - - try { - gamepad = Controllers.getController(0) - } - catch (e: IndexOutOfBoundsException) { - println("[Player] gamepad not detected.") - } } override fun update(gc: GameContainer, delta: Int) { diff --git a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt index 15d5e18c7..058737afe 100644 --- a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt @@ -126,32 +126,56 @@ internal class AILuaAPI(val g: Globals, actor: ActorWithBody) { } } - class MoveLeft(val actor: AIControlled) : ZeroArgFunction() { - override fun call(): LuaValue { + class MoveLeft(val actor: AIControlled) : LuaFunction() { + override fun call(): LuaValue { // hard key press actor.moveLeft() return LuaValue.NONE } + + /** @param amount [0.0 - 1.0] */ + override fun call(amount: LuaValue): LuaValue { // stick tilt + actor.moveLeft(amount.checkdouble().toFloat()) + return LuaValue.NONE + } } - class MoveRight(val actor: AIControlled) : ZeroArgFunction() { - override fun call(): LuaValue { + class MoveRight(val actor: AIControlled) : LuaFunction() { + override fun call(): LuaValue { // hard key press actor.moveRight() return LuaValue.NONE } - } - class MoveUp(val actor: AIControlled) : ZeroArgFunction() { - override fun call(): LuaValue { - actor.moveUp() + /** @param amount [0.0 - 1.0] */ + override fun call(amount: LuaValue): LuaValue { // stick tilt + actor.moveRight(amount.checkdouble().toFloat()) return LuaValue.NONE } } - class MoveDown(val actor: AIControlled) : ZeroArgFunction() { - override fun call(): LuaValue { + class MoveUp(val actor: AIControlled) : LuaFunction() { + override fun call(): LuaValue { // hard key press + actor.moveUp() + return LuaValue.NONE + } + + /** @param amount [0.0 - 1.0] */ + override fun call(amount: LuaValue): LuaValue { // stick tilt + actor.moveUp(amount.checkdouble().toFloat()) + return LuaValue.NONE + } + } + + class MoveDown(val actor: AIControlled) : LuaFunction() { + override fun call(): LuaValue { // hard key press actor.moveDown() return LuaValue.NONE } + + /** @param amount [0.0 - 1.0] */ + override fun call(amount: LuaValue): LuaValue { // stick tilt + actor.moveDown(amount.checkdouble().toFloat()) + return LuaValue.NONE + } } class MoveTo(val actor: AIControlled) : LuaFunction() { @@ -166,11 +190,17 @@ internal class AILuaAPI(val g: Globals, actor: ActorWithBody) { } } - class Jump(val actor: AIControlled) : ZeroArgFunction() { + class Jump(val actor: AIControlled) : LuaFunction() { override fun call(): LuaValue { actor.moveJump() return LuaValue.NONE } + + /** @param amount [0.0 - 1.0] */ + override fun call(amount: LuaValue): LuaValue { // stick tilt + actor.moveJump(amount.checkdouble().toFloat()) + return LuaValue.NONE + } } } diff --git a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt index 13ba626b4..d0a2a6f7b 100644 --- a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt @@ -40,9 +40,9 @@ function update(delta) elseif currentMode == "move" then -- move if moveMode == "left" then - ai.moveLeft() + ai.moveLeft(0.5) elseif moveMode == "right" then - ai.moveRight() + ai.moveRight(0.5) end -- reset counter if timeCounter >= countMax then