mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
AI auto jump test
Former-commit-id: f48972fa48a526e8f697a47cde90b26240f549a3 Former-commit-id: c45dcbcae2f7d85c801ed87c049c403609a6d6d0
This commit is contained in:
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
|
||||
"""
|
||||
}
|
||||
@@ -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())
|
||||
))
|
||||
}*/
|
||||
|
||||
Reference in New Issue
Block a user