diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index 91a4f0163..ec3fe80d3 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -112,6 +112,9 @@ private fun sounds(provider: MatteryLanguageProvider) { sound("rifle_shot", "Plasma rifle fires") sound("plasma_weapon_overheat", "Plasma weapon overheats") sound("player_become_android", "Player became android") + sound("projectile_parry", "Projectile parried") + sound("jump_boost", "Jump boost") + sound("shockwave", "Landing shockwave") sound(MSoundEvents.CARGO_CRATE_OPEN, "Cargo crate opened") } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index 4b21207ca..0185cd36c 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -121,6 +121,9 @@ private fun sounds(provider: MatteryLanguageProvider) { sound("rifle_shot", "Выстрел плазменной винтовки") sound("plasma_weapon_overheat", "Плазменное оружие перегрелось") sound("player_become_android", "Игрок превратился в андроида") + sound("projectile_parry", "Снаряд парирован") + sound("jump_boost", "Усиленный прыжок") + sound("shockwave", "Ударная волна от приземления") sound(MSoundEvents.CARGO_CRATE_OPEN, "Открыт грузовой ящик") } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt index c7bf10448..326316880 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt @@ -363,7 +363,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc { !isRemoved || creationVersion != currentVersion }, // IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!") // what a shame. - { onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) } }) + { if (SERVER_IS_LIVE) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) } }) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt index 7d1d84e17..184917bff 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt @@ -35,6 +35,7 @@ import ru.dbotthepony.mc.otm.storage.* import java.math.BigInteger import java.util.* import java.util.function.Consumer +import java.util.function.Supplier import java.util.stream.Stream private data class SlotTuple(val slot: Int, val stack: ItemStack) @@ -130,7 +131,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter } init { - savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY) + savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) }) } override fun setLevel(level: Level) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index 2eb5f7747..090a594f4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -38,6 +38,7 @@ import ru.dbotthepony.mc.otm.storage.ItemStorageStack import ru.dbotthepony.mc.otm.storage.StorageStack import java.math.BigInteger import java.util.* +import java.util.function.Supplier abstract class AbstractStorageImportExport( blockType: BlockEntityType<*>, @@ -111,7 +112,7 @@ abstract class AbstractStorageImportExport( } init { - savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY) + savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) }) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt index dcad21601..4f0f53114 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt @@ -27,7 +27,7 @@ class ItemFilter private constructor(private val filter: Array, val i get() = filter.size fun set(index: Int, value: ItemStack): ItemFilter { - if (ItemStack.isSameItemSameComponents(filter[index], value) || filter.any { ItemStack.isSameItemSameComponents(it, value) }) + if (ItemStack.isSameItemSameComponents(filter[index], value) || !value.isEmpty && filter.any { ItemStack.isSameItemSameComponents(it, value) }) return this return copy(filter.copyOf().also { it[index] = value }) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt index 9d7c2583c..caa118d04 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt @@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.nbt.set import java.util.function.Supplier +import kotlin.jvm.optionals.getOrNull import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty0 @@ -174,8 +175,8 @@ class Savetables : INBTSerializable { fun codecNullable(prop: Delegate, codec: Codec, name: String): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow() { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow() { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } + .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write save data for '$name': $it") } } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).resultOrPartial { throw IllegalStateException("Failed to read save data for '$name'", RuntimeException(it)) }.getOrNull()?.first } } fun codecNullable(prop: KMutableProperty0, codec: Codec, name: String = prop.name): Stateless { @@ -184,8 +185,8 @@ class Savetables : INBTSerializable { fun codecNullable(prop: Delegate, codec: Codec, name: String, default: T?): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).mapOrElse({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } + .withSerializer { prop.get()?.let { codec.encode(it, NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write save data for '$name': $it") } } } + .withDeserializer { codec.decode(NbtOps.INSTANCE, it).resultOrPartial { LOGGER.error("Failed to read save data for '$name'", RuntimeException(it)) }.map { it.first }.orElse(default) } .withDefault { default } } @@ -195,15 +196,28 @@ class Savetables : INBTSerializable { fun codec(prop: Delegate, codec: Codec, name: String): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).getOrThrow() { throw IllegalStateException("Failed to read NBT data for $name: $it") }.first } + .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write save data for '$name': $it") } } + .withDeserializer { + codec.decode(NbtOps.INSTANCE, it).let { res -> + res + .resultOrPartial { LOGGER.error("Failed to read save data for '$name'", RuntimeException(it)) } + .map { it.first } + .orElseThrow { throw RuntimeException("Failed to read save data for '$name': ${res.error().get().message()}") } + } + } } - fun codec(prop: Delegate, codec: Codec, name: String, default: T): Stateless { + fun codec(prop: Delegate, codec: Codec, name: String, default: Supplier): Stateless { return Stateless(prop, name, Tag::class.java) - .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write NBT data for $name: $it") } } - .withDeserializer { codec.decode(NbtOps.INSTANCE, it).mapOrElse({ it.first }, { LOGGER.error("Failed to read NBT data for $name", RuntimeException(it.message())); default }) } - .withDefault { default } + .withSerializer { codec.encode(prop.get(), NbtOps.INSTANCE, NbtOps.INSTANCE.empty()).getOrThrow { throw IllegalStateException("Failed to write save data for '$name': $it") } } + .withDeserializer { + codec + .decode(NbtOps.INSTANCE, it) + .resultOrPartial { LOGGER.error("Failed to read save data for '$name'", RuntimeException(it)) } + .map { it.first } + .orElseGet(default) + } + .withDefault { default.get() } } fun codec(prop: KMutableProperty0, codec: Codec, name: String = prop.name): Stateless { @@ -211,10 +225,22 @@ class Savetables : INBTSerializable { } fun codec(prop: KMutableProperty0, codec: Codec, name: String = prop.name, default: T): Stateless { + return codec(Delegate.Of(prop), codec, name, Supplier { default }) + } + + fun codec(prop: KMutableProperty0, codec: Codec, name: String = prop.name, default: Supplier): Stateless { return codec(Delegate.Of(prop), codec, name, default) } + fun codec(prop: KMutableProperty0, codec: Codec, default: Supplier): Stateless { + return codec(Delegate.Of(prop), codec, prop.name, default) + } + fun vector(prop: Delegate, name: String, default: Vector = Vector.ZERO): Stateless { + return codec(prop, Vector.CODEC, name, Supplier { default }) + } + + fun vector(prop: Delegate, name: String, default: Supplier): Stateless { return codec(prop, Vector.CODEC, name, default) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt index 6fb4c5090..380a1014e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MatteryMenu.kt @@ -197,7 +197,7 @@ abstract class MatteryMenu( fun decimalInput(allowSpectators: Boolean = false, handler: (Decimal) -> Unit) = PlayerInput(StreamCodecs.DECIMAL, allowSpectators, handler) fun booleanInput(allowSpectators: Boolean = false, handler: (Boolean) -> Unit) = PlayerInput(StreamCodecs.BOOLEAN, allowSpectators, handler) fun itemInput(allowSpectators: Boolean = false, handler: (Item) -> Unit) = PlayerInput(StreamCodecs.ITEM_TYPE, allowSpectators, handler) - fun itemStackInput(allowSpectators: Boolean = false, handler: (ItemStack) -> Unit) = PlayerInput(ItemStack.STREAM_CODEC.wrap(), allowSpectators, handler) + fun itemStackInput(allowSpectators: Boolean = false, handler: (ItemStack) -> Unit) = PlayerInput(ItemStack.OPTIONAL_STREAM_CODEC.wrap(), allowSpectators, handler) fun nullableItemInput(allowSpectators: Boolean = false, handler: (Item?) -> Unit) = PlayerInput(StreamCodecs.ITEM_TYPE.nullable(), allowSpectators, handler) fun stringInput(allowSpectators: Boolean = false, handler: (String) -> Unit) = PlayerInput(StreamCodecs.STRING, allowSpectators, handler) fun floatInput(allowSpectators: Boolean = false, handler: (Float) -> Unit) = PlayerInput(StreamCodecs.FLOAT, allowSpectators, handler) diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/energy_servo_multiparttest_whatthefuck.json b/src/main/resources/assets/overdrive_that_matters/models/block/energy_servo_multiparttest_whatthefuck.json index f09d10e58..40a1e2739 100644 --- a/src/main/resources/assets/overdrive_that_matters/models/block/energy_servo_multiparttest_whatthefuck.json +++ b/src/main/resources/assets/overdrive_that_matters/models/block/energy_servo_multiparttest_whatthefuck.json @@ -1,5 +1,5 @@ { - "loader": "forge:composite", + "loader": "neoforge:composite", "parts": { "body": { "parent": "overdrive_that_matters:block/energy_servo_body",