IC2 rework to avoid a coremod or @Optional (#3034)

* IC2 rework to avoid a coremod or @Optional

Updated IC2 dependency

Refactored IC2 itemcharging to use an IBackupElectricManager.
Allows charging any ae powered item by using an IBackupElectricManager
instead of having to implement IElectricItem and stripping it by some
sort.

Updated IAEItemPowerStorage to use Actionable for an easier handling
with power APIs supporting a simulation.

Refactored EU P2P to avoid method stripping
Use a modified internal BasicSinkSource instead of implementing
IEnergySource and IEnergySink directly on the tunnel.

Removed the superfluous EU P2P layers.

* Removed internalBattery due to being too complex

* Creative Energy Cell is not a chargeable item
This commit is contained in:
yueh
2017-08-17 17:35:34 +02:00
committed by GitHub
parent 630fae3f73
commit 4f9fd1b369
23 changed files with 559 additions and 993 deletions
@@ -1,204 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.layers;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergyEmitter;
import ic2.api.energy.tile.IEnergySink;
import ic2.api.energy.tile.IEnergyTile;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.LayerBase;
import appeng.api.parts.LayerFlags;
import appeng.util.Platform;
public class LayerIEnergySink extends LayerBase implements IEnergySink
{
private TileEntity getEnergySinkTile()
{
IPartHost host = (IPartHost) this;
return host.getTile();
}
private World getEnergySinkWorld()
{
if( this.getEnergySinkTile() == null )
{
return null;
}
return this.getEnergySinkTile().getWorld();
}
private boolean isTileValid()
{
TileEntity te = this.getEnergySinkTile();
if( te == null )
{
return false;
}
return !te.isInvalid() && te.getWorld().isBlockLoaded( te.getPos() );
}
private void addToENet()
{
if( this.getEnergySinkWorld() == null )
{
return;
}
// re-add
this.removeFromENet();
if( !this.isInIC2() && Platform.isServer() && this.isTileValid() )
{
this.getLayerFlags().add( LayerFlags.IC2_ENET );
MinecraftForge.EVENT_BUS.post( new ic2.api.energy.event.EnergyTileLoadEvent( (IEnergyTile) this.getEnergySinkTile() ) );
}
}
private void removeFromENet()
{
if( this.getEnergySinkWorld() == null )
{
return;
}
if( this.isInIC2() && Platform.isServer() )
{
this.getLayerFlags().remove( LayerFlags.IC2_ENET );
MinecraftForge.EVENT_BUS.post( new ic2.api.energy.event.EnergyTileUnloadEvent( (IEnergyTile) this.getEnergySinkTile() ) );
}
}
private boolean interestedInIC2()
{
if( !( (IPartHost) this ).isInWorld() )
{
return false;
}
int interested = 0;
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergyTile )
{
interested++;
}
}
return interested == 1;// if more then one tile is interested we need to abandon...
}
@Override
public void partChanged()
{
super.partChanged();
if( this.interestedInIC2() )
{
this.addToENet();
}
else
{
this.removeFromENet();
}
}
@Override
public boolean acceptsEnergyFrom( IEnergyEmitter emitter, EnumFacing direction )
{
if( !this.isInIC2() )
{
return false;
}
IPart part = this.getPart( direction );
if( part instanceof IEnergySink )
{
return ( (IEnergyAcceptor) part ).acceptsEnergyFrom( emitter, direction );
}
return false;
}
private boolean isInIC2()
{
return this.getLayerFlags().contains( LayerFlags.IC2_ENET );
}
@Override
public double getDemandedEnergy()
{
if( !this.isInIC2() )
{
return 0;
}
// this is a flawed implementation, that requires a change to the IC2 API.
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergySink )
{
// use lower number cause ic2 deletes power it sends that isn't received.
return ( (IEnergySink) part ).getDemandedEnergy();
}
}
return 0;
}
@Override
public int getSinkTier()
{
return Integer.MAX_VALUE; // no real options here...
}
@Override
public double injectEnergy( EnumFacing directionFrom, double amount, double voltage )
{
if( !this.isInIC2() )
{
return amount;
}
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergySink )
{
return ( (IEnergySink) part ).injectEnergy( directionFrom, amount, voltage );
}
}
return amount;
}
}
@@ -1,205 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.layers;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergyEmitter;
import ic2.api.energy.tile.IEnergySource;
import ic2.api.energy.tile.IEnergyTile;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.LayerBase;
import appeng.api.parts.LayerFlags;
import appeng.util.Platform;
public class LayerIEnergySource extends LayerBase implements IEnergySource
{
private TileEntity getEnergySourceTile()
{
IPartHost host = (IPartHost) this;
return host.getTile();
}
private World getEnergySourceWorld()
{
if( this.getEnergySourceTile() == null )
{
return null;
}
return this.getEnergySourceTile().getWorld();
}
private boolean isTileValid()
{
TileEntity te = this.getEnergySourceTile();
return te != null && !te.isInvalid();
}
private void addToENet()
{
if( this.getEnergySourceWorld() == null )
{
return;
}
// re-add
this.removeFromENet();
if( !this.isInIC2() && Platform.isServer() && this.isTileValid() )
{
this.getLayerFlags().add( LayerFlags.IC2_ENET );
MinecraftForge.EVENT_BUS.post( new ic2.api.energy.event.EnergyTileLoadEvent( (IEnergyTile) this.getEnergySourceTile() ) );
}
}
private void removeFromENet()
{
if( this.getEnergySourceWorld() == null )
{
return;
}
if( this.isInIC2() && Platform.isServer() )
{
this.getLayerFlags().remove( LayerFlags.IC2_ENET );
MinecraftForge.EVENT_BUS.post( new ic2.api.energy.event.EnergyTileUnloadEvent( (IEnergyTile) this.getEnergySourceTile() ) );
}
}
private boolean interestedInIC2()
{
if( !( (IPartHost) this ).isInWorld() )
{
return false;
}
int interested = 0;
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergyTile )
{
interested++;
}
}
return interested == 1;// if more then one tile is interested we need to abandon...
}
@Override
public void partChanged()
{
super.partChanged();
if( this.interestedInIC2() )
{
this.addToENet();
}
else
{
this.removeFromENet();
}
}
@Override
public boolean emitsEnergyTo( IEnergyAcceptor receiver, EnumFacing direction )
{
if( !this.isInIC2() )
{
return false;
}
IPart part = this.getPart( direction );
if( part instanceof IEnergyEmitter )
{
return ( (IEnergyEmitter) part ).emitsEnergyTo( receiver, direction );
}
return false;
}
private boolean isInIC2()
{
return this.getLayerFlags().contains( LayerFlags.IC2_ENET );
}
@Override
public double getOfferedEnergy()
{
if( !this.isInIC2() )
{
return 0;
}
// this is a flawed implementation, that requires a change to the IC2 API.
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergySource )
{
// use lower number cause ic2 deletes power it sends that isn't received.
return ( (IEnergySource) part ).getOfferedEnergy();
}
}
return 0;
}
@Override
public void drawEnergy( double amount )
{
// this is a flawed implementation, that requires a change to the IC2 API.
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergySource )
{
( (IEnergySource) part ).drawEnergy( amount );
return;
}
}
}
@Override
public int getSourceTier()
{
// this is a flawed implementation, that requires a change to the IC2 API.
for( EnumFacing dir : EnumFacing.values() )
{
IPart part = this.getPart( dir );
if( part instanceof IEnergySource )
{
return ( (IEnergySource) part ).getSourceTier();
}
}
return 0;
}
}
@@ -25,28 +25,22 @@ import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import ic2.api.energy.prefab.BasicSinkSource;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergyEmitter;
import ic2.api.energy.tile.IEnergySink;
import ic2.api.energy.tile.IEnergySource;
import appeng.api.config.PowerUnits;
import appeng.api.parts.IPartModel;
import appeng.coremod.annotations.Integration.Interface;
import appeng.coremod.annotations.Integration.InterfaceList;
import appeng.integration.IntegrationType;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.cache.helpers.TunnelCollection;
import appeng.util.Platform;
@InterfaceList( value = {
@Interface( iface = "ic2.api.energy.tile.IEnergySink", iname = IntegrationType.IC2 ),
@Interface( iface = "ic2.api.energy.tile.IEnergySource", iname = IntegrationType.IC2 )
} )
public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power> implements IEnergySink, IEnergySource
public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power>
{
private static final String TAG_BUFFERED_ENERGY_1 = "bufferedEnergy1";
@@ -56,18 +50,14 @@ public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power> implements I
private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_ic2" );
@PartModels
public static List<IPartModel> getModels()
{
return MODELS.getModels();
}
// Buffer the energy + voltage for two IC2 ENET packets
private double bufferedEnergy1;
private double bufferedVoltage1;
private double bufferedEnergy2;
private double bufferedVoltage2;
private BasicSinkSource sinkSource;
public PartP2PIC2Power( ItemStack is )
{
super( is );
@@ -96,162 +86,29 @@ public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power> implements I
@Override
public void onTunnelConfigChange()
{
this.updateSinkSource();
this.getHost().partChanged();
}
@Override
public void onTunnelNetworkChange()
{
this.updateSinkSource();
this.getHost().notifyNeighbors();
}
@Override
public boolean acceptsEnergyFrom( IEnergyEmitter emitter, EnumFacing direction )
public void removeFromWorld()
{
return !this.isOutput() && direction == this.getSide().getFacing();
super.removeFromWorld();
this.invalidateSinkSource();
}
@Override
public boolean emitsEnergyTo( IEnergyAcceptor receiver, EnumFacing direction )
public void addToWorld()
{
return this.isOutput() && direction == this.getSide().getFacing();
}
@Override
public double getDemandedEnergy()
{
if( this.isOutput() )
{
return 0;
}
try
{
for( PartP2PIC2Power t : this.getOutputs() )
{
if( t.bufferedEnergy1 <= 0.0001 || t.bufferedEnergy2 <= 0.0001 )
{
return 2048;
}
}
}
catch( GridAccessException e )
{
return 0;
}
return 0;
}
@Override
public int getSinkTier()
{
return 4;
}
@Override
public double injectEnergy( EnumFacing directionFrom, double amount, double voltage )
{
TunnelCollection<PartP2PIC2Power> outs;
try
{
outs = this.getOutputs();
}
catch( GridAccessException e )
{
return amount;
}
if( outs.isEmpty() )
{
return amount;
}
LinkedList<PartP2PIC2Power> options = new LinkedList<>();
for( PartP2PIC2Power o : outs )
{
if( o.bufferedEnergy1 <= 0.01 )
{
options.add( o );
}
}
if( options.isEmpty() )
{
for( PartP2PIC2Power o : outs )
{
if( o.bufferedEnergy2 <= 0.01 )
{
options.add( o );
}
}
}
if( options.isEmpty() )
{
for( PartP2PIC2Power o : outs )
{
options.add( o );
}
}
if( options.isEmpty() )
{
return amount;
}
PartP2PIC2Power x = Platform.pickRandom( options );
if( x != null && x.bufferedEnergy1 <= 0.001 )
{
this.queueTunnelDrain( PowerUnits.EU, amount );
x.bufferedEnergy1 = amount;
x.bufferedVoltage1 = voltage;
return 0;
}
if( x != null && x.bufferedEnergy2 <= 0.001 )
{
this.queueTunnelDrain( PowerUnits.EU, amount );
x.bufferedEnergy2 = amount;
x.bufferedVoltage2 = voltage;
return 0;
}
return amount;
}
@Override
public double getOfferedEnergy()
{
if( this.isOutput() )
{
return this.bufferedEnergy1;
}
return 0;
}
@Override
public void drawEnergy( double amount )
{
this.bufferedEnergy1 -= amount;
if( this.bufferedEnergy1 < 0.001 )
{
this.bufferedEnergy1 = this.bufferedEnergy2;
this.bufferedEnergy2 = 0;
this.bufferedVoltage1 = this.bufferedVoltage2;
this.bufferedVoltage2 = 0;
}
}
@Override
public int getSourceTier()
{
// Sadly IC2 doesn't support changing the tier once we're registered, so we
// go with the highest here... At this point it's somewhat unclear as to what effect
// this realistically has.
return 4;
super.addToWorld();
this.updateSinkSource();
}
@Override
@@ -260,4 +117,171 @@ public class PartP2PIC2Power extends PartP2PTunnel<PartP2PIC2Power> implements I
return MODELS.getModel( this.isPowered(), this.isActive() );
}
@PartModels
public static List<IPartModel> getModels()
{
return MODELS.getModels();
}
private void updateSinkSource()
{
if( this.sinkSource == null )
{
this.sinkSource = new SinkSource( this.getHost().getTile().getWorld(), this.getHost().getLocation().getPos(), 2048, 4, 4 );
}
this.sinkSource.update();
}
private void invalidateSinkSource()
{
if( this.sinkSource != null )
{
this.sinkSource.invalidate();
}
}
private class SinkSource extends BasicSinkSource
{
SinkSource( World world, BlockPos pos, int i, int j, int k )
{
super( world, pos, i, j, k );
}
@Override
public boolean emitsEnergyTo( IEnergyAcceptor receiver, EnumFacing side )
{
return PartP2PIC2Power.this.isOutput() && side == PartP2PIC2Power.this.getSide().getFacing();
}
@Override
public boolean acceptsEnergyFrom( IEnergyEmitter emitter, EnumFacing side )
{
return !PartP2PIC2Power.this.isOutput() && side == PartP2PIC2Power.this.getSide().getFacing();
}
@Override
public double getDemandedEnergy()
{
if( PartP2PIC2Power.this.isOutput() )
{
return 0;
}
try
{
for( PartP2PIC2Power t : PartP2PIC2Power.this.getOutputs() )
{
if( t.bufferedEnergy1 <= 0.0001 || t.bufferedEnergy2 <= 0.0001 )
{
return 2048;
}
}
}
catch( GridAccessException e )
{
return 0;
}
return 0;
}
@Override
public double injectEnergy( EnumFacing directionFrom, double amount, double voltage )
{
TunnelCollection<PartP2PIC2Power> outs;
try
{
outs = PartP2PIC2Power.this.getOutputs();
}
catch( GridAccessException e )
{
return amount;
}
if( outs.isEmpty() )
{
return amount;
}
LinkedList<PartP2PIC2Power> options = new LinkedList<>();
for( PartP2PIC2Power o : outs )
{
if( o.bufferedEnergy1 <= 0.01 )
{
options.add( o );
}
}
if( options.isEmpty() )
{
for( PartP2PIC2Power o : outs )
{
if( o.bufferedEnergy2 <= 0.01 )
{
options.add( o );
}
}
}
if( options.isEmpty() )
{
for( PartP2PIC2Power o : outs )
{
options.add( o );
}
}
if( options.isEmpty() )
{
return amount;
}
PartP2PIC2Power x = Platform.pickRandom( options );
if( x != null && x.bufferedEnergy1 <= 0.001 )
{
PartP2PIC2Power.this.queueTunnelDrain( PowerUnits.EU, amount );
x.bufferedEnergy1 = amount;
x.bufferedVoltage1 = voltage;
return 0;
}
if( x != null && x.bufferedEnergy2 <= 0.001 )
{
PartP2PIC2Power.this.queueTunnelDrain( PowerUnits.EU, amount );
x.bufferedEnergy2 = amount;
x.bufferedVoltage2 = voltage;
return 0;
}
return amount;
}
@Override
public double getOfferedEnergy()
{
if( PartP2PIC2Power.this.isOutput() )
{
return PartP2PIC2Power.this.bufferedEnergy1;
}
return 0;
}
@Override
public void drawEnergy( double amount )
{
PartP2PIC2Power.this.bufferedEnergy1 -= amount;
if( PartP2PIC2Power.this.bufferedEnergy1 < 0.001 )
{
PartP2PIC2Power.this.bufferedEnergy1 = PartP2PIC2Power.this.bufferedEnergy2;
PartP2PIC2Power.this.bufferedEnergy2 = 0;
PartP2PIC2Power.this.bufferedVoltage1 = PartP2PIC2Power.this.bufferedVoltage2;
PartP2PIC2Power.this.bufferedVoltage2 = 0;
}
}
}
}