From f1fd07240019a64a8783f1658dc7abc99f6bd235 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 31 Mar 2020 14:16:38 -0400 Subject: [PATCH] Game state cleanup --- core/src/mindustry/Vars.java | 4 ++++ core/src/mindustry/core/Control.java | 4 ++-- core/src/mindustry/core/GameState.java | 5 ++++- core/src/mindustry/core/Logic.java | 11 +++++------ core/src/mindustry/core/NetClient.java | 4 ---- core/src/mindustry/core/World.java | 13 ++----------- core/src/mindustry/editor/MapEditorDialog.java | 10 +++++----- core/src/mindustry/io/SaveVersion.java | 7 ++++--- .../maps/generators/FileMapGenerator.java | 3 ++- core/src/mindustry/net/ArcNetProvider.java | 8 +++----- core/src/mindustry/net/NetworkIO.java | 6 +++--- core/src/mindustry/ui/dialogs/GameOverDialog.java | 8 ++------ core/src/mindustry/ui/dialogs/LoadDialog.java | 1 - core/src/mindustry/ui/dialogs/PausedDialog.java | 3 --- desktop/src/mindustry/desktop/DesktopLauncher.java | 7 +++---- desktop/src/mindustry/desktop/steam/SNet.java | 4 +--- gradle.properties | 2 +- server/src/mindustry/server/ServerControl.java | 14 ++++++-------- tests/src/test/java/ApplicationTests.java | 2 +- tools/build.gradle | 6 +++--- 20 files changed, 51 insertions(+), 71 deletions(-) diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 12821c4bed..d3fed00cba 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -18,6 +18,7 @@ import mindustry.game.EventType.*; import mindustry.gen.*; import mindustry.input.*; import mindustry.maps.*; +import mindustry.maps.Map; import mindustry.mod.*; import mindustry.net.Net; import mindustry.net.*; @@ -142,6 +143,8 @@ public class Vars implements Loadable{ public static Fi schematicDirectory; /** data subdirectory used for bleeding edge build versions */ public static Fi bebuildDirectory; + /** empty map, indicates no current map */ + public static Map emptyMap; /** map file extension */ public static final String mapExtension = "msav"; /** save file extension */ @@ -219,6 +222,7 @@ public class Vars implements Loadable{ modDirectory = dataDirectory.child("mods/"); schematicDirectory = dataDirectory.child("schematics/"); bebuildDirectory = dataDirectory.child("be_builds/"); + emptyMap = new Map(new StringMap()); if(tree == null) tree = new FileTree(); if(mods == null) mods = new Mods(); diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 1cf4562ac0..6b41a97a5f 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -88,9 +88,9 @@ public class Control implements ApplicationListener, Loadable{ }); Events.on(WaveEvent.class, event -> { - if(world.getMap().getHightScore() < state.wave){ + if(state.map.getHightScore() < state.wave){ hiscore = true; - world.getMap().setHighScore(state.wave); + state.map.setHighScore(state.wave); } Sounds.wave.play(); diff --git a/core/src/mindustry/core/GameState.java b/core/src/mindustry/core/GameState.java index 3ea19618e4..6cd548ab6c 100644 --- a/core/src/mindustry/core/GameState.java +++ b/core/src/mindustry/core/GameState.java @@ -5,9 +5,10 @@ import arc.util.ArcAnnotate.*; import mindustry.game.EventType.*; import mindustry.game.*; import mindustry.gen.*; +import mindustry.maps.*; import mindustry.type.*; -import static mindustry.Vars.net; +import static mindustry.Vars.*; public class GameState{ /** Current wave number, can be anything in non-wave modes. */ @@ -16,6 +17,8 @@ public class GameState{ public float wavetime; /** Whether the game is in game over state. */ public boolean gameOver = false, launched = false; + /** Map that is currently being played on. */ + public @NonNull Map map = emptyMap; /** The current game rules. */ public Rules rules = new Rules(); /** Statistics for this save/game. Displayed after game over. */ diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 2c6c02e311..91bd2c7020 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -120,12 +120,11 @@ public class Logic implements ApplicationListener{ } public void reset(){ - state.wave = 1; - state.wavetime = state.rules.waveSpacing; - state.gameOver = state.launched = false; - state.teams = new Teams(); - state.rules = new Rules(); - state.stats = new Stats(); + State prev = state.getState(); + //recreate gamestate - sets state to menu + state = new GameState(); + //fire change event, since it was technically changed + Events.fire(new StateChangeEvent(prev, State.menu)); Groups.all.clear(); Time.clear(); diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index f2a7208bd8..2b426aa855 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -92,7 +92,6 @@ public class NetClient implements ApplicationListener{ if(quietReset) return; connecting = false; - state.set(State.menu); logic.reset(); platform.updateRPC(); player.name(Core.settings.getString("name")); @@ -207,7 +206,6 @@ public class NetClient implements ApplicationListener{ @Remote(called = Loc.client, variants = Variant.one) public static void onConnect(String ip, int port){ netClient.disconnectQuietly(); - state.set(State.menu); logic.reset(); ui.join.connect(ip, port); @@ -233,7 +231,6 @@ public class NetClient implements ApplicationListener{ @Remote(variants = Variant.one, priority = PacketPriority.high) public static void onKick(KickReason reason){ netClient.disconnectQuietly(); - state.set(State.menu); logic.reset(); if(!reason.quiet){ @@ -249,7 +246,6 @@ public class NetClient implements ApplicationListener{ @Remote(variants = Variant.one, priority = PacketPriority.high) public static void onKick(String reason){ netClient.disconnectQuietly(); - state.set(State.menu); logic.reset(); ui.showText("$disconnect", reason, Align.left); ui.loadfrag.hide(); diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index 90f9179fcb..0aa9504d2f 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -26,7 +26,6 @@ import static mindustry.Vars.*; public class World{ public final Context context = new Context(); - private Map currentMap = new Map(new StringMap()); public @NonNull Tiles tiles = new Tiles(0, 0); private boolean generating, invalidMap; @@ -60,14 +59,6 @@ public class World{ return !wallSolid(x, y - 1) || !wallSolid(x, y + 1) || !wallSolid(x - 1, y) || !wallSolid(x + 1, y); } - public Map getMap(){ - return currentMap; - } - - public void setMap(Map map){ - this.currentMap = map; - } - public int width(){ return tiles.width; } @@ -214,7 +205,7 @@ public class World{ } public void loadSector(Sector sector){ - currentMap = new Map(StringMap.of("name", sector.planet.localizedName + "; Sector " + sector.id)); + state.map = new Map(StringMap.of("name", sector.planet.localizedName + "; Sector " + sector.id)); state.rules.sector = sector; int size = sector.getSize(); loadGenerator(size, size, tiles -> sector.planet.generator.generate(tiles, sector)); @@ -238,7 +229,7 @@ public class World{ return; } - this.currentMap = map; + state.map = map; invalidMap = false; diff --git a/core/src/mindustry/editor/MapEditorDialog.java b/core/src/mindustry/editor/MapEditorDialog.java index 48d6fe7845..57003e2e3b 100644 --- a/core/src/mindustry/editor/MapEditorDialog.java +++ b/core/src/mindustry/editor/MapEditorDialog.java @@ -247,11 +247,11 @@ public class MapEditorDialog extends Dialog implements Disposable{ player.reset(); state.rules = Gamemode.editor.apply(lastSavedRules.copy()); state.rules.sector = null; - world.setMap(new Map(StringMap.of( - "name", "Editor Playtesting", - "width", editor.width(), - "height", editor.height() - ))); + state.map = new Map(StringMap.of( + "name", "Editor Playtesting", + "width", editor.width(), + "height", editor.height() + )); world.endMapLoad(); //add entities so they update. is this really needed? for(Tile tile : world.tiles){ diff --git a/core/src/mindustry/io/SaveVersion.java b/core/src/mindustry/io/SaveVersion.java index be1c04175e..fa71dbda4e 100644 --- a/core/src/mindustry/io/SaveVersion.java +++ b/core/src/mindustry/io/SaveVersion.java @@ -62,7 +62,7 @@ public abstract class SaveVersion extends SaveFileReader{ "saved", Time.millis(), "playtime", headless ? 0 : control.saves.getTotalPlaytime(), "build", Version.build, - "mapname", world.getMap() == null ? "unknown" : world.getMap().name(), + "mapname", state.map.name(), "wave", state.wave, "wavetime", state.wavetime, "stats", JsonIO.write(state.stats), @@ -84,11 +84,12 @@ public abstract class SaveVersion extends SaveFileReader{ lastReadBuild = map.getInt("build", -1); Map worldmap = maps.byName(map.get("mapname", "\\\\\\")); - world.setMap(worldmap == null ? new Map(StringMap.of( + Map map1 = worldmap == null ? new Map(StringMap.of( "name", map.get("mapname", "Unknown"), "width", 1, "height", 1 - )) : worldmap); + )) : worldmap; + state.map = map1; } public void writeMap(DataOutput stream) throws IOException{ diff --git a/core/src/mindustry/maps/generators/FileMapGenerator.java b/core/src/mindustry/maps/generators/FileMapGenerator.java index 653c8a64a9..d299a2604c 100644 --- a/core/src/mindustry/maps/generators/FileMapGenerator.java +++ b/core/src/mindustry/maps/generators/FileMapGenerator.java @@ -22,6 +22,7 @@ public class FileMapGenerator implements WorldGenerator{ @Override public void generate(Tiles tiles){ + if(true) throw new IllegalArgumentException("no!"); tiles.fill(); SaveIO.load(map.file); @@ -60,6 +61,6 @@ public class FileMapGenerator implements WorldGenerator{ } world.prepareTiles(tiles); - world.setMap(map); + state.map = map; } } diff --git a/core/src/mindustry/net/ArcNetProvider.java b/core/src/mindustry/net/ArcNetProvider.java index 1ed6713e93..0d458621b0 100644 --- a/core/src/mindustry/net/ArcNetProvider.java +++ b/core/src/mindustry/net/ArcNetProvider.java @@ -58,7 +58,7 @@ public class ArcNetProvider implements NetProvider{ Core.app.post(() -> { try{ net.handleClientReceived(object); - }catch(Exception e){ + }catch(Throwable e){ handleException(e); } }); @@ -113,9 +113,7 @@ public class ArcNetProvider implements NetProvider{ Core.app.post(() -> { try{ net.handleServerReceived(k, object); - }catch(RuntimeException e){ - e.printStackTrace(); - }catch(Exception e){ + }catch(Throwable e){ e.printStackTrace(); } }); @@ -267,7 +265,7 @@ public class ArcNetProvider implements NetProvider{ return null; } - private void handleException(Exception e){ + private void handleException(Throwable e){ if(e instanceof ArcNetException){ Core.app.post(() -> net.showError(new IOException("mismatch"))); }else if(e instanceof ClosedChannelException){ diff --git a/core/src/mindustry/net/NetworkIO.java b/core/src/mindustry/net/NetworkIO.java index 0c6a435343..55cc6fc364 100644 --- a/core/src/mindustry/net/NetworkIO.java +++ b/core/src/mindustry/net/NetworkIO.java @@ -21,7 +21,7 @@ public class NetworkIO{ try(DataOutputStream stream = new DataOutputStream(os)){ stream.writeUTF(JsonIO.write(state.rules)); - SaveIO.getSaveWriter().writeStringMap(stream, world.getMap().tags); + SaveIO.getSaveWriter().writeStringMap(stream, state.map.tags); stream.writeInt(state.wave); stream.writeFloat(state.wavetime); @@ -41,7 +41,7 @@ public class NetworkIO{ try(DataInputStream stream = new DataInputStream(is)){ Time.clear(); state.rules = JsonIO.read(Rules.class, stream.readUTF()); - world.setMap(new Map(SaveIO.getSaveWriter().readStringMap(stream))); + state.map = new Map(SaveIO.getSaveWriter().readStringMap(stream)); state.wave = stream.readInt(); state.wavetime = stream.readFloat(); @@ -65,7 +65,7 @@ public class NetworkIO{ public static ByteBuffer writeServerData(){ String name = (headless ? Config.name.string() : player.name()); String description = headless && !Config.desc.string().equals("off") ? Config.desc.string() : ""; - String map = world.getMap() == null ? "None" : world.getMap().name(); + String map = state.map.name(); ByteBuffer buffer = ByteBuffer.allocate(512); diff --git a/core/src/mindustry/ui/dialogs/GameOverDialog.java b/core/src/mindustry/ui/dialogs/GameOverDialog.java index a012b6c7a0..39a324d13d 100644 --- a/core/src/mindustry/ui/dialogs/GameOverDialog.java +++ b/core/src/mindustry/ui/dialogs/GameOverDialog.java @@ -1,12 +1,11 @@ package mindustry.ui.dialogs; import arc.*; -import mindustry.core.GameState.*; -import mindustry.game.*; import mindustry.game.EventType.*; import mindustry.game.Stats.*; +import mindustry.game.*; import mindustry.type.*; -import mindustry.ui.Cicon; +import mindustry.ui.*; import static mindustry.Vars.*; @@ -40,7 +39,6 @@ public class GameOverDialog extends FloatingDialog{ cont.add(Core.bundle.format("gameover.pvp", winner.localized())).pad(6); buttons.addButton("$menu", () -> { hide(); - state.set(State.menu); logic.reset(); }).size(130f, 60f); }else{ @@ -90,14 +88,12 @@ public class GameOverDialog extends FloatingDialog{ if(state.isCampaign()){ buttons.addButton("$continue", () -> { hide(); - state.set(State.menu); logic.reset(); ui.planet.show(); }).size(130f, 60f); }else{ buttons.addButton("$menu", () -> { hide(); - state.set(State.menu); logic.reset(); }).size(130f, 60f); } diff --git a/core/src/mindustry/ui/dialogs/LoadDialog.java b/core/src/mindustry/ui/dialogs/LoadDialog.java index e2895f1a92..8765b85f36 100644 --- a/core/src/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/mindustry/ui/dialogs/LoadDialog.java @@ -178,7 +178,6 @@ public class LoadDialog extends FloatingDialog{ state.set(State.playing); }catch(SaveException e){ Log.err(e); - state.set(State.menu); logic.reset(); ui.showErrorMessage("$save.corrupted"); } diff --git a/core/src/mindustry/ui/dialogs/PausedDialog.java b/core/src/mindustry/ui/dialogs/PausedDialog.java index 62ce1e2a0d..8c5865851c 100644 --- a/core/src/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/mindustry/ui/dialogs/PausedDialog.java @@ -2,7 +2,6 @@ package mindustry.ui.dialogs; import arc.*; import arc.input.*; -import mindustry.core.GameState.*; import mindustry.gen.*; import static mindustry.Vars.*; @@ -118,7 +117,6 @@ public class PausedDialog extends FloatingDialog{ } if(control.saves.getCurrent() == null || !control.saves.getCurrent().isAutosave() || state.rules.tutorial || wasClient){ - state.set(State.menu); logic.reset(); return; } @@ -130,7 +128,6 @@ public class PausedDialog extends FloatingDialog{ e.printStackTrace(); ui.showException("[accent]" + Core.bundle.get("savefail"), e); } - state.set(State.menu); logic.reset(); }); } diff --git a/desktop/src/mindustry/desktop/DesktopLauncher.java b/desktop/src/mindustry/desktop/DesktopLauncher.java index c9c446bce3..377eea4427 100644 --- a/desktop/src/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/mindustry/desktop/DesktopLauncher.java @@ -248,10 +248,9 @@ public class DesktopLauncher extends ClientLauncher{ String uiState = ""; if(inGame){ - if(world.getMap() != null){ - //TODO implement nice name for sector - gameMapWithWave = Strings.capitalize(world.getMap().name()); - } + //TODO implement nice name for sector + gameMapWithWave = Strings.capitalize(state.map.name()); + if(state.rules.waves){ gameMapWithWave += " | Wave " + state.wave; } diff --git a/desktop/src/mindustry/desktop/steam/SNet.java b/desktop/src/mindustry/desktop/steam/SNet.java index f8f82a8092..82e55d246a 100644 --- a/desktop/src/mindustry/desktop/steam/SNet.java +++ b/desktop/src/mindustry/desktop/steam/SNet.java @@ -9,7 +9,6 @@ import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.SteamFriends.*; import com.codedisaster.steamworks.SteamMatchmaking.*; import com.codedisaster.steamworks.SteamNetworking.*; -import mindustry.core.GameState.*; import mindustry.core.*; import mindustry.game.EventType.*; import mindustry.game.*; @@ -242,7 +241,6 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback, logic.reset(); net.reset(); - state.set(State.menu); currentLobby = steamIDLobby; currentServer = smat.getLobbyOwner(steamIDLobby); @@ -346,7 +344,7 @@ public class SNet implements SteamNetworkingCallback, SteamMatchmakingCallback, currentLobby = steamID; smat.setLobbyData(steamID, "name", player.name()); - smat.setLobbyData(steamID, "mapname", world.getMap().name()); + smat.setLobbyData(steamID, "mapname", state.map.name()); smat.setLobbyData(steamID, "version", Version.build + ""); smat.setLobbyData(steamID, "versionType", Version.type); smat.setLobbyData(steamID, "wave", state.wave + ""); diff --git a/gradle.properties b/gradle.properties index 2e10589d8c..63704699ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=463da29cdf7fb64526c06852a10c750a2dbc48d3 +archash=1b96f9149cce63e7c4b72b5798c58e8f62b1f185 diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index fd9efed173..e831ffef3a 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -11,7 +11,6 @@ import arc.util.CommandHandler.*; import arc.util.Timer.*; import arc.util.serialization.*; import arc.util.serialization.JsonValue.*; -import mindustry.*; import mindustry.core.GameState.*; import mindustry.core.*; import mindustry.game.EventType.*; @@ -129,13 +128,13 @@ public class ServerControl implements ApplicationListener{ Events.on(GameOverEvent.class, event -> { if(inExtraRound) return; if(state.rules.waves){ - info("&lcGame over! Reached wave &ly{0}&lc with &ly{1}&lc players online on map &ly{2}&lc.", state.wave, Groups.player.size(), Strings.capitalize(world.getMap().name())); + info("&lcGame over! Reached wave &ly{0}&lc with &ly{1}&lc players online on map &ly{2}&lc.", state.wave, Groups.player.size(), Strings.capitalize(state.map.name())); }else{ - info("&lcGame over! Team &ly{0}&lc is victorious with &ly{1}&lc players online on map &ly{2}&lc.", event.winner.name, Groups.player.size(), Strings.capitalize(world.getMap().name())); + info("&lcGame over! Team &ly{0}&lc is victorious with &ly{1}&lc players online on map &ly{2}&lc.", event.winner.name, Groups.player.size(), Strings.capitalize(state.map.name())); } //set next map to be played - Map map = nextMapOverride != null ? nextMapOverride : maps.getNextMap(world.getMap()); + Map map = nextMapOverride != null ? nextMapOverride : maps.getNextMap(state.map); nextMapOverride = null; if(map != null){ Call.onInfoMessage((state.rules.pvp @@ -220,8 +219,7 @@ public class ServerControl implements ApplicationListener{ return; } }else{ - Array maps = Vars.maps.customMaps().size == 0 ? Vars.maps.defaultMaps() : Vars.maps.customMaps(); - result = maps.random(); + result = maps.getShuffleMode().next(state.map); info("Randomized next map to be {0}.", result.name()); } @@ -280,7 +278,7 @@ public class ServerControl implements ApplicationListener{ info("Status: &rserver closed"); }else{ info("Status:"); - info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name()), state.wave); + info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(state.map.name()), state.wave); if(state.rules.waves){ info("&ly {0} enemies.", state.enemies); @@ -884,7 +882,7 @@ public class ServerControl implements ApplicationListener{ Call.onWorldDataBegin(); run.run(); - state.rules = world.getMap().applyRules(lastMode); + state.rules = state.map.applyRules(lastMode); logic.play(); for(Playerc p : players){ diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index b7bfe1bf91..2c0607c38b 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -201,7 +201,7 @@ public class ApplicationTests{ @Test void load(){ world.loadMap(testMap); - Map map = world.getMap(); + Map map = state.map; SaveIO.save(saveDirectory.child("0.msav")); resetWorld(); diff --git a/tools/build.gradle b/tools/build.gradle index 6159c9e9e0..760734ba61 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -171,9 +171,9 @@ def scaleImage = { File file -> M = getRGB(x, y - 2) if(B == D && B != F && D != H && (E != A || E == C || E == G || A == J || A == K)) p1 = B - if(B == F & B != D & F != H && (E != C || E == A || E == I || C == J || C == L)) p2 = F - if(D == H & B != D & F != H && (E != G || E == A || E == I || G == K || G == M)) p3 = D - if(F == H & B != F & D != H && (E != I || E == C || E == G || I == L || I == M)) p4 = H + if(B == F && B != D && F != H && (E != C || E == A || E == I || C == J || C == L)) p2 = F + if(D == H && B != D && F != H && (E != G || E == A || E == I || G == K || G == M)) p3 = D + if(F == H && B != F && D != H && (E != I || E == C || E == G || I == L || I == M)) p4 = H scaled.setRGB(x * 2, y * 2 + 1, p1) scaled.setRGB(x * 2 + 1, y * 2 + 1, p2)