From e499c24c0d4e0bdf5e58073010fe305a37653e7d Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Sat, 7 Jan 2017 00:37:46 +0900 Subject: [PATCH] AI auto jump test Former-commit-id: f48972fa48a526e8f697a47cde90b26240f549a3 Former-commit-id: c45dcbcae2f7d85c801ed87c049c403609a6d6d0 --- src/net/torvald/point/Point2d.kt | 3 +- src/net/torvald/terrarum/StateInGame.kt | 2 +- src/net/torvald/terrarum/console/Teleport.kt | 4 +- .../terrarum/gameactors/ActorHumanoid.kt | 5 -- .../terrarum/gameactors/ActorWithBody.kt | 10 +++- .../terrarum/gameactors/HumanoidNPC.kt | 8 +-- .../gameactors/PlayerBuilderCynthia.kt | 4 +- .../terrarum/gameactors/ai/AILuaAPI.kt | 59 ++++++++++++++++--- .../ai/scripts/EncapsulatedString.kt | 11 ---- .../{PokemonNPCAI.kt => PokemonNPCAI.lua} | 51 ++++++++-------- .../terrarum/gamecontroller/GameController.kt | 2 +- 11 files changed, 96 insertions(+), 63 deletions(-) delete mode 100644 src/net/torvald/terrarum/gameactors/ai/scripts/EncapsulatedString.kt rename src/net/torvald/terrarum/gameactors/ai/scripts/{PokemonNPCAI.kt => PokemonNPCAI.lua} (51%) diff --git a/src/net/torvald/point/Point2d.kt b/src/net/torvald/point/Point2d.kt index cb6609af5..e90f2cefa 100644 --- a/src/net/torvald/point/Point2d.kt +++ b/src/net/torvald/point/Point2d.kt @@ -49,5 +49,6 @@ class Point2d(var x: Double, var y: Double) : Cloneable { fun toVector() = Vector2(x, y) - fun length(other: Point2d) = ((this.x - other.x).sqr() + (this.y - other.y).sqr()).sqrt() + fun length(other: Point2d) = distSqr(other).sqrt() + fun distSqr(other: Point2d) = ((this.x - other.x).sqr() + (this.y - other.y).sqr()) } diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index 7122a6396..b16eb1be2 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -533,7 +533,7 @@ constructor() : BasicGameState() { * NOTE: concurrency for actor updating is currently disabled because of it's poor performance */ fun updateActors(gc: GameContainer, delta: Int) { - if (false) { // don't multithread this for now, it's SLOWER //if (Terrarum.MULTITHREAD) { + if (false) { // don't multithread this for now, it's SLOWER //if (Terrarum.MULTITHREAD && actorContainer.size > Terrarum.THREADS) { val actors = actorContainer.size.toFloat() // set up indices for (i in 0..Terrarum.THREADS - 1) { diff --git a/src/net/torvald/terrarum/console/Teleport.kt b/src/net/torvald/terrarum/console/Teleport.kt index 3a3651368..9fc51a2fe 100644 --- a/src/net/torvald/terrarum/console/Teleport.kt +++ b/src/net/torvald/terrarum/console/Teleport.kt @@ -62,8 +62,8 @@ internal object Teleport : ConsoleCommand { } fromActor.setPosition( - targetActor.feetPosition.x, - targetActor.feetPosition.y + targetActor.feetPosVector.x, + targetActor.feetPosVector.y ) } else if (args.size == 5) { diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt index f5d692890..bf7d42de5 100644 --- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt @@ -347,11 +347,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null) if (airJumpingAllowed || (!airJumpingAllowed && grounded)) { jumping = true - - - if (!isGamer) { - println("[ActorHumanoid] jumping = true") - } } jump() } diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 6288dddd2..cd89c4f6b 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -305,12 +305,16 @@ open class ActorWithBody : Actor() { baseHitboxH * scale) } - val centrePosition: Vector2 + val centrePosVector: Vector2 get() = Vector2(hitbox.centeredX, hitbox.centeredY) val centrePosPoint: Point2d get() = Point2d(hitbox.centeredX, hitbox.centeredY) - val feetPosition: Vector2 - get() = Vector2(hitbox.centeredX, hitbox.posY + hitbox.height) + val feetPosVector: Vector2 + get() = Vector2(hitbox.centeredX, hitbox.endPointY) + val feetPosPoint: Point2d + get() = Point2d(hitbox.centeredX, hitbox.endPointY) + val feetPosTile: IntArray + get() = intArrayOf(tilewiseHitbox.centeredX.floorInt(), tilewiseHitbox.endPointY.floorInt()) override fun run() = update(gameContainer, updateDelta) diff --git a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt index b57c0f33c..c31fa8393 100644 --- a/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/gameactors/HumanoidNPC.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.gameactors import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.ai.AILuaAPI -import net.torvald.terrarum.gameactors.ai.scripts.EncapsulatedString import net.torvald.terrarum.gameitem.EquipPosition import net.torvald.terrarum.gameitem.InventoryItem import org.luaj.vm2.* @@ -19,9 +18,7 @@ import java.io.Reader /** * Created by minjaesong on 16-01-31. */ -open class HumanoidNPC(luaScript: EncapsulatedString, born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem { - - override val scriptPath: String = "" +open class HumanoidNPC(override val scriptPath: String, born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem { protected val luag: Globals = JsePlatform.standardGlobals() @@ -39,7 +36,8 @@ open class HumanoidNPC(luaScript: EncapsulatedString, born: GameDate) : ActorHum luag["luajava"] = LuaValue.NIL aiLuaAPI = AILuaAPI(luag, this) // load the script and execute it (initialises target script) - luaInstance = luag.load(luaScript.getString(), luaScript.javaClass.simpleName) + val inputStream = javaClass.getResourceAsStream(scriptPath) + luaInstance = luag.load(InputStreamReader(inputStream), scriptPath.split(Regex("[\\/]")).last()) luaInstance.call() } diff --git a/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt index cba020bea..c0c3a65cb 100644 --- a/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt +++ b/src/net/torvald/terrarum/gameactors/PlayerBuilderCynthia.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.gameactors import net.torvald.spriteanimation.SpriteAnimation import net.torvald.terrarum.gameactors.ActorHumanoid -import net.torvald.terrarum.gameactors.ai.scripts.PokemonNPCAI import net.torvald.terrarum.mapdrawer.FeaturesDrawer /** @@ -12,7 +11,8 @@ object PlayerBuilderCynthia { operator fun invoke(): ActorWithBody { //val p: Player = Player(GameDate(100, 143)) // random value thrown - val p: HumanoidNPC = HumanoidNPC(PokemonNPCAI, GameDate(100, 143)) // random value thrown + val p: HumanoidNPC = HumanoidNPC("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua", + GameDate(100, 143)) // random value thrown InjectCreatureRaw(p.actorValue, "CreatureHuman.json") p.actorValue[AVKey.__PLAYER_QUICKBARSEL] = 0 diff --git a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt index e3b78b253..0a7732220 100644 --- a/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt @@ -5,10 +5,9 @@ import net.torvald.terrarum.gameactors.AIControlled import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.mapdrawer.LightmapRenderer -import org.luaj.vm2.Globals -import org.luaj.vm2.LuaFunction -import org.luaj.vm2.LuaTable -import org.luaj.vm2.LuaValue +import net.torvald.terrarum.tileproperties.TileCodex +import org.luaj.vm2.* +import org.luaj.vm2.lib.OneArgFunction import org.luaj.vm2.lib.ZeroArgFunction /** @@ -16,6 +15,8 @@ import org.luaj.vm2.lib.ZeroArgFunction */ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { + // FIXME when actor jumps, the actor releases left/right stick + init { if (actor !is AIControlled) throw IllegalArgumentException("The actor is not AIControlled! $actor") @@ -37,6 +38,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { g["ai"]["moveTo"] = MoveTo(actor) g["ai"]["jump"] = Jump(actor) + g["ai"]["getNearbyTiles"] = GetNearbyTiles(actor) g["game"] = LuaValue.tableOf() g["game"]["version"] = GameVersion() @@ -48,7 +50,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { * Reads arbitrary ActorWithBody and returns its information as Lua table */ fun composeActorObject(actor: ActorWithBody): LuaTable { - val t: LuaTable = LuaValue.tableOf() + val t: LuaTable = LuaTable() t["name"] = actor.actorValue.getAsString(AVKey.NAME).toLua() t["posX"] = actor.hitbox.centeredX.toLua() @@ -84,7 +86,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { fun Double?.toLua() = if (this == null) LuaValue.NIL else this.toLua() fun Int?.toLua() = if (this == null) LuaValue.NIL else this.toLua() fun String?.toLua() = if (this == null) LuaValue.NIL else this.toLua() - + fun Boolean.toInt() = if (this) 1 else 0 } class GetSelfActorInfo(val actor: ActorWithBody) : ZeroArgFunction() { @@ -212,16 +214,57 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) { } } + class GetNearbyTiles(val actor: ActorWithBody) : OneArgFunction() { + + /** @param radius: lookahead + * + * 3 will return 7x7 array, 0 will return 1x1, 1 will return 3x3 + * + * Index: [-3: y][-3: x] ... [0: y][0: x] ... [3: y][3: x] + * Return value: bitset (int 0-7) + * 1 -- solidity + * 2 -- liquidity + * 3 -- gravity + */ + override fun call(radius: LuaValue): LuaValue { + val radius = radius.checkint() + + if (radius < 0) { + return LuaValue.NONE + } + else { + val luatable = LuaTable() + val feetTilePos = actor.feetPosTile + for (y in feetTilePos[1] - radius..feetTilePos[1] + radius) { + luatable[y - feetTilePos[1]] = LuaTable() + + for (x in feetTilePos[0] - radius..feetTilePos[0] + radius) { + val tile = TileCodex[Terrarum.ingame.world.getTileFromTerrain(x, y) ?: 4096] + val solidity = tile.isSolid.toInt() + val liquidity = tile.isFluid.toInt() + val gravity = tile.isFallable.toInt() + val tileFlag: Int = gravity.shl(2) + liquidity.shl(1) + solidity + + luatable[y - feetTilePos[1]][x - feetTilePos[0]] = + LuaInteger.valueOf(tileFlag) + } + } + + return luatable + } + } + } - class GameVersion() : ZeroArgFunction() { + + class GameVersion : ZeroArgFunction() { override fun call(): LuaValue { return Terrarum.VERSION_STRING.toLua() } } - class GameVersionRaw() : ZeroArgFunction() { + class GameVersionRaw : ZeroArgFunction() { override fun call(): LuaValue { return Terrarum.VERSION_RAW.toLua() } diff --git a/src/net/torvald/terrarum/gameactors/ai/scripts/EncapsulatedString.kt b/src/net/torvald/terrarum/gameactors/ai/scripts/EncapsulatedString.kt deleted file mode 100644 index 709d729ef..000000000 --- a/src/net/torvald/terrarum/gameactors/ai/scripts/EncapsulatedString.kt +++ /dev/null @@ -1,11 +0,0 @@ -package net.torvald.terrarum.gameactors.ai.scripts - -/** - * Encapsulated text file - * - * Created by SKYHi14 on 2016-12-28. - */ -abstract class EncapsulatedString { - abstract fun getString(): String - override fun toString() = getString() -} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua similarity index 51% rename from src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt rename to src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua index 367d2afb2..78acca8ee 100644 --- a/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.kt +++ b/src/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua @@ -1,36 +1,42 @@ -package net.torvald.terrarum.gameactors.ai.scripts - -/** - * Randomly roams around. - * - * Created by SKYHi14 on 2016-12-23. - */ - - -object PokemonNPCAI : EncapsulatedString() { - override fun getString() = """ +-- +-- Created by minjaesong on 2017-01-06. +-- timeCounter = 0 countMax = 0 moveMode = math.random() >= 0.5 and "left" or "right" -currentMode = "turn" +currentMode = "move" local function generateCountMax() - function generateTurn() + local function generateTurn() return 4600 + 1250 * math.random() end - function generateWalk() - return 568 + 342 * math.random() + local function generateWalk() + return 1645 + 402 * math.random() end return (currentMode == "move") and generateWalk() or generateTurn() end -local function moveToDirection() +local function moveToDirection(delta) + local tiles = ai.getNearbyTiles(1) + if moveMode == "left" then - ai.moveLeft(0.5) + if bit32.band(bit32.bor(tiles[0][-1], tiles[-1][-1]), 1) == 1 then + ai.moveLeft(0.75) + ai.jump() + else + timeCounter = timeCounter + delta -- no countup when jumping + ai.moveLeft(0.5) + end elseif moveMode == "right" then - ai.moveRight(0.5) + if bit32.band(bit32.bor(tiles[0][1], tiles[-1][1]), 1) == 1 then + ai.moveRight(0.75) + ai.jump() + else + timeCounter = timeCounter + delta -- no countup when jumping + ai.moveRight(0.5) + end end end @@ -47,10 +53,10 @@ end countMax = generateCountMax() function update(delta) - timeCounter = timeCounter + delta - if currentMode == "move" then - moveToDirection() + moveToDirection(delta) + else + timeCounter = timeCounter + delta -- no countup when jumping end if timeCounter >= countMax then @@ -62,6 +68,3 @@ function update(delta) end end end - -""" -} diff --git a/src/net/torvald/terrarum/gamecontroller/GameController.kt b/src/net/torvald/terrarum/gamecontroller/GameController.kt index 80d347c06..612f26960 100644 --- a/src/net/torvald/terrarum/gamecontroller/GameController.kt +++ b/src/net/torvald/terrarum/gamecontroller/GameController.kt @@ -115,7 +115,7 @@ object GameController { /*if (button == 0) { Terrarum.ingame.addActor(ProjectileSimple( 0, - Terrarum.ingame.player.centrePosition, + Terrarum.ingame.player.centrePosVector, Vector2(mouseX.toDouble(), mouseY.toDouble()) )) }*/