Add IContainerFactory for reading custom container data on the client

This commit is contained in:
tterrag 2019-06-10 18:14:09 -04:00
parent 5dc944c1c3
commit d5ee80a70a
6 changed files with 117 additions and 9 deletions

View File

@ -0,0 +1,25 @@
--- a/net/minecraft/client/gui/ScreenManager.java
+++ b/net/minecraft/client/gui/ScreenManager.java
@@ -39,6 +39,10 @@
private static final Map<ContainerType<?>, ScreenManager.IScreenFactory<?, ?>> field_216914_b = Maps.newHashMap();
public static <T extends Container> void func_216909_a(@Nullable ContainerType<T> p_216909_0_, Minecraft p_216909_1_, int p_216909_2_, ITextComponent p_216909_3_) {
+ getScreenFactory(p_216909_0_, p_216909_1_, p_216909_2_, p_216909_3_).ifPresent(f -> f.func_216908_a(p_216909_3_, p_216909_0_, p_216909_1_, p_216909_2_));
+ }
+
+ public static <T extends Container> java.util.Optional<IScreenFactory<T, ?>> getScreenFactory(@Nullable ContainerType<T> p_216909_0_, Minecraft p_216909_1_, int p_216909_2_, ITextComponent p_216909_3_) {
if (p_216909_0_ == null) {
field_216913_a.warn("Trying to open invalid screen with name: {}", (Object)p_216909_3_.getString());
} else {
@@ -46,9 +50,10 @@
if (iscreenfactory == null) {
field_216913_a.warn("Failed to create screen for menu type: {}", (Object)Registry.field_218366_G.func_177774_c(p_216909_0_));
} else {
- iscreenfactory.func_216908_a(p_216909_3_, p_216909_0_, p_216909_1_, p_216909_2_);
+ return java.util.Optional.of(iscreenfactory);
}
}
+ return java.util.Optional.empty();
}
@Nullable

View File

