This commit is contained in:
DBotThePony 2024-01-09 13:43:24 +07:00
commit 4a606b8d36
Signed by: DBot
GPG Key ID: DCC23B5715498507
17 changed files with 136 additions and 74 deletions

View File

@ -17,7 +17,6 @@ Minecraft mod with science fiction style, about matter, and energy, combined.
### Mods with special compatibility code
* [JEI](https://www.curseforge.com/minecraft/mc-mods/jei)
* [Mekanism](https://www.curseforge.com/minecraft/mc-mods/Mekanism)
* [Curios](https://www.curseforge.com/minecraft/mc-mods/curios)
* [Cosmetic Armor Reworked](https://www.curseforge.com/minecraft/mc-mods/cosmetic-armor-reworked)

View File

@ -62,7 +62,7 @@ class FluidTankBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), Entity
val tile = level?.getExistingBlockEntity(pos) ?: lightLevel
if (tile is FluidTankBlockEntity) {
val fluid = tile.synchronizedFluid
val fluid = tile.fluid.fluid
if (!fluid.isEmpty) {
val newLevel = fluid.fluid.fluidType.getLightLevel(fluid)

View File

@ -1,6 +1,9 @@
package ru.dbotthepony.mc.otm.block.decorative
import net.minecraft.core.BlockPos
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
@ -10,6 +13,8 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.Material
import net.minecraft.world.level.material.MaterialColor
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.BlockHitResult
import net.minecraftforge.fluids.FluidUtil
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity
@ -18,6 +23,15 @@ class InfiniteWaterSourceBlock : RotatableMatteryBlock(Properties.of(Material.ME
return InfiniteWaterSourceBlockEntity(p_153215_, p_153216_)
}
@Suppress("OVERRIDE_DEPRECATION")
override fun use(blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, hand: InteractionHand, blockHitResult: BlockHitResult): InteractionResult {
if (FluidUtil.interactWithFluidHandler(ply, hand, level, blockPos, blockHitResult.direction)) {
return InteractionResult.sidedSuccess(level.isClientSide)
}
return super.use(blockState, level, blockPos, ply, hand, blockHitResult)
}
override fun getPistonPushReaction(p_60584_: BlockState): PushReaction {
return PushReaction.NORMAL
}

View File

@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectArraySet
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
@ -619,8 +620,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
private class ChunkSubscribers(level: ServerLevel, val chunkPos: Long) {
val level = WeakReference(level)
val blockEntities = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0)
val players = ObjectLinkedOpenHashSet<ServerPlayer>(0)
val veto = ObjectLinkedOpenHashSet<ServerPlayer>(0)
val players = ObjectArraySet<ServerPlayer>(0)
val veto = ObjectArraySet<ServerPlayer>(0)
val blockEntitiesWithObservers = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0)
operator fun component1() = blockEntities

View File

@ -27,12 +27,15 @@ import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.FLUID_TANK, blockPos, blockState) {
val fluid = BlockMatteryFluidHandler(::onChanged, ItemsConfig::FLUID_TANK_CAPACITY)
var synchronizedFluid by synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec, setter = { value, access, remote ->
val fluid = BlockMatteryFluidHandler(ItemsConfig::FLUID_TANK_CAPACITY, synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec, setter = { value, access, remote ->
access.write(value)
level?.lightEngine?.checkBlock(blockPos)
})
if (!remote) {
markDirtyFast()
}
}))
val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
val drainInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
@ -73,11 +76,6 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery
savetables.stateful(::output)
}
private fun onChanged(new: FluidStack, old: FluidStack) {
synchronizedFluid = new.copy()
markDirtyFast()
}
private fun drainItem() {
val item = drainInput[0]

View File

@ -7,18 +7,14 @@ import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.tagNotNull
import ru.dbotthepony.mc.otm.network.synchronizer.IMutableField
import java.util.function.IntSupplier
/**
* Fluid handler for blocks
*/
class BlockMatteryFluidHandler(val onChanged: (new: FluidStack, old: FluidStack) -> Unit, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), INBTSerializable<CompoundTag?> {
override var fluid: FluidStack = FluidStack.EMPTY
set(value) {
val old = field
field = value
onChanged(value, old)
}
open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: IMutableField<FluidStack>) : AbstractMatteryFluidHandler(), INBTSerializable<CompoundTag?> {
override var fluid by field
override val capacity: Int
get() = _capacity.asInt

View File

@ -32,7 +32,7 @@ class FluidTankRenderer(private val context: BlockEntityRendererProvider.Context
packedLight: Int,
packedOverlay: Int
) {
renderFluidInTank(tile.fluid, tile.synchronizedFluid, poseStack, bufferSource, packedLight, packedOverlay)
renderFluidInTank(tile.fluid, tile.fluid.fluid, poseStack, bufferSource, packedLight, packedOverlay)
}
object FluidTankItemRenderer : BlockEntityWithoutLevelRenderer(minecraft.blockEntityRenderDispatcher, minecraft.entityModels) {

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.client.screen
import mezz.jei.api.constants.RecipeTypes
import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
@ -187,6 +188,8 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen<Exopack
it.dock = Dock.LEFT
it.dockLeft = 9f
it.dockResize = DockResizeMode.NONE
it.setRecipeType { listOf(RecipeTypes.SMELTING) }
}
SlotPanel(this, row, menu.furnaceOutputs[i]).also {

View File

@ -14,7 +14,6 @@ import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.renderer.Rect2i
import net.minecraft.network.chat.Component
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.SystemTime
import ru.dbotthepony.mc.otm.client.CursorType
@ -29,6 +28,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel
import ru.dbotthepony.mc.otm.core.collect.concatIterators
import ru.dbotthepony.mc.otm.core.collect.flatMap
import java.util.*
import java.util.function.Predicate
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
@ -56,10 +56,6 @@ interface ISlotPanel<out S : Slot> {
val slot: S
}
interface IItemStackPanel {
val itemStack: ItemStack
}
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
fun toIntRect(): Rect2i {
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
@ -1016,9 +1012,30 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
return false to null
}
fun findItemStack(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): Pair<EditablePanel<*>?, ItemStack> {
data class PanelOfTypeResult<T>(val panel: T?, val interrupt: Boolean) {
constructor(panel: T) : this(panel, true)
companion object {
private val notFound0 = PanelOfTypeResult(null, false)
private val notFound1 = PanelOfTypeResult(null, true)
fun <T> notFoundInterrupt(): PanelOfTypeResult<T> {
return notFound1 as PanelOfTypeResult<T>
}
fun <T> notFoundContinue(): PanelOfTypeResult<T> {
return notFound0 as PanelOfTypeResult<T>
}
}
}
inline fun <reified T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): T? {
return panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock) { it is T }.panel
}
fun <T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate<EditablePanel<*>>): PanelOfTypeResult<T> {
if (!isVisible()) {
return null to ItemStack.EMPTY
return PanelOfTypeResult.notFoundContinue()
}
if (!acceptMouseInput && !ignoreMouseInputLock) {
@ -1026,20 +1043,20 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
mouseX <= absoluteX + width &&
mouseY >= absoluteY &&
mouseY <= absoluteY + height) {
return this to ItemStack.EMPTY
return PanelOfTypeResult.notFoundInterrupt()
} else {
return null to ItemStack.EMPTY
return PanelOfTypeResult.notFoundContinue()
}
}
if (grabMouseInput && this is IItemStackPanel) {
return this to this.itemStack
if (grabMouseInput && tester.test(this)) {
return PanelOfTypeResult(this as T)
}
for (child in visibleChildrenInternal) {
val status = child.findItemStack(mouseX, mouseY, ignoreMouseInputLock)
val status = child.panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock, tester)
if (status.first != null) {
if (status.interrupt) {
return status
}
}
@ -1050,14 +1067,14 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
mouseY >= absoluteY &&
mouseY <= absoluteY + height
) {
if (this is IItemStackPanel) {
return this to this.itemStack
if (tester.test(this)) {
return PanelOfTypeResult(this as T)
}
return this to ItemStack.EMPTY
return PanelOfTypeResult.notFoundInterrupt()
}
return null to ItemStack.EMPTY
return PanelOfTypeResult.notFoundContinue()
}
fun renderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {

View File

@ -5,24 +5,26 @@ import net.minecraft.client.renderer.GameRenderer
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraftforge.client.extensions.common.IClientItemExtensions
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.IItemStackPanel
import ru.dbotthepony.mc.otm.core.math.RGBAColor
abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constructor(
abstract class AbstractSlotPanel<out S : MatteryScreen<*>>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel {
) : EditablePanel<S>(screen, parent, x, y, width, height) {
open var slotBackground: IGUIRenderable? = null
open var slotBackgroundEmpty: IGUIRenderable? = null
abstract val itemStack: ItemStack
protected open fun renderSlotBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
SLOT_BACKGROUND.render(graphics, width = width, height = height)
slotBackground?.render(graphics, 0f, 0f, width, height)

View File

@ -3,17 +3,19 @@ package ru.dbotthepony.mc.otm.client.screen.widget
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.inventory.InventoryMenu
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions
import net.minecraftforge.fml.ModList
import org.lwjgl.opengl.GL11
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.ShiftPressedCond
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.tesselator
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
@ -22,6 +24,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.linearInterpolation
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.util.formatFluidLevel
import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget
@ -37,10 +40,16 @@ open class FluidGaugePanel<out S : Screen>(
}
protected open fun makeTooltip(): MutableList<Component> {
return mutableListOf(
val tooltip = mutableListOf<Component>(
if (widget.fluid.isEmpty) TranslatableComponent("otm.gui.empty") else TextComponent(String.format("%s: %.2f%%", widget.fluid.displayName.string, widget.percentage * 100.0)),
formatFluidLevel(if (widget.fluid.isEmpty) 0 else widget.fluid.amount, widget.maxCapacity, formatAsReadable = ShiftPressedCond)
)
if (widget.fluid.isNotEmpty) {
tooltip.add(TextComponent(ModList.get().getModContainerById(widget.fluid.fluid.registryName!!.namespace).get().modInfo.displayName).withStyle(ChatFormatting.BLUE).withStyle(ChatFormatting.ITALIC))
}
return tooltip
}
override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {

View File

@ -54,11 +54,6 @@ open class ProgressGaugePanel<out S : Screen>(
)
}
if (recipeTypeSupplier != null) {
tooltip.add(TextComponent(""))
tooltip.add(TranslatableComponent("jei.tooltip.show.recipes").withStyle(ChatFormatting.GRAY))
}
return tooltip
}

View File

@ -4,6 +4,7 @@ import mezz.jei.api.IModPlugin
import mezz.jei.api.JeiPlugin
import mezz.jei.api.constants.RecipeTypes
import mezz.jei.api.constants.VanillaTypes
import mezz.jei.api.forge.ForgeTypes
import mezz.jei.api.gui.handlers.IGuiContainerHandler
import mezz.jei.api.helpers.IJeiHelpers
import mezz.jei.api.ingredients.ITypedIngredient
@ -17,14 +18,17 @@ import mezz.jei.api.runtime.IJeiRuntime
import net.minecraft.client.renderer.Rect2i
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraftforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.FluidGaugePanel
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.filterIsInstance
import ru.dbotthepony.mc.otm.core.collect.filterNotNull
import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.toList
import ru.dbotthepony.mc.otm.core.filterNotNull
import ru.dbotthepony.mc.otm.core.value
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu
@ -134,23 +138,9 @@ class JEIPlugin : IModPlugin {
mouseX: Double,
mouseY: Double
): Optional<IClickableIngredient<*>> {
return containerScreen.panelsView
.stream()
.map { it.findItemStack(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) }
.filter { it.first != null }
.findAny()
.flatMap { a -> helpers.ingredientManager.createTypedIngredient(VanillaTypes.ITEM_STACK, a.second).map { a.first to it } }
.map {
object : IClickableIngredient<ItemStack> {
override fun getTypedIngredient(): ITypedIngredient<ItemStack> {
return it.second
}
override fun getArea(): Rect2i {
return it.first!!.calculateAbsoluteRectangle().toIntRect()
}
}
}
return Panel2ClickableIngredient.find(mouseX, mouseY, VanillaTypes.ITEM_STACK, containerScreen.panelsView, AbstractSlotPanel<*>::itemStack).or {
Panel2ClickableIngredient.find(mouseX, mouseY, ForgeTypes.FLUID_STACK, containerScreen.panelsView) { it: FluidGaugePanel<*> -> it.widget.fluid }
}
}
})
}

View File

@ -0,0 +1,31 @@
package ru.dbotthepony.mc.otm.compat.jei
import mezz.jei.api.ingredients.IIngredientType
import mezz.jei.api.ingredients.ITypedIngredient
import mezz.jei.api.runtime.IClickableIngredient
import net.minecraft.client.renderer.Rect2i
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.core.filterNotNull
import java.util.*
class Panel2ClickableIngredient<P : EditablePanel<*>, T>(val panel: P, val ingredient: ITypedIngredient<T>) : IClickableIngredient<T> {
override fun getTypedIngredient(): ITypedIngredient<T> {
return ingredient
}
override fun getArea(): Rect2i {
return panel.calculateAbsoluteRectangle().toIntRect()
}
companion object {
inline fun <reified P : EditablePanel<*>, T : Any> find(mouseX: Double, mouseY: Double, type: IIngredientType<T>, source: Collection<EditablePanel<*>>, noinline provider: (P) -> T): Optional<IClickableIngredient<*>> {
return source
.stream()
.map { it.panelOfTypeUnderCursor<P>(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) }
.filterNotNull()
.findAny()
.flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } }
.map { Panel2ClickableIngredient(it.first!!, it.second) }
}
}
}

View File

@ -17,6 +17,8 @@ import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.onceClient
import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.reduce
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem
import ru.dbotthepony.mc.otm.matter.MatterManager
import java.util.*
@ -69,12 +71,11 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
val blockEntity = level.getBlockEntity(position)
if (blockEntity == null) {
LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog because there is literally no block entity there! This is CERTAINLY a bug in one of optimizing mods you have or server has installed! This might cause memory leak.")
backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() }
val list = backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() }
.computeIfAbsent(position, Object2ObjectFunction { ArrayList() })
.add(this)
list.add(buffer.copyOf(validBytes))
LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog (size: ${list.iterator().map { it.size }.reduce(0, Int::plus)} bytes) because there is literally no block entity there! This might cause memory leak.")
return
} else if (blockEntity !is MatteryBlockEntity) {
LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!")
@ -89,7 +90,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
LOGGER.info("Unfolding ${packets.size} backlog packets for $position (${level.getBlockState(position)}/$blockEntity)")
for (packet in packets) {
blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes))
blockEntity.synchronizer.read(FastByteArrayInputStream(packet))
}
}
@ -104,7 +105,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
}
companion object {
private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<BlockEntitySyncPacket>>>()
private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<ByteArray>>>()
fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket {
val position = buff.readBlockPos()
@ -121,10 +122,10 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
try {
if (packets != null) {
LOGGER.info("Unfolding ${packets.size} backlog packets for ${blockEntity.blockPos} (${blockEntity.level!!.getBlockState(blockEntity.blockPos)}/$blockEntity)")
LOGGER.info("Unfolding ${packets.size} backlog packets (size: ${packets.iterator().map { it.size }.reduce(0, Int::plus)} bytes) for ${blockEntity.blockPos} (${blockEntity.level!!.getBlockState(blockEntity.blockPos)}/$blockEntity)")
for (packet in packets) {
blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes))
blockEntity.synchronizer.read(FastByteArrayInputStream(packet))
}
}
} catch(err: Throwable) {

View File

@ -147,6 +147,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
accept(MItems.TRITANIUM_ORE)
accept(MItems.DEEPSLATE_TRITANIUM_ORE)
accept(MItems.TRITANIUM_ORE_CLUMP)
accept(MItems.TRITANIUM_RAW_BLOCK)
accept(MItems.TRITANIUM_DUST)
accept(MItems.TRITANIUM_NUGGET)
accept(MItems.TRITANIUM_INGOT)
@ -185,6 +186,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
fluids(MItems.FLUID_CAPSULE)
fluids(MItems.FLUID_TANK)
accept(MItems.INFINITE_WATER_SOURCE)
base(MItems.CARGO_CRATE_MINECARTS)

View File

@ -128,6 +128,7 @@ object MItems {
machines.addAll(CHEMICAL_GENERATOR.asSupplierArray())
machines.addAll(ENERGY_SERVO.asSupplierArray())
machines.add(::PHANTOM_ATTRACTOR)
machines.add(::PAINTER)
machines.addAll(COBBLESTONE_GENERATOR.asSupplierArray().iterator())
machines.addAll(ESSENCE_STORAGE.asSupplierArray().iterator())
@ -142,6 +143,9 @@ object MItems {
machines.addAll(MATTER_BOTTLER.asSupplierArray().iterator())
machines.add(::MATTER_ENTANGLER)
machines.addAll(MATTER_RECYCLER.asSupplierArray().iterator())
machines.addAll(MATTER_RECONSTRUCTOR.asSupplierArray().iterator())
machines.add(::GRAVITATION_STABILIZER)
machines.add(::STORAGE_BUS)
machines.add(::STORAGE_IMPORTER)