From e9e7d2e2894e90df75c22bfbffa181a98f5d434e Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 30 May 2018 18:32:01 -0400 Subject: [PATCH] Place menu scrolling, fixed some settings menu bugs --- core/assets/bundles/bundle.properties | 1 + core/src/io/anuke/mindustry/Vars.java | 1 - .../io/anuke/mindustry/content/Recipes.java | 2 +- .../anuke/mindustry/core/ContentLoader.java | 5 +- .../io/anuke/mindustry/entities/Player.java | 9 +- .../anuke/mindustry/input/AndroidInput.java | 21 +-- .../anuke/mindustry/input/DesktopInput.java | 43 +---- .../anuke/mindustry/input/InputHandler.java | 24 ++- .../io/anuke/mindustry/input/PlaceMode.java | 5 + .../type/{Section.java => Category.java} | 2 +- core/src/io/anuke/mindustry/type/Recipe.java | 30 ++- .../ui/fragments/BlocksFragment.java | 171 +++++++++--------- .../mindustry/ui/fragments/HudFragment.java | 4 +- core/src/io/anuke/mindustry/world/Build.java | 61 +++---- 14 files changed, 194 insertions(+), 185 deletions(-) create mode 100644 core/src/io/anuke/mindustry/input/PlaceMode.java rename core/src/io/anuke/mindustry/type/{Section.java => Category.java} (82%) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index e719fef6d4..33db572e8f 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -215,6 +215,7 @@ text.editor=Editor text.mapeditor=Map Editor text.donate=Donate text.settings.reset=Reset to Defaults +text.settings.rebind=Rebind text.settings.controls=Controls text.settings.game=Game text.settings.sound=Sound diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 3eb23ab244..a02210dba2 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -24,7 +24,6 @@ import io.anuke.ucore.util.OS; import java.util.Locale; public class Vars{ - public static final boolean testMobile = false; //shorthand for whether or not this is running on android or ios public static boolean mobile; diff --git a/core/src/io/anuke/mindustry/content/Recipes.java b/core/src/io/anuke/mindustry/content/Recipes.java index 3fa5eba724..e4b3ef715e 100644 --- a/core/src/io/anuke/mindustry/content/Recipes.java +++ b/core/src/io/anuke/mindustry/content/Recipes.java @@ -4,7 +4,7 @@ import io.anuke.mindustry.content.blocks.*; import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Recipe; -import static io.anuke.mindustry.type.Section.*; +import static io.anuke.mindustry.type.Category.*; public class Recipes implements ContentList{ diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index 1eedbad101..2d5dd7fd3f 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -10,6 +10,7 @@ import io.anuke.mindustry.entities.units.UnitType; import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; +import io.anuke.ucore.core.Effects; import io.anuke.ucore.util.Log; /**Loads all game content. @@ -83,9 +84,9 @@ public class ContentLoader { } Log.info("--- CONTENT INFO ---"); - Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nBullet types loaded: {6}\nStatus effects loaded: {7}\nRecipes loaded: {8}\nTotal content classes: {9}", + Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nBullet types loaded: {6}\nStatus effects loaded: {7}\nRecipes loaded: {8}\nEffects loaded: {9}\nTotal content classes: {10}", Block.getAllBlocks().size, io.anuke.mindustry.type.Item.all().size, Liquid.all().size, - io.anuke.mindustry.type.Mech.all().size, UnitType.getAllTypes().size, io.anuke.mindustry.type.AmmoType.all().size, BulletType.all().size, StatusEffect.getAllEffects().size, io.anuke.mindustry.type.Recipe.all().size, content.length); + io.anuke.mindustry.type.Mech.all().size, UnitType.getAllTypes().size, io.anuke.mindustry.type.AmmoType.all().size, BulletType.all().size, StatusEffect.getAllEffects().size, io.anuke.mindustry.type.Recipe.all().size, Effects.all().size, content.length); Log.info("-------------------"); } diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 02c9a6ad6b..a4104fffa1 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -275,17 +275,12 @@ public class Player extends Unit implements BlockBuilder { }else{ //draw place request Draw.color(Palette.accent); + Lines.stroke((1f-request.progress)); Lines.poly(request.x * tilesize + request.recipe.result.offset(), request.y * tilesize + request.recipe.result.offset(), - 4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f)); - - Lines.stroke((1f-request.progress)*2f); - - Lines.poly(request.x * tilesize + request.recipe.result.offset(), - request.y * tilesize + request.recipe.result.offset(), - 4, request.recipe.result.size * tilesize /2f + 3f, 45 + 15); + 4, request.recipe.result.size * tilesize /2f, 45 + 15); } } diff --git a/core/src/io/anuke/mindustry/input/AndroidInput.java b/core/src/io/anuke/mindustry/input/AndroidInput.java index 96edca8985..3260bfd04f 100644 --- a/core/src/io/anuke/mindustry/input/AndroidInput.java +++ b/core/src/io/anuke/mindustry/input/AndroidInput.java @@ -34,6 +34,7 @@ import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.input.PlaceMode.none; public class AndroidInput extends InputHandler implements GestureListener{ private static Rectangle r1 = new Rectangle(), r2 = new Rectangle(); @@ -63,6 +64,8 @@ public class AndroidInput extends InputHandler implements GestureListener{ private boolean selecting; /**Whether the player is currently in line-place mode.*/ private boolean lineMode; + /**Current place mode.*/ + private PlaceMode mode = none; public AndroidInput(Player player){ super(player); @@ -164,7 +167,7 @@ public class AndroidInput extends InputHandler implements GestureListener{ removals.addAll(placement); placement.clear(); selecting = false; - }); + }).cell.disabled(i -> placement.size == 0); //Add a rotate button new imagebutton("icon-arrow", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4)) @@ -173,7 +176,7 @@ public class AndroidInput extends InputHandler implements GestureListener{ i.getImage().setOrigin(Align.center); }).cell.disabled(i -> recipe == null || !recipe.result.rotate); }}.end(); - }}.visible(() -> isPlacing() && placement.size > 0).end(); + }}.visible(this::isPlacing).end(); } @Override @@ -266,24 +269,14 @@ public class AndroidInput extends InputHandler implements GestureListener{ Tile linked = cursor.target(); - //show-hide configuration fragment for blocks - if(linked.block().isConfigurable(linked)){ - frag.config.showConfig(linked); - }else if(!frag.config.hasConfigMouse()){ - frag.config.hideConfig(); - } - //when tapping a build block, select it if(linked.block() instanceof BuildBlock){ BuildEntity entity = linked.entity(); - player.replaceBuilding(linked.x, linked.y, linked.getRotation(), entity.recipe); + }else if(pointer == 0 && !selecting){ + tileTapped(cursor); } - //call tapped() event - //TODO net event for block tapped - linked.block().tapped(linked, player); - return false; } diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 006f06b085..325207fd5e 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -22,7 +22,7 @@ import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; -import static io.anuke.mindustry.input.DesktopInput.PlaceMode.*; +import static io.anuke.mindustry.input.PlaceMode.*; public class DesktopInput extends InputHandler{ //controller info @@ -43,28 +43,7 @@ public class DesktopInput extends InputHandler{ this.section = "player_" + (player.playerIndex + 1); } - void tileTapped(Tile tile){ - - //check if tapped block is configurable - if(tile.block().isConfigurable(tile)){ - if((!frag.config.isShown() //if the config fragment is hidden, show - //alternatively, the current selected block can 'agree' to switch config tiles - || frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile))) { - frag.config.showConfig(tile); - } - //otherwise... - }else if(!frag.config.hasConfigMouse()){ //make sure a configuration fragment isn't on the cursor - //then, if it's shown and the current block 'agrees' to hide, hide it. - if(frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)) { - frag.config.hideConfig(); - } - } - - //TODO network event! - //call tapped event - tile.block().tapped(tile, player); - } - + /**Draws a placement icon for a specific block.*/ void drawPlace(int x, int y, Block block, int rotation){ if(validPlace(x, y, block, rotation)){ Draw.color(); @@ -87,7 +66,7 @@ public class DesktopInput extends InputHandler{ if(cursor == null) return; - //draw selection + //draw selection(s) if(mode == placing) { NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursor.x, cursor.y, rotation, true, maxLength); @@ -189,8 +168,7 @@ public class DesktopInput extends InputHandler{ if(cursor == null) return false; - //if left, begin placing or tap a tile - if(button == Buttons.LEFT) { + if(button == Buttons.LEFT) { //left = begin placing if (isPlacing()) { selectX = cursor.x; selectY = cursor.y; @@ -198,11 +176,11 @@ public class DesktopInput extends InputHandler{ } else { tileTapped(cursor); } - }else if(button == Buttons.RIGHT){ + }else if(button == Buttons.RIGHT){ //right = begin breaking selectX = cursor.x; selectY = cursor.y; mode = breaking; - }else if(button == Buttons.MIDDLE){ + }else if(button == Buttons.MIDDLE){ //middle button = cancel placing recipe = null; mode = none; } @@ -221,7 +199,8 @@ public class DesktopInput extends InputHandler{ return false; } - if(mode == placing){ + + if(mode == placing){ //touch up while placing, place everything in selection NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursor.x, cursor.y, rotation, true, maxLength); for(int i = 0; i <= result.getLength(); i += recipe.result.size){ @@ -232,7 +211,7 @@ public class DesktopInput extends InputHandler{ tryPlaceBlock(x, y); } - }else if(mode == breaking){ + }else if(mode == breaking){ //touch up while breaking, break everything in selection NormalizeResult result = PlaceUtils.normalizeArea(selectX, selectY, cursor.x, cursor.y, rotation, false, maxLength); for(int x = 0; x <= Math.abs(result.x2 - result.x); x ++ ){ @@ -310,8 +289,4 @@ public class DesktopInput extends InputHandler{ controly = control.gdxInput().getY(); } } - - enum PlaceMode{ - none, breaking, placing; - } } diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 5df1455079..c5db577359 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -81,6 +81,29 @@ public abstract class InputHandler extends InputAdapter{ } + /**Handles tile tap events that are not platform specific.*/ + public void tileTapped(Tile tile){ + + //check if tapped block is configurable + if(tile.block().isConfigurable(tile)){ + if((!frag.config.isShown() //if the config fragment is hidden, show + //alternatively, the current selected block can 'agree' to switch config tiles + || frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile))) { + frag.config.showConfig(tile); + } + //otherwise... + }else if(!frag.config.hasConfigMouse()){ //make sure a configuration fragment isn't on the cursor + //then, if it's shown and the current block 'agrees' to hide, hide it. + if(frag.config.isShown() && frag.config.getSelectedTile().block().onConfigureTileTapped(frag.config.getSelectedTile(), tile)) { + frag.config.hideConfig(); + } + } + + //TODO network event! + //call tapped event + tile.block().tapped(tile, player); + } + //utility methods /**Returns the tile at the specified MOUSE coordinates.*/ @@ -170,7 +193,6 @@ public abstract class InputHandler extends InputAdapter{ public void tryPlaceBlock(int x, int y){ if(recipe != null && validPlace(x, y, recipe.result, rotation) && cursorNear()){ - placeBlock(x, y, recipe, rotation); } } diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java new file mode 100644 index 0000000000..bccef0e74b --- /dev/null +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -0,0 +1,5 @@ +package io.anuke.mindustry.input; + +enum PlaceMode{ + none, breaking, placing; +} diff --git a/core/src/io/anuke/mindustry/type/Section.java b/core/src/io/anuke/mindustry/type/Category.java similarity index 82% rename from core/src/io/anuke/mindustry/type/Section.java rename to core/src/io/anuke/mindustry/type/Category.java index 98f0342167..58ccdb9015 100644 --- a/core/src/io/anuke/mindustry/type/Section.java +++ b/core/src/io/anuke/mindustry/type/Category.java @@ -1,5 +1,5 @@ package io.anuke.mindustry.type; -public enum Section{ +public enum Category { weapon, production, distribution, liquid, power, defense, crafting, units } diff --git a/core/src/io/anuke/mindustry/type/Recipe.java b/core/src/io/anuke/mindustry/type/Recipe.java index 767f0cdf5c..db7504e8e1 100644 --- a/core/src/io/anuke/mindustry/type/Recipe.java +++ b/core/src/io/anuke/mindustry/type/Recipe.java @@ -2,9 +2,12 @@ package io.anuke.mindustry.type; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.world.Block; +import static io.anuke.mindustry.Vars.headless; + public class Recipe implements Content{ private static int lastid; private static Array allRecipes = new Array<>(); @@ -13,16 +16,16 @@ public class Recipe implements Content{ public final int id; public final Block result; public final ItemStack[] requirements; - public final Section section; + public final Category category; public final float cost; public boolean desktopOnly = false, debugOnly = false; - public Recipe(Section section, Block result, ItemStack... requirements){ + public Recipe(Category category, Block result, ItemStack... requirements){ this.id = lastid ++; this.result = result; this.requirements = requirements; - this.section = section; + this.category = category; float timeToPlace = 0f; for(ItemStack stack : requirements){ @@ -55,14 +58,29 @@ public class Recipe implements Content{ return "recipe"; } - public static Array getBySection(Section section, Array r){ + /**Returns unlocked recipes in a category. + * Do not call on the server backend, as unlocking does not exist!*/ + public static void getUnlockedByCategory(Category category, Array r){ + if(headless){ + throw new RuntimeException("Not enabled on the headless backend!"); + } + + r.clear(); for(Recipe recipe : allRecipes){ - if(recipe.section == section ) { + if(recipe.category == category && Vars.control.database().isUnlocked(recipe)) { r.add(recipe); } } + } - return r; + /**Returns all recipes in a category.*/ + public static void getByCategory(Category category, Array r){ + r.clear(); + for(Recipe recipe : allRecipes){ + if(recipe.category == category) { + r.add(recipe); + } + } } public static Array all(){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index 312f92ec23..d5bd458125 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.ui.fragments; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.utils.Array; @@ -8,9 +7,11 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.input.InputHandler; +import io.anuke.mindustry.type.Category; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Recipe; -import io.anuke.mindustry.type.Section; +import io.anuke.ucore.core.Core; +import io.anuke.ucore.core.Graphics; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.actions.Actions; @@ -18,40 +19,56 @@ import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.event.ClickListener; import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.Touchable; -import io.anuke.ucore.scene.ui.ButtonGroup; -import io.anuke.ucore.scene.ui.Image; -import io.anuke.ucore.scene.ui.ImageButton; -import io.anuke.ucore.scene.ui.Label; +import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; -import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.*; public class BlocksFragment implements Fragment{ - private Table desctable, blocks; - private Stack stack = new Stack(); + /**Table containing description that is shown on top.*/ + private Table desctable; + /**Main table containing the whole menu.*/ + private Table blocks; + /**Whether the whole thing is shown or hidden by the popup button.*/ private boolean shown = true; - private Recipe hoveredDescriptionRecipe; + /**Recipe currently hovering over.*/ + private Recipe hoverRecipe; + /**Temporary recipe array for storage*/ + private Array recipes = new Array<>(); + + //number of block icon rows + private static final int rows = 4; + //number of category button rows + private static final int secrows = 4; + //size of each block icon + private static final float size = 48; + //maximum recipe rows + private static final int maxrow = 3; public void build(Group parent){ InputHandler input = control.input(0); + //create container table new table(){{ abottom(); aright(); + //make it only be shown when needed. visible(() -> !state.is(State.menu) && shown); + //create the main blocks table blocks = new table(){{ + + //add top description table desctable = new Table("button"); - desctable.setVisible(() -> hoveredDescriptionRecipe != null || input.recipe != null); + desctable.setVisible(() -> hoverRecipe != null || input.recipe != null); //make sure it's visible when necessary desctable.update(() -> { // note: This is required because there is no direct connection between // input.recipe and the description ui. If input.recipe gets set to null // a proper cleanup of the ui elements is required. - boolean anyRecipeShown = input.recipe != null || hoveredDescriptionRecipe != null; + boolean anyRecipeShown = input.recipe != null || hoverRecipe != null; boolean descriptionTableClean = desctable.getChildren().size == 0; boolean cleanupRequired = !anyRecipeShown && !descriptionTableClean; if(cleanupRequired){ @@ -59,57 +76,60 @@ public class BlocksFragment implements Fragment{ } }); - stack.add(desctable); - - add(stack).fillX().uniformX(); + add(desctable).fillX().uniformX(); row(); + //now add the block selection menu new table("pane") {{ touchable(Touchable.enabled); - int rows = 4; - int maxcol = 0; - float size = 48; + get().setRound(true); Stack stack = new Stack(); ButtonGroup group = new ButtonGroup<>(); - Array recipes = new Array<>(); - for (Section sec : Section.values()) { - recipes.clear(); - Recipe.getBySection(sec, recipes); - maxcol = Math.max((int) ((float) recipes.size / rows + 1), maxcol); - } + //add categories + for (Category cat : Category.values()) { + //get recipes out by category + Recipe.getUnlockedByCategory(cat, recipes); - for (Section sec : Section.values()) { - int secrows = 4; + //empty section, nothing to see here + if(recipes.size == 0){ + continue; + } - recipes.clear(); - Recipe.getBySection(sec, recipes); + //table where actual recipes go + Table recipeTable = new Table(); + recipeTable.margin(4).top().left().marginRight(15); - Table table = new Table(); - - ImageButton button = new ImageButton("icon-" + sec.name(), "toggle"); - button.clicked(() -> { - if (!table.isVisible() && input.recipe != null) { + //add category button + ImageButton catb = get().addImageButton( "icon-" + cat.name(), "toggle", 40, () -> { + if (!recipeTable.isVisible() && input.recipe != null) { input.recipe = null; } + }).growX().height(54).padTop(cat.ordinal() <= secrows-1 ? -10 : -5).group(group) + .name("sectionbutton" + cat.name()).get(); + + //scrollpane for recipes + ScrollPane pane = new ScrollPane(recipeTable, "clear-black"); + pane.setOverscroll(false, false); + pane.setVisible(catb::isChecked); + pane.update(() -> { + Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true); + if(e != null && e.isDescendantOf(pane)){ + Core.scene.setScrollFocus(pane); + } }); + stack.add(pane); - button.setName("sectionbutton" + sec.name()); - add(button).growX().height(54).padLeft(-1).padTop(sec.ordinal() <= secrows-1 ? -10 : -5); - button.getImageCell().size(40).padBottom(4).padTop(2); - group.add(button); - - if (sec.ordinal() % secrows == secrows-1) { + //add a new row here when needed + if (cat.ordinal() % secrows == secrows-1) { row(); } - table.margin(4); - table.top().left(); - int i = 0; + //add actual recipes for (Recipe r : recipes) { ImageButton image = new ImageButton(new TextureRegion(), "select"); @@ -121,14 +141,15 @@ public class BlocksFragment implements Fragment{ image.getImageCell().setActor(istack).size(size); image.addChild(istack); + image.setTouchable(Touchable.enabled); image.getImage().remove(); image.addListener(new ClickListener(){ @Override public void enter(InputEvent event, float x, float y, int pointer, Element fromActor) { super.enter(event, x, y, pointer, fromActor); - if (hoveredDescriptionRecipe != r) { - hoveredDescriptionRecipe = r; + if (hoverRecipe != r) { + hoverRecipe = r; updateRecipe(r); } } @@ -136,41 +157,33 @@ public class BlocksFragment implements Fragment{ @Override public void exit(InputEvent event, float x, float y, int pointer, Element toActor) { super.exit(event, x, y, pointer, toActor); - hoveredDescriptionRecipe = null; + hoverRecipe = null; updateRecipe(input.recipe); } }); - image.addListener(new ClickListener(){ - @Override - public void clicked(InputEvent event, float x, float y){ - // note: input.recipe only gets set here during a click. - // during a hover only the visual description will be updated. - InputHandler handler = mobile ? input : control.input(event.getPointer()); + image.clicked(() -> { + // note: input.recipe only gets set here during a click. + // during a hover only the visual description will be updated. + InputHandler handler = mobile ? input : control.input(0); - boolean nothingSelectedYet = handler.recipe == null; - boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r; - boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse; - if (shouldMakeSelection) { - handler.recipe = r; - hoveredDescriptionRecipe = r; - updateRecipe(r); - } else { - handler.recipe = null; - hoveredDescriptionRecipe = null; - updateRecipe(null); - } + boolean nothingSelectedYet = handler.recipe == null; + boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r; + boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse; + if (shouldMakeSelection) { + handler.recipe = r; + hoverRecipe = r; + updateRecipe(r); + } else { + handler.recipe = null; + hoverRecipe = null; + updateRecipe(null); } }); - table.add(image).size(size + 8); + recipeTable.add(image).size(size + 8); image.update(() -> { - image.setTouchable(Touchable.enabled); - for(Element e : istack.getChildren()){ - e.setColor(Color.WHITE); - } - for(Player player : players){ if(control.input(player.playerIndex).recipe == r){ image.setChecked(true); @@ -181,26 +194,22 @@ public class BlocksFragment implements Fragment{ }); if (i % rows == rows - 1) { - table.row(); + recipeTable.row(); } i++; } - - table.setVisible(button::isChecked); - - stack.add(table); } row(); - add(stack).colspan(Section.values().length); + add(stack).colspan(Category.values().length).padBottom(-5).height((size + 12)*maxrow); margin(10f); - marginLeft(1f); - marginRight(1f); + marginLeft(0f); + marginRight(0f); end(); - }}.right().bottom().uniformX(); + }}.right().bottom(); visible(() -> !state.is(State.menu) && shown); @@ -210,7 +219,7 @@ public class BlocksFragment implements Fragment{ public void toggle(boolean show, float t, Interpolation ip){ if(!show){ - blocks.actions(Actions.translateBy(0, -blocks.getHeight() - stack.getHeight(), t, ip), Actions.call(() -> shown = false)); + blocks.actions(Actions.translateBy(0, -blocks.getHeight() - desctable.getHeight(), t, ip), Actions.call(() -> shown = false)); }else{ shown = true; blocks.actions(Actions.translateBy(0, -blocks.getTranslation().y, t, ip)); @@ -272,10 +281,6 @@ public class BlocksFragment implements Fragment{ } desctable.row(); - - Label label = new Label("[health]"+ Bundles.get("text.health")+": " + recipe.result.health); - label.setWrap(true); - desctable.add(label).width(200).padTop(4).padBottom(2); } private void checkUnlockableBlocks(){ diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 5855ff5057..3cc97c95f9 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -188,12 +188,12 @@ public class HudFragment implements Fragment{ flip.getStyle().imageUp = Core.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up"); if (shown) { - //blockfrag.toggle(false, dur, in); + blockfrag.toggle(false, dur, in); wavetable.actions(Actions.translateBy(0, wavetable.getHeight() + dsize, dur, in), Actions.call(() -> shown = false)); infolabel.actions(Actions.translateBy(0, wavetable.getHeight(), dur, in), Actions.call(() -> shown = false)); } else { shown = true; - //blockfrag.toggle(true, dur, in); + blockfrag.toggle(true, dur, in); wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in)); infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in)); } diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index 1c52fc13cc..4d099c748d 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -81,70 +81,65 @@ public class Build { } /**Returns whether a tile can be placed at this location by this team.*/ - public static boolean validPlace(Team team, int x, int y, Block type, int rotation){ + public static boolean validPlace(Team team, int x, int y, Block type, int rotation) { Recipe recipe = Recipe.getByResult(type); - if(recipe == null){ + if (recipe == null) { return false; } rect.setSize(type.size * tilesize, type.size * tilesize); rect.setCenter(type.offset() + x * tilesize, type.offset() + y * tilesize); - if(type.solid || type.solidifes) - synchronized (Entities.entityLock) { - try { + if (type.solid || type.solidifes) + synchronized (Entities.entityLock) { + try { - rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()); - boolean[] result = {false}; + rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()); + boolean[] result = {false}; - Units.getNearby(rect, e -> { - if (e == null) return; //not sure why this happens? - Rectangle rect = e.hitbox.getRect(e.x, e.y); + Units.getNearby(rect, e -> { + if (e == null) return; //not sure why this happens? + Rectangle rect = e.hitbox.getRect(e.x, e.y); - if (Build.rect.overlaps(rect) && !e.isFlying()) { - result[0] = true; - } - }); + if (Build.rect.overlaps(rect) && !e.isFlying()) { + result[0] = true; + } + }); - if (result[0]) return false; - }catch (Exception e){ - return false; + if (result[0]) return false; + } catch (Exception e) { + return false; + } } - } Tile tile = world.tile(x, y); - if(tile == null || (isSpawnPoint(tile) && (type.solidifes || type.solid))) return false; + if (tile == null) return false; - if(type.isMultiblock()){ - if(type.canReplace(tile.block()) && tile.block().size == type.size){ + if (type.isMultiblock()) { + if (type.canReplace(tile.block()) && tile.block().size == type.size) { return true; } - int offsetx = -(type.size-1)/2; - int offsety = -(type.size-1)/2; - for(int dx = 0; dx < type.size; dx ++){ - for(int dy = 0; dy < type.size; dy ++){ + int offsetx = -(type.size - 1) / 2; + int offsety = -(type.size - 1) / 2; + for (int dx = 0; dx < type.size; dx++) { + for (int dy = 0; dy < type.size; dy++) { Tile other = world.tile(x + dx + offsetx, y + dy + offsety); - if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) || isSpawnPoint(other) || !other.floor().placeableOn){ + if (other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) || !other.floor().placeableOn) { return false; } } } return true; - }else { + } else { return (tile.getTeam() == Team.none || tile.getTeam() == team) && tile.floor().placeableOn - && ((type.canReplace(tile.block()) && !(type == tile.block() && rotation == tile.getRotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air) + && ((type.canReplace(tile.block()) && !(type == tile.block() && rotation == tile.getRotation() && type.rotate)) || tile.block().alwaysReplace || tile.block() == Blocks.air) && tile.block().isMultiblock() == type.isMultiblock() && type.canPlaceOn(tile); } } - //TODO make this work! - public static boolean isSpawnPoint(Tile tile){ - return false; - } - /**Returns whether the tile at this position is breakable by this team*/ public static boolean validBreak(Team team, int x, int y) { Tile tile = world.tile(x, y);