From dfeb638b7c8cab55e8dd5e59b7c6618f988c295a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 6 Jan 2025 12:46:22 +0700 Subject: [PATCH] Experience storage for briefcase grill --- .../mc/otm/block/entity/ExperienceStorage.kt | 12 +++++++++++- .../otm/block/entity/decorative/GrillBlockEntity.kt | 5 +++++ .../dbotthepony/mc/otm/menu/decorative/GrillMenu.kt | 9 +++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt index 586e344b5..9e80b32ed 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/ExperienceStorage.kt @@ -23,10 +23,20 @@ import java.util.function.DoubleSupplier class ExperienceStorage(val maxExperience: DoubleSupplier = DoubleSupplier { Double.POSITIVE_INFINITY }) : IFluidHandler, INBTSerializable, INeighbourChangeListener { constructor(max: Double) : this({ max }) + private val listeners = ArrayList() + + fun addListener(listener: Runnable) { + listeners.add(listener) + } + var experience = 0.0 private set(value) { require(value >= 0.0) { "Negative experience: $value" } - field = value + + if (field != value) { + field = value + listeners.forEach { it.run() } + } } fun popExperience(player: ServerPlayer) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/GrillBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/GrillBlockEntity.kt index 585b65da5..2d35f562f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/GrillBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/GrillBlockEntity.kt @@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.mc.otm.block.IBlockWithCustomName import ru.dbotthepony.mc.otm.block.decorative.GrillBlock +import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity.Companion @@ -106,6 +107,7 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc private val outputs = arrayOfNulls(SLOTS) private val activeSlots = IntArrayList() private val inputProgress = IntArray(SLOTS) + val experience = ExperienceStorage().also(::addNeighbourListener) var fuelTicks = 0 private set @@ -131,10 +133,12 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc } init { + experience.addListener(::markDirtyFast) savetablesLevel.int(::fuelTicks) savetablesLevel.int(::fuelTotalTicks) savetables.stateful(::inputSlots) savetables.stateful(::fuelSlot) + savetables.stateful(::experience) // TODO: could have been done as list (and get more space efficient storage), but we use an array, oh well for (i in inputProgress.indices) { @@ -181,6 +185,7 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc val recipe = outputs[slot]!! if (recipe.cookingTime * 3 <= ++inputProgress[slot]) { + experience.storeExperience(recipe.experience) inputSlots[slot] = recipe.assemble(SingleRecipeInput(inputSlots[slot]), level!!.registryAccess()) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/GrillMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/GrillMenu.kt index a7d4fb74e..69b8bf52b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/GrillMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/GrillMenu.kt @@ -1,9 +1,11 @@ package ru.dbotthepony.mc.otm.menu.decorative import com.google.common.collect.ImmutableList +import net.minecraft.server.level.ServerPlayer import net.minecraft.world.Container import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.entity.player.Player import net.minecraft.world.item.ItemStack import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.item.crafting.SingleRecipeInput @@ -37,6 +39,13 @@ class GrillMenu( } }) { c, i -> object : MatterySlot(c, i) { + override fun onTake(p_150645_: Player, p_150646_: ItemStack) { + super.onTake(p_150645_, p_150646_) + + if (p_150645_ is ServerPlayer) + tile?.experience?.popExperience(p_150645_) + } + override fun mayPlace(itemStack: ItemStack): Boolean { val input = SingleRecipeInput(itemStack) return super.mayPlace(itemStack) && player.level().recipeManager.byType(RecipeType.SMOKING).any { it.value.matches(input, player.level()) }