Initial 1.4.2 and UE 1.0 update

This commit is contained in:
Calclavia 2012-10-28 13:25:56 +08:00
commit e13a214549
56 changed files with 5379 additions and 0 deletions

22
.gitattributes vendored Normal file
View file

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

33
.gitignore vendored Normal file
View file

@ -0,0 +1,33 @@
/bin/*
/conf/*
/docs/*
/eclipse/*
/forge/*
/jars/*
/lib/*
/logs/*
/modsrc/*
/reobf/*
/runtime/*
/temp/*
CHANGELOG
LICENSE.txt
*.bat
*.sh
/src/minecraft/*
/src/minecraft_server/*
/src/common/*
/builds/
!/src/*/assemblyline/
!/src/*/dan200/
!/src/*/buildcraft/
!/src/*/universalelectricity/
!/Include Resources.bat
!/mcmod.info
!/resources/*
!/modversion.txt
!/publish.bat
!/README

4
Include Resources.bat Normal file
View file

@ -0,0 +1,4 @@
@echo off
cd resources
"..\..\7za.exe" a "..\jars\bin\minecraft.jar" "*"
pause

22
mcmod.info Normal file
View file

@ -0,0 +1,22 @@
[
{
"modid": "AssemblyLine",
"name": "Assembly Line",
"description": "A mod bringing a realistic conveyor belt transporting system to Minecraft.",
"version": "0.1.0",
"mcversion": "1.4.2",
"url": "http://calclavia.com/universalelectricity/?m=18",
"updateUrl": "http://calclavia.com/universalelectricity/?m=18",
"authors": [
"Calclavia",
"Darkguardsman"
],
"credits": "Authored by Calclavia and Darkguardsman",
"logoFile": "",
"screenshots": [
],
"parent":"",
"dependencies": [
]
}
]

1
modversion.txt Normal file
View file

@ -0,0 +1 @@
0.0.6

View file

@ -0,0 +1,57 @@
package assemblyline;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import asmline.GUIEjectorSettings;
import assemblyline.interaction.ContainerEjector;
import assemblyline.interaction.TileEntityEjector;
import cpw.mods.fml.common.network.IGuiHandler;
public class ALProxy implements IGuiHandler
{
public void preInit()
{
}
public void init()
{
}
public void postInit()
{
}
@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if (tileEntity != null)
{
switch(ID)
{
case 0: return new GUIEjectorSettings(player.inventory, ((TileEntityEjector)tileEntity));
}
}
return null;
}
@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if (tileEntity != null)
{
switch(ID)
{
case 0: return new ContainerEjector(player.inventory, ((TileEntityEjector)tileEntity));
}
}
return null;
}
}

View file

@ -0,0 +1,100 @@
package assemblyline;
import java.io.File;
import net.minecraft.src.Block;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.oredict.ShapedOreRecipe;
import net.minecraftforge.oredict.ShapelessOreRecipe;
import universalelectricity.prefab.network.PacketManager;
import assemblyline.belts.BlockConveyorBelt;
import assemblyline.belts.TileEntityConveyorBelt;
import assemblyline.interaction.BlockInteraction;
import assemblyline.interaction.ItemMachine;
import assemblyline.interaction.TileEntityEjector;
import assemblyline.interaction.TileEntityMachineInput;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
@Mod(modid = "asmLine", name = "Assemble Line", version = "V2.3", dependencies = "after:UniversalElectricity")
@NetworkMod(channels =
{ "asmLine" }, clientSideRequired = true, serverSideRequired = false, packetHandler = PacketManager.class)
public class AssembleLine
{
@SidedProxy(clientSide = "asmline.asmClientProxy", serverSide = "asmline.asmProxy")
public static ALProxy proxy;
public static AssembleLine instance;
public static final Configuration config = new Configuration(new File(cpw.mods.fml.common.Loader.instance().getConfigDir(), "UniversalElectricity/ConveyorBelts.cfg"));
public static int machineID = configurationProperties();
public static int machine2ID;
public static int beltBlockID;
public static boolean animationOn;
public static final String TEXTURE_PATH = "/textures";
public static final Block blockConveyorBelt = new BlockConveyorBelt(beltBlockID);
public static final Block blockMachine = new BlockInteraction(machineID);
public static int configurationProperties()
{
config.load();
beltBlockID = Integer.parseInt(config.getBlock(Configuration.CATEGORY_BLOCK, "BeltBlockID", 3003).value);
machineID = Integer.parseInt(config.getBlock(Configuration.CATEGORY_BLOCK, "MachineID", 3005).value);
animationOn = Boolean.parseBoolean(config.get(Configuration.CATEGORY_GENERAL, "BeltAnimationOn", true).value);
config.save();
return machineID;
}
@PreInit
public void preInit(FMLPreInitializationEvent event)
{
instance = this;
NetworkRegistry.instance().registerGuiHandler(this, this.proxy);
GameRegistry.registerBlock(blockConveyorBelt);
GameRegistry.registerBlock(blockMachine, ItemMachine.class);
proxy.preInit();
}
@Init
public void load(FMLInitializationEvent evt)
{
GameRegistry.registerTileEntity(TileEntityConveyorBelt.class, "belt");
GameRegistry.registerTileEntity(TileEntityEjector.class, "ejector");
GameRegistry.registerTileEntity(TileEntityMachineInput.class, "scop");
proxy.init();
// Names
LanguageRegistry.addName(new ItemStack(blockConveyorBelt, 1), "Coneveyor Belt");
LanguageRegistry.addName(new ItemStack(blockMachine, 1, 0), "Ejector");
LanguageRegistry.addName(new ItemStack(blockMachine, 1, 4), "MachineInput");
LanguageRegistry.addName(new ItemStack(blockMachine, 1, 8), "FutureBlock");
LanguageRegistry.addName(new ItemStack(blockMachine, 1, 12), "FutureBlock");
}
@PostInit
public void postInit(FMLPostInitializationEvent event)
{
//Conveyor Belt
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockConveyorBelt), new Object[]
{ "III", "MCM", 'I', Item.ingotIron, 'M', "motor", 'C', "basicCircuit" }));
//Rejector
GameRegistry.addRecipe(new ItemStack(blockMachine, 1, 0), new Object[]
{ "WPW", "@R@", '@', "plateSteel", 'R', Item.redstone, 'P', Block.pistonBase, 'C', "basicCircuit", 'W', "copperWire"});
//Retriever
GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(blockMachine, 1, 4), new Object[]
{ Block.dispenser, "basicCircuit"}));
proxy.postInit();
}
}

View file

@ -0,0 +1,278 @@
package assemblyline;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import universalelectricity.prefab.TileEntityAdvanced;
import universalelectricity.prefab.network.IPacketReceiver;
public abstract class TileEntityBase extends TileEntityAdvanced implements IPacketReceiver, IInventory
{
/**
* The items this container contains.
*/
protected ItemStack[] containingItems = new ItemStack[this.getSizeInventory()];
/**
* The amount of players using this tile entity.
*/
protected int playerUsing = 0;
/**
* Is this tile entity locked?
*/
protected boolean locked = false;
/**
* The owner of this tile entity.
*/
protected String owner = "";
/*
* { if (count++ >=
* 10) { count = 0; if (!worldObj.isRemote &&
* this.sendDataA() != null) { Packet packet =
* PacketManager.getPacket("asmLine", this,
* this.buildData(1));
* PacketManager.sendPacketToClients(packet,
* worldObj, Vector3.get(this), 40); } if
* (!worldObj.isRemote && this.sendDataG() !=
* null && this.isOpen) { Packet packet =
* PacketManager.getPacket("asmLine", this,
* this.buildData(0));
* PacketManager.sendPacketToClients(packet,
* worldObj, Vector3.get(this), 10); } } if
* (ticks++ % tickRate() >= 0 &&
* !isDisabled()) { this.tickedUpdate(); } }
*/
/**
* Inventory functions.
*/
@Override
public ItemStack getStackInSlot(int par1)
{
return this.containingItems[par1];
}
@Override
public ItemStack decrStackSize(int par1, int par2)
{
if (this.containingItems[par1] != null)
{
ItemStack var3;
if (this.containingItems[par1].stackSize <= par2)
{
var3 = this.containingItems[par1];
this.containingItems[par1] = null;
return var3;
}
else
{
var3 = this.containingItems[par1].splitStack(par2);
if (this.containingItems[par1].stackSize == 0)
{
this.containingItems[par1] = null;
}
return var3;
}
}
else
{
return null;
}
}
@Override
public ItemStack getStackInSlotOnClosing(int par1)
{
if (this.containingItems[par1] != null)
{
ItemStack var2 = this.containingItems[par1];
this.containingItems[par1] = null;
return var2;
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
{
this.containingItems[par1] = par2ItemStack;
if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
{
par2ItemStack.stackSize = this.getInventoryStackLimit();
}
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
{
return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64.0D;
}
@Override
public void openChest()
{
this.playerUsing++;
}
@Override
public void closeChest()
{
this.playerUsing--;
}
/**
* NBT Data
*/
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.locked = nbt.getBoolean("locked");
this.owner = nbt.getString("Owner");
NBTTagList var2 = nbt.getTagList("Items");
this.containingItems = new ItemStack[this.getSizeInventory()];
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3);
byte var5 = var4.getByte("Slot");
if (var5 >= 0 && var5 < this.containingItems.length)
{
this.containingItems[var5] = ItemStack.loadItemStackFromNBT(var4);
}
}
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("locked", this.locked);
nbt.setString("Owner", this.owner);
NBTTagList var2 = new NBTTagList();
for (int var3 = 0; var3 < this.containingItems.length; ++var3)
{
if (this.containingItems[var3] != null)
{
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte) var3);
this.containingItems[var3].writeToNBT(var4);
var2.appendTag(var4);
}
}
nbt.setTag("Items", var2);
}
/*
@Override
public void handlePacketData(NetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream)
{
if (worldObj.isRemote)
{
try
{
int ID = dataStream.readInt();
if (ID == 0)
{
this.guiPacket(network, packetType, packet, player, dataStream);
}
else if (ID == 1)
{
this.animationPacket(network, packetType, packet, player, dataStream);
}
else
{
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* Used to read GUI only data sent to the TE
public abstract void guiPacket(NetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream);
/**
* Used to read animation data for things that
* can be seen on a TE
public abstract void animationPacket(NetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream);
/**
* Used to read data for none animation or gui
* server sent packets
*
public abstract void otherPacket(NetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream);
public Object[] buildData(int packetID)
{
Object[] data = new Object[1];
if (packetID == 0)
{
data = new Object[this.sendDataG().length + 1];
data[0] = packetID;
for (int i = 0; i < this.sendDataG().length; i++)
{
data[i + 1] = this.sendDataG()[i];
}
}
else if (packetID == 1)
{
data = new Object[this.sendDataA().length + 1];
data[0] = packetID;
for (int i = 0; i < this.sendDataA().length; i++)
{
data[i + 1] = this.sendDataA()[i];
}
}
return data;
}
/**
* Array of data too be sent for animation
* updates
*
* @return
*
public abstract Object[] sendDataA();
/**
* Array of data too be sent if the TE's GUI
* is open at the time
*
* @return
*
public abstract Object[] sendDataG();
*/
}

View file

@ -0,0 +1,88 @@
package assemblyline.belts;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityLiving;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.Material;
import net.minecraft.src.MathHelper;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import universalelectricity.prefab.BlockMachine;
import asmline.beltRenders.BeltRenderHelper;
/**
* The block for the actual conveyor!
*
* @Oldauthors Calclavia,Elusivehawk
* @author DarkGuardsman
*/
public class BlockConveyorBelt extends BlockMachine
{
public BlockConveyorBelt(int id)
{
super("Conveyor Belt", id, Material.wood);
this.setBlockBounds(0, 0, 0, 1, 0.3f, 1);
this.setTextureFile("/textures/items.png");
this.blockIndexInTexture = 0;
this.setCreativeTab(CreativeTabs.tabRedstone);
}
@Override
public void onBlockPlacedBy(World par1World, int x, int y, int z, EntityLiving par5EntityLiving)
{
int angle = MathHelper.floor_double((par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, angle);
}
@Override
public boolean onUseWrench(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
int metadata = par1World.getBlockMetadata(x, y, z);
if (metadata >= 0 && metadata < 4)
{
if (metadata == 3)
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, 0);
return true;
}
else
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, metadata + 1);
return true;
}
}
return true;
}
/**
* Returns the TileEntity used by this block.
*/
@Override
public TileEntity createNewTileEntity(World var1,int meta)
{
if(meta >=0 && meta < 4)
{
return new TileEntityConveyorBelt();
}
return null;
}
@Override
public int getRenderType()
{
return BeltRenderHelper.blockRenderId;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
}

View file

