Jump to content

Creating a custom workbench


winnetrie

Recommended Posts

I want for example to create a birch workbench. What do i need to do to make this work?

This i think i need:

-guihandler class

-guicontainer

-container class

-block class

I have these 4 made, but it isn't working right now. I also haven't found out where or how to add textures to the block. I guess it's not via .json blockstates!

So the block is there ingame (pink/black squared for the moment) when right clicking you see a flashing of the gui. It looks like it is opening and closing almost instantly.

 

guihandler:

Spoiler

public class ModGuiHandler implements IGuiHandler{
	
	public static final int MOD_WORKBENCH_GUI = 0;

	@Override
	public Object getServerGuiElement(int ID, EntityPlayer player, World world,
			int x, int y, int z) {
		switch (ID){
		case MOD_WORKBENCH_GUI: {
			return new EntityWorkbench(player.inventory, world, new BlockPos(x, y, z));
			}
		
		}
		
		return null;
	}

	@Override
	public Object getClientGuiElement(int ID, EntityPlayer player, World world,
			int x, int y, int z) {
		switch (ID){
		case MOD_WORKBENCH_GUI: {
			return new ModGuiCrafting(player.inventory, world);
			}
		}
		
		return null;
	}

}

 

container:

Spoiler

public class ModContainerWorkbench extends Container{
	
	/** The crafting matrix inventory (3x3). */
    public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3);
    public IInventory craftResult = new InventoryCraftResult();
    private final World world;
    /** Position of the workbench */
    private final BlockPos pos;

    public ModContainerWorkbench(InventoryPlayer playerInventory, World worldIn, BlockPos posIn)
    {
        this.world = worldIn;
        this.pos = posIn;
        this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35));

        for (int i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 3; ++j)
            {
                this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18));
            }
        }

        for (int k = 0; k < 3; ++k)
        {
            for (int i1 = 0; i1 < 9; ++i1)
            {
                this.addSlotToContainer(new Slot(playerInventory, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18));
            }
        }

        for (int l = 0; l < 9; ++l)
        {
            this.addSlotToContainer(new Slot(playerInventory, l, 8 + l * 18, 142));
        }

        this.onCraftMatrixChanged(this.craftMatrix);
    }

    /**
     * Callback for when the crafting matrix is changed.
     */
    public void onCraftMatrixChanged(IInventory inventoryIn)
    {
        this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.world));
    }

    /**
     * Called when the container is closed.
     */
    public void onContainerClosed(EntityPlayer playerIn)
    {
        super.onContainerClosed(playerIn);

        if (!this.world.isRemote)
        {
            for (int i = 0; i < 9; ++i)
            {
                ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i);

                if (!itemstack.isEmpty())
                {
                    playerIn.dropItem(itemstack, false);
                }
            }
        }
    }

    /**
     * Determines whether supplied player can use this container
     */
    public boolean canInteractWith(EntityPlayer playerIn)
    {
    	
        return this.world.getBlockState(this.pos).getBlock() != Blocks.CRAFTING_TABLE ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
    }

    /**
     * Take a stack from the specified inventory slot.
     */
    public ItemStack transferStackInSlot(EntityPlayer playerIn, int index)
    {
        ItemStack itemstack = ItemStack.EMPTY;
        Slot slot = (Slot)this.inventorySlots.get(index);

        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (index == 0)
            {
                itemstack1.getItem().onCreated(itemstack1, this.world, playerIn);

                if (!this.mergeItemStack(itemstack1, 10, 46, true))
                {
                    return ItemStack.EMPTY;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }
            else if (index >= 10 && index < 37)
            {
                if (!this.mergeItemStack(itemstack1, 37, 46, false))
                {
                    return ItemStack.EMPTY;
                }
            }
            else if (index >= 37 && index < 46)
            {
                if (!this.mergeItemStack(itemstack1, 10, 37, false))
                {
                    return ItemStack.EMPTY;
                }
            }
            else if (!this.mergeItemStack(itemstack1, 10, 46, false))
            {
                return ItemStack.EMPTY;
            }

            if (itemstack1.isEmpty())
            {
                slot.putStack(ItemStack.EMPTY);
            }
            else
            {
                slot.onSlotChanged();
            }

            if (itemstack1.getCount() == itemstack.getCount())
            {
                return ItemStack.EMPTY;
            }

            ItemStack itemstack2 = slot.onTake(playerIn, itemstack1);

            if (index == 0)
            {
                playerIn.dropItem(itemstack2, false);
            }
        }

        return itemstack;
    }

    /**
     * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in
     * is null for the initial slot that was double-clicked.
     */
    public boolean canMergeSlot(ItemStack stack, Slot slotIn)
    {
        return slotIn.inventory != this.craftResult && super.canMergeSlot(stack, slotIn);
    }

}

 

