Support for wave shields
This commit is contained in:
@@ -328,6 +328,7 @@ waves.never = <never>
|
||||
waves.every = every
|
||||
waves.waves = wave(s)
|
||||
waves.perspawn = per spawn
|
||||
waves.shields = shields/wave
|
||||
waves.to = to
|
||||
waves.guardian = Guardian
|
||||
waves.preview = Preview
|
||||
|
||||
Binary file not shown.
@@ -128,7 +128,7 @@ public class Vars implements Loadable{
|
||||
/** whether typing into the console is enabled - developers only */
|
||||
public static boolean enableConsole = false;
|
||||
/** whether to clear sector saves when landing */
|
||||
public static boolean clearSectors = false;
|
||||
public static boolean clearSectors = true;
|
||||
/** whether any light rendering is enabled */
|
||||
public static boolean enableLight = true;
|
||||
/** application data directory, equivalent to {@link Settings#getDataDirectory()} */
|
||||
|
||||
@@ -48,7 +48,7 @@ public class WaveSpawner{
|
||||
|
||||
eachFlyerSpawn((spawnX, spawnY) -> {
|
||||
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.add();
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class WaveSpawner{
|
||||
for(int i = 0; i < spawned; i++){
|
||||
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);
|
||||
Time.run(Math.min(i * 5, 60 * 2), () -> spawnEffect(unit));
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class ContentLoader{
|
||||
return (BulletType)getByID(ContentType.bullet, id);
|
||||
}
|
||||
|
||||
public Array<SectorPreset> zones(){
|
||||
public Array<SectorPreset> sectors(){
|
||||
return getBy(ContentType.sector);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +195,24 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
}).width(80f);
|
||||
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.check("$waves.guardian", b -> group.effect = (b ? StatusEffects.boss : null)).padTop(4).update(b -> b.setChecked(group.effect == StatusEffects.boss));
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package mindustry.game;
|
||||
|
||||
import arc.util.serialization.Json;
|
||||
import arc.util.serialization.Json.Serializable;
|
||||
import arc.util.serialization.JsonValue;
|
||||
import arc.util.serialization.*;
|
||||
import arc.util.serialization.Json.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.ContentType;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
@@ -30,6 +29,10 @@ public class SpawnGroup implements Serializable{
|
||||
public int max = 100;
|
||||
/** How many waves need to pass before the amount of units spawned increases by 1 */
|
||||
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 */
|
||||
public int unitAmount = 1;
|
||||
/** 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.
|
||||
* This method does not add() the unit.
|
||||
*/
|
||||
public Unitc createUnit(Team team){
|
||||
public Unitc createUnit(Team team, int wave){
|
||||
Unitc unit = type.create(team);
|
||||
|
||||
if(effect != null){
|
||||
@@ -68,6 +71,8 @@ public class SpawnGroup implements Serializable{
|
||||
unit.addItem(items.item, items.amount);
|
||||
}
|
||||
|
||||
unit.shield(Math.max(shields + shieldScaling*(wave - begin), 0));
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
@@ -80,6 +85,8 @@ public class SpawnGroup implements Serializable{
|
||||
if(spacing != 1) json.writeValue("spacing", spacing);
|
||||
//if(max != 40) json.writeValue("max", max);
|
||||
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(effect != null) json.writeValue("effect", effect.id);
|
||||
}
|
||||
@@ -93,6 +100,8 @@ public class SpawnGroup implements Serializable{
|
||||
spacing = data.getInt("spacing", 1);
|
||||
//max = data.getInt("max", 40);
|
||||
unitScaling = data.getFloat("scaling", never);
|
||||
shields = data.getFloat("shields", 0);
|
||||
shieldScaling = data.getFloat("shieldScaling", 0);
|
||||
unitAmount = data.getInt("amount", 1);
|
||||
effect = content.getByID(ContentType.status, data.getInt("effect", -1));
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class SectorPreset extends UnlockableContent{
|
||||
}
|
||||
|
||||
public void updateObjectives(Runnable closure){
|
||||
Array<SectorObjective> incomplete = content.zones()
|
||||
Array<SectorObjective> incomplete = content.sectors()
|
||||
.flatMap(z -> z.requirements)
|
||||
.select(o -> o.zone() == this && !o.complete())
|
||||
.as(SectorObjective.class);
|
||||
@@ -99,7 +99,7 @@ public class SectorPreset extends UnlockableContent{
|
||||
closure.run();
|
||||
for(SectorObjective objective : incomplete){
|
||||
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 -> {
|
||||
if(!content.zones().contains(z -> !z.canConfigure())){
|
||||
if(!content.sectors().contains(z -> !z.canConfigure())){
|
||||
configAllZones.complete();
|
||||
}
|
||||
});
|
||||
@@ -147,7 +147,7 @@ public class SStats implements SteamUserStatsCallback{
|
||||
if(e.content == Items.thorium) obtainThorium.complete();
|
||||
if(e.content == Items.titanium) obtainTitanium.complete();
|
||||
|
||||
if(!content.zones().contains(SectorPreset::locked)){
|
||||
if(!content.sectors().contains(SectorPreset::locked)){
|
||||
unlockAllZones.complete();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.core.GameState.*;
|
||||
import mindustry.game.*;
|
||||
@@ -13,7 +14,7 @@ import static mindustry.Vars.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
public class ZoneTests{
|
||||
public class SectorTests{
|
||||
|
||||
@BeforeAll
|
||||
static void launchApplication(){
|
||||
@@ -32,16 +33,14 @@ public class ZoneTests{
|
||||
Array<DynamicTest> out = new Array<>();
|
||||
if(world == null) world = new World();
|
||||
|
||||
//TODO fix
|
||||
if(true) return new DynamicTest[0];
|
||||
//fail("Zone validity tests need to be refactored!");
|
||||
for(SectorPreset zone : content.sectors()){
|
||||
|
||||
for(SectorPreset zone : content.zones()){
|
||||
out.add(dynamicTest(zone.name, () -> {
|
||||
logic.reset();
|
||||
try{
|
||||
//world.loadGenerator(zone.generator);
|
||||
world.loadGenerator(zone.generator.map.width, zone.generator.map.height, zone.generator::generate);
|
||||
}catch(SaveException e){
|
||||
//fails randomly and I don't care about fixing it
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
@@ -59,25 +58,37 @@ public class ZoneTests{
|
||||
}
|
||||
|
||||
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;
|
||||
for(SpawnGroup spawn : spawns){
|
||||
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(spawner.countSpawns() > 0 || (state.rules.attackMode && state.teams.get(state.rules.waveTeam).hasCore()), "Zone \"" + 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 + "\"");
|
||||
}
|
||||
assertTrue(hasSpawnPoint, "Sector \"" + zone.name + "\" has no spawn points.");
|
||||
assertTrue(spawner.countSpawns() > 0 || (state.rules.attackMode && state.teams.get(state.rules.waveTeam).hasCore()), "Sector \"" + zone.name + "\" has no enemy spawn points: " + spawner.countSpawns());
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user