@ -0,0 +1,334 @@
package assemblyline.belts;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.Vector3;
import universalelectricity.implement.IConductor;
import universalelectricity.prefab.TileEntityElectricityReceiver;
import universalelectricity.prefab.network.IPacketReceiver;
import universalelectricity.prefab.network.PacketManager;
import assemblyline.AssembleLine;
import com.google.common.io.ByteArrayDataInput;
public class TileEntityConveyorBelt extends TileEntityElectricityReceiver implements IPacketReceiver
{
public double electricityStored = 0;
public final double electricityRequired = 0.1f;
public final double energyMax = 10;
private float speed = -0.05F;
public float wheelRotation = 0;
public boolean running = false;
public boolean flip = false;
public TileEntityConveyorBelt[] adjBelts =
{ null, null, null, null };
public int clearCount = 0;
public int range = 0;
public boolean connected = false;
public List<Entity> entityIgnoreList = new ArrayList<Entity>();
// Checks Adjacent belt to see if there
// powered. Reduces need for wire per belt
public boolean powerNeighbor()
{
for (int n = 2; n < 6; n++)
{
ForgeDirection d = ForgeDirection.getOrientation(n);
TileEntity ent = worldObj.getBlockTileEntity(xCoord - d.offsetX, yCoord, zCoord - d.offsetZ);
if (ent instanceof TileEntityConveyorBelt)
{
adjBelts[n - 2] = (TileEntityConveyorBelt) ent;
}
else
{
adjBelts[n - 2] = null;
}
}
int rr = 0;
for (int b = 0; b < 4; b++)
{
if (adjBelts[b] instanceof TileEntityConveyorBelt)
{
TileEntityConveyorBelt belt = (TileEntityConveyorBelt) adjBelts[b];
if (belt.range > rr)
{
rr = belt.getRange();
}
}
}
this.range = rr - 1;
return false;
}
public int getRange()
{
return this.range;
}
@Override
public void updateEntity()
{
super.updateEntity();
if (this.ticks % 10 == 0)
{
if (worldObj.getBlockTileEntity(xCoord, yCoord - 1, zCoord) instanceof IConductor)
{
this.connected = true;
}
else
{
this.connected = false;
}
if (this.electricityStored >= this.electricityRequired)
{
this.electricityStored = Math.max(this.electricityStored - this.electricityRequired, 0);
this.range = 20;
}
else
{
this.range = 0;
}
if (!this.connected)
{
powerNeighbor();
}
if (this.range > 0)
{
this.running = true;
}
else
{
this.running = false;
}
if (!worldObj.isRemote)
{
Packet packet = PacketManager.getPacket("asmLine", this, new Object[]
{ running, range });
PacketManager.sendPacketToClients(packet, worldObj, new Vector3(xCoord, yCoord, zCoord), 40);
}
}
if (this.running)
{
AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord, this.zCoord, this.xCoord + 1, this.yCoord + 1, this.zCoord + 1);
try
{
List<Entity> entityOnTop = worldObj.getEntitiesWithinAABB(Entity.class, bounds);
for (Entity entity : entityOnTop)
{
int direction = worldObj.getBlockMetadata(xCoord, yCoord, zCoord);
if (!this.entityIgnoreList.contains(entity))
{
if (direction == 0)
{
entity.motionZ -= 1 * this.speed;
}
if (direction == 1)
{
entity.motionX += 1 * this.speed;
}
if (direction == 2)
{
entity.motionZ += 1 * this.speed;
}
if (direction == 3)
{
entity.motionX -= 1 * this.speed;
}
}
if (this.clearCount++ >= 4)
{
// clear the temp ignore
// list every 2 second
this.entityIgnoreList.clear();
}
if (entity instanceof EntityItem)
{
EntityItem entityItem = (EntityItem) entity;
// Make sure the item
// doesn't decay/disappear
if (entityItem.age >= 1000)
{
entityItem.age = 0;
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
if (AssembleLine.animationOn)
{
if (flip == true)
{
flip = false;
}
else
{
flip = true;
}
this.wheelRotation -= this.speed;
}
}
}
@Override
public double wattRequest()
{
return energyMax - electricityStored;
}
@Override
public boolean canReceiveFromSide(ForgeDirection side)
{
return side == ForgeDirection.DOWN;
}
public int getBeltDirection()
{
int meta = worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
if (meta >= 0 && meta < 4)
{
switch (meta)
{
case 0:
return 2;
case 1:
return 5;
case 2:
return 3;
case 3:
return 4;
}
}
return 0;
}
public boolean middleBelt()
{
ForgeDirection front = ForgeDirection.getOrientation(getBeltDirection());
ForgeDirection back = ForgeDirection.getOrientation(getBeltDirection()).getOpposite();
TileEntity fBelt = worldObj.getBlockTileEntity(xCoord + front.offsetX, yCoord + front.offsetY, zCoord + front.offsetZ);
TileEntity BBelt = worldObj.getBlockTileEntity(xCoord + back.offsetX, yCoord + back.offsetY, zCoord + back.offsetZ);
if (fBelt instanceof TileEntityConveyorBelt && BBelt instanceof TileEntityConveyorBelt)
{
int fD = ((TileEntityConveyorBelt) fBelt).getBeltDirection();
int BD = ((TileEntityConveyorBelt) BBelt).getBeltDirection();
int TD = this.getBeltDirection();
if (fD == TD && BD == TD) { return true; }
}
return false;
}
public boolean FrontCap()
{
ForgeDirection front = ForgeDirection.getOrientation(getBeltDirection());
ForgeDirection back = ForgeDirection.getOrientation(getBeltDirection()).getOpposite();
TileEntity fBelt = worldObj.getBlockTileEntity(xCoord + front.offsetX, yCoord + front.offsetY, zCoord + front.offsetZ);
TileEntity BBelt = worldObj.getBlockTileEntity(xCoord + back.offsetX, yCoord + back.offsetY, zCoord + back.offsetZ);
if (fBelt instanceof TileEntityConveyorBelt)
{
int fD = ((TileEntityConveyorBelt) fBelt).getBeltDirection();
int TD = this.getBeltDirection();
if (fD == TD) { return true; }
}
return false;
}
public boolean BackCap()
{
ForgeDirection front = ForgeDirection.getOrientation(getBeltDirection());
ForgeDirection back = ForgeDirection.getOrientation(getBeltDirection()).getOpposite();
TileEntity fBelt = worldObj.getBlockTileEntity(xCoord + front.offsetX, yCoord + front.offsetY, zCoord + front.offsetZ);
TileEntity BBelt = worldObj.getBlockTileEntity(xCoord + back.offsetX, yCoord + back.offsetY, zCoord + back.offsetZ);
if (BBelt instanceof TileEntityConveyorBelt)
{
int BD = ((TileEntityConveyorBelt) BBelt).getBeltDirection();
int TD = this.getBeltDirection();
if (BD == TD) { return true; }
}
return false;
}
@Override
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream)
{
if (worldObj.isRemote)
{
try
{
this.running = dataStream.readBoolean();
this.range = dataStream.readInt();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
@Override
public void onReceive(TileEntity sender, double amps, double voltage, ForgeDirection side)
{
this.electricityStored += (amps * voltage);
}
/**
* Used to tell the belt not to apply velocity
* to some Entity in case they are being
* handled by another block. For example
* ejector
*
* @param entity
*/
public void ignore(Entity entity)
{
if (!this.entityIgnoreList.contains(entity))
{
this.entityIgnoreList.add(entity);
}
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.electricityStored = nbt.getDouble("energy");
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setDouble("energy", this.electricityStored);
}
}

View file

@ -0,0 +1,45 @@
package assemblyline.crafting;
import net.minecraft.src.BlockContainer;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.Material;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
public class BlockCrafter extends BlockContainer
{
protected BlockCrafter(int par1)
{
super(par1, Material.iron);
this.setResistance(5.0f);
this.setHardness(5.0f);
this.setCreativeTab(CreativeTabs.tabTools);
}
@Override
public TileEntity createNewTileEntity(World var1) {
return null;
}
@Override
public TileEntity createNewTileEntity(World var1, int meta) {
if(meta >= 0 && meta < 4)
{
return new TileEntityAutoCrafter();
}
if(meta >= 4 && meta < 8)
{
return new TileEntityCraftingArm();
}
if(meta >= 8 && meta < 12)
{
}
if(meta >= 12 && meta < 16)
{
}
return null;
}
}

View file

@ -0,0 +1,30 @@
package assemblyline.crafting;
import net.minecraft.src.Entity;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.World;
public class EntityCraftingArm extends Entity {
public EntityCraftingArm(World par1World) {
super(par1World);
}
@Override
protected void entityInit()
{
}
@Override
protected void readEntityFromNBT(NBTTagCompound var1) {
// TODO Auto-generated method stub
}
@Override
protected void writeEntityToNBT(NBTTagCompound var1) {
// TODO Auto-generated method stub
}
}

View file

@ -0,0 +1,46 @@
package assemblyline.crafting;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.ISidedInventory;
import universalelectricity.prefab.TileEntityAdvanced;
import assemblyline.TileEntityBase;
import com.google.common.io.ByteArrayDataInput;
public class TileEntityAutoCrafter extends TileEntityBase implements ISidedInventory
{
@Override
public String getInvName()
{
return "Auto Crafter";
}
@Override
public int getSizeInventory()
{
return 10;
}
@Override
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream)
{
}
@Override
public int getStartInventorySide(ForgeDirection side)
{
return 0;
}
@Override
public int getSizeInventorySide(ForgeDirection side)
{
return 0;
}
}

View file

@ -0,0 +1,7 @@
package assemblyline.crafting;
import net.minecraft.src.TileEntity;
public class TileEntityCraftingArm extends TileEntity {
}

View file

@ -0,0 +1,146 @@
package assemblyline.interaction;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.Material;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import universalelectricity.prefab.BlockMachine;
import asmline.beltRenders.BeltRenderHelper;
import assemblyline.AssembleLine;
public class BlockInteraction extends BlockMachine
{
public BlockInteraction(int id)
{
super("Machine", id, Material.iron);
this.setCreativeTab(CreativeTabs.tabRedstone);
}
public int damageDropped(int metadata)
{
if (metadata >= 0 && metadata < 4) { return 0; }
if (metadata >= 4 && metadata < 8) { return 4; }
if (metadata >= 8 && metadata < 12) { return 8; }
if (metadata >= 12 && metadata < 16) { return 12; }
return 0;
}
public boolean onSneakUseWrench(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
if (!par1World.isRemote)
{
par5EntityPlayer.openGui(AssembleLine.instance, 0, par1World, x, y, z);
return true;
}
return true;
}
@Override
public boolean onUseWrench(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
int metadata = par1World.getBlockMetadata(x, y, z);
if (metadata == 3)
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, 0);
return true;
}
else if (metadata == 7)
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, 4);
return true;
}
else if (metadata == 11)
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, 8);
return true;
}
else if (metadata == 15)
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, 12);
return true;
}
else
{
par1World.setBlockAndMetadataWithNotify(x, y, z, this.blockID, metadata + 1);
return true;
}
}
/**
* gets the correct facing direction from meta
* data
*
* @param meta
* @return facing direction(int)
*/
public byte getDirection(int meta)
{
switch (meta)
{
case 0:
return 2;
case 1:
return 5;
case 2:
return 3;
case 3:
return 4;
case 4:
return 2;
case 5:
return 5;
case 6:
return 3;
case 7:
return 4;
case 8:
return 2;
case 9:
return 5;
case 10:
return 3;
case 11:
return 4;
case 12:
return 2;
case 13:
return 5;
case 14:
return 3;
case 15:
return 4;
}
return 0;
}
@Override
public TileEntity createNewTileEntity(World var1, int metadata)
{
if (metadata >= 0 && metadata < 4) { return new TileEntityEjector(); }
if (metadata >= 4 && metadata < 8) { return new TileEntityMachineInput(); }
if (metadata >= 8 && metadata < 12) { return null; }
if (metadata >= 12 && metadata < 16) { return null; }
return null;
}
@Override
public int getRenderType()
{
return BeltRenderHelper.blockRenderId;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
}

View file

@ -0,0 +1,95 @@
package assemblyline.interaction;
import net.minecraft.src.Container;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.InventoryPlayer;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Slot;
public class ContainerEjector extends Container
{
private TileEntityEjector tileEntity;
public ContainerEjector(InventoryPlayer par1InventoryPlayer, TileEntityEjector tileEntity)
{
this.tileEntity = tileEntity;
for(int i = 0; i < 4; i++)
{
this.addSlotToContainer(new Slot(tileEntity, 0+i, 33 +i*18, 34));
}
int var3;
for (var3 = 0; var3 < 3; ++var3)
{
for (int var4 = 0; var4 < 9; ++var4)
{
this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18));
}
}
for (var3 = 0; var3 < 9; ++var3)
{
this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142));
}
}
@Override
public boolean canInteractWith(EntityPlayer par1EntityPlayer)
{
return this.tileEntity.isUseableByPlayer(par1EntityPlayer);
}
/**
* Called to transfer a stack from one inventory to the other eg. when shift clicking.
*/
@Override
public ItemStack transferStackInSlot(int par1)
{
ItemStack var2 = null;
Slot var3 = (Slot)this.inventorySlots.get(par1);
if (var3 != null && var3.getHasStack())
{
ItemStack var4 = var3.getStack();
var2 = var4.copy();
if (par1 != 0)
{
if (var4.itemID == Item.coal.shiftedIndex)
{
if (!this.mergeItemStack(var4, 0, 1, false))
{
return null;
}
}
else if (par1 >= 30 && par1 < 37 && !this.mergeItemStack(var4, 3, 30, false))
{
return null;
}
}
else if (!this.mergeItemStack(var4, 3, 37, false))
{
return null;
}
if (var4.stackSize == 0)
{
var3.putStack((ItemStack)null);
}
else
{
var3.onSlotChanged();
}
if (var4.stackSize == var2.stackSize)
{
return null;
}
var3.onPickupFromSlot(var4);
}
return var2;
}
}

View file

