mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 11:34:05 +09:00
AI API
Former-commit-id: 7821931c73c0d90a883b3732eb5a950c2b2a0402 Former-commit-id: b77ed6d9cc3effd183646a7e0c8411b4e125cfd2
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package net.torvald.colourutil
|
package net.torvald.colourutil
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.colourutil.CIELChUtil.toLCh
|
||||||
|
import net.torvald.colourutil.CIELChUtil.toLab
|
||||||
import net.torvald.colourutil.CIELabUtil.toLab
|
import net.torvald.colourutil.CIELabUtil.toLab
|
||||||
import net.torvald.colourutil.CIELabUtil.toRGB
|
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||||
@@ -49,15 +51,15 @@ object CIELChUtil {
|
|||||||
return CIELab(L, a, b, alpha)
|
return CIELab(L, a, b, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Color.toLCh() = this.toXYZ().toLab().toLCh()
|
|
||||||
fun CIELCh.toRGB() = this.toLab().toXYZ().toRGB()
|
|
||||||
|
|
||||||
private fun Float.sqr() = this * this
|
private fun Float.sqr() = this * this
|
||||||
private fun Float.sqrt() = Math.sqrt(this.toDouble()).toFloat()
|
private fun Float.sqrt() = Math.sqrt(this.toDouble()).toFloat()
|
||||||
|
|
||||||
private fun Float.abs() = FastMath.abs(this)
|
private fun Float.abs() = FastMath.abs(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Color.toLCh() = this.toXYZ().toLab().toLCh()
|
||||||
|
fun CIELCh.toRGB() = this.toLab().toXYZ().toRGB()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param L : Luminosity in 0.0 - 1.0
|
* @param L : Luminosity in 0.0 - 1.0
|
||||||
* @param C : Chroma (saturation) in 0.0 - 1.0
|
* @param C : Chroma (saturation) in 0.0 - 1.0
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package net.torvald.colourutil
|
package net.torvald.colourutil
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.colourutil.CIELabUtil.toLab
|
||||||
|
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||||
|
import net.torvald.colourutil.CIELabUtil.toRawRGB
|
||||||
|
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||||
import org.newdawn.slick.Color
|
import org.newdawn.slick.Color
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,11 +51,6 @@ object CIELabUtil {
|
|||||||
return CIELab(newL, newA, newB, newAlpha).toRGB()
|
return CIELab(newL, newA, newB, newAlpha).toRGB()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Color.toLab() = this.toXYZ().toLab()
|
|
||||||
fun RGB.toLab() = this.toXYZ().toLab()
|
|
||||||
fun CIELab.toRGB() = this.toXYZ().toRGB()
|
|
||||||
fun CIELab.toRawRGB() = this.toXYZ().toRawRGB()
|
|
||||||
|
|
||||||
fun RGB.toXYZ(): CIEXYZ {
|
fun RGB.toXYZ(): CIEXYZ {
|
||||||
val newR = if (r > 0.04045f)
|
val newR = if (r > 0.04045f)
|
||||||
((r + 0.055f) / 1.055f).powerOf(2.4f)
|
((r + 0.055f) / 1.055f).powerOf(2.4f)
|
||||||
@@ -133,6 +132,11 @@ object CIELabUtil {
|
|||||||
private fun Float.powerOf(exp: Float) = FastMath.pow(this, exp)
|
private fun Float.powerOf(exp: Float) = FastMath.pow(this, exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Color.toLab() = this.toXYZ().toLab()
|
||||||
|
fun RGB.toLab() = this.toXYZ().toLab()
|
||||||
|
fun CIELab.toRGB() = this.toXYZ().toRGB()
|
||||||
|
fun CIELab.toRawRGB() = this.toXYZ().toRawRGB()
|
||||||
|
|
||||||
internal val D65 = CIEXYZ(0.95047f, 1.00f, 1.08883f)
|
internal val D65 = CIEXYZ(0.95047f, 1.00f, 1.08883f)
|
||||||
val epsilon = 216f/24389f
|
val epsilon = 216f/24389f
|
||||||
val kappa = 24389f/27f
|
val kappa = 24389f/27f
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import org.newdawn.slick.Color
|
|||||||
import net.torvald.colourutil.CIELabUtil.toXYZ
|
import net.torvald.colourutil.CIELabUtil.toXYZ
|
||||||
import net.torvald.colourutil.CIELabUtil.toRawRGB
|
import net.torvald.colourutil.CIELabUtil.toRawRGB
|
||||||
import net.torvald.colourutil.CIELabUtil.toRGB
|
import net.torvald.colourutil.CIELabUtil.toRGB
|
||||||
|
import net.torvald.colourutil.CIELuvUtil.toLuv
|
||||||
|
import net.torvald.colourutil.CIELuvUtil.toXYZ
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A modification of CIEXYZ that is useful for additive mixtures of lights.
|
* A modification of CIEXYZ that is useful for additive mixtures of lights.
|
||||||
@@ -91,14 +93,14 @@ object CIELuvUtil {
|
|||||||
return CIEXYZ(X, Y, Z, alpha)
|
return CIEXYZ(X, Y, Z, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Color.toLuv() = this.toXYZ().toLuv()
|
|
||||||
fun CIELuv.toRawRGB() = this.toXYZ().toRawRGB()
|
|
||||||
fun CIELuv.toRGB() = this.toXYZ().toRGB()
|
|
||||||
|
|
||||||
private fun Float.cbrt() = FastMath.pow(this, 1f / 3f)
|
private fun Float.cbrt() = FastMath.pow(this, 1f / 3f)
|
||||||
private fun Float.cube() = this * this * this
|
private fun Float.cube() = this * this * this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Color.toLuv() = this.toXYZ().toLuv()
|
||||||
|
fun CIELuv.toRawRGB() = this.toXYZ().toRawRGB()
|
||||||
|
fun CIELuv.toRGB() = this.toXYZ().toRGB()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Range:
|
* Range:
|
||||||
* L: 0-100.0
|
* L: 0-100.0
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ constructor() : BasicGameState() {
|
|||||||
|
|
||||||
|
|
||||||
// make camara work //
|
// make camara work //
|
||||||
// compensate for zoom. UIs have to be treated specially! (see UIHandler)
|
// compensate for zoom. UIs must be treated specially! (see UIHandler)
|
||||||
g.translate(-MapCamera.cameraX * screenZoom, -MapCamera.cameraY * screenZoom)
|
g.translate(-MapCamera.cameraX * screenZoom, -MapCamera.cameraY * screenZoom)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ import net.torvald.terrarum.gameactors.ai.ActorAI
|
|||||||
* Created by minjaesong on 16-03-14.
|
* Created by minjaesong on 16-03-14.
|
||||||
*/
|
*/
|
||||||
interface AIControlled {
|
interface AIControlled {
|
||||||
var actorAI: ActorAI
|
val scriptPath: String
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,41 @@
|
|||||||
package net.torvald.terrarum.gameactors
|
package net.torvald.terrarum.gameactors
|
||||||
|
|
||||||
import net.torvald.terrarum.console.ActorHumanoid
|
import net.torvald.terrarum.console.ActorHumanoid
|
||||||
import net.torvald.terrarum.gameactors.ai.ActorAI
|
|
||||||
import net.torvald.terrarum.gameactors.faction.Faction
|
|
||||||
import net.torvald.terrarum.gameitem.InventoryItem
|
import net.torvald.terrarum.gameitem.InventoryItem
|
||||||
import net.torvald.terrarum.realestate.RealEstateUtility.getAbsoluteTileNumber
|
import org.luaj.vm2.Globals
|
||||||
|
import org.luaj.vm2.LoadState
|
||||||
|
import org.luaj.vm2.LuaError
|
||||||
|
import org.luaj.vm2.LuaValue
|
||||||
|
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.newdawn.slick.GameContainer
|
import org.newdawn.slick.GameContainer
|
||||||
import java.util.*
|
import java.io.InputStreamReader
|
||||||
|
import java.io.Reader
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 16-03-14.
|
* Created by minjaesong on 16-03-14.
|
||||||
*/
|
*/
|
||||||
open class HumanoidNPC(born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem {
|
open class HumanoidNPC(aiFile: String, born: GameDate) : ActorHumanoid(born), AIControlled, CanBeAnItem {
|
||||||
|
|
||||||
override var actorAI: ActorAI = object : ActorAI {
|
override val scriptPath: String = aiFile
|
||||||
// TODO fully establish ActorAI so that I can implement AI here
|
|
||||||
|
companion object {
|
||||||
|
protected val luag = Globals()
|
||||||
|
|
||||||
|
init {
|
||||||
|
luag.load(JseBaseLib())
|
||||||
|
luag.load(TableLib())
|
||||||
|
luag.load(StringLib())
|
||||||
|
luag.load(TableLib())
|
||||||
|
luag.load(CoroutineLib())
|
||||||
|
luag.load(Bit32Lib())
|
||||||
|
luag.load(PackageLib())
|
||||||
|
luag.load(JseMathLib())
|
||||||
|
LoadState.install(luag)
|
||||||
|
LuaC.install(luag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're having InventoryItem data so that this class could be somewhat universal
|
// we're having InventoryItem data so that this class could be somewhat universal
|
||||||
@@ -74,4 +95,65 @@ open class HumanoidNPC(born: GameDate) : ActorHumanoid(born), AIControlled, CanB
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
val inputStream = javaClass.getResourceAsStream(scriptPath)
|
||||||
|
runCommand(InputStreamReader(inputStream), scriptPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun update(gc: GameContainer, delta: Int) {
|
||||||
|
super.update(gc, delta)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentExecutionThread = Thread()
|
||||||
|
var threadRun = false
|
||||||
|
|
||||||
|
fun runCommand(reader: Reader, filename: String) {
|
||||||
|
if (!threadRun && !flagDespawn) {
|
||||||
|
currentExecutionThread = Thread(ThreadRunCommand(luag, reader, filename))
|
||||||
|
currentExecutionThread.start()
|
||||||
|
threadRun = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreadRunCommand : Runnable {
|
||||||
|
|
||||||
|
val mode: Int
|
||||||
|
val arg1: Any
|
||||||
|
val arg2: String
|
||||||
|
val lua: Globals
|
||||||
|
|
||||||
|
constructor(luaInstance: Globals, line: String, env: String) {
|
||||||
|
mode = 0
|
||||||
|
arg1 = line
|
||||||
|
arg2 = env
|
||||||
|
lua = luaInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(luaInstance: Globals, reader: Reader, filename: String) {
|
||||||
|
mode = 1
|
||||||
|
arg1 = reader
|
||||||
|
arg2 = filename
|
||||||
|
lua = luaInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
try {
|
||||||
|
val chunk: LuaValue
|
||||||
|
if (mode == 0)
|
||||||
|
chunk = lua.load(arg1 as String, arg2)
|
||||||
|
else if (mode == 1)
|
||||||
|
chunk = lua.load(arg1 as Reader, arg2)
|
||||||
|
else
|
||||||
|
throw IllegalArgumentException("Unsupported mode: $mode")
|
||||||
|
|
||||||
|
|
||||||
|
chunk.call()
|
||||||
|
}
|
||||||
|
catch (e: LuaError) {
|
||||||
|
e.printStackTrace(System.err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
98
src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt
Normal file
98
src/net/torvald/terrarum/gameactors/ai/AILuaAPI.kt
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
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.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 org.luaj.vm2.lib.ZeroArgFunction
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 16-10-24.
|
||||||
|
*/
|
||||||
|
internal class AILuaAPI(g: Globals, actor: ActorWithBody) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun composeActorObject(actor: ActorWithBody): LuaTable {
|
||||||
|
val t = LuaValue.tableOf()
|
||||||
|
|
||||||
|
t["name"] = actor.actorValue.getAsString(AVKey.NAME)
|
||||||
|
t["posX"] = actor.hitbox.centeredX
|
||||||
|
t["posY"] = actor.hitbox.centeredY
|
||||||
|
|
||||||
|
t["veloX"] = actor.veloX
|
||||||
|
t["veloY"] = actor.veloY
|
||||||
|
|
||||||
|
t["width"] = actor.hitbox.width
|
||||||
|
t["height"] = actor.hitbox.height
|
||||||
|
|
||||||
|
val lumrgb: Int = actor.actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
|
||||||
|
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)
|
||||||
|
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ai.getNearestActor(nullable any criterion, nullable number range) */
|
||||||
|
class GetNearestActor() : LuaFunction() {
|
||||||
|
override fun call(): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun call(crit: LuaValue): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun call(crit: LuaValue, range: LuaValue): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ai.getNearestPlayer(nullable any criterion, nullable number range) */
|
||||||
|
class GetNearestPlayer() : LuaFunction() {
|
||||||
|
override fun call(): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun call(crit: LuaValue): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun call(crit: LuaValue, range: LuaValue): LuaValue {
|
||||||
|
return LuaValue.NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetX(val actor: ActorWithBody) : ZeroArgFunction() {
|
||||||
|
override fun call(): LuaValue {
|
||||||
|
return LuaValue.valueOf(actor.hitbox.centeredX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetY(val actor: ActorWithBody) : ZeroArgFunction() {
|
||||||
|
override fun call(): LuaValue {
|
||||||
|
return LuaValue.valueOf(actor.hitbox.centeredY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user