diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 94bb7a0a3f..bf023cb2e3 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -24,7 +24,10 @@ load.content = Content load.system = System load.mod = Mods +schematic.add = Save Schematic... schematics = Schematics +schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic +schematic.saved = Schematic saved. stat.wave = Waves Defeated:[accent] {0} stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} @@ -629,6 +632,8 @@ keybind.press.axis = Press an axis or key... keybind.screenshot.name = Map Screenshot keybind.move_x.name = Move x keybind.move_y.name = Move y +keybind.schematic_flip_x.name = Flip Schematic X +keybind.schematic_flip_y.name = Flip Schematic Y keybind.fullscreen.name = Toggle Fullscreen keybind.select.name = Select/Shoot keybind.diagonal_placement.name = Diagonal Placement diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 99ce599252..da0182ee35 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -186,6 +186,13 @@ public class UI implements ApplicationListener, Loadable{ Core.scene.act(); Core.scene.draw(); + if(Core.input.keyTap(KeyCode.MOUSE_LEFT) && Core.scene.getKeyboardFocus() instanceof TextField){ + Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + if(!(e instanceof TextField)){ + Core.scene.setKeyboardFocus(null); + } + } + //draw overlay for buttons if(state.rules.tutorial){ control.tutorial.draw(); @@ -309,7 +316,7 @@ public class UI implements ApplicationListener, Loadable{ Table table = new Table(); table.setFillParent(true); table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.remove()); - table.top().add(info).padTop(10); + table.top().add(info).style(Styles.outlineLabel).padTop(10); Core.scene.add(table); } diff --git a/core/src/io/anuke/mindustry/game/Schematic.java b/core/src/io/anuke/mindustry/game/Schematic.java index 24e3e1cae8..5d7b5565f4 100644 --- a/core/src/io/anuke/mindustry/game/Schematic.java +++ b/core/src/io/anuke/mindustry/game/Schematic.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.game; import io.anuke.arc.collection.*; +import io.anuke.arc.files.*; import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.world.*; @@ -9,6 +10,7 @@ public class Schematic{ public StringMap tags; public int width, height; public boolean workshop; + public @Nullable FileHandle file; public Schematic(Array tiles, StringMap tags, int width, int height){ this.tiles = tiles; diff --git a/core/src/io/anuke/mindustry/game/Schematics.java b/core/src/io/anuke/mindustry/game/Schematics.java index a73045e966..c0942eb1f7 100644 --- a/core/src/io/anuke/mindustry/game/Schematics.java +++ b/core/src/io/anuke/mindustry/game/Schematics.java @@ -244,6 +244,7 @@ public class Schematics implements Loadable{ if(!s.tags.containsKey("name")){ s.tags.put("name", file.nameWithoutExtension()); } + s.file = file; return s; } diff --git a/core/src/io/anuke/mindustry/input/Binding.java b/core/src/io/anuke/mindustry/input/Binding.java index c3eab6a3d5..cc5e0d3145 100644 --- a/core/src/io/anuke/mindustry/input/Binding.java +++ b/core/src/io/anuke/mindustry/input/Binding.java @@ -19,6 +19,8 @@ public enum Binding implements KeyBind{ diagonal_placement(KeyCode.CONTROL_LEFT), pick(KeyCode.MOUSE_MIDDLE), schematic(KeyCode.F), + schematic_flip_x(KeyCode.Z), + schematic_flip_y(KeyCode.X), dash(KeyCode.SHIFT_LEFT), gridMode(KeyCode.BACKTICK), gridModeShift(KeyCode.ALT_LEFT), diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 47bcda5892..21694b8be8 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -7,6 +7,7 @@ import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.input.*; import io.anuke.arc.math.*; import io.anuke.arc.scene.*; +import io.anuke.arc.scene.event.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.core.GameState.*; @@ -42,7 +43,7 @@ public class DesktopInput extends InputHandler{ public void buildUI(Group group){ group.fill(t -> { t.bottom().update(() -> t.getColor().a = Mathf.lerpDelta(t.getColor().a, player.isBuilding() ? 1f : 0f, 0.15f)); - t.visible(() -> Core.settings.getBool("hints")); + t.visible(() -> Core.settings.getBool("hints") && selectRequests.isEmpty()); t.table(Styles.black6, b -> { b.defaults().left(); b.label(() -> Core.bundle.format(!player.isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.name())).style(Styles.outlineLabel); @@ -50,6 +51,28 @@ public class DesktopInput extends InputHandler{ b.add(Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.name())).style(Styles.outlineLabel); }).margin(10f); }); + + group.fill(t -> { + t.visible(() -> lastSchematic != null && !selectRequests.isEmpty()); + t.bottom(); + t.table(Styles.black6, b -> { + b.touchable(Touchable.enabled); + b.defaults().left(); + b.add(Core.bundle.format("schematic.flip", + Core.keybinds.get(Binding.schematic_flip_x).key.name(), + Core.keybinds.get(Binding.schematic_flip_y).key.name())).style(Styles.outlineLabel); + b.row(); + b.table(a -> { + a.addImageTextButton("$schematic.add", Icon.saveSmall, () -> { + ui.showTextInput("$schematic.add", "$name", "", text -> { + lastSchematic.tags.put("name", text); + schematics.add(lastSchematic); + ui.showInfoFade("$schematic.saved"); + }); + }).colspan(2).size(250f, 50f); + }); + }).margin(6f); + }); } @Override @@ -172,6 +195,8 @@ public class DesktopInput extends InputHandler{ if(Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0 && isPlacing() && mode == placing){ updateLine(selectX, selectY); + }else if(Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0 && !selectRequests.isEmpty()){ + rotateRequests(selectRequests, (int)Core.input.axisTap(Binding.rotate)); } Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY()); @@ -256,9 +281,11 @@ public class DesktopInput extends InputHandler{ } if(Core.input.keyRelease(Binding.schematic)){ - Schematic schem = schematics.create(schemX, schemY, rawCursorX, rawCursorY); - schematics.add(schem); - useSchematic(schem); + lastSchematic = schematics.create(schemX, schemY, rawCursorX, rawCursorY); + useSchematic(lastSchematic); + if(selectRequests.isEmpty()){ + lastSchematic = null; + } } //TODO remove diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 6a19c12d70..14572f2f25 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -14,13 +14,14 @@ import io.anuke.arc.scene.*; import io.anuke.arc.scene.event.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; +import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.mindustry.content.*; import io.anuke.mindustry.entities.*; import io.anuke.mindustry.entities.effect.*; import io.anuke.mindustry.entities.traits.BuilderTrait.*; import io.anuke.mindustry.entities.type.*; -import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.EventType.*; +import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.Teams.*; import io.anuke.mindustry.gen.*; import io.anuke.mindustry.graphics.*; @@ -52,6 +53,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ public boolean droppingItem; public Group uiGroup; + protected @Nullable Schematic lastSchematic; protected GestureDetector detector; protected PlaceLine line = new PlaceLine(); protected BuildRequest resultreq; @@ -224,6 +226,27 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ selectRequests.addAll(schematics.toRequests(schem, world.toTile(player.x), world.toTile(player.y))); } + public void rotateRequests(Array requests, int direction){ + int ox = tileX(getMouseX()), oy = tileY(getMouseY()); + + requests.each(req -> { + //req.x -= ox; + //req.y -= oy; + float wx = (req.x - ox) * tilesize + req.block.offset(), wy = (req.y - oy) * tilesize + req.block.offset(); + float x = wx; + if(direction >= 0){ + wx = -wy; + wy = x; + }else{ + wx = wy; + wy = -x; + } + req.x = world.toTile(wx - req.block.offset()) + ox; + req.y = world.toTile(wy - req.block.offset()) + oy; + req.rotation += direction; + }); + } + /** Returns the selection request that overlaps this position, or null. */ protected BuildRequest getRequest(int x, int y){ return getRequest(x, y, 1, null);