Added all placement controls
This commit is contained in:
@@ -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},
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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(){
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user