@ -0,0 +1,83 @@
package assemblyline.interaction;
import java.util.List;
import net.minecraft.src.Block;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemBlock;
import net.minecraft.src.ItemStack;
import net.minecraft.src.MathHelper;
import net.minecraft.src.World;
import assemblyline.AssembleLine;
public class ItemMachine extends ItemBlock {
public ItemMachine(int par1) {
super(par1);
this.setHasSubtypes(true);
this.setCreativeTab(CreativeTabs.tabRedstone);
}
private String[] names = new String[] {"Ejector", "ItemScooper", "FB","FB"};
int blockID = AssembleLine.machineID;
public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
par3List.add(new ItemStack(AssembleLine.blockMachine,1,0));
par3List.add(new ItemStack(AssembleLine.blockMachine,1,4));
//par3List.add(new ItemStack(AssembleLine.blockMachine,1,8));
//par3List.add(new ItemStack(AssembleLine.blockMachine,1,12));
}
public String getItemNameIS(ItemStack itemstack)
{
int meta = itemstack.getItemDamage();
switch(meta)
{
case 0: return names[0];
case 4: return names[1];
case 8: return names[2];
case 12: return names[3];
}
return "FB";
}
@Override
public int getIconFromDamage(int i)
{
switch(i)
{
case 0:return 1;
case 4:return 2;
case 8:return 3;
case 12:return 4;
}
return this.iconIndex + i;
}
public int getMetadata(int par1)
{
return 0;
}
@Override
public int getBlockID()
{
return AssembleLine.machineID;
}
@Override
public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
{
int angle = MathHelper.floor_double((player.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
player.sendChatToPlayer("M:"+stack.getItemDamage()+"A:"+angle);
if (!world.setBlockAndMetadataWithNotify(x, y, z, this.blockID, stack.getItemDamage()+angle))
{
return false;
}
if (world.getBlockId(x, y, z) == this.blockID)
{
Block.blocksList[this.blockID].updateBlockMetadata(world, x, y, z, side, hitX, hitY, hitZ);
Block.blocksList[this.blockID].onBlockPlacedBy(world, x, y, z, player);
}
return true;
}
}

View file

@ -0,0 +1,334 @@
package assemblyline.interaction;
import java.util.List;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.Vector3;
import universalelectricity.implement.IElectricityReceiver;
import universalelectricity.prefab.network.IPacketReceiver;
import universalelectricity.prefab.network.PacketManager;
import assemblyline.TileEntityBase;
import assemblyline.belts.TileEntityConveyorBelt;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.PacketDispatcher;
public class TileEntityEjector extends TileEntityBase implements IElectricityReceiver, IPacketReceiver
{
/**
* Joules required per tick.
*/
public static final int WATTS_REQUIRED = 10;
public double wattsReceived = 0;
public boolean firePiston = false;
public boolean pFirePiston = false;
public boolean rejectItems = true;
public boolean[] onOff = new boolean[]
{ true, true, true, true };
public TileEntityConveyorBelt beltSide = null;
@Override
public double wattRequest()
{
return WATTS_REQUIRED;
}
// TODO add computer craft support to change
// onOff values, or even select what can be
// rejected.
// If option two add a rejector item to tell
// the computer what item is in front of the
// ejector
@Override
public void updateEntity()
{
super.updateEntity();
if (this.ticks % 10 == 0)
{
int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord);
ForgeDirection searchPosition = Vector3.getOrientationFromSide(ForgeDirection.getOrientation(getDirection(meta)), ForgeDirection.SOUTH);
TileEntity tileEntity = worldObj.getBlockTileEntity(xCoord + searchPosition.offsetX, yCoord + searchPosition.offsetY, zCoord + searchPosition.offsetZ);
if (tileEntity instanceof TileEntityConveyorBelt)
{
this.beltSide = (TileEntityConveyorBelt) tileEntity;
}
else
{
this.beltSide = null;
}
this.firePiston = false;
try
{
AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(xCoord + searchPosition.offsetX, yCoord + searchPosition.offsetY, zCoord + searchPosition.offsetZ, xCoord + searchPosition.offsetX + 1, yCoord + searchPosition.offsetY + 1, zCoord + searchPosition.offsetZ + 1);
List<EntityItem> itemsBehind = worldObj.getEntitiesWithinAABB(EntityItem.class, bounds);
if (itemsBehind.size() > 0 && this.wattsReceived > this.WATTS_REQUIRED)
{
for (EntityItem entity : itemsBehind)
{
if (this.canItemBeThrow(entity))
{
this.throwItem(searchPosition, entity);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* Used to do the actual throwing of the item
* from the piston arm
*
* @param side
* - used to do the offset
* @param entity
* - Entity being thrown
*/
public void throwItem(ForgeDirection side, Entity entity)
{
this.firePiston = true;
if (this.beltSide != null)
{
this.beltSide.ignore(entity);
}
entity.motionX = (double) side.offsetX * 0.1;
entity.motionY += 0.10000000298023224D;
entity.motionZ = (double) side.offsetZ * 0.1;
this.wattsReceived -= this.WATTS_REQUIRED;
}
public boolean canItemBeThrow(Entity entity)
{
// TODO add ability to eject Entities that
// are not items, though i might want to
// create a bigger ejector for this
// TODO might also want to add damaging
// effect to items like glass once i make
// a sorter arm
if (entity instanceof EntityItem)
{
EntityItem itemE = (EntityItem) entity;
ItemStack item = itemE.item;
if (this.rejectItems)
{
// reject the items with same IDS
// as those placed in inventory
for (int i = 0; i < this.containingItems.length; i++)
{
if (containingItems[i] != null)
{
if (containingItems[i].itemID == item.itemID && containingItems[i].getItemDamage() == item.getItemDamage()) { return true; }
}
}
return false;
}
else if (!this.rejectItems)
{
// reject all but the items with
// same IDS as those placed in
// inventory
for (int i = 0; i < this.containingItems.length; i++)
{
if (containingItems[i] != null)
{
if (containingItems[i].itemID == item.itemID && containingItems[i].getItemDamage() == item.getItemDamage()) { return false; }
}
}
return true;
}
}
return false;
}
public byte getDirection(int meta)
{
switch (meta)
{
case 0:
return 2;
case 1:
return 5;
case 2:
return 3;
case 3:
return 4;
}
return 0;
}
@Override
public boolean canReceiveFromSide(ForgeDirection side)
{
// TODO Auto-generated method stub
return side == ForgeDirection.DOWN;
}
/*
* @Override public Object[] sendDataA() {
* return new Object[] { this.firePiston,
* this.rejectItems }; }
*
* @Override public Object[] sendDataG() {
* Object[] data = new
* Object[this.onOff.length]; for (int i = 0;
* i < this.onOff.length; i++) { data[i] =
* onOff[i]; } return data; }
*
* @Override public void
* guiPacket(NetworkManager network, int
* packetType, Packet250CustomPayload packet,
* EntityPlayer player, ByteArrayDataInput
* dataStream) { if (worldObj.isRemote) { try
* { for (int i = 0; i < this.onOff.length;
* i++) { this.onOff[i] =
* dataStream.readBoolean(); }
*
* } catch (Exception e) {
* e.printStackTrace(); } }
*
* }
*
* @Override public void
* animationPacket(NetworkManager network, int
* packetType, Packet250CustomPayload packet,
* EntityPlayer player, ByteArrayDataInput
* dataStream) { if (worldObj.isRemote) { try
* { this.firePiston =
* dataStream.readBoolean(); this.rejectItems
* = dataStream.readBoolean();
*
* } catch (Exception e) {
* e.printStackTrace(); } }
*
* }
*
* @Override public void
* otherPacket(NetworkManager network, int
* packetType, Packet250CustomPayload packet,
* EntityPlayer player, ByteArrayDataInput
* dataStream) { if (worldObj.isRemote) { try
* {
*
* } catch (Exception e) {
* e.printStackTrace(); } } else if
* (!worldObj.isRemote) { try { int ID =
* dataStream.readInt(); if (ID == 0) {
* this.changeOnOff(dataStream.readInt()); }
* else if (ID == 1) { this.changeRejected();
* }
*
* } catch (Exception e) {
* e.printStackTrace(); } }
*
* }
*/
public void changeOnOff(int i)
{
if (i >= this.onOff.length) { return; }
boolean cc = this.onOff[i];
if (cc)
{
cc = false;
}
else
{
cc = true;
}
this.onOff[i] = cc;
if (worldObj.isRemote)
{
Packet packet = PacketManager.getPacket("asmLine", this, new Object[]
{ 2, 0, i });
PacketDispatcher.sendPacketToServer(packet);
}
}
public void changeRejected()
{
boolean cc = this.rejectItems;
if (cc)
{
cc = false;
}
else
{
cc = true;
}
this.rejectItems = cc;
if (worldObj.isRemote)
{
Packet packet = PacketManager.getPacket("asmLine", this, new Object[]
{ 2, 1 });
PacketDispatcher.sendPacketToServer(packet);
}
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
for (int i = 0; i < this.onOff.length; i++)
{
this.onOff[i] = nbt.getBoolean("onOff" + i);
}
this.rejectItems = nbt.getBoolean("reject");
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
for (int i = 0; i < this.onOff.length; i++)
{
nbt.setBoolean("onOff" + i, this.onOff[i]);
}
nbt.setBoolean("reject", this.rejectItems);
}
@Override
public String getInvName()
{
return "Ejector";
}
@Override
public int getInventoryStackLimit()
{
return 1;
}
@Override
public void onReceive(TileEntity sender, double amps, double voltage, ForgeDirection side)
{
this.wattsReceived += (amps * voltage);
}
}

View file

@ -0,0 +1,307 @@
package assemblyline.interaction;
import java.util.List;
import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.TileEntity;
import net.minecraft.src.TileEntityChest;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.prefab.TileEntityElectricityReceiver;
import universalelectricity.prefab.network.IPacketReceiver;
import com.google.common.io.ByteArrayDataInput;
public class TileEntityMachineInput extends TileEntityElectricityReceiver implements IPacketReceiver,IInventory {
public float energyReq = .1f;
public float energyMax = 10f;
public float energyStor = 0f;
private ItemStack[] containingItems = new ItemStack[1];
public ForgeDirection dir = ForgeDirection.DOWN;
private int count = 0;
@Override
public double wattRequest() {
return energyMax-energyStor;
}
@Override
public void updateEntity()
{
if(count++ >=10){
count = 0;
if(!isDisabled())
{
int meta = worldObj.getBlockMetadata(xCoord, yCoord, zCoord);
ForgeDirection searchPosition = ForgeDirection.getOrientation(this.getBeltDirection());
dir = searchPosition;
try
{
AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(xCoord+searchPosition.offsetX,yCoord+ searchPosition.offsetY,zCoord+ searchPosition.offsetZ, xCoord+searchPosition.offsetX+1,yCoord+ searchPosition.offsetY+1,zCoord+ searchPosition.offsetZ+1);
TileEntity bEnt = worldObj.getBlockTileEntity(xCoord+searchPosition.getOpposite().offsetX,yCoord+ searchPosition.getOpposite().offsetY,zCoord+ searchPosition.getOpposite().offsetZ);
List<EntityItem> itemsBehind = worldObj.getEntitiesWithinAABB(EntityItem.class, bounds);
ItemStack tItem = this.containingItems[0];
if(itemsBehind.size() > 0 && this.energyStor > this.energyReq && bEnt instanceof IInventory)
{ energyStor -= energyReq;
for(EntityItem entity : itemsBehind)
{
ItemStack eStack = entity.item;
int ite = eStack.stackSize;
if(bEnt instanceof TileEntityChest)
{
TileEntityChest bEntChest2 = null;
TileEntityChest bEntChest = (TileEntityChest)bEnt;
for(int i = 2; i<6; i++)
{
ForgeDirection si = ForgeDirection.getOrientation(i);
if(worldObj.getBlockTileEntity(xCoord+dir.getOpposite().offsetX+si.offsetX, yCoord+dir.getOpposite().offsetY+si.offsetY, zCoord+dir.getOpposite().offsetZ+si.offsetZ) instanceof TileEntityChest)
{
bEntChest2 = (TileEntityChest) worldObj.getBlockTileEntity(xCoord+dir.getOpposite().offsetX+si.offsetX, yCoord+dir.getOpposite().offsetY+si.offsetY, zCoord+dir.getOpposite().offsetZ+si.offsetZ);
break;
}
}
if(eStack != null && eStack.stackSize > 0){
for(int i =0; i < bEntChest.getSizeInventory(); i++)
{
ItemStack stack = bEntChest.getStackInSlot(i);
if(stack == null)
{
bEntChest.setInventorySlotContents(i, eStack);
entity.setDead();
eStack = null;
break;
}else
if(stack.getItem().equals(eStack.getItem()) && stack.getItemDamage() == eStack.getItemDamage())
{
int rej = Math.max((stack.stackSize + eStack.stackSize) - stack.getItem().getItemStackLimit(), 0);
stack.stackSize = Math.min(Math.max((stack.stackSize + eStack.stackSize - rej),0),stack.getItem().getItemStackLimit());
eStack.stackSize = rej;
bEntChest.setInventorySlotContents(i, stack);
if(eStack.stackSize <= 0)
{
entity.setDead();
eStack = null;
break;
}
}
}
}
if(bEntChest2 != null && eStack != null && eStack.stackSize > 0)
{
for(int i =0; i < bEntChest2.getSizeInventory(); i++)
{
ItemStack stack = bEntChest2.getStackInSlot(i);
if(stack == null)
{
bEntChest2.setInventorySlotContents(i, eStack);
entity.setDead();
eStack = null;
break;
}else
if(stack.getItem().equals(eStack.getItem()) && stack.getItemDamage() == eStack.getItemDamage())
{
int rej = Math.max((stack.stackSize + eStack.stackSize) - stack.getItem().getItemStackLimit(), 0);
stack.stackSize = Math.min(Math.max((stack.stackSize + eStack.stackSize - rej),0),stack.getItem().getItemStackLimit());
eStack.stackSize = rej;
bEntChest2.setInventorySlotContents(i, stack);
if(eStack.stackSize <= 0)
{
entity.setDead();
eStack = null;
break;
}
}
}
}if(entity != null && eStack != null){
if(eStack != null && eStack.stackSize <= 0)
{
entity.setDead();
eStack = null;
break;
}else
{
entity.setDead();
EntityItem var23 = new EntityItem(worldObj, entity.posX, entity.posY + 0.1D, entity.posZ, eStack);
worldObj.spawnEntityInWorld(var23);
}}
}//end chest trade
//TODO setup for ISideInventory
}
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
public int getBeltDirection()
{
int meta = worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
if(meta >= 4 && meta < 8)
{
switch(meta)
{
case 4: return 2;
case 5: return 5;
case 6: return 3;
case 7: return 4;
}
}
return 0;
}
@Override
public boolean canReceiveFromSide(ForgeDirection side) {
if(side == dir ||side == dir.getOpposite())
{
return false;
}
return true;
}
@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
NBTTagList var2 = par1NBTTagCompound.getTagList("Items");
this.containingItems = new ItemStack[this.getSizeInventory()];
for (int var3 = 0; var3 < var2.tagCount(); ++var3)
{
NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
byte var5 = var4.getByte("Slot");
if (var5 >= 0 && var5 < this.containingItems.length)
{
this.containingItems[var5] = ItemStack.loadItemStackFromNBT(var4);
}
}
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
NBTTagList var2 = new NBTTagList();
for (int var3 = 0; var3 < this.containingItems.length; ++var3)
{
if (this.containingItems[var3] != null)
{
NBTTagCompound var4 = new NBTTagCompound();
var4.setByte("Slot", (byte)var3);
this.containingItems[var3].writeToNBT(var4);
var2.appendTag(var4);
}
}
par1NBTTagCompound.setTag("Items", var2);
}
@Override
public int getSizeInventory()
{
return this.containingItems.length;
}
@Override
public ItemStack getStackInSlot(int par1)
{
return this.containingItems[par1];
}
@Override
public ItemStack decrStackSize(int par1, int par2)
{
if (this.containingItems[par1] != null)
{
ItemStack var3;
if (this.containingItems[par1].stackSize <= par2)
{
var3 = this.containingItems[par1];
this.containingItems[par1] = null;
return var3;
}
else
{
var3 = this.containingItems[par1].splitStack(par2);
if (this.containingItems[par1].stackSize == 0)
{
this.containingItems[par1] = null;
}
return var3;
}
}
else
{
return null;
}
}
@Override
public ItemStack getStackInSlotOnClosing(int par1)
{
if (this.containingItems[par1] != null)
{
ItemStack var2 = this.containingItems[par1];
this.containingItems[par1] = null;
return var2;
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
{
this.containingItems[par1] = par2ItemStack;
if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
{
par2ItemStack.stackSize = this.getInventoryStackLimit();
}
}
@Override
public String getInvName()
{
return "Ejector";
}
@Override
public int getInventoryStackLimit()
{
//TODO change
return 0;
}
@Override
public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
{
return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64.0D;
}
@Override
public void openChest() { }
@Override
public void closeChest() { }
@Override
public void onReceive(TileEntity sender, double amps, double voltage,
ForgeDirection side) {
this.energyStor+=(amps*voltage);
}
@Override
public void handlePacketData(NetworkManager network, int packetType,
Packet250CustomPayload packet, EntityPlayer player,
ByteArrayDataInput dataStream) {
}
}

View file

@ -0,0 +1,21 @@
[
{
"modid": "asmLine",
"name": "Assemble Line",
"description": "This mod is a revamp of Calclavia's and ElusiveHawk's Conveyor belts in the form of a factory assemble line",
"version": "0.0.4",
"mcversion": "1.3.2",
"url": "http://www.minecraftforge.net/forum/index.php/board,50.0.html",
"updateUrl": "",
"authors": [
"DarkGuardsman"
],
"credits": "Orignal Devs Calclavia,ElusiveHawk",
"logoFile": "",
"screenshots": [
],
"parent":"",
"dependencies": ["UE"
]
}
]

View file

@ -0,0 +1,35 @@
package buildcraft.api.tools;
import net.minecraft.src.EntityPlayer;
/***
* Implement this interface on subclasses of Item to have that item work as a
* wrench for buildcraft
*/
public interface IToolWrench {
/***
* Called to ensure that the wrench can be used. To get the ItemStack that
* is used, check player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates for the block being wrenched
*
* @return true if wrenching is allowed, false if not
*/
public boolean canWrench(EntityPlayer player, int x, int y, int z);
/***
* Callback after the wrench has been used. This can be used to decrease
* durability or for other purposes. To get the ItemStack that was used,
* check player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates of the block being wrenched
*/
public void wrenchUsed(EntityPlayer player, int x, int y, int z);
}

View file

@ -0,0 +1,131 @@
package dan200.computer.api;
/**
* The interface passed to peripherals by computers or turtles, providing methods
* that they can call. This should not be implemented by your classes. Do not interact
* with computers except via this interface.
*/
public interface IComputerAccess
{
/**
* Creates a new numbered directory in a subPath of the users game save, and return that number. To be used with mountSaveDir.<br>
* For example: n = createNewSaveDir( "computer/cdrom" ), will create a new
* numbered folder in the "computer/cdrom" subdirectory of the users save file, and return that number.
* mountSaveDir( "computer/rom", n ) could then be used to mount that folder onto the computers directory
* structure, and the value n could be saved out and used again in future to give the peripheral
* persistant storage.
* @param subPath A relative file path from the users world save, where the directory should be located.
* @return The numeric represenation of the name of the folder created. Will be positive.
* @see #mountSaveDir(String, String, int, boolean, long)
*/
public int createNewSaveDir( String subPath );
/**
* Equivalent to mountSaveDir( String desiredLocation, String subPath, int id, boolean readOnly, long spaceLimit ) with no space limit.
* Mounts created with this method will have unlimited capacity.
* @see #mountSaveDir(String, String, int, boolean, long)
*/
public String mountSaveDir( String desiredLocation, String subPath, int id, boolean readOnly );
/**
* Mounts a directory into the computers file system, from a real directory a subPath of the users game save,
* with a numerical name. To be used with createNewSaveDir.<br>
* For example: n = createNewSaveDir( "computer/cdrom" ), will create a new
* numbered folder in the "computer/cdrom" subdirectory of the users save file, and return that number.
* mountSaveDir( "computer/rom", n ) could then be used to mount that folder onto the computers directory
* structure, and the value n can be saved out by the peripheral and used again, to give the peripheral
* persistant storage.<br>
* When a directory is mounted, it will appear in the computers file system, and the user will be
* able to use file operation to read from and write to the directory (unless readOnly, then only writes will be allowed).
* @param desiredLocation The desired location in the computers file system where you would like the directory to appear.
* If this location already exists, a number will be appended until a free name is found, and the
* actual location will be returned. eg: "cdrom" can become "cdrom2" if two peripherals attempt to
* mount "cdrom", or a "cdrom" folder already exists.
* @param subPath The real relative file path from the users world save, where the directory to mount can be located.
* @param id The numerical name of the folder to mount from the subPath: ex: mountSaveDir( "cdrom", "computer/cdrom", 7 )
* will mount the directory "computer/cdrom/7". Use createNewSaveDir to obtain a unique directory id.
* @param readOnly Whether the computer will be disallowed from making changes to the mounted directory and modifing or creating files therin.
* @param spaceLimit The size limit of the mount, in bytes.
* @return The location in the computers file system where the directory was mounted. This may differ from "desiredLocation", so the
* return value should be kept track of so the folder can be unmounted later.
* @see #createNewSaveDir(String)
* @see #mountFixedDir(String, String, boolean, long)
* @see #unmount(String)
*/
public String mountSaveDir( String desiredLocation, String subPath, int id, boolean readOnly, long spaceLimit );
/**
* Equivalent to mountFixedDir( String desiredLocation, String path, boolean readOnly, long spaceLimit ) with no space limit.
* Mounts created with this method will have unlimited capacity.
* @see #mountFixedDir(String, String, boolean, long)
*/
public String mountFixedDir( String desiredLocation, String path, boolean readOnly );
/**
* Mounts a directory into the computers file system, from a real directory in the Minecraft install folder.<br>
* For example: mountFixedDir( "stuff", "mods/mymod/lua/stuff", true ), will mount the "lua/stuff" folder from
* your mod's directory into the computers filesystem at the location "stuff", with readonly permission, giving the
* computer access to those files.<br>
* When a directory is mounted, it will appear in the computers file system, and the user will be
* able to use file operation to read from and write to the directory (unless readOnly, then only writes will be allowed).<br>
* mountFixedDir can also be used to mount files, for example: mountFixedDir( "rom/apis/myapi", "mods/mymod/lua/myapi.lua", true ) can
* be used to have the peripheral install an API onto the computer it attaches to.
* @param desiredLocation The desired location in the computers file system where you would like the directory to appear.
* If this location already exists, a number will be appended until a free name is found, and the
* actual location will be returned. eg: "cdrom" can become "cdrom2" if two peripherals attempt to
* mount "cdrom", or a "cdrom" folder already exists.
* @param subPath The real relative file path from the minecraft install root, where the directory to mount can be located.
* @param readOnly Whether the computer will be disallowed from making changes to the mounted directory and modifing or creating files therin.
* @param spaceLimit The size limit of the mount, in bytes.
* @return The location in the computers file system where the directory was mounted. This may differ from "desiredLocation", so the
* return value should be kept track of so the folder can be unmounted later.
* @see #mountSaveDir(String, String, int, boolean, long)
* @see #unmount(String)
*/
public String mountFixedDir( String desiredLocation, String path, boolean readOnly, long spaceLimit );
/**
* Unmounts a directory previously mounted onto the computers file system by mountSaveDir or mountFixedDir.<br>
* When a directory is unmounted, it will disappear from the computers file system, and the user will no longer be able to
* access it. All directories mounted by a mountFixedDir or mountSaveDir are automatically unmounted when the peripheral
* is attached if they have not been explicitly unmounted.
* @param location The desired location in the computers file system of the directory to unmount.
* This must be the location of a directory previously mounted by mountFixedDir() or mountSaveDir(), as
* indicated by their return value.
* @see #mountSaveDir(String, String, int, boolean, long)
* @see #mountFixedDir(String, String, boolean, long)
*/
public void unmount( String location );
/**
* Returns the numerical ID of this computer.<br>
* This is the same number obtained by calling os.getComputerID() or running the "id" program from lua,
* and is guarunteed unique. This number will be positive.
* @return The identifier.
*/
public int getID();
/**
* Equivalent to queueEvent( String event, Object[] arguments ) with an empty arguments array.
* @see #queueEvent(String, Object[])
*/
public void queueEvent( String event );
/**
* Causes an event to be raised on this computer, which the computer can respond to by calling
* os.pullEvent(). This can be used to notify the computer when things happen in the world or to
* this peripheral.
* @param event A string identifying the type of event that has occurred, this will be
* returned as the first value from os.pullEvent(). It is recommended that you
* you choose a name that is unique, and recognisable as originating from your
* peripheral. eg: If your peripheral type is "button", a suitable event would be
* "button_pressed".
* @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will
* be supplied as extra return values to os.pullEvent(). Objects in the array will be converted
* to lua data types in the same fashion as the return values of IPeripheral.callMethod().<br>
* You may supply null to indicate that no arguments are to be supplied.
* @see IPeripheral#callMethod
*/
public void queueEvent( String event, Object[] arguments );
}

View file

@ -0,0 +1,103 @@
package dan200.computer.api;
/**
* The interface that defines a peripheral. This should be implemented by the
* TileEntity of any block that you wish to be interacted with by
* computer or turtle.
*/
public interface IPeripheral
{
/**
* Should return a string that uniquely identifies this type of peripheral.
* This can be queried from lua by calling peripheral.getType()
* @return A string identifying the type of peripheral.
*/
public String getType();
/**
* Should return an array of strings that identify the methods that this
* peripheral exposes to Lua. This will be called once before each attachment,
* and should not change when called multiple times.
* @return An array of strings representing method names.
* @see #callMethod
*/
public String[] getMethodNames();
/**
* This is called when a lua program on an attached computer calls peripheral.call() with
* one of the methods exposed by getMethodNames().<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is making the call. Remember that multiple
* computers can be attached to a peripheral at once.
* @param method An integer identifying which of the methods from getMethodNames() the computer
* wishes to call. The integer indicates the index into the getMethodNames() table
* that corresponds to the string passed into peripheral.call()
* @param arguments An array of objects, representing the arguments passed into peripheral.call().<br>
* Lua values of type "string" will be represented by Object type String.<br>
* Lua values of type "number" will be represented by Object type Double.<br>
* Lua values of type "boolean" will be represented by Object type Boolean.<br>
* Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed.
* @return An array of objects, representing values you wish to return to the lua program.<br>
* Integers, Doubles, Floats, Strings, Booleans and null be converted to their corresponding lua type.<br>
* All other types will be converted to nil.<br>
* You may return null to indicate no values should be returned.
* @throws Exception If you throw any exception from this function, a lua error will be raised with the
* same message as your exception. Use this to throw appropriate errors if the wrong
* arguments are supplied to your method.
* @see #getMethodNames
*/
public Object[] callMethod( IComputerAccess computer, int method, Object[] arguments ) throws Exception;
/**
* Is called before the computer attempts to attach to the peripheral, and should return whether to allow
* the attachment. Use this to restrict the number of computers that can attach, or to limit attachments to
* certain world directions.<br>
* If true is returned, attach() will be called shortly afterwards, and the computer will be able to make method calls.
* If false is returned, attach() will not be called, and the peripheral will be invisible to the computer.
* @param side The world direction (0=bottom, 1=top, etc) that the computer lies relative to the peripheral.
* @return Whether to allow the attachment, as a boolean.
* @see #attach
*/
public boolean canAttachToSide( int side );
/**
* Is called when canAttachToSide has returned true, and a computer is attaching to the peripheral.
* This will occur when a peripheral is placed next to an active computer, when a computer is turned on next to a peripheral,
* or when a turtle travels into a square next to a peripheral.
* Between calls to attach() and detach(), the attached computer can make method calls on the peripheral using peripheral.call().
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when attachment
* occurs.<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is being attached. Remember that multiple
* computers can be attached to a peripheral at once.
* @param computerSide A string indicating which "side" of the computer the peripheral is attaching,
* relative to the computers orientation. This value will be one of "top", "bottom",
* "left", "right", "front" or "back". This can be used to uniquely identify the
* peripheral when raising events or returning values to the computer.
* @see #canAttachToSide
* @see #detach
*/
public void attach( IComputerAccess computer, String computerSide );
/**
* Is called when a computer is detaching from the peripheral.
* This will occur when a computer shuts down, when the peripheral is removed while attached to computers,
* or when a turtle moves away from a square attached to a peripheral.
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when detachment
* occurs.<br>
* <br>
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with minecraft objects.
* @param computer The interface to the computer that is being detached. Remember that multiple
* computers can be attached to a peripheral at once.
* @see #canAttachToSide
* @see #detach
*/
public void detach( IComputerAccess computer );
}

View file

@ -0,0 +1,50 @@
package universalelectricity.core;
import net.minecraftforge.common.Configuration;
public class UEConfig
{
public static int getConfigData(Configuration configuration, String name, int defaultInt)
{
configuration.load();
int returnInt = defaultInt;
returnInt = Integer.parseInt(configuration.get(name, Configuration.CATEGORY_GENERAL, defaultInt).value);
configuration.save();
return returnInt;
}
public static boolean getConfigData(Configuration configuration, String name, boolean defaultBoolean)
{
configuration.load();
boolean returnBoolean = defaultBoolean;
returnBoolean = Boolean.parseBoolean(configuration.get(name, Configuration.CATEGORY_GENERAL, defaultBoolean).value);
configuration.save();
return returnBoolean;
}
public static int getBlockConfigID(Configuration configuration, String name, int defaultID)
{
configuration.load();
int id = defaultID;
id = Integer.parseInt(configuration.getBlock(name, defaultID).value);
if (id <= 136) { return defaultID; }
configuration.save();
return id;
}
public static int getItemConfigID(Configuration configuration, String name, int defaultID)
{
configuration.load();
int id = defaultID;
id = Integer.parseInt(configuration.getItem(name, Configuration.CATEGORY_ITEM, defaultID).value);
if (id < 256) { return defaultID; }
configuration.save();
return id;
}
}

View file

@ -0,0 +1,68 @@
package universalelectricity.core;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.world.WorldEvent.Load;
import net.minecraftforge.event.world.WorldEvent.Unload;
import universalelectricity.electricity.ElectricityManager;
import universalelectricity.electricity.ElectricityManagerTicker;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.registry.TickRegistry;
/**
* A class used to load Universal Electricity and make it work.
* @author Calclavia
*
*/
public class UELoader
{
public static final UELoader INSTANCE = new UELoader();
public static boolean isInitialized = false;
public void initiate()
{
if (!isInitialized)
{
TickRegistry.registerTickHandler(new ElectricityManagerTicker(), Side.SERVER);
ElectricityManager.instance = new ElectricityManager();
MinecraftForge.EVENT_BUS.register(this);
if (UniversalElectricity.BC3_RATIO <= 0 || !Loader.isModLoaded("BuildCraft|Core"))
{
FMLLog.fine("Disabled Buildcraft electricity conversion!");
}
else
{
FMLLog.fine("Buildcraft conversion ratio: " + UniversalElectricity.BC3_RATIO);
}
if (UniversalElectricity.IC2_RATIO <= 0 || !Loader.isModLoaded("IC2"))
{
FMLLog.fine("Disabled Industrialcraft electricity conversion!");
}
else
{
FMLLog.fine("IC2 conversion ratio: " + UniversalElectricity.IC2_RATIO);
}
FMLLog.finest("Universal Electricity v" + UniversalElectricity.VERSION + " successfully loaded!");
isInitialized = true;
}
}
@ForgeSubscribe
public void onWorldLoad(Load event)
{
ElectricityManagerTicker.inGameTicks = 0;
}
@ForgeSubscribe
public void onWorldUnload(Unload event)
{
ElectricityManager.instance = new ElectricityManager();
}
}

View file

@ -0,0 +1,119 @@
package universalelectricity.core;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.MapColor;
import net.minecraft.src.Material;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.ForgeVersion;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
/**
* Instructions for using the Universal Electricity API.
*
* The less you include of the API, the more compatible your
* mod will be for future releases of Universal Electricity.
*
* REQUIRED PACKAGES:
* "universalelectricity"
* "universalelectricity.electricity"
* "universalelectricity.implements" - Some interfaces can be removed if not needed.
*
* The rest of the classes should be removed if you are not going to use them.
*
* @author Calclavia
*
*/
public class UniversalElectricity
{
/**
* The version of the Universal Electricity API.
*/
public static final int MAJOR_VERSION = 1;
public static final int MINOR_VERSION = 0;
public static final int REVISION_VERSION = 0;
public static final String VERSION = MAJOR_VERSION + "." + MINOR_VERSION + "." + REVISION_VERSION;
/**
* The Universal Electricity configuration file.
*/
public static final Configuration CONFIGURATION = new Configuration(new File(Loader.instance().getConfigDir(), "UniversalElectricity/UniversalElectricity.cfg"));
/**
* Conversion ratios between Buildcraft and Industrialcraft energy.
*/
// EU to Watts ratio
public static final float IC2_RATIO = (float) UEConfig.getConfigData(CONFIGURATION, "IndustrialCraft Conversion Ratio", 7);
// MJ to Watts ratio.
public static final float BC3_RATIO = (float) UEConfig.getConfigData(CONFIGURATION, "BuildCraft Conversion Ratio", 85);;
public static final float TO_IC2_RATIO = 1 / IC2_RATIO;
public static final float TO_BC_RATIO = 1 / BC3_RATIO;
/**
* Use this material for all your machine blocks. It can be breakable by
* hand.
*/
public static final Material machine = new Material(MapColor.ironColor);
public static final List<Object> mods = new ArrayList<Object>();
/**
* You must register your mod with Universal Electricity. Call this in your
* mod's pre-initialization stage.
*/
public static void register(Object mod, int major, int minor, int revision, boolean strict)
{
if (MAJOR_VERSION != major) { throw new RuntimeException("Universal Electricity wrong version! Require v" + major + "." + minor + "." + revision); }
if (MINOR_VERSION < minor) { throw new RuntimeException("Universal Electricity minor version is too old! Require v" + major + "." + minor + "." + revision); }
if (REVISION_VERSION < revision)
{
if (strict)
{
throw new RuntimeException("Universal Electricity is too old! Require v" + major + "." + minor + "." + revision);
}
else
{
FMLLog.warning("Universal Electricity is not the specified version. Odd things might happen. Recommend to have v" + major + "." + minor + "." + revision);
}
}
mods.add(mod);
FMLLog.fine(mod.getClass().getSimpleName()+" has been registered to Universal Electricity.");
UELoader.INSTANCE.initiate();
}
/**
* A function that allows you to lock your mod to a specific version of
* Forge.
*/
public static void forgeLock(int major, int minor, int revision, boolean strict)
{
if (ForgeVersion.getMajorVersion() != major) { throw new RuntimeException("Universal Electricity: Wrong Minecraft Forge version! Require " + major + "." + minor + "." + revision); }
if (ForgeVersion.getMinorVersion() < minor) { throw new RuntimeException("Universal Electricity: Minecraft Forge minor version is too old! Require " + major + "." + minor + "." + revision); }
if (ForgeVersion.getRevisionVersion() < revision)
{
if (strict)
{
throw new RuntimeException("Universal Electricity: Minecraft Forge revision version is too old! Require " + major + "." + minor + "." + revision);
}
else
{
System.out.println("Universal Electricity Warning: Minecraft Forge is not the specified version. Odd things might happen. Require " + major + "." + minor + "." + revision);
}
}
}
public static void forgeLock(int major, int minor, int revision)
{
forgeLock(major, minor, revision, false);
}
}

View file

@ -0,0 +1,106 @@
package universalelectricity.core;
import net.minecraft.src.MathHelper;
/**
* Vector2 Class is used for defining objects in a 2D space. Vector2 makes it
* easier to handle the coordinates of objects. Instead of fumbling with x and y
* variables, all x and y variables are stored in one class. Vector3.x,
* Vector3.y.
*
* @author Calclavia
*/
public class Vector2 implements Cloneable
{
public double x;
public double y;
public Vector2()
{
this(0, 0);
}
public Vector2(int x, int y)
{
this.x = x;
this.y = y;
}
public Vector2(double x, double y)
{
this.x = x;
this.y = y;
}
// Returns the values as an int
public int intX()
{
return (int) Math.floor(this.x);
}
public int intY()
{
return (int) Math.floor(this.y);
}
/**
* Makes a new copy of this Vector. Prevents variable referencing problems.
*/
@Override
public Vector2 clone()
{
return new Vector2(this.x, this.y);
}
public static boolean isPointInRegion(Vector2 point, Vector2 minPoint, Vector2 maxPoint)
{
return (point.x > minPoint.x && point.x < maxPoint.x) && (point.y > minPoint.y && point.y < maxPoint.y);
}
public static double distance(Vector2 par1, Vector2 par2)
{
double var2 = par1.x - par2.x;
double var4 = par1.y - par2.y;
return MathHelper.sqrt_double(var2 * var2 + var4 * var4);
}
public static double slope(Vector2 par1, Vector2 par2)
{
double var2 = par1.x - par2.x;
double var4 = par1.y - par2.y;
return var4 / var2;
}
public void add(Vector2 par1)
{
this.x += par1.x;
this.y += par1.y;
}
public void add(double par1)
{
this.x += par1;
this.y += par1;
}
public Vector2 round()
{
return new Vector2(Math.round(this.x), Math.round(this.y));
}
public Vector2 floor()
{
return new Vector2(Math.floor(this.x), Math.floor(this.y));
}
public String output()
{
return "Vector2: " + this.x + "," + this.y;
}
public void printVector()
{
System.out.println(output());
}
}

View file

@ -0,0 +1,448 @@
package universalelectricity.core;
import net.minecraft.src.ChunkCoordinates;
import net.minecraft.src.Entity;
import net.minecraft.src.MathHelper;
import net.minecraft.src.MovingObjectPosition;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import net.minecraft.src.Vec3;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.implement.IConnector;
/**
* Vector3 Class is used for defining objects in a 3D space. Vector3 makes it
* easier to handle the coordinates of objects. Instead of fumbling with x, y
* and z variables, all x, y and z variables are stored in one class. Vector3.x,
* Vector3.y, Vector3.z.
*
* @author Calclavia
*/
public class Vector3 extends Vector2 implements Cloneable
{
public double z;
public Vector3()
{
this(0, 0, 0);
}
public Vector3(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Vector3(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
/**
* Returns the coordinates as integers
*/
public int intX()
{
return (int) Math.floor(this.x);
}
public int intY()
{
return (int) Math.floor(this.y);
}
public int intZ()
{
return (int) Math.floor(this.z);
}
/**
* Makes a new copy of this Vector. Prevents variable referencing problems.
*/
@Override
public Vector3 clone()
{
return new Vector3(this.x, this.y, this.z);
}
/**
* Converts a TileEntity's position into Vector3
*/
public static Vector3 get(Entity par1)
{
return new Vector3(par1.posX, par1.posY, par1.posZ);
}
/**
* Converts an entity's position into Vector3
*/
public static Vector3 get(TileEntity par1)
{
return new Vector3(par1.xCoord, par1.yCoord, par1.zCoord);
}
/**
* Converts from Vec3 into a Vector3
*/
public static Vector3 get(Vec3 par1)
{
return new Vector3(par1.xCoord, par1.yCoord, par1.zCoord);
}
/**
* Converts a MovingObjectPosition to Vector3
*/
public static Vector3 get(MovingObjectPosition par1)
{
return new Vector3(par1.blockX, par1.blockY, par1.blockZ);
}
/**
* Converts a MovingObjectPosition to Vector3
*/
public static Vector3 get(ChunkCoordinates par1)
{
return new Vector3(par1.posX, par1.posY, par1.posZ);
}
public int getBlockID(World world)
{
return world.getBlockId(this.intX(), this.intY(), this.intZ());
}
public int getBlockMetadata(World world)
{
return world.getBlockMetadata(this.intX(), this.intY(), this.intZ());
}
public TileEntity getTileEntity(World world)
{
return world.getBlockTileEntity(this.intX(), this.intY(), this.intZ());
}
public void setBlock(World world, int id, int metadata)
{
world.setBlockAndMetadata(this.intX(), this.intY(), this.intZ(), id, metadata);
}
public void setBlock(World world, int id)
{
world.setBlock(this.intX(), this.intY(), this.intZ(), id);
}
public void setBlockWithNotify(World world, int id, int metadata)
{
world.setBlockAndMetadataWithNotify(this.intX(), this.intY(), this.intZ(), id, metadata);
}
public void setBlockWithNotify(World world, int id)
{
world.setBlockWithNotify(this.intX(), this.intY(), this.intZ(), id);
}
/**
* Converts this Vector3 into a Vector2 by dropping the Y axis.
*/
public Vector2 toVector2()
{
return new Vector2(this.x, this.z);
}
/**
* Converts this vector three into a Minecraft Vec3 object
*/
public Vec3 toVec3()
{
return Vec3.createVectorHelper(this.x, this.y, this.z);
}
/**
* Checks if a Vector3 point is located inside a region
*/
public static boolean isPointInRegion(Vector3 point, Vector3 minPoint, Vector3 maxPoint)
{
return (point.x > minPoint.x && point.x < maxPoint.x) && (point.y > minPoint.y && point.y < maxPoint.y) && (point.z > minPoint.z && point.z < maxPoint.z);
}
/**
* Compares two vectors and see if they are equal. True if so.
*/
public boolean isEqual(Vector3 vector3)
{
return (this.x == vector3.x && this.y == vector3.y && this.z == vector3.z);
}
/**
* Gets the distance between two vectors
*
* @return The distance
*/
public static double distance(Vector3 par1, Vector3 par2)
{
double var2 = par1.x - par2.x;
double var4 = par1.y - par2.y;
double var6 = par1.z - par2.z;
return MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6);
}
public double distanceTo(Vector3 vector3)
{
double var2 = vector3.x - this.x;
double var4 = vector3.y - this.y;
double var6 = vector3.z - this.z;
return MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6);
}
public static Vector3 subtract(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x - par2.x, par1.y - par2.y, par1.z - par2.z);
}
public static Vector3 add(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x + par2.x, par1.y + par2.y, par1.z + par2.z);
}
public static Vector3 add(Vector3 par1, double par2)
{
return new Vector3(par1.x + par2, par1.y + par2, par1.z + par2);
}
public void add(Vector3 par1)
{
this.x += par1.x;
this.y += par1.y;
this.z += par1.z;
}
@Override
public void add(double par1)
{
this.x += par1;
this.y += par1;
this.z += par1;
}
public static Vector3 multiply(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x * par2.x, par1.y * par2.y, par1.z * par2.z);
}
public static Vector3 multiply(Vector3 par1, double par2)
{
return new Vector3(par1.x * par2, par1.y * par2, par1.z * par2);
}
public static Vector3 readFromNBT(String prefix, NBTTagCompound par1NBTTagCompound)
{
Vector3 tempVector = new Vector3();
tempVector.x = par1NBTTagCompound.getDouble(prefix + "X");
tempVector.y = par1NBTTagCompound.getDouble(prefix + "Y");
tempVector.z = par1NBTTagCompound.getDouble(prefix + "Z");
return tempVector;
}
/**
* Saves this Vector3 to disk
*
* @param prefix
* - The prefix of this save. Use some unique string.
* @param par1NBTTagCompound
* - The NBT compound object to save the data in
*/
public void writeToNBT(String prefix, NBTTagCompound par1NBTTagCompound)
{
par1NBTTagCompound.setDouble(prefix + "X", this.x);
par1NBTTagCompound.setDouble(prefix + "Y", this.y);
par1NBTTagCompound.setDouble(prefix + "Z", this.z);
}
@Override
public Vector3 round()
{
return new Vector3(Math.round(this.x), Math.round(this.y), Math.round(this.z));
}
@Override
public Vector3 floor()
{
return new Vector3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z));
}
@Override
public String output()
{
return "Vector3: " + this.x + "," + this.y + "," + this.z;
}
/**
* Gets a position relative to another position's side
*
* @param position
* - The position
* @param side
* - The side. 0-5
* @return The position relative to the original position's side
*/
public void modifyPositionFromSide(ForgeDirection side)
{
switch (side.ordinal())
{
case 0:
this.y -= 1;
break;
case 1:
this.y += 1;
break;
case 2:
this.z -= 1;
break;
case 3:
this.z += 1;
break;
case 4:
this.x -= 1;
break;
case 5:
this.x += 1;
break;
}
}
public static TileEntity getTileEntityFromSide(World world, Vector3 position, ForgeDirection side)
{
position.modifyPositionFromSide(side);
return world.getBlockTileEntity(position.intX(), position.intY(), position.intZ());
}
/**
* Gets a connector unit based on the given side.
*/
public static TileEntity getConnectorFromSide(World world, Vector3 position, ForgeDirection side)
{
TileEntity tileEntity = getTileEntityFromSide(world, position, side);
if (tileEntity instanceof IConnector)
{
if (((IConnector) tileEntity).canConnect(getOrientationFromSide(side, ForgeDirection.NORTH))) { return tileEntity; }
}
return null;
}
/**
* Finds the side of a block depending on it's facing direction from the
* given side. The side numbers are compatible with the
* function"getBlockTextureFromSideAndMetadata".
*
* Bottom: 0; Top: 1; Back: 2; Front: 3; Left: 4; Right: 5;
*
* @param front
* - The direction in which this block is facing/front. Use a
* number between 0 and 5. Default is 3.
* @param side
* - The side you are trying to find. A number between 0 and 5.
* @return The side relative to the facing direction.
*/
public static ForgeDirection getOrientationFromSide(ForgeDirection front, ForgeDirection side)
{
switch (front.ordinal())
{
case 0:
switch (side.ordinal())
{
case 0:
return ForgeDirection.getOrientation(3);
case 1:
return ForgeDirection.getOrientation(2);
case 2:
return ForgeDirection.getOrientation(1);
case 3:
return ForgeDirection.getOrientation(0);
case 4:
return ForgeDirection.getOrientation(5);
case 5:
return ForgeDirection.getOrientation(4);
}
case 1:
switch (side.ordinal())
{
case 0:
return ForgeDirection.getOrientation(4);
case 1:
return ForgeDirection.getOrientation(5);
case 2:
return ForgeDirection.getOrientation(0);
case 3:
return ForgeDirection.getOrientation(1);
case 4:
return ForgeDirection.getOrientation(2);
case 5:
return ForgeDirection.getOrientation(3);
}
case 2:
switch (side.ordinal())
{
case 0:
return ForgeDirection.getOrientation(0);
case 1:
return ForgeDirection.getOrientation(1);
case 2:
return ForgeDirection.getOrientation(3);
case 3:
return ForgeDirection.getOrientation(2);
case 4:
return ForgeDirection.getOrientation(5);
case 5:
return ForgeDirection.getOrientation(4);
}
case 3:
return side;
case 4:
switch (side.ordinal())
{
case 0:
return ForgeDirection.getOrientation(0);
case 1:
return ForgeDirection.getOrientation(1);
case 2:
return ForgeDirection.getOrientation(5);
case 3:
return ForgeDirection.getOrientation(4);
case 4:
return ForgeDirection.getOrientation(3);
case 5:
return ForgeDirection.getOrientation(2);
}
case 5:
switch (side.ordinal())
{
case 0:
return ForgeDirection.getOrientation(0);
case 1:
return ForgeDirection.getOrientation(1);
case 2:
return ForgeDirection.getOrientation(4);
case 3:
return ForgeDirection.getOrientation(5);
case 4:
return ForgeDirection.getOrientation(2);
case 5:
return ForgeDirection.getOrientation(3);
}
}
return ForgeDirection.UNKNOWN;
}
}

View file

@ -0,0 +1,203 @@
package universalelectricity.electricity;
/**
* An easy way to display information on electricity.
*
* @author Calclavia
*/
public class ElectricInfo
{
public static enum ElectricUnit
{
AMPERE("Amp", "I"), AMP_HOUR("Amp Hour", "Ah"), VOLTAGE("Volt", "V"), WATT("Watt", "W"), WATT_HOUR("Watt Hour", "Wh"), RESISTANCE("Ohm", "R"), CONDUCTANCE("Siemen", "S"), JOULES("Joule", "J");
public String name;
public String symbol;
private ElectricUnit(String name, String symbol)
{
this.name = name;
this.symbol = symbol;
}
public String getPlural()
{
return this.name + "s";
}
}
public static enum MeasurementUnit
{
MICRO("Micro", "mi", 0.000001), MILLI("Milli", "m", 0.001), KILO("Kilo", "k", 1000), MEGA("Mega", "M", 1000000);
public String name;
public String symbol;
public double process;
private MeasurementUnit(String name, String symbol, double process)
{
this.name = name;
this.symbol = symbol;
this.process = process;
}
public String getName(boolean isSymbol)
{
if (isSymbol)
{
return symbol;
}
else
{
return name;
}
}
public double process(double value)
{
return value / this.process;
}
}
public static double getJoules(double watts, double seconds)
{
return watts * seconds;
}
public static double getJoules(double amps, double voltage, double seconds)
{
return amps * voltage * seconds;
}
public static double getWattsFromJoules(double joules, double seconds)
{
return joules / seconds;
}
public static double getAmps(double watts, double voltage)
{
return watts / voltage;
}
public static double getAmps(double ampHours)
{
return ampHours * 3600;
}
public static double getAmpsFromWattHours(double wattHours, double voltage)
{
return getWatts(wattHours) / voltage;
}
public static double getWattHoursFromAmpHours(double ampHours, double voltage)
{
return ampHours * voltage;
}
public static double getAmpHours(double amps)
{
return amps / 3600;
}
public static double getWatts(double amps, double voltage)
{
return amps * voltage;
}
public static double getWatts(double wattHours)
{
return wattHours * 3600;
}
public static double getWattHours(double watts)
{
return watts / 3600;
}
public static double getWattHours(double amps, double voltage)
{
return getWattHours(getWatts(amps, voltage));
}
public static double getResistance(double amps, double voltage)
{
return voltage / amps;
}
public static double getConductance(double amps, double voltage)
{
return amps / voltage;
}
/**
* Displays the unit as text. Works only for positive numbers.
*/
public static String getDisplay(double value, ElectricUnit unit, int significantFigures, boolean isShort)
{
String unitName = unit.name;
if (isShort)
{
unitName = unit.symbol;
}
else if (value > 1)
{
unitName = unit.getPlural();
}
if (value == 0) { return value + " " + unitName; }
if (value <= MeasurementUnit.MILLI.process) { return roundDecimals(MeasurementUnit.MICRO.process(value), significantFigures) + " " + MeasurementUnit.MICRO.getName(isShort) + unitName; }
if (value < 1) { return roundDecimals(MeasurementUnit.MILLI.process(value), significantFigures) + " " + MeasurementUnit.MILLI.getName(isShort) + unitName; }
if (value > MeasurementUnit.KILO.process) { return roundDecimals(MeasurementUnit.KILO.process(value), significantFigures) + " " + MeasurementUnit.KILO.getName(isShort) + unitName; }
if (value > MeasurementUnit.MEGA.process) { return roundDecimals(MeasurementUnit.MEGA.process(value), significantFigures) + " " + MeasurementUnit.MEGA.getName(isShort) + unitName; }
return roundDecimals(value, significantFigures) + " " + unitName;
}
public static String getDisplayShort(double value, ElectricUnit unit)
{
return getDisplay(value, unit, 2, true);
}
public static String getDisplay(double value, ElectricUnit unit)
{
return getDisplay(value, unit, 2, false);
}
public static String getDisplaySimple(double value, ElectricUnit unit, int significantFigures)
{
if (value > 1)
{
if (significantFigures < 1) { return (int) value + " " + unit.getPlural(); }
return roundDecimals(value, significantFigures) + " " + unit.getPlural();
}
if (significantFigures < 1) { return (int) value + " " + unit.name; }
return roundDecimals(value, significantFigures) + " " + unit.name;
}
/**
* Rounds a number to a specific number place places
*
* @param The
* number
* @return The rounded number
*/
public static double roundDecimals(double d, int significantFigures)
{
int j = (int) (d * Math.pow(10, significantFigures));
return j / (double) Math.pow(10, significantFigures);
}
public static double roundDecimals(double d)
{
return roundDecimals(d, 2);
}
}

View file

@ -0,0 +1,412 @@
package universalelectricity.electricity;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.Vector3;
import universalelectricity.implement.IConductor;
import universalelectricity.implement.IElectricityReceiver;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.TickType;
/**
* This class is used to manage electricity
* transferring and flow. It is also used to call
* updates on UE tile entities.
*
* @author Calclavia
*
*/
public class ElectricityManager
{
/**
* ElectricityManager exists on both client
* and server side. Rely on the server side
* one as it is more accurate! Client side
* only simulates.
*/
public static ElectricityManager instance;
private List<ElectricityTransferData> electricityTransferQueue = new ArrayList<ElectricityTransferData>();
private List<ElectricityNetwork> electricityNetworks = new ArrayList<ElectricityNetwork>();
public ElectricityManager()
{
System.out.println("Universal Electricity's Electricity Manager Initiated.");
}
/**
* Registers a the conductor into the UE
* electricity net.
*
* @param conductor
* - The IConductor tile entity.
*/
public void registerConductor(IConductor newConductor)
{
cleanUpConnections();
this.electricityNetworks.add(new ElectricityNetwork(newConductor));
}
/**
* Merges two connection lines together into
* one.
*
* @param networkA
* - The network to be merged into.
* This network will be kept.
* @param networkB
* - The network to be merged. This
* network will be deleted.
*/
public void mergeConnection(ElectricityNetwork networkA, ElectricityNetwork networkB)
{
if (networkA != networkB)
{
if (networkA != null && networkB != null)
{
networkA.conductors.addAll(networkB.conductors);
networkA.setNetwork();
this.electricityNetworks.remove(networkB);
networkB = null;
}
else
{
System.err.println("Failed to merge Universal Electricity wire connections!");
}
}
}
/**
* Separate one connection line into two
* different ones between two conductors. This
* function does this by resetting all wires
* in the connection line and making them each
* reconnect.
*
* @param conductorA
* - existing conductor
* @param conductorB
* - broken/invalid conductor
*/
public void splitConnection(IConductor conductorA, IConductor conductorB)
{
ElectricityNetwork connection = conductorA.getNetwork();
if (connection != null)
{
connection.cleanUpArray();
for (IConductor conductor : connection.conductors)
{
conductor.reset();
}
for (IConductor conductor : connection.conductors)
{
for (byte i = 0; i < 6; i++)
{
conductor.updateConnectionWithoutSplit(Vector3.getConnectorFromSide(conductor.getWorld(), new Vector3(((TileEntity) conductor).xCoord, ((TileEntity) conductor).yCoord, ((TileEntity) conductor).zCoord), ForgeDirection.getOrientation(i)), ForgeDirection.getOrientation(i));
}
}
}
else
{
FMLLog.severe("Conductor invalid network while splitting connection!");
}
}
/**
* Clean up and remove all useless and invalid
* connections.
*/
public void cleanUpConnections()
{
try
{
for (int i = 0; i < this.electricityNetworks.size(); i++)
{
this.electricityNetworks.get(i).cleanUpArray();
if (this.electricityNetworks.get(i).conductors.size() == 0)
{
this.electricityNetworks.remove(i);
}
}
}
catch (Exception e)
{
FMLLog.severe("Failed to clean up wire connections!");
}
}
/**
* Produces electricity into a specific wire
* which will be distributed across the
* electricity network.
*
* @param sender
* The machine sending the
* electricity.
* @param targetConductor
* The conductor receiving the
* electricity (or connected to the
* machine).
* @param amps
* The amount of amps this machine
* is sending.
* @param voltage
* The amount of volts this machine
* is sending.
*/
public void produceElectricity(TileEntity sender, IConductor targetConductor, double amps, double voltage)
{
if (targetConductor != null && amps > 0 && voltage > 0)
{
// Find a path between this conductor
// and all connected units and
// try to send the electricity to them
// directly
ElectricityNetwork electricityNetwork = targetConductor.getNetwork();
if (electricityNetwork != null)
{
List<IElectricityReceiver> allElectricUnitsInLine = electricityNetwork.getConnectedReceivers();
double leftOverAmps = amps;
for (IConductor conductor : electricityNetwork.conductors)
{
for (byte i = 0; i < conductor.getConnectedBlocks().length; i++)
{
TileEntity tileEntity = conductor.getConnectedBlocks()[i];
if (tileEntity != null)
{
if (tileEntity instanceof IElectricityReceiver)
{
IElectricityReceiver receiver = (IElectricityReceiver) tileEntity;
if (this.getActualWattRequest(receiver) > 0 && receiver.canReceiveFromSide(ForgeDirection.getOrientation(i).getOpposite()))
{
double transferAmps = Math.max(0, Math.min(leftOverAmps, Math.min(amps / allElectricUnitsInLine.size(), ElectricInfo.getAmps(this.getActualWattRequest(receiver), receiver.getVoltage()))));
leftOverAmps -= transferAmps;
// Calculate
// electricity
// loss
double distance = Vector3.distance(Vector3.get(sender), Vector3.get((TileEntity) receiver));
double ampsReceived = transferAmps - (transferAmps * transferAmps * targetConductor.getResistance() * distance) / voltage;
double voltsReceived = voltage - (transferAmps * targetConductor.getResistance() * distance);
this.electricityTransferQueue.add(new ElectricityTransferData(sender, receiver, electricityNetwork, ForgeDirection.getOrientation(i).getOpposite(), ampsReceived, voltsReceived));
}
}
}
}
}
}
else
{
FMLLog.severe("Conductor not registered to a network!");
}
}
}
/**
* Gets the actual watt request of an electric
* receiver accounting all current electricity
* packets qued up for it.
*
* @return - The amount of watts requested.
*/
public double getActualWattRequest(IElectricityReceiver receiver)
{
double wattsRequest = receiver.wattRequest();
try
{
for (int i = 0; i < electricityTransferQueue.size(); i++)
{
if (electricityTransferQueue.get(i) != null)
{
if (electricityTransferQueue.get(i).isValid())
{
if (electricityTransferQueue.get(i).receiver == receiver)
{
wattsRequest -= electricityTransferQueue.get(i).amps * electricityTransferQueue.get(i).voltage;
}
}
}
}
}
catch (Exception e)
{
FMLLog.severe("Failed to get watt request!");
}
return Math.max(Math.min(wattsRequest, receiver.wattRequest()), 0);
}
/**
* Checks if the current connection line needs
* electricity
*
* @return - The amount of joules this
* connection line needs
*/
public double getElectricityRequired(ElectricityNetwork network)
{
double need = 0;
if (network != null)
{
for (IConductor conductor : network.conductors)
{
for (byte i = 0; i < conductor.getConnectedBlocks().length; i++)
{
TileEntity tileEntity = conductor.getConnectedBlocks()[i];
if (tileEntity != null)
{
if (tileEntity instanceof IElectricityReceiver)
{
IElectricityReceiver electricUnit = (IElectricityReceiver) tileEntity;
if (electricUnit.canReceiveFromSide(ForgeDirection.getOrientation(i).getOpposite()))
{
need += electricUnit.wattRequest();
}
}
}
}
}
}
return need;
}
public double getActualElectricityRequired(ElectricityNetwork network)
{
double need = 0;
if (network != null)
{
for (IConductor conductor : network.conductors)
{
for (byte i = 0; i < conductor.getConnectedBlocks().length; i++)
{
TileEntity tileEntity = conductor.getConnectedBlocks()[i];
if (tileEntity != null)
{
if (tileEntity instanceof IElectricityReceiver)
{
IElectricityReceiver electricUnit = (IElectricityReceiver) tileEntity;
if (electricUnit.canReceiveFromSide(ForgeDirection.getOrientation(i).getOpposite()))
{
need += this.getActualWattRequest(electricUnit);
}
}
}
}
}
}
return need;
}
/**
* This function is called to refresh all
* conductors in the world.
*/
public void refreshConductors()
{
try
{
Iterator it = electricityNetworks.iterator();
while (it.hasNext())
{
((ElectricityNetwork) it.next()).refreshConductors();
}
}
catch (Exception e)
{
FMLLog.fine("Failed to refresh conductors.");
}
}
public void onTick(EnumSet<TickType> type, Object... tickData)
{
if (type.contains(TickType.WORLD) && !type.contains(TickType.WORLDLOAD))
{
if (ElectricityManagerTicker.inGameTicks % 40 == 0)
{
this.refreshConductors();
}
try
{
HashMap conductorAmpData = new HashMap<ElectricityNetwork, Double>();
for (int i = 0; i < electricityTransferQueue.size(); i++)
{
if (electricityTransferQueue.get(i) != null)
{
if (electricityTransferQueue.get(i).isValid())
{
double amps = electricityTransferQueue.get(i).amps;
if (conductorAmpData.containsKey(electricityTransferQueue.get(i).network))
{
amps += (Double) conductorAmpData.get(electricityTransferQueue.get(i).network);
}
conductorAmpData.put(electricityTransferQueue.get(i).network, amps);
electricityTransferQueue.get(i).receiver.onReceive(electricityTransferQueue.get(i).sender, electricityTransferQueue.get(i).amps, electricityTransferQueue.get(i).voltage, electricityTransferQueue.get(i).side);
}
}
electricityTransferQueue.remove(i);
}
Iterator it = conductorAmpData.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
if (pairs.getKey() != null && pairs.getValue() != null)
{
if (pairs.getKey() instanceof ElectricityNetwork && pairs.getValue() instanceof Double)
{
if (((Double) pairs.getValue()) > ((ElectricityNetwork) pairs.getKey()).getLowestAmpConductor())
{
((ElectricityNetwork) pairs.getKey()).onOverCharge();
}
}
}
it.remove();
}
}
catch (Exception e)
{
System.err.println("Failed to transfer electricity to receivers.");
e.printStackTrace();
}
}
if (ElectricityManagerTicker.inGameTicks == 0)
{
this.refreshConductors();
}
}
}

View file

@ -0,0 +1,45 @@
package universalelectricity.electricity;
import java.util.EnumSet;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
public class ElectricityManagerTicker implements ITickHandler
{
public static long inGameTicks = 0;
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)
{
if (ElectricityManager.instance != null)
{
ElectricityManager.instance.onTick(type, tickData);
}
inGameTicks++;
if (inGameTicks >= Long.MAX_VALUE)
{
inGameTicks = 0;
}
}
@Override
public void tickEnd(EnumSet<TickType> type, Object... tickData)
{
}
@Override
public EnumSet<TickType> ticks()
{
return EnumSet.of(TickType.WORLD, TickType.WORLDLOAD, TickType.SERVER);
}
@Override
public String getLabel()
{
return "Electricity Manager";
}
}

View file

@ -0,0 +1,123 @@
package universalelectricity.electricity;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.implement.IConductor;
import universalelectricity.implement.IElectricityReceiver;
public class ElectricityNetwork
{
public List<IConductor> conductors = new ArrayList<IConductor>();
public ElectricityNetwork(IConductor conductor)
{
this.addConductor(conductor);
}
public void addConductor(IConductor newConductor)
{
this.cleanUpArray();
if (!conductors.contains(newConductor))
{
conductors.add(newConductor);
newConductor.setNetwork(this);
}
}
/**
* Get only the electric units that can receive electricity from the given
* side.
*/
public List<IElectricityReceiver> getConnectedReceivers()
{
this.cleanUpArray();
List<IElectricityReceiver> returnArray = new ArrayList<IElectricityReceiver>();
for (IConductor conductor : conductors)
{
for (byte i = 0; i < conductor.getConnectedBlocks().length; i++)
{
TileEntity tileEntity = conductor.getConnectedBlocks()[i];
if (tileEntity != null)
{
if (tileEntity instanceof IElectricityReceiver)
{
if (!returnArray.contains((IElectricityReceiver) tileEntity) && ((IElectricityReceiver) tileEntity).canReceiveFromSide(ForgeDirection.getOrientation(i).getOpposite()))
{
returnArray.add((IElectricityReceiver) tileEntity);
}
}
}
}
}
return returnArray;
}
public void cleanUpArray()
{
for (int i = 0; i < conductors.size(); i++)
{
if (conductors.get(i) == null)
{
conductors.remove(i);
}
else if (((TileEntity) conductors.get(i)).isInvalid())
{
conductors.remove(i);
}
}
}
public void setNetwork()
{
this.cleanUpArray();
for (IConductor conductor : this.conductors)
{
conductor.setNetwork(this);
}
}
public void onOverCharge()
{
this.cleanUpArray();
for (int i = 0; i < conductors.size(); i++)
{
conductors.get(i).onOverCharge();
}
}
public double getLowestAmpConductor()
{
double lowestAmp = 0;
for (IConductor conductor : conductors)
{
if (lowestAmp == 0 || conductor.getMaxAmps() < lowestAmp)
{
lowestAmp = conductor.getMaxAmps();
}
}
return lowestAmp;
}
/**
* This function is called to refresh all conductors in this network
*/
public void refreshConductors()
{
for (int j = 0; j < this.conductors.size(); j++)
{
IConductor conductor = this.conductors.get(j);
conductor.refreshConnectedBlocks();
}
}
}

View file

@ -0,0 +1,42 @@
package universalelectricity.electricity;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.implement.IElectricityReceiver;
public class ElectricityTransferData
{
public TileEntity sender;
public IElectricityReceiver receiver;
public ElectricityNetwork network;
public double amps;
public double voltage;
public ForgeDirection side;
/**
* @param sender
* - Tile that's sending electricity.
* @param receiver
* - Receiver that's receiving electricity
* @param conductor
* - Conductor that is conducting the electricity
* @param side
* -
* @param amps
* @param voltage
*/
public ElectricityTransferData(TileEntity sender, IElectricityReceiver receiver, ElectricityNetwork network, ForgeDirection side, double amps, double voltage)
{
this.sender = sender;
this.receiver = receiver;
this.network = network;
this.side = side;
this.amps = amps;
this.voltage = voltage;
}
public boolean isValid()
{
return this.sender != null && this.receiver != null && this.network != null && this.amps > 0 && this.voltage > 0;
}
}

View file

@ -0,0 +1,71 @@
package universalelectricity.implement;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.electricity.ElectricityNetwork;
/**
* Must be applied to all tile entities that are conductors.
*
* @author Calclavia
*
*/
public interface IConductor extends IConnector
{
/**
* The electrical network this conductor is on.
*/
public ElectricityNetwork getNetwork();
public void setNetwork(ElectricityNetwork network);
/**
* The UE tile entities that this conductor is connected to.
*
* @return
*/
public TileEntity[] getConnectedBlocks();
/**
* Gets the resistance of the conductor. Used to calculate energy loss. A
* higher resistance means a higher energy loss.
*
* @return The amount of Ohm's of resistance.
*/
public double getResistance();
/**
* The maximum amount of amps this conductor can handle before melting down.
* This is calculating PER TICK!
*
* @return The amount of amps in volts
*/
public double getMaxAmps();
/**
* Called when the electricity passing through exceeds the maximum voltage.
*/
public void onOverCharge();
/**
* Resets the conductor and recalculate connection IDs again
*/
public void reset();
public World getWorld();
/**
* Adds a connection between this conductor and a UE unit
*
* @param tileEntity
* - Must be either a producer, consumer or a conductor
* @param side
* - side in which the connection is coming from
*/
public void updateConnection(TileEntity tileEntity, ForgeDirection side);
public void updateConnectionWithoutSplit(TileEntity connectorFromSide, ForgeDirection orientation);
public void refreshConnectedBlocks();
}

View file

@ -0,0 +1,21 @@
package universalelectricity.implement;
import net.minecraftforge.common.ForgeDirection;
/**
* Applied to TileEntities that can connect to UE wires.
*
* @author Calclavia
*
*/
public interface IConnector
{
/**
* Can this tile entity visually connect to a wire on this specific side?
*
* @param side
* - The side in which the connection is coming from.
* @return - True if so.
*/
public boolean canConnect(ForgeDirection side);
}

View file

@ -0,0 +1,26 @@
package universalelectricity.implement;
/**
* This class should be applied to all tile entities (mainly machines) that can
* be disabled (by things like EMP, short circuit etc.).
*
* @author Calclavia
*
*/
public interface IDisableable
{
/**
* This is called when the tile entity is to be disabled.
*
* @param duration
* - The duration of the disable in ticks.
*/
public void onDisable(int duration);
/**
* Called to see if this tile entity is disabled.
*
* @return True if the tile entity is disabled.
*/
public boolean isDisabled();
}

View file

@ -0,0 +1,20 @@
package universalelectricity.implement;
import net.minecraftforge.common.ForgeDirection;
/**
* Applied to tile entities that can produce electricity
*
* @author Calclavia
*/
public interface IElectricityProducer extends IConnector, IDisableable, IVoltage
{
/**
* Can this machine visually connect to a wire on this specific side?
*
* @param side
* . 0-5 byte
* @return - True if so.
*/
public boolean canConnect(ForgeDirection side);
}

View file

@ -0,0 +1,41 @@
package universalelectricity.implement;
import net.minecraft.src.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* The IElectricityReceiver interface is an interface that must be applied to
* all tile entities that can input or output electricity.
*
* @author Calclavia
*
*/
public interface IElectricityReceiver extends IDisableable, IConnector, IVoltage
{
/**
* Called every tick on this machine.
*
* @param amps
* - Amount of amps this electric unit is receiving.
* @param voltage
* - The voltage of the electricity sent. If more than one packet
* is being sent to you in this update, the highest voltage will
* override.
* @param side
* - The side of the block in which the electricity is coming
* from.
*/
public void onReceive(TileEntity sender, double amps, double voltage, ForgeDirection side);
/**
* How many watts does this electrical unit need this tick? Recommended for
* you to return the max electricity storage of this machine (if there is
* one).
*/
public double wattRequest();
/**
* Can this unit receive electricity from this specific side?
*/
public boolean canReceiveFromSide(ForgeDirection side);
}

View file

@ -0,0 +1,33 @@
package universalelectricity.implement;
import net.minecraft.src.ItemStack;
public interface IItemElectric extends IJouleStorage, IVoltage
{
/**
* Called when this item receives electricity.
*/
public double onReceive(double amps, double voltage, ItemStack itemStack);
/**
* Called when something requests electricity from this item.
*
* @return - The amount of given joules
*/
public double onUse(double joulesNeeded, ItemStack itemStack);
/**
* @return Returns true or false if this consumer can receive electricity at
* this given tick or moment.
*/
public boolean canReceiveElectricity();
/**
* Can this item give out electricity when placed in an tile entity?
* Electric items like batteries should be able to produce electricity (if
* they are rechargeable).
*
* @return - True or False.
*/
public boolean canProduceElectricity();
}

View file

@ -0,0 +1,25 @@
package universalelectricity.implement;
/**
* This interface is to be applied to all tile entities which stores energy
* within them.
*
* @author Calclavia
*/
public interface IJouleStorage
{
/**
* Returns the amount of joules this unit has stored.
*/
public double getJoules(Object... data);
/**
* Sets the amount of joules this unit has stored.
*/
public void setJoules(double wattHours, Object... data);
/**
* Gets the maximum amount of joules this unit can store.
*/
public double getMaxJoules();
}

View file

@ -0,0 +1,14 @@
package universalelectricity.implement;
/**
* This should be applied on tile entities that can provide redstone power
*
* @author Henry
*
*/
public interface IRedstoneProvider
{
public boolean isPoweringTo(byte side);
public boolean isIndirectlyPoweringTo(byte side);
}

View file

@ -0,0 +1,21 @@
package universalelectricity.implement;
/**
* OPTIONAL This interface should be applied onto all tile entities that needs
* to receive redstone power. Look at TileEntityBatteryBox for reference.
*
* @author Calclavia
*
*/
public interface IRedstoneReceptor
{
/**
* Called when the block is powered on by redstone
*/
public void onPowerOn();
/**
* Called when the block is powered off by redstone
*/
public void onPowerOff();
}

View file

@ -0,0 +1,33 @@
package universalelectricity.implement;
import net.minecraftforge.common.ForgeDirection;
/**
* This interface should be applied onto all tile entities that are
* rotatable. This interface however is optional and you do not need it for your
* add-on to function. It just makes things easier for you to code.
*
* @author Calclavia
*
*/
public interface IRotatable
{
/**
* Gets the facing direction of the tile entity. Always returns the front
* side of the tile entity.
*
* @return The facing side from 0-5 The full list of which side the number
* represents is in the UniversalElectricity class.
*/
public ForgeDirection getDirection();
/**
* Sets the facing direction of the tile entity.
*
* @param facingDirection
* - A direction from 0-5. The full list of which side the number
* represents is in the UniversalElectricity class.
*/
public void setDirection(ForgeDirection facingDirection);
}

View file

@ -0,0 +1,25 @@
package universalelectricity.implement;
/**
* This interface should be applied to all things that has a tier/level.
*
* @author Calclavia
*
*/
public interface ITier
{
/**
* Gets the tier of this object
*
* @return - The tier
*/
public int getTier();
/**
* Sets the tier of the object
*
* @param tier
* - The tier to be set
*/
public void setTier(int tier);
}

View file

@ -0,0 +1,15 @@
package universalelectricity.implement;
/**
* Applies to all objects that has a voltage.
* @author Calclavia
*
*/
public interface IVoltage
{
/**
* Gets the voltage of this object.
* @return The amount of volts. E.g 120v or 240v
*/
public double getVoltage();
}

View file

@ -0,0 +1,57 @@
package universalelectricity.implement;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.DamageSource;
import cpw.mods.fml.common.registry.LanguageRegistry;
public class UEDamageSource extends DamageSource
{
public static final List<UEDamageSource> damageSources = new ArrayList<UEDamageSource>();
/**
* Use this damage source for all types of electrical attacks.
*/
public static final UEDamageSource electrocution = (UEDamageSource) new UEDamageSource("electrocution", "%1$s got electrocuted!").setDamageBypassesArmor();
public String deathMessage;
public UEDamageSource(String damageType)
{
super(damageType);
damageSources.add(this);
}
public UEDamageSource(String damageType, String deathMessage)
{
this(damageType);
this.setDeathMessage(deathMessage);
}
public UEDamageSource setDeathMessage(String deathMessage)
{
this.deathMessage = deathMessage;
return this;
}
public DamageSource setDamageBypassesArmor()
{
return super.setDamageBypassesArmor();
}
public DamageSource setDamageAllowedInCreativeMode()
{
return super.setDamageAllowedInCreativeMode();
}
public DamageSource setFireDamage()
{
return super.setFireDamage();
}
public void registerDeathMessage()
{
LanguageRegistry.instance().addStringLocalization("death." + this.damageType, this.deathMessage);
}
}

View file

@ -0,0 +1,55 @@
package universalelectricity.prefab;
import net.minecraft.src.BlockContainer;
import net.minecraft.src.Material;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import universalelectricity.implement.IConductor;
public abstract class BlockConductor extends BlockContainer
{
public BlockConductor(int id, Material material)
{
super(id, material);
}
/**
* Called whenever the block is added into the world. Args: world, x, y, z
*/
@Override
public void onBlockAdded(World world, int x, int y, int z)
{
super.onBlockAdded(world, x, y, z);
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if(tileEntity != null)
{
if(tileEntity instanceof IConductor)
{
((IConductor)tileEntity).refreshConnectedBlocks();
}
}
}
/**
* Lets the block know when one of its neighbor changes. Doesn't know which
* neighbor changed (coordinates passed are their own) Args: x, y, z,
* neighbor blockID
*/
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int blockID)
{
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
if(tileEntity != null)
{
if(tileEntity instanceof IConductor)
{
((IConductor)tileEntity).refreshConnectedBlocks();
}
}
world.markBlockNeedsUpdate(x, y, z);
}
}

View file

@ -0,0 +1,226 @@
package universalelectricity.prefab;
import java.util.Random;
import net.minecraft.src.BlockContainer;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Material;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import universalelectricity.implement.IItemElectric;
import buildcraft.api.tools.IToolWrench;
/**
* A block you may extend from to create your machine blocks! You do not have to
* extend from this block if you do not want to. It's optional but it comes with
* some useful functions that will make coding easier for you.
*/
public abstract class BlockMachine extends BlockContainer
{
public BlockMachine(String name, int id, Material material)
{
super(id, material);
this.setBlockName(name);
this.setHardness(0.5F);
}
public BlockMachine(String name, int id, Material material, CreativeTabs creativeTab)
{
this(name, id, material);
this.setCreativeTab(creativeTab);
}
@Override
public int damageDropped(int metadata)
{
return metadata;
}
/**
* Returns the quantity of items to drop on block destruction.
*/
@Override
public int quantityDropped(Random par1Random)
{
return 1;
}
/**
* Returns the ID of the items to drop on destruction.
*/
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return this.blockID;
}
/**
* DO NOT OVERRIDE THIS FUNCTION! Called when the block is right clicked by
* the player. This modified version detects electric items and wrench
* actions on your machine block. Do not override this function. Use
* machineActivated instead! (It does the same thing)
*/
@Override
public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
int metadata = par1World.getBlockMetadata(x, y, z);
/**
* Check if the player is holding a wrench or an electric item. If so,
* do not open the GUI.
*/
if (par5EntityPlayer.inventory.getCurrentItem() != null)
{
if (par5EntityPlayer.inventory.getCurrentItem().getItem() instanceof IToolWrench)
{
par1World.notifyBlocksOfNeighborChange(x, y, z, this.blockID);
((IToolWrench) par5EntityPlayer.inventory.getCurrentItem().getItem()).wrenchUsed(par5EntityPlayer, x, y, z);
if (par5EntityPlayer.isSneaking())
{
return this.onSneakUseWrench(par1World, x, y, z, par5EntityPlayer);
}
else
{
return this.onUseWrench(par1World, x, y, z, par5EntityPlayer);
}
}
else if (par5EntityPlayer.inventory.getCurrentItem().getItem() instanceof IItemElectric)
{
if (this.onUseElectricItem(par1World, x, y, z, par5EntityPlayer)) { return true; }
}
}
if (par5EntityPlayer.isSneaking())
{
return this.onSneakMachineActivated(par1World, x, y, z, par5EntityPlayer);
}
else
{
return this.onMachineActivated(par1World, x, y, z, par5EntityPlayer);
}
}
/**
* Called when the machine is right clicked by the player
*
* @return True if something happens
*/
public boolean onMachineActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
return false;
}
/**
* Called when the machine is right clicked by the player while sneaking
* (shift clicking)
*
* @return True if something happens
*/
public boolean onSneakMachineActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
return false;
}
/**
* Called when a player uses an electric item on the machine
*
* @return True if some happens
*/
public boolean onUseElectricItem(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
return false;
}
/**
* Called when a player uses a wrench on the machine
*
* @return True if some happens
*/
public boolean onUseWrench(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
return false;
}
/**
* Called when a player uses a wrench on the machine while sneaking
*
* @return True if some happens
*/
public boolean onSneakUseWrench(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer)
{
return this.onUseWrench(par1World, x, y, z, par5EntityPlayer);
}
/**
* Returns the TileEntity used by this block. You should use the metadata
* sensitive version of this to get the maximum optimization!
*/
@Override
public TileEntity createNewTileEntity(World var1)
{
return null;
}
/**
* Override this if you don't need it. This will eject all items out of this
* machine if it has an inventory
*/
@Override
public void breakBlock(World par1World, int x, int y, int z, int par5, int par6)
{
TileEntity tileEntity = par1World.getBlockTileEntity(x, y, z);
if (tileEntity != null)
{
if (tileEntity instanceof IInventory)
{
IInventory inventory = (IInventory) tileEntity;
for (int var6 = 0; var6 < inventory.getSizeInventory(); ++var6)
{
ItemStack var7 = inventory.getStackInSlot(var6);
if (var7 != null)
{
Random random = new Random();
float var8 = random.nextFloat() * 0.8F + 0.1F;
float var9 = random.nextFloat() * 0.8F + 0.1F;
float var10 = random.nextFloat() * 0.8F + 0.1F;
while (var7.stackSize > 0)
{
int var11 = random.nextInt(21) + 10;
if (var11 > var7.stackSize)
{
var11 = var7.stackSize;
}
var7.stackSize -= var11;
EntityItem var12 = new EntityItem(par1World, (x + var8), (y + var9), (z + var10), new ItemStack(var7.itemID, var11, var7.getItemDamage()));
if (var7.hasTagCompound())
{
var12.item.setTagCompound((NBTTagCompound) var7.getTagCompound().copy());
}
float var13 = 0.05F;
var12.motionX = ((float) random.nextGaussian() * var13);
var12.motionY = ((float) random.nextGaussian() * var13 + 0.2F);
var12.motionZ = ((float) random.nextGaussian() * var13);
par1World.spawnEntityInWorld(var12);
}
}
}
}
}
super.breakBlock(par1World, x, y, z, par5, par6);
}
}

