move some stuff from core machine
This commit is contained in:
parent
7449c78567
commit
b7d6a8c6cf
42 changed files with 4420 additions and 4 deletions
|
@ -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
|
/** Handler to make registering all parts of a mod's objects that are loaded into the game by forge
|
||||||
*
|
*
|
||||||
* @author DarkGuardsman */
|
* @author DarkGuardsman */
|
||||||
public class ModObjectRegistry
|
public class CoreRegistry
|
||||||
{
|
{
|
||||||
public static HashMap<Block, String> registredBlocks = new HashMap<Block, String>();
|
public static HashMap<Block, String> registredBlocks = new HashMap<Block, String>();
|
||||||
public static HashMap<Item, String> registredItems = new HashMap<Item, 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)
|
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)
|
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)
|
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);
|
registredBlocks.put(block, name);
|
||||||
proxy.registerBlock(block, itemClass, name, modID);
|
proxy.registerBlock(block, itemClass, name, modID);
|
||||||
ModObjectRegistry.finishCreation(block);
|
CoreRegistry.finishCreation(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
|
@ -2,16 +2,30 @@ package com.dark;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.item.Item;
|
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
|
public class DarkCore
|
||||||
{
|
{
|
||||||
private static DarkCore instance;
|
private static DarkCore instance;
|
||||||
|
|
||||||
|
private boolean pre, load, post;
|
||||||
|
|
||||||
public static final String TEXTURE_DIRECTORY = "textures/";
|
public static final String TEXTURE_DIRECTORY = "textures/";
|
||||||
public static final String BLOCK_DIRECTORY = TEXTURE_DIRECTORY + "blocks/";
|
public static final String BLOCK_DIRECTORY = TEXTURE_DIRECTORY + "blocks/";
|
||||||
public static final String ITEM_DIRECTORY = TEXTURE_DIRECTORY + "items/";
|
public static final String ITEM_DIRECTORY = TEXTURE_DIRECTORY + "items/";
|
||||||
public static final String MODEL_DIRECTORY = TEXTURE_DIRECTORY + "models/";
|
public static final String MODEL_DIRECTORY = TEXTURE_DIRECTORY + "models/";
|
||||||
public static final String GUI_DIRECTORY = TEXTURE_DIRECTORY + "gui/";
|
public static final String GUI_DIRECTORY = TEXTURE_DIRECTORY + "gui/";
|
||||||
|
public static final String CHANNEL = "DARKCORE";
|
||||||
|
|
||||||
/* START IDS */
|
/* START IDS */
|
||||||
public static int BLOCK_ID_PRE = 3100;
|
public static int BLOCK_ID_PRE = 3100;
|
||||||
|
@ -26,6 +40,39 @@ public class DarkCore
|
||||||
return instance;
|
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
|
/** Gets the next unused ID in the block list. Does not prevent config file issues after the file
|
||||||
* has been made */
|
* has been made */
|
||||||
public static int getNextID()
|
public static int getNextID()
|
||||||
|
@ -63,4 +110,5 @@ public class DarkCore
|
||||||
ITEM_ID_PREFIX = id + 1;
|
ITEM_ID_PREFIX = id + 1;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
68
src/com/dark/IndustryCreativeTab.java
Normal file
68
src/com/dark/IndustryCreativeTab.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/com/dark/fluid/EnumFluid.java
Normal file
21
src/com/dark/fluid/EnumFluid.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
76
src/com/dark/fluid/EnumGas.java
Normal file
76
src/com/dark/fluid/EnumGas.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
58
src/com/dark/fluid/FilteredTank.java
Normal file
58
src/com/dark/fluid/FilteredTank.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
432
src/com/dark/fluid/FluidHelper.java
Normal file
432
src/com/dark/fluid/FluidHelper.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
17
src/com/dark/fluid/Gas.java
Normal file
17
src/com/dark/fluid/Gas.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
38
src/com/dark/fluid/GasTank.java
Normal file
38
src/com/dark/fluid/GasTank.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
src/com/dark/fluid/LiquidTank.java
Normal file
38
src/com/dark/fluid/LiquidTank.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
543
src/com/dark/helpers/AutoCraftingManager.java
Normal file
543
src/com/dark/helpers/AutoCraftingManager.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
67
src/com/dark/helpers/ConnectionHelper.java
Normal file
67
src/com/dark/helpers/ConnectionHelper.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
185
src/com/dark/helpers/EntityDictionary.java
Normal file
185
src/com/dark/helpers/EntityDictionary.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
340
src/com/dark/helpers/InvInteractionHelper.java
Normal file
340
src/com/dark/helpers/InvInteractionHelper.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
143
src/com/dark/helpers/ItemWorldHelper.java
Normal file
143
src/com/dark/helpers/ItemWorldHelper.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
206
src/com/dark/helpers/MathHelper.java
Normal file
206
src/com/dark/helpers/MathHelper.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
65
src/com/dark/helpers/PlayerKeyHandler.java
Normal file
65
src/com/dark/helpers/PlayerKeyHandler.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
278
src/com/dark/helpers/RayTraceHelper.java
Normal file
278
src/com/dark/helpers/RayTraceHelper.java
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/com/dark/interfaces/IControlReceiver.java
Normal file
16
src/com/dark/interfaces/IControlReceiver.java
Normal 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);
|
||||||
|
}
|
11
src/com/dark/interfaces/IExtendedStorage.java
Normal file
11
src/com/dark/interfaces/IExtendedStorage.java
Normal 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);
|
||||||
|
}
|
14
src/com/dark/interfaces/IPowerLess.java
Normal file
14
src/com/dark/interfaces/IPowerLess.java
Normal 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);
|
||||||
|
}
|
17
src/com/dark/network/IPacketManager.java
Normal file
17
src/com/dark/network/IPacketManager.java
Normal 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);
|
||||||
|
}
|
20
src/com/dark/network/ISimplePacketReceiver.java
Normal file
20
src/com/dark/network/ISimplePacketReceiver.java
Normal 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);
|
||||||
|
}
|
79
src/com/dark/network/PacketDataWatcher.java
Normal file
79
src/com/dark/network/PacketDataWatcher.java
Normal 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"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
346
src/com/dark/network/PacketHandler.java
Normal file
346
src/com/dark/network/PacketHandler.java
Normal 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
78
src/com/dark/network/PacketManagerEntity.java
Normal file
78
src/com/dark/network/PacketManagerEntity.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/com/dark/network/PacketManagerKeyEvent.java
Normal file
84
src/com/dark/network/PacketManagerKeyEvent.java
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
67
src/com/dark/network/PacketManagerTile.java
Normal file
67
src/com/dark/network/PacketManagerTile.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
20
src/com/dark/prefab/ItemBasic.java
Normal file
20
src/com/dark/prefab/ItemBasic.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
30
src/com/dark/prefab/ItemBlockHolder.java
Normal file
30
src/com/dark/prefab/ItemBlockHolder.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
120
src/com/dark/prefab/tile/network/NetworkItemSupply.java
Normal file
120
src/com/dark/prefab/tile/network/NetworkItemSupply.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
src/com/dark/prefab/tile/network/NetworkPathFinder.java
Normal file
54
src/com/dark/prefab/tile/network/NetworkPathFinder.java
Normal 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
31
src/com/dark/prefab/tile/network/NetworkResourceSupply.java
Normal file
31
src/com/dark/prefab/tile/network/NetworkResourceSupply.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
182
src/com/dark/prefab/tile/network/NetworkSharedPower.java
Normal file
182
src/com/dark/prefab/tile/network/NetworkSharedPower.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
280
src/com/dark/prefab/tile/network/NetworkTileEntities.java
Normal file
280
src/com/dark/prefab/tile/network/NetworkTileEntities.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
159
src/com/dark/prefab/tile/network/NetworkUpdateHandler.java
Normal file
159
src/com/dark/prefab/tile/network/NetworkUpdateHandler.java
Normal 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";
|
||||||
|
}
|
||||||
|
}
|
24
src/com/dark/tile/network/IMotionPath.java
Normal file
24
src/com/dark/tile/network/IMotionPath.java
Normal 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);
|
||||||
|
}
|
18
src/com/dark/tile/network/INetworkContainer.java
Normal file
18
src/com/dark/tile/network/INetworkContainer.java
Normal 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);
|
||||||
|
}
|
20
src/com/dark/tile/network/INetworkEnergyPart.java
Normal file
20
src/com/dark/tile/network/INetworkEnergyPart.java
Normal 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);
|
||||||
|
}
|
20
src/com/dark/tile/network/INetworkPart.java
Normal file
20
src/com/dark/tile/network/INetworkPart.java
Normal 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);
|
||||||
|
}
|
43
src/com/dark/tile/network/ITileConnector.java
Normal file
43
src/com/dark/tile/network/ITileConnector.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
60
src/com/dark/tile/network/ITileNetwork.java
Normal file
60
src/com/dark/tile/network/ITileNetwork.java
Normal 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();
|
||||||
|
}
|
Loading…
Reference in a new issue