move some stuff from core machine

This commit is contained in:
DarkGuardsman 2013-12-18 16:00:37 -05:00
parent 7449c78567
commit b7d6a8c6cf
42 changed files with 4420 additions and 4 deletions

View file

@ -25,7 +25,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
/** Handler to make registering all parts of a mod's objects that are loaded into the game by forge
*
* @author DarkGuardsman */
public class ModObjectRegistry
public class CoreRegistry
{
public static HashMap<Block, String> registredBlocks = new HashMap<Block, String>();
public static HashMap<Item, String> registredItems = new HashMap<Item, String>();
@ -37,12 +37,12 @@ public class ModObjectRegistry
public static Block createNewBlock(String name, String modID, Class<? extends Block> blockClass)
{
return ModObjectRegistry.createNewBlock(name, modID, blockClass, true);
return CoreRegistry.createNewBlock(name, modID, blockClass, true);
}
public static Block createNewBlock(String name, String modID, Class<? extends Block> blockClass, boolean canDisable)
{
return ModObjectRegistry.createNewBlock(name, modID, blockClass, null, canDisable);
return CoreRegistry.createNewBlock(name, modID, blockClass, null, canDisable);
}
public static Block createNewBlock(String name, String modID, Class<? extends Block> blockClass, Class<? extends ItemBlock> itemClass)
@ -72,7 +72,7 @@ public class ModObjectRegistry
{
registredBlocks.put(block, name);
proxy.registerBlock(block, itemClass, name, modID);
ModObjectRegistry.finishCreation(block);
CoreRegistry.finishCreation(block);
}
}
return block;

View file

@ -2,16 +2,30 @@ package com.dark;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
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.tile.network.NetworkUpdateHandler;
import com.dark.save.SaveManager;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.relauncher.Side;
public class DarkCore
{
private static DarkCore instance;
private boolean pre, load, post;
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/";
public static final String MODEL_DIRECTORY = TEXTURE_DIRECTORY + "models/";
public static final String GUI_DIRECTORY = TEXTURE_DIRECTORY + "gui/";
public static final String CHANNEL = "DARKCORE";
/* START IDS */
public static int BLOCK_ID_PRE = 3100;
@ -26,6 +40,39 @@ public class DarkCore
return instance;
}
public void preLoad()
{
if (!pre)
{
MinecraftForge.EVENT_BUS.register(new FluidHelper());
MinecraftForge.EVENT_BUS.register(SaveManager.instance());
TickRegistry.registerTickHandler(NetworkUpdateHandler.instance(), Side.SERVER);
TickRegistry.registerScheduledTickHandler(new PlayerKeyHandler(), Side.CLIENT);
UniversalElectricity.initiate();
Compatibility.initiate();
pre = true;
}
}
public void Load()
{
if (!load)
{
ExternalModHandler.init();
CoreRegistry.masterBlockConfig.load();
load = true;
}
}
public void postLoad()
{
if (!post)
{
CoreRegistry.masterBlockConfig.save();
post = true;
}
}
/** Gets the next unused ID in the block list. Does not prevent config file issues after the file
* has been made */
public static int getNextID()
@ -63,4 +110,5 @@ public class DarkCore
ITEM_ID_PREFIX = id + 1;
return id;
}
}

View file

@ -0,0 +1,68 @@
package com.dark;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class IndustryCreativeTab extends CreativeTabs
{
public ItemStack itemStack = new ItemStack(Item.ingotIron, 1, 0);
private static IndustryCreativeTab tabAutomation = new IndustryCreativeTab("Automation");
private static IndustryCreativeTab tabIndustrial = new IndustryCreativeTab("Industrial");
private static IndustryCreativeTab tabHydrualic = new IndustryCreativeTab("Hydraulic");
private static IndustryCreativeTab tabMining = new IndustryCreativeTab("Mining");
public IndustryCreativeTab(String label)
{
super(label);
}
@Override
public ItemStack getIconItemStack()
{
return this.itemStack;
}
public void setIconItemStack(ItemStack stack)
{
this.itemStack = stack;
}
public static IndustryCreativeTab tabAutomation()
{
if (tabAutomation == null)
{
tabAutomation = new IndustryCreativeTab("Automation");
}
return tabAutomation;
}
public static IndustryCreativeTab tabIndustrial()
{
if (tabIndustrial == null)
{
tabIndustrial = new IndustryCreativeTab("Industrial");
}
return tabIndustrial;
}
public static IndustryCreativeTab tabHydraulic()
{
if (tabHydrualic == null)
{
tabHydrualic = new IndustryCreativeTab("Hydraulic");
}
return tabHydrualic;
}
public static IndustryCreativeTab tabMining()
{
if (tabMining == null)
{
tabMining = new IndustryCreativeTab("Mining");
}
return tabMining;
}
}

View file

@ -0,0 +1,21 @@
package com.dark.fluid;
import net.minecraftforge.fluids.Fluid;
/** Some common Fluid that other mods use
*
* @author DarkGuardsman */
public enum EnumFluid
{
FUEL(new Fluid("fuel").setUnlocalizedName("fluid.fuel.name")),
OIL(new Fluid("oil").setUnlocalizedName("fluid.oil.name").setDensity(1500).setViscosity(4700)),
BIOFUEL(new Fluid("biofuel").setUnlocalizedName("fluid.biofuel.name")),
WASTE(new Fluid("waste").setUnlocalizedName("fluid.waste.name").setDensity(1300).setViscosity(1800));
public final Fluid fluid;
private EnumFluid(Fluid fluid)
{
this.fluid = fluid;
}
}

View file

@ -0,0 +1,76 @@
package com.dark.fluid;
import com.builtbroken.common.science.ChemElement;
import com.builtbroken.common.science.ChemicalCompound;
/** Enum of gases used to create all the gas fluids
*
* @author DarkGuardsman */
public enum EnumGas
{
CARBONDIOXIDE("Carbon DiOxide", false),
OXYGEN(ChemElement.Oxygen, 2f, true),
BUTANE(ChemicalCompound.BUTANE, true),
METHANE(ChemicalCompound.METHANE, true),
NATURAL_GAS("Natural Gas", false),
PROPANE("Propane", false);
/** Name used when creating this as a fluid */
public final String fluidName;
/** Name used to display to the players */
public final String name;
/** Object data reference that was used to create this gas, can be a ChemicalCompound, Element,
* or Fluid */
public final Object data;
public boolean enabled = false;
/** Only used for elements since when used as a gas they sometimes bind together */
private float molePerGasMolecule = 1.0f;
/** Local instance of the gas used when the getGas method is called */
private Gas gas;
private EnumGas(String name, boolean enabled)
{
this.fluidName = name.replace(" ", "").toLowerCase();
this.name = name;
data = null;
this.enabled = enabled;
}
private EnumGas(ChemicalCompound compound, boolean enabled)
{
this.fluidName = "gas:" + compound.compoundName.replace(" ", "").toLowerCase();
this.name = compound.compoundName;
data = compound;
this.enabled = enabled;
}
private EnumGas(ChemElement element, float molesPerGasMolecule, boolean enabled)
{
this.fluidName = "gas:" + element.elementName.replace(" ", "").toLowerCase();
this.name = element.elementName;
data = element;
this.enabled = enabled;
this.molePerGasMolecule = molesPerGasMolecule;
}
public Gas getGas()
{
if (gas == null)
{
gas = new Gas(fluidName);
if (data instanceof ChemElement)
{
gas.setDensity((int) ((ChemElement) data).density * 1000);
}
else if (data instanceof ChemicalCompound)
{
gas.setDensity((int) ((ChemicalCompound) data).density * 1000);
}
else
{
gas.setDensity(-1000);
}
}
return gas;
}
}

View file

@ -0,0 +1,58 @@
package com.dark.fluid;
import java.util.ArrayList;
import java.util.List;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
/** Tank that has a filter on the fluid ids it will accept
*
* @author DarkGuardsman */
public class FilteredTank extends FluidTank
{
private List<Integer> fluidIds = new ArrayList<Integer>();
boolean gas = true;
boolean liquid = true;
public FilteredTank(int capacity, int... fluidIds)
{
this(capacity, true, true, fluidIds);
}
public FilteredTank(int capacity, boolean gas, boolean liquid, int... fluidIds)
{
super(capacity);
this.gas = gas;
this.liquid = liquid;
for (int id : fluidIds)
{
this.fluidIds.add(id);
}
}
public FilteredTank(FluidStack stack, int capacity)
{
super(stack, capacity);
}
public FilteredTank(Fluid fluid, int amount, int capacity)
{
super(fluid, amount, capacity);
}
@Override
public int fill(FluidStack resource, boolean doFill)
{
if (resource != null && resource.getFluid() != null && (!gas || gas && resource.getFluid().isGaseous()) && (!liquid || liquid && !resource.getFluid().isGaseous()))
{
if (fluidIds.contains(resource.fluidID))
{
return super.fill(resource, doFill);
}
}
return 0;
}
}

View file

