actor AI from Lua script

Former-commit-id: 184160efc59c4f846f1cc154fe3e60d21b301ee3
Former-commit-id: 4e228542975ea52945a597b7ca1bc06b407c3be7
This commit is contained in:
Song Minjae
2016-12-26 23:55:54 +09:00
parent d0109a88af
commit 35a723ee0f
15 changed files with 132 additions and 95 deletions

View File

@@ -22,7 +22,7 @@ import java.util.*
* Created by minjaesong on 16-10-24.
*/
open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
: HistoricalFigure(birth, death), Controllable, Pocketed, Factionable, Luminous, LandHolder {
: HistoricalFigure(birth, death), Controllable, Pocketed, Factionable, Luminous, LandHolder {
/** Must be set by PlayerFactory */
override var inventory: ActorInventory = ActorInventory()
@@ -197,6 +197,22 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
isDownDown = isFuncDown(input, EnumKeyFunc.MOVE_DOWN)
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)
// deadzonning
if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0f
if (Math.abs(axisY) < Terrarum.CONTROLLER_DEADZONE) axisY = 0f
if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0f
if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0f
gamepad!!.isButtonPressed(GAMEPAD_JUMP)
}
}
}
@@ -204,29 +220,17 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (!noClip) {
if (grounded) {
actorValue[AVKey.ACCELMULT] = 1.0
} else {
}
else {
actorValue[AVKey.ACCELMULT] = ACCEL_MULT_IN_FLIGHT
}
} else {
}
else {
actorValue[AVKey.ACCELMULT] = 1.0
}
}
override fun processInput(gc: GameContainer, delta: Int, input: Input) {
if (isGamer && Terrarum.hasController) {
gamepad = Controllers.getController(0)
axisX = gamepad!!.getAxisValue(0)
axisY = gamepad!!.getAxisValue(1)
axisRX = gamepad!!.getAxisValue(2)
axisRY = gamepad!!.getAxisValue(3)
// deadzonning
if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0f
if (Math.abs(axisY) < Terrarum.CONTROLLER_DEADZONE) axisY = 0f
if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0f
if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0f
}
///////////////////
// MOUSE CONTROL //
///////////////////
@@ -333,16 +337,18 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
/**
* Jump control
*/
if (isJumpDown || isGamer && Terrarum.hasController && gamepad!!.isButtonPressed(GAMEPAD_JUMP)) {
if (isJumpDown) {
if (!noClip) {
if (grounded) {
jumping = true
}
jump()
} else {
}
else {
walkVertical(true, AXIS_POSMAX)
}
} else {
}
else {
jumping = false
jumpCounter = 0
jumpAcc = 0.0
@@ -376,7 +382,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
if ((!walledLeft && left) || (!walledRight && !left)) {
readonly_totalX =
absMax( // keyboard
absMax(// keyboard
actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
Math.sqrt(scale) *
@@ -414,7 +420,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
*/
private fun walkVertical(up: Boolean, absAxisVal: Float) {
readonly_totalY =
absMax( // keyboard
absMax(// keyboard
actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
Math.sqrt(scale) *
@@ -465,7 +471,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* TODO linear function (play Super Mario Bros. and you'll get what I'm talking about)
*/
private fun jump() {
val len = MAX_JUMP_LENGTH.toFloat()
val pwr = actorValue.getAsDouble(AVKey.JUMPPOWER)!! * (actorValue.getAsDouble(AVKey.JUMPPOWERMULT) ?: 1.0)
val jumpLinearThre = 0.08
@@ -537,7 +542,8 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (spriteGlow != null) {
spriteGlow!!.flip(true, false)
}
} else {
}
else {
sprite!!.flip(false, false)
if (spriteGlow != null) {
spriteGlow!!.flip(false, false)

View File

@@ -907,7 +907,7 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat()
)
// Q&D fix for Roundworld anormaly
// Q&D fix for Roundworld anomaly
spriteGlow!!.render(g,
(hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE,
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
@@ -925,7 +925,7 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat()
)
// Q&D fix for Roundworld anormaly
// Q&D fix for Roundworld anomaly
spriteGlow!!.render(g,
(hitbox.posX - scale).toFloat() + world.width * TILE_SIZE,
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
@@ -956,7 +956,7 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat()
)
// Q&D fix for Roundworld anormaly
// Q&D fix for Roundworld anomaly
sprite!!.render(g,
(hitbox.posX - hitboxTranslateX * scale).toFloat() + world.width * TILE_SIZE,
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
@@ -974,7 +974,7 @@ open class ActorWithBody : Actor() {
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),
(scale).toFloat()
)
// Q&D fix for Roundworld anormaly
// Q&D fix for Roundworld anomaly
sprite!!.render(g,
(hitbox.posX - scale).toFloat() + world.width * TILE_SIZE,
(hitbox.posY + hitboxTranslateY * scale - (baseSpriteHeight - baseHitboxH) * scale + 2).toFloat(),

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.gameactors
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.gameactors.ai.AILuaAPI
import net.torvald.terrarum.gameitem.EquipPosition
import net.torvald.terrarum.gameitem.InventoryItem
import org.luaj.vm2.Globals
@@ -11,25 +12,23 @@ import org.luaj.vm2.compiler.LuaC
import org.luaj.vm2.lib.*
import org.luaj.vm2.lib.jse.JseBaseLib
import org.luaj.vm2.lib.jse.JseMathLib
import org.luaj.vm2.lib.jse.JsePlatform
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input
import java.io.InputStreamReader
import java.io.Reader
/**
* Created by minjaesong on 16-01-31.
*/
open class HumanoidNPC(luaScript: String, born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem {
open class HumanoidNPC(val luaScript: String, born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem {
override val scriptPath: String = ""
companion object {
protected val luag = Globals()
protected val luag: Globals = JsePlatform.standardGlobals()
init {
luag.load(JseBaseLib())
LoadState.install(luag)
LuaC.install(luag)
}
init {
AILuaAPI(luag, this)
}
// we're having InventoryItem data so that this class could be somewhat universal
@@ -72,13 +71,15 @@ open class HumanoidNPC(luaScript: String, born: GameDate) : ActorHumanoid(born),
init {
//val inputStream = javaClass.getResourceAsStream(scriptPath)
//runCommand(InputStreamReader(inputStream), scriptPath)
runCommand(luaScript)
}
override fun update(gc: GameContainer, delta: Int) {
super.update(gc, delta)
//runCommand(luaScript)
luag.load(luaScript).call()
//moveRight()
}
override fun moveLeft() { // hit the buttons on the controller box
@@ -126,7 +127,7 @@ open class HumanoidNPC(luaScript: String, born: GameDate) : ActorHumanoid(born),
fun runCommand(script: String) {
if (!threadRun && !flagDespawn) {
currentExecutionThread = Thread(ThreadRunCommand(luag, script, "="))
currentExecutionThread = Thread(ThreadRunCommand(luag, script, ""))
currentExecutionThread.start()
threadRun = true
}

View File

@@ -14,6 +14,8 @@ import java.security.SecureRandom
*/
object InjectCreatureRaw {
// FIXME strength not injected properly?
const val JSONPATH = "./assets/raw/creatures/"
private const val MULTIPLIER_RAW_ELEM_SUFFIX = AVKey.MULT

View File

@@ -16,6 +16,7 @@ object PlayerBuilderCynthia {
InjectCreatureRaw(p.actorValue, "CreatureHuman.json")
p.actorValue[AVKey.__PLAYER_QUICKBARSEL] = 0
p.actorValue[AVKey.NAME] = "Cynthia"
p.makeNewSprite(26, 42)

View File

@@ -16,12 +16,17 @@ 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")
if (actor !is AIControlled)
throw IllegalArgumentException("The actor is not AIControlled! $actor")
// load things. WARNING: THIS IS MANUAL!
g["ai"] = LuaValue.tableOf()
g["ai"]["getSelfActorInfo"] = GetSelfActorInfo(actor)
g["ai"]["getNearestActor"] = GetNearestActor()
g["ai"]["getNearestPlayer"] = GetNearestPlayer()
g["ai"]["getX"] = GetX(actor)
g["ai"]["getY"] = GetY(actor)
g["ai"]["moveUp"] = MoveUp(actor)
@@ -29,10 +34,14 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
g["ai"]["moveLeft"] = MoveLeft(actor)
g["ai"]["moveRight"] = MoveRight(actor)
g["ai"]["moveTo"] = MoveTo(actor)
g["ai"]["jump"] = Jump(actor)
}
companion object {
/**
* Reads arbitrary ActorWithBody and returns its information as Lua table
*/
fun composeActorObject(actor: ActorWithBody): LuaTable {
val t = LuaValue.tableOf()
@@ -48,7 +57,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
t["mass"] = actor.mass
t["collision_type"] = actor.collisionType
t["collisionType"] = actor.collisionType
t["strength"] = actor.actorValue.getAsInt(AVKey.STRENGTH) ?: 0
@@ -56,7 +65,7 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
val MUL_2 = LightmapRenderer.MUL_2
val MUL = LightmapRenderer.MUL
val CHMAX = LightmapRenderer.CHANNEL_MAX
t["luminosity_rgb"] = lumrgb
t["luminosityRGB"] = lumrgb
t["luminosity"] = (lumrgb.div(MUL_2).and(CHMAX).times(3) +
lumrgb.div(MUL).and(CHMAX).times(4) +
lumrgb.and(1023)) / 8 // quick luminosity calculation
@@ -65,6 +74,12 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
}
}
class GetSelfActorInfo(val actor: ActorWithBody) : ZeroArgFunction() {
override fun call(): LuaValue {
return composeActorObject(actor)
}
}
/** ai.getNearestActor(nullable any criterion, nullable number range) */
class GetNearestActor() : LuaFunction() {
override fun call(): LuaValue {
@@ -147,4 +162,11 @@ internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
}
}
}
class Jump(val actor: AIControlled) : ZeroArgFunction() {
override fun call(): LuaValue {
actor.moveJump()
return LuaValue.NONE
}
}
}

View File

@@ -1,10 +1,16 @@
package net.torvald.terrarum.gameactors.ai.scripts
/**
* Randomly roams around.
*
* Created by SKYHi14 on 2016-12-23.
*/
object PokemonNPCAI {
operator fun invoke(): String = """
ai.jump()
ai.moveRight()
thisActorInfo = ai.getSelfActorInfo()
print(thisActorInfo.strength)
"""
}