Больше тестов декодирования предметов

This commit is contained in:
DBotThePony 2022-12-30 15:43:30 +07:00
parent d016aa807c
commit 727727b7cd
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 116 additions and 26 deletions

View File

@ -437,7 +437,7 @@ object Starbound {
}
private fun loadItemDefinitions(callback: (String) -> Unit) {
val files = listOf(".item", ".currency")
val files = listOf(".item", ".currency", ".head", ".chest", ".legs")
for (fs in fileSystems) {
for (listedFile in fs.explore().filter { it.isFile }.filter { f -> files.any { f.name.endsWith(it) } }) {

View File

@ -172,6 +172,61 @@ data class ItemDefinition(
* Lua скрипты для выполнения
*/
val scripts: List<String> = listOf(),
val animationScripts: List<String> = listOf(),
// ----------------
// Броня
// ----------------
/**
* это где либо ещё применяется кроме брони?
*/
val tooltipKind: String? = null,
/**
* Изначальный уровень, может быть изменён позднее чем угодно
*/
val level: Int? = null,
/**
* Эффекты предмета, растущие с уровнем
*/
val leveledStatusEffects: List<StatusEffect> = listOf(),
/**
* Варианты покраски (???)
*/
// val colorOptions: Map<String, String> = mapOf(),
/**
* Визуальные кадры анимации, когда надето на гуманоида мужского пола
*/
val maleFrames: ArmorFrames? = null,
/**
* Визуальные кадры анимации, когда надето на гуманоида женского пола
*/
val femaleFrames: ArmorFrames? = null,
// ----------------
// /Броня
// ----------------
// ----------------
// activeitem
// ----------------
// TODO: это указатель на структуру
val animation: String? = null,
/**
* Занимает ли предмет обе руки
*/
val twoHanded: Boolean = false,
// ----------------
// /activeitem
// ----------------
/**
* Прототип данного предмета, как JSON структура
@ -186,6 +241,18 @@ data class ItemDefinition(
val description: String = "..."
)
data class ArmorFrames(
val body: String,
val backSleeve: String,
val frontSleeve: String,
)
data class StatusEffect(
val levelFunction: String,
val stat: String,
val baseMultiplier: Double,
)
companion object {
val ADAPTER = KConcreteTypeAdapter.Builder(ItemDefinition::class)
.plain(ItemDefinition::itemName)
@ -205,7 +272,7 @@ data class ItemDefinition(
.list(ItemDefinition::pickupQuestTemplates)
.plain(ItemDefinition::race)
.plain(ItemDefinition::displayImage, Starbound::readingFolderTransformerNullable)
.plain(ItemDefinition::displayImage, transformer = Starbound::readingFolderTransformerNullable)
.plain(ItemDefinition::displayoffset)
.plain(ItemDefinition::fossilSetName)
.plain(ItemDefinition::setIndex)
@ -227,6 +294,17 @@ data class ItemDefinition(
.plain(ItemDefinition::value)
.list(ItemDefinition::scripts, transformer = Starbound::readingFolderListTransformer)
.list(ItemDefinition::animationScripts, transformer = Starbound::readingFolderListTransformer)
.plain(ItemDefinition::tooltipKind)
.plain(ItemDefinition::level)
.list(ItemDefinition::leveledStatusEffects)
// .map(ItemDefinition::colorOptions)
.plain(ItemDefinition::maleFrames)
.plain(ItemDefinition::femaleFrames)
.plain(ItemDefinition::animation, transformer = Starbound::readingFolderTransformerNullable)
.plain(ItemDefinition::twoHanded)
.storesJson()
@ -239,9 +317,23 @@ data class ItemDefinition(
.specifyStringInterner(ADAPTER.stringInterner)
.build()
val ARMOR_FRAMES_ADAPTER = KConcreteTypeAdapter.Builder(ArmorFrames::class)
.plain(ArmorFrames::body, transformer = Starbound::readingFolderTransformer)
.plain(ArmorFrames::backSleeve, transformer = Starbound::readingFolderTransformer)
.plain(ArmorFrames::frontSleeve, transformer = Starbound::readingFolderTransformer)
.build()
val STATUS_EFFECT_ADAPTER = KConcreteTypeAdapter.Builder(StatusEffect::class)
.plain(StatusEffect::levelFunction)
.plain(StatusEffect::stat)
.plain(StatusEffect::baseMultiplier)
.build()
fun registerGson(gsonBuilder: GsonBuilder) {
gsonBuilder.registerTypeAdapter(ADAPTER)
gsonBuilder.registerTypeAdapter(FOSSIL_ADAPTER)
gsonBuilder.registerTypeAdapter(ARMOR_FRAMES_ADAPTER)
gsonBuilder.registerTypeAdapter(STATUS_EFFECT_ADAPTER)
}
}
}

View File

@ -338,19 +338,11 @@ class KConcreteTypeAdapter<T : Any> private constructor(
if (!iterator.hasNext()) {
val name = fieldId.toString()
if (loggedMisses.add(name)) {
if (storesJson) {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field, it will be only visible to Lua scripts")
} else {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field, it will be only visible to Lua scripts (reading: $currentSymbolicName)")
}
if (!storesJson && loggedMisses.add(name)) {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field")
} else {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field")
} else {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field (reading: $currentSymbolicName)")
}
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field (reading: $currentSymbolicName)")
}
}
@ -392,19 +384,11 @@ class KConcreteTypeAdapter<T : Any> private constructor(
val fieldId = mapped.getInt(name)
if (fieldId == -1) {
if (loggedMisses.add(name)) {
if (storesJson) {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field, it will be only visible to Lua scripts")
} else {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field, it will be only visible to Lua scripts (reading: $currentSymbolicName)")
}
if (!storesJson && loggedMisses.add(name)) {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field")
} else {
if (currentSymbolicName == null) {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field")
} else {
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field (reading: $currentSymbolicName)")
}
LOGGER.warn("Skipping JSON field with name $name because ${bound.simpleName} has no such field (reading: $currentSymbolicName)")
}
}
@ -636,6 +620,20 @@ class KConcreteTypeAdapter<T : Any> private constructor(
return this
}
/**
* Добавляет поле-таблицу, кодирование зависит от контекста:
* * Если [K] является [String], кодирование происходит как Json Object
* * Иначе кодирование происходит как Json Array
*
* Таблица неизменяема (создаётся объект [ImmutableMap])
*/
inline fun <reified K, reified V> map(field: KProperty1<T, Map<K, V>>): Builder<T> {
if (K::class == String::class)
return this.map(field as KProperty1<T, Map<String, V>?>, V::class.java)
return this.map(field, K::class.java, V::class.java)
}
/**
* Добавляет поле-таблицу, которое кодируется как [[key, value], [key, value], ...]
*