diff --git a/assets/hbm/textures/blocks/machine_keyforge_bottom.png b/assets/hbm/textures/blocks/machine_keyforge_bottom.png new file mode 100644 index 000000000..28b0a53f1 Binary files /dev/null and b/assets/hbm/textures/blocks/machine_keyforge_bottom.png differ diff --git a/assets/hbm/textures/blocks/machine_keyforge_side.png b/assets/hbm/textures/blocks/machine_keyforge_side.png index 23b4fbeab..2eff37c77 100644 Binary files a/assets/hbm/textures/blocks/machine_keyforge_side.png and b/assets/hbm/textures/blocks/machine_keyforge_side.png differ diff --git a/assets/hbm/textures/blocks/machine_keyforge_side_side.png b/assets/hbm/textures/blocks/machine_keyforge_side_side.png new file mode 100644 index 000000000..23b4fbeab Binary files /dev/null and b/assets/hbm/textures/blocks/machine_keyforge_side_side.png differ diff --git a/assets/hbm/textures/blocks/machine_keyforge_top.png b/assets/hbm/textures/blocks/machine_keyforge_top.png index 6f02e9b08..8a12afa4a 100644 Binary files a/assets/hbm/textures/blocks/machine_keyforge_top.png and b/assets/hbm/textures/blocks/machine_keyforge_top.png differ diff --git a/assets/hbm/textures/blocks/machine_keyforge_top_alt.png b/assets/hbm/textures/blocks/machine_keyforge_top_alt.png new file mode 100644 index 000000000..6f02e9b08 Binary files /dev/null and b/assets/hbm/textures/blocks/machine_keyforge_top_alt.png differ diff --git a/com/hbm/blocks/machine/MachineKeyForge.java b/com/hbm/blocks/machine/MachineKeyForge.java index 25bdc7890..10b6b35a2 100644 --- a/com/hbm/blocks/machine/MachineKeyForge.java +++ b/com/hbm/blocks/machine/MachineKeyForge.java @@ -29,9 +29,11 @@ public class MachineKeyForge extends BlockContainer { private final Random field_149933_a = new Random(); private Random rand; private static boolean keepInventory; - + @SideOnly(Side.CLIENT) private IIcon iconTop; + @SideOnly(Side.CLIENT) + private IIcon iconBottom; public MachineKeyForge(Material p_i45386_1_) { super(p_i45386_1_); @@ -45,15 +47,16 @@ public class MachineKeyForge extends BlockContainer { @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { - + this.iconTop = iconRegister.registerIcon(RefStrings.MODID + ":machine_keyforge_top"); + this.iconBottom = iconRegister.registerIcon(RefStrings.MODID + ":machine_keyforge_bottom"); this.blockIcon = iconRegister.registerIcon(RefStrings.MODID + ":machine_keyforge_side"); } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int metadata) { - return side == 1 ? this.iconTop : (side == 0 ? this.iconTop : this.blockIcon); + return side == 0 ? this.iconBottom : (side == 1 ? this.iconTop : this.blockIcon); } @Override diff --git a/com/hbm/handler/GUIHandler.java b/com/hbm/handler/GUIHandler.java index 5213df71c..f187046ff 100644 --- a/com/hbm/handler/GUIHandler.java +++ b/com/hbm/handler/GUIHandler.java @@ -3,7 +3,9 @@ package com.hbm.handler; import com.hbm.blocks.ModBlocks; import com.hbm.inventory.container.*; import com.hbm.inventory.gui.*; +import com.hbm.inventory.inv.InventoryLeadBox; import com.hbm.items.ModItems; +import com.hbm.items.tool.ItemLeadBox; import com.hbm.tileentity.bomb.*; import com.hbm.tileentity.machine.*; @@ -742,12 +744,12 @@ public class GUIHandler implements IGuiHandler { } } } else { - //CLIENTONLY CONTAINERS + //NON-TE CONTAINERS switch(ID) { case ModItems.guiID_item_box: - return new ContainerLeadBox(player.inventory); + return new ContainerLeadBox(player, player.inventory, new InventoryLeadBox(player.getHeldItem())); } } @@ -1493,7 +1495,7 @@ public class GUIHandler implements IGuiHandler { case ModItems.guiID_item_sat_interface: return new GUIScreenSatInterface(player); case ModItems.guiID_item_box: - return new GUILeadBox(player.inventory); + return new GUILeadBox(new ContainerLeadBox(player, player.inventory, new InventoryLeadBox(player.getHeldItem()))); } } return null; diff --git a/com/hbm/inventory/container/ContainerLeadBox.java b/com/hbm/inventory/container/ContainerLeadBox.java index 859bb4f34..78e258ca1 100644 --- a/com/hbm/inventory/container/ContainerLeadBox.java +++ b/com/hbm/inventory/container/ContainerLeadBox.java @@ -1,5 +1,6 @@ package com.hbm.inventory.container; +import com.hbm.inventory.inv.InventoryLeadBox; import com.hbm.items.ModItems; import com.hbm.items.tool.ItemLeadBox; @@ -8,43 +9,191 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; public class ContainerLeadBox extends Container { - public ContainerLeadBox(InventoryPlayer invPlayer) { - - /*IInventory inv = + /** + * The Item Inventory for this Container, only needed if you want to + * reference isUseableByPlayer + */ + public final InventoryLeadBox inventory; - this.addSlotToContainer(new Slot(inv, 0, 71, 18)); - this.addSlotToContainer(new Slot(inv, 1, 71, 18)); - this.addSlotToContainer(new Slot(inv, 2, 71, 18)); - this.addSlotToContainer(new Slot(inv, 3, 71, 18)); - this.addSlotToContainer(new Slot(inv, 4, 71, 18)); - this.addSlotToContainer(new Slot(inv, 5, 71, 18)); - this.addSlotToContainer(new Slot(inv, 6, 71, 18)); - this.addSlotToContainer(new Slot(inv, 7, 71, 18)); - this.addSlotToContainer(new Slot(inv, 8, 71, 18)); - this.addSlotToContainer(new Slot(inv, 9, 71, 18)); - this.addSlotToContainer(new Slot(inv, 10, 71, 18)); - this.addSlotToContainer(new Slot(inv, 11, 71, 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, 84 + i * 18 + 20)); + /** + * Using these will make transferStackInSlot easier to understand and + * implement INV_START is the index of the first slot in the Player's + * Inventory, so our InventoryItem's number of slots (e.g. 5 slots is array + * indices 0-4, so start at 5) Notice how we don't have to remember how many + * slots we made? We can just use InventoryItem.INV_SIZE and if we ever + * change it, the Container updates automatically. + */ + private static final int INV_START = InventoryLeadBox.INV_SIZE, INV_END = INV_START + 26, + HOTBAR_START = INV_END + 1, HOTBAR_END = HOTBAR_START + 8; + + // If you're planning to add armor slots, put those first like this: + // ARMOR_START = InventoryItem.INV_SIZE, ARMOR_END = ARMOR_START+3, + // INV_START = ARMOR_END+1, and then carry on like above. + + public ContainerLeadBox(EntityPlayer par1Player, InventoryPlayer inventoryPlayer, InventoryLeadBox inventoryItem) { + this.inventory = inventoryItem; + + int i; + + // ITEM INVENTORY - you'll need to adjust the slot locations to match + // your texture file + // I have them set vertically in columns of 4 to the right of the player + // model + for (i = 0; i < InventoryLeadBox.INV_SIZE; ++i) { + // You can make a custom Slot if you need different behavior, + // such as only certain item types can be put into this slot + // We made a custom slot to prevent our inventory-storing item + // from being stored within itself, but if you want to allow that + // and + // you followed my advice at the end of the above step, then you + // could get away with using the vanilla Slot class + this.addSlotToContainer(new Slot(this.inventory, i, 80 + (18 * (int) (i / 4)), 8 + (18 * (i % 4)))); + } + + // If you want, you can add ARMOR SLOTS here as well, but you need to + // make a public version of SlotArmor. I won't be doing that in this + // tutorial. + /* + * for (i = 0; i < 4; ++i) { // These are the standard positions for + * survival inventory layout this.addSlotToContainer(new + * SlotArmor(this.player, inventoryPlayer, + * inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18, i)); } + */ + + // PLAYER INVENTORY - uses default locations for standard inventory + // texture file + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); } } - - for(int i = 0; i < 9; i++) - { - this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 142 + 20)); - }*/ + + // PLAYER ACTION BAR - uses default locations for standard action bar + // texture file + for (i = 0; i < 9; ++i) { + this.addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142)); + } } @Override - public boolean canInteractWith(EntityPlayer p_75145_1_) { - return true; + public boolean canInteractWith(EntityPlayer player) { + // be sure to return the inventory's isUseableByPlayer method + // if you defined special behavior there: + return inventory.isUseableByPlayer(player); + } + + /** + * Called when a player shift-clicks on a slot. You must override this or + * you will crash when someone does that. + */ + public ItemStack transferStackInSlot(EntityPlayer player, int index) { + ItemStack itemstack = null; + Slot slot = (Slot) this.inventorySlots.get(index); + + if (slot != null && slot.getHasStack()) { + ItemStack itemstack1 = slot.getStack(); + itemstack = itemstack1.copy(); + + // If item is in our custom Inventory or armor slot + if (index < INV_START) { + // try to place in player inventory / action bar + if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) { + return null; + } + + slot.onSlotChange(itemstack1, itemstack); + } + // Item is in inventory / hotbar, try to place in custom inventory + // or armor slots + else { + /* + * If your inventory only stores certain instances of Items, you + * can implement shift-clicking to your inventory like this: + * + * // Check that the item is the right type if + * (itemstack1.getItem() instanceof ItemCustom) { // Try to + * merge into your custom inventory slots // We use + * 'InventoryItem.INV_SIZE' instead of INV_START just in case // + * you also add armor or other custom slots if + * (!this.mergeItemStack(itemstack1, 0, InventoryItem.INV_SIZE, + * false)) { return null; } } // If you added armor slots, check + * them here as well: // Item being shift-clicked is armor - try + * to put in armor slot if (itemstack1.getItem() instanceof + * ItemArmor) { int type = ((ItemArmor) + * itemstack1.getItem()).armorType; if + * (!this.mergeItemStack(itemstack1, ARMOR_START + type, + * ARMOR_START + type + 1, false)) { return null; } } Otherwise, + * you have basically 2 choices: 1. shift-clicking between + * player inventory and custom inventory 2. shift-clicking + * between action bar and inventory + * + * Be sure to choose only ONE of the following + * implementations!!! + */ + /** + * Implementation number 1: Shift-click into your custom + * inventory + */ + if (index >= INV_START) { + // place in custom inventory + if (!this.mergeItemStack(itemstack1, 0, INV_START, false)) { + return null; + } + } + + /** + * Implementation number 2: Shift-click items between action bar + * and inventory + */ + // item is in player's inventory, but not in action bar + if (index >= INV_START && index < HOTBAR_START) { + // place in action bar + if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_END + 1, false)) { + return null; + } + } + // item in action bar - place in player inventory + else if (index >= HOTBAR_START && index < HOTBAR_END + 1) { + if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false)) { + return null; + } + } + } + + if (itemstack1.stackSize == 0) { + slot.putStack((ItemStack) null); + } else { + slot.onSlotChanged(); + } + + if (itemstack1.stackSize == itemstack.stackSize) { + return null; + } + + slot.onPickupFromSlot(player, itemstack1); + } + + return itemstack; + } + + /** + * You should override this method to prevent the player from moving the + * stack that opened the inventory, otherwise if the player moves it, the + * inventory will not be able to save properly + */ + @Override + public ItemStack slotClick(int slot, int button, int flag, EntityPlayer player) { + // this will prevent the player from interacting with the item that + // opened the inventory: + if (slot >= 0 && getSlot(slot) != null && getSlot(slot).getStack() == player.getHeldItem()) { + return null; + } + + return super.slotClick(slot, button, flag, player); } } diff --git a/com/hbm/inventory/gui/GUILeadBox.java b/com/hbm/inventory/gui/GUILeadBox.java index 466e41a5c..c336bb9be 100644 --- a/com/hbm/inventory/gui/GUILeadBox.java +++ b/com/hbm/inventory/gui/GUILeadBox.java @@ -4,6 +4,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerLeadBox; import com.hbm.inventory.container.ContainerWasteDrum; +import com.hbm.inventory.inv.InventoryLeadBox; import com.hbm.items.ModItems; import com.hbm.items.tool.ItemLeadBox; import com.hbm.lib.RefStrings; @@ -19,9 +20,11 @@ import net.minecraft.util.ResourceLocation; public class GUILeadBox extends GuiContainer { private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/gui_containment.png"); - - public GUILeadBox(InventoryPlayer invPlayer) { - super(new ContainerLeadBox(invPlayer)); + private final InventoryLeadBox inventory; + + public GUILeadBox(ContainerLeadBox container) { + super(container); + this.inventory = container.inventory; this.xSize = 176; this.ySize = 186; @@ -29,7 +32,7 @@ public class GUILeadBox extends GuiContainer { @Override protected void drawGuiContainerForegroundLayer(int i, int j) { - String name = "";//ItemLeadBox.getGuiName(); + String name = this.inventory.getInventoryName(); this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752); this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); diff --git a/com/hbm/inventory/inv/InventoryLeadBox.java b/com/hbm/inventory/inv/InventoryLeadBox.java new file mode 100644 index 000000000..df265dcd0 --- /dev/null +++ b/com/hbm/inventory/inv/InventoryLeadBox.java @@ -0,0 +1,204 @@ +package com.hbm.inventory.inv; + +import com.hbm.items.special.ItemRadioactive; +import com.hbm.items.tool.ItemLeadBox; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; + +public class InventoryLeadBox implements IInventory { + + private String name = "Inventory Item"; + + /** Provides NBT Tag Compound to reference */ + private final ItemStack invItem; + + /** Defining your inventory size this way is handy */ + public static final int INV_SIZE = 20; + + /** + * Inventory's size must be same as number of slots you add to the Container + * class + */ + private ItemStack[] inventory = new ItemStack[INV_SIZE]; + + /** + * @param itemstack - the ItemStack to which this inventory belongs + */ + public InventoryLeadBox(ItemStack stack) + { + invItem = stack; + + // Create a new NBT Tag Compound if one doesn't already exist, or you will crash + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); + } + // note that it's okay to use stack instead of invItem right there + // both reference the same memory location, so whatever you change using + // either reference will change in the other + + // Read the inventory contents from NBT + readFromNBT(stack.getTagCompound()); + } + + @Override + public int getSizeInventory() { + return inventory.length; + } + + @Override + public ItemStack getStackInSlot(int slot) { + return inventory[slot]; + } + + @Override + public ItemStack decrStackSize(int slot, int amount) { + ItemStack stack = getStackInSlot(slot); + if (stack != null) { + if (stack.stackSize > amount) { + stack = stack.splitStack(amount); + // Don't forget this line or your inventory will not be saved! + markDirty(); + } else { + // this method also calls onInventoryChanged, so we don't need + // to call it again + setInventorySlotContents(slot, null); + } + } + return stack; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + ItemStack stack = getStackInSlot(slot); + setInventorySlotContents(slot, null); + return stack; + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + inventory[slot] = stack; + + if (stack != null && stack.stackSize > getInventoryStackLimit()) { + stack.stackSize = getInventoryStackLimit(); + } + + // Don't forget this line or your inventory will not be saved! + markDirty(); + } + + // 1.7.2+ renamed to getInventoryName + @Override + public String getInventoryName() { + return name; + } + + // 1.7.2+ renamed to hasCustomInventoryName + @Override + public boolean hasCustomInventoryName() { + return name.length() > 0; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + /** + * This is the method that will handle saving the inventory contents, as it + * is called (or should be called!) anytime the inventory changes. Perfect. + * Much better than using onUpdate in an Item, as this will also let you + * change things in your inventory without ever opening a Gui, if you want. + */ + // 1.7.2+ renamed to markDirty + @Override + public void markDirty() { + + for (int i = 0; i < getSizeInventory(); ++i) { + if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) { + inventory[i] = null; + } + } + + // This line here does the work: + writeToNBT(invItem.getTagCompound()); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + // 1.7.2+ renamed to openInventory(EntityPlayer player) + @Override + public void openInventory() { } + + // 1.7.2+ renamed to closeInventory(EntityPlayer player) + @Override + public void closeInventory() { } + + /** + * This method doesn't seem to do what it claims to do, as items can still + * be left-clicked and placed in the inventory even when this returns false + */ + @Override + public boolean isItemValidForSlot(int slot, ItemStack itemstack) { + // Don't want to be able to store the inventory item within itself + // Bad things will happen, like losing your inventory + // Actually, this needs a custom Slot to work + return (itemstack.getItem() instanceof ItemRadioactive); + } + + /** + * A custom method to read our inventory from an ItemStack's NBT compound + */ + public void readFromNBT(NBTTagCompound compound) { + // Gets the custom taglist we wrote to this compound, if any + // 1.7.2+ change to compound.getTagList("ItemInventory", + // Constants.NBT.TAG_COMPOUND); + NBTTagList items = compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < items.tagCount(); ++i) { + // 1.7.2+ change to items.getCompoundTagAt(i) + NBTTagCompound item = (NBTTagCompound) items.getCompoundTagAt(i); + int slot = item.getInteger("Slot"); + + // Just double-checking that the saved slot index is within our + // inventory array bounds + if (slot >= 0 && slot < getSizeInventory()) { + inventory[slot] = ItemStack.loadItemStackFromNBT(item); + } + } + } + + /** + * A custom method to write our inventory to an ItemStack's NBT compound + */ + public void writeToNBT(NBTTagCompound tagcompound) { + // Create a new NBT Tag List to store itemstacks as NBT Tags + NBTTagList items = new NBTTagList(); + + for (int i = 0; i < getSizeInventory(); ++i) { + // Only write stacks that contain items + if (getStackInSlot(i) != null) { + // Make a new NBT Tag Compound to write the itemstack and slot + // index to + NBTTagCompound item = new NBTTagCompound(); + item.setInteger("Slot", i); + // Writes the itemstack in slot(i) to the Tag Compound we just + // made + getStackInSlot(i).writeToNBT(item); + + // add the tag compound to our tag list + items.appendTag(item); + } + } + // Add the TagList to the ItemStack's Tag Compound with the name + // "ItemInventory" + tagcompound.setTag("ItemInventory", items); + } +} diff --git a/com/hbm/items/tool/ItemLeadBox.java b/com/hbm/items/tool/ItemLeadBox.java index 879f02cea..d8eeca383 100644 --- a/com/hbm/items/tool/ItemLeadBox.java +++ b/com/hbm/items/tool/ItemLeadBox.java @@ -12,6 +12,12 @@ import net.minecraft.world.World; public class ItemLeadBox extends Item { + // Without this method, your inventory will NOT work!!! + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 1; // return any value greater than zero + } + @Override public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { diff --git a/com/hbm/items/weapon/GunZOMG.java b/com/hbm/items/weapon/GunZOMG.java index 2854a69fb..88f1fe660 100644 --- a/com/hbm/items/weapon/GunZOMG.java +++ b/com/hbm/items/weapon/GunZOMG.java @@ -61,44 +61,44 @@ public class GunZOMG extends Item { if (!player.inventory.hasItem(ModItems.nugget_euphemium) && !player.inventory.hasItem(ModItems.ingot_euphemium)) { stack.stackTagCompound.setBoolean("valid", false); - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Validation lost!")); player.addChatMessage(new ChatComponentText("[ZOMG] Request new validation!")); } } } } else { - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Gun not validated!")); player.addChatMessage(new ChatComponentText("[ZOMG] Validate your gun with shift right-click.")); } } } else { if (stack.stackTagCompound.getBoolean("valid")) { - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Gun has already been validated.")); } } else { if (player.inventory.hasItem(ModItems.nugget_euphemium) || player.inventory.hasItem(ModItems.ingot_euphemium)) { stack.stackTagCompound.setBoolean("valid", true); - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Gun has been validated!")); } //if(Library.superuser.contains(player.getUniqueID().toString())) { if(player.inventory.hasItem(ModItems.polaroid)) { - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Welcome, superuser!")); } stack.stackTagCompound.setBoolean("superuser", true); } else { - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Welcome, user!")); } stack.stackTagCompound.setBoolean("superuser", false); } } else { - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Validation failed!")); player.addChatMessage(new ChatComponentText("[ZOMG] No external negative gravity well found!")); } @@ -176,7 +176,7 @@ public class GunZOMG extends Item { if (!player.inventory.hasItem(ModItems.nugget_euphemium) && !player.inventory.hasItem(ModItems.ingot_euphemium)) { stack.stackTagCompound.setBoolean("valid", false); - if (world.isRemote) { + if (!world.isRemote) { player.addChatMessage(new ChatComponentText("[ZOMG] Validation lost!")); player.addChatMessage(new ChatComponentText("[ZOMG] Request new validation!")); } diff --git a/com/hbm/main/CraftingManager.java b/com/hbm/main/CraftingManager.java index 3738faa14..1a5bc48a0 100644 --- a/com/hbm/main/CraftingManager.java +++ b/com/hbm/main/CraftingManager.java @@ -1455,7 +1455,7 @@ public class CraftingManager { GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModItems.photo_panel), new Object[] { " G ", "IPI", " C ", 'G', "paneGlass", 'I', ModItems.plate_polymer, 'P', "dustNetherQuartz", 'C', ModItems.circuit_aluminium })); GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.machine_satlinker), new Object[] { "PSP", "SCS", "PSP", 'P', "plateSteel", 'S', ModItems.ingot_starmetal, 'C', ModItems.sat_chip })); GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.machine_telelinker), new Object[] { "PSP", "SCS", "PSP", 'P', "plateSteel", 'S', "ingotAdvanced", 'C', ModItems.turret_biometry })); - GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.machine_keyforge), new Object[] { "PSP", "SCS", "PSP", 'P', "plateSteel", 'S', "ingotTungsten", 'C', ModItems.padlock })); + GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ModBlocks.machine_keyforge), new Object[] { "PCP", "WSW", "WSW", 'P', "plateSteel", 'S', "ingotTungsten", 'C', ModItems.padlock, 'W', "plankWood" })); GameRegistry.addRecipe(new ItemStack(ModItems.sat_chip), new Object[] { "WWW", "CIC", "WWW", 'W', ModItems.wire_red_copper, 'C', ModItems.circuit_red_copper, 'I', ModItems.ingot_polymer }); GameRegistry.addRecipe(new ItemStack(ModItems.sat_mapper), new Object[] { "H", "B", 'H', ModItems.sat_head_mapper, 'B', ModItems.sat_base }); GameRegistry.addRecipe(new ItemStack(ModItems.sat_scanner), new Object[] { "H", "B", 'H', ModItems.sat_head_scanner, 'B', ModItems.sat_base });