guicontainer:

Spoiler

@SideOnly(Side.CLIENT)
public class ModGuiCrafting extends GuiContainer
{
    private static final ResourceLocation CRAFTING_TABLE_GUI_TEXTURES = new ResourceLocation("minecraft:textures/gui/container/crafting_table.png");

    public ModGuiCrafting(InventoryPlayer playerInv, World worldIn)
    {
        this(playerInv, worldIn, BlockPos.ORIGIN);
    }

    public ModGuiCrafting(InventoryPlayer playerInv, World worldIn, BlockPos blockPosition)
    {
        super(new ModContainerWorkbench(playerInv, worldIn, blockPosition));
    }

    /**
     * Draw the foreground layer for the GuiContainer (everything in front of the items)
     */
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
    {
        this.fontRendererObj.drawString(I18n.format("container.crafting", new Object[0]), 28, 6, 4210752);
        this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 2, 4210752);
    }

    /**
     * Draws the background layer of this container (behind the items).
     */
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
    {
        GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(CRAFTING_TABLE_GUI_TEXTURES);
        int i = (this.width - this.xSize) / 2;
        int j = (this.height - this.ySize) / 2;
        this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
    }
}

 

and the block:

Spoiler

public class BlockModWorkbench extends Block{

	public BlockModWorkbench(Material materialIn) {
		super(materialIn);
		setUnlocalizedName("test_bench");
		setRegistryName("test_bench");
		
	}
	
	 public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
	    {
	        if (worldIn.isRemote)
	        {
	            return true;
	        }
	        else
	        {
	            playerIn.displayGui(new BlockWorkbench.InterfaceCraftingTable(worldIn, pos));
	            playerIn.addStat(StatList.CRAFTING_TABLE_INTERACTION);
	            return true;
	        }
	    }

	    public static class InterfaceCraftingTable implements IInteractionObject
	        {
	            private final World world;
	            private final BlockPos position;

	            public InterfaceCraftingTable(World worldIn, BlockPos pos)
	            {
	                this.world = worldIn;
	                this.position = pos;
	            }

	            /**
	             * Get the name of this object. For players this returns their username
	             */
	            public String getName()
	            {
	                return "crafting_table";
	            }

	            /**
	             * Returns true if this thing is named
	             */
	            public boolean hasCustomName()
	            {
	                return false;
	            }

	            /**
	             * Get the formatted ChatComponent that will be used for the sender's username in chat
	             */
	            public ITextComponent getDisplayName()
	            {
	                return new TextComponentTranslation(Blocks.CRAFTING_TABLE.getUnlocalizedName() + ".name", new Object[0]);
	            }

	            public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
	            {
	                return new ModContainerWorkbench(playerInventory, this.world, this.position);
	            }

	            public String getGuiID()
	            {
	                return "minecraft:crafting_table";
	            }
	        }

}

 

 

Link to comment
Share on other sites

Quote

I have these 4 made, but it isn't working right now. I also haven't found out where or how to add textures to the block. I guess it's not via .json blockstates!

Yes it is! Take a look at the forge blockstate docs.

23 minutes ago, winnetrie said:

case MOD_WORKBENCH_GUI: { 
  return new EntityWorkbench(player.inventory, world, new BlockPos(x, y, z));
}

 

What is EntityWorkbench? You should return your Container in this method.

23 minutes ago, winnetrie said:

playerIn.displayGui(new BlockWorkbench.InterfaceCraftingTable(worldIn, pos));

This is the vanilla method which doesn't refer to your GuiHandler at all. You need to use player#openGui(Object modInstance, int guiID, World world, int x, int y, int z). That will call the appropriate-side methods from your GUI handler to get the correct container/GUI.

Edited by Jay Avery
Link to comment
Share on other sites

Ah yes ofc i changed it to

playerIn.openGui(Tem.instance, ModGuiHandler.MOD_WORKBENCH_GUI, worldIn, pos.getX(), pos.getY(), pos.getZ());

Works fine now!

Where and how do i apply textures to the block now?