@ -0,0 +1,432 @@
package com.dark.fluid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fluids.IFluidHandler;
import universalelectricity.core.vector.Vector3;
import com.builtbroken.common.Pair;
import com.dark.helpers.AutoCraftingManager;
public class FluidHelper
{
public static List<Pair<Integer, Integer>> replacableBlockMeta = new ArrayList<Pair<Integer, Integer>>();
public static List<Block> replacableBlocks = new ArrayList<Block>();
public static List<Block> nonBlockDropList = new ArrayList<Block>();
static
{
/* Adds default fluid replaceable blocks */
replacableBlocks.add(Block.crops);
replacableBlocks.add(Block.deadBush);
nonBlockDropList.add(Block.deadBush);
//TODO have waterlily raise and lower when automaticly filling or draining a block rather than remove it
replacableBlocks.add(Block.waterlily);
replacableBlocks.add(Block.mushroomRed);
replacableBlocks.add(Block.mushroomBrown);
replacableBlocks.add(Block.netherStalk);
replacableBlocks.add(Block.sapling);
replacableBlocks.add(Block.melonStem);
nonBlockDropList.add(Block.melonStem);
replacableBlocks.add(Block.pumpkinStem);
nonBlockDropList.add(Block.pumpkinStem);
replacableBlocks.add(Block.tallGrass);
replacableBlocks.add(Block.torchWood);
}
/** Gets the block's fluid if it has one
*
* @param world - world we are working in
* @param vector - 3D location in world
* @return @Fluid that the block is */
public static Fluid getLiquidFromBlock(World world, Vector3 vector)
{
return FluidHelper.getFluidFromBlockID(vector.getBlockID(world));
}
/** Gets a fluid from blockID */
public static Fluid getFluidFromBlockID(int id)
{
if (Block.blocksList[id] instanceof IFluidBlock)
{
return ((IFluidBlock) Block.blocksList[id]).getFluid();
}
else if (id == Block.waterStill.blockID || id == Block.waterMoving.blockID)
{
return FluidRegistry.getFluid("water");
}
else if (id == Block.lavaStill.blockID || id == Block.lavaMoving.blockID)
{
return FluidRegistry.getFluid("lava");
}
return null;
}
public static FluidStack getStack(FluidStack stack, int amount)
{
if (stack != null)
{
FluidStack newStack = stack.copy();
newStack.amount = amount;
return newStack;
}
return stack;
}
/** Drains a block of fluid
*
* @Note sets the block with a client update only. Doesn't tick the block allowing for better
* placement of fluid that can flow infinitely
*
* @param doDrain - do the action
* @return FluidStack drained from the block */
public static FluidStack drainBlock(World world, Vector3 node, boolean doDrain)
{
return drainBlock(world, node, doDrain, 2);
}
/** Drains a block of fluid
*
* @param doDrain - do the action
* @param update - block update flag to use
* @return FluidStack drained from the block */
public static FluidStack drainBlock(World world, Vector3 node, boolean doDrain, int update)
{
if (world == null || node == null)
{
return null;
}
int blockID = node.getBlockID(world);
int meta = node.getBlockMetadata(world);
Block block = Block.blocksList[blockID];
if (block != null)
{
if (block instanceof IFluidBlock && ((IFluidBlock) block).canDrain(world, node.intX(), node.intY(), node.intZ()))
{
return ((IFluidBlock) block).drain(world, node.intX(), node.intY(), node.intZ(), doDrain);
}
else if ((block.blockID == Block.waterStill.blockID || block.blockID == Block.waterMoving.blockID) && node.getBlockMetadata(world) == 0)
{
if (doDrain)
{
Vector3 vec = node.clone().modifyPositionFromSide(ForgeDirection.UP);
if (vec.getBlockID(world) == Block.waterlily.blockID)
{
vec.setBlock(world, 0, 0, update);
node.setBlock(world, blockID, meta);
}
else
{
node.setBlock(world, 0, 0, update);
}
}
return new FluidStack(FluidRegistry.getFluid("water"), FluidContainerRegistry.BUCKET_VOLUME);
}
else if ((block.blockID == Block.lavaStill.blockID || block.blockID == Block.lavaMoving.blockID) && node.getBlockMetadata(world) == 0)
{
if (doDrain)
{
node.setBlock(world, 0, 0, update);
}
return new FluidStack(FluidRegistry.getFluid("lava"), FluidContainerRegistry.BUCKET_VOLUME);
}
}
return null;
}
/** Checks to see if a non-fluid block is able to be filled with fluid */
public static boolean isFillableBlock(World world, Vector3 node)
{
if (world == null || node == null)
{
return false;
}
int blockID = node.getBlockID(world);
int meta = node.getBlockMetadata(world);
Block block = Block.blocksList[blockID];
if (drainBlock(world, node, false) != null)
{
return false;
}
else if (block == null || block.blockID == 0 || block.isAirBlock(world, node.intX(), node.intY(), node.intZ()))
{
return true;
}
else if (!(block instanceof IFluidBlock || block instanceof BlockFluid) && block.isBlockReplaceable(world, node.intX(), node.intY(), node.intZ()) || replacableBlockMeta.contains(new Pair<Integer, Integer>(blockID, meta)) || replacableBlocks.contains(block))
{
return true;
}
return false;
}
/** Checks to see if a fluid related block is able to be filled */
public static boolean isFillableFluid(World world, Vector3 node)
{
if (world == null || node == null)
{
return false;
}
int blockID = node.getBlockID(world);
int meta = node.getBlockMetadata(world);
Block block = Block.blocksList[blockID];
//TODO when added change this to call canFill and fill
if (drainBlock(world, node, false) != null)
{
return false;
}
else if (block instanceof IFluidBlock || block instanceof BlockFluid)
{
return meta != 0;
}
return false;
}
/** Helper method to fill a location with a fluid
*
* Note: This does not update the block to prevent the liquid from flowing
*
* @return */
public static int fillBlock(World world, Vector3 node, FluidStack stack, boolean doFill)
{
if ((isFillableBlock(world, node) || isFillableFluid(world, node)) && stack != null && stack.amount >= FluidContainerRegistry.BUCKET_VOLUME)
{
if (doFill)
{
int blockID = node.getBlockID(world);
int meta = node.getBlockMetadata(world);
Block block = Block.blocksList[blockID];
Vector3 vec = node.clone().modifyPositionFromSide(ForgeDirection.UP);
if (block != null)
{
if (block.blockID == Block.waterlily.blockID && vec.getBlockID(world) == 0)
{
vec.setBlock(world, blockID, meta);
}
else if (block != null && replacableBlocks.contains(block) && !nonBlockDropList.contains(block))
{
block.dropBlockAsItem(world, node.intX(), node.intY(), node.intZ(), meta, 1);
block.breakBlock(world, node.intX(), node.intY(), node.intZ(), blockID, meta);
}
}
node.setBlock(world, stack.getFluid().getBlockID());
}
return FluidContainerRegistry.BUCKET_VOLUME;
}
return 0;
}
/** Fills all instances of IFluidHandler surrounding the origin
*
* @param stack - FluidStack that will be filled into the tanks
* @param doFill - Actually perform the action or simulate action
* @param ignore - ForgeDirections to ignore
* @return amount of fluid that was used from the stack */
public static int fillTanksAllSides(World world, Vector3 origin, FluidStack stack, boolean doFill, ForgeDirection... ignore)
{
int filled = 0;
FluidStack fillStack = stack != null ? stack.copy() : null;
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
if (fillStack == null || fillStack.amount <= 0)
{
return filled;
}
if (ignore != null)
{
for (int i = 0; i < ignore.length; i++)
{
if (direction == ignore[i])
{
continue;
}
}
}
filled += fillTankSide(world, origin, stack, doFill, direction);
fillStack = getStack(stack, stack.amount - filled);
}
return filled;
}
/** Fills an instance of IFluidHandler in the given direction
*
* @param stack - FluidStack to fill the tank will
* @param doFill - Actually perform the action or simulate action
* @param direction - direction to fill in from the origin
* @return amount of fluid that was used from the stack */
public static int fillTankSide(World world, Vector3 origin, FluidStack stack, boolean doFill, ForgeDirection direction)
{
TileEntity entity = origin.clone().modifyPositionFromSide(direction).getTileEntity(world);
if (entity instanceof IFluidHandler && ((IFluidHandler) entity).canFill(direction.getOpposite(), stack.getFluid()))
{
return ((IFluidHandler) entity).fill(direction.getOpposite(), stack, doFill);
}
return 0;
}
/** Does all the work needed to fill or drain an item of fluid when a player clicks on the block. */
public static boolean playerActivatedFluidItem(World world, int x, int y, int z, EntityPlayer entityplayer, int side)
{
//TODO add double click support similar to the crates in assembly line
ItemStack current = entityplayer.inventory.getCurrentItem();
if (current != null && world.getBlockTileEntity(x, y, z) instanceof IFluidHandler)
{
FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(current);
IFluidHandler tank = (IFluidHandler) world.getBlockTileEntity(x, y, z);
if (liquid != null)
{
if (tank.fill(ForgeDirection.UNKNOWN, liquid, true) != 0 && !entityplayer.capabilities.isCreativeMode)
{
entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, AutoCraftingManager.consumeItem(current, 1));
}
return true;
}
else
{
FluidStack available = tank.drain(ForgeDirection.getOrientation(side), Integer.MAX_VALUE, false);
if (available != null)
{
ItemStack filled = FluidContainerRegistry.fillFluidContainer(available, current);
liquid = FluidContainerRegistry.getFluidForFilledItem(filled);
if (liquid != null)
{
if (!entityplayer.capabilities.isCreativeMode)
{
if (current.stackSize > 1)
{
if (!entityplayer.inventory.addItemStackToInventory(filled))
{
return false;
}
else
{
entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, AutoCraftingManager.consumeItem(current, 1));
}
}
else
{
entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, AutoCraftingManager.consumeItem(current, 1));
entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, filled);
}
}
tank.drain(ForgeDirection.UNKNOWN, liquid.amount, true);
return true;
}
}
}
}
return false;
}
/** Drains an item of fluid and fills the tank with what was drained
*
* @param consumeItem - should it consume the item. Used mainly for creative mode players. This
* does effect the return of the method
* @return Item stack that would be returned if the item was drain of its fluid. Water bucket ->
* empty bucket */
public static ItemStack drainItem(ItemStack stack, IFluidHandler tank, ForgeDirection side)
{
if (stack != null && tank != null)
{
FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(stack);
if (liquid != null)
{
if (tank.fill(side, liquid, true) > 0)
{
return stack.getItem().getContainerItemStack(stack);
}
}
}
return stack;
}
/** Fills an item with fluid from the tank
*
* @param consumeItem - should it consume the item. Used mainly for creative mode players. This
* does effect the return of the method
* @return Item stack that would be returned if the item was filled with fluid. empty bucket ->
* water bucket */
public static ItemStack fillItem(ItemStack stack, IFluidHandler tank, ForgeDirection side)
{
if (stack != null && tank != null)
{
FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(stack);
FluidStack drainStack = tank.drain(side, Integer.MAX_VALUE, false);
if (liquid == null && drainStack != null)
{
ItemStack liquidItem = FluidContainerRegistry.fillFluidContainer(drainStack, stack);
if (tank.drain(side, FluidContainerRegistry.getFluidForFilledItem(liquidItem), true) != null)
{
return liquidItem;
}
}
}
return stack;
}
/** Builds a list of fluidStacks from FluidTankInfo general taken from an instanceof
* IFluidHandler */
public static List<FluidStack> getFluidList(FluidTankInfo... fluidTankInfos)
{
List<FluidStack> stackList = new ArrayList<FluidStack>();
HashMap<FluidStack, Integer> map = new HashMap<FluidStack, Integer>();
if (fluidTankInfos != null)
{
for (int i = 0; i < fluidTankInfos.length; i++)
{
FluidTankInfo info = fluidTankInfos[i];
if (info != null && info.fluid != null)
{
FluidStack stack = info.fluid;
if (map.containsKey(FluidHelper.getStack(stack, 0)))
{
map.put(FluidHelper.getStack(stack, 0), map.get(FluidHelper.getStack(stack, 0)) + stack.amount);
}
else
{
map.put(FluidHelper.getStack(stack, 0), stack.amount);
}
}
}
Iterator<Entry<FluidStack, Integer>> it = map.entrySet().iterator();
while (it.hasNext())
{
Entry<FluidStack, Integer> entry = it.next();
stackList.add(FluidHelper.getStack(entry.getKey(), entry.getValue()));
}
}
return stackList;
}
}

View file

@ -0,0 +1,17 @@
package com.dark.fluid;
import net.minecraftforge.fluids.Fluid;
/** These is an extension of the Fluid system forcing it to be a gas on creation
*
* @author Archadia, DarkGuardsman */
public class Gas extends Fluid
{
public Gas(String name)
{
super(name);
this.isGaseous = true;
this.density = -1000;
}
}

View file

@ -0,0 +1,38 @@
package com.dark.fluid;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
/** Version of the fluid tank that is restricted to gases only
*
* @author DarkGuardsman */
public class GasTank extends FluidTank
{
public GasTank(int capacity)
{
super(capacity);
}
public GasTank(FluidStack stack, int capacity)
{
super(stack, capacity);
}
public GasTank(Fluid fluid, int amount, int capacity)
{
super(fluid, amount, capacity);
}
@Override
public int fill(FluidStack resource, boolean doFill)
{
if (resource != null && resource.getFluid() != null && resource.getFluid().isGaseous())
{
return super.fill(resource, doFill);
}
return 0;
}
}

View file

@ -0,0 +1,38 @@
package com.dark.fluid;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
/** Version of the fluid tank that only supports liquids
*
* @author DarkGuardsman */
public class LiquidTank extends FluidTank
{
public LiquidTank(int capacity)
{
super(capacity);
}
public LiquidTank(FluidStack stack, int capacity)
{
super(stack, capacity);
}
public LiquidTank(Fluid fluid, int amount, int capacity)
{
super(fluid, amount, capacity);
}
@Override
public int fill(FluidStack resource, boolean doFill)
{
if (resource != null && resource.getFluid() != null && !resource.getFluid().isGaseous())
{
return super.fill(resource, doFill);
}
return 0;
}
}

View file

