diff --git a/core/assets-raw/sprites/enemies/enemy-t1.png b/core/assets-raw/sprites/enemies/standardenemy-t1.png similarity index 100% rename from core/assets-raw/sprites/enemies/enemy-t1.png rename to core/assets-raw/sprites/enemies/standardenemy-t1.png diff --git a/core/assets-raw/sprites/enemies/enemy-t2.png b/core/assets-raw/sprites/enemies/standardenemy-t2.png similarity index 100% rename from core/assets-raw/sprites/enemies/enemy-t2.png rename to core/assets-raw/sprites/enemies/standardenemy-t2.png diff --git a/core/assets-raw/sprites/enemies/enemy-t3.png b/core/assets-raw/sprites/enemies/standardenemy-t3.png similarity index 100% rename from core/assets-raw/sprites/enemies/enemy-t3.png rename to core/assets-raw/sprites/enemies/standardenemy-t3.png diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index cdf5dcbd48..facae62515 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -405,7 +405,7 @@ blocks/grassblock2 index: -1 blocks/grassedge rotate: false - xy: 152, 91 + xy: 124, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -433,7 +433,7 @@ blocks/ice3 index: -1 blocks/iceedge rotate: false - xy: 166, 91 + xy: 138, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -538,7 +538,7 @@ blocks/lava index: -1 blocks/lavaedge rotate: false - xy: 95, 75 + xy: 152, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -650,7 +650,7 @@ blocks/oil index: -1 blocks/oiledge rotate: false - xy: 109, 75 + xy: 95, 75 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -839,7 +839,7 @@ blocks/sandblock3 index: -1 blocks/sandedge rotate: false - xy: 95, 47 + xy: 95, 61 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -937,7 +937,7 @@ blocks/snowblock3 index: -1 blocks/snowedge rotate: false - xy: 95, 33 + xy: 95, 47 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -1278,72 +1278,44 @@ enemies/empenemy-t3 orig: 14, 14 offset: 0, 0 index: -1 -enemies/enemy-t1 - rotate: false - xy: 646, 243 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -enemies/targetenemy-t1 - rotate: false - xy: 646, 243 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -enemies/enemy-t2 - rotate: false - xy: 124, 91 - size: 12, 12 - orig: 12, 12 - offset: 0, 0 - index: -1 -enemies/enemy-t3 - rotate: false - xy: 138, 91 - size: 12, 12 - orig: 12, 12 - offset: 0, 0 - index: -1 enemies/fastenemy-t1 rotate: false - xy: 718, 297 + xy: 646, 243 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t2 rotate: false - xy: 495, 120 + xy: 718, 297 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/fastenemy-t3 rotate: false - xy: 492, 104 + xy: 495, 120 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t1 rotate: false - xy: 511, 120 + xy: 492, 104 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t2 rotate: false - xy: 508, 104 + xy: 511, 120 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/flamerenemy-t3 rotate: false - xy: 519, 208 + xy: 508, 104 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1371,67 +1343,95 @@ enemies/fortressenemy-t3 index: -1 enemies/healerenemy-t1 rotate: false - xy: 519, 192 + xy: 519, 208 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t2 rotate: false - xy: 521, 162 + xy: 519, 192 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/healerenemy-t3 rotate: false - xy: 521, 146 + xy: 521, 162 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 738, 396 + xy: 738, 412 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 754, 414 + xy: 738, 396 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 754, 398 + xy: 754, 414 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 770, 414 + xy: 754, 398 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 770, 398 + xy: 770, 414 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 + rotate: false + xy: 770, 398 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +enemies/standardenemy-t1 rotate: false xy: 786, 419 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 +enemies/targetenemy-t1 + rotate: false + xy: 786, 419 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +enemies/standardenemy-t2 + rotate: false + xy: 109, 61 + size: 12, 12 + orig: 12, 12 + offset: 0, 0 + index: -1 +enemies/standardenemy-t3 + rotate: false + xy: 95, 33 + size: 12, 12 + orig: 12, 12 + offset: 0, 0 + index: -1 enemies/tankenemy-t1 rotate: false xy: 786, 403 @@ -1560,14 +1560,14 @@ laserfull index: -1 mechs/mech-standard rotate: false - xy: 95, 61 + xy: 166, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mechs/ship-standard rotate: false - xy: 109, 61 + xy: 109, 75 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -1715,7 +1715,7 @@ ui/icons/controller-cursor index: -1 ui/icons/icon-add rotate: false - xy: 535, 209 + xy: 521, 146 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1729,7 +1729,7 @@ ui/icons/icon-areaDelete index: -1 ui/icons/icon-arrow rotate: false - xy: 535, 193 + xy: 535, 209 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1771,14 +1771,14 @@ ui/icons/icon-back index: -1 ui/icons/icon-cancel rotate: false - xy: 551, 211 + xy: 535, 193 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-check rotate: false - xy: 551, 195 + xy: 551, 211 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1827,7 +1827,7 @@ ui/icons/icon-defense index: -1 ui/icons/icon-discord rotate: false - xy: 567, 211 + xy: 551, 195 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1841,28 +1841,28 @@ ui/icons/icon-distribution index: -1 ui/icons/icon-donate rotate: false - xy: 567, 195 + xy: 567, 211 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-dots rotate: false - xy: 583, 213 + xy: 567, 195 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-editor rotate: false - xy: 583, 197 + xy: 583, 213 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-file-text rotate: false - xy: 599, 216 + xy: 583, 197 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1876,21 +1876,21 @@ ui/icons/icon-fill index: -1 ui/icons/icon-floppy rotate: false - xy: 599, 200 + xy: 599, 216 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-folder rotate: false - xy: 615, 216 + xy: 599, 200 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-folder-parent rotate: false - xy: 615, 200 + xy: 615, 216 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1918,14 +1918,14 @@ ui/icons/icon-holdDelete index: -1 ui/icons/icon-home rotate: false - xy: 631, 220 + xy: 615, 200 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-host rotate: false - xy: 631, 204 + xy: 631, 220 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1946,7 +1946,7 @@ ui/icons/icon-line index: -1 ui/icons/icon-load rotate: false - xy: 647, 227 + xy: 631, 204 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2016,7 +2016,7 @@ ui/icons/icon-play index: -1 ui/icons/icon-play-2 rotate: false - xy: 647, 211 + xy: 647, 227 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2037,7 +2037,7 @@ ui/icons/icon-production index: -1 ui/icons/icon-quit rotate: false - xy: 647, 195 + xy: 647, 211 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2051,7 +2051,7 @@ ui/icons/icon-redo index: -1 ui/icons/icon-rename rotate: false - xy: 631, 188 + xy: 647, 195 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2065,35 +2065,35 @@ ui/icons/icon-resize index: -1 ui/icons/icon-rotate rotate: false - xy: 647, 179 + xy: 631, 188 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-arrow rotate: false - xy: 722, 411 + xy: 647, 179 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-left rotate: false - xy: 722, 395 + xy: 722, 411 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-rotate-right rotate: false - xy: 724, 365 + xy: 722, 395 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-save rotate: false - xy: 724, 349 + xy: 724, 365 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2128,7 +2128,7 @@ ui/icons/icon-terrain index: -1 ui/icons/icon-tools rotate: false - xy: 724, 333 + xy: 724, 349 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -2149,14 +2149,14 @@ ui/icons/icon-touchDelete index: -1 ui/icons/icon-trash rotate: false - xy: 724, 317 + xy: 724, 333 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icons/icon-tutorial rotate: false - xy: 738, 412 + xy: 724, 317 size: 14, 14 orig: 14, 14 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 8c5a9b4ae9..ee141ff3ed 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml index ca65df4293..ae09f6ff54 100644 --- a/core/src/Mindustry.gwt.xml +++ b/core/src/Mindustry.gwt.xml @@ -2,9 +2,7 @@ - - \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index e89ef2ea99..044770952c 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -5,9 +5,9 @@ import com.badlogic.gdx.ai.pfa.PathSmoother; import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; - import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.Tile; @@ -28,25 +28,27 @@ public class Pathfind{ findNode(enemy); } - if(enemy.path == null){ - return vector.set(enemy.x, enemy.y); - }else if(enemy.node == -2){ + if(enemy.node == -2){ enemy.node = -1; } + + if(enemy.node < 0 || Vars.control.getSpawnPoints().get(enemy.lane).pathTiles == null){ + return vector.set(enemy.x, enemy.y); + } + + Tile[] path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles; - Tile[] path = enemy.path; - - - if(enemy.idletime > Enemy.maxIdle){ + if(enemy.idletime > EnemyType.maxIdle){ //TODO reverse Tile target = path[enemy.node]; - if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null){ - if(enemy.node > 1) + if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null) { + if (enemy.node > 1) enemy.node = enemy.node - 1; enemy.idletime = 0; - }else{ - //must be blocked by a playermade block, do nothing } + + //else, must be blocked by a playermade block, do nothing + } //-1 is only possible here if both pathfindings failed, which should NOT happen @@ -157,22 +159,24 @@ public class Pathfind{ return; } - enemy.path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles; + Tile[] path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles; - int closest = findClosest(enemy.path, enemy.x, enemy.y); + int closest = findClosest(path, enemy.x, enemy.y); - closest = Mathf.clamp(closest, 1, enemy.path.length-1); + closest = Mathf.clamp(closest, 1, path.length-1); if(closest == -1){ return; } - - Tile end = enemy.path[closest]; + enemy.node = closest; - + + //TODO + + //Tile end = path[closest]; //if the enemy can't get to this node, teleport to it - if(enemy.node < enemy.path.length - 2 && Vars.world.raycastWorld(enemy.x, enemy.y, end.worldx(), end.worldy()) != null){ + //if(enemy.node < path.length - 2 && Vars.world.raycastWorld(enemy.x, enemy.y, end.worldx(), end.worldy()) != null){ // Timers.run(Mathf.random(20f), () -> enemy.set(end.worldx(), end.worldy())); - } + //} } private static int findClosest(Tile[] tiles, float x, float y){ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 2c6fa4610c..9e34ed638a 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -5,15 +5,13 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Buttons; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.reflect.ClassReflection; 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.Shield; import io.anuke.mindustry.entities.enemies.Enemy; -import io.anuke.mindustry.entities.enemies.FortressEnemy; -import io.anuke.mindustry.entities.enemies.HealerEnemy; +import io.anuke.mindustry.entities.enemies.EnemyTypes; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.DesktopInput; @@ -356,21 +354,17 @@ public class Control extends Module{ float range = 12f; Timers.run(index*5f, ()->{ - try{ - Enemy enemy = ClassReflection.newInstance(spawn.type); - enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range)); - enemy.lane = fl; - enemy.tier = spawn.tier(wave, fl); - enemy.add(); - Effects.effect(Fx.spawn, enemy); + Enemy enemy = new Enemy(spawn.type); + enemy.set(tile.worldx() + Mathf.range(range), tile.worldy() + Mathf.range(range)); + enemy.lane = fl; + enemy.tier = spawn.tier(wave, fl); + enemy.add(); - Vars.netServer.handleEnemySpawn(enemy); - - enemies ++; - }catch (Exception e){ - throw new RuntimeException(e); - } + Effects.effect(Fx.spawn, enemy); + Vars.netServer.handleEnemySpawn(enemy); + + enemies ++; }); } } @@ -601,10 +595,10 @@ public class Control extends Module{ if(Inputs.keyTap(Keys.Y)){ if(Inputs.keyDown(Keys.SHIFT_LEFT)){ - new HealerEnemy().set(player.x, player.y).add(); + new Enemy(EnemyTypes.healer).set(player.x, player.y).add(); }else{ float px = player.x, py = player.y; - Timers.run(30f, ()-> new FortressEnemy().set(px, py).add()); + Timers.run(30f, ()-> new Enemy(EnemyTypes.fortress).set(px, py).add()); } } } diff --git a/core/src/io/anuke/mindustry/entities/EnemySpawn.java b/core/src/io/anuke/mindustry/entities/EnemySpawn.java index be96fb5bc1..0057953727 100644 --- a/core/src/io/anuke/mindustry/entities/EnemySpawn.java +++ b/core/src/io/anuke/mindustry/entities/EnemySpawn.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.entities; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.ucore.core.Settings; import io.anuke.ucore.util.Mathf; @@ -9,7 +9,7 @@ public class EnemySpawn{ private static float[] scalings = {4f, 2.5f, 1.5f}; /**The enemy type spawned*/ - public final Class type; + public final EnemyType type; /**When this spawns should end*/ protected int before = Integer.MAX_VALUE; /**When this spawns should start*/ @@ -29,7 +29,7 @@ public class EnemySpawn{ /**Amount of enemies spawned initially, with no scaling*/ protected int amount = 1; - public EnemySpawn(Class type){ + public EnemySpawn(EnemyType type){ this.type = type; } @@ -39,10 +39,10 @@ public class EnemySpawn{ } float scaling = this.scaling * scalings[(Settings.getInt("difficulty"))]; - return Math.min(amount-1 + 1 * Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max); + return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) - (tier(wave, lane)-1) * tierscaleback, max); } public int tier(int wave, int lane){ - return Mathf.clamp(tier + (wave-after)/tierscale, 1, Enemy.maxtier); + return Mathf.clamp(tier + (wave-after)/tierscale, 1, EnemyType.maxtier); } } diff --git a/core/src/io/anuke/mindustry/entities/WaveCreator.java b/core/src/io/anuke/mindustry/entities/WaveCreator.java index a725011bcc..d5827a6d5f 100644 --- a/core/src/io/anuke/mindustry/entities/WaveCreator.java +++ b/core/src/io/anuke/mindustry/entities/WaveCreator.java @@ -1,22 +1,18 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.reflect.ClassReflection; - -import io.anuke.mindustry.entities.enemies.*; +import io.anuke.mindustry.entities.enemies.EnemyTypes; public class WaveCreator{ public static Array getSpawns(){ - //TODO - //Gdx.app.exit(); return Array.with( - new EnemySpawn(Enemy.class){{ + new EnemySpawn(EnemyTypes.standard){{ scaling = 1; before = 3; }}, - new EnemySpawn(FastEnemy.class){{ + new EnemySpawn(EnemyTypes.fast){{ scaling = 1; after = 3; spacing = 5; @@ -24,7 +20,7 @@ public class WaveCreator{ tierscaleback = 0; }}, - new EnemySpawn(BlastEnemy.class){{ + new EnemySpawn(EnemyTypes.blast){{ after = 4; amount = 3; spacing = 5; @@ -32,56 +28,56 @@ public class WaveCreator{ tierscaleback = 0; }}, - new EnemySpawn(TankEnemy.class){{ + new EnemySpawn(EnemyTypes.tank){{ after = 5; spacing = 5; scaling = 2; amount = 2; }}, - new EnemySpawn(RapidEnemy.class){{ + new EnemySpawn(EnemyTypes.rapid){{ after = 7; spacing = 5; scaling = 2; amount = 3; }}, - new EnemySpawn(HealerEnemy.class){{ + new EnemySpawn(EnemyTypes.healer){{ after = 5; spacing = 5; scaling = 1; amount = 1; }}, - new EnemySpawn(Enemy.class){{ + new EnemySpawn(EnemyTypes.standard){{ scaling = 3; after = 8; spacing = 4; tier = 2; }}, - new EnemySpawn(TitanEnemy.class){{ + new EnemySpawn(EnemyTypes.titan){{ after = 6; amount = 2; spacing = 5; scaling = 3; }}, - new EnemySpawn(FlamerEnemy.class){{ + new EnemySpawn(EnemyTypes.flamer){{ after = 12; amount = 3; spacing = 5; scaling = 3; }}, - new EnemySpawn(EmpEnemy.class){{ + new EnemySpawn(EnemyTypes.emp){{ after = 15; amount = 1; spacing = 5; scaling = 2; }}, - new EnemySpawn(BlastEnemy.class){{ + new EnemySpawn(EnemyTypes.blast){{ after = 4 + 5 + 5; amount = 3; spacing = 5; @@ -89,14 +85,14 @@ public class WaveCreator{ tierscaleback = 0; }}, //boss wave - new EnemySpawn(FortressEnemy.class){{ + new EnemySpawn(EnemyTypes.fortress){{ after = 16; amount = 1; spacing = 5; scaling = 1; }}, - new EnemySpawn(TitanEnemy.class){{ + new EnemySpawn(EnemyTypes.titan){{ after = 16; amount = 1; spacing = 5; @@ -104,7 +100,7 @@ public class WaveCreator{ tierscaleback = 0; }}, - new EnemySpawn(HealerEnemy.class){{ + new EnemySpawn(EnemyTypes.healer){{ after = 16; spacing = 5; scaling = 2; @@ -113,14 +109,14 @@ public class WaveCreator{ //end boss wave //enchanced boss wave - new EnemySpawn(MortarEnemy.class){{ + new EnemySpawn(EnemyTypes.mortar){{ after = 16 + 5; amount = 1; spacing = 5; scaling = 3; }}, - new EnemySpawn(EmpEnemy.class){{ + new EnemySpawn(EnemyTypes.emp){{ after = 16 + 5; amount = 1; spacing = 5; @@ -129,71 +125,7 @@ public class WaveCreator{ //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 = 5; - scaling = 7; - }}, - 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 = 6; - scaling = 3; - }}, - 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 ++){ @@ -205,7 +137,7 @@ public class WaveCreator{ total += a; if(a > 0){ - System.out.print(a+"x" + ClassReflection.getSimpleName(spawn.type) + "-" + t + " "); + System.out.print(a+"x" + spawn.type.name + "-" + t + " "); } } System.out.print(" (" + total + ")"); diff --git a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java deleted file mode 100644 index e5756febff..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import com.badlogic.gdx.math.Vector2; - -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.Bullet; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.ucore.util.Tmp; - -public class BlastEnemy extends Enemy{ - - public BlastEnemy() { - maxhealth = 30; - speed = 0.7f; - bullet = null; - turretrotatespeed = 0f; - mass = 0.8f; - stopNearCore = false; - - heal(); - } - - void move(){ - super.move(); - float range = 10f; - Vector2 offset = Tmp.v3.setZero(); - if(target instanceof TileEntity){ - TileEntity e = (TileEntity)target; - range = (e.tile.block().width * Vars.tilesize) /2f + 8f; - offset.set(e.tile.block().getPlaceOffset()); - } - - if(target != null && target.distanceTo(this.x - offset.x, this.y - offset.y) < range){ - explode(); - } - } - - @Override - public void onDeath(){ - super.onDeath(); - explode(); - } - - void explode(){ - Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add(); - b.damage = BulletType.blast.damage + (tier-1) * 40; - damage(999); - remove(); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java deleted file mode 100644 index 0b1ab729e9..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.entities.BulletType; - -public class EmpEnemy extends Enemy{ - - public EmpEnemy() { - - speed = 0.3f; - reload = 70; - maxhealth = 210; - range = 80f; - bullet = BulletType.emp; - turretrotatespeed = 0.1f; - - heal(); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index 95a0f13451..3955007fe3 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -1,209 +1,57 @@ package io.anuke.mindustry.entities.enemies; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.graphics.Fx; -import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Syncable; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.ucore.core.Draw; -import io.anuke.ucore.core.Effects; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.DestructibleEntity; -import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.util.Angles; -import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Timer; -import io.anuke.ucore.util.Tmp; - -import static io.anuke.mindustry.Vars.world; public class Enemy extends DestructibleEntity implements Syncable{ - public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; - public final static int maxtier = 4; - public final static float maxIdle = 60*1.5f; - public final static float maxIdleLife = 60f*13f; //13 seconds idle = death - - protected int timeid; - protected Timer timer = new Timer(5); - protected float speed = 0.4f; - protected float reload = 32; - protected float range = 60; - protected float length = 4; - protected float rotatespeed = 0.1f; - protected float turretrotatespeed = 0.2f; - protected boolean alwaysRotate = false; - protected BulletType bullet = BulletType.small; - protected String shootsound = "enemyshoot"; - protected int damage; - protected Enemy spawner; - protected int spawned = 0; - protected boolean targetCore = false; - protected boolean stopNearCore = true; - protected float mass = 1f; - protected String className; + protected Interpolator inter = new Interpolator<>(SyncType.enemy); - protected Interpolator inter = new Interpolator(SyncType.enemy); + public final EnemyType type; + public Timer timer = new Timer(5); public float idletime = 0f; public int lane; public int node = -1; - public Tile[] path; + + public Enemy spawner; + public int spawned; public float angle; - public float xvelocity, yvelocity; + public Vector2 velocity = new Vector2(); public Entity target; public int tier = 1; - - protected final int timerTarget = timeid ++; - protected final int timerReload = timeid ++; - - public Enemy() { - hitbox.setSize(5f); - hitboxTile.setSize(4f); - - maxhealth = 60; - heal(); - - className = ClassReflection.getSimpleName(getClass()).toLowerCase(); - } - - public Interpolator getInterpolator() { - return inter; - } - - public float drawSize(){ - return 12; - } - - void move(){ - if(Net.client() && Net.active()){ - inter.update(this); - return; - } - - Tile core = Vars.control.getCore(); - - if(idletime > maxIdleLife){ - onDeath(); - return; - } - - boolean nearCore = distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore; - Vector2 vec; - - if(nearCore){ - vec = Tmp.v1.setZero(); - if(targetCore) target = core.entity; - }else{ - vec = Vars.world.pathfinder().find(this); - vec.sub(x, y).limit(speed); - } - - Vector2 shift = Tmp.v3.setZero(); - float shiftRange = hitbox.width + 2f; - float avoidRange = shiftRange + 4f; - float attractRange = avoidRange + 7f; - float avoidSpeed = this.speed/2.7f; - - Entities.getNearby(Vars.control.enemyGroup, x, y, range, other -> { - Enemy enemy = (Enemy)other; - if(other == this) return; - float dst = other.distanceTo(this); - - if(dst < shiftRange){ - float scl = Mathf.clamp(1.4f - dst / shiftRange) * enemy.mass * 1f/mass; - shift.add((x - other.x) * scl, (y - other.y) * scl); - }else if(dst < avoidRange){ - Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed); - shift.add(Tmp.v2.scl(1.1f)); - }else if(dst < attractRange && !nearCore){ - Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed); - shift.add(Tmp.v2.scl(-1)); - } - }); - - shift.limit(1f); - vec.add(shift.scl(0.5f)); - - move(vec.x * Timers.delta(), vec.y * Timers.delta()); - - updateTargeting(nearCore); - } - - void updateTargeting(boolean nearCore){ - if(target != null && target instanceof TileEntity && ((TileEntity)target).dead){ - target = null; - } - - if(timer.get(timerTarget, 15) && !nearCore){ - target = Vars.world.findTileTarget(x, y, null, range, false); - - //no tile found - if(target == null){ - target = Entities.getClosest(Vars.control.playerGroup, x, y, range, e -> true); - } - }else if(nearCore){ - target = Vars.control.getCore().entity; - } - - if(target != null && bullet != null){ - updateShooting(); - } - } - - void updateShooting(){ - if(timer.get(timerReload, reload * Vars.multiplier)){ - shoot(bullet); - if(shootsound != null) Effects.sound(shootsound, this); - } - } - - void shoot(BulletType bullet){ - shoot(bullet, 0); - } - - void shoot(BulletType bullet, float rotation){ - - if(!(Net.active() && Net.client())) { - Angles.translation(angle + rotation, length); - Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add(); - out.damage = (int) (damage * Vars.multiplier); - onShoot(bullet, rotation); - - if(Net.active() && Net.server()){ - Vars.netServer.handleBullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation, (short) (damage * Vars.multiplier)); - } - } - } - - void onShoot(BulletType type, float rotation){ + public Enemy(EnemyType type){ + this.type = type; } @Override - public void added(){ - if(bullet != null){ - damage = (int) (bullet.damage * (1 + (tier - 1) * 1f)); - } + public void update(){ + type.update(this); + } - maxhealth *= tier; - speed += 0.04f * tier /*+ Mathf.range(0.1f)*/; - reload /= Math.max(tier / 1.5f, 1f); - range += tier * 5; - speed = Math.max(speed, 0.07f); + @Override + public void draw(){ + type.draw(this); + } - heal(); + @Override + public void drawOver(){ + type.drawOver(this); + } + + @Override + public float drawSize(){ + return 14; } @Override @@ -213,90 +61,48 @@ public class Enemy extends DestructibleEntity implements Syncable{ @Override public void onDeath(){ - Effects.effect(Fx.explosion, this); - Effects.shake(3f, 4f, this); - Effects.sound("bang2", this); - remove(); - dead = true; - - if(Net.active() && Net.server()){ - Vars.netServer.handleEnemyDeath(this); - } + type.onDeath(this); } @Override public void removed(){ - if(!dead){ - - if(spawner != null){ - spawner.spawned --; - }else{ - Vars.control.enemyDeath(); - } - } + type.removed(this); } @Override - public void update(){ - float lastx = x, lasty = y; + public void added(){ + hitbox.setSize(type.hitsize); + hitboxTile.setSize(type.hitsizeTile); + maxhealth = type.health * tier; - move(); - - xvelocity = (x - lastx) / Timers.delta(); - yvelocity = (y - lasty) / Timers.delta(); - - float minv = 0.07f; - - if(Vector2.dst(xvelocity, yvelocity, 0, 0) < minv && node > 0 && target == null){ - idletime += Timers.delta(); - }else{ - idletime = 0; - } - - Tile tile = world.tileWorld(x, y); - if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){ - damage(health+1); //drown - } - - if(Float.isNaN(angle)){ - angle = 0; - } - - if(target == null || alwaysRotate){ - angle = Mathf.slerp(angle, 180f+Mathf.atan2(xvelocity, yvelocity), rotatespeed * Timers.delta()); - }else{ - angle = Mathf.slerp(angle, angleTo(target), turretrotatespeed * Timers.delta()); - } - } - - @Override - public void draw(){ - String region = className + "-t" + Mathf.clamp(tier, 1, 3); - - Shaders.outline.color.set(tierColors[tier - 1]); - Shaders.outline.region = Draw.region(region); - - Shaders.outline.apply(); - - Draw.rect(region, x, y, this.angle - 90); - - if(Vars.showPaths){ - Draw.color(Color.PURPLE); - Draw.line(x, y, x + xvelocity*10f, y + yvelocity*10f); - - Draw.color(Color.BLACK, Color.WHITE, idletime / maxIdleLife); - Draw.square(x, y, 7f); - - Draw.color(); - } - - Draw.color(); - - Graphics.flush(); + heal(); } @Override public Enemy add(){ return add(Vars.control.enemyGroup); } + + @Override + public Interpolator getInterpolator() { + return inter; + } + + public void shoot(BulletType bullet){ + shoot(bullet, 0); + } + + public void shoot(BulletType bullet, float rotation){ + + if(!(Net.active() && Net.client())) { + Angles.translation(angle + rotation, type.length); + Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add(); + out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f)) * Vars.multiplier); + type.onShoot(this, bullet, rotation); + + if(Net.active() && Net.server()){ + Vars.netServer.handleBullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation, (short)out.damage); + } + } + } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java new file mode 100644 index 0000000000..46aa61f5a7 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java @@ -0,0 +1,230 @@ +package io.anuke.mindustry.entities.enemies; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.graphics.Fx; +import io.anuke.mindustry.graphics.Shaders; +import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.Blocks; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.core.Effects; +import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.Tmp; + +import static io.anuke.mindustry.Vars.world; + +public class EnemyType { + + //TODO documentation, comments + private static byte lastid = 0; + private static Array types = new Array<>(); + + public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; + public final static int maxtier = 4; + public final static float maxIdle = 60*1.5f; + public final static float maxIdleLife = 60f*13f; //13 seconds idle = death + + public final String name; + public final byte id; + + protected int timeid; + protected int health = 60; + protected float hitsize = 5f; + protected float hitsizeTile = 4f; + protected float speed = 0.4f; + protected float reload = 32; + protected float range = 60; + protected float length = 4; + protected float rotatespeed = 0.1f; + protected float turretrotatespeed = 0.2f; + protected boolean alwaysRotate = false; + protected BulletType bullet = BulletType.small; + protected String shootsound = "enemyshoot"; + protected boolean targetCore = false; + protected boolean stopNearCore = true; + protected float mass = 1f; + + protected final int timerTarget = timeid ++; + protected final int timerReload = timeid ++; + + public EnemyType(String name){ + this.id = lastid++; + this.name = name; + types.add(this); + } + + public void draw(Enemy enemy){ + String region = name + "-t" + Mathf.clamp(enemy.tier, 1, 3); + + Shaders.outline.color.set(tierColors[enemy.tier - 1]); + Shaders.outline.region = Draw.region(region); + + Shaders.outline.apply(); + + Draw.rect(region, enemy.x, enemy.y, enemy.angle - 90); + Draw.color(); + + Graphics.flush(); + } + + public void drawOver(Enemy enemy){ } + + public void update(Enemy enemy){ + float lastx = enemy.x, lasty = enemy.y; + + move(enemy); + + enemy.velocity.set(enemy.x - lastx, enemy.y - lasty).scl(1f / Timers.delta()); + + float minv = 0.07f; + + if(enemy.velocity.len() < minv && enemy.node > 0 && enemy.target == null){ + enemy.idletime += Timers.delta(); + }else{ + enemy.idletime = 0; + } + + Tile tile = world.tileWorld(enemy.x, enemy.y); + if(tile != null && tile.floor().liquid && tile.block() == Blocks.air){ + enemy.damage(enemy.health+1); //drown + } + + if(Float.isNaN(enemy.angle)){ + enemy.angle = 0; + } + + if(enemy.target == null || alwaysRotate){ + enemy.angle = Mathf.slerp(enemy.angle, 180f + enemy.velocity.angle(), rotatespeed * Timers.delta()); + }else{ + enemy.angle = Mathf.slerp(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed * Timers.delta()); + } + } + + public void move(Enemy enemy){ + float speed = this.speed + 0.04f * enemy.tier; + float range = this.range + enemy.tier * 5; + + if(Net.client() && Net.active()){ + enemy.inter.update(enemy); //TODO? better structure for interpolation + return; + } + + Tile core = Vars.control.getCore(); + + if(enemy.idletime > maxIdleLife){ + enemy.onDeath(); + return; + } + + boolean nearCore = enemy.distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore; + Vector2 vec; + + if(nearCore){ + vec = Tmp.v1.setZero(); + if(targetCore) enemy.target = core.entity; + }else{ + vec = Vars.world.pathfinder().find(enemy); + vec.sub(enemy.x, enemy.y).limit(speed); + } + + Vector2 shift = Tmp.v3.setZero(); + float shiftRange = enemy.hitbox.width + 2f; + float avoidRange = shiftRange + 4f; + float attractRange = avoidRange + 7f; + float avoidSpeed = this.speed/2.7f; + + Entities.getNearby(Vars.control.enemyGroup, enemy.x, enemy.y, range, en -> { + Enemy other = (Enemy)en; + if(other == enemy) return; + float dst = other.distanceTo(enemy); + + if(dst < shiftRange){ + float scl = Mathf.clamp(1.4f - dst / shiftRange) * mass * 1f/mass; + shift.add((enemy.x - other.x) * scl, (enemy.y - other.y) * scl); + }else if(dst < avoidRange){ + Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed); + shift.add(Tmp.v2.scl(1.1f)); + }else if(dst < attractRange && !nearCore){ + Tmp.v2.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed); + shift.add(Tmp.v2.scl(-1)); + } + }); + + shift.limit(1f); + vec.add(shift.scl(0.5f)); + + enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta()); + + updateTargeting(enemy, nearCore); + } + + public void updateTargeting(Enemy enemy, boolean nearCore){ + if(enemy.target != null && enemy.target instanceof TileEntity && ((TileEntity)enemy.target).dead){ + enemy.target = null; + } + + if(enemy.timer.get(timerTarget, 15) && !nearCore){ + enemy.target = Vars.world.findTileTarget(enemy.x, enemy.y, null, range, false); + + //no tile found + if(enemy.target == null){ + enemy.target = Entities.getClosest(Vars.control.playerGroup, enemy.x, enemy.y, range, e -> true); + } + }else if(nearCore){ + enemy.target = Vars.control.getCore().entity; + } + + if(enemy.target != null && bullet != null){ + updateShooting(enemy); + } + } + + public void updateShooting(Enemy enemy){ + float reload = this.reload / Math.max(enemy.tier / 1.5f, 1f); + + if(enemy.timer.get(timerReload, reload * Vars.multiplier)){ + shoot(enemy); + } + } + + public void shoot(Enemy enemy){ + enemy.shoot(bullet); + if(shootsound != null) Effects.sound(shootsound, enemy); + } + + public void onShoot(Enemy enemy, BulletType type, float rotation){} + + public void onDeath(Enemy enemy){ + Effects.effect(Fx.explosion, enemy); + Effects.shake(3f, 4f, enemy); + Effects.sound("bang2", enemy); + enemy.remove(); + enemy.dead = true; + + if(Net.active() && Net.server()){ + Vars.netServer.handleEnemyDeath(enemy); + } + } + + public void removed(Enemy enemy){ + if(!enemy.dead){ + if(enemy.spawner != null){ + enemy.spawner.spawned --; + }else{ + Vars.control.enemyDeath(); + } + } + } + + public static EnemyType getByID(byte id){ + return types.get(id); + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/EnemyTypes.java b/core/src/io/anuke/mindustry/entities/enemies/EnemyTypes.java new file mode 100644 index 0000000000..a2116848ab --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/EnemyTypes.java @@ -0,0 +1,32 @@ +package io.anuke.mindustry.entities.enemies; + +import io.anuke.mindustry.entities.enemies.types.BlastEnemy; +import io.anuke.mindustry.entities.enemies.types.EmpEnemy; +import io.anuke.mindustry.entities.enemies.types.FastEnemy; +import io.anuke.mindustry.entities.enemies.types.FlamerEnemy; +import io.anuke.mindustry.entities.enemies.types.FortressEnemy; +import io.anuke.mindustry.entities.enemies.types.HealerEnemy; +import io.anuke.mindustry.entities.enemies.types.MortarEnemy; +import io.anuke.mindustry.entities.enemies.types.RapidEnemy; +import io.anuke.mindustry.entities.enemies.types.*; +import io.anuke.mindustry.entities.enemies.types.TankEnemy; +import io.anuke.mindustry.entities.enemies.types.TargetEnemy; +import io.anuke.mindustry.entities.enemies.types.TitanEnemy; + +public class EnemyTypes { + public static final EnemyType + + standard = new StandardEnemy(), + fast = new FastEnemy(), + rapid = new RapidEnemy(), + flamer = new FlamerEnemy(), + tank = new TankEnemy(), + blast = new BlastEnemy(), + mortar = new MortarEnemy(), + healer = new HealerEnemy(), + titan = new TitanEnemy(), + emp = new EmpEnemy(), + fortress = new FortressEnemy(), + target = new TargetEnemy(); + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java deleted file mode 100644 index 01d80d0524..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/FastEnemy.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -public class FastEnemy extends Enemy{ - - public FastEnemy() { - - speed = 0.73f; - reload = 25; - mass = 0.2f; - - maxhealth = 40; - heal(); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java deleted file mode 100644 index 2407149fa5..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/FortressEnemy.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.graphics.Fx; -import io.anuke.ucore.core.Effects; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Angles; - -public class FortressEnemy extends Enemy{ - static int maxSpawn = 6; - - float spawnTime = 190; - boolean deployed; - - public FortressEnemy() { - - speed = 0.25f; - reload = 90; - maxhealth = 700; - range = 70f; - bullet = BulletType.yellowshell; - hitbox.setSize(10f); - turretrotatespeed = rotatespeed = 0.08f; - length = 7f; - mass = 7f; - - heal(); - } - - @Override - public void move(){ - super.move(); - - if(deployed){ - - if(Timers.get(this, "spawn", spawnTime) && spawned < maxSpawn){ - Angles.translation(angle, 20f); - - FastEnemy enemy = new FastEnemy(); - enemy.lane = lane; - enemy.tier = this.tier; - enemy.spawner = this; - enemy.set(x + Angles.x(), y + Angles.y()); - Effects.effect(Fx.spawn, enemy); - enemy.add(); - spawned ++; - } - }else if(distanceTo(Vars.control.getCore().worldx(), - Vars.control.getCore().worldy()) <= 90f){ - deployed = true; - speed = 0.001f; - } - } - - - void onShoot(BulletType type, float rotation){ - Effects.effect(Fx.largeCannonShot, x + Angles.x(), y + Angles.y(), angle); - Effects.shake(3f, 3f, this); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java deleted file mode 100644 index b43add15c7..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java +++ /dev/null @@ -1,91 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import com.badlogic.gdx.math.MathUtils; - -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.Bullet; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.graphics.Fx; -import io.anuke.mindustry.graphics.Shaders; -import io.anuke.ucore.core.*; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.graphics.Hue; -import io.anuke.ucore.util.Angles; - -public class HealerEnemy extends Enemy{ - - public HealerEnemy() { - - speed = 0.25f; - reload = 10; - maxhealth = 200; - bullet = BulletType.shot; - range = 40f; - alwaysRotate = false; - targetCore = false; - stopNearCore = true; - mass = 1.1f; - - heal(); - } - - @Override - void move(){ - super.move(); - - if(idletime > 60f*3){ //explode after 3 seconds of stillness - explode(); - Effects.effect(Fx.shellexplosion, this); - Effects.effect(Fx.shellsmoke, this); - } - } - - @Override - void updateTargeting(boolean nearCore){ - if(timer.get(timerTarget, 15)){ - target = Entities.getClosest(Vars.control.enemyGroup, - x, y, range, e -> e instanceof Enemy && e != this && ((Enemy)e).healthfrac() < 1f); - } - - if(target != null){ - updateShooting(); - } - } - - @Override - void updateShooting(){ - Enemy enemy = (Enemy)target; - - if(enemy.health < enemy.maxhealth && Timers.get(this, "heal", reload)){ - enemy.health ++; - idletime = 0; - } - } - - @Override - public void drawOver(){ - super.drawOver(); - Enemy enemy = (Enemy)target; - - if(enemy == null) return; - - Angles.translation(this.angleTo(enemy), 5f); - - Graphics.shader(); - if(enemy != null && enemy.health < enemy.maxhealth){ - Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f)); - Draw.alpha(0.9f); - Draw.laser("laser", "laserend", x + Angles.x(), y + Angles.y(), enemy.x - Angles.x()/1.5f, enemy.y - Angles.y()/1.5f); - Draw.color(); - } - Graphics.shader(Shaders.outline); - } - - void explode(){ - Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add(); - b.damage = BulletType.blast.damage + (tier-1) * 30; - damage(999); - remove(); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java deleted file mode 100644 index 44948908eb..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.entities.BulletType; - -public class RapidEnemy extends Enemy{ - - public RapidEnemy() { - - reload = 8; - bullet = BulletType.purple; - rotatespeed = 0.08f; - maxhealth = 260; - speed = 0.33f; - heal(); - hitbox.setSize(8f); - mass = 3f; - - range = 70; - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java deleted file mode 100644 index 4ca5a514ed..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/TankEnemy.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.Bullet; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.ucore.util.Angles; - -public class TankEnemy extends Enemy{ - - public TankEnemy() { - - maxhealth = 350; - speed = 0.24f; - reload = 90f; - rotatespeed = 0.06f; - bullet = BulletType.small; - length = 3f; - mass = 1.4f; - } - - void shoot(){ - Angles.translation(angle, 8f); - - Angles.shotgun(3, 8f, angle, f->{ - Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, f).add(); - out.damage = (int)(damage*Vars.multiplier); - }); - - - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java deleted file mode 100644 index 609d6e0f83..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/TargetEnemy.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import com.badlogic.gdx.graphics.Color; - -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.ucore.core.Draw; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Mathf; - -public class TargetEnemy extends Enemy{ - - public TargetEnemy(){ - speed = 0f; - maxhealth = 25; - shootsound = null; - } - - @Override - void move(){ - speed = 0f; - super.move(); - } - - @Override - void shoot(BulletType bullet){ - //do nothing - } - - @Override - public void removed(){ - //don't call enemy death since this is only a target - } - - @Override - public void draw(){ - super.draw(); - - Draw.color(Color.YELLOW); - - if(Vars.control.getTutorial().showTarget()){ - Draw.spikes(x, y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time()); - } - - Draw.color(); - } - - @Override - public void onDeath(){ - super.onDeath(); - Timers.run(100f, ()->{ - 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 deleted file mode 100644 index 56da2fdcfa..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/TestEnemy.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.ucore.core.Timers; - -public class TestEnemy extends Enemy{ - boolean dir = false; - - public TestEnemy() { - maxhealth = 99999; - heal(); - } - - void move(){ - if(Timers.get(this, "switch", 300)){ - dir = !dir; - } - - move(dir ? -0.3f * Timers.delta() : 0.3f * Timers.delta(), 0); - } -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java deleted file mode 100644 index 8b6d6cbfab..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.entities.BulletType; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Angles; -import io.anuke.ucore.util.Mathf; - -public class TitanEnemy extends Enemy{ - - public TitanEnemy() { - - speed = 0.26f; - reload = 30; - maxhealth = 430; - range = 60f; - bullet = BulletType.small; - hitbox.setSize(7f); - mass = 4f; - - heal(); - - Timers.reset(this, "salvo", 0); - Timers.reset(this, "shotgun", 0); - Timers.reset(this, "circle", 0); - } - - @Override - void updateShooting(){ - Timers.get(this, "salvo", 240); - - if(Timers.getTime(this, "salvo") < 60){ - if(Timers.get(this, "salvoShoot", 6)){ - shoot(BulletType.flame, Mathf.range(20f)); - } - } - - if(Timers.get(this, "shotgun", 80)){ - Angles.shotgun(5, 10f, 0f, f->{ - shoot(BulletType.smallSlow, f); - }); - } - - if(Timers.get(this, "circle", 200)){ - Angles.circle(8, 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 deleted file mode 100644 index 2fbb27ff14..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/flying/FlyingEnemy.java +++ /dev/null @@ -1,11 +0,0 @@ -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/entities/enemies/types/BlastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/BlastEnemy.java new file mode 100644 index 0000000000..567ac9a800 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/BlastEnemy.java @@ -0,0 +1,56 @@ +package io.anuke.mindustry.entities.enemies.types; + +import com.badlogic.gdx.math.Vector2; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.Bullet; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.ucore.util.Tmp; + +public class BlastEnemy extends EnemyType { + + public BlastEnemy() { + super("blastenemy"); + health = 30; + speed = 0.7f; + bullet = null; + turretrotatespeed = 0f; + mass = 0.8f; + stopNearCore = false; + } + + @Override + public void move(Enemy enemy){ + super.move(enemy); + + float range = 10f; + Vector2 offset = Tmp.v3.setZero(); + + if(enemy.target instanceof TileEntity){ + TileEntity e = (TileEntity)enemy.target; + range = (e.tile.block().width * Vars.tilesize) /2f + 8f; + offset.set(e.tile.block().getPlaceOffset()); + } + + if(enemy.target != null && enemy.target.distanceTo(enemy.x - offset.x, enemy.y - offset.y) < range){ + explode(enemy); + } + } + + @Override + public void onDeath(Enemy enemy){ + super.onDeath(enemy); + explode(enemy); + } + + void explode(Enemy enemy){ + Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add(); + b.damage = BulletType.blast.damage + (enemy.tier-1) * 40; + enemy.damage(999); + enemy.remove(); + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/EmpEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/EmpEnemy.java new file mode 100644 index 0000000000..a5a9772f45 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/EmpEnemy.java @@ -0,0 +1,19 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.EnemyType; + +public class EmpEnemy extends EnemyType { + + public EmpEnemy() { + super("empenemy"); + + speed = 0.3f; + reload = 70; + health = 210; + range = 80f; + bullet = BulletType.emp; + turretrotatespeed = 0.1f; + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/FastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/FastEnemy.java new file mode 100644 index 0000000000..7ab613c8b3 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/FastEnemy.java @@ -0,0 +1,17 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.enemies.EnemyType; + +public class FastEnemy extends EnemyType { + + public FastEnemy() { + super("fastenemy"); + + speed = 0.73f; + reload = 25; + mass = 0.2f; + + health = 40; + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/FlamerEnemy.java similarity index 51% rename from core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java rename to core/src/io/anuke/mindustry/entities/enemies/types/FlamerEnemy.java index 3c85c450a3..69d95ca70f 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/FlamerEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/types/FlamerEnemy.java @@ -1,22 +1,20 @@ -package io.anuke.mindustry.entities.enemies; +package io.anuke.mindustry.entities.enemies.types; import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.EnemyType; -public class FlamerEnemy extends Enemy{ +public class FlamerEnemy extends EnemyType { public FlamerEnemy() { + super("flamerenemy"); speed = 0.35f; - - maxhealth = 150; + health = 150; reload = 6; bullet = BulletType.flameshot; shootsound = "flame"; mass = 1.5f; - range = 40; - - heal(); } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/FortressEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/FortressEnemy.java new file mode 100644 index 0000000000..98b149448d --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/FortressEnemy.java @@ -0,0 +1,61 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.mindustry.entities.enemies.EnemyTypes; +import io.anuke.mindustry.graphics.Fx; +import io.anuke.ucore.core.Effects; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.util.Angles; + +public class FortressEnemy extends EnemyType { + final int maxSpawn = 6; + final float spawnTime = 190; + + public FortressEnemy() { + super("fortressenemy"); + + speed = 0.25f; + reload = 90; + health = 700; + range = 70f; + bullet = BulletType.yellowshell; + hitsize = 10f; + turretrotatespeed = rotatespeed = 0.08f; + length = 7f; + mass = 7f; + } + + @Override + public void move(Enemy enemy){ + if(enemy.distanceTo(Vars.control.getCore().worldx(), + Vars.control.getCore().worldy()) <= 90f){ + + if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){ + Angles.translation(enemy.angle, 20f); + + Enemy s = new Enemy(EnemyTypes.fast); //TODO assign type! + s.lane = enemy.lane; + s.tier = enemy.tier; + s.spawner = enemy; + s.set(enemy.x + Angles.x(), enemy.y + Angles.y()); + s.add(); + + Effects.effect(Fx.spawn, enemy); + enemy.spawned ++; + } + + }else { + super.move(enemy); + } + } + + + public void onShoot(Enemy enemy, BulletType type, float rotation){ + Effects.effect(Fx.largeCannonShot, enemy.x + Angles.x(), enemy.y + Angles.y(), enemy.angle); + Effects.shake(3f, 3f, enemy); + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/HealerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/HealerEnemy.java new file mode 100644 index 0000000000..479ba5c58e --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/HealerEnemy.java @@ -0,0 +1,91 @@ +package io.anuke.mindustry.entities.enemies.types; + +import com.badlogic.gdx.math.MathUtils; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.Bullet; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.mindustry.graphics.Fx; +import io.anuke.mindustry.graphics.Shaders; +import io.anuke.ucore.core.*; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.graphics.Hue; +import io.anuke.ucore.util.Angles; + +public class HealerEnemy extends EnemyType { + + public HealerEnemy() { + super("healerenemy"); + + speed = 0.25f; + reload = 10; + health = 200; + bullet = BulletType.shot; + range = 40f; + alwaysRotate = false; + targetCore = false; + stopNearCore = true; + mass = 1.1f; + } + + @Override + public void move(Enemy enemy){ + super.move(enemy); + + if(enemy.idletime > 60f*3){ //explode after 3 seconds of stillness + explode(enemy); + Effects.effect(Fx.shellexplosion, enemy); + Effects.effect(Fx.shellsmoke, enemy); + } + } + + @Override + public void updateTargeting(Enemy enemy, boolean nearCore){ + if(enemy.timer.get(timerTarget, 15)){ + enemy.target = Entities.getClosest(Vars.control.enemyGroup, + enemy.x, enemy.y, range, e -> e instanceof Enemy && e != enemy && ((Enemy)e).healthfrac() < 1f); + } + + if(enemy.target != null){ + updateShooting(enemy); + } + } + + @Override + public void updateShooting(Enemy enemy){ + Enemy target = (Enemy)enemy.target; + + if(target.health < target.maxhealth && enemy.timer.get(timerReload, reload)){ + target.health ++; + enemy.idletime = 0; + } + } + + @Override + public void drawOver(Enemy enemy){ + Enemy target = (Enemy)enemy.target; + + if(target == null) return; + + Angles.translation(enemy.angleTo(target), 5f); + + Graphics.shader(); + if(target.health < target.maxhealth){ + Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f)); + Draw.alpha(0.9f); + Draw.laser("laser", "laserend", enemy.x + Angles.x(), enemy.y + Angles.y(), target.x - Angles.x()/1.5f, target.y - Angles.y()/1.5f); + Draw.color(); + } + Graphics.shader(Shaders.outline); + } + + void explode(Enemy enemy){ + Bullet b = new Bullet(BulletType.blast, enemy, enemy.x, enemy.y, 0).add(); + b.damage = BulletType.blast.damage + (enemy.tier-1) * 30; + enemy.damage(999); + enemy.remove(); + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/MortarEnemy.java similarity index 54% rename from core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java rename to core/src/io/anuke/mindustry/entities/enemies/types/MortarEnemy.java index 9df78bf784..e990d77d12 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/types/MortarEnemy.java @@ -1,12 +1,14 @@ -package io.anuke.mindustry.entities.enemies; +package io.anuke.mindustry.entities.enemies.types; import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.EnemyType; -public class MortarEnemy extends Enemy{ +public class MortarEnemy extends EnemyType { public MortarEnemy() { + super("mortarenemy"); - maxhealth = 200; + health = 200; speed = 0.25f; reload = 100f; bullet = BulletType.shell; @@ -14,8 +16,6 @@ public class MortarEnemy extends Enemy{ rotatespeed = 0.05f; range = 120f; mass = 1.2f; - - heal(); } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/RapidEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/RapidEnemy.java new file mode 100644 index 0000000000..388f16894a --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/RapidEnemy.java @@ -0,0 +1,21 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.EnemyType; + +public class RapidEnemy extends EnemyType { + + public RapidEnemy() { + super("rapidenemy"); + + reload = 8; + bullet = BulletType.purple; + rotatespeed = 0.08f; + health = 260; + speed = 0.33f; + hitsize = 8f; + mass = 3f; + range = 70; + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/StandardEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/StandardEnemy.java new file mode 100644 index 0000000000..abff564c44 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/StandardEnemy.java @@ -0,0 +1,10 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.enemies.EnemyType; + +public class StandardEnemy extends EnemyType { + + public StandardEnemy(){ + super("standardenemy"); + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TankEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/TankEnemy.java new file mode 100644 index 0000000000..297bea37ea --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/TankEnemy.java @@ -0,0 +1,33 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.ucore.util.Angles; + +public class TankEnemy extends EnemyType { + + public TankEnemy() { + super("tankenemy"); + + health = 350; + speed = 0.24f; + reload = 90f; + rotatespeed = 0.06f; + bullet = BulletType.small; + length = 3f; + mass = 1.4f; + } + + @Override + public void shoot(Enemy enemy){ + super.shoot(enemy); + + Angles.translation(enemy.angle, 8f); + + Angles.shotgun(3, 8f, enemy.angle, f -> { + enemy.shoot(bullet, f); + }); + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TargetEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/TargetEnemy.java new file mode 100644 index 0000000000..7880f71ecb --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/TargetEnemy.java @@ -0,0 +1,58 @@ +package io.anuke.mindustry.entities.enemies.types; + +import com.badlogic.gdx.graphics.Color; + +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.mindustry.entities.enemies.EnemyTypes; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.util.Mathf; + +public class TargetEnemy extends EnemyType { + + public TargetEnemy(){ + super("targetenemy"); + + speed = 0f; + health = 25; + shootsound = null; + } + + @Override + public void move(Enemy enemy){ + super.move(enemy); + } + + @Override + public void shoot(Enemy enemy){ + //do nothing + } + + @Override + public void removed(Enemy enemy){ + //don't call enemy death since this is only a target + } + + @Override + public void draw(Enemy enemy){ + super.draw(enemy); + + Draw.color(Color.YELLOW); + + if(Vars.control.getTutorial().showTarget()){ + Draw.spikes(enemy.x, enemy.y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time()); + } + + Draw.color(); + } + + @Override + public void onDeath(Enemy enemy){ + super.onDeath(enemy); + Timers.run(100f, ()->{ + new Enemy(EnemyTypes.target).set(enemy.x, enemy.y).add(); + }); + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TitanEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/types/TitanEnemy.java new file mode 100644 index 0000000000..2aca97437e --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/types/TitanEnemy.java @@ -0,0 +1,47 @@ +package io.anuke.mindustry.entities.enemies.types; + +import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Mathf; + +public class TitanEnemy extends EnemyType { + + public TitanEnemy() { + super("titanenemy"); + + speed = 0.26f; + reload = 30; + health = 430; + range = 60f; + bullet = BulletType.small; + hitsize = 7f; + mass = 4f; + } + + @Override + public void updateShooting(Enemy enemy){ + Timers.get(enemy, "salvo", 240); + + if(Timers.getTime(enemy, "salvo") < 60){ + if(Timers.get(enemy, "salvoShoot", 6)){ + enemy.shoot(BulletType.flame, Mathf.range(20f)); + } + } + + if(Timers.get(enemy, "shotgun", 80)){ + Angles.shotgun(5, 10f, 0f, f->{ + enemy.shoot(BulletType.smallSlow, f); + }); + } + + if(Timers.get(enemy, "circle", 200)){ + Angles.circle(8, f->{ + enemy.shoot(BulletType.smallSlow, f); + }); + } + } + +} diff --git a/core/src/io/anuke/mindustry/io/NetworkIO.java b/core/src/io/anuke/mindustry/io/NetworkIO.java index 210139242b..385e318084 100644 --- a/core/src/io/anuke/mindustry/io/NetworkIO.java +++ b/core/src/io/anuke/mindustry/io/NetworkIO.java @@ -1,10 +1,12 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.GameMode; import io.anuke.mindustry.world.Tile; @@ -16,9 +18,6 @@ import io.anuke.ucore.entities.Entities; import java.io.*; -import static io.anuke.mindustry.io.SaveFileVersion.enemyIDs; -import static io.anuke.mindustry.io.SaveFileVersion.idEnemies; - public class NetworkIO { private static final int fileVersionID = 13; @@ -45,28 +44,20 @@ public class NetworkIO { } //--ENEMIES-- + Array enemies = Vars.control.enemyGroup.all(); - int totalEnemies = 0; + stream.writeInt(enemies.size); //enemy amount - for(Enemy entity : Vars.control.enemyGroup.all()){ - if(idEnemies.containsKey(entity.getClass())){ - totalEnemies ++; - } - } - - stream.writeInt(totalEnemies); //enemy amount - - for(Enemy enemy : Vars.control.enemyGroup.all()){ - if(idEnemies.containsKey(enemy.getClass())){ - stream.writeInt(enemy.id); - stream.writeByte(idEnemies.get(enemy.getClass())); //type - stream.writeByte(enemy.lane); //lane - stream.writeFloat(enemy.x); //x - stream.writeFloat(enemy.y); //y - stream.writeByte(enemy.tier); //tier - stream.writeShort(enemy.health); //health - stream.writeShort(enemy.node); //current node - } + for(int i = 0; i < enemies.size; i ++){ + Enemy enemy = enemies.get(i); + stream.writeInt(enemy.id); + stream.writeByte(enemy.type.id); //type + stream.writeByte(enemy.lane); //lane + stream.writeFloat(enemy.x); //x + stream.writeFloat(enemy.y); //y + stream.writeByte(enemy.tier); //tier + stream.writeShort(enemy.health); //health + stream.writeShort(enemy.node); //current node } //--MAP DATA-- @@ -210,19 +201,15 @@ public class NetworkIO { short health = stream.readShort(); short node = stream.readShort(); - try{ - Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type)); - enemy.id = id; - enemy.lane = lane; - enemy.health = health; - enemy.x = x; - enemy.y = y; - enemy.tier = tier; - enemy.node = node; - enemy.add(Vars.control.enemyGroup); - }catch (Exception e){ - throw new RuntimeException(e); - } + Enemy enemy = new Enemy(EnemyType.getByID(type)); + enemy.id = id; + enemy.lane = lane; + enemy.health = health; + enemy.x = x; + enemy.y = y; + enemy.tier = tier; + enemy.node = node; + enemy.add(Vars.control.enemyGroup); } Vars.control.setWaveData(enemies, wave, wavetime); diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index 49a63d59b9..f95e72ff44 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -1,34 +1,10 @@ package io.anuke.mindustry.io; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.ObjectMap; -import io.anuke.mindustry.entities.enemies.*; - import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; public abstract class SaveFileVersion { - public static final Array> enemyIDs = Array.with( - Enemy.class, - FastEnemy.class, - RapidEnemy.class, - FlamerEnemy.class, - TankEnemy.class, - BlastEnemy.class, - MortarEnemy.class, - TestEnemy.class, - HealerEnemy.class, - TitanEnemy.class, - EmpEnemy.class - ); - - public static final ObjectMap, Byte> idEnemies = new ObjectMap, Byte>(){{ - for(int i = 0; i < enemyIDs.size; i ++){ - put(enemyIDs.get(i), (byte)i); - } - }}; - public final int version; public SaveFileVersion(int version){ diff --git a/core/src/io/anuke/mindustry/io/versions/Save12.java b/core/src/io/anuke/mindustry/io/versions/Save12.java index 9aab74821f..a4a893b9b4 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save12.java +++ b/core/src/io/anuke/mindustry/io/versions/Save12.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.io.versions; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Weapon; @@ -101,7 +101,7 @@ public class Save12 extends SaveFileVersion { int health = stream.readInt(); try{ - Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type)); + Enemy enemy = new Enemy(EnemyType.getByID(type)); enemy.lane = lane; enemy.health = health; enemy.x = x; @@ -219,29 +219,18 @@ public class Save12 extends SaveFileVersion { //--ENEMIES-- - int totalEnemies = 0; - Array enemies = Vars.control.enemyGroup.all(); - for(int i = 0; i < enemies.size; i ++){ - Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - totalEnemies ++; - } - } - - stream.writeInt(totalEnemies); //enemy amount + stream.writeInt(enemies.size); //enemy amount for(int i = 0; i < enemies.size; i ++){ Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - stream.writeByte(idEnemies.get(enemy.getClass())); //type - stream.writeByte(enemy.lane); //lane - stream.writeFloat(enemy.x); //x - stream.writeFloat(enemy.y); //y - stream.writeByte(enemy.tier); //tier - stream.writeInt(enemy.health); //health - } + stream.writeByte(enemy.type.id); //type + stream.writeByte(enemy.lane); //lane + stream.writeFloat(enemy.x); //x + stream.writeFloat(enemy.y); //y + stream.writeByte(enemy.tier); //tier + stream.writeInt(enemy.health); //health } //--MAP DATA-- diff --git a/core/src/io/anuke/mindustry/io/versions/Save13.java b/core/src/io/anuke/mindustry/io/versions/Save13.java index 220daf1bc6..39ce78b9fa 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save13.java +++ b/core/src/io/anuke/mindustry/io/versions/Save13.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.io.versions; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Weapon; @@ -101,7 +101,7 @@ public class Save13 extends SaveFileVersion { int health = stream.readShort(); try{ - Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type)); + Enemy enemy = new Enemy(EnemyType.getByID(type)); enemy.lane = lane; enemy.health = health; enemy.x = x; @@ -228,30 +228,18 @@ public class Save13 extends SaveFileVersion { } //--ENEMIES-- - - int totalEnemies = 0; - Array enemies = Vars.control.enemyGroup.all(); - for(int i = 0; i < enemies.size; i ++){ - Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - totalEnemies ++; - } - } - - stream.writeInt(totalEnemies); //enemy amount + stream.writeInt(enemies.size); //enemy amount for(int i = 0; i < enemies.size; i ++){ Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - stream.writeByte(idEnemies.get(enemy.getClass())); //type - stream.writeByte(enemy.lane); //lane - stream.writeFloat(enemy.x); //x - stream.writeFloat(enemy.y); //y - stream.writeByte(enemy.tier); //tier - stream.writeShort(enemy.health); //health - } + stream.writeByte(enemy.type.id); //type + stream.writeByte(enemy.lane); //lane + stream.writeFloat(enemy.x); //x + stream.writeFloat(enemy.y); //y + stream.writeByte(enemy.tier); //tier + stream.writeShort(enemy.health); //health } //--MAP DATA-- diff --git a/core/src/io/anuke/mindustry/io/versions/Save14.java b/core/src/io/anuke/mindustry/io/versions/Save14.java index 84f0aa150b..ce61a074e4 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save14.java +++ b/core/src/io/anuke/mindustry/io/versions/Save14.java @@ -3,9 +3,9 @@ package io.anuke.mindustry.io.versions; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Weapon; @@ -119,7 +119,7 @@ public class Save14 extends SaveFileVersion{ int health = stream.readShort(); try{ - Enemy enemy = ClassReflection.newInstance(enemyIDs.get(type)); + Enemy enemy = new Enemy(EnemyType.getByID(type)); enemy.lane = lane; enemy.health = health; enemy.x = x; @@ -257,29 +257,18 @@ public class Save14 extends SaveFileVersion{ //--ENEMIES-- - int totalEnemies = 0; - Array enemies = Vars.control.enemyGroup.all(); - for(int i = 0; i < enemies.size; i ++){ - Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - totalEnemies ++; - } - } - - stream.writeInt(totalEnemies); //enemy amount + stream.writeInt(enemies.size); //enemy amount for(int i = 0; i < enemies.size; i ++){ Enemy enemy = enemies.get(i); - if(idEnemies.containsKey(enemy.getClass())){ - stream.writeByte(idEnemies.get(enemy.getClass())); //type - stream.writeByte(enemy.lane); //lane - stream.writeFloat(enemy.x); //x - stream.writeFloat(enemy.y); //y - stream.writeByte(enemy.tier); //tier - stream.writeShort(enemy.health); //health - } + stream.writeByte(enemy.type.id); //type + stream.writeByte(enemy.lane); //lane + stream.writeFloat(enemy.x); //x + stream.writeFloat(enemy.y); //y + stream.writeByte(enemy.tier); //tier + stream.writeShort(enemy.health); //health } //--MAP DATA-- diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java index f8d037eaee..ef2969f7b8 100644 --- a/core/src/io/anuke/mindustry/net/Registrator.java +++ b/core/src/io/anuke/mindustry/net/Registrator.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.net; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.enemies.*; +import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Streamable.StreamBegin; import io.anuke.mindustry.net.Streamable.StreamChunk; @@ -50,17 +50,7 @@ public class Registrator { Player.class, Mech.class, - Enemy.class, - FastEnemy.class, - RapidEnemy.class, - FlamerEnemy.class, - TankEnemy.class, - BlastEnemy.class, - MortarEnemy.class, - TestEnemy.class, - HealerEnemy.class, - TitanEnemy.class, - EmpEnemy.class + Enemy.class }; } } diff --git a/core/src/io/anuke/mindustry/world/BlockLoader.java b/core/src/io/anuke/mindustry/world/BlockLoader.java index 0b3c96bb1d..2fef106002 100644 --- a/core/src/io/anuke/mindustry/world/BlockLoader.java +++ b/core/src/io/anuke/mindustry/world/BlockLoader.java @@ -117,10 +117,6 @@ public class BlockLoader { //add any new block sections here }; - for(Block block : Block.getAllBlocks()){ - UCore.log("\""+block.name+"\"", block.id, ""); - } - for(String string : defaultMap.keys()){ Block block = Block.getByName(string); blockmap.put(defaultMap.get(string, -1), block); diff --git a/core/src/io/anuke/mindustry/world/Generator.java b/core/src/io/anuke/mindustry/world/Generator.java index 693e4008d1..aa1336303f 100644 --- a/core/src/io/anuke/mindustry/world/Generator.java +++ b/core/src/io/anuke/mindustry/world/Generator.java @@ -4,11 +4,11 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.ObjectMap; - import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.enemies.TargetEnemy; +import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.EnemyTypes; import io.anuke.mindustry.world.ColorMapper.BlockPair; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.SpecialBlocks; @@ -77,7 +77,7 @@ public class Generator{ } if(color == Hue.rgb(Color.PURPLE)){ - if(!Vars.android) new TargetEnemy().set(x * Vars.tilesize, y * Vars.tilesize).add(); + if(!Vars.android) new Enemy(EnemyTypes.target).set(x * Vars.tilesize, y * Vars.tilesize).add(); floor = Blocks.stone; } 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 4a8da2fd5b..38391da0f0 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 @@ -149,7 +149,7 @@ public class Turret extends Block{ if(entity.target != null){ float targetRot = Angles.predictAngle(tile.worldx(), tile.worldy(), - entity.target.x, entity.target.y, entity.target.xvelocity, entity.target.yvelocity, bullet.speed); + entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed); if(Float.isNaN(entity.rotation)){ entity.rotation = 0; @@ -192,17 +192,17 @@ public class Turret extends Block{ float hittime = dst / bullet.speed; float angle = Angles.predictAngle(tile.worldx(), tile.worldy(), - entity.target.x, entity.target.y, entity.target.xvelocity, entity.target.yvelocity, bullet.speed); + entity.target.x, entity.target.y, entity.target.velocity.x, entity.target.velocity.y, bullet.speed); - float predictX = entity.target.x + entity.target.xvelocity * hittime, - predictY = entity.target.y + entity.target.yvelocity * hittime; + float predictX = entity.target.x + entity.target.velocity.x * hittime, + predictY = entity.target.y + entity.target.velocity.y * hittime; Draw.color(Color.GREEN); Draw.line(tile.worldx(), tile.worldy(), entity.target.x, entity.target.y); Draw.color(Color.RED); - Draw.line(tile.worldx(), tile.worldy(), entity.target.x + entity.target.xvelocity * hittime, - entity.target.y + entity.target.yvelocity * hittime); + Draw.line(tile.worldx(), tile.worldy(), entity.target.x + entity.target.velocity.x * hittime, + entity.target.y + entity.target.velocity.y * hittime); Draw.color(Color.PURPLE); Draw.thick(2f);