Edited by winnetrie
nvm i didn't find an workbench.json in the minecraft blockstates before, but it appears to be called craftingtable.....
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • my arrow wont move at all it would stay mid air and show no collision   my Entity class: package net.jeezedboi.epicraft.entity.custom; import net.jeezedboi.epicraft.init.ModItems; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.projectile.AbstractArrowEntity; import net.minecraft.item.ItemStack; import net.minecraft.network.IPacket; import net.minecraft.util.math.EntityRayTraceResult; import net.minecraft.world.Explosion; import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkHooks; public class ExplosiveArrowEntity extends AbstractArrowEntity { // default constructor, required to register the entity public ExplosiveArrowEntity(EntityType<ExplosiveArrowEntity> entityType, World world) { super(entityType, world); } public ExplosiveArrowEntity(EntityType<ExplosiveArrowEntity> entityType, double x, double y, double z, World world) { super(entityType, x, y, z, world); } // the constructor used by the ArrowItem public ExplosiveArrowEntity(EntityType<ExplosiveArrowEntity> entityType, LivingEntity shooter, World world) { super(entityType, shooter, world); } // the item stack to give the player when they walk over your arrow stuck in the ground @Override protected ItemStack getArrowStack() { return new ItemStack(ModItems.EXPLOSIVE_ARROW.get()); } @Override protected void onEntityHit(EntityRayTraceResult result) { super.onEntityHit(result); // this, x, y, z, explosionStrength, setsFires, breakMode (NONE, BREAK, DESTROY) this.world.createExplosion(this, this.getPosX(), this.getPosY(), this.getPosZ(), 4.0f, true, Explosion.Mode.BREAK); } // called each tick while in the ground @Override public void tick() { if (this.timeInGround > 60){ this.world.createExplosion(this, this.getPosX(), this.getPosY(), this.getPosZ(), 4.0f, true, Explosion.Mode.BREAK); this.remove(); } } // syncs to the client @Override public IPacket<?> createSpawnPacket() { return NetworkHooks.getEntitySpawningPacket(this); } } my item class :   package net.jeezedboi.epicraft.item.custom; import net.jeezedboi.epicraft.entity.custom.ExplosiveArrowEntity; import net.jeezedboi.epicraft.init.ModEntityTypes; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.projectile.AbstractArrowEntity; import net.minecraft.item.ArrowItem; import net.minecraft.item.ItemStack; import net.minecraft.world.World; public class ExplosiveArrowItem extends ArrowItem { public ExplosiveArrowItem(Properties props) { super(props); } @Override public AbstractArrowEntity createArrow(World world, ItemStack ammoStack, LivingEntity shooter) { ExplosiveArrowEntity explosiveArrowEntity = new ExplosiveArrowEntity(ModEntityTypes.EXPLOSIVE_ARROW.get(), shooter, world); return explosiveArrowEntity; } } other stuffs: public static final RegistryObject<Item> EXPLOSIVE_ARROW = ITEMS.register("explosive_arrow", () -> new ExplosiveArrowItem(new Item.Properties().group(ModItemGroup.Epic_Items))); public static final RegistryObject<EntityType<ExplosiveArrowEntity>> EXPLOSIVE_ARROW = ENTITY_TYPES.register("explosive_arrow", () -> EntityType.Builder.create((EntityType.IFactory<ExplosiveArrowEntity>) ExplosiveArrowEntity::new, EntityClassification.MISC) .size(0.5F, 0.5F).build("explosive_arrow")); mappings channel: 'snapshot', version: '20210309-1.16.5'
    • may i ask what it was that fixed it, I'm having the same problem and its frustrating because I'm making an origin.
    • I need to accesses byPath field of net.minecraft.client.renderer.texture.TextureManager. As I found out I need to use accesstransformer.cfg file and make the field public via it. In this file field names look like f_<numbers>. And I was unable to figure out, how to get those. It seems like it is connected to something called mappings (thing left after Minecraft decompile process). How can I get such a name for a class field?
    • The game crashed whilst rendering overlay Error: java.lang.OutOfMemoryError: Java heap space Exit Code: -1   Crash Report:                                              Log: https://pastebin.com/9NMLr5bD       https://pastebin.com/av6Q2jCf Password: gpTq3Gvkc5                     qdF0BeJGYN   Any suggestions what should i do here?
  • Topics

×
×
  • Create New...

Important Information

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