diff --git a/core/assets-raw/sprites/ui/icons/controller-cursor.png b/core/assets-raw/sprites/ui/icons/controller-cursor.png new file mode 100644 index 0000000000..0fed7f4245 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/controller-cursor.png differ diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml index bb7603f2f8..fbf60c0299 100644 --- a/core/src/Mindustry.gwt.xml +++ b/core/src/Mindustry.gwt.xml @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index d057fb03d7..b1fe6f1961 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -30,9 +30,9 @@ public class Vars{ //discord group URL public static final String discordURL = "https://discord.gg/r8BkXNd"; //directory for user-created map data - public static final FileHandle customMapDirectory = Gdx.files.local("mindustry-maps/"); + public static final FileHandle customMapDirectory = gwt ? null : Gdx.files.local("mindustry-maps/"); //save file directory - public static final FileHandle saveDirectory = Gdx.files.local("mindustry-saves/"); + public static final FileHandle saveDirectory = gwt ? null : Gdx.files.local("mindustry-saves/"); //scale of the font public static float fontscale = Math.max(Unit.dp.scl(1f)/2f, 0.5f); //camera zoom displayed on startup diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index fb34df8c09..1513ba7ce8 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -237,7 +237,7 @@ public class Control extends Module{ //multiplying by 2 so you start with more time in the beginning wavetime = waveSpacing()*2; - if(mode == GameMode.sandbox){ + if(mode.infiniteResources){ Arrays.fill(items, 999999999); } @@ -347,7 +347,7 @@ public class Control extends Module{ int last = Settings.getInt("hiscore" + world.getMap().name); - if(wave > last && mode != GameMode.sandbox){ + if(wave > last && !mode.infiniteResources && !mode.toggleWaves){ Settings.putInt("hiscore" + world.getMap().name, wave); Settings.save(); hiscore = true; @@ -622,7 +622,7 @@ public class Control extends Module{ tutorial.update(); } - if(!tutorial.active() && mode != GameMode.sandbox){ + if(!tutorial.active() && !mode.toggleWaves){ if(enemies <= 0){ wavetime -= delta(); diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 367e5f5509..087ab3c03b 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -152,7 +152,7 @@ public class Renderer extends RendererModule{ camera.position.set(lastx - deltax, lasty - deltay, 0); - record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't + if(Vars.debug) record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't } } FrameBuffer buffer = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 345b37ec86..619fbc86ba 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -51,7 +51,7 @@ public class UI extends SceneModule{ Tooltip tooltip; Tile configTile; Array statlist = new Array<>(); - MapEditor editor = new MapEditor(); + MapEditor editor; boolean wasPaused = false; private Fragment blockfrag = new BlocksFragment(), @@ -175,7 +175,10 @@ public class UI extends SceneModule{ configtable = new Table(); scene.add(configtable); - if(!Vars.gwt) editorDialog = new MapEditorDialog(editor); + if(!Vars.gwt){ + editor = new MapEditor(); + editorDialog = new MapEditorDialog(editor); + } settingserror = new Dialog("Warning", "dialog"); settingserror.content().add("[crimson]Failed to access local storage.\nSettings will not be saved."); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 698b01e129..c1d1c5fe20 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -113,6 +113,10 @@ public class World extends Module{ } public Tile[] getNearby(int x, int y){ + return getNearby(x, y, temptiles); + } + + public Tile[] getNearby(int x, int y, Tile[] temptiles){ temptiles[0] = tile(x+1, y); temptiles[1] = tile(x, y+1); temptiles[2] = tile(x-1, y); diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index ac206bffcc..5b245ed086 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -27,6 +27,7 @@ public class DesktopInput extends InputHandler{ int endx, endy; private boolean enableHold = false; private boolean beganBreak; + private boolean rotated = false; @Override public float getCursorEndX(){ return endx; } @Override public float getCursorEndY(){ return endy; } @@ -64,7 +65,12 @@ public class DesktopInput extends InputHandler{ renderer.scaleCamera((int)Inputs.getAxis("zoom")); } - player.rotation += Inputs.getAxis("rotate_alt"); + if(!rotated) { + player.rotation += Inputs.getAxis("rotate_alt"); + rotated = true; + } + if(!Inputs.getAxisActive("rotate_alt")) rotated = false; + player.rotation += Inputs.getAxis("rotate"); player.rotation = Mathf.mod(player.rotation, 4); @@ -74,8 +80,8 @@ public class DesktopInput extends InputHandler{ player.breakMode = PlaceMode.hold; } - for(int i = 1; i <= 6 && i < control.getWeapons().size; i ++){ - if(Inputs.keyTap("weapon_" + i) && i < control.getWeapons().size){ + for(int i = 1; i <= 6 && i <= control.getWeapons().size; i ++){ + if(Inputs.keyTap("weapon_" + i)){ player.weapon = control.getWeapons().get(i - 1); ui.updateWeapons(); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index adacd97a40..c4d6d2b6c2 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -15,6 +15,8 @@ import io.anuke.mindustry.resource.Section; import io.anuke.mindustry.ui.FloatingDialog; import io.anuke.ucore.core.Draw; import io.anuke.ucore.graphics.Hue; +import io.anuke.ucore.scene.builders.button; +import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.ui.*; @@ -25,112 +27,122 @@ import io.anuke.ucore.util.Mathf; public class BlocksFragment implements Fragment{ private Table desctable; private Array statlist = new Array<>(); + private boolean shown = true; public void build(){ + new table(){{ abottom(); aright(); - - new table("button"){{ - visible(()->player.recipe != null); - desctable = get(); - fillX(); - }}.end().uniformX(); - - row(); - new table("pane"){{ - get().setTouchable(Touchable.enabled); - int rows = 4; - int maxcol = 0; - float size = 48; - - Stack stack = new Stack(); - ButtonGroup group = new ButtonGroup<>(); - Array recipes = new Array(); - - for(Section sec : Section.values()){ - recipes.clear(); - Recipe.getBy(sec, recipes); - maxcol = Math.max((int)((float)recipes.size/rows+1), maxcol); - } - - for(Section sec : Section.values()){ - recipes.clear(); - Recipe.getBy(sec, recipes); - - Table table = new Table(); - - ImageButton button = new ImageButton("icon-"+sec.name(), "toggle"); - button.clicked(()->{ - if(!table.isVisible() && player.recipe != null){ - player.recipe = null; - } - }); - button.setName("sectionbutton" + sec.name()); - add(button).growX().height(54).padTop(sec.ordinal() <= 2 ? -10 : -5); - button.getImageCell().size(40).padBottom(4).padTop(2); - group.add(button); - - if(sec.ordinal() % 3 == 2 && sec.ordinal() > 0){ - row(); + new table(){{ + + new table("button") {{ + visible(() -> player.recipe != null); + desctable = get(); + fillX(); + }}.end().uniformX(); + + row(); + + new table("pane") {{ + touchable(Touchable.enabled); + int rows = 4; + int maxcol = 0; + float size = 48; + + Stack stack = new Stack(); + ButtonGroup group = new ButtonGroup<>(); + Array recipes = new Array(); + + for (Section sec : Section.values()) { + recipes.clear(); + Recipe.getBy(sec, recipes); + maxcol = Math.max((int) ((float) recipes.size / rows + 1), maxcol); } - - table.margin(4); - table.top().left(); - - int i = 0; - - for(Recipe r : recipes){ - TextureRegion region = Draw.hasRegion(r.result.name() + "-icon") ? - Draw.region(r.result.name() + "-icon") : Draw.region(r.result.name()); - ImageButton image = new ImageButton(region, "select"); - - image.clicked(()->{ - if(player.recipe == r){ + + for (Section sec : Section.values()) { + recipes.clear(); + Recipe.getBy(sec, recipes); + + Table table = new Table(); + + ImageButton button = new ImageButton("icon-" + sec.name(), "toggle"); + button.clicked(() -> { + if (!table.isVisible() && player.recipe != null) { player.recipe = null; - }else{ - player.recipe = r; - updateRecipe(); } }); - - table.add(image).size(size+8).pad(2); - image.getImageCell().size(size); - - image.update(()->{ - - boolean canPlace = !control.getTutorial().active() || control.getTutorial().canPlace(); - boolean has = (control.hasItems(r.requirements)) && canPlace; - //image.setDisabled(!has); - image.setChecked(player.recipe == r); - image.setTouchable(canPlace ? Touchable.enabled : Touchable.disabled); - image.getImage().setColor(has ? Color.WHITE : Hue.lightness(0.33f)); - }); - - if(i % rows == rows-1) - table.row(); - - i++; + button.setName("sectionbutton" + sec.name()); + add(button).growX().height(54).padTop(sec.ordinal() <= 2 ? -10 : -5); + button.getImageCell().size(40).padBottom(4).padTop(2); + group.add(button); + + if (sec.ordinal() % 3 == 2 && sec.ordinal() > 0) { + row(); + } + + table.margin(4); + table.top().left(); + + int i = 0; + + for (Recipe r : recipes) { + TextureRegion region = Draw.hasRegion(r.result.name() + "-icon") ? + Draw.region(r.result.name() + "-icon") : Draw.region(r.result.name()); + ImageButton image = new ImageButton(region, "select"); + + image.clicked(() -> { + if (player.recipe == r) { + player.recipe = null; + } else { + player.recipe = r; + updateRecipe(); + } + }); + + table.add(image).size(size + 8).pad(2); + image.getImageCell().size(size); + + image.update(() -> { + + boolean canPlace = !control.getTutorial().active() || control.getTutorial().canPlace(); + boolean has = (control.hasItems(r.requirements)) && canPlace; + //image.setDisabled(!has); + image.setChecked(player.recipe == r); + image.setTouchable(canPlace ? Touchable.enabled : Touchable.disabled); + image.getImage().setColor(has ? Color.WHITE : Hue.lightness(0.33f)); + }); + + if (i % rows == rows - 1) + table.row(); + + i++; + } + + table.setVisible(button::isChecked); + + stack.add(table); } - - table.setVisible(()-> button.isChecked()); - - stack.add(table); - } - - - row(); - add(stack).colspan(Section.values().length); - margin(10f); - - get().marginLeft(0f); - get().marginRight(0f); - - end(); - }}.right().bottom().uniformX(); - - visible(()->!GameState.is(State.menu)); + + + row(); + add(stack).colspan(Section.values().length); + margin(10f); + + get().marginLeft(0f); + get().marginRight(0f); + + end(); + }}.right().bottom().uniformX(); + + visible(() -> !GameState.is(State.menu) && shown); + + }}.end(); + + //new imagebutton("icon-arrow-right", 10*2, () -> { + // shown = !shown; + //}).uniformY().fillY(); }}.end(); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index b07977f2ad..910f016d6d 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -67,7 +67,7 @@ public class HudFragment implements Fragment{ itemtable = new table("button").end().top().left().fillX().size(-1).get(); itemtable.setTouchable(Touchable.enabled); - itemtable.setVisible(()-> control.getMode() != GameMode.sandbox); + itemtable.setVisible(()-> !control.getMode().infiniteResources); itemcell = get().getCell(itemtable); get().setVisible(()->!GameState.is(State.menu)); @@ -169,7 +169,7 @@ public class HudFragment implements Fragment{ new label(()-> control.getEnemiesRemaining() > 0 ? control.getEnemiesRemaining() + printEnemiesRemaining() : - (control.getTutorial().active() || Vars.control.getMode() == GameMode.sandbox) ? "waiting..." : "Wave in " + (int) (control.getWaveCountdown() / 60f)) + (control.getTutorial().active() || Vars.control.getMode().toggleWaves) ? "waiting..." : "Wave in " + (int) (control.getWaveCountdown() / 60f)) .minWidth(140).left(); margin(12f); @@ -186,7 +186,7 @@ public class HudFragment implements Fragment{ Vars.control.runWave(); }).height(uheight).fillX().right().padTop(-8f).padBottom(-12f).padRight(-36) .padLeft(-10f).width(40f).update(l->{ - boolean vis = Vars.control.getMode() == GameMode.sandbox && Vars.control.getEnemiesRemaining() <= 0; + boolean vis = Vars.control.getMode().toggleWaves && Vars.control.getEnemiesRemaining() <= 0; boolean paused = GameState.is(State.paused) || !vis; l.setVisible(vis); @@ -200,7 +200,7 @@ public class HudFragment implements Fragment{ itemtable.clear(); itemtable.left(); - if(control.getMode() == GameMode.sandbox){ + if(control.getMode().infiniteResources){ return; } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index cfc6f18fa1..04f06e4595 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -22,7 +22,8 @@ public class Block{ private static Array blocks = new Array(); protected static TextureRegion temp = new TextureRegion(); - + + public Tile[] temptiles = new Tile[4]; /**internal name*/ public final String name; /**internal ID*/ @@ -148,7 +149,7 @@ public class Block{ byte i = tile.getDump(); byte pdump = (byte)(i % 4); - Tile[] tiles = tile.getNearby(); + Tile[] tiles = tile.getNearby(temptiles); for(int j = 0; j < 4; j ++){ Tile other = tiles[i]; @@ -157,7 +158,6 @@ public class Block{ tile.setDump((byte)((i+1)%4)); return; } - tiles = tile.getNearby(); i++; i %= 4; } @@ -176,7 +176,7 @@ public class Block{ protected boolean tryDump(Tile tile, int direction, Item todump){ int i = tile.getDump()%4; - Tile[] tiles = tile.getNearby(); + Tile[] tiles = tile.getNearby(temptiles); for(int j = 0; j < 4; j ++){ Tile other = tiles[i]; @@ -194,7 +194,6 @@ public class Block{ } } } - tiles = tile.getNearby(); i++; i %= 4; } diff --git a/core/src/io/anuke/mindustry/world/GameMode.java b/core/src/io/anuke/mindustry/world/GameMode.java index 62405136fd..bdf6b6250c 100644 --- a/core/src/io/anuke/mindustry/world/GameMode.java +++ b/core/src/io/anuke/mindustry/world/GameMode.java @@ -1,5 +1,18 @@ package io.anuke.mindustry.world; public enum GameMode{ - waves, sandbox; + waves, + sandbox{ + { + infiniteResources = true; + toggleWaves = true; + } + }, + freebuild{ + { + toggleWaves = true; + } + }; + public boolean infiniteResources; + public boolean toggleWaves; } diff --git a/core/src/io/anuke/mindustry/world/Maps.java b/core/src/io/anuke/mindustry/world/Maps.java index 0fc6f0644d..80a40e3588 100644 --- a/core/src/io/anuke/mindustry/world/Maps.java +++ b/core/src/io/anuke/mindustry/world/Maps.java @@ -41,12 +41,14 @@ public class Maps implements Disposable{ if(!loadMapFile(Gdx.files.internal("maps/maps.json"))){ throw new RuntimeException("Failed to load maps!"); } - - if(!loadMapFile(Vars.customMapDirectory.child("maps.json"))){ - try{ - Vars.customMapDirectory.child("maps.json").writeString("{}", false); - }catch(Exception e){ - throw new RuntimeException("Failed to create custom map directory!"); + + if(!Vars.gwt) { + if (!loadMapFile(Vars.customMapDirectory.child("maps.json"))) { + try { + Vars.customMapDirectory.child("maps.json").writeString("{}", false); + } catch (Exception e) { + throw new RuntimeException("Failed to create custom map directory!"); + } } } } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 87c2d9c8c6..3b222d1932 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -213,6 +213,10 @@ public class Tile{ public Tile[] getNearby(){ return Vars.world.getNearby(x, y); } + + public Tile[] getNearby(Tile[] copy){ + return Vars.world.getNearby(x, y); + } public void changed(){ if(entity != null){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java index 6235725047..01301f9d38 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java @@ -35,6 +35,8 @@ public class TunnelConveyor extends Block{ @Override public boolean acceptItem(Item item, Tile dest, Tile source){ + int rot = source.relativeTo(dest.x, dest.y); + if(rot != (dest.getRotation() + 2)%4) return false; Tile tunnel = getDestTunnel(dest); if(tunnel != null){ Tile to = tunnel.getNearby()[tunnel.getRotation()]; diff --git a/html/build.gradle b/html/build.gradle index d84ca56e4c..0db4be6279 100644 --- a/html/build.gradle +++ b/html/build.gradle @@ -10,10 +10,10 @@ gwt { modules 'io.anuke.mindustry.GdxDefinition' devModules 'io.anuke.mindustry.GdxDefinitionSuperdev' project.webAppDirName = 'webapp' + compiler.style = de.richsource.gradle.plugins.gwt.Style.PRETTY; compiler { strict = true; - //enableClosureCompiler = true; disableCastChecking = true; } }