mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-09 07:17:36 +07:00
Place menu scrolling, fixed some settings menu bugs
This commit is contained in:
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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{
|
||||
|
||||
|
@ -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("-------------------");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
5
core/src/io/anuke/mindustry/input/PlaceMode.java
Normal file
5
core/src/io/anuke/mindustry/input/PlaceMode.java
Normal file
@ -0,0 +1,5 @@
|
||||
package io.anuke.mindustry.input;
|
||||
|
||||
enum PlaceMode{
|
||||
none, breaking, placing;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package io.anuke.mindustry.type;
|
||||
|
||||
public enum Section{
|
||||
public enum Category {
|
||||
weapon, production, distribution, liquid, power, defense, crafting, units
|
||||
}
|
@ -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<Recipe> 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<Recipe> getBySection(Section section, Array<Recipe> 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<Recipe> 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<Recipe> r){
|
||||
r.clear();
|
||||
for(Recipe recipe : allRecipes){
|
||||
if(recipe.category == category) {
|
||||
r.add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Array<Recipe> all(){
|
||||
|
@ -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<Recipe> 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<ImageButton> group = new ButtonGroup<>();
|
||||
Array<Recipe> 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);
|
||||
|
||||
//empty section, nothing to see here
|
||||
if(recipes.size == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Section sec : Section.values()) {
|
||||
int secrows = 4;
|
||||
//table where actual recipes go
|
||||
Table recipeTable = new Table();
|
||||
recipeTable.margin(4).top().left().marginRight(15);
|
||||
|
||||
recipes.clear();
|
||||
Recipe.getBySection(sec, recipes);
|
||||
|
||||
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){
|
||||
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(event.getPointer());
|
||||
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;
|
||||
hoverRecipe = r;
|
||||
updateRecipe(r);
|
||||
} else {
|
||||
handler.recipe = null;
|
||||
hoveredDescriptionRecipe = 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(){
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -81,17 +81,17 @@ 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)
|
||||
if (type.solid || type.solidifes)
|
||||
synchronized (Entities.entityLock) {
|
||||
try {
|
||||
|
||||
@ -108,43 +108,38 @@ public class Build {
|
||||
});
|
||||
|
||||
if (result[0]) return false;
|
||||
}catch (Exception e){
|
||||
} 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)
|
||||
&& 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);
|
||||
|
Reference in New Issue
Block a user