Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.4] How i can make a own inventory


Klarks
 Share

Recommended Posts

I found the ivent that calls by key pressing

@SubscribeEvent (priority = EventPriority.LOWEST)
public static void onClientTick(TickEvent.ClientTickEvent event) throws Exception {
    if(KEYBIND_ARRAY == null){
        KEYBIND_ARRAY = KeyBinding.class.getDeclaredField("KEYBIND_ARRAY");
        KEYBIND_ARRAY.setAccessible(true);
    }
    if(event.phase.equals(TickEvent.Phase.END)){
        Map<String, KeyBinding> binds = (Map<String, KeyBinding>) KEYBIND_ARRAY.get(null);
        for (String bind : binds.keySet()) {
            if(binds.get(bind).isKeyDown() && (binds.get(bind) == TEST)){
                System.out.println("R");
                break;
            }
        }
    }
}

But i dont understend how i need to code the Container for this and open the gui by press.  

 

My Screen class
 

public class NewInvScreen extends ContainerScreen<NewInvContainer> {
    private ResourceLocation GUI = new ResourceLocation(Main.MODID,"textures/gui/new_inv.png");

    public NewInvScreen( PlayerInventory inv, ITextComponent titleIn) {
        super(null, inv, new TranslationTextComponent("containers.hen.inv"));
    }

    @Override
    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
        this.renderBackground(matrixStack);
        //this.playerInventoryTitleX = 10;
        // this.playerInventoryTitleY = 42;
        super.render(matrixStack, mouseX, mouseY, partialTicks);
        this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
    }
    @Override
    protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) {
        RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.minecraft.getTextureManager().bindTexture(GUI);
        int i = (this.width - this.xSize) / 2;
        int j = (this.height - this.ySize) / 2;
        this.blit(matrixStack, i, j, 0, 0, this.xSize, this.ySize);
    }

    @Override

    protected void drawGuiContainerForegroundLayer(MatrixStack matrixStack, int x, int y) {

        this.font.func_243248_b(matrixStack, this.title, (float)10, (float)this.titleY, 4210752);
        this.font.func_243248_b(matrixStack, this.playerInventory.getDisplayName(), (float)10, (float)42, 4210752);
    }
}

 

Container Class
 

public class NewInvContainer extends Container {

    private  IItemHandler playerInventory;


    protected NewInvContainer( int id, PlayerInventory playerInventory) {
        super(NEWINV_CONTAINER.get(), id);

        this.playerInventory = new InvWrapper(playerInventory);
        playerInventory.player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(h -> {

            addSlot(new SlotItemHandler(h,0,79,18));
        });
        layoutPlayerInventory(7,54);
    }


    private int addSlotRange(IItemHandler handler, int index, int x, int y, int amount, int dx)
    {
        for(int i = 0; i < amount;i++)
        {
            addSlot(new SlotItemHandler(handler,index,x,y));
            x+=dx;
            index++;
        }
        return index;
    }

    private int addSlotBox(IItemHandler handler,int index,int x,int y,int horAmount,int dx,int verAmount,int dy)
    {
        for (int j = 0;j<verAmount;j++)
        {
            index = addSlotRange(handler,index,x,y,horAmount,dx);
            y+=dy;
        }
        return index;
    }

    private void layoutPlayerInventory(int leftCol, int topRow)
    {
        addSlotBox(playerInventory,9,leftCol,topRow,9,18,3,18);
        topRow += 58;
        addSlotRange(playerInventory,0,leftCol,topRow,9,18);
    }

    @Override
    public boolean canInteractWith(PlayerEntity playerIn) {
        return true;
    }
}

 

 

Screen Manger Registry

@Mod.EventBusSubscriber(modid = Main.MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class ClientEventBusSubscriber {
    public static final KeyBinding TEST = new KeyBinding("key.structure.desc", GLFW.GLFW_KEY_R, "key.magicbeans.category");
    private static Field KEYBIND_ARRAY = null;

    @SubscribeEvent
    public static void clientSetup(FMLClientSetupEvent event) {

       
        ScreenManager.registerFactory(RegObj.NEWINV_CONTAINER.get(),NewInvScreen::new);
        ClientRegistry.registerKeyBinding(TEST);
    }

}

 

Registry 

public class RegObj {
   
    public static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, Main.MODID);

    public static final RegistryObject<ContainerType<NewInvContainer>> NEWINV_CONTAINER = CONTAINERS.register("newinv", () -> IForgeContainerType.create((windowId, inv,data) -> {
        World world = inv.player.getEntityWorld();
        return  new NewInvContainer(windowId,inv);
            }));


//Minecraft.getInstance().player








}

 

Main

@Mod(Main.MODID)
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class Main {

    public static final String MODID = "mymod";

    public Main() {

        IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        RegObj.CONTAINERS.register(bus);


    }

  

}
Link to comment
Share on other sites

Why are you still doing that strange reflection stuff with the key bindings? You already have your KeyBinding stored in a field. Just use it!

Opening a container GUI is a server-side operation, as such you need to send a packet to the server to open the inventory.

 

However - do you really need a custom container? If you simply want a different layout you can leave the container alone and simply replace the ContainerScreen.

Link to comment
Share on other sites

18 hours ago, Klarks said:

 


@SubscribeEvent (priority = EventPriority.LOWEST)
public static void onClientTick(TickEvent.ClientTickEvent event) throws Exception {
    if(KEYBIND_ARRAY == null){
        KEYBIND_ARRAY = KeyBinding.class.getDeclaredField("KEYBIND_ARRAY");
        KEYBIND_ARRAY.setAccessible(true);
    }
    if(event.phase.equals(TickEvent.Phase.END)){
        Map<String, KeyBinding> binds = (Map<String, KeyBinding>) KEYBIND_ARRAY.get(null);
        for (String bind : binds.keySet()) {
            if(binds.get(bind).isKeyDown() && (binds.get(bind) == TEST)){
                System.out.println("R");
                break;
            }
        }
    }
}

 

