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 it.unimi.dsi.fastutil.objects.Object2IntMaps
|
||||||
import net.minecraft.core.HolderLookup
|
import net.minecraft.core.HolderLookup
|
||||||
import net.minecraft.core.NonNullList
|
import net.minecraft.core.NonNullList
|
||||||
import net.minecraft.data.recipes.FinishedRecipe
|
import net.minecraft.core.component.DataComponents
|
||||||
import net.minecraft.resources.ResourceLocation
|
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.util.StringRepresentable
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.item.DyeColor
|
||||||
import net.minecraft.world.item.*
|
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.Ingredient
|
||||||
import net.minecraft.world.item.crafting.RecipeInput
|
import net.minecraft.world.item.crafting.RecipeInput
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
|
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.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.PredicatedCodecList
|
||||||
import ru.dbotthepony.mc.otm.data.minRange
|
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.MItems
|
||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
import java.util.function.Predicate
|
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(
|
abstract class AbstractPainterRecipe(
|
||||||
dyes: Map<out DyeColor?, Int>
|
dyes: Map<out DyeColor?, Int>
|
||||||
@ -63,7 +82,7 @@ abstract class AbstractPainterRecipe(
|
|||||||
|
|
||||||
override fun isSpecial(): Boolean = true
|
override fun isSpecial(): Boolean = true
|
||||||
|
|
||||||
open fun getOutput(container: Container): ItemStack {
|
open fun getOutput(container: RecipeInput): ItemStack {
|
||||||
if (container.isEmpty) return ItemStack.EMPTY
|
if (container.isEmpty) return ItemStack.EMPTY
|
||||||
|
|
||||||
return container[0].copy()
|
return container[0].copy()
|
||||||
@ -96,6 +115,12 @@ abstract class AbstractPainterRecipe(
|
|||||||
companion object {
|
companion object {
|
||||||
private val wrapperCodec: Codec<DyeColorWrapper> = StringRepresentable.fromEnum(DyeColorWrapper::values)
|
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
|
@JvmStatic
|
||||||
protected val dyesFieldCodec: MapCodec<Map<DyeColor?, Int>> = PredicatedCodecList<Map<DyeColorWrapper, Int>>(
|
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 },
|
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 {
|
override fun isIncomplete(): Boolean {
|
||||||
return input.isActuallyEmpty || output.isEmpty
|
return input.hasNoItems() || output.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIngredients(): NonNullList<Ingredient> {
|
override fun getIngredients(): NonNullList<Ingredient> {
|
||||||
return NonNullList.of(Ingredient.EMPTY, input)
|
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 ->
|
return output.copy().also { o ->
|
||||||
p_44001_[0].tag?.let {
|
o.applyComponentsAndValidate(input[0].componentsPatch)
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,30 +164,39 @@ class PainterRecipe(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getSerializer(): RecipeSerializer<*> {
|
override fun getSerializer(): RecipeSerializer<*> {
|
||||||
return SERIALIZER
|
return Companion
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getType(): RecipeType<*> {
|
override fun getType(): RecipeType<*> {
|
||||||
return MRecipes.PAINTER
|
return MRecipes.PAINTER
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
override fun getOutput(container: RecipeInput): ItemStack {
|
||||||
return SERIALIZER.toFinished(this, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOutput(container: Container): ItemStack {
|
|
||||||
return output.copy()
|
return output.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object : RecipeSerializer<PainterRecipe> {
|
||||||
val SERIALIZER = Codec2RecipeSerializer<PainterRecipe> { context ->
|
private val codec = RecordCodecBuilder.mapCodec {
|
||||||
RecordCodecBuilder.create {
|
it.group(
|
||||||
it.group(
|
Ingredient.CODEC_NONEMPTY.fieldOf("input").forGetter(PainterRecipe::input),
|
||||||
context.ingredients.fieldOf("input").forGetter(PainterRecipe::input),
|
ItemStack.CODEC.fieldOf("output").forGetter(PainterRecipe::output),
|
||||||
ItemStack.CODEC.fieldOf("output").forGetter(PainterRecipe::output),
|
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
||||||
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
).apply(it, ::PainterRecipe)
|
||||||
).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 } })
|
) : this(Object2IntArrayMap<DyeColor?>().also { map -> dyes.forEach { map[it] = 1 } })
|
||||||
|
|
||||||
override fun matches(value: ItemStack): Boolean {
|
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 {
|
private fun assemble(value: ItemStack): ItemStack {
|
||||||
var output = container[0].copy()
|
var output = value.copy()
|
||||||
|
|
||||||
dyes.forEach { entry ->
|
if (dyes.size == 1 && dyes.keys.first() == null) {
|
||||||
if (entry.key == null) {
|
output[DataComponents.DYED_COLOR] = null
|
||||||
(output.item as DyeableLeatherItem).clearColor(output)
|
} else {
|
||||||
} else {
|
output = DyedItemColor.applyDyes(output, dyes.keys.map { DyeItem.byColor(it!!) })
|
||||||
output = DyeableLeatherItem.dyeArmor(output.copy(), listOf(DyeItem.byColor(entry.key!!)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
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 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 getType(): RecipeType<*> = MRecipes.PAINTER
|
||||||
|
|
||||||
override fun isIncomplete(): Boolean = dyes.isEmpty()
|
override fun isIncomplete(): Boolean = dyes.isEmpty()
|
||||||
|
|
||||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
override fun getOutput(container: RecipeInput): ItemStack {
|
||||||
return SERIALIZER.toFinished(this, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOutput(container: Container): ItemStack {
|
|
||||||
if (container.isEmpty) return ItemStack.EMPTY
|
if (container.isEmpty) return ItemStack.EMPTY
|
||||||
|
return assemble(container[0])
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object : RecipeSerializer<PainterArmorDyeRecipe> {
|
||||||
val SERIALIZER = Codec2RecipeSerializer<PainterArmorDyeRecipe> { _ ->
|
private val codec by lazy {
|
||||||
RecordCodecBuilder.create {
|
RecordCodecBuilder.mapCodec {
|
||||||
it.group(
|
it.group(
|
||||||
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
dyesFieldCodec.forGetter(AbstractPainterRecipe::dyes),
|
||||||
).apply(it, ::PainterArmorDyeRecipe)
|
).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