package mekanism.generators.common.tile;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import mekanism.api.Coord4D;
import mekanism.api.MekanismConfig.generators;
import mekanism.common.base.IBoundingBlock;
import mekanism.common.util.ChargeUtils;
import mekanism.common.util.MekanismUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityWindGenerator extends TileEntityGenerator implements IBoundingBlock
{
public static final float SPEED = 32F;
public static final float SPEED_SCALED = 256F/SPEED;
/** The angle the blades of this Wind Turbine are currently at. */
public double angle;
public float currentMultiplier;
public TileEntityWindGenerator()
{
super("wind", "WindGenerator", 200000, (generators.windGenerationMax)*2);
inventory = new ItemStack[1];
}
@Override
public void onUpdate()
{
super.onUpdate();
if(!worldObj.isRemote)
{
ChargeUtils.charge(0, this);
if(ticker % 20 == 0)
{
setActive((currentMultiplier = getMultiplier()) > 0);
}
if(getActive())
{
setEnergy(electricityStored + (generators.windGenerationMin*currentMultiplier));
}
}
else {
if(getActive())
{
angle = (angle+(getPos().getY()+4F)/SPEED_SCALED) % 360;
}
}
}
@Override
public void handlePacketData(ByteBuf dataStream)
{
super.handlePacketData(dataStream);
if(worldObj.isRemote)
{
currentMultiplier = dataStream.readFloat();
}
}
@Override
public ArrayList getNetworkedData(ArrayList data)
{
super.getNetworkedData(data);
data.add(currentMultiplier);
return data;
}
/** Determines the current output multiplier, taking sky visibility and height into account. **/
public float getMultiplier()
{
if(worldObj.canSeeSky(getPos().add(0, 4, 0)))
{
final float minY = (float)generators.windGenerationMinY;
final float maxY = (float)generators.windGenerationMaxY;
final float minG = (float)generators.windGenerationMin;
final float maxG = (float)generators.windGenerationMax;
final float slope = (maxG - minG) / (maxY - minY);
final float intercept = minG - slope * minY;
final float clampedY = Math.min(maxY, Math.max(minY, (float)(getPos().getY()+4)));
final float toGen = slope * clampedY + intercept;
return toGen / minG;
}
else {
return 0;
}
}
@Override
@SideOnly(Side.CLIENT)
public float getVolume()
{
return 1.5F*super.getVolume();
}
private static final String[] methods = new String[] {"getEnergy", "getOutput", "getMaxEnergy", "getEnergyNeeded", "getMultiplier"};
@Override
public String[] getMethods()
{
return methods;
}
@Override
public Object[] invoke(int method, Object[] arguments) throws Exception
{
switch(method)
{
case 0:
return new Object[] {electricityStored};
case 1:
return new Object[] {output};
case 2:
return new Object[] {BASE_MAX_ENERGY};
case 3:
return new Object[] {(BASE_MAX_ENERGY -electricityStored)};
case 4:
return new Object[] {getMultiplier()};
default:
throw new NoSuchMethodException();
}
}
@Override
public boolean canOperate()
{
return electricityStored < BASE_MAX_ENERGY && getMultiplier() > 0 && MekanismUtils.canFunction(this);
}
@Override
public void onPlace()
{
Coord4D current = Coord4D.get(this);
MekanismUtils.makeBoundingBlock(worldObj, getPos().offset(EnumFacing.UP, 1), current);
MekanismUtils.makeBoundingBlock(worldObj, getPos().offset(EnumFacing.UP, 2), current);
MekanismUtils.makeBoundingBlock(worldObj, getPos().offset(EnumFacing.UP, 3), current);
MekanismUtils.makeBoundingBlock(worldObj, getPos().offset(EnumFacing.UP, 4), current);
}
@Override
public void onBreak()
{
worldObj.setBlockToAir(getPos().add(0, 1, 0));
worldObj.setBlockToAir(getPos().add(0, 2, 0));
worldObj.setBlockToAir(getPos().add(0, 3, 0));
worldObj.setBlockToAir(getPos().add(0, 4, 0));
worldObj.setBlockToAir(getPos());
}
@Override
public boolean renderUpdate()
{
return false;
}
@Override
public boolean lightUpdate()
{
return false;
}
}