View file

@ -0,0 +1,207 @@
package universalelectricity.prefab;
import java.util.List;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagFloat;
import net.minecraft.src.World;
import universalelectricity.electricity.ElectricInfo;
import universalelectricity.electricity.ElectricInfo.ElectricUnit;
import universalelectricity.implement.IItemElectric;
/**
* Extend from this class if your item requires electricity or to be charged.
* Optionally, you can implement IItemElectric instead.
*
* @author Calclavia
*
*/
public abstract class ItemElectric extends Item implements IItemElectric
{
public ItemElectric(int id, CreativeTabs tabs)
{
super(id);
this.setMaxStackSize(1);
this.setMaxDamage((int) this.getMaxJoules());
this.setNoRepair();
this.setCreativeTab(tabs);
}
public ItemElectric(int id)
{
this(id, CreativeTabs.tabTools);
}
/**
* Allows items to add custom lines of information to the mouseover
* description. If you want to add more information to your item, you can
* super.addInformation() to keep the electiricty info in the item info bar.
*/
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
String color = "";
double joules = this.getJoules(par1ItemStack);
if (joules <= this.getMaxJoules() / 3)
{
color = "\u00a74";
}
else if (joules > this.getMaxJoules() * 2 / 3)
{
color = "\u00a72";
}
else
{
color = "\u00a76";
}
par3List.add(color + ElectricInfo.getDisplay(joules, ElectricUnit.JOULES) + " - " + Math.round((joules / this.getMaxJoules()) * 100) + "%");
}
/**
* Make sure you super this method!
*/
@Override
public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5)
{
// Makes sure the damage is set correctly for this electric item!
ItemElectric item = ((ItemElectric) par1ItemStack.getItem());
item.setJoules(item.getJoules(par1ItemStack), par1ItemStack);
}
/**
* Makes sure the item is uncharged when it is crafted and not charged.
* Change this if you do not want this to happen!
*/
@Override
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
par1ItemStack = this.getUncharged();
}
@Override
public double onReceive(double amps, double voltage, ItemStack itemStack)
{
double rejectedElectricity = Math.max((this.getJoules(itemStack) + ElectricInfo.getJoules(amps, voltage, 1)) - this.getMaxJoules(), 0);
this.setJoules(this.getJoules(itemStack) + ElectricInfo.getJoules(amps, voltage, 1) - rejectedElectricity, itemStack);
return rejectedElectricity;
}
@Override
public double onUse(double joulesNeeded, ItemStack itemStack)
{
double electricityToUse = Math.min(this.getJoules(itemStack), joulesNeeded);
this.setJoules(this.getJoules(itemStack) - electricityToUse, itemStack);
return electricityToUse;
}
public boolean canReceiveElectricity()
{
return true;
}
public boolean canProduceElectricity()
{
return false;
}
/**
* This function sets the electriicty. Do not directly call this function.
* Try to use onReceiveElectricity or onUseElectricity instead.
*
* @param wattHours
* - The amount of electricity in joules
*/
@Override
public void setJoules(double wattHours, Object... data)
{
if (data[0] instanceof ItemStack)
{
ItemStack itemStack = (ItemStack) data[0];
// Saves the frequency in the itemstack
if (itemStack.stackTagCompound == null)
{
itemStack.setTagCompound(new NBTTagCompound());
}
double electricityStored = Math.max(Math.min(wattHours, this.getMaxJoules()), 0);
itemStack.stackTagCompound.setDouble("electricity", electricityStored);
itemStack.setItemDamage((int) (getMaxJoules() - electricityStored));
}
}
/**
* This function is called to get the electricity stored in this item
*
* @return - The amount of electricity stored in watts
*/
@Override
public double getJoules(Object... data)
{
if (data[0] instanceof ItemStack)
{
ItemStack itemStack = (ItemStack) data[0];
if (itemStack.stackTagCompound == null) { return 0; }
double electricityStored = 0;
if (itemStack.stackTagCompound.getTag("electricity") instanceof NBTTagFloat)
{
electricityStored = itemStack.stackTagCompound.getFloat("electricity");
}
else
{
electricityStored = itemStack.stackTagCompound.getDouble("electricity");
}
itemStack.setItemDamage((int) (getMaxJoules() - electricityStored));
return electricityStored;
}
return -1;
}
/**
* Returns an uncharged version of the electric item. Use this if you want
* the crafting recipe to use a charged version of the electric item instead
* of an empty version of the electric item
*
* @return The ItemStack of a fully charged electric item
*/
public ItemStack getUncharged()
{
ItemStack chargedItem = new ItemStack(this);
chargedItem.setItemDamage((int) this.getMaxJoules());
return chargedItem;
}
public static ItemStack getUncharged(ItemStack itemStack)
{
if(itemStack.getItem() instanceof IItemElectric)
{
ItemStack chargedItem = itemStack.copy();
chargedItem.setItemDamage((int)((IItemElectric)itemStack.getItem()).getMaxJoules());
return chargedItem;
}
return null;
}
@Override
public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
// Add an uncharged version of the electric item
ItemStack unchargedItem = new ItemStack(this, 1);
unchargedItem.setItemDamage((int) this.getMaxJoules());
par3List.add(unchargedItem);
// Add an electric item to the creative list that is fully charged
ItemStack chargedItem = new ItemStack(this, 1);
this.setJoules(((IItemElectric) chargedItem.getItem()).getMaxJoules(), chargedItem);
par3List.add(chargedItem);
}
}

