From aa4f73bc01e71b1102b2008a9484abe9e6314630 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 30 Mar 2023 10:56:33 +0700 Subject: [PATCH] root.questConfig --- .../dbotthepony/kstarbound/ObjectRegistry.kt | 32 +++++++++++++++++-- .../ru/dbotthepony/kstarbound/Starbound.kt | 8 ++++- .../ru/dbotthepony/kstarbound/lua/LuaState.kt | 9 ++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/ObjectRegistry.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/ObjectRegistry.kt index f989b5bd..aeeb09db 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/ObjectRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/ObjectRegistry.kt @@ -16,6 +16,7 @@ import org.apache.logging.log4j.LogManager import ru.dbotthepony.kstarbound.api.IStarboundFile import ru.dbotthepony.kstarbound.lua.LuaState import ru.dbotthepony.kstarbound.util.PathStack +import ru.dbotthepony.kstarbound.util.set import java.util.* import kotlin.reflect.KClass @@ -23,17 +24,44 @@ inline fun ObjectRegistry(name: String, noinline key: ((T) -> return ObjectRegistry(T::class, name, key, intKey) } +private fun merge(source: JsonObject, destination: JsonObject): JsonObject { + for ((k, v) in source.entrySet()) { + if (!destination.has(k)) { + destination[k] = v.deepCopy() + } else if (destination[k] is JsonObject && v is JsonObject) { + merge(v, destination[k] as JsonObject) + } + } + + return destination +} + class RegistryObject(val value: T, private val json: JsonObject, val file: IStarboundFile, val gson: Gson, val pathStack: PathStack) { + /** + * Возвращает копию оригинальной JSON структуры, из которой был спрототипирован [value] + * + * Более полная JSON структура (обработанная) доступа из метода [toJson] + */ fun copy(): JsonObject { return json.deepCopy() } fun push(lua: LuaState) { - lua.push(json) + lua.push(toJson()) } fun push(lua: LuaState.ArgStack) { - lua.push(json) + lua.push(toJson()) + } + + /** + * Возвращает полную (обработанную) структуру [JsonObject] объекта [value] + * + * Полнота определяется тем, что [value] может иметь свойства по умолчанию, которые не указаны + * в оригинальной JSON структуре. [copy] не вернёт данные свойства по умолчанию, а [toJson] вернёт. + */ + fun toJson(): JsonObject { + return merge(json, gson.toJsonTree(value) as JsonObject) } override fun equals(other: Any?): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt index 321cb6c5..791f0384 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt @@ -438,7 +438,7 @@ class Starbound : ISBFileLocator { state.setTableFunction("npcConfig", this) { args -> // Json root.npcConfig(String npcType) val name = args.getString() - args.lua.push(npcTypes[name]?.copy() ?: throw NoSuchElementException("No such NPC type $name")) + args.push(npcTypes[name] ?: throw NoSuchElementException("No such NPC type $name")) 1 } @@ -608,6 +608,12 @@ class Starbound : ISBFileLocator { 1 } + state.setTableFunction("questConfig", this) { args -> + val name = args.getString() + args.push(questTemplates[name] ?: throw NoSuchElementException("No such quest template $name")) + 1 + } + state.pop() state.load(polyfill, "@starbound.jar!/scripts/polyfill.lua") diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaState.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaState.kt index 67c5eec4..619384f2 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaState.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaState.kt @@ -19,6 +19,7 @@ import jnr.ffi.Pointer import org.apache.logging.log4j.LogManager import org.lwjgl.system.MemoryStack import org.lwjgl.system.MemoryUtil +import ru.dbotthepony.kstarbound.RegistryObject import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.io.json.InternedJsonElementAdapter import ru.dbotthepony.kvector.vector.nint.Vector2i @@ -595,6 +596,7 @@ class LuaState private constructor(private val pointer: Pointer, val stringInter fun push(value: Boolean) = this@LuaState.push(value) fun push(value: String?) = this@LuaState.push(value) fun push(value: JsonElement?) = this@LuaState.push(value) + fun push(value: RegistryObject<*>?) = this@LuaState.push(value) } /** @@ -1056,6 +1058,13 @@ class LuaState private constructor(private val pointer: Pointer, val stringInter } } + fun push(value: RegistryObject<*>?) { + if (value == null) + push() + else + push(value.toJson()) + } + companion object { private val LOGGER = LogManager.getLogger()