Jump to content

[1.7.10] Progress Bar Crafting


Fenrir_Felix

Recommended Posts

Hi everyone! So I had a quick question about how I would incorporate a crafting matrix system to a tile entity that produces an output after a certain amount of time. Basically a crafting table that has a progress bar like a furnace.

 

I've successfully made custom crafting tables (5x3) as well as dual input furnaces and such with simple recipe systems, but I'm not sure how to combine the two with a matrix so that shaped an shapeless crafting can be done. I figured you could use the crafting manger "findMatchingRecipe" method  when a value (ie cooktime) reaches a certain point, but I can't seem to get it to work (if it's the correct way to do so).

 

Any help is appreciated! I'll provide more details (code and such) if necessary. Thanks!

 

-Fenrir

Maker of the WIP mod: AdvanceCraft

Link to comment
Share on other sites

Alright, so here's my attempt. As a note, both the regular crafting (without the progress bar) and the progress bar itself work individually, just not in tandem:

 

Tile Entity

package com.felix.advancecraft.tileEntities;




import com.felix.advancecraft.AdvanceCraft;
import com.felix.advancecraft.block.ACBlocks;
import com.felix.advancecraft.block.BlockACFurnace;
import com.felix.advancecraft.block.BlockFirePit;
import com.felix.advancecraft.container.ContainerClayCrucible;
import com.felix.advancecraft.container.ContainerForge;
import com.felix.advancecraft.recipes.ClayCrucibleRecipes;
import com.felix.advancecraft.recipes.managers.ForgeCraftingManager;
import com.felix.advancecraft.recipes.managers.ForgeShapedRecipes;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

public class TileEntityForge extends TileEntity implements ISidedInventory {


private static final int[] slots_top = new int[]{0,1,2,3};
private static final int[] slots_bottom = new int[]{16};


public int direction;
public int heatpower;

private ItemStack[] slots = new ItemStack[17];

private String localizedname;

public int forgespeed = 100;
public int forgetime;




public TileEntityForge()
{

}

@Override public int getSizeInventory()
{
	return slots.length;
}

@Override
public ItemStack getStackInSlot(int slot) 
{
	return this.slots[slot];
}

@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
	if (this.slots[slot] != null)
	{
		ItemStack itemstack = this.slots[slot];
		this.slots[slot] = null;
		return itemstack;
	}
	else
	{
		return null;
	}
}

@Override
public void setInventorySlotContents(int slot, ItemStack stack)
{
	slots[slot] = stack;

	if (stack != null && stack.stackSize > getInventoryStackLimit()) 
	{
		stack.stackSize = getInventoryStackLimit();
	}
}

@Override
public ItemStack decrStackSize(int slot, int amt)
{
	ItemStack stack = getStackInSlot(slot);

	if (stack != null)
	{
		if (stack.stackSize <= amt) 
		{
			setInventorySlotContents(slot, null);
		}
		else
		{
			stack = stack.splitStack(amt);
			if (stack.stackSize == 0) 
			{
				setInventorySlotContents(slot, null);
			}
		}
	}

	return stack;
}


@SideOnly(Side.CLIENT)
public int ForgeProgressScaled(int par1)
{
return this.forgetime * par1 / forgespeed;
}


public boolean HasVentilation()
{
int x = this.xCoord;
int y = this.yCoord;
int z = this.zCoord;

//if(this.worldObj.getBlock(x, y-1, z).equals(ACBlocks.firepit) || this.worldObj.getBlock(x, y-1, z).equals(Blocks.fire))

return true;

}


public void updateEntity()
{
boolean flag = this.forgetime > 0;
boolean flag1 = false;

int x = this.xCoord;
int y = this.yCoord;
int z = this.zCoord;



if(!this.worldObj.isRemote)
{
	if(this.HasVentilation())
	{

		if(this.slots[0] != null)
		{	

			this.forgetime++;

				if (this.forgetime == forgespeed)
				{
					CastItems();
					forgetime = 0;
				}
			}

		if(flag1)
		{
			this.markDirty();
		}
	}
}	

}


private void CastItems() {

{
	ItemStack itemstack = ForgeCraftingManager.getInstance().findMatchingRecipe(ContainerForge.craftMatrix, worldObj);


	if (slots[1] == null)
	{
		slots[1] = itemstack.copy();
	}
	else if (slots[1].isItemEqual(itemstack))
	{
		slots[1].stackSize += itemstack.stackSize;
	}

	for (int i = 2; i < 16; i++)
	{
		if (slots[i].stackSize <= 0)
		{
			slots[i] = new ItemStack(slots[i].getItem().setFull3D());
		}
		else
		{
			slots[i].stackSize--;
		}
		if (slots[i].stackSize <= 0)
		{
			slots[i] = null;
		}
	}
}

}

 