View file

@ -0,0 +1,96 @@
package universalelectricity.prefab;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.CraftingManager;
import net.minecraft.src.IRecipe;
import net.minecraft.src.ItemStack;
import net.minecraftforge.common.Configuration;
import universalelectricity.core.UEConfig;
import cpw.mods.fml.common.registry.GameRegistry;
/**
* This class is used to replace recipes that are already added in the existing
* recipe pool for crafting and smelting. All recipe functions take account of
* the Forge Ore Dictionary. It also includes some recipe helper functions to
* shorten some of your function calls.
*
* @author Calclavia
*
*/
public class RecipeHelper
{
public static List<IRecipe> getRecipesByOutput(ItemStack output)
{
List<IRecipe> list = new ArrayList<IRecipe>();
for (Object obj : CraftingManager.getInstance().getRecipeList())
{
if (obj instanceof IRecipe)
{
if (((IRecipe) obj).getRecipeOutput() == output)
{
list.add((IRecipe)obj);
}
}
}
return list;
}
public static boolean replaceRecipe(IRecipe recipe, IRecipe newRecipe)
{
for (Object obj : CraftingManager.getInstance().getRecipeList())
{
if (obj instanceof IRecipe)
{
if (((IRecipe) obj).equals(recipe) || obj == recipe)
{
CraftingManager.getInstance().getRecipeList().remove(obj);
CraftingManager.getInstance().getRecipeList().add(newRecipe);
return true;
}
}
}
return false;
}
public static boolean removeRecipe(IRecipe recipe)
{
for (Object obj : CraftingManager.getInstance().getRecipeList())
{
if (obj instanceof IRecipe)
{
if (((IRecipe) obj).equals(recipe) || obj == recipe)
{
CraftingManager.getInstance().getRecipeList().remove(obj);
return true;
}
}
}
return false;
}
/**
* Use this function if you want to check if the recipe is allowed in the
* configuration file.
*/
public static void addRecipe(IRecipe recipe, String name, Configuration config, boolean defaultBoolean)
{
if (config != null)
{
if (UEConfig.getConfigData(config, "Allow " + name + " Crafting", defaultBoolean))
{
GameRegistry.addRecipe(recipe);
}
}
}
public static void addRecipe(IRecipe recipe, Configuration config, boolean defaultBoolean)
{
addRecipe(recipe, recipe.getRecipeOutput().getItemName(), config, defaultBoolean);
}
}

