From 7b6fac6a428af0dbcfc231d77782d88e01a22852 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 20 Dec 2013 02:13:00 -0500 Subject: [PATCH] add some things from the core macine yes piecing out the core machine though i will clean up and reduce a lot of this later --- src/com/dark/DarkCore.java | 30 +- src/com/dark/EnumMaterial.java | 149 +++++++++ src/com/dark/EnumOrePart.java | 46 +++ src/com/dark/LaserEvent.java | 279 +++++++++++++++++ src/com/dark/helpers/ColorCode.java | 103 ++++++ src/com/dark/interfaces/IAimable.java | 23 ++ src/com/dark/interfaces/IMultiBlock.java | 22 ++ src/com/dark/interfaces/IToolReadOut.java | 34 ++ src/com/dark/prefab/BlockMulti.java | 180 +++++++++++ src/com/dark/prefab/DataPack.java | 75 +++++ src/com/dark/prefab/EnergyHelper.java | 81 +++++ src/com/dark/prefab/RecipeLoader.java | 92 ++++++ src/com/dark/prefab/TileEntityMulti.java | 140 +++++++++ .../dark/prefab/invgui/GuiInvMachineBase.java | 9 + .../dark/prefab/invgui/GuiMachineBase.java | 190 ++++++++++++ .../prefab/invgui/GuiMachineContainer.java | 205 ++++++++++++ .../api/reciepes/AssemblyObjectManager.java | 45 +++ src/dark/api/reciepes/IAssemblier.java | 38 +++ src/dark/api/reciepes/IAssemblyObject.java | 19 ++ src/dark/api/reciepes/IAssemblyRecipe.java | 19 ++ src/dark/api/reciepes/IBlueprint.java | 17 + src/dark/api/reciepes/IInjectorMold.java | 15 + src/dark/api/reciepes/IProcessable.java | 22 ++ .../api/reciepes/MachineRecipeHandler.java | 292 ++++++++++++++++++ src/dark/api/reciepes/ProcessorRecipe.java | 23 ++ src/dark/api/reciepes/ProcessorType.java | 28 ++ 26 files changed, 2174 insertions(+), 2 deletions(-) create mode 100644 src/com/dark/EnumMaterial.java create mode 100644 src/com/dark/EnumOrePart.java create mode 100644 src/com/dark/LaserEvent.java create mode 100644 src/com/dark/helpers/ColorCode.java create mode 100644 src/com/dark/interfaces/IAimable.java create mode 100644 src/com/dark/interfaces/IMultiBlock.java create mode 100644 src/com/dark/interfaces/IToolReadOut.java create mode 100644 src/com/dark/prefab/BlockMulti.java create mode 100644 src/com/dark/prefab/DataPack.java create mode 100644 src/com/dark/prefab/EnergyHelper.java create mode 100644 src/com/dark/prefab/RecipeLoader.java create mode 100644 src/com/dark/prefab/TileEntityMulti.java create mode 100644 src/com/dark/prefab/invgui/GuiInvMachineBase.java create mode 100644 src/com/dark/prefab/invgui/GuiMachineBase.java create mode 100644 src/com/dark/prefab/invgui/GuiMachineContainer.java create mode 100644 src/dark/api/reciepes/AssemblyObjectManager.java create mode 100644 src/dark/api/reciepes/IAssemblier.java create mode 100644 src/dark/api/reciepes/IAssemblyObject.java create mode 100644 src/dark/api/reciepes/IAssemblyRecipe.java create mode 100644 src/dark/api/reciepes/IBlueprint.java create mode 100644 src/dark/api/reciepes/IInjectorMold.java create mode 100644 src/dark/api/reciepes/IProcessable.java create mode 100644 src/dark/api/reciepes/MachineRecipeHandler.java create mode 100644 src/dark/api/reciepes/ProcessorRecipe.java create mode 100644 src/dark/api/reciepes/ProcessorType.java diff --git a/src/com/dark/DarkCore.java b/src/com/dark/DarkCore.java index e0fb89092..3987ac44c 100644 --- a/src/com/dark/DarkCore.java +++ b/src/com/dark/DarkCore.java @@ -1,16 +1,21 @@ package com.dark; +import java.io.File; + import net.minecraft.block.Block; import net.minecraft.item.Item; +import net.minecraftforge.common.Configuration; import net.minecraftforge.common.MinecraftForge; import universalelectricity.compatibility.Compatibility; import universalelectricity.core.UniversalElectricity; import com.dark.fluid.FluidHelper; import com.dark.helpers.PlayerKeyHandler; +import com.dark.prefab.BlockMulti; import com.dark.save.SaveManager; import com.dark.tilenetwork.prefab.NetworkUpdateHandler; +import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.registry.TickRegistry; import cpw.mods.fml.relauncher.Side; @@ -20,6 +25,9 @@ public class DarkCore private boolean pre, load, post; + public static final String DOMAIN = "darkcore"; + public static final String PREFIX = DOMAIN + ":"; + public static final String TEXTURE_DIRECTORY = "textures/"; public static final String BLOCK_DIRECTORY = TEXTURE_DIRECTORY + "blocks/"; public static final String ITEM_DIRECTORY = TEXTURE_DIRECTORY + "items/"; @@ -27,13 +35,19 @@ public class DarkCore public static final String GUI_DIRECTORY = TEXTURE_DIRECTORY + "gui/"; public static final String CHANNEL = "DARKCORE"; - public static final String DOMAIN = "darkcore"; - public static final String PREFIX = DOMAIN + ":"; + public static String DIRECTORY_NO_SLASH = "assets/" + DOMAIN + "/"; + public static String DIRECTORY = "/" + DIRECTORY_NO_SLASH; + public static String LANGUAGE_PATH = DIRECTORY + "languages/"; + public static String SOUND_PATH = DIRECTORY + "audio/"; + + public static final Configuration CONFIGURATION = new Configuration(new File(Loader.instance().getConfigDir(), "Dark/Main.cfg")); /* START IDS */ public static int BLOCK_ID_PRE = 3100; public static int ITEM_ID_PREFIX = 13200; + public static BlockMulti multiBlock = null; + public static DarkCore instance() { if (instance == null) @@ -43,6 +57,18 @@ public class DarkCore return instance; } + public static void requestMultiBlock(String modID) + { + if (multiBlock == null) + { + Block b = CoreRegistry.createNewBlock("DMBlockMulti", modID, BlockMulti.class, false); + if (b instanceof BlockMulti) + { + multiBlock = (BlockMulti) b; + } + } + } + public void preLoad() { if (!pre) diff --git a/src/com/dark/EnumMaterial.java b/src/com/dark/EnumMaterial.java new file mode 100644 index 000000000..86f4eb169 --- /dev/null +++ b/src/com/dark/EnumMaterial.java @@ -0,0 +1,149 @@ +package com.dark; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.EnumToolMaterial; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Icon; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** Class for storing materials, there icon names, sub items to be made from them or there sub ores + * + * + * @author DarkGuardsman */ +public enum EnumMaterial +{ + WOOD("Wood", EnumToolMaterial.WOOD, EnumOrePart.INGOTS, EnumOrePart.PLATES, EnumOrePart.RUBBLE, EnumOrePart.ROD, EnumOrePart.GEARS, EnumOrePart.MOLTEN), + STONE("Stone", EnumToolMaterial.STONE, EnumOrePart.INGOTS, EnumOrePart.SCRAPS, EnumOrePart.MOLTEN), + IRON("Iron", EnumToolMaterial.IRON, EnumOrePart.INGOTS), + OBBY("Obby", true, 7.0f, 500, 4, EnumOrePart.INGOTS, EnumOrePart.RUBBLE, EnumOrePart.SCRAPS, EnumOrePart.PLATES, EnumOrePart.MOLTEN), + GOLD("Gold", EnumToolMaterial.GOLD, EnumOrePart.GEARS, EnumOrePart.INGOTS), + COAL("Coal", EnumToolMaterial.WOOD, EnumOrePart.GEARS, EnumOrePart.TUBE, EnumOrePart.PLATES, EnumOrePart.RUBBLE, EnumOrePart.SCRAPS, EnumOrePart.MOLTEN), + + COPPER("Copper", true, 3.5f, 79, 1), + TIN("Tin", true, 2.0f, 50, 1, EnumOrePart.GEARS, EnumOrePart.TUBE), + LEAD("Lead", false, 0, 0, 1, EnumOrePart.GEARS, EnumOrePart.TUBE), + ALUMINIUM("Aluminum", true, 5.0f, 100, 2, EnumOrePart.GEARS, EnumOrePart.TUBE), + SILVER("Silver", true, 11.0f, 30, 0, EnumOrePart.GEARS), + STEEL("Steel", true, 7.0f, 4, 1000, EnumOrePart.RUBBLE), + BRONZE("Bronze", true, 6.5f, 3, 560, EnumOrePart.RUBBLE); + + /** Name of the material */ + public String simpleName; + /** List of ore parts that to not be created for the material */ + public List unneedItems; + + public boolean hasTools = false; + + /** Limit by which each material is restricted by for creating orePart sub items */ + public static final int itemCountPerMaterial = 50; + + /** Client side only var used by ore items to store icon per material set */ + @SideOnly(Side.CLIENT) + public Icon[] itemIcons; + + public float materialEffectiveness = 2.0f; + public int maxUses = 100; + public float damageBoost = 0; + + private EnumMaterial(String name, EnumToolMaterial material, EnumOrePart... enumOreParts) + { + this(name, false, material.getEfficiencyOnProperMaterial(), material.getMaxUses(), material.getDamageVsEntity(), enumOreParts); + } + + private EnumMaterial(String name, boolean tool, float effectiveness, int toolUses, float damage, EnumOrePart... enumOreParts) + { + this.simpleName = name; + this.hasTools = tool; + this.materialEffectiveness = effectiveness; + this.maxUses = toolUses; + this.damageBoost = damage; + unneedItems = new ArrayList(); + for (int i = 0; enumOreParts != null && i < enumOreParts.length; i++) + { + unneedItems.add(enumOreParts[i]); + } + } + + /** Creates a new item stack using material and part given. Uses a preset length of 50 for parts + * enum so to prevent any unwanted changes in loading of itemStacks metadata. + * + * @param mat - material + * @param part - part + * @return new ItemStack created from the two enums as long as everything goes right */ + public static ItemStack getStack(Item item, EnumMaterial mat, EnumOrePart part, int ammount) + { + ItemStack reStack = null; + if (mat != null && part != null) + { + if (part == EnumOrePart.INGOTS) + { + if (mat == EnumMaterial.IRON) + { + return new ItemStack(Item.ingotIron, 1); + } + else if (mat == EnumMaterial.GOLD) + { + return new ItemStack(Item.ingotGold, 1); + } + } + int meta = mat.ordinal() * itemCountPerMaterial; + meta += part.ordinal(); + return new ItemStack(item, ammount, meta); + } + return reStack; + } + + public ItemStack getStack(Item item, EnumOrePart part) + { + return this.getStack(item, part, 1); + } + + public ItemStack getStack(Item item, EnumOrePart part, int ammount) + { + return getStack(item, this, part, ammount); + } + + public static Icon getIcon(int metadata) + { + int mat = metadata / EnumMaterial.itemCountPerMaterial; + if (mat < EnumMaterial.values().length) + { + return EnumMaterial.values()[metadata / EnumMaterial.itemCountPerMaterial].itemIcons[metadata % EnumMaterial.itemCountPerMaterial]; + } + return null; + } + + public static String getOreName(EnumMaterial mat, EnumOrePart part) + { + return mat.getOreName(part); + } + + public String getOreName(EnumOrePart part) + { + return this.simpleName.toLowerCase() + part.simpleName; + } + + public static String getOreNameReverse(EnumMaterial mat, EnumOrePart part) + { + return mat.getOreNameReverse(part); + } + + public String getOreNameReverse(EnumOrePart part) + { + return part.simpleName.toLowerCase() + this.simpleName; + } + + public boolean shouldCreateItem(EnumOrePart part) + { + return this.unneedItems == null || !this.unneedItems.contains(part); + } + + public boolean shouldCreateTool() + { + return this.hasTools; + } +} diff --git a/src/com/dark/EnumOrePart.java b/src/com/dark/EnumOrePart.java new file mode 100644 index 000000000..32ef763e6 --- /dev/null +++ b/src/com/dark/EnumOrePart.java @@ -0,0 +1,46 @@ +package com.dark; + +public enum EnumOrePart +{ + + RUBBLE("Rubble"), + DUST("Dust"), + INGOTS("Ingot"), + PLATES("Plate"), + GEARS("Gears"), + TUBE("Tube"), + ROD("Rod"), + SCRAPS("Scraps"), + MOLTEN("Molten"); + + public String simpleName; + + private EnumOrePart(String name) + { + this.simpleName = name; + } + + /** This gets the part name based on the meta value of the ore dirv item. However can also be + * used to get the part name if under X value */ + public static String getPartName(int meta) + { + int partID = meta % EnumMaterial.itemCountPerMaterial; + if (partID < EnumOrePart.values().length) + { + return EnumOrePart.values()[partID].simpleName; + } + return "Part[" + partID + "]"; + } + + /** This gets the full name based on the metadata of the ore dirv item */ + public static String getFullName(int itemMetaData) + { + int matID = itemMetaData / EnumMaterial.itemCountPerMaterial; + int partID = itemMetaData % EnumMaterial.itemCountPerMaterial; + if (matID < EnumMaterial.values().length && partID < EnumOrePart.values().length) + { + return EnumMaterial.values()[matID].simpleName + EnumOrePart.values()[partID].simpleName; + } + return "OrePart[" + matID + "][" + partID + "]"; + } +} diff --git a/src/com/dark/LaserEvent.java b/src/com/dark/LaserEvent.java new file mode 100644 index 000000000..9f4d6876c --- /dev/null +++ b/src/com/dark/LaserEvent.java @@ -0,0 +1,279 @@ +package com.dark; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.Cancelable; +import net.minecraftforge.event.Event; +import universalelectricity.core.vector.Vector3; + +import com.dark.helpers.ItemWorldHelper; + +/** An event triggered by entities or tiles that create lasers + * + * @author DarkGuardsman */ +public class LaserEvent extends Event +{ + public World world; + public Vector3 spot; + public Vector3 target; + + public LaserEvent(World world, Vector3 spot, Vector3 target) + { + this.world = world; + this.spot = spot; + this.target = target; + } + + /** Called when a laser is fired */ + @Cancelable + public static class LaserFireEvent extends LaserEvent + { + public Object shooter; + + public LaserFireEvent(World world, Vector3 spot, Vector3 target, Object shooter) + { + super(world, spot, target); + this.shooter = shooter; + } + + public LaserFireEvent(TileEntity tileEntity, MovingObjectPosition hit) + { + super(tileEntity.worldObj, new Vector3(tileEntity), new Vector3(hit)); + this.shooter = tileEntity; + } + } + + /** Called when a player fires a laser. Use this to cancel a laser hit event */ + @Cancelable + public static class LaserFiredPlayerEvent extends LaserFireEvent + { + public ItemStack laserItem; + public MovingObjectPosition hit; + + public LaserFiredPlayerEvent(EntityPlayer player, MovingObjectPosition hit, ItemStack stack) + { + super(player.worldObj, new Vector3(player), new Vector3(hit), player); + this.laserItem = stack; + this.hit = hit; + } + } + + /** Called when a laser is heating up a block to be mined */ + public static class LaserMeltBlockEvent extends LaserEvent + { + public Object shooter; + + public LaserMeltBlockEvent(World world, Vector3 spot, Vector3 hit, Object shooter) + { + super(world, spot, hit); + this.shooter = shooter; + } + } + + /** Use this to change what drops when the laser finishes mining a block */ + public static class LaserDropItemEvent extends LaserEvent + { + public List items; + + public LaserDropItemEvent(World world, Vector3 spot, Vector3 hit, List items) + { + super(world, spot, hit); + this.items = items; + } + } + + /** Called before a laser mines a block */ + @Cancelable + public static class LaserMineBlockEvent extends LaserEvent + { + public Object shooter; + + public LaserMineBlockEvent(World world, Vector3 spot, Vector3 hit, Object shooter) + { + super(world, spot, hit); + this.shooter = shooter; + } + + } + + public static boolean doLaserHarvestCheck(World world, Vector3 pos, Object player, Vector3 hit) + { + LaserEvent event = new LaserMineBlockEvent(world, pos, hit, player); + MinecraftForge.EVENT_BUS.post(event); + return !event.isCanceled(); + } + + /** Called while the block is being mined */ + public static void onLaserHitBlock(World world, Object player, Vector3 vec, ForgeDirection side) + { + int id = vec.getBlockID(world); + int meta = vec.getBlockID(world); + Block block = Block.blocksList[id]; + + Vector3 faceVec = vec.clone().modifyPositionFromSide(side); + int id2 = faceVec.getBlockID(world); + Block block2 = Block.blocksList[id2]; + + Vector3 start = null; + + if (player instanceof Entity) + { + start = new Vector3((Entity) player); + } + else if (player instanceof TileEntity) + { + start = new Vector3((TileEntity) player); + } + if (block != null) + { + float chance = world.rand.nextFloat(); + + int fireChance = block.getFlammability(world, vec.intX(), vec.intY(), vec.intZ(), meta, side); + if ((fireChance / 300) >= chance && (block2 == null || block2.isAirBlock(world, vec.intX(), vec.intY(), vec.intZ()))) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), Block.fire.blockID, 0, 3); + return; + } + if (block.blockID == Block.grass.blockID && (block2 == null || block2.isAirBlock(world, vec.intX(), vec.intY() + 1, vec.intZ()))) + { + world.setBlock(vec.intX(), vec.intY() + 1, vec.intZ(), Block.fire.blockID, 0, 3); + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), Block.dirt.blockID, 0, 3); + return; + } + if (chance > 0.8f) + { + //TODO turn water into steam + if (block.blockID == Block.sand.blockID) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), Block.glass.blockID, 0, 3); + return; + } + else if (block.blockID == Block.cobblestone.blockID) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), 1, 0, 3); + return; + } + else if (block.blockID == Block.ice.blockID) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), Block.waterStill.blockID, 15, 3); + return; + } + else if (block.blockID == Block.obsidian.blockID) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), Block.lavaStill.blockID, 15, 3); + return; + } + } + MinecraftForge.EVENT_BUS.post(new LaserEvent.LaserMeltBlockEvent(world, start, vec, player)); + } + } + + /** Called when the block is actually mined */ + public static void onBlockMinedByLaser(World world, Object player, Vector3 vec) + { + int id = vec.getBlockID(world); + int meta = vec.getBlockID(world); + Block block = Block.blocksList[id]; + + Vector3 start = null; + if (player instanceof Entity) + { + start = new Vector3((Entity) player); + } + else if (player instanceof TileEntity) + { + start = new Vector3((TileEntity) player); + } + + //TODO make this use or call to the correct methods, and events so it can be canceled + if (block != null && block.getBlockHardness(world, vec.intX(), vec.intY(), vec.intZ()) >= 0 && doLaserHarvestCheck(world, start, player, vec)) + { + try + { + + Block blockBellow = Block.blocksList[vec.clone().modifyPositionFromSide(ForgeDirection.DOWN).getBlockID(world)]; + if (block != null) + { + if (block.blockID == Block.tnt.blockID) + { + world.setBlock(vec.intX(), vec.intY(), vec.intZ(), 0, 0, 3); + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (vec.intX() + 0.5F), (vec.intY() + 0.5F), (vec.intZ() + 0.5F), player instanceof EntityLivingBase ? ((EntityLivingBase) player) : null); + entitytntprimed.fuse = world.rand.nextInt(entitytntprimed.fuse / 4) + entitytntprimed.fuse / 8; + world.spawnEntityInWorld(entitytntprimed); + return; + } + if (block.blockMaterial == Material.wood || block.blockMaterial == Material.plants || block.blockMaterial == Material.vine || block.blockMaterial == Material.plants || block.blockMaterial == Material.pumpkin || block.blockMaterial == Material.cloth || block.blockMaterial == Material.web) + { + if (blockBellow != null && blockBellow.blockID == Block.tilledField.blockID && block instanceof IPlantable) + { + vec.clone().translate(new Vector3(0, -1, 0)).setBlock(world, Block.dirt.blockID, 0, 3); + } + vec.setBlock(world, Block.fire.blockID, 0, 3); + return; + } + List items = block.getBlockDropped(world, vec.intX(), vec.intY(), vec.intZ(), meta, 1); + if (items == null) + { + items = new ArrayList(); + } + //TODO have glass refract the laser causing it to hit random things + if (id == Block.glass.blockID) + { + items.add(new ItemStack(Block.glass, 1, meta)); + } + if (id == Block.thinGlass.blockID) + { + items.add(new ItemStack(Block.thinGlass, 1)); + } + List removeList = new ArrayList(); + for (int i = 0; i < items.size(); i++) + { + if (items.get(i).itemID == Block.wood.blockID) + { + items.set(i, new ItemStack(Item.coal, 1, 1)); + } + else if (items.get(i).itemID == Block.wood.blockID) + { + if (world.rand.nextFloat() < .25f) + { + items.set(i, new ItemStack(Item.coal, 1, 1)); + } + else + { + removeList.add(items.get(i)); + } + } + } + items.removeAll(removeList); + LaserEvent.LaserDropItemEvent event = new LaserEvent.LaserDropItemEvent(world, start, vec, items); + MinecraftForge.EVENT_BUS.post(event); + items = event.items; + for (ItemStack stack : items) + { + ItemWorldHelper.dropItemStack(world, vec.translate(0.5), stack, false); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + world.setBlockToAir(vec.intX(), vec.intY(), vec.intZ()); + } + } +} diff --git a/src/com/dark/helpers/ColorCode.java b/src/com/dark/helpers/ColorCode.java new file mode 100644 index 000000000..48469eac2 --- /dev/null +++ b/src/com/dark/helpers/ColorCode.java @@ -0,0 +1,103 @@ +package com.dark.helpers; + +import java.awt.Color; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public enum ColorCode +{ + BLACK("Black", Color.black), + RED("Red", Color.red), + GREEN("Green", Color.green), + BROWN("Brown", new Color(139, 69, 19)), + BLUE("Blue", Color.BLUE), + PURPLE("Purple", new Color(75, 0, 130)), + CYAN("Cyan", Color.cyan), + SILVER("Silver", new Color(192, 192, 192)), + GREY("Grey", Color.gray), + PINK("Pink", Color.pink), + LIME("Lime", new Color(0, 255, 0)), + YELLOW("Yellow", Color.yellow), + LIGHTBLUE("LightBlue", new Color(135, 206, 250)), + MAGENTA("Magenta", Color.magenta), + ORANGE("Orange", Color.orange), + WHITE("White", Color.white), + UNKOWN("", Color.BLACK); + + public String name; + public Color color; + + private ColorCode(String name, Color color) + { + this.name = name; + this.color = color; + } + + public String getName() + { + return this.name; + } + + /** gets a ColorCode from any of the following + * + * @param obj - Integer,String,LiquidData,ColorCode + * @return Color NONE if it can't find it */ + public static ColorCode get(Object obj) + { + if (obj instanceof Integer && ((Integer) obj) < ColorCode.values().length) + { + return ColorCode.values()[((Integer) obj)]; + } + else if (obj instanceof ColorCode) + { + return (ColorCode) obj; + } + else if (obj instanceof String) + { + for (int i = 0; i < ColorCode.values().length; i++) + { + if (((String) obj).equalsIgnoreCase(ColorCode.get(i).getName())) + { + return ColorCode.get(i); + } + } + } + return UNKOWN; + } + + /** Used on anything that is coded for a set color for varies reasons */ + public static interface IColorCoded + { + /** Returns the ColorCode of the object */ + public ColorCode getColor(); + + /** Sets the ColorCode of the Object */ + public boolean setColor(Object obj); + } + + public static interface IColoredItem + { + /** Returns the ColorCode of the object */ + public ColorCode getColor(ItemStack stack); + + /** Sets the ColorCode of the Object */ + public boolean setColor(ItemStack stack, Object obj); + } + + public static interface IColoredId + { + /** Returns the ColorCode of the object */ + public ColorCode getColor(int i); + } + + public static interface IColoredBlock + { + /** Returns the ColorCode of the object */ + public ColorCode getColor(World world, int x, int y, int z); + + /** Sets the ColorCode of the Object */ + public void setColor(World world, int x, int y, int z, Object obj); + } + +} diff --git a/src/com/dark/interfaces/IAimable.java b/src/com/dark/interfaces/IAimable.java new file mode 100644 index 000000000..4dae3f419 --- /dev/null +++ b/src/com/dark/interfaces/IAimable.java @@ -0,0 +1,23 @@ +package com.dark.interfaces; + +import universalelectricity.core.vector.Vector3; + +/** Applied to objects that can be aimed by yaw and pitch. This is used by things like sentry guns, + * vehicles, or mining tools. + * + * @author DarkGuardsman */ +public interface IAimable +{ + /** Vector which runs from the objects eyes(or gun). Should be right outside the objects bounds + * but no farther than that. */ + public Vector3 getLook(); + + /** X pitch, Y is yaw, z is roll. Roll is almost never used */ + public Vector3 getRotation(); + + /** This does not set the rotation but rather moves the current rotation by the given values */ + public void updateRotation(float pitch, float yaw, float roll); + + /** Forces the rotation to the angles */ + public void setRotation(float pitch, float yaw, float roll); +} diff --git a/src/com/dark/interfaces/IMultiBlock.java b/src/com/dark/interfaces/IMultiBlock.java new file mode 100644 index 000000000..3428798a1 --- /dev/null +++ b/src/com/dark/interfaces/IMultiBlock.java @@ -0,0 +1,22 @@ +package com.dark.interfaces; + + +import net.minecraft.tileentity.TileEntity; +import universalelectricity.core.vector.Vector3; + +/** Interface to be applied to tile entity blocks that occupies more than one block space. Useful for + * large machines. + * + * @author Calclavia */ +public interface IMultiBlock extends IBlockActivated +{ + /** Called when this multiblock is created + * + * @param placedPosition - The position the block was placed at */ + public void onCreate(Vector3 placedPosition); + + /** Called when one of the multiblocks of this block is destroyed + * + * @param callingBlock - The tile entity who called the onDestroy function */ + public void onDestroy(TileEntity callingBlock); +} diff --git a/src/com/dark/interfaces/IToolReadOut.java b/src/com/dark/interfaces/IToolReadOut.java new file mode 100644 index 000000000..8486f086b --- /dev/null +++ b/src/com/dark/interfaces/IToolReadOut.java @@ -0,0 +1,34 @@ +package com.dark.interfaces; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.ForgeDirection; + +/** Simple way to control the read-out display over several tools when they are used on the + * tileEntity + * + * @author DarkGuardsman */ +public interface IToolReadOut +{ + /** Grabs the message displayed to the user on right click of the machine with the given tool + * + * @param user + * @param side - may not work correctly yet but should give you a side + * @return - a string to be displayed to the player for a reading. automatically adds ReadOut: + * to the beginning */ + public String getMeterReading(EntityPlayer user, ForgeDirection side, EnumTools tool); + + public static enum EnumTools + { + PIPE_GUAGE(), + MULTI_METER(); + + public static EnumTools get(int meta) + { + if (meta < EnumTools.values().length) + { + return EnumTools.values()[meta]; + } + return null; + } + } +} diff --git a/src/com/dark/prefab/BlockMulti.java b/src/com/dark/prefab/BlockMulti.java new file mode 100644 index 000000000..5e631010e --- /dev/null +++ b/src/com/dark/prefab/BlockMulti.java @@ -0,0 +1,180 @@ +package com.dark.prefab; + +import java.util.List; +import java.util.Random; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import net.minecraftforge.common.Configuration; +import universalelectricity.core.UniversalElectricity; +import universalelectricity.core.vector.Vector3; + +import com.builtbroken.common.Pair; +import com.dark.DarkCore; +import com.dark.IExtraInfo.IExtraBlockInfo; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class BlockMulti extends BlockContainer implements IExtraBlockInfo +{ + public String textureName = null; + public String channel = ""; + + public BlockMulti() + { + super(DarkCore.CONFIGURATION.getBlock("MultiBlock", DarkCore.getNextID()).getInt(), UniversalElectricity.machine); + this.setHardness(0.8F); + this.setUnlocalizedName("multiBlock"); + this.setChannel(DarkCore.CHANNEL); + } + + public BlockMulti setChannel(String channel) + { + this.channel = channel; + return this; + } + + @Override + public BlockMulti setTextureName(String name) + { + this.textureName = name; + return this; + } + + public void makeFakeBlock(World worldObj, Vector3 position, Vector3 mainBlock) + { + worldObj.setBlock(position.intX(), position.intY(), position.intZ(), this.blockID); + ((TileEntityMulti) worldObj.getBlockTileEntity(position.intX(), position.intY(), position.intZ())).setMainBlock(mainBlock); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IconRegister iconRegister) + { + if (this.textureName != null) + { + this.blockIcon = iconRegister.registerIcon(this.textureName); + } + else + { + super.registerIcons(iconRegister); + } + } + + @Override + public void breakBlock(World world, int x, int y, int z, int par5, int par6) + { + TileEntity tileEntity = world.getBlockTileEntity(x, y, z); + + if (tileEntity instanceof TileEntityMulti) + { + ((TileEntityMulti) tileEntity).onBlockRemoval(); + } + + super.breakBlock(world, x, y, z, par5, par6); + } + + /** Called when the block is right clicked by the player. This modified version detects electric + * items and wrench actions on your machine block. Do not override this function. Use + * machineActivated instead! (It does the same thing) */ + @Override + public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) + { + TileEntityMulti tileEntity = (TileEntityMulti) par1World.getBlockTileEntity(x, y, z); + return tileEntity.onBlockActivated(par1World, x, y, z, par5EntityPlayer); + } + + /** Returns the quantity of items to drop on block destruction. */ + @Override + public int quantityDropped(Random par1Random) + { + return 0; + } + + @Override + public int getRenderType() + { + return -1; + } + + @Override + public boolean isOpaqueCube() + { + return false; + } + + @Override + public boolean renderAsNormalBlock() + { + return false; + } + + @Override + public TileEntity createNewTileEntity(World var1) + { + return new TileEntityMulti(this.channel); + } + + @Override + public ItemStack getPickBlock(MovingObjectPosition target, World par1World, int x, int y, int z) + { + TileEntity tileEntity = par1World.getBlockTileEntity(x, y, z); + Vector3 mainBlockPosition = ((TileEntityMulti) tileEntity).mainBlockPosition; + + if (mainBlockPosition != null) + { + int mainBlockID = par1World.getBlockId(mainBlockPosition.intX(), mainBlockPosition.intY(), mainBlockPosition.intZ()); + + if (mainBlockID > 0) + { + return Block.blocksList[mainBlockID].getPickBlock(target, par1World, mainBlockPosition.intX(), mainBlockPosition.intY(), mainBlockPosition.intZ()); + } + } + + return null; + } + + @Override + public void getTileEntities(int blockID, Set>> list) + { + list.add(new Pair>("DMMultiBlock", TileEntityMulti.class)); + + } + + @Override + @SideOnly(Side.CLIENT) + public void getClientTileEntityRenderers(List, TileEntitySpecialRenderer>> list) + { + + } + + @Override + public boolean hasExtraConfigs() + { + // TODO Auto-generated method stub + return false; + } + + @Override + public void loadExtraConfigs(Configuration config) + { + // TODO Auto-generated method stub + + } + + @Override + public void loadOreNames() + { + // TODO Auto-generated method stub + + } +} \ No newline at end of file diff --git a/src/com/dark/prefab/DataPack.java b/src/com/dark/prefab/DataPack.java new file mode 100644 index 000000000..976dff8b0 --- /dev/null +++ b/src/com/dark/prefab/DataPack.java @@ -0,0 +1,75 @@ +package com.dark.prefab; + +import net.minecraft.nbt.NBTTagCompound; + +import com.dark.save.ISaveObj; +import com.dark.save.NBTFileHelper; + +/** Wrapper for data to be sent threw a network to a device + * + * @author DarkGuardsman */ +public class DataPack implements ISaveObj, Cloneable +{ + private Object[] data; + + public DataPack(Object... data) + { + this.data = data; + } + + public Object[] getData() + { + return this.data; + } + + @Override + public void save(NBTTagCompound nbt) + { + if (data != null) + { + nbt.setInteger("dataCnt", data.length); + for (int i = 0; i < data.length; i++) + { + if (data[i] != null) + { + NBTFileHelper.saveObject(nbt, "data" + i, data[i]); + } + } + } + } + + @Override + public void load(NBTTagCompound nbt) + { + if (nbt.hasKey("dataCnt")) + { + int dataLength = nbt.getInteger("dataCnt"); + data = new Object[dataLength]; + for (int i = 0; i < dataLength; i++) + { + if (nbt.hasKey("data" + i)) + { + data[i] = NBTFileHelper.loadObject(nbt, "data" + i); + } + } + } + + } + + @Override + public DataPack clone() + { + return new DataPack(this.data); + } + + public boolean isEqual(DataPack pack) + { + return this.data != null && pack.data != null && this.data.equals(pack.data); + } + + @Override + public String toString() + { + return "DataPack [Obj:" + (this.data != null ? data.length : "none") + "]"; + } +} diff --git a/src/com/dark/prefab/EnergyHelper.java b/src/com/dark/prefab/EnergyHelper.java new file mode 100644 index 000000000..e5916a977 --- /dev/null +++ b/src/com/dark/prefab/EnergyHelper.java @@ -0,0 +1,81 @@ +package com.dark.prefab; + + +import ic2.api.item.IElectricItemManager; +import ic2.api.item.ISpecialElectricItem; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.ForgeDirection; +import universalelectricity.compatibility.Compatibility; +import universalelectricity.core.item.ElectricItemHelper; +import universalelectricity.core.item.IItemElectric; + +public class EnergyHelper +{ + + /** Recharges electric item. */ + public static void recharge(ItemStack itemStack, TileEntityEnergyMachine machine) + { + if (itemStack != null) + { + if (itemStack.getItem() instanceof IItemElectric) + { + machine.setEnergyStored(machine.getEnergyStored() - ElectricItemHelper.chargeItem(itemStack, machine.getProvide(ForgeDirection.UNKNOWN))); + + } + else if (itemStack.getItem() instanceof ISpecialElectricItem) + { + ISpecialElectricItem electricItem = (ISpecialElectricItem) itemStack.getItem(); + IElectricItemManager manager = electricItem.getManager(itemStack); + float energy = Math.max(machine.getProvide(ForgeDirection.UNKNOWN) * Compatibility.IC2_RATIO, 0); + energy = manager.charge(itemStack, (int) (energy * Compatibility.TO_IC2_RATIO), 0, false, false) * Compatibility.IC2_RATIO; + machine.provideElectricity(energy, true); + } + } + } + + /** Discharges electric item. */ + public static void discharge(ItemStack itemStack, TileEntityEnergyMachine machine) + { + if (itemStack != null) + { + if (itemStack.getItem() instanceof IItemElectric) + { + machine.setEnergyStored(machine.getEnergyStored() + ElectricItemHelper.dischargeItem(itemStack, machine.getRequest(ForgeDirection.UNKNOWN))); + + } + else if (itemStack.getItem() instanceof ISpecialElectricItem) + { + ISpecialElectricItem electricItem = (ISpecialElectricItem) itemStack.getItem(); + + if (electricItem.canProvideEnergy(itemStack)) + { + IElectricItemManager manager = electricItem.getManager(itemStack); + float energy = Math.max(machine.getRequest(ForgeDirection.UNKNOWN) * Compatibility.IC2_RATIO, 0); + energy = manager.discharge(itemStack, (int) (energy * Compatibility.TO_IC2_RATIO), 0, false, false); + machine.receiveElectricity(energy, true); + } + } + } + } + + public static boolean isBatteryItem(ItemStack itemStack) + { + if (itemStack != null) + { + if (itemStack.getItem() instanceof IItemElectric) + { + return true; + } + else if (itemStack.getItem() instanceof ISpecialElectricItem) + { + ISpecialElectricItem electricItem = (ISpecialElectricItem) itemStack.getItem(); + + if (electricItem.canProvideEnergy(itemStack)) + { + return true; + } + } + } + return false; + } +} diff --git a/src/com/dark/prefab/RecipeLoader.java b/src/com/dark/prefab/RecipeLoader.java new file mode 100644 index 000000000..be73fe820 --- /dev/null +++ b/src/com/dark/prefab/RecipeLoader.java @@ -0,0 +1,92 @@ +package com.dark.prefab; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +/** Recipe system to make it easier to load recipes for a mod + * + * @author DarkGuardsman */ +public abstract class RecipeLoader +{ + protected static Object circuit; + protected static Object circuit2; + protected static Object circuit3; + protected static Object steel; + protected static Object steelPlate; + protected static Object motor; + protected static Object bronze; + protected static Object bronzePlate; + protected static Object copper; + protected static Object copperPlate; + + static boolean loaded = false; + + /** Should be called to load recipes. The main class only loads ore name items to decrease + * chances of missing items in recipes */ + public void loadRecipes() + { + if (!loaded) + { + /* Vinalla items load first */ + circuit = Item.redstoneRepeater; + circuit2 = Item.comparator; + steel = Item.ingotIron; + steelPlate = Item.ingotGold; + copper = Item.ingotIron; + copperPlate = Item.ingotGold; + motor = Block.pistonBase; + bronze = Item.ingotIron; + bronzePlate = Item.ingotGold; + /* Ore directory items load over the vinalla ones if they are present */ + if (OreDictionary.getOres("basicCircuit").size() > 0) + { + circuit = "basicCircuit"; + } + if (OreDictionary.getOres("advancedCircuit").size() > 0) + { + circuit = "advancedCircuit"; + } + if (OreDictionary.getOres("ingotSteel").size() > 0) + { + steel = "ingotSteel"; + } + if (OreDictionary.getOres("plateSteel").size() > 0) + { + steelPlate = "plateSteel"; + } + if (OreDictionary.getOres("motor").size() > 0) + { + motor = "motor"; + } + if (OreDictionary.getOres("ingotBronze").size() > 0) + { + bronze = "ingotBronze"; + } + if (OreDictionary.getOres("plateBronze").size() > 0) + { + bronzePlate = "plateBronze"; + } + if (OreDictionary.getOres("copperBronze").size() > 0) + { + bronze = "copperBronze"; + } + if (OreDictionary.getOres("copperBronze").size() > 0) + { + bronzePlate = "copperBronze"; + } + } + } + + public ItemStack setStackSize(ItemStack stack, int amount) + { + if (stack != null) + { + ItemStack itemStack = stack.copy(); + itemStack.stackSize = amount; + return itemStack; + } + return stack; + } +} diff --git a/src/com/dark/prefab/TileEntityMulti.java b/src/com/dark/prefab/TileEntityMulti.java new file mode 100644 index 000000000..c3c3525ef --- /dev/null +++ b/src/com/dark/prefab/TileEntityMulti.java @@ -0,0 +1,140 @@ +package com.dark.prefab; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.INetworkManager; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.Packet250CustomPayload; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import universalelectricity.core.vector.Vector3; +import universalelectricity.prefab.network.IPacketReceiver; + +import com.dark.interfaces.IMultiBlock; +import com.dark.network.PacketHandler; +import com.google.common.io.ByteArrayDataInput; + +/** This is a multiblock to be used for blocks that are bigger than one block. + * + * @author Calclavia */ +public class TileEntityMulti extends TileEntity implements IPacketReceiver +{ + // The the position of the main block + public Vector3 mainBlockPosition; + public String channel; + + public TileEntityMulti() + { + + } + + public TileEntityMulti(String channel) + { + this.channel = channel; + } + + public void setMainBlock(Vector3 mainBlock) + { + this.mainBlockPosition = mainBlock; + + if (!this.worldObj.isRemote) + { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + } + + @Override + public Packet getDescriptionPacket() + { + if (this.mainBlockPosition != null) + { + if (this.channel == null || this.channel == "" && this.getBlockType() instanceof BlockMulti) + { + this.channel = ((BlockMulti) this.getBlockType()).channel; + } + + return PacketHandler.instance().getTilePacket(this.channel, this, this.mainBlockPosition.intX(), this.mainBlockPosition.intY(), this.mainBlockPosition.intZ()); + + } + + return null; + } + + public void onBlockRemoval() + { + if (this.mainBlockPosition != null) + { + TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.mainBlockPosition.intX(), this.mainBlockPosition.intY(), this.mainBlockPosition.intZ()); + + if (tileEntity != null && tileEntity instanceof IMultiBlock) + { + IMultiBlock mainBlock = (IMultiBlock) tileEntity; + + if (mainBlock != null) + { + mainBlock.onDestroy(this); + } + } + } + } + + public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer) + { + if (this.mainBlockPosition != null) + { + TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.mainBlockPosition.intX(), this.mainBlockPosition.intY(), this.mainBlockPosition.intZ()); + + if (tileEntity != null) + { + if (tileEntity instanceof IMultiBlock) + { + return ((IMultiBlock) tileEntity).onActivated(par5EntityPlayer); + } + } + } + + return false; + } + + /** Reads a tile entity from NBT. */ + @Override + public void readFromNBT(NBTTagCompound nbt) + { + super.readFromNBT(nbt); + this.mainBlockPosition = new Vector3(nbt.getCompoundTag("mainBlockPosition")); + } + + /** Writes a tile entity to NBT. */ + @Override + public void writeToNBT(NBTTagCompound nbt) + { + super.writeToNBT(nbt); + + if (this.mainBlockPosition != null) + { + nbt.setCompoundTag("mainBlockPosition", this.mainBlockPosition.writeToNBT(new NBTTagCompound())); + } + } + + /** Determines if this TileEntity requires update calls. + * + * @return True if you want updateEntity() to be called, false if not */ + @Override + public boolean canUpdate() + { + return false; + } + + @Override + public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream) + { + try + { + this.mainBlockPosition = new Vector3(dataStream.readInt(), dataStream.readInt(), dataStream.readInt()); + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/com/dark/prefab/invgui/GuiInvMachineBase.java b/src/com/dark/prefab/invgui/GuiInvMachineBase.java new file mode 100644 index 000000000..c312aba41 --- /dev/null +++ b/src/com/dark/prefab/invgui/GuiInvMachineBase.java @@ -0,0 +1,9 @@ +package com.dark.prefab.invgui; + +/** Same as the GuiMachineBase but supports inventory pages + * + * @author DarkGuardsman */ +public class GuiInvMachineBase +{ + +} diff --git a/src/com/dark/prefab/invgui/GuiMachineBase.java b/src/com/dark/prefab/invgui/GuiMachineBase.java new file mode 100644 index 000000000..ade13721e --- /dev/null +++ b/src/com/dark/prefab/invgui/GuiMachineBase.java @@ -0,0 +1,190 @@ +package com.dark.prefab.invgui; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import com.dark.DarkCore; +import com.dark.prefab.TileEntityMachine; +import com.dark.prefab.invgui.GuiButtonImage.ButtonIcon; + +import cpw.mods.fml.client.FMLClientHandler; + +/** To be used with all machine that have a gui to allow generic settings and feature all all devices + * + * @author DarkGuardsman */ +public class GuiMachineBase extends GuiBase +{ + + public static final ResourceLocation TEXTURE = new ResourceLocation(DarkCore.DOMAIN, DarkCore.GUI_DIRECTORY + "gui_grey.png"); + + protected static final int MAX_BUTTON_ID = 3; + protected TileEntityMachine tileEntity; + protected EntityPlayer entityPlayer; + protected Object mod; + protected int guiID = -1, guiID2 = -1, guiID3 = -1; + protected ButtonIcon guiIcon = ButtonIcon.CHEST, guiIcon2 = ButtonIcon.PERSON, guiIcon3 = ButtonIcon.BLANK; + protected String invName = "Home", invName2 = "2", invName3 = "3"; + + public GuiMachineBase(Object mod, EntityPlayer player, TileEntityMachine tileEntity) + { + this.tileEntity = tileEntity; + this.entityPlayer = player; + this.guiSize.y = 380 / 2; + this.mod = mod; + } + + @SuppressWarnings("unchecked") + @Override + public void initGui() + { + super.initGui(); + this.buttonList.clear(); + + // Inventory, Should be the Gui the machine opens to unless it has no inventory + if (guiID != -1) + this.buttonList.add(new GuiButtonImage(0, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 0, guiIcon)); + + // Machine settings + if (guiID2 != -1) + this.buttonList.add(new GuiButtonImage(1, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 22, guiIcon2)); + + if (guiID3 != -1) + this.buttonList.add(new GuiButtonImage(2, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 44, guiIcon3)); + + } + + @Override + protected void actionPerformed(GuiButton button) + { + switch (button.id) + { + case 0: + { + if (guiID != -1) + entityPlayer.openGui(mod, guiID, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord); + break; + } + case 1: + { + if (guiID2 != -1) + entityPlayer.openGui(mod, guiID2, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord); + break; + } + case 2: + { + if (guiID3 != -1) + entityPlayer.openGui(mod, guiID3, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord); + break; + } + } + } + + /** Draw the foreground layer for the GuiContainer (everything in front of the items) */ + @Override + protected void drawForegroundLayer(int x, int y, float var1) + { + this.fontRenderer.drawString("\u00a77" + tileEntity.getInvName(), (int) (this.guiSize.intX() / 2 - 7 * 2.5), 4, 4210752); + /** Render Tool Tips */ + if (((GuiButtonImage) this.buttonList.get(0)).isIntersect(x, y) && guiID != -1) + { + this.drawTooltip(x - this.c.intX(), y - this.c.intY() + 10, invName); + } + else if (((GuiButtonImage) this.buttonList.get(1)).isIntersect(x, y) && guiID2 != -1) + { + this.drawTooltip(x - this.c.intX(), y - this.c.intY() + 10, invName2); + } + else if (((GuiButtonImage) this.buttonList.get(2)).isIntersect(x, y) && guiID3 != -1) + { + this.drawTooltip(x - this.c.intX(), y - this.c.intY() + 10, invName3); + } + } + + /** Draw the background layer for the GuiContainer (everything behind the items) */ + @Override + protected void drawBackgroundLayer(int x, int y, float var1) + { + FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + int containerWidth = (this.width - this.guiSize.intX()) / 2; + int containerHeight = (this.height - this.guiSize.intY()) / 2; + this.drawTexturedModalRect(containerWidth, containerHeight, 0, 0, this.guiSize.intX(), this.guiSize.intY()); + } + + @Override + public void drawTooltip(int x, int y, String... toolTips) + { + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + + if (toolTips != null) + { + int var5 = 0; + int var6; + int var7; + + for (var6 = 0; var6 < toolTips.length; ++var6) + { + var7 = this.fontRenderer.getStringWidth(toolTips[var6]); + + if (var7 > var5) + { + var5 = var7; + } + } + + var6 = x + 12; + var7 = y - 12; + int var9 = 8; + + if (toolTips.length > 1) + { + var9 += 2 + (toolTips.length - 1) * 10; + } + + if (this.c.intY() + var7 + var9 + 6 > this.height) + { + var7 = this.height - var9 - this.c.intY() - 6; + } + + this.zLevel = 300.0F; + int var10 = -267386864; + this.drawGradientRect(var6 - 3, var7 - 4, var6 + var5 + 3, var7 - 3, var10, var10); + this.drawGradientRect(var6 - 3, var7 + var9 + 3, var6 + var5 + 3, var7 + var9 + 4, var10, var10); + this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 + var9 + 3, var10, var10); + this.drawGradientRect(var6 - 4, var7 - 3, var6 - 3, var7 + var9 + 3, var10, var10); + this.drawGradientRect(var6 + var5 + 3, var7 - 3, var6 + var5 + 4, var7 + var9 + 3, var10, var10); + int var11 = 1347420415; + int var12 = (var11 & 16711422) >> 1 | var11 & -16777216; + this.drawGradientRect(var6 - 3, var7 - 3 + 1, var6 - 3 + 1, var7 + var9 + 3 - 1, var11, var12); + this.drawGradientRect(var6 + var5 + 2, var7 - 3 + 1, var6 + var5 + 3, var7 + var9 + 3 - 1, var11, var12); + this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 - 3 + 1, var11, var11); + this.drawGradientRect(var6 - 3, var7 + var9 + 2, var6 + var5 + 3, var7 + var9 + 3, var12, var12); + + for (int var13 = 0; var13 < toolTips.length; ++var13) + { + String var14 = "\u00a77" + toolTips[var13]; + + this.fontRenderer.drawStringWithShadow(var14, var6, var7, -1); + + if (var13 == 0) + { + var7 += 2; + } + + var7 += 10; + } + + this.zLevel = 0.0F; + } + } + +} diff --git a/src/com/dark/prefab/invgui/GuiMachineContainer.java b/src/com/dark/prefab/invgui/GuiMachineContainer.java new file mode 100644 index 000000000..cdc512e05 --- /dev/null +++ b/src/com/dark/prefab/invgui/GuiMachineContainer.java @@ -0,0 +1,205 @@ +package com.dark.prefab.invgui; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.tileentity.TileEntity; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import com.dark.prefab.TileEntityMachine; +import com.dark.prefab.invgui.GuiButtonImage.ButtonIcon; + +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public abstract class GuiMachineContainer extends GuiContainer +{ + protected static final int MAX_BUTTON_ID = 3; + protected TileEntityMachine tileEntity; + protected EntityPlayer entityPlayer; + protected Object mod; + protected int guiID = -1, guiID2 = -1, guiID3 = -1; + protected ButtonIcon guiIcon = ButtonIcon.CHEST, guiIcon2 = ButtonIcon.PERSON, guiIcon3 = ButtonIcon.BLANK; + protected String invName = "Home", invName2 = "2", invName3 = "3"; + + protected int containerWidth; + protected int containerHeight; + + public GuiMachineContainer(Object mod, Container container, InventoryPlayer inventoryPlayer, TileEntityMachine tileEntity) + { + super(container); + this.tileEntity = tileEntity; + this.entityPlayer = inventoryPlayer.player; + this.ySize = 380 / 2; + this.mod = mod; + } + + @SuppressWarnings("unchecked") + @Override + public void initGui() + { + super.initGui(); + this.buttonList.clear(); + containerWidth = (this.width - this.xSize) / 2; + containerHeight = (this.height - this.ySize) / 2; + if (guiID != -1) + this.buttonList.add(new GuiButtonImage(0, containerWidth - 22, containerHeight + 0, guiIcon)); + if (guiID2 != -1) + this.buttonList.add(new GuiButtonImage(1, containerWidth - 22, containerHeight + 22, guiIcon2)); + if (guiID3 != -1) + this.buttonList.add(new GuiButtonImage(2, containerWidth - 22, containerHeight + 44, guiIcon3)); + + } + + @Override + protected void actionPerformed(GuiButton button) + { + super.actionPerformed(button); + switch (button.id) + { + case 0: + { + if (guiID != -1) + this.entityPlayer.openGui(mod, guiID, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord); + break; + } + case 1: + { + if (guiID2 != -1) + this.entityPlayer.openGui(mod, guiID2, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord); + break; + } + case 2: + { + if (guiID3 != -1) + this.entityPlayer.openGui(mod, guiID3, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord); + break; + } + } + } + + /** Draw the foreground layer for the GuiContainer (everything in front of the items) */ + @Override + protected void drawGuiContainerForegroundLayer(int x, int y) + { + this.fontRenderer.drawString("\u00a77" + tileEntity.getInvName(), (int) (this.xSize / 2 - 7 * 2.5), 4, 4210752); + + /** Render Tool Tips */ + if (((GuiButtonImage) this.buttonList.get(0)).isIntersect(x, y)) + { + this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName); + } + else if (((GuiButtonImage) this.buttonList.get(1)).isIntersect(x, y)) + { + this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName2); + } + else if (((GuiButtonImage) this.buttonList.get(2)).isIntersect(x, y)) + { + this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName3); + } + } + + /** Draw the background layer for the GuiContainer (everything behind the items) */ + @Override + protected void drawGuiContainerBackgroundLayer(float par1, int x, int y) + { + FMLClientHandler.instance().getClient().renderEngine.bindTexture(GuiMachineBase.TEXTURE); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + int containerWidth = (this.width - this.xSize) / 2; + int containerHeight = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(containerWidth, containerHeight, 0, 0, this.xSize, this.ySize); + } + + public void drawTooltip(int x, int y, String... toolTips) + { + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + + if (toolTips != null) + { + int var5 = 0; + int var6; + int var7; + + for (var6 = 0; var6 < toolTips.length; ++var6) + { + var7 = this.fontRenderer.getStringWidth(toolTips[var6]); + + if (var7 > var5) + { + var5 = var7; + } + } + + var6 = x + 12; + var7 = y - 12; + int var9 = 8; + + if (toolTips.length > 1) + { + var9 += 2 + (toolTips.length - 1) * 10; + } + + if (this.guiTop + var7 + var9 + 6 > this.height) + { + var7 = this.height - var9 - this.guiTop - 6; + } + + this.zLevel = 300.0F; + int var10 = -267386864; + this.drawGradientRect(var6 - 3, var7 - 4, var6 + var5 + 3, var7 - 3, var10, var10); + this.drawGradientRect(var6 - 3, var7 + var9 + 3, var6 + var5 + 3, var7 + var9 + 4, var10, var10); + this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 + var9 + 3, var10, var10); + this.drawGradientRect(var6 - 4, var7 - 3, var6 - 3, var7 + var9 + 3, var10, var10); + this.drawGradientRect(var6 + var5 + 3, var7 - 3, var6 + var5 + 4, var7 + var9 + 3, var10, var10); + int var11 = 1347420415; + int var12 = (var11 & 16711422) >> 1 | var11 & -16777216; + this.drawGradientRect(var6 - 3, var7 - 3 + 1, var6 - 3 + 1, var7 + var9 + 3 - 1, var11, var12); + this.drawGradientRect(var6 + var5 + 2, var7 - 3 + 1, var6 + var5 + 3, var7 + var9 + 3 - 1, var11, var12); + this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 - 3 + 1, var11, var11); + this.drawGradientRect(var6 - 3, var7 + var9 + 2, var6 + var5 + 3, var7 + var9 + 3, var12, var12); + + for (int var13 = 0; var13 < toolTips.length; ++var13) + { + String var14 = "\u00a77" + toolTips[var13]; + + this.fontRenderer.drawStringWithShadow(var14, var6, var7, -1); + + if (var13 == 0) + { + var7 += 2; + } + + var7 += 10; + } + + this.zLevel = 0.0F; + } + } + + public int getGuiTop() + { + return this.guiTop; + } + + public int getGuiLeft() + { + return this.guiLeft; + } + + public TileEntity getTile() + { + return this.tileEntity; + } +} diff --git a/src/dark/api/reciepes/AssemblyObjectManager.java b/src/dark/api/reciepes/AssemblyObjectManager.java new file mode 100644 index 000000000..a62fee4e0 --- /dev/null +++ b/src/dark/api/reciepes/AssemblyObjectManager.java @@ -0,0 +1,45 @@ +package dark.api.reciepes; + +import java.util.HashMap; + +import net.minecraft.item.ItemStack; + +import com.builtbroken.common.Pair; + +public class AssemblyObjectManager +{ + /** Generic item or block based recipes. Entity recipes are handled by the entity */ + private HashMap, IAssemblyRecipe> itemRecipes = new HashMap(); + + private static AssemblyObjectManager instance; + + public static AssemblyObjectManager instance() + { + if (instance == null) + { + instance = new AssemblyObjectManager(); + } + return instance; + } + + public IAssemblyRecipe getRecipeFor(Object object) + { + IAssemblyRecipe re = null; + + if (re instanceof IAssemblyObject) + { + re = ((IAssemblyObject) object).getRecipe(object); + } + + if (re == null && object instanceof ItemStack) + { + re = itemRecipes.get(new Pair(((ItemStack) object).itemID, ((ItemStack) object).getItemDamage())); + if (re == null && ((ItemStack) object).getItem() instanceof IAssemblyObject) + { + re = ((IAssemblyObject) ((ItemStack) object).getItem()).getRecipe(object); + } + } + + return re; + } +} diff --git a/src/dark/api/reciepes/IAssemblier.java b/src/dark/api/reciepes/IAssemblier.java new file mode 100644 index 000000000..3b61f7b72 --- /dev/null +++ b/src/dark/api/reciepes/IAssemblier.java @@ -0,0 +1,38 @@ +package dark.api.reciepes; + +/** Machine or entity that is creating a AssemblyObject. Avoid actually storing the recipe item if + * there is one. Instead do what a few other mods do an give the illusion of the recipe being + * imprinted into the machine while letting the player keep the item + * + * @author DarkGuardsman */ +public interface IAssemblier +{ + /** @param assembler - this, used in the case that an item is the assembler, or even a block + * without a tileEntiy. Eg a Workbench is an example of this as it has no tileEntiy but supports + * crafting + * @return current recipe */ + public IAssemblyRecipe getCurrentRecipe(Object object); + + /** @param assembler - this, used in the case that an item is the assembler, or even a block + * without a tileEntiy. Eg a Workbench is an example of this as it has no tileEntiy but supports + * crafting + * @return true if the recipe was set correctly */ + public boolean setCurrentRecipe(Object assembler, IAssemblyRecipe recipe); + + /** @param assembler - this, used in the case that an item is the assembler, or even a block + * without a tileEntiy. Eg a Workbench is an example of this as it has no tileEntiy but supports + * crafting + * @return current work in progress */ + public IAssemblyObject getCurrentWork(Object assembler); + + /** Checks if the recipe can be created by this assembler. Should be used in cases were an + * assembler is designed for one task type + * + * @param assembler - this, used in the case that an item is the assembler, or even a block + * without a tileEntiy. Eg a Workbench is an example of this as it has no tileEntiy but supports + * crafting + * @param recipe - recipe + * @return */ + public boolean canSupportRecipe(Object assembler, IAssemblyRecipe recipe); + +} diff --git a/src/dark/api/reciepes/IAssemblyObject.java b/src/dark/api/reciepes/IAssemblyObject.java new file mode 100644 index 000000000..e3c18a1bc --- /dev/null +++ b/src/dark/api/reciepes/IAssemblyObject.java @@ -0,0 +1,19 @@ +package dark.api.reciepes; + +/** Applied to objects that are not complete and are being constructed from parts slowly. Used mainly + * with assembly line armbots to create large objects like rockets automatically. + * + * @author DarkGuardsman */ +public interface IAssemblyObject +{ + /** Gets the recipe that this object is being build from */ + public IAssemblyRecipe getRecipe(Object object); + + /** Called each time the assembler makes a change to the object. Use this to trigger render + * updates of the object */ + public void onChanged(Object object); + + public void setStep(Object object, int step); + + public int getStep(Object object); +} diff --git a/src/dark/api/reciepes/IAssemblyRecipe.java b/src/dark/api/reciepes/IAssemblyRecipe.java new file mode 100644 index 000000000..56f1c4ee7 --- /dev/null +++ b/src/dark/api/reciepes/IAssemblyRecipe.java @@ -0,0 +1,19 @@ +package dark.api.reciepes; + +import net.minecraft.item.ItemStack; + +/** WIP feature to allow an item/block to be slowly built one step at a time. Object can be an + * ItemStack, Entity, or even an object just for this purpose. Though if its not world based you'll + * need to inform the assembler that it exists + * + * @author Darkgaurdsman */ +public interface IAssemblyRecipe +{ + /** Cost in materials(ItemStack) to complete the next step in the build process */ + public ItemStack[] getCostAtStep(Object object, int step); + + /** Number of steps to complete the crafting */ + public int getSteps(Object object); + + public void nextStep(Object Object); +} diff --git a/src/dark/api/reciepes/IBlueprint.java b/src/dark/api/reciepes/IBlueprint.java new file mode 100644 index 000000000..e6f89548c --- /dev/null +++ b/src/dark/api/reciepes/IBlueprint.java @@ -0,0 +1,17 @@ +package dark.api.reciepes; + +/** Advanced version of the assemblyRecipe. This is also used to display the recipe like a blueprint + * + * @author DarkGuardsman */ +public interface IBlueprint extends IAssemblyRecipe +{ + /** Check if the blueprint can be used by the object + * + * @param object - player, assembler,drone, entity, block, tileEntity + * @return true if it can be used. This is mainly used for disabling recipes for players */ + public boolean canUseBlueprint(Object object); + + /** Should a blueprint item be created for this blueprint. */ + public boolean createItemFor(); + +} diff --git a/src/dark/api/reciepes/IInjectorMold.java b/src/dark/api/reciepes/IInjectorMold.java new file mode 100644 index 000000000..4de0cf469 --- /dev/null +++ b/src/dark/api/reciepes/IInjectorMold.java @@ -0,0 +1,15 @@ +package dark.api.reciepes; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +/** Items that are used as molds by the mold-injector to create items from liquid materials. Eg iron + * armor from molten iron fluid + * + * @author Darkguardsman */ +public interface IInjectorMold +{ + public ItemStack getOutput(FluidStack fluid, ItemStack mold); + + public FluidStack getRequirement(ItemStack mold); +} diff --git a/src/dark/api/reciepes/IProcessable.java b/src/dark/api/reciepes/IProcessable.java new file mode 100644 index 000000000..b8473a587 --- /dev/null +++ b/src/dark/api/reciepes/IProcessable.java @@ -0,0 +1,22 @@ +package dark.api.reciepes; + +import net.minecraft.item.ItemStack; + +/** Simple interface that allows an item to control how its salvaged, processed, or refined by a + * processor. This is 100% optional as the processor by default can break down most items. The only + * reason to use this is for more complex processing or were the item was created with NBT. + * + * @author Darkgaurdsman */ +public interface IProcessable +{ + /** Can this item be Processed by the machine */ + public boolean canProcess(ProcessorType type, ItemStack stack); + + /** Gets the output array of items when this item is processed by a processor machine + * + * @param type - type of machine see ProcessorTypes enum for info + * @param stack - ItemStack of this item or block + * @return Array of all item outputed, Make sure to return less than or equal to the amount of + * items it takes to craft only one of this item */ + public ItemStack[] getProcesserOutput(ProcessorType type, ItemStack stack); +} diff --git a/src/dark/api/reciepes/MachineRecipeHandler.java b/src/dark/api/reciepes/MachineRecipeHandler.java new file mode 100644 index 000000000..261ae375c --- /dev/null +++ b/src/dark/api/reciepes/MachineRecipeHandler.java @@ -0,0 +1,292 @@ +package dark.api.reciepes; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemTool; + +import com.builtbroken.common.Pair; +import com.dark.helpers.AutoCraftingManager; + +/** Recipes for ore processor machines + * + * @author DarkGuardsman */ +public class MachineRecipeHandler +{ + private static Random random = new Random(); + + static + { + newProcessorRecipe(ProcessorType.CRUSHER, Block.stone, Block.cobblestone); + newProcessorRecipe(ProcessorType.CRUSHER, Block.oreDiamond, Item.diamond); + newProcessorRecipe(ProcessorType.CRUSHER, Block.oreLapis, new ItemStack(Item.dyePowder.itemID, 4, 4)); + newProcessorRecipe(ProcessorType.CRUSHER, Block.oreRedstone, new ItemStack(Item.redstone.itemID, 4, 0)); + newProcessorRecipe(ProcessorType.CRUSHER, Block.oreEmerald, new ItemStack(Item.redstone.itemID, 4, 0)); + + newProcessorRecipe(ProcessorType.GRINDER, new ItemStack(Block.cobblestone.blockID, 1, 0), new ItemStack(Block.sand.blockID, 1, 0)); + newProcessorRecipe(ProcessorType.GRINDER, Block.glass, Block.sand); + + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.GRINDER, Block.stone, Block.cobblestone); + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.GRINDER, Block.cobblestoneMossy, Block.cobblestone); + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.GRINDER, Block.glass, Block.sand); + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.CRUSHER, Item.stick, null); + + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.CRUSHER, Block.stone, Block.cobblestone); + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.CRUSHER, Block.cobblestoneMossy, Block.cobblestone); + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.CRUSHER, Item.stick, null); + + //TODO replace these with ItemOreDirv glass shards + MachineRecipeHandler.newAltProcessorOutput(ProcessorType.CRUSHER, Block.glass, Block.sand); + } + + /** Creates a new recipe for the type of processor machine + * + * @param type - machine type + * @param in - input item, stacksize is ignored + * @param out - output item */ + public static void newProcessorRecipe(ProcessorType type, Object in, Object out) + { + newProcessorRecipe(type, in, out, -1, -1); + } + + /** Creates a new recipe for the type of processor machine + * + * @param type - machine type + * @param in - input item, stacksize is ignored + * @param out - output item + * @param min - min stacksize to return as output + * @param max- max stacksize to return as output */ + public static void newProcessorRecipe(ProcessorType type, Object in, Object out, int min, int max) + { + newProcessorRecipe(type, in, out, min, max, false); + } + + /** Creates a new recipe for the type of processor machine + * + * @param type - machine type + * @param in - input item, stacksize is ignored + * @param out - output item + * @param min - min stacksize to return as output + * @param max- max stacksize to return as output + * @param ignoreNBT - only use this if your item's nbt doesn't play a factor in what items were + * used to craft it */ + public static void newProcessorRecipe(ProcessorType type, Object in, Object out, int min, int max, boolean ignoreNBT) + { + if (in != null && out != null && type != null) + { + ItemStack input = convertToItemStack(in); + ItemStack output = convertToItemStack(out); + if (input != null && output != null && type.recipes != null) + { + if (!ignoreNBT && (input.getTagCompound() != null || input.isItemEnchanted())) + { + System.out.println("[MachineRecipeHandler]Error: NBT or Enchanted Items must use the IProccesable interface to properlly handle recipe outputs."); + System.out.println("[MachineRecipeHandler]Item>> Data: " + input.toString() + " Name: " + input.getItem().getUnlocalizedName()); + return; + } + if (min == -1) + { + min = output.stackSize; + } + if (max == -1 || max < min) + { + max = output.stackSize; + } + type.recipes.put(new Pair(input.itemID, input.getItemDamage()), new ProcessorRecipe(output, min, max)); + } + } + } + + /** Used to track items that should be converted to different items during salvaging. */ + public static void newAltProcessorOutput(ProcessorType type, Object in, Object out) + { + if (in != null && out != null && type != null) + { + ItemStack input = convertToItemStack(in); + ItemStack output = convertToItemStack(out); + if (input != null && output != null && type.altOutput != null) + { + type.altOutput.put(new Pair(input.itemID, input.getItemDamage()), output); + } + } + } + + /** Marks an itemstack as unsalvagable by all processors */ + public static void banProcessingOfItem(ItemStack stack) + { + if (stack != null) + { + for (ProcessorType type : ProcessorType.values()) + { + banProcessingOfItem(type, stack); + } + } + } + + /** Marks an itemstack as unusable by processors. This will jam the processor if the item enters + * it */ + public static void banProcessingOfItem(ProcessorType type, ItemStack stack) + { + if (type != null && stack != null) + { + type.banList.add(new Pair(stack.itemID, stack.getItemDamage())); + } + } + + /** Converts an object input into an itemstack for use */ + private static ItemStack convertToItemStack(Object object) + { + if (object instanceof ItemStack) + { + ItemStack stack = (ItemStack) object; + if (stack.getItemDamage() < 0) + { + stack.setItemDamage(0); + } + return stack; + } + if (object instanceof Block) + { + return new ItemStack(((Block) object).blockID, 1, -1); + } + if (object instanceof Item) + { + return new ItemStack(((Item) object).itemID, 1, -1); + } + return null; + } + + /** Gets the lit of items that are created from the input item stack. General this will be an + * array of one item. However, in salavaging cases it can be up to 8 items. + * + * @param type - Processor type + * @param inputStack - item stack input ignores stacksize + * @return array of itemStacks */ + public static ItemStack[] getProcessorOutput(ProcessorType type, ItemStack inputStack) + { + if (inputStack != null && type != null) + { + ItemStack[] reList = null; + if (inputStack.getItem() instanceof IProcessable) + { + if (!((IProcessable) inputStack.getItem()).canProcess(type, inputStack)) + { + return null; + } + reList = ((IProcessable) inputStack.getItem()).getProcesserOutput(type, inputStack); + } + if (reList == null) + { + reList = getOuputNormal(type, inputStack); + } + if (reList == null) + { + //TODO Disabled due to bug and needs to be fixed to make the processors more functional + //reList = salvageItem(type, inputStack); + } + return reList; + } + return null; + } + + /** Salvages an itemStack for the items used to craft it + * + * @param type - processor type used to determine damage results + * @param stack - itemStack being salvaged + * @return Array of all items salvaged */ + public static ItemStack[] salvageItem(ProcessorType type, ItemStack stack) + { + return salvageItem(type, stack, true); + } + + /** Salvages an itemStack for the items used to craft it + * + * @param type - processor type used to determine damage results + * @param stack - itemStack being salvaged + * @param damage - damage the output items. Eg ironIngot becomes ironDust, or ironScraps + * @return Array of all items salvaged */ + public static ItemStack[] salvageItem(ProcessorType type, ItemStack stack, boolean damage) + { + float bar = 0.1f; + //Allow tools and armor to be salvaged but at a very low rate + if ((stack.getItem() instanceof ItemArmor || stack.getItem() instanceof ItemTool) && stack.isItemDamaged()) + { + bar = (stack.getItemDamage() / stack.getMaxDamage()); + } + ItemStack[] reList = salvageItem(stack, bar); + if (damage && reList != null && type.altOutput != null) + { + for (int i = 0; i < reList.length; i++) + { + if (type.altOutput.containsKey(new Pair(reList[i].itemID, reList[i].getItemDamage()))) + { + reList[i] = convertToItemStack(type.altOutput.get(new Pair(reList[i].itemID, reList[i].getItemDamage()))); + } + } + } + return reList; + } + + /** Salvages an itemStack for the items used to craft it + * + * @param stack - itemStack being salvaged + * @param bar - chance per item that the random must be above inorder to salvage the output + * @return Array of all items salvaged */ + public static ItemStack[] salvageItem(ItemStack stack, float bar) + { + //TODO find a way around having to force recipe to be the same stack size of the salvage. Maybe percentage based salvaging or min stacksize from machine? + ItemStack[] recipeList = AutoCraftingManager.getReverseRecipe(stack.copy(), stack.stackSize); + if (recipeList != null) + { + ItemStack[] reList = new ItemStack[recipeList.length]; + boolean items = false; + for (int i = 0; i < recipeList.length; i++) + { + if (random.nextFloat() >= bar) + { + reList[i] = recipeList[i].copy(); + items = true; + if (recipeList[i].itemID < Block.blocksList.length && Block.blocksList[recipeList[i].itemID] != null && recipeList[i].getItemDamage() > 16) + { + reList[i].setItemDamage(0); + } + + } + } + return items ? reList : null; + } + return null; + } + + public static ItemStack[] getOuputNormal(ProcessorType type, ItemStack stack) + { + if (type.recipes != null) + { + ProcessorRecipe re = type.recipes.get(new Pair(stack.itemID, -1)); + if (re == null || re.output == null) + { + re = type.recipes.get(new Pair(stack.itemID, stack.getItemDamage())); + } + if (type.altOutput != null && (re == null || re.output == null)) + { + return new ItemStack[] { type.altOutput.get(new Pair(stack.itemID, stack.getItemDamage())) }; + } + if (re != null && re.output != null) + { + ItemStack output = re.output.copy(); + output.stackSize = Math.min(re.maxItemsOut, re.minItemsOut + random.nextInt(re.minItemsOut)); + if (re.chancePerItem < 1.0f) + { + + } + return new ItemStack[] { output }; + } + } + + return null; + } + +} diff --git a/src/dark/api/reciepes/ProcessorRecipe.java b/src/dark/api/reciepes/ProcessorRecipe.java new file mode 100644 index 000000000..38db8e16d --- /dev/null +++ b/src/dark/api/reciepes/ProcessorRecipe.java @@ -0,0 +1,23 @@ +package dark.api.reciepes; + +import net.minecraft.item.ItemStack; + +/** Processor Recipe output Container. Input is controlled by the processor recipes class. */ +public class ProcessorRecipe +{ + /** Output of the recipe */ + public ItemStack output; + /** Chance per item after the stack size has been calculated from min and max size */ + public float chancePerItem = 1.0f; + /** Min the recipe can output */ + public int minItemsOut = -1; + /** Max the recipe can output */ + public int maxItemsOut = -1; + + public ProcessorRecipe(ItemStack output, int min, int max) + { + this.output = output; + this.minItemsOut = min; + this.maxItemsOut = max; + } +} diff --git a/src/dark/api/reciepes/ProcessorType.java b/src/dark/api/reciepes/ProcessorType.java new file mode 100644 index 000000000..26fd0b240 --- /dev/null +++ b/src/dark/api/reciepes/ProcessorType.java @@ -0,0 +1,28 @@ +package dark.api.reciepes; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import net.minecraft.item.ItemStack; + +import com.builtbroken.common.Pair; + +/** Enum of machines that support a simple A -> B processor recipe format. More complex machine will + * have there own recipe handlers + * + * @author Darkguardsman */ +public enum ProcessorType +{ + /** Pistons that smash the object */ + CRUSHER(), + /** Several disks that shred the item up */ + GRINDER(), + /** Grinds the edge or surface of the item sharpening it */ + SHARPENING_STONE(), + /** Breaks down an item carefully giving an almost complete output of item used to craft it */ + SALVAGER(); + public HashMap, ProcessorRecipe> recipes = new HashMap(); + public HashMap, ItemStack> altOutput = new HashMap(); + public List> banList = new ArrayList(); +}