diff --git a/src/api/java/appeng/api/networking/energy/IEnergyGridProvider.java b/src/api/java/appeng/api/networking/energy/IEnergyGridProvider.java index b24af8e3..d7e6d782 100644 --- a/src/api/java/appeng/api/networking/energy/IEnergyGridProvider.java +++ b/src/api/java/appeng/api/networking/energy/IEnergyGridProvider.java @@ -24,6 +24,7 @@ package appeng.api.networking.energy; +import java.util.Collection; import java.util.Set; import appeng.api.config.Actionable; @@ -37,15 +38,30 @@ public interface IEnergyGridProvider /** * internal use only */ - double extractAEPower( double amt, Actionable mode, Set seen ); + Collection providers(); /** * internal use only */ - double injectAEPower( double amt, Actionable mode, Set seen ); + double extractProviderPower( double amt, Actionable mode, Set seen ); /** * internal use only */ - double getEnergyDemand( double d, Set seen ); + double injectProviderPower( double amt, Actionable mode, Set seen ); + + /** + * internal use only + */ + double getProviderEnergyDemand( double d, Set seen ); + + /** + * internal use only + */ + double getProviderStoredEnergy(); + + /** + * internal use only + */ + double getProviderMaxEnergy(); } diff --git a/src/main/java/appeng/integration/modules/ic2/IC2PowerSinkAdapter.java b/src/main/java/appeng/integration/modules/ic2/IC2PowerSinkAdapter.java index 5672d952..b15740d4 100644 --- a/src/main/java/appeng/integration/modules/ic2/IC2PowerSinkAdapter.java +++ b/src/main/java/appeng/integration/modules/ic2/IC2PowerSinkAdapter.java @@ -28,6 +28,7 @@ import net.minecraft.util.EnumFacing; import ic2.api.energy.prefab.BasicSink; import ic2.api.energy.tile.IEnergyEmitter; +import appeng.api.config.Actionable; import appeng.api.config.PowerUnits; import appeng.integration.abstraction.IC2PowerSink; import appeng.tile.powersink.IExternalPowerSink; @@ -76,7 +77,7 @@ public class IC2PowerSinkAdapter extends BasicSink implements IC2PowerSink @Override public double injectEnergy( EnumFacing directionFrom, double amount, double voltage ) { - return PowerUnits.EU.convertTo( PowerUnits.AE, this.powerSink.injectExternalPower( PowerUnits.EU, amount ) ); + return PowerUnits.EU.convertTo( PowerUnits.AE, this.powerSink.injectExternalPower( PowerUnits.EU, amount, Actionable.MODULATE ) ); } @Override diff --git a/src/main/java/appeng/me/cache/EnergyGridCache.java b/src/main/java/appeng/me/cache/EnergyGridCache.java index 81d65528..7a191013 100644 --- a/src/main/java/appeng/me/cache/EnergyGridCache.java +++ b/src/main/java/appeng/me/cache/EnergyGridCache.java @@ -19,11 +19,16 @@ package appeng.me.cache; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.NavigableSet; +import java.util.PriorityQueue; +import java.util.Queue; import java.util.Set; import com.google.common.collect.HashMultiset; @@ -48,8 +53,8 @@ import appeng.api.networking.events.MENetworkPostCacheConstruction; import appeng.api.networking.events.MENetworkPowerIdleChange; import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.events.MENetworkPowerStorage; +import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType; import appeng.api.networking.pathing.IPathingGrid; -import appeng.api.networking.storage.IStackWatcherHost; import appeng.me.Grid; import appeng.me.GridNode; import appeng.me.energy.EnergyThreshold; @@ -59,6 +64,18 @@ import appeng.me.energy.EnergyWatcher; public class EnergyGridCache implements IEnergyGrid { + private static final double MAX_BUFFER_STORAGE = 200; + private static final Comparator COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), + o1.getProviderStoredEnergy() ); + + private static final Comparator COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> + { + final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 ); + final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 ); + + return Double.compare( percent1, percent2 ); + }; + private final NavigableSet interests = Sets.newTreeSet(); private final double averageLength = 40.0; private final Set providers = new LinkedHashSet<>(); @@ -66,13 +83,14 @@ public class EnergyGridCache implements IEnergyGrid private final Multiset energyGridProviders = HashMultiset.create(); private final IGrid myGrid; private final HashMap watchers = new HashMap<>(); - private final Set localSeen = new HashSet<>(); + /** * estimated power available. */ private int availableTicksSinceUpdate = 0; private double globalAvailablePower = 0; - private double globalMaxPower = 0; + private double globalMaxPower = MAX_BUFFER_STORAGE; + /** * idle draw. */ @@ -81,24 +99,25 @@ public class EnergyGridCache implements IEnergyGrid private double avgInjectionPerTick = 0; private double tickDrainPerTick = 0; private double tickInjectionPerTick = 0; + /** * power status */ private boolean publicHasPower = false; private boolean hasPower = true; private long ticksSinceHasPowerChange = 900; - /** - * excess power in the system. - */ - private double extra = 0; + private IAEPowerStorage lastProvider; private IAEPowerStorage lastRequester; private PathGridCache pgc; private double lastStoredPower = -1; + private final GridPowerStorage localStorage = new GridPowerStorage(); + public EnergyGridCache( final IGrid g ) { this.myGrid = g; + this.requesters.add( this.localStorage ); } @MENetworkEventSubscribe @@ -179,12 +198,12 @@ public class EnergyGridCache implements IEnergyGrid if( this.drainPerTick > 0.0001 ) { - final double drained = this.extractAEPower( this.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG ); + final double drained = this.localStorage.extractAEPower( this.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG ); currentlyHasPower = drained >= this.drainPerTick - 0.001; } else { - currentlyHasPower = this.extractAEPower( 0.1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0; + currentlyHasPower = this.localStorage.extractAEPower( 0.1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0; } // ticks since change.. @@ -216,8 +235,30 @@ public class EnergyGridCache implements IEnergyGrid @Override public double extractAEPower( final double amt, final Actionable mode, final PowerMultiplier pm ) { - this.localSeen.clear(); - return pm.divide( this.extractAEPower( pm.multiply( amt ), mode, this.localSeen ) ); + final double toExtract = pm.multiply( amt ); + final Queue toVisit = new PriorityQueue<>( COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST ); + final Set visited = new HashSet<>(); + + double extracted = 0; + toVisit.add( this ); + + while( !toVisit.isEmpty() && extracted < toExtract ) + { + final IEnergyGridProvider next = toVisit.poll(); + visited.add( next ); + + extracted += next.extractProviderPower( toExtract - extracted, mode, visited ); + + for( IEnergyGridProvider iEnergyGridProvider : next.providers() ) + { + if( !visited.contains( iEnergyGridProvider ) ) + { + toVisit.add( iEnergyGridProvider ); + } + } + } + + return pm.divide( extracted ); } @Override @@ -244,7 +285,7 @@ public class EnergyGridCache implements IEnergyGrid private void refreshPower() { this.availableTicksSinceUpdate = 0; - this.globalAvailablePower = 0; + this.globalAvailablePower = this.localStorage.getAECurrentPower(); for( final IAEPowerStorage p : this.providers ) { this.globalAvailablePower += p.getAECurrentPower(); @@ -252,55 +293,37 @@ public class EnergyGridCache implements IEnergyGrid } @Override - public double extractAEPower( final double amt, final Actionable mode, final Set seen ) + public Collection providers() { - if( !seen.add( this ) ) - { - return 0; - } + return this.energyGridProviders; + } - double extractedPower = this.extra; + @Override + public double extractProviderPower( final double amt, final Actionable mode, final Set seen ) + { + double extractedPower = 0; if( mode == Actionable.SIMULATE ) { extractedPower += this.simulateExtract( extractedPower, amt ); - if( extractedPower < amt ) - { - final Iterator i = this.energyGridProviders.iterator(); - while( extractedPower < amt && i.hasNext() ) - { - extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen ); - } - } - return extractedPower; } else { - this.extra = 0; extractedPower = this.doExtract( extractedPower, amt ); } // got more then we wanted? if( extractedPower > amt ) { - this.extra = extractedPower - amt; + this.localStorage.addAECurrentPower( extractedPower - amt ); this.globalAvailablePower -= amt; this.tickDrainPerTick += amt; return amt; } - if( extractedPower < amt ) - { - final Iterator i = this.energyGridProviders.iterator(); - while( extractedPower < amt && i.hasNext() ) - { - extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen ); - } - } - // go less or the correct amount? this.globalAvailablePower -= extractedPower; this.tickDrainPerTick += extractedPower; @@ -308,16 +331,8 @@ public class EnergyGridCache implements IEnergyGrid } @Override - public double injectAEPower( double amt, final Actionable mode, final Set seen ) + public double injectProviderPower( double amt, final Actionable mode, final Set seen ) { - if( !seen.add( this ) ) - { - return 0; - } - - final double ignore = this.extra; - amt += this.extra; - if( mode == Actionable.SIMULATE ) { final Iterator it = this.requesters.iterator(); @@ -327,16 +342,10 @@ public class EnergyGridCache implements IEnergyGrid amt = node.injectAEPower( amt, Actionable.SIMULATE ); } - final Iterator i = this.energyGridProviders.iterator(); - while( amt > 0 && i.hasNext() ) - { - amt = i.next().injectAEPower( amt, mode, seen ); - } } else { - this.tickInjectionPerTick += amt - ignore; - // totalInjectionPastTicks[0] += i; + this.tickInjectionPerTick += amt; while( amt > 0 && !this.requesters.isEmpty() ) { @@ -349,35 +358,15 @@ public class EnergyGridCache implements IEnergyGrid this.lastRequester = null; } } - - final Iterator i = this.energyGridProviders.iterator(); - while( amt > 0 && i.hasNext() ) - { - final IEnergyGridProvider what = i.next(); - final Set listCopy = new HashSet<>(); - listCopy.addAll( seen ); - - final double cannotHold = what.injectAEPower( amt, Actionable.SIMULATE, listCopy ); - what.injectAEPower( amt - cannotHold, mode, seen ); - - amt = cannotHold; - } - - this.extra = amt; } - return Math.max( 0.0, amt - this.buffer() ); + return Math.max( 0.0, amt ); } @Override - public double getEnergyDemand( final double maxRequired, final Set seen ) + public double getProviderEnergyDemand( final double maxRequired, final Set seen ) { - if( !seen.add( this ) ) - { - return 0; - } - - double required = this.buffer() - this.extra; + double required = 0; final Iterator it = this.requesters.iterator(); while( required < maxRequired && it.hasNext() ) @@ -389,13 +378,6 @@ public class EnergyGridCache implements IEnergyGrid } } - final Iterator ix = this.energyGridProviders.iterator(); - while( required < maxRequired && ix.hasNext() ) - { - final IEnergyGridProvider node = ix.next(); - required += node.getEnergyDemand( maxRequired - required, seen ); - } - return required; } @@ -432,7 +414,6 @@ public class EnergyGridCache implements IEnergyGrid } } - // totalDrainPastTicks[0] += extractedPower; return extractedPower; } @@ -468,8 +449,32 @@ public class EnergyGridCache implements IEnergyGrid @Override public double injectPower( final double amt, final Actionable mode ) { - this.localSeen.clear(); - return this.injectAEPower( amt, mode, this.localSeen ); + final Queue toVisit = new PriorityQueue<>( COMPARATOR_LOWEST_PERCENTAGE_FIRST ); + final Set visited = new HashSet<>(); + toVisit.add( this ); + + double leftover = this.localStorage.injectAEPower( amt, mode ); + + while( !toVisit.isEmpty() && leftover > 0 ) + { + final IEnergyGridProvider next = toVisit.poll(); + visited.add( next ); + + final double cannotHold = next.injectProviderPower( amt, Actionable.SIMULATE, visited ); + next.injectProviderPower( leftover - cannotHold, mode, visited ); + + leftover = cannotHold; + + for( IEnergyGridProvider iEnergyGridProvider : next.providers() ) + { + if( !visited.contains( iEnergyGridProvider ) ) + { + toVisit.add( iEnergyGridProvider ); + } + } + } + + return leftover; } private IAEPowerStorage getFirstRequester() @@ -483,11 +488,6 @@ public class EnergyGridCache implements IEnergyGrid return this.lastRequester; } - private double buffer() - { - return this.providers.isEmpty() ? 1000.0 : 0.0; - } - @Override public double getStoredPower() { @@ -508,8 +508,41 @@ public class EnergyGridCache implements IEnergyGrid @Override public double getEnergyDemand( final double maxRequired ) { - this.localSeen.clear(); - return this.getEnergyDemand( maxRequired, this.localSeen ); + final Queue toVisit = new ArrayDeque<>(); + final Set visited = new HashSet<>(); + toVisit.add( this ); + + double required = 0; + + while( !toVisit.isEmpty() && required < maxRequired ) + { + final IEnergyGridProvider next = toVisit.poll(); + visited.add( next ); + + required += next.getProviderEnergyDemand( maxRequired - required, visited ); + + for( IEnergyGridProvider iEnergyGridProvider : next.providers() ) + { + if( !visited.contains( iEnergyGridProvider ) ) + { + toVisit.add( iEnergyGridProvider ); + } + } + } + + return required; + } + + @Override + public double getProviderStoredEnergy() + { + return this.getStoredPower(); + } + + @Override + public double getProviderMaxEnergy() + { + return this.getMaxStoredPower(); } @Override @@ -517,7 +550,7 @@ public class EnergyGridCache implements IEnergyGrid { if( machine instanceof IEnergyGridProvider ) { - this.energyGridProviders.remove( machine ); + this.energyGridProviders.remove( (IEnergyGridProvider) machine ); } // idle draw. @@ -546,18 +579,19 @@ public class EnergyGridCache implements IEnergyGrid this.lastRequester = null; } - this.providers.remove( machine ); - this.requesters.remove( machine ); + this.providers.remove( ps ); + this.requesters.remove( ps ); } } - if( machine instanceof IStackWatcherHost ) + if( machine instanceof IEnergyWatcherHost ) { - final IEnergyWatcher myWatcher = this.watchers.get( machine ); - if( myWatcher != null ) + final IEnergyWatcher watcher = this.watchers.get( node ); + + if( watcher != null ) { - myWatcher.reset(); - this.watchers.remove( machine ); + watcher.reset(); + this.watchers.remove( node ); } } } @@ -607,6 +641,7 @@ public class EnergyGridCache implements IEnergyGrid { final IEnergyWatcherHost swh = (IEnergyWatcherHost) machine; final EnergyWatcher iw = new EnergyWatcher( this, swh ); + this.watchers.put( node, iw ); swh.updateWatcher( iw ); } @@ -617,20 +652,21 @@ public class EnergyGridCache implements IEnergyGrid @Override public void onSplit( final IGridStorage storageB ) { - this.extra /= 2; - storageB.dataObject().setDouble( "extraEnergy", this.extra ); + final double newBuffer = this.localStorage.getAECurrentPower() / 2; + this.localStorage.setAECurrentPower( newBuffer ); + storageB.dataObject().setDouble( "buffer", newBuffer ); } @Override public void onJoin( final IGridStorage storageB ) { - this.extra += storageB.dataObject().getDouble( "extraEnergy" ); + this.localStorage.addAECurrentPower( storageB.dataObject().getDouble( "buffer" ) ); } @Override public void populateGridStorage( final IGridStorage storage ) { - storage.dataObject().setDouble( "extraEnergy", this.extra ); + storage.dataObject().setDouble( "buffer", this.localStorage.getAECurrentPower() ); } public boolean registerEnergyInterest( final EnergyThreshold threshold ) @@ -643,4 +679,78 @@ public class EnergyGridCache implements IEnergyGrid return this.interests.remove( threshold ); } + private class GridPowerStorage implements IAEPowerStorage + { + double stored = 0; + + @Override + public double extractAEPower( double amt, Actionable mode, PowerMultiplier usePowerMultiplier ) + { + double extracted = Math.min( amt, this.stored ); + + if( mode == Actionable.MODULATE ) + { + this.stored -= extracted; + + if( this.stored < MAX_BUFFER_STORAGE - 0.001 ) + { + EnergyGridCache.this.myGrid.postEvent( new MENetworkPowerStorage( this, PowerEventType.REQUEST_POWER ) ); + } + } + + if( extracted < amt ) + { + extracted += EnergyGridCache.this.extractAEPower( amt - extracted, Actionable.MODULATE, PowerMultiplier.CONFIG ); + } + + return extracted; + } + + @Override + public boolean isAEPublicPowerStorage() + { + return true; + } + + @Override + public double injectAEPower( double amt, Actionable mode ) + { + double toStore = Math.min( amt, MAX_BUFFER_STORAGE - this.stored ); + + if( mode == Actionable.MODULATE ) + { + this.stored += toStore; + } + + return amt - toStore; + } + + @Override + public AccessRestriction getPowerFlow() + { + return AccessRestriction.READ_WRITE; + } + + @Override + public double getAEMaxPower() + { + return MAX_BUFFER_STORAGE; + } + + @Override + public double getAECurrentPower() + { + return this.stored; + } + + public void setAECurrentPower( double amount ) + { + this.stored = amount; + } + + public void addAECurrentPower( double amount ) + { + this.stored += amount; + } + } } diff --git a/src/main/java/appeng/parts/networking/PartQuartzFiber.java b/src/main/java/appeng/parts/networking/PartQuartzFiber.java index ae32fe5c..b7015fa8 100644 --- a/src/main/java/appeng/parts/networking/PartQuartzFiber.java +++ b/src/main/java/appeng/parts/networking/PartQuartzFiber.java @@ -19,7 +19,9 @@ package appeng.parts.networking; +import java.util.Collection; import java.util.EnumSet; +import java.util.LinkedList; import java.util.Set; import net.minecraft.entity.player.EntityPlayer; @@ -131,14 +133,14 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider } @Override - public double extractAEPower( final double amt, final Actionable mode, final Set seen ) + public Collection providers() { - double acquiredPower = 0; + Collection stuff = new LinkedList<>(); try { final IEnergyGrid eg = this.getProxy().getEnergy(); - acquiredPower += eg.extractAEPower( amt - acquiredPower, mode, seen ); + stuff.add( eg ); } catch( final GridAccessException e ) { @@ -148,7 +150,43 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider try { final IEnergyGrid eg = this.outerProxy.getEnergy(); - acquiredPower += eg.extractAEPower( amt - acquiredPower, mode, seen ); + stuff.add( eg ); + } + catch( final GridAccessException e ) + { + // :P + } + + return stuff; + } + + @Override + public double extractProviderPower( final double amt, final Actionable mode, final Set seen ) + { + double acquiredPower = 0; + + try + { + final IEnergyGrid eg = this.getProxy().getEnergy(); + + if( !seen.contains( eg ) ) + { + acquiredPower += eg.extractProviderPower( amt - acquiredPower, mode, seen ); + } + } + catch( final GridAccessException e ) + { + // :P + } + + try + { + final IEnergyGrid eg = this.outerProxy.getEnergy(); + + if( !seen.contains( eg ) ) + { + acquiredPower += eg.extractProviderPower( amt - acquiredPower, mode, seen ); + } } catch( final GridAccessException e ) { @@ -159,15 +197,17 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider } @Override - public double injectAEPower( final double amt, final Actionable mode, final Set seen ) + public double injectProviderPower( final double amt, final Actionable mode, final Set seen ) { + double amount = amt; + try { final IEnergyGrid eg = this.getProxy().getEnergy(); if( !seen.contains( eg ) ) { - return eg.injectAEPower( amt, mode, seen ); + amount = eg.injectProviderPower( amount, mode, seen ); } } catch( final GridAccessException e ) @@ -180,7 +220,7 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider final IEnergyGrid eg = this.outerProxy.getEnergy(); if( !seen.contains( eg ) ) { - return eg.injectAEPower( amt, mode, seen ); + amount = eg.injectProviderPower( amount, mode, seen ); } } catch( final GridAccessException e ) @@ -188,18 +228,21 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider // :P } - return amt; + return amount; } @Override - public double getEnergyDemand( final double amt, final Set seen ) + public double getProviderEnergyDemand( final double amt, final Set seen ) { double demand = 0; try { final IEnergyGrid eg = this.getProxy().getEnergy(); - demand += eg.getEnergyDemand( amt - demand, seen ); + if( !seen.contains( eg ) ) + { + demand += eg.getProviderEnergyDemand( amt - demand, seen ); + } } catch( final GridAccessException e ) { @@ -209,7 +252,10 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider try { final IEnergyGrid eg = this.outerProxy.getEnergy(); - demand += eg.getEnergyDemand( amt - demand, seen ); + if( !seen.contains( eg ) ) + { + demand += eg.getProviderEnergyDemand( amt - demand, seen ); + } } catch( final GridAccessException e ) { @@ -219,6 +265,18 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider return demand; } + @Override + public double getProviderStoredEnergy() + { + return 0; + } + + @Override + public double getProviderMaxEnergy() + { + return 0; + } + @Override public IPartModel getStaticModels() { diff --git a/src/main/java/appeng/tile/misc/TileCharger.java b/src/main/java/appeng/tile/misc/TileCharger.java index dfe69dc9..cca24530 100644 --- a/src/main/java/appeng/tile/misc/TileCharger.java +++ b/src/main/java/appeng/tile/misc/TileCharger.java @@ -130,7 +130,7 @@ public class TileCharger extends AENetworkPowerTile implements ICrankable, IGrid @Override public void applyTurn() { - this.injectExternalPower( PowerUnits.AE, 150 ); + this.injectExternalPower( PowerUnits.AE, 150, Actionable.MODULATE ); final ItemStack myItem = this.inv.getStackInSlot( 0 ); if( this.getInternalCurrentPower() > 1499 ) @@ -222,7 +222,7 @@ public class TileCharger extends AENetworkPowerTile implements ICrankable, IGrid try { this.injectExternalPower( PowerUnits.AE, this.getProxy().getEnergy().extractAEPower( Math.min( 500.0, 1500.0 - this.getInternalCurrentPower() ), - Actionable.MODULATE, PowerMultiplier.ONE ) ); + Actionable.MODULATE, PowerMultiplier.ONE ), Actionable.MODULATE ); } catch( final GridAccessException e ) { @@ -246,7 +246,8 @@ public class TileCharger extends AENetworkPowerTile implements ICrankable, IGrid { final double oldPower = this.getInternalCurrentPower(); - final double adjustment = ps.injectAEPower( myItem, this.extractAEPower( 150.0, Actionable.MODULATE, PowerMultiplier.CONFIG ), Actionable.MODULATE ); + final double adjustment = ps.injectAEPower( myItem, this.extractAEPower( 150.0, Actionable.MODULATE, PowerMultiplier.CONFIG ), + Actionable.MODULATE ); this.setInternalCurrentPower( this.getInternalCurrentPower() + adjustment ); if( oldPower > this.getInternalCurrentPower() ) diff --git a/src/main/java/appeng/tile/networking/TileController.java b/src/main/java/appeng/tile/networking/TileController.java index e11f8bed..e3a042e7 100644 --- a/src/main/java/appeng/tile/networking/TileController.java +++ b/src/main/java/appeng/tile/networking/TileController.java @@ -29,6 +29,7 @@ import net.minecraftforge.items.wrapper.EmptyHandler; import appeng.api.config.Actionable; import appeng.api.networking.GridFlags; +import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.events.MENetworkControllerChange; import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkPowerStatusChange; @@ -137,7 +138,9 @@ public class TileController extends AENetworkPowerTile { try { - return this.getProxy().getEnergy().getEnergyDemand( 8000 ); + final IEnergyGrid grid = this.getProxy().getEnergy(); + + return grid.getEnergyDemand( maxReceived ); } catch( final GridAccessException e ) { @@ -151,12 +154,10 @@ public class TileController extends AENetworkPowerTile { try { - final double ret = this.getProxy().getEnergy().injectPower( power, mode ); - if( mode == Actionable.SIMULATE ) - { - return ret; - } - return 0; + final IEnergyGrid grid = this.getProxy().getEnergy(); + final double leftOver = grid.injectPower( power, mode ); + + return leftOver; } catch( final GridAccessException e ) { diff --git a/src/main/java/appeng/tile/networking/TileEnergyAcceptor.java b/src/main/java/appeng/tile/networking/TileEnergyAcceptor.java index c9ecb7bd..69607da2 100644 --- a/src/main/java/appeng/tile/networking/TileEnergyAcceptor.java +++ b/src/main/java/appeng/tile/networking/TileEnergyAcceptor.java @@ -69,6 +69,7 @@ public class TileEnergyAcceptor extends AENetworkPowerTile try { final IEnergyGrid grid = this.getProxy().getEnergy(); + return grid.getEnergyDemand( maxRequired ); } catch( final GridAccessException e ) @@ -84,11 +85,8 @@ public class TileEnergyAcceptor extends AENetworkPowerTile { final IEnergyGrid grid = this.getProxy().getEnergy(); final double leftOver = grid.injectPower( power, mode ); - if( mode == Actionable.SIMULATE ) - { - return leftOver; - } - return 0.0; + + return leftOver; } catch( final GridAccessException e ) { diff --git a/src/main/java/appeng/tile/powersink/AEBasePoweredTile.java b/src/main/java/appeng/tile/powersink/AEBasePoweredTile.java index 774e7e0c..8dd4bb13 100644 --- a/src/main/java/appeng/tile/powersink/AEBasePoweredTile.java +++ b/src/main/java/appeng/tile/powersink/AEBasePoweredTile.java @@ -105,9 +105,9 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe } @Override - public final double injectExternalPower( final PowerUnits input, final double amt ) + public final double injectExternalPower( final PowerUnits input, final double amt, Actionable mode ) { - return PowerUnits.AE.convertTo( input, this.funnelPowerIntoStorage( input.convertTo( PowerUnits.AE, amt ), Actionable.MODULATE ) ); + return PowerUnits.AE.convertTo( input, this.funnelPowerIntoStorage( input.convertTo( PowerUnits.AE, amt ), mode ) ); } protected double funnelPowerIntoStorage( final double power, final Actionable mode ) @@ -123,34 +123,20 @@ public abstract class AEBasePoweredTile extends AEBaseInvTile implements IAEPowe return 0; } - if( mode == Actionable.SIMULATE ) - { - final double fakeBattery = this.getInternalCurrentPower() + amt; + final double required = this.getAEMaxPower() - this.getAECurrentPower(); + final double insertable = Math.min( required, amt ); - if( fakeBattery > this.getInternalMaxPower() ) - { - return fakeBattery - this.getInternalMaxPower(); - } - - return 0; - } - else + if( mode == Actionable.MODULATE ) { - if( this.getInternalCurrentPower() < 0.01 && amt > 0.01 ) + if( this.getInternalCurrentPower() < 0.01 && insertable > 0.01 ) { this.PowerEvent( PowerEventType.PROVIDE_POWER ); } - this.setInternalCurrentPower( this.getInternalCurrentPower() + amt ); - if( this.getInternalCurrentPower() > this.getInternalMaxPower() ) - { - amt = this.getInternalCurrentPower() - this.getInternalMaxPower(); - this.setInternalCurrentPower( this.getInternalMaxPower() ); - return amt; - } - - return 0; + this.setInternalCurrentPower( this.getInternalCurrentPower() + insertable ); } + + return amt - insertable; } protected void PowerEvent( final PowerEventType x ) diff --git a/src/main/java/appeng/tile/powersink/ForgeEnergyAdapter.java b/src/main/java/appeng/tile/powersink/ForgeEnergyAdapter.java index 3c257375..c5572c60 100644 --- a/src/main/java/appeng/tile/powersink/ForgeEnergyAdapter.java +++ b/src/main/java/appeng/tile/powersink/ForgeEnergyAdapter.java @@ -4,6 +4,7 @@ package appeng.tile.powersink; import net.minecraftforge.energy.IEnergyStorage; +import appeng.api.config.Actionable; import appeng.api.config.PowerUnits; @@ -23,15 +24,10 @@ class ForgeEnergyAdapter implements IEnergyStorage @Override public final int receiveEnergy( int maxReceive, boolean simulate ) { - final int networkDemand = (int) Math.floor( this.sink.getExternalPowerDemand( PowerUnits.RF, maxReceive ) ); - final int used = Math.min( maxReceive, networkDemand ); + final double offered = (double) maxReceive; + final double overflow = this.sink.injectExternalPower( PowerUnits.RF, offered, simulate ? Actionable.SIMULATE : Actionable.MODULATE ); - if( !simulate ) - { - this.sink.injectExternalPower( PowerUnits.RF, used ); - } - - return used; + return (int) ( maxReceive - overflow ); } @Override diff --git a/src/main/java/appeng/tile/powersink/IExternalPowerSink.java b/src/main/java/appeng/tile/powersink/IExternalPowerSink.java index a4884375..568bc696 100644 --- a/src/main/java/appeng/tile/powersink/IExternalPowerSink.java +++ b/src/main/java/appeng/tile/powersink/IExternalPowerSink.java @@ -19,6 +19,7 @@ package appeng.tile.powersink; +import appeng.api.config.Actionable; import appeng.api.config.PowerUnits; import appeng.api.networking.energy.IAEPowerStorage; @@ -26,8 +27,22 @@ import appeng.api.networking.energy.IAEPowerStorage; public interface IExternalPowerSink extends IAEPowerStorage { - double injectExternalPower( PowerUnits input, double amt ); + /** + * Inject power into the network + * + * @param externalUnit The {@link PowerUnits} used by the input + * @param amount The amount offered to the sink. + * @param mode Modulate or simulate the operation. + * @return The unused amount, which could not be inserted into the sink. + */ + double injectExternalPower( PowerUnits externalUnit, double amount, Actionable mode ); + /** + * + * @param externalUnit The {@link PowerUnits} used by the input + * @param maxPowerRequired Limit the demand to this upper bound. + * @return The amount of power demanded by the sink. + */ double getExternalPowerDemand( PowerUnits externalUnit, double maxPowerRequired ); } diff --git a/src/main/java/appeng/tile/powersink/TeslaEnergyAdapter.java b/src/main/java/appeng/tile/powersink/TeslaEnergyAdapter.java index 6d3c71dc..a644c88c 100644 --- a/src/main/java/appeng/tile/powersink/TeslaEnergyAdapter.java +++ b/src/main/java/appeng/tile/powersink/TeslaEnergyAdapter.java @@ -21,6 +21,7 @@ package appeng.tile.powersink; import net.darkhax.tesla.api.ITeslaConsumer; +import appeng.api.config.Actionable; import appeng.api.config.PowerUnits; @@ -41,17 +42,10 @@ class TeslaEnergyAdapter implements ITeslaConsumer public long givePower( long power, boolean simulated ) { // Cut it down to what we can represent in a double - double powerDbl = (double) power; + double offeredPower = (double) power; - double networkDemand = this.sink.getExternalPowerDemand( PowerUnits.RF, powerDbl ); - long used = (long) Math.min( powerDbl, networkDemand ); + final double overflow = this.sink.injectExternalPower( PowerUnits.RF, offeredPower, simulated ? Actionable.SIMULATE : Actionable.MODULATE ); - if( !simulated ) - { - this.sink.injectExternalPower( PowerUnits.RF, used ); - } - - return used; + return (long) ( power - overflow ); } - }