Package powercrystals.minefactoryreloaded.tile.base

Source Code of powercrystals.minefactoryreloaded.tile.base.TileEntityFactoryPowered

package powercrystals.minefactoryreloaded.tile.base;

import java.util.ArrayList;
import java.util.List;

import ic2.api.Direction;
import ic2.api.energy.event.EnergyTileLoadEvent;
import ic2.api.energy.event.EnergyTileUnloadEvent;
import ic2.api.energy.tile.IEnergySink;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.MinecraftForge;
import powercrystals.core.power.PowerProviderAdvanced;
import powercrystals.core.util.Util;
import powercrystals.core.util.UtilInventory;
import powercrystals.minefactoryreloaded.setup.Machine;
import universalelectricity.core.block.IConnector;
import universalelectricity.core.block.IVoltage;
import universalelectricity.core.electricity.ElectricityNetworkHelper;
import universalelectricity.core.electricity.ElectricityPack;
import buildcraft.api.power.IPowerProvider;
import buildcraft.api.power.IPowerReceptor;

/*
* There are three pieces of information tracked - energy, work, and idle ticks.
*
* Energy is stored and used when the machine activates. The energy stored must be >= energyActivation for the activateMachine() method to be called.
* If activateMachine() returns true, energy will be drained.
*
* Work is built up and then when at 100% something happens. This is tracked/used entirely by the derived class. If not used (f.ex. harvester), return max 1.
*
* Idle ticks cause an artificial delay before activateMachine() is called again. Max should be the highest value the machine will use, to draw the
* progress bar correctly.
*/

