Support for mod containers.
This commit is contained in:
parent
2e6ad0cfb0
commit
8b4a000bb9
|
@ -66,6 +66,7 @@ dependencies {
|
|||
|
||||
remapSpigotJar {
|
||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||
}
|
||||
|
||||
generateArclightMeta {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package io.izzel.arclight.common.mixin.bukkit;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.tileentity.LecternTileEntity;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(value = CraftInventory.class, remap = false)
|
||||
public class CraftInventoryMixin {
|
||||
|
||||
@Shadow @Final protected IInventory inventory;
|
||||
|
||||
@Inject(method = "getType", cancellable = true, at = @At("HEAD"))
|
||||
private void arclight$lecternType(CallbackInfoReturnable<InventoryType> cir) {
|
||||
if (inventory.getClass().getDeclaringClass() == LecternTileEntity.class) {
|
||||
cir.setReturnValue(InventoryType.LECTERN);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
|||
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||
import io.izzel.arclight.common.mod.util.ChestBlockDoubleInventoryHacks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -397,9 +398,11 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
|||
|
||||
@Inject(method = "sendAllContents", at = @At("RETURN"))
|
||||
private void arclight$sendExtra(Container container, NonNullList<ItemStack> itemsList, CallbackInfo ci) {
|
||||
ArclightCaptures.captureContainerOwner((ServerPlayerEntity) (Object) this);
|
||||
if (EnumSet.of(InventoryType.CRAFTING, InventoryType.WORKBENCH).contains(((ContainerBridge) container).bridge$getBukkitView().getType())) {
|
||||
this.connection.sendPacket(new SSetSlotPacket(container.windowId, 0, container.getSlot(0).getStack()));
|
||||
}
|
||||
ArclightCaptures.resetContainerOwner();
|
||||
}
|
||||
|
||||
@Inject(method = "closeScreen", at = @At("HEAD"))
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package io.izzel.arclight.common.mixin.core.inventory.container;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||
import io.izzel.arclight.common.bridge.inventory.container.SlotBridge;
|
||||
import io.izzel.arclight.common.mod.ArclightMod;
|
||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.CraftResultInventory;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
|
@ -18,10 +23,13 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryCustom;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -31,6 +39,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -54,8 +63,59 @@ public abstract class ContainerMixin implements ContainerBridge {
|
|||
// @formatter:on
|
||||
|
||||
public boolean checkReachable = true;
|
||||
private InventoryView bukkitView;
|
||||
|
||||
public abstract InventoryView getBukkitView();
|
||||
// todo check this
|
||||
public InventoryView getBukkitView() {
|
||||
if (bukkitView == null) {
|
||||
PlayerEntity candidate = null;
|
||||
Set<IInventory> set = new HashSet<>();
|
||||
for (Slot slot : this.inventorySlots) {
|
||||
if (slot.inventory != null) {
|
||||
if (slot.inventory instanceof PlayerInventory) {
|
||||
if (candidate != null && ((PlayerInventory) slot.inventory).player != candidate) {
|
||||
ArclightMod.LOGGER.warn("Duplicate PlayerInventory inside {}, previous {}, new {}", this, candidate, slot.inventory);
|
||||
}
|
||||
candidate = ((PlayerInventory) slot.inventory).player;
|
||||
} else {
|
||||
set.add(slot.inventory);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (candidate == null) {
|
||||
if (ArclightCaptures.getContainerOwner() != null) {
|
||||
candidate = ArclightCaptures.getContainerOwner();
|
||||
} else {
|
||||
throw new RuntimeException("candidate cannot be null");
|
||||
}
|
||||
}
|
||||
CraftResultInventory resultCandidate = null;
|
||||
IInventory mainCandidate = null;
|
||||
for (IInventory inventory : set) {
|
||||
if (inventory instanceof CraftResultInventory) {
|
||||
resultCandidate = (CraftResultInventory) inventory;
|
||||
} else {
|
||||
mainCandidate = inventory;
|
||||
}
|
||||
}
|
||||
Inventory inv;
|
||||
if (mainCandidate == null && resultCandidate != null) {
|
||||
mainCandidate = resultCandidate;
|
||||
resultCandidate = null;
|
||||
}
|
||||
if (mainCandidate != null) {
|
||||
if (resultCandidate != null) {
|
||||
inv = new org.bukkit.craftbukkit.v.inventory.CraftResultInventory(mainCandidate, resultCandidate);
|
||||
} else {
|
||||
inv = new CraftInventory(mainCandidate);
|
||||
}
|
||||
} else { // container has no slots
|
||||
inv = new CraftInventoryCustom(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), 0);
|
||||
}
|
||||
bukkitView = new CraftInventoryView(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), inv, (Container) (Object) this);
|
||||
}
|
||||
return bukkitView;
|
||||
}
|
||||
|
||||
public void transferTo(Container other, CraftHumanEntity player) {
|
||||
InventoryView source = this.getBukkitView();
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.izzel.arclight.common.mod.util;
|
|||
import io.izzel.arclight.common.mod.ArclightConstants;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
|
@ -180,6 +181,20 @@ public class ArclightCaptures {
|
|||
}
|
||||
}
|
||||
|
||||
private static transient PlayerEntity containerOwner;
|
||||
|
||||
public static void captureContainerOwner(PlayerEntity entity) {
|
||||
containerOwner = entity;
|
||||
}
|
||||
|
||||
public static PlayerEntity getContainerOwner() {
|
||||
return containerOwner;
|
||||
}
|
||||
|
||||
public static void resetContainerOwner() {
|
||||
containerOwner = null;
|
||||
}
|
||||
|
||||
private static void recapture(String type) {
|
||||
throw new IllegalStateException("Recapturing " + type);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"CraftConsoleCommandSenderMixin",
|
||||
"CraftEntityMixin",
|
||||
"CraftEventFactoryMixin",
|
||||
"CraftInventoryMixin",
|
||||
"CraftItemFactoryMixin",
|
||||
"CraftMagicNumbersMixin",
|
||||
"CraftServerMixin",
|
||||
|
|
|
@ -115,6 +115,7 @@ jar {
|
|||
|
||||
remapSpigotJar {
|
||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||
}
|
||||
|
||||
mixin {
|
||||
|
|
|
@ -115,6 +115,7 @@ jar {
|
|||
|
||||
remapSpigotJar {
|
||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||
}
|
||||
|
||||
mixin {
|
||||
|
|
Loading…
Reference in New Issue
Block a user