Bump JEI version, make use of createUnregisteredRecipeTransferHandler
This commit is contained in:
parent
583b467e69
commit
43c081277b
@ -13,7 +13,7 @@ mc_version=1.19.2
|
|||||||
forge_gradle_version=5.1.27
|
forge_gradle_version=5.1.27
|
||||||
forge_version=43.1.1
|
forge_version=43.1.1
|
||||||
|
|
||||||
jei_version=11.2.0.254
|
jei_version=11.3.0.262
|
||||||
jupiter_version=5.8.2
|
jupiter_version=5.8.2
|
||||||
the_one_probe_version=6.2.1
|
the_one_probe_version=6.2.1
|
||||||
mekanism_version=10.3.2.homebaked
|
mekanism_version=10.3.2.homebaked
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.compat.jei
|
package ru.dbotthepony.mc.otm.compat.jei
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap
|
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArraySet
|
import it.unimi.dsi.fastutil.ints.IntArraySet
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
|
||||||
import mezz.jei.api.IModPlugin
|
import mezz.jei.api.IModPlugin
|
||||||
import mezz.jei.api.JeiPlugin
|
import mezz.jei.api.JeiPlugin
|
||||||
import mezz.jei.api.constants.RecipeTypes
|
import mezz.jei.api.constants.RecipeTypes
|
||||||
@ -17,6 +12,7 @@ import mezz.jei.api.helpers.IJeiHelpers
|
|||||||
import mezz.jei.api.recipe.RecipeIngredientRole
|
import mezz.jei.api.recipe.RecipeIngredientRole
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError
|
import mezz.jei.api.recipe.transfer.IRecipeTransferError
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler
|
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler
|
||||||
|
import mezz.jei.api.recipe.transfer.IRecipeTransferInfo
|
||||||
import mezz.jei.api.registration.IGuiHandlerRegistration
|
import mezz.jei.api.registration.IGuiHandlerRegistration
|
||||||
import mezz.jei.api.registration.IRecipeCatalystRegistration
|
import mezz.jei.api.registration.IRecipeCatalystRegistration
|
||||||
import mezz.jei.api.registration.IRecipeCategoryRegistration
|
import mezz.jei.api.registration.IRecipeCategoryRegistration
|
||||||
@ -27,7 +23,6 @@ import net.minecraft.resources.ResourceLocation
|
|||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.MenuType
|
import net.minecraft.world.inventory.MenuType
|
||||||
import net.minecraft.world.inventory.Slot
|
import net.minecraft.world.inventory.Slot
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.crafting.CraftingRecipe
|
import net.minecraft.world.item.crafting.CraftingRecipe
|
||||||
import net.minecraft.world.item.crafting.RecipeType
|
import net.minecraft.world.item.crafting.RecipeType
|
||||||
@ -35,14 +30,12 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
|||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.toImmutableList
|
||||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
|
|
||||||
import ru.dbotthepony.mc.otm.network.MoveMultipleItemsPacket
|
|
||||||
import ru.dbotthepony.mc.otm.recipe.EnergyContainerRecipe
|
import ru.dbotthepony.mc.otm.recipe.EnergyContainerRecipe
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.BiFunction
|
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
@ -89,6 +82,38 @@ class JEIPlugin : IModPlugin {
|
|||||||
val helper = registration.transferHelper
|
val helper = registration.transferHelper
|
||||||
|
|
||||||
registration.addRecipeTransferHandler(object : IRecipeTransferHandler<ExoSuitInventoryMenu, CraftingRecipe> {
|
registration.addRecipeTransferHandler(object : IRecipeTransferHandler<ExoSuitInventoryMenu, CraftingRecipe> {
|
||||||
|
private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo<ExoSuitInventoryMenu, CraftingRecipe> {
|
||||||
|
override fun getContainerClass(): Class<out ExoSuitInventoryMenu> {
|
||||||
|
return ExoSuitInventoryMenu::class.java
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMenuType(): Optional<MenuType<ExoSuitInventoryMenu>> {
|
||||||
|
return Optional.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
|
||||||
|
return RecipeTypes.CRAFTING
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canHandle(container: ExoSuitInventoryMenu, recipe: CraftingRecipe): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRecipeSlots(
|
||||||
|
container: ExoSuitInventoryMenu,
|
||||||
|
recipe: CraftingRecipe
|
||||||
|
): List<Slot> {
|
||||||
|
return container.craftingSlots
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInventorySlots(
|
||||||
|
container: ExoSuitInventoryMenu,
|
||||||
|
recipe: CraftingRecipe
|
||||||
|
): List<Slot> {
|
||||||
|
return container.playerInventorySlots
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
override fun getContainerClass(): Class<out ExoSuitInventoryMenu> {
|
override fun getContainerClass(): Class<out ExoSuitInventoryMenu> {
|
||||||
return ExoSuitInventoryMenu::class.java
|
return ExoSuitInventoryMenu::class.java
|
||||||
}
|
}
|
||||||
@ -122,8 +147,6 @@ class JEIPlugin : IModPlugin {
|
|||||||
it.put(4, i)
|
it.put(4, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// i wonder why Mezz didn't expose IConnectionToServer
|
|
||||||
// because without it there is a lot of code duplication!
|
|
||||||
override fun transferRecipe(
|
override fun transferRecipe(
|
||||||
container: ExoSuitInventoryMenu,
|
container: ExoSuitInventoryMenu,
|
||||||
recipe: CraftingRecipe,
|
recipe: CraftingRecipe,
|
||||||
@ -144,143 +167,50 @@ class JEIPlugin : IModPlugin {
|
|||||||
return helper.createUserErrorWithTooltip(TranslatableComponent("jei.tooltip.error.recipe.transfer.too.large.player.inventory"))
|
return helper.createUserErrorWithTooltip(TranslatableComponent("jei.tooltip.error.recipe.transfer.too.large.player.inventory"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val missingItems = inputs.stream()
|
val filteredInputs = ArrayList<IRecipeSlotView>()
|
||||||
.filter { !it.isEmpty }
|
|
||||||
.filter { it.itemStacks.noneMatch { recipeItem -> container.allAccessibleSlots.any { it.mayPickup(player) && it.item.item === recipeItem.item } } }
|
|
||||||
.collect(Collectors.toList())
|
|
||||||
|
|
||||||
if (missingItems.isNotEmpty()) {
|
|
||||||
return helper.createUserErrorForMissingSlots(TranslatableComponent("jei.tooltip.error.recipe.transfer.missing"), missingItems)
|
|
||||||
}
|
|
||||||
|
|
||||||
val emptySlots = container.allAccessibleSlots.stream().filter { it.item.isEmpty }.toList()
|
|
||||||
val filledCraftingSlots = container.craftingSlots.stream().filter { !it.item.isEmpty }.count()
|
|
||||||
|
|
||||||
if (emptySlots.size < filledCraftingSlots) {
|
|
||||||
return helper.createUserErrorWithTooltip(TranslatableComponent("jei.tooltip.error.recipe.transfer.inventory.full"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doTransfer) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val desiredItems = inputs.stream()
|
|
||||||
.filter { !it.isEmpty }
|
|
||||||
.flatMap { it.itemStacks }
|
|
||||||
.map { it.item }
|
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toSet())
|
|
||||||
|
|
||||||
val sources = Object2ObjectArrayMap<Item, MutableList<Slot>>()
|
|
||||||
|
|
||||||
for (slot in container.allAccessibleSlots) {
|
|
||||||
if (!slot.item.isEmpty && slot.mayPickup(player) && slot.item.item in desiredItems) {
|
|
||||||
sources.computeIfAbsent(slot.item.item, Object2ObjectFunction { ArrayList() }).add(slot)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val bestSources = Array(inputs.size) {
|
|
||||||
val ingredient = inputs[it]
|
|
||||||
|
|
||||||
if (ingredient.isEmpty) {
|
|
||||||
kotlin.collections.ArrayDeque()
|
|
||||||
} else {
|
|
||||||
var bestMatch: List<Slot>? = null
|
|
||||||
var bestMatchSize = 0
|
|
||||||
|
|
||||||
for (item in ingredient.itemStacks) {
|
|
||||||
val slots = sources[item.item]
|
|
||||||
|
|
||||||
if (slots != null) {
|
|
||||||
var thisSize = 0
|
|
||||||
for (slot in slots) thisSize += slot.item.count
|
|
||||||
|
|
||||||
if (bestMatchSize < thisSize) {
|
|
||||||
bestMatchSize = thisSize
|
|
||||||
bestMatch = slots
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val bestMatchNN = bestMatch ?: throw NullPointerException("Could not find best matching set of slots for recipe autofill (this exception should be never reachable)")
|
|
||||||
val trulyBest: List<Slot>
|
|
||||||
|
|
||||||
if (bestMatchNN.size <= 99) {
|
|
||||||
trulyBest = bestMatchNN
|
|
||||||
} else {
|
|
||||||
trulyBest = ArrayList<Slot>(99).also { for (i in 0 .. 39) it.add(bestMatchNN[i]) }
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin.collections.ArrayDeque<Slot>(trulyBest.size).also {
|
|
||||||
it.addAll(trulyBest)
|
|
||||||
|
|
||||||
it.sortWith { a, b ->
|
|
||||||
a.item.count.compareTo(b.item.count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val actions = ArrayList<MoveMultipleItemsPacket.Move>()
|
|
||||||
|
|
||||||
val nextEmpty = emptySlots.iterator()
|
|
||||||
val emptiedSlots = IntArraySet()
|
|
||||||
|
|
||||||
// clear crafting slots
|
|
||||||
for (slot in container.craftingSlots) {
|
|
||||||
if (!slot.item.isEmpty) {
|
|
||||||
val emptySlot = nextEmpty.next()
|
|
||||||
actions.add(MoveMultipleItemsPacket.Move(setOf(slot.index), emptySlot.index, slot.item.count))
|
|
||||||
emptiedSlots.add(slot.index)
|
|
||||||
|
|
||||||
for (sourceList in bestSources) {
|
|
||||||
if (sourceList.isNotEmpty() && sourceList.first().item.item === slot.item.item) {
|
|
||||||
sourceList.addFirst(emptySlot)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val pieWishers = Object2IntArrayMap<Item>()
|
|
||||||
|
|
||||||
for (slots in bestSources) {
|
|
||||||
if (slots.isNotEmpty()) {
|
|
||||||
pieWishers.compute(slots.first().item.item) { _, count -> (count ?: 0) + 1 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var transferCount = if (maxTransfer) 64 else 1
|
|
||||||
|
|
||||||
if (transferCount != 1) {
|
|
||||||
for ((i, ingredient) in inputs.withIndex()) {
|
|
||||||
if (!ingredient.isEmpty) {
|
|
||||||
var maxTransferThis = 0
|
|
||||||
for (slot in bestSources[i]) maxTransferThis += slot.item.count
|
|
||||||
transferCount = transferCount.coerceAtMost(maxTransferThis / pieWishers.getInt(bestSources[i].first().item.item))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val remap = if (container.craftingSlots.size == 9) directMap else smallMap
|
|
||||||
|
|
||||||
for ((i, ingredient) in inputs.withIndex()) {
|
for ((i, ingredient) in inputs.withIndex()) {
|
||||||
if (!ingredient.isEmpty) {
|
if (i in validSlots) {
|
||||||
actions.add(MoveMultipleItemsPacket.Move(
|
filteredInputs.add(ingredient)
|
||||||
IntArrayList().also { for (slot in bestSources[i]) if (slot.index !in emptiedSlots) it.add(slot.index) },
|
|
||||||
container.craftingSlots[remap[i]].index,
|
|
||||||
transferCount))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val packetA = MoveMultipleItemsPacket(actions, mapOf())
|
val outputs = recipeSlots.getSlotViews(RecipeIngredientRole.OUTPUT).toImmutableList()
|
||||||
val result = packetA.execute(player, container)
|
val catalysts = recipeSlots.getSlotViews(RecipeIngredientRole.CATALYST).toImmutableList()
|
||||||
val packetB = MoveMultipleItemsPacket(actions, result)
|
val render = recipeSlots.getSlotViews(RecipeIngredientRole.RENDER_ONLY).toImmutableList()
|
||||||
|
|
||||||
MenuNetworkChannel.sendToServer(packetB)
|
val combine = ArrayList<IRecipeSlotView>(filteredInputs.size + outputs.size + render.size)
|
||||||
|
|
||||||
return null
|
combine.addAll(filteredInputs)
|
||||||
|
combine.addAll(outputs)
|
||||||
|
combine.addAll(render)
|
||||||
|
|
||||||
|
val combined = combine.toImmutableList()
|
||||||
|
|
||||||
|
val newView = object : IRecipeSlotsView {
|
||||||
|
override fun getSlotViews(): MutableList<IRecipeSlotView> {
|
||||||
|
return combined
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSlotViews(role: RecipeIngredientRole): MutableList<IRecipeSlotView> {
|
||||||
|
return when (role) {
|
||||||
|
RecipeIngredientRole.INPUT -> filteredInputs
|
||||||
|
RecipeIngredientRole.OUTPUT -> outputs
|
||||||
|
RecipeIngredientRole.CATALYST -> catalysts
|
||||||
|
RecipeIngredientRole.RENDER_ONLY -> render
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findSlotByName(slotName: String): Optional<IRecipeSlotView> {
|
||||||
|
return combined.stream().filter { it.slotName.orElse(null) == slotName }.findAny()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.transfer.transferRecipe(container, recipe, newView, player, maxTransfer, doTransfer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.transfer.transferRecipe(container, recipe, recipeSlots, player, maxTransfer, doTransfer)
|
||||||
}
|
}
|
||||||
}, RecipeTypes.CRAFTING)
|
}, RecipeTypes.CRAFTING)
|
||||||
}
|
}
|
||||||
|
@ -331,3 +331,7 @@ fun FriendlyByteBuf.readItemType(): Item? {
|
|||||||
operator fun <T : Comparable<T>> StateHolder<*, *>.get(value: Property<T>): T {
|
operator fun <T : Comparable<T>> StateHolder<*, *>.get(value: Property<T>): T {
|
||||||
return getValue(value)
|
return getValue(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> List<T>.toImmutableList(): ImmutableList<T> {
|
||||||
|
return ImmutableList.copyOf(this)
|
||||||
|
}
|
||||||
|
@ -65,189 +65,6 @@ class SetCarriedPacket(val item: ItemStack) : MatteryPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveMultipleItemsPacket(val actions: Collection<Move>, val changedSlots: Map<Int, ItemStack>, val error: Throwable? = null) : MatteryPacket {
|
|
||||||
data class Move(val sourceSlots: Collection<Int>, val destinationSlot: Int, val count: Int) {
|
|
||||||
fun write(buff: FriendlyByteBuf) {
|
|
||||||
buff.writeInt(sourceSlots.size)
|
|
||||||
|
|
||||||
for (slot in sourceSlots) {
|
|
||||||
buff.writeInt(slot)
|
|
||||||
}
|
|
||||||
|
|
||||||
buff.writeInt(destinationSlot)
|
|
||||||
buff.writeInt(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun read(buff: FriendlyByteBuf): Move {
|
|
||||||
val listSize = buff.readInt()
|
|
||||||
require(listSize <= 100) { "Too many source slots! ($listSize received)" }
|
|
||||||
|
|
||||||
val seen = IntAVLTreeSet()
|
|
||||||
val list = IntArrayList()
|
|
||||||
|
|
||||||
for (i in 0 until listSize) {
|
|
||||||
val index = buff.readInt()
|
|
||||||
|
|
||||||
if (seen.add(index)) {
|
|
||||||
list.add(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val destinationSlot = buff.readInt()
|
|
||||||
val count = buff.readInt()
|
|
||||||
|
|
||||||
return Move(list, destinationSlot, count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun write(buff: FriendlyByteBuf) {
|
|
||||||
buff.writeInt(actions.size)
|
|
||||||
|
|
||||||
for (action in actions) {
|
|
||||||
action.write(buff)
|
|
||||||
}
|
|
||||||
|
|
||||||
buff.writeInt(changedSlots.size)
|
|
||||||
|
|
||||||
for ((k, v) in changedSlots) {
|
|
||||||
buff.writeInt(k)
|
|
||||||
buff.writeItem(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun execute(ply: Player, container: AbstractContainerMenu): Map<Int, ItemStack> {
|
|
||||||
val changedSlots = Int2ObjectArrayMap<ItemStack>()
|
|
||||||
|
|
||||||
for ((sourceSlots, destinationSlotIndex, count) in actions) {
|
|
||||||
val destinationSlot = container.slots[destinationSlotIndex]
|
|
||||||
|
|
||||||
if (!destinationSlot.item.isEmpty) {
|
|
||||||
// clear slot first
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val realSourceSlots = sourceSlots.map { container.slots[it] }
|
|
||||||
|
|
||||||
if (realSourceSlots.isEmpty() || realSourceSlots.all { it.item.isEmpty }) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val type = realSourceSlots.first { !it.item.isEmpty }.item
|
|
||||||
|
|
||||||
if (!realSourceSlots.all { it.item.isEmpty || it.item.item === type.item }) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!destinationSlot.mayPlace(type)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var pickedUp = 0
|
|
||||||
val maxPickup = destinationSlot.getMaxStackSize(type).coerceAtMost(count)
|
|
||||||
|
|
||||||
for (slot in realSourceSlots) {
|
|
||||||
if (slot.mayPickup(ply) && !slot.item.isEmpty) {
|
|
||||||
if (!destinationSlot.item.isEmpty && !ItemStack.isSameItemSameTags(destinationSlot.item, slot.item)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val old = pickedUp
|
|
||||||
pickedUp = (pickedUp + slot.item.count).coerceAtMost(maxPickup)
|
|
||||||
val diff = pickedUp - old
|
|
||||||
|
|
||||||
val copy = slot.item.copy().also { it.count = diff }
|
|
||||||
|
|
||||||
slot.item.count -= diff
|
|
||||||
|
|
||||||
if (slot.item.isEmpty) {
|
|
||||||
slot.set(ItemStack.EMPTY)
|
|
||||||
changedSlots[slot.index] = ItemStack.EMPTY
|
|
||||||
} else {
|
|
||||||
slot.setChanged()
|
|
||||||
changedSlots[slot.index] = slot.item.copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (destinationSlot.item.isEmpty) {
|
|
||||||
destinationSlot.set(copy)
|
|
||||||
} else {
|
|
||||||
destinationSlot.item.count += diff
|
|
||||||
destinationSlot.setChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pickedUp == maxPickup) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pickedUp != 0) {
|
|
||||||
changedSlots[destinationSlot.index] = destinationSlot.item.copy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changedSlots
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
|
||||||
context.packetHandled = true
|
|
||||||
|
|
||||||
if (error != null) {
|
|
||||||
context.sender!!.connection.disconnect(TextComponent("Caught an exception processing ${MoveMultipleItemsPacket::class.qualifiedName}: $error"))
|
|
||||||
LOGGER.error("Processing multi move input from player ${context.sender} has thrown an exception!", error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
context.enqueueWork {
|
|
||||||
try {
|
|
||||||
val container = context.sender!!.containerMenu
|
|
||||||
|
|
||||||
if (container is ExoSuitInventoryMenu) {
|
|
||||||
execute(context.sender!!, container)
|
|
||||||
|
|
||||||
for ((index, contents) in changedSlots) {
|
|
||||||
container.setRemoteSlot(index, contents)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err: Throwable) {
|
|
||||||
context.sender!!.connection.disconnect(TextComponent("Caught an exception processing ${MoveMultipleItemsPacket::class.qualifiedName}: $err"))
|
|
||||||
LOGGER.error("Processing multi move input from player ${context.sender} has thrown an exception!", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val LOGGER = LogManager.getLogger()
|
|
||||||
|
|
||||||
fun read(buff: FriendlyByteBuf): MoveMultipleItemsPacket {
|
|
||||||
try {
|
|
||||||
val actionCount = buff.readInt()
|
|
||||||
require(actionCount <= 40) { "Too many actions!" }
|
|
||||||
|
|
||||||
val actions = ArrayList<Move>(actionCount)
|
|
||||||
|
|
||||||
for (i in 0 until actionCount) {
|
|
||||||
actions.add(Move.read(buff))
|
|
||||||
}
|
|
||||||
|
|
||||||
val changedSlotCount = buff.readInt()
|
|
||||||
require(changedSlotCount <= 40) { "Too many changed slots!" }
|
|
||||||
|
|
||||||
val changedSlots = Int2ObjectAVLTreeMap<ItemStack>()
|
|
||||||
|
|
||||||
for (i in 0 until changedSlotCount) {
|
|
||||||
changedSlots.put(buff.readInt(), buff.readItem())
|
|
||||||
}
|
|
||||||
|
|
||||||
return MoveMultipleItemsPacket(actions, changedSlots)
|
|
||||||
} catch (err: Throwable) {
|
|
||||||
return MoveMultipleItemsPacket(listOf(), mapOf(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object MenuNetworkChannel : MatteryNetworkChannel(
|
object MenuNetworkChannel : MatteryNetworkChannel(
|
||||||
version = "1",
|
version = "1",
|
||||||
name = "menu"
|
name = "menu"
|
||||||
@ -272,7 +89,6 @@ object MenuNetworkChannel : MatteryNetworkChannel(
|
|||||||
add(BooleanPlayerInputPacket::class.java, BooleanPlayerInputPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
|
add(BooleanPlayerInputPacket::class.java, BooleanPlayerInputPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
|
||||||
|
|
||||||
// menu specific
|
// menu specific
|
||||||
add(MoveMultipleItemsPacket::class.java, MoveMultipleItemsPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
|
|
||||||
|
|
||||||
// Item monitor
|
// Item monitor
|
||||||
add(ItemMonitorPlayerSettings::class.java, ItemMonitorPlayerSettings.Companion::read)
|
add(ItemMonitorPlayerSettings::class.java, ItemMonitorPlayerSettings.Companion::read)
|
||||||
|
Loading…
Reference in New Issue
Block a user