Added sandbox mode and new fortress enemy
This commit is contained in:
BIN
core/assets-raw/sprites/enemies/fortressenemy-t1.png
Normal file
BIN
core/assets-raw/sprites/enemies/fortressenemy-t1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 451 B |
BIN
core/assets-raw/sprites/enemies/fortressenemy-t2.png
Normal file
BIN
core/assets-raw/sprites/enemies/fortressenemy-t2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 447 B |
BIN
core/assets-raw/sprites/enemies/fortressenemy-t3.png
Normal file
BIN
core/assets-raw/sprites/enemies/fortressenemy-t3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 470 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 50 KiB |
@@ -31,6 +31,7 @@ public class Mindustry extends ModuleCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//always initialize blocks in this order, otherwise there are ID errors
|
//always initialize blocks in this order, otherwise there are ID errors
|
||||||
public Block[] blockClasses = {
|
public Block[] blockClasses = {
|
||||||
Blocks.air,
|
Blocks.air,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class Pathfind{
|
|||||||
|
|
||||||
for(SpawnPoint point : Vars.control.getSpawnPoints()){
|
for(SpawnPoint point : Vars.control.getSpawnPoints()){
|
||||||
if(!point.request.pathFound){
|
if(!point.request.pathFound){
|
||||||
if(point.finder.search(point.request, ms*2)){
|
if(point.finder.search(point.request, ms)){
|
||||||
smoother.smoothPath(point.path);
|
smoother.smoothPath(point.path);
|
||||||
point.pathTiles = point.path.nodes.toArray(Tile.class);
|
point.pathTiles = point.path.nodes.toArray(Tile.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import io.anuke.ucore.util.Profiler;
|
|||||||
public class Control extends Module{
|
public class Control extends Module{
|
||||||
int targetscale = baseCameraScale;
|
int targetscale = baseCameraScale;
|
||||||
|
|
||||||
public Tutorial tutorial = new Tutorial();
|
Tutorial tutorial = new Tutorial();
|
||||||
boolean hiscore = false;
|
boolean hiscore = false;
|
||||||
|
|
||||||
final Array<Weapon> weapons = new Array<>();
|
final Array<Weapon> weapons = new Array<>();
|
||||||
@@ -51,6 +51,7 @@ public class Control extends Module{
|
|||||||
float wavetime;
|
float wavetime;
|
||||||
float extrawavetime;
|
float extrawavetime;
|
||||||
int enemies = 0;
|
int enemies = 0;
|
||||||
|
GameMode mode = GameMode.waves;
|
||||||
|
|
||||||
Tile core;
|
Tile core;
|
||||||
Array<SpawnPoint> spawnpoints = new Array<>();
|
Array<SpawnPoint> spawnpoints = new Array<>();
|
||||||
@@ -162,7 +163,7 @@ public class Control extends Module{
|
|||||||
|
|
||||||
public void reset(){
|
public void reset(){
|
||||||
weapons.clear();
|
weapons.clear();
|
||||||
Vars.renderer.clearTiles();
|
renderer.clearTiles();
|
||||||
|
|
||||||
weapons.add(Weapon.blaster);
|
weapons.add(Weapon.blaster);
|
||||||
player.weapon = weapons.first();
|
player.weapon = weapons.first();
|
||||||
@@ -187,7 +188,7 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void play(){
|
public void play(){
|
||||||
Vars.renderer.clearTiles();
|
renderer.clearTiles();
|
||||||
|
|
||||||
player.x = core.worldx();
|
player.x = core.worldx();
|
||||||
player.y = core.worldy() - Vars.tilesize*2 - ((int)(Gdx.graphics.getWidth() / (float)Core.cameraScale * 2) % 2 == 0 ? 0.5f : 0);
|
player.y = core.worldy() - Vars.tilesize*2 - ((int)(Gdx.graphics.getWidth() / (float)Core.cameraScale * 2) % 2 == 0 ? 0.5f : 0);
|
||||||
@@ -232,6 +233,14 @@ public class Control extends Module{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GameMode getMode(){
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(GameMode mode){
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasWeapon(Weapon weapon){
|
public boolean hasWeapon(Weapon weapon){
|
||||||
return weapons.contains(weapon, true);
|
return weapons.contains(weapon, true);
|
||||||
}
|
}
|
||||||
@@ -443,7 +452,7 @@ public class Control extends Module{
|
|||||||
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
||||||
new HealerEnemy(0).set(player.x, player.y).add();
|
new HealerEnemy(0).set(player.x, player.y).add();
|
||||||
}else{
|
}else{
|
||||||
new TitanEnemy(0).set(player.x, player.y).add();
|
new FortressEnemy(0).set(player.x, player.y).add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,17 +488,19 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tutorial.active()){
|
if(tutorial.active()){
|
||||||
|
tutorial.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!tutorial.active() && mode != GameMode.sandbox){
|
||||||
extrawavetime -= delta();
|
extrawavetime -= delta();
|
||||||
|
|
||||||
if(enemies <= 0){
|
if(enemies <= 0){
|
||||||
wavetime -= delta();
|
wavetime -= delta();
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
tutorial.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wavetime <= 0 || (debug && Inputs.keyUp(Keys.F)) || extrawavetime <= 0){
|
if(wavetime <= 0){
|
||||||
runWave();
|
runWave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
|
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
|
||||||
static Color lightOrange = Color.valueOf("f68021");
|
static Color lightOrange = Color.valueOf("f68021");
|
||||||
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
|
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
|
||||||
|
static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f);
|
||||||
|
|
||||||
public static final BulletType
|
public static final BulletType
|
||||||
|
|
||||||
@@ -128,7 +129,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
Effects.effect(Fx.shellsmoke, b);
|
Effects.effect(Fx.shellsmoke, b);
|
||||||
Effects.effect(Fx.shellexplosion, 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 Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
titanshell = new BulletType(1.8f, 60){
|
titanshell = new BulletType(1.8f, 60){
|
||||||
@@ -162,6 +163,37 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
|
|||||||
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
DamageArea.damage(!(b.owner instanceof Enemy), b.x, b.y, 25f, (int)(damage * 2f/3f));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
yellowshell = new BulletType(1.2f, 20){
|
||||||
|
{
|
||||||
|
lifetime = 60f;
|
||||||
|
hitsize = 11f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Bullet b){
|
||||||
|
Draw.color(whiteYellow);
|
||||||
|
Draw.rect("titanshell", b.x, b.y, b.angle());
|
||||||
|
Draw.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Bullet b){
|
||||||
|
if(Timers.get(b, "smoke", 4)){
|
||||||
|
Effects.effect(Fx.smoke, b.x + Mathf.range(2), b.y + Mathf.range(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void despawned(Bullet b){
|
||||||
|
removed(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removed(Bullet b){
|
||||||
|
Effects.shake(3f, 3f, b);
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
},
|
||||||
blast = new BulletType(1.1f, 80){
|
blast = new BulletType(1.1f, 80){
|
||||||
{
|
{
|
||||||
lifetime = 0f;
|
lifetime = 0f;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class DamageArea{
|
|||||||
public static void damage(boolean enemies, float x, float y, float radius, int damage){
|
public static void damage(boolean enemies, float x, float y, float radius, int damage){
|
||||||
|
|
||||||
if(enemies){
|
if(enemies){
|
||||||
Entities.getNearby(x, y, radius*2, entity->{
|
Entities.getNearby(Entities.getGroup(Enemy.class), x, y, radius*2, entity->{
|
||||||
if(entity instanceof Enemy){
|
if(entity instanceof Enemy){
|
||||||
Enemy enemy = (Enemy)entity;
|
Enemy enemy = (Enemy)entity;
|
||||||
if(enemy.distanceTo(x, y) > radius){
|
if(enemy.distanceTo(x, y) > radius){
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class Fx{
|
|||||||
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
|
static Color lightRed = Hue.mix(Color.WHITE, Color.FIREBRICK, 0.1f);
|
||||||
static Color lightOrange = Color.valueOf("f68021");
|
static Color lightOrange = Color.valueOf("f68021");
|
||||||
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
|
static Color whiteOrange = Hue.mix(lightOrange, Color.WHITE, 0.6f);
|
||||||
|
static Color whiteYellow = Hue.mix(Color.YELLOW, Color.WHITE, 0.6f);
|
||||||
|
|
||||||
public static final Effect
|
public static final Effect
|
||||||
|
|
||||||
@@ -34,6 +35,28 @@ public class Fx{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
mortarshot = new Effect(10f, e -> {
|
||||||
|
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
|
||||||
|
Draw.thick(e.fract()*6f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*10f);
|
||||||
|
Draw.thick(e.fract()*5f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
|
||||||
|
Draw.thick(e.fract()*1f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
|
||||||
|
Draw.reset();
|
||||||
|
}),
|
||||||
|
|
||||||
|
railshot = new Effect(9f, e -> {
|
||||||
|
Draw.color(Color.WHITE, Color.DARK_GRAY, e.ifract());
|
||||||
|
Draw.thick(e.fract()*5f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*8f);
|
||||||
|
Draw.thick(e.fract()*4f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
|
||||||
|
Draw.thick(e.fract()*1f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*14f);
|
||||||
|
Draw.reset();
|
||||||
|
}),
|
||||||
|
|
||||||
titanshot = new Effect(12f, e -> {
|
titanshot = new Effect(12f, e -> {
|
||||||
Draw.color(Color.WHITE, lightOrange, e.ifract());
|
Draw.color(Color.WHITE, lightOrange, e.ifract());
|
||||||
Draw.thick(e.fract()*7f);
|
Draw.thick(e.fract()*7f);
|
||||||
@@ -45,6 +68,17 @@ public class Fx{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
largeCannonShot = new Effect(11f, e -> {
|
||||||
|
Draw.color(Color.WHITE, whiteYellow, e.ifract());
|
||||||
|
Draw.thick(e.fract()*6f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*12f);
|
||||||
|
Draw.thick(e.fract()*3f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*16f);
|
||||||
|
Draw.thick(e.fract()*1f);
|
||||||
|
Draw.lineAngle(e.x, e.y, e.rotation, e.fract()*18f);
|
||||||
|
Draw.reset();
|
||||||
|
}),
|
||||||
|
|
||||||
shockwave = new Effect(10f, e -> {
|
shockwave = new Effect(10f, e -> {
|
||||||
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
|
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
|
||||||
Draw.thick(e.fract()*2f + 0.2f);
|
Draw.thick(e.fract()*2f + 0.2f);
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ import io.anuke.mindustry.entities.Player;
|
|||||||
import io.anuke.mindustry.entities.effect.Fx;
|
import io.anuke.mindustry.entities.effect.Fx;
|
||||||
import io.anuke.mindustry.entities.effect.Shaders;
|
import io.anuke.mindustry.entities.effect.Shaders;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.core.*;
|
import io.anuke.ucore.core.*;
|
||||||
import io.anuke.ucore.entities.*;
|
import io.anuke.ucore.entities.*;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
@@ -24,18 +26,21 @@ public class Enemy extends DestructibleEntity{
|
|||||||
protected float reload = 32;
|
protected float reload = 32;
|
||||||
protected float range = 60;
|
protected float range = 60;
|
||||||
protected float length = 4;
|
protected float length = 4;
|
||||||
protected float rotatespeed = 7f;
|
protected float rotatespeed = 0.1f;
|
||||||
protected float turretrotatespeed = 0.2f;
|
protected float turretrotatespeed = 0.2f;
|
||||||
protected boolean alwaysRotate = false;
|
protected boolean alwaysRotate = false;
|
||||||
protected BulletType bullet = BulletType.small;
|
protected BulletType bullet = BulletType.small;
|
||||||
protected String shootsound = "enemyshoot";
|
protected String shootsound = "enemyshoot";
|
||||||
protected int damage;
|
protected int damage;
|
||||||
|
protected Enemy spawner;
|
||||||
|
protected int spawned = 0;
|
||||||
|
protected float angle;
|
||||||
|
protected boolean targetCore = false;
|
||||||
|
|
||||||
public int spawn;
|
public int spawn;
|
||||||
public int node = -1;
|
public int node = -1;
|
||||||
public Tile[] path;
|
public Tile[] path;
|
||||||
|
|
||||||
public Vector2 direction = new Vector2();
|
|
||||||
public float xvelocity, yvelocity;
|
public float xvelocity, yvelocity;
|
||||||
public Entity target;
|
public Entity target;
|
||||||
public int tier = 1;
|
public int tier = 1;
|
||||||
@@ -63,7 +68,7 @@ public class Enemy extends DestructibleEntity{
|
|||||||
|
|
||||||
if(nearCore){
|
if(nearCore){
|
||||||
vec = Tmp.v2.setZero();
|
vec = Tmp.v2.setZero();
|
||||||
target = core.entity;
|
if(targetCore) target = core.entity;
|
||||||
}else{
|
}else{
|
||||||
vec = Vars.world.pathfinder().find(this);
|
vec = Vars.world.pathfinder().find(this);
|
||||||
vec.sub(x, y).setLength(speed);
|
vec.sub(x, y).setLength(speed);
|
||||||
@@ -94,7 +99,6 @@ public class Enemy extends DestructibleEntity{
|
|||||||
|
|
||||||
move(vec.x * Timers.delta(), vec.y * Timers.delta());
|
move(vec.x * Timers.delta(), vec.y * Timers.delta());
|
||||||
|
|
||||||
|
|
||||||
updateTargeting(nearCore);
|
updateTargeting(nearCore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +112,10 @@ public class Enemy extends DestructibleEntity{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(target instanceof Enemy){
|
||||||
|
UCore.log(target);
|
||||||
|
}
|
||||||
|
|
||||||
if(target != null && bullet != null){
|
if(target != null && bullet != null){
|
||||||
updateShooting();
|
updateShooting();
|
||||||
}
|
}
|
||||||
@@ -125,8 +133,8 @@ public class Enemy extends DestructibleEntity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void shoot(BulletType bullet, float rotation){
|
void shoot(BulletType bullet, float rotation){
|
||||||
vector.set(length, 0).rotate(direction.angle() + rotation);
|
Angles.translation(angle + rotation, length);
|
||||||
Bullet out = new Bullet(bullet, this, x + vector.x, y + vector.y, direction.angle() + rotation).add();
|
Bullet out = new Bullet(bullet, this, x + Angles.x(), y + Angles.y(), this.angle + rotation).add();
|
||||||
out.damage = (int) (damage * Vars.multiplier);
|
out.damage = (int) (damage * Vars.multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +203,9 @@ public class Enemy extends DestructibleEntity{
|
|||||||
public void removed(){
|
public void removed(){
|
||||||
if(!dead){
|
if(!dead){
|
||||||
Vars.control.enemyDeath();
|
Vars.control.enemyDeath();
|
||||||
|
if(spawner != null){
|
||||||
|
spawner.spawned --;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +219,9 @@ public class Enemy extends DestructibleEntity{
|
|||||||
yvelocity = (y - lasty) / Timers.delta();
|
yvelocity = (y - lasty) / Timers.delta();
|
||||||
|
|
||||||
if(target == null || alwaysRotate){
|
if(target == null || alwaysRotate){
|
||||||
direction.add(xvelocity * Timers.delta() / 3f, yvelocity * Timers.delta() / 3f);
|
angle = Mathf.slerp(angle, 180f+Mathf.atan2(xvelocity, yvelocity), rotatespeed * Timers.delta());
|
||||||
direction.limit(speed * rotatespeed);
|
|
||||||
}else{
|
}else{
|
||||||
float angle = angleTo(target);
|
angle = Mathf.slerp(angle, angleTo(target), turretrotatespeed * Timers.delta());
|
||||||
direction.lerp(vector.set(1f, 0f).rotate(angle), turretrotatespeed * Timers.delta());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +235,7 @@ public class Enemy extends DestructibleEntity{
|
|||||||
Shaders.outline.apply();
|
Shaders.outline.apply();
|
||||||
|
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.rect(region, x, y, direction.angle() - 90);
|
Draw.rect(region, x, y, this.angle - 90);
|
||||||
|
|
||||||
Graphics.flush();
|
Graphics.flush();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
|
import io.anuke.mindustry.entities.effect.Fx;
|
||||||
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
|
||||||
|
public class FortressEnemy extends Enemy{
|
||||||
|
static int maxSpawn = 6;
|
||||||
|
|
||||||
|
float spawnTime = 240;
|
||||||
|
boolean deployed;
|
||||||
|
|
||||||
|
public FortressEnemy(int spawn) {
|
||||||
|
super(spawn);
|
||||||
|
|
||||||
|
speed = 0.1f;
|
||||||
|
reload = 90;
|
||||||
|
maxhealth = 700;
|
||||||
|
range = 70f;
|
||||||
|
bullet = BulletType.yellowshell;
|
||||||
|
hitbox.setSize(9f);
|
||||||
|
turretrotatespeed = rotatespeed = 0.08f;
|
||||||
|
length = 7f;
|
||||||
|
|
||||||
|
heal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(){
|
||||||
|
super.move();
|
||||||
|
|
||||||
|
if(deployed){
|
||||||
|
|
||||||
|
if(Timers.get(this, "spawn", spawnTime) && spawned < maxSpawn){
|
||||||
|
Angles.translation(angle, 20f);
|
||||||
|
|
||||||
|
FastEnemy enemy = new FastEnemy(spawn);
|
||||||
|
enemy.tier = this.tier;
|
||||||
|
enemy.spawner = this;
|
||||||
|
enemy.set(x + Angles.x(), y + Angles.y());
|
||||||
|
Effects.effect(Fx.spawn, enemy);
|
||||||
|
enemy.add();
|
||||||
|
spawned ++;
|
||||||
|
}
|
||||||
|
}else if(distanceTo(Vars.control.getCore().worldx(),
|
||||||
|
Vars.control.getCore().worldy()) <= 120f){
|
||||||
|
deployed = true;
|
||||||
|
speed = 0.001f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shoot(BulletType type){
|
||||||
|
super.shoot(bullet);
|
||||||
|
Effects.effect(Fx.largeCannonShot, x + Angles.x(), y + Angles.y(), angle);
|
||||||
|
Effects.shake(3f, 3f, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ public class HealerEnemy extends Enemy{
|
|||||||
bullet = BulletType.shot;
|
bullet = BulletType.shot;
|
||||||
range = 30f;
|
range = 30f;
|
||||||
alwaysRotate = false;
|
alwaysRotate = false;
|
||||||
|
targetCore = false;
|
||||||
|
|
||||||
heal();
|
heal();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ public class TankEnemy extends Enemy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void shoot(){
|
void shoot(){
|
||||||
vector.set(length, 0).rotate(direction.angle());
|
Angles.translation(angle, 8f);
|
||||||
|
|
||||||
Angles.shotgun(3, 8f, direction.angle(), f->{
|
Angles.shotgun(3, 8f, angle, f->{
|
||||||
Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, f).add();
|
Bullet out = new Bullet(bullet, this, x+vector.x, y+vector.y, f).add();
|
||||||
out.damage = (int)(damage*Vars.multiplier);
|
out.damage = (int)(damage*Vars.multiplier);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ import io.anuke.mindustry.Vars;
|
|||||||
import io.anuke.mindustry.entities.enemies.*;
|
import io.anuke.mindustry.entities.enemies.*;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.Map;
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -38,6 +36,8 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
* Wave (int)
|
* Wave (int)
|
||||||
* Wave countdown time (float)
|
* Wave countdown time (float)
|
||||||
*
|
*
|
||||||
|
* Gamemode Ordinal (byte)
|
||||||
|
*
|
||||||
* Player X (float)
|
* Player X (float)
|
||||||
* Player Y (float)
|
* Player Y (float)
|
||||||
* Player health (int)
|
* Player health (int)
|
||||||
@@ -82,7 +82,7 @@ import io.anuke.ucore.entities.Entities;
|
|||||||
*/
|
*/
|
||||||
public class SaveIO{
|
public class SaveIO{
|
||||||
/**Save file version ID. Should be incremented every breaking release.*/
|
/**Save file version ID. Should be incremented every breaking release.*/
|
||||||
private static final int fileVersionID = 9;
|
private static final int fileVersionID = 10;
|
||||||
|
|
||||||
//TODO automatic registration of types?
|
//TODO automatic registration of types?
|
||||||
private static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
|
private static final Array<Class<? extends Enemy>> enemyIDs = Array.with(
|
||||||
@@ -135,9 +135,21 @@ public class SaveIO{
|
|||||||
public static int getWave(int slot){
|
public static int getWave(int slot){
|
||||||
|
|
||||||
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
|
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
|
||||||
stream.readInt();
|
stream.readInt(); //read version
|
||||||
stream.readLong();
|
stream.readLong(); //read last saved time
|
||||||
return stream.readInt();
|
stream.readByte(); //read the gamemode
|
||||||
|
return stream.readInt(); //read the wave
|
||||||
|
}catch (IOException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameMode getMode(int slot){
|
||||||
|
|
||||||
|
try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){
|
||||||
|
stream.readInt(); //read version
|
||||||
|
stream.readLong(); //read last saved time
|
||||||
|
return GameMode.values()[stream.readByte()]; //read the gamemode
|
||||||
}catch (IOException e){
|
}catch (IOException e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -151,10 +163,13 @@ public class SaveIO{
|
|||||||
|
|
||||||
try(DataOutputStream stream = new DataOutputStream(file.write(false))){
|
try(DataOutputStream stream = new DataOutputStream(file.write(false))){
|
||||||
|
|
||||||
|
//--META--
|
||||||
stream.writeInt(fileVersionID); //version id
|
stream.writeInt(fileVersionID); //version id
|
||||||
stream.writeLong(TimeUtils.millis());
|
stream.writeLong(TimeUtils.millis()); //last saved
|
||||||
|
|
||||||
//--GENERAL STATE--
|
//--GENERAL STATE--
|
||||||
|
stream.writeByte(Vars.control.getMode().ordinal()); //gamemode
|
||||||
|
|
||||||
stream.writeInt(Vars.control.getWave()); //wave
|
stream.writeInt(Vars.control.getWave()); //wave
|
||||||
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
|
stream.writeFloat(Vars.control.getWaveCountdown()); //wave countdown
|
||||||
|
|
||||||
@@ -270,6 +285,7 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//general state
|
//general state
|
||||||
|
byte mode = stream.readByte();
|
||||||
|
|
||||||
int wave = stream.readInt();
|
int wave = stream.readInt();
|
||||||
float wavetime = stream.readFloat();
|
float wavetime = stream.readFloat();
|
||||||
@@ -282,6 +298,7 @@ public class SaveIO{
|
|||||||
Vars.player.x = playerx;
|
Vars.player.x = playerx;
|
||||||
Vars.player.y = playery;
|
Vars.player.y = playery;
|
||||||
Vars.player.health = playerhealth;
|
Vars.player.health = playerhealth;
|
||||||
|
Vars.control.setMode(GameMode.values()[mode]);
|
||||||
Core.camera.position.set(playerx, playery, 0);
|
Core.camera.position.set(playerx, playery, 0);
|
||||||
|
|
||||||
//weapons
|
//weapons
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ package io.anuke.mindustry.ui;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.world.GameMode;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.function.StringSupplier;
|
import io.anuke.ucore.function.StringSupplier;
|
||||||
import io.anuke.ucore.scene.ui.ImageButton;
|
import io.anuke.ucore.scene.ui.*;
|
||||||
import io.anuke.ucore.scene.ui.ScrollPane;
|
|
||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
import io.anuke.ucore.scene.ui.layout.Table;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||||
|
import io.anuke.ucore.scene.utils.Elements;
|
||||||
|
|
||||||
public class LevelDialog extends FloatingDialog{
|
public class LevelDialog extends FloatingDialog{
|
||||||
private Map selectedMap = Map.delta;
|
private Map selectedMap = Map.delta;
|
||||||
@@ -31,6 +32,21 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
|
|
||||||
int maxwidth = 4;
|
int maxwidth = 4;
|
||||||
|
|
||||||
|
Table selmode = new Table();
|
||||||
|
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
||||||
|
selmode.add("Gamemode: ").padRight(10f).units(Unit.dp);
|
||||||
|
|
||||||
|
for(GameMode mode : GameMode.values()){
|
||||||
|
TextButton b = Elements.newButton(mode.toString(), "toggle", ()->{
|
||||||
|
Vars.control.setMode(mode);
|
||||||
|
});
|
||||||
|
group.add(b);
|
||||||
|
selmode.add(b).size(130f, 54f).units(Unit.dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
content().add(selmode);
|
||||||
|
content().row();
|
||||||
|
|
||||||
for(int i = 0; i < Map.values().length; i ++){
|
for(int i = 0; i < Map.values().length; i ++){
|
||||||
Map map = Map.values()[i];
|
Map map = Map.values()[i];
|
||||||
|
|
||||||
@@ -61,7 +77,7 @@ public class LevelDialog extends FloatingDialog{
|
|||||||
maps.add(image).width(170).pad(4f).units(Unit.dp);
|
maps.add(image).width(170).pad(4f).units(Unit.dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
content().add(pane);
|
content().add(pane).uniformX();
|
||||||
|
|
||||||
shown(()->{
|
shown(()->{
|
||||||
//this is necessary for some reason?
|
//this is necessary for some reason?
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ public class LoadDialog extends FloatingDialog{
|
|||||||
|
|
||||||
button.row();
|
button.row();
|
||||||
|
|
||||||
Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "<empty>" : "Wave " +
|
Label info = new Label("[gray]" + (!SaveIO.isSaveValid(i) ? "<empty>" : SaveIO.getMode(slot) + ", Wave " +
|
||||||
SaveIO.getWave(slot)+"\nLast Saved: " + SaveIO.getTimeString(i)));
|
SaveIO.getWave(slot) + "\nLast Saved: " + SaveIO.getTimeString(i)));
|
||||||
info.setAlignment(Align.center, Align.center);
|
info.setAlignment(Align.center, Align.center);
|
||||||
|
|
||||||
button.add(info).padBottom(2).padTop(6);
|
button.add(info).padBottom(2).padTop(6);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class BlocksFragment implements Fragment{
|
|||||||
|
|
||||||
image.update(()->{
|
image.update(()->{
|
||||||
|
|
||||||
boolean canPlace = !control.tutorial.active() || control.tutorial.canPlace();
|
boolean canPlace = !control.getTutorial().active() || control.getTutorial().canPlace();
|
||||||
boolean has = control.hasItems(r.requirements) && canPlace;
|
boolean has = control.hasItems(r.requirements) && canPlace;
|
||||||
//image.setDisabled(!has);
|
//image.setDisabled(!has);
|
||||||
image.setChecked(player.recipe == r);
|
image.setChecked(player.recipe == r);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import io.anuke.mindustry.core.GameState;
|
|||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
|
import io.anuke.mindustry.world.GameMode;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
@@ -73,9 +74,9 @@ public class HudFragment implements Fragment{
|
|||||||
|
|
||||||
//ui table
|
//ui table
|
||||||
new table(){{
|
new table(){{
|
||||||
control.tutorial.buildUI(this);
|
control.getTutorial().buildUI(this);
|
||||||
|
|
||||||
visible(()->control.tutorial.active());
|
visible(()->control.getTutorial().active());
|
||||||
}}.end();
|
}}.end();
|
||||||
|
|
||||||
//paused table
|
//paused table
|
||||||
@@ -93,6 +94,13 @@ public class HudFragment implements Fragment{
|
|||||||
atop();
|
atop();
|
||||||
aright();
|
aright();
|
||||||
|
|
||||||
|
float uheight = 72f;
|
||||||
|
|
||||||
|
new imagebutton("icon-play", Unit.dp.inPixels(30f), ()->{
|
||||||
|
Vars.control.runWave();
|
||||||
|
}).size(uheight).uniformY().units(Unit.dp)
|
||||||
|
.visible(()-> Vars.control.getMode() == GameMode.sandbox && Vars.control.getEnemiesRemaining() <= 0);
|
||||||
|
|
||||||
new table("button"){{
|
new table("button"){{
|
||||||
|
|
||||||
new label(()->"[orange]Wave " + control.getWave()).scale(fontscale*2f).left();
|
new label(()->"[orange]Wave " + control.getWave()).scale(fontscale*2f).left();
|
||||||
@@ -101,11 +109,11 @@ public class HudFragment implements Fragment{
|
|||||||
|
|
||||||
new label(()-> control.getEnemiesRemaining() > 0 ?
|
new label(()-> control.getEnemiesRemaining() > 0 ?
|
||||||
control.getEnemiesRemaining() + " Enemies remaining" :
|
control.getEnemiesRemaining() + " Enemies remaining" :
|
||||||
control.tutorial.active() ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f))
|
(control.getTutorial().active() || Vars.control.getMode() == GameMode.sandbox) ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f))
|
||||||
.minWidth(150);
|
.minWidth(150);
|
||||||
|
|
||||||
get().pad(Unit.dp.inPixels(12));
|
get().pad(Unit.dp.inPixels(12));
|
||||||
}};
|
}}.height(uheight).units(Unit.dp);
|
||||||
|
|
||||||
visible(()->!GameState.is(State.menu));
|
visible(()->!GameState.is(State.menu));
|
||||||
}}.end();
|
}}.end();
|
||||||
|
|||||||
5
core/src/io/anuke/mindustry/world/GameMode.java
Normal file
5
core/src/io/anuke/mindustry/world/GameMode.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
|
public enum GameMode{
|
||||||
|
waves, sandbox;
|
||||||
|
}
|
||||||
@@ -103,6 +103,7 @@ public class WeaponBlocks{
|
|||||||
bullet = BulletType.sniper;
|
bullet = BulletType.sniper;
|
||||||
ammo = Item.steel;
|
ammo = Item.steel;
|
||||||
health = 70;
|
health = 70;
|
||||||
|
shootEffect = Fx.railshot;
|
||||||
fullDescription = "Advanced long-range turret. Uses steel for ammo. Very high damage, but low fire rate. "
|
fullDescription = "Advanced long-range turret. Uses steel for ammo. Very high damage, but low fire rate. "
|
||||||
+ "Expensive to use, but can be placed far away from enemy lines due to its range.";
|
+ "Expensive to use, but can be placed far away from enemy lines due to its range.";
|
||||||
}
|
}
|
||||||
@@ -121,6 +122,8 @@ public class WeaponBlocks{
|
|||||||
fullDescription = "Advanced splash-damage turret. Uses coal for ammo. "
|
fullDescription = "Advanced splash-damage turret. Uses coal for ammo. "
|
||||||
+ "Very slow fire rate and bullets, but very high single-target and splash damage. "
|
+ "Very slow fire rate and bullets, but very high single-target and splash damage. "
|
||||||
+ "Useful for large crowds of enemies.";
|
+ "Useful for large crowds of enemies.";
|
||||||
|
shootEffect = Fx.mortarshot;
|
||||||
|
shootShake = 2f;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -189,6 +192,7 @@ public class WeaponBlocks{
|
|||||||
shots = 2;
|
shots = 2;
|
||||||
fullDescription = "The ultimate rapid-fire turret. Uses uranium as ammo. Shoots large slugs at a high fire rate. "
|
fullDescription = "The ultimate rapid-fire turret. Uses uranium as ammo. Shoots large slugs at a high fire rate. "
|
||||||
+ "Medium range. Spans multiple tiles. Extremely tough.";
|
+ "Medium range. Spans multiple tiles. Extremely tough.";
|
||||||
|
shootEffect = Fx.chainshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO specify turret shoot effect in turret instead of doing it manually
|
//TODO specify turret shoot effect in turret instead of doing it manually
|
||||||
@@ -203,7 +207,7 @@ public class WeaponBlocks{
|
|||||||
for(int i = -1; i < 1; i ++){
|
for(int i = -1; i < 1; i ++){
|
||||||
Angles.vector.set(len, Mathf.sign(i) * space).rotate(entity.rotation);
|
Angles.vector.set(len, Mathf.sign(i) * space).rotate(entity.rotation);
|
||||||
bullet(tile, entity.rotation);
|
bullet(tile, entity.rotation);
|
||||||
Effects.effect(Fx.chainshot, tile.worldx() + Angles.x() + offset.x,
|
Effects.effect(shootEffect, tile.worldx() + Angles.x() + offset.x,
|
||||||
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
|
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,19 +229,8 @@ public class WeaponBlocks{
|
|||||||
shootCone = 9f;
|
shootCone = 9f;
|
||||||
fullDescription = "The ultimate long-range turret. Uses uranium as ammo. Shoots large splash-damage shells at a medium rate of fire. "
|
fullDescription = "The ultimate long-range turret. Uses uranium as ammo. Shoots large splash-damage shells at a medium rate of fire. "
|
||||||
+ "Long range. Spans multiple tiles. Extremely tough.";
|
+ "Long range. Spans multiple tiles. Extremely tough.";
|
||||||
}
|
shootEffect = Fx.titanshot;
|
||||||
|
shootShake = 3f;
|
||||||
@Override
|
|
||||||
protected void shoot(Tile tile){
|
|
||||||
TurretEntity entity = tile.entity();
|
|
||||||
Vector2 offset = getPlaceOffset();
|
|
||||||
|
|
||||||
Angles.translation(entity.rotation, 14f);
|
|
||||||
bullet(tile, entity.rotation);
|
|
||||||
Effects.effect(Fx.titanshot, tile.worldx() + Angles.x() + offset.x,
|
|
||||||
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
|
|
||||||
|
|
||||||
Effects.shake(3f, 3f, tile.worldx(), tile.worldy());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.anuke.mindustry.world.Block;
|
|||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.core.Draw;
|
import io.anuke.ucore.core.Draw;
|
||||||
import io.anuke.ucore.core.Effects;
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.core.Effects.Effect;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.util.Angles;
|
import io.anuke.ucore.util.Angles;
|
||||||
@@ -41,6 +42,8 @@ public class Turret extends Block{
|
|||||||
protected int maxammo = 400;
|
protected int maxammo = 400;
|
||||||
protected float rotatespeed = 0.2f;
|
protected float rotatespeed = 0.2f;
|
||||||
protected float shootCone = 5f;
|
protected float shootCone = 5f;
|
||||||
|
protected Effect shootEffect = null;
|
||||||
|
protected float shootShake = 0f;
|
||||||
|
|
||||||
public Turret(String name) {
|
public Turret(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
@@ -216,6 +219,8 @@ public class Turret extends Block{
|
|||||||
protected void shoot(Tile tile){
|
protected void shoot(Tile tile){
|
||||||
TurretEntity entity = tile.entity();
|
TurretEntity entity = tile.entity();
|
||||||
|
|
||||||
|
Vector2 offset = getPlaceOffset();
|
||||||
|
|
||||||
Angles.translation(entity.rotation, width * Vars.tilesize / 2f);
|
Angles.translation(entity.rotation, width * Vars.tilesize / 2f);
|
||||||
|
|
||||||
for(int i = 0; i < shots; i ++){
|
for(int i = 0; i < shots; i ++){
|
||||||
@@ -228,12 +233,21 @@ public class Turret extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(shootEffect != null){
|
||||||
|
Effects.effect(shootEffect, tile.worldx() + Angles.x() + offset.x,
|
||||||
|
tile.worldy()+ Angles.y() + offset.y, entity.rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shootShake > 0){
|
||||||
|
Effects.shake(shootShake, shootShake, tile.entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bullet(Tile tile, float angle){
|
protected void bullet(Tile tile, float angle){
|
||||||
Vector2 offset = getPlaceOffset();
|
Vector2 offset = getPlaceOffset();
|
||||||
Bullet out = new Bullet(bullet, tile.entity, tile.worldx() + Angles.x() + offset.x, tile.worldy() + Angles.y() + offset.y, angle).add();
|
Bullet out = new Bullet(bullet, tile.entity, tile.worldx() + Angles.x() + offset.x, tile.worldy() + Angles.y() + offset.y, angle).add();
|
||||||
out.damage = (int)(bullet.damage*Vars.multiplier);
|
out.damage = (int)(bullet.damage*Vars.multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TurretEntity extends TileEntity{
|
public static class TurretEntity extends TileEntity{
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user