Added all placement controls

This commit is contained in:
Anuken
2018-11-19 14:20:57 -05:00
parent c75cdc6d28
commit 1ad4815983
6 changed files with 67 additions and 113 deletions

View File

@@ -40,7 +40,9 @@ ImageButtonStyle: {
toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white }, toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white },
select: {checked: button-select, up: none }, select: {checked: button-select, up: none },
clear: {down: clear-down, up: clear, over: clear-over}, clear: {down: clear-down, up: clear, over: clear-over},
clear-partial: {down: clear-down, up: none, over: clear-over},
clear-toggle: {down: clear-down, checked: clear-down, up: clear, over: clear-over}, clear-toggle: {down: clear-down, checked: clear-down, up: clear, over: clear-over},
clear-toggle-partial: {down: clear-down, checked: clear-down, up: none, over: clear-over},
}, },
ScrollPaneStyle: { ScrollPaneStyle: {
default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical-black}, default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical-black},

View File

@@ -25,7 +25,7 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator; import io.anuke.ucore.util.Translator;
@@ -145,7 +145,7 @@ public abstract class InputHandler extends InputAdapter{
return false; return false;
} }
public void buildUI(Group group){ public void buildUI(Table table){
} }

View File

@@ -30,8 +30,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@@ -208,78 +207,53 @@ public class MobileInput extends InputHandler implements GestureListener{
//region UI and drawing //region UI and drawing
@Override @Override
public void buildUI(Group group){ public void buildUI(Table table){
table.addImage("blank").color(Palette.accent).height(3f).colspan(4).growX();
table.row();
table.left().margin(0f).defaults().size(48f);
//Create confirm/cancel table table.addImageButton("icon-break", "clear-toggle-partial", 16 * 2f, () -> {
group.fill(c -> { mode = mode == breaking ? recipe == null ? none : placing : breaking;
c.bottom().left().visible(() -> !state.is(State.menu)); lastRecipe = recipe;
if(mode == breaking){
showGuide("deconstruction");
}
}).update(l -> l.setChecked(mode == breaking));
c.table("pane", act -> { //rotate button
act.margin(5); table.addImageButton("icon-arrow", "clear-partial", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
act.defaults().size(60f); .update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center))
.visible(() -> recipe != null && recipe.result.rotate);
//Add a cancel button //cancel button
act.addImageButton("icon-cancel", 16*2f, () -> { table.addImageButton("icon-cancel", "clear-partial", 16 * 2f, () -> {
mode = none; player.clearBuilding();
recipe = null; mode = none;
}); recipe = null;
}).visible(() -> player.isBuilding() || mode != none);
act.row(); //confirm button
table.addImageButton("icon-check", "clear-partial", 16 * 2f, () -> {
for(PlaceRequest request : selection){
Tile tile = request.tile();
//Add an accept button, which places everything. //actually place/break all selected blocks
act.addImageButton("icon-check", 16 * 2f, () -> { if(tile != null){
for(PlaceRequest request : selection){ if(!request.remove){
Tile tile = request.tile(); rotation = request.rotation;
recipe = request.recipe;
//actually place/break all selected blocks tryPlaceBlock(tile.x, tile.y);
if(tile != null){ }else{
if(!request.remove){ tryBreakBlock(tile.x, tile.y);
rotation = request.rotation;
recipe = request.recipe;
tryPlaceBlock(tile.x, tile.y);
}else{
tryBreakBlock(tile.x, tile.y);
}
}
} }
}
}
//move all current requests to removal array so they fade out //move all current requests to removal array so they fade out
removals.addAll(selection); removals.addAll(selection);
selection.clear(); selection.clear();
selecting = false; selecting = false;
}).disabled(i -> selection.size == 0); }).visible(() -> !selection.isEmpty());
act.row();
//Add a rotate button
act.addImageButton("icon-arrow", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
.update(i -> i.getImage().setRotationOrigin(rotation * 90, Align.center))
.disabled(i -> recipe == null || !recipe.result.rotate);
}).visible(() -> mode != none).touchable(Touchable.enabled);
c.row();
c.table("pane", remove -> {
remove.defaults().size(60f);
//Add a break button.
remove.addImageButton("icon-break", "toggle", 16 * 2f, () -> {
mode = mode == breaking ? recipe == null ? none : placing : breaking;
lastRecipe = recipe;
if(mode == breaking){
showGuide("deconstruction");
}
}).update(l -> l.setChecked(mode == breaking));
}).margin(5).touchable(Touchable.enabled);
c.table("pane", cancel -> {
cancel.defaults().size(60f);
//Add a 'cancel building' button.
cancel.addImageButton("icon-cancel", 16 * 2f, player::clearBuilding);
}).left().colspan(2).margin(5).touchable(Touchable.enabled).visible(() -> player.getPlaceQueue().size > 0);
});
} }
@Override @Override

View File

