diff --git a/core/assets/maps/saltFlats.msav b/core/assets/maps/saltFlats.msav index 6c2ae62d65..5a8285f910 100644 Binary files a/core/assets/maps/saltFlats.msav and b/core/assets/maps/saltFlats.msav differ diff --git a/core/assets/zones/nomap.png b/core/assets/zones/nomap.png new file mode 100644 index 0000000000..00241f7666 Binary files /dev/null and b/core/assets/zones/nomap.png differ diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index 24faea8266..27971e0d5c 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -1673,9 +1673,9 @@ public class Blocks implements ContentList{ type = UnitTypes.crawler; produceTime = 250; size = 2; - maxSpawn = 6; + maxSpawn = 8; consumes.power(0.4f); - consumes.items(new ItemStack(Items.coal, 6)); + consumes.items(new ItemStack(Items.coal, 5)); }}; titanFactory = new UnitFactory("titan-factory"){{ @@ -1699,7 +1699,8 @@ public class Blocks implements ContentList{ repairPoint = new RepairPoint("repair-point"){{ requirements(Category.units, ItemStack.with(Items.lead, 15, Items.copper, 15, Items.silicon, 15)); - repairSpeed = 0.3f; + repairSpeed = 0.5f; + repairRadius = 65f; powerUse = 1f; }}; diff --git a/core/src/io/anuke/mindustry/content/Bullets.java b/core/src/io/anuke/mindustry/content/Bullets.java index 992bc626c9..0738306466 100644 --- a/core/src/io/anuke/mindustry/content/Bullets.java +++ b/core/src/io/anuke/mindustry/content/Bullets.java @@ -470,6 +470,11 @@ public class Bullets implements ContentList{ status = StatusEffects.burning; } + @Override + public float range(){ + return 50f; + } + @Override public void draw(Bullet b){ } diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index 54fcf2ceb8..3f95baccb9 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -105,16 +105,18 @@ public class UnitTypes implements ContentList{ titan = new UnitType("titan", Titan.class, Titan::new){{ maxVelocity = 0.8f; - speed = 0.18f; + speed = 0.22f; drag = 0.4f; mass = 3.5f; hitsize = 9f; + range = 10f; rotatespeed = 0.1f; - health = 440; + health = 460; immunities.add(StatusEffects.burning); weapon = new Weapon("flamethrower"){{ length = 1f; reload = 14f; + range = 30f; roundrobin = true; recoil = 1f; ejectEffect = Fx.none; diff --git a/core/src/io/anuke/mindustry/content/Zones.java b/core/src/io/anuke/mindustry/content/Zones.java index 46dcd7fbfd..72de064f1c 100644 --- a/core/src/io/anuke/mindustry/content/Zones.java +++ b/core/src/io/anuke/mindustry/content/Zones.java @@ -79,12 +79,11 @@ public class Zones implements ContentList{ saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{ startingItems = ItemStack.list(Items.copper, 200, Items.silicon, 200, Items.lead, 200); - alwaysUnlocked = true; - conditionWave = 5; - launchPeriod = 5; loadout = Loadouts.basicFoundation; + conditionWave = 10; + launchPeriod = 5; zoneRequirements = ZoneRequirement.with(desertWastes, 60); - blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.draugFactory, Blocks.door}; + blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.draugFactory, Blocks.door, Blocks.waterExtractor}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand, Items.titanium}; }}; @@ -114,7 +113,7 @@ public class Zones implements ContentList{ conditionWave = 20; launchPeriod = 20; zoneRequirements = ZoneRequirement.with(desertWastes, 20, craters, 15); - blockRequirements = new Block[]{Blocks.graphitePress, Blocks.combustionGenerator, Blocks.kiln}; + blockRequirements = new Block[]{Blocks.graphitePress, Blocks.combustionGenerator, Blocks.kiln, Blocks.mechanicalPump}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand}; }}; @@ -125,14 +124,14 @@ public class Zones implements ContentList{ conditionWave = 10; launchPeriod = 10; zoneRequirements = ZoneRequirement.with(frozenForest, 15); - blockRequirements = new Block[]{Blocks.pneumaticDrill}; + blockRequirements = new Block[]{Blocks.pneumaticDrill, Blocks.powerNode, Blocks.turbineGenerator}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand}; }}; fungalPass = new Zone("fungalPass", new MapGenerator("fungalPass")){{ startingItems = ItemStack.list(Items.copper, 250, Items.lead, 250, Items.metaglass, 100, Items.graphite, 100); zoneRequirements = ZoneRequirement.with(stainedMountains, 15); - blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.crawlerFactory, Blocks.door}; + blockRequirements = new Block[]{Blocks.daggerFactory, Blocks.crawlerFactory, Blocks.door, Blocks.siliconSmelter}; resources = new Item[]{Items.copper, Items.lead, Items.coal, Items.titanium, Items.sand}; }}; @@ -153,7 +152,7 @@ public class Zones implements ContentList{ conditionWave = 15; launchPeriod = 10; zoneRequirements = ZoneRequirement.with(ruinousShores, 20); - blockRequirements = new Block[]{Blocks.coalCentrifuge}; + blockRequirements = new Block[]{Blocks.coalCentrifuge, Blocks.conduit, Blocks.wave}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand}; }}; @@ -164,7 +163,7 @@ public class Zones implements ContentList{ conditionWave = 3; launchPeriod = 2; zoneRequirements = ZoneRequirement.with(tarFields, 20); - blockRequirements = new Block[]{Blocks.thermalGenerator}; + blockRequirements = new Block[]{Blocks.thermalGenerator, Blocks.thoriumReactor}; resources = new Item[]{Items.copper, Items.scrap, Items.lead, Items.coal, Items.titanium, Items.sand, Items.thorium}; }}; diff --git a/core/src/io/anuke/mindustry/entities/effect/Decal.java b/core/src/io/anuke/mindustry/entities/effect/Decal.java index 79b2c3276d..dd8a499f50 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Decal.java +++ b/core/src/io/anuke/mindustry/entities/effect/Decal.java @@ -17,7 +17,7 @@ public abstract class Decal extends TimedEntity implements BelowLiquidTrait, Dra @Override public float lifetime(){ - return 8200f; + return 3600; } @Override diff --git a/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java b/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java index 8f2fb733ef..222d1355e4 100644 --- a/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/RubbleDecal.java @@ -25,6 +25,11 @@ public class RubbleDecal extends Decal{ decal.add(); } + @Override + public float lifetime(){ + return 8200f; + } + @Override public void drawDecal(){ if(!Core.atlas.isFound(region)){ diff --git a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java index c5828f3078..89f4eacf6f 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java @@ -34,7 +34,7 @@ public class ScorchDecal extends Decal{ @Override public void drawDecal(){ - for(int i = 0; i < 5; i++){ + for(int i = 0; i < 3; i++){ TextureRegion region = regions[Mathf.randomSeed(id - i, 0, scorches - 1)]; float rotation = Mathf.randomSeed(id + i, 0, 360); float space = 1.5f + Mathf.randomSeed(id + i + 1, 0, 20) / 10f; diff --git a/core/src/io/anuke/mindustry/type/Zone.java b/core/src/io/anuke/mindustry/type/Zone.java index fe5f5210ac..a89d7f3079 100644 --- a/core/src/io/anuke/mindustry/type/Zone.java +++ b/core/src/io/anuke/mindustry/type/Zone.java @@ -59,6 +59,26 @@ public class Zone extends UnlockableContent{ return metCondition() && wave % launchPeriod == 0; } + public boolean canUnlock(){ + if(data.isUnlocked(this)){ + return true; + } + + for(ZoneRequirement other : zoneRequirements){ + if(other.zone.bestWave() < other.wave){ + return false; + } + } + + for(Block other : blockRequirements){ + if(!data.isUnlocked(other)){ + return false; + } + } + + return true; + } + public ItemStack[] getLaunchCost(){ if(launchCost == null){ updateLaunchCost(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java index 1ff47ea3d7..45c935b79a 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.dialogs; import io.anuke.arc.*; import io.anuke.arc.collection.*; import io.anuke.arc.collection.ObjectSet.*; +import io.anuke.arc.function.*; import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.math.*; @@ -14,6 +15,7 @@ import io.anuke.arc.scene.utils.*; import io.anuke.arc.util.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.core.GameState.*; +import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.Saves.*; import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.io.SaveIO.*; @@ -30,10 +32,13 @@ public class DeployDialog extends FloatingDialog{ private ObjectSet nodes = new ObjectSet<>(); private ZoneInfoDialog info = new ZoneInfoDialog(); private Rectangle bounds = new Rectangle(); + private Texture nomap = new Texture("zones/nomap.png"); public DeployDialog(){ super("", "fulldialog"); + Events.on(DisposeEvent.class, e -> nomap.dispose()); + ZoneNode root = new ZoneNode(Zones.groundZero, null); TreeLayout layout = new TreeLayout(); @@ -173,9 +178,10 @@ public class DeployDialog extends FloatingDialog{ if(zone.unlocked() && !hidden(zone)){ button.labelWrap(zone.localizedName()).style("outline").width(140).growX().get().setAlignment(Align.center); }else{ - button.addImage("icon-locked"); + Consumer flasher = zone.canUnlock() && !hidden(zone) ? e -> e.update(() -> e.getColor().set(Color.WHITE).lerp(Pal.accent, Mathf.absin(3f, 1f))) : e -> {}; + flasher.accept(button.addImage("icon-locked").get()); button.row(); - button.add("$locked"); + flasher.accept(button.add("$locked").get()); } } @@ -193,13 +199,7 @@ public class DeployDialog extends FloatingDialog{ } stack.setSize(Tmp.v1.x, Tmp.v1.y); - if(node.zone.unlocked() && node.zone.preview != null){ - stack.add(new Table(t -> t.margin(4f).add(new Image(node.zone.preview) - .setScaling(Scaling.stretch)).color(Color.DARK_GRAY).grow())); - }else{ - stack.add(new Table(t -> t.margin(4f).add(new Image("whiteui", Color.BLACK).setScaling(Scaling.stretch)).grow())); - } - + stack.add(new Table(t -> t.margin(4f).add(new Image(node.zone.preview != null ? node.zone.preview : nomap).setScaling(Scaling.stretch)).color(node.zone.unlocked() ? Color.DARK_GRAY : Color.fromGray(0.2f)).grow())); stack.update(() -> stack.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f, Align.center)); Button button = new Button("square"); @@ -235,6 +235,7 @@ public class DeployDialog extends FloatingDialog{ for(ZoneNode node : nodes){ for(ZoneNode child : node.allChildren){ Lines.stroke(UnitScl.dp.scl(4f), node.zone.locked() || child.zone.locked() ? Pal.gray : Pal.gray); + Draw.alpha(parentAlpha); Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java index 83c0ca4f2c..41790548a8 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MinimapDialog.java @@ -30,6 +30,7 @@ public class MinimapDialog extends FloatingDialog{ t.addRect((x, y, width, height) -> { if(renderer.minimap.getRegion() == null) return; Draw.color(Color.WHITE); + Draw.alpha(parentAlpha); Draw.rect(renderer.minimap.getRegion(), x + width / 2f, y + height / 2f, width, height); if(renderer.minimap.getTexture() != null){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java index 1ff99705c4..a3d0ce2c9a 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java @@ -151,29 +151,9 @@ public class ZoneInfoDialog extends FloatingDialog{ hide(); control.playZone(zone); } - }).minWidth(150f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !canUnlock(zone) : !data.hasItems(zone.getLaunchCost())).uniformY().get(); + }).minWidth(150f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !zone.canUnlock() : !data.hasItems(zone.getLaunchCost())).uniformY().get(); button.row(); button.add(iteminfo); } - - private boolean canUnlock(Zone zone){ - if(data.isUnlocked(zone)){ - return true; - } - - for(ZoneRequirement other : zone.zoneRequirements){ - if(other.zone.bestWave() < other.wave){ - return false; - } - } - - for(Block other : zone.blockRequirements){ - if(!data.isUnlocked(other)){ - return false; - } - } - - return true; - } } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 0079062142..61fc8230c5 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -280,7 +280,7 @@ public class Block extends BlockStorage{ Geometry.circle(tile.x, tile.y, range, (x, y) -> { Tile other = world.ltile(x, y); if(other != null && other.block instanceof PowerNode && ((PowerNode)other.block).linkValid(other, tile) && !other.entity.proximity().contains(tile) && - !tile.entity.proximity().contains(p -> p.entity != null && p.entity.power != null && p.entity.power.graph == other.entity.power.graph)){ + !(outputsPower && tile.entity.proximity().contains(p -> p.entity != null && p.entity.power != null && p.entity.power.graph == other.entity.power.graph))){ tempTiles.add(other); } }); diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index b0738925c3..05e0f6c1ac 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -220,7 +220,7 @@ public class Tile implements Position, TargetTrait{ } public boolean isEnemyCheat(){ - return getTeam() == waveTeam && !state.rules.pvp; + return getTeam() == waveTeam && state.rules.enemyCheat; } public boolean isLinked(){ 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 f3816f9a15..a32572b893 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -235,7 +235,7 @@ public class PowerNode extends PowerBlock{ } public boolean linkValid(Tile tile, Tile link, boolean checkMaxNodes){ - if(tile == link || link == null || !link.block().hasPower || tile.getTeam() != link.getTeam()) return false; + if(tile == link || link == null || link.entity == null || tile.entity == null || !link.block().hasPower || tile.getTeam() != link.getTeam()) return false; if(overlaps(tile, link, laserRange * tilesize) || (link.block() instanceof PowerNode && overlaps(link, tile, link.cblock().laserRange * tilesize))){ if(checkMaxNodes && link.block() instanceof PowerNode){