Some minor changes for 1.21
This commit is contained in:
parent
0a4468fcdd
commit
91835905a3
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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_)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user