parent
ba52af00fb
commit
994058b187
@ -43,6 +43,7 @@ import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||
@ -920,5 +921,29 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun pickBlockHook(determinedSlot: Int, itemStack: ItemStack) {
|
||||
val player = minecraft.player ?: return
|
||||
|
||||
if (player.abilities.instabuild || determinedSlot != -1 || itemStack.isEmpty) {
|
||||
return
|
||||
}
|
||||
|
||||
val matteryPlayer = player.matteryPlayer ?: return
|
||||
|
||||
if (!matteryPlayer.hasExoSuit) {
|
||||
return
|
||||
}
|
||||
|
||||
val targetSlot = player.inventory.suitableHotbarSlot
|
||||
val itemSlot = matteryPlayer.exoSuitContainer.indexOfFirst { !it.isEmpty && ItemStack.isSameItemSameTags(itemStack, it) }
|
||||
|
||||
if (itemSlot == -1) {
|
||||
return
|
||||
}
|
||||
|
||||
MatteryPlayerNetworkChannel.sendToServer(PickItemFromInventoryPacket(targetSlot, itemSlot))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.*
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots
|
||||
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
|
||||
import ru.dbotthepony.mc.otm.container.iterator
|
||||
@ -213,6 +214,7 @@ class ExoSuitInventoryMenu(val capability: MatteryPlayerCapability) : MatteryMen
|
||||
}
|
||||
|
||||
fun sendSlotChange(container: ExoSuitInventoryMenu, slotId: Int, itemStack: ItemStack) {
|
||||
if (container.slots[slotId].container != container.ply.inventory || container.ply.containerMenu is ExoSuitInventoryMenu)
|
||||
MatteryPlayerNetworkChannel.send(container.ply as ServerPlayer, ExoSuitSlotPacket(slotId, itemStack, container.stateId))
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,11 @@ package ru.dbotthepony.mc.otm.network
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
|
||||
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
|
||||
@ -19,7 +23,10 @@ import ru.dbotthepony.mc.otm.android.feature.TriggerShockwavePacket
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.MatteryGUI
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.container.get
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.io.ByteArrayInputStream
|
||||
@ -237,6 +244,11 @@ class ExoSuitSlotPacket(val slotId: Int, val itemStack: ItemStack, val container
|
||||
return@enqueueWork
|
||||
}
|
||||
|
||||
// don't duplicate data
|
||||
// really.
|
||||
if (mattery.exoSuitMenu.slots[slotId].container == minecraft.player?.inventory && minecraft.player?.containerMenu !is ExoSuitInventoryMenu)
|
||||
return@enqueueWork
|
||||
|
||||
mattery.exoSuitMenu.slots[slotId].set(itemStack)
|
||||
mattery.exoSuitMenu.stateId = containerState
|
||||
}
|
||||
@ -376,6 +388,48 @@ class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : MatteryPac
|
||||
}
|
||||
}
|
||||
|
||||
class PickItemFromInventoryPacket(
|
||||
val targetHotbarSlot: Int,
|
||||
val sourceExosuitSlot: Int
|
||||
) : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeVarInt(targetHotbarSlot)
|
||||
buff.writeVarInt(sourceExosuitSlot)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val player = context.sender ?: return@enqueueWork
|
||||
val mattery = player.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
if (!mattery.hasExoSuit || sourceExosuitSlot !in 0 until mattery.exoSuitContainer.containerSize) {
|
||||
return@enqueueWork
|
||||
}
|
||||
|
||||
if (!Inventory.isHotbarSlot(targetHotbarSlot)) {
|
||||
return@enqueueWork
|
||||
}
|
||||
|
||||
player.inventory.selected = targetHotbarSlot
|
||||
val existingItem = player.inventory[targetHotbarSlot].copy()
|
||||
val inventoryItem = mattery.exoSuitContainer[sourceExosuitSlot].copy()
|
||||
|
||||
player.inventory[targetHotbarSlot] = if (inventoryItem.isEmpty) ItemStack.EMPTY else inventoryItem
|
||||
mattery.exoSuitContainer[sourceExosuitSlot] = if (existingItem.isEmpty) ItemStack.EMPTY else existingItem
|
||||
|
||||
player.connection.send(ClientboundSetCarriedItemPacket(targetHotbarSlot))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): PickItemFromInventoryPacket {
|
||||
return PickItemFromInventoryPacket(buff.readVarInt(), buff.readVarInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
|
||||
version = "1",
|
||||
name = "player"
|
||||
@ -401,5 +455,7 @@ object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
|
||||
|
||||
add(TriggerShockwavePacket::class, { TriggerShockwavePacket }, PLAY_TO_SERVER)
|
||||
add(TriggerJumpBoostPacket::class, { TriggerJumpBoostPacket }, PLAY_TO_SERVER)
|
||||
|
||||
add(PickItemFromInventoryPacket::class, PickItemFromInventoryPacket.Companion::read, PLAY_TO_SERVER)
|
||||
}
|
||||
}
|
||||
|
@ -510,26 +510,8 @@ var returnCodes = [
|
||||
opcodesRemapped.lreturn,
|
||||
]
|
||||
|
||||
function injectAtTail(path, instructions) {
|
||||
return method(path, function(node) {
|
||||
for (var instr = node.instructions.size() - 1; instr >= 0; instr--) {
|
||||
if (includes(returnCodes, node.instructions.get(instr).getOpcode())) {
|
||||
var last = node.instructions.get(instr > 0 ? --instr : instr)
|
||||
var next
|
||||
|
||||
for (var i = 0; i < instructions.length; i++) {
|
||||
next = instructions[i]
|
||||
node.instructions.insert(last, next)
|
||||
last = next
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
print('[Overdrive That Matters Coremod] Unable to find tail of ' + path + ', injecting at beginning!')
|
||||
|
||||
var last = undefined
|
||||
function putInstructions(node, after, instructions) {
|
||||
var last = after
|
||||
var next
|
||||
|
||||
for (var i = 0; i < instructions.length; i++) {
|
||||
@ -543,7 +525,19 @@ function injectAtTail(path, instructions) {
|
||||
|
||||
last = next
|
||||
}
|
||||
}
|
||||
|
||||
function injectAtTail(path, instructions) {
|
||||
return method(path, function(node) {
|
||||
for (var instr = node.instructions.size() - 1; instr >= 0; instr--) {
|
||||
if (includes(returnCodes, node.instructions.get(instr).getOpcode())) {
|
||||
putInstructions(node, node.instructions.get(instr > 0 ? --instr : instr), instructions)
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
print('[Overdrive That Matters Coremod] Unable to find tail of ' + path + ', injecting at beginning!')
|
||||
putInstructions(node, undefined, instructions)
|
||||
return node
|
||||
})
|
||||
}
|
||||
@ -614,6 +608,21 @@ function patchBlendFunc(node) {
|
||||
return node
|
||||
}
|
||||
|
||||
function backtrack(instructions, from, opcode, skipAmount) {
|
||||
for (var i = from; i >= 0; i--) {
|
||||
if (instructions.get(i).getOpcode() === opcode) {
|
||||
if (skipAmount > 0) {
|
||||
skipAmount--
|
||||
continue
|
||||
}
|
||||
|
||||
return instructions.get(i)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function initializeCoreMod() {
|
||||
return {
|
||||
'Inventory#dropAll': injectAtTail(
|
||||
@ -700,6 +709,74 @@ function initializeCoreMod() {
|
||||
'transformer': patchBlendFunc
|
||||
},
|
||||
|
||||
'Minecraft#pickBlock patch for exosuit':
|
||||
method('net.minecraft.client.Minecraft.m_91280_()V', function(node) {
|
||||
// 275: invokevirtual #7672 // Method net/minecraft/world/entity/Entity.getType:()Lnet/minecraft/world/entity/EntityType;
|
||||
// 278: invokevirtual #7667 // Method net/minecraft/core/DefaultedRegistry.getKey:(Ljava/lang/Object;)Lnet/minecraft/resources/ResourceLocation;
|
||||
// 281: invokevirtual #4475 // Method net/minecraft/resources/ResourceLocation.toString:()Ljava/lang/String;
|
||||
// 284: astore 5
|
||||
// 286: getstatic #5986 // Field LOGGER:Lorg/slf4j/Logger;
|
||||
// 289: ldc_w #4484 // String Picking on: [{}] {} gave null item
|
||||
// 292: aload_3
|
||||
// 293: aload 5
|
||||
// 295: invokeinterface #3145, 4 // InterfaceMethod org/slf4j/Logger.warn:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
|
||||
// 300: goto 405
|
||||
// 303: aload_0
|
||||
// 304: getfield #6654 // Field player:Lnet/minecraft/client/player/LocalPlayer;
|
||||
// 307: invokevirtual #7409 // Method net/minecraft/client/player/LocalPlayer.getInventory:()Lnet/minecraft/world/entity/player/Inventory;
|
||||
// 310: astore 5
|
||||
// 312: aload_2
|
||||
// 313: ifnull 324
|
||||
// 316: aload_0
|
||||
// 317: aload 4
|
||||
// 319: aload_2
|
||||
// 320: invokevirtual #7675 // Method addCustomNbtData:(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/block/entity/BlockEntity;)Lnet/minecraft/world/item/ItemStack;
|
||||
// 323: pop
|
||||
// 324: aload 5
|
||||
// 326: aload 4
|
||||
// 328: invokevirtual #7678 // Method net/minecraft/world/entity/player/Inventory.findSlotMatchingItem:(Lnet/minecraft/world/item/ItemStack;)I
|
||||
// 331: istore 6
|
||||
// <-- Our target
|
||||
// 333: iload_1
|
||||
// 334: ifeq 372
|
||||
// 337: aload 5
|
||||
// 339: aload 4
|
||||
// 341: invokevirtual #7681 // Method net/minecraft/world/entity/player/Inventory.setPickedItem:(Lnet/minecraft/world/item/ItemStack;)V
|
||||
// 344: aload_0
|
||||
|
||||
for (var i = 0; i < node.instructions.size(); i++) {
|
||||
var determinedOffset = test([
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.getfield,
|
||||
opcodesRemapped.invokevirtual,
|
||||
opcodesRemapped.astore,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.ifnull,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.invokevirtual,
|
||||
opcodesRemapped.pop,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.aload,
|
||||
opcodesRemapped.invokevirtual,
|
||||
opcodesRemapped.istore,
|
||||
], node.instructions, i)
|
||||
|
||||
if (determinedOffset != -1) {
|
||||
putInstructions(node, node.instructions.get(determinedOffset), [
|
||||
new VarInsnNode(opcodesRemapped.iload, backtrack(node.instructions, determinedOffset, opcodesRemapped.istore, 0)['var']),
|
||||
new VarInsnNode(opcodesRemapped.aload, backtrack(node.instructions, determinedOffset, opcodesRemapped.aload, 0)['var']),
|
||||
new MethodInsnNode(opcodesRemapped.invokestatic, 'ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability', 'pickBlockHook', '(ILnet/minecraft/world/item/ItemStack;)V', false)
|
||||
])
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
}),
|
||||
|
||||
'Inventory#add patch': {
|
||||
'target': {
|
||||
'type': 'METHOD',
|
||||
@ -812,7 +889,7 @@ function initializeCoreMod() {
|
||||
injectInventoryInsertHook(node.instructions, determinedOffset,
|
||||
'inventoryAddDamagedItemHook',
|
||||
'(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/item/ItemStack;)V',
|
||||
new VarInsnNode(opcodesRemapped.iload, 1))
|
||||
new VarInsnNode(opcodesRemapped.iload, node.instructions.get(determinedOffset - 1)['var']))
|
||||
|
||||
break
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user