View file

@ -0,0 +1,31 @@
package universalelectricity.prefab;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Slot;
import universalelectricity.implement.IItemElectric;
/**
* This slot should be used by any container that needs the slot for an electric
* items only.
*
* @author Calclavia
*
*/
public class SlotElectricItem extends Slot
{
public SlotElectricItem(IInventory par2IInventory, int par3, int par4, int par5)
{
super(par2IInventory, par3, par4, par5);
}
/**
* Check if the stack is a valid item for this slot. Always true beside for
* the armor slots.
*/
@Override
public boolean isItemValid(ItemStack par1ItemStack)
{
return par1ItemStack.getItem() instanceof IItemElectric;
}
}

View file

@ -0,0 +1,60 @@
package universalelectricity.prefab;
import net.minecraft.src.Block;
import net.minecraft.src.TileEntity;
/**
* A TileEntity with some pre-added functionalities.
*
* @author Calclavia
*
*/
public abstract class TileEntityAdvanced extends TileEntity
{
protected long ticks = 0;
@Override
public void updateEntity()
{
if (this.ticks == 0)
{
this.initiate();
}
if (this.ticks >= Long.MAX_VALUE)
{
this.ticks = 1;
}
this.ticks++;
}
/**
* Called on the TileEntity's first tick.
*/
protected void initiate()
{
}
@Override
public int getBlockMetadata()
{
if (this.blockMetadata == -1)
{
this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
}
return this.blockMetadata;
}
@Override
public Block getBlockType()
{
if (this.blockType == null)
{
this.blockType = Block.blocksList[this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord)];
}
return this.blockType;
}
}

