resonant-induction/mechanical/src/main/scala/resonantinduction/mechanical/process/mixer/TileMixer.java
2014-06-10 20:31:33 -04:00

284 lines
7 KiB
Java

package resonantinduction.mechanical.process.mixer;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.IFluidBlock;
import resonant.api.recipe.MachineRecipes;
import resonant.lib.utility.inventory.InventoryUtility;
import resonantinduction.core.Reference;
import resonantinduction.core.ResonantInduction.RecipeType;
import resonantinduction.core.Timer;
import resonantinduction.core.interfaces.IMechanicalNode;
import resonantinduction.core.resource.ResourceGenerator;
import resonantinduction.core.resource.fluid.BlockFluidMixture;
import resonantinduction.mechanical.energy.grid.MechanicalNode;
import resonantinduction.mechanical.energy.grid.TileMechanical;
import universalelectricity.api.vector.Vector3;
/**
* @author Calclavia
*/
public class TileMixer extends TileMechanical implements IInventory
{
public static final long POWER = 500000;
public static final int PROCESS_TIME = 12 * 20;
public static final Timer<EntityItem> timer = new Timer<EntityItem>();
private boolean areaBlockedFromMoving = false;
public TileMixer()
{
super(Material.iron);
mechanicalNode = new MixerNode(this).setConnection(Byte.parseByte("000011", 2));
isOpaqueCube = false;
normalRender = false;
customItemRender = true;
textureName = "material_metal_top";
}
@Override
public void updateEntity()
{
if (!world().isRemote && ticks % 20 == 0)
{
this.areaBlockedFromMoving = false;
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
if (x != 0 && z != 0)
{
int id = position().translate(x, 0, z).getBlockID(world());
Block block = Block.blocksList[id];
if (block != null && !(block instanceof IFluidBlock) && !(block instanceof BlockFluid))
{
this.areaBlockedFromMoving = true;
return;
}
}
}
}
}
super.updateEntity();
if (canWork())
{
doWork();
}
}
/**
* Can this machine work this tick?
*
* @return
*/
public boolean canWork()
{
return mechanicalNode.getAngularSpeed() != 0 && !areaBlockedFromMoving;
}
public void doWork()
{
boolean didWork = false;
// Search for an item to "process"
AxisAlignedBB aabb = AxisAlignedBB.getAABBPool().getAABB(this.xCoord - 1, this.yCoord, this.zCoord - 1, this.xCoord + 2, this.yCoord + 1, this.zCoord + 2);
List<Entity> entities = this.worldObj.getEntitiesWithinAABB(Entity.class, aabb);
Set<EntityItem> processItems = new LinkedHashSet<EntityItem>();
for (Entity entity : entities)
{
/**
* Rotate entities around the mixer
*/
Vector3 originalPosition = new Vector3(entity);
Vector3 relativePosition = originalPosition.clone().subtract(new Vector3(this).add(0.5));
relativePosition.rotate(-mechanicalNode.getAngularSpeed(), 0, 0);
Vector3 newPosition = new Vector3(this).add(0.5).add(relativePosition);
Vector3 difference = newPosition.difference(originalPosition).scale(0.5);
entity.addVelocity(difference.x, difference.y, difference.z);
entity.onGround = false;
if (entity instanceof EntityItem)
{
if (MachineRecipes.INSTANCE.getOutput(RecipeType.MIXER.name(), ((EntityItem) entity).getEntityItem()).length > 0)
{
processItems.add((EntityItem) entity);
}
}
}
for (EntityItem processingItem : processItems)
{
if (!timer.containsKey(processingItem))
{
timer.put(processingItem, PROCESS_TIME);
}
if (!processingItem.isDead && new Vector3(this).add(0.5).distance(processingItem) < 2)
{
int timeLeft = timer.decrease(processingItem);
if (timeLeft <= 0)
{
if (doneWork(processingItem))
{
if (--processingItem.getEntityItem().stackSize <= 0)
{
processingItem.setDead();
timer.remove(processingItem);
}
else
{
processingItem.setEntityItemStack(processingItem.getEntityItem());
// Reset timer
timer.put(processingItem, PROCESS_TIME);
}
}
}
else
{
processingItem.delayBeforeCanPickup = 20;
this.worldObj.spawnParticle("bubble", processingItem.posX, processingItem.posY, processingItem.posZ, (Math.random() - 0.5f) * 3, (Math.random() - 0.5f) * 3, (Math.random() - 0.5f) * 3);
}
didWork = true;
}
else
{
timer.remove(processingItem);
}
}
if (didWork)
{
if (this.ticks % 20 == 0)
{
this.worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, Reference.PREFIX + "mixer", 0.5f, 1);
}
}
}
private boolean doneWork(EntityItem entity)
{
Vector3 mixPosition = new Vector3(entity.posX, yCoord, entity.posZ);
if (mixPosition.getBlockID(world()) != blockID())
{
Block block = Block.blocksList[mixPosition.getBlockID(worldObj)];
Block blockFluidFinite = ResourceGenerator.getMixture(ResourceGenerator.getName(entity.getEntityItem()));
if (blockFluidFinite != null)
{
if (block instanceof BlockFluidMixture)
{
ItemStack itemStack = entity.getEntityItem().copy();
if (((BlockFluidMixture) block).mix(worldObj, mixPosition.intX(), mixPosition.intY(), mixPosition.intZ(), itemStack))
{
worldObj.notifyBlocksOfNeighborChange(mixPosition.intX(), mixPosition.intY(), mixPosition.intZ(), mixPosition.getBlockID(worldObj));
return true;
}
}
else if (block != null && (block.blockID == Block.waterStill.blockID || block.blockID == Block.waterMoving.blockID))
{
mixPosition.setBlock(worldObj, blockFluidFinite.blockID);
}
}
}
return false;
}
@Override
public int getSizeInventory()
{
return 1;
}
@Override
public ItemStack getStackInSlot(int i)
{
return null;
}
@Override
public ItemStack decrStackSize(int i, int j)
{
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
if (!worldObj.isRemote)
{
Vector3 spawnVector = new Vector3(this).translate(ForgeDirection.getOrientation(worldObj.rand.nextInt(4) + 2)).translate(0.5);
InventoryUtility.dropItemStack(worldObj, spawnVector, itemstack, 20, 0);
}
}
@Override
public String getInvName()
{
return null;
}
@Override
public boolean isInvNameLocalized()
{
return false;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return false;
}
@Override
public void openChest()
{
}
@Override
public void closeChest()
{
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return MachineRecipes.INSTANCE.getOutput(RecipeType.MIXER.name(), itemstack).length > 0;
}
}