diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 4ce05d5e0f..a59e2fff42 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -463,7 +463,7 @@ load = Load save = Save fps = FPS: {0} ping = Ping: {0}ms -language.restart = Please restart your game for the language settings to take effect. +language.restart = Restart your game for the language settings to take effect. settings = Settings tutorial = Tutorial tutorial.retake = Re-Take Tutorial diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index dfd2984e75..e0902201a8 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -187,7 +187,7 @@ public class Vars implements Loadable{ public static ContentLoader content; public static GameState state; public static EntityCollisions collisions; - public static DefaultWaves defaultWaves; + public static Waves waves; public static LoopControl loops; public static Platform platform = new Platform(){}; public static Mods mods; @@ -256,7 +256,7 @@ public class Vars implements Loadable{ content = new ContentLoader(); loops = new LoopControl(); - defaultWaves = new DefaultWaves(); + waves = new Waves(); collisions = new EntityCollisions(); world = new World(); universe = new Universe(); diff --git a/core/src/mindustry/editor/WaveInfoDialog.java b/core/src/mindustry/editor/WaveInfoDialog.java index a374613b24..a98d03a923 100644 --- a/core/src/mindustry/editor/WaveInfoDialog.java +++ b/core/src/mindustry/editor/WaveInfoDialog.java @@ -64,7 +64,7 @@ public class WaveInfoDialog extends BaseDialog{ }).disabled(b -> Core.app.getClipboardText() == null || Core.app.getClipboardText().isEmpty()); dialog.cont.row(); dialog.cont.button("@settings.reset", () -> ui.showConfirm("@confirm", "@settings.clear.confirm", () -> { - groups = JsonIO.copy(defaultWaves.get()); + groups = JsonIO.copy(waves.get()); buildGroups(); dialog.hide(); })); @@ -98,7 +98,7 @@ public class WaveInfoDialog extends BaseDialog{ if(experimental){ buttons.button("Random", Icon.refresh, () -> { groups.clear(); - groups = DefaultWaves.generate(1f / 10f); + groups = Waves.generate(1f / 10f); updateWaves(); }).width(200f); } @@ -125,7 +125,7 @@ public class WaveInfoDialog extends BaseDialog{ } void setup(){ - groups = JsonIO.copy(state.rules.spawns.isEmpty() ? defaultWaves.get() : state.rules.spawns); + groups = JsonIO.copy(state.rules.spawns.isEmpty() ? waves.get() : state.rules.spawns); cont.clear(); cont.stack(new Table(Tex.clear, main -> { diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index 44824e3674..0f517ab3fe 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -33,6 +33,7 @@ import mindustry.world.blocks.power.*; import mindustry.world.blocks.production.*; import mindustry.world.blocks.sandbox.*; import mindustry.world.blocks.storage.*; +import mindustry.world.meta.*; import java.io.*; import java.util.zip.*; @@ -297,7 +298,8 @@ public class Schematics implements Loadable{ Stile core = s.tiles.find(t -> t.block instanceof CoreBlock); //make sure a core exists, and that the schematic is small enough. - if(core == null || (validate && (s.width > core.block.size + maxLoadoutSchematicPad *2 || s.height > core.block.size + maxLoadoutSchematicPad *2))) return; + if(core == null || (validate && (s.width > core.block.size + maxLoadoutSchematicPad *2 || s.height > core.block.size + maxLoadoutSchematicPad *2 + || s.tiles.contains(t -> t.block.buildVisibility == BuildVisibility.sandboxOnly)))) return; //place in the cache loadouts.get((CoreBlock)core.block, Seq::new).add(s); diff --git a/core/src/mindustry/game/SectorInfo.java b/core/src/mindustry/game/SectorInfo.java index 3ef6946424..6b2cd491d6 100644 --- a/core/src/mindustry/game/SectorInfo.java +++ b/core/src/mindustry/game/SectorInfo.java @@ -57,6 +57,8 @@ public class SectorInfo{ public float secondsPassed; /** Display name. */ public @Nullable String name; + /** Version of generated waves. When it doesn't match, new waves are generated. */ + public int waveVersion = -1; /** Special variables for simulation. */ public float sumHealth, sumRps, sumDps, waveHealthBase, waveHealthSlope, waveDpsBase, waveDpsSlope; @@ -118,6 +120,11 @@ public class SectorInfo{ state.rules.winWave = winWave; state.rules.attackMode = attack; + //assign new wave patterns when the version changes + if(waveVersion != Waves.waveVersion && state.rules.sector.preset == null){ + state.rules.spawns = Waves.generate(state.rules.sector.baseCoverage); + } + CoreBuild entity = state.rules.defaultTeam.core(); if(entity != null){ entity.items.clear(); @@ -143,6 +150,7 @@ public class SectorInfo{ spawnPosition = entity.pos(); } + waveVersion = Waves.waveVersion; waveSpacing = state.rules.waveSpacing; wave = state.wave; winWave = state.rules.winWave; diff --git a/core/src/mindustry/game/DefaultWaves.java b/core/src/mindustry/game/Waves.java similarity index 98% rename from core/src/mindustry/game/DefaultWaves.java rename to core/src/mindustry/game/Waves.java index 48582e0eb2..16d542b393 100644 --- a/core/src/mindustry/game/DefaultWaves.java +++ b/core/src/mindustry/game/Waves.java @@ -9,7 +9,9 @@ import mindustry.type.*; import static mindustry.content.UnitTypes.*; -public class DefaultWaves{ +public class Waves{ + public static final int waveVersion = 1; + private Seq spawns; public Seq get(){ @@ -337,7 +339,7 @@ public class DefaultWaves{ step += (int)(rand.random(15, 30) * Mathf.lerp(1f, 0.5f, difficulty)); } - int bossWave = (int)(rand.random(30, 60) * Mathf.lerp(1f, 0.7f, difficulty)); + int bossWave = (int)(rand.random(50, 70) * Mathf.lerp(1f, 0.6f, difficulty)); int bossSpacing = (int)(rand.random(25, 40) * Mathf.lerp(1f, 0.6f, difficulty)); //main boss progression diff --git a/core/src/mindustry/io/SaveVersion.java b/core/src/mindustry/io/SaveVersion.java index a1e26c9b57..ab243b0823 100644 --- a/core/src/mindustry/io/SaveVersion.java +++ b/core/src/mindustry/io/SaveVersion.java @@ -107,7 +107,7 @@ public abstract class SaveVersion extends SaveFileReader{ state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing); state.stats = JsonIO.read(GameStats.class, map.get("stats", "{}")); state.rules = JsonIO.read(Rules.class, map.get("rules", "{}")); - if(state.rules.spawns.isEmpty()) state.rules.spawns = defaultWaves.get(); + if(state.rules.spawns.isEmpty()) state.rules.spawns = waves.get(); lastReadBuild = map.getInt("build", -1); if(!headless){ diff --git a/core/src/mindustry/maps/Map.java b/core/src/mindustry/maps/Map.java index 0fdc818139..62d47d9412 100644 --- a/core/src/mindustry/maps/Map.java +++ b/core/src/mindustry/maps/Map.java @@ -101,7 +101,7 @@ public class Map implements Comparable, Publishable{ //this replacement is a MASSIVE hack but it fixes some incorrect overwriting of team-specific rules. //may need to be tweaked later Rules result = JsonIO.read(Rules.class, base, tags.get("rules", "{}").replace("teams:{2:{infiniteAmmo:true}},", "")); - if(result.spawns.isEmpty()) result.spawns = Vars.defaultWaves.get(); + if(result.spawns.isEmpty()) result.spawns = Vars.waves.get(); return result; }catch(Exception e){ //error reading rules. ignore? diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index 4c7bd49a4e..4b878d3dd2 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -420,7 +420,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ state.rules.waves = sector.info.waves = true; //TODO better waves - state.rules.spawns = DefaultWaves.generate(difficulty); + state.rules.spawns = Waves.generate(difficulty); } @Override diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 4fdf9a34b0..eb05dc6c6b 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -295,7 +295,7 @@ public class ContentParser{ group.type = unit; } - Vars.defaultWaves.get().addAll(groups); + Vars.waves.get().addAll(groups); } readFields(unit, value, true); diff --git a/ios/src/mindustry/ios/IOSLauncher.java b/ios/src/mindustry/ios/IOSLauncher.java index d46c5b016c..d725c1053b 100644 --- a/ios/src/mindustry/ios/IOSLauncher.java +++ b/ios/src/mindustry/ios/IOSLauncher.java @@ -205,7 +205,7 @@ public class IOSLauncher extends IOSApplication.Delegate{ UIInterfaceOrientation o = UIApplication.getSharedApplication().getStatusBarOrientation(); return forced && (o == UIInterfaceOrientation.Portrait || o == UIInterfaceOrientation.PortraitUpsideDown); }); - t.add("Please rotate the device to landscape orientation to use the editor.").wrap().grow(); + t.add("Rotate the device to landscape orientation to use the editor.").wrap().grow(); }); })); }); diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index 7e1be67c52..06a117d1b0 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -42,8 +42,8 @@ public class ServerControl implements ApplicationListener{ protected static DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss"), autosaveDate = DateTimeFormatter.ofPattern("MM-dd-yyyy_HH-mm-ss"); - private final CommandHandler handler = new CommandHandler(""); - private final Fi logFolder = Core.settings.getDataDirectory().child("logs/"); + public final CommandHandler handler = new CommandHandler(""); + public final Fi logFolder = Core.settings.getDataDirectory().child("logs/"); private Fi currentLogFile; private boolean inExtraRound; @@ -55,8 +55,7 @@ public class ServerControl implements ApplicationListener{ private Thread socketThread; private ServerSocket serverSocket; private PrintWriter socketOutput; - - private String yes; + private String suggested; public ServerControl(String[] args){ Core.settings.defaults( @@ -916,10 +915,10 @@ public class ServerControl implements ApplicationListener{ }); handler.register("yes", "Run the last suggested incorrect command.", arg -> { - if(yes == null){ + if(suggested == null){ err("There is nothing to say yes to."); }else{ - handleCommandString(yes); + handleCommandString(suggested); } }); @@ -953,7 +952,7 @@ public class ServerControl implements ApplicationListener{ if(closest != null){ err("Command not found. Did you mean \"" + closest.text + "\"?"); - yes = line.replace(response.runCommand, closest.text); + suggested = line.replace(response.runCommand, closest.text); }else{ err("Invalid command. Type 'help' for help."); } @@ -962,7 +961,7 @@ public class ServerControl implements ApplicationListener{ }else if(response.type == ResponseType.manyArguments){ err("Too many command arguments. Usage: " + response.command.text + " " + response.command.paramText); }else if(response.type == ResponseType.valid){ - yes = null; + suggested = null; } }