public abstract class TileEntityFactoryPowered extends TileEntityFactoryInventory implements IPowerReceptor, IEnergySink, IVoltage, IConnector
  public static final int energyPerEU = 4;
  public static final int energyPerMJ = 10;
  public static final int wPerEnergy = 7;
 
  private int _energyStored;
  protected int _energyActivation;
 
  protected int _energyRequiredThisTick = 0;
 
  private int _workDone;
 
  private int _idleTicks;
 
  protected List<ItemStack> failedDrops = null;
  private List<ItemStack> missedDrops = new ArrayList<ItemStack>();
 
  protected int _failedDropTicksMax = 20;
  private int _failedDropTicks = 0;
 
  // buildcraft-related fields
 
  private IPowerProvider _powerProvider;
 
  // IC2-related fields
 
  private boolean _isAddedToIC2EnergyNet;
  private boolean _addToNetOnNextTick;
 
  // UE-related fields
 
  private int _ueBuffer;
 
  // constructors
 
  protected TileEntityFactoryPowered(Machine machine)
  {
    this(machine, machine.getActivationEnergyMJ());
  }
 
  protected TileEntityFactoryPowered(Machine machine, int activationCostMJ)
  {
    super(machine);
    _energyActivation = activationCostMJ * energyPerMJ;
    _powerProvider = new PowerProviderAdvanced();
    configurePowerProvider();
    setIsActive(false);
  }
 
  // local methods
 
  private void configurePowerProvider()
  { // TODO: inline into constructor in 2.8
    int activation = getMaxEnergyPerTick() / energyPerMJ;
    int maxReceived = Math.min(activation * 20, 1000);
    _powerProvider.configure(0, activation < 10 ? 1 : 10, maxReceived, 1, 1000);
  }
 
  @Override
  public void updateEntity()
  {
    super.updateEntity();
   
    _energyStored = Math.min(_energyStored, getEnergyStoredMax());
   
    if(worldObj.isRemote)
    {
      return;
    }
   
    if(_addToNetOnNextTick)
    {
      if(!worldObj.isRemote)
      {
        MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
      }
      _addToNetOnNextTick = false;
      _isAddedToIC2EnergyNet = true;
    }
   
    int energyRequired = Math.min(getEnergyStoredMax() - getEnergyStored(), getMaxEnergyPerTick());
   
    if (energyRequired > 0)
    {
      IPowerProvider pp = getPowerProvider();
      bcpower: if(pp != null)
      {
        int mjRequired = energyRequired / energyPerMJ;
        if (mjRequired <= 0) break bcpower;
       
        pp.update(this);
       
        if(pp.useEnergy(0, mjRequired, false) > 0)
        {
          int mjGained = (int)(pp.useEnergy(0, mjRequired, true) * energyPerMJ);
          _energyStored += mjGained;
          energyRequired -= mjGained;
        }
      }
     
      ElectricityPack powerRequested = new ElectricityPack(energyRequired * wPerEnergy / getVoltage(), getVoltage());
      ElectricityPack powerPack = ElectricityNetworkHelper.consumeFromMultipleSides(this, powerRequested);
      _ueBuffer += powerPack.getWatts();
     
      int energyFromUE = Math.min(_ueBuffer / wPerEnergy, energyRequired);
      _energyStored += energyFromUE;
      energyRequired -= energyFromUE;
      _ueBuffer -= (energyFromUE * wPerEnergy);
    }
   
    _energyRequiredThisTick = energyRequired;
   
    setIsActive(_energyStored >= _energyActivation * 2);
   
    if (failedDrops != null)
    {
      if (_failedDropTicks < _failedDropTicksMax)
      {
        _failedDropTicks++;
        return;
      }
      _failedDropTicks = 0;
      if (!doDrop(failedDrops))
      {
        setIdleTicks(getIdleTicksMax());
        return;
      }
      failedDrops = null;
    }
   
    if(Util.isRedstonePowered(this))
    {
      setIdleTicks(getIdleTicksMax());
    }
    else if(_idleTicks > 0)
    {
      _idleTicks--;
    }
    else if(_energyStored >= _energyActivation)
    {
      if(activateMachine())
      {
        _energyStored -= _energyActivation;
      }
    }
  }

  public boolean doDrop(ItemStack drop)
  {
    drop = UtilInventory.dropStack(this, drop, this.getDropDirection());
    if (drop != null && drop.stackSize > 0)
    {
      if (failedDrops == null)
      {
        failedDrops = new ArrayList<ItemStack>();
      }
      failedDrops.add(drop);
    }
    return true;
  }
 
  public boolean doDrop(List<ItemStack> drops)
  {
    if (drops == null || drops.size() <= 0)
    {
      return true;
    }
    List<ItemStack> missed = missedDrops;
    missed.clear();
    for (int i = drops.size(); i --> 0; )
    {
      ItemStack dropStack = drops.get(i);
      dropStack = UtilInventory.dropStack(this, dropStack, this.getDropDirection());
      if (dropStack != null && dropStack.stackSize > 0)
      {
        missed.add(dropStack);
      }
    }
   
    if (missed.size() != 0)
    {
      if (drops != failedDrops)
      {
        if (failedDrops == null)
        {
          failedDrops = new ArrayList<ItemStack>();
        }
        failedDrops.addAll(missed);
      }
      else
      {
        failedDrops.clear();
        failedDrops.addAll(missed);
      }
      return false;
    }
   
    return true;
  }
 
  @Override
  public void validate()
  {
    super.validate();
    if(!_isAddedToIC2EnergyNet)
    {
      _addToNetOnNextTick = true;
    }
  }
 
  @Override
  public void invalidate()
  {
    if(_isAddedToIC2EnergyNet)
    {
      if(!worldObj.isRemote)
      {
        MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
      }
      _isAddedToIC2EnergyNet = false;
    }
    ElectricityNetworkHelper.invalidate(this);
    super.invalidate();
  }
 
  protected abstract boolean activateMachine();
 
  @Override
  public void onBlockBroken()
  {
    super.onBlockBroken();
    if(_isAddedToIC2EnergyNet)
    {
      _isAddedToIC2EnergyNet = false;
      MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
    }
  }
 
  public int getMaxEnergyPerTick()
  {
    return _energyActivation;
  }
 
  public int getEnergyStored()
  {
    return _energyStored;
  }
 
  public abstract int getEnergyStoredMax();
 
  public void setEnergyStored(int energy)
  {
    _energyStored = energy;
  }
 
  public int getWorkDone()
  {
    return _workDone;
  }
 
  public abstract int getWorkMax();
 
  public void setWorkDone(int work)
  {
    _workDone = work;
  }
 
  public int getIdleTicks()
  {
    return _idleTicks;
  }
 
  public abstract int getIdleTicksMax();
 
  public void setIdleTicks(int ticks)
  {
    _idleTicks = ticks;
  }
 
  @Override
  public void writeToNBT(NBTTagCompound tag)
  {
    super.writeToNBT(tag);
   
    tag.setInteger("energyStored", _energyStored);
    tag.setInteger("workDone", _workDone);
    tag.setInteger("ueBuffer", _ueBuffer);
    NBTTagCompound pp = new NBTTagCompound();
    _powerProvider.writeToNBT(pp);
    tag.setCompoundTag("powerProvider", pp);
   
    if (failedDrops != null)
    {
      NBTTagList nbttaglist = new NBTTagList();
      for (ItemStack item : failedDrops)
      {
        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
        item.writeToNBT(nbttagcompound1);
        nbttaglist.appendTag(nbttagcompound1);
      }
      tag.setTag("DropItems", nbttaglist);
    }
  }
 
  @Override
  public void readFromNBT(NBTTagCompound tag)
  {
    super.readFromNBT(tag);
   
    _energyStored = Math.min(tag.getInteger("energyStored"), getEnergyStoredMax());
    _workDone = Math.min(tag.getInteger("workDone"), getWorkMax());
    _ueBuffer = tag.getInteger("ueBuffer");
    if (tag.hasKey("powerProvider"))
    {
      _powerProvider.readFromNBT(tag.getCompoundTag("powerProvider"));
    }
    else // TODO: remove legacy code (below) in 2.8, losses from upgrades 2.6 or below acceptable
    {
      _powerProvider.readFromNBT(tag);
      configurePowerProvider();
      tag.removeTag("latency");
      tag.removeTag("minEnergyReceived");
      tag.removeTag("maxEnergyReceived");
      tag.removeTag("maxStoreEnergy");
      tag.removeTag("minActivationEnergy");
      tag.removeTag("storedEnergy");
    }

    if (tag.hasKey("DropItems"))
    {
      List<ItemStack> drops = new ArrayList<ItemStack>();
      NBTTagList nbttaglist = tag.getTagList("DropItems");
      for (int i = nbttaglist.tagCount(); i --> 0; )
      {
        NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
        ItemStack item = ItemStack.loadItemStackFromNBT(nbttagcompound1);
        if (item != null && item.stackSize > 0)
        {
          drops.add(item);
        }
      }
      if (drops.size() != 0)
      {
        failedDrops = drops;
      }
    }
  }
 
  public int getEnergyRequired()
  {
    return Math.min(getEnergyStoredMax() - getEnergyStored(), _energyRequiredThisTick);
  }
 
  // BC methods
 
  @Override
  public void setPowerProvider(IPowerProvider provider)
  {
    _powerProvider = provider;
  }
 
  @Override
  public IPowerProvider getPowerProvider()
  {
    return _powerProvider;
  }
 
  @Override
  public int powerRequest(ForgeDirection from)
  {
    int powerProviderPower = (int)Math.min(_powerProvider.getMaxEnergyStored() - _powerProvider.getEnergyStored(), _powerProvider.getMaxEnergyReceived());
    return Math.max(powerProviderPower, 0);
  }
 
  @Override
  public final void doWork()
  {
  }
 
  // IC2 methods
 
  @Override
  public int demandsEnergy()
  {
    return Math.max(getEnergyRequired() / energyPerEU, 0);
  }
 
  @Override
  public int injectEnergy(Direction directionFrom, int amount)
  {
    int euInjected = Math.max(Math.min(demandsEnergy(), amount), 0);
    int energyInjected = euInjected * energyPerEU;
    _energyStored += energyInjected;
    _energyRequiredThisTick -= energyInjected;
    return amount - euInjected;
  }
 
  @Override
  public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction)
  {
    return true;
  }
 
  @Override
  public boolean isAddedToEnergyNet()
  {
    return _isAddedToIC2EnergyNet;
  }
 
  @Override
  public int getMaxSafeInput()
  {
    return 128;
  }
 
  // UE Methods
 
  @Override
  public double getVoltage()
  {
    return 120;
  }
 
  @Override
  public boolean canConnect(ForgeDirection direction)
  {
    return true;
  }
}
TOP

Related Classes of powercrystals.minefactoryreloaded.tile.base.TileEntityFactoryPowered

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.