From af91979d4c6547d4d20a28878d2dc8c49650a5ea Mon Sep 17 00:00:00 2001 From: Franciszek Zaranowicz <30700722+Natchuz@users.noreply.github.com> Date: Sat, 20 Apr 2019 20:19:17 +0200 Subject: [PATCH] New custom games and custom rules screen (#464) * New waves and limited respawning option. Added ability to manipulate number of respawns per wave. Added option to hold counting for next wave until all enemies are destroyed * Critical bug fixed Fixed frozen wave timer when rules.waitForWaveToEnd was enabled * Requested changes * Missed Import * New custom game and custom rules screen RulePreset is now a Gamemode (because each of them has a different goal). New button under Gamemode selection which opens a dialog to modify rules of gamemode. Now without any mutually exclusive options * Requested changes * Applied some text sugestions * Wrong waveInProgress message displaying fixed * Unwanted text * Text changes * I broke git * Fixed chrash * More fixes New rule : manyCores; needed for sanbox mode * Visual fix * Requested changes #1 : small oversights * Moved respawning logic to Player and another imports cleanup * manyCores in now attackMode * UI changes * Given back waves to sandbox and integer input in custom rules * Renamed functions in CustomRulesScreen * SPACES... Actually one space... --- core/assets/bundles/bundle.properties | 18 ++- core/src/io/anuke/mindustry/core/Logic.java | 10 +- core/src/io/anuke/mindustry/core/World.java | 2 +- .../anuke/mindustry/entities/type/Player.java | 10 +- .../game/{RulePreset.java => Gamemode.java} | 8 +- core/src/io/anuke/mindustry/game/Rules.java | 8 ++ .../ui/dialogs/CustomGameDialog.java | 44 +++--- .../ui/dialogs/CustomRulesDialog.java | 125 +++++++++++++----- .../mindustry/ui/fragments/HudFragment.java | 2 +- .../anuke/mindustry/server/ServerControl.java | 4 +- 10 files changed, 161 insertions(+), 70 deletions(-) rename core/src/io/anuke/mindustry/game/{RulePreset.java => Gamemode.java} (90%) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 807523d577..b5a0ed4678 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -158,6 +158,7 @@ confirm = Confirm delete = Delete ok = OK open = Open +customize = Customize cancel = Cancel openlink = Open Link copylink = Copy Link @@ -174,6 +175,7 @@ loading = [accent]Loading... saving = [accent]Saving... wave = [accent]Wave {0} wave.waiting = [LIGHT_GRAY]Wave in {0} +wave.waveInProgress = [LIGHT_GRAY]Wave in progress waiting = [LIGHT_GRAY]Waiting... waiting.players = Waiting for players... wave.enemies = [LIGHT_GRAY]{0} Enemies Remaining @@ -496,21 +498,18 @@ mode.survival.name = Survival mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandbox mode.sandbox.description = Infinite resources and no timer for waves. -mode.freebuild.name = Freebuild -mode.freebuild.description = Limited resources and no timer for waves. mode.pvp.name = PvP mode.pvp.description = Fight against other players locally. mode.attack.name = Attack -mode.attack.description = No waves, with the goal to destroy the enemy base. +mode.attack.description = Destroy the enemy's base. No waves. mode.custom = Custom Rules rules.infiniteresources = Infinite Resources rules.wavetimer = Wave Timer rules.waves = Waves rules.enemyCheat = Infinite AI (Red Team) Resources -rules.pvp = PvP rules.unitdrops = Unit Drops -rules.unitbuildspeedmultiplier = Unit Creation Speed Multiplier +rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier rules.unithealthmultiplier = Unit Health Multiplier rules.playerhealthmultiplier = Player Health Multiplier rules.playerdamagemultiplier = Player Damage Multiplier @@ -520,6 +519,15 @@ rules.respawntime = Respawn Time:[LIGHT_GRAY] (sec) rules.wavespacing = Wave Spacing:[LIGHT_GRAY] (sec) rules.buildcostmultiplier = Build Cost Multiplier rules.buildspeedmultiplier = Build Speed Multiplier +rules.waitForWaveToEnd = Waves wait for enemies +rules.respawns = Max respawns per wave +rules.limitedRespawns = Limit Respawns +rules.title.waves = Waves +rules.title.respawns = Respawns +rules.title.resourcesbuilding = Resources & Building +rules.title.player = Players +rules.title.enemy = Enemies +rules.title.unit = Units content.item.name = Items content.liquid.name = Liquids diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index a450acf61c..c9ed00eeb6 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -9,6 +9,7 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.*; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.*; @@ -33,6 +34,9 @@ public class Logic implements ApplicationListener{ if(world.isZone()){ world.getZone().updateWave(state.wave); } + for (Player p : playerGroup.all()) { + p.respawns = state.rules.respawns; + } }); } @@ -88,7 +92,7 @@ public class Logic implements ApplicationListener{ if(state.rules.waves && state.teams.get(defaultTeam).cores.size == 0 && !state.gameOver){ state.gameOver = true; Events.fire(new GameOverEvent(waveTeam)); - }else if(!state.rules.waves){ + }else if(state.rules.attackMode){ Team alive = null; for(Team team : Team.all){ @@ -144,7 +148,9 @@ public class Logic implements ApplicationListener{ Time.update(); if(state.rules.waves && state.rules.waveTimer && !state.gameOver){ - state.wavetime = Math.max(state.wavetime - Time.delta(), 0); + if(!state.rules.waitForWaveToEnd || unitGroups[waveTeam.ordinal()].size() == 0){ + state.wavetime = Math.max(state.wavetime - Time.delta(), 0); + } } if(!Net.client() && state.wavetime <= 0 && state.rules.waves){ diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index af3ac67537..b4f5c0b59e 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -263,7 +263,7 @@ public class World implements ApplicationListener{ if(invalidMap){ ui.showError("$map.nospawn.pvp"); } - }else if(!state.rules.waves){ //pvp maps need two cores to be valid + }else if(state.rules.attackMode){ //pvp maps need two cores to be valid invalidMap = state.teams.get(waveTeam).cores.isEmpty(); if(invalidMap){ ui.showError("$map.nospawn.attack"); diff --git a/core/src/io/anuke/mindustry/entities/type/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java index 922d4bd4ce..5f05396bd0 100644 --- a/core/src/io/anuke/mindustry/entities/type/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -54,6 +54,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ public Color color = new Color(); public Mech mech; public SpawnerTrait spawner, lastSpawner; + public int respawns; public NetConnection con; public boolean isLocal = false; @@ -103,6 +104,9 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ public void onRespawn(Tile tile){ boostHeat = 1f; achievedFlight = true; + if(state.rules.limitedRespawns){ + respawns--; + } } @Override @@ -489,7 +493,6 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ @Override public void update(){ - hitTime -= Time.delta(); if(Float.isNaN(x) || Float.isNaN(y)){ @@ -516,7 +519,9 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ if(isDead()){ isBoosting = false; boostHeat = 0f; - updateRespawning(); + if(respawns!=0){ + updateRespawning(); + } return; }else{ spawner = null; @@ -777,6 +782,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{ boostHeat = drownTime = hitTime = 0f; mech = getStarterMech(); placeQueue.clear(); + respawns = state.rules.respawns; } public Mech getStarterMech(){ diff --git a/core/src/io/anuke/mindustry/game/RulePreset.java b/core/src/io/anuke/mindustry/game/Gamemode.java similarity index 90% rename from core/src/io/anuke/mindustry/game/RulePreset.java rename to core/src/io/anuke/mindustry/game/Gamemode.java index 4968f24db3..4211e1fcf9 100644 --- a/core/src/io/anuke/mindustry/game/RulePreset.java +++ b/core/src/io/anuke/mindustry/game/Gamemode.java @@ -4,7 +4,7 @@ import io.anuke.arc.Core; import io.anuke.arc.function.Supplier; /** Defines preset rule sets.. */ -public enum RulePreset{ +public enum Gamemode{ survival(() -> new Rules(){{ waveTimer = true; waves = true; @@ -16,11 +16,12 @@ public enum RulePreset{ waves = true; waveTimer = false; respawnTime = 0f; - spawns = DefaultWaves.get(); }}), attack(() -> new Rules(){{ enemyCheat = true; unitDrops = true; + waves = false; + attackMode = true; }}), pvp(() -> new Rules(){{ pvp = true; @@ -32,11 +33,12 @@ public enum RulePreset{ playerHealthMultiplier = 0.8f; unitBuildSpeedMultiplier = 3f; unitHealthMultiplier = 2f; + attackMode = true; }}); private final Supplier rules; - RulePreset(Supplier rules){ + Gamemode(Supplier rules){ this.rules = rules; } diff --git a/core/src/io/anuke/mindustry/game/Rules.java b/core/src/io/anuke/mindustry/game/Rules.java index 44db4aabdf..22af97fc9a 100644 --- a/core/src/io/anuke/mindustry/game/Rules.java +++ b/core/src/io/anuke/mindustry/game/Rules.java @@ -45,4 +45,12 @@ public class Rules{ public byte zone = -1; /** Spawn layout. Since only zones modify this, it should be assigned on save load. */ public transient Array spawns = DefaultWaves.get(); + /** Determines if there should be limited respawns. */ + public boolean limitedRespawns = false; + /** How many times player can respawn during one wave. */ + public int respawns = 5; + /** Hold wave timer until all enemies are destroyed. */ + public boolean waitForWaveToEnd = false; + /** Determinates if gamemode is attack mode */ + public boolean attackMode = false; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java index aa0c22c37e..06edc28521 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java @@ -4,12 +4,16 @@ import io.anuke.arc.Core; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.scene.event.Touchable; -import io.anuke.arc.scene.ui.*; +import io.anuke.arc.scene.ui.ButtonGroup; +import io.anuke.arc.scene.ui.ImageButton; +import io.anuke.arc.scene.ui.ScrollPane; +import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Align; import io.anuke.arc.util.Scaling; import io.anuke.mindustry.game.Difficulty; -import io.anuke.mindustry.game.RulePreset; +import io.anuke.mindustry.game.Gamemode; +import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.ui.BorderImage; @@ -17,21 +21,21 @@ import static io.anuke.mindustry.Vars.*; public class CustomGameDialog extends FloatingDialog{ Difficulty difficulty = Difficulty.normal; - RulePreset lastPreset = RulePreset.survival; CustomRulesDialog dialog = new CustomRulesDialog(); + Rules rules; + Gamemode selectedGamemode; public CustomGameDialog(){ super("$customgame"); addCloseButton(); shown(this::setup); - onResize(this::setup); } void setup(){ - if(lastPreset == null){ - lastPreset = RulePreset.survival; - } + selectedGamemode = Gamemode.survival; + rules = selectedGamemode.get(); + cont.clear(); Table maps = new Table(); @@ -48,21 +52,17 @@ public class CustomGameDialog extends FloatingDialog{ int i = 0; Table modes = new Table(); - modes.marginBottom(5); - for(RulePreset mode : RulePreset.values()){ + for(Gamemode mode : Gamemode.values()){ modes.addButton(mode.toString(), "toggle", () -> { - lastPreset = mode; - }).update(b -> b.setChecked(lastPreset == mode)).group(group).size(140f, 54f); + selectedGamemode = mode; + rules = mode.get(); + dialog.selectedGamemode = null; + dialog.rules = null; + }).update(b -> b.setChecked(selectedGamemode == mode)).group(group).size(140f, 54f); if(i++ % 2 == 1) modes.row(); } selmode.add(modes); - selmode.addButton("$mode.custom", "toggle", () -> { - }) - .update(b -> b.setChecked(lastPreset == null)).size(108f).group(group).get().tapped(() -> { - lastPreset = null; - dialog.show(); - }); selmode.addButton("?", this::displayGameModeHelp).width(50f).fillY().padLeft(18f); cont.add(selmode); @@ -93,8 +93,9 @@ public class CustomGameDialog extends FloatingDialog{ difficulty = (ds[Mathf.mod(difficulty.ordinal() + 1, ds.length)]); state.wavetime = difficulty.waveTime; }).width(s); + sdif.addButton("$customize", () -> dialog.show(rules, selectedGamemode)).width(140).padLeft(10); - cont.add(sdif).visible(() -> lastPreset != null); + cont.add(sdif); cont.row(); float images = 146f; @@ -122,7 +123,7 @@ public class CustomGameDialog extends FloatingDialog{ image.clicked(() -> { hide(); - control.playMap(map, lastPreset == null ? dialog.rules : lastPreset.get()); + control.playMap(map, (dialog.rules == null) ? rules : dialog.rules); }); maps.add(image); @@ -145,7 +146,7 @@ public class CustomGameDialog extends FloatingDialog{ ScrollPane pane = new ScrollPane(table); pane.setFadeScrollBars(false); table.row(); - for(RulePreset mode : RulePreset.values()){ + for(Gamemode mode : Gamemode.values()){ table.labelWrap("[accent]" + mode.toString() + ":[] [lightgray]" + mode.description()).width(400f); table.row(); } @@ -154,5 +155,4 @@ public class CustomGameDialog extends FloatingDialog{ d.buttons.addButton("$ok", d::hide).size(110, 50).pad(10f); d.show(); } - -} +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java index 2b8073eff7..624d4d38fe 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/CustomRulesDialog.java @@ -1,67 +1,128 @@ package io.anuke.mindustry.ui.dialogs; +import io.anuke.arc.function.BooleanConsumer; +import io.anuke.arc.function.BooleanProvider; import io.anuke.arc.function.FloatConsumer; import io.anuke.arc.function.FloatProvider; +import io.anuke.arc.graphics.Color; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Strings; +import io.anuke.arc.util.Structs; import io.anuke.mindustry.core.Platform; +import io.anuke.mindustry.game.Gamemode; import io.anuke.mindustry.game.Rules; +import io.anuke.mindustry.graphics.Pal; import static io.anuke.mindustry.Vars.tilesize; public class CustomRulesDialog extends FloatingDialog{ - public final Rules rules = new Rules(); private Table main; + public Rules rules; + public Gamemode selectedGamemode; public CustomRulesDialog(){ super("$mode.custom"); - rules.waves = true; - rules.waveTimer = true; - setFillParent(true); shown(this::setup); addCloseButton(); } + public void show(Rules rules, Gamemode gamemode){ + this.rules = rules; + this.selectedGamemode = gamemode; + show(); + } + void setup(){ cont.clear(); cont.pane(m -> main = m); main.margin(10f); - + main.addButton("$settings.reset", () -> {rules = selectedGamemode.get(); setup();}).size(300f, 50f); main.left().defaults().fillX().left().pad(5); main.row(); - main.addCheck("$rules.infiniteresources", b -> rules.infiniteResources = b).checked(b -> rules.infiniteResources); - main.row(); - main.addCheck("$rules.wavetimer", b -> rules.waveTimer = b).checked(b -> rules.waveTimer); - main.row(); - main.addCheck("$rules.waves", b -> rules.waves = b).checked(b -> rules.waves); - main.row(); - main.addCheck("$rules.pvp", b -> rules.pvp = b).checked(b -> rules.pvp); - main.row(); - main.addCheck("$rules.unitdrops", b -> rules.unitDrops = b).checked(b -> rules.unitDrops); - main.row(); - number("$rules.buildcostmultiplier", f -> rules.buildCostMultiplier = f, () -> rules.buildCostMultiplier); - number("$rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier); - number("$rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier); - number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier); - number("$rules.playerhealthmultiplier", f -> rules.playerHealthMultiplier = f, () -> rules.playerHealthMultiplier); - number("$rules.playerdamagemultiplier", f -> rules.playerDamageMultiplier = f, () -> rules.playerDamageMultiplier); - number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier); - number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200)); - number("$rules.respawntime", f -> rules.respawnTime = f * 60f, () -> rules.respawnTime / 60f); - number("$rules.wavespacing", f -> rules.waveSpacing = f * 60f, () -> rules.waveSpacing / 60f); + title("$rules.title.waves", Gamemode.survival, Gamemode.sandbox); + check("$rules.waves", b -> rules.waves = b, () -> rules.waves, ()->selectedGamemode!=Gamemode.survival, Gamemode.survival, Gamemode.sandbox); + check("$rules.wavetimer", b -> rules.waveTimer = b, () -> rules.waveTimer, ()->rules.waves, Gamemode.survival, Gamemode.sandbox); + check("$rules.waitForWaveToEnd", b -> rules.waitForWaveToEnd = b, () -> rules.waitForWaveToEnd, ()->rules.waves, Gamemode.survival, Gamemode.sandbox); + number("$rules.wavespacing", f -> rules.waveSpacing = f * 60f, () -> rules.waveSpacing / 60f, ()->rules.waves, Gamemode.survival, Gamemode.sandbox); + title("$rules.title.respawns"); + check("$rules.limitedRespawns", b -> rules.limitedRespawns= b, () -> rules.limitedRespawns, ()->true); + integer("$rules.respawns", f -> rules.respawns = (int) f, () -> rules.respawns, ()->rules.limitedRespawns); + number("$rules.respawntime", f -> rules.respawnTime = f * 60f, () -> rules.respawnTime / 60f, ()->true); + title("$rules.title.resourcesbuilding", Gamemode.attack, Gamemode.pvp, Gamemode.survival, Gamemode.sandbox); + check("$rules.infiniteresources", b -> rules.infiniteResources = b, () -> rules.infiniteResources, ()->true, Gamemode.attack, Gamemode.pvp, Gamemode.survival, Gamemode.sandbox); + number("$rules.buildcostmultiplier", f -> rules.buildCostMultiplier = f, () -> rules.buildCostMultiplier, ()->!rules.infiniteResources, Gamemode.attack, Gamemode.pvp, Gamemode.survival, Gamemode.sandbox); + number("$rules.buildspeedmultiplier", f -> rules.buildSpeedMultiplier = f, () -> rules.buildSpeedMultiplier, ()->true, Gamemode.attack, Gamemode.pvp, Gamemode.survival, Gamemode.sandbox); + title("$rules.title.player"); + number("$rules.playerdamagemultiplier", f -> rules.playerDamageMultiplier = f, () -> rules.playerDamageMultiplier, ()->true); + number("$rules.playerhealthmultiplier", f -> rules.playerHealthMultiplier = f, () -> rules.playerHealthMultiplier, ()-> true); + title("$rules.title.unit"); + check("$rules.unitdrops", b -> rules.unitDrops = b, () -> rules.unitDrops, ()->true); + number("$rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, ()->true); + number("$rules.unithealthmultiplier", f -> rules.unitHealthMultiplier = f, () -> rules.unitHealthMultiplier, ()->true); + number("$rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier, ()->true); + title("$rules.title.enemy", Gamemode.attack, Gamemode.pvp); + number("$rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200), ()->true, Gamemode.attack, Gamemode.pvp); } - void number(String text, FloatConsumer cons, FloatProvider prov){ + void number(String text, FloatConsumer cons, FloatProvider prov, BooleanProvider condition){ main.table(t -> { t.left(); - t.add(text).left().padRight(5); + t.add(text).left().padRight(5) + .update(a->a.setColor(condition.get() ? Color.WHITE : Color.GRAY)); Platform.instance.addDialog(t.addField(prov.get() + "", s -> cons.accept(Strings.parseFloat(s))) - .valid(Strings::canParsePositiveFloat).width(120f).left().get()); - }); - + .padRight(100f) + .update(a -> a.setDisabled(!condition.get())) + .valid(Strings::canParsePositiveFloat).width(120f) .left().get()); + }).padTop(0); main.row(); - } -} + + void number(String text, FloatConsumer cons, FloatProvider prov, BooleanProvider condition, Gamemode... gamemodes){ + if(Structs.contains(gamemodes, selectedGamemode)){ + number(text, cons, prov, condition); + } + } + + void integer(String text, FloatConsumer cons, FloatProvider prov, BooleanProvider condition){ + main.table(t -> { + t.left(); + t.add(text).left().padRight(5) + .update(a->a.setColor(condition.get() ? Color.WHITE : Color.GRAY)); + Platform.instance.addDialog(t.addField(((int) prov.get()) + "", s -> cons.accept(Strings.parseFloat(s))) + .padRight(100f) + .update(a -> a.setDisabled(!condition.get())) + .valid(Strings::canParsePostiveInt).width(120f) .left().get()); + }).padTop(0); + main.row(); + } + + void integer(String text, FloatConsumer cons, FloatProvider prov, BooleanProvider condition, Gamemode... gamemodes){ + if(Structs.contains(gamemodes, selectedGamemode)){ + integer(text, cons, prov, condition); + } + } + + void check(String text, BooleanConsumer cons, BooleanProvider prov, BooleanProvider condition){ + main.addCheck(text, cons).checked(prov.get()).update(a -> a.setDisabled(!condition.get())).padRight(100f); + main.row(); + } + + void check(String text, BooleanConsumer cons, BooleanProvider prov, BooleanProvider condition, Gamemode... gamemodes){ + if(Structs.contains(gamemodes, selectedGamemode)){ + check(text, cons, prov, condition); + } + } + + void title(String text, Gamemode... gamemodes){ + if(Structs.contains(gamemodes, selectedGamemode)){ + title(text); + } + } + + void title(String text){ + main.add(text).color(Pal.accent).padTop(20).padBottom(20).padRight(100f); + main.row(); + } +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index ef847fb53e..fa294a642a 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -459,7 +459,7 @@ public class HudFragment extends Fragment{ } if(state.rules.waveTimer){ - builder.append(waitingf.get((int)(state.wavetime / 60))); + builder.append((state.rules.waitForWaveToEnd && unitGroups[waveTeam.ordinal()].size() > 0) ? Core.bundle.get("wave.waveInProgress") : ( waitingf.get((int)(state.wavetime/60)))); }else if(state.enemies() == 0){ builder.append(Core.bundle.get("waiting")); } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 323a6bde73..a0c739692c 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -204,11 +204,11 @@ public class ServerControl implements ApplicationListener{ return; } - RulePreset preset = RulePreset.survival; + Gamemode preset = Gamemode.survival; if(arg.length > 1){ try{ - preset = RulePreset.valueOf(arg[1]); + preset = Gamemode.valueOf(arg[1]); }catch(IllegalArgumentException e){ err("No gamemode '{0}' found.", arg[1]); return;