diff --git a/core/assets-raw/sprites/blocks/extra/cross-3.png b/core/assets-raw/sprites/blocks/extra/cross-3.png new file mode 100644 index 0000000000..60567dc1bf Binary files /dev/null and b/core/assets-raw/sprites/blocks/extra/cross-3.png differ diff --git a/core/assets-raw/sprites/blocks/production/coalextractor.png b/core/assets-raw/sprites/blocks/production/coalextractor.png index a0ab6216b9..27e85b1258 100644 Binary files a/core/assets-raw/sprites/blocks/production/coalextractor.png and b/core/assets-raw/sprites/blocks/production/coalextractor.png differ diff --git a/core/assets-raw/sprites/blocks/production/titaniumextractor.png b/core/assets-raw/sprites/blocks/production/titaniumextractor.png index 82d2b85848..81dca5c35a 100644 Binary files a/core/assets-raw/sprites/blocks/production/titaniumextractor.png and b/core/assets-raw/sprites/blocks/production/titaniumextractor.png differ diff --git a/core/assets/shaders/oil.fragment b/core/assets/shaders/oil.fragment index a1077bb9f1..52701e09a2 100644 --- a/core/assets/shaders/oil.fragment +++ b/core/assets/shaders/oil.fragment @@ -71,8 +71,8 @@ void main() { color = old; } - float n1 = snoise(coords / 20.0 + vec2(-time) / 340.0); - float n2 = snoise((coords + vec2(632.0)) / 7.0 + vec2(0.0, time) / 310.0); + float n1 = snoise(coords / 22.0 + vec2(-time) / 540.0); + float n2 = snoise((coords + vec2(632.0)) / 8.0 + vec2(0.0, time) / 510.0); float r = (n1 + n2) / 2.0; diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index b77326b83e..91e95d302b 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/version.properties b/core/assets/version.properties index 78d196f785..b817bacf7c 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Wed Mar 14 14:12:06 EDT 2018 +#Wed Mar 14 17:58:02 EDT 2018 version=release -androidBuildCode=496 +androidBuildCode=499 name=Mindustry code=3.4 build=custom build diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml index c964b6179d..b99a471915 100644 --- a/core/src/Mindustry.gwt.xml +++ b/core/src/Mindustry.gwt.xml @@ -4,7 +4,7 @@ - + diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index bb4dd8453d..855e4fce3c 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.effect.Shield; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.net.ClientDebug; import io.anuke.mindustry.net.ServerDebug; @@ -136,7 +136,7 @@ public class Vars{ public static Player player; public static final EntityGroup playerGroup = Entities.addGroup(Player.class).enableMapping(); - public static final EntityGroup enemyGroup = Entities.addGroup(Enemy.class).enableMapping(); + public static final EntityGroup enemyGroup = Entities.addGroup(BaseUnit.class).enableMapping(); public static final EntityGroup tileGroup = Entities.addGroup(TileEntity.class, false); public static final EntityGroup bulletGroup = Entities.addGroup(Bullet.class); public static final EntityGroup shieldGroup = Entities.addGroup(Shield.class, false); diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 1d65921692..c2e48d6e03 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -4,15 +4,14 @@ import com.badlogic.gdx.ai.pfa.PathFinderRequest; import com.badlogic.gdx.ai.pfa.PathSmoother; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Timers; -import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Log; -import io.anuke.ucore.util.Mathf; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.state; +import static io.anuke.mindustry.Vars.world; public class Pathfind{ /**Maximum time taken per frame on pathfinding for a single path.*/ @@ -33,91 +32,9 @@ public class Pathfind{ * If the path is not yet calculated, this returns the enemy's position (i. e. "don't move") * @param enemy The enemy to find a path for * @return The position the enemy should move to.*/ - public Vector2 find(Enemy enemy){ - //TODO fix -1/-2 node usage - if(enemy.node == -1 || enemy.node == -2){ - findNode(enemy); - } - - if(enemy.node == -2){ - enemy.node = -1; - } - - if(enemy.node < 0 || world.getSpawns().get(enemy.lane).pathTiles == null){ - return vector.set(enemy.x, enemy.y); - } - - Tile[] path = world.getSpawns().get(enemy.lane).pathTiles; - - if(enemy.node >= path.length){ - enemy.node = -1; - return vector.set(enemy.x, enemy.y); - } - - if(enemy.node <= -1){ - return vector.set(enemy.x, enemy.y); - } - - //TODO documentation on what this does - Tile prev = path[enemy.node - 1]; - - Tile target = path[enemy.node]; - - //a bridge has been broken, re-path - if(!world.passable(target.x, target.y)){ - remakePath(); - return vector.set(enemy.x, enemy.y); - } - - float projectLen = Vector2.dst(prev.worldx(), prev.worldy(), target.worldx(), target.worldy()) / 6f; - - Vector2 projection = projectPoint(prev.worldx(), prev.worldy(), - target.worldx(), target.worldy(), enemy.x, enemy.y); - - boolean canProject = true; - - if(projectLen < 8 || !onLine(projection, prev.worldx(), prev.worldy(), target.worldx(), target.worldy())){ - canProject = false; - }else{ - projection.add(v1.set(projectLen, 0).rotate(Angles.angle(prev.worldx(), prev.worldy(), - target.worldx(), target.worldy()))); - } - - float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy()); - float nlinedist = enemy.node >= path.length - 1 ? 9999 : - pointLineDist(path[enemy.node].worldx(), path[enemy.node].worldy(), - path[enemy.node + 1].worldx(), path[enemy.node + 1].worldy(), enemy.x, enemy.y); - - if(dst < 8 || nlinedist < 8){ - if(enemy.node <= path.length-2) - enemy.node ++; - - target = path[enemy.node]; - } - - if(canProject && projection.dst(enemy.x, enemy.y) < Vector2.dst(target.x, target.y, enemy.x, enemy.y)){ - vector.set(projection); - }else{ - vector.set(target.worldx(), target.worldy()); - } - - //near the core, stop - if(enemy.node == path.length - 1){ - vector.set(target.worldx(), target.worldy()); - } - - return vector; - - } - - /**Re-calculate paths for all enemies. Runs when a path changes while moving.*/ - private void remakePath(){ - for(int i = 0; i < enemyGroup.size(); i ++){ - Enemy enemy = enemyGroup.all().get(i); - enemy.node = -1; - } - - resetPaths(); + public Vector2 find(BaseUnit enemy){ + //TODO! + return v1.set(enemy.x, enemy.y); } /**Update the pathfinders and continue calculating the path if it hasn't been calculated yet. @@ -185,28 +102,6 @@ public class Pathfind{ point.request.statusChanged = true; //IMPORTANT! } - /**For an enemy that was just loaded from a save, find the node in the path it should be following.*/ - void findNode(Enemy enemy){ - if(enemy.lane >= world.getSpawns().size || enemy.lane < 0){ - enemy.lane = 0; - } - - if(world.getSpawns().get(enemy.lane).pathTiles == null){ - return; - } - - Tile[] path = world.getSpawns().get(enemy.lane).pathTiles; - - int closest = findClosest(path, enemy.x, enemy.y); - - closest = Mathf.clamp(closest, 1, path.length-1); - if(closest == -1){ - return; - } - - enemy.node = closest; - } - /**Finds the closest tile to a position, in an array of tiles.*/ private int findClosest(Tile[] tiles, float x, float y){ int cindex = -2; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 59072b4de1..eed3b75d35 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -17,6 +17,7 @@ import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.io.Saves; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.resource.Mech; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Map; import io.anuke.ucore.UCore; @@ -132,7 +133,7 @@ public class Control extends Module{ player = new Player(); player.name = Settings.getString("name"); - player.isAndroid = android; + player.mech = android ? Mech.standardShip : Mech.standard; player.color.set(Settings.getInt("color")); player.isLocal = true; diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index ef703fd940..562bc2fda7 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -2,25 +2,19 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.game.EnemySpawn; import io.anuke.mindustry.game.EventType.GameOverEvent; import io.anuke.mindustry.game.EventType.PlayEvent; import io.anuke.mindustry.game.EventType.ResetEvent; import io.anuke.mindustry.game.EventType.WaveEvent; -import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.game.WaveCreator; -import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; -import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.ProductionBlocks; -import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Events; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.modules.Module; -import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; @@ -73,30 +67,7 @@ public class Logic extends Module { } for(EnemySpawn spawn : spawns){ - Array spawns = world.getSpawns(); - - for(int lane = 0; lane < spawns.size; lane ++){ - int fl = lane; - Tile tile = spawns.get(lane).start; - int spawnamount = spawn.evaluate(state.wave, lane); - - for(int i = 0; i < spawnamount; i ++){ - float range = 12f; - - Timers.runTask(i*5f, () -> { - - 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(state.wave, fl); - enemy.add(); - - Effects.effect(Fx.spawn, enemy); - - state.enemies ++; - }); - } - } + //TODO spawn enemies for that spawnpoint } state.wave ++; diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 97cb4668c4..a12c3fc52b 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.SyncEntity; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net.SendMode; @@ -139,7 +139,7 @@ public class NetClient extends Module { SyncEntity entity = (SyncEntity) group.getByID(id); if(entity instanceof Player) players ++; - if(entity instanceof Enemy) enemies ++; + if(entity instanceof BaseUnit) enemies ++; if (entity == null || id == player.id) { if (id != player.id) { @@ -199,7 +199,7 @@ public class NetClient extends Module { }); Net.handleClient(EnemyDeathPacket.class, packet -> { - Enemy enemy = enemyGroup.getByID(packet.id); + BaseUnit enemy = enemyGroup.getByID(packet.id); if (enemy != null){ enemy.type.onDeath(enemy, true); }else if(recent.get(packet.id) != null){ diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index bca30b9f46..a04470aede 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -85,7 +85,7 @@ public class NetServer extends Module{ player.isAdmin = admins.isAdmin(Net.getConnection(id).address); player.clientid = id; player.name = packet.name; - player.isAndroid = packet.android; + player.mech = packet.android ? Mech.standardShip : Mech.standard; player.set(world.getSpawnX(), world.getSpawnY()); player.setNet(player.x, player.y); player.setNet(player.x, player.y); @@ -219,7 +219,7 @@ public class NetServer extends Module{ Net.handleServer(UpgradePacket.class, (id, packet) -> { Player player = connections.get(id); - Weapon weapon = (Weapon) Upgrade.getByID(packet.id); + Weapon weapon = Upgrade.getByID(packet.id); if (!weapons.containsKey(player.name)) weapons.put(player.name, new ByteArray()); if (!weapons.get(player.name).contains(weapon.id)) weapons.get(player.name).add(weapon.id); diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 5dea8438a6..0667505660 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -15,7 +15,7 @@ import com.badlogic.gdx.utils.Pools; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.SyncEntity; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.graphics.BlockRenderer; import io.anuke.mindustry.graphics.Shaders; @@ -282,7 +282,7 @@ public class Renderer extends RendererModule{ Graphics.surface(indicatorSurface); Draw.color(Color.RED); - for(Enemy enemy : enemyGroup.all()) { + for(BaseUnit enemy : enemyGroup.all()) { if (rect.setSize(camera.viewportWidth, camera.viewportHeight).setCenter(camera.position.x, camera.position.y) .overlaps(enemy.hitbox.getRect(enemy.x, enemy.y))) { @@ -503,7 +503,7 @@ public class Renderer extends RendererModule{ if((!debug || showUI) && Settings.getBool("healthbars")){ //draw entity health bars - for(Enemy entity : enemyGroup.all()){ + for(BaseUnit entity : enemyGroup.all()){ drawHealth(entity); } diff --git a/core/src/io/anuke/mindustry/entities/Bullet.java b/core/src/io/anuke/mindustry/entities/Bullet.java index 279993b4c4..60e43ddd4f 100644 --- a/core/src/io/anuke/mindustry/entities/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/Bullet.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.entities; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.entities.BulletEntity; import io.anuke.ucore.entities.Entity; @@ -37,7 +37,7 @@ public class Bullet extends BulletEntity{ } public boolean collidesTiles(){ - return owner instanceof Enemy; + return owner instanceof BaseUnit; } @Override diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 4a3963ecc9..386b86c745 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.graphics.Color; import io.anuke.mindustry.entities.effect.DamageArea; import io.anuke.mindustry.entities.effect.EMP; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.graphics.Fx; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.core.Effects; @@ -122,7 +122,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shellexplosion, b); - DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f)); + DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f)); } }, flak = new BulletType(2.9f, 8) { @@ -202,7 +202,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shockwaveSmall, b); - DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 50f, (int)(damage * 2f/3f)); + DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 50f, (int)(damage * 2f/3f)); } }, yellowshell = new BulletType(1.2f, 20){ @@ -233,7 +233,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.shellsmoke, b); Effects.effect(Fx.shockwaveSmall, b); - DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f)); + DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 25f, (int)(damage * 2f/3f)); } }, blast = new BulletType(1.1f, 90){ @@ -371,7 +371,7 @@ public abstract class BulletType extends BaseBulletType{ Effects.effect(Fx.clusterbomb, b); - DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 35f, damage); + DamageArea.damage(!(b.owner instanceof BaseUnit), b.x, b.y, 35f, damage); } }, vulcan = new BulletType(4.5f, 12) { diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 0a53034999..a878be07f2 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -23,17 +23,14 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.*; -public class Player extends SyncEntity{ +public class Player extends Unit{ static final float speed = 1.1f; static final float dashSpeed = 1.8f; static final int timerDash = 0; - static final int timerShootLeft = 1; - static final int timerShootRight = 2; static final int timerRegen = 3; public String name = "name"; - public boolean isAndroid; public boolean isAdmin; public Color color = new Color(); @@ -60,9 +57,14 @@ public class Player extends SyncEntity{ heal(); } + @Override + public float getMass(){ + return mech.mass; + } + @Override public void damage(int amount){ - if(debug || isAndroid) return; + if(debug || mech.flying) return; health -= amount; if(health <= 0 && !dead && isLocal){ //remote players don't die normally @@ -79,7 +81,7 @@ public class Player extends SyncEntity{ return false; } } - return !isDead() && super.collides(other) && !isAndroid; + return !isDead() && super.collides(other) && !mech.flying; } @Override @@ -113,34 +115,33 @@ public class Player extends SyncEntity{ @Override public void drawSmooth(){ - if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) || dead) return; + if((debug && (!showPlayer || !showUI)) || dead) return; boolean snap = snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal; - String part = isAndroid ? "ship" : "mech"; + String mname = "mech-" + mech.name; Shaders.outline.color.set(getColor()); Shaders.outline.lighten = 0f; - Shaders.outline.region = Draw.region(part + "-" + mech.name); + Shaders.outline.region = Draw.region(mname); Shaders.outline.apply(); - if(!isAndroid) { - for (int i : Mathf.signs) { - Weapon weapon = i < 0 ? weaponLeft : weaponRight; - tr.trns(angle - 90, 3*i, 2); - float w = i > 0 ? -8 : 8; - if(snap){ - Draw.rect(weapon.name + "-equip", (int)x + tr.x, (int)y + tr.y, w, 8, angle - 90); - }else{ - Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, angle - 90); - } + for (int i : Mathf.signs) { + Weapon weapon = i < 0 ? weaponLeft : weaponRight; + tr.trns(rotation - 90, 3*i, 2); + float w = i > 0 ? -8 : 8; + if(snap){ + Draw.rect(weapon.name + "-equip", (int)x + tr.x, (int)y + tr.y, w, 8, rotation - 90); + }else{ + Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, rotation - 90); } } + if(snap){ - Draw.rect(part + "-" + mech.name, (int)x, (int)y, angle-90); + Draw.rect(mname, (int)x, (int)y, rotation -90); }else{ - Draw.rect(part + "-" + mech.name, x, y, angle-90); + Draw.rect(mname, x, y, rotation -90); } Graphics.flush(); @@ -148,16 +149,25 @@ public class Player extends SyncEntity{ @Override public void update(){ - if(!isLocal || isAndroid){ - if(isAndroid && isLocal){ - angle = Mathf.slerpDelta(angle, targetAngle, 0.2f); - } - if(!isLocal) interpolate(); + if(!isLocal){ + interpolate(); return; } if(isDead()) return; + if(mech.flying){ + updateFlying(); + }else{ + updateMech(); + } + + x = Mathf.clamp(x, 0, world.width() * tilesize); + y = Mathf.clamp(y, 0, world.height() * tilesize); + } + + protected void updateMech(){ + Tile tile = world.tileWorld(x, y); //if player is in solid block @@ -175,14 +185,14 @@ public class Player extends SyncEntity{ if(ui.chatfrag.chatOpen()) return; dashing = Inputs.keyDown("dash"); - + float speed = dashing ? (debug ? Player.dashSpeed * 5f : Player.dashSpeed) : Player.speed; - + if(health < maxhealth && timer.get(timerRegen, 20)) health ++; health = Mathf.clamp(health, -1, maxhealth); - + movement.set(0, 0); float xa = Inputs.getAxis("move_x"); @@ -192,7 +202,7 @@ public class Player extends SyncEntity{ movement.y += ya*speed; movement.x += xa*speed; - + boolean shooting = !Inputs.keyDown("dash") && Inputs.keyDown("shoot") && control.input().recipe == null && !ui.hasMouse() && !control.input().onConfigurable(); @@ -200,30 +210,31 @@ public class Player extends SyncEntity{ weaponLeft.update(player, true); weaponRight.update(player, false); } - + if(dashing && timer.get(timerDash, 3) && movement.len() > 0){ - Effects.effect(Fx.dashsmoke, x + Angles.trnsx(angle + 180f, 3f), y + Angles.trnsy(angle + 180f, 3f)); + Effects.effect(Fx.dashsmoke, x + Angles.trnsx(rotation + 180f, 3f), y + Angles.trnsy(rotation + 180f, 3f)); } - + movement.limit(speed); - + if(!noclip){ move(movement.x*Timers.delta(), movement.y*Timers.delta()); }else{ x += movement.x*Timers.delta(); y += movement.y*Timers.delta(); } - + if(!shooting){ if(!movement.isZero()) - angle = Mathf.slerpDelta(angle, movement.angle(), 0.13f); + rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f); }else{ float angle = Angles.mouseAngle(x, y); - this.angle = Mathf.slerpDelta(this.angle, angle, 0.1f); + this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f); } + } - x = Mathf.clamp(x, 0, world.width() * tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize); + protected void updateFlying(){ + rotation = Mathf.slerpDelta(rotation, targetAngle, 0.2f); } @Override @@ -233,7 +244,7 @@ public class Player extends SyncEntity{ @Override public String toString() { - return "Player{" + id + ", android=" + isAndroid + ", local=" + isLocal + ", " + x + ", " + y + "}\n"; + return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}\n"; } @Override @@ -242,7 +253,7 @@ public class Player extends SyncEntity{ buffer.put(name.getBytes()); buffer.put(weaponLeft.id); buffer.put(weaponRight.id); - buffer.put(isAndroid ? 1 : (byte)0); + buffer.put(mech.id); buffer.put(isAdmin ? 1 : (byte)0); buffer.putInt(Color.rgba8888(color)); buffer.putFloat(x); @@ -255,9 +266,9 @@ public class Player extends SyncEntity{ byte[] n = new byte[nlength]; buffer.get(n); name = new String(n); - weaponLeft = (Weapon) Upgrade.getByID(buffer.get()); - weaponRight = (Weapon) Upgrade.getByID(buffer.get()); - isAndroid = buffer.get() == 1; + weaponLeft = Upgrade.getByID(buffer.get()); + weaponRight = Upgrade.getByID(buffer.get()); + mech = Upgrade.getByID(buffer.get()); isAdmin = buffer.get() == 1; color.set(buffer.getInt()); x = buffer.getFloat(); @@ -274,7 +285,7 @@ public class Player extends SyncEntity{ data.putFloat(interpolator.target.x); data.putFloat(interpolator.target.y); } - data.putFloat(angle); + data.putFloat(rotation); data.putShort((short)health); data.put((byte)(dashing ? 1 : 0)); } @@ -299,10 +310,10 @@ public class Player extends SyncEntity{ Interpolator i = interpolator; - float tx = x + Angles.trnsx(angle + 180f, 4f); - float ty = y + Angles.trnsy(angle + 180f, 4f); + float tx = x + Angles.trnsx(rotation + 180f, 4f); + float ty = y + Angles.trnsy(rotation + 180f, 4f); - if(isAndroid && i.target.dst(i.last) > 2f && timer.get(timerDash, 1)){ + if(mech.flying && i.target.dst(i.last) > 2f && timer.get(timerDash, 1)){ Effects.effect(Fx.dashsmoke, tx, ty); } diff --git a/core/src/io/anuke/mindustry/entities/SyncEntity.java b/core/src/io/anuke/mindustry/entities/SyncEntity.java index 21f3000a24..1e34c724e8 100644 --- a/core/src/io/anuke/mindustry/entities/SyncEntity.java +++ b/core/src/io/anuke/mindustry/entities/SyncEntity.java @@ -3,9 +3,7 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.utils.ObjectIntMap; import com.badlogic.gdx.utils.TimeUtils; -import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.DestructibleEntity; import io.anuke.ucore.util.Mathf; @@ -14,24 +12,13 @@ import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.threads; +/**Base class for any entity that needs to be synced across clients.*/ public abstract class SyncEntity extends DestructibleEntity{ - private static ObjectIntMap> writeSizes = new ObjectIntMap<>(); - protected transient Interpolator interpolator = new Interpolator(); - - //smoothed position/angle + /**smoothed position and rotation*/ private Vector3 spos = new Vector3(); - - public float angle; - - static{ - setWriteSize(Enemy.class, 4 + 4 + 2 + 2); - setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1); - } - - public static boolean isSmoothing(){ - return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f; - } + /**the general rotation.*/ + public float rotation; public abstract void writeSpawn(ByteBuffer data); public abstract void readSpawn(ByteBuffer data); @@ -39,56 +26,47 @@ public abstract class SyncEntity extends DestructibleEntity{ public abstract void write(ByteBuffer data); public abstract void read(ByteBuffer data, long time); + /**Interpolate everything needed. Should be called in update() for non-local entities.*/ public void interpolate(){ interpolator.update(); x = interpolator.pos.x; y = interpolator.pos.y; - angle = interpolator.angle; + rotation = interpolator.rotation; } + /**Same as draw, but for interpolated drawing at low tick speeds.*/ + public abstract void drawSmooth(); + + /**Do not override, use drawSmooth instead.*/ @Override public final void draw(){ - final float x = this.x, y = this.y, angle = this.angle; + final float x = this.x, y = this.y, rotation = this.rotation; //interpolates data at low tick speeds. if(isSmoothing()){ if(Vector2.dst(spos.x, spos.y, x, y) > 128){ - spos.set(x, y, angle); + spos.set(x, y, rotation); } this.x = spos.x = Mathf.lerpDelta(spos.x, x, 0.2f); this.y = spos.y = Mathf.lerpDelta(spos.y, y, 0.2f); - this.angle = spos.z = Mathf.slerpDelta(spos.z, angle, 0.3f); + this.rotation = spos.z = Mathf.slerpDelta(spos.z, rotation, 0.3f); } drawSmooth(); this.x = x; this.y = y; - this.angle = angle; + this.rotation = rotation; } + /**Returns smoothed position. x = x, y = y, z = rotation.*/ public Vector3 getDrawPosition(){ - return isSmoothing() ? spos : spos.set(x, y, angle); - } - - public void drawSmooth(){} - - public int getWriteSize(){ - return getWriteSize(getClass()); - } - - public static int getWriteSize(Class type){ - int i = writeSizes.get(type, -1); - if(i == -1) throw new RuntimeException("Write size for class \"" + type + "\" is not defined!"); - return i; - } - - protected static void setWriteSize(Class type, int size){ - writeSizes.put(type, size); + return isSmoothing() ? spos : spos.set(x, y, rotation); } + /**Set position and interpolator position.*/ public T setNet(float x, float y){ set(x, y); interpolator.target.set(x, y); @@ -98,6 +76,10 @@ public abstract class SyncEntity extends DestructibleEntity{ return (T)this; } + private static boolean isSmoothing(){ + return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f; + } + public static class Interpolator { //used for movement public Vector2 target = new Vector2(); @@ -108,7 +90,7 @@ public abstract class SyncEntity extends DestructibleEntity{ //current state public Vector2 pos = new Vector2(); - public float angle; + public float rotation; public void read(float cx, float cy, float x, float y, float angle, long sent){ targetrot = angle; @@ -124,7 +106,7 @@ public abstract class SyncEntity extends DestructibleEntity{ Mathf.lerp2(pos.set(last), target, time); - angle = Mathf.slerpDelta(angle, targetrot, 0.6f); + rotation = Mathf.slerpDelta(rotation, targetrot, 0.6f); if(target.dst(pos) > 128){ pos.set(target); diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java new file mode 100644 index 0000000000..61467c19a9 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -0,0 +1,15 @@ +package io.anuke.mindustry.entities; + +import com.badlogic.gdx.math.Vector2; +import io.anuke.mindustry.game.Team; + +public abstract class Unit extends SyncEntity { + //total duration of hit effect + public static final float hitDuration = 5f; + + public Team team = Team.blue; + public Vector2 velocity = new Vector2(); + public float hitTime; + + public abstract float getMass(); +} diff --git a/core/src/io/anuke/mindustry/entities/effect/DamageArea.java b/core/src/io/anuke/mindustry/entities/effect/DamageArea.java index c1ce0382f9..d58ba9727a 100644 --- a/core/src/io/anuke/mindustry/entities/effect/DamageArea.java +++ b/core/src/io/anuke/mindustry/entities/effect/DamageArea.java @@ -45,7 +45,7 @@ public class DamageArea{ rect.height += expand*2; Consumer cons = e -> { - if(e == owner || (e instanceof Player && ((Player)e).isAndroid)) return; + if(e == owner) return; DestructibleEntity enemy = (DestructibleEntity) e; Rectangle other = enemy.hitbox.getRect(enemy.x, enemy.y); other.y -= expand; @@ -69,7 +69,7 @@ public class DamageArea{ damage(true, x, y, radius, damage); for(Player player : playerGroup.all()){ - if(player.isAndroid) continue; + //if(player.isAndroid) continue; int amount = calculateDamage(x, y, player.x, player.y, radius, damage); player.damage(amount); } @@ -78,7 +78,7 @@ public class DamageArea{ public static void damage(boolean enemies, float x, float y, float radius, int damage){ Consumer cons = entity -> { DestructibleEntity enemy = (DestructibleEntity)entity; - if(enemy.distanceTo(x, y) > radius || (entity instanceof Player && ((Player)entity).isAndroid)){ + if(enemy.distanceTo(x, y) > radius){ return; } int amount = calculateDamage(x, y, enemy.x, enemy.y, radius, damage); diff --git a/core/src/io/anuke/mindustry/entities/effect/Shield.java b/core/src/io/anuke/mindustry/entities/effect/Shield.java index 0b46e777a7..e829f6c30a 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Shield.java +++ b/core/src/io/anuke/mindustry/entities/effect/Shield.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.entities.effect; import com.badlogic.gdx.math.Interpolation; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock; import io.anuke.ucore.core.Timers; @@ -55,7 +55,7 @@ public class Shield extends Entity{ Entities.getNearby(bulletGroup, x, y, block.shieldRadius * 2*uptime + 10, entity->{ BulletEntity bullet = (BulletEntity)entity; - if((bullet.owner instanceof Enemy || hitPlayers)){ + if((bullet.owner instanceof BaseUnit || hitPlayers)){ float dst = entity.distanceTo(this); diff --git a/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java b/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java index eb35433236..89b84e40e5 100644 --- a/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java +++ b/core/src/io/anuke/mindustry/entities/effect/TeslaOrb.java @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectSet; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.graphics.Fx; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; @@ -19,7 +19,7 @@ import static io.anuke.mindustry.Vars.enemyGroup; public class TeslaOrb extends Entity{ private Array points = new Array<>(); - private ObjectSet hit = new ObjectSet<>(); + private ObjectSet hit = new ObjectSet<>(); private int damage = 0; private float range = 0; private float lifetime = 30f; @@ -47,10 +47,10 @@ public class TeslaOrb extends Entity{ Array enemies = Entities.getNearby(enemyGroup, curx, cury, range*2f); for(SolidEntity entity : enemies){ - if(entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((Enemy)entity)){ - hit.add((Enemy)entity); + if(entity != null && entity.distanceTo(curx, cury) < range && !hit.contains((BaseUnit)entity)){ + hit.add((BaseUnit)entity); points.add(new Vector2(entity.x + Mathf.range(shake), entity.y + Mathf.range(shake))); - damageEnemy((Enemy)entity); + damageEnemy((BaseUnit)entity); curx = entity.x; cury = entity.y; break; @@ -63,7 +63,7 @@ public class TeslaOrb extends Entity{ } } - void damageEnemy(Enemy enemy){ + void damageEnemy(BaseUnit enemy){ enemy.damage(damage); Effects.effect(Fx.laserhit, enemy.x + Mathf.range(2f), enemy.y + Mathf.range(2f)); } diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/BaseUnit.java similarity index 51% rename from core/src/io/anuke/mindustry/entities/enemies/Enemy.java rename to core/src/io/anuke/mindustry/entities/enemies/BaseUnit.java index 8050b08d20..19c2c11c26 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/BaseUnit.java @@ -1,50 +1,31 @@ package io.anuke.mindustry.entities.enemies; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.entities.Bullet; -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.SyncEntity; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.net.NetEvents; +import io.anuke.mindustry.entities.Unit; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.SolidEntity; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Timer; -import io.anuke.ucore.util.Translator; import java.nio.ByteBuffer; import static io.anuke.mindustry.Vars.enemyGroup; -public class Enemy extends SyncEntity { - public EnemyType type; - +public class BaseUnit extends Unit { + public UnitType type; public Timer timer = new Timer(5); - public float idletime = 0f; - public int lane; - public int node = -1; - - public Enemy spawner; - public int spawned; - - public Vector2 velocity = new Vector2(); - public Vector2 totalMove = new Vector2(); - public Vector2 tpos = new Vector2(-999, -999); public Entity target; - public float hitTime; - public int tier = 1; - public TextureRegion region; - public Translator tr = new Translator(); - - public Enemy(EnemyType type){ + public BaseUnit(UnitType type){ this.type = type; } /**internal constructor used for deserialization, DO NOT USE*/ - public Enemy(){} + public BaseUnit(){} + + @Override + public float getMass() { + return type.mass; + } @Override public void update(){ @@ -68,13 +49,13 @@ public class Enemy extends SyncEntity { @Override public boolean collides(SolidEntity other){ - return (other instanceof Bullet) && !(((Bullet) other).owner instanceof Enemy); + return (other instanceof Bullet) && !(((Bullet) other).owner instanceof BaseUnit); } @Override public void damage(int amount){ super.damage(amount); - hitTime = EnemyType.hitDuration; + hitTime = hitDuration; } @Override @@ -91,22 +72,16 @@ public class Enemy extends SyncEntity { public void added(){ hitbox.setSize(type.hitsize); hitboxTile.setSize(type.hitsizeTile); - maxhealth = type.health * tier; - region = Draw.region(type.name + "-t" + Mathf.clamp(tier, 1, 3)); - - heal(); } @Override - public Enemy add(){ + public BaseUnit add(){ return add(enemyGroup); } @Override public void writeSpawn(ByteBuffer buffer) { buffer.put(type.id); - buffer.put((byte)lane); - buffer.put((byte)tier); buffer.putFloat(x); buffer.putFloat(y); buffer.putShort((short)health); @@ -114,9 +89,7 @@ public class Enemy extends SyncEntity { @Override public void readSpawn(ByteBuffer buffer) { - type = EnemyType.getByID(buffer.get()); - lane = buffer.get(); - tier = buffer.get(); + type = UnitType.getByID(buffer.get()); x = buffer.getFloat(); y = buffer.getFloat(); health = buffer.getShort(); @@ -127,38 +100,18 @@ public class Enemy extends SyncEntity { public void write(ByteBuffer data) { data.putFloat(x); data.putFloat(y); - data.putShort((short)(angle*2)); + data.putShort((short)(rotation *2)); data.putShort((short)health); } @Override public void read(ByteBuffer data, long time) { - float x = data.getFloat(); float y = data.getFloat(); short angle = data.getShort(); short health = data.getShort(); this.health = health; - interpolator.read(this.x, this.y, x, y, angle/2f, time); } - - public void shoot(BulletType bullet){ - shoot(bullet, 0); - } - - public void shoot(BulletType bullet, float rotation){ - - if(!(Net.client())) { - tr.trns(angle + rotation, type.length); - Bullet out = new Bullet(bullet, this, x + tr.x, y + tr.y, this.angle + rotation).add(); - out.damage = (int) ((bullet.damage * (1 + (tier - 1) * 1f))); - type.onShoot(this, bullet, rotation); - - if(Net.server()){ - NetEvents.handleBullet(bullet, this, x + tr.x, y + tr.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 deleted file mode 100644 index b5603fd8a9..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java +++ /dev/null @@ -1,289 +0,0 @@ -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.entities.BulletType; -import io.anuke.mindustry.entities.Player; -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.NetEvents; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.Blocks; -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.graphics.Draw; -import io.anuke.ucore.graphics.Lines; -import io.anuke.ucore.util.Mathf; -import io.anuke.ucore.util.Strings; - -import static io.anuke.mindustry.Vars.*; - -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"), Color.valueOf("cb2dff"), Color.valueOf("362020") }; - public final static int maxtier = tierColors.length; - public final static float maxIdleLife = 60f*2f; //2 seconds idle = death - public final static float hitDuration = 5f; - - 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 boolean targetClient = false; - protected float mass = 1f; - - protected final int timerTarget = timeid ++; - protected final int timerReload = timeid ++; - protected final int timerReset = timeid ++; - - protected final Vector2 shift = new Vector2(); - protected final Vector2 move = new Vector2(); - protected final Vector2 calc = new Vector2(); - - public EnemyType(String name){ - this.id = lastid++; - this.name = name; - types.add(this); - } - - public void draw(Enemy enemy){ - Shaders.outline.color.set(tierColors[enemy.tier - 1]); - Shaders.outline.lighten = Mathf.clamp(enemy.hitTime/hitDuration); - Shaders.outline.region = enemy.region; - - Shaders.outline.apply(); - - Draw.rect(enemy.region, enemy.x, enemy.y, enemy.angle - 90); - Draw.color(); - - Graphics.flush(); - - if(isCalculating(enemy)){ - Draw.color(Color.SKY); - Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f); - Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f + 180f); - Draw.color(); - } - - if(showPaths){ - Draw.tscl(0.25f); - Draw.text((int)enemy.idletime + " " + enemy.node + " " + enemy.id + "\n" + Strings.toFixed(enemy.totalMove.x, 2) + ", " - + Strings.toFixed(enemy.totalMove.x, 2), enemy.x, enemy.y); - Draw.tscl(fontscale); - } - - Shaders.outline.lighten = 0f; - } - - public void drawOver(Enemy enemy){ } - - public void update(Enemy enemy){ - float lastx = enemy.x, lasty = enemy.y; - if(enemy.hitTime > 0){ - enemy.hitTime -= Timers.delta(); - } - - if(enemy.lane >= world.getSpawns().size || enemy.lane < 0) enemy.lane = 0; - - boolean waiting = enemy.lane >= world.getSpawns().size || enemy.lane < 0 - || world.getSpawns().get(enemy.lane).pathTiles == null || enemy.node <= 0; - - move(enemy); - - enemy.velocity.set(enemy.x - lastx, enemy.y - lasty).scl(1f / Timers.delta()); - enemy.totalMove.add(enemy.velocity); - - float minv = 0.07f; - - if(enemy.timer.get(timerReset, 80)){ - enemy.totalMove.setZero(); - } - - if(enemy.velocity.len() < minv && !waiting && enemy.target == null){ - enemy.idletime += Timers.delta(); - }else{ - enemy.idletime = 0; - } - - if(enemy.timer.getTime(timerReset) > 50 && enemy.totalMove.len() < 0.2f && !waiting && enemy.target == null){ - enemy.idletime = 999999f; - } - - 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.slerpDelta(enemy.angle, enemy.velocity.angle(), rotatespeed); - }else{ - enemy.angle = Mathf.slerpDelta(enemy.angle, enemy.angleTo(enemy.target), turretrotatespeed); - } - - enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize); - enemy.y = Mathf.clamp(enemy.y, 0, world.height() * tilesize); - } - - public void move(Enemy enemy){ - if(Net.client()){ - enemy.interpolate(); - if(targetClient) updateTargeting(enemy, false); - return; - } - - float speed = this.speed + 0.04f * enemy.tier; - float range = this.range + enemy.tier * 5; - - Tile core = world.getCore(); - - if(core == null) return; - - if(enemy.idletime > maxIdleLife && enemy.node > 0){ - enemy.onDeath(); - return; - } - - boolean nearCore = enemy.distanceTo(core.worldx(), core.worldy()) <= range - 18f && stopNearCore; - Vector2 vec; - - if(nearCore){ - vec = move.setZero(); - if(targetCore) enemy.target = core.entity; - }else{ - vec = world.pathfinder().find(enemy); - vec.sub(enemy.x, enemy.y).limit(speed); - } - - shift.setZero(); - float shiftRange = enemy.hitbox.width + 2f; - float avoidRange = shiftRange + 4f; - float attractRange = avoidRange + 7f; - float avoidSpeed = this.speed/2.7f; - - Entities.getNearby(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){ - calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed); - shift.add(calc.scl(1.1f)); - }else if(dst < attractRange && !nearCore && !isCalculating(enemy)){ - calc.set((enemy.x - other.x), (enemy.y - other.y)).setLength(avoidSpeed); - shift.add(calc.scl(-1)); - } - }); - - shift.limit(1f); - vec.add(shift.scl(0.5f)); - - enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta()); - - updateTargeting(enemy, nearCore); - - behavior(enemy); - } - - public void behavior(Enemy enemy){} - - 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 = world.findTileTarget(enemy.x, enemy.y, null, range, false); - - //no tile found - if(enemy.target == null){ - enemy.target = Entities.getClosest(playerGroup, enemy.x, enemy.y, range, e -> !((Player)e).isAndroid && - !((Player)e).isDead()); - } - }else if(nearCore){ - enemy.target = world.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)){ - 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, boolean force){ - if(Net.server()){ - NetEvents.handleEnemyDeath(enemy); - } - - if(!Net.client() || force) { - Effects.effect(Fx.explosion, enemy); - Effects.shake(3f, 4f, enemy); - Effects.sound("bang2", enemy); - enemy.remove(); - enemy.dead = true; - } - } - - public void removed(Enemy enemy){ - if(!enemy.dead){ - if(enemy.spawner != null){ - enemy.spawner.spawned --; - }else{ - state.enemies --; - } - } - } - - public boolean isCalculating(Enemy enemy){ - return enemy.node < 0 && !Net.client(); - } - - 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 deleted file mode 100644 index 799b8fb1be..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/EnemyTypes.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.anuke.mindustry.entities.enemies; - -import io.anuke.mindustry.entities.enemies.types.BlastType; -import io.anuke.mindustry.entities.enemies.types.EmpType; -import io.anuke.mindustry.entities.enemies.types.FastType; -import io.anuke.mindustry.entities.enemies.types.FlamerType; -import io.anuke.mindustry.entities.enemies.types.FortressType; -import io.anuke.mindustry.entities.enemies.types.HealerType; -import io.anuke.mindustry.entities.enemies.types.MortarType; -import io.anuke.mindustry.entities.enemies.types.RapidType; -import io.anuke.mindustry.entities.enemies.types.*; -import io.anuke.mindustry.entities.enemies.types.TankType; -import io.anuke.mindustry.entities.enemies.types.TargetType; -import io.anuke.mindustry.entities.enemies.types.TitanType; - -public class EnemyTypes { - public static final EnemyType - - standard = new StandardType(), - fast = new FastType(), - rapid = new RapidType(), - flamer = new FlamerType(), - tank = new TankType(), - blast = new BlastType(), - mortar = new MortarType(), - healer = new HealerType(), - titan = new TitanType(), - emp = new EmpType(), - fortress = new FortressType(), - target = new TargetType(); - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/UnitType.java b/core/src/io/anuke/mindustry/entities/enemies/UnitType.java new file mode 100644 index 0000000000..c465d68e24 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/UnitType.java @@ -0,0 +1,81 @@ +package io.anuke.mindustry.entities.enemies; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.ucore.util.Mathf; + +import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.world; + +public class UnitType { + private static byte lastid = 0; + private static Array types = new Array<>(); + + public final String name; + public final byte id; + + protected int health = 60; + protected float hitsize = 5f; + protected float hitsizeTile = 4f; + protected float speed = 0.4f; + protected float range = 60; + protected float rotatespeed = 0.1f; + protected float mass = 1f; + protected boolean isFlying; + + public UnitType(String name){ + this.id = lastid++; + this.name = name; + types.add(this); + } + + public void draw(BaseUnit enemy){ + //TODO + } + + public void drawOver(BaseUnit enemy){ + //TODO + } + + public void update(BaseUnit enemy){ + //TODO + enemy.x = Mathf.clamp(enemy.x, 0, world.width() * tilesize); + enemy.y = Mathf.clamp(enemy.y, 0, world.height() * tilesize); + } + + public void move(BaseUnit enemy){ + //TODO + } + + public void behavior(BaseUnit enemy){ + //TODO + } + + public void updateTargeting(BaseUnit enemy){ + //TODO + } + + public void updateShooting(BaseUnit enemy){ + //TODO + } + + public void shoot(BaseUnit enemy){ + //TODO + } + + public void onShoot(BaseUnit enemy, BulletType type, float rotation){ + //TODO + } + + public void onDeath(BaseUnit enemy, boolean force){ + //TODO + } + + public void removed(BaseUnit enemy){ + //TODO + } + + public static UnitType getByID(byte id){ + return types.get(id); + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/UnitTypes.java b/core/src/io/anuke/mindustry/entities/enemies/UnitTypes.java new file mode 100644 index 0000000000..249f9e92fb --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/UnitTypes.java @@ -0,0 +1,5 @@ +package io.anuke.mindustry.entities.enemies; + +public class UnitTypes { + //TODO list types here. +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/BlastType.java b/core/src/io/anuke/mindustry/entities/enemies/types/BlastType.java deleted file mode 100644 index 9132d5a666..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/BlastType.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -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 static io.anuke.mindustry.Vars.tilesize; - -public class BlastType extends EnemyType { - - public BlastType() { - super("blastenemy"); - health = 30; - speed = 0.8f; - bullet = null; - turretrotatespeed = 0f; - mass = 0.8f; - stopNearCore = false; - } - - @Override - public void behavior(Enemy enemy){ - - float range = 10f; - float ox = 0, oy = 0; - - if(enemy.target instanceof TileEntity){ - TileEntity e = (TileEntity)enemy.target; - range = (e.tile.block().size * tilesize) /2f + 8f; - ox = e.tile.block().getPlaceOffset().x; - oy = e.tile.block().getPlaceOffset().y; - } - - if(enemy.target != null && enemy.target.distanceTo(enemy.x - ox, enemy.y - oy) < range){ - explode(enemy); - } - } - - @Override - public void onDeath(Enemy enemy, boolean force){ - if(force) explode(enemy); - super.onDeath(enemy, force); - } - - 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/EmpType.java b/core/src/io/anuke/mindustry/entities/enemies/types/EmpType.java deleted file mode 100644 index cfe1a62da2..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/EmpType.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class EmpType extends EnemyType { - - public EmpType() { - 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/FastType.java b/core/src/io/anuke/mindustry/entities/enemies/types/FastType.java deleted file mode 100644 index 29c7ed5a0c..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/FastType.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class FastType extends EnemyType { - - public FastType() { - super("fastenemy"); - - speed = 0.73f; - reload = 20; - mass = 0.2f; - - health = 50; - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/FlamerType.java b/core/src/io/anuke/mindustry/entities/enemies/types/FlamerType.java deleted file mode 100644 index 0aad1e7b10..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/FlamerType.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class FlamerType extends EnemyType { - - public FlamerType() { - super("flamerenemy"); - - speed = 0.35f; - health = 150; - reload = 6; - bullet = BulletType.flameshot; - shootsound = "flame"; - mass = 1.5f; - range = 40; - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java b/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java deleted file mode 100644 index d02c85fe7c..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/FortressType.java +++ /dev/null @@ -1,60 +0,0 @@ -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.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; - -import static io.anuke.mindustry.Vars.world; - -public class FortressType extends EnemyType { - final int maxSpawn = 6; - final float spawnTime = 190; - - public FortressType() { - 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 behavior(Enemy enemy){ - if(enemy.distanceTo(world.getCore().worldx(), - world.getCore().worldy()) <= 90f){ - - if(Timers.get(this, "spawn", spawnTime) && enemy.spawned < maxSpawn){ - enemy.tr.trns(enemy.angle, 20f); - - Enemy s = new Enemy(EnemyTypes.fast); - s.lane = enemy.lane; - s.tier = enemy.tier; - s.spawner = enemy; - s.set(enemy.x + enemy.tr.x, enemy.y + enemy.tr.y); - s.add(); - - Effects.effect(Fx.spawn, enemy); - enemy.spawned ++; - } - - } - } - - - public void onShoot(Enemy enemy, BulletType type, float rotation){ - Effects.effect(Fx.largeCannonShot, enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, enemy.angle); - Effects.shake(3f, 3f, enemy); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/HealerType.java b/core/src/io/anuke/mindustry/entities/enemies/types/HealerType.java deleted file mode 100644 index 938f33c27c..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/HealerType.java +++ /dev/null @@ -1,99 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.MathUtils; -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.Effects; -import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Hue; -import io.anuke.ucore.graphics.Shapes; - -import static io.anuke.mindustry.Vars.enemyGroup; - -public class HealerType extends EnemyType { - - public HealerType() { - super("healerenemy"); - speed = 0.25f; - reload = 10; - health = 200; - bullet = BulletType.shot; - range = 40f; - alwaysRotate = false; - targetCore = false; - stopNearCore = true; - targetClient = true; - mass = 1.1f; - } - - - @Override - public void behavior(Enemy 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(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; - - enemy.tr.trns(enemy.angleTo(target), 5f); - - Shaders.outline.color.set(Color.CLEAR); - Shaders.outline.apply(); - - if(target.health < target.maxhealth){ - Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 13f)); - Draw.alpha(0.9f); - Shapes.laser("laser", "laserend", enemy.x + enemy.tr.x, enemy.y + enemy.tr.y, target.x - enemy.tr.x/1.5f, target.y - enemy.tr.y/1.5f); - Draw.color(); - } - - Graphics.flush(); - } - - 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/types/MortarType.java b/core/src/io/anuke/mindustry/entities/enemies/types/MortarType.java deleted file mode 100644 index ad1ac1bfbc..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/MortarType.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class MortarType extends EnemyType { - - public MortarType() { - super("mortarenemy"); - - health = 200; - speed = 0.25f; - reload = 100f; - bullet = BulletType.shell; - turretrotatespeed = 0.15f; - rotatespeed = 0.05f; - range = 120f; - mass = 1.2f; - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/RapidType.java b/core/src/io/anuke/mindustry/entities/enemies/types/RapidType.java deleted file mode 100644 index ed2621d74c..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/RapidType.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.BulletType; -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class RapidType extends EnemyType { - - public RapidType() { - 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/StandardType.java b/core/src/io/anuke/mindustry/entities/enemies/types/StandardType.java deleted file mode 100644 index 112155beeb..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/StandardType.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import io.anuke.mindustry.entities.enemies.EnemyType; - -public class StandardType extends EnemyType { - - public StandardType(){ - super("standardenemy"); - } -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TankType.java b/core/src/io/anuke/mindustry/entities/enemies/types/TankType.java deleted file mode 100644 index 64a827c1b2..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/TankType.java +++ /dev/null @@ -1,30 +0,0 @@ -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 TankType extends EnemyType { - - public TankType() { - super("tankenemy"); - - health = 350; - speed = 0.24f; - reload = 90f; - rotatespeed = 0.06f; - bullet = BulletType.small; - length = 3f; - mass = 1.4f; - length = 8f; - } - - @Override - public void shoot(Enemy enemy){ - super.shoot(enemy); - - Angles.shotgun(3, 8f, enemy.angle, f -> enemy.shoot(bullet, f)); - } - -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java b/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java deleted file mode 100644 index 822e9d5823..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.anuke.mindustry.entities.enemies.types; - -import com.badlogic.gdx.graphics.Color; -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.Timers; -import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Lines; -import io.anuke.ucore.util.Mathf; - -import static io.anuke.mindustry.Vars.control; - -public class TargetType extends EnemyType { - - public TargetType(){ - super("targetenemy"); - - speed = 0f; - health = 40; - shootsound = null; - } - - @Override - public void move(Enemy 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(control.tutorial().showTarget()){ - Lines.spikes(enemy.x, enemy.y, 11f + Mathf.sin(Timers.time(), 7f, 1f), 4f, 8, Timers.time()); - } - - Draw.color(); - } - - @Override - public void onDeath(Enemy enemy, boolean force){ - super.onDeath(enemy, force); - Timers.run(100f, ()->{ - new Enemy(EnemyTypes.target).set(enemy.x, enemy.y).add(); - }); - } - - @Override - public boolean isCalculating(Enemy enemy){ - return false; - } -} diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java b/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java deleted file mode 100644 index c8e2786b94..0000000000 --- a/core/src/io/anuke/mindustry/entities/enemies/types/TitanType.java +++ /dev/null @@ -1,47 +0,0 @@ -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 TitanType extends EnemyType { - - public TitanType() { - 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.flameshot, 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/game/EnemySpawn.java b/core/src/io/anuke/mindustry/game/EnemySpawn.java index eff8e10a44..358112fe18 100644 --- a/core/src/io/anuke/mindustry/game/EnemySpawn.java +++ b/core/src/io/anuke/mindustry/game/EnemySpawn.java @@ -1,13 +1,13 @@ package io.anuke.mindustry.game; -import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.mindustry.entities.enemies.UnitType; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.state; public class EnemySpawn{ /**The enemy type spawned*/ - public final EnemyType type; + public final UnitType type; /**When this spawns should end*/ protected int before = Integer.MAX_VALUE; /**When this spawns should start*/ @@ -27,7 +27,7 @@ public class EnemySpawn{ /**Amount of enemies spawned initially, with no scaling*/ protected int amount = 1; - public EnemySpawn(EnemyType type){ + public EnemySpawn(UnitType type){ this.type = type; } @@ -41,6 +41,6 @@ public class EnemySpawn{ } public int tier(int wave, int lane){ - return Mathf.clamp(tier + (wave-after)/tierscale, 1, EnemyType.maxtier); + return Mathf.clamp(tier + (wave-after)/tierscale, 1, UnitType.maxtier); } } diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index c900741b7e..beb0e5456d 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.game; import io.anuke.mindustry.core.GameState.State; 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.BaseUnit; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -41,7 +41,7 @@ public class EventType { } public interface EnemyDeathEvent extends Event{ - void handle(Enemy enemy); + void handle(BaseUnit enemy); } public interface BlockDestroyEvent extends Event{ diff --git a/core/src/io/anuke/mindustry/game/Team.java b/core/src/io/anuke/mindustry/game/Team.java new file mode 100644 index 0000000000..dbe4a0c78f --- /dev/null +++ b/core/src/io/anuke/mindustry/game/Team.java @@ -0,0 +1,15 @@ +package io.anuke.mindustry.game; + +import com.badlogic.gdx.graphics.Color; + +public enum Team { + none(Color.GRAY), + blue(Color.BLUE), + red(Color.RED); + + public final Color color; + + Team(Color color){ + this.color = color; + } +} diff --git a/core/src/io/anuke/mindustry/game/WaveCreator.java b/core/src/io/anuke/mindustry/game/WaveCreator.java index b44fcbf98e..79b2f7cd9d 100644 --- a/core/src/io/anuke/mindustry/game/WaveCreator.java +++ b/core/src/io/anuke/mindustry/game/WaveCreator.java @@ -1,130 +1,12 @@ package io.anuke.mindustry.game; import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.entities.enemies.EnemyTypes; public class WaveCreator{ public static Array getSpawns(){ - - return Array.with( - new EnemySpawn(EnemyTypes.standard){{ - scaling = 1; - before = 3; - }}, - - new EnemySpawn(EnemyTypes.fast){{ - scaling = 1; - after = 3; - spacing = 5; - amount = 3; - tierscaleback = 0; - }}, - - new EnemySpawn(EnemyTypes.blast){{ - after = 4; - amount = 2; - spacing = 5; - scaling = 2; - tierscaleback = 1; - }}, - - new EnemySpawn(EnemyTypes.tank){{ - after = 5; - spacing = 5; - scaling = 2; - amount = 2; - }}, - - new EnemySpawn(EnemyTypes.rapid){{ - after = 7; - spacing = 5; - scaling = 2; - amount = 3; - }}, - - new EnemySpawn(EnemyTypes.healer){{ - after = 5; - spacing = 5; - scaling = 1; - amount = 1; - }}, - - new EnemySpawn(EnemyTypes.standard){{ - scaling = 3; - after = 8; - spacing = 4; - tier = 2; - }}, - - new EnemySpawn(EnemyTypes.titan){{ - after = 6; - amount = 2; - spacing = 5; - scaling = 3; - }}, - - new EnemySpawn(EnemyTypes.flamer){{ - after = 12; - amount = 2; - spacing = 5; - scaling = 3; - }}, - - new EnemySpawn(EnemyTypes.emp){{ - after = 15; - amount = 1; - spacing = 5; - scaling = 2; - }}, - - new EnemySpawn(EnemyTypes.blast){{ - after = 4 + 5 + 5; - amount = 3; - spacing = 5; - scaling = 2; - tierscaleback = 0; - }}, - //boss wave - new EnemySpawn(EnemyTypes.fortress){{ - after = 16; - amount = 1; - spacing = 5; - scaling = 1; - }}, - - new EnemySpawn(EnemyTypes.titan){{ - after = 16; - amount = 1; - spacing = 5; - scaling = 3; - tierscaleback = 0; - }}, - - new EnemySpawn(EnemyTypes.healer){{ - after = 16; - spacing = 5; - scaling = 2; - amount = 2; - }}, - //end boss wave - - //enchanced boss wave - new EnemySpawn(EnemyTypes.mortar){{ - after = 16 + 5; - amount = 1; - spacing = 5; - scaling = 3; - }}, - - new EnemySpawn(EnemyTypes.emp){{ - after = 16 + 5; - amount = 1; - spacing = 5; - scaling = 3; - }} - //end enchanced boss wave - ); + //TODO + return null; } public static void testWaves(int from, int to){ diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index e5d04817f1..dd141b35d0 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.utils.Array; -import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Layer; @@ -86,10 +85,7 @@ public class BlockRenderer{ } if(!(block instanceof StaticBlock)){ - if(block == Blocks.air){ - if(!state.is(State.paused)) tile.floor().update(tile); - }else{ - + if(block != Blocks.air){ if(!expanded){ addRequest(tile, Layer.block); } diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 3e9258e98e..d84bba7608 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -3,8 +3,8 @@ 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 io.anuke.mindustry.entities.enemies.Enemy; -import io.anuke.mindustry.entities.enemies.EnemyType; +import io.anuke.mindustry.entities.enemies.BaseUnit; +import io.anuke.mindustry.entities.enemies.UnitType; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.io.SaveFileVersion; @@ -120,7 +120,7 @@ public class Save16 extends SaveFileVersion { int enemies = stream.readInt(); - Array enemiesToUpdate = new Array<>(); + Array enemiesToUpdate = new Array<>(); for(int i = 0; i < enemies; i ++){ byte type = stream.readByte(); @@ -131,7 +131,7 @@ public class Save16 extends SaveFileVersion { int health = stream.readShort(); try{ - Enemy enemy = new Enemy(EnemyType.getByID(type)); + BaseUnit enemy = new BaseUnit(UnitType.getByID(type)); enemy.lane = lane; enemy.health = health; enemy.x = x; @@ -158,7 +158,7 @@ public class Save16 extends SaveFileVersion { world.loadMap(world.maps().getMap(mapid), seed); if(!headless) renderer.clearTiles(); - for(Enemy enemy : enemiesToUpdate){ + for(BaseUnit enemy : enemiesToUpdate){ enemy.node = -2; } @@ -278,12 +278,12 @@ public class Save16 extends SaveFileVersion { //--ENEMIES-- - EntityContainer enemies = enemyGroup.all(); + EntityContainer enemies = enemyGroup.all(); stream.writeInt(enemies.size()); //enemy amount for(int i = 0; i < enemies.size(); i ++){ - Enemy enemy = enemies.get(i); + BaseUnit enemy = enemies.get(i); stream.writeByte(enemy.type.id); //type stream.writeByte(enemy.lane); //lane stream.writeFloat(enemy.x); //x diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index d378c69133..d618aa9d0b 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.resource.Weapon; @@ -40,7 +40,7 @@ public class NetEvents { Net.send(packet, SendMode.udp); } - public static void handleEnemyDeath(Enemy enemy){ + public static void handleEnemyDeath(BaseUnit enemy){ EnemyDeathPacket packet = new EnemyDeathPacket(); packet.id = enemy.id; Net.send(packet, SendMode.tcp); diff --git a/core/src/io/anuke/mindustry/net/ServerDebug.java b/core/src/io/anuke/mindustry/net/ServerDebug.java index a34b05e7c1..6623d602fc 100644 --- a/core/src/io/anuke/mindustry/net/ServerDebug.java +++ b/core/src/io/anuke/mindustry/net/ServerDebug.java @@ -34,8 +34,8 @@ public class ServerDebug { build.append(player.clientid); build.append(" / player '"); build.append(player.name); - build.append(" android: "); - build.append(player.isAndroid); + build.append(" mech: "); + build.append(player.mech); build.append("'\n"); for(Class type : map.orderedKeys()){ diff --git a/core/src/io/anuke/mindustry/resource/Mech.java b/core/src/io/anuke/mindustry/resource/Mech.java index 57a9bf4800..44726ba3af 100644 --- a/core/src/io/anuke/mindustry/resource/Mech.java +++ b/core/src/io/anuke/mindustry/resource/Mech.java @@ -3,9 +3,14 @@ package io.anuke.mindustry.resource; public class Mech extends Upgrade{ public static final Mech - standard = new Mech("standard"); + standard = new Mech("standard", false), + standardShip = new Mech("standard-ship", true); - public Mech(String name){ + public boolean flying; + public float mass = 1f; + + public Mech(String name, boolean flying){ super(name); + this.flying = flying; } } diff --git a/core/src/io/anuke/mindustry/resource/Upgrade.java b/core/src/io/anuke/mindustry/resource/Upgrade.java index 423528a483..d8ed2b421c 100644 --- a/core/src/io/anuke/mindustry/resource/Upgrade.java +++ b/core/src/io/anuke/mindustry/resource/Upgrade.java @@ -23,8 +23,8 @@ public abstract class Upgrade { return Bundles.get("upgrade." + name + ".name"); } - public static Upgrade getByID(byte id){ - return upgrades.get(id); + public static T getByID(byte id){ + return (T)upgrades.get(id); } public static Array getAllUpgrades() { diff --git a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java index a141e5d591..e8c9c49048 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.ui.fragments; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.enemies.Enemy; -import io.anuke.mindustry.entities.enemies.EnemyTypes; +import io.anuke.mindustry.entities.enemies.BaseUnit; +import io.anuke.mindustry.entities.enemies.UnitTypes; import io.anuke.mindustry.net.Net; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.builders.button; @@ -67,7 +67,7 @@ public class DebugFragment implements Fragment { }); row(); new button("spawn", () -> { - new Enemy(EnemyTypes.healer).set(player.x, player.y).add(); + new BaseUnit(UnitTypes.healer).set(player.x, player.y).add(); }); row(); }}.end(); @@ -163,8 +163,8 @@ public class DebugFragment implements Fragment { result.append(", "); result.append(player.y); result.append("\n"); - result.append(" android: "); - result.append(player.isAndroid); + result.append(" mech: "); + result.append(player.mech); result.append("\n"); result.append(" local: "); result.append(player.isLocal); diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index b5d0e96f01..78e1fa7813 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.modules.InventoryModule; import io.anuke.mindustry.world.blocks.types.modules.LiquidModule; @@ -25,6 +26,7 @@ public class Tile{ private byte rotation; private byte dump; private byte extra; + private byte team; /**The coordinates of the core tile this is linked to, in the form of two bytes packed into one. * This is relative to the block it is linked to; negate coords to find the link.*/ public byte link = 0; @@ -125,6 +127,15 @@ public class Tile{ public Block block(){ return Block.getByID(getWallID()); } + + //TODO save team + public Team getTeam(){ + return Team.values()[team]; + } + + public void setTeam(Team team){ + this.team = (byte)team.ordinal(); + } /**Returns the breaktime of the block, or the breaktime of the linked block, if this tile is linked.*/ public float getBreakTime(){ diff --git a/core/src/io/anuke/mindustry/world/WorldGenerator.java b/core/src/io/anuke/mindustry/world/WorldGenerator.java index 96ad8acc58..d46fd62c0f 100644 --- a/core/src/io/anuke/mindustry/world/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/WorldGenerator.java @@ -5,8 +5,8 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.enemies.Enemy; -import io.anuke.mindustry.entities.enemies.EnemyTypes; +import io.anuke.mindustry.entities.enemies.BaseUnit; +import io.anuke.mindustry.entities.enemies.UnitTypes; import io.anuke.mindustry.game.SpawnPoint; import io.anuke.mindustry.world.ColorMapper.BlockPair; import io.anuke.mindustry.world.blocks.Blocks; @@ -77,7 +77,7 @@ public class WorldGenerator { } if(color == Hue.rgb(Color.PURPLE)){ - if(!Vars.android) new Enemy(EnemyTypes.target).set(x * tilesize, y * tilesize).add(); + if(!Vars.android) new BaseUnit(UnitTypes.target).set(x * tilesize, y * 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 3be7eb6b48..6edac8b261 100644 --- a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java @@ -180,7 +180,7 @@ public class ProductionBlocks{ { resource = Blocks.uranium; result = Item.uranium; - drillTime = 540; + drillTime = 600; } }, diff --git a/core/src/io/anuke/mindustry/world/blocks/types/defense/LaserTurret.java b/core/src/io/anuke/mindustry/world/blocks/types/defense/LaserTurret.java index fb75fbd9b2..96aaabffd6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/defense/LaserTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/defense/LaserTurret.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.types.defense; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.MathUtils; -import io.anuke.mindustry.entities.enemies.Enemy; +import io.anuke.mindustry.entities.enemies.BaseUnit; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Tile; @@ -32,7 +32,7 @@ public class LaserTurret extends PowerTurret{ @Override public void shoot(Tile tile){ TurretEntity entity = tile.entity(); - Enemy enemy = entity.target; + BaseUnit enemy = entity.target; if(Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) < cone){ enemy.damage(damage); @@ -43,7 +43,7 @@ public class LaserTurret extends PowerTurret{ @Override public void drawLayer2(Tile tile){ TurretEntity entity = tile.entity(); - Enemy enemy = entity.target; + BaseUnit enemy = entity.target; if(enemy != null && Angles.angleDist(entity.rotation, Angles.angle(tile.drawx(), tile.drawy(), enemy.x, enemy.y)) <= cone){ 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 f3aeb74173..a92073eda8 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 @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color; 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.BaseUnit; import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.*; @@ -131,8 +131,8 @@ public class Turret extends Block{ if(hasAmmo(tile) || (debug && infiniteAmmo)){ if(entity.timer.get(timerTarget, targetInterval)){ - entity.target = (Enemy)Entities.getClosest(enemyGroup, - tile.worldx(), tile.worldy(), range, e-> e instanceof Enemy && !((Enemy)e).isDead()); + entity.target = (BaseUnit)Entities.getClosest(enemyGroup, + tile.worldx(), tile.worldy(), range, e-> e instanceof BaseUnit && !((BaseUnit)e).isDead()); } if(entity.target != null){ @@ -240,7 +240,7 @@ public class Turret extends Block{ public TileEntity blockTarget; public int ammo; public float rotation = 90; - public Enemy target; + public BaseUnit target; @Override public void write(DataOutputStream stream) throws IOException{ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/Centrifuge.java b/core/src/io/anuke/mindustry/world/blocks/types/production/Centrifuge.java index 79afb99b3a..a787c268ee 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/Centrifuge.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/Centrifuge.java @@ -3,6 +3,8 @@ package io.anuke.mindustry.world.blocks.types.production; import io.anuke.mindustry.world.Tile; public class Centrifuge extends LiquidCrafter { + protected float powerUsed = 0.1f; + protected float timeUsed = 360f; public Centrifuge(String name) { super(name);