@@ -23,6 +23,7 @@ import static io.anuke.mindustry.Vars.*;
public class Recipe extends UnlockableContent{ public class Recipe extends UnlockableContent{
private static ObjectMap<Block, Recipe> recipeMap = new ObjectMap<>(); private static ObjectMap<Block, Recipe> recipeMap = new ObjectMap<>();
private static Array<Recipe> returnArray = new Array<>();
public final Block result; public final Block result;
public final ItemStack[] requirements; public final ItemStack[] requirements;
@@ -55,34 +56,15 @@ public class Recipe extends UnlockableContent{
recipeMap.put(result, this); recipeMap.put(result, this);
} }
/** /**Returns all non-hidden recipes in a category.*/
* Returns unlocked recipes in a category. public static Array<Recipe> getByCategory(Category category){
* Do not call on the server backend, as unlocking does not exist! returnArray.clear();
*/
public static void getUnlockedByCategory(Category category, Array<Recipe> arr){
if(headless){
throw new RuntimeException("Not implemented on the headless backend!");
}
arr.clear();
for(Recipe r : content.recipes()){
if(r.category == category && (control.unlocks.isUnlocked(r)) &&
!((r.mode != null && r.mode != state.mode) || !r.visibility.shown())){
arr.add(r);
}
}
}
/**
* Returns all recipes in a category.
*/
public static void getByCategory(Category category, Array<Recipe> r){
r.clear();
for(Recipe recipe : content.recipes()){ for(Recipe recipe : content.recipes()){
if(recipe.category == category){ if(recipe.category == category && !recipe.isHidden()){
r.add(recipe); returnArray.add(recipe);
} }
} }
return returnArray;
} }
public static Recipe getByResult(Block block){ public static Recipe getByResult(Block block){

View File

@@ -31,7 +31,7 @@ public class OverlayFragment extends Fragment{
config.build(group); config.build(group);
consume.build(group); consume.build(group);
input.buildUI(group); //input.buildUI(group);
} }
public void remove(){ public void remove(){

View File

@@ -2,7 +2,6 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
@@ -29,7 +28,6 @@ import static io.anuke.mindustry.Vars.*;
public class PlacementFragment extends Fragment{ public class PlacementFragment extends Fragment{
final int rowWidth = 4; final int rowWidth = 4;
Array<Recipe> returned = new Array<>();
Category currentCategory = Category.turret; Category currentCategory = Category.turret;
Block hovered, lastDisplay; Block hovered, lastDisplay;
Tile hoverTile; Tile hoverTile;
@@ -44,6 +42,7 @@ public class PlacementFragment extends Fragment{
full.table(frame -> { full.table(frame -> {
InputHandler input = control.input(0); InputHandler input = control.input(0);
//rebuilds the category table with the correct recipes //rebuilds the category table with the correct recipes
Runnable rebuildCategory = () -> { Runnable rebuildCategory = () -> {
blockTable.clear(); blockTable.clear();
@@ -54,7 +53,7 @@ public class PlacementFragment extends Fragment{
ButtonGroup<ImageButton> group = new ButtonGroup<>(); ButtonGroup<ImageButton> group = new ButtonGroup<>();
group.setMinCheckCount(0); group.setMinCheckCount(0);
for(Recipe recipe : recipes(currentCategory)){ for(Recipe recipe : Recipe.getByCategory(currentCategory)){
if(index++ % rowWidth == 0){ if(index++ % rowWidth == 0){
blockTable.row(); blockTable.row();
@@ -98,6 +97,7 @@ public class PlacementFragment extends Fragment{
blockTable.act(0f); blockTable.act(0f);
}; };
//top table with hover info
frame.table("clear", top -> { frame.table("clear", top -> {
top.add(new Table()).growX().update(topTable -> { top.add(new Table()).growX().update(topTable -> {
if((tileDisplayBlock() == null && lastDisplay == getSelected()) || if((tileDisplayBlock() == null && lastDisplay == getSelected()) ||
@@ -113,12 +113,12 @@ public class PlacementFragment extends Fragment{
header.left(); header.left();
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8*4); header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8*4);
header.labelWrap(() -> header.labelWrap(() ->
!control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName) !control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5); .left().width(190f).padLeft(5);
header.add().growX(); header.add().growX();
if(control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay))){ if(control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay))){
header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay))) header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay)))
.size(8 * 5).padTop(-5).padRight(-5).right().grow(); .size(8 * 5).padTop(-5).padRight(-5).right().grow();
} }
}).growX().left(); }).growX().left();
topTable.row(); topTable.row();
@@ -155,15 +155,19 @@ public class PlacementFragment extends Fragment{
top.addImage("blank").growX().color(Palette.accent).height(3f); top.addImage("blank").growX().color(Palette.accent).height(3f);
}).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled); }).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled);
frame.row(); frame.row();
frame.table("clear", blocks -> blockTable = blocks).fillY().bottom().touchable(Touchable.enabled); frame.table("clear", blocksSelect -> {
blocksSelect.table(blocks -> blockTable = blocks).grow();
blocksSelect.row();
blocksSelect.table(input::buildUI).growX();
}).fillY().bottom().touchable(Touchable.enabled);
frame.addImage("blank").width(3f).fillY().color(Palette.accent); frame.addImage("blank").width(3f).fillY().color(Palette.accent);
frame.table(categories -> { frame.table(categories -> {
categories.defaults().size(48f); categories.defaults().size(50f);
ButtonGroup<ImageButton> group = new ButtonGroup<>(); ButtonGroup<ImageButton> group = new ButtonGroup<>();
for(Category cat : Category.values()){ for(Category cat : Category.values()){
if(recipes(cat).isEmpty()) continue; if(Recipe.getByCategory(cat).isEmpty()) continue;
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16*2, () -> { categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16*2, () -> {
currentCategory = cat; currentCategory = cat;
@@ -213,15 +217,7 @@ public class PlacementFragment extends Fragment{
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null; return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null;
} }
Array<Recipe> recipes(Category cat){ /**Show or hide the placement menu.*/
returned.clear();
for(Recipe recipe : content.recipes()){
if(recipe.category != cat || recipe.isHidden()) continue;
returned.add(recipe);
}
return returned;
}
void toggle(float t, Interpolation ip){ void toggle(float t, Interpolation ip){
if(shown){ if(shown){
shown = false; shown = false;