package micdoodle8.mods.galacticraft.core.energy.tile; import ic2.api.energy.tile.IEnergyEmitter; import ic2.api.energy.tile.IEnergyTile; import ic2.api.item.ElectricItem; import ic2.api.item.IElectricItem; import ic2.api.item.ISpecialElectricItem; import mekanism.api.energy.EnergizedItemManager; import mekanism.api.energy.IEnergizedItem; import micdoodle8.mods.galacticraft.api.item.ElectricItemHelper; import micdoodle8.mods.galacticraft.api.item.IItemElectric; import micdoodle8.mods.galacticraft.api.transmission.tile.IConductor; import micdoodle8.mods.galacticraft.api.transmission.tile.IElectrical; import micdoodle8.mods.galacticraft.core.energy.EnergyConfigHandler; import micdoodle8.mods.galacticraft.core.tile.ReceiverMode; import micdoodle8.mods.galacticraft.core.util.CompatibilityManager; import micdoodle8.mods.miccore.Annotations.RuntimeInterface; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.MathHelper; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.Event; import java.util.EnumSet; public abstract class TileBaseUniversalElectrical extends EnergyStorageTile { protected boolean isAddedToEnergyNet; protected Object powerHandlerBC; // @NetworkedField(targetSide = Side.CLIENT) // public float energyStored = 0; private float IC2surplusInGJ = 0F; @Override public double getPacketRange() { return 12.0D; } @Override public int getPacketCooldown() { return 3; } @Override public boolean isNetworkedTile() { return true; } public EnumSet<EnumFacing> getElectricalInputDirections() { return EnumSet.allOf(EnumFacing.class); } public EnumSet<EnumFacing> getElectricalOutputDirections() { return EnumSet.noneOf(EnumFacing.class); } @Override public float getRequest(EnumFacing direction) { if (this.getElectricalInputDirections().contains(direction) || direction == null) { return super.getRequest(direction); } return 0F; } @Override public float receiveElectricity(EnumFacing from, float receive, int tier, boolean doReceive) { if (this.getElectricalInputDirections().contains(from) || from == null) { return super.receiveElectricity(from, receive, tier, doReceive); } return 0F; } // @Override // public float receiveElectricity(EnumFacing from, ElectricityPack receive, boolean doReceive) // { // if (from == EnumFacing.UNKNOWN || this.getElectricalInputDirections().contains(from)) // { // if (!doReceive) // { // return this.getRequest(from); // } // // return this.receiveElectricity(receive, doReceive); // } // // return 0F; // } /** * A non-side specific version of receiveElectricity for you to optionally * use it internally. */ // public float receiveElectricity(ElectricityPack receive, boolean doReceive) // { // if (receive != null) // { // float prevEnergyStored = this.getEnergyStored(); // float newStoredEnergy = Math.min(this.getEnergyStored() + receive.getWatts(), this.getMaxEnergyStored()); // // if (doReceive) // { // this.setEnergyStored(newStoredEnergy); // } // // return Math.max(newStoredEnergy - prevEnergyStored, 0); // } // // return 0; // } // public float receiveElectricity(float energy, boolean doReceive) // { // return this.receiveElectricity(ElectricityPack.getFromWatts(energy, this.getVoltage()), doReceive); // } // @Override // public void setEnergyStored(float energy) // { // this.energyStored = Math.max(Math.min(energy, this.getMaxEnergyStored()), 0); // } // @Override // public float getEnergyStored() // { // return this.energyStored; // } // public boolean canConnect(EnumFacing direction, NetworkType type) // { // if (direction == null || direction.equals(EnumFacing.UNKNOWN) || type != NetworkType.POWER) // { // return false; // } // // return this.getElectricalInputDirections().contains(direction) || this.getElectricalOutputDirections().contains(direction); // } // @Override // public float getVoltage() // { // return 0.120F; // } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); // this.energyStored = nbt.getFloat("energyStored"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); // nbt.setFloat("energyStored", this.energyStored); } public void discharge(ItemStack itemStack) { if (itemStack != null) { Item item = itemStack.getItem(); float energyToDischarge = this.getRequest(null); if (item instanceof IItemElectric) { this.storage.receiveEnergyGC(ElectricItemHelper.dischargeItem(itemStack, energyToDischarge)); } // else if (EnergyConfigHandler.isRFAPILoaded() && item instanceof IEnergyContainerItem) // { // this.storage.receiveEnergyGC(((IEnergyContainerItem)item).extractEnergy(itemStack, (int) (energyToDischarge / EnergyConfigHandler.RF_RATIO), false) * EnergyConfigHandler.RF_RATIO); // } else if (EnergyConfigHandler.isMekanismLoaded() && item instanceof IEnergizedItem && ((IEnergizedItem) item).canSend(itemStack)) { this.storage.receiveEnergyGC((float) EnergizedItemManager.discharge(itemStack, energyToDischarge / EnergyConfigHandler.MEKANISM_RATIO) * EnergyConfigHandler.MEKANISM_RATIO); } else if (EnergyConfigHandler.isIndustrialCraft2Loaded()) { if (item instanceof ISpecialElectricItem) { ISpecialElectricItem electricItem = (ISpecialElectricItem) item; if (electricItem.canProvideEnergy(itemStack)) { double energyDischargeIC2 = energyToDischarge / EnergyConfigHandler.IC2_RATIO; double result = electricItem.getManager(itemStack).discharge(itemStack, energyDischargeIC2, 4, false, false, false); float energyDischarged = (float) result * EnergyConfigHandler.IC2_RATIO; this.storage.receiveEnergyGC(energyDischarged); } } else if (item instanceof IElectricItem) { IElectricItem electricItem = (IElectricItem) item; if (electricItem.canProvideEnergy(itemStack)) { double energyDischargeIC2 = energyToDischarge / EnergyConfigHandler.IC2_RATIO; double result = ElectricItem.manager.discharge(itemStack, energyDischargeIC2, 4, false, false, false); float energyDischarged = (float) result * EnergyConfigHandler.IC2_RATIO; this.storage.receiveEnergyGC(energyDischarged); } } } // else if (GCCoreCompatibilityManager.isTELoaded() && itemStack.getItem() instanceof IEnergyContainerItem) // { // float given = ((IEnergyContainerItem) itemStack.getItem()).extractEnergy(itemStack, (int) Math.floor(this.getRequest(EnumFacing.UNKNOWN) * EnergyConfigHandler.TO_TE_RATIO), false); // this.receiveElectricity(given * EnergyConfigHandler.TE_RATIO, true); // } } } @Override public void initiate() { super.initiate(); // if (EnergyConfigHandler.isBuildcraftLoaded()) // { // this.initBuildCraft(); // } TODO } @Override public void update() { super.update(); if (!this.worldObj.isRemote) { if (!this.isAddedToEnergyNet) { // Register to the IC2 Network this.initIC(); } if (EnergyConfigHandler.isIndustrialCraft2Loaded() && this.IC2surplusInGJ >= 0.001F) { this.IC2surplusInGJ -= this.storage.receiveEnergyGC(this.IC2surplusInGJ); if (this.IC2surplusInGJ < 0.001F) { this.IC2surplusInGJ = 0; } } // if (EnergyConfigHandler.isBuildcraftLoaded()) // { // if (this.powerHandlerBC == null) // { // this.initBuildCraft(); // } // // PowerHandler handler = (PowerHandler) this.powerHandlerBC; // // double energyBC = handler.getEnergyStored(); // if (energyBC > 0D) // { // float usedBC = this.storage.receiveEnergyGC((float) energyBC * EnergyConfigHandler.BC3_RATIO) / EnergyConfigHandler.BC3_RATIO; // energyBC -= usedBC; // if (energyBC < 0D) // { // energyBC = 0D; // } // handler.setEnergy(energyBC); // } // } TODO } } /** * IC2 Methods */ @Override public void invalidate() { this.unloadTileIC2(); super.invalidate(); } @Override public void onChunkUnload() { this.unloadTileIC2(); super.onChunkUnload(); } protected void initIC() { if (EnergyConfigHandler.isIndustrialCraft2Loaded()) { try { Object o = CompatibilityManager.classIC2tileEventLoad.getConstructor(IEnergyTile.class).newInstance(this); if (o instanceof Event) { MinecraftForge.EVENT_BUS.post((Event) o); } } catch (Exception e) { e.printStackTrace(); } } this.isAddedToEnergyNet = true; } private void unloadTileIC2() { if (this.isAddedToEnergyNet && this.worldObj != null) { if (EnergyConfigHandler.isIndustrialCraft2Loaded() && !this.worldObj.isRemote) { try { Object o = CompatibilityManager.classIC2tileEventUnload.getConstructor(IEnergyTile.class).newInstance(this); if (o instanceof Event) { MinecraftForge.EVENT_BUS.post((Event) o); } } catch (Exception e) { e.printStackTrace(); } } this.isAddedToEnergyNet = false; } } @RuntimeInterface(clazz = "ic2.api.energy.tile.IEnergySink", modID = "IC2") public double getDemandedEnergy() { if (EnergyConfigHandler.disableIC2Input) { return 0.0; } try { if (this.IC2surplusInGJ < 0.001F) { this.IC2surplusInGJ = 0F; return Math.ceil((this.storage.receiveEnergyGC(Integer.MAX_VALUE, true)) / EnergyConfigHandler.IC2_RATIO); } float received = this.storage.receiveEnergyGC(this.IC2surplusInGJ, true); if (received == this.IC2surplusInGJ) { return Math.ceil((this.storage.receiveEnergyGC(Integer.MAX_VALUE, true) - this.IC2surplusInGJ) / EnergyConfigHandler.IC2_RATIO); } } catch (Exception e) { e.printStackTrace(); } return 0D; } @RuntimeInterface(clazz = "ic2.api.energy.tile.IEnergySink", modID = "IC2") public double injectEnergy(EnumFacing direction, double amount, double voltage) { //IC2 in 1.8.9 seems to have reversed the sense of direction here, but not in acceptsEnergyFrom. (Seriously?!) if (!EnergyConfigHandler.disableIC2Input && (direction == null || this.getElectricalInputDirections().contains(direction.getOpposite()))) { float convertedEnergy = (float) amount * EnergyConfigHandler.IC2_RATIO; int tierFromIC2 = ((int) voltage > 120) ? (((int) voltage > 256) ? 4 : 2) : 1; float receive = this.receiveElectricity(direction == null ? null : direction.getOpposite(), convertedEnergy, tierFromIC2, true); if (convertedEnergy > receive) { this.IC2surplusInGJ = convertedEnergy - receive; } else { this.IC2surplusInGJ = 0F; } // injectEnergy returns left over energy but all is used or goes into 'surplus' return 0D; } return amount; } @RuntimeInterface(clazz = "ic2.api.energy.tile.IEnergySink", modID = "IC2") public int getSinkTier() { return 3; } @RuntimeInterface(clazz = "ic2.api.energy.tile.IEnergyAcceptor", modID = "IC2") public boolean acceptsEnergyFrom(IEnergyEmitter emitter, EnumFacing direction) { //Don't add connection to IC2 grid if it's a Galacticraft tile if (emitter instanceof IElectrical || emitter instanceof IConductor || !(emitter instanceof IEnergyTile)) { return false; } return this.getElectricalInputDirections().contains(direction); } @RuntimeInterface(clazz = "cofh.api.energy.IEnergyReceiver", modID = "") public int receiveEnergy(EnumFacing from, int maxReceive, boolean simulate) { if (EnergyConfigHandler.disableRFInput) { return 0; } if (!this.getElectricalInputDirections().contains(from)) { return 0; } return MathHelper.floor_float(super.receiveElectricity(from, maxReceive * EnergyConfigHandler.RF_RATIO, 1, !simulate) / EnergyConfigHandler.RF_RATIO); } @RuntimeInterface(clazz = "cofh.api.energy.IEnergyHandler", modID = "") public boolean canConnectEnergy(EnumFacing from) { return this.getElectricalInputDirections().contains(from) || this.getElectricalOutputDirections().contains(from); } @RuntimeInterface(clazz = "cofh.api.energy.IEnergyHandler", modID = "") public int getEnergyStored(EnumFacing from) { return MathHelper.floor_float(this.getEnergyStoredGC() / EnergyConfigHandler.RF_RATIO); } @RuntimeInterface(clazz = "cofh.api.energy.IEnergyHandler", modID = "") public int getMaxEnergyStored(EnumFacing from) { return MathHelper.floor_float(this.getMaxEnergyStoredGC() / EnergyConfigHandler.RF_RATIO); } @RuntimeInterface(clazz = "mekanism.api.energy.IStrictEnergyAcceptor", modID = "Mekanism") public double transferEnergyToAcceptor(EnumFacing from, double amount) { if (EnergyConfigHandler.disableMekanismInput) { return 0; } if (!this.getElectricalInputDirections().contains(from)) { return 0; } return this.receiveElectricity(from, (float) amount * EnergyConfigHandler.MEKANISM_RATIO, 1, true) / EnergyConfigHandler.MEKANISM_RATIO; } @RuntimeInterface(clazz = "mekanism.api.energy.IStrictEnergyAcceptor", modID = "Mekanism") public boolean canReceiveEnergy(EnumFacing side) { return this.getElectricalInputDirections().contains(side); } @RuntimeInterface(clazz = "mekanism.api.energy.IStrictEnergyAcceptor", modID = "Mekanism") public double getEnergy() { if (EnergyConfigHandler.disableMekanismInput) { return 0.0; } return this.getEnergyStoredGC() / EnergyConfigHandler.MEKANISM_RATIO; } @RuntimeInterface(clazz = "mekanism.api.energy.IStrictEnergyAcceptor", modID = "Mekanism") public void setEnergy(double energy) { if (EnergyConfigHandler.disableMekanismInput) { return; } this.storage.setEnergyStored((float) energy * EnergyConfigHandler.MEKANISM_RATIO); } @RuntimeInterface(clazz = "mekanism.api.energy.IStrictEnergyAcceptor", modID = "Mekanism") public double getMaxEnergy() { if (EnergyConfigHandler.disableMekanismInput) { return 0.0; } return this.getMaxEnergyStoredGC() / EnergyConfigHandler.MEKANISM_RATIO; } @RuntimeInterface(clazz = "mekanism.api.energy.ICableOutputter", modID = "Mekanism") public boolean canOutputTo(EnumFacing side) { return false; } @Override public ReceiverMode getModeFromDirection(EnumFacing direction) { if (this.getElectricalInputDirections().contains(direction)) { return ReceiverMode.RECEIVE; } else if (this.getElectricalOutputDirections().contains(direction)) { return ReceiverMode.EXTRACT; } return null; } /* * Compatibility: call this if the facing metadata is updated */ public void updateFacing() { if (EnergyConfigHandler.isIndustrialCraft2Loaded() && !this.worldObj.isRemote) { //This seems the only method to tell IC2 the connection sides have changed //(Maybe there is an internal refresh() method but it's not in the API) this.unloadTileIC2(); //This will do an initIC2 on next tick update. } } }