@ -0,0 +1,543 @@
package com.dark.helpers;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBucket;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe;
import com.builtbroken.common.Pair;
import cpw.mods.fml.relauncher.ReflectionHelper;
/** Rewrite of the imprinter crafting system into its own manageable class
*
* @author DarkGuardsman */
public class AutoCraftingManager
{
static boolean doDebug = false;
TileEntity craftingEntity;
IInventory craftingInv;
/** The entity must be an instance of IInventory to pass only the tileEntity */
public AutoCraftingManager(final IAutoCrafter entity)
{
this.craftingEntity = (TileEntity) entity;
if (entity instanceof IInventory)
{
this.craftingInv = (IInventory) entity;
}
}
/** Use only the entity if it is also an instance of IInventory */
public AutoCraftingManager(final IAutoCrafter entity, final IInventory inv)
{
this(entity);
if (inv != null)
{
this.craftingInv = inv;
}
}
public void printDebug(String pre, String msg)
{
if (doDebug)
{
System.out.println("[AutoCrafter]: " + pre + " > " + msg);
}
}
public static void printRecipe(Object[] objects)
{
//TODO format and make it look nice
for (Object obj : objects)
{
System.out.println(obj);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void printRecipes(ItemStack stack)
{
List<IRecipe> recipes = getRecipes(stack);
for (IRecipe recipe : recipes)
{
if (recipe.getRecipeOutput() != null)
{
if (AutoCraftingManager.areStacksEqual(recipe.getRecipeOutput(), stack))
{
if (recipe instanceof ShapedRecipes)
{
printRecipe(((ShapedRecipes) recipe).recipeItems);
}
else if (recipe instanceof ShapelessRecipes)
{
printRecipe(((ShapelessRecipes) recipe).recipeItems.toArray(new Object[1]));
}
else if (recipe instanceof ShapedOreRecipe)
{
ShapedOreRecipe oreRecipe = (ShapedOreRecipe) recipe;
printRecipe((Object[]) ReflectionHelper.getPrivateValue(ShapedOreRecipe.class, oreRecipe, "input"));
}
else if (recipe instanceof ShapelessOreRecipe)
{
ShapelessOreRecipe oreRecipe = (ShapelessOreRecipe) recipe;
ArrayList oreRecipeInput = (ArrayList) ReflectionHelper.getPrivateValue(ShapelessOreRecipe.class, oreRecipe, "input");
for (Object obj : oreRecipeInput)
{
System.out.println(obj);
}
}
}
}
}
}
/** Grabs a list of recipes that can be used to create the given item */
public static List<IRecipe> getRecipes(ItemStack stack)
{
List<IRecipe> recipes = new ArrayList<IRecipe>();
for (Object object : CraftingManager.getInstance().getRecipeList())
{
if (object instanceof IRecipe)
{
if (((IRecipe) object).getRecipeOutput() != null)
{
if (AutoCraftingManager.areStacksEqual(stack, ((IRecipe) object).getRecipeOutput()))
{
recipes.add((IRecipe) object);
}
}
}
}
return recipes;
}
/** Does this player's inventory contain the required resources to craft this item?
*
* @return Required items to make the desired item. */
@SuppressWarnings({ "unchecked", "rawtypes" })
public Pair<ItemStack, ItemStack[]> getIdealRecipe(ItemStack outputItem)
{
this.printDebug("IdealRecipe", outputItem.toString());
for (Object object : CraftingManager.getInstance().getRecipeList())
{
if (object instanceof IRecipe)
{
if (((IRecipe) object).getRecipeOutput() != null)
{
if (AutoCraftingManager.areStacksEqual(outputItem, ((IRecipe) object).getRecipeOutput()))
{
this.printDebug("IdealRecipe", "Output Match Found");
if (object instanceof ShapedRecipes)
{
if (this.hasResource(((ShapedRecipes) object).recipeItems) != null)
{
this.printDebug("IdealRecipe", "Shaped Recipe Found");
return new Pair<ItemStack, ItemStack[]>(((IRecipe) object).getRecipeOutput().copy(), ((ShapedRecipes) object).recipeItems);
}
}
else if (object instanceof ShapelessRecipes)
{
if (this.hasResource(((ShapelessRecipes) object).recipeItems.toArray(new ItemStack[1])) != null)
{
this.printDebug("IdealRecipe", "Shapeless Recipe Found");
return new Pair<ItemStack, ItemStack[]>(((IRecipe) object).getRecipeOutput().copy(), (ItemStack[]) ((ShapelessRecipes) object).recipeItems.toArray(new ItemStack[1]));
}
}
else if (object instanceof ShapedOreRecipe)
{
ShapedOreRecipe oreRecipe = (ShapedOreRecipe) object;
Object[] oreRecipeInput = (Object[]) ReflectionHelper.getPrivateValue(ShapedOreRecipe.class, oreRecipe, "input");
ArrayList<ItemStack> hasResources = this.hasResource(oreRecipeInput);
if (hasResources != null)
{
this.printDebug("IdealRecipe", "ShapedOre Recipe Found");
return new Pair<ItemStack, ItemStack[]>(((IRecipe) object).getRecipeOutput().copy(), hasResources.toArray(new ItemStack[1]));
}
}
else if (object instanceof ShapelessOreRecipe)
{
ShapelessOreRecipe oreRecipe = (ShapelessOreRecipe) object;
ArrayList oreRecipeInput = (ArrayList) ReflectionHelper.getPrivateValue(ShapelessOreRecipe.class, oreRecipe, "input");
List<ItemStack> hasResources = this.hasResource(oreRecipeInput.toArray());
if (hasResources != null)
{
this.printDebug("IdealRecipe", "ShapelessOre Recipe Found");
return new Pair<ItemStack, ItemStack[]>(((IRecipe) object).getRecipeOutput().copy(), hasResources.toArray(new ItemStack[1]));
}
}
}
}
}
}
return null;
}
/** Gets a basic array containing all items that were used to craft the given item. Doesn't sort
* threw the recipes and will return the first possible recipe */
@SuppressWarnings({ "rawtypes", "unchecked" })
public static ItemStack[] getReverseRecipe(ItemStack outputItem, int outputSize)
{
for (Object object : CraftingManager.getInstance().getRecipeList())
{
if (object instanceof IRecipe)
{
if (((IRecipe) object).getRecipeOutput() != null)
{
if (((IRecipe) object).getRecipeOutput().isItemEqual(outputItem) && (outputSize == -1 || ((IRecipe) object).getRecipeOutput().stackSize == outputItem.stackSize))
{
if (object instanceof ShapedRecipes)
{
return ((ShapedRecipes) object).recipeItems.clone();
}
else if (object instanceof ShapelessRecipes)
{
return (ItemStack[]) ((ShapelessRecipes) object).recipeItems.toArray(new ItemStack[9]).clone();
}
else if (object instanceof ShapedOreRecipe)
{
ShapedOreRecipe oreRecipe = (ShapedOreRecipe) object;
Object[] recipeItems = (Object[]) ReflectionHelper.getPrivateValue(ShapedOreRecipe.class, oreRecipe, "input");
ItemStack[] actualResources;
if (recipeItems != null)
{
actualResources = new ItemStack[recipeItems.length];
for (int i = 0; i < recipeItems.length; i++)
{
if (recipeItems[i] instanceof ItemStack)
{
actualResources[i] = ((ItemStack) recipeItems[i]).copy();
}
else if (recipeItems[i] instanceof ArrayList)
{
Object[] ingredientsArray = ((ArrayList) recipeItems[i]).toArray();
for (int x = 0; x < ingredientsArray.length; x++)
{
if (ingredientsArray[x] != null && ingredientsArray[x] instanceof ItemStack)
{
actualResources[i] = ((ItemStack) ingredientsArray[x]).copy();
break;
}
}
}
}
return actualResources;
}
}
else if (object instanceof ShapelessOreRecipe)
{
ShapelessOreRecipe oreRecipe = (ShapelessOreRecipe) object;
return (ItemStack[]) ((ArrayList) ReflectionHelper.getPrivateValue(ShapelessOreRecipe.class, oreRecipe, "input")).toArray(new ItemStack[9]).clone();
}
}
}
}
}
return null;
}
/** Gets the itemStacks in the inv based on slots
*
* @param inv - @IInventory instance
* @param slots - slot # to be used
* @return array of itemStack the same size as the slots input array */
public ItemStack[] getInvItems(IInventory inv, int... slots)
{
ItemStack[] containingItems = new ItemStack[slots.length];
for (int slot = 0; slot < slots.length; slot++)
{
if (inv.getStackInSlot(slots[slot]) != null)
{
containingItems[slot] = inv.getStackInSlot(slots[slot]).copy();
}
}
return containingItems;
}
/** Returns if the following inventory has the following resource required.
*
* @param recipeItems - The items to be checked for the recipes. */
@SuppressWarnings("rawtypes")
public ArrayList<ItemStack> hasResource(Object[] recipeItems)
{
try
{
ItemStack[] containingItems = this.getInvItems(this.craftingInv, ((IAutoCrafter) this.craftingEntity).getCraftingInv());
this.printDebug("ResourceChecker", "Looking for items");
for (int i = 0; i < recipeItems.length && AutoCraftingManager.doDebug; i++)
{
this.printDebug("ResourceChecker", "Looking for " + recipeItems.toString());
}
/** The actual amount of resource required. Each ItemStack will only have stacksize of 1. */
ArrayList<ItemStack> actualResources = new ArrayList<ItemStack>();
int itemMatch = 0;
int itemInList = 0;
for (Object obj : recipeItems)
{
itemInList++;
if (obj instanceof ItemStack)
{
ItemStack recipeItem = (ItemStack) obj;
actualResources.add(recipeItem.copy());
if (recipeItem != null)
{
this.printDebug("ResourceChecker", "Item0" + itemInList + " = " + recipeItem.toString());
int match = this.doesItemExist(recipeItem, containingItems);
if (match >= 0)
{
containingItems[match] = AutoCraftingManager.decrStackSize(containingItems[match], recipeItem.stackSize);
this.printDebug("ResourceChecker", "Match found @" + match);
itemMatch++;
}
}
}
else if (obj instanceof ArrayList)
{
/** Look for various possible ingredients of the same item and try to match it. */
ArrayList ingredientsList = (ArrayList) obj;
Object[] ingredientsArray = ingredientsList.toArray();
this.printDebug("ResourceChecker", "Obj0" + itemInList + " = " + obj.toString());
for (int x = 0; x < ingredientsArray.length; x++)
{
if (ingredientsArray[x] != null && ingredientsArray[x] instanceof ItemStack)
{
ItemStack recipeItem = (ItemStack) ingredientsArray[x];
actualResources.add(recipeItem.copy());
if (recipeItem != null)
{
int match = this.doesItemExist(recipeItem, containingItems);
if (match >= 0)
{
containingItems[match] = AutoCraftingManager.decrStackSize(containingItems[match], recipeItem.stackSize);
this.printDebug("ResourceChecker", "Match found @" + match);
itemMatch++;
break;
}
}
}
}
}
else
{
this.printDebug("ResourceChecker", "Item0" + itemInList + " = null");
}
}
boolean resourcesFound = itemMatch >= actualResources.size();
this.printDebug("ResourceChecker", actualResources.size() + " items needed and " + itemMatch + " valid matches found");
this.printDebug("ResourceChecker", "has all resources been found? /n A: " + resourcesFound);
return resourcesFound ? actualResources : null;
}
catch (Exception e)
{
System.out.println("Failed to find recipes in the imprinter.");
e.printStackTrace();
}
return null;
}
/** Decreases the stack by a set amount
*
* @param stack - starting stack
* @param amount - amount of items
* @return the edited stack */
public static ItemStack decrStackSize(ItemStack stack, int amount)
{
if (stack != null)
{
ItemStack itemStack = stack.copy();
if (itemStack.stackSize <= amount)
{
return null;
}
else
{
itemStack.stackSize -= amount;
if (itemStack.stackSize <= 0)
{
return null;
}
return itemStack;
}
}
else
{
return null;
}
}
/** Checks if an item exist within the inv array
*
* @param recipeItem - itemstack being searched for
* @param containingItems - inv array containing the search bounds
* @return the point in the array the item was found -1 = the item was null or not valid -2 =
* the item was not found */
private int doesItemExist(ItemStack recipeItem, ItemStack[] containingItems)
{
if (recipeItem == null || recipeItem.itemID == 0 || recipeItem.stackSize <= 0)
{
return -1;
}
this.printDebug("ResourceChecker", "Checking inv for item " + recipeItem.toString());
for (int i = 0; i < containingItems.length; i++)
{
ItemStack checkStack = containingItems[i];
if (checkStack != null)
{
this.printDebug("ResourceChecker", " -----Item in slot0" + i + " = " + checkStack.toString());
if (AutoCraftingManager.areStacksEqual(recipeItem, checkStack))
{
this.printDebug("ResourceChecker", "Found matching item " + checkStack.toString());
return i;
}
}
}
return -2;
}
/** Checks if itemstack are equal based on crafting result rather than normal itemstack this is
* done so that if the itemstack returns with
*
* @param recipeItem - itemstack being compared
* @param checkStack - itemstack being comparted
* @return true if the items are a match for each other
*
* If the item can't be stack and is able to take damage the item will be check on damaged
* status
*
* If the item's meta data is not normal or in other words equals 32767 the meta data will be
* ignored */
public static boolean areStacksEqual(ItemStack recipeItem, ItemStack checkStack)
{
if (recipeItem == null || checkStack == null)
{
return false;
}
if (recipeItem.itemID < Block.blocksList.length && recipeItem.getItemDamage() == 32767)
{
return recipeItem.itemID == checkStack.itemID;
}
if (recipeItem.isItemStackDamageable())
{
return !recipeItem.isItemDamaged() && recipeItem.itemID == checkStack.itemID;
}
return recipeItem.isItemEqual(checkStack);
}
/** Consumes an item checking for extra conditions like container items
*
* @param stack - starting itemStack
* @param ammount - amount to consume
* @return what is left of the itemStack if any */
public static ItemStack consumeItem(ItemStack itemStack, int amount)
{
if (itemStack == null)
{
return null;
}
ItemStack stack = itemStack.copy();
if (stack.getItem() instanceof ItemBucket && stack.itemID != Item.bucketEmpty.itemID)
{
return new ItemStack(Item.bucketEmpty, 1);
}
if (stack.getItem().hasContainerItem())
{
ItemStack containerStack = stack.getItem().getContainerItemStack(stack);
if (containerStack.isItemStackDamageable() && containerStack.getItemDamage() > containerStack.getMaxDamage())
{
try
{
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(null, containerStack));
}
catch (Exception e)
{
}
return null;
}
if (containerStack != null && !stack.getItem().doesContainerItemLeaveCraftingGrid(stack))
{
return containerStack;
}
}
//System.out.println("ItemGrinder: "+stack.toString());
return decrStackSize(stack, amount);
}
/** Used to automatically remove selected items from crafting inv
*
* @param requiredItems - items that are to be removed */
public void consumeItems(ItemStack... requiredItems)
{
if (requiredItems != null)
{
for (ItemStack searchStack : requiredItems)
{
if (searchStack != null)
{
int[] invSlots = ((IAutoCrafter) this.craftingEntity).getCraftingInv();
for (int i = 0; i < invSlots.length; i++)
{
ItemStack checkStack = this.craftingInv.getStackInSlot(invSlots[i]);
if (checkStack != null)
{
if (AutoCraftingManager.areStacksEqual(searchStack, checkStack))
{
this.craftingInv.setInventorySlotContents(invSlots[i], AutoCraftingManager.consumeItem(checkStack, 1));
break;
}
}
}
}
}
}
}
public static interface IAutoCrafter
{
/** The slots used by the crafter for resources */
public int[] getCraftingInv();
}
}

View file

@ -0,0 +1,67 @@
package com.dark.helpers;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
public class ConnectionHelper
{
/** Used to find all tileEntities sounding the location you will have to filter for selective
* tileEntities
*
* @param world - the world being searched threw
* @param x
* @param y
* @param z
* @return an array of up to 6 tileEntities */
public static TileEntity[] getSurroundingTileEntities(TileEntity ent)
{
return getSurroundingTileEntities(ent.worldObj, ent.xCoord, ent.yCoord, ent.zCoord);
}
public static TileEntity[] getSurroundingTileEntities(World world, Vector3 vec)
{
return getSurroundingTileEntities(world, vec.intX(), vec.intY(), vec.intZ());
}
public static TileEntity[] getSurroundingTileEntities(World world, int x, int y, int z)
{
TileEntity[] list = new TileEntity[6];
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
list[direction.ordinal()] = world.getBlockTileEntity(x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ);
}
return list;
}
/** Used to find which of 4 Corners this block is in a group of blocks 0 = not a corner 1-4 = a
* corner of some direction */
public static int corner(TileEntity entity)
{
TileEntity[] en = getSurroundingTileEntities(entity.worldObj, entity.xCoord, entity.yCoord, entity.zCoord);
TileEntity north = en[ForgeDirection.NORTH.ordinal()];
TileEntity south = en[ForgeDirection.SOUTH.ordinal()];
TileEntity east = en[ForgeDirection.EAST.ordinal()];
TileEntity west = en[ForgeDirection.WEST.ordinal()];
if (west != null && north != null && east == null && south == null)
{
return 3;
}
if (north != null && east != null && south == null && west == null)
{
return 4;
}
if (east != null && south != null && west == null && north == null)
{
return 1;
}
if (south != null && west != null && north == null && east == null)
{
return 2;
}
return 0;
}
}

View file

