Inventory scrollbar in all inventories

Fixes #120
This commit is contained in:
DBotThePony 2022-10-20 20:59:04 +07:00
parent c6fae3348b
commit d2257749e0
Signed by: DBot
GPG Key ID: DCC23B5715498507
7 changed files with 372 additions and 60 deletions

View File

@ -14,8 +14,6 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ru.dbotthepony.mc.otm.android.AndroidResearchManager; import ru.dbotthepony.mc.otm.android.AndroidResearchManager;
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature; import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature;
import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity; import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity;
@ -56,7 +54,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
public final class OverdriveThatMatters { public final class OverdriveThatMatters {
// Directly reference a log4j logger. // Directly reference a log4j logger.
public static final String MOD_ID = "overdrive_that_matters"; public static final String MOD_ID = "overdrive_that_matters";
private static final Logger LOGGER = LogManager.getLogger();
public static OverdriveThatMatters INSTANCE; public static OverdriveThatMatters INSTANCE;
private StorageStackType<ItemStackWrapper> ITEM_STORAGE; private StorageStackType<ItemStackWrapper> ITEM_STORAGE;
@ -184,6 +181,8 @@ public final class OverdriveThatMatters {
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onMovementInputUpdate); EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onMovementInputUpdate);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onScreenOpen); EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onScreenOpen);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onPostScreenInit); EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onPostScreenInit);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onMouseDragged);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onMouseScrolled);
EVENT_BUS.addListener(EventPriority.LOWEST, ClientTickHandlerKt::onClientTick); EVENT_BUS.addListener(EventPriority.LOWEST, ClientTickHandlerKt::onClientTick);
EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientConnected); EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientConnected);
EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientDisconnected); EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientDisconnected);

View File

