Some minor changes for 1.21

This commit is contained in:
DBotThePony 2024-07-01 20:02:32 +07:00
parent 0a4468fcdd
commit 91835905a3
Signed by: DBot
GPG Key ID: DCC23B5715498507
14 changed files with 174 additions and 125 deletions

View File

@ -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<IMatteryUpgrade> 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);
}
}

View File

@ -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

View File

@ -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<ItemStack> {
interface IMatteryContainer : IContainer, RecipeInput, Iterable<ItemStack> {
fun getSlotFilter(slot: Int): Item?
/**
@ -19,8 +20,13 @@ interface IMatteryContainer : IContainer, Iterable<ItemStack> {
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<ItemStack> {
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)

View File

@ -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<SerializedItem> = 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<SerializedFilter> = 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<SerializedItem>,
val filters: List<SerializedFilter>
) {
companion object {
val CODEC: Codec<SerializedState> = 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<ItemStack> {
return StreamSupport.stream(spliterator(), false)
}
companion object {
private val LOGGER = LogManager.getLogger()
}
}

View File

@ -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 <T> LazyOptional<T>.ifPresentK(lambda: (T) -> Unit) {
}
}
val ItemStack.tagNotNull: CompoundTag get() = orCreateTag
inline val FluidStack.isNotEmpty get() = !isEmpty
inline val ItemStack.isNotEmpty get() = !isEmpty

View File

@ -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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.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 <V : Any> Codec<V>.toNetwork(buff: FriendlyByteBuf, value: V) {
@ -70,7 +73,7 @@ fun <V : Any> Codec<V>.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 <T> IForgeRegistry<T>.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<DamageType>): Holder<DamageType> {
return registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(key)
}
// 1.21
fun ResourceLocation(namespace: String, path: String) = ResourceLocation.fromNamespaceAndPath(namespace, path)
// mojang hello?
fun <IN, OUT> DataResult<IN>.get(map: (IN) -> OUT, orThrow: (DataResult.Error<IN>) -> Nothing): OUT {
return result().map(map).orElseGet { orThrow(error().get()) }
}
fun <IN, OUT> DataResult<IN>.getOrNull(map: (IN) -> OUT): OUT? {
return result().map(map).orElse(null)
}

View File

@ -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

View File

@ -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<C : Container> : Recipe<C> {
interface IMatteryRecipe<C : RecipeInput> : Recipe<C> {
override fun getRemainingItems(p_44004_: C): NonNullList<ItemStack> {
return super.getRemainingItems(p_44004_)
}

View File

@ -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<CraftingContainer>, Iterable<Ingredient> {
interface IIngredientMatrix : Predicate<CraftingInput>, Iterable<Ingredient> {
val width: Int
val height: Int
val isEmpty: Boolean
@ -52,8 +54,8 @@ interface IIngredientMatrix : Predicate<CraftingContainer>, Iterable<Ingredient>
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<CraftingContainer>, Iterable<Ingredient>
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<CraftingContainer>, Iterable<Ingredient>
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

View File

@ -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<CraftingContainer> {
interface IMatterEntanglerRecipe : IMatteryRecipe<CraftingInput> {
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<UUID> = 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
}
}

View File

@ -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<Container> {
override fun matches(container: Container, level: Level): Boolean {
) : Recipe<RecipeInput> {
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
}

View File

@ -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<out DyeColor?, Int>
) : IMatteryRecipe<Container> {
) : IMatteryRecipe<RecipeInput> {
val dyes: Object2IntMap<DyeColor?> = 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

View File

@ -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<Container> {
override fun matches(container: Container, p_44003_: Level): Boolean {
) : Recipe<RecipeInput> {
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

View File

@ -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")