diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index 90c7f3aa5..6d09603f4 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.capability; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityToken; -import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import org.jetbrains.annotations.NotNull; import ru.dbotthepony.mc.otm.block.entity.cable.EnergyCableBlockEntity; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; @@ -66,16 +65,4 @@ public class MatteryCapability { @Nonnull @NotNull public static final Capability UPGRADE = CapabilityManager.get(new CapabilityToken<>() {}); - - public static void register(RegisterCapabilitiesEvent event) { - event.register(IMatteryEnergyStorage.class); - event.register(MatteryPlayerCapability.class); - event.register(IMatterStorage.class); - event.register(MatterNode.class); - event.register(IPatternStorage.class); - event.register(IReplicationTaskProvider.class); - event.register(IMatteryDrive.class); - event.register(StorageNode.class); - event.register(IMatteryUpgrade.class); - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt index c446c7340..e7777e03b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt @@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.FluidGaugePanel +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filterIsInstance import ru.dbotthepony.mc.otm.core.collect.map diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt index b1d30a73f..fcc12e259 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/IMatteryContainer.kt @@ -4,12 +4,13 @@ import it.unimi.dsi.fastutil.ints.IntIterable import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.minecraft.world.item.crafting.RecipeInput import ru.dbotthepony.mc.otm.container.util.IContainerSlot import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.isNotEmpty -interface IMatteryContainer : IContainer, Iterable { +interface IMatteryContainer : IContainer, RecipeInput, Iterable { fun getSlotFilter(slot: Int): Item? /** @@ -19,8 +20,13 @@ interface IMatteryContainer : IContainer, Iterable { return false } + override fun isEmpty(): Boolean fun setChanged(slot: Int) + override fun size(): Int { + return containerSize + } + /** * Iterates over non-empty itemstacks of this container */ @@ -105,7 +111,7 @@ interface IMatteryContainer : IContainer, Iterable { if ( (ignoreFilters || !isSlotForbiddenForAutomation(slot)) && - ItemStack.isSameItemSameTags(getItem(slot), stack) && + ItemStack.isSameItemSameComponents(getItem(slot), stack) && (ignoreFilters || !filterPass && !hasSlotFilter(slot) || filterPass && hasSlotFilter(slot) && testSlotFilter(slot, stack)) ) { val slotStack = getItem(slot) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index ca3f6a276..7c9a607a0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -1,14 +1,18 @@ package ru.dbotthepony.mc.otm.container +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.IntAVLTreeSet import it.unimi.dsi.fastutil.ints.IntArrayList import it.unimi.dsi.fastutil.ints.IntComparators import it.unimi.dsi.fastutil.ints.IntSpliterator import it.unimi.dsi.fastutil.objects.ObjectSpliterators +import net.minecraft.core.HolderLookup import net.minecraft.world.item.ItemStack import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag +import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag import net.minecraft.resources.ResourceLocation import net.minecraft.world.Container @@ -19,6 +23,7 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.Items import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.registries.ForgeRegistries +import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.collect.ListenableMap import ru.dbotthepony.kommons.io.DelegateSyncher import ru.dbotthepony.kommons.io.VarIntValueCodec @@ -34,6 +39,7 @@ import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.util.ItemValueCodec +import ru.dbotthepony.mc.otm.data.minRange import java.util.* import java.util.function.Consumer import java.util.function.Predicate @@ -184,58 +190,43 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I protected open fun startedIgnoringUpdates() {} protected open fun stoppedIgnoringUpdates() {} - private fun deserializeNBT(tag: CompoundTag) { - // нам не интересен размер - tag.map("items") { it: ListTag -> - deserializeNBT(it) - } - - tag.map("filters") { it: ListTag -> - val map = filterSynchronizer?.delegate - - for (i in 0 until it.size.coerceAtMost(size)) { - val nbt = it[i] as CompoundTag - val index = nbt.getInt("slotIndex") - filters[index] = ForgeRegistries.ITEMS.getValue(ResourceLocation.tryParse(nbt.getString("filter")) ?: continue) - - if (filters[index] != null) { - map?.put(index, filters[index]!!) - } - } - } - - setChanged() - } - - private fun deserializeNBT(tag: ListTag) { - if (tag.all { (it as CompoundTag).contains("slotIndex") }) { - val freeSlots = IntAVLTreeSet() - - for (i in 0 until size) - freeSlots.add(i) - - for (i in 0 until tag.size.coerceAtMost(size)) { - val nbt = tag[i] as CompoundTag - var slotID = nbt.getInt("slotIndex") - - if (freeSlots.remove(slotID)) { - slots[slotID] = ItemStack.of(nbt) - } else if (freeSlots.isEmpty()) { - break - } else { - slotID = freeSlots.firstInt() - freeSlots.remove(slotID) - slots[slotID] = ItemStack.of(nbt) - } - } - } else { - for (i in 0 until tag.size.coerceAtMost(size)) { - slots[i] = ItemStack.of(tag[i] as CompoundTag) + private data class SerializedItem(val item: ItemStack, val slot: Int) { + companion object { + val CODEC: Codec = RecordCodecBuilder.create { + it.group( + ItemStack.CODEC.fieldOf("item").forGetter { it.item }, + Codec.INT.minRange(0).fieldOf("slot").forGetter { it.slot }, + ).apply(it, ::SerializedItem) } } } - override fun deserializeNBT(tag: Tag?) { + private data class SerializedFilter(val item: Item, val slot: Int) { + companion object { + val CODEC: Codec = RecordCodecBuilder.create { + it.group( + ForgeRegistries.ITEMS.codec.fieldOf("item").forGetter { it.item }, + Codec.INT.minRange(0).fieldOf("slot").forGetter { it.slot }, + ).apply(it, ::SerializedFilter) + } + } + } + + private data class SerializedState( + val items: List, + val filters: List + ) { + companion object { + val CODEC: Codec = RecordCodecBuilder.create { + it.group( + Codec.list(SerializedItem.CODEC).fieldOf("items").forGetter { it.items }, + Codec.list(SerializedFilter.CODEC).fieldOf("filters").forGetter { it.filters }, + ).apply(it, ::SerializedState) + } + } + } + + override fun deserializeNBT(registries: HolderLookup.Provider, tag: Tag?) { Arrays.fill(slots, ItemStack.EMPTY) Arrays.fill(filters, null) nonEmptyFlags.clear() @@ -243,14 +234,37 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I filterSynchronizer?.delegate?.clear() - when (tag) { - is CompoundTag -> deserializeNBT(tag) - is ListTag -> { - deserializeNBT(tag) - setChanged() - } + if (tag != null) { + SerializedState.CODEC.parse(registries.createSerializationContext(NbtOps.INSTANCE), tag) + .resultOrPartial { LOGGER.error("Error deserializing container: $it") } + .ifPresent { + val freeSlots = IntAVLTreeSet() - else -> setChanged() + for (i in 0 until size) + freeSlots.add(i) + + for ((item, slotID) in it.items) { + if (item.isEmpty) + continue + + if (freeSlots.remove(slotID)) { + slots[slotID] = item + } else if (freeSlots.isEmpty()) { + break + } else { + val slotID = freeSlots.firstInt() + freeSlots.remove(slotID) + slots[slotID] = item + } + } + + val map = filterSynchronizer?.delegate + + for ((item, index) in it.filters) { + filters[index] = item + map?.put(index, item) + } + } } } @@ -274,12 +288,13 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I listener.setChanged(slot, new, old) } - override fun serializeNBT(): CompoundTag { + override fun serializeNBT(registries: HolderLookup.Provider): CompoundTag { return CompoundTag().also { it["items"] = ListTag().also { for ((i, item) in slots.withIndex()) { if (!item.isEmpty) { - it.add(item.serializeNBT().also { + it.add(item.save(registries).also { + it as CompoundTag it["slotIndex"] = i }) } @@ -311,7 +326,7 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I operator fun contains(other: ItemStack): Boolean { for (i in 0 until size) { - if (ItemStack.isSameItemSameTags(this[i], other)) { + if (ItemStack.isSameItemSameComponents(this[i], other)) { return true } } @@ -399,7 +414,7 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I } final override fun setChanged(slot: Int) { - if (!slots[slot].equals(trackedSlots[slot], false)) { + if (!ItemStack.isSameItemSameComponents(slots[slot], trackedSlots[slot])) { trackedSlots[slot] = slots[slot].copy() updateEmptyFlag(slot) changeset++ @@ -567,4 +582,8 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I fun stream(): Stream { return StreamSupport.stream(spliterator(), false) } + + companion object { + private val LOGGER = LogManager.getLogger() + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index e75359b92..18a9e39d6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -24,7 +24,9 @@ import net.minecraft.world.entity.Entity import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items +import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient +import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.Level import net.minecraft.world.level.LevelAccessor @@ -72,6 +74,10 @@ import java.util.stream.Stream import java.util.stream.StreamSupport import kotlin.reflect.KProperty +operator fun RecipeInput.get(index: Int): ItemStack = getItem(index) +operator fun CraftingInput.get(x: Int, y: Int): ItemStack = getItem(x, y) +operator fun CraftingInput.get(x: Int, y: Int, flop: Boolean): ItemStack = if (flop) getItem(x, y) else getItem(width() - x - 1, y) + fun FriendlyByteBuf.writeBigInteger(value: BigInteger) { writeByteArray(value.toByteArray()) } @@ -142,8 +148,6 @@ inline fun LazyOptional.ifPresentK(lambda: (T) -> Unit) { } } -val ItemStack.tagNotNull: CompoundTag get() = orCreateTag - inline val FluidStack.isNotEmpty get() = !isEmpty inline val ItemStack.isNotEmpty get() = !isEmpty diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt index 3cc18df17..428f34283 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/UnOverengineering.kt @@ -2,7 +2,9 @@ package ru.dbotthepony.mc.otm.core import com.google.gson.JsonElement import com.google.gson.JsonSyntaxException +import com.mojang.datafixers.util.Either import com.mojang.serialization.Codec +import com.mojang.serialization.DataResult import com.mojang.serialization.JsonOps import net.minecraft.core.Holder import net.minecraft.core.RegistryAccess @@ -11,7 +13,7 @@ import net.minecraft.nbt.NbtOps import net.minecraft.nbt.Tag import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.chat.MutableComponent -import net.minecraft.network.chat.contents.LiteralContents +import net.minecraft.network.chat.contents.PlainTextContents import net.minecraft.network.chat.contents.TranslatableContents import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceLocation @@ -26,38 +28,39 @@ import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.IForgeRegistry import ru.dbotthepony.mc.otm.core.util.readBinaryJson import ru.dbotthepony.mc.otm.core.util.writeBinaryJson +import kotlin.jvm.optionals.getOrNull // because doing it inline is ugly fun Codec.fromJson(value: JsonElement): V? { - return decode(JsonOps.INSTANCE, value).get().map({ left -> left.first }, { null }) + return decode(JsonOps.INSTANCE, value).result().map { left -> left.first }.getOrNull() } fun Codec.fromJsonStrict(value: JsonElement): V { - return decode(JsonOps.INSTANCE, value).get().map({ left -> left.first }, { throw JsonSyntaxException("Error decoding element: ${it.message()}") }) + return decode(JsonOps.INSTANCE, value).get({ left -> left.first }, { throw JsonSyntaxException("Error decoding element: ${it.message()}") }) } fun Codec.toJson(value: V, prefix: JsonElement = JsonOps.INSTANCE.empty()): JsonElement? { - return encode(value, JsonOps.INSTANCE, prefix).get().map({ it }, { null }) + return encode(value, JsonOps.INSTANCE, prefix).getOrNull { it } } fun Codec.toJsonStrict(value: V, prefix: JsonElement = JsonOps.INSTANCE.empty()): JsonElement { - return encode(value, JsonOps.INSTANCE, prefix).get().map({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) + return encode(value, JsonOps.INSTANCE, prefix).get({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) } fun Codec.fromNbt(value: Tag): V? { - return decode(NbtOps.INSTANCE, value).get().map({ left -> left.first }, { null }) + return decode(NbtOps.INSTANCE, value).getOrNull { left -> left.first } } fun Codec.fromNbtStrict(value: Tag): V { - return decode(NbtOps.INSTANCE, value).get().map({ left -> left.first }, { throw RuntimeException("Error decoding element: ${it.message()}") }) + return decode(NbtOps.INSTANCE, value).get({ left -> left.first }, { throw RuntimeException("Error decoding element: ${it.message()}") }) } fun Codec.toNbt(value: V, prefix: Tag = NbtOps.INSTANCE.empty()): Tag? { - return encode(value, NbtOps.INSTANCE, prefix).get().map({ it }, { null }) + return encode(value, NbtOps.INSTANCE, prefix).getOrNull { it } } fun Codec.toNbtStrict(value: V, prefix: Tag = NbtOps.INSTANCE.empty()): Tag { - return encode(value, NbtOps.INSTANCE, prefix).get().map({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) + return encode(value, NbtOps.INSTANCE, prefix).get({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") }) } fun Codec.toNetwork(buff: FriendlyByteBuf, value: V) { @@ -70,7 +73,7 @@ fun Codec.fromNetwork(buff: FriendlyByteBuf): V { // 1.19 being 1.19 fun TranslatableComponent(key: String, vararg values: Any): MutableComponent = MutableComponent.create(TranslatableContents(key, null, values)) -fun TextComponent(value: String): MutableComponent = MutableComponent.create(LiteralContents(value)) +fun TextComponent(value: String): MutableComponent = MutableComponent.create(PlainTextContents.create(value)) fun IForgeRegistry.getKeyNullable(value: T): ResourceLocation? { val key = getResourceKey(value) @@ -100,3 +103,15 @@ inline val DamageSource.isFire get() = `is`(DamageTypeTags.IS_FIRE) fun RegistryAccess.damageType(key: ResourceKey): Holder { return registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(key) } + +// 1.21 +fun ResourceLocation(namespace: String, path: String) = ResourceLocation.fromNamespaceAndPath(namespace, path) + +// mojang hello? +fun DataResult.get(map: (IN) -> OUT, orThrow: (DataResult.Error) -> Nothing): OUT { + return result().map(map).orElseGet { orThrow(error().get()) } +} + +fun DataResult.getOrNull(map: (IN) -> OUT): OUT? { + return result().map(map).orElse(null) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt index c8f8f5753..168385514 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/FluidTankItem.kt @@ -14,9 +14,13 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ICapabilityProvider import ru.dbotthepony.mc.otm.block.decorative.FluidTankBlock import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity +import ru.dbotthepony.mc.otm.capability.FlowDirection +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.fluid.BlockMatteryFluidHandler import ru.dbotthepony.mc.otm.capability.fluidLevel import ru.dbotthepony.mc.otm.client.render.blockentity.FluidTankRenderer +import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.core.TooltipList import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.ifPresentK diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt index 3e5ac763e..8d3e9ae30 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IMatteryRecipe.kt @@ -5,12 +5,13 @@ import net.minecraft.world.Container import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Recipe +import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.item.crafting.RecipeSerializer import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer // passthrough all default methods to fix Kotlin bug related to implementation delegation not properly working on Java interfaces // https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods -interface IMatteryRecipe : Recipe { +interface IMatteryRecipe : Recipe { override fun getRemainingItems(p_44004_: C): NonNullList { return super.getRemainingItems(p_44004_) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt index 07a50aad2..a9d6a96d9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/IngredientMatrix.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.recipe import net.minecraft.core.NonNullList import net.minecraft.world.inventory.CraftingContainer +import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.container.get @@ -9,12 +10,13 @@ import ru.dbotthepony.mc.otm.core.collect.allEqual import ru.dbotthepony.mc.otm.core.collect.any import ru.dbotthepony.mc.otm.core.collect.flatMap import ru.dbotthepony.mc.otm.core.collect.map +import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.util.countingLazy import java.util.function.Predicate -interface IIngredientMatrix : Predicate, Iterable { +interface IIngredientMatrix : Predicate, Iterable { val width: Int val height: Int val isEmpty: Boolean @@ -52,8 +54,8 @@ interface IIngredientMatrix : Predicate, Iterable return result } - fun test(t: CraftingContainer, fromColumn: Int, fromRow: Int, flop: Boolean): Boolean { - if (t.width - fromColumn < width || t.height - fromRow < height) + fun test(t: CraftingInput, fromColumn: Int, fromRow: Int, flop: Boolean): Boolean { + if (t.width() - fromColumn < width || t.height() - fromRow < height) return false for (column in 0 until width) @@ -64,8 +66,8 @@ interface IIngredientMatrix : Predicate, Iterable return true } - fun preemptiveTest(t: CraftingContainer, fromColumn: Int, fromRow: Int, flop: Boolean): Boolean { - if (t.width - fromColumn < width || t.height - fromRow < height) + fun preemptiveTest(t: CraftingInput, fromColumn: Int, fromRow: Int, flop: Boolean): Boolean { + if (t.width() - fromColumn < width || t.height() - fromRow < height) return false for (column in 0 until width) { @@ -82,24 +84,24 @@ interface IIngredientMatrix : Predicate, Iterable return true } - override fun test(t: CraftingContainer): Boolean { - if (t.width < width || t.height < height) + override fun test(t: CraftingInput): Boolean { + if (t.width() < width || t.height() < height) return false - for (column in 0 .. t.width - width) - for (row in 0 .. t.height - height) + for (column in 0 .. t.width() - width) + for (row in 0 .. t.height() - height) if (test(t, column, row, false) || test(t, column, row, true)) return true return false } - fun preemptiveTest(t: CraftingContainer): Boolean { - if (t.width < width || t.height < height) + fun preemptiveTest(t: CraftingInput): Boolean { + if (t.width() < width || t.height() < height) return false - for (column in 0 .. t.width - width) - for (row in 0 .. t.height - height) + for (column in 0 .. t.width() - width) + for (row in 0 .. t.height() - height) if (preemptiveTest(t, column, row, false) || preemptiveTest(t, column, row, true)) return true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt index a8dc68f98..a95f676e5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatterEntanglerRecipe.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.recipe import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.core.UUIDUtil @@ -9,6 +10,7 @@ import net.minecraft.data.recipes.FinishedRecipe import net.minecraft.resources.ResourceLocation import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.CraftingInput import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeType @@ -31,14 +33,14 @@ import java.util.Optional import java.util.UUID import kotlin.jvm.optionals.getOrElse -interface IMatterEntanglerRecipe : IMatteryRecipe { +interface IMatterEntanglerRecipe : IMatteryRecipe { val matter: Decimal val ticks: Double val ingredients: IIngredientMatrix val result: ItemStack val experience: Float - fun preemptivelyMatches(container: CraftingContainer, level: Level): Boolean + fun preemptivelyMatches(container: CraftingInput, level: Level): Boolean } open class MatterEntanglerRecipe( @@ -50,17 +52,17 @@ open class MatterEntanglerRecipe( val uuidKey: String = "uuid", val fixedUuid: Optional = Optional.empty() ) : IMatterEntanglerRecipe { - override fun matches(container: CraftingContainer, level: Level): Boolean { + override fun matches(container: CraftingInput, level: Level): Boolean { if (isIncomplete) return false return ingredients.test(container) } - override fun preemptivelyMatches(container: CraftingContainer, level: Level): Boolean { + override fun preemptivelyMatches(container: CraftingInput, level: Level): Boolean { if (isIncomplete) return false return ingredients.preemptiveTest(container) } - override fun assemble(container: CraftingContainer, registry: RegistryAccess): ItemStack { + override fun assemble(container: CraftingInput, registry: HolderLookup.Provider): ItemStack { return result.copy().also { it.tagNotNull[uuidKey] = fixedUuid.getOrElse { UUID.randomUUID() } } @@ -106,9 +108,9 @@ open class MatterEntanglerRecipe( fun matter() = Matter(this) open class Energy(val parent: MatterEntanglerRecipe) : IMatterEntanglerRecipe by parent { - override fun assemble(container: CraftingContainer, registry: RegistryAccess): ItemStack { + override fun assemble(container: CraftingInput, registry: HolderLookup.Provider): ItemStack { return parent.assemble(container, registry).also { result -> - container.iterator().map { it.matteryEnergy }.filterNotNull().forEach { + container.items().iterator().map { it.matteryEnergy }.filterNotNull().forEach { result.matteryEnergy!!.batteryLevel += it.batteryLevel } } @@ -124,9 +126,9 @@ open class MatterEntanglerRecipe( } open class Matter(val parent: MatterEntanglerRecipe) : IMatterEntanglerRecipe by parent { - override fun assemble(container: CraftingContainer, registry: RegistryAccess): ItemStack { + override fun assemble(container: CraftingInput, registry: HolderLookup.Provider): ItemStack { return parent.assemble(container, registry).also { result -> - container.iterator().map { it.matter }.filterNotNull().forEach { + container.items().iterator().map { it.matter }.filterNotNull().forEach { result.matter!!.storedMatter += it.storedMatter } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt index 138247afc..f3bb8f4dd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/MatteryCookingRecipe.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.recipe import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.data.recipes.FinishedRecipe @@ -16,6 +17,7 @@ import net.minecraft.world.item.crafting.* import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.container.get +import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer @@ -29,15 +31,15 @@ abstract class MatteryCookingRecipe( val count: Int = 1, val workTime: Int = 200, val experience: FloatProvider = ConstantFloat.ZERO -) : Recipe { - override fun matches(container: Container, level: Level): Boolean { +) : Recipe { + override fun matches(container: RecipeInput, level: Level): Boolean { if (isIncomplete) return false return input.test(container[0]) } - fun matches(container: Container, slot: Int): Boolean { + fun matches(container: RecipeInput, slot: Int): Boolean { if (isIncomplete) return false @@ -63,11 +65,11 @@ abstract class MatteryCookingRecipe( override fun isIncomplete(): Boolean = input.isActuallyEmpty || output.isActuallyEmpty - override fun assemble(container: Container, registry: RegistryAccess): ItemStack = outputStack.copy() + override fun assemble(container: RecipeInput, registry: HolderLookup.Provider): ItemStack = outputStack.copy() override fun canCraftInDimensions(width: Int, height: Int): Boolean = true - override fun getResultItem(registry: RegistryAccess): ItemStack = outputStack + override fun getResultItem(registry: HolderLookup.Provider): ItemStack = outputStack abstract fun toFinished(id: ResourceLocation): FinishedRecipe } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt index bc89e7f34..124d68946 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PainterRecipe.kt @@ -6,6 +6,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder import it.unimi.dsi.fastutil.objects.Object2IntArrayMap import it.unimi.dsi.fastutil.objects.Object2IntMap import it.unimi.dsi.fastutil.objects.Object2IntMaps +import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.data.recipes.FinishedRecipe @@ -14,12 +15,13 @@ import net.minecraft.util.StringRepresentable import net.minecraft.world.Container import net.minecraft.world.item.* import net.minecraft.world.item.crafting.Ingredient -import net.minecraft.world.item.crafting.Recipe +import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity import ru.dbotthepony.mc.otm.container.get +import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.tagNotNull @@ -32,12 +34,12 @@ import java.util.function.Predicate abstract class AbstractPainterRecipe( dyes: Map -) : IMatteryRecipe { +) : IMatteryRecipe { val dyes: Object2IntMap = Object2IntMaps.unmodifiable(Object2IntArrayMap(dyes)) abstract fun matches(value: ItemStack): Boolean - override fun matches(contaier: Container, level: Level): Boolean { + override fun matches(contaier: RecipeInput, level: Level): Boolean { return !isIncomplete && matches(contaier[0]) } @@ -128,7 +130,7 @@ class PainterRecipe( return NonNullList.of(Ingredient.EMPTY, input) } - override fun assemble(p_44001_: Container, p_267165_: RegistryAccess): ItemStack { + override fun assemble(p_44001_: RecipeInput, registries: HolderLookup.Provider): ItemStack { return output.copy().also { o -> p_44001_[0].tag?.let { if (o.tag == null) { @@ -142,7 +144,7 @@ class PainterRecipe( } } - override fun getResultItem(p_267052_: RegistryAccess): ItemStack { + override fun getResultItem(registries: HolderLookup.Provider): ItemStack { return output } @@ -185,7 +187,7 @@ class PainterArmorDyeRecipe( return !isIncomplete && value.item is DyeableArmorItem } - override fun assemble(container: Container, registry: RegistryAccess): ItemStack { + override fun assemble(container: RecipeInput, registry: HolderLookup.Provider): ItemStack { var output = container[0].copy() dyes.forEach { entry -> @@ -199,7 +201,7 @@ class PainterArmorDyeRecipe( return output } - override fun getResultItem(registry: RegistryAccess): ItemStack = ItemStack.EMPTY + override fun getResultItem(registry: HolderLookup.Provider): ItemStack = ItemStack.EMPTY override fun getSerializer(): RecipeSerializer<*> = SERIALIZER diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt index 1561f8b43..cba8be8c9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.recipe import com.mojang.serialization.Codec import com.mojang.serialization.codecs.RecordCodecBuilder +import net.minecraft.core.HolderLookup import net.minecraft.core.NonNullList import net.minecraft.core.RegistryAccess import net.minecraft.resources.ResourceLocation @@ -11,11 +12,13 @@ import net.minecraft.world.Container import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Recipe +import net.minecraft.world.item.crafting.RecipeInput import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.level.Level import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.container.get +import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.isActuallyEmpty import ru.dbotthepony.mc.otm.registry.MRecipes import ru.dbotthepony.mc.otm.core.registryName @@ -29,8 +32,8 @@ class PlatePressRecipe( val count: Int = 1, val workTime: Int = 200, val experience: FloatProvider = ConstantFloat.ZERO -) : Recipe { - override fun matches(container: Container, p_44003_: Level): Boolean { +) : Recipe { + override fun matches(container: RecipeInput, p_44003_: Level): Boolean { if (isIncomplete) return false @@ -65,9 +68,9 @@ class PlatePressRecipe( return input.isActuallyEmpty || output.isActuallyEmpty } - override fun assemble(p_44001_: Container, registry: RegistryAccess): ItemStack = outputStack.copy() + override fun assemble(p_44001_: RecipeInput, registry: HolderLookup.Provider): ItemStack = outputStack.copy() override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int) = true - override fun getResultItem(registry: RegistryAccess): ItemStack = outputStack + override fun getResultItem(registry: HolderLookup.Provider): ItemStack = outputStack override fun getSerializer(): RecipeSerializer<*> { return SERIALIZER diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt index 4130f31ef..6be2006db 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRecipes.kt @@ -8,6 +8,7 @@ import net.minecraftforge.registries.DeferredRegister import net.minecraftforge.registries.ForgeRegistries import net.minecraftforge.registries.RegistryObject import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.core.ResourceLocation import ru.dbotthepony.mc.otm.recipe.* @Suppress("SameParameterValue")