Support for wave shields

This commit is contained in:
Anuken
2020-05-20 17:16:18 -04:00
parent dc58626602
commit 78f24b8840
10 changed files with 70 additions and 31 deletions
+1
View File
@@ -328,6 +328,7 @@ waves.never = <never>
waves.every = every waves.every = every
waves.waves = wave(s) waves.waves = wave(s)
waves.perspawn = per spawn waves.perspawn = per spawn
waves.shields = shields/wave
waves.to = to waves.to = to
waves.guardian = Guardian waves.guardian = Guardian
waves.preview = Preview waves.preview = Preview
Binary file not shown.
+1 -1
View File
@@ -128,7 +128,7 @@ public class Vars implements Loadable{
/** whether typing into the console is enabled - developers only */ /** whether typing into the console is enabled - developers only */
public static boolean enableConsole = false; public static boolean enableConsole = false;
/** whether to clear sector saves when landing */ /** whether to clear sector saves when landing */
public static boolean clearSectors = false; public static boolean clearSectors = true;
/** whether any light rendering is enabled */ /** whether any light rendering is enabled */
public static boolean enableLight = true; public static boolean enableLight = true;
/** application data directory, equivalent to {@link Settings#getDataDirectory()} */ /** application data directory, equivalent to {@link Settings#getDataDirectory()} */
+2 -2
View File
@@ -48,7 +48,7 @@ public class WaveSpawner{
eachFlyerSpawn((spawnX, spawnY) -> { eachFlyerSpawn((spawnX, spawnY) -> {
for(int i = 0; i < spawned; i++){ for(int i = 0; i < spawned; i++){
Unitc unit = group.createUnit(state.rules.waveTeam); Unitc unit = group.createUnit(state.rules.waveTeam, state.wave - 1);
unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread));
unit.add(); unit.add();
} }
@@ -61,7 +61,7 @@ public class WaveSpawner{
for(int i = 0; i < spawned; i++){ for(int i = 0; i < spawned; i++){
Tmp.v1.rnd(spread); Tmp.v1.rnd(spread);
Unitc unit = group.createUnit(state.rules.waveTeam); Unitc unit = group.createUnit(state.rules.waveTeam, state.wave - 1);
unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y); unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y);
Time.run(Math.min(i * 5, 60 * 2), () -> spawnEffect(unit)); Time.run(Math.min(i * 5, 60 * 2), () -> spawnEffect(unit));
} }
+1 -1
View File
@@ -266,7 +266,7 @@ public class ContentLoader{
return (BulletType)getByID(ContentType.bullet, id); return (BulletType)getByID(ContentType.bullet, id);
} }
public Array<SectorPreset> zones(){ public Array<SectorPreset> sectors(){
return getBy(ContentType.sector); return getBy(ContentType.sector);
} }
@@ -195,6 +195,24 @@ public class WaveInfoDialog extends FloatingDialog{
}).width(80f); }).width(80f);
a.add("$waves.perspawn").padLeft(4); a.add("$waves.perspawn").padLeft(4);
}); });
t.row();
t.table(a -> {
a.field((int)group.shields + "", TextFieldFilter.digitsOnly, text -> {
if(Strings.canParsePostiveInt(text)){
group.shields = Strings.parseInt(text);
updateWaves();
}
}).width(80f);
a.add(" + ");
a.field((int)group.shieldScaling + "", TextFieldFilter.digitsOnly, text -> {
if(Strings.canParsePostiveInt(text)){
group.shieldScaling = Strings.parseInt(text);
updateWaves();
}
}).width(80f);
a.add("$waves.shields").padLeft(4);
});
t.row(); t.row();
t.check("$waves.guardian", b -> group.effect = (b ? StatusEffects.boss : null)).padTop(4).update(b -> b.setChecked(group.effect == StatusEffects.boss)); t.check("$waves.guardian", b -> group.effect = (b ? StatusEffects.boss : null)).padTop(4).update(b -> b.setChecked(group.effect == StatusEffects.boss));
+14 -5
View File
@@ -1,10 +1,9 @@
package mindustry.game; package mindustry.game;
import arc.util.serialization.Json; import arc.util.serialization.*;
import arc.util.serialization.Json.Serializable; import arc.util.serialization.Json.*;
import arc.util.serialization.JsonValue;
import mindustry.content.*; import mindustry.content.*;
import mindustry.ctype.ContentType; import mindustry.ctype.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
@@ -30,6 +29,10 @@ public class SpawnGroup implements Serializable{
public int max = 100; public int max = 100;
/** How many waves need to pass before the amount of units spawned increases by 1 */ /** How many waves need to pass before the amount of units spawned increases by 1 */
public float unitScaling = never; public float unitScaling = never;
/** Shield points that this unit has. */
public float shields = 0f;
/** How much shields get increased per wave. */
public float shieldScaling = 0f;
/** Amount of enemies spawned initially, with no scaling */ /** Amount of enemies spawned initially, with no scaling */
public int unitAmount = 1; public int unitAmount = 1;
/** Status effect applied to the spawned unit. Null to disable. */ /** Status effect applied to the spawned unit. Null to disable. */
@@ -57,7 +60,7 @@ public class SpawnGroup implements Serializable{
* Creates a unit, and assigns correct values based on this group's data. * Creates a unit, and assigns correct values based on this group's data.
* This method does not add() the unit. * This method does not add() the unit.
*/ */
public Unitc createUnit(Team team){ public Unitc createUnit(Team team, int wave){
Unitc unit = type.create(team); Unitc unit = type.create(team);
if(effect != null){ if(effect != null){
@@ -68,6 +71,8 @@ public class SpawnGroup implements Serializable{
unit.addItem(items.item, items.amount); unit.addItem(items.item, items.amount);
} }
unit.shield(Math.max(shields + shieldScaling*(wave - begin), 0));
return unit; return unit;
} }
@@ -80,6 +85,8 @@ public class SpawnGroup implements Serializable{
if(spacing != 1) json.writeValue("spacing", spacing); if(spacing != 1) json.writeValue("spacing", spacing);
//if(max != 40) json.writeValue("max", max); //if(max != 40) json.writeValue("max", max);
if(unitScaling != never) json.writeValue("scaling", unitScaling); if(unitScaling != never) json.writeValue("scaling", unitScaling);
if(shields != 0) json.writeValue("shields", shields);
if(shieldScaling != 0) json.writeValue("shieldScaling", shieldScaling);
if(unitAmount != 1) json.writeValue("amount", unitAmount); if(unitAmount != 1) json.writeValue("amount", unitAmount);
if(effect != null) json.writeValue("effect", effect.id); if(effect != null) json.writeValue("effect", effect.id);
} }
@@ -93,6 +100,8 @@ public class SpawnGroup implements Serializable{
spacing = data.getInt("spacing", 1); spacing = data.getInt("spacing", 1);
//max = data.getInt("max", 40); //max = data.getInt("max", 40);
unitScaling = data.getFloat("scaling", never); unitScaling = data.getFloat("scaling", never);
shields = data.getFloat("shields", 0);
shieldScaling = data.getFloat("shieldScaling", 0);
unitAmount = data.getInt("amount", 1); unitAmount = data.getInt("amount", 1);
effect = content.getByID(ContentType.status, data.getInt("effect", -1)); effect = content.getByID(ContentType.status, data.getInt("effect", -1));
} }
+2 -2
View File
@@ -91,7 +91,7 @@ public class SectorPreset extends UnlockableContent{
} }
public void updateObjectives(Runnable closure){ public void updateObjectives(Runnable closure){
Array<SectorObjective> incomplete = content.zones() Array<SectorObjective> incomplete = content.sectors()
.flatMap(z -> z.requirements) .flatMap(z -> z.requirements)
.select(o -> o.zone() == this && !o.complete()) .select(o -> o.zone() == this && !o.complete())
.as(SectorObjective.class); .as(SectorObjective.class);
@@ -99,7 +99,7 @@ public class SectorPreset extends UnlockableContent{
closure.run(); closure.run();
for(SectorObjective objective : incomplete){ for(SectorObjective objective : incomplete){
if(objective.complete()){ if(objective.complete()){
Events.fire(new ZoneRequireCompleteEvent(objective.preset, content.zones().find(z -> z.requirements.contains(objective)), objective)); Events.fire(new ZoneRequireCompleteEvent(objective.preset, content.sectors().find(z -> z.requirements.contains(objective)), objective));
} }
} }
} }
@@ -87,7 +87,7 @@ public class SStats implements SteamUserStatsCallback{
}); });
Events.on(ZoneConfigureCompleteEvent.class, e -> { Events.on(ZoneConfigureCompleteEvent.class, e -> {
if(!content.zones().contains(z -> !z.canConfigure())){ if(!content.sectors().contains(z -> !z.canConfigure())){
configAllZones.complete(); configAllZones.complete();
} }
}); });
@@ -147,7 +147,7 @@ public class SStats implements SteamUserStatsCallback{
if(e.content == Items.thorium) obtainThorium.complete(); if(e.content == Items.thorium) obtainThorium.complete();
if(e.content == Items.titanium) obtainTitanium.complete(); if(e.content == Items.titanium) obtainTitanium.complete();
if(!content.zones().contains(SectorPreset::locked)){ if(!content.sectors().contains(SectorPreset::locked)){
unlockAllZones.complete(); unlockAllZones.complete();
} }
}); });
@@ -1,5 +1,6 @@
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.core.GameState.*; import mindustry.core.GameState.*;
import mindustry.game.*; import mindustry.game.*;
@@ -13,7 +14,7 @@ import static mindustry.Vars.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.junit.jupiter.api.DynamicTest.dynamicTest;
public class ZoneTests{ public class SectorTests{
@BeforeAll @BeforeAll
static void launchApplication(){ static void launchApplication(){
@@ -32,16 +33,14 @@ public class ZoneTests{
Array<DynamicTest> out = new Array<>(); Array<DynamicTest> out = new Array<>();
if(world == null) world = new World(); if(world == null) world = new World();
//TODO fix for(SectorPreset zone : content.sectors()){
if(true) return new DynamicTest[0];
//fail("Zone validity tests need to be refactored!");
for(SectorPreset zone : content.zones()){
out.add(dynamicTest(zone.name, () -> { out.add(dynamicTest(zone.name, () -> {
logic.reset(); logic.reset();
try{ try{
//world.loadGenerator(zone.generator); world.loadGenerator(zone.generator.map.width, zone.generator.map.height, zone.generator::generate);
}catch(SaveException e){ }catch(SaveException e){
//fails randomly and I don't care about fixing it
e.printStackTrace(); e.printStackTrace();
return; return;
} }
@@ -59,25 +58,37 @@ public class ZoneTests{
} }
Array<SpawnGroup> spawns = state.rules.spawns; Array<SpawnGroup> spawns = state.rules.spawns;
for(int i = 1; i <= 100; i++){
int bossWave = 0;
outer:
for(int i = 1; i <= 1000; i++){
for(SpawnGroup spawn : spawns){
if(spawn.effect == StatusEffects.boss && spawn.getUnitsSpawned(i) > 0){
bossWave = i;
break outer;
}
}
}
if(state.rules.attackMode){
bossWave = 100;
}else{
assertNotEquals(0, bossWave, "Sector doesn't have a boss wave.");
}
//TODO check for difficulty?
for(int i = 1; i <= bossWave; i++){
int total = 0; int total = 0;
for(SpawnGroup spawn : spawns){ for(SpawnGroup spawn : spawns){
total += spawn.getUnitsSpawned(i); total += spawn.getUnitsSpawned(i);
} }
assertNotEquals(0, total, "Zone " + zone + " has no spawned enemies at wave " + i); assertNotEquals(0, total, "Sector " + zone + " has no spawned enemies at wave " + i);
assertTrue(total < 75, "Sector spawns too many enemies at wave " + i + " (" + total + ")");
} }
assertTrue(hasSpawnPoint, "Zone \"" + zone.name + "\" has no spawn points."); assertTrue(hasSpawnPoint, "Sector \"" + zone.name + "\" has no spawn points.");
assertTrue(spawner.countSpawns() > 0 || (state.rules.attackMode && state.teams.get(state.rules.waveTeam).hasCore()), "Zone \"" + zone.name + "\" has no enemy spawn points: " + spawner.countSpawns()); assertTrue(spawner.countSpawns() > 0 || (state.rules.attackMode && state.teams.get(state.rules.waveTeam).hasCore()), "Sector \"" + zone.name + "\" has no enemy spawn points: " + spawner.countSpawns());
for(Item item : resources){
assertTrue(zone.resources.contains(item), "Zone \"" + zone.name + "\" is missing item in resource list: \"" + item.name + "\"");
}
for(Item item : zone.resources){
assertTrue(resources.contains(item), "Zone \"" + zone.name + "\" has unnecessary item in resource list: \"" + item.name + "\"");
}
})); }));
} }