diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml
index 4da9038d49..c7a38eeb99 100644
--- a/core/src/Mindustry.gwt.xml
+++ b/core/src/Mindustry.gwt.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java
index 5f08d35f69..441d671ead 100644
--- a/core/src/io/anuke/mindustry/Vars.java
+++ b/core/src/io/anuke/mindustry/Vars.java
@@ -72,6 +72,8 @@ public class Vars{
//whether to show block debug
public static boolean showBlockDebug = false;
+ public static boolean showFog = true;
+
public static final int maxTextLength = 150;
public static final int maxNameLength = 40;
public static final int maxCharNameLength = 20;
diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java
index e10911face..f130378736 100644
--- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java
+++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java
@@ -2,12 +2,12 @@ package io.anuke.mindustry.ai;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Bits;
-import io.anuke.mindustry.content.AmmoTypes;
-import io.anuke.mindustry.content.UnitTypes;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.Squad;
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
+import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.Team;
+import io.anuke.mindustry.game.WaveCreator;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.util.Mathf;
@@ -23,6 +23,8 @@ public class WaveSpawner {
private Bits quadrants;
+ private Array groups;
+
private Array flySpawns = new Array<>();
private Array groundSpawns = new Array<>();
@@ -62,11 +64,20 @@ public class WaveSpawner {
}
public void spawnEnemies(){
- int spawned = Math.min(state.wave, 6);
- int groundGroups = 1 + state.wave / 20;
- int flyGroups = state.wave / 20;
+ int flyGroups = 0;
+ int groundGroups = 0;
- //add extra groups if necessary
+ //count total subgroups spawned by flying/group types
+ for(SpawnGroup group : groups){
+ int amount = group.getGroupsSpawned(state.wave);
+ if(group.type.isFlying){
+ flyGroups += amount;
+ }else{
+ groundGroups += amount;
+ }
+ }
+
+ //add extra groups if the total exceeds it
for (int i = 0; i < groundGroups - groundSpawns.size; i++) {
GroundSpawn spawn = new GroundSpawn();
findLocation(spawn);
@@ -79,45 +90,49 @@ public class WaveSpawner {
flySpawns.add(spawn);
}
- if(state.wave % 20 == 0){
- for(FlyerSpawn spawn : flySpawns) findLocation(spawn);
- for(GroundSpawn spawn : groundSpawns) findLocation(spawn);
- }
+ //store index of last used fly/ground spawn locations
+ int flyCount = 0, groundCount = 0;
- for(GroundSpawn spawn : groundSpawns){
- checkQuadrant(spawn.x, spawn.y);
- if(!getQuad(spawn.x, spawn.y)){
- findLocation(spawn);
- }
+ for(SpawnGroup group : groups){
+ int groups = group.getGroupsSpawned(state.wave);
+ int spawned = group.getUnitsSpawned(state.wave);
- Squad squad = new Squad();
+ for (int i = 0; i < groups; i++) {
+ Squad squad = new Squad();
+ float spawnX, spawnY;
+ float spread;
- for(int i = 0; i < spawned; i ++){
- BaseUnit unit = UnitTypes.scout.create(Team.red);
- unit.inventory.addAmmo(AmmoTypes.bulletLead);
- unit.setWave();
- unit.setSquad(squad);
- unit.set(spawn.x * quadsize * tilesize + quadsize * tilesize/2f + Mathf.range(quadsize*tilesize/3f),
- spawn.y * quadsize * tilesize + quadsize * tilesize/2f + Mathf.range(quadsize*tilesize/3));
- unit.add();
- }
- }
+ if(group.type.isFlying){
+ FlyerSpawn spawn = flySpawns.get(flyCount);
+ //TODO verify flyer spawn
- for(FlyerSpawn spawn : flySpawns){
- Squad squad = new Squad();
- float addition = 40f;
- float spread = addition / 1.5f;
+ float margin = 40f; //how far away from the edge flying units spawn
+ spawnX = world.width() *tilesize/2f + Mathf.sqrwavex(spawn.angle) * (world.width()/2f*tilesize + margin);
+ spawnY = world.height() * tilesize/2f + Mathf.sqrwavey(spawn.angle) * (world.height()/2f*tilesize + margin);
+ spread = margin / 1.5f;
- float baseX = world.width() *tilesize/2f + Mathf.sqrwavex(spawn.angle) * (world.width()/2f*tilesize + addition),
- baseY = world.height() * tilesize/2f + Mathf.sqrwavey(spawn.angle) * (world.height()/2f*tilesize + addition);
+ flyCount ++;
+ }else{
+ GroundSpawn spawn = groundSpawns.get(groundCount);
+ checkQuadrant(spawn.x, spawn.y);
+ if(!getQuad(spawn.x, spawn.y)){
+ findLocation(spawn);
+ }
- for(int i = 0; i < spawned; i ++){
- BaseUnit unit = UnitTypes.vtol.create(Team.red);
- unit.inventory.addAmmo(AmmoTypes.bulletLead);
- unit.setWave();
- unit.setSquad(squad);
- unit.set(baseX + Mathf.range(spread), baseY + Mathf.range(spread));
- unit.add();
+ spawnX = spawn.x * quadsize * tilesize + quadsize * tilesize/2f;
+ spawnY = spawn.y * quadsize * tilesize + quadsize * tilesize/2f;
+ spread = quadsize*tilesize/3f;
+
+ groundCount ++;
+ }
+
+ for (int j = 0; j < spawned; j++) {
+ BaseUnit unit = group.createUnit(Team.red);
+ unit.setWave();
+ unit.setSquad(squad);
+ unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread));
+ unit.add();
+ }
}
}
}
@@ -150,6 +165,10 @@ public class WaveSpawner {
flySpawns.clear();
groundSpawns.clear();
quadrants = new Bits(quadWidth() * quadHeight());
+
+ if(groups == null){
+ groups = WaveCreator.getSpawns();
+ }
}
private boolean getQuad(int quadx, int quady){
@@ -164,6 +183,7 @@ public class WaveSpawner {
}
}
+ //TODO instead of randomly scattering locations around the map, find spawns close to each other
private void findLocation(GroundSpawn spawn){
spawn.x = -1;
spawn.y = -1;
@@ -182,6 +202,7 @@ public class WaveSpawner {
});
}
+ //TODO instead of randomly scattering locations around the map, find spawns close to each other
private void findLocation(FlyerSpawn spawn){
spawn.angle = Mathf.random(360f);
}
@@ -197,18 +218,10 @@ public class WaveSpawner {
private class FlyerSpawn{
//square angle
float angle;
-
- FlyerSpawn(){
-
- }
}
private class GroundSpawn{
//quadrant spawn coordinates
int x, y;
-
- GroundSpawn(){
-
- }
}
}
diff --git a/core/src/io/anuke/mindustry/content/StatusEffects.java b/core/src/io/anuke/mindustry/content/StatusEffects.java
index 8f978be392..baca35c0b0 100644
--- a/core/src/io/anuke/mindustry/content/StatusEffects.java
+++ b/core/src/io/anuke/mindustry/content/StatusEffects.java
@@ -42,7 +42,6 @@ public class StatusEffects implements ContentList {
if (Mathf.chance(Timers.delta() * 0.2f)) {
Effects.effect(EnvironmentFx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
}
-
}
};
diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java
index 8d6787a3e1..3cde2e0733 100644
--- a/core/src/io/anuke/mindustry/content/Weapons.java
+++ b/core/src/io/anuke/mindustry/content/Weapons.java
@@ -58,7 +58,7 @@ public class Weapons implements ContentList {
ejectEffect = Fx.none;
velocityRnd = 1f;
inaccuracy = 40f;
- setAmmo(AmmoTypes.bombExplosive);
+ setAmmo(AmmoTypes.bombExplosive, AmmoTypes.bombIncendiary);
}};
}
diff --git a/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java b/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java
index b222b554d3..641a1644ce 100644
--- a/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java
+++ b/core/src/io/anuke/mindustry/content/bullets/WeaponBullets.java
@@ -35,13 +35,13 @@ public class WeaponBullets extends BulletList {
}
};
- bombIncendiary = new BombBulletType(20f, 20f, "shell"){
+ bombIncendiary = new BombBulletType(15f, 10f, "shell"){
{
- bulletWidth = 9f;
- bulletHeight = 13f;
+ bulletWidth = 8f;
+ bulletHeight = 12f;
hiteffect = BulletFx.flakExplosion;
- backColor = Palette.darkFlame;
- frontColor = Palette.lightFlame;
+ backColor = Palette.lightOrange;
+ frontColor = Palette.lightishOrange;
}
@Override
diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java
index 324dd5632a..86881af83a 100644
--- a/core/src/io/anuke/mindustry/core/Renderer.java
+++ b/core/src/io/anuke/mindustry/core/Renderer.java
@@ -247,7 +247,9 @@ public class Renderer extends RendererModule{
batch.end();
- fog.draw();
+ if(showFog){
+ fog.draw();
+ }
}
private void drawAllTeams(boolean flying){
diff --git a/core/src/io/anuke/mindustry/entities/Damage.java b/core/src/io/anuke/mindustry/entities/Damage.java
index 514b34e48e..2ea6643f5e 100644
--- a/core/src/io/anuke/mindustry/entities/Damage.java
+++ b/core/src/io/anuke/mindustry/entities/Damage.java
@@ -169,7 +169,8 @@ public class Damage {
private static float calculateDamage(float x, float y, float tx, float ty, float radius, float damage){
float dist = Vector2.dst(x, y, tx, ty);
- float scaled = 1f - dist/radius;
+ float falloff = 0.4f;
+ float scaled = Mathf.lerp(1f - dist/radius, 1f, falloff);
return damage * scaled;
}
}
diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java
index 3a6cc041b7..b71bb35817 100644
--- a/core/src/io/anuke/mindustry/entities/Player.java
+++ b/core/src/io/anuke/mindustry/entities/Player.java
@@ -228,6 +228,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float explosiveness = 2f + (player.inventory.hasItem() ? player.inventory.getItem().item.explosiveness * player.inventory.getItem().amount : 0f);
float flammability = (player.inventory.hasItem() ? player.inventory.getItem().item.flammability * player.inventory.getItem().amount : 0f);
Damage.dynamicExplosion(player.x, player.y, flammability, explosiveness, 0f, player.getSize()/2f, Palette.darkFlame);
+
ScorchDecal.create(player.x, player.y);
Effects.sound("die", player);
player.onDeath();
@@ -471,7 +472,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(ui.chatfrag.chatOpen()) return;
- float speed = isBoosting && !mech.flying ? mech.boostSpeed : mech.speed;
+ float speed = isBoosting && !mech.flying ? debug ? 5f : mech.boostSpeed : mech.speed;
//fraction of speed when at max load
float carrySlowdown = 0.7f;
diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
index 8e71ca2211..526ffbb718 100644
--- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
+++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java
@@ -6,6 +6,7 @@ import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.fx.ExplosionFx;
+import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
@@ -15,9 +16,11 @@ import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.gen.CallEntity;
+import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
+import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.units.UnitFactory.UnitFactoryEntity;
@@ -25,9 +28,8 @@ import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
-import io.anuke.ucore.util.Geometry;
-import io.anuke.ucore.util.Mathf;
-import io.anuke.ucore.util.Timer;
+import io.anuke.ucore.graphics.Draw;
+import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -149,6 +151,23 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
return null;
}
+ protected void drawItems(){
+ float backTrns = 4f, itemSize = 5f;
+ if(inventory.hasItem()){
+ ItemStack stack = inventory.getItem();
+ int stored = Mathf.clamp(stack.amount / 6, 1, 8);
+
+ for(int i = 0; i < stored; i ++) {
+ float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f);
+ float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f;
+ Draw.rect(stack.item.region,
+ x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
+ y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
+ itemSize, itemSize, rotation);
+ }
+ }
+ }
+
@Override
public Timer getTimer() {
return timer;
@@ -354,9 +373,14 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
public static void onUnitDeath(BaseUnit unit){
if(unit == null) return;
- unit.onSuperDeath();
UnitDrops.dropItems(unit);
+ float explosiveness = 2f + (unit.inventory.hasItem() ? unit.inventory.getItem().item.explosiveness * unit.inventory.getItem().amount : 0f);
+ float flammability = (unit.inventory.hasItem() ? unit.inventory.getItem().item.flammability * unit.inventory.getItem().amount : 0f);
+ Damage.dynamicExplosion(unit.x, unit.y, flammability, explosiveness, 0f, unit.getSize()/2f, Palette.darkFlame);
+
+ unit.onSuperDeath();
+
ScorchDecal.create(unit.x, unit.y);
Effects.effect(ExplosionFx.explosion, unit);
Effects.shake(2f, 2f, unit);
diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java
index 756533825d..b3ca78b506 100644
--- a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java
+++ b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java
@@ -9,7 +9,6 @@ import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.AmmoType;
-import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Timers;
@@ -66,20 +65,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
Draw.rect(type.name, x, y, rotation - 90);
- float backTrns = 4f, itemSize = 5f;
- if(inventory.hasItem()){
- ItemStack stack = inventory.getItem();
- int stored = Mathf.clamp(stack.amount / 6, 1, 8);
-
- for(int i = 0; i < stored; i ++) {
- float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f);
- float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f;
- Draw.rect(stack.item.region,
- x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
- y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
- itemSize, itemSize, rotation);
- }
- }
+ drawItems();
Draw.alpha(1f);
}
diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
index 849a22c943..e44297fe22 100644
--- a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
+++ b/core/src/io/anuke/mindustry/entities/units/GroundUnit.java
@@ -28,9 +28,6 @@ import static io.anuke.mindustry.Vars.world;
public abstract class GroundUnit extends BaseUnit {
protected static Translator vec = new Translator();
- protected static float maxAim = 30f;
-
- protected static final int timerReloadAlt = timerIndex++;
protected float walkTime;
protected float baseRotation;
@@ -53,7 +50,9 @@ public abstract class GroundUnit extends BaseUnit {
@Override
public void move(float x, float y){
- baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
+ if(Mathf.dst(x, y) > 0.01f){
+ baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
+ }
super.move(x, y);
}
@@ -66,7 +65,7 @@ public abstract class GroundUnit extends BaseUnit {
public void update() {
super.update();
- if(!velocity.isZero(0.001f) && (target == null || !inventory.hasAmmo() || (inventory.hasAmmo() && distanceTo(target) > inventory.getAmmoRange()))){
+ if(!velocity.isZero(0.0001f) && (target == null || !inventory.hasAmmo() || (inventory.hasAmmo() && distanceTo(target) > inventory.getAmmoRange()))){
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.2f);
}
}
@@ -115,6 +114,8 @@ public abstract class GroundUnit extends BaseUnit {
y + Angles.trnsy(tra, type.weaponOffsetX * i, trY), w, 12, rotation - 90);
}
+ drawItems();
+
Draw.alpha(1f);
}
diff --git a/core/src/io/anuke/mindustry/game/EnemySpawn.java b/core/src/io/anuke/mindustry/game/EnemySpawn.java
deleted file mode 100644
index 1339b93fa0..0000000000
--- a/core/src/io/anuke/mindustry/game/EnemySpawn.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package io.anuke.mindustry.game;
-
-import io.anuke.mindustry.entities.units.UnitType;
-import io.anuke.ucore.util.Mathf;
-
-import static io.anuke.mindustry.Vars.state;
-
-public class EnemySpawn{
- /**The enemy type spawned*/
- public final UnitType type;
- /**When this spawns should end*/
- protected int before = Integer.MAX_VALUE;
- /**When this spawns should start*/
- protected int after;
- /**The spacing, in waves, of spawns. 2 = spawns every other wave*/
- protected int spacing = 1;
- /**How many waves need to pass after the start of this spawn for the tier to increase by one*/
- protected int tierscale = 17;
- /**How many more enemies there are, every time the tier increases*/
- protected int tierscaleback = 0;
- /**The tier this spawn starts at.*/
- protected int tier = 1;
- /**Maximum amount of enemies that spawn*/
- protected int max = 60;
- /**How many waves need to pass before the amount of enemies increases by 1*/
- protected float scaling = 9999f;
- /**Amount of enemies spawned initially, with no scaling*/
- protected int amount = 1;
-
- public EnemySpawn(UnitType type){
- this.type = type;
- }
-
- //TODO
- public int evaluate(int wave, int lane){
- if(wave < after || wave > before || (wave - after) % spacing != 0){
- return 0;
- }
- float scaling = this.scaling * state.difficulty.enemyScaling;
-
- return Math.min(amount-1 + Math.max((int)((wave / spacing) / scaling), 1) + (tier(wave, lane)-1) * tierscaleback, max);
- }
-
- public int tier(int wave, int lane){
- return Mathf.clamp(tier + (wave-after)/tierscale, 1, 5);
- }
-}
diff --git a/core/src/io/anuke/mindustry/game/SpawnGroup.java b/core/src/io/anuke/mindustry/game/SpawnGroup.java
new file mode 100644
index 0000000000..33e85d536e
--- /dev/null
+++ b/core/src/io/anuke/mindustry/game/SpawnGroup.java
@@ -0,0 +1,93 @@
+package io.anuke.mindustry.game;
+
+import io.anuke.mindustry.entities.units.BaseUnit;
+import io.anuke.mindustry.entities.units.GroundUnit;
+import io.anuke.mindustry.entities.units.UnitType;
+import io.anuke.mindustry.type.Item;
+import io.anuke.mindustry.type.ItemStack;
+import io.anuke.mindustry.type.StatusEffect;
+import io.anuke.mindustry.type.Weapon;
+
+import static io.anuke.mindustry.Vars.state;
+
+/**A spawn group defines spawn information for a specific type of unit, with optional extra information like
+ * weapon equipped, ammo used, and status effects.
+ * Each spawn group can have multiple sub-groups spawned in different areas of the map.*/
+public class SpawnGroup {
+ /**The unit type spawned*/
+ public final UnitType type;
+ /**When this spawn should end*/
+ protected int end = Integer.MAX_VALUE;
+ /**When this spawn should start*/
+ protected int begin;
+ /**The spacing, in waves, of spawns. For example, 2 = spawns every other wave*/
+ protected int spacing = 1;
+ /**Maximum amount of units that spawn*/
+ protected int max = 60;
+ /**How many waves need to pass before the amount of units spawned increases by 1*/
+ protected float unitScaling = 9999f;
+ /**How many waves need to pass before the amount of instances of this group increases by 1*/
+ protected float groupScaling = 9999f;
+ /**Amount of enemies spawned initially, with no scaling*/
+ protected int unitAmount = 1;
+ /**Amount of enemies spawned initially, with no scaling*/
+ protected int groupAmount = 1;
+ /**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/
+ protected Weapon weapon;
+ /**Status effect applied to the spawned unit. Null to disable.*/
+ protected StatusEffect effect;
+ /**Items this unit spawns with. Null to disable.*/
+ protected ItemStack items;
+ /**Ammo type this unit spawns with. Null to use the first available ammo.*/
+ protected Item ammoItem;
+
+ public SpawnGroup(UnitType type){
+ this.type = type;
+ }
+
+ /**Returns the amount of units spawned on a specific wave.*/
+ public int getUnitsSpawned(int wave){
+ if(wave < begin || wave > end || (wave - begin) % spacing != 0){
+ return 0;
+ }
+ float scaling = this.unitScaling * state.difficulty.enemyScaling;
+
+ return Math.min(unitAmount-1 + Math.max((int)((wave / spacing) / scaling), 1), max);
+ }
+
+ /**Returns the amount of different unit groups at a specific wave.*/
+ public int getGroupsSpawned(int wave){
+ if(wave < begin || wave > end || (wave - begin) % spacing != 0){
+ return 0;
+ }
+ float scaling = this.groupScaling;
+
+ return Math.min(groupAmount-1 + Math.max((int)((wave / spacing) / groupScaling), 1), max);
+ }
+
+ /**Creates a unit, and assigns correct values based on this group's data.
+ * This method does not add() the unit.*/
+ public BaseUnit createUnit(Team team){
+ BaseUnit unit = type.create(team);
+
+ if(unit instanceof GroundUnit && weapon != null){
+ ((GroundUnit) unit).setWeapon(weapon);
+ }
+
+ if(effect != null){
+ unit.applyEffect(effect, 1f);
+ }
+
+ if(items != null){
+ unit.inventory.addItem(items.item, items.amount);
+ }
+
+ if(ammoItem != null){
+ unit.inventory.addAmmo(unit.getWeapon().getAmmoType(ammoItem));
+ }else{
+ unit.inventory.addAmmo(unit.getWeapon().getAmmoType(unit.getWeapon().getAcceptedItems().iterator().next()));
+ }
+
+ return unit;
+ }
+}
diff --git a/core/src/io/anuke/mindustry/game/WaveCreator.java b/core/src/io/anuke/mindustry/game/WaveCreator.java
index 79b2f7cd9d..eb7f8dd7a4 100644
--- a/core/src/io/anuke/mindustry/game/WaveCreator.java
+++ b/core/src/io/anuke/mindustry/game/WaveCreator.java
@@ -1,26 +1,48 @@
package io.anuke.mindustry.game;
import com.badlogic.gdx.utils.Array;
+import io.anuke.mindustry.content.Items;
+import io.anuke.mindustry.content.UnitTypes;
+import io.anuke.mindustry.type.ItemStack;
public class WaveCreator{
- public static Array getSpawns(){
- //TODO
- return null;
+ public static Array getSpawns(){
+ return Array.with(
+ new SpawnGroup(UnitTypes.scout){{
+ end = 5;
+ }},
+
+ new SpawnGroup(UnitTypes.titan){{
+ begin = 6;
+ }},
+
+ new SpawnGroup(UnitTypes.scout){{
+ begin = 6;
+ items = new ItemStack(Items.thermite, 100);
+ }},
+
+ new SpawnGroup(UnitTypes.vtol){{
+ begin = 8;
+ }},
+
+ new SpawnGroup(UnitTypes.monsoon){{
+ begin = 16;
+ }}
+ );
}
public static void testWaves(int from, int to){
- Array spawns = getSpawns();
+ Array spawns = getSpawns();
for(int i = from; i <= to; i ++){
System.out.print(i+": ");
int total = 0;
- for(EnemySpawn spawn : spawns){
- int a = spawn.evaluate(i, 0);
- int t = spawn.tier(i, 0);
+ for(SpawnGroup spawn : spawns){
+ int a = spawn.getUnitsSpawned(i);
total += a;
if(a > 0){
- System.out.print(a+"x" + spawn.type.name + "-" + t + " ");
+ System.out.print(a+"x" + spawn.type.name);
}
}
System.out.print(" (" + total + ")");
diff --git a/core/src/io/anuke/mindustry/type/StatusEffect.java b/core/src/io/anuke/mindustry/type/StatusEffect.java
index 6c36a655b4..17a04881de 100644
--- a/core/src/io/anuke/mindustry/type/StatusEffect.java
+++ b/core/src/io/anuke/mindustry/type/StatusEffect.java
@@ -14,9 +14,9 @@ public class StatusEffect implements Content{
public final float baseDuration;
public final int id;
- public float damageMultiplier; //damage dealt
- public float armorMultiplier; //armor points
- public float speedMultiplier; //speed
+ public float damageMultiplier = 1f; //damage dealt
+ public float armorMultiplier = 1f; //armor points
+ public float speedMultiplier = 1f; //speed
/**Set of 'opposite' effects, which will decrease the duration of this effect when applied.*/
protected ObjectSet opposites = new ObjectSet<>();
diff --git a/core/src/io/anuke/mindustry/type/Weapon.java b/core/src/io/anuke/mindustry/type/Weapon.java
index e5477068bf..52f1fe2af3 100644
--- a/core/src/io/anuke/mindustry/type/Weapon.java
+++ b/core/src/io/anuke/mindustry/type/Weapon.java
@@ -1,7 +1,7 @@
package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
-import com.badlogic.gdx.utils.ObjectMap;
+import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
@@ -23,7 +23,7 @@ public class Weapon extends Upgrade {
/**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/
protected static float minPlayerDist = 20f;
/**ammo type map. set with setAmmo()*/
- protected ObjectMap- ammoMap = new ObjectMap<>();
+ protected OrderedMap
- ammoMap = new OrderedMap<>();
/**shell ejection effect*/
protected Effect ejectEffect = Fx.none;
/**weapon reload in frames*/
@@ -112,7 +112,7 @@ public class Weapon extends Upgrade {
}
public Iterable
- getAcceptedItems(){
- return ammoMap.keys();
+ return ammoMap.orderedKeys();
}
public AmmoType getAmmoType(Item item){
diff --git a/core/src/io/anuke/mindustry/ui/Minimap.java b/core/src/io/anuke/mindustry/ui/Minimap.java
index d9e02676b3..9e469bac1f 100644
--- a/core/src/io/anuke/mindustry/ui/Minimap.java
+++ b/core/src/io/anuke/mindustry/ui/Minimap.java
@@ -14,6 +14,7 @@ import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Table;
import static io.anuke.mindustry.Vars.renderer;
+import static io.anuke.mindustry.Vars.showFog;
public class Minimap extends Table {
@@ -35,18 +36,19 @@ public class Minimap extends Table {
renderer.minimap().drawEntities(x, y, width, height);
}
- renderer.fog().getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
+ if(showFog) {
+ renderer.fog().getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
- draw.getRegion().setTexture(renderer.fog().getTexture());
- draw.getRegion().setV(1f - draw.getRegion().getV());
- draw.getRegion().setV2(1f - draw.getRegion().getV2());
+ draw.getRegion().setTexture(renderer.fog().getTexture());
+ draw.getRegion().setV(1f - draw.getRegion().getV());
+ draw.getRegion().setV2(1f - draw.getRegion().getV2());
+ Graphics.shader(Shaders.fog);
+ super.draw(batch, parentAlpha);
+ Graphics.shader();
- Graphics.shader(Shaders.fog);
- super.draw(batch, parentAlpha);
- Graphics.shader();
-
- renderer.fog().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
+ renderer.fog().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
+ }
}
};
diff --git a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java
index 097e88e3a5..658a46959e 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java
@@ -2,10 +2,9 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
-import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
-import io.anuke.mindustry.entities.bullet.Bullet;
+import io.anuke.mindustry.entities.effect.Fire;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.net.Net;
@@ -58,19 +57,21 @@ public class DebugFragment implements Fragment {
row();
new button("noclip", "toggle", () -> noclip = !noclip);
row();
+ new button("fire", () -> {
+ for (int i = 0; i < 10; i++) {
+ Fire.create(world.tileWorld(player.x + Mathf.range(20), player.y + Mathf.range(20)));
+ }
+ });
+ row();
new button("team", "toggle", () -> player.toggleTeam());
row();
new button("blocks", "toggle", () -> showBlockDebug = !showBlockDebug);
row();
- new button("effect", () -> {
- for(int i = 0; i < 20; i ++){
- Bullet.create(TurretBullets.fireball, player, player.getTeam(), player.x, player.y, Mathf.random(360f));
- }
- });
+ new button("fog", () -> showFog = !showFog);
row();
new button("wave", () -> state.wavetime = 0f);
row();
- new button("death", () -> player.damage(99999, false));
+ new button("death", () -> player.damage(99999, true));
row();
new button("spawn", () -> {
FloatingDialog dialog = new FloatingDialog("debug spawn");