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 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 literal 3707 zcmZwHZBSHI90u?MD$dxqW-418s%6<-n3zCx2(pNm2wGM$C;_2(i(*U#Evd{B#w-lf5tPtWJ zAp#1QW=H)gf`nwslEr_dxT+^p?oBF{_oZTSfC$;SV}ZOxEtHq|Me`Cpf}A>aTxTj4cZm~6-7c-k3k!vsAy=*a%g-7_C=CB{-3JsUKD&YtDooejbXZ z_ESD;{TlT7sEQYm?V~PI)+|&bsmoMpHmc?qp?s>4Dxz*tzfz``Fm^X}o7%G$)k$h^ zE;0|bG!L1XdWNc?;@6=sovNjh^HHs(+?1&R)pY8)myuOcGgRp-sP3b#QyGP*7Eoo> zR;sKBeHW-H>K3)J7=3k=kGih})odzRgUU3wS7G@FEve>-as{vy0ZaU`9{b?c{d@Ope|G(`;9tXiEL;y zbbJf+-doTpb%$E971i7-sN`*EUUIQ4YEsA@J?jc zsGbjzweNz=A3=>&50(8fs{NE{FETrIhO*b98bNhY1Jrpc_!Ep6qE^)*bJXdr3=krt zPH&}@vrccIl*6T$s;Vv_uR{Hn2Id3=$^RB6S~mUlk4Pw6`Hjq7yVZ=c`hm98 zLyr0;MKw)*^Q@fp?pc+wZ#~sb4N#8#dI^z%a-3a_m7k1xGN*qgmphRtL~Mf|B3Je_ z`ndqn5m2 zb{^|IbJ(YZu=(ez-^eo6yvx->^hZuwq7R2!x=9}neTv-1f>jR|Y<0`k>GNcB%VAn} zHx6wQ$C_GHQP0wH_hX06lUZAE;B7`VPL2=Ekr#UlPI&*^tgXhZ|2>gmt?Db)cUoKZ zuFD6swdx0xvbXBRNj=WKG%B5{rOa)2uRPR0lk+vpf0o&t>yfbMiR?w|RHvp_EP3Udckw&)$iWocOP~LbHq};ROew-&r!B^ zWT{jqb)E|EK;O+ysG|$&qQZ|O%ca_>LF&^J=Z|YBHv)A~T~xzmR1Z*bqsZ#1*sI8%qGHC7rCo#C zsFUN!y1me9ALRTIs-fDcQ`DLp=XEi diff --git a/desktop/mindustry-saves/2.mins b/desktop/mindustry-saves/2.mins index e8eda1212daabccc621c10cd78f325872c9d2ed5..94eac02a1470253bdd576aebabc2e301d4696806 100644 GIT binary patch literal 17639 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 literal 3663 zcmZwIZBSHI90u?Mnto{dmP2B!3cJgqvYNc5NQ4WnW{reKrY58y7KUg_ay+Vj5 zg$T)gCj0fRVxEvp|2M;z-ehaD^xx}{<2*4xMChtY<|wDR@>KbRatc*WLY_{{(sFW&OjLfzas?bBn4A4O%R1^c*mP6$$AX_X{NsT5T z^Cv-*&qIUBP=5;4o(4^?huSRAa0WC@y}AL}7`4rc?B|Wp)FvoVJ}-I5XLX0NZbnw~ zGSp0&UO^T|J=lWGoC#G@x2c9KRExJlIoqIG>K7{aHB^^oLw3r%1KCl^N!_C!Qt3M} z<0oo{vg|^&fGVZZccWTN9nL{EN!_Kwa#7ty?Wd-xx8FkFHL83Mvb?>JH4pMrVfn}= zs0I6wZKMXN-U3t??uXV=!_<%Opz5RUQYD3`c2X169cuUh`tDN|?;`7`d{kHwssjh1 z)MBWI8l(0dLiG|gM2%6msI`YN<0|ET57{`CT!QR(D&c)($EkLzi?WrXFTM;~T@GD1 z0(DTUjv^bhK{w>DnmodV@KZ_0k=0X+Dv&)}2`!;osJIVNZJ-%?&`fclF{`3y4*_0S3`pQ@t1rxF`5WAPa%iSmAq?71%>FO_;0SvPfsifj}i zvaWtROcGH6V|~Eb)QHt`sK_RDjaX$NWew$s3Xs0atDdWUvX%2>Tvxk>0FA&ia>lt_-E z9c8mJIn;MoW@c^Hz=cplkG z>IKS5ncC2|j7p^Jl<{M;-uaO$3 zQif68Ky^^5BdDIG9Mrl|RO=|K4_W;fbe&2YN0vdgO(2WE38hhG)S5|DlPL?;OeNex vpM}~@RZw=yO?jwIeynni>Y_YU>lFGt)6n@}p-w9AA+oQi3)CCGY1RJ#VzZ99