Update upgrade recipe, and merge energy container recipe onto upgrade recipe
This commit is contained in:
parent
7f927d5f05
commit
4c0bac35c1
@ -4,7 +4,6 @@ package ru.dbotthepony.mc.otm.datagen.recipes
|
|||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import net.minecraft.advancements.Advancement
|
import net.minecraft.advancements.Advancement
|
||||||
import net.minecraft.advancements.Criterion
|
import net.minecraft.advancements.Criterion
|
||||||
import net.minecraft.advancements.CriterionTriggerInstance
|
|
||||||
import net.minecraft.data.recipes.FinishedRecipe
|
import net.minecraft.data.recipes.FinishedRecipe
|
||||||
import net.minecraft.data.recipes.RecipeCategory
|
import net.minecraft.data.recipes.RecipeCategory
|
||||||
import net.minecraft.data.recipes.RecipeOutput
|
import net.minecraft.data.recipes.RecipeOutput
|
||||||
@ -20,9 +19,7 @@ import ru.dbotthepony.mc.otm.core.registryName
|
|||||||
import ru.dbotthepony.mc.otm.core.set
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||||
import ru.dbotthepony.mc.otm.recipe.EnergyContainerRecipe
|
|
||||||
import ru.dbotthepony.mc.otm.recipe.UpgradeRecipe
|
import ru.dbotthepony.mc.otm.recipe.UpgradeRecipe
|
||||||
import java.util.function.Consumer
|
|
||||||
|
|
||||||
private interface RecipeCell {
|
private interface RecipeCell {
|
||||||
val value: Ingredient
|
val value: Ingredient
|
||||||
@ -191,7 +188,7 @@ class MatteryRecipe(val result: ItemLike, val count: Int = 1, val category: Reci
|
|||||||
object : FinishedRecipe by it {
|
object : FinishedRecipe by it {
|
||||||
override fun serializeRecipeData(pJson: JsonObject) {
|
override fun serializeRecipeData(pJson: JsonObject) {
|
||||||
pJson["parent"] = it.serializeRecipe()
|
pJson["parent"] = it.serializeRecipe()
|
||||||
pJson["copyPaths"] = UpgradeRecipe.COPY_PATHS_CODEC.toJsonStrict(copyPaths)
|
pJson["copyPaths"] = UpgradeRecipe.OPERATION_CODEC.toJsonStrict(copyPaths)
|
||||||
pJson["source"] = upgradeSource!!.toString()
|
pJson["source"] = upgradeSource!!.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
|||||||
val canSetBatteryLevel: Boolean get() = true
|
val canSetBatteryLevel: Boolean get() = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How much energy (estimated) is stored in this energy storage. Why estimated? Because some objects can be bottomless.
|
* How much energy (considered to be estimated, and not ground truth) is stored in this energy storage
|
||||||
*
|
*
|
||||||
* Implementations are free to throw [UnsupportedOperationException] if setting battery level is not supported
|
* Implementations are free to throw [UnsupportedOperationException] if setting battery level is not supported
|
||||||
* due to technical complications (in this case, [canSetBatteryLevel] MUST be false)
|
* due to technical complications (in this case, [canSetBatteryLevel] MUST be false)
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.recipe
|
|
||||||
|
|
||||||
import com.mojang.serialization.Codec
|
|
||||||
import com.mojang.serialization.MapCodec
|
|
||||||
import net.minecraft.core.HolderLookup
|
|
||||||
import net.minecraft.core.RegistryAccess
|
|
||||||
import net.minecraft.core.component.DataComponents
|
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
|
||||||
import net.minecraft.network.codec.StreamCodec
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.item.crafting.CraftingBookCategory
|
|
||||||
import net.minecraft.world.item.crafting.CraftingInput
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
|
||||||
import net.minecraft.world.item.crafting.ShapedRecipe
|
|
||||||
import net.minecraft.world.item.crafting.ShapedRecipePattern
|
|
||||||
import net.minecraft.world.item.enchantment.ItemEnchantments
|
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.container.util.iterator
|
|
||||||
import ru.dbotthepony.mc.otm.core.filterNotNull
|
|
||||||
|
|
||||||
class EnergyContainerRecipe(group: String, category: CraftingBookCategory, pattern: ShapedRecipePattern, result: ItemStack, showNotification: Boolean = true) : ShapedRecipe(group, category, pattern, result, showNotification) {
|
|
||||||
constructor(parent: ShapedRecipe) : this(parent.group, parent.category(), parent.pattern, parent.result, parent.showNotification())
|
|
||||||
|
|
||||||
override fun assemble(container: CraftingInput, registryAccess: HolderLookup.Provider): ItemStack {
|
|
||||||
val itemStack = super.assemble(container, registryAccess)
|
|
||||||
|
|
||||||
val battery = container.items().stream()
|
|
||||||
.filter { !it.isEmpty }
|
|
||||||
.map { it.matteryEnergy }
|
|
||||||
.filterNotNull()
|
|
||||||
.findAny().orElse(null)
|
|
||||||
|
|
||||||
if (battery != null) {
|
|
||||||
itemStack.matteryEnergy?.batteryLevel = battery.batteryLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemStack.isEnchantable) {
|
|
||||||
for (it in container.items()) {
|
|
||||||
val enchantments = it[DataComponents.ENCHANTMENTS]
|
|
||||||
|
|
||||||
if (enchantments != null) {
|
|
||||||
itemStack[DataComponents.ENCHANTMENTS] = ItemEnchantments.Mutable(itemStack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).let {
|
|
||||||
for ((key, level) in enchantments.entrySet()) {
|
|
||||||
it.upgrade(key, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.toImmutable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemStack
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun matches(container: CraftingInput, level: Level): Boolean {
|
|
||||||
return super.matches(container, level) && container.items().none { it.isDamaged }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSerializer(): RecipeSerializer<EnergyContainerRecipe> {
|
|
||||||
return Companion
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : RecipeSerializer<EnergyContainerRecipe> {
|
|
||||||
private val codec by lazy {
|
|
||||||
RecipeSerializer.SHAPED_RECIPE.codec().xmap(::EnergyContainerRecipe, { it })
|
|
||||||
}
|
|
||||||
|
|
||||||
private val streamCodec by lazy {
|
|
||||||
RecipeSerializer.SHAPED_RECIPE.streamCodec().map(::EnergyContainerRecipe, { it })
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun codec(): MapCodec<EnergyContainerRecipe> {
|
|
||||||
return codec
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun streamCodec(): StreamCodec<RegistryFriendlyByteBuf, EnergyContainerRecipe> {
|
|
||||||
return streamCodec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +1,59 @@
|
|||||||
package ru.dbotthepony.mc.otm.recipe
|
package ru.dbotthepony.mc.otm.recipe
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList
|
|
||||||
import com.mojang.serialization.Codec
|
|
||||||
import com.mojang.serialization.MapCodec
|
import com.mojang.serialization.MapCodec
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
import net.minecraft.core.NonNullList
|
import net.minecraft.core.HolderLookup
|
||||||
import net.minecraft.core.RegistryAccess
|
import net.minecraft.core.component.DataComponentType
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.core.component.DataComponents
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||||
|
import net.minecraft.network.codec.ByteBufCodecs
|
||||||
|
import net.minecraft.network.codec.StreamCodec
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.util.StringRepresentable
|
import net.minecraft.util.StringRepresentable
|
||||||
import net.minecraft.world.inventory.CraftingContainer
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.crafting.CraftingBookCategory
|
import net.minecraft.world.item.crafting.CraftingBookCategory
|
||||||
import net.minecraft.world.item.crafting.CraftingRecipe
|
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.RecipeSerializer
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
|
||||||
import net.minecraft.world.item.crafting.ShapedRecipe
|
import net.minecraft.world.item.crafting.ShapedRecipe
|
||||||
|
import net.minecraft.world.item.crafting.ShapedRecipePattern
|
||||||
|
import net.minecraft.world.item.enchantment.ItemEnchantments
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.crafting.IShapedRecipe
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.container.util.stream
|
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
|
||||||
import ru.dbotthepony.mc.otm.core.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
|
||||||
import ru.dbotthepony.mc.otm.data.SingletonCodec
|
|
||||||
import java.util.stream.Stream
|
|
||||||
|
|
||||||
class UpgradeRecipe(
|
class UpgradeRecipe(
|
||||||
val parent: ShapedRecipe,
|
group: String,
|
||||||
copyPaths: Stream<Op>,
|
category: CraftingBookCategory,
|
||||||
val source: ResourceLocation,
|
pattern: ShapedRecipePattern,
|
||||||
) : CraftingRecipe, IShapedRecipe<CraftingContainer> by parent {
|
result: ItemStack,
|
||||||
constructor(parent: ShapedRecipe, copyPaths: Collection<Op>, source: ResourceLocation) : this(parent, copyPaths.stream(), source)
|
val operations: List<Pair<ResourceLocation, Op>>,
|
||||||
|
showNotification: Boolean = true,
|
||||||
override fun matches(p_44002_: CraftingContainer, p_44003_: Level): Boolean {
|
) : ShapedRecipe(group, category, pattern, result, showNotification) {
|
||||||
return parent.matches(p_44002_, p_44003_)
|
constructor(parent: ShapedRecipe, operations: List<Pair<ResourceLocation, Op>>) : this(parent.group, parent.category(), parent.pattern, parent.result, operations, parent.showNotification())
|
||||||
}
|
|
||||||
|
|
||||||
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int): Boolean {
|
|
||||||
return parent.canCraftInDimensions(p_43999_, p_44000_)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getResultItem(p_267052_: RegistryAccess): ItemStack {
|
|
||||||
return parent.getResultItem(p_267052_)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRemainingItems(p_44004_: CraftingContainer): NonNullList<ItemStack> {
|
|
||||||
return parent.getRemainingItems(p_44004_)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIngredients(): NonNullList<Ingredient> {
|
|
||||||
return parent.ingredients
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isSpecial(): Boolean {
|
|
||||||
return parent.isSpecial
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showNotification(): Boolean {
|
|
||||||
return parent.showNotification()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getGroup(): String {
|
|
||||||
return parent.group
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getToastSymbol(): ItemStack {
|
|
||||||
return parent.toastSymbol
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isIncomplete(): Boolean {
|
|
||||||
return parent.isIncomplete
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getType(): RecipeType<*> {
|
|
||||||
return parent.type
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun category(): CraftingBookCategory {
|
|
||||||
return parent.category()
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class OpType : StringRepresentable {
|
enum class OpType : StringRepresentable {
|
||||||
DIRECT {
|
COPY_COMPONENT {
|
||||||
override val codec: MapCodec<Direct> = RecordCodecBuilder.mapCodec {
|
override val codec: MapCodec<CopyComponent<*>> = RecordCodecBuilder.mapCodec {
|
||||||
it.group(
|
it.group(
|
||||||
Codec.STRING.fieldOf("path").forGetter(Direct::path)
|
DataComponentType.CODEC.fieldOf("component").forGetter(CopyComponent<*>::component)
|
||||||
).apply(it, ::Direct)
|
).apply(it) { CopyComponent(it) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
INDIRECT {
|
COPY_ALL_COMPONENTS {
|
||||||
override val codec: MapCodec<Indirect> = RecordCodecBuilder.mapCodec {
|
override val codec: MapCodec<CopyAllComponents> = MapCodec.unit(CopyAllComponents)
|
||||||
it.group(
|
|
||||||
Codec.STRING.fieldOf("source").forGetter(Indirect::pathSource),
|
|
||||||
Codec.STRING.fieldOf("destination").forGetter(Indirect::pathDestination),
|
|
||||||
).apply(it, ::Indirect)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ALL {
|
COPY_ENCHANTMENTS {
|
||||||
override val codec: MapCodec<All> by lazy { MapCodec.unit(All) }
|
override val codec: MapCodec<CopyEnchantments> = MapCodec.unit(CopyEnchantments)
|
||||||
|
},
|
||||||
|
COPY_ENERGY_CHARGE {
|
||||||
|
override val codec: MapCodec<CopyEnergyCharge> = MapCodec.unit(CopyEnergyCharge)
|
||||||
},
|
},
|
||||||
;
|
;
|
||||||
|
|
||||||
|
private val serName = name.lowercase()
|
||||||
|
|
||||||
override fun getSerializedName(): String {
|
override fun getSerializedName(): String {
|
||||||
return name.lowercase()
|
return serName
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract val codec: MapCodec<out Op>
|
abstract val codec: MapCodec<out Op>
|
||||||
@ -111,134 +61,120 @@ class UpgradeRecipe(
|
|||||||
|
|
||||||
sealed class Op {
|
sealed class Op {
|
||||||
abstract val type: OpType
|
abstract val type: OpType
|
||||||
abstract fun apply(source: CompoundTag, destination: CompoundTag)
|
abstract fun apply(source: ItemStack, container: CraftingInput, registry: HolderLookup.Provider, destination: ItemStack)
|
||||||
|
|
||||||
|
open fun matches(container: CraftingInput, level: Level): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Direct(val path: String) : Op() {
|
data class CopyComponent<T>(val component: DataComponentType<T>) : Op() {
|
||||||
private val split = path.split('.')
|
|
||||||
override val type: OpType
|
override val type: OpType
|
||||||
get() = OpType.DIRECT
|
get() = OpType.COPY_COMPONENT
|
||||||
|
|
||||||
override fun apply(source: CompoundTag, destination: CompoundTag) {
|
override fun apply(source: ItemStack, container: CraftingInput, registry: HolderLookup.Provider, destination: ItemStack) {
|
||||||
var a = source
|
val existing = source[component]
|
||||||
var b = destination
|
|
||||||
|
|
||||||
for (i in 0 until split.size - 1) {
|
if (existing != null) {
|
||||||
val value = split[i]
|
destination[component] = existing
|
||||||
|
|
||||||
if (value !in a) {
|
|
||||||
a[value] = CompoundTag()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value !in b) {
|
|
||||||
b[value] = CompoundTag()
|
|
||||||
}
|
|
||||||
|
|
||||||
a = a[value] as CompoundTag
|
|
||||||
b = b[value] as CompoundTag
|
|
||||||
}
|
|
||||||
|
|
||||||
val value = split.last()
|
|
||||||
|
|
||||||
if (value in a) {
|
|
||||||
b[value] = a[value]!!.copy()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Indirect(val pathSource: String, val pathDestination: String) : Op() {
|
object CopyAllComponents : Op() {
|
||||||
private val splitSource = pathSource.split('.')
|
|
||||||
private val splitDestination = pathDestination.split('.')
|
|
||||||
|
|
||||||
override val type: OpType
|
override val type: OpType
|
||||||
get() = OpType.INDIRECT
|
get() = OpType.COPY_ALL_COMPONENTS
|
||||||
|
|
||||||
override fun apply(source: CompoundTag, destination: CompoundTag) {
|
override fun apply(source: ItemStack, container: CraftingInput, registry: HolderLookup.Provider, destination: ItemStack) {
|
||||||
var a = source
|
destination.applyComponentsAndValidate(source.componentsPatch)
|
||||||
var b = destination
|
|
||||||
|
|
||||||
for (i in 0 until splitSource.size - 1) {
|
|
||||||
val value = splitSource[i]
|
|
||||||
|
|
||||||
if (value !in a) {
|
|
||||||
a[value] = CompoundTag()
|
|
||||||
}
|
|
||||||
|
|
||||||
a = a[value] as CompoundTag
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in 0 until splitDestination.size - 1) {
|
|
||||||
val value = splitDestination[i]
|
|
||||||
|
|
||||||
if (value !in b) {
|
|
||||||
b[value] = CompoundTag()
|
|
||||||
}
|
|
||||||
|
|
||||||
b = b[value] as CompoundTag
|
|
||||||
}
|
|
||||||
|
|
||||||
val valueA = splitSource.last()
|
|
||||||
val valueB = splitDestination.last()
|
|
||||||
|
|
||||||
if (valueA in a) {
|
|
||||||
b[valueB] = a[valueA]!!.copy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object All : Op() {
|
object CopyEnchantments : Op() {
|
||||||
override val type: OpType
|
override val type: OpType
|
||||||
get() = OpType.ALL
|
get() = OpType.COPY_ENCHANTMENTS
|
||||||
|
|
||||||
override fun apply(source: CompoundTag, destination: CompoundTag) {
|
override fun apply(source: ItemStack, container: CraftingInput, registry: HolderLookup.Provider, destination: ItemStack) {
|
||||||
source.allKeys.forEach {
|
val enchantments = source[DataComponents.ENCHANTMENTS]
|
||||||
destination[it] = source[it]!!
|
|
||||||
|
if (enchantments != null) {
|
||||||
|
destination[DataComponents.ENCHANTMENTS] = ItemEnchantments.Mutable(destination.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).let {
|
||||||
|
for ((key, level) in enchantments.entrySet()) {
|
||||||
|
it.upgrade(key, level)
|
||||||
|
}
|
||||||
|
|
||||||
|
it.toImmutable()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val copyPaths: ImmutableList<Op> = copyPaths.collect(ImmutableList.toImmutableList())
|
object CopyEnergyCharge : Op() {
|
||||||
|
override val type: OpType
|
||||||
|
get() = OpType.COPY_ENERGY_CHARGE
|
||||||
|
|
||||||
override fun assemble(pInv: CraftingContainer, registryAccess: RegistryAccess): ItemStack {
|
override fun apply(source: ItemStack, container: CraftingInput, registry: HolderLookup.Provider, destination: ItemStack) {
|
||||||
val result = parent.assemble(pInv, registryAccess)
|
val batterySource = source.getCapability(MatteryCapability.ITEM_ENERGY) ?: return
|
||||||
|
val batteryDestination = destination.getCapability(MatteryCapability.ITEM_ENERGY) ?: return
|
||||||
|
batteryDestination.batteryLevel += batterySource.batteryLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun assemble(input: CraftingInput, registry: HolderLookup.Provider): ItemStack {
|
||||||
|
val result = super.assemble(input, registry)
|
||||||
|
|
||||||
if (result.isEmpty) {
|
if (result.isEmpty) {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val sources = pInv.stream().filter { !it.isEmpty && it.item.registryName == source }.toList()
|
for ((item, op) in operations) {
|
||||||
|
input.items()
|
||||||
if (sources.size != 1) {
|
.filter { it.item.registryName == item }
|
||||||
return ItemStack.EMPTY
|
.forEach { op.apply(it, input, registry, result) }
|
||||||
}
|
|
||||||
|
|
||||||
val source = sources.first()
|
|
||||||
|
|
||||||
for (op in copyPaths) {
|
|
||||||
op.apply(source.tagNotNull, result.tagNotNull)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSerializer(): RecipeSerializer<UpgradeRecipe> {
|
override fun matches(p_345040_: CraftingInput, p_44167_: Level): Boolean {
|
||||||
return CODEC
|
return super.matches(p_345040_, p_44167_) && operations.all { it.second.matches(p_345040_, p_44167_) }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
override fun getSerializer(): RecipeSerializer<UpgradeRecipe> {
|
||||||
val COPY_PATHS_CODEC: Codec<List<Op>> = StringRepresentable
|
return Companion
|
||||||
.fromEnum(OpType::values)
|
}
|
||||||
.dispatch({ it.type }, { it.codec })
|
|
||||||
.listOf()
|
|
||||||
|
|
||||||
val CODEC = Codec2RecipeSerializer<UpgradeRecipe> { p ->
|
companion object : RecipeSerializer<UpgradeRecipe> {
|
||||||
RecordCodecBuilder.create {
|
private val operationCodec: MapCodec<Op> = StringRepresentable
|
||||||
|
.fromEnum(OpType::values)
|
||||||
|
.dispatchMap({ it.type }, { it.codec })
|
||||||
|
|
||||||
|
private val operationEntryCodec = RecordCodecBuilder.create<Pair<ResourceLocation, Op>> {
|
||||||
it.group(
|
it.group(
|
||||||
p.wrap(ShapedRecipe.Serializer.SHAPED_RECIPE).fieldOf("parent").forGetter(UpgradeRecipe::parent),
|
ResourceLocation.CODEC.fieldOf("item").forGetter(Pair<ResourceLocation, Op>::first),
|
||||||
COPY_PATHS_CODEC.fieldOf("copyPaths").forGetter(UpgradeRecipe::copyPaths),
|
operationCodec.forGetter(Pair<ResourceLocation, Op>::second),
|
||||||
ResourceLocation.CODEC.fieldOf("source").forGetter(UpgradeRecipe::source)
|
).apply(it) { a, b -> Pair(a, b) }
|
||||||
|
}.listOf()
|
||||||
|
|
||||||
|
private val codec = RecordCodecBuilder.mapCodec {
|
||||||
|
it.group(
|
||||||
|
Serializer.CODEC.forGetter { it },
|
||||||
|
operationEntryCodec.fieldOf("operations").forGetter(UpgradeRecipe::operations)
|
||||||
).apply(it, ::UpgradeRecipe)
|
).apply(it, ::UpgradeRecipe)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val streamCodec = StreamCodec.composite(
|
||||||
|
Serializer.STREAM_CODEC, { it },
|
||||||
|
ByteBufCodecs.fromCodecWithRegistries(operationEntryCodec), { it.operations }, // quite lazy solution
|
||||||
|
::UpgradeRecipe
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun codec(): MapCodec<UpgradeRecipe> {
|
||||||
|
return codec
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun streamCodec(): StreamCodec<RegistryFriendlyByteBuf, UpgradeRecipe> {
|
||||||
|
return streamCodec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user