From 19a4dd41e3d5995c59666df76dc04c20a3da87f2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 3 Dec 2017 12:02:48 -0500 Subject: [PATCH] Balanced all enemies, tweaked waves --- core/src/io/anuke/mindustry/Vars.java | 2 +- core/src/io/anuke/mindustry/core/Control.java | 72 +------ .../anuke/mindustry/entities/BulletType.java | 4 +- .../anuke/mindustry/entities/EnemySpawn.java | 12 +- .../anuke/mindustry/entities/WaveCreator.java | 201 ++++++++++++++++++ .../entities/enemies/BlastEnemy.java | 5 +- .../mindustry/entities/enemies/EmpEnemy.java | 3 +- .../mindustry/entities/enemies/Enemy.java | 6 +- .../mindustry/entities/enemies/FastEnemy.java | 9 +- .../entities/enemies/FlamerEnemy.java | 3 +- .../entities/enemies/FortressEnemy.java | 8 +- .../entities/enemies/HealerEnemy.java | 3 +- .../entities/enemies/MortarEnemy.java | 5 +- .../entities/enemies/RapidEnemy.java | 5 +- .../mindustry/entities/enemies/TankEnemy.java | 5 +- .../entities/enemies/TargetEnemy.java | 5 +- .../mindustry/entities/enemies/TestEnemy.java | 3 +- .../entities/enemies/TitanEnemy.java | 11 +- .../entities/enemies/flying/FlyingEnemy.java | 11 + core/src/io/anuke/mindustry/input/Input.java | 4 +- core/src/io/anuke/mindustry/io/SaveIO.java | 3 +- .../anuke/mindustry/resource/ItemStack.java | 4 + .../io/anuke/mindustry/resource/Recipe.java | 36 ++-- .../src/io/anuke/mindustry/ui/LoadDialog.java | 2 +- .../io/anuke/mindustry/world/Generator.java | 6 +- .../world/blocks/ProductionBlocks.java | 1 + .../mindustry/world/blocks/WeaponBlocks.java | 4 +- .../mindustry/world/blocks/types/Wall.java | 2 +- .../world/blocks/types/defense/Turret.java | 1 + .../world/blocks/types/production/Drill.java | 4 +- .../blocks/types/production/Generator.java | 2 +- desktop/mindustry-saves/0.mins | Bin 3828 -> 8862 bytes desktop/mindustry-saves/1.mins | Bin 3707 -> 13400 bytes desktop/mindustry-saves/2.mins | Bin 3663 -> 17639 bytes 34 files changed, 304 insertions(+), 138 deletions(-) create mode 100644 core/src/io/anuke/mindustry/entities/WaveCreator.java create mode 100644 core/src/io/anuke/mindustry/entities/enemies/flying/FlyingEnemy.java diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index ad34385288..3403d4d2cc 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -43,7 +43,7 @@ public class Vars{ //whether to draw chunk borders public static boolean debugChunks = false; //whether turrets have infinite ammo (only with debug) - public static boolean infiniteAmmo = false; + public static boolean infiniteAmmo = true; //whether to show paths of enemies public static boolean showPaths = true; //number of save slots-- increasing may lead to layout issues diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 2b96963d48..63dc8719f6 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -9,14 +9,15 @@ import com.badlogic.gdx.input.GestureDetector; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.reflect.ClassReflection; -import com.badlogic.gdx.utils.reflect.Constructor; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.effect.Fx; -import io.anuke.mindustry.entities.enemies.*; +import io.anuke.mindustry.entities.enemies.BlastEnemy; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.HealerEnemy; import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.GestureHandler; import io.anuke.mindustry.input.Input; @@ -113,61 +114,8 @@ public class Control extends Module{ player = new Player(); - spawns = Array.with( - new EnemySpawn(TitanEnemy.class){{ - after = 5; - spacing = 2; - scaling = 5; - }}, - new EnemySpawn(FortressEnemy.class){{ - after = 12; - spacing = 3; - scaling = 5; - }}, - new EnemySpawn(HealerEnemy.class){{ - scaling = 3; - spacing = 2; - after = 8; - }}, - new EnemySpawn(Enemy.class){{ - scaling = 3; - tierscaleback = 3; - }}, - new EnemySpawn(FastEnemy.class){{ - after = 2; - scaling = 3; - }}, - new EnemySpawn(FlamerEnemy.class){{ - after = 14; - spacing = 5; - scaling = 2; - }}, - new EnemySpawn(BlastEnemy.class){{ - after = 12; - spacing = 2; - scaling = 3; - }}, - new EnemySpawn(RapidEnemy.class){{ - after = 7; - spacing = 3; - scaling = 3; - }}, - new EnemySpawn(EmpEnemy.class){{ - after = 19; - spacing = 3; - scaling = 5; - }}, - new EnemySpawn(TankEnemy.class){{ - after = 4; - spacing = 2; - scaling = 3; - }}, - new EnemySpawn(MortarEnemy.class){{ - after = 20; - spacing = 3; - scaling = 5; - }} - ); + spawns = WaveCreator.getSpawns(); + WaveCreator.testWaves(1, 30); } public void reset(){ @@ -290,9 +238,9 @@ public class Control extends Module{ Timers.run(index*50f, ()->{ try{ - Constructor c = ClassReflection.getConstructor(spawn.type, int.class); - Enemy enemy = (Enemy)c.newInstance(fl); + Enemy enemy = ClassReflection.newInstance(spawn.type); enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range)); + enemy.spawn = fl; enemy.tier = spawn.tier(wave, fl); Effects.effect(Fx.spawn, enemy); enemy.add(enemyGroup); @@ -466,15 +414,15 @@ public class Control extends Module{ if(Inputs.keyUp(Keys.Y)){ if(Inputs.keyDown(Keys.SHIFT_LEFT)){ - new HealerEnemy(0).set(player.x, player.y).add(); + new HealerEnemy().set(player.x, player.y).add(); }else{ float px = player.x, py = player.y; - Timers.run(30f, ()->new BlastEnemy(0).set(px, py).add()); + Timers.run(30f, ()->new BlastEnemy().set(px, py).add()); } } } - if(shouldUpdateItems && Timers.get("updateItems", 8)){ + if(shouldUpdateItems && (Timers.get("updateItems", 8) || GameState.is(State.paused))){ ui.updateItems(); shouldUpdateItems = false; } diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 12de2f69d5..23818dfb76 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -232,14 +232,14 @@ public abstract class BulletType extends BaseBulletType{ } public void draw(Bullet b){} }, - small = new BulletType(1.5f, 1){ + small = new BulletType(1.5f, 2){ public void draw(Bullet b){ Draw.color(glowy); Draw.rect("shot", b.x, b.y, b.angle() - 45); Draw.reset(); } }, - smallSlow = new BulletType(1.2f, 1){ + smallSlow = new BulletType(1.2f, 2){ public void draw(Bullet b){ Draw.color("orange"); Draw.rect("shot", b.x, b.y, b.angle() - 45); diff --git a/core/src/io/anuke/mindustry/entities/EnemySpawn.java b/core/src/io/anuke/mindustry/entities/EnemySpawn.java index 1e47e49094..27805bc200 100644 --- a/core/src/io/anuke/mindustry/entities/EnemySpawn.java +++ b/core/src/io/anuke/mindustry/entities/EnemySpawn.java @@ -4,14 +4,24 @@ import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.ucore.util.Mathf; public class EnemySpawn{ + /**The enemy type spawned*/ public final Class type; + /**When this spawns should end*/ protected int before = Integer.MAX_VALUE; + /**When this spawns should start*/ protected int after; + /**The spacing, in waves, of spawns. 2 = spawns every other wave*/ protected int spacing = 1; + /**How many waves need to pass after the start of this spawn for the tier to increase by one*/ protected int tierscale = 15; + /**How many less enemies there are, every time the tier increases*/ protected int tierscaleback = 1; + /**Maximum amount of enemies that spawn*/ protected int max = 17; + /**How many waves need to pass before the amount of enemies increases by 1*/ protected float scaling = 9999f; + /**Amount of enemies spawned initially, with no scaling*/ + protected int amount = 1; public EnemySpawn(Class type){ this.type = type; @@ -21,7 +31,7 @@ public class EnemySpawn{ if(wave < after || wave > before || (wave - after) % spacing != 0){ return 0; } - return Math.min(1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max); + return Math.min(amount-1 + 1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max); } public int tier(int wave, int lane){ diff --git a/core/src/io/anuke/mindustry/entities/WaveCreator.java b/core/src/io/anuke/mindustry/entities/WaveCreator.java new file mode 100644 index 0000000000..bdc7a1fc6b --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/WaveCreator.java @@ -0,0 +1,201 @@ +package io.anuke.mindustry.entities; + +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.reflect.ClassReflection; + +import io.anuke.mindustry.entities.enemies.*; + +public class WaveCreator{ + + public static Array getSpawns(){ + //TODO + //Gdx.app.exit(); + return Array.with( + new EnemySpawn(Enemy.class){{ + scaling = 1; + before = 3; + }}, + + new EnemySpawn(FastEnemy.class){{ + scaling = 1; + after = 3; + spacing = 5; + amount = 4; + tierscaleback = 0; + }}, + + new EnemySpawn(BlastEnemy.class){{ + after = 4; + amount = 3; + spacing = 5; + scaling = 1; + tierscaleback = 0; + }}, + + new EnemySpawn(TankEnemy.class){{ + after = 5; + spacing = 5; + scaling = 1; + amount = 2; + }}, + + new EnemySpawn(RapidEnemy.class){{ + after = 7; + spacing = 5; + scaling = 2; + amount = 3; + }}, + + new EnemySpawn(HealerEnemy.class){{ + after = 5; + spacing = 5; + scaling = 1; + amount = 1; + }}, + + new EnemySpawn(TitanEnemy.class){{ + after = 6; + amount = 2; + spacing = 5; + scaling = 3; + }}, + + new EnemySpawn(FlamerEnemy.class){{ + after = 12; + amount = 3; + spacing = 5; + scaling = 2; + }}, + + new EnemySpawn(BlastEnemy.class){{ + after = 4 + 5 + 5; + amount = 3; + spacing = 5; + scaling = 1; + tierscaleback = 0; + }}, + //boss wave + new EnemySpawn(FortressEnemy.class){{ + after = 16; + amount = 2; + spacing = 5; + scaling = 1; + }}, + + new EnemySpawn(TitanEnemy.class){{ + after = 16; + amount = 2; + spacing = 5; + scaling = 3; + tierscaleback = 0; + }}, + + new EnemySpawn(HealerEnemy.class){{ + after = 16; + spacing = 5; + scaling = 1; + amount = 2; + }}, + //end boss wave + + //enchanced boss wave + new EnemySpawn(MortarEnemy.class){{ + after = 16 + 5; + amount = 1; + spacing = 5; + scaling = 1; + }}, + + new EnemySpawn(EmpEnemy.class){{ + after = 16 + 5; + amount = 1; + spacing = 5; + scaling = 1; + }} + //end enchanced boss wave + ); + } + + public static Array getSpawnsOld(){ + return Array.with( + new EnemySpawn(Enemy.class){{ + scaling = 2; + before = 4; + }}, + new EnemySpawn(Enemy.class){{ + scaling = 3; + tierscaleback = 3; + spacing = 2; + after = 4; + }}, + new EnemySpawn(TitanEnemy.class){{ + after = 5; + spacing = 2; + scaling = 5; + }}, + new EnemySpawn(FortressEnemy.class){{ + after = 12; + spacing = 3; + scaling = 5; + }}, + new EnemySpawn(HealerEnemy.class){{ + scaling = 3; + spacing = 2; + after = 8; + }}, + new EnemySpawn(FastEnemy.class){{ + after = 2; + scaling = 3; + }}, + new EnemySpawn(FlamerEnemy.class){{ + after = 14; + spacing = 5; + scaling = 2; + }}, + new EnemySpawn(BlastEnemy.class){{ + after = 12; + spacing = 2; + scaling = 3; + }}, + new EnemySpawn(RapidEnemy.class){{ + after = 7; + spacing = 3; + scaling = 3; + }}, + new EnemySpawn(EmpEnemy.class){{ + after = 19; + spacing = 3; + scaling = 5; + }}, + new EnemySpawn(TankEnemy.class){{ + after = 4; + spacing = 2; + scaling = 3; + }}, + new EnemySpawn(MortarEnemy.class){{ + after = 20; + spacing = 3; + scaling = 5; + }} + ); + } + + public static void testWaves(int from, int to){ + Array spawns = getSpawns(); + for(int i = from; i <= to; i ++){ + System.out.print(i+": "); + int total = 0; + for(EnemySpawn spawn : spawns){ + int a = spawn.evaluate(i, 0); + int t = spawn.tier(i, 0); + total += a; + + if(a > 0){ + System.out.print(a+"x" + ClassReflection.getSimpleName(spawn.type) + "-" + t + " "); + } + } + System.out.print(" (" + total + ")"); + System.out.println(); + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java index 9a40debd03..8b174a5b68 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java @@ -7,10 +7,9 @@ import io.anuke.mindustry.entities.TileEntity; public class BlastEnemy extends Enemy{ - public BlastEnemy(int spawn) { - super(spawn); + public BlastEnemy() { maxhealth = 30; - speed = 0.65f; + speed = 0.7f; bullet = null; turretrotatespeed = 0f; mass = 0.8f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java index cd9424a791..5215719e37 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java @@ -4,8 +4,7 @@ import io.anuke.mindustry.entities.BulletType; public class EmpEnemy extends Enemy{ - public EmpEnemy(int spawn) { - super(spawn); + public EmpEnemy() { speed = 0.27f; reload = 70; diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index e87552cb22..88d4660797 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -22,7 +22,7 @@ public class Enemy extends DestructibleEntity{ public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; public final static int maxtier = 4; - protected float speed = 0.3f; + protected float speed = 0.4f; protected float reload = 32; protected float range = 60; protected float length = 4; @@ -47,9 +47,7 @@ public class Enemy extends DestructibleEntity{ public Entity target; public int tier = 1; - public Enemy(int spawn) { - this.spawn = spawn; - + public Enemy() { hitbox.setSize(5f); hitboxTile.setSize(4f); diff --git a/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java index cd71689a20..01d80d0524 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java @@ -2,14 +2,13 @@ package io.anuke.mindustry.entities.enemies; public class FastEnemy extends Enemy{ - public FastEnemy(int spawn) { - super(spawn); + public FastEnemy() { - speed = 0.7f; - reload = 30; + speed = 0.73f; + reload = 25; mass = 0.2f; - maxhealth = 30; + maxhealth = 40; heal(); } diff --git a/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java index d2832f1f3a..3c85c450a3 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java @@ -4,8 +4,7 @@ import io.anuke.mindustry.entities.BulletType; public class FlamerEnemy extends Enemy{ - public FlamerEnemy(int spawn) { - super(spawn); + public FlamerEnemy() { speed = 0.35f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java index 94f82ce501..a925814e1c 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java @@ -13,10 +13,9 @@ public class FortressEnemy extends Enemy{ float spawnTime = 240; boolean deployed; - public FortressEnemy(int spawn) { - super(spawn); + public FortressEnemy() { - speed = 0.12f; + speed = 0.2f; reload = 90; maxhealth = 700; range = 70f; @@ -38,7 +37,8 @@ public class FortressEnemy extends Enemy{ if(Timers.get(this, "spawn", spawnTime) && spawned < maxSpawn){ Angles.translation(angle, 20f); - FastEnemy enemy = new FastEnemy(spawn); + FastEnemy enemy = new FastEnemy(); + enemy.spawn = spawn; enemy.tier = this.tier; enemy.spawner = this; enemy.set(x + Angles.x(), y + Angles.y()); diff --git a/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java index 45fe62720a..886662d797 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java @@ -13,8 +13,7 @@ import io.anuke.ucore.util.Angles; public class HealerEnemy extends Enemy{ - public HealerEnemy(int spawn) { - super(spawn); + public HealerEnemy() { speed = 0.2f; reload = 14; diff --git a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java index adfac7e879..9df78bf784 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java @@ -4,11 +4,10 @@ import io.anuke.mindustry.entities.BulletType; public class MortarEnemy extends Enemy{ - public MortarEnemy(int spawn) { - super(spawn); + public MortarEnemy() { maxhealth = 200; - speed = 0.2f; + speed = 0.25f; reload = 100f; bullet = BulletType.shell; turretrotatespeed = 0.15f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java index 3f06326a86..44948908eb 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java @@ -4,14 +4,13 @@ import io.anuke.mindustry.entities.BulletType; public class RapidEnemy extends Enemy{ - public RapidEnemy(int spawn) { - super(spawn); + public RapidEnemy() { reload = 8; bullet = BulletType.purple; rotatespeed = 0.08f; maxhealth = 260; - speed = 0.27f; + speed = 0.33f; heal(); hitbox.setSize(8f); mass = 3f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java index 265d526c28..4ca5a514ed 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java @@ -7,11 +7,10 @@ import io.anuke.ucore.util.Angles; public class TankEnemy extends Enemy{ - public TankEnemy(int spawn) { - super(spawn); + public TankEnemy() { maxhealth = 350; - speed = 0.2f; + speed = 0.24f; reload = 90f; rotatespeed = 0.06f; bullet = BulletType.small; diff --git a/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java index a2e319e27a..5ec216e001 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java @@ -9,8 +9,7 @@ import io.anuke.ucore.core.Timers; public class TargetEnemy extends Enemy{ - public TargetEnemy(int spawn){ - super(0); + public TargetEnemy(){ speed = 0f; maxhealth = 10; } @@ -48,7 +47,7 @@ public class TargetEnemy extends Enemy{ public void onDeath(){ super.onDeath(); Timers.run(100f, ()->{ - new TargetEnemy(0).set(x, y).add(); + new TargetEnemy().set(x, y).add(); }); } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/TestEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TestEnemy.java index cd1a714bbf..56da2fdcfa 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/TestEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/TestEnemy.java @@ -5,8 +5,7 @@ import io.anuke.ucore.core.Timers; public class TestEnemy extends Enemy{ boolean dir = false; - public TestEnemy(int spawn) { - super(spawn); + public TestEnemy() { maxhealth = 99999; heal(); } diff --git a/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java index d2e3d14318..d7c78920d5 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java @@ -7,12 +7,11 @@ import io.anuke.ucore.util.Mathf; public class TitanEnemy extends Enemy{ - public TitanEnemy(int spawn) { - super(spawn); + public TitanEnemy() { - speed = 0.14f; + speed = 0.22f; reload = 30; - maxhealth = 400; + maxhealth = 421; range = 60f; bullet = BulletType.small; hitbox.setSize(7f); @@ -27,7 +26,7 @@ public class TitanEnemy extends Enemy{ @Override void updateShooting(){ - Timers.get(this, "salvo", 250); + Timers.get(this, "salvo", 240); if(Timers.getTime(this, "salvo") < 60){ if(Timers.get(this, "salvoShoot", 6)){ @@ -35,7 +34,7 @@ public class TitanEnemy extends Enemy{ } } - if(Timers.get(this, "shotgun", 90)){ + if(Timers.get(this, "shotgun", 80)){ Angles.shotgun(5, 10f, 0f, f->{ shoot(BulletType.smallSlow, f); }); diff --git a/core/src/io/anuke/mindustry/entities/enemies/flying/FlyingEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/flying/FlyingEnemy.java new file mode 100644 index 0000000000..2fbb27ff14 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/flying/FlyingEnemy.java @@ -0,0 +1,11 @@ +package io.anuke.mindustry.entities.enemies.flying; + +import io.anuke.mindustry.entities.enemies.Enemy; + +public class FlyingEnemy extends Enemy{ + + public FlyingEnemy() { + + } + +} diff --git a/core/src/io/anuke/mindustry/input/Input.java b/core/src/io/anuke/mindustry/input/Input.java index f2092fc956..7dc2c67d96 100644 --- a/core/src/io/anuke/mindustry/input/Input.java +++ b/core/src/io/anuke/mindustry/input/Input.java @@ -7,6 +7,8 @@ import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.core.GameState; +import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Tile; @@ -23,7 +25,7 @@ public class Input{ //player is dead if(player.health <= 0) return; - if(Inputs.scrolled()){ + if(Inputs.scrolled() && GameState.is(State.playing)){ Vars.renderer.scaleCamera(Inputs.scroll()); } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index d812253195..b1e5b2d6c6 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -357,7 +357,8 @@ public class SaveIO{ int health = stream.readInt(); try{ - Enemy enemy = (Enemy)ClassReflection.getConstructor(enemyIDs.get(type), int.class).newInstance(lane); + Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type)); + enemy.spawn = lane; enemy.health = health; enemy.x = x; enemy.y = y; diff --git a/core/src/io/anuke/mindustry/resource/ItemStack.java b/core/src/io/anuke/mindustry/resource/ItemStack.java index c402284766..9d6bceb017 100644 --- a/core/src/io/anuke/mindustry/resource/ItemStack.java +++ b/core/src/io/anuke/mindustry/resource/ItemStack.java @@ -9,4 +9,8 @@ public class ItemStack{ this.item = item; this.amount = amount; } + + public boolean equals(ItemStack other){ + return other != null && other.item == item && other.amount == amount; + } } diff --git a/core/src/io/anuke/mindustry/resource/Recipe.java b/core/src/io/anuke/mindustry/resource/Recipe.java index 636931ee74..06c6295380 100644 --- a/core/src/io/anuke/mindustry/resource/Recipe.java +++ b/core/src/io/anuke/mindustry/resource/Recipe.java @@ -19,7 +19,7 @@ public enum Recipe{ duriumwalllarge(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 8)), door(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3)), largedoor(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4)), - titaniumshieldwall(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 2)), + titaniumshieldwall(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 3)), conveyor(distribution, DistributionBlocks.conveyor, stack(Item.stone, 1)), steelconveyor(distribution, DistributionBlocks.steelconveyor, stack(Item.steel, 1)), @@ -43,36 +43,36 @@ public enum Recipe{ mortarturret(weapon, WeaponBlocks.mortarturret, stack(Item.steel, 20), stack(Item.titanium, 15)), teslaturret(weapon, WeaponBlocks.teslaturret, stack(Item.steel, 10), stack(Item.titanium, 15), stack(Item.dirium, 15)), plasmaturret(weapon, WeaponBlocks.plasmaturret, stack(Item.steel, 10), stack(Item.titanium, 10), stack(Item.dirium, 15)), - chainturret(weapon, WeaponBlocks.chainturret, stack(Item.steel, 10), stack(Item.titanium, 10), stack(Item.dirium, 15)), - titanturret(weapon, WeaponBlocks.titanturret, stack(Item.steel, 10), stack(Item.titanium, 10), stack(Item.dirium, 15)), + chainturret(weapon, WeaponBlocks.chainturret, stack(Item.steel, 35), stack(Item.titanium, 25), stack(Item.dirium, 35)), + titanturret(weapon, WeaponBlocks.titanturret, stack(Item.steel, 50), stack(Item.titanium, 45), stack(Item.dirium, 55)), smelter(crafting, ProductionBlocks.smelter, stack(Item.stone, 40), stack(Item.iron, 40)), crucible(crafting, ProductionBlocks.crucible, stack(Item.titanium, 40), stack(Item.steel, 40)), coalpurifier(crafting, ProductionBlocks.coalpurifier, stack(Item.steel, 10), stack(Item.iron, 10)), titaniumpurifier(crafting, ProductionBlocks.titaniumpurifier, stack(Item.steel, 30), stack(Item.iron, 30)), - oilrefinery(crafting, ProductionBlocks.oilrefinery, stack(Item.steel, 30), stack(Item.iron, 30)), - stoneformer(crafting, ProductionBlocks.stoneformer, stack(Item.steel, 30), stack(Item.iron, 30)), - lavasmelter(crafting, ProductionBlocks.lavasmelter, stack(Item.steel, 30), stack(Item.iron, 30)), + oilrefinery(crafting, ProductionBlocks.oilrefinery, stack(Item.steel, 15), stack(Item.iron, 15)), + stoneformer(crafting, ProductionBlocks.stoneformer, stack(Item.steel, 10), stack(Item.iron, 10)), + lavasmelter(crafting, ProductionBlocks.lavasmelter, stack(Item.steel, 20), stack(Item.iron, 20), stack(Item.titanium, 10)), stonedrill(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)), irondrill(production, ProductionBlocks.irondrill, stack(Item.stone, 25)), coaldrill(production, ProductionBlocks.coaldrill, stack(Item.stone, 25), stack(Item.iron, 40)), titaniumdrill(production, ProductionBlocks.titaniumdrill, stack(Item.iron, 40), stack(Item.steel, 40)), - uraniumdrill(production, ProductionBlocks.uraniumdrill, stack(Item.titanium, 20), stack(Item.steel, 40)), - omnidrill(production, ProductionBlocks.omnidrill, stack(Item.titanium, 20), stack(Item.dirium, 20)), + uraniumdrill(production, ProductionBlocks.uraniumdrill, stack(Item.iron, 40), stack(Item.steel, 40)), + omnidrill(production, ProductionBlocks.omnidrill, stack(Item.titanium, 30), stack(Item.dirium, 20)), - coalgenerator(power, ProductionBlocks.coalgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)), - thermalgenerator(power, ProductionBlocks.thermalgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)), - combustiongenerator(power, ProductionBlocks.combustiongenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)), - rtgenerator(power, ProductionBlocks.rtgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)), - nuclearreactor(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 10), stack(Item.dirium, 10)), - powerbooster(power, DistributionBlocks.powerbooster, stack(Item.titanium, 10), stack(Item.dirium, 10)), - powerlaser(power, DistributionBlocks.powerlaser, stack(Item.titanium, 10), stack(Item.dirium, 10)), - powerlaserrouter(power, DistributionBlocks.powerlaserrouter, stack(Item.titanium, 10), stack(Item.dirium, 10)), + coalgenerator(power, ProductionBlocks.coalgenerator, stack(Item.iron, 30), stack(Item.stone, 20)), + thermalgenerator(power, ProductionBlocks.thermalgenerator, stack(Item.steel, 30), stack(Item.iron, 30)), + combustiongenerator(power, ProductionBlocks.combustiongenerator, stack(Item.iron, 30), stack(Item.stone, 20)), + rtgenerator(power, ProductionBlocks.rtgenerator, stack(Item.titanium, 20), stack(Item.steel, 20)), + nuclearreactor(power, ProductionBlocks.nuclearReactor, stack(Item.titanium, 40), stack(Item.dirium, 40), stack(Item.steel, 50)), + powerbooster(power, DistributionBlocks.powerbooster, stack(Item.steel, 8), stack(Item.iron, 8)), + powerlaser(power, DistributionBlocks.powerlaser, stack(Item.steel, 3), stack(Item.iron, 3)), + powerlaserrouter(power, DistributionBlocks.powerlaserrouter, stack(Item.steel, 5), stack(Item.iron, 5)), - shieldgenerator(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 10), stack(Item.dirium, 10)), + shieldgenerator(power, DefenseBlocks.shieldgenerator, stack(Item.titanium, 30), stack(Item.dirium, 40)), - teleporter(distribution, DistributionBlocks.teleporter, stack(Item.titanium, 10), stack(Item.dirium, 10)), + teleporter(distribution, DistributionBlocks.teleporter, stack(Item.steel, 20), stack(Item.dirium, 15)), healturret(power, DefenseBlocks.repairturret, stack(Item.iron, 30)), megahealturret(power, DefenseBlocks.megarepairturret, stack(Item.iron, 20), stack(Item.steel, 30)), diff --git a/core/src/io/anuke/mindustry/ui/LoadDialog.java b/core/src/io/anuke/mindustry/ui/LoadDialog.java index f1d8d69bfb..5baf7f27d9 100644 --- a/core/src/io/anuke/mindustry/ui/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/LoadDialog.java @@ -52,7 +52,7 @@ public class LoadDialog extends FloatingDialog{ for(int i = 0; i < Vars.saveSlots; i++){ final int slot = i; - TextButton button = new TextButton("[orange]Slot " + (i + 1)); + TextButton button = new TextButton("[accent]Slot " + (i + 1)); button.pad(Unit.dp.inPixels(12)); button.getLabelCell().top().left().growX(); diff --git a/core/src/io/anuke/mindustry/world/Generator.java b/core/src/io/anuke/mindustry/world/Generator.java index a1b29667be..b6109f5243 100644 --- a/core/src/io/anuke/mindustry/world/Generator.java +++ b/core/src/io/anuke/mindustry/world/Generator.java @@ -86,11 +86,11 @@ public class Generator{ floor = Blocks.coal; } - if(Noise.nnoise(x + 9999, y + 9999, 8, 1) > 0.253){ + if(Noise.nnoise(x + 9999, y + 9999, 8, 1) > 0.264){ floor = Blocks.titanium; } - if(Noise.nnoise(x + 99999, y + 99999, 7, 1) > 0.258){ + if(Noise.nnoise(x + 99999, y + 99999, 7, 1) > 0.259){ floor = Blocks.uranium; } } @@ -112,7 +112,7 @@ public class Generator{ } if(color == Hue.rgb(Color.PURPLE)){ - if(!Vars.android) new TargetEnemy(0).set(x * Vars.tilesize, y * Vars.tilesize).add(); + if(!Vars.android) new TargetEnemy().set(x * Vars.tilesize, y * Vars.tilesize).add(); floor = Blocks.stone; } diff --git a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java index a76c189a28..bfb64aff8f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java @@ -151,6 +151,7 @@ public class ProductionBlocks{ stonedrill = new Drill("stonedrill"){{ resource = Blocks.stone; result = Item.stone; + time = 4; formalName = "stone drill"; description = "Mines 1 "+resource.name+" every "+time+" seconds."; fullDescription = "The essential drill. When placed on stone tiles, outputs stone at a slow pace indefinitely."; diff --git a/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java b/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java index 67b43d0ca0..3e315e9c0e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java @@ -74,8 +74,8 @@ public class WeaponBlocks{ bullet = BulletType.iron; ammo = Item.iron; health = 70; - shots = 7; - inaccuracy = 30f; + shots = 5; + inaccuracy = 15f; shotDelayScale = 0.7f; fullDescription = "A standard turret. Uses iron for ammo. Shoots a spread of 7 bullets. " + "Lower range, but higher damage output than the gattling turret."; diff --git a/core/src/io/anuke/mindustry/world/blocks/types/Wall.java b/core/src/io/anuke/mindustry/world/blocks/types/Wall.java index e2f2afefc7..f5f15533e5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/Wall.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/Wall.java @@ -11,7 +11,7 @@ public class Wall extends Block{ } public boolean canReplace(Block other){ - return other instanceof Wall; + return other instanceof Wall && health > other.health; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java index 32ef2ec8e8..b0cb9402f8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java @@ -228,6 +228,7 @@ public class Turret extends Block{ bullet(tile, entity.rotation + Mathf.range(inaccuracy)); }else{ Timers.run(i * shotDelayScale, ()->{ + Angles.translation(entity.rotation, width * Vars.tilesize / 2f); bullet(tile, entity.rotation + Mathf.range(inaccuracy)); }); } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/types/production/Drill.java index 72cb20bdd2..f9a67be841 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/Drill.java @@ -33,7 +33,7 @@ public class Drill extends Block{ @Override public void update(Tile tile){ - if(tile.floor() == resource && Timers.get(tile, "drill", 60 * time) && tile.entity.totalItems() < capacity){ + if((tile.floor() == resource || (resource.drops.equals(tile.floor().drops))) && Timers.get(tile, "drill", 60 * time) && tile.entity.totalItems() < capacity){ offloadNear(tile, result); Effects.effect(Fx.spark, tile.worldx(), tile.worldy()); } @@ -45,7 +45,7 @@ public class Drill extends Block{ @Override public void drawOver(Tile tile){ - if(tile.floor() != resource && resource != null){ + if(tile.floor() != resource && !(resource.drops.equals(tile.floor().drops)) && resource != null){ Draw.colorl(0.85f + Mathf.absin(Timers.time(), 6f, 0.15f)); Draw.rect("cross", tile.worldx(), tile.worldy()); Draw.color(); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java b/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java index 70a4b931ab..c8061930f0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java @@ -58,7 +58,7 @@ public class Generator extends PowerBlock{ Effects.effect(Fx.shockwave, x, y); Timers.run(12f + Mathf.random(20f), () -> { - tile.damageNearby(3, 40, 0f); + tile.damageNearby(4, 40, 0f); }); Effects.sound(explosionSound, x, y); diff --git a/desktop/mindustry-saves/0.mins b/desktop/mindustry-saves/0.mins index 2badafeb22c63fda688f9b25b507b3b3efeffda2..bffadbd2494854ad53ae60fd1427d420c474720c 100644 GIT binary patch literal 8862 zcmZQzVBle3U`&vDai5=ok%57M$z|f6i!M3M#x7#b#taM$DGW>?VJij(28JRK!N6F* zf`NgVm4RWK2$(Oyz;H+$#=0R5W4X(KS>g-~4G@+D14FzlOl&=bCBeXO0?xW52bPs! zV6c-1v&0z~{Nb#{5S9c3!!9`MIGlA0&bkL@`6|Fn34^mD;H)?}s|e284q-_!FkFPQ z?!Z}_6~X3#+ze;!QG$tCD#KWg5SBOtLjasL9m0}eU^ohAJ%Y2gslfE!hO9_!A*=vHu#2FYiLs$|F4CmmiOK_H!7FeAG1H)!G>olCzrwxRFEK@z0 zm^qwf1!oSu-Il2?mBVBbeS<5S9c3!y7m&36zr<7{nPERzX-23=C`FtetRHfeFl% zayV-NgeAeia2LW7XJAM(g{iBCvwGkxMKiFh1OtO3geA_v-~(YvFfar_SmF!}NpMyT zoV5|cl3-vs4QHK$vu;9I;tUMW;VeaSm~EC2mN)~0Bb?<5XZgWdwQ$yY2up&2!P)|B ziZ}y96`a)rXHA5&&Olfa3=Gd9EO7<~YfG5k95`z-oHYf`5(O7x3=#|s;&7HOoK*&4 zi8C-9g|I;R9L{dJJc&*~4^{Ls+0P7S8I0vxFRA>ZIVTQV2_&f#D#8 zCBeX;=?GId(HX|N3So&eFuZXGi-|KZ2zh{65)2F%AS`hPhD!*R7g$!Df#EZRCBeWj z!5b_l!N8#A17r32!dRyvEO7<~ML(FBGMuFXXL&$apqPQPl>K2koCCltaR!Ft5S9c3 z!xacioPps3oFy3uRtKtu;H=Yd)+Y!{oPmKa2&PUI&YA{iorkc*85pj@S=ZpK#9)}- za}X9Nr@&d^Au!nw5SBOtgKa2SOq_wi4$caOup}5565*^j5SBOtgHsqx$MJ9&>nfb} z7S0NZ0Lw}+Fr0+2#2FaQ!dcJYEcZyTI&lVucnC{^f#C~;CCj1?9oRt7)*~Woo#TgjFAS?+6h9WqtAI_4D z2dk4{U`T+o-auI53=Dn=U|CS>0nW;Tup}55mcm)9;jE1i7ARN1Syv$}2?hqgM3{N2 zAS?+6hTCw~LpZBE39L?nfuRe|nhIylfwOi(SfJ7Z!jfQMh)#y-jfJzWz*%?TtY>gm zK?+Pq4V<+F!V+g-*ac_phO-XCS@$6<2?hqkRIn+aln7@ zoV69g5@%r80cRb6vkt*o_aH0@28OV7uz8@G7{UUD8l1HQ!V+g-*a>ItgR>T7!1OML zv-ZPT7vU`POqjYj2n&>6;H(Zfs~66i4Pk*w8aT@=3ua0*)UVg;4C{h%OAp$U|^_(v*trs;tUKc;jC?N)^RxNI)nwPLvvtu?1Qu1 za$#Z}5EiKY3}J~gFr0+5ZbDcR3=GfUte0?>e?Hh02?mB7IBPS6CCU9eCOrlQFNhi7%FhVqHO6@i3_ef^P#C}^ zKu!sObnYY=7|P+S8aV3^geA_vZ~?-SU|?`7hJ*vM|2&GzL0m=#2G8OOD9fw363U7# z1~EVluze7gI0M5WI7`0-CTj{|i8C;`l|bwOc>x@Tj10GZI2jn+(Z!h<7*g698P?rk zVDKnu2N?u%14I?5>Bae~ZCDCt9fq@>Kv)tC3^uer1}mr-NDWwwiQ%HnABM$z?->}Z(d8H!7<>{K7;MnRnHU%>tr-~h zb22d4qRTNdFbK;rFxWxGLGA$C!^rp~;R6GMJ;ceNz=Ns)#Wh3)14G*s1_qDP=^#y@ z04kjUWqFm(gt8t$^h+=>yoIyO%8)$Iz`$S*;UkhQBg0jvJ_ZI0OmPNxNd^W>EaH|E z7#OUe;z%wOi&kV{u!e}cf}8|$xeYR(5friv3=Fo&f(#4{b`U@Q|uaKMmbWUvfmV0gEmfx!`7j)jrI|2QLqnkgg0-+zn@`>PokoY2)UF)%o3 zGBAAk$iU!?F2};a;D3UVLHIZW!=p3?hAvhH1{ZWS3=9me=wi%_3{f(S3_n5`7}^vW z7~G)p@IYf=U~q?sxqyNO6kr|@J|Zj_7#KXUhv;|u=uru2qF|S zFfcfwi!m}V)c;^$aDj+Jst1^DuGj?KkOdhS7`!2Ta3z4^Q6Go|qPBqWF%_-_7kQu% zxd~x`vJRZ}1Aa>jFExC_C5oH3#Pb+yDtNS7u>X4aF%r~*amS12A5h)8(bk`sF}qRqD6v% zVH%vZ0Kx)w9N{dNIxGf4#83@fQ3rFwMmXy@oOKbxl3-wPsmEda3uEJT) z%`hD?a8@Cl<<$a{^=pN(D&VZ?aMq~n5-|H1EMvJwmoli{puaMn{eOKvV$oj3!->v>?71OtQEd@xI# zfk6V!>V~i+7#RBDtjTbe%mSE>P6$hafuR@9>R1Stm0(~v4rlc*f{DF@v$_|<#Dtf? zSbcETEjUYLDNObZoHczJOl%dLCA1tS#ckls>L4r$28OAdz+w^%3|rx>GjNviX0WU{149RdCBeY363#jXXT5>5-osg+ z;4JAaFjLk;SP~2jlG|Wna&VR{oaF*%g~3^+5S9c3LlvC0AI?(V4l^$l&MJejBp4WK z;H+*qYXzJoy91_o4TL4Zz!13;CYAubtMoM$Tm1@F`Tsm&e{xT z9f7mn!dXGPVdfP@daMmR_OJxsChYOtL0cZKbS&?v7F@z<-!0-XilG+P1 zB>~QAgs>zS7&_ssX>gY6K9~+IILjQ)a)h&d;jCmhYc_-hDqr9%oBc5JHbYpT{03*) z9)QWNhOi_U7|y_13l4&1L16`FIUE9ui8C;G!CB=HmIMPsJ)AWk&e{uS)g1=w1(nZm z)+IRWA)Hlx1g5SX&gz4+Cc;@u;jB$?))hEQ{V3QJ(3~xVCBeWj3C@}gXDx)Y4#8PB z;H=wlR^2hMc@hi^4RF?MIBPSUbqLN{d>p3ZF`QL&0w#6<&bkF>sh$MOiZd{%!&%i3 z7RX*Ws}Iha4QH)}vv$B)FX1fBQ!tZb;j9V>3zYZatgUd?NjU2+oK<}qY>ET}!!o1}rPizz_^))j?Pi3=A!B)=W6d`z%aHGMqIH!jfQMm<4B@g|pnw!E^+`S)p*& zObAPYfnhG3bs5gO4QK5+4>m=Dfg$SxjCC5$x(H`^UIfdEGceR#0<$C-82aF>EpXON zI4kWkSRJUP1z~~4U*W8zD=^t?2up&2ArHb5XJBZ%3YL{%V7LiqWnKe|i8C-vhp<55 kasw;|n$?E0*27t6;H)V(Ve0n6S&MJO#16q(Tkk={04;W@y#N3J literal 3828 zcmZQzVBlt8U`&vR>iy2Z#=yY9=(23?JC|i9G0sy0<})xbq%g2EGRU>0GJ^;f2Dz37 zRuI7iA{ZFtTBfo=SRk#Aq6`d-;S3C^(hMLV#lVm)17a{pF)-xH!dPW+Rt21uDF>4+ zg0u1!VPfTQR)!KxtV9{c%2$E0s?=bta%~tZQ5VLlg0t%2tQtL-Y^gqs)nEW)oic&3 z&YHqlN6cZYvvAfi3z*m`IP0txOzeOSjCIxy#yaBwV_kEEu}(O_SQp?dXLp#`5f2#a znkS59=L2Ke`@&cWaMo-;nAie1YoW8y*qF`cna8?(bbr{YPkA|s}fU`W{ta3Q(3Y;Y! z1JmIKXI+J}9Ae?Ja8@gvbs5eQi-V~vfU_FmtmAN&R6I=GX*la5oaL4Pll6eJCcs&- zi7?sFBp53R&UyuB1t!B}gW#;gaMoowOCklPP72P-gR>66S^H99>h{A~r{JvmG??r` zIO|3_Ow2t4#@d|;V;zOF!n0svWpLI$IO{N+bpg)01!p~gv&6Guri8&+hvBT#aF%5b zOx->>>oJ^lAQvY4Bp=3lS^#66EP}D(ieaoZaMmU`Yd@TI56-$@0@IOJ3S%vSvzEbG zr{JtxaMoiuYgHLcZ%jFiRRd=&g|iM;z+{(K!dQt_FxDM7>rgdJ>`)DibrR0%s)dOy zfU{)lU}6z))`EJtSObhT2hO_Q2osys1Y=EwvyQ@9GR-hqBRFdQ;4GbfnAl4=OJM>`Oc~B{fU|PoEQN_Mbt-U{_9U2C3Y_%<&QhEVlU0JV z^x-UjILl}XOkMm`7|VDXj8z9`wZmCT(-{~U7#N&EYBU%a7?jcYDrkJA8DRCgAWb0k zAbrYM#8jYSAbFTNRfw1~GXnzyNK6gFM=?tsiolE zsmz2p5F`V#1VpRN1m`kF1_t$+;9SPYz@RY`oXZ#)7#wDT)PR~a&T!URI7?*~#5|C_ zVDp$5=5QG@WHKZ(FsP!-u`)2kCo?ce|72kJn8CoXhk=1%k}U&++AMH-1=$bLVadS2 zzyzu{HD-a+DkB5Ko>?$gsLY1g$OH{0kht3H=^zSZ!fdctK|Yubb|fPML*Q(XB*+Jg z;H(vJmdqTOtkN8a$#B1bA{>jD3RDc)1*#A+XP90!2p=`_u!w0u#4sao0o++j;Vh-O zUnBN|@?jlW|q%xiKBV5}}UYd4%FxdLYWLw~@1#s5&B`{f)rC`@- zg81Nuiz>Q+8oEH#QjlU$%v^`FZo*j#%V4r9%g~KR5nyCsP(u-5U|>jsYu*WGsVqk~ z2329F>@+xQC!E!H5+*wt&RPm*IiG^b zmcv=g;VhfeFj)sUYswjz*mO8+`B|8l%Q+Zp5}Y*`&RPLyIi829TMB0_x&RZ~3}?-{ x2oqZmXL($PiTT1=esGrWRhVquH5hBz4Hzr<9*h+NXRW*s6H9pnW2HZZumGJKoh$$V diff --git a/desktop/mindustry-saves/1.mins b/desktop/mindustry-saves/1.mins index a5297efc389d47732d2b95726b74057c5bcebdeb..d780fe1229eabf6ba381cf818af4c7686244dd96 100644 GIT binary patch literal 13400 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 W%1xNMy>Qmz+c2?1aMsp)5HSGaiH>~$ literal 3707 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%0D~I?3xgt~ zGDAHhDC{H|k{Fm7WEqthYMA~qd}9z~@L=L(0Il{HWdN0PAou)Yc+0So;XVU{Gc+E- zYq z@N{Ec3$g@MN4wObr649ohI9^wm7s-6t`IqJpG*a01xQmEL=arBK#BzsCrM*T28Qrj zSayo2g=ME{5PKvT7#2WSpjD=DmP;L)-HZ$id2cf?xI)Ci_QJcqVGuz?QU}$s)0uu| zU1xe1yqSr?<}VYgnkv&rfqhK>|2$_BeHy~_`NCnQS9?}6@vN|5dOKw!lVn2@14B5( z9B}Z=1rEjn2?hp}2ACV18z4>xMJB98<^mOim0S#r3@e2- z85mq4;$ZI}Vjm(1_5|1f4km{BV@wihsZ1~3=QI7%y~4yG%EI*W{{kkl=MhXlE?i<@ zXhvAy2(cbv6(d9J9R`Ll3~?rg-7gpzG8!#7ILo;i&1^hn zu`s9@JgyiR7%sKJT<`(T;ss9_fc$F=VTm&^m_t|+3=GcgSX=-RLtWVB3K2vkEKt8d zl!3twDvs=2U%2sMP+4S0I(ML130gF{hJnEaB93M)HbFOtAlNP72my_MNH8$Ccfhai`4A`X~rfPflbi1AM6OweoiwZlR0vCgf#DIHkDB?FfhD_vjnDsWhEFG`z*(24!AubV&!m7NRtmxrXJ9xDF4{q2Z)d^ONzVqe#2FZ- zL0F(&WpGwEXsr_iNXKM2>l&Q(6wZn4RF>jIO__WwPH2c4haT^>u}a>IBUilnCw9~>ja#22F|($ zX9=!_>DUfu9e}getb@tkgR?}}gT+A0S|BV528P{mRyk-H7C7ZJ!dYA3tQ~Nc@kW>_ zbr6;W1H;r!U@-{>hOKbc892*$GgwxffuRG!l3-w131=OHv);g2@8PUZaF#S^2m%}n z>me)&1_sG(Fq7rrEL%9s12?mBLIBP$grMw+xUMQSZ24P7sFx0?V-Eh_l zI7=4PxCXm#4TL4Zz!13;W?mYc)dXQlFfeR{vrKov)RjP3Alu-q#c#XGOwU#SoSR1H%V6OKLC7lms}d z5yFySVCaOiromaN`(Qe>;4E`E%Ms4W+cUlVD(IfU{=9S)1XkLvYsO<1ihM;jALiaS-5A985<5oD~XZ z&4jQd7#QZlS(o9g+i=z%(4igRSjf5nHV?ELAI`c6XL()(%Zf8F)La6yBp4X_;H)ih z)=fAo?J`&$sHFvANiZ-J!&ymJV6xc|mIMPs9)u;%z|eLTEGxmla1+kTyapB%XJD8P oVS&Qs23QPq!U3GM9?m)gXHB^YQ@0n+T6`NOb_mYedJiH704I;y5C8xG literal 3663 zcmZQzVBlt8U`&t*3lC;sV_;xlbou6b%4J5)V&~nrmoqRhq%g2EGRU=*FoOsd2Dz37 zRuI7iA{ZFtTH4qkECvP!hR#|B21YLihIDBVk3ouop$g8*k%ft+%E4G=a8`vpOsqx` z#;R9=v1(Oetb8>XD^C-~s?mnADs^D28eJHx0nR#U3KP3%4r86SfUyo)!&tj*VXP&N zFxC|(7;CXJjCITv#<~J$1-ik+PQzIt?l7^d9x&D=PZ-P03&y$zXSsXB#JYW8tT}L& zhA&La7|y!u4-?Z1fUz3jtjloLq#&4VK`@LJ9|B|b!C5!qtb|aQtYR39)d6SeMZv_X z;jCG3)@?ZJ9-QS84byP~&bk3-Imf_c)8VW#ILjptCR+e!6~)8E&cj*P;Vkh4m~0H3 zl>uj6fwM9bVd@URS(QmJv6N&O%RL3gx(H{9r^3X}!daqeFfk7}>kyo^EgdE+nE_*2 z!CA-PtRq=4*;8=VbvUae8z#E~&N>TcU4yfZ<-pY4fwSs!VPd=CtW$87cpgl4Z$6A= zUjSomfU{1+S!snZ*^O}4Q8?=~oOJ=tvMPe<*av5=EQX1lfwQbjU}6v9EYnh$SRI_T z1kPFwXVsL!)R|PkSVomF*0L%XYdM@{Pz@71R0Crju7$BK!dd2ZFtLenmUKN#Or`AO!db?RFxg3P)=4-ktO+I?(F|kBw!m0&aMrn2nAoN^80#pUrP>Y?i-NP}!&xig zthpU9b>f{cRuG(}+6@!4fwSJgS?WD7Sxq?09L`z~XB~&Lw)MhvY=^UU!C9~1tinE+ zx{`hvYYm*W3C`LJXT629Y$w2Us7{2jbl|L1II9KD+6iZwO@ir=pA2J}!&#fAz{Cuv z!dRQ&EcL(KAQIq87*w|F zqw$?*fK^H{Fsy^KHo#f3GhwnSGa;S=@j(s)@tFQHFsRKe2MIAUFsRQ2=Uqky2925E zyvxYIpa;=~upN!>2sdAD7RVS-Q$%GJ$ZQ6LmsuFz*KA`D4a#PCXAs4}z&o3PK^0vM z69dEFI}8lRlNcD(W`T1J$VCuUmJAFGOc9^}odwP@j0_A;aNE4$tZq1KE1ab=8{!rw zkZzCz85tPZ%@`QeW`koJWXEi9V1ax+8|)cI28QU_Af+I`bir9lb08*x;szXkpu~km zOa&?iw~>K?K@}qA4AZLy;Uhwbfq_9Cif3V^e=!&zPPVd^v&z*u+TEXjp1F?~484$g9ivosdN z)M>$4W^h&qoF%surY;%Ix&dch1~si2KvB7U1x(#VIP1nLn3&pX80!+8rMwm<7O)P+ z>V>oV*2BbFHo{o0n_w)pEihIroRzl?CYH1v#>$4X*6xOhb?t?*R_ueZmh6YIOb)W8z=!&$aRVd|#CS!duZ+hZ_UH#loKoMnF;COZwz znh9swoP^2t!&&a9U}6(b!&nF5EXOl2F;_Ti@mZLd$vGIy5zeZBvn