diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt index 1dbb33b5..f937cf1e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Starbound.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.kstarbound +import com.google.common.collect.ImmutableList import com.google.gson.* import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap @@ -65,6 +66,13 @@ object Starbound { return null } + fun readingFolderListTransformer(input: List?): List? { + if (input == null) + return null + + return input.stream().map { readingFolderTransformer(it) }.collect(ImmutableList.toImmutableList()) + } + private val tiles = Object2ObjectOpenHashMap() private val tilesByMaterialID = Int2ObjectOpenHashMap() @@ -429,8 +437,10 @@ object Starbound { } private fun loadItemDefinitions(callback: (String) -> Unit) { + val files = listOf(".item", ".currency") + for (fs in fileSystems) { - for (listedFile in fs.explore().filter { it.isFile }.filter { it.name.endsWith(".item") }) { + for (listedFile in fs.explore().filter { it.isFile }.filter { f -> files.any { f.name.endsWith(it) } }) { try { callback("Loading $listedFile") @@ -448,5 +458,7 @@ object Starbound { } } } + + items.values.stream().filter { it.currency != null }.forEach(::println) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt index 83f35a88..6c6152b6 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.kstarbound.defs.item +import com.google.common.collect.ImmutableList import com.google.gson.GsonBuilder import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.io.KConcreteTypeAdapter @@ -123,6 +124,54 @@ data class ItemDefinition( * Топливо корабля */ val fuelAmount: Long? = null, + + // ---------------- + // Поля ниже были видны только в файлах валюты + // ---------------- + + /** + * Звуки при поднятии "малого" количества предметов. Не имеет никакого смысла без [smallStackLimit] + */ + val pickupSoundsSmall: List = listOf(), + + /** + * Звуки при поднятии "среднего" количества предметов. Не имеет никакого смысла без [mediumStackLimit] + */ + val pickupSoundsMedium: List = listOf(), + + /** + * Звуки при поднятии "большого" количества предметов. Не имеет никакого смысла без [smallStackLimit] и без [mediumStackLimit] + */ + val pickupSoundsLarge: List = listOf(), + + /** + * Количество предметов ниже или равному данному значению проиграет звук [pickupSoundsSmall] + */ + val smallStackLimit: Long? = null, + + /** + * Количество предметов ниже или равному данному значению (но не меньше [smallStackLimit]) проиграет звук [pickupSoundsMedium] + */ + val mediumStackLimit: Long? = null, + + /** + * Превращает предмет в валюту + */ + val currency: String? = null, + + /** + * Ценность в [currency] + */ + val value: Long? = null, + + // ---------------- + // /Валюта + // ---------------- + + /** + * Lua скрипты для выполнения + */ + val scripts: List = listOf(), ) { data class FossilSetDescription( val price: Long = 0L, @@ -162,12 +211,23 @@ data class ItemDefinition( .list(ItemDefinition::radioMessagesOnPickup) .plain(ItemDefinition::fuelAmount) + .list(ItemDefinition::pickupSoundsSmall) + .list(ItemDefinition::pickupSoundsMedium) + .list(ItemDefinition::pickupSoundsLarge) + .plain(ItemDefinition::smallStackLimit) + .plain(ItemDefinition::mediumStackLimit) + .plain(ItemDefinition::currency) + .plain(ItemDefinition::value) + + .list(ItemDefinition::scripts, transformer = Starbound::readingFolderListTransformer) + .build() val FOSSIL_ADAPTER = KConcreteTypeAdapter.Builder(FossilSetDescription::class) .plain(FossilSetDescription::price) .plain(FossilSetDescription::shortdescription) .plain(FossilSetDescription::description) + .specifyStringInterner(ADAPTER.stringInterner) .build() fun registerGson(gsonBuilder: GsonBuilder) { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt index 105d3d69..6f79459a 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt @@ -174,7 +174,7 @@ class KConcreteTypeAdapter private constructor( val bound: KClass, private val types: ImmutableList>, private val asJsonArray: Boolean = false, - private val stringInterner: Interner + val stringInterner: Interner ) : TypeAdapter() { private val mapped = Object2IntArrayMap() private val loggedMisses = ObjectArraySet() @@ -219,7 +219,10 @@ class KConcreteTypeAdapter private constructor( private val syntheticFactory: Constructor? = try { bound.java.getDeclaredConstructor(*types.map { (it.returnType.classifier as KClass<*>).java }.also { it as MutableList - it.add(Int::class.java) + + for (i in 0 until (if (types.size % 31 == 0) types.size / 31 else types.size / 31 + 1)) + it.add(Int::class.java) + it.add(DefaultConstructorMarker::class.java) }.toTypedArray()) } catch(_: NoSuchMethodException) { @@ -434,7 +437,12 @@ class KConcreteTypeAdapter private constructor( */ class Builder(val clazz: KClass) { private val types = ArrayList>() - private val stringInterner = Interners.newWeakInterner() + var stringInterner: Interner = Interners.newWeakInterner() + + fun specifyStringInterner(interner: Interner): Builder { + stringInterner = interner + return this + } private val internedStringAdapter: TypeAdapter = object : TypeAdapter() { override fun write(out: JsonWriter, value: String) { @@ -511,8 +519,8 @@ class KConcreteTypeAdapter private constructor( * * Список неизменяем (создаётся объект [ImmutableList]) */ - fun list(field: KProperty1?>, type: Class): Builder { - types.add(PackedProperty(field, ListAdapter(type, internedStringAdapter))) + fun list(field: KProperty1?>, type: Class, transformer: (List?) -> List? = { it }): Builder { + types.add(PackedProperty(field, ListAdapter(type, internedStringAdapter), transformer = transformer)) return this } @@ -521,8 +529,8 @@ class KConcreteTypeAdapter private constructor( * * Список неизменяем (создаётся объект [ImmutableList]) */ - inline fun list(field: KProperty1?>): Builder { - return this.list(field, V::class.java) + inline fun list(field: KProperty1?>, noinline transformer: (List?) -> List? = { it }): Builder { + return this.list(field, V::class.java, transformer) } /**