Skip to content

Commit

Permalink
fix: use FoodSurrogate instead of serializing FoodComponent due to us…
Browse files Browse the repository at this point in the history
…ingConvertsTo & prefab-load-order
  • Loading branch information
Boy0000 committed Oct 27, 2024
1 parent dc58abe commit 173f6a2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,37 @@ import kotlin.time.DurationUnit

@Serializable
@SerialName("FoodComponent")
private class FoodComponentSurrogate(
class FoodComponentSurrogate(
val nutrition: Int,
val saturation: Float,
val eatSeconds: Float = 1.6f,
val canAlwaysEat: Boolean = false,
val usingConvertsTo: SerializableItemStack? = null,
val effects: List<FoodEffectWrapper> = emptyList()
) {

constructor(food: FoodComponent) : this(
food.nutrition,
food.saturation,
food.eatSeconds,
food.canAlwaysEat(),
food.usingConvertsTo?.toSerializable(),
food.effects.map { FoodEffectWrapper(it.effect, it.probability) })

init {
require(nutrition >= 0) { "FoodComponent must have a positive nutrition" }
require(saturation >= 0) { "FoodComponent must have a positive saturation" }
require(eatSeconds >= 0) { "FoodComponent must have a positive eatSeconds" }
require(effects.all { it.probability in 0.0..1.0 }) { "FoodEffect-probability must be between 0.0..1.0" }
}
}

object FoodComponentSerializer : KSerializer<FoodComponent> {
override val descriptor: SerialDescriptor = FoodComponentSurrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: FoodComponent) {
val surrogate = FoodComponentSurrogate(
value.nutrition,
value.saturation,
value.eatSeconds,
value.canAlwaysEat(),
value.usingConvertsTo?.toSerializable(),
value.effects.map { FoodEffectWrapper(it.effect, it.probability) }
)
encoder.encodeSerializableValue(FoodComponentSurrogate.serializer(), surrogate)
}

override fun deserialize(decoder: Decoder): FoodComponent {
return ItemStack(Material.PAPER).itemMeta.food.apply {
val surrogate = decoder.decodeSerializableValue(FoodComponentSurrogate.serializer())
nutrition = surrogate.nutrition
saturation = surrogate.saturation
setCanAlwaysEat(surrogate.canAlwaysEat)
eatSeconds = surrogate.eatSeconds
usingConvertsTo = surrogate.usingConvertsTo?.toItemStackOrNull()
surrogate.effects.forEach { addEffect(it.effect, it.probability) }
val foodComponent: FoodComponent
get() = ItemStack.of(Material.PAPER).itemMeta.food.also {
it.nutrition = nutrition
it.saturation = saturation
it.eatSeconds = eatSeconds
it.setCanAlwaysEat(canAlwaysEat)
it.usingConvertsTo = usingConvertsTo?.toItemStackOrNull()
effects.forEach { e -> it.addEffect(e.effect, e.probability) }
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ data class BaseSerializableItemStack(
@EncodeDefault(NEVER) val customPotionEffects: List<@Serializable(with = PotionEffectSerializer::class) PotionEffect> = listOf(),
@EncodeDefault(NEVER) val knowledgeBookRecipes: List<String>? = null,
@EncodeDefault(NEVER) val color: @Serializable(with = ColorSerializer::class) Color? = null,
@EncodeDefault(NEVER) val food: @Serializable(with = FoodComponentSerializer::class) FoodComponent? = null,
@EncodeDefault(NEVER) val food: FoodComponentSurrogate? = null,
@EncodeDefault(NEVER) val tool: @Serializable(with = ToolComponentSerializer::class) ToolComponent? = null,
@EncodeDefault(NEVER) val jukeboxPlayable: @Serializable(with = JukeboxPlayableSerializer::class) JukeboxPlayableComponent? = null,
@EncodeDefault(NEVER) val hideTooltip: Boolean? = null,
Expand Down Expand Up @@ -161,7 +161,7 @@ data class BaseSerializableItemStack(
}

enchantmentGlintOverride?.let(meta::setEnchantmentGlintOverride)
food?.let(meta::setFood)
food?.foodComponent?.let(meta::setFood)
tool?.let(meta::setTool)
jukeboxPlayable?.let(meta::setJukeboxPlayable)
maxStackSize?.let(meta::setMaxStackSize)
Expand Down Expand Up @@ -213,7 +213,7 @@ fun ItemStack.toSerializable(): SerializableItemStack = with(itemMeta) {
attributeModifiers = attributeList.takeIf { it.isNotEmpty() },
basePotionType = (this as? PotionMeta)?.basePotionType,
color = (this as? PotionMeta)?.color ?: (this as? LeatherArmorMeta)?.color,
food = if (hasFood()) food else null,
food = if (hasFood()) FoodComponentSurrogate(food) else null,
tool = if (hasTool()) tool else null,
jukeboxPlayable = if (hasJukeboxPlayable()) jukeboxPlayable else null,
enchantmentGlintOverride = if (hasEnchantmentGlintOverride()) enchantmentGlintOverride else null,
Expand Down

0 comments on commit 173f6a2

Please sign in to comment.