@ -0,0 +1,185 @@
package com.dark.helpers;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntitySlime;
import net.minecraft.entity.monster.EntitySpider;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.passive.EntitySheep;
import net.minecraft.entity.player.EntityPlayer;
/** Dictionary to track entities by several names to be used for anything. Current use is armbot task
* so the user has an easy way to ID creatures.
*
* @author DarkGuardsman */
public class EntityDictionary
{
public static HashMap<String, Class<? extends Entity>> entityMap = new HashMap();
public static HashMap<Class<? extends Entity>, Boolean> grabMap = new HashMap();
private static boolean init = false;
/** Call this very last in a mod so that all mods have a chance to load there entities */
public static void init()
{
if (!init)
{
init = true;
for (Object object : EntityList.classToStringMapping.entrySet())
{
if (object instanceof Entry)
{
Object key = ((Entry) object).getKey();
Object value = ((Entry) object).getKey();
if (key instanceof Class && value instanceof String)
{
entityMap.put((String) value, (Class) key);
}
}
}
}
}
static
{
addName("chicken", EntityChicken.class);
addName("cow", EntityCow.class);
addName("sheep", EntitySheep.class);
addName("pig", EntityPig.class);
addName("player", EntityPlayer.class);
addName("zombie", EntityZombie.class);
addName("zomb", EntityZombie.class);
addName("skeleton", EntitySkeleton.class);
addName("skel", EntitySkeleton.class);
addName("animal", EntityAnimal.class);
addName("monster", EntityMob.class);
addName("mob", EntityMob.class);
addName("creeper", EntityCreeper.class);
addName("spider", EntitySpider.class);
addName("slime", EntitySlime.class);
addName("items", EntityItem.class);
addName("item", EntityItem.class);
addName("all", Entity.class);
addName("everything", Entity.class);
addName("boat", EntityBoat.class);
addName("cart", EntityMinecart.class);
setCanNotBeGrabbed(EntityDragon.class);
setCanNotBeGrabbed(EntityWither.class);
}
public static Class<? extends Entity> get(String name)
{
return entityMap.get(name);
}
/** Can the entity be grabbed by something such as a robot, or another entity. By default most
* entities can be grabbed by another object. */
public static boolean canGrab(String name)
{
if (entityMap.containsKey(name))
{
return canGrab(entityMap.get(name));
}
return true;
}
/** Can the entity be grabbed by something such as a robot, or another entity. By default most
* entities can be grabbed by another object. */
public static boolean canGrab(Entity entity)
{
if (entity != null)
{
if (canGrab(entity.getClass()))
{
return true;
}
else
{
for (Entry<Class<? extends Entity>, Boolean> entry : grabMap.entrySet())
{
if (entry.getKey().isInstance(entity))
{
return entry.getValue();
}
}
return true;
}
}
return false;
}
/** Can the entity be grabbed by something such as a robot, or another entity. By default most
* entities can be grabbed by another object. */
public static boolean canGrab(Class<? extends Entity> clazz)
{
if (grabMap.containsKey(clazz))
{
return grabMap.get(clazz);
}
else
{
for (Entry<Class<? extends Entity>, Boolean> entry : grabMap.entrySet())
{
if (entry.getKey().isAssignableFrom(clazz))
{
return entry.getValue();
}
}
return true;
}
}
public static void setCanNotBeGrabbed(Class<? extends Entity> clazz)
{
grabMap.put(clazz, false);
}
public static void setCanBeGrabbed(Class<? extends Entity> clazz)
{
grabMap.put(clazz, true);
}
public static void addName(Class<? extends Entity> clazz, String name)
{
entityMap.put(name, clazz);
}
public static void addName(String name, Class<? extends Entity> clazz)
{
addName(clazz, name);
}
public static List<Class<? extends Entity>> getList()
{
// TODO Auto-generated method stub
return null;
}
public static String get(Class<? extends Entity> entityToInclude)
{
for (Entry<String, Class<? extends Entity>> entry : entityMap.entrySet())
{
if (entry.getClass() != null && entry.getClass().equals(entityToInclude))
{
return entry.getKey();
}
}
return null;
}
}

View file

@ -0,0 +1,340 @@
package com.dark.helpers;
import java.util.ArrayList;
import java.util.List;
import com.dark.interfaces.IExtendedStorage;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
/** Helper that handles most of the interaction of the tile with the inventories around it
*
* @author Rseifert */
public class InvInteractionHelper
{
public World world;
Vector3 location;
List<ItemStack> filteredItems;
boolean inverted;
public InvInteractionHelper(World world, Vector3 location, List<ItemStack> filters, boolean inverted)
{
this.world = world;
this.location = location;
this.filteredItems = filters;
if (filteredItems == null)
{
filteredItems = new ArrayList<ItemStack>();
}
this.inverted = inverted;
}
public void setFilter(List<ItemStack> filters, boolean inverted)
{
this.filteredItems = filters;
this.inverted = inverted;
}
/** Throws the items from the manipulator into the world.
*
* @param outputPosition
* @param items */
public void throwItem(Vector3 outputPosition, ItemStack items)
{
if (!world.isRemote)
{
EntityItem entityItem = new EntityItem(world, outputPosition.x + 0.5, outputPosition.y + 0.8, outputPosition.z + 0.5, items);
entityItem.motionX = 0;
entityItem.motionZ = 0;
entityItem.motionY /= 5;
entityItem.delayBeforeCanPickup = 20;
world.spawnEntityInWorld(entityItem);
}
}
public ItemStack storeItem(ItemStack item, ForgeDirection... directions)
{
if (item != null)
{
ItemStack remainingStack = item.copy();
for (ForgeDirection direction : directions)
{
remainingStack = tryPlaceInPosition(remainingStack, this.location.clone().modifyPositionFromSide(direction), direction.getOpposite());
}
return remainingStack;
}
return item;
}
/** Tries to place an itemStack in a specific position if it is an inventory.
*
* @return The ItemStack remained after place attempt */
public ItemStack tryPlaceInPosition(ItemStack itemStack, Vector3 position, ForgeDirection dir)
{
TileEntity tileEntity = position.getTileEntity(world);
ForgeDirection direction = dir.getOpposite();
if (tileEntity != null && itemStack != null)
{
if (tileEntity instanceof TileEntityChest)
{
TileEntityChest[] chests = { (TileEntityChest) tileEntity, null };
/** Try to find a double chest. */
for (int i = 2; i < 6; i++)
{
ForgeDirection searchDirection = ForgeDirection.getOrientation(i);
Vector3 searchPosition = position.clone();
searchPosition.modifyPositionFromSide(searchDirection);
if (searchPosition.getTileEntity(world) != null)
{
if (searchPosition.getTileEntity(world).getClass() == chests[0].getClass())
{
chests[1] = (TileEntityChest) searchPosition.getTileEntity(world);
break;
}
}
}
for (TileEntityChest chest : chests)
{
if (chest != null)
{
for (int i = 0; i < chest.getSizeInventory(); i++)
{
itemStack = this.addStackToInventory(i, chest, itemStack);
if (itemStack == null)
{
return null;
}
}
}
}
}
else if (tileEntity instanceof IExtendedStorage)
{
return ((IExtendedStorage) tileEntity).addStackToStorage(itemStack);
}
else if (tileEntity instanceof ISidedInventory)
{
ISidedInventory inventory = (ISidedInventory) tileEntity;
int[] slots = inventory.getAccessibleSlotsFromSide(direction.ordinal());
for (int i = 0; i < slots.length; i++)
{
if (inventory.canInsertItem(slots[i], itemStack, direction.ordinal()))
{
itemStack = this.addStackToInventory(slots[i], inventory, itemStack);
}
if (itemStack == null)
{
return null;
}
}
}
else if (tileEntity instanceof IInventory)
{
IInventory inventory = (IInventory) tileEntity;
for (int i = 0; i < inventory.getSizeInventory(); i++)
{
itemStack = this.addStackToInventory(i, inventory, itemStack);
if (itemStack == null)
{
return null;
}
}
}
}
if (itemStack == null || itemStack.stackSize <= 0)
{
return null;
}
return itemStack;
}
public ItemStack addStackToInventory(int slotIndex, IInventory inventory, ItemStack itemStack)
{
if (inventory.getSizeInventory() > slotIndex)
{
ItemStack stackInInventory = inventory.getStackInSlot(slotIndex);
if (stackInInventory == null)
{
inventory.setInventorySlotContents(slotIndex, itemStack);
if (inventory.getStackInSlot(slotIndex) == null)
{
return itemStack;
}
return null;
}
else if (stackInInventory.isItemEqual(itemStack) && stackInInventory.isStackable())
{
stackInInventory = stackInInventory.copy();
int stackLim = Math.min(inventory.getInventoryStackLimit(), itemStack.getMaxStackSize());
int rejectedAmount = Math.max((stackInInventory.stackSize + itemStack.stackSize) - stackLim, 0);
stackInInventory.stackSize = Math.min(Math.max((stackInInventory.stackSize + itemStack.stackSize - rejectedAmount), 0), inventory.getInventoryStackLimit());
itemStack.stackSize = rejectedAmount;
inventory.setInventorySlotContents(slotIndex, stackInInventory);
}
}
if (itemStack.stackSize <= 0)
{
return null;
}
return itemStack;
}
/** Tries to get an item from a position
*
* @param position - location of item
* @param direction - direction this item is from the original
* @param ammount - amount up to one stack to grab
* @return the grabbed item stack */
public ItemStack tryGrabFromPosition(Vector3 position, ForgeDirection dir, int ammount)
{
ItemStack returnStack = null;
TileEntity tileEntity = position.getTileEntity(world);
ForgeDirection direction = dir.getOpposite();
if (tileEntity != null)
{
if (tileEntity.getClass() == TileEntityChest.class)
{
TileEntityChest[] chests = { (TileEntityChest) tileEntity, null };
/** Try to find a double chest. */
for (int i = 2; i < 6; i++)
{
ForgeDirection searchDirection = ForgeDirection.getOrientation(i);
Vector3 searchPosition = position.clone();
searchPosition.modifyPositionFromSide(searchDirection);
if (searchPosition.getTileEntity(world) != null)
{
if (searchPosition.getTileEntity(world).getClass() == chests[0].getClass())
{
chests[1] = (TileEntityChest) searchPosition.getTileEntity(world);
break;
}
}
}
chestSearch:
for (TileEntityChest chest : chests)
{
if (chest != null)
{
for (int i = 0; i < chest.getSizeInventory(); i++)
{
ItemStack itemStack = this.removeStackFromInventory(i, chest, ammount);
if (itemStack != null)
{
returnStack = itemStack;
break chestSearch;
}
}
}
}
}
else if (tileEntity instanceof ISidedInventory)
{
ISidedInventory inventory = (ISidedInventory) tileEntity;
int[] slots = inventory.getAccessibleSlotsFromSide(direction.ordinal());
for (int i = 0; i < slots.length; i++)
{
int slot = slots[i];
ItemStack slotStack = inventory.getStackInSlot(slot);
if (inventory.canExtractItem(slot, slotStack, direction.ordinal()))
{
ItemStack itemStack = this.removeStackFromInventory(slot, inventory, ammount);
if (itemStack != null)
{
returnStack = itemStack;
break;
}
}
}
}
else if (tileEntity instanceof IInventory)
{
IInventory inventory = (IInventory) tileEntity;
for (int i = 0; i < inventory.getSizeInventory(); i++)
{
ItemStack itemStack = this.removeStackFromInventory(i, inventory, ammount);
if (itemStack != null)
{
returnStack = itemStack;
break;
}
}
}
}
return returnStack;
}
/** Takes an item from the given inventory */
public ItemStack removeStackFromInventory(int slotIndex, IInventory inventory, int amount)
{
if (inventory.getStackInSlot(slotIndex) != null)
{
ItemStack itemStack = inventory.getStackInSlot(slotIndex).copy();
if (this.getFilters().size() == 0 || this.isFiltering(itemStack))
{
amount = Math.min(amount, itemStack.stackSize);
itemStack.stackSize = amount;
inventory.decrStackSize(slotIndex, amount);
return itemStack;
}
}
return null;
}
/** is the item being restricted to a filter set */
public boolean isFiltering(ItemStack itemStack)
{
if (this.getFilters() != null && itemStack != null)
{
for (int i = 0; i < getFilters().size(); i++)
{
if (getFilters().get(i) != null)
{
if (getFilters().get(i).isItemEqual(itemStack))
{
return !inverted;
}
}
}
}
return inverted;
}
public List<ItemStack> getFilters()
{
if (this.filteredItems == null)
{
this.filteredItems = new ArrayList<ItemStack>();
}
return this.filteredItems;
}
}

View file

@ -0,0 +1,143 @@
package com.dark.helpers;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.command.IEntitySelector;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
public class ItemWorldHelper
{
/** gets all EntityItems in a location using a start and end point */
public static List<EntityItem> findAllItemsIn(World world, Vector3 start, Vector3 end)
{
return world.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(start.x, start.y, start.z, end.x, end.y, end.z));
}
public static List<EntityItem> getEntitiesInDirection(World world, Vector3 center, ForgeDirection dir)
{
List<EntityItem> list = world.selectEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getAABBPool().getAABB(center.x + dir.offsetX, center.y + dir.offsetY, center.z + dir.offsetZ, center.x + dir.offsetX + 1, center.y + dir.offsetY + 1, center.z + dir.offsetZ + 1), IEntitySelector.selectAnything);
return list.size() > 0 ? list : null;
}
/** Gets all EntityItems in an area and sorts them by a list of itemStacks
*
* @param world - world being worked in
* @param start - start point
* @param end - end point
* @param disiredItems - list of item that are being looked for
* @return a list of EntityItem that match the itemStacks desired */
public static List<EntityItem> findSelectItems(World world, Vector3 start, Vector3 end, List<ItemStack> disiredItems)
{
List<EntityItem> entityItems = ItemWorldHelper.findAllItemsIn(world, start, end);
return filterEntityItemsList(entityItems, disiredItems);
}
/** filters an EntityItem List to a List of Items */
public static List<EntityItem> filterEntityItemsList(List<EntityItem> entityItems, List<ItemStack> disiredItems)
{
List<EntityItem> newItemList = new ArrayList<EntityItem>();
for (ItemStack itemStack : disiredItems)
{
for (EntityItem entityItem : entityItems)
{
if (entityItem.getEntityItem().isItemEqual(itemStack) && !newItemList.contains(entityItem))
{
newItemList.add(entityItem);
break;
}
}
}
return newItemList;
}
/** filters out EnittyItems from an Entity list */
public static List<EntityItem> filterOutEntityItems(List<Entity> entities)
{
List<EntityItem> newEntityList = new ArrayList<EntityItem>();
for (Entity entity : entities)
{
if (entity instanceof EntityItem)
{
newEntityList.add((EntityItem) entity);
}
}
return newEntityList;
}
/** filter a list of itemStack to another list of itemStacks
*
* @param totalItems - full list of items being filtered
* @param desiredItems - list the of item that are being filtered too
* @return a list of item from the original that are wanted */
public static List<ItemStack> filterItems(List<ItemStack> totalItems, List<ItemStack> desiredItems)
{
List<ItemStack> newItemList = new ArrayList<ItemStack>();
for (ItemStack entityItem : totalItems)
{
for (ItemStack itemStack : desiredItems)
{
if (entityItem.itemID == itemStack.itemID && entityItem.getItemDamage() == itemStack.getItemDamage() && !newItemList.contains(entityItem))
{
newItemList.add(entityItem);
break;
}
}
}
return newItemList;
}
/** grabs all the items that the block can drop then pass them onto dropBlockAsItem_do
*
* @param world
* @param x
* @param y
* @param z */
public static void dropBlockAsItem(World world, Vector3 loc)
{
if (!world.isRemote)
{
int meta = loc.getBlockMetadata(world);
int id = loc.getBlockID(world);
ArrayList<ItemStack> items = Block.blocksList[id].getBlockDropped(world, loc.intX(), loc.intY(), loc.intZ(), meta, 0);
for (ItemStack item : items)
{
dropItemStack(world, loc, item, false);
}
}
}
public static ItemStack dropItemStack(World world, Vector3 location, ItemStack itemStack, boolean random)
{
if (!world.isRemote && world.getGameRules().getGameRuleBooleanValue("doTileDrops"))
{
float f = 0.7F;
double xx = 0;
double yy = 0;
double zz = 0;
if (random)
{
xx = (world.rand.nextFloat() * f) + (1.0F - f) * 0.5D;
yy = (world.rand.nextFloat() * f) + (1.0F - f) * 0.5D;
zz = (world.rand.nextFloat() * f) + (1.0F - f) * 0.5D;
}
EntityItem entityitem = new EntityItem(world, location.x + xx, location.y + yy, location.z + zz, itemStack);
entityitem.delayBeforeCanPickup = 10;
world.spawnEntityInWorld(entityitem);
return null;
}
return itemStack;
}
}

