Experience storage for briefcase grill

This commit is contained in:
DBotThePony 2025-01-06 12:46:22 +07:00
parent 7c35c284cd
commit dfeb638b7c
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 25 additions and 1 deletions

View File

@ -23,10 +23,20 @@ import java.util.function.DoubleSupplier
class ExperienceStorage(val maxExperience: DoubleSupplier = DoubleSupplier { Double.POSITIVE_INFINITY }) : IFluidHandler, INBTSerializable<DoubleTag?>, INeighbourChangeListener { class ExperienceStorage(val maxExperience: DoubleSupplier = DoubleSupplier { Double.POSITIVE_INFINITY }) : IFluidHandler, INBTSerializable<DoubleTag?>, INeighbourChangeListener {
constructor(max: Double) : this({ max }) constructor(max: Double) : this({ max })
private val listeners = ArrayList<Runnable>()
fun addListener(listener: Runnable) {
listeners.add(listener)
}
var experience = 0.0 var experience = 0.0
private set(value) { private set(value) {
require(value >= 0.0) { "Negative experience: $value" } require(value >= 0.0) { "Negative experience: $value" }
field = value
if (field != value) {
field = value
listeners.forEach { it.run() }
}
} }
fun popExperience(player: ServerPlayer) { fun popExperience(player: ServerPlayer) {

View File

@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.util.Delegate import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.block.IBlockWithCustomName import ru.dbotthepony.mc.otm.block.IBlockWithCustomName
import ru.dbotthepony.mc.otm.block.decorative.GrillBlock 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.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity.Companion import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity.Companion
@ -106,6 +107,7 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc
private val outputs = arrayOfNulls<SmokingRecipe>(SLOTS) private val outputs = arrayOfNulls<SmokingRecipe>(SLOTS)
private val activeSlots = IntArrayList() private val activeSlots = IntArrayList()
private val inputProgress = IntArray(SLOTS) private val inputProgress = IntArray(SLOTS)
val experience = ExperienceStorage().also(::addNeighbourListener)
var fuelTicks = 0 var fuelTicks = 0
private set private set
@ -131,10 +133,12 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc
} }
init { init {
experience.addListener(::markDirtyFast)
savetablesLevel.int(::fuelTicks) savetablesLevel.int(::fuelTicks)
savetablesLevel.int(::fuelTotalTicks) savetablesLevel.int(::fuelTotalTicks)
savetables.stateful(::inputSlots) savetables.stateful(::inputSlots)
savetables.stateful(::fuelSlot) 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 // 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) { for (i in inputProgress.indices) {
@ -181,6 +185,7 @@ class GrillBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBloc
val recipe = outputs[slot]!! val recipe = outputs[slot]!!
if (recipe.cookingTime * 3 <= ++inputProgress[slot]) { if (recipe.cookingTime * 3 <= ++inputProgress[slot]) {
experience.storeExperience(recipe.experience)
inputSlots[slot] = recipe.assemble(SingleRecipeInput(inputSlots[slot]), level!!.registryAccess()) inputSlots[slot] = recipe.assemble(SingleRecipeInput(inputSlots[slot]), level!!.registryAccess())
} }
} }

View File

@ -1,9 +1,11 @@
package ru.dbotthepony.mc.otm.menu.decorative package ru.dbotthepony.mc.otm.menu.decorative
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container import net.minecraft.world.Container
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.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.item.crafting.SingleRecipeInput import net.minecraft.world.item.crafting.SingleRecipeInput
@ -37,6 +39,13 @@ class GrillMenu(
} }
}) { c, i -> }) { c, i ->
object : MatterySlot(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 { override fun mayPlace(itemStack: ItemStack): Boolean {
val input = SingleRecipeInput(itemStack) val input = SingleRecipeInput(itemStack)
return super.mayPlace(itemStack) && player.level().recipeManager.byType(RecipeType.SMOKING).any { it.value.matches(input, player.level()) } return super.mayPlace(itemStack) && player.level().recipeManager.byType(RecipeType.SMOKING).any { it.value.matches(input, player.level()) }