From cfdcfe8309f55397e9963972086b6e469ebe524f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 5 Nov 2017 16:08:35 -0500 Subject: [PATCH] Added 3 new enemies, minor balancing changes --- .../src/io/anuke/mindustry/EffectCreator.java | 16 +++ .../anuke/mindustry/entities/BulletType.java | 36 +++++- .../anuke/mindustry/entities/effect/EMP.java | 113 ++++++++++++++++++ .../mindustry/entities/enemies/EmpEnemy.java | 19 +++ .../mindustry/entities/enemies/Enemy.java | 22 ++-- .../entities/enemies/HealerEnemy.java | 70 +++++++++++ .../entities/enemies/MortarEnemy.java | 2 + .../entities/enemies/RapidEnemy.java | 2 +- .../entities/enemies/TitanEnemy.java | 38 ++++++ .../world/blocks/types/BlockPart.java | 9 ++ .../world/blocks/types/PowerAcceptor.java | 5 + .../world/blocks/types/PowerBlock.java | 6 + .../blocks/types/production/Generator.java | 1 + 13 files changed, 330 insertions(+), 9 deletions(-) create mode 100644 core/src/io/anuke/mindustry/entities/effect/EMP.java create mode 100644 core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java create mode 100644 core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java create mode 100644 core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java diff --git a/core/src/io/anuke/mindustry/EffectCreator.java b/core/src/io/anuke/mindustry/EffectCreator.java index c2dbf9c666..62956ec147 100644 --- a/core/src/io/anuke/mindustry/EffectCreator.java +++ b/core/src/io/anuke/mindustry/EffectCreator.java @@ -32,6 +32,22 @@ public class EffectCreator{ Draw.reset(); }); + Effects.create("empshockwave", 7f, e -> { + Draw.color(Color.WHITE, Color.SKY, e.ifract()); + Draw.thick(e.fract()*2f); + Draw.circle(e.x, e.y, e.ifract()*40f); + Draw.reset(); + }); + + Effects.create("empspark", 13, e -> { + Angles.randLenVectors(e.id, 7, 1f + e.ifract()*12f, (x, y)->{ + float len = 1f+e.fract()*6f; + Draw.color(Color.SKY); + Draw.lineAngle(e.x + x, e.y + y, Mathf.atan2(x, y), len); + Draw.reset(); + }); + }); + Effects.create("shellsmoke", 21, e -> { Angles.randLenVectors(e.id, 8, 1f + e.ifract()*16f, (x, y)->{ float size = 2f+e.fract()*5f; diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 68433da3aa..36177aa495 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.graphics.Color; +import io.anuke.mindustry.entities.effect.EMP; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; @@ -45,6 +46,39 @@ public abstract class BulletType extends BaseBulletType{ } } }, + emp = new BulletType(1.6f, 5){ //TODO implement + { + lifetime = 50f; + hitsize = 6f; + } + + public void draw(Bullet b){ + float rad = 6f + Mathf.sin(Timers.time(), 5f, 2f); + + Draw.color(Color.SKY); + Draw.circle(b.x, b.y, 4f); + Draw.rect("circle", b.x, b.y, rad, rad); + Draw.reset(); + } + + public void update(Bullet b){ + if(Timers.get(b, "smoke", 2)){ + Effects.effect("empspark", b.x + Mathf.range(2), b.y + Mathf.range(2)); + } + } + + public void despawned(Bullet b){ + removed(b); + } + + public void removed(Bullet b){ + Timers.run(5f, ()->{ + new EMP(b.x, b.y).add(); + }); + Effects.effect("empshockwave", b); + Effects.shake(3f, 3f, b); + } + }, shell = new BulletType(1.1f, 85){ { lifetime = 110f; @@ -128,7 +162,7 @@ public abstract class BulletType extends BaseBulletType{ Draw.reset(); } }, - smallfast = new BulletType(1.6f, 2){ + purple = new BulletType(1.6f, 2){ Color color = new Color(0x8b5ec9ff); public void draw(Bullet b){ Draw.color(color); diff --git a/core/src/io/anuke/mindustry/entities/effect/EMP.java b/core/src/io/anuke/mindustry/entities/effect/EMP.java new file mode 100644 index 0000000000..ebd537fefa --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/effect/EMP.java @@ -0,0 +1,113 @@ +package io.anuke.mindustry.entities.effect; + +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.world.Tile; +import io.anuke.mindustry.world.World; +import io.anuke.mindustry.world.blocks.types.PowerAcceptor; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.core.Effects; +import io.anuke.ucore.entities.TimedEntity; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Mathf; + +public class EMP extends TimedEntity{ + static final int maxTargets = 8; + static Array array = new Array<>(); + + int radius = 4; + int damage = 6; + Array targets = new Array<>(maxTargets); + + public EMP(float x, float y){ + set(x, y); + + lifetime = 30f; + + int worldx = Mathf.scl2(x, Vars.tilesize); + int worldy = Mathf.scl2(y, Vars.tilesize); + + array.clear(); + + for(int dx = -radius; dx <= radius; dx ++){ + for(int dy = -radius; dy <= radius; dy ++){ + if(Vector2.dst(dx, dy, 0, 0) < radius){ + Tile tile = World.tile(worldx + dx, worldy + dy); + + if(tile != null && tile.block().update/* && tile.block() instanceof PowerAcceptor*/){ + array.add(tile); + } + } + } + } + + array.shuffle(); + + for(int i = 0; i < array.size && i < maxTargets; i ++){ + Tile tile = array.get(i); + targets.add(tile); + + if(tile.block() instanceof PowerAcceptor){ + PowerAcceptor p = (PowerAcceptor)tile.block(); + p.setPower(tile, 0f); + } + + Effects.effect("empspark", tile.entity); + tile.entity.damage(damage); + } + } + + @Override + public void drawOver(){ + Draw.color(Color.SKY); + + for(int i = 0; i < targets.size; i ++){ + Tile target = targets.get(i); + + drawLine(target.worldx(), target.worldy()); + + float rad = 5f*fract(); + Draw.rect("circle", target.worldx(), target.worldy(), rad, rad); + } + + for(int i = 0; i < 7; i ++){ + Angles.translation(Mathf.randomSeed(i + id*77)*360f, radius * Vars.tilesize); + drawLine(x + Angles.x(), y + Angles.y()); + } + + + Draw.thick(fract()*2f); + Draw.circle(x, y, radius * Vars.tilesize); + + Draw.reset(); + } + + private void drawLine(float targetx, float targety){ + int joints = 3; + float r = 3f; + float lastx = x, lasty = y; + + for(int seg = 0; seg < joints; seg ++){ + float dx = Mathf.range(r), + dy = Mathf.range(r); + + float frac = (float)(seg+1f)/joints; + + float tx = (targetx - x)*frac + x + dx, + ty = (targety - y)*frac + y + dy; + + drawLaser(lastx, lasty, tx, ty); + + lastx = tx; + lasty = ty; + } + } + + private void drawLaser(float x, float y, float x2, float y2){ + Draw.thick(fract() * 2f); + Draw.line(x, y, x2, y2); + } +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java new file mode 100644 index 0000000000..36b7525545 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/EmpEnemy.java @@ -0,0 +1,19 @@ +package io.anuke.mindustry.entities.enemies; + +import io.anuke.mindustry.entities.BulletType; + +public class EmpEnemy extends Enemy{ + + public EmpEnemy(int spawn) { + super(spawn); + + speed = 0.4f; + reload = 50; + maxhealth = 210; + range = 80f; + bullet = BulletType.emp; + + heal(); + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index 85183cb32a..7bb26a2399 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -72,16 +72,24 @@ public class Enemy extends DestructibleEntity{ } if(target != null && bullet != null){ - if(Timers.get(this, "reload", reload*Vars.multiplier)){ - shoot(); - Effects.sound(shootsound, this); - } + updateShooting(); } } - void shoot(){ - vector.set(length, 0).rotate(direction.angle()); - Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, direction.angle()).add(); + void updateShooting(){ + if(Timers.get(this, "reload", reload*Vars.multiplier)){ + shoot(bullet); + Effects.sound(shootsound, this); + } + } + + void shoot(BulletType bullet){ + shoot(bullet, 0); + } + + void shoot(BulletType bullet, float rotation){ + vector.set(length, 0).rotate(direction.angle() + rotation); + Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, direction.angle() + rotation).add(); out.damage = (int)(damage*Vars.multiplier); } diff --git a/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java new file mode 100644 index 0000000000..556c91e69b --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/HealerEnemy.java @@ -0,0 +1,70 @@ +package io.anuke.mindustry.entities.enemies; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; + +import io.anuke.mindustry.ai.Pathfind; +import io.anuke.mindustry.entities.BulletType; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.graphics.Hue; +import io.anuke.ucore.util.Angles; + +public class HealerEnemy extends Enemy{ + int healTime = 10; + + public HealerEnemy(int spawn) { + super(spawn); + + speed = 0.4f; + reload = 30; + maxhealth = 210; + range = 80f; + bullet = BulletType.shot; + range = 30f; + + heal(); + } + + @Override + void move(){ + Vector2 vec = Pathfind.find(this); + vec.sub(x, y).setLength(speed); + + move(vec.x*Timers.delta(), vec.y*Timers.delta()); + + if(Timers.get(this, 15)){ + target = Entities.getClosest(x, y, range, e->e instanceof Enemy); + } + + if(target != null){ + updateShooting(); + } + } + + @Override + void updateShooting(){ + Enemy enemy = (Enemy)target; + + if(enemy.health < enemy.maxhealth && Timers.get(this, "heal", healTime)){ + enemy.health ++; + } + } + + @Override + public void drawOver(){ + super.drawOver(); + Enemy enemy = (Enemy)target; + + Angles.translation(this.angleTo(enemy), 3f); + + if(enemy != null && enemy.health < enemy.maxhealth){ + Draw.color(Hue.rgb(138, 244, 138, (MathUtils.sin(Timers.time()) + 1f) / 14f)); + Draw.alpha(0.3f); + Draw.laser("laser", "laserend", x + Angles.x(), y + Angles.y(), enemy.x, enemy.y); + Draw.color(); + } + } + +} diff --git a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java index 50c9019d86..cd78c201e2 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/MortarEnemy.java @@ -14,6 +14,8 @@ public class MortarEnemy extends Enemy{ turretrotatespeed = 0.15f; rotatespeed = 7f; range = 120f; + + heal(); } } diff --git a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java index c381615f06..5e5b7b814a 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/RapidEnemy.java @@ -8,7 +8,7 @@ public class RapidEnemy extends Enemy{ super(spawn); reload = 8; - bullet = BulletType.smallfast; + bullet = BulletType.purple; rotatespeed = 30f; maxhealth = 260; speed = 0.27f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java new file mode 100644 index 0000000000..05e59cb658 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/enemies/TitanEnemy.java @@ -0,0 +1,38 @@ +package io.anuke.mindustry.entities.enemies; + +import io.anuke.mindustry.entities.BulletType; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.util.Angles; + +public class TitanEnemy extends Enemy{ + + public TitanEnemy(int spawn) { + super(spawn); + + speed = 0.4f; + reload = 30; + maxhealth = 210; + range = 80f; + bullet = BulletType.emp; + + heal(); + } + + @Override + void updateShooting(){ + if(Timers.getTime(this, "salvo") < 30){ + if(Timers.get(this, "salvoShoot", 6)){ + shoot(BulletType.shot2); + } + + Timers.get(this, "salvo", 200); + } + + if(Timers.get(this, "shotgun", 50)){ + Angles.shotgun(5, 10f, 0f, f->{ + shoot(BulletType.purple, f); + }); + } + } + +} diff --git a/core/src/io/anuke/mindustry/world/blocks/types/BlockPart.java b/core/src/io/anuke/mindustry/world/blocks/types/BlockPart.java index 8ef032b353..aca3e6cf66 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/BlockPart.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/BlockPart.java @@ -79,5 +79,14 @@ public class BlockPart extends Block implements PowerAcceptor, LiquidAcceptor{ return tile.getLinked().block(); } + @Override + public void setPower(Tile tile, float power){ + Block block = linked(tile); + + if(block instanceof PowerAcceptor){ + ((PowerAcceptor)block).setPower(tile.getLinked(), power); + } + } + } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/PowerAcceptor.java b/core/src/io/anuke/mindustry/world/blocks/types/PowerAcceptor.java index 282f9ca222..3fc033c218 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/PowerAcceptor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/PowerAcceptor.java @@ -6,5 +6,10 @@ public interface PowerAcceptor{ /**Attempts to add some power to this block; returns the amount of power not accepted. * To add no power, you would return amount.*/ public float addPower(Tile tile, float amount); + + /**Whether this block accepts power at all.*/ public boolean acceptsPower(Tile tile); + + /**Sets the power on this block. This can be negative!*/ + public void setPower(Tile tile, float power); } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/PowerBlock.java b/core/src/io/anuke/mindustry/world/blocks/types/PowerBlock.java index 237eb189af..36d3a6926b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/PowerBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/PowerBlock.java @@ -70,6 +70,12 @@ public abstract class PowerBlock extends Block implements PowerAcceptor{ return canAccept; } + @Override + public void setPower(Tile tile, float power){ + PowerEntity entity = tile.entity(); + entity.power = power; + } + @Override public TileEntity getEntity(){ return new PowerEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java b/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java index e85b97e65e..921f50d56a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/Generator.java @@ -180,4 +180,5 @@ public class Generator extends PowerBlock{ } } } + }