Container

 

package com.felix.advancecraft.container;

import com.felix.advancecraft.block.ACBlocks;
import com.felix.advancecraft.recipes.managers.ForgeCraftingManager;
import com.felix.advancecraft.recipes.managers.WoodenMoldCraftingManager;
import com.felix.advancecraft.tileEntities.TileEntityACFurnace;
import com.felix.advancecraft.tileEntities.TileEntityForge;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCraftResult;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.world.World;

public class ContainerForge extends Container {


public static InventoryCrafting craftMatrix;
public IInventory craftResult;
private World worldObj;
private int posX;
private int posY;
private int posZ;

public int lastforgetime;

private TileEntityForge teForge;

public ContainerForge(InventoryPlayer invPlayer, TileEntityForge entity, World world, int x, int y, int z)
{
	craftMatrix = new InventoryCrafting(this, 5, 3);
	craftResult = new InventoryCraftResult();
	worldObj = world;
	posX = x;
	posY = y;
	posZ = z;

	this.teForge = entity;

	this.addSlotToContainer(new Slot(entity, 0, 31, 86));

	this.addSlotToContainer(new SlotCrafting(invPlayer.player, craftMatrix, craftResult, 1, 134, 86));

	for(int i = 0; i < 3; i++)
	{
		for(int k = 0; k < 5; k++)
		{
			this.addSlotToContainer(new Slot(craftMatrix, k + i* 5, k * 18 + 26, 19 + i * 18));
		}
	}

	for(int i = 0; i < 3; ++i)
	{
		for(int j = 0; j < 9; ++j)
		{

			this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j*18, 118 + i*18));
		}
	}
	for(int i = 0; i < 9; ++i)
	{
		this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 177));
	}


}

public void addCraftingToCrafters(ICrafting icrafting)
{
	super.addCraftingToCrafters(icrafting);
	icrafting.sendProgressBarUpdate(this, 0, this.teForge.forgetime);

}

public void detectAndSendChanges()
{
	super.detectAndSendChanges();

	for(int i = 0;  i < this.crafters.size(); ++i)
	{
		ICrafting icrafting = (ICrafting) this.crafters.get(i);

		if(this.lastforgetime != this.teForge.forgetime)
		{
			icrafting.sendProgressBarUpdate(this, 0, this.teForge.forgetime);
		}

	}
	this.lastforgetime = this.teForge.forgetime;

}

@SideOnly(Side.CLIENT)
public void updateProgressBar(int par1, int par2)
{
	if (par1 == 0)
	{
		this.teForge.forgetime = par2;
	}


}


public void onContainerClosed(EntityPlayer player)
    {
        
    }




public void onCraftMatrixChanged(IInventory iinventory)
{

	//craftResult.setInventorySlotContents(0, ForgeCraftingManager.getInstance().findMatchingRecipe(craftMatrix, worldObj));

}

@Override
public boolean canInteractWith(EntityPlayer entityplayer) {
	return this.teForge.isUseableByPlayer(entityplayer);
}



}

 

Crafting Manager

 

package com.felix.advancecraft.recipes.managers;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import com.felix.advancecraft.item.ACItems;

import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.world.World;

public class ForgeCraftingManager {
    /** The static instance of this class */
    private static final ForgeCraftingManager instance = new ForgeCraftingManager();
    /** A list of all the recipes added */
    private List recipes = new ArrayList();
    private static final String __OBFID = "CL_00000090";

    /**
     * Returns the static instance of this class
     */
    public static final ForgeCraftingManager getInstance()
    {
        /** The static instance of this class */
        return instance;
    }

    private ForgeCraftingManager()
    {
        recipes = new ArrayList();
        
        this.addRecipe(new ItemStack(ACItems.copper_cast_pick, 1), new Object[]
        		{
        		
        		"     ",
        		" AAA ",
        		"A A A",
        		'A', ACItems.copperingot});
    	
        Collections.sort(this.recipes, new ForgeRecipeSorter(this));
        
       
    }