View file

@ -0,0 +1,206 @@
package com.dark.helpers;
import java.util.Random;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
public class MathHelper extends net.minecraft.util.MathHelper
{
/** Generates an array of random numbers
*
* @param random - random instance to be used
* @param maxNumber - max size of the int to use
* @param arraySize - length of the array
* @return array of random numbers */
public static int[] generateRandomIntArray(Random random, int maxNumber, int arraySize)
{
return MathHelper.generateRandomIntArray(random, 0, maxNumber, arraySize);
}
/** Generates an array of random numbers
*
* @param random - random instance to be used
* @param minNumber - smallest random Integer to use. Warning can lead to longer than normal
* delay in returns
* @param maxNumber - max size of the int to use
* @param arraySize - length of the array
* @return array of random numbers */
public static int[] generateRandomIntArray(Random random, int minNumber, int maxNumber, int arraySize)
{
int[] array = new int[arraySize];
for (int i = 0; i < array.length; i++)
{
int number = random.nextInt(maxNumber);
if (minNumber != 0)
{
while (number < minNumber)
{
number = random.nextInt(maxNumber);
}
}
array[i] = number;
}
return array;
}
/** @param vec - vector3 that is on the sphere
* @return new Vector3(radius, inclination, azimuth) */
public static Vector3 vecToSphereAngles(Vector3 vec)
{
double radius = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y) + (vec.z * vec.z));
double inclination = Math.acos(vec.z / radius);
double azimuth = Math.atan(vec.y / vec.z);
return new Vector3(radius, inclination, azimuth);
}
/** Turns radius and sphere cords into a vector3
*
* @param radius - sphere radius
* @param inclination -
* @param azimuth
* @return Vector3(x,y,z) */
public static Vector3 sphereAnglesToVec(Double radius, Double inclination, Double azimuth)
{
double x = radius * Math.sin(inclination) * Math.cos(azimuth);
double y = radius * Math.sin(inclination) * Math.sin(azimuth);
double z = radius * Math.cos(inclination);
return new Vector3(x, y, z);
}
/** Clamps the angles to a min max by adding or subtracting the min max. This way it maintanes
* the change in angle in the chance it goes out of bounds */
public static float clampAngle(float var, float min, float max)
{
while (var < min)
{
var += min;
}
while (var > max)
{
var -= max;
}
return var;
}
public static float clamp(float var, float min, float max)
{
if (var < min)
{
return min;
}
else if (var > max)
{
return max;
}
else
{
return var;
}
}
/** Clamps an angle to 360 degree circle */
public static float clampAngleTo360(float var)
{
return MathHelper.clampAngle(var, 0, 360);
}
/** Find the shortest delta change to the angle goal from the current angle */
public static float shortestAngleTo360(float angle, float angleGoal)
{
angle = clampAngleTo360(angle);
angleGoal = clampAngleTo360(angleGoal);
if (angle == angleGoal)
{
return 0;
}
else if (angle > angleGoal)
{
return angleGoal - angle;
}
else
{
return angle - angleGoal;
}
}
public static double updateRotation(double from, double to, double speed)
{
from = net.minecraft.util.MathHelper.wrapAngleTo180_double(from);
to = net.minecraft.util.MathHelper.wrapAngleTo180_double(to);
double delta = Math.abs(from - to);
if (delta > 0.001f)
{
if (from > to)
{
from += (delta >= 0) ? speed : -speed;
}
else
{
from += (delta >= 0) ? -speed : speed;
}
if (delta < speed + 0.1f)
{
from = to;
}
}
return from;
}
public static double updateRotation(float from, float to, float speed)
{
from = net.minecraft.util.MathHelper.wrapAngleTo180_float(from);
to = net.minecraft.util.MathHelper.wrapAngleTo180_float(to);
double delta = Math.abs(from - to);
if (delta > 0.001f)
{
if (from > to)
{
from += (delta >= 0) ? speed : -speed;
}
else
{
from += (delta >= 0) ? -speed : speed;
}
if (delta < speed + 0.1f)
{
from = to;
}
}
return from;
}
/** gets the facing direction using the yaw angle */
public static ForgeDirection getFacingDirectionFromAngle(float yaw)
{
float angle = net.minecraft.util.MathHelper.wrapAngleTo180_float(yaw);
if (angle >= -45 && angle <= 45)
{
return ForgeDirection.SOUTH;
}
else if (angle >= 45 && angle <= 135)
{
return ForgeDirection.WEST;
}
else if (angle >= 135 && angle <= -135)
{
return ForgeDirection.NORTH;
}
else
{
return ForgeDirection.EAST;
}
}
/** gets the facing direction using the yaw angle */
public static ForgeDirection getFacingDirectionFromAngle(double yaw)
{
return getFacingDirectionFromAngle((float) yaw);
}
}

View file

@ -0,0 +1,65 @@
package com.dark.helpers;
import java.util.EnumSet;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.dark.network.PacketManagerKeyEvent;
import cpw.mods.fml.common.IScheduledTickHandler;
import cpw.mods.fml.common.TickType;
/** This class handles keys already binded to the game so to avoid creating new key bindings
*
* @author DarkGuardsman */
public class PlayerKeyHandler implements IScheduledTickHandler
{
@Override
public final void tickStart(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, false);
}
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, true);
}
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
{
for (int i = 0; i < Minecraft.getMinecraft().gameSettings.keyBindings.length; i++)
{
KeyBinding keyBinding = Minecraft.getMinecraft().gameSettings.keyBindings[i];
int keyCode = keyBinding.keyCode;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state)
{
PacketManagerKeyEvent.sendPacket(keyCode);
}
}
}
@Override
public EnumSet<TickType> ticks()
{
return EnumSet.of(TickType.CLIENT);
}
@Override
public String getLabel()
{
return "[CoreMachine]KeyBindingCatcher";
}
@Override
public int nextTickSpacing()
{
return 2;
}
}

View file

@ -0,0 +1,278 @@
package com.dark.helpers;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import universalelectricity.core.vector.Vector3;
public class RayTraceHelper
{
public static MovingObjectPosition raytraceEntities_fromAnEntity(World world, Entity entity, Vec3 error, double reachDistance, boolean collisionFlag)
{
MovingObjectPosition pickedEntity = null;
Vec3 playerPosition = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
Vec3 playerLook = entity.getLookVec();
Vec3 playerViewOffset = Vec3.createVectorHelper(playerPosition.xCoord + playerLook.xCoord * reachDistance + error.xCoord, playerPosition.yCoord + playerLook.yCoord * reachDistance + error.yCoord, playerPosition.zCoord + playerLook.zCoord * reachDistance + error.zCoord);
double playerBorder = 1.1 * reachDistance;
AxisAlignedBB boxToScan = entity.boundingBox.expand(playerBorder, playerBorder, playerBorder);
List<Entity> entitiesHit = world.getEntitiesWithinAABBExcludingEntity(entity, boxToScan);
double closestEntity = reachDistance;
if (entitiesHit == null || entitiesHit.isEmpty())
{
return null;
}
for (Entity entityHit : entitiesHit)
{
if (entityHit != null && entityHit.canBeCollidedWith() && entityHit.boundingBox != null)
{
float border = entityHit.getCollisionBorderSize();
AxisAlignedBB aabb = entityHit.boundingBox.expand(border, border, border);
MovingObjectPosition hitMOP = aabb.calculateIntercept(playerPosition, playerViewOffset);
if (hitMOP != null)
{
if (aabb.isVecInside(playerPosition))
{
if (0.0D < closestEntity || closestEntity == 0.0D)
{
pickedEntity = new MovingObjectPosition(entityHit);
if (pickedEntity != null)
{
pickedEntity.hitVec = hitMOP.hitVec;
closestEntity = 0.0D;
}
}
}
else
{
double distance = playerPosition.distanceTo(hitMOP.hitVec);
if (distance < closestEntity || closestEntity == 0.0D)
{
pickedEntity = new MovingObjectPosition(entityHit);
pickedEntity.hitVec = hitMOP.hitVec;
closestEntity = distance;
}
}
}
}
}
return pickedEntity;
}
@SuppressWarnings("unchecked")
public static MovingObjectPosition raytraceEntities(World world, Vec3 start, Vec3 end, double range, boolean collisionFlag, Entity exclude)
{
AxisAlignedBB boxToScan = AxisAlignedBB.getBoundingBox(start.xCoord, start.yCoord, start.zCoord, end.xCoord, end.yCoord, end.zCoord);
List<Entity> entitiesHit = null;
if (exclude != null)
{
entitiesHit = world.getEntitiesWithinAABBExcludingEntity(exclude, boxToScan);
}
else
{
entitiesHit = world.getEntitiesWithinAABB(Entity.class, boxToScan);
}
MovingObjectPosition pickedEntity = null;
double closestEntity = range;
if (entitiesHit == null || entitiesHit.isEmpty())
{
return null;
}
for (Entity entityHit : entitiesHit)
{
if (entityHit != null && entityHit.canBeCollidedWith() && entityHit.boundingBox != null)
{
float border = entityHit.getCollisionBorderSize();
AxisAlignedBB aabb = entityHit.boundingBox.expand(border, border, border);
MovingObjectPosition hitMOP = aabb.calculateIntercept(start, end);
if (hitMOP != null)
{
if (aabb.isVecInside(start))
{
if (0.0D < closestEntity || closestEntity == 0.0D)
{
pickedEntity = new MovingObjectPosition(entityHit);
if (pickedEntity != null)
{
pickedEntity.hitVec = hitMOP.hitVec;
closestEntity = 0.0D;
}
}
}
else
{
double distance = start.distanceTo(hitMOP.hitVec);
if (distance < closestEntity || closestEntity == 0.0D)
{
pickedEntity = new MovingObjectPosition(entityHit);
pickedEntity.hitVec = hitMOP.hitVec;
closestEntity = distance;
}
}
}
}
}
return pickedEntity;
}
public static MovingObjectPosition raytraceBlocks_fromAnEntity(World world, Entity entity, Vec3 error, double reachDistance, boolean collisionFlag)
{
Vec3 playerPosition = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
Vec3 playerLook = entity.getLookVec();
Vec3 playerViewOffset = Vec3.createVectorHelper(playerPosition.xCoord + playerLook.xCoord * reachDistance + error.xCoord, playerPosition.yCoord + playerLook.yCoord * reachDistance + error.yCoord, playerPosition.zCoord + playerLook.zCoord * reachDistance + error.zCoord);
return raytraceBlocks(world, playerPosition, playerViewOffset, collisionFlag);
}
public static MovingObjectPosition raytraceBlocks_fromAnEntity(World world, Entity entity, double reachDistance, boolean collisionFlag)
{
Vec3 playerPosition = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
Vec3 playerLook = entity.getLookVec();
Vec3 playerViewOffset = Vec3.createVectorHelper(playerPosition.xCoord + playerLook.xCoord * reachDistance, playerPosition.yCoord + playerLook.yCoord * reachDistance, playerPosition.zCoord + playerLook.zCoord * reachDistance);
return raytraceBlocks(world, playerPosition, playerViewOffset, collisionFlag);
}
public static MovingObjectPosition raytraceBlocks(World world, Vec3 start, Vec3 end, boolean collisionFlag)
{
return world.rayTraceBlocks_do_do(start, end, collisionFlag, !collisionFlag);
}
public static Vector3 getPosFromRotation(final Vector3 center, float reachDistance, float yaw, float pitch)
{
return center.clone().translate(getLook(yaw, pitch, 1.0F).scale(reachDistance));
}
/** Does a ray trace from start to end vector
*
* @param world - world to do the ray trace in
* @param start - starting point clear of any collisions from its caster
* @param end - end point
* @param collisionFlag
* @return */
public static MovingObjectPosition ray_trace_do(final World world, final Vec3 start, final Vec3 end, final float range, boolean collisionFlag)
{
MovingObjectPosition hitBlock = raytraceBlocks(world, new Vector3(start).toVec3(), new Vector3(end).toVec3(), collisionFlag);
MovingObjectPosition hitEntity = raytraceEntities(world, start, end, range, collisionFlag, null);
if (hitEntity == null)
{
return hitBlock;
}
else if (hitBlock == null)
{
return hitEntity;
}
else
{
if (hitEntity.hitVec.distanceTo(start) < hitBlock.hitVec.distanceTo(start))
{
return hitEntity;
}
else
{
return hitBlock;
}
}
}
/** Does a ray trace from an entities look angle out to a set distance from the entity
*
* @param entity - entity who's view angles will be used for finding the start and end points of
* the ray
* @param e - error(or adjustments) to add to it if this ray is being used for weapon
* calculations
* @param reachDistance - distance the ray will extend to
* @param collisionFlag
* @return */
public static MovingObjectPosition do_rayTraceFromEntity(Entity entity, Vec3 e, double reachDistance, boolean collisionFlag)
{
MovingObjectPosition hitBlock = raytraceBlocks_fromAnEntity(entity.worldObj, entity, e, reachDistance, collisionFlag);
MovingObjectPosition hitEntity = raytraceEntities_fromAnEntity(entity.worldObj, entity, e, reachDistance, collisionFlag);
if (hitEntity == null)
{
return hitBlock;
}
else if (hitBlock == null)
{
return hitEntity;
}
else
{
Vec3 playerPosition = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
if (hitEntity.hitVec.distanceTo(playerPosition) < hitBlock.hitVec.distanceTo(playerPosition))
{
return hitEntity;
}
else
{
return hitBlock;
}
}
}
public static Vec3 getLook(Entity entity, float par1)
{
float f1;
float f2;
float f3;
float f4;
if (par1 == 1.0F)
{
f1 = MathHelper.cos(-entity.rotationYaw * 0.017453292F - (float) Math.PI);
f2 = MathHelper.sin(-entity.rotationYaw * 0.017453292F - (float) Math.PI);
f3 = -MathHelper.cos(-entity.rotationPitch * 0.017453292F);
f4 = MathHelper.sin(-entity.rotationPitch * 0.017453292F);
return entity.worldObj.getWorldVec3Pool().getVecFromPool((f2 * f3), f4, (f1 * f3));
}
else
{
f1 = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par1;
f2 = entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par1;
f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI);
f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI);
float f5 = -MathHelper.cos(-f1 * 0.017453292F);
float f6 = MathHelper.sin(-f1 * 0.017453292F);
return entity.worldObj.getWorldVec3Pool().getVecFromPool((f4 * f5), f6, (f3 * f5));
}
}
public static Vector3 getLook(float yaw, float pitch, float distance)
{
float f1, f2, f3, f4;
if (distance == 1.0F)
{
f1 = MathHelper.cos(-yaw * 0.017453292F - (float) Math.PI);
f2 = MathHelper.sin(-yaw * 0.017453292F - (float) Math.PI);
f3 = -MathHelper.cos(-pitch * 0.017453292F);
f4 = MathHelper.sin(-pitch * 0.017453292F);
return new Vector3((f2 * f3), f4, (f1 * f3));
}
else
{
f1 = pitch * distance;
f2 = yaw * distance;
f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI);
f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI);
float f5 = -MathHelper.cos(-f1 * 0.017453292F);
float f6 = MathHelper.sin(-f1 * 0.017453292F);
return new Vector3((f4 * f5), f6, (f3 * f5));
}
}
}

