Network storage items as ItemStackWrappers
so they can have counts of more than 2bil Add some formatting for biginteger
This commit is contained in:
parent
11f416c601
commit
5833448584
@ -416,6 +416,8 @@ private fun gui(provider: MatteryLanguageProvider) {
|
|||||||
gui("item_monitor.amount.one", "Exactly one item")
|
gui("item_monitor.amount.one", "Exactly one item")
|
||||||
gui("item_monitor.amount.stack", "Exactly one stack. This is the behavior you see in AE2 and Refined Storage")
|
gui("item_monitor.amount.stack", "Exactly one stack. This is the behavior you see in AE2 and Refined Storage")
|
||||||
gui("item_monitor.amount.full", "Stack of ingredients. Craft until reaching stack size of one of ingredients. If at least one of inputs is not stackable then 'one stack' mode is used instead")
|
gui("item_monitor.amount.full", "Stack of ingredients. Craft until reaching stack size of one of ingredients. If at least one of inputs is not stackable then 'one stack' mode is used instead")
|
||||||
|
|
||||||
|
gui("stored_amount", "Exact amount stored: %s")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen
|
package ru.dbotthepony.mc.otm.client.screen
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
@ -50,27 +51,41 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
|||||||
|
|
||||||
val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
|
val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
|
||||||
|
|
||||||
val scroll_bar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
|
val scrollBar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
|
||||||
scroll_bar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH }
|
scrollBar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH }
|
||||||
views.add(grid)
|
views.add(grid)
|
||||||
views.add(scroll_bar)
|
views.add(scrollBar)
|
||||||
|
|
||||||
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
||||||
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
||||||
override fun getItemStack(): ItemStack {
|
override fun getItemStack(): ItemStack {
|
||||||
val index = i + scroll_bar.getScroll(menu.view.sortedView.size / GRID_WIDTH)
|
val index = i + scrollBar.getScroll(menu.view.sortedView.size / GRID_WIDTH)
|
||||||
return menu.view.sortedView.getOrNull(index)?.stack ?: ItemStack.EMPTY
|
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
|
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
|
||||||
return scroll_bar.mouseScrolledInner(mouse_x, mouse_y, scroll)
|
return scrollBar.mouseScrolledInner(mouse_x, mouse_y, scroll)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
||||||
val index = i + scroll_bar.getScroll(GRID_WIDTH)
|
val index = i + scrollBar.getScroll(GRID_WIDTH)
|
||||||
menu.view.mouseClick(index, mouse_click_type)
|
menu.view.mouseClick(index, mouse_click_type)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
||||||
|
renderSlotBackground(stack, mouse_x, mouse_y, flag)
|
||||||
|
renderRegular(stack, getItemStack(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||||
|
return super.getItemStackTooltip(stack).also {
|
||||||
|
it as MutableList<Component>
|
||||||
|
val index = i + scrollBar.getScroll(menu.view.sortedView.size / GRID_WIDTH)
|
||||||
|
val realStack = menu.view.sortedView.getOrNull(index)!!.stack
|
||||||
|
it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen
|
package ru.dbotthepony.mc.otm.client.screen
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
@ -11,17 +12,10 @@ import ru.dbotthepony.mc.otm.client.render.SkinGrid
|
|||||||
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.equalDownDivision
|
||||||
|
import ru.dbotthepony.mc.otm.core.formatReadableNumber
|
||||||
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
||||||
import ru.dbotthepony.mc.otm.next
|
import java.text.NumberFormat
|
||||||
import ru.dbotthepony.mc.otm.prev
|
|
||||||
|
|
||||||
private fun div(a: Int, b: Int): Int {
|
|
||||||
if (a % b == 0) {
|
|
||||||
return a / b - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return a / b
|
|
||||||
}
|
|
||||||
|
|
||||||
class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Component) :
|
class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Component) :
|
||||||
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
|
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
|
||||||
@ -42,7 +36,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
|
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
|
||||||
|
|
||||||
val viewScrollBar = ScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
val viewScrollBar = ScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
||||||
viewScrollBar.setupRowMultiplier { div(menu.view.itemCount, ITEM_GRID_WIDTH) }
|
viewScrollBar.setupRowMultiplier { equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH) }
|
||||||
|
|
||||||
viewScrollBar.dock = Dock.RIGHT
|
viewScrollBar.dock = Dock.RIGHT
|
||||||
viewScrollBar.setDockMargin(left = 2f)
|
viewScrollBar.setDockMargin(left = 2f)
|
||||||
@ -53,8 +47,8 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
|
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
|
||||||
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
|
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
|
||||||
override fun getItemStack(): ItemStack {
|
override fun getItemStack(): ItemStack {
|
||||||
val index = i + viewScrollBar.getScroll(div(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
val index = i + viewScrollBar.getScroll(equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
||||||
return menu.view.sortedView.getOrNull(index)?.stack ?: ItemStack.EMPTY
|
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
|
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
|
||||||
@ -62,10 +56,24 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
|
||||||
val index = i + viewScrollBar.getScroll(div(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
val index = i + viewScrollBar.getScroll(equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
||||||
menu.view.mouseClick(index, mouse_click_type)
|
menu.view.mouseClick(index, mouse_click_type)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
||||||
|
renderSlotBackground(stack, mouse_x, mouse_y, flag)
|
||||||
|
renderRegular(stack, getItemStack(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||||
|
return super.getItemStackTooltip(stack).also {
|
||||||
|
it as MutableList<Component>
|
||||||
|
val index = i + viewScrollBar.getScroll(menu.view.sortedView.size / DriveViewerScreen.GRID_WIDTH)
|
||||||
|
val realStack = menu.view.sortedView.getOrNull(index)!!.stack
|
||||||
|
it.add(TranslatableComponent("otm.gui.stored_amount", realStack.count.formatReadableNumber()).withStyle(ChatFormatting.DARK_GRAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import net.minecraft.network.chat.Component
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.client.RenderProperties
|
import net.minecraftforge.client.RenderProperties
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
@ -47,7 +48,7 @@ abstract class AbstractSlotPanel @JvmOverloads constructor(
|
|||||||
screen.itemRenderer.blitOffset = accumulatedDepth - 100 // force item to draw only 50 units "above" background
|
screen.itemRenderer.blitOffset = accumulatedDepth - 100 // force item to draw only 50 units "above" background
|
||||||
|
|
||||||
screen.itemRenderer.renderAndDecorateItem(
|
screen.itemRenderer.renderAndDecorateItem(
|
||||||
Minecraft.getInstance().player,
|
requireNotNull(minecraft.player) { "yo, dude, what the fuck" },
|
||||||
itemstack,
|
itemstack,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -6,7 +6,10 @@ package ru.dbotthepony.mc.otm.core
|
|||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.Vec3i
|
import net.minecraft.core.Vec3i
|
||||||
import java.math.BigDecimal
|
import net.minecraft.nbt.ByteArrayTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
operator fun BlockPos.plus(direction: Vec3i): BlockPos = this.offset(direction)
|
operator fun BlockPos.plus(direction: Vec3i): BlockPos = this.offset(direction)
|
||||||
operator fun BlockPos.plus(direction: Direction): BlockPos = this.offset(direction.normal)
|
operator fun BlockPos.plus(direction: Direction): BlockPos = this.offset(direction.normal)
|
||||||
@ -217,3 +220,20 @@ fun Byte.toImpreciseFraction() = ImpreciseFraction(this)
|
|||||||
fun Short.toImpreciseFraction() = ImpreciseFraction(this)
|
fun Short.toImpreciseFraction() = ImpreciseFraction(this)
|
||||||
fun Long.toImpreciseFraction() = ImpreciseFraction(this)
|
fun Long.toImpreciseFraction() = ImpreciseFraction(this)
|
||||||
fun ImpreciseFraction.toImpreciseFraction() = this
|
fun ImpreciseFraction.toImpreciseFraction() = this
|
||||||
|
|
||||||
|
fun BigInteger(tag: Tag?): BigInteger {
|
||||||
|
if (tag !is ByteArrayTag)
|
||||||
|
return BigInteger.ZERO
|
||||||
|
|
||||||
|
return BigInteger(tag.asByteArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BigInteger.serializeNBT(): ByteArrayTag {
|
||||||
|
return ByteArrayTag(toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FriendlyByteBuf.writeBigInteger(value: BigInteger) {
|
||||||
|
writeByteArray(value.toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FriendlyByteBuf.readBigInteger(byteLimit: Int = 128) = BigInteger(readByteArray(byteLimit))
|
||||||
|
42
src/main/kotlin/ru/dbotthepony/mc/otm/core/Formatting.kt
Normal file
42
src/main/kotlin/ru/dbotthepony/mc/otm/core/Formatting.kt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core
|
||||||
|
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
|
fun BigInteger.formatReadableNumber(): String {
|
||||||
|
if (isZero) {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
val strValue = toString()
|
||||||
|
|
||||||
|
val absLength = strValue.length - (if (isNegative) 1 else 0)
|
||||||
|
val remainder = absLength % 3
|
||||||
|
var groups = absLength / 3
|
||||||
|
|
||||||
|
if (remainder == 0) {
|
||||||
|
groups--
|
||||||
|
}
|
||||||
|
|
||||||
|
val buffer = CharArray((if (remainder == 0) 3 else remainder) + groups * 4 + if (isNegative) 1 else 0)
|
||||||
|
var c = 0
|
||||||
|
var index = buffer.size - 1
|
||||||
|
|
||||||
|
for (i in strValue.length - 1 downTo (if (isNegative) 1 else 0)) {
|
||||||
|
c++
|
||||||
|
|
||||||
|
if (c == 4) {
|
||||||
|
buffer[index] = ' '
|
||||||
|
index--
|
||||||
|
c = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[index] = strValue[i]
|
||||||
|
index--
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNegative) {
|
||||||
|
buffer[index] = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(buffer)
|
||||||
|
}
|
@ -1,20 +1,16 @@
|
|||||||
package ru.dbotthepony.mc.otm.core
|
package ru.dbotthepony.mc.otm.core
|
||||||
|
|
||||||
import net.minecraft.nbt.ByteArrayTag
|
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
|
||||||
inline val BigInteger.isZero get() = this == BigInteger.ZERO
|
inline val BigInteger.isZero get() = this == BigInteger.ZERO
|
||||||
inline val BigInteger.isPositive get() = this > BigInteger.ZERO
|
inline val BigInteger.isPositive get() = this > BigInteger.ZERO
|
||||||
inline val BigInteger.isNegative get() = this < BigInteger.ZERO
|
inline val BigInteger.isNegative get() = this < BigInteger.ZERO
|
||||||
|
|
||||||
fun BigInteger.serializeNBT(): ByteArrayTag {
|
@Suppress("SameParameterValue")
|
||||||
return ByteArrayTag(toByteArray())
|
fun equalDownDivision(a: Int, b: Int): Int {
|
||||||
|
if (a % b == 0) {
|
||||||
|
return a / b - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BigInteger(tag: Tag?): BigInteger {
|
return a / b
|
||||||
if (tag !is ByteArrayTag)
|
|
||||||
return BigInteger.ZERO
|
|
||||||
|
|
||||||
return BigInteger(tag.asByteArray)
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.menu.data
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
@ -10,11 +9,11 @@ import net.minecraft.server.level.ServerPlayer
|
|||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.ClickAction
|
import net.minecraft.world.inventory.ClickAction
|
||||||
import net.minecraft.world.inventory.ClickType
|
import net.minecraft.world.inventory.ClickType
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.network.NetworkEvent
|
import net.minecraftforge.network.NetworkEvent
|
||||||
import net.minecraftforge.network.PacketDistributor
|
import net.minecraftforge.network.PacketDistributor
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.readBigInteger
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeBigInteger
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
||||||
@ -23,15 +22,11 @@ import java.math.BigInteger
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
class StackAddPacket(val id: Int, val stack_id: Int, val stack: ItemStack) {
|
class StackAddPacket(val containerId: Int, val id: Int, val stack: ItemStackWrapper) {
|
||||||
fun write(buffer: FriendlyByteBuf) {
|
fun write(buffer: FriendlyByteBuf) {
|
||||||
|
buffer.writeInt(containerId)
|
||||||
buffer.writeInt(id)
|
buffer.writeInt(id)
|
||||||
buffer.writeInt(stack_id)
|
buffer.writeBigItem(stack)
|
||||||
buffer.writeRegistryId(stack.item)
|
|
||||||
buffer.writeInt(stack.count)
|
|
||||||
buffer.writeBoolean(stack.shareTag != null)
|
|
||||||
|
|
||||||
if (stack.tag != null) buffer.writeNbt(stack.shareTag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun play(context: Supplier<NetworkEvent.Context>) {
|
fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
@ -39,17 +34,17 @@ class StackAddPacket(val id: Int, val stack_id: Int, val stack: ItemStack) {
|
|||||||
context.get().enqueueWork {
|
context.get().enqueueWork {
|
||||||
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
|
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
|
||||||
|
|
||||||
if (get.containerId != id)
|
if (get.containerId != containerId)
|
||||||
return@enqueueWork
|
return@enqueueWork
|
||||||
|
|
||||||
val view = (get as? INetworkedItemViewSupplier)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $id")
|
val view = (get as? INetworkedItemViewSupplier)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $containerId")
|
||||||
|
|
||||||
if (view.localState.containsKey(stack_id)) {
|
if (view.localState.containsKey(id)) {
|
||||||
throw IllegalStateException("Item tracker $id already has stack with id of $stack_id")
|
throw IllegalStateException("Item tracker $containerId already has stack with id of $id")
|
||||||
}
|
}
|
||||||
|
|
||||||
val state = NetworkedItemView.NetworkedItem(stack_id, stack)
|
val state = NetworkedItemView.NetworkedItem(id, stack)
|
||||||
view.localState[stack_id] = state
|
view.localState[id] = state
|
||||||
|
|
||||||
/*val iterator = view.sortedView.iterator().withIndex()
|
/*val iterator = view.sortedView.iterator().withIndex()
|
||||||
var lastCompare = 0
|
var lastCompare = 0
|
||||||
@ -77,22 +72,19 @@ class StackAddPacket(val id: Int, val stack_id: Int, val stack: ItemStack) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun read(buffer: FriendlyByteBuf): StackAddPacket {
|
fun read(buffer: FriendlyByteBuf): StackAddPacket {
|
||||||
|
val containerId = buffer.readInt()
|
||||||
val id = buffer.readInt()
|
val id = buffer.readInt()
|
||||||
val stack = buffer.readInt()
|
val item = buffer.readBigItem()
|
||||||
val item = buffer.readRegistryIdSafe(Item::class.java)
|
return StackAddPacket(containerId, id, item)
|
||||||
val count = buffer.readInt()
|
|
||||||
val state = ItemStack(item, count)
|
|
||||||
if (buffer.readBoolean()) state.readShareTag(buffer.readNbt())
|
|
||||||
return StackAddPacket(id, stack, state)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StackChangePacket(val id: Int, val stackID: Int, val newCount: Int) {
|
class StackChangePacket(val id: Int, val stackID: Int, val newCount: BigInteger) {
|
||||||
fun write(buffer: FriendlyByteBuf) {
|
fun write(buffer: FriendlyByteBuf) {
|
||||||
buffer.writeInt(id)
|
buffer.writeInt(id)
|
||||||
buffer.writeInt(stackID)
|
buffer.writeInt(stackID)
|
||||||
buffer.writeInt(newCount)
|
buffer.writeBigInteger(newCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun play(context: Supplier<NetworkEvent.Context>) {
|
fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
@ -115,7 +107,7 @@ class StackChangePacket(val id: Int, val stackID: Int, val newCount: Int) {
|
|||||||
fun read(buffer: FriendlyByteBuf): StackChangePacket {
|
fun read(buffer: FriendlyByteBuf): StackChangePacket {
|
||||||
val id = buffer.readInt()
|
val id = buffer.readInt()
|
||||||
val stackID = buffer.readInt()
|
val stackID = buffer.readInt()
|
||||||
val newCount = buffer.readInt()
|
val newCount = buffer.readBigInteger()
|
||||||
return StackChangePacket(id, stackID, newCount)
|
return StackChangePacket(id, stackID, newCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +147,7 @@ class StackRemovePacket(val id: Int, val stackID: Int) {
|
|||||||
* Creates a virtual, slotless container for Player to interaction with.
|
* Creates a virtual, slotless container for Player to interaction with.
|
||||||
*/
|
*/
|
||||||
open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: Boolean) : IStorageEventConsumer<ItemStackWrapper> {
|
open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: Boolean) : IStorageEventConsumer<ItemStackWrapper> {
|
||||||
data class NetworkedItem constructor(val id: Int, val stack: ItemStack, val upstreamId: UUID? = null)
|
data class NetworkedItem constructor(val id: Int, val stack: ItemStackWrapper, val upstreamId: UUID? = null)
|
||||||
|
|
||||||
override val storageType: StorageStackType<ItemStackWrapper>
|
override val storageType: StorageStackType<ItemStackWrapper>
|
||||||
get() = ITEM_STORAGE
|
get() = ITEM_STORAGE
|
||||||
@ -188,7 +180,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
|
|
||||||
fun resort() {
|
fun resort() {
|
||||||
sortedView.sortWith { a, b ->
|
sortedView.sortWith { a, b ->
|
||||||
return@sortWith sorter.compare(a.stack, b.stack)
|
return@sortWith sorter.compare(a.stack.item, b.stack.item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,8 +222,21 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
|
|
||||||
val itemCount get() = localState.values.size
|
val itemCount get() = localState.values.size
|
||||||
|
|
||||||
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) = addObject(stack.stack, id)
|
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) {
|
||||||
override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) = changeObject(id, stack.count.toInt())
|
check(!upstreamState.containsKey(id)) { "Already tracking ItemStack with upstream id $id!" }
|
||||||
|
|
||||||
|
val state = NetworkedItem(nextItemID++, stack.copy(), id)
|
||||||
|
|
||||||
|
this.localState[state.id] = state
|
||||||
|
upstreamState[id] = state
|
||||||
|
network { StackAddPacket(menu.containerId, state.id, state.stack) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) {
|
||||||
|
val get = upstreamState[id] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id!")
|
||||||
|
get.stack.count = stack.count
|
||||||
|
network { StackChangePacket(menu.containerId, get.id, stack.count) }
|
||||||
|
}
|
||||||
|
|
||||||
protected fun network(fn: () -> Any) {
|
protected fun network(fn: () -> Any) {
|
||||||
if (!remote) {
|
if (!remote) {
|
||||||
@ -248,22 +253,6 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
|
|
||||||
protected var nextItemID = 0
|
protected var nextItemID = 0
|
||||||
|
|
||||||
fun addObject(stack: ItemStack, id_upstream: UUID) {
|
|
||||||
check(!upstreamState.containsKey(id_upstream)) { "Already tracking ItemStack with upstream id $id_upstream!" }
|
|
||||||
|
|
||||||
val state = NetworkedItem(nextItemID++, stack.copy(), id_upstream)
|
|
||||||
|
|
||||||
this.localState[state.id] = state
|
|
||||||
upstreamState[id_upstream] = state
|
|
||||||
network { StackAddPacket(menu.containerId, state.id, stack) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun changeObject(id_upstream: UUID, new_count: Int) {
|
|
||||||
val get = upstreamState[id_upstream] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id_upstream!")
|
|
||||||
get.stack.count = new_count
|
|
||||||
network { StackChangePacket(menu.containerId, get.id, new_count) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
sortedView.clear()
|
sortedView.clear()
|
||||||
upstreamState.clear()
|
upstreamState.clear()
|
||||||
@ -293,9 +282,8 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
if (stack_id < 0 || !ply.abilities.instabuild) return
|
if (stack_id < 0 || !ply.abilities.instabuild) return
|
||||||
|
|
||||||
val state = get(stack_id) ?: return
|
val state = get(stack_id) ?: return
|
||||||
val copy: ItemStack = state.stack.copy()
|
val copy = state.stack.stack.also { it.count = it.maxStackSize }
|
||||||
|
|
||||||
copy.count = Math.min(copy.count, copy.maxStackSize)
|
|
||||||
ply.containerMenu.carried = copy
|
ply.containerMenu.carried = copy
|
||||||
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(ply.containerMenu.carried))
|
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(ply.containerMenu.carried))
|
||||||
ply.containerMenu.setRemoteCarried(ply.containerMenu.carried.copy())
|
ply.containerMenu.setRemoteCarried(ply.containerMenu.carried.copy())
|
||||||
@ -308,9 +296,9 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
|
|
||||||
val amount =
|
val amount =
|
||||||
if (action == ClickAction.PRIMARY)
|
if (action == ClickAction.PRIMARY)
|
||||||
state.stack.maxStackSize
|
state.stack.item.maxStackSize
|
||||||
else
|
else
|
||||||
1.coerceAtLeast(state.stack.maxStackSize / 2)
|
1.coerceAtLeast(state.stack.item.maxStackSize / 2)
|
||||||
|
|
||||||
val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), true)
|
val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), true)
|
||||||
|
|
||||||
@ -352,9 +340,9 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
|||||||
|
|
||||||
val amount =
|
val amount =
|
||||||
if (action == ClickAction.PRIMARY)
|
if (action == ClickAction.PRIMARY)
|
||||||
state.stack.maxStackSize
|
state.stack.item.maxStackSize
|
||||||
else
|
else
|
||||||
(state.stack.count / 2).coerceAtMost(state.stack.maxStackSize / 2).coerceAtLeast(1)
|
(state.stack.stack.count / 2).coerceAtMost(state.stack.item.maxStackSize / 2).coerceAtLeast(1)
|
||||||
|
|
||||||
val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), false)
|
val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), false)
|
||||||
menu.carried = extracted.stack
|
menu.carried = extracted.stack
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.storage
|
package ru.dbotthepony.mc.otm.storage
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.world.item.Item
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
@ -7,6 +8,8 @@ import net.minecraftforge.registries.ForgeRegistry
|
|||||||
import org.jetbrains.annotations.ApiStatus
|
import org.jetbrains.annotations.ApiStatus
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.core.isPositive
|
import ru.dbotthepony.mc.otm.core.isPositive
|
||||||
|
import ru.dbotthepony.mc.otm.core.readBigInteger
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeBigInteger
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,8 +89,22 @@ class ItemStackWrapper : IStorageStack {
|
|||||||
return "ItemStackWrapper[$count $registryName]"
|
return "ItemStackWrapper[$count $registryName]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeItem(item)
|
||||||
|
buff.writeBigInteger(count)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val EMPTY = ItemStackWrapper(ItemStack.EMPTY)
|
val EMPTY = ItemStackWrapper(ItemStack.EMPTY)
|
||||||
|
|
||||||
|
fun read(buff: FriendlyByteBuf): ItemStackWrapper {
|
||||||
|
val item = buff.readItem()
|
||||||
|
val count = buff.readBigInteger()
|
||||||
|
return ItemStackWrapper(item, copy = false).also { it.count = count }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FriendlyByteBuf.writeBigItem(value: ItemStackWrapper) = value.write(this)
|
||||||
|
fun FriendlyByteBuf.readBigItem() = ItemStackWrapper.read(this)
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.tests
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import ru.dbotthepony.mc.otm.core.formatReadableNumber
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
|
object FormattingTests {
|
||||||
|
@Test
|
||||||
|
@DisplayName("BigInteger formatting")
|
||||||
|
fun biginteger() {
|
||||||
|
assertEquals("0", BigInteger("0").formatReadableNumber())
|
||||||
|
assertEquals("45", BigInteger("45").formatReadableNumber())
|
||||||
|
assertEquals("-45", BigInteger("-45").formatReadableNumber())
|
||||||
|
assertEquals("0", BigInteger("-0").formatReadableNumber())
|
||||||
|
|
||||||
|
assertEquals("100", BigInteger("100").formatReadableNumber())
|
||||||
|
assertEquals("-100", BigInteger("-100").formatReadableNumber())
|
||||||
|
assertEquals("999", BigInteger("999").formatReadableNumber())
|
||||||
|
assertEquals("1 999", BigInteger("1999").formatReadableNumber())
|
||||||
|
assertEquals("8 992", BigInteger("8992").formatReadableNumber())
|
||||||
|
assertEquals("-8 992", BigInteger("-8992").formatReadableNumber())
|
||||||
|
assertEquals("100 200", BigInteger("100200").formatReadableNumber())
|
||||||
|
assertEquals("-100 200", BigInteger("-100200").formatReadableNumber())
|
||||||
|
|
||||||
|
assertEquals("-1 100 200", BigInteger("-1100200").formatReadableNumber())
|
||||||
|
assertEquals("1 100 200", BigInteger("1100200").formatReadableNumber())
|
||||||
|
assertEquals("2 730 250 200", BigInteger("2730250200").formatReadableNumber())
|
||||||
|
assertEquals("1 222 730 250 200", BigInteger("1222730250200").formatReadableNumber())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user