root.itemConfig и root.createItem

This commit is contained in:
DBotThePony 2023-03-29 18:19:50 +07:00
parent eaa0ce58bf
commit 90040aec3a
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 79 additions and 21 deletions

View File

@ -69,6 +69,7 @@ import ru.dbotthepony.kstarbound.util.ItemStack
import ru.dbotthepony.kstarbound.util.PathStack import ru.dbotthepony.kstarbound.util.PathStack
import ru.dbotthepony.kstarbound.util.SBPattern import ru.dbotthepony.kstarbound.util.SBPattern
import ru.dbotthepony.kstarbound.util.WriteOnce import ru.dbotthepony.kstarbound.util.WriteOnce
import ru.dbotthepony.kstarbound.util.set
import ru.dbotthepony.kstarbound.util.traverseJsonPath import ru.dbotthepony.kstarbound.util.traverseJsonPath
import ru.dbotthepony.kvector.vector.nint.Vector2i import ru.dbotthepony.kvector.vector.nint.Vector2i
import java.io.* import java.io.*
@ -77,7 +78,6 @@ import java.lang.ref.WeakReference
import java.text.DateFormat import java.text.DateFormat
import java.time.Duration import java.time.Duration
import java.util.* import java.util.*
import java.util.concurrent.locks.LockSupport
import java.util.function.BiConsumer import java.util.function.BiConsumer
import java.util.function.BinaryOperator import java.util.function.BinaryOperator
import java.util.function.Function import java.util.function.Function
@ -462,7 +462,47 @@ class Starbound : ISBFileLocator {
state.setTableFunction("itemHasTag", this) { args -> state.setTableFunction("itemHasTag", this) { args ->
val name = args.getString() val name = args.getString()
val tag = args.getString() val tag = args.getString()
args.lua.push((items[name]?.value?.itemTags ?: throw NoSuchElementException("No such item $name")).contains(tag)) args.push((items[name]?.value?.itemTags ?: throw NoSuchElementException("No such item $name")).contains(tag))
1
}
// TODO: генерация
state.setTableFunction("itemConfig", this) { args ->
// Json root.itemConfig(ItemDescriptor descriptor, [float level], [unsigned seed])
val item = item(args.getValue())
val level = if (args.hasSomethingAt()) args.getDouble() else null
val seed = if (args.hasSomethingAt()) args.getLong() else null
if (item.isEmpty) {
args.push()
} else {
args.push(JsonObject().also {
it["directory"] = item.item!!.file.computeDirectory()
it["config"] = item.item!!.copy()
it["parameters"] = item.parameters
})
}
1
}
// TODO: генерация
state.setTableFunction("createItem", this) { args ->
// ItemDescriptor root.createItem(ItemDescriptor descriptor, [float level], [unsigned seed])
val item = item(args.getValue())
val level = if (args.hasSomethingAt()) args.getDouble() else null
val seed = if (args.hasSomethingAt()) args.getLong() else null
if (item.isEmpty) {
args.push()
return@setTableFunction 1
}
if (item.maxStackSize < item.size) {
item.size = item.maxStackSize
}
args.push(gson.toJsonTree(item))
1 1
} }

View File

@ -461,6 +461,20 @@ class LuaState private constructor(private val pointer: Pointer, val stringInter
val lua get() = this@LuaState val lua get() = this@LuaState
var position = 1 var position = 1
fun hasSomethingAt(position: Int): Boolean {
check(position in 1 ..this.top) { "JVM code error: Invalid argument position: $position" }
return this@LuaState.typeAt() != LuaType.NONE
}
fun hasSomethingAt(): Boolean {
if (hasSomethingAt(this.position + 1)) {
return true
}
this.position++
return false
}
fun getString(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): String { fun getString(position: Int = this.position++, limit: Long = DEFAULT_STRING_LIMIT): String {
check(position in 1 ..this.top) { "JVM code error: Invalid argument position: $position" } check(position in 1 ..this.top) { "JVM code error: Invalid argument position: $position" }
return this@LuaState.getString(position, limit = limit) return this@LuaState.getString(position, limit = limit)

View File

@ -20,10 +20,10 @@ class AvatarBag(val avatar: Avatar, val config: InventoryConfig.Bag, val filter:
fun mergeFrom(value: ItemStack, simulate: Boolean) { fun mergeFrom(value: ItemStack, simulate: Boolean) {
if (item == null) { if (item == null) {
if (!simulate) { if (!simulate) {
item = value.copy().also { it.count = value.count.coerceAtMost(value.item!!.value.maxStack) } item = value.copy().also { it.size = value.size.coerceAtMost(value.item!!.value.maxStack) }
} }
value.count -= value.item!!.value.maxStack value.size -= value.item!!.value.maxStack
} else { } else {
item!!.mergeFrom(value, simulate) item!!.mergeFrom(value, simulate)
} }

View File

@ -10,6 +10,7 @@ import com.google.gson.stream.JsonWriter
import ru.dbotthepony.kstarbound.RegistryObject import ru.dbotthepony.kstarbound.RegistryObject
import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.item.api.IItemDefinition import ru.dbotthepony.kstarbound.defs.item.api.IItemDefinition
import ru.dbotthepony.kstarbound.io.json.consumeNull
class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, count: Long, val parameters: JsonObject, marker: Unit) { class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, count: Long, val parameters: JsonObject, marker: Unit) {
constructor(item: RegistryObject<IItemDefinition>, count: Long = 1L, parameters: JsonObject = JsonObject()) : this(item, count, parameters, Unit) constructor(item: RegistryObject<IItemDefinition>, count: Long = 1L, parameters: JsonObject = JsonObject()) : this(item, count, parameters, Unit)
@ -17,9 +18,9 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
var item: RegistryObject<IItemDefinition>? = item var item: RegistryObject<IItemDefinition>? = item
private set private set
var count = count var size = count
set(value) { set(value) {
if (field == 0L) if (field == 0L || item == null)
return return
field = value.coerceAtLeast(0L) field = value.coerceAtLeast(0L)
@ -30,17 +31,20 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
} }
val isEmpty: Boolean val isEmpty: Boolean
get() = count <= 0 || item == null get() = size <= 0 || item == null
val isNotEmpty: Boolean val isNotEmpty: Boolean
get() = count > 0 && item != null get() = size > 0 && item != null
val maxStackSize: Long
get() = item?.value?.maxStack ?: 0L
fun grow(amount: Long) { fun grow(amount: Long) {
count += amount size += amount
} }
fun shrink(amount: Long) { fun shrink(amount: Long) {
count -= amount size -= amount
} }
/** /**
@ -56,12 +60,12 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
fun mergeFrom(other: ItemStack, simulate: Boolean) { fun mergeFrom(other: ItemStack, simulate: Boolean) {
if (isStackable(other)) { if (isStackable(other)) {
val newCount = (count + other.count).coerceAtMost(item!!.value.maxStack) val newCount = (size + other.size).coerceAtMost(item!!.value.maxStack)
val diff = newCount - count val diff = newCount - size
other.count -= diff other.size -= diff
if (!simulate) if (!simulate)
count = newCount size = newCount
} }
} }
@ -72,11 +76,11 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
if (isEmpty) if (isEmpty)
return other.isEmpty return other.isEmpty
return other.count == count && other.item == item return other.size == size && other.item == item
} }
fun isStackable(other: ItemStack): Boolean { fun isStackable(other: ItemStack): Boolean {
return count != 0L && other.count != 0L && item!!.value.maxStack < count && other.item == item && other.parameters == parameters return size != 0L && other.size != 0L && item!!.value.maxStack < size && other.item == item && other.parameters == parameters
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@ -86,7 +90,7 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
if (isEmpty) if (isEmpty)
return other.isEmpty return other.isEmpty
return other.count == count && other.item == item && other.parameters == parameters return other.size == size && other.item == item && other.parameters == parameters
} }
// мы не можем делать хеш из count и parameters так как они изменяемы // мы не можем делать хеш из count и parameters так как они изменяемы
@ -98,14 +102,14 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
if (isEmpty) if (isEmpty)
return "ItemDescriptor.EMPTY" return "ItemDescriptor.EMPTY"
return "ItemDescriptor[${item!!.value.itemName}, count = $count, params = $parameters]" return "ItemDescriptor[${item!!.value.itemName}, count = $size, params = $parameters]"
} }
fun copy(): ItemStack { fun copy(): ItemStack {
if (isEmpty) if (isEmpty)
return this return this
return ItemStack(item, count, parameters.deepCopy(), Unit) return ItemStack(item, size, parameters.deepCopy(), Unit)
} }
fun toJson(): JsonObject? { fun toJson(): JsonObject? {
@ -115,7 +119,7 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
return JsonObject().also { return JsonObject().also {
it.add("name", JsonPrimitive(item!!.value.itemName)) it.add("name", JsonPrimitive(item!!.value.itemName))
it.add("count", JsonPrimitive(count)) it.add("count", JsonPrimitive(size))
it.add("parameters", parameters.deepCopy()) it.add("parameters", parameters.deepCopy())
} }
} }
@ -131,7 +135,7 @@ class ItemStack private constructor(item: RegistryObject<IItemDefinition>?, coun
} }
override fun read(`in`: JsonReader): ItemStack { override fun read(`in`: JsonReader): ItemStack {
if (`in`.peek() == JsonToken.NULL) if (`in`.consumeNull())
return EMPTY return EMPTY
return starbound.item(TypeAdapters.JSON_ELEMENT.read(`in`)) return starbound.item(TypeAdapters.JSON_ELEMENT.read(`in`))