View file

@ -0,0 +1,16 @@
package com.dark.interfaces;
import net.minecraft.entity.player.EntityPlayer;
/** Applied to objects that can be control by the player using the keyboard
*
* @author DarkGuardsman */
public interface IControlReceiver
{
/** Called when the player presses a key
*
* @param player - client player
* @param character - character code
* @param keycode - keyboard code */
public boolean keyTyped(EntityPlayer player, int keycode);
}

View file

@ -0,0 +1,11 @@
package com.dark.interfaces;
import net.minecraft.item.ItemStack;
/** Applied to blocks that store items in stacks above 64 and as one large collective of items
*
* @author DarkGuardsman */
public interface IExtendedStorage
{
public ItemStack addStackToStorage(ItemStack stack);
}

View file

@ -0,0 +1,14 @@
package com.dark.interfaces;
/** Applied to devices that have the option to run without power. Normally this option is only shown
* to creative mode players
*
* @author DarkGuardsman */
public interface IPowerLess
{
/** Should this run without power */
public boolean runPowerLess();
/** Set if this should run powerless */
public void setPowerLess(boolean bool);
}

View file

@ -0,0 +1,17 @@
package com.dark.network;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.Player;
public interface IPacketManager
{
public int getID();
public void setID(int maxID);
public void handlePacket(INetworkManager network, Packet250CustomPayload packet, Player player, ByteArrayDataInput data);
}

View file

@ -0,0 +1,20 @@
package com.dark.network;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.Player;
/** Simplified version of IPackerReceiver for tiles that only need a packet ID, data, and player
* Reference
*
* @author DarkGuardsman */
public interface ISimplePacketReceiver
{
/** Simplified version of IPacketReceiver's HandlePacketData
*
* @param id - packet ID as a string
* @param data - data from the packet, after location has been read
* @param player - player that the packet was sent to or came from
* @return true if the packet was used */
public boolean simplePacket(String id, ByteArrayDataInput data, Player player);
}

View file

@ -0,0 +1,79 @@
package com.dark.network;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import net.minecraft.item.Item;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.world.World;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import universalelectricity.core.vector.Vector3;
import com.builtbroken.common.Pair;
public class PacketDataWatcher
{
HashMap<Pair<World, Vector3>, List<Integer>> packetSizes = new HashMap<Pair<World, Vector3>, List<Integer>>();
public static PacketDataWatcher instance = new PacketDataWatcher();
public boolean enable = false;
public void onPacketData(TileEntity entity, Packet250CustomPayload data, long t)
{
if (entity != null && enable)
{
Pair<World, Vector3> location = new Pair<World, Vector3>(entity.worldObj, new Vector3(entity));
List<Integer> l = this.packetSizes.get(location);
if (l == null)
{
l = new ArrayList<Integer>();
}
l.add(data.getPacketSize());
this.packetSizes.put(location, l);
}
}
@ForgeSubscribe
public void playerRightClickEvent(PlayerInteractEvent event)
{
if (event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.capabilities.isCreativeMode && event.entityPlayer.getHeldItem() != null && event.entityPlayer.getHeldItem().itemID == Item.blazeRod.itemID)
{
if (event.entityPlayer.worldObj.isRemote)
{
if (event.entityPlayer.isSneaking())
{
this.enable = !this.enable;
event.entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText("PacketWatcher is now " + (this.enable ? "Enabled. Now caching packet sizes." : "Disabled. Data cache has been cleared")));
this.packetSizes.clear();
}
else
{
TileEntity ent = event.entityPlayer.worldObj.getBlockTileEntity(event.x, event.y, event.z);
if (ent != null)
{
System.out.println("Entity Check");
Pair<World, Vector3> location = new Pair(ent.worldObj, new Vector3(ent));
int p = 0, a = 0;
if (this.packetSizes.get(location) != null)
{
for (int i : this.packetSizes.get(location))
{
a += i;
}
p = this.packetSizes.get(location).size();
a /= (p > 0 ? p : 1);
}
event.entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText("AveragePacketSize: " + a + "bits for " + p + " packets"));
}
}
}
}
}
}

View file