View file

@ -0,0 +1,47 @@
package universalelectricity.prefab;
import universalelectricity.implement.IDisableable;
/**
* An easier way to implement the methods from IElectricityDisableable with
* default values set.
*
* @author Calclavia
*/
public abstract class TileEntityDisableable extends TileEntityAdvanced implements IDisableable
{
protected int disabledTicks = 0;
@Override
public void updateEntity()
{
super.updateEntity();
if (this.disabledTicks > 0)
{
this.disabledTicks--;
this.whileDisable();
return;
}
}
/**
* Called every tick while this tile entity is disabled.
*/
protected void whileDisable()
{
}
@Override
public void onDisable(int duration)
{
this.disabledTicks = duration;
}
@Override
public boolean isDisabled()
{
return this.disabledTicks > 0;
}
}

View file

@ -0,0 +1,36 @@
package universalelectricity.prefab;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.implement.IElectricityReceiver;
/**
* An easier way to implement the methods from IElectricityReceiver with default
* values set.
*
* @author Calclavia
*/
public abstract class TileEntityElectricityReceiver extends TileEntityDisableable implements IElectricityReceiver
{
public TileEntityElectricityReceiver()
{
super();
}
@Override
public void updateEntity()
{
super.updateEntity();
}
@Override
public boolean canConnect(ForgeDirection side)
{
return this.canReceiveFromSide(side);
}
@Override
public double getVoltage()
{
return 120;
}
}

