Partial utility bindings
This commit is contained in:
parent
d627526088
commit
658dffc832
@ -119,6 +119,9 @@ In addition to `add`, `multiply`, `merge` and `override` new merge methods are a
|
|||||||
* Example: Status controller scripts now get `monster` bindings when running in context of Monster's status controller, etc
|
* Example: Status controller scripts now get `monster` bindings when running in context of Monster's status controller, etc
|
||||||
* `behavior.behavior` third argument (specified commonly as `_ENV`) is ignored and can be omitted (set to nil)
|
* `behavior.behavior` third argument (specified commonly as `_ENV`) is ignored and can be omitted (set to nil)
|
||||||
* It was used solely to get Lua engine (Lua execution context), and could have been deprecated long time ago even in original engine, because there is now a way in original engine to get Lua engine when binding is called
|
* It was used solely to get Lua engine (Lua execution context), and could have been deprecated long time ago even in original engine, because there is now a way in original engine to get Lua engine when binding is called
|
||||||
|
* Added `sb.logFatal`, similar to other log functions
|
||||||
|
* `print(...)` now prints to both console (stdout) and logs
|
||||||
|
* `sb.log` functions now accept everything `string.format` accepts, and not only `%s` and `%%`
|
||||||
|
|
||||||
## Random
|
## Random
|
||||||
* Added `random:randn(deviation: double, mean: double): double`, returns normally distributed double, where `deviation` stands for [Standard deviation](https://en.wikipedia.org/wiki/Standard_deviation), and `mean` specifies middle point
|
* Added `random:randn(deviation: double, mean: double): double`, returns normally distributed double, where `deviation` stands for [Standard deviation](https://en.wikipedia.org/wiki/Standard_deviation), and `mean` specifies middle point
|
||||||
|
@ -374,6 +374,14 @@ open class ItemStack(val entry: ItemRegistry.Entry, val config: JsonObject, para
|
|||||||
return createDescriptor().toJson()
|
return createDescriptor().toJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toTable(allocator: TableFactory): Table? {
|
||||||
|
if (isEmpty) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return createDescriptor().toTable(allocator)
|
||||||
|
}
|
||||||
|
|
||||||
class Adapter(gson: Gson) : TypeAdapter<ItemStack>() {
|
class Adapter(gson: Gson) : TypeAdapter<ItemStack>() {
|
||||||
override fun write(out: JsonWriter, value: ItemStack?) {
|
override fun write(out: JsonWriter, value: ItemStack?) {
|
||||||
val json = value?.toJson()
|
val json = value?.toJson()
|
||||||
|
@ -206,8 +206,8 @@ class LuaEnvironment : StateContext {
|
|||||||
// TODO: NYI, maybe polyfill?
|
// TODO: NYI, maybe polyfill?
|
||||||
Utf8Lib.installInto(this, globals)
|
Utf8Lib.installInto(this, globals)
|
||||||
|
|
||||||
provideRootBindings(this)
|
// provideRootBindings(this)
|
||||||
provideUtilityBindings(this)
|
// provideUtilityBindings(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val scripts = ObjectArraySet<ChunkFactory>()
|
private val scripts = ObjectArraySet<ChunkFactory>()
|
||||||
|
@ -22,6 +22,8 @@ import ru.dbotthepony.kommons.util.KOptional
|
|||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
import ru.dbotthepony.kstarbound.defs.AssetPath
|
import ru.dbotthepony.kstarbound.defs.AssetPath
|
||||||
import ru.dbotthepony.kstarbound.json.InternedJsonElementAdapter
|
import ru.dbotthepony.kstarbound.json.InternedJsonElementAdapter
|
||||||
|
import ru.dbotthepony.kstarbound.lua.bindings.provideRootBindings
|
||||||
|
import ru.dbotthepony.kstarbound.lua.bindings.provideUtilityBindings
|
||||||
import ru.dbotthepony.kstarbound.util.random.random
|
import ru.dbotthepony.kstarbound.util.random.random
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.lang.ref.Cleaner
|
import java.lang.ref.Cleaner
|
||||||
@ -71,47 +73,8 @@ class LuaThread private constructor(
|
|||||||
LuaJNR.INSTANCE.luaopen_utf8(this.pointer)
|
LuaJNR.INSTANCE.luaopen_utf8(this.pointer)
|
||||||
this.storeGlobal("utf8")
|
this.storeGlobal("utf8")
|
||||||
|
|
||||||
push {
|
provideUtilityBindings(this)
|
||||||
LOGGER.info(it.nextString())
|
provideRootBindings(this)
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
storeGlobal("__print")
|
|
||||||
|
|
||||||
push {
|
|
||||||
val path = it.nextString()
|
|
||||||
|
|
||||||
try {
|
|
||||||
load(Starbound.readLuaScript(path).join(), "@$path")
|
|
||||||
1
|
|
||||||
} catch (err: Exception) {
|
|
||||||
LOGGER.error("Exception loading Lua script $path", err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
storeGlobal("__require")
|
|
||||||
|
|
||||||
push {
|
|
||||||
push(random.nextDouble())
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
storeGlobal("__random_double")
|
|
||||||
|
|
||||||
push {
|
|
||||||
push(random.nextLong(it.nextLong(), it.nextLong()))
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
storeGlobal("__random_long")
|
|
||||||
|
|
||||||
push {
|
|
||||||
random = random(it.nextLong())
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
storeGlobal("__random_seed")
|
|
||||||
|
|
||||||
load(globalScript, "@starbound.jar!/scripts/global.lua")
|
load(globalScript, "@starbound.jar!/scripts/global.lua")
|
||||||
call()
|
call()
|
||||||
@ -818,6 +781,10 @@ class LuaThread private constructor(
|
|||||||
return this@LuaThread.typeAt(position)
|
return this@LuaThread.typeAt(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hasNext(): Boolean {
|
||||||
|
return position <= top
|
||||||
|
}
|
||||||
|
|
||||||
fun nextString(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): String {
|
fun nextString(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): String {
|
||||||
if (position !in 1 ..this.top)
|
if (position !in 1 ..this.top)
|
||||||
throw IllegalArgumentException("bad argument #$position: string expected, got nil")
|
throw IllegalArgumentException("bad argument #$position: string expected, got nil")
|
||||||
@ -851,6 +818,13 @@ class LuaThread private constructor(
|
|||||||
return value ?: throw IllegalArgumentException("bad argument #$position: anything expected, got ${this@LuaThread.typeAt(position)}")
|
return value ?: throw IllegalArgumentException("bad argument #$position: anything expected, got ${this@LuaThread.typeAt(position)}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun nextOptionalJson(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): JsonElement? {
|
||||||
|
if (position !in 1 ..this.top)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return this@LuaThread.getJson(position, limit = limit)
|
||||||
|
}
|
||||||
|
|
||||||
fun nextTable(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): JsonObject {
|
fun nextTable(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): JsonObject {
|
||||||
if (position !in 1 ..this.top)
|
if (position !in 1 ..this.top)
|
||||||
throw IllegalArgumentException("bad argument #$position: table expected, got nil")
|
throw IllegalArgumentException("bad argument #$position: table expected, got nil")
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
package ru.dbotthepony.kstarbound.lua.bindings
|
package ru.dbotthepony.kstarbound.lua.bindings
|
||||||
|
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
import org.apache.logging.log4j.LogManager
|
import com.google.gson.JsonNull
|
||||||
import org.classdump.luna.ByteString
|
import org.classdump.luna.ByteString
|
||||||
import org.classdump.luna.Table
|
import org.classdump.luna.Table
|
||||||
import org.classdump.luna.runtime.ExecutionContext
|
import org.classdump.luna.runtime.ExecutionContext
|
||||||
|
import ru.dbotthepony.kommons.util.XXHash32
|
||||||
|
import ru.dbotthepony.kommons.util.XXHash64
|
||||||
import ru.dbotthepony.kstarbound.math.vector.Vector2d
|
import ru.dbotthepony.kstarbound.math.vector.Vector2d
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
import ru.dbotthepony.kstarbound.defs.PerlinNoiseParameters
|
import ru.dbotthepony.kstarbound.defs.PerlinNoiseParameters
|
||||||
import ru.dbotthepony.kstarbound.json.JsonPath
|
import ru.dbotthepony.kstarbound.json.JsonPath
|
||||||
import ru.dbotthepony.kstarbound.lua.LuaEnvironment
|
import ru.dbotthepony.kstarbound.lua.LuaEnvironment
|
||||||
|
import ru.dbotthepony.kstarbound.lua.LuaThread
|
||||||
|
import ru.dbotthepony.kstarbound.lua.LuaThread.Companion
|
||||||
|
import ru.dbotthepony.kstarbound.lua.LuaType
|
||||||
import ru.dbotthepony.kstarbound.lua.from
|
import ru.dbotthepony.kstarbound.lua.from
|
||||||
import ru.dbotthepony.kstarbound.lua.get
|
import ru.dbotthepony.kstarbound.lua.get
|
||||||
import ru.dbotthepony.kstarbound.lua.luaFunction
|
import ru.dbotthepony.kstarbound.lua.luaFunction
|
||||||
import ru.dbotthepony.kstarbound.lua.luaFunctionArray
|
import ru.dbotthepony.kstarbound.lua.luaFunctionArray
|
||||||
import ru.dbotthepony.kstarbound.lua.luaFunctionN
|
import ru.dbotthepony.kstarbound.lua.luaFunctionN
|
||||||
import ru.dbotthepony.kstarbound.lua.nextOptionalFloat
|
|
||||||
import ru.dbotthepony.kstarbound.lua.set
|
import ru.dbotthepony.kstarbound.lua.set
|
||||||
import ru.dbotthepony.kstarbound.lua.toByteString
|
|
||||||
import ru.dbotthepony.kstarbound.lua.toJson
|
import ru.dbotthepony.kstarbound.lua.toJson
|
||||||
import ru.dbotthepony.kstarbound.lua.toJsonFromLua
|
|
||||||
import ru.dbotthepony.kstarbound.lua.toVector2d
|
import ru.dbotthepony.kstarbound.lua.toVector2d
|
||||||
import ru.dbotthepony.kstarbound.lua.userdata.LuaPerlinNoise
|
import ru.dbotthepony.kstarbound.lua.userdata.LuaPerlinNoise
|
||||||
import ru.dbotthepony.kstarbound.lua.userdata.LuaRandomGenerator
|
import ru.dbotthepony.kstarbound.lua.userdata.LuaRandomGenerator
|
||||||
@ -28,26 +30,17 @@ import ru.dbotthepony.kstarbound.util.SBPattern
|
|||||||
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
|
import ru.dbotthepony.kstarbound.util.random.AbstractPerlinNoise
|
||||||
import ru.dbotthepony.kstarbound.util.random.nextNormalDouble
|
import ru.dbotthepony.kstarbound.util.random.nextNormalDouble
|
||||||
import ru.dbotthepony.kstarbound.util.random.random
|
import ru.dbotthepony.kstarbound.util.random.random
|
||||||
import ru.dbotthepony.kstarbound.util.random.staticRandom32
|
import ru.dbotthepony.kstarbound.util.random.staticRandom32FromList
|
||||||
|
import ru.dbotthepony.kstarbound.util.random.staticRandom64FromList
|
||||||
import ru.dbotthepony.kstarbound.util.random.staticRandomDouble
|
import ru.dbotthepony.kstarbound.util.random.staticRandomDouble
|
||||||
|
import ru.dbotthepony.kstarbound.util.random.staticRandomDoubleFromList
|
||||||
|
import ru.dbotthepony.kstarbound.util.random.staticRandomIntFromList
|
||||||
import ru.dbotthepony.kstarbound.util.random.staticRandomLong
|
import ru.dbotthepony.kstarbound.util.random.staticRandomLong
|
||||||
|
import ru.dbotthepony.kstarbound.util.random.staticRandomLongFromList
|
||||||
|
import ru.dbotthepony.kstarbound.util.random.toBytes
|
||||||
import ru.dbotthepony.kstarbound.util.toStarboundString
|
import ru.dbotthepony.kstarbound.util.toStarboundString
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.random.RandomGenerator
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
private val LOGGER = LogManager.getLogger()
|
|
||||||
|
|
||||||
private val logInfo = luaFunctionN("logInfo") { args ->
|
|
||||||
LOGGER.info(args.nextString().toString().format(*args.copyRemaining()))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val logWarn = luaFunctionN("logWarn") { args ->
|
|
||||||
LOGGER.warn(args.nextString().toString().format(*args.copyRemaining()))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val logError = luaFunctionN("logError") { args ->
|
|
||||||
LOGGER.error(args.nextString().toString().format(*args.copyRemaining()))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val interpolateSinEase = luaFunctionArray { args ->
|
private val interpolateSinEase = luaFunctionArray { args ->
|
||||||
if (args.size < 3)
|
if (args.size < 3)
|
||||||
@ -71,75 +64,224 @@ private val interpolateSinEase = luaFunctionArray { args ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val replaceTags = luaFunction { string: ByteString, tags: Table ->
|
// TODO: Lua-side implementation for better performance?
|
||||||
returnBuffer.setTo(SBPattern.of(string.toString()).resolveOrSkip({ tags[it]?.toString() }).toByteString())
|
private fun replaceTags(args: LuaThread.ArgStack): Int {
|
||||||
|
val string = args.nextString()
|
||||||
|
val tagsList = args.lua
|
||||||
|
.readTable(
|
||||||
|
args.position++,
|
||||||
|
{ getString(it) ?: throw IllegalStateException("Tags table contain non-string keys") },
|
||||||
|
{ getString(it) ?: throw IllegalStateException("Tags table contain non-string values") }
|
||||||
|
) ?: throw IllegalArgumentException("bad argument #2: table expected, got ${args.peek(args.position - 1)}")
|
||||||
|
|
||||||
|
val tags = tagsList.toMap()
|
||||||
|
|
||||||
|
args.lua.push(SBPattern.of(string).resolveOrSkip({ tags[it] }))
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private val makePerlinSource = luaFunction { settings: Table ->
|
private val makePerlinSource = luaFunction { settings: Table ->
|
||||||
returnBuffer.setTo(LuaPerlinNoise(AbstractPerlinNoise.of(Starbound.gson.fromJson(settings.toJson(), PerlinNoiseParameters::class.java))))
|
returnBuffer.setTo(LuaPerlinNoise(AbstractPerlinNoise.of(Starbound.gson.fromJson(settings.toJson(), PerlinNoiseParameters::class.java))))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val staticRandomI32 = luaFunctionArray {
|
private fun hash32(args: LuaThread.ArgStack): Int {
|
||||||
returnBuffer.setTo(staticRandom32(*it))
|
val digest = XXHash32(2938728349.toInt())
|
||||||
}
|
|
||||||
|
|
||||||
private val staticRandomDouble = luaFunctionArray {
|
while (args.hasNext()) {
|
||||||
returnBuffer.setTo(staticRandomDouble(*it))
|
when (args.peek()) {
|
||||||
}
|
LuaType.BOOLEAN -> digest.update(if (args.nextBoolean()) 1 else 0)
|
||||||
|
LuaType.NUMBER -> toBytes(digest::update, args.nextDouble())
|
||||||
private val staticRandomDoubleRange = luaFunctionN("staticRandomDoubleRange") {
|
LuaType.STRING -> digest.update(args.nextString().toByteArray(Charsets.UTF_8))
|
||||||
val min = it.nextFloat()
|
else -> throw IllegalArgumentException("bad argument #${args.position} to staticRandomI32")
|
||||||
val max = it.nextFloat()
|
}
|
||||||
returnBuffer.setTo(staticRandomDouble(*it.copyRemaining()) * (max - min) + min)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val staticRandomI32Range = luaFunctionN("staticRandomI32Range") {
|
|
||||||
val min = it.nextInteger()
|
|
||||||
val max = it.nextInteger()
|
|
||||||
returnBuffer.setTo(staticRandomLong(min, max, *it.copyRemaining()))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val mergeJson = luaFunction { a: Any?, b: Any? ->
|
|
||||||
returnBuffer.setTo(from(ru.dbotthepony.kstarbound.json.mergeJson(toJsonFromLua(a), toJsonFromLua(b))))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun provideUtilityBindings(lua: LuaEnvironment) {
|
|
||||||
val table = lua.newTable()
|
|
||||||
lua.globals["sb"] = table
|
|
||||||
|
|
||||||
table["makeUuid"] = luaFunction {
|
|
||||||
returnBuffer.setTo(UUID(lua.random.nextLong(), lua.random.nextLong()).toStarboundString().toByteString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table["logInfo"] = logInfo
|
return digest.digestAsInt()
|
||||||
table["logWarn"] = logWarn
|
}
|
||||||
table["logError"] = logError
|
|
||||||
|
|
||||||
table["nrand"] = luaFunctionN("nrand") { args ->
|
private fun hash64(args: LuaThread.ArgStack): Long {
|
||||||
val stdev = args.nextOptionalFloat() ?: 1.0
|
val digest = XXHash64(1997293021376312589L)
|
||||||
val mean = args.nextOptionalFloat() ?: 0.0
|
|
||||||
lua.random.nextNormalDouble(stdev, mean)
|
while (args.hasNext()) {
|
||||||
|
when (args.peek()) {
|
||||||
|
LuaType.BOOLEAN -> digest.update(if (args.nextBoolean()) 1 else 0)
|
||||||
|
LuaType.NUMBER -> toBytes(digest::update, args.nextDouble())
|
||||||
|
LuaType.STRING -> digest.update(args.nextString().toByteArray(Charsets.UTF_8))
|
||||||
|
else -> throw IllegalArgumentException("bad argument #${args.position} to staticRandomI32")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table["print"] = lua.globals["tostring"]
|
return digest.digestAsLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun staticRandomI32(args: LuaThread.ArgStack): Int {
|
||||||
|
args.lua.push(hash32(args).toLong())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun staticRandomI64(args: LuaThread.ArgStack): Int {
|
||||||
|
args.lua.push(hash64(args))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun staticRandomDouble(args: LuaThread.ArgStack): Int {
|
||||||
|
args.lua.push(hash64(args).ushr(11) * 1.1102230246251565E-16)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun staticRandomDoubleRange(args: LuaThread.ArgStack): Int {
|
||||||
|
val min = args.nextDouble()
|
||||||
|
val max = args.nextDouble()
|
||||||
|
val double = hash64(args).ushr(11) * 1.1102230246251565E-16
|
||||||
|
args.lua.push(double * (max - min) + min)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: incorrect.
|
||||||
|
private fun staticRandomI64Range(args: LuaThread.ArgStack): Int {
|
||||||
|
val min = args.nextDouble()
|
||||||
|
val max = args.nextDouble()
|
||||||
|
val double = hash64(args).ushr(11) * 1.1102230246251565E-16
|
||||||
|
args.lua.push((min + (max - min + 1L) * double).toLong())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: incorrect.
|
||||||
|
private fun staticRandomI32Range(args: LuaThread.ArgStack): Int {
|
||||||
|
val min = args.nextDouble()
|
||||||
|
val max = args.nextDouble()
|
||||||
|
val double = hash64(args).ushr(11) * 1.1102230246251565E-16
|
||||||
|
args.lua.push((min + (max - min + 1L) * double).toInt().toLong())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Lua-side implementation for better performance?
|
||||||
|
private fun makeUuid(args: LuaThread.ArgStack): Int {
|
||||||
|
args.lua.push(UUID(args.lua.random.nextLong(), args.lua.random.nextLong()).toStarboundString())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nrand(args: LuaThread.ArgStack): Int {
|
||||||
|
val stdev = args.nextOptionalDouble() ?: 1.0
|
||||||
|
val mean = args.nextOptionalDouble() ?: 0.0
|
||||||
|
args.lua.push(args.lua.random.nextNormalDouble(stdev, mean))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Lua-side implementation for better performance?
|
||||||
|
private fun jsonMerge(args: LuaThread.ArgStack): Int {
|
||||||
|
val a = args.nextOptionalJson() ?: JsonNull.INSTANCE
|
||||||
|
val b = args.nextOptionalJson() ?: JsonNull.INSTANCE
|
||||||
|
|
||||||
|
args.lua.push(ru.dbotthepony.kstarbound.json.mergeJson(a, b))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Lua-side implementation for better performance?
|
||||||
|
private fun jsonQuery(args: LuaThread.ArgStack): Int {
|
||||||
|
val json = args.nextOptionalJson() ?: JsonNull.INSTANCE
|
||||||
|
val path = args.nextString()
|
||||||
|
val default = args.nextOptionalJson() ?: JsonNull.INSTANCE
|
||||||
|
|
||||||
|
args.lua.push(JsonPath.query(path).get(json, default))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun provideUtilityBindings(lua: LuaThread) {
|
||||||
|
with(lua) {
|
||||||
|
push {
|
||||||
|
LuaThread.LOGGER.info(it.nextString())
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__print")
|
||||||
|
|
||||||
|
push {
|
||||||
|
LuaThread.LOGGER.warn(it.nextString())
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__print_warn")
|
||||||
|
|
||||||
|
push {
|
||||||
|
LuaThread.LOGGER.error(it.nextString())
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__print_error")
|
||||||
|
|
||||||
|
push {
|
||||||
|
LuaThread.LOGGER.fatal(it.nextString())
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__print_fatal")
|
||||||
|
|
||||||
|
push {
|
||||||
|
val path = it.nextString()
|
||||||
|
|
||||||
|
try {
|
||||||
|
load(Starbound.readLuaScript(path).join(), "@$path")
|
||||||
|
1
|
||||||
|
} catch (err: Exception) {
|
||||||
|
LuaThread.LOGGER.error("Exception loading Lua script $path", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__require")
|
||||||
|
|
||||||
|
push {
|
||||||
|
push(random.nextDouble())
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__random_double")
|
||||||
|
|
||||||
|
push {
|
||||||
|
push(random.nextLong(it.nextLong(), it.nextLong()))
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__random_long")
|
||||||
|
|
||||||
|
push {
|
||||||
|
random = random(it.nextLong())
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
storeGlobal("__random_seed")
|
||||||
|
}
|
||||||
|
|
||||||
|
lua.pushTable()
|
||||||
|
lua.dup()
|
||||||
|
lua.storeGlobal("sb")
|
||||||
|
|
||||||
|
lua.setTableValue("makeUuid", ::makeUuid)
|
||||||
|
lua.setTableValue("nrand", ::nrand)
|
||||||
|
lua.setTableValue("jsonMerge", ::jsonMerge)
|
||||||
|
lua.setTableValue("jsonQuery", ::jsonQuery)
|
||||||
|
|
||||||
|
lua.setTableValue("replaceTags", ::replaceTags)
|
||||||
|
|
||||||
|
lua.setTableValue("staticRandomI32", ::staticRandomI32)
|
||||||
|
lua.setTableValue("staticRandomI32Range", ::staticRandomI32Range)
|
||||||
|
lua.setTableValue("staticRandomI64", ::staticRandomI64)
|
||||||
|
lua.setTableValue("staticRandomI64Range", ::staticRandomI64Range)
|
||||||
|
lua.setTableValue("staticRandomDouble", ::staticRandomDouble)
|
||||||
|
lua.setTableValue("staticRandomDoubleRange", ::staticRandomDoubleRange)
|
||||||
|
|
||||||
|
/*table["print"] = lua.globals["tostring"]
|
||||||
table["printJson"] = lua.globals["tostring"]
|
table["printJson"] = lua.globals["tostring"]
|
||||||
table["interpolateSinEase"] = interpolateSinEase
|
table["interpolateSinEase"] = interpolateSinEase
|
||||||
table["replaceTags"] = replaceTags
|
|
||||||
table["makeRandomSource"] = luaFunction { seed: Long? ->
|
table["makeRandomSource"] = luaFunction { seed: Long? ->
|
||||||
returnBuffer.setTo(LuaRandomGenerator(random(seed ?: lua.random.nextLong())))
|
returnBuffer.setTo(LuaRandomGenerator(random(seed ?: lua.random.nextLong())))
|
||||||
}
|
}
|
||||||
|
|
||||||
table["makePerlinSource"] = makePerlinSource
|
table["makePerlinSource"] = makePerlinSource*/
|
||||||
|
|
||||||
table["staticRandomI32"] = staticRandomI32
|
lua.pop()
|
||||||
table["staticRandomI64"] = staticRandomI32
|
|
||||||
table["staticRandomDouble"] = staticRandomDouble
|
|
||||||
|
|
||||||
table["staticRandomDoubleRange"] = staticRandomDoubleRange
|
|
||||||
table["staticRandomI32Range"] = staticRandomI32Range
|
|
||||||
table["staticRandomI64Range"] = staticRandomI32Range
|
|
||||||
|
|
||||||
table["jsonMerge"] = mergeJson
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun provideConfigBindings(lua: LuaEnvironment, lookup: ExecutionContext.(path: JsonPath, ifMissing: Any?) -> Any?) {
|
fun provideConfigBindings(lua: LuaEnvironment, lookup: ExecutionContext.(path: JsonPath, ifMissing: Any?) -> Any?) {
|
||||||
|
@ -35,19 +35,19 @@ fun random(seed: Long = System.nanoTime()): RandomGenerator {
|
|||||||
*/
|
*/
|
||||||
val threadLocalRandom: RandomGenerator by ThreadLocal.withInitial { random() }
|
val threadLocalRandom: RandomGenerator by ThreadLocal.withInitial { random() }
|
||||||
|
|
||||||
private fun toBytes(accept: ByteConsumer, value: Short) {
|
fun toBytes(accept: ByteConsumer, value: Short) {
|
||||||
accept.accept(value.toByte())
|
accept.accept(value.toByte())
|
||||||
accept.accept((value.toInt() ushr 8).toByte())
|
accept.accept((value.toInt() ushr 8).toByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toBytes(accept: ByteConsumer, value: Int) {
|
fun toBytes(accept: ByteConsumer, value: Int) {
|
||||||
accept.accept(value.toByte())
|
accept.accept(value.toByte())
|
||||||
accept.accept((value ushr 8).toByte())
|
accept.accept((value ushr 8).toByte())
|
||||||
accept.accept((value ushr 16).toByte())
|
accept.accept((value ushr 16).toByte())
|
||||||
accept.accept((value ushr 24).toByte())
|
accept.accept((value ushr 24).toByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toBytes(accept: ByteConsumer, value: Long) {
|
fun toBytes(accept: ByteConsumer, value: Long) {
|
||||||
accept.accept(value.toByte())
|
accept.accept(value.toByte())
|
||||||
accept.accept((value ushr 8).toByte())
|
accept.accept((value ushr 8).toByte())
|
||||||
accept.accept((value ushr 16).toByte())
|
accept.accept((value ushr 16).toByte())
|
||||||
@ -58,15 +58,19 @@ private fun toBytes(accept: ByteConsumer, value: Long) {
|
|||||||
accept.accept((value ushr 56).toByte())
|
accept.accept((value ushr 56).toByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toBytes(accept: ByteConsumer, value: Double) {
|
fun toBytes(accept: ByteConsumer, value: Double) {
|
||||||
toBytes(accept, value.toBits())
|
toBytes(accept, value.toBits())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toBytes(accept: ByteConsumer, value: Float) {
|
fun toBytes(accept: ByteConsumer, value: Float) {
|
||||||
toBytes(accept, value.toBits())
|
toBytes(accept, value.toBits())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun staticRandom32(vararg values: Any?): Int {
|
fun staticRandom32(vararg values: Any?): Int {
|
||||||
|
return staticRandom32FromList(values.asIterable())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun staticRandom32FromList(values: Iterable<Any?>): Int {
|
||||||
val digest = XXHash32(2938728349.toInt())
|
val digest = XXHash32(2938728349.toInt())
|
||||||
|
|
||||||
for (value in values) {
|
for (value in values) {
|
||||||
@ -96,6 +100,10 @@ fun staticRandomDouble(vararg values: Any?): Double {
|
|||||||
return staticRandom64(*values).ushr(11) * 1.1102230246251565E-16
|
return staticRandom64(*values).ushr(11) * 1.1102230246251565E-16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun staticRandomDoubleFromList(values: Iterable<Any?>): Double {
|
||||||
|
return staticRandom64FromList(values).ushr(11) * 1.1102230246251565E-16
|
||||||
|
}
|
||||||
|
|
||||||
fun staticRandomInt(min: Int, max: Int, vararg values: Any?): Int {
|
fun staticRandomInt(min: Int, max: Int, vararg values: Any?): Int {
|
||||||
val hash = staticRandomDouble(*values)
|
val hash = staticRandomDouble(*values)
|
||||||
return (min + (max - min + 1) * hash).toInt()
|
return (min + (max - min + 1) * hash).toInt()
|
||||||
@ -106,7 +114,21 @@ fun staticRandomLong(min: Long, max: Long, vararg values: Any?): Long {
|
|||||||
return (min + (max - min + 1L) * hash).toLong()
|
return (min + (max - min + 1L) * hash).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun staticRandomIntFromList(min: Int, max: Int, values: Iterable<Any?>): Int {
|
||||||
|
val hash = staticRandomDoubleFromList(values)
|
||||||
|
return (min + (max - min + 1) * hash).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun staticRandomLongFromList(min: Long, max: Long, values: Iterable<Any?>): Long {
|
||||||
|
val hash = staticRandomDoubleFromList(values)
|
||||||
|
return (min + (max - min + 1L) * hash).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
fun staticRandom64(vararg values: Any?): Long {
|
fun staticRandom64(vararg values: Any?): Long {
|
||||||
|
return staticRandom64FromList(values.asIterable())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun staticRandom64FromList(values: Iterable<Any?>): Long {
|
||||||
val digest = XXHash64(1997293021376312589L)
|
val digest = XXHash64(1997293021376312589L)
|
||||||
|
|
||||||
for (value in values) {
|
for (value in values) {
|
||||||
|
@ -147,6 +147,10 @@ end
|
|||||||
|
|
||||||
do
|
do
|
||||||
local __print = __print
|
local __print = __print
|
||||||
|
local __print_warn = __print_warn
|
||||||
|
local __print_error = __print_error
|
||||||
|
local __print_fatal = __print_fatal
|
||||||
|
local format = string.format
|
||||||
|
|
||||||
function print(...)
|
function print(...)
|
||||||
local values = {}
|
local values = {}
|
||||||
@ -158,6 +162,22 @@ do
|
|||||||
|
|
||||||
__print(table.concat(values, '\t'))
|
__print(table.concat(values, '\t'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sb.logInfo(text, ...)
|
||||||
|
__print(format(text, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function sb.logWarn(text, ...)
|
||||||
|
__print_warn(format(text, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function sb.logError(text, ...)
|
||||||
|
__print_error(format(text, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function sb.logFatal(text, ...)
|
||||||
|
__print_fatal(format(text, ...))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -258,3 +278,5 @@ do
|
|||||||
__random_seed(floor(seed))
|
__random_seed(floor(seed))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user