@ -5,7 +5,22 @@
import net.minecraftforge.api.distmarker.OnlyIn;
-public class ContainerType<T extends Container> {
+public class ContainerType<T extends Container> extends net.minecraftforge.registries.ForgeRegistryEntry<ContainerType<?>> {
+public class ContainerType<T extends Container> extends net.minecraftforge.registries.ForgeRegistryEntry<ContainerType<?>> implements net.minecraftforge.common.extensions.IForgeContainerType<T> {
public static final ContainerType<ChestContainer> field_221507_a = func_221505_a("generic_9x1", ChestContainer::func_216986_a);
public static final ContainerType<ChestContainer> field_221508_b = func_221505_a("generic_9x2", ChestContainer::func_216987_b);
public static final ContainerType<ChestContainer> field_221509_c = func_221505_a("generic_9x3", ChestContainer::func_216988_c);
@@ -45,6 +45,14 @@
public T func_221506_a(int p_221506_1_, PlayerInventory p_221506_2_) {
return this.field_221530_x.create(p_221506_1_, p_221506_2_);
}
+
+ @Override
+ public T create(int windowId, PlayerInventory playerInv, net.minecraft.network.PacketBuffer extraData) {
+ if (this.field_221530_x instanceof net.minecraftforge.fml.network.IContainerFactory) {
+ return ((net.minecraftforge.fml.network.IContainerFactory<T>) this.field_221530_x).create(windowId, playerInv, extraData);
+ }
+ return func_221506_a(windowId, playerInv);
+ }
public interface IFactory<T extends Container> {
@OnlyIn(Dist.CLIENT)

View File

@ -0,0 +1,16 @@
package net.minecraftforge.common.extensions;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer;
public interface IForgeContainerType<T>
{
static <T extends Container> ContainerType<T> create(net.minecraftforge.fml.network.IContainerFactory<T> factory)
{
return new ContainerType<>(factory);
}
T create(int windowId, PlayerInventory playerInv, PacketBuffer extraData);
}

View File

@ -21,11 +21,13 @@ package net.minecraftforge.fml.network;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IHasContainer;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation;
@ -208,8 +210,14 @@ public class FMLPlayMessages
public static void handle(OpenContainer msg, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
// TODO extend IScreenFactory to allow for extra data
ScreenManager.openScreen(msg.getType(), Minecraft.getInstance(), msg.getWindowId(), msg.getName());
ScreenManager.getScreenFactory(msg.getType(), Minecraft.getInstance(), msg.getWindowId(), msg.getName())
.ifPresent(f -> {
Container c = msg.getType().create(msg.getWindowId(), Minecraft.getInstance().player.inventory, msg.getAdditionalData());
@SuppressWarnings("unchecked")
Screen s = ((ScreenManager.IScreenFactory<Container, ?>)f).create(c, Minecraft.getInstance().player.inventory, msg.getName());
Minecraft.getInstance().player.openContainer = ((IHasContainer<?>)s).getContainer();
Minecraft.getInstance().displayGuiScreen(s);
});
});
ctx.get().setPacketHandled(true);
}

View File

@ -0,0 +1,17 @@
package net.minecraftforge.fml.network;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer;
public interface IContainerFactory<T extends Container> extends ContainerType.IFactory<T>
{
T create(int windowId, PlayerInventory inv, PacketBuffer data);
@Override
default T create(int p_create_1_, PlayerInventory p_create_2_)
{
return create(p_create_1_, p_create_2_, null);
}
}

View File

@ -24,18 +24,26 @@ import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Hand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.registries.ObjectHolder;
@Mod("containertypetest")
@ -45,9 +53,21 @@ public class ContainerTypeTest
public static final ContainerType<TestContainer> TYPE = null;
public class TestContainer extends Container
{
protected TestContainer(int windowId, PlayerInventory inv)
private final String text;
protected TestContainer(int windowId, PlayerInventory playerInv, PacketBuffer extraData)
{
this(windowId, new Inventory(9), extraData.readString(128));
}
public TestContainer(int windowId, Inventory inv, String text)
{
super(TYPE, windowId);
this.text = text;
for (int i = 0; i < 9; i++)
{
this.addSlot(new Slot(inv, i, (i % 3) * 18, (i / 3) * 18));
}
}
@Override
@ -67,7 +87,7 @@ public class ContainerTypeTest
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
drawString(this.font, "Hello World!", mouseX, mouseY, -1);
drawString(this.font, getContainer().text, mouseX, mouseY, -1);
}
}
@ -80,7 +100,7 @@ public class ContainerTypeTest
private void registerContainers(final RegistryEvent.Register<ContainerType<?>> event)
{
event.getRegistry().register(new ContainerType<TestContainer>(TestContainer::new).setRegistryName("container"));
event.getRegistry().register(IForgeContainerType.create(TestContainer::new).setRegistryName("container"));
}
private void setup(FMLClientSetupEvent event)
@ -94,13 +114,18 @@ public class ContainerTypeTest
{
if (event.getWorld().getBlockState(event.getPos()).getBlock() == Blocks.SPONGE)
{
event.getEntityPlayer().openContainer(new INamedContainerProvider()
String text = "Hello World!";
NetworkHooks.openGui((ServerPlayerEntity) event.getEntityPlayer(), new INamedContainerProvider()
{
@Override
public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_)
{
return TYPE.func_221506_a(p_createMenu_1_, p_createMenu_2_);
Inventory inv = new Inventory(9);
for (int i = 0; i < inv.getSizeInventory(); i++)
{
inv.setInventorySlotContents(i, new ItemStack(Items.DIAMOND));
}
return new TestContainer(p_createMenu_1_, inv, text);
}
@Override
@ -108,6 +133,8 @@ public class ContainerTypeTest
{
return new StringTextComponent("Test");
}
}, extraData -> {
extraData.writeString(text);
});
}
}