From 0372ec7c9fab852be75b3e150d68aee7b5fdc8cb Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 24 Jul 2020 12:42:59 -0400 Subject: [PATCH] Bugfixes, balancing --- core/src/mindustry/content/Blocks.java | 5 +- core/src/mindustry/content/UnitTypes.java | 4 +- .../mindustry/entities/comp/BuildingComp.java | 8 +-- .../mindustry/entities/comp/FlyingComp.java | 2 +- .../blocks/distribution/StackConveyor.java | 10 +-- .../world/blocks/power/PowerDiode.java | 4 +- .../world/blocks/power/PowerGraph.java | 22 +++---- .../world/blocks/power/PowerNode.java | 23 +++---- .../mindustry/world/modules/ItemModule.java | 65 ++++++++++--------- .../mindustry/world/modules/LiquidModule.java | 18 +++-- 10 files changed, 86 insertions(+), 75 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 01721a6286..8c9ba68f18 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -911,8 +911,9 @@ public class Blocks implements ContentList{ plastaniumConveyor = new StackConveyor("plastanium-conveyor"){{ requirements(Category.distribution, with(Items.plastanium, 1, Items.silicon, 1, Items.graphite, 1)); health = 75; - speed = 2.5f / 60f; - recharge = 2f; + speed = 3.5f / 60f; + itemCapacity = 10; + displayedSpeed = 30f; }}; armoredConveyor = new ArmoredConveyor("armored-conveyor"){{ diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 6c16e2f95a..7812d01714 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -931,7 +931,7 @@ public class UnitTypes implements ContentList{ lifetime = 60f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.14f; + tileDamageMultiplier = 0.1f; }}; }}); }}; @@ -969,7 +969,7 @@ public class UnitTypes implements ContentList{ lifetime = 70f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - tileDamageMultiplier = 0.15f; + tileDamageMultiplier = 0.1f; homingPower = 0.04f; }}; }}); diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 62e14c2b37..b9f557fd28 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -663,8 +663,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, public void updatePowerGraph(){ for(Building other : getPowerConnections(tempTileEnts)){ - if(other.power() != null){ - other.power().graph.addGraph(power.graph); + if(other.power != null){ + other.power.graph.addGraph(power.graph); } } } @@ -688,7 +688,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, if(power == null) return out; for(Building other : proximity){ - if(other != null && other.power() != null + if(other != null && other.power != null && !(block.consumesPower && other.block.consumesPower && !block.outputsPower && !other.block.outputsPower) && !power.links.contains(other.pos())){ out.add(other); @@ -800,7 +800,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, Building other = world.build(x, y); if(other != null && other.block instanceof PowerNode && ((PowerNode)other.block).linkValid(other, base()) && !PowerNode.insulated(other, base()) && !other.proximity().contains(this.base()) && - !(block.outputsPower && proximity.contains(p -> p.power() != null && p.power().graph == other.power().graph))){ + !(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){ tempTiles.add(other.tile()); } }); diff --git a/core/src/mindustry/entities/comp/FlyingComp.java b/core/src/mindustry/entities/comp/FlyingComp.java index ef53b1fece..bc27a2b084 100644 --- a/core/src/mindustry/entities/comp/FlyingComp.java +++ b/core/src/mindustry/entities/comp/FlyingComp.java @@ -50,7 +50,7 @@ abstract class FlyingComp implements Posc, Velc, Healthc, Hitboxc{ void moveAt(Vec2 vector, float acceleration){ Vec2 t = tmp1.set(vector).scl(floorSpeedMultiplier()); //target vector - tmp2.set(t).sub(vel).limit(acceleration * vector.len()); //delta vector + tmp2.set(t).sub(vel).limit(acceleration * vector.len() * Time.delta); //delta vector vel.add(tmp2); } diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index 1868e02662..3619835d5f 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -25,8 +25,8 @@ public class StackConveyor extends Block implements Autotiler{ public @Load("@-stack") TextureRegion stackRegion; public float speed = 0f; - public float recharge = 4f; public boolean splitOut = true; + public float displayedSpeed = 30f; public StackConveyor(String name){ super(name); @@ -47,7 +47,7 @@ public class StackConveyor extends Block implements Autotiler{ public void setStats(){ super.setStats(); - stats.add(BlockStat.itemsMoved, Mathf.round(itemCapacity * speed * 60), StatUnit.itemsSecond); + stats.add(BlockStat.itemsMoved, displayedSpeed, StatUnit.itemsSecond); } @Override @@ -166,7 +166,7 @@ public class StackConveyor extends Block implements Autotiler{ @Override public void updateTile(){ // reel in crater - if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta(), 0f, recharge); + if(cooldown > 0f) cooldown = Mathf.clamp(cooldown - speed * edelta()); if(link == -1){ return; @@ -200,7 +200,7 @@ public class StackConveyor extends Block implements Autotiler{ link = -1; items.clear(); - cooldown = recharge; + cooldown = 1f; e.cooldown = 1; } } @@ -249,7 +249,7 @@ public class StackConveyor extends Block implements Autotiler{ @Override public boolean acceptItem(Building source, Item item){ if(this == source) return true; // player threw items - if(cooldown > recharge - 1f) return false; // still cooling down + if(cooldown > 0) return false; // still cooling down return !((state != stateLoad) // not a loading dock || (items.total() > 0 && !items.has(item)) // incompatible items || (items.total() >= getMaximumAccepted(item)) // filled to capacity diff --git a/core/src/mindustry/world/blocks/power/PowerDiode.java b/core/src/mindustry/world/blocks/power/PowerDiode.java index cdbf612745..9a984ef51f 100644 --- a/core/src/mindustry/world/blocks/power/PowerDiode.java +++ b/core/src/mindustry/world/blocks/power/PowerDiode.java @@ -55,8 +55,8 @@ public class PowerDiode extends Block{ if(tile.front() == null || tile.back() == null || !tile.back().block().hasPower || !tile.front().block().hasPower || tile.back().team() != tile.front().team()) return; - PowerGraph backGraph = tile.back().power().graph; - PowerGraph frontGraph = tile.front().power().graph; + PowerGraph backGraph = tile.back().power.graph; + PowerGraph frontGraph = tile.front().power.graph; if(backGraph == frontGraph) return; // 0f - 1f of battery capacity in use diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index e0447dbad5..8277f7e19f 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -86,7 +86,7 @@ public class PowerGraph{ for(Building battery : batteries){ Consumers consumes = battery.block().consumes; if(consumes.hasPower()){ - totalAccumulator += battery.power().status * consumes.getPower().capacity; + totalAccumulator += battery.power.status * consumes.getPower().capacity; } } return totalAccumulator; @@ -97,7 +97,7 @@ public class PowerGraph{ for(Building battery : batteries){ if(battery.block().consumes.hasPower()){ ConsumePower power = battery.block().consumes.getPower(); - totalCapacity += (1f - battery.power().status) * power.capacity; + totalCapacity += (1f - battery.power.status) * power.capacity; } } return totalCapacity; @@ -122,7 +122,7 @@ public class PowerGraph{ for(Building battery : batteries){ Consumers consumes = battery.block().consumes; if(consumes.hasPower()){ - battery.power().status *= (1f-consumedPowerPercentage); + battery.power.status *= (1f-consumedPowerPercentage); } } return used; @@ -139,7 +139,7 @@ public class PowerGraph{ if(consumes.hasPower()){ ConsumePower consumePower = consumes.getPower(); if(consumePower.capacity > 0f){ - battery.power().status += (1f-battery.power().status) * chargedPercent; + battery.power.status += (1f- battery.power.status) * chargedPercent; } } } @@ -157,17 +157,17 @@ public class PowerGraph{ if(!Mathf.zero(consumePower.capacity)){ // Add an equal percentage of power to all buffers, based on the global power coverage in this graph float maximumRate = consumePower.requestedPower(consumer) * coverage * consumer.delta(); - consumer.power().status = Mathf.clamp(consumer.power().status + maximumRate / consumePower.capacity); + consumer.power.status = Mathf.clamp(consumer.power.status + maximumRate / consumePower.capacity); } }else{ //valid consumers get power as usual if(otherConsumersAreValid(consumer, consumePower)){ - consumer.power().status = coverage; + consumer.power.status = coverage; }else{ //invalid consumers get an estimate, if they were to activate - consumer.power().status = Math.min(1, produced / (needed + consumePower.usage * consumer.delta())); + consumer.power.status = Math.min(1, produced / (needed + consumePower.usage * consumer.delta())); //just in case - if(Float.isNaN(consumer.power().status)){ - consumer.power().status = 0f; + if(Float.isNaN(consumer.power.status)){ + consumer.power.status = 0f; } } } @@ -275,7 +275,7 @@ public class PowerGraph{ //go through all the connections of this tile for(Building other : tile.getPowerConnections(outArray1)){ //a graph has already been assigned to this tile from a previous call, skip it - if(other.power().graph != this) continue; + if(other.power.graph != this) continue; //create graph for this branch PowerGraph graph = new PowerGraph(); @@ -294,7 +294,7 @@ public class PowerGraph{ for(Building next : child.getPowerConnections(outArray2)){ //make sure it hasn't looped back, and that the new graph being assigned hasn't already been assigned //also skip closed tiles - if(next != tile && next.power().graph != graph && !closedSet.contains(next.pos())){ + if(next != tile && next.power.graph != graph && !closedSet.contains(next.pos())){ queue.addLast(next); closedSet.add(next.pos()); } diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index ae76588b8b..5fc2683b98 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -42,19 +42,19 @@ public class PowerNode extends PowerBlock{ config(Integer.class, (entity, value) -> { PowerModule power = entity.power; Building other = world.build(value); - boolean contains = power.links.contains(value), valid = other != null && other.power() != null; + boolean contains = power.links.contains(value), valid = other != null && other.power != null; if(contains){ //unlink power.links.removeValue(value); - if(valid) other.power().links.removeValue(entity.pos()); + if(valid) other.power.links.removeValue(entity.pos()); PowerGraph newgraph = new PowerGraph(); //reflow from this point, covering all tiles on this side newgraph.reflow(entity); - if(valid && other.power().graph != newgraph){ + if(valid && other.power.graph != newgraph){ //create new graph for other end PowerGraph og = new PowerGraph(); //reflow from other end @@ -68,8 +68,8 @@ public class PowerNode extends PowerBlock{ if(other.team() == entity.team()){ - if(!other.power().links.contains(entity.pos())){ - other.power().links.add(entity.pos()); + if(!other.power.links.contains(entity.pos())){ + other.power.links.add(entity.pos()); } } @@ -84,6 +84,7 @@ public class PowerNode extends PowerBlock{ tile.power.links.add(Point2.pack(p.x + tile.tileX(), p.y + tile.tileY())); } } + tile.updatePowerGraph(); }); } @@ -171,10 +172,10 @@ public class PowerNode extends PowerBlock{ } protected void getPotentialLinks(Tile tile, Cons others){ - Boolf valid = other -> other != null && other.tile() != tile && other.power() != null && + Boolf valid = other -> other != null && other.tile() != tile && other.power != null && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && overlaps(tile.x * tilesize + offset, tile.y * tilesize + offset, other.tile(), laserRange * tilesize) && other.team() == player.team() - && !other.proximity().contains(e -> e.tile() == tile) && !graphs.contains(other.power().graph); + && !other.proximity().contains(e -> e.tile() == tile) && !graphs.contains(other.power.graph); tempTileEnts.clear(); graphs.clear(); @@ -196,7 +197,7 @@ public class PowerNode extends PowerBlock{ }); tempTileEnts.each(valid, t -> { - graphs.add(t.power().graph); + graphs.add(t.power.graph); others.get(t); }); } @@ -228,7 +229,7 @@ public class PowerNode extends PowerBlock{ if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, ((PowerNode)link.block()).laserRange * tilesize))){ if(checkMaxNodes && link.block() instanceof PowerNode){ - return link.power().links.size < ((PowerNode)link.block()).maxNodes || link.power().links.contains(tile.pos()); + return link.power.links.size < ((PowerNode)link.block()).maxNodes || link.power.links.contains(tile.pos()); } return true; } @@ -269,7 +270,7 @@ public class PowerNode extends PowerBlock{ Boolf valid = other -> other != null && other != this && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(this, other) - && !other.proximity().contains(this) && other.power().graph != power.graph; + && !other.proximity().contains(this) && other.power.graph != power.graph; tempTileEnts.clear(); Geometry.circle(tile.x, tile.y, (int)(laserRange + 2), (x, y) -> { @@ -308,7 +309,7 @@ public class PowerNode extends PowerBlock{ } if(this == other){ - if(other.power().links.size == 0){ + if(other.power.links.size == 0){ int[] total = {0}; getPotentialLinks(tile, link -> { if(!insulated(this, link) && total[0]++ < maxNodes){ diff --git a/core/src/mindustry/world/modules/ItemModule.java b/core/src/mindustry/world/modules/ItemModule.java index 09824a112b..b0bd7e1cde 100644 --- a/core/src/mindustry/world/modules/ItemModule.java +++ b/core/src/mindustry/world/modules/ItemModule.java @@ -14,12 +14,13 @@ import static mindustry.Vars.content; public class ItemModule extends BlockModule{ public static final ItemModule empty = new ItemModule(); - private static final int windowSize = 60 * 4; + private static final int windowSize = 6; private static WindowedMean[] cacheFlow; private static float[] cacheSums; private static float[] displayFlow; - private static Bits cacheBits = new Bits(); - private static Interval flowTimer = new Interval(1); + private static final Bits cacheBits = new Bits(); + private static final Interval flowTimer = new Interval(2); + private static final float pollScl = 20f; protected int[] items = new int[content.items().size]; protected int total; @@ -41,38 +42,42 @@ public class ItemModule extends BlockModule{ public void update(boolean showFlow){ if(showFlow){ - if(flow == null){ - if(cacheFlow == null || cacheFlow.length != items.length){ - cacheFlow = new WindowedMean[items.length]; - for(int i = 0; i < items.length; i++){ - cacheFlow[i] = new WindowedMean(windowSize); + //update the flow at 30fps at most + if(flowTimer.get(1, pollScl)){ + + if(flow == null){ + if(cacheFlow == null || cacheFlow.length != items.length){ + cacheFlow = new WindowedMean[items.length]; + for(int i = 0; i < items.length; i++){ + cacheFlow[i] = new WindowedMean(windowSize); + } + cacheSums = new float[items.length]; + displayFlow = new float[items.length]; + }else{ + for(int i = 0; i < items.length; i++){ + cacheFlow[i].reset(); + } + Arrays.fill(cacheSums, 0); + cacheBits.clear(); } - cacheSums = new float[items.length]; - displayFlow = new float[items.length]; - }else{ - for(int i = 0; i < items.length; i++){ - cacheFlow[i].reset(); - } - Arrays.fill(cacheSums, 0); - cacheBits.clear(); + + Arrays.fill(displayFlow, -1); + + flow = cacheFlow; } - Arrays.fill(displayFlow, -1); + boolean updateFlow = flowTimer.get(30); - flow = cacheFlow; - } + for(int i = 0; i < items.length; i++){ + flow[i].add(cacheSums[i]); + if(cacheSums[i] > 0){ + cacheBits.set(i); + } + cacheSums[i] = 0; - boolean updateFlow = flowTimer.get(30); - - for(int i = 0; i < items.length; i++){ - flow[i].add(cacheSums[i]); - if(cacheSums[i] > 0){ - cacheBits.set(i); - } - cacheSums[i] = 0; - - if(updateFlow){ - displayFlow[i] = flow[i].hasEnoughData() ? flow[i].mean() / Time.delta : -1; + if(updateFlow){ + displayFlow[i] = flow[i].hasEnoughData() ? flow[i].mean() / pollScl : -1; + } } } }else{ diff --git a/core/src/mindustry/world/modules/LiquidModule.java b/core/src/mindustry/world/modules/LiquidModule.java index 8725f78fa4..2d8a34d165 100644 --- a/core/src/mindustry/world/modules/LiquidModule.java +++ b/core/src/mindustry/world/modules/LiquidModule.java @@ -11,8 +11,9 @@ import java.util.*; import static mindustry.Vars.content; public class LiquidModule extends BlockModule{ - private static final int windowSize = 60, updateInterval = 60; - private static Interval flowTimer = new Interval(1); + private static final int windowSize = 3, updateInterval = 60; + private static final Interval flowTimer = new Interval(2); + private static final float pollScl = 20f; private float[] liquids = new float[content.liquids().size]; private float total; @@ -25,11 +26,14 @@ public class LiquidModule extends BlockModule{ public void update(boolean showFlow){ smoothLiquid = Mathf.lerpDelta(smoothLiquid, currentAmount(), 0.1f); if(showFlow){ - if(flow == null) flow = new WindowedMean(windowSize); - flow.add(lastAdded); - lastAdded = 0; - if(currentFlowRate < 0 || flowTimer.get(updateInterval)){ - currentFlowRate = flow.hasEnoughData() ? flow.mean() / Time.delta : -1f; + if(flowTimer.get(1, pollScl)){ + + if(flow == null) flow = new WindowedMean(windowSize); + flow.add(lastAdded); + lastAdded = 0; + if(currentFlowRate < 0 || flowTimer.get(updateInterval)){ + currentFlowRate = flow.hasEnoughData() ? flow.mean() / pollScl : -1f; + } } }else{ currentFlowRate = -1f;