diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 6a7c2cde6a..9102a1527b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -11,6 +11,7 @@ link.google-play.description = Google Play store listing link.wiki.description = Official Mindustry wiki linkfail = Failed to open link!\nThe URL has been copied to your clipboard. screenshot = Screenshot saved to {0} +screenshot.invalid = Map too large, potentially not enough memory for screenshot. gameover = Game Over gameover.pvp = The[accent] {0}[] team is victorious! highscore = [accent]New highscore! @@ -509,6 +510,7 @@ rules.unitdrops = Unit Drops rules.unitbuildspeedmultiplier = Unit Creation Speed Multiplier rules.unithealthmultiplier = Unit Health Multiplier rules.playerdamagemultiplier = Player Damage Multiplier +rules.unitdamagemultiplier = Unit Damage Multiplier rules.enemycorebuildradius = Enemy Core No-Build Radius:[LIGHT_GRAY] (tiles) rules.respawntime = Respawn Time:[LIGHT_GRAY] (sec) rules.wavespacing = Wave Spacing:[LIGHT_GRAY] (sec) diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java index 119c867403..6978140083 100644 --- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java +++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java @@ -53,6 +53,10 @@ public class WaveSpawner{ } } + public int countSpawns(){ + return groundSpawns.size; + } + /**@return true if the player is near a ground spawn point.*/ public boolean playerNear(){ return groundSpawns.count(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < maxShockwaveDst) > 0; diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index 407fed03bc..1b92195f9b 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -610,19 +610,6 @@ public class Blocks implements ContentList{ consumes.liquid(Liquids.slag, 0.07f); }}; - cultivator = new Cultivator("cultivator"){{ - requirements(Category.crafting, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20)); - outputItem = new ItemStack(Items.sporePod, 1); - craftTime = 160; - size = 2; - hasLiquids = true; - hasPower = true; - hasItems = true; - - consumes.power(0.80f); - consumes.liquid(Liquids.water, 0.15f); - }}; - sporePress = new GenericCrafter("spore-press"){{ requirements(Category.crafting, ItemStack.with(Items.lead, 70, Items.silicon, 60)); liquidCapacity = 60f; @@ -822,7 +809,7 @@ public class Blocks implements ContentList{ phaseBoost = 4f; phaseRangeBoost = 20f; health = 80; - consumes.item(Items.silicon).optional(true); + consumes.item(Items.silicon).boost(); }}; mendProjector = new MendProjector("mend-projector"){{ @@ -833,20 +820,20 @@ public class Blocks implements ContentList{ range = 85f; healPercent = 14f; health = 80 * size * size; - consumes.item(Items.phasefabric).optional(true); + consumes.item(Items.phasefabric).boost(); }}; overdriveProjector = new OverdriveProjector("overdrive-projector"){{ requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.silicon, 150, Items.plastanium, 60)); consumes.power(3.50f); size = 2; - consumes.item(Items.phasefabric).optional(true); + consumes.item(Items.phasefabric).boost(); }}; forceProjector = new ForceProjector("force-projector"){{ requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.silicon, 250)); size = 3; - consumes.item(Items.phasefabric).optional(true); + consumes.item(Items.phasefabric).boost(); }}; shockMine = new ShockMine("shock-mine"){{ @@ -1052,7 +1039,7 @@ public class Blocks implements ContentList{ hasLiquids = true; size = 3; - consumes.item(Items.pyratite); + consumes.item(Items.pyratite).optional(true, false); consumes.liquid(Liquids.cryofluid, 0.2f); }}; @@ -1075,7 +1062,7 @@ public class Blocks implements ContentList{ }}; thoriumReactor = new NuclearReactor("thorium-reactor"){{ - requirements(Category.power, ItemStack.with(Items.lead, 600, Items.silicon, 400, Items.graphite, 300, Items.thorium, 300)); + requirements(Category.power, ItemStack.with(Items.lead, 600, Items.silicon, 400, Items.graphite, 300, Items.thorium, 300, Items.metaglass, 100)); size = 3; health = 700; powerProduction = 14f; @@ -1091,7 +1078,7 @@ public class Blocks implements ContentList{ powerProduction = 110f; itemDuration = 40f; consumes.power(25f); - consumes.item(Items.blastCompound); + consumes.item(Items.blastCompound).optional(true, false); consumes.liquid(Liquids.cryofluid, 0.3f); }}; @@ -1104,7 +1091,7 @@ public class Blocks implements ContentList{ drillTime = 600; size = 2; drawMineItem = true; - consumes.liquid(Liquids.water, 0.05f).optional(true); + consumes.liquid(Liquids.water, 0.05f).boost(); }}; pneumaticDrill = new Drill("pneumatic-drill"){{ @@ -1113,7 +1100,7 @@ public class Blocks implements ContentList{ drillTime = 480; size = 2; drawMineItem = true; - consumes.liquid(Liquids.water, 0.06f).optional(true); + consumes.liquid(Liquids.water, 0.06f).boost(); }}; laserDrill = new Drill("laser-drill"){{ @@ -1126,7 +1113,7 @@ public class Blocks implements ContentList{ drillEffect = Fx.mineBig; consumes.power(1.10f); - consumes.liquid(Liquids.water, 0.08f).optional(true); + consumes.liquid(Liquids.water, 0.08f).boost(); }}; blastDrill = new Drill("blast-drill"){{ @@ -1143,7 +1130,7 @@ public class Blocks implements ContentList{ warmupSpeed = 0.01f; consumes.power(3f); - consumes.liquid(Liquids.water, 0.1f).optional(true); + consumes.liquid(Liquids.water, 0.1f).boost(); }}; waterExtractor = new SolidPump("water-extractor"){{ @@ -1158,6 +1145,19 @@ public class Blocks implements ContentList{ consumes.power(0.90f); }}; + cultivator = new Cultivator("cultivator"){{ + requirements(Category.production, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20)); + outputItem = new ItemStack(Items.sporePod, 1); + craftTime = 160; + size = 2; + hasLiquids = true; + hasPower = true; + hasItems = true; + + consumes.power(0.80f); + consumes.liquid(Liquids.water, 0.15f); + }}; + oilExtractor = new Fracker("oil-extractor"){{ requirements(Category.production, ItemStack.with(Items.copper, 300, Items.graphite, 350, Items.lead, 230, Items.thorium, 230, Items.silicon, 150)); result = Liquids.oil; @@ -1497,7 +1497,7 @@ public class Blocks implements ContentList{ shootCone = 24f; health = 155 * size * size; - consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true); + consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 2f)).update(false).optional(true, false); }}; meltdown = new LaserTurret("meltdown"){{ diff --git a/core/src/io/anuke/mindustry/content/Zones.java b/core/src/io/anuke/mindustry/content/Zones.java index 088a1230bb..190c3229e9 100644 --- a/core/src/io/anuke/mindustry/content/Zones.java +++ b/core/src/io/anuke/mindustry/content/Zones.java @@ -35,7 +35,7 @@ public class Zones implements ContentList{ conditionWave = 10; zoneRequirements = ZoneRequirement.with(groundZero, 10); blockRequirements = new Block[]{Blocks.router}; - resources = new Item[]{Items.copper, Items.lead}; + resources = new Item[]{Items.copper, Items.lead, Items.coal}; rules = () -> new Rules(){{ waves = true; waveTimer = true; @@ -98,7 +98,7 @@ public class Zones implements ContentList{ launchPeriod = 10; zoneRequirements = ZoneRequirement.with(frozenForest, 15); blockRequirements = new Block[]{Blocks.pneumaticDrill}; - resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium}; + resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand}; rules = () -> new Rules(){{ waves = true; waveTimer = true; diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 7ae8d05870..ca54b07dd0 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -330,6 +330,12 @@ public class Renderer implements ApplicationListener{ drawGroundShadows(); int w = world.width()*tilesize, h = world.height()*tilesize; + int memory = w * h * 4 / 1024 / 1024; + + if(memory >= 65){ + ui.showInfo("$screenshot.invalid"); + return; + } boolean hadShields = Core.settings.getBool("animatedshields"); boolean hadWater = Core.settings.getBool("animatedwater"); diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index e4b1731661..406192c411 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -175,14 +175,17 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{ @Override public void write(DataOutput data) throws IOException{ - data.writeFloat(x); - data.writeFloat(y); + data.writeInt(tile.pos()); + data.writeFloat(lifetime); } @Override public void read(DataInput data) throws IOException{ - x = data.readFloat(); - y = data.readFloat(); + int pos = data.readInt(); + this.lifetime = data.readFloat(); + + x = Pos.x(pos) * tilesize; + y = Pos.y(pos) * tilesize; } @Override diff --git a/core/src/io/anuke/mindustry/entities/type/BaseUnit.java b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java index 8b9549a72c..d4d2ad4063 100644 --- a/core/src/io/anuke/mindustry/entities/type/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java @@ -17,9 +17,7 @@ import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.ShooterTrait; import io.anuke.mindustry.entities.traits.TargetTrait; -import io.anuke.mindustry.entities.units.StateMachine; -import io.anuke.mindustry.entities.units.UnitDrops; -import io.anuke.mindustry.entities.units.UnitState; +import io.anuke.mindustry.entities.units.*; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; @@ -27,9 +25,7 @@ import io.anuke.mindustry.type.*; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; +import java.io.*; import static io.anuke.mindustry.Vars.*; @@ -181,6 +177,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ return hasEffect(StatusEffects.boss); } + @Override + public float getDamageMultipler(){ + return status.getDamageMultiplier() * Vars.state.rules.unitDamageMultiplier; + } + @Override public boolean isImmune(StatusEffect effect){ return type.immunities.contains(effect); diff --git a/core/src/io/anuke/mindustry/game/Rules.java b/core/src/io/anuke/mindustry/game/Rules.java index fedd3b3054..4e6d35cb58 100644 --- a/core/src/io/anuke/mindustry/game/Rules.java +++ b/core/src/io/anuke/mindustry/game/Rules.java @@ -25,6 +25,8 @@ public class Rules{ public float unitHealthMultiplier = 1f; /**How much damage player mechs deal.*/ public float playerDamageMultiplier = 1f; + /**How much damage any other units deal.*/ + public float unitDamageMultiplier = 1f; /**Multiplier for buildings for the player.*/ public float buildCostMultiplier = 1f; /**Multiplier for building speed.*/ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java index 7f9b419cae..87c0c5d0c7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java @@ -46,6 +46,7 @@ public class CustomRulesDialog extends FloatingDialog{ number("$rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier); number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier); number("$rules.playerdamagemultiplier", f -> rules.playerDamageMultiplier = f, () -> rules.playerDamageMultiplier); + number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f*tilesize, () -> Math.min(rules.enemyCoreBuildRadius/tilesize, 200)); number("$rules.respawntime", f -> rules.respawnTime = f*60f, () -> rules.respawnTime/60f); number("$rules.wavespacing", f -> rules.waveSpacing = f*60f, () -> rules.waveSpacing/60f); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java index e00c628c2a..6df557e01a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java @@ -55,7 +55,7 @@ public class ForceProjector extends Block { canOverdrive = false; hasLiquids = true; hasItems = true; - consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).optional(true).update(false); + consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).boost().update(false); consumePower = new ConsumeForceProjectorPower(60f, 60f); consumes.add(consumePower); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java index 2a1cbe6e64..d9cffb3be8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java @@ -25,7 +25,7 @@ public class CooledTurret extends Turret{ hasLiquids = true; liquidCapacity = 20f; - consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.2f)).update(false).optional(true); + consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.2f)).update(false).boost(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index abaad60151..73d224b2d9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -100,7 +100,18 @@ public class ItemBridge extends Block{ public void drawPlace(int x, int y, int rotation, boolean valid){ Tile link = findLink(x, y); - Draw.tint(Pal.placing); + Lines.stroke(2f, Pal.placing); + for(int i = 0; i < 4; i++){ + Lines.dashLine( + x * tilesize + Geometry.d4[i].x * (tilesize / 2f + 2), + y * tilesize + Geometry.d4[i].y * (tilesize / 2f + 2), + x * tilesize + Geometry.d4[i].x * (range + 0.5f) * tilesize, + y * tilesize + Geometry.d4[i].y * (range + 0.5f) * tilesize, + range); + } + + Draw.reset(); + Draw.color(Pal.placing); Lines.stroke(1f); if(link != null){ int rot = link.absoluteRelativeTo(x, y); @@ -246,7 +257,7 @@ public class ItemBridge extends Block{ @Override public boolean acceptItem(Item item, Tile tile, Tile source){ - if(tile.getTeamID() != source.target().getTeamID()) return false; + if(tile.getTeam() != source.target().getTeam()) return false; ItemBridgeEntity entity = tile.entity(); Tile other = world.tile(entity.link); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java index 1d27e7951d..f33becc63a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java @@ -1,11 +1,12 @@ package io.anuke.mindustry.world.blocks.distribution; +import io.anuke.arc.collection.IntSet.IntSetIterator; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.util.Time; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.meta.BlockGroup; -import io.anuke.arc.util.Time; -import io.anuke.arc.math.Mathf; import static io.anuke.mindustry.Vars.world; @@ -58,6 +59,20 @@ public class LiquidBridge extends ItemBridge{ @Override public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + if(tile.getTeam() != source.target().getTeam()) return false; + + ItemBridgeEntity entity = tile.entity(); + Tile other = world.tile(entity.link); + + if(linkValid(tile, other)){ + int rel = tile.absoluteRelativeTo(other.x, other.y); + int rel2 = tile.relativeTo(source.x, source.y); + + if(rel == rel2) return false; + }else if(!(source.block() instanceof ItemBridge && source.entity().link == tile.pos())){ + return false; + } + return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f); } @@ -67,7 +82,18 @@ public class LiquidBridge extends ItemBridge{ Tile other = world.tile(entity.link); if(!linkValid(tile, other)){ - return !(to.block() instanceof LiquidBridge); + Tile edge = Edges.getFacingEdge(to, tile); + int i = tile.absoluteRelativeTo(edge.x, edge.y); + + IntSetIterator it = entity.incoming.iterator(); + + while(it.hasNext){ + int v = it.next(); + if(tile.absoluteRelativeTo(Pos.x(v), Pos.y(v)) == i){ + return false; + } + } + return true; } int rel = tile.absoluteRelativeTo(other.x, other.y); 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 79ad2cc897..6af6b8f13f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -46,11 +46,11 @@ public class ItemLiquidGenerator extends PowerGenerator{ this.hasLiquids = hasLiquids; if(hasItems){ - consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false); + consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true, false); } if(hasLiquids){ - consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, maxLiquidGenerate)).update(false); + consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, maxLiquidGenerate)).update(false).optional(true, false); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index b54b633a7b..e5ed83c7ac 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -7,7 +7,10 @@ import io.anuke.mindustry.world.meta.BlockStats; /**An abstract class that defines a type of resource that a block can consume.*/ public abstract class Consume{ + /**If true, this consumer will not influence consumer validity.*/ protected boolean optional; + /**If true, this consumer will be displayed as a boost input.*/ + protected boolean booster; protected boolean update = true; /**Apply a filter to items accepted. @@ -22,11 +25,16 @@ public abstract class Consume{ } - public Consume optional(boolean optional){ + public Consume optional(boolean optional, boolean boost){ this.optional = optional; + this.booster = boost; return this; } + public Consume boost(){ + return optional(true, true); + } + public Consume update(boolean update){ this.update = update; return this; diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java index 4fe813032e..6faf18a27b 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java @@ -76,6 +76,6 @@ public class ConsumeItemFilter extends Consume{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.booster : BlockStat.input, new ItemFilterValue(filter)); + stats.add(booster ? BlockStat.booster : BlockStat.input, new ItemFilterValue(filter)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java index c81f26c7f0..9f7da16a2d 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java @@ -61,6 +61,6 @@ public class ConsumeItems extends Consume{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.booster : BlockStat.input, new ItemListValue(items)); + stats.add(booster ? BlockStat.booster : BlockStat.input, new ItemListValue(items)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java index 468750e0cd..7cb41cce5c 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.world.consumers; import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.util.Log; import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.ui.ReqImage; @@ -44,6 +43,6 @@ public class ConsumeLiquid extends ConsumeLiquidBase{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.booster : BlockStat.input, liquid, amount * timePeriod, timePeriod == 60); + stats.add(booster ? BlockStat.booster : BlockStat.input, liquid, amount * timePeriod, timePeriod == 60); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java index 63ee4299f1..f0f2d7aaad 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -53,6 +53,6 @@ public class ConsumeLiquidFilter extends ConsumeLiquidBase{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.booster : BlockStat.input, new LiquidFilterValue(filter, amount * timePeriod, timePeriod == 60f)); + stats.add(booster ? BlockStat.booster : BlockStat.input, new LiquidFilterValue(filter, amount * timePeriod, timePeriod == 60f)); } } diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index d4809b2746..24167f3550 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -6,31 +6,19 @@ import io.anuke.arc.math.geom.Point2; import io.anuke.arc.util.Log; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.UnitTypes; +import io.anuke.mindustry.content.*; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.core.Logic; -import io.anuke.mindustry.core.NetServer; -import io.anuke.mindustry.core.World; +import io.anuke.mindustry.core.*; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.entities.type.base.Spirit; -import io.anuke.mindustry.game.Content; -import io.anuke.mindustry.game.SpawnGroup; -import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.game.*; import io.anuke.mindustry.io.BundleLoader; import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Zone; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Edges; -import io.anuke.mindustry.world.Tile; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import io.anuke.mindustry.type.*; +import io.anuke.mindustry.world.*; +import org.junit.jupiter.api.*; import static io.anuke.mindustry.Vars.*; import static org.junit.jupiter.api.Assertions.*; diff --git a/tests/src/test/java/ZoneTests.java b/tests/src/test/java/ZoneTests.java new file mode 100644 index 0000000000..9061f29833 --- /dev/null +++ b/tests/src/test/java/ZoneTests.java @@ -0,0 +1,68 @@ +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.ObjectSet; +import io.anuke.arc.util.Structs; +import io.anuke.arc.util.Time; +import io.anuke.mindustry.core.GameState.State; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.Zone; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.storage.CoreBlock; +import org.junit.jupiter.api.*; + +import static io.anuke.mindustry.Vars.*; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +public class ZoneTests{ + + @BeforeAll + static void launchApplication(){ + ApplicationTests.launchApplication(); + } + + @BeforeEach + void resetWorld(){ + Time.setDeltaProvider(() -> 1f); + logic.reset(); + state.set(State.menu); + } + + @TestFactory + DynamicTest[] testZoneResources(){ + Array out = new Array<>(); + + for(Zone zone : content.zones()){ + out.add(dynamicTest(zone.name, () -> { + logic.reset(); + world.loadGenerator(zone.generator); + ObjectSet resources = new ObjectSet<>(); + boolean hasSpawnPoint = false; + + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ + Tile tile = world.tile(x, y); + if(tile.drop() != null){ + resources.add(tile.drop()); + } + if(tile.block() instanceof CoreBlock){ + hasSpawnPoint = true; + } + } + } + + assertTrue(hasSpawnPoint, "Zone \"" + zone.name + "\" has no spawn points."); + //assertTrue(world.spawner.countSpawns() > 0, "Zone \"" + zone.name + "\" has no enemy spawn points: " + world.spawner.countSpawns()); + + for(Item item : resources){ + assertTrue(Structs.contains(zone.resources, item), "Zone \"" + zone.name + "\" is missing item in resource list: \"" + item.name + "\""); + } + + for(Item item : zone.resources){ + assertTrue(resources.contains(item), "Zone \"" + zone.name + "\" has unnecessary item in resoruce list: \"" + item.name + "\""); + } + })); + } + + return out.toArray(DynamicTest.class); + } +}