Tentatively reintroduce a container-opening system

This commit is contained in:
Vincent Lee 2019-02-07 20:31:17 -06:00
parent 065ebd748a
commit 153e7a1806
5 changed files with 106 additions and 1 deletions

View File

@ -500,7 +500,7 @@
if (this.func_70608_bn()) {
f = 0.2F;
} else if (!this.func_203007_ba() && !this.func_184613_cA() && this.field_70131_O != 0.6F) {
@@ -1967,6 +2096,30 @@
@@ -1967,6 +2096,41 @@
return this.field_71075_bZ.field_75098_d && this.func_184840_I() >= 2;
}
@ -527,6 +527,17 @@
+ public Collection<ITextComponent> getSuffixes() {
+ return this.suffixes;
+ }
+
+ /**
+ * Opens a modded container, based on {@code container.getGuiID}
+ * Container.getGuiID must return a valid ResourceLocation in String form. Vanilla follows this, but does not enforce it.
+ * @param container The container provider. The container will be obtained using {@link IInteractionObject#createContainer}.
+ * @param extraData Any extra data to communicate to the client
+ */
+ public void openGui(IInteractionObject container, @Nullable io.netty.buffer.ByteBuf extraData)
+ {
+ if (!field_70170_p.field_72995_K) net.minecraftforge.fml.network.NetworkHooks.openGui((EntityPlayerMP) this, container, extraData);
+ }
+
public static enum EnumChatVisibility {
FULL(0, "options.chat.visibility.full"),

View File

@ -33,5 +33,6 @@ public class FMLPlayHandler
static
{
channel.registerMessage(0, FMLPlayMessages.SpawnEntity.class, FMLPlayMessages.SpawnEntity::encode, FMLPlayMessages.SpawnEntity::decode, FMLPlayMessages.SpawnEntity::handle);
channel.registerMessage(1, FMLPlayMessages.OpenContainer.class, FMLPlayMessages.OpenContainer::encode, FMLPlayMessages.OpenContainer::decode, FMLPlayMessages.OpenContainer::handle);
}
}

View File

@ -19,15 +19,20 @@
package net.minecraftforge.fml.network;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityTracker;
import net.minecraft.entity.EntityType;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;
public class FMLPlayMessages
@ -156,4 +161,45 @@ public class FMLPlayMessages
ctx.get().setPacketHandled(true);
}
}
public static class OpenContainer
{
private final ResourceLocation id;
private final int windowId;
private final byte[] additionalData;
public OpenContainer(ResourceLocation id, int windowId, byte[] additionalData)
{
this.id = id;
this.windowId = windowId;
this.additionalData = additionalData;
}
public static void encode(OpenContainer msg, PacketBuffer buf)
{
buf.writeResourceLocation(msg.id);
buf.writeVarInt(msg.windowId);
buf.writeByteArray(msg.additionalData);
}
public static OpenContainer decode(PacketBuffer buf)
{
return new OpenContainer(buf.readResourceLocation(), buf.readVarInt(), buf.readByteArray());
}
public static void handle(OpenContainer msg, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
Supplier<Function<ByteBuf, GuiScreen>> sup = NetworkRegistry.guiHandlers.get(msg.id);
if (sup != null) {
GuiScreen gui = sup.get().apply(Unpooled.wrappedBuffer(msg.additionalData));
if (gui != null) {
Minecraft.getInstance().displayGuiScreen(gui);
Minecraft.getInstance().player.openContainer.windowId = msg.windowId;
}
}
});
ctx.get().setPacketHandled(true);
}
}
}

View File

@ -19,15 +19,21 @@
package net.minecraftforge.fml.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.handshake.client.CPacketHandshake;
import net.minecraft.server.network.NetHandlerLoginServer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IInteractionObject;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import javax.annotation.Nullable;
import java.util.Objects;
public class NetworkHooks
@ -80,4 +86,26 @@ public class NetworkHooks
{
return FMLHandshakeHandler.tickLogin(networkManager);
}
public static void openGui(EntityPlayerMP player, IInteractionObject container, @Nullable ByteBuf extraData)
{
ResourceLocation id = new ResourceLocation(container.getGuiID());
Container c = container.createContainer(player.inventory, player);
player.closeScreen();
player.getNextWindowId();
player.openContainer = c;
player.openContainer.windowId = player.currentWindowId;
player.openContainer.addListener(player);
MinecraftForge.EVENT_BUS.post(new PlayerContainerEvent.Open(player, c));
byte[] additional;
if (extraData == null) {
additional = new byte[0];
} else {
additional = new byte[extraData.readableBytes()];
extraData.readBytes(additional);
}
FMLPlayMessages.OpenContainer msg = new FMLPlayMessages.OpenContainer(id, player.currentWindowId, additional);
FMLPlayHandler.channel.sendTo(msg, player.connection.getNetworkManager(), NetworkDirection.PLAY_TO_CLIENT);
}
}

View File

@ -19,6 +19,8 @@
package net.minecraftforge.fml.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
@ -33,7 +35,9 @@ import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@ -47,6 +51,21 @@ public class NetworkRegistry
private static final Marker NETREGISTRY = MarkerManager.getMarker("NETREGISTRY");
private static Map<ResourceLocation, NetworkInstance> instances = new HashMap<>();
static final Map<ResourceLocation, Supplier<Function<ByteBuf, GuiScreen>>> guiHandlers = new ConcurrentHashMap<>();
/**
* Registers a client-side GUI handler for the given ID.
* The function takes any extra data provided to {@link net.minecraft.entity.player.EntityPlayer#openGui}
* and returns a {@link GuiScreen} to display.
* Call this during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}.
* This method is safe to call in parallel mod loading
* @param id
* @param handler
*/
public static void registerGui(ResourceLocation id, Supplier<Function<ByteBuf, GuiScreen>> handler)
{
guiHandlers.put(id, handler);
}
/**
* Special value for clientAcceptedVersions and serverAcceptedVersions predicates indicating the other side lacks