@ -0,0 +1,346 @@
package com.dark.network;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools;
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.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import dark.machines.PacketManagerEffects;
/** Packet manager based off the PacketManager from UE created by Calclavia. However changed so it
* can easily be extended without changing the base handler file. Instead of changing the base file
* manager can be registered to the handle that pickup on ids and then handle there own data from
* those ids. This lets new and complex handling to be created without many overlap or long methods
* in the packet handler
*
* @author DarkGuardsman */
public class PacketHandler implements IPacketHandler, IPacketReceiver
{
protected static PacketHandler instance;
public static HashMap<Integer, IPacketManager> packetTypes = new HashMap<Integer, IPacketManager>();
public static PacketManagerTile tile = new PacketManagerTile();
public static PacketManagerEffects effects = new PacketManagerEffects();
public static int maxID = 0;
static
{
registerManager(new PacketManagerTile());
registerManager(new PacketManagerEffects());
registerManager(PacketManagerKeyEvent.instance());
registerManager(new PacketManagerEntity());
}
public static void registerManager(IPacketManager manager)
{
if (manager != null)
{
packetTypes.put(maxID, manager);
manager.setID(maxID);
maxID++;
}
}
public static IPacketManager getManager(int id)
{
return packetTypes.get(id);
}
public static PacketHandler instance()
{
if (instance == null)
{
instance = new PacketHandler();
}
return instance;
}
/** Writes a compressed NBTTagCompound to the OutputStream */
public void writeNBTTagCompound(NBTTagCompound tag, DataOutputStream dataStream) throws IOException
{
if (tag == null)
{
dataStream.writeShort(-1);
}
else
{
byte[] var2 = CompressedStreamTools.compress(tag);
dataStream.writeShort((short) var2.length);
dataStream.write(var2);
}
}
public void writeNBTTagCompound(NBTTagCompound tag, ByteArrayDataOutput dataStream) throws IOException
{
if (tag == null)
{
dataStream.writeShort(-1);
}
else
{
byte[] var2 = CompressedStreamTools.compress(tag);
dataStream.writeShort((short) var2.length);
dataStream.write(var2);
}
}
/** Reads a compressed NBTTagCompount in a ByteStream. */
public NBTTagCompound readNBTTagCompound(DataInputStream dataStream) throws IOException
{
short var1 = dataStream.readShort();
if (var1 < 0)
{
return null;
}
else
{
byte[] var2 = new byte[var1];
dataStream.readFully(var2);
return CompressedStreamTools.decompress(var2);
}
}
public NBTTagCompound readNBTTagCompound(ByteArrayDataInput dataStream) throws IOException
{
short var1 = dataStream.readShort();
if (var1 < 0)
{
return null;
}
else
{
byte[] var2 = new byte[var1];
dataStream.readFully(var2);
return CompressedStreamTools.decompress(var2);
}
}
public static Vector3 readVector3(ByteArrayDataInput data) throws IOException
{
return new Vector3(data.readDouble(), data.readDouble(), data.readDouble());
}
@SuppressWarnings("resource")
public Packet getPacketWithID(String channelName, int id, Object... sendData)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeInt(id);
data = encodeDataStream(data, sendData);
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.channel = channelName;
packet.data = bytes.toByteArray();
packet.length = packet.data.length;
return packet;
}
catch (IOException e)
{
System.out.println("Failed to create packet.");
e.printStackTrace();
}
return null;
}
public Packet getPacket(String channelName, Object... sendData)
{
return getPacketWithID(channelName, -1, sendData);
}
/** Gets a packet for the tile entity.
*
* @return */
@SuppressWarnings("resource")
public Packet getTilePacket(String channelName, TileEntity sender, Object... sendData)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeInt(PacketHandler.tile.getID());
data.writeInt(sender.xCoord);
data.writeInt(sender.yCoord);
data.writeInt(sender.zCoord);
data = encodeDataStream(data, sendData);
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.channel = channelName;
packet.data = bytes.toByteArray();
packet.length = packet.data.length;
return packet;
}
catch (IOException e)
{
System.out.println("Failed to create packet.");
e.printStackTrace();
}
return null;
}
/** Sends packets to clients around a specific coordinate. A wrapper using Vector3. See
* {@PacketDispatcher} for detailed information. */
public void sendPacketToClients(Packet packet, World worldObj, Vector3 position, double range)
{
try
{
PacketDispatcher.sendPacketToAllAround(position.x, position.y, position.z, range, worldObj.provider.dimensionId, packet);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
/** Sends a packet to all the clients on this server. */
public void sendPacketToClients(Packet packet, World worldObj)
{
try
{
PacketDispatcher.sendPacketToAllInDimension(packet, worldObj.provider.dimensionId);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
public void sendPacketToClients(Packet packet)
{
try
{
PacketDispatcher.sendPacketToAllPlayers(packet);
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
public DataOutputStream encodeDataStream(DataOutputStream data, Object... sendData)
{
try
{
for (Object dataValue : sendData)
{
if (dataValue instanceof Vector3)
{
data.writeDouble(((Vector3) dataValue).x);
data.writeDouble(((Vector3) dataValue).y);
data.writeDouble(((Vector3) dataValue).z);
}
else if (dataValue instanceof Integer)
{
data.writeInt((Integer) dataValue);
}
else if (dataValue instanceof Float)
{
data.writeFloat((Float) dataValue);
}
else if (dataValue instanceof Double)
{
data.writeDouble((Double) dataValue);
}
else if (dataValue instanceof Byte)
{
data.writeByte((Byte) dataValue);
}
else if (dataValue instanceof Boolean)
{
data.writeBoolean((Boolean) dataValue);
}
else if (dataValue instanceof String)
{
data.writeUTF((String) dataValue);
}
else if (dataValue instanceof Short)
{
data.writeShort((Short) dataValue);
}
else if (dataValue instanceof Long)
{
data.writeLong((Long) dataValue);
}
else if (dataValue instanceof NBTTagCompound)
{
writeNBTTagCompound((NBTTagCompound) dataValue, data);
}
}
return data;
}
catch (IOException e)
{
System.out.println("Packet data encoding failed.");
e.printStackTrace();
}
return data;
}
@Override
public void onPacketData(INetworkManager network, Packet250CustomPayload packet, Player player)
{
try
{
ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
int packetTypeID = data.readInt();
IPacketManager packetType = getManager(packetTypeID);
if (packetType != null)
{
packetType.handlePacket(network, packet, player, data);
}
else
{
this.handlePacketData(network, packetTypeID, packet, ((EntityPlayer) player), data);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream)
{
}
}

View file

@ -0,0 +1,78 @@
package com.dark.network;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.world.World;
import universalelectricity.core.vector.Vector3;
import com.dark.DarkCore;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
public class PacketManagerEntity implements IPacketManager
{
static int packetID = 0;
@Override
public int getID()
{
return packetID;
}
@Override
public void setID(int maxID)
{
packetID = maxID;
}
@Override
public void handlePacket(INetworkManager network, Packet250CustomPayload packet, Player player, ByteArrayDataInput data)
{
try
{
int entityId = data.readInt();
World world = ((EntityPlayer) player).worldObj;
if (world != null)
{
Entity entity = world.getEntityByID(entityId);
if (entity instanceof ISimplePacketReceiver)
{
String id = data.readUTF();
((ISimplePacketReceiver) entity).simplePacket(id, data, player);
}
}
}
catch (Exception e)
{
System.out.println("[CoreMachine] Error reading packet for an entity");
e.printStackTrace();
}
}
public static void sendEntityUpdatePacket(Entity entity, boolean toServer, String id, Object... objects)
{
Object[] obj = new Object[2 + objects.length];
obj[0] = entity.entityId;
obj[1] = id;
for (int i = 0; i < objects.length; i++)
{
obj[2 + i] = objects[i];
}
Packet packet = PacketHandler.instance().getPacketWithID(DarkCore.CHANNEL, packetID, obj);
if (toServer)
{
PacketDispatcher.sendPacketToServer(packet);
}
else
{
PacketHandler.instance().sendPacketToClients(packet, entity.worldObj, new Vector3(entity), 64);
}
}
}

View file

@ -0,0 +1,84 @@
package com.dark.network;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import com.dark.DarkCore;
import com.dark.interfaces.IControlReceiver;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
public class PacketManagerKeyEvent implements IPacketManager
{
static int packetID = 0;
private static PacketManagerKeyEvent instance;
private List<IControlReceiver> receivers = new ArrayList<IControlReceiver>();
public static PacketManagerKeyEvent instance()
{
if (instance == null)
{
instance = new PacketManagerKeyEvent();
}
return instance;
}
public void register(IControlReceiver rec)
{
if (!this.receivers.contains(rec))
{
this.receivers.add(rec);
}
}
public void remove(IControlReceiver rec)
{
this.receivers.remove(rec);
}
@Override
public int getID()
{
return packetID;
}
@Override
public void setID(int maxID)
{
packetID = maxID;
}
@Override
public void handlePacket(INetworkManager network, Packet250CustomPayload packet, Player player, ByteArrayDataInput data)
{
try
{
int key = data.readInt();
for (IControlReceiver receiver : instance().receivers)
{
if (receiver.keyTyped((EntityPlayer) player, key))
{
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void sendPacket(int key)
{
PacketDispatcher.sendPacketToServer(PacketHandler.instance().getPacketWithID(DarkCore.CHANNEL, PacketManagerKeyEvent.packetID, key));
}
}

View file

@ -0,0 +1,67 @@
package com.dark.network;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import universalelectricity.prefab.network.IPacketReceiver;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.Player;
public class PacketManagerTile implements IPacketManager
{
static int packetID = 0;
@Override
public int getID()
{
return packetID;
}
@Override
public void setID(int maxID)
{
packetID = maxID;
}
@Override
public void handlePacket(INetworkManager network, Packet250CustomPayload packet, Player player, ByteArrayDataInput data)
{
try
{
int x = data.readInt();
int y = data.readInt();
int z = data.readInt();
World world = ((EntityPlayer) player).worldObj;
if (world != null)
{
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if (tileEntity != null)
{
PacketDataWatcher.instance.onPacketData(tileEntity, packet, System.currentTimeMillis());
if (tileEntity instanceof ISimplePacketReceiver)
{
String pId = data.readUTF();
((ISimplePacketReceiver) tileEntity).simplePacket(pId, data, player);
}
if (tileEntity instanceof IPacketReceiver)
{
((IPacketReceiver) tileEntity).handlePacketData(network, 0, packet, ((EntityPlayer) player), data);
}
}
}
}
catch (Exception e)
{
System.out.println("[CoreMachine] Error reading packet at tile packet manager");
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,20 @@
package com.dark.prefab;
import net.minecraft.item.Item;
import net.minecraftforge.common.Configuration;
import com.dark.DarkCore;
public class ItemBasic extends Item
{
public ItemBasic(int itemID, String name, Configuration config)
{
super(config.getItem(name, itemID).getInt());
this.setUnlocalizedName(name);
}
public ItemBasic(String name, Configuration config)
{
this(DarkCore.getNextID(), name, config);
}
}

View file

@ -0,0 +1,30 @@
package com.dark.prefab;
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
/** Simple itemBlock class for quick use with a block
*
* @author Darkguardsman */
public class ItemBlockHolder extends ItemBlock
{
public ItemBlockHolder(int id)
{
super(id);
this.setMaxDamage(0);
this.setHasSubtypes(true);
}
@Override
public int getMetadata(int damage)
{
return damage;
}
@Override
public String getUnlocalizedName(ItemStack itemStack)
{
return Block.blocksList[this.getBlockID()].getUnlocalizedName() + "." + itemStack.getItemDamage();
}
}

View file

@ -0,0 +1,120 @@
package com.dark.prefab.tile.network;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
import com.builtbroken.common.Pair;
import com.dark.tile.network.IMotionPath;
import com.dark.tile.network.INetworkPart;
/** Class that acts like the redpower pipes system. Each item is marked with a destination. Intended
* use it to improve the assembly line network
*
* @author DarkGuardsman */
public class NetworkItemSupply extends NetworkTileEntities
{
List<Pair<Entity, Vector3>> trackingList = new ArrayList<Pair<Entity, Vector3>>();
List<Entity> ignoreList = new ArrayList<Entity>();
/** Same as valid directions from forge direction enum but Unknown was added so that is gets
* check and checked first */
public static final ForgeDirection[] VALID_DIRECTIONS = { ForgeDirection.UNKNOWN, ForgeDirection.DOWN, ForgeDirection.UP, ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.WEST, ForgeDirection.EAST };
public NetworkItemSupply(INetworkPart... parts)
{
super(parts);
}
@Override
public void updateTick()
{
Iterator<Pair<Entity, Vector3>> it = trackingList.iterator();
while (it.hasNext())
{
Pair<Entity, Vector3> entry = it.next();
if (entry.left() == null || !this.isOnPath(entry.left()))
{
it.remove();
}
else
{
if (entry.right() == null)
{
entry.setRight(new Vector3(entry.left()));
}
else
{
entry.left().setPosition(entry.right().x, entry.right().y, entry.right().z);
}
}
}
}
@Override
public int getUpdateRate()
{
return 1;
}
/** Remove an entity from the tracking list */
public void removeEntity(Entity entity)
{
this.trackingList.remove(entity);
}
/** Ignores an entity so that is can be controlled by something else for a while. Eg armbots, and
* drones */
public void ignoreEntity(Entity entity)
{
if (!this.ignoreList.contains(entity))
{
this.ignoreList.add(entity);
}
}
/** Add and entity to the tracking list */
public void addEntity(Entity entity)
{
if (!this.trackingList.contains(entity))
{
this.trackingList.add(new Pair<Entity, Vector3>(entity, new Vector3(entity)));
}
}
public boolean isTrackingEntity(Entity entity)
{
return this.trackingList.contains(entity);
}
public boolean isOnPath(Entity entity)
{
if (entity != null)
{
Vector3 ent = new Vector3(entity);
//Check all directions including the current position of the entity
for (ForgeDirection direction : NetworkItemSupply.VALID_DIRECTIONS)
{
TileEntity a = ent.clone().modifyPositionFromSide(direction).getTileEntity(entity.worldObj);
if (a instanceof IMotionPath && ((IMotionPath) a).canMoveEntity(entity) && this.networkMembers.contains(a))
{
return true;
}
}
}
return false;
}
@Override
public boolean isValidMember(INetworkPart part)
{
return super.isValidMember(part) && part instanceof IMotionPath;
}
}

View file

@ -0,0 +1,54 @@
package com.dark.prefab.tile.network;
import java.util.HashSet;
import java.util.Set;
import com.dark.tile.network.INetworkPart;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import universalelectricity.core.path.IPathCallBack;
import universalelectricity.core.path.Pathfinder;
import universalelectricity.core.vector.Vector3;
/** Check if a conductor connects with another. */
public class NetworkPathFinder extends Pathfinder
{
public NetworkPathFinder(final World world, final INetworkPart targetPoint, final INetworkPart... ignoredTiles)
{
super(new IPathCallBack()
{
@Override
public Set<Vector3> getConnectedNodes(Pathfinder finder, Vector3 currentNode)
{
Set<Vector3> neighbors = new HashSet<Vector3>();
TileEntity tile = currentNode.getTileEntity(world);
if (tile instanceof INetworkPart)
{
for (TileEntity ent : ((INetworkPart) tile).getNetworkConnections())
{
if (ent instanceof INetworkPart)
{
neighbors.add(new Vector3(ent));
}
}
}
return neighbors;
}
@Override
public boolean onSearch(Pathfinder finder, Vector3 node)
{
if (node.getTileEntity(world) == targetPoint)
{
finder.results.add(node);
return true;
}
return false;
}
});
}
}

View file

@ -0,0 +1,31 @@
package com.dark.prefab.tile.network;
import java.util.HashMap;
import java.util.List;
import com.dark.tile.network.INetworkPart;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/** Network that supplies resources to tiles that demand a set resource
*
* @param C - Storage class used to handle what the network transports
* @param I - Base acceptor class
* @author DarkGuardsman */
public class NetworkResourceSupply<C, I> extends NetworkTileEntities
{
protected C storage;
protected HashMap<I, List<ForgeDirection>> acceptors = new HashMap();
public NetworkResourceSupply(INetworkPart... parts)
{
super(parts);
}
public boolean isValidAcceptor(TileEntity entity)
{
return entity != null && !entity.isInvalid();
}
}

View file

@ -0,0 +1,182 @@
package com.dark.prefab.tile.network;
import com.dark.interfaces.IPowerLess;
import com.dark.tile.network.INetworkEnergyPart;
import com.dark.tile.network.INetworkPart;
import net.minecraft.tileentity.TileEntity;
import universalelectricity.core.block.IElectricalStorage;
import universalelectricity.core.electricity.ElectricityPack;
/** Used for tile networks that only need to share power or act like a group battery that doesn't
* store power on world save
*
* @author DarkGuardsman */
public class NetworkSharedPower extends NetworkTileEntities implements IElectricalStorage, IPowerLess
{
private float energy, energyMax;
private boolean runPowerLess;
public NetworkSharedPower(INetworkPart... parts)
{
super(parts);
}
@Override
public boolean isValidMember(INetworkPart part)
{
return super.isValidMember(part) && part instanceof INetworkEnergyPart;
}
public float receiveElectricity(TileEntity source, float power, boolean doFill)
{
if (!this.runPowerLess && this.networkMembers.contains(source))
{
return this.receiveElectricity(power, doFill);
}
return 0;
}
public float receiveElectricity(ElectricityPack receive, boolean doReceive)
{
if (receive != null)
{
float prevEnergyStored = this.getEnergyStored();
float newStoredEnergy = Math.min(this.getEnergyStored() + receive.getWatts(), this.getMaxEnergyStored());
if (doReceive)
{
this.setEnergyStored(newStoredEnergy);
}
return Math.max(newStoredEnergy - prevEnergyStored, 0);
}
return 0;
}
public float receiveElectricity(float energy, boolean doReceive)
{
return this.receiveElectricity(ElectricityPack.getFromWatts(energy, .120f), doReceive);
}
public boolean drainPower(TileEntity source, float power, boolean doDrain)
{
if (this.networkMembers.contains(source) && (this.getEnergyStored() >= power || this.runPowerLess))
{
if (doDrain && !this.runPowerLess)
{
this.setEnergyStored(this.getEnergyStored() - power);
}
return true;
}
return false;
}
@Override
public void cleanUpMembers()
{
super.cleanUpMembers();
boolean set = false;
this.energyMax = 0;
for (INetworkPart part : this.networkMembers)
{
if (!set && part instanceof IPowerLess && ((IPowerLess) part).runPowerLess())
{
this.setPowerLess(((IPowerLess) part).runPowerLess());
set = true;
}
if (part instanceof INetworkEnergyPart)
{
this.energyMax += ((INetworkEnergyPart) part).getPartMaxEnergy();
}
}
}
@Override
public boolean runPowerLess()
{
return this.runPowerLess;
}
@Override
public void setPowerLess(boolean bool)
{
this.runPowerLess = bool;
for (INetworkPart part : this.networkMembers)
{
if (part instanceof IPowerLess)
{
((IPowerLess) part).setPowerLess(bool);
}
}
}
@Override
public void setEnergyStored(float energy)
{
this.energy = energy;
if (this.energy > this.getMaxEnergyStored())
{
this.energy = this.getMaxEnergyStored();
}
}
@Override
public float getEnergyStored()
{
if (this.energy < 0)
{
this.energy = 0;
}
return this.energy;
}
@Override
public float getMaxEnergyStored()
{
if (this.energyMax < 0)
{
this.energyMax = Math.abs(this.energyMax);
}
return this.energyMax;
}
/** Space left to store more energy */
public float getEnergySpace()
{
return Math.max(this.getMaxEnergyStored() - this.getEnergyStored(), 0);
}
@Override
public void save()
{
this.cleanUpMembers();
float energyRemaining = this.getEnergyStored();
for (INetworkPart part : this.getMembers())
{
float watts = energyRemaining / this.getMembers().size();
if (part instanceof INetworkEnergyPart)
{
((INetworkEnergyPart) part).setEnergyStored(Math.min(watts, ((INetworkEnergyPart) part).getMaxEnergyStored()));
energyRemaining -= Math.min(watts, ((INetworkEnergyPart) part).getMaxEnergyStored());
}
}
}
@Override
public void load()
{
this.setEnergyStored(0);
this.cleanUpMembers();
for (INetworkPart part : this.getMembers())
{
if (part instanceof INetworkEnergyPart)
{
this.setEnergyStored(this.getEnergyStored() + ((INetworkEnergyPart) part).getPartEnergy());
}
}
}
}

View file

@ -0,0 +1,280 @@
package com.dark.prefab.tile.network;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.dark.tile.network.INetworkPart;
import com.dark.tile.network.ITileNetwork;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.path.Pathfinder;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
public class NetworkTileEntities implements ITileNetwork
{
protected Set<INetworkPart> networkMembers = new HashSet<INetworkPart>();
public NetworkTileEntities()
{
NetworkUpdateHandler.instance().registerNetwork(this);
}
public NetworkTileEntities(INetworkPart... parts)
{
this();
if (parts != null)
{
for (INetworkPart part : parts)
{
if (this.isValidMember(part))
{
part.setTileNetwork(this);
networkMembers.add(part);
}
}
}
}
@Override
public String getName()
{
return "TileNetwork";
}
@Override
public Set<INetworkPart> getMembers()
{
if (this.networkMembers == null)
{
this.networkMembers = new HashSet<INetworkPart>();
}
return networkMembers;
}
@Override
public void onCreated()
{
this.load();
this.cleanUpMembers();
}
@Override
public int getUpdateRate()
{
return -1;
}
@Override
public void updateTick()
{
// TODO Auto-generated method stub
}
@Override
public void refreshTick()
{
// TODO Auto-generated method stub
}
@Override
public boolean addTile(TileEntity ent, boolean member)
{
if (ent == null || ent.isInvalid())
{
return false;
}
else if (ent instanceof INetworkPart && this.isValidMember((INetworkPart) ent) && member)
{
((INetworkPart) ent).setTileNetwork(this);
if (this.networkMembers.contains(ent))
{
return true;
}
return this.networkMembers.add((INetworkPart) ent);
}
return false;
}
@Override
public boolean removeTile(TileEntity ent)
{
return this.networkMembers.remove(ent);
}
/** Cleans the list of networkMembers and remove those that no longer belong */
public void cleanUpMembers()
{
Iterator<INetworkPart> it = this.networkMembers.iterator();
while (it.hasNext())
{
INetworkPart part = it.next();
if (!this.isValidMember(part))
{
it.remove();
}
else
{
part.setTileNetwork(this);
}
}
}
/** Is this part a valid member of the network */
public boolean isValidMember(INetworkPart part)
{
return part != null && part instanceof TileEntity && !((TileEntity) part).isInvalid();
}
@Override
public void save()
{
// TODO Auto-generated method stub
}
@Override
public void load()
{
// TODO Auto-generated method stub
}
@Override
public void mergeNetwork(ITileNetwork network, INetworkPart mergePoint)
{
if (network != null && network != this && network.getClass().equals(this.getClass()))
{
if (this.preMergeProcessing(network, mergePoint))
{
this.mergeDo(network);
}
}
}
/** Processing that needs too be done before the network merges. Use this to do final network
* merge calculations and to cause network merge failure
*
* @param network the network that is to merge with this one
* @param part the part at which started the network merge. Use this to cause damage if two
* networks merge with real world style failures
*
* @return false if the merge needs to be canceled.
*
* Cases in which the network should fail to merge are were the two networks merge with error.
* Or, in the case of pipes the two networks merge and the merge point was destroyed by
* combination of liquids.
*
* Ex Lava and water */
public boolean preMergeProcessing(ITileNetwork network, INetworkPart part)
{
this.save();
return true;
}
/** Merges the two networks together */
protected void mergeDo(ITileNetwork network)
{
ITileNetwork newNetwork = NetworkUpdateHandler.createNewNetwork(NetworkUpdateHandler.getID(this.getClass()));
if (newNetwork != null)
{
newNetwork.getMembers().addAll(this.getMembers());
newNetwork.getMembers().addAll(network.getMembers());
newNetwork.onCreated();
this.invalidate();
}
else
{
System.out.println("[CoreMachine]NetworkTileEntities: Failed to merge network due to network creation failure");
}
}
@Override
public void splitNetwork(INetworkPart splitPoint)
{
this.getMembers().remove(splitPoint);
if (splitPoint instanceof TileEntity)
{
List<TileEntity> connections = splitPoint.getNetworkConnections();
for (final TileEntity connectionStart : connections)
{
if (connectionStart instanceof INetworkPart)
{
for (final TileEntity connectionEnd : connections)
{
if (connectionStart != connectionEnd && connectionEnd instanceof INetworkPart)
{
Pathfinder finder = new NetworkPathFinder(connectionEnd.worldObj, (INetworkPart) connectionEnd, splitPoint);
finder.init(new Vector3(connectionStart));
if (finder.results.size() <= 0)
{
this.save();
/* NO LONGER CONNECTED ELSE WHERE SO SPLIT AND REFRESH */
ITileNetwork newNetwork = NetworkUpdateHandler.createNewNetwork(NetworkUpdateHandler.getID(this.getClass()));
if (newNetwork != null)
{
for (Vector3 node : finder.closedSet)
{
TileEntity entity = node.getTileEntity(connectionEnd.worldObj);
if (entity instanceof INetworkPart)
{
if (node != splitPoint)
{
newNetwork.getMembers().add((INetworkPart) entity);
}
}
}
newNetwork.onCreated();
}
}
}
}
}
}
}
}
@Override
public String toString()
{
return this.getName() + "[" + this.hashCode() + "| Parts:" + this.networkMembers.size() + "]";
}
@Override
public boolean isInvalid()
{
return this.networkMembers.isEmpty();
}
@Override
public void invalidate()
{
this.networkMembers.clear();
}
public static void invalidate(TileEntity tileEntity)
{
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity checkTile = VectorHelper.getConnectorFromSide(tileEntity.worldObj, new Vector3(tileEntity), direction);
if (checkTile instanceof INetworkPart && ((INetworkPart) checkTile).getTileNetwork() != null)
{
((INetworkPart) checkTile).getTileNetwork().removeTile(tileEntity);
}
}
}
}

View file

@ -0,0 +1,159 @@
package com.dark.prefab.tile.network;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.dark.tile.network.ITileNetwork;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
/** Manages all the tile networks making sure they get world save events, and updates every so often
*
* @author DarkGuardsman */
public class NetworkUpdateHandler implements ITickHandler
{
private static HashMap<String, Class<?>> nameToClassMap = new HashMap<String, Class<?>>();
private static HashMap<Class<?>, String> classToNameMap = new HashMap<Class<?>, String>();
private int count = 0;
private static int refreshTicks = 6000;
private Set<ITileNetwork> activeNetworks = new HashSet();
private Set<ITileNetwork> allNetworks = new HashSet();
private static NetworkUpdateHandler instance;
static
{
registerNetworkClass("base", NetworkTileEntities.class);
}
public static NetworkUpdateHandler instance()
{
if (instance == null)
{
instance = new NetworkUpdateHandler();
}
return instance;
}
public void registerNetwork(ITileNetwork network)
{
if (network != null && !activeNetworks.contains(network))
{
this.allNetworks.add(network);
if (network.getUpdateRate() > 0)
{
this.activeNetworks.add(network);
}
}
}
public static void registerNetworkClass(String id, Class<?> clazz)
{
if (!nameToClassMap.containsKey(id) && !classToNameMap.containsKey(clazz))
{
nameToClassMap.put(id, clazz);
classToNameMap.put(clazz, id);
}
}
public static String getID(Class<?> clazz)
{
return classToNameMap.get(clazz);
}
public static Class<?> getClazz(String id)
{
return nameToClassMap.get(id);
}
public static ITileNetwork createNewNetwork(String id)
{
Class<?> clazz = getClazz(id);
if (clazz != null)
{
try
{
Object object = clazz.newInstance();
if (object instanceof ITileNetwork)
{
return (ITileNetwork) object;
}
}
catch (Exception e)
{
System.out.println("[CoreMachine]TileNetworkHandler: Failed to create a new network object");
e.printStackTrace();
}
}
else
{
System.out.println("[CoreMachine]TileNetworkHandler: Unkown id: " + id);
}
return null;
}
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)
{
if (count + 1 >= NetworkUpdateHandler.refreshTicks)
{
count = 0;
for (ITileNetwork network : allNetworks)
{
if (!network.isInvalid())
{
network.refreshTick();
}
}
}
else
{
count++;
for (ITileNetwork network : activeNetworks)
{
if (!network.isInvalid())
{
network.updateTick();
}
}
}
}
@Override
public void tickEnd(EnumSet<TickType> type, Object... tickData)
{
Iterator<ITileNetwork> it = activeNetworks.iterator();
while (it.hasNext())
{
ITileNetwork network = it.next();
if (network.isInvalid())
{
network.invalidate();
it.remove();
allNetworks.remove(network);
}
}
}
@Override
public EnumSet<TickType> ticks()
{
return EnumSet.of(TickType.SERVER);
}
@Override
public String getLabel()
{
return "[CoreMachine]TileNetworkHandler";
}
}

View file

@ -0,0 +1,24 @@
package com.dark.tile.network;
import net.minecraft.entity.Entity;
import universalelectricity.core.vector.Vector3;
/** Use by tiles to control the path of motion of an item threw a tile network such as items pipes
*
* @author DarkGuardsman */
public interface IMotionPath
{
/** Gets the motion applied to the entity while its on the tile **/
public Vector3 getMotion(Entity entity);
/** Can the path controller move the entity over this tile. Make sure to check the position of
* the tile as the controller doesn't know the range of control of the tile. Though it does
* limit itself to blocks around the entity. So if your tile only effects entities above it
* within its bound then make sure the tile is inside those bounds
*
* @param entity - entity in question
* @param from - direction the entity came from
* @return true if it can, false if something is wrong like no power, or solid side */
public boolean canMoveEntity(Entity entity);
}

View file

@ -0,0 +1,18 @@
package com.dark.tile.network;
/** Used on tiles that can contain more than one tile network. Currently WIP so don't use unless you
* know what your doing. When using this use networks like items and store them in slots.
*
* @author DarkGuardsman */
public interface INetworkContainer
{
/** Gets a list of all networks slots and their connected networks. Used both to see the max
* limit of networks this tile may contain, and if there are networks currently in use */
public ITileNetwork[] getContainedNetworks();
/** Sets the network in the given slot */
public boolean setNetwork(int slot, ITileNetwork network);
/** Gets the network in the slot */
public ITileNetwork getNetwork(int slot);
}

View file

@ -0,0 +1,20 @@
package com.dark.tile.network;
import universalelectricity.core.block.IElectricalStorage;
/** Tiles that use NetworkSharedPower class should implements this. All methods in IElectricalStorage
* should point to the network instead of the tile. This is why more energy methods are added to
* this interface
*
* @author DarkGuardsman */
public interface INetworkEnergyPart extends INetworkPart, IElectricalStorage
{
/** Gets the energy stored in the part */
public float getPartEnergy();
/** Gets the max energy storage limit of the part */
public float getPartMaxEnergy();
/** Sets the energy stored in the part */
public void setPartEnergy(float energy);
}

View file

@ -0,0 +1,20 @@
package com.dark.tile.network;
import java.util.List;
import net.minecraft.tileentity.TileEntity;
public interface INetworkPart extends ITileConnector
{
/** Array of connections this tile has to other tiles */
public List<TileEntity> getNetworkConnections();
/** Update the connection this tile has to other tiles */
public void refresh();
/** Gets the networkPart's primary network */
public ITileNetwork getTileNetwork();
/** Sets the networkPart's primary network */
public void setTileNetwork(ITileNetwork network);
}

View file

@ -0,0 +1,43 @@
package com.dark.tile.network;
import net.minecraftforge.common.ForgeDirection;
/** Used on tiles that want control over what can connect to there device. It is suggest that other
* interfaces for connection be routed threw this to reduce the need to change things
*
* @author DarkGuardsman */
public interface ITileConnector
{
/** Can this tile connect on the given side */
public boolean canTileConnect(Connection type, ForgeDirection dir);
/** Types of connections */
public static enum Connection
{
/** Energy from BC, UE, IC2 */
Eletricity(),
/** Fluids from anything including BC pipes, DM pipes, Mek pipes */
FLUIDS(),
/** Force mainly from rotating rods */
FORCE(),
/** Hydraulic pressure from DM pipe */
FLUID_PRESSURE(),
AIR_PRESSURE(),
/** Item pipe */
ITEMS(),
/** Data line input */
DATA(),
/** Another tile entity */
TILE(),
/** Network of tile entities */
NETWORK(),
/** Thermal connection */
HEAT(),
/** Wire containing several wires of unknown color */
MULTI_WIRE(),
/** Bundle of pipes containing several colored pipes */
MULTI_PIPE(),
/** Device that contains several networks that can be of any type */
MULTI_NETWORK();
}
}

View file

@ -0,0 +1,60 @@
package com.dark.tile.network;
import java.util.Set;
import net.minecraft.tileentity.TileEntity;
/** Applies to objects that act as a collection of tile entities.
*
* @author DarkGuardsman */
public interface ITileNetwork
{
/** Gets the name of the network */
public String getName();
/** Gets a list of all tiles that are part of this network */
public Set<INetworkPart> getMembers();
/** Called when something want the network to add the tile
*
* @param entity - tile in question
* @param member - add it as a member if true
* @return true if added without issue */
public boolean addTile(TileEntity ent, boolean member);
/** Removes a tile from all parts of the network */
public boolean removeTile(TileEntity ent);
/** Called when this network is just created */
public void onCreated();
/** How many ticks should base between updates, return 0 or bellow for no ticks */
public int getUpdateRate();
/** Called every so many ticks so the network has a chance to update */
public void updateTick();
/** Called every so many mins when the networks needs to refresh and repair. Each part should
* still handle there own refresh when edited, or updated. This is more for the network to do
* house cleaning */
public void refreshTick();
/** Called when two networks try to merge together */
public void mergeNetwork(ITileNetwork network, INetworkPart mergePoint);
/** Called when a peace of the network is removed and might need to split in two */
public void splitNetwork(INetworkPart splitPoint);
/** Check by the network handle if this network is invalid or no longer functional */
public boolean isInvalid();
/** This is called when your network is considered invalid. You should cut all ties in the
* network to its object so GC will delete it */
public void invalidate();
/** Called when the network needs to save */
public void save();
/** Called when the network needs to load */
public void load();
}