Update painter recipe
This commit is contained in:
parent
a751cebf2d
commit
64ba95e305
@ -8,27 +8,46 @@ 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.data.recipes.FinishedRecipe
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.core.component.DataComponents
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.tags.ItemTags
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.item.*
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.DyeItem
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.component.DyedItemColor
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
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
|
||||
import ru.dbotthepony.mc.otm.data.PredicatedCodecList
|
||||
import ru.dbotthepony.mc.otm.data.minRange
|
||||
import ru.dbotthepony.mc.otm.network.MatteryStreamCodec
|
||||
import ru.dbotthepony.mc.otm.network.nullable
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||
import java.util.function.Predicate
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.Map
|
||||
import kotlin.collections.Set
|
||||
import kotlin.collections.all
|
||||
import kotlin.collections.associateWith
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.first
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.iterator
|
||||
import kotlin.collections.map
|
||||
import kotlin.collections.mapKeys
|
||||
import kotlin.collections.mapOf
|
||||
import kotlin.collections.none
|
||||
import kotlin.collections.set
|
||||
|
||||
abstract class AbstractPainterRecipe(
|
||||
dyes: Map<out DyeColor?, Int>
|
||||
@ -63,7 +82,7 @@ abstract class AbstractPainterRecipe(
|
||||
|
||||
override fun isSpecial(): Boolean = true
|
||||
|
||||
open fun getOutput(container: Container): ItemStack {
|
||||
open fun getOutput(container: RecipeInput): ItemStack {
|
||||
if (container.isEmpty) return ItemStack.EMPTY
|
||||
|
||||
return container[0].copy()
|
||||
@ -96,6 +115,12 @@ abstract class AbstractPainterRecipe(
|
||||
companion object {
|
||||
private val wrapperCodec: Codec<DyeColorWrapper> = StringRepresentable.fromEnum(DyeColorWrapper::values)
|
||||
|
||||
@JvmStatic
|
||||
protected val dyesFieldStreamCodec: StreamCodec<FriendlyByteBuf, Map<DyeColor?, Int>> = ByteBufCodecs.map(
|
||||
{ Object2IntArrayMap(it) },
|
||||
MatteryStreamCodec.Enum<FriendlyByteBuf, DyeColor>(DyeColor::class.java).nullable(),
|
||||
ByteBufCodecs.INT)
|
||||
|
||||
@JvmStatic
|
||||
protected val dyesFieldCodec: MapCodec<Map<DyeColor?, Int>> = PredicatedCodecList<Map<DyeColorWrapper, Int>>(
|
||||
wrapperCodec.xmap({ mapOf(it to 1) }, { it.keys.first() }) to Predicate { it.keys.size == 1 && it.values.first() == 1 },
|
||||
@ -121,24 +146,16 @@ class PainterRecipe(
|
||||
}
|
||||
|
||||
override fun isIncomplete(): Boolean {
|
||||
return input.isActuallyEmpty || output.isEmpty
|
||||
return input.hasNoItems() || output.isEmpty
|
||||
}
|
||||
|
||||
override fun getIngredients(): NonNullList<Ingredient> {
|
||||
return NonNullList.of(Ingredient.EMPTY, input)
|
||||
}
|
||||
|
||||
override fun assemble(p_44001_: RecipeInput, registries: HolderLookup.Provider): ItemStack {
|
||||
override fun assemble(input: RecipeInput, registries: HolderLookup.Provider): ItemStack {
|
||||
return output.copy().also { o ->
|
||||
p_44001_[0].tag?.let {
|
||||
if (o.tag == null) {
|
||||
o.tag = it.copy()
|
||||
} else {
|
||||
for (k in it.allKeys)
|
||||
if (k !in o.tagNotNull)
|
||||
o.tagNotNull[k] = it[k]!!.copy()
|
||||
}
|
||||
}
|
||||
o.applyComponentsAndValidate(input[0].componentsPatch)
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,30 +164,39 @@ class PainterRecipe(
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
return SERIALIZER
|
||||
return Companion
|
||||
}
|
||||
|
||||
override fun getType(): RecipeType<*> {
|
||||
return MRecipes.PAINTER
|
||||
}
|
||||
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
override fun getOutput(container: Container): ItemStack {
|
||||
override fun getOutput(container: RecipeInput): ItemStack {
|
||||
return output.copy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2RecipeSerializer<PainterRecipe> { context ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
context.ingredients.fieldOf("input").forGetter(PainterRecipe::input),
|
||||
ItemStack.CODEC.fieldOf("output").forGetter(PainterRecipe::output),
|
||||
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
||||
).apply(it, ::PainterRecipe)
|
||||
}
|
||||
companion object : RecipeSerializer<PainterRecipe> {
|
||||
private val codec = RecordCodecBuilder.mapCodec {
|
||||
it.group(
|
||||
Ingredient.CODEC_NONEMPTY.fieldOf("input").forGetter(PainterRecipe::input),
|
||||
ItemStack.CODEC.fieldOf("output").forGetter(PainterRecipe::output),
|
||||
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
||||
).apply(it, ::PainterRecipe)
|
||||
}
|
||||
|
||||
private val streamCodec = StreamCodec.composite(
|
||||
Ingredient.CONTENTS_STREAM_CODEC, PainterRecipe::input,
|
||||
ItemStack.STREAM_CODEC, PainterRecipe::output,
|
||||
dyesFieldStreamCodec, PainterRecipe::dyes,
|
||||
::PainterRecipe
|
||||
)
|
||||
|
||||
override fun codec(): MapCodec<PainterRecipe> {
|
||||
return codec
|
||||
}
|
||||
|
||||
override fun streamCodec(): StreamCodec<RegistryFriendlyByteBuf, PainterRecipe> {
|
||||
return streamCodec
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,58 +208,56 @@ class PainterArmorDyeRecipe(
|
||||
) : this(Object2IntArrayMap<DyeColor?>().also { map -> dyes.forEach { map[it] = 1 } })
|
||||
|
||||
override fun matches(value: ItemStack): Boolean {
|
||||
return !isIncomplete && value.item is DyeableArmorItem
|
||||
return !isIncomplete && value.`is`(ItemTags.DYEABLE)
|
||||
}
|
||||
|
||||
override fun assemble(container: RecipeInput, registry: HolderLookup.Provider): ItemStack {
|
||||
var output = container[0].copy()
|
||||
private fun assemble(value: ItemStack): ItemStack {
|
||||
var output = value.copy()
|
||||
|
||||
dyes.forEach { entry ->
|
||||
if (entry.key == null) {
|
||||
(output.item as DyeableLeatherItem).clearColor(output)
|
||||
} else {
|
||||
output = DyeableLeatherItem.dyeArmor(output.copy(), listOf(DyeItem.byColor(entry.key!!)))
|
||||
}
|
||||
if (dyes.size == 1 && dyes.keys.first() == null) {
|
||||
output[DataComponents.DYED_COLOR] = null
|
||||
} else {
|
||||
output = DyedItemColor.applyDyes(output, dyes.keys.map { DyeItem.byColor(it!!) })
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
override fun assemble(container: RecipeInput, registry: HolderLookup.Provider): ItemStack {
|
||||
if (container.isEmpty) return ItemStack.EMPTY
|
||||
return assemble(container[0])
|
||||
}
|
||||
|
||||
override fun getResultItem(registry: HolderLookup.Provider): ItemStack = ItemStack.EMPTY
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> = SERIALIZER
|
||||
override fun getSerializer(): RecipeSerializer<*> = Companion
|
||||
|
||||
override fun getType(): RecipeType<*> = MRecipes.PAINTER
|
||||
|
||||
override fun isIncomplete(): Boolean = dyes.isEmpty()
|
||||
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
override fun getOutput(container: Container): ItemStack {
|
||||
override fun getOutput(container: RecipeInput): ItemStack {
|
||||
if (container.isEmpty) return ItemStack.EMPTY
|
||||
|
||||
var output = container[0].copy()
|
||||
|
||||
dyes.forEach { entry ->
|
||||
if (entry.key == null) {
|
||||
(output.item as DyeableLeatherItem).clearColor(output)
|
||||
} else {
|
||||
output = DyeableLeatherItem.dyeArmor(output, listOf(DyeItem.byColor(entry.key!!)))
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
return assemble(container[0])
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2RecipeSerializer<PainterArmorDyeRecipe> { _ ->
|
||||
RecordCodecBuilder.create {
|
||||
companion object : RecipeSerializer<PainterArmorDyeRecipe> {
|
||||
private val codec by lazy {
|
||||
RecordCodecBuilder.mapCodec {
|
||||
it.group(
|
||||
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
||||
).apply(it, ::PainterArmorDyeRecipe)
|
||||
}
|
||||
}
|
||||
|
||||
private val streamCodec = dyesFieldStreamCodec.map(::PainterArmorDyeRecipe, AbstractPainterRecipe::dyes)
|
||||
|
||||
override fun codec(): MapCodec<PainterArmorDyeRecipe> {
|
||||
return codec
|
||||
}
|
||||
|
||||
override fun streamCodec(): StreamCodec<RegistryFriendlyByteBuf, PainterArmorDyeRecipe> {
|
||||
return streamCodec as StreamCodec<RegistryFriendlyByteBuf, PainterArmorDyeRecipe>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user