paint and remove armor dye in painting table
This commit is contained in:
parent
6c9058e72d
commit
94e1ce6d8e
@ -10,6 +10,7 @@ import net.minecraft.world.item.crafting.Ingredient
|
|||||||
import ru.dbotthepony.mc.otm.core.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import ru.dbotthepony.mc.otm.core.stream
|
import ru.dbotthepony.mc.otm.core.stream
|
||||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||||
|
import ru.dbotthepony.mc.otm.recipe.PainterArmorDyeRecipe
|
||||||
import ru.dbotthepony.mc.otm.recipe.PainterRecipe
|
import ru.dbotthepony.mc.otm.recipe.PainterRecipe
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
@ -283,4 +284,9 @@ fun addPainterRecipes(consumer: RecipeOutput) {
|
|||||||
striped(consumer, "stairs", MRegistry.TRITANIUM_STRIPED_STAIRS.itemsWithColor, MRegistry.TRITANIUM_STAIRS.items)
|
striped(consumer, "stairs", MRegistry.TRITANIUM_STRIPED_STAIRS.itemsWithColor, MRegistry.TRITANIUM_STAIRS.items)
|
||||||
striped(consumer, "walls", MRegistry.TRITANIUM_STRIPED_WALL.itemsWithColor, MRegistry.TRITANIUM_WALL.items)
|
striped(consumer, "walls", MRegistry.TRITANIUM_STRIPED_WALL.itemsWithColor, MRegistry.TRITANIUM_WALL.items)
|
||||||
striped(consumer, "slabs", MRegistry.TRITANIUM_STRIPED_SLAB.itemsWithColor, MRegistry.TRITANIUM_SLAB.items)
|
striped(consumer, "slabs", MRegistry.TRITANIUM_STRIPED_SLAB.itemsWithColor, MRegistry.TRITANIUM_SLAB.items)
|
||||||
|
|
||||||
|
for (color in DyeColor.entries) {
|
||||||
|
consumer.accept(PainterArmorDyeRecipe(mapOf(color to 1)).toFinished(modLocation("painter/armor_dye_" + color.getName().lowercase())))
|
||||||
|
}
|
||||||
|
consumer.accept(PainterArmorDyeRecipe(mapOf(null to 15)).toFinished(modLocation("painter/armor_clear_dye")))
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import ru.dbotthepony.mc.otm.core.map
|
|||||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator
|
import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator
|
||||||
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
|
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
|
||||||
|
import ru.dbotthepony.mc.otm.recipe.PainterRecipe
|
||||||
|
|
||||||
class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) : MatteryScreen<PainterMenu>(menu, inventory, title) {
|
class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) : MatteryScreen<PainterMenu>(menu, inventory, title) {
|
||||||
private inner class Bar(parent: EditablePanel<*>, val dye: DyeColor?) : EditablePanel<PainterScreen>(this@PainterScreen, parent, width = 5f) {
|
private inner class Bar(parent: EditablePanel<*>, val dye: DyeColor?) : EditablePanel<PainterScreen>(this@PainterScreen, parent, width = 5f) {
|
||||||
@ -130,8 +131,19 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
|
|||||||
buttons.forEach { it.remove() }
|
buttons.forEach { it.remove() }
|
||||||
buttons.clear()
|
buttons.clear()
|
||||||
|
|
||||||
for (recipe in menu.possibleRecipes.sortedWith(CreativeMenuItemComparator.map { it.value.output.item })) {
|
val recipes = menu.possibleRecipes
|
||||||
object : LargeRectangleButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas, icon = ItemStackIcon(recipe.value.output, 14f, 14f).fixed()) {
|
.filter { !it.value.ingredients.isEmpty() }
|
||||||
|
.sortedWith(CreativeMenuItemComparator.map { it.value.getOutput(menu.inputContainer).item })
|
||||||
|
.plus(
|
||||||
|
menu.possibleRecipes
|
||||||
|
.filter { it.value.ingredients.isEmpty() }
|
||||||
|
.sortedBy { it.id }
|
||||||
|
)
|
||||||
|
|
||||||
|
for (recipe in recipes) {
|
||||||
|
val recipeOutput = recipe.value.getOutput(menu.inputContainer)
|
||||||
|
|
||||||
|
object : LargeRectangleButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas, icon = ItemStackIcon(recipeOutput, 14f, 14f).fixed()) {
|
||||||
init {
|
init {
|
||||||
buttons.add(this)
|
buttons.add(this)
|
||||||
dockRight = 1f
|
dockRight = 1f
|
||||||
@ -143,7 +155,7 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
|
|||||||
set(value) {}
|
set(value) {}
|
||||||
|
|
||||||
override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
||||||
val list = getTooltipFromItem(minecraft!!, recipe.value.output)
|
val list = getTooltipFromItem(minecraft!!, recipeOutput)
|
||||||
|
|
||||||
recipe.value.dyes.forEach {
|
recipe.value.dyes.forEach {
|
||||||
val (dye, amount) = it
|
val (dye, amount) = it
|
||||||
|
@ -3,8 +3,7 @@ package ru.dbotthepony.mc.otm.menu.decorative
|
|||||||
import net.minecraft.world.SimpleContainer
|
import net.minecraft.world.SimpleContainer
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.DyeColor
|
import net.minecraft.world.item.*
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.item.crafting.RecipeHolder
|
import net.minecraft.world.item.crafting.RecipeHolder
|
||||||
import net.minecraft.world.level.material.Fluids
|
import net.minecraft.world.level.material.Fluids
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
@ -17,19 +16,14 @@ import ru.dbotthepony.mc.otm.core.ISubscriptable
|
|||||||
import ru.dbotthepony.mc.otm.core.addAll
|
import ru.dbotthepony.mc.otm.core.addAll
|
||||||
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
|
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
|
||||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||||
import ru.dbotthepony.mc.otm.core.collect.find
|
|
||||||
import ru.dbotthepony.mc.otm.core.collect.maybe
|
import ru.dbotthepony.mc.otm.core.collect.maybe
|
||||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
|
||||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||||
import ru.dbotthepony.mc.otm.core.map
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.ResourceLocationValueCodec
|
import ru.dbotthepony.mc.otm.core.util.ResourceLocationValueCodec
|
||||||
import ru.dbotthepony.mc.otm.isClientThread
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterySlot
|
import ru.dbotthepony.mc.otm.menu.MatterySlot
|
||||||
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||||
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
|
||||||
import ru.dbotthepony.mc.otm.recipe.PainterRecipe
|
import ru.dbotthepony.mc.otm.recipe.AbstractPainterRecipe
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -48,7 +42,7 @@ class PainterMenu(
|
|||||||
|
|
||||||
val inputContainer = MatteryContainer(::rescan, 1)
|
val inputContainer = MatteryContainer(::rescan, 1)
|
||||||
val outputContainer = MatteryContainer(1)
|
val outputContainer = MatteryContainer(1)
|
||||||
private var lastRecipe: RecipeHolder<PainterRecipe>? = null
|
private var lastRecipe: RecipeHolder<out AbstractPainterRecipe>? = null
|
||||||
var selectedRecipe by mSynchronizer.Field(null, ResourceLocationValueCodec.nullable).also { it.addListener { rescan() } }
|
var selectedRecipe by mSynchronizer.Field(null, ResourceLocationValueCodec.nullable).also { it.addListener { rescan() } }
|
||||||
|
|
||||||
val isBulk = BooleanInputWithFeedback(this, tile?.let { it::isBulk })
|
val isBulk = BooleanInputWithFeedback(this, tile?.let { it::isBulk })
|
||||||
@ -59,6 +53,10 @@ class PainterMenu(
|
|||||||
|
|
||||||
val inputSlot = object : MatterySlot(inputContainer, 0) {
|
val inputSlot = object : MatterySlot(inputContainer, 0) {
|
||||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||||
|
if (!itemStack.isEmpty && itemStack.item is DyeableArmorItem) {
|
||||||
|
return super.mayPlace(itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.any { it.value.input.test(itemStack) }
|
return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.any { it.value.input.test(itemStack) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,18 +124,24 @@ class PainterMenu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val listeners = ISubscriptable.Impl<Unit>()
|
val listeners = ISubscriptable.Impl<Unit>()
|
||||||
val possibleRecipes = ArrayList<RecipeHolder<PainterRecipe>>()
|
val possibleRecipes = ArrayList<RecipeHolder<out AbstractPainterRecipe>>()
|
||||||
|
|
||||||
private fun rescan() {
|
private fun rescan() {
|
||||||
possibleRecipes.clear()
|
possibleRecipes.clear()
|
||||||
possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.iterator().filter { it.value.input.test(inputContainer[0]) })
|
possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.iterator().filter { it.value.input.test(inputContainer[0]) })
|
||||||
|
|
||||||
|
if (!inputContainer[0].isEmpty && inputContainer[0].item is DyeableArmorItem) {
|
||||||
|
possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER_ARMOR_DYE).values)
|
||||||
|
}
|
||||||
|
|
||||||
listeners.accept(Unit)
|
listeners.accept(Unit)
|
||||||
if (tile !is PainterBlockEntity) return
|
if (tile !is PainterBlockEntity) return
|
||||||
|
|
||||||
if (inputContainer.isEmpty || selectedRecipe == null) {
|
if (inputContainer.isEmpty || selectedRecipe == null) {
|
||||||
outputContainer.clearContent()
|
outputContainer.clearContent()
|
||||||
} else {
|
} else {
|
||||||
val recipe = inventory.player.level().recipeManager.byType(MRecipes.PAINTER)[selectedRecipe]
|
// val recipe = inventory.player.level().recipeManager.byType(MRecipes.PAINTER)[selectedRecipe]
|
||||||
|
val recipe = inventory.player.level().recipeManager.byKey(selectedRecipe).get() as RecipeHolder<AbstractPainterRecipe>?
|
||||||
|
|
||||||
if (recipe == null || !recipe.value.canCraft(dyeStoredDirect) || !recipe.value.matches(inputContainer, inventory.player.level())) {
|
if (recipe == null || !recipe.value.canCraft(dyeStoredDirect) || !recipe.value.matches(inputContainer, inventory.player.level())) {
|
||||||
outputContainer.clearContent()
|
outputContainer.clearContent()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.dbotthepony.mc.otm.recipe
|
package ru.dbotthepony.mc.otm.recipe
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap
|
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap
|
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap
|
||||||
@ -12,8 +11,7 @@ import net.minecraft.data.recipes.FinishedRecipe
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.util.StringRepresentable
|
import net.minecraft.util.StringRepresentable
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
import net.minecraft.world.item.DyeColor
|
import net.minecraft.world.item.*
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.item.crafting.Ingredient
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
import net.minecraft.world.item.crafting.Recipe
|
import net.minecraft.world.item.crafting.Recipe
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||||
@ -29,24 +27,15 @@ 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.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.EnumMap
|
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.stream.Collector
|
|
||||||
import java.util.stream.Collectors
|
|
||||||
|
|
||||||
class PainterRecipe(
|
abstract class AbstractPainterRecipe(
|
||||||
val input: Ingredient,
|
|
||||||
val output: ItemStack,
|
|
||||||
dyes: Map<out DyeColor?, Int>
|
dyes: Map<out DyeColor?, Int>
|
||||||
) : Recipe<Container> {
|
) : Recipe<Container> {
|
||||||
constructor(
|
|
||||||
input: Ingredient,
|
|
||||||
output: ItemStack,
|
|
||||||
dyes: Set<DyeColor?>
|
|
||||||
) : this(input, output, Object2IntArrayMap<DyeColor?>().also { map -> dyes.forEach { map[it] = 1 } })
|
|
||||||
|
|
||||||
val dyes: Object2IntMap<DyeColor?> = Object2IntMaps.unmodifiable(Object2IntArrayMap(dyes))
|
val dyes: Object2IntMap<DyeColor?> = Object2IntMaps.unmodifiable(Object2IntArrayMap(dyes))
|
||||||
|
|
||||||
|
override fun getToastSymbol(): ItemStack = ItemStack(MItems.PAINTER)
|
||||||
|
|
||||||
fun canCraft(storedDyes: Map<out DyeColor?, Int>): Boolean {
|
fun canCraft(storedDyes: Map<out DyeColor?, Int>): Boolean {
|
||||||
if (isIncomplete) return false
|
if (isIncomplete) return false
|
||||||
if (dyes.isEmpty() || dyes.values.none { it > 0 }) return true
|
if (dyes.isEmpty() || dyes.values.none { it > 0 }) return true
|
||||||
@ -63,6 +52,52 @@ class PainterRecipe(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int): Boolean = true
|
||||||
|
|
||||||
|
override fun isSpecial(): Boolean = true
|
||||||
|
|
||||||
|
open fun getOutput(container: Container): ItemStack {
|
||||||
|
if (container.isEmpty) return ItemStack.EMPTY
|
||||||
|
|
||||||
|
return container[0].copy()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DyeColorWrapper(private val refName: String, val key: DyeColor?) : StringRepresentable {
|
||||||
|
WHITE("white", DyeColor.WHITE),
|
||||||
|
ORANGE("orange", DyeColor.ORANGE),
|
||||||
|
MAGENTA("magenta", DyeColor.MAGENTA),
|
||||||
|
LIGHT_BLUE("light_blue", DyeColor.LIGHT_BLUE),
|
||||||
|
YELLOW("yellow", DyeColor.YELLOW),
|
||||||
|
LIME("lime", DyeColor.LIME),
|
||||||
|
PINK("pink", DyeColor.PINK),
|
||||||
|
GRAY("gray", DyeColor.GRAY),
|
||||||
|
LIGHT_GRAY("light_gray", DyeColor.LIGHT_GRAY),
|
||||||
|
CYAN("cyan", DyeColor.CYAN),
|
||||||
|
PURPLE("purple", DyeColor.PURPLE),
|
||||||
|
BLUE("blue", DyeColor.BLUE),
|
||||||
|
BROWN("brown", DyeColor.BROWN),
|
||||||
|
GREEN("green", DyeColor.GREEN),
|
||||||
|
RED("red", DyeColor.RED),
|
||||||
|
BLACK("black", DyeColor.BLACK),
|
||||||
|
WATER("water", null);
|
||||||
|
|
||||||
|
override fun getSerializedName(): String {
|
||||||
|
return refName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PainterRecipe(
|
||||||
|
val input: Ingredient,
|
||||||
|
val output: ItemStack,
|
||||||
|
dyes: Map<out DyeColor?, Int>
|
||||||
|
) : AbstractPainterRecipe(dyes) {
|
||||||
|
constructor(
|
||||||
|
input: Ingredient,
|
||||||
|
output: ItemStack,
|
||||||
|
dyes: Set<DyeColor?>
|
||||||
|
) : this(input, output, Object2IntArrayMap<DyeColor?>().also { map -> dyes.forEach { map[it] = 1 } })
|
||||||
|
|
||||||
override fun matches(p_44002_: Container, p_44003_: Level): Boolean {
|
override fun matches(p_44002_: Container, p_44003_: Level): Boolean {
|
||||||
if (isIncomplete) return false
|
if (isIncomplete) return false
|
||||||
return input.test(p_44002_[0])
|
return input.test(p_44002_[0])
|
||||||
@ -90,14 +125,6 @@ class PainterRecipe(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isSpecial(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getResultItem(p_267052_: RegistryAccess): ItemStack {
|
override fun getResultItem(p_267052_: RegistryAccess): ItemStack {
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
@ -110,36 +137,12 @@ class PainterRecipe(
|
|||||||
return MRecipes.PAINTER
|
return MRecipes.PAINTER
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getToastSymbol(): ItemStack {
|
|
||||||
return ItemStack(MItems.PAINTER)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||||
return SERIALIZER.toFinished(this, id)
|
return SERIALIZER.toFinished(this, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class DyeColorWrapper(val refName: String, val key: DyeColor?) : StringRepresentable {
|
override fun getOutput(container: Container): ItemStack {
|
||||||
WHITE("white", DyeColor.WHITE),
|
return this.output
|
||||||
ORANGE("orange", DyeColor.ORANGE),
|
|
||||||
MAGENTA("magenta", DyeColor.MAGENTA),
|
|
||||||
LIGHT_BLUE("light_blue", DyeColor.LIGHT_BLUE),
|
|
||||||
YELLOW("yellow", DyeColor.YELLOW),
|
|
||||||
LIME("lime", DyeColor.LIME),
|
|
||||||
PINK("pink", DyeColor.PINK),
|
|
||||||
GRAY("gray", DyeColor.GRAY),
|
|
||||||
LIGHT_GRAY("light_gray", DyeColor.LIGHT_GRAY),
|
|
||||||
CYAN("cyan", DyeColor.CYAN),
|
|
||||||
PURPLE("purple", DyeColor.PURPLE),
|
|
||||||
BLUE("blue", DyeColor.BLUE),
|
|
||||||
BROWN("brown", DyeColor.BROWN),
|
|
||||||
GREEN("green", DyeColor.GREEN),
|
|
||||||
RED("red", DyeColor.RED),
|
|
||||||
BLACK("black", DyeColor.BLACK),
|
|
||||||
WATER("water", null);
|
|
||||||
|
|
||||||
override fun getSerializedName(): String {
|
|
||||||
return refName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -160,3 +163,75 @@ class PainterRecipe(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class PainterArmorDyeRecipe(
|
||||||
|
dyes: Map<out DyeColor?, Int>
|
||||||
|
) : AbstractPainterRecipe(dyes) {
|
||||||
|
constructor(
|
||||||
|
dyes: Set<DyeColor?>
|
||||||
|
) : this(Object2IntArrayMap<DyeColor?>().also { map -> dyes.forEach { map[it] = 1 } })
|
||||||
|
|
||||||
|
override fun matches(contaier: Container, level: Level): Boolean {
|
||||||
|
if (this.isIncomplete) return false
|
||||||
|
val stack = contaier[0]
|
||||||
|
|
||||||
|
return (!stack.isEmpty && stack.item is DyeableArmorItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assemble(container: Container, registry: RegistryAccess): ItemStack {
|
||||||
|
var output = container[0].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!!)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getResultItem(registry: RegistryAccess): ItemStack = ItemStack.EMPTY
|
||||||
|
|
||||||
|
override fun getSerializer(): RecipeSerializer<*> = SERIALIZER
|
||||||
|
|
||||||
|
override fun getType(): RecipeType<*> = MRecipes.PAINTER_ARMOR_DYE
|
||||||
|
|
||||||
|
override fun isIncomplete(): Boolean = dyes.isEmpty()
|
||||||
|
|
||||||
|
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||||
|
return SERIALIZER.toFinished(this, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOutput(container: Container): 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.copy(), listOf(DyeItem.byColor(entry.key!!)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val wrapperCodec = StringRepresentable.fromEnum(DyeColorWrapper::values)
|
||||||
|
|
||||||
|
val SERIALIZER = Codec2RecipeSerializer<PainterArmorDyeRecipe> { _ ->
|
||||||
|
RecordCodecBuilder.create {
|
||||||
|
it.group(
|
||||||
|
PredicatedCodecList<Map<DyeColorWrapper, Int>>(
|
||||||
|
wrapperCodec.xmap({ mapOf(it to 1) }, { it.keys.first() }) to Predicate { it.keys.size == 1 && it.values.first() == 1 },
|
||||||
|
Codec.list(wrapperCodec).xmap({ it.associateWith { 1 } }, { ArrayList(it.keys) }) to Predicate { it.values.all { it == 1 } },
|
||||||
|
Codec.unboundedMap(wrapperCodec, Codec.INT.minRange(1)) to Predicate { true }
|
||||||
|
).fieldOf("dyes").xmap({ it.mapKeys { it.key.key } }, { it.mapKeys { k -> DyeColorWrapper.entries.first { k.key == it.key } } }).forGetter(PainterArmorDyeRecipe::dyes),
|
||||||
|
).apply(it, ::PainterArmorDyeRecipe)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ object MRecipes {
|
|||||||
|
|
||||||
val PLATE_PRESS by register<PlatePressRecipe>("plate_press")
|
val PLATE_PRESS by register<PlatePressRecipe>("plate_press")
|
||||||
val PAINTER by register<PainterRecipe>("painter")
|
val PAINTER by register<PainterRecipe>("painter")
|
||||||
|
val PAINTER_ARMOR_DYE by register<PainterArmorDyeRecipe>("painter_armor_dye")
|
||||||
val MATTER_ENTANGLER by register<IMatterEntanglerRecipe>("matter_entangler")
|
val MATTER_ENTANGLER by register<IMatterEntanglerRecipe>("matter_entangler")
|
||||||
val MICROWAVE by register<MicrowaveRecipe>("microwave")
|
val MICROWAVE by register<MicrowaveRecipe>("microwave")
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ object MRecipes {
|
|||||||
serializers.register("upgrade") { UpgradeRecipe.CODEC }
|
serializers.register("upgrade") { UpgradeRecipe.CODEC }
|
||||||
serializers.register("hammer_priming") { ExplosiveHammerPrimingRecipe.CODEC }
|
serializers.register("hammer_priming") { ExplosiveHammerPrimingRecipe.CODEC }
|
||||||
serializers.register("painter") { PainterRecipe.SERIALIZER }
|
serializers.register("painter") { PainterRecipe.SERIALIZER }
|
||||||
|
serializers.register("painter_armor_dye") { PainterArmorDyeRecipe.SERIALIZER }
|
||||||
serializers.register("matter_entangler") { MatterEntanglerRecipe.SERIALIZER }
|
serializers.register("matter_entangler") { MatterEntanglerRecipe.SERIALIZER }
|
||||||
serializers.register("matter_entangler_energetic") { MatterEntanglerRecipe.ENERGY_SERIALIZER }
|
serializers.register("matter_entangler_energetic") { MatterEntanglerRecipe.ENERGY_SERIALIZER }
|
||||||
serializers.register("matter_entangler_matter") { MatterEntanglerRecipe.MATTER_SERIALIZER }
|
serializers.register("matter_entangler_matter") { MatterEntanglerRecipe.MATTER_SERIALIZER }
|
||||||
|
Loading…
Reference in New Issue
Block a user