All this can be replaced with

@SubscribeEvent (priority = EventPriority.LOWEST)
public static void onClientTick(TickEvent.ClientTickEvent event) throws Exception {
    if(event.phase.equals(TickEvent.Phase.END)){
        if(TEST.isKeyDown()){
            System.out.println("R");
        }
    }
}

 

Link to comment
Share on other sites

Should i use it like this?

@SubscribeEvent (priority = EventPriority.LOWEST)
public static void onClientTick(TickEvent.ClientTickEvent event) throws Exception {
    if(event.phase.equals(TickEvent.Phase.END)){
       World world = Minecraft.getInstance().world;
        PlayerEntity player = Minecraft.getInstance().player;
        if(TEST.isKeyDown()){
            if(!world.isRemote)
            {
                    NetworkHooks.openGui((ServerPlayerEntity) player,(INamedContainerProvider) );
            }
        }
    }
}
Link to comment
Share on other sites

i made what i needed but only as a command. But i cant understand how i can open it on key press. What i should send to the server for it to open

@Override
public int run(CommandContext<CommandSource> context) throws CommandSyntaxException {
    ServerPlayerEntity player = context.getSource().asPlayer();
    Networking.sendToClient(new PacketOpenGui(), player);
    return 0;
}


My Networking class
 

public class Networking {
   public static SimpleChannel INSTANCE;
   private static int ID;

   public static int nextID() {return ID++;}

   public static void RegMes()
   {
       INSTANCE = NetworkRegistry.newSimpleChannel(new ResourceLocation(Main.MODID,"netw"),() -> "1",s -> true,s -> true);

       INSTANCE.messageBuilder(PacketOpenGui.class, nextID())
               .encoder((packetOpenGui, packetBuffer) -> {})
               .decoder(buf -> new PacketOpenGui())
               .consumer(PacketOpenGui::handle)
               .add();
       INSTANCE.messageBuilder(PacketSpawn.class, nextID())
               .encoder(PacketSpawn::toBytes)
               .decoder(PacketSpawn::new)
               .consumer(PacketSpawn::handle)
               .add();
   }

    public static void sendToClient(Object packet, ServerPlayerEntity player) {
        INSTANCE.sendTo(packet, player.connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
    }

    public static void sendToServer(Object packet) {
        INSTANCE.sendToServer(packet);
    }

}
Link to comment
Share on other sites

I have questioned similar things for years as to how to know when a player is pressing the q key.

 

A tossed thing is an object. A thrown thing could be anything such as a rock that way or a flying projectile.

 

if this.objectIsTossed

if this.objectIsThrown

 

Both are pretty good though, for sure. But, yeah.

Edited by Guru
Link to comment
Share on other sites

33 minutes ago, Klarks said:

Yes I have the method but I dont know how to use it properly and what i should sent to the server. 

 

Your packet, and then you can call NetworkHooks#openGui in PacketSpawn::handle when you have received the packet

 

1 hour ago, Klarks said:

 



       INSTANCE.messageBuilder(PacketSpawn.class, nextID())
               .encoder(PacketSpawn::toBytes)
               .decoder(PacketSpawn::new)
               .consumer(PacketSpawn::handle)

 

Link to comment
Share on other sites

its working but did i do this right? 

Send the packet to the server if key r is pressed.

@Mod.EventBusSubscriber(modid = Main.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ForgeHelperMod {
    public static final KeyBinding TEST = new KeyBinding("key.structure.desc", GLFW.GLFW_KEY_R, "key.magicbeans.category");
    private static Field KEYBIND_ARRAY = null;


    @SubscribeEvent
    public static void serverLoad(RegisterCommandsEvent event) {
        ModCommands.register(event.getDispatcher());
    }

    @SubscribeEvent (priority = EventPriority.LOWEST)
    public static void onClientTick(TickEvent.ClientTickEvent event) throws Exception {
        if(event.phase.equals(TickEvent.Phase.END)){
           World world = Minecraft.getInstance().world;
            PlayerEntity player = Minecraft.getInstance().player;
            if(TEST.isKeyDown()){
                System.out.println("R");
Networking.sendToServer(new IfKeyPresed());

            }
        }
    }

}

 

Packet itself. It sends the packet to the client  for gui open.

public class IfKeyPresed {

    public void handle (Supplier<NetworkEvent.Context> ctx)
    {
        ServerPlayerEntity player = ctx.get().getSender();
        ctx.get().enqueueWork(() ->
        {
            Networking.sendToClient(new PacketOpenGui(), player);
        });
        ctx.get().setPacketHandled(true);
    }
}

 

Gui open packet

public class PacketOpenGui {


    public void handle (Supplier<NetworkEvent.Context> ctx)
    {
        ctx.get().enqueueWork(NewInvScreen::open);
        ctx.get().setPacketHandled(true);
    }
}

 

And open method from Screen
 

public static void open() {
    Minecraft.getInstance().displayGuiScreen(new NewInvScreen());
}

 

Is it correct? And also in single player when i press r to open the gui, it opens but for some reason it pause the game but on server it didn't

Link to comment
Share on other sites

You are now making an unnecessary network round-trip. If you just call displayGuiScreen to display a normal screen, you can do that directly from the key handler.

You only need to open container-based GUIs on the server, using NetworkHooks.openGui.

 

2 minutes ago, Klarks said:

And also in single player when i press r to open the gui, it opens but for some reason it pause the game but on server it didn't

Of course a server game never gets paused (because the server doesn't pause). Override Screen#isPauseScreen to control this behavior in single player.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.