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.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("stored_amount", "Exact amount stored: %s")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
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 scroll_bar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
|
||||
scroll_bar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH }
|
||||
val scrollBar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
|
||||
scrollBar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH }
|
||||
views.add(grid)
|
||||
views.add(scroll_bar)
|
||||
views.add(scrollBar)
|
||||
|
||||
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
||||
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
val index = i + scroll_bar.getScroll(menu.view.sortedView.size / GRID_WIDTH)
|
||||
return menu.view.sortedView.getOrNull(index)?.stack ?: ItemStack.EMPTY
|
||||
val index = i + scrollBar.getScroll(menu.view.sortedView.size / GRID_WIDTH)
|
||||
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||
}
|
||||
|
||||
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 {
|
||||
val index = i + scroll_bar.getScroll(GRID_WIDTH)
|
||||
val index = i + scrollBar.getScroll(GRID_WIDTH)
|
||||
menu.view.mouseClick(index, mouse_click_type)
|
||||
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
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
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.screen.panels.*
|
||||
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.next
|
||||
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
|
||||
}
|
||||
import java.text.NumberFormat
|
||||
|
||||
class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Component) :
|
||||
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
|
||||
|
||||
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.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) {
|
||||
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
val index = i + viewScrollBar.getScroll(div(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
||||
return menu.view.sortedView.getOrNull(index)?.stack ?: ItemStack.EMPTY
|
||||
val index = i + viewScrollBar.getScroll(equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
||||
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||
}
|
||||
|
||||
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 {
|
||||
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)
|
||||
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.minecraftforge.client.RenderProperties
|
||||
import org.lwjgl.opengl.GL11
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
||||
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.renderAndDecorateItem(
|
||||
Minecraft.getInstance().player,
|
||||
requireNotNull(minecraft.player) { "yo, dude, what the fuck" },
|
||||
itemstack,
|
||||
0,
|
||||
0,
|
||||
|
@ -6,7 +6,10 @@ package ru.dbotthepony.mc.otm.core
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
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: Direction): BlockPos = this.offset(direction.normal)
|
||||
@ -217,3 +220,20 @@ fun Byte.toImpreciseFraction() = ImpreciseFraction(this)
|
||||
fun Short.toImpreciseFraction() = ImpreciseFraction(this)
|
||||
fun Long.toImpreciseFraction() = ImpreciseFraction(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
|
||||
|
||||
import net.minecraft.nbt.ByteArrayTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import java.math.BigInteger
|
||||
|
||||
inline val BigInteger.isZero get() = this == BigInteger.ZERO
|
||||
inline val BigInteger.isPositive get() = this > BigInteger.ZERO
|
||||
inline val BigInteger.isNegative get() = this < BigInteger.ZERO
|
||||
|
||||
fun BigInteger.serializeNBT(): ByteArrayTag {
|
||||
return ByteArrayTag(toByteArray())
|
||||
}
|
||||
@Suppress("SameParameterValue")
|
||||
fun equalDownDivision(a: Int, b: Int): Int {
|
||||
if (a % b == 0) {
|
||||
return a / b - 1
|
||||
}
|
||||
|
||||
fun BigInteger(tag: Tag?): BigInteger {
|
||||
if (tag !is ByteArrayTag)
|
||||
return BigInteger.ZERO
|
||||
|
||||
return BigInteger(tag.asByteArray)
|
||||
return a / b
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.menu.data
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
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.inventory.ClickAction
|
||||
import net.minecraft.world.inventory.ClickType
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
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.network.MatteryNetworking
|
||||
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
||||
@ -23,15 +22,11 @@ import java.math.BigInteger
|
||||
import java.util.*
|
||||
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) {
|
||||
buffer.writeInt(containerId)
|
||||
buffer.writeInt(id)
|
||||
buffer.writeInt(stack_id)
|
||||
buffer.writeRegistryId(stack.item)
|
||||
buffer.writeInt(stack.count)
|
||||
buffer.writeBoolean(stack.shareTag != null)
|
||||
|
||||
if (stack.tag != null) buffer.writeNbt(stack.shareTag)
|
||||
buffer.writeBigItem(stack)
|
||||
}
|
||||
|
||||
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 {
|
||||
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
|
||||
|
||||
if (get.containerId != id)
|
||||
if (get.containerId != containerId)
|
||||
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)) {
|
||||
throw IllegalStateException("Item tracker $id already has stack with id of $stack_id")
|
||||
if (view.localState.containsKey(id)) {
|
||||
throw IllegalStateException("Item tracker $containerId already has stack with id of $id")
|
||||
}
|
||||
|
||||
val state = NetworkedItemView.NetworkedItem(stack_id, stack)
|
||||
view.localState[stack_id] = state
|
||||
val state = NetworkedItemView.NetworkedItem(id, stack)
|
||||
view.localState[id] = state
|
||||
|
||||
/*val iterator = view.sortedView.iterator().withIndex()
|
||||
var lastCompare = 0
|
||||
@ -77,22 +72,19 @@ class StackAddPacket(val id: Int, val stack_id: Int, val stack: ItemStack) {
|
||||
|
||||
companion object {
|
||||
fun read(buffer: FriendlyByteBuf): StackAddPacket {
|
||||
val containerId = buffer.readInt()
|
||||
val id = buffer.readInt()
|
||||
val stack = buffer.readInt()
|
||||
val item = buffer.readRegistryIdSafe(Item::class.java)
|
||||
val count = buffer.readInt()
|
||||
val state = ItemStack(item, count)
|
||||
if (buffer.readBoolean()) state.readShareTag(buffer.readNbt())
|
||||
return StackAddPacket(id, stack, state)
|
||||
val item = buffer.readBigItem()
|
||||
return StackAddPacket(containerId, id, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
buffer.writeInt(id)
|
||||
buffer.writeInt(stackID)
|
||||
buffer.writeInt(newCount)
|
||||
buffer.writeBigInteger(newCount)
|
||||
}
|
||||
|
||||
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 {
|
||||
val id = buffer.readInt()
|
||||
val stackID = buffer.readInt()
|
||||
val newCount = buffer.readInt()
|
||||
val newCount = buffer.readBigInteger()
|
||||
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.
|
||||
*/
|
||||
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>
|
||||
get() = ITEM_STORAGE
|
||||
@ -188,7 +180,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
||||
|
||||
fun resort() {
|
||||
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
|
||||
|
||||
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) = addObject(stack.stack, id)
|
||||
override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) = changeObject(id, stack.count.toInt())
|
||||
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) {
|
||||
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) {
|
||||
if (!remote) {
|
||||
@ -248,22 +253,6 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
||||
|
||||
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() {
|
||||
sortedView.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
|
||||
|
||||
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
|
||||
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(ply.containerMenu.carried))
|
||||
ply.containerMenu.setRemoteCarried(ply.containerMenu.carried.copy())
|
||||
@ -308,9 +296,9 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
|
||||
|
||||
val amount =
|
||||
if (action == ClickAction.PRIMARY)
|
||||
state.stack.maxStackSize
|
||||
state.stack.item.maxStackSize
|
||||
else
|
||||
1.coerceAtLeast(state.stack.maxStackSize / 2)
|
||||
1.coerceAtLeast(state.stack.item.maxStackSize / 2)
|
||||
|
||||
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 =
|
||||
if (action == ClickAction.PRIMARY)
|
||||
state.stack.maxStackSize
|
||||
state.stack.item.maxStackSize
|
||||
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)
|
||||
menu.carried = extracted.stack
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.storage
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
@ -7,6 +8,8 @@ import net.minecraftforge.registries.ForgeRegistry
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
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
|
||||
|
||||
/**
|
||||
@ -86,8 +89,22 @@ class ItemStackWrapper : IStorageStack {
|
||||
return "ItemStackWrapper[$count $registryName]"
|
||||
}
|
||||
|
||||
fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeItem(item)
|
||||
buff.writeBigInteger(count)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
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