    public ForgeShapedRecipes addRecipe(ItemStack itemstack, Object ... obj)
    {
        String s = "";
        int i = 0;
        int j = 0;
        int k = 0;

        if (obj[i] instanceof String[])
        {
            String[] astring = (String[])((String[])obj[i++]);

            for (int l = 0; l < astring.length; ++l)
            {
                String s1 = astring[l];
                ++k;
                j = s1.length();
                s = s + s1;
            }
        }
        else
        {
            while (obj[i] instanceof String)
            {
                String s2 = (String)obj[i++];
                ++k;
                j = s2.length();
                s = s + s2;
            }
        }

        HashMap hashmap;

        for (hashmap = new HashMap(); i < obj.length; i += 2)
        {
            Character character = (Character)obj[i];
            ItemStack itemstack1 = null;

            if (obj[i + 1] instanceof Item)
            {
                itemstack1 = new ItemStack((Item)obj[i + 1]);
            }
            else if (obj[i + 1] instanceof Block)
            {
                itemstack1 = new ItemStack((Block)obj[i + 1], 1, 32767);
            }
            else if (obj[i + 1] instanceof ItemStack)
            {
                itemstack1 = (ItemStack)obj[i + 1];
            }

            hashmap.put(character, itemstack1);
        }

        ItemStack[] aitemstack = new ItemStack[j * k];

        for (int i1 = 0; i1 < j * k; ++i1)
        {
            char c0 = s.charAt(i1);

            if (hashmap.containsKey(Character.valueOf(c0)))
            {
                aitemstack[i1] = ((ItemStack)hashmap.get(Character.valueOf(c0))).copy();
            }
            else
            {
                aitemstack[i1] = null;
            }
        }

       ForgeShapedRecipes shapedrecipes = new ForgeShapedRecipes(j, k, aitemstack, itemstack);
        this.recipes.add(shapedrecipes);
        return shapedrecipes;
    }

    public void addShapelessRecipe(ItemStack p_77596_1_, Object ... p_77596_2_)
    {
        ArrayList arraylist = new ArrayList();
        Object[] aobject = p_77596_2_;
        int i = p_77596_2_.length;

        for (int j = 0; j < i; ++j)
        {
            Object object1 = aobject[j];

            if (object1 instanceof ItemStack)
            {
                arraylist.add(((ItemStack)object1).copy());
            }
            else if (object1 instanceof Item)
            {
                arraylist.add(new ItemStack((Item)object1));
            }
            else
            {
                if (!(object1 instanceof Block))
                {
                    throw new RuntimeException("Invalid shapeless recipe!");
                }

                arraylist.add(new ItemStack((Block)object1));
            }
        }

        this.recipes.add(new ShapelessRecipes(p_77596_1_, arraylist));
    }

    public ItemStack findMatchingRecipe(InventoryCrafting inventorycrafting, World world)
    {
        int i = 0;
        ItemStack itemstack = null;
        ItemStack itemstack1 = null;
        int j;

        for (j = 0; j < inventorycrafting.getSizeInventory(); ++j)
        {
            ItemStack itemstack2 = inventorycrafting.getStackInSlot(j);

            if (itemstack2 != null)
            {
                if (i == 0)
                {
                    itemstack = itemstack2;
                }

                if (i == 1)
                {
                    itemstack1 = itemstack2;
                }

                ++i;
            }
        }

        if (i == 2 && itemstack.getItem() == itemstack1.getItem() && itemstack.stackSize == 1 && itemstack1.stackSize == 1 && itemstack.getItem().isRepairable())
        {
            Item item = itemstack.getItem();
            int j1 = item.getMaxDamage() - itemstack.getItemDamageForDisplay();
            int k = item.getMaxDamage() - itemstack1.getItemDamageForDisplay();
            int l = j1 + k + item.getMaxDamage() * 5 / 100;
            int i1 = item.getMaxDamage() - l;

            if (i1 < 0)
            {
                i1 = 0;
            }

            return new ItemStack(itemstack.getItem(), 1, i1);
        }
        else
        {
            for (j = 0; j < this.recipes.size(); ++j)
            {
                IRecipe irecipe = (IRecipe)this.recipes.get(j);

                if (irecipe.matches(inventorycrafting, world))
                {
                    return irecipe.getCraftingResult(inventorycrafting);
                }
            }

            return null;
        }
    }

    /**
     * returns the List<> of all recipes
     */
    public List getRecipeList()
    {
        return this.recipes;
    }
}

 

When I try this with anything in my container in-game it crashes and reports an error with my update entity method when it tries to use "CastItems", which is to be expected. The attempted crafting is the "copper pick" in the crafting manager.

 

Also I left out some unnecessary code for the sake of simplicity (shift clicking and such). But i can post anything else that should be looked at.

 

Thanks again!

 

- Fenrir

 

 

Maker of the WIP mod: AdvanceCraft

Link to comment
Share on other sites

Okay, I see what you mean. Sorry for the amateur questions, I looked through the vanilla code and realized that my tile entites already implement methods from I IInventory and such. So I need to send my variables to my TE not to the regular crafting inventory. Which means replacing InventoryCrafting with my tile entity.

 

However, now I'm at a loss on how to setup the inventory in my tile entity so that the recipe can be recognized. But this is probably because I need to look through the code a bit more and figure it out myself. Unless it's rather easy to explain, in which I'd be happy to see an example! Regardless thanks for the help!

Maker of the WIP mod: AdvanceCraft

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



×
×
  • Create New...

Important Information

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