View file

@ -0,0 +1,15 @@
package universalelectricity.prefab.network;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.Packet250CustomPayload;
import com.google.common.io.ByteArrayDataInput;
public interface IPacketReceiver
{
/**
* Sends some data to the tile entity.
*/
public void handlePacketData(INetworkManager network, int packetType, Packet250CustomPayload packet, EntityPlayer player, ByteArrayDataInput dataStream);
}

View file

@ -0,0 +1,266 @@
package universalelectricity.prefab.network;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import universalelectricity.core.Vector3;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
/**
* This class is used for sending and receiving packets between the server and
* the client. You can directly use this by registering this packet manager with
* NetworkMod. Example:
*
* @NetworkMod(channels = { "BasicComponents" }, clientSideRequired = true,
* serverSideRequired = false, packetHandler =
* PacketManager.class)
*
* Check out {@link #BasicComponents} for better reference.
*
* @author Calclavia
*/
public class PacketManager implements IPacketHandler, IPacketReceiver
{
public enum PacketType
{
UNSPECIFIED, TILEENTITY;
public static PacketType get(int id)
{
if (id >= 0 && id < PacketType.values().length) { return PacketType.values()[id]; }
return UNSPECIFIED;
}
}
public static 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 static Packet getPacket(String channelName, Object... sendData)
{
return getPacketWithID(channelName, PacketType.UNSPECIFIED.ordinal(), sendData);
}
/**
* Gets a packet for the tile entity.
*
* @return
*/
public static Packet getPacket(String channelName, TileEntity sender, Object... sendData)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try
{
data.writeInt(PacketType.TILEENTITY.ordinal());
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 static 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 static 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 static void sendPacketToClients(Packet packet)
{
try
{
if (FMLCommonHandler.instance().getMinecraftServerInstance() != null)
{
FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().sendPacketToAllPlayers(packet);
}
}
catch (Exception e)
{
System.out.println("Sending packet to client failed.");
e.printStackTrace();
}
}
public static DataOutputStream encodeDataStream(DataOutputStream data, Object... sendData)
{
try
{
for (Object dataValue : sendData)
{
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);
}
}
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();
PacketType packetType = PacketType.get(packetTypeID);
if (packetType == PacketType.TILEENTITY)
{
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)
{
if (tileEntity instanceof IPacketReceiver)
{
((IPacketReceiver) tileEntity).handlePacketData(network, packetTypeID, packet, ((EntityPlayer) 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)
{
}
}