diff --git a/core/assets-raw/sprites/blocks/power/battery-large.png b/core/assets-raw/sprites/blocks/power/battery-large.png index 08ed3aa464..74bce7fc54 100644 Binary files a/core/assets-raw/sprites/blocks/power/battery-large.png and b/core/assets-raw/sprites/blocks/power/battery-large.png differ diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index e5f3da8e31..6995ed27d9 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -152,7 +152,7 @@ public class Block extends BaseBlock { } } - entity.power.graph = new PowerGraph(); + entity.power.graph = new PowerGraph(entity); entity.power.graph.add(tile); }else{ //TODO diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 72f8756517..dd79badee0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -366,11 +366,11 @@ public class Conveyor extends Block{ ConveyorEntity entity = tile.entity(); Array arr = super.getDebugInfo(tile); arr.addAll(Array.with( - "mincarry", entity.minCarry, - "minitem", entity.minCarry, - "carrying", entity.carrying, - "clogHeat", entity.clogHeat, - "sleeping", entity.isSleeping() + "mincarry", entity.minCarry, + "minitem", entity.minCarry, + "carrying", entity.carrying, + "clogHeat", entity.clogHeat, + "sleeping", entity.isSleeping() )); return arr; } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java index d31f5a5ed7..0cc940c41c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java @@ -50,7 +50,7 @@ public class FusionReactor extends PowerGenerator{ entity.power.amount += powerAdded; entity.totalProgress += entity.warmup * Timers.delta(); - distributePower(tile); + tile.entity.power.graph.update(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java index 0de68c738d..0a810d4d9c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java @@ -106,8 +106,7 @@ public abstract class ItemGenerator extends PowerGenerator{ entity.generateTime = 1f; } - distributePower(tile); - + tile.entity.power.graph.update(); } protected abstract float getItemEfficiency(Item item); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index 5df81813da..a4fd452e47 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -77,7 +77,7 @@ public abstract class ItemLiquidGenerator extends ItemGenerator{ } } - distributePower(tile); + tile.entity.power.graph.update(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java index d1a9e312e8..44b78bdd69 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java @@ -61,7 +61,7 @@ public abstract class LiquidGenerator extends PowerGenerator{ } } - distributePower(tile); + tile.entity.power.graph.update(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index 8c0e34c9ec..48bd304ef5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -124,7 +124,7 @@ public class NuclearReactor extends PowerGenerator{ if(entity.heat >= 0.999f){ entity.kill(); }else{ - distributePower(tile); + tile.entity.power.graph.update(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java index e4b6836506..12354ac3da 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerDistributor.java @@ -12,6 +12,6 @@ public class PowerDistributor extends PowerBlock{ @Override public void update(Tile tile){ - tile.entity.power.graph.distribute(tile); + tile.entity.power.graph.update(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index 0390aa7679..a5f9588400 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -1,21 +1,67 @@ package io.anuke.mindustry.world.blocks.power; import com.badlogic.gdx.utils.ObjectSet; +import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.world.Tile; +import static io.anuke.mindustry.Vars.threads; + public class PowerGraph{ - private ObjectSet producers = new ObjectSet<>(); - private ObjectSet consumers = new ObjectSet<>(); - private ObjectSet all = new ObjectSet<>(); + private final ObjectSet producers = new ObjectSet<>(); + private final ObjectSet consumers = new ObjectSet<>(); + private final ObjectSet all = new ObjectSet<>(); + private final TileEntity seed; - public void distribute(Tile tile){ + private long lastFrameUpdated; + public PowerGraph(TileEntity seed){ + this.seed = seed; + } + + public boolean isSeed(TileEntity entity){ + return seed == entity; + } + + public void update(){ + if(threads.getFrameID() == lastFrameUpdated || consumers.size == 0 || producers.size == 0){ + return; + } + + lastFrameUpdated = threads.getFrameID(); + + for(Tile producer : producers){ + float accumulator = producer.entity.power.amount; + + float toEach = accumulator / consumers.size; + float outputs = 0f; + + for(Tile tile : consumers){ + outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach; + } + + float finalEach = toEach / outputs; + float buffer = 0f; + + if(Float.isNaN(finalEach)){ + return; + } + + for(Tile tile : consumers){ + float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach); + buffer += used; + tile.entity.power.amount += used; + } + + producer.entity.power.amount -= buffer; + } } public void add(Tile tile){ all.add(tile); if(tile.block().outputsPower){ producers.add(tile); + }else{ + consumers.add(tile); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 3e66dbb588..5fbe158458 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -110,7 +110,7 @@ public class PowerNode extends PowerBlock{ @Override public void update(Tile tile){ - distributeLaserPower(tile); + tile.entity.power.graph.update(); } @Override @@ -227,56 +227,6 @@ public class PowerNode extends PowerBlock{ return canAccept; } - protected boolean shouldDistribute(Tile tile, Tile other){ - return other != null && other.entity != null && other.block().hasPower && other.getTeamID() == tile.getTeamID() && other.entity.power.amount / other.block().powerCapacity <= tile.entity.power.amount / powerCapacity && - !(other.block() instanceof PowerGenerator); //do not distribute to power generators - } - - protected boolean shouldLeechPower(Tile tile, Tile other){ - return other.getTeamID() == tile.getTeamID() && !(other.block() instanceof PowerNode) - && other.block() instanceof PowerDistributor //only suck power from batteries and power generators - && other.entity.power.amount / other.block().powerCapacity > tile.entity.power.amount / powerCapacity; - } - - protected void distributeLaserPower(Tile tile){ - DistributorEntity entity = tile.entity(); - - if(Float.isNaN(entity.power.amount)){ - entity.power.amount = 0f; - } - - int targets = 0; - - //validate everything first. - for(int i = 0; i < entity.links.size; i++){ - Tile target = world.tile(entity.links.get(i)); - if(!linkValid(tile, target)){ - entity.links.removeIndex(i); - i--; - }else if(shouldDistribute(tile, target)){ - targets++; - } - } - - float result = Math.min(entity.power.amount / targets, powerSpeed * Timers.delta()); - - for(int i = 0; i < entity.links.size; i++){ - Tile target = world.tile(entity.links.get(i)); - if(targets > 0 && shouldDistribute(tile, target)){ - - float transmit = Math.min(result, entity.power.amount); - if(target.block().acceptPower(target, tile, transmit)){ - entity.power.amount -= target.block().addPower(target, transmit); - } - }else if(shouldLeechPower(tile, target)){ - float diff = (target.entity.power.amount / target.block().powerCapacity - tile.entity.power.amount / powerCapacity) / 1.4f; - float transmit = Math.min(Math.min(target.block().powerCapacity * diff, target.entity.power.amount), powerCapacity - tile.entity.power.amount); - entity.power.amount += transmit; - target.entity.power.amount -= transmit; - } - } - } - protected boolean linked(Tile tile, Tile other){ return tile.entity().links.contains(other.packedPosition()); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java index 5dfe21ebf3..03e017e896 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java @@ -28,7 +28,7 @@ public class SolarGenerator extends PowerGenerator{ public void update(Tile tile){ addPower(tile, generation * Timers.delta()); - distributePower(tile); + tile.entity.power.graph.update(); } } diff --git a/core/src/io/anuke/mindustry/world/modules/PowerModule.java b/core/src/io/anuke/mindustry/world/modules/PowerModule.java index 2647a442c1..b75a85fc76 100644 --- a/core/src/io/anuke/mindustry/world/modules/PowerModule.java +++ b/core/src/io/anuke/mindustry/world/modules/PowerModule.java @@ -22,7 +22,6 @@ public class PowerModule extends BlockModule{ } float canAccept = Math.min(capacity - amount, add); - amount += canAccept; return canAccept;