Microwave oven in-world rendering
This commit is contained in:
parent
ef4f65656c
commit
2dcfa99f9c
@ -5,6 +5,7 @@ import net.minecraft.server.level.ServerLevel
|
|||||||
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.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.crafting.AbstractCookingRecipe
|
import net.minecraft.world.item.crafting.AbstractCookingRecipe
|
||||||
import net.minecraft.world.item.crafting.BlastingRecipe
|
import net.minecraft.world.item.crafting.BlastingRecipe
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
@ -44,19 +45,31 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
|
|||||||
blockState: BlockState,
|
blockState: BlockState,
|
||||||
val recipeType: RecipeType<P>,
|
val recipeType: RecipeType<P>,
|
||||||
val secondaryRecipeType: RecipeType<S>?,
|
val secondaryRecipeType: RecipeType<S>?,
|
||||||
val config: WorkerBalanceValues
|
val config: WorkerBalanceValues,
|
||||||
) : MatteryWorkerBlockEntity<ItemJob>(type, blockPos, blockState, ItemJob.CODEC, 2) {
|
maxJobs: Int = 2
|
||||||
|
) : MatteryWorkerBlockEntity<ItemJob>(type, blockPos, blockState, ItemJob.CODEC, maxJobs) {
|
||||||
final override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING)
|
final override val upgrades = UpgradeContainer(this::markDirtyFast, 2, UpgradeType.BASIC_PROCESSING)
|
||||||
final override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
|
final override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
|
||||||
|
|
||||||
val inputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
val inputs = immutableList(maxJobs) { MatteryContainer(this::itemContainerUpdated, 1) }
|
||||||
val outputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
|
val outputs = immutableList(maxJobs) { MatteryContainer(this::itemContainerUpdated, 1) }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
inputs.forEach { addDroppableContainer(it) }
|
inputs.forEach { addDroppableContainer(it) }
|
||||||
outputs.forEach { addDroppableContainer(it) }
|
outputs.forEach { addDroppableContainer(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class SyncSlot {
|
||||||
|
var inputItem by synchronizer.item(observe = false)
|
||||||
|
var outputItem by synchronizer.item(observe = false)
|
||||||
|
var progress by synchronizer.float().property
|
||||||
|
var visualRotation = 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastRender = 0L
|
||||||
|
|
||||||
|
val syncSlots = immutableList(maxJobs) { SyncSlot() }
|
||||||
|
|
||||||
val experience = ExperienceStorage(config::maxExperienceStored).also(::addNeighbourListener)
|
val experience = ExperienceStorage(config::maxExperienceStored).also(::addNeighbourListener)
|
||||||
val energyConfig = ConfigurableEnergy(energy)
|
val energyConfig = ConfigurableEnergy(energy)
|
||||||
val itemConfig = ConfigurableItemHandler(
|
val itemConfig = ConfigurableItemHandler(
|
||||||
@ -90,11 +103,19 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
|
|||||||
override fun onJobFinish(status: JobStatus<ItemJob>, id: Int) {
|
override fun onJobFinish(status: JobStatus<ItemJob>, id: Int) {
|
||||||
if (outputs[id].fullyAddItem(status.job.itemStack)) {
|
if (outputs[id].fullyAddItem(status.job.itemStack)) {
|
||||||
experience.storeExperience(status.experience, this)
|
experience.storeExperience(status.experience, this)
|
||||||
|
syncSlots[id].inputItem = ItemStack.EMPTY
|
||||||
|
syncSlots[id].outputItem = ItemStack.EMPTY
|
||||||
|
syncSlots[id].progress = 0f
|
||||||
} else {
|
} else {
|
||||||
status.noItem()
|
status.noItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onJobTick(status: JobStatus<ItemJob>, id: Int) {
|
||||||
|
super.onJobTick(status, id)
|
||||||
|
syncSlots[id].progress = status.workProgress
|
||||||
|
}
|
||||||
|
|
||||||
override fun computeNextJob(id: Int): JobContainer<ItemJob> {
|
override fun computeNextJob(id: Int): JobContainer<ItemJob> {
|
||||||
if (!energy.batteryLevel.isPositive)
|
if (!energy.batteryLevel.isPositive)
|
||||||
return JobContainer.noEnergy()
|
return JobContainer.noEnergy()
|
||||||
@ -129,9 +150,14 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
|
|||||||
|
|
||||||
return level.recipeManager.getRecipeFor(recipeType, inputs[id], level).map {
|
return level.recipeManager.getRecipeFor(recipeType, inputs[id], level).map {
|
||||||
val output = it.value.assemble(inputs[id], level.registryAccess())
|
val output = it.value.assemble(inputs[id], level.registryAccess())
|
||||||
|
val inputItem = inputs[id][0].copyWithCount(1)
|
||||||
val toProcess = inputs[id][0].count.coerceAtMost(upgrades.processingItems + 1)
|
val toProcess = inputs[id][0].count.coerceAtMost(upgrades.processingItems + 1)
|
||||||
inputs[id][0].shrink(toProcess)
|
inputs[id][0].shrink(toProcess)
|
||||||
|
|
||||||
|
syncSlots[id].inputItem = inputItem
|
||||||
|
syncSlots[id].outputItem = output.copy()
|
||||||
|
syncSlots[id].progress = 0f
|
||||||
|
|
||||||
JobContainer.success(ItemJob(
|
JobContainer.success(ItemJob(
|
||||||
output.copyWithCount(toProcess), it.value.cookingTime * config.workTimeMultiplier, config.energyConsumption * toProcess, it.value.experience * toProcess
|
output.copyWithCount(toProcess), it.value.cookingTime * config.workTimeMultiplier, config.energyConsumption * toProcess, it.value.experience * toProcess
|
||||||
))
|
))
|
||||||
|
@ -58,7 +58,7 @@ class MatterReplicatorRenderer(private val context: BlockEntityRendererProvider.
|
|||||||
tile.particleRenderScore += diff
|
tile.particleRenderScore += diff
|
||||||
|
|
||||||
if (tile.particleRenderScore > 30_000_000L) {
|
if (tile.particleRenderScore > 30_000_000L) {
|
||||||
tile.particleRenderScore = tile.particleRenderScore % 30_000_000L
|
tile.particleRenderScore %= 30_000_000L
|
||||||
|
|
||||||
if (rand.nextDouble() > 0.75 && !isPaused && tile.blockState[WorkerState.WORKER_STATE] == WorkerState.WORKING) {
|
if (rand.nextDouble() > 0.75 && !isPaused && tile.blockState[WorkerState.WORKER_STATE] == WorkerState.WORKING) {
|
||||||
val (x, y, z) = tile.blockPos
|
val (x, y, z) = tile.blockPos
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.render.blockentity
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
||||||
|
import net.minecraft.world.item.ItemDisplayContext
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.normalizeAngle
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.rotateY
|
||||||
|
|
||||||
|
class PoweredSmokerRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<AbstractPoweredFurnaceBlockEntity<*, *>> {
|
||||||
|
override fun render(tile: AbstractPoweredFurnaceBlockEntity<*, *>, partialTick: Float, pose: PoseStack, buffers: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
|
||||||
|
val diff = System.nanoTime() - tile.lastRender
|
||||||
|
tile.lastRender = System.nanoTime()
|
||||||
|
|
||||||
|
for (slot in tile.syncSlots) {
|
||||||
|
if (slot.inputItem.isEmpty && slot.outputItem.isEmpty) continue
|
||||||
|
slot.visualRotation = normalizeAngle(slot.visualRotation + diff / 400_000_000f)
|
||||||
|
|
||||||
|
pose.pushPose()
|
||||||
|
pose.translate(0.625f, 0.5f, 0.5f)
|
||||||
|
pose.scale(0.25f, 0.25f, 0.25f)
|
||||||
|
|
||||||
|
pose.rotateY(slot.visualRotation)
|
||||||
|
|
||||||
|
if (slot.progress <= 0.8f && !slot.inputItem.isEmpty) {
|
||||||
|
val model = context.itemRenderer.getModel(
|
||||||
|
slot.inputItem,
|
||||||
|
tile.level,
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
context.itemRenderer.render(
|
||||||
|
slot.inputItem,
|
||||||
|
ItemDisplayContext.NONE,
|
||||||
|
false,
|
||||||
|
pose,
|
||||||
|
buffers,
|
||||||
|
packedLight,
|
||||||
|
packedOverlay,
|
||||||
|
model
|
||||||
|
)
|
||||||
|
} else if (slot.progress > 0.8f && !slot.outputItem.isEmpty) {
|
||||||
|
val model = context.itemRenderer.getModel(
|
||||||
|
slot.outputItem,
|
||||||
|
tile.level,
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
context.itemRenderer.render(
|
||||||
|
slot.outputItem,
|
||||||
|
ItemDisplayContext.NONE,
|
||||||
|
false,
|
||||||
|
pose,
|
||||||
|
buffers,
|
||||||
|
packedLight,
|
||||||
|
packedOverlay,
|
||||||
|
model
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pose.popPose()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -52,9 +52,10 @@ class Savetables : INBTSerializable<CompoundTag?> {
|
|||||||
return stateful(getter, name, T::class.java)
|
return stateful(getter, name, T::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <V : INBTSerializable<T?>, reified T : Tag> stateful(values: List<V>, name: String): ImmutableList<Stateful<V, T>> {
|
inline fun <V : INBTSerializable<T?>, reified T : Tag> stateful(values: Collection<V>, name: String): ImmutableList<Stateful<V, T>> {
|
||||||
|
val iterator = values.iterator()
|
||||||
return immutableList(values.size) {
|
return immutableList(values.size) {
|
||||||
stateful(values[it], "${name}_$it", T::class.java)
|
stateful(iterator.next(), "${name}_$it", T::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ object MBlockEntities {
|
|||||||
BlockEntityRenderers.register(MATTER_RECONSTRUCTOR, ::MatterReconstructorRenderer)
|
BlockEntityRenderers.register(MATTER_RECONSTRUCTOR, ::MatterReconstructorRenderer)
|
||||||
BlockEntityRenderers.register(MATTER_REPLICATOR, ::MatterReplicatorRenderer)
|
BlockEntityRenderers.register(MATTER_REPLICATOR, ::MatterReplicatorRenderer)
|
||||||
BlockEntityRenderers.register(MATTER_SCANNER, ::MatterScannerRenderer)
|
BlockEntityRenderers.register(MATTER_SCANNER, ::MatterScannerRenderer)
|
||||||
|
BlockEntityRenderers.register(POWERED_SMOKER, ::PoweredSmokerRenderer)
|
||||||
BlockEntityRenderers.register(HOLO_SIGN, ::HoloSignRenderer)
|
BlockEntityRenderers.register(HOLO_SIGN, ::HoloSignRenderer)
|
||||||
BlockEntityRenderers.register(FLUID_TANK, ::FluidTankRenderer)
|
BlockEntityRenderers.register(FLUID_TANK, ::FluidTankRenderer)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user