@ -113,7 +113,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
private set(value) { private set(value) {
_exoSuitMenu = null _exoSuitMenu = null
if (ply.containerMenu.slots.any { it.container == field }) { @Suppress("SENSELESS_COMPARISON")
if (ply.containerMenu != null && (ply !is ServerPlayer || ply.connection != null)) {
ply.closeContainer() ply.closeContainer()
} }

View File

@ -1,38 +1,32 @@
package ru.dbotthepony.mc.otm.client package ru.dbotthepony.mc.otm.client
import com.mojang.blaze3d.pipeline.MainTarget
import com.mojang.blaze3d.platform.GlConst.GL_COLOR_BUFFER_BIT
import com.mojang.blaze3d.platform.GlStateManager
import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
import com.mojang.blaze3d.vertex.BufferUploader
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Matrix4f
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.world.inventory.InventoryMenu import net.minecraft.world.inventory.InventoryMenu
import net.minecraft.world.inventory.Slot
import net.minecraftforge.client.event.MovementInputUpdateEvent import net.minecraftforge.client.event.MovementInputUpdateEvent
import net.minecraftforge.client.event.ScreenEvent import net.minecraftforge.client.event.ScreenEvent
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature import net.minecraftforge.client.event.ScreenEvent.MouseDragged
import net.minecraftforge.client.event.ScreenEvent.MouseScrolled
import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.GlitchRenderer
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.tesselator
import ru.dbotthepony.mc.otm.client.render.zLevel
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.DiscreteScrollBarPanel
import ru.dbotthepony.mc.otm.client.screen.panels.LargeRectangleButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget
import ru.dbotthepony.mc.otm.compat.InventoryScrollPacket
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.identityFast import ru.dbotthepony.mc.otm.core.maxScrollDivision
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import kotlin.math.min
fun onMovementInputUpdate(event: MovementInputUpdateEvent) { fun onMovementInputUpdate(event: MovementInputUpdateEvent) {
val ply = event.entity val ply = event.entity
@ -73,14 +67,18 @@ fun onMovementInputUpdate(event: MovementInputUpdateEvent) {
} }
var shouldOpenVanillaInventory = false var shouldOpenVanillaInventory = false
var inventoryScroll = 0
fun onPostScreenInit(event: ScreenEvent.Init.Post) { private fun inventoryLogic(event: ScreenEvent.Init.Post) {
val player = minecraft.player?.matteryPlayer ?: return val player = minecraft.player?.matteryPlayer ?: return
if (!player.hasExoSuit) {
return
}
val eventScreen = event.screen val eventScreen = event.screen
val screen = if (eventScreen is AbstractContainerScreen<*> && (eventScreen.menu is InventoryMenu || eventScreen.isCosmeticArmorScreen)) eventScreen else return val screen = if (eventScreen is AbstractContainerScreen<*> && (eventScreen.menu is InventoryMenu || eventScreen.isCosmeticArmorScreen)) eventScreen else return
if (player.hasExoSuit) {
val widget = Panel2Widget(LargeRectangleButtonPanel(screen, null, val widget = Panel2Widget(LargeRectangleButtonPanel(screen, null,
x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE, x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE,
y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2, y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2,
@ -103,7 +101,102 @@ fun onPostScreenInit(event: ScreenEvent.Init.Post) {
widget.panel.x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE widget.panel.x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE
widget.panel.y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2f widget.panel.y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2f
} }
}
private fun exosuitInventoryLogic(event: ScreenEvent.Init.Post) {
val player = minecraft.player ?: return
val matteryPlayer = player.matteryPlayer ?: return
if (!matteryPlayer.hasExoSuit || matteryPlayer.exoSuitContainer.containerSize == 0) {
return
} }
val screen = event.screen
if (screen !is AbstractContainerScreen<*> || screen.menu is MatteryMenu || screen.menu is InventoryMenu) {
return
}
val foundInventorySlots = Int2ObjectArrayMap<Slot>()
for (slot in screen.menu.slots) {
if (slot.container === player.inventory && slot.slotIndex in 9 .. 35) {
foundInventorySlots[slot.slotIndex] = slot
}
}
for (i in 9 .. 35) {
if (i !in foundInventorySlots) {
return
}
}
val mostTop = foundInventorySlots.values
.stream()
.min { o1, o2 -> o1.y.compareTo(o2.y) }
.get().y.toFloat()
val mostBottom = foundInventorySlots.values
.stream()
.max { o1, o2 -> o1.y.compareTo(o2.y) }
.get().y.toFloat()
val mostLeft = foundInventorySlots.values
.stream()
.max { o1, o2 -> o1.x.compareTo(o2.x) }
.get().x.toFloat() + 26f
val scrollbar = DiscreteScrollBarPanel(screen, null, { maxScrollDivision(matteryPlayer.exoSuitContainer.containerSize, 9) }, { _, _, newScroll ->
inventoryScroll = newScroll
MenuNetworkChannel.sendToServer(InventoryScrollPacket(newScroll).also { it.play(player) })
}, isSlim = true)
// HOW
scrollbar.x = mostLeft + screen.guiLeft - 9f
scrollbar.y = mostTop + screen.guiTop - 1f
scrollbar.height = mostBottom - mostTop + AbstractSlotPanel.SIZE
val widget = Panel2Widget(scrollbar)
event.addListener(widget)
scrollbar.scroll = inventoryScroll
}
fun onMouseDragged(event: MouseDragged.Pre) {
val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return
if (screen is MatteryScreen<*>)
return
for (widget in screen.renderables) {
if (widget is Panel2Widget<*, *>) {
if (widget.panel.mouseDraggedChecked(event.mouseX, event.mouseY, event.mouseButton, event.dragX, event.dragY)) {
event.isCanceled = true
return
}
}
}
}
fun onMouseScrolled(event: MouseScrolled.Pre) {
val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return
if (screen is MatteryScreen<*>)
return
for (widget in screen.renderables) {
if (widget is Panel2Widget<*, *>) {
if (widget.panel.mouseScrolledChecked(event.mouseX, event.mouseY, event.scrollDelta)) {
event.isCanceled = true
return
}
}
}
}
fun onPostScreenInit(event: ScreenEvent.Init.Post) {
inventoryLogic(event)
exosuitInventoryLogic(event)
} }
fun onScreenOpen(event: ScreenEvent.Opening) { fun onScreenOpen(event: ScreenEvent.Opening) {

View File

@ -18,9 +18,9 @@ open class FramePanel<out S : Screen>(
y: Float, y: Float,
width: Float, width: Float,
height: Float, height: Float,
protected var title: Component protected var title: Component?
) : EditablePanel<S>(screen, parent, x, y, width, height), NarratableEntry { ) : EditablePanel<S>(screen, parent, x, y, width, height), NarratableEntry {
constructor(screen: S, width: Float, height: Float, title: Component) : this(screen, null, 0f, 0f, width, height, title) constructor(screen: S, width: Float, height: Float, title: Component?) : this(screen, null, 0f, 0f, width, height, title)
open inner class Tab( open inner class Tab(
var onOpen: Runnable? = null, var onOpen: Runnable? = null,
@ -134,7 +134,7 @@ open class FramePanel<out S : Screen>(
protected var dragging = false protected var dragging = false
init { init {
setDockPadding(PADDING, PADDING_TOP, PADDING, PADDING) setDockPadding(PADDING, if (title != null) PADDING_TOP else PADDING, PADDING, PADDING)
} }
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
@ -160,17 +160,33 @@ open class FramePanel<out S : Screen>(
override fun mouseDraggedInner(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean { override fun mouseDraggedInner(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean {
if (dragging) { if (dragging) {
val oldX = this.x
val oldY = this.y
if (canDrag(oldX, oldY, this.x + xDelta.toFloat(), this.y + yDelta.toFloat(), xDelta.toFloat(), yDelta.toFloat())) {
this.x += xDelta.toFloat() this.x += xDelta.toFloat()
this.y += yDelta.toFloat() this.y += yDelta.toFloat()
onDragged(oldX, oldY, this.x, this.y, xDelta.toFloat(), yDelta.toFloat())
}
} }
return super.mouseDraggedInner(x, y, button, xDelta, yDelta) return super.mouseDraggedInner(x, y, button, xDelta, yDelta)
} }
protected open fun canDrag(oldX: Float, oldY: Float, newX: Float, newY: Float, dragX: Float, dragY: Float): Boolean {
return true
}
protected open fun onDragged(oldX: Float, oldY: Float, newX: Float, newY: Float, dragX: Float, dragY: Float) {
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) { override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
RECTANGLE.render(stack, width = width, height = height) RECTANGLE.render(stack, width = width, height = height)
// title // title
val title = title ?: return
RenderSystem.depthFunc(GL30.GL_ALWAYS) RenderSystem.depthFunc(GL30.GL_ALWAYS)
font.draw(stack, title, 8f, 5f, 4210752) font.draw(stack, title, 8f, 5f, 4210752)
RenderSystem.depthFunc(GL30.GL_ALWAYS) RenderSystem.depthFunc(GL30.GL_ALWAYS)
@ -194,7 +210,7 @@ open class FramePanel<out S : Screen>(
y: Float, y: Float,
width: Float, width: Float,
height: Float, height: Float,
title: Component title: Component?
) = FramePanel(screen, parent, x, y, width + PADDING * 2, height + PADDING_TOP + PADDING, title) ) = FramePanel(screen, parent, x, y, width + PADDING * 2, height + PADDING_TOP + PADDING, title)
fun <S : Screen> padded( fun <S : Screen> padded(
@ -202,14 +218,14 @@ open class FramePanel<out S : Screen>(
parent: EditablePanel<*>?, parent: EditablePanel<*>?,
width: Float, width: Float,
height: Float, height: Float,
title: Component title: Component?
) = FramePanel(screen, parent, 0f, 0f, width + PADDING * 2, height + PADDING_TOP + PADDING, title) ) = FramePanel(screen, parent, 0f, 0f, width + PADDING * 2, height + PADDING_TOP + PADDING, title)
fun <S : Screen> padded( fun <S : Screen> padded(
screen: S, screen: S,
width: Float, width: Float,
height: Float, height: Float,
title: Component title: Component?
) = FramePanel(screen, null, 0f, 0f, width + PADDING * 2, height + PADDING_TOP + PADDING, title) ) = FramePanel(screen, null, 0f, 0f, width + PADDING * 2, height + PADDING_TOP + PADDING, title)
const val PADDING = 8f const val PADDING = 8f

View File

@ -0,0 +1,200 @@
package ru.dbotthepony.mc.otm.compat
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.network.NetworkEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.packetHandled
import ru.dbotthepony.mc.otm.network.sender
import java.util.*
import java.util.function.Supplier
private val menuConfigurations = WeakHashMap<AbstractContainerMenu, MenuConfiguration>()
private class MenuConfiguration(
private val player: Player,
private val menu: AbstractContainerMenu,
originalInventorySlots: Collection<Slot>,
private val indices: Collection<Int>
) {
private data class SlotPos(val x: Int, val y: Int) {
constructor(slot: Slot) : this(slot.x, slot.y)
}
private val slotPositions = Int2ObjectArrayMap<List<SlotPos>>()
private val rows = Int2ObjectAVLTreeMap<List<Slot>>()
val isIncomplete: Boolean
var scroll = 0
set(value) {
if (field == value || isIncomplete || value < 0) {
return
}
val matteryPlayer = player.matteryPlayer ?: return
if (!matteryPlayer.hasExoSuit || matteryPlayer.exoSuitContainer.containerSize <= value * 9) {
return
}
field = value
val indices = indices.iterator()
for (rowIndex in 0 .. 2) {
val row = rows.computeIfAbsent(rowIndex + value, Int2ObjectFunction {
val row = ArrayList<Slot>(9)
val offset = (it - 3) * 9
for (i in 0 .. 8) {
if (matteryPlayer.exoSuitContainer.containerSize > i + offset) {
row.add(MatterySlot(matteryPlayer.exoSuitContainer, i + offset))
} else {
row.add(FakeSlot())
}
}
row
})
val positions = slotPositions[rowIndex] ?: throw IndexOutOfBoundsException("$rowIndex")
for (column in 0 .. 8) {
val slot = row[column]
val (x, y) = positions[column]
val index = indices.next()
menu.slots[index] = slot
slot.x = x
slot.y = y
if (slot.item.isEmpty) {
menu.setRemoteSlotNoCopy(index, ItemStack(Items.BARRIER))
} else {
menu.setRemoteSlotNoCopy(index, ItemStack.EMPTY)
}
slot.index = index
}
}
}
init {
kotlin.run {
for (i in 0 .. 2) {
val offset = 9 + i * 9
val row = ArrayList<Slot>(9)
val slotPositions = ArrayList<SlotPos>(9)
for (i2 in 0 .. 8) {
val slot = originalInventorySlots.firstOrNull { it.slotIndex == i2 + offset }
if (slot == null) {
this.isIncomplete = true
if (loggedClasses.add(menu::class.java)) {
LOGGER.error("Menu $menu <${menu::class.qualifiedName}> is incomplete, missing inventory slot at ${i2 + offset}")
}
return@run
}
row.add(slot)
slotPositions.add(SlotPos(slot))
}
rows[i] = row
this.slotPositions[i] = slotPositions
}
this.isIncomplete = false
}
}
companion object {
private val LOGGER = LogManager.getLogger()
private val loggedClasses = ReferenceArraySet<Class<*>>()
}
}
private class FakeSlot : MatterySlot(SimpleContainer(1), 0, 0, 0) {
override fun mayPickup(player: Player): Boolean {
return false
}
override fun mayPlace(itemStack: ItemStack): Boolean {
return false
}
override fun getItem(): ItemStack {
return ItemStack.EMPTY
}
override fun hasItem(): Boolean {
return false
}
override fun set(p_40240_: ItemStack) {
// no op
}
override fun remove(p_40227_: Int): ItemStack {
return ItemStack.EMPTY
}
override fun setChanged() {
// no op
}
override fun isSameInventory(other: Slot): Boolean {
return false
}
override fun allowModification(p_150652_: Player): Boolean {
return false
}
}
class InventoryScrollPacket(val scroll: Int) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeVarInt(scroll)
}
fun play(player: Player) {
val containerMenu = player.containerMenu ?: return
menuConfigurations.computeIfAbsent(containerMenu) {
val originalSlots = Int2ObjectAVLTreeMap<Slot>()
for (slot in it.slots) {
if (slot.container === player.inventory && slot.slotIndex in 9 .. 35) {
originalSlots[slot.index] = slot
}
}
MenuConfiguration(player, containerMenu, originalSlots.values, originalSlots.keys)
}.scroll = scroll
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
play(context.sender ?: throw IllegalStateException("Illegal side"))
}
companion object {
fun read(buff: FriendlyByteBuf): InventoryScrollPacket {
return InventoryScrollPacket(buff.readVarInt())
}
}
}

View File

@ -1,25 +1,24 @@
package ru.dbotthepony.mc.otm.network package ru.dbotthepony.mc.otm.network
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
import it.unimi.dsi.fastutil.ints.IntArrayList
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.NetworkDirection import net.minecraftforge.network.NetworkDirection
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.compat.InventoryScrollPacket
import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket
import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.menu.CancelTaskPacket
import ru.dbotthepony.mc.otm.menu.* import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.data.* import ru.dbotthepony.mc.otm.menu.PatternsChangePacket
import ru.dbotthepony.mc.otm.menu.ReplicationRequestPacket
import ru.dbotthepony.mc.otm.menu.TasksChangePacket
import ru.dbotthepony.mc.otm.menu.data.ClearItemViewPacket
import ru.dbotthepony.mc.otm.menu.data.ItemViewInteractPacket
import ru.dbotthepony.mc.otm.menu.data.StackAddPacket
import ru.dbotthepony.mc.otm.menu.data.StackChangePacket
import ru.dbotthepony.mc.otm.menu.data.StackRemovePacket
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket
import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket
import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket
@ -98,5 +97,7 @@ object MenuNetworkChannel : MatteryNetworkChannel(
add(PatternsChangePacket::class.java, PatternsChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) add(PatternsChangePacket::class.java, PatternsChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(TasksChangePacket::class.java, TasksChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT) add(TasksChangePacket::class.java, TasksChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(ReplicationRequestPacket::class.java, ReplicationRequestPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER) add(ReplicationRequestPacket::class.java, ReplicationRequestPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(InventoryScrollPacket::class.java, InventoryScrollPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
} }
} }

View File

@ -172,3 +172,5 @@ public net.minecraft.client.renderer.RenderStateShard f_173089_ # VIEW_SCALE_Z_E
public net.minecraft.client.renderer.RenderStateShard f_110127_ # WEATHER_TARGET public net.minecraft.client.renderer.RenderStateShard f_110127_ # WEATHER_TARGET
public net.minecraft.client.renderer.RenderStateShard$LineStateShard public net.minecraft.client.renderer.RenderStateShard$LineStateShard
public net.minecraft.world.inventory.AbstractContainerMenu m_38897_(Lnet/minecraft/world/inventory/Slot;)Lnet/minecraft/world/inventory/Slot; # addSlot