Merge
This commit is contained in:
@@ -32,8 +32,10 @@ public class Bar extends Element{
|
||||
|
||||
public Bar(Supplier<String> name, Supplier<Color> color, FloatProvider fraction){
|
||||
this.fraction = fraction;
|
||||
lastValue = value = Mathf.clamp(fraction.get());
|
||||
update(() -> {
|
||||
this.name = name.get();
|
||||
this.blinkColor.set(color.get());
|
||||
setColor(color.get());
|
||||
});
|
||||
}
|
||||
@@ -45,13 +47,14 @@ public class Bar extends Element{
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
if(!Mathf.isEqual(lastValue, fraction.get())){
|
||||
float computed = Mathf.clamp(fraction.get());
|
||||
if(!Mathf.isEqual(lastValue, computed)){
|
||||
blink = 1f;
|
||||
lastValue = fraction.get();
|
||||
lastValue = computed;
|
||||
}
|
||||
|
||||
blink = Mathf.lerpDelta(blink, 0f, 0.2f);
|
||||
value = Mathf.lerpDelta(value, fraction.get(), 0.15f);
|
||||
value = Mathf.lerpDelta(value, computed, 0.15f);
|
||||
|
||||
Draw.colorl(0.1f);
|
||||
Draw.drawable("bar", x, y, width, height);
|
||||
@@ -75,6 +78,7 @@ public class Bar extends Element{
|
||||
GlyphLayout lay = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
|
||||
lay.setText(font, name);
|
||||
|
||||
font.setColor(Color.WHITE);
|
||||
font.draw(name, x + width/2f - lay.width/2f, y + height/2f + lay.height/2f + 1);
|
||||
|
||||
Pools.free(lay);
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.graphics.Texture;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
@@ -36,7 +36,7 @@ public class BorderImage extends Image{
|
||||
float scaleX = getScaleX();
|
||||
float scaleY = getScaleY();
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
Draw.color(Pal.accent);
|
||||
Lines.stroke(Unit.dp.scl(thickness));
|
||||
Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY);
|
||||
Draw.reset();
|
||||
|
||||
@@ -5,8 +5,8 @@ import io.anuke.arc.collection.OrderedMap;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.mindustry.entities.units.UnitType;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.UnitType;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.type.Mech;
|
||||
@@ -25,7 +25,7 @@ public class ContentDisplay{
|
||||
int size = 8 * 6;
|
||||
|
||||
title.addImage(block.icon(Icon.large)).size(size);
|
||||
title.add("[accent]" + block.formalName).padLeft(5);
|
||||
title.add("[accent]" + block.localizedName).padLeft(5);
|
||||
});
|
||||
|
||||
table.row();
|
||||
@@ -34,8 +34,8 @@ public class ContentDisplay{
|
||||
|
||||
table.row();
|
||||
|
||||
if(block.fullDescription != null){
|
||||
table.add(block.fullDescription).padLeft(5).padRight(5).width(400f).wrap().fillX();
|
||||
if(block.description != null){
|
||||
table.add(block.description).padLeft(5).padRight(5).width(400f).wrap().fillX();
|
||||
table.row();
|
||||
|
||||
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(8).padLeft(0).padRight(0).fillX();
|
||||
@@ -49,7 +49,7 @@ public class ContentDisplay{
|
||||
|
||||
if(map.size == 0) continue;
|
||||
|
||||
table.add("$category." + cat.name()).color(Palette.accent).fillX();
|
||||
table.add("$category." + cat.name()).color(Pal.accent).fillX();
|
||||
table.row();
|
||||
|
||||
for(BlockStat stat : map.keys()){
|
||||
@@ -86,13 +86,11 @@ public class ContentDisplay{
|
||||
|
||||
table.left().defaults().fillX();
|
||||
|
||||
table.add(Core.bundle.format("item.explosiveness", (int) (item.explosiveness * 100 * 2f)));
|
||||
table.add(Core.bundle.format("item.explosiveness", (int) (item.explosiveness * 100)));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("item.flammability", (int) (item.flammability * 100 * 2f)));
|
||||
table.add(Core.bundle.format("item.flammability", (int) (item.flammability * 100)));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("item.radioactivity", (int) (item.radioactivity * 100 * 2f)));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("item.fluxiness", (int) (item.fluxiness * 100 * 2f)));
|
||||
table.add(Core.bundle.format("item.radioactivity", (int) (item.radioactivity * 100)));
|
||||
table.row();
|
||||
}
|
||||
|
||||
@@ -119,9 +117,9 @@ public class ContentDisplay{
|
||||
|
||||
table.left().defaults().fillX();
|
||||
|
||||
table.add(Core.bundle.format("item.explosiveness", (int) (liquid.explosiveness * 100 * 2f)));
|
||||
table.add(Core.bundle.format("item.explosiveness", (int) (liquid.explosiveness * 100)));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("item.flammability", (int) (liquid.flammability * 100 * 2f)));
|
||||
table.add(Core.bundle.format("item.flammability", (int) (liquid.flammability * 100)));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("liquid.heatcapacity", (int) (liquid.heatCapacity * 100)));
|
||||
table.row();
|
||||
@@ -161,7 +159,7 @@ public class ContentDisplay{
|
||||
table.add(Core.bundle.format("mech.ability", Core.bundle.get("mech." + mech.name + ".ability")));
|
||||
table.row();
|
||||
}
|
||||
table.add(Core.bundle.format("mech.armor", mech.armor));
|
||||
table.add(Core.bundle.format("mech.health", (int)mech.health));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("mech.itemcapacity", mech.itemCapacity));
|
||||
table.row();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.arc.function.Supplier;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
@@ -9,6 +10,14 @@ import io.anuke.arc.scene.ui.layout.Table;
|
||||
|
||||
public class ItemImage extends Stack{
|
||||
|
||||
public ItemImage(TextureRegion region, int amount){
|
||||
Table t = new Table().left().bottom();
|
||||
t.add(amount + "").name("item-label");
|
||||
|
||||
add(new Image(region));
|
||||
add(t);
|
||||
}
|
||||
|
||||
public ItemImage(TextureRegion region, Supplier<CharSequence> text){
|
||||
Table t = new Table().left().bottom();
|
||||
t.label(text).name("item-label");
|
||||
@@ -18,7 +27,7 @@ public class ItemImage extends Stack{
|
||||
}
|
||||
|
||||
public ItemImage(ItemStack stack){
|
||||
add(new Image(stack.item.region));
|
||||
add(new Image(stack.item.icon(Icon.medium)));
|
||||
|
||||
if(stack.amount != 0){
|
||||
Table t = new Table().left().bottom();
|
||||
|
||||
41
core/src/io/anuke/mindustry/ui/ItemsDisplay.java
Normal file
41
core/src/io/anuke/mindustry/ui/ItemsDisplay.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.collection.ObjectIntMap;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.type.ItemType;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import static io.anuke.mindustry.Vars.content;
|
||||
import static io.anuke.mindustry.Vars.data;
|
||||
|
||||
public class ItemsDisplay extends Table{
|
||||
private static final NumberFormat format = NumberFormat.getNumberInstance(Locale.getDefault());
|
||||
|
||||
public ItemsDisplay(){
|
||||
rebuild();
|
||||
}
|
||||
|
||||
public void rebuild(){
|
||||
clear();
|
||||
top().left();
|
||||
margin(0);
|
||||
|
||||
table("flat", t -> {
|
||||
t.margin(10).marginLeft(15).marginTop(15f);
|
||||
ObjectIntMap<Item> items = data.items();
|
||||
for(Item item : content.items()){
|
||||
if(item.type == ItemType.material && data.isUnlocked(item)){
|
||||
t.label(() -> format.format(items.get(item, 0))).left();
|
||||
t.addImage(item.icon(Icon.medium)).size(8*3).padLeft(4).padRight(4);
|
||||
t.add(item.localizedName()).color(Color.LIGHT_GRAY).left();
|
||||
t.row();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ public class Links{
|
||||
|
||||
private static void createLinks(){
|
||||
links = new LinkEntry[]{
|
||||
new LinkEntry("discord", "https://discord.gg/BKADYds", Color.valueOf("7289da")),
|
||||
new LinkEntry("discord", "https://discord.gg/mindustry", Color.valueOf("7289da")),
|
||||
new LinkEntry("trello", "https://trello.com/b/aE2tcUwF", Color.valueOf("026aa7")),
|
||||
new LinkEntry("wiki", "http://mindustry.wikia.com/wiki/Mindustry_Wiki", Color.valueOf("0f142f")),
|
||||
new LinkEntry("itch.io", "https://anuke.itch.io/mindustry", Color.valueOf("fa5c5c")),
|
||||
|
||||
31
core/src/io/anuke/mindustry/ui/MultiReqImage.java
Normal file
31
core/src/io/anuke/mindustry/ui/MultiReqImage.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.util.Time;
|
||||
|
||||
public class MultiReqImage extends Stack{
|
||||
private Array<ReqImage> displays = new Array<>();
|
||||
private float time;
|
||||
|
||||
public void add(ReqImage display){
|
||||
displays.add(display);
|
||||
super.add(display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta){
|
||||
super.act(delta);
|
||||
|
||||
time += Time.delta() / 60f;
|
||||
|
||||
displays.each(req -> req.visible(false));
|
||||
|
||||
ReqImage valid = displays.find(ReqImage::valid);
|
||||
if(valid != null){
|
||||
valid.visible(true);
|
||||
}else{
|
||||
displays.get((int)(time) % displays.size).visible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
core/src/io/anuke/mindustry/ui/ReqImage.java
Normal file
42
core/src/io/anuke/mindustry/ui/ReqImage.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package io.anuke.mindustry.ui;
|
||||
|
||||
import io.anuke.arc.function.BooleanProvider;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.Element;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
|
||||
public class ReqImage extends Stack{
|
||||
private final BooleanProvider valid;
|
||||
|
||||
public ReqImage(Element image, BooleanProvider valid){
|
||||
this.valid = valid;
|
||||
add(image);
|
||||
add(new Element(){
|
||||
{
|
||||
visible(() -> !valid.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Lines.stroke(Unit.dp.scl(2f), Pal.removeBack);
|
||||
Lines.line(x, y - 2f + height, x + width, y - 2f);
|
||||
Draw.color(Pal.remove);
|
||||
Lines.line(x, y + height, x + width, y);
|
||||
Draw.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ReqImage(TextureRegion region, BooleanProvider valid){
|
||||
this(new Image(region), valid);
|
||||
}
|
||||
|
||||
public boolean valid(){
|
||||
return valid.get();
|
||||
}
|
||||
}
|
||||
@@ -292,12 +292,12 @@ public class TreeLayout{
|
||||
center, towardsRoot, awayFromRoot
|
||||
}
|
||||
|
||||
public static class TreeNode{
|
||||
public static class TreeNode<T extends TreeNode>{
|
||||
public float width, height, x, y;
|
||||
|
||||
//should be initialized by user
|
||||
public TreeNode[] children;
|
||||
public TreeNode parent;
|
||||
public T[] children;
|
||||
public T parent;
|
||||
|
||||
private float mode, prelim, change, shift;
|
||||
private int number = -1;
|
||||
|
||||
@@ -4,7 +4,7 @@ import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectSet;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.io.Contributors;
|
||||
import io.anuke.mindustry.io.Contributors.Contributor;
|
||||
import io.anuke.mindustry.ui.Links;
|
||||
@@ -103,7 +103,7 @@ public class AboutDialog extends FloatingDialog{
|
||||
dialog.cont.add("$credits.text");
|
||||
dialog.cont.row();
|
||||
if(!contributors.isEmpty()){
|
||||
dialog.cont.addImage("blank").color(Palette.accent).fillX().height(3f).pad(3f);
|
||||
dialog.cont.addImage("blank").color(Pal.accent).fillX().height(3f).pad(3f);
|
||||
dialog.cont.row();
|
||||
dialog.cont.add("$contributors");
|
||||
dialog.cont.row();
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.KeybindDialog;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
|
||||
public class ControlsDialog extends KeybindDialog{
|
||||
|
||||
@@ -16,7 +16,7 @@ public class ControlsDialog extends KeybindDialog{
|
||||
title.setAlignment(Align.center);
|
||||
titleTable.row();
|
||||
titleTable.add(new Image("white"))
|
||||
.growX().height(3f).pad(4f).get().setColor(Palette.accent);
|
||||
.growX().height(3f).pad(4f).get().setColor(Pal.accent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class CustomGameDialog extends FloatingDialog{
|
||||
Difficulty difficulty = Difficulty.normal;
|
||||
RulePreset lastPreset = RulePreset.survival;
|
||||
|
||||
public CustomGameDialog(){
|
||||
super("$customgame");
|
||||
@@ -30,6 +31,7 @@ public class CustomGameDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
void setup(){
|
||||
state.rules = lastPreset.get();
|
||||
cont.clear();
|
||||
|
||||
Table maps = new Table();
|
||||
@@ -48,10 +50,10 @@ public class CustomGameDialog extends FloatingDialog{
|
||||
modes.marginBottom(5);
|
||||
|
||||
for(RulePreset mode : RulePreset.values()){
|
||||
|
||||
//todo fix presets
|
||||
modes.addButton(mode.toString(), "toggle", () -> state.rules = mode.get())/*
|
||||
.update(b -> b.setChecked(state.rules == mode))*/.group(group).size(140f, 54f);
|
||||
modes.addButton(mode.toString(), "toggle", () -> {
|
||||
state.rules = mode.get();
|
||||
lastPreset = mode;
|
||||
}).update(b -> b.setChecked(lastPreset == mode)).group(group).size(140f, 54f);
|
||||
if(i++ % 2 == 1) modes.row();
|
||||
}
|
||||
selmode.add(modes);
|
||||
@@ -112,7 +114,7 @@ public class CustomGameDialog extends FloatingDialog{
|
||||
|
||||
image.clicked(() -> {
|
||||
hide();
|
||||
control.playMap(map);
|
||||
control.playMap(map, lastPreset.get());
|
||||
});
|
||||
|
||||
maps.add(image);
|
||||
@@ -120,14 +122,6 @@ public class CustomGameDialog extends FloatingDialog{
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
ImageButton gen = maps.addImageButton("icon-editor", "clear", 16*4, () -> {
|
||||
hide();
|
||||
world.generator.playRandomMap();
|
||||
}).growY().get();
|
||||
gen.row();
|
||||
gen.add("$map.random");*/
|
||||
|
||||
if(world.maps.all().size == 0){
|
||||
maps.add("$maps.none").pad(50);
|
||||
}
|
||||
@@ -136,7 +130,7 @@ public class CustomGameDialog extends FloatingDialog{
|
||||
}
|
||||
|
||||
private void displayGameModeHelp(){
|
||||
FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.text.help.title"));
|
||||
FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.help.title"));
|
||||
d.setFillParent(false);
|
||||
Table table = new Table();
|
||||
table.defaults().pad(1f);
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.game.Content;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
import io.anuke.arc.scene.event.HandCursorListener;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.ScrollPane;
|
||||
import io.anuke.arc.scene.ui.Tooltip;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.utils.UIUtils;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Content;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
|
||||
public class DatabaseDialog extends FloatingDialog{
|
||||
|
||||
public DatabaseDialog(){
|
||||
super("database");
|
||||
super("$database");
|
||||
|
||||
shouldPause = true;
|
||||
addCloseButton();
|
||||
@@ -38,31 +37,29 @@ public class DatabaseDialog extends FloatingDialog{
|
||||
for(int j = 0; j < allContent.length; j ++){
|
||||
ContentType type = ContentType.values()[j];
|
||||
|
||||
Array<Content> array = allContent[j];
|
||||
if(array.size == 0 || !(array.first() instanceof UnlockableContent)) continue;
|
||||
Array<Content> array = allContent[j].select(c -> c instanceof UnlockableContent && !((UnlockableContent)c).isHidden());
|
||||
if(array.size == 0) continue;
|
||||
|
||||
table.add("$content." + type.name() + ".name").growX().left().color(Palette.accent);
|
||||
table.add("$content." + type.name() + ".name").growX().left().color(Pal.accent);
|
||||
table.row();
|
||||
table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Palette.accent);
|
||||
table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent);
|
||||
table.row();
|
||||
table.table(list -> {
|
||||
list.left();
|
||||
|
||||
int maxWidth = UIUtils.portrait() ? 7 : 13;
|
||||
int size = 8 * 6;
|
||||
int size = 8 * 4;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for(int i = 0; i < array.size; i++){
|
||||
UnlockableContent unlock = (UnlockableContent) array.get(i);
|
||||
|
||||
if(unlock.isHidden()) continue;
|
||||
|
||||
Image image = data.isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-tree-locked");
|
||||
Image image = unlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-tree-locked");
|
||||
image.addListener(new HandCursorListener());
|
||||
list.add(image).size(size).pad(3);
|
||||
|
||||
if(data.isUnlocked(unlock)){
|
||||
if(unlocked(unlock)){
|
||||
image.clicked(() -> Vars.ui.content.show(unlock));
|
||||
image.addListener(new Tooltip<>(new Table("button"){{
|
||||
add(unlock.localizedName());
|
||||
@@ -79,4 +76,8 @@ public class DatabaseDialog extends FloatingDialog{
|
||||
|
||||
cont.add(pane);
|
||||
}
|
||||
|
||||
boolean unlocked(UnlockableContent content){
|
||||
return (!Vars.world.isZone() && !Vars.state.is(State.menu)) || content.unlocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,198 +1,102 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.ObjectIntMap;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.ScrollPane;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectSet;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.ui.TextButton;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.arc.util.Structs;
|
||||
import io.anuke.mindustry.content.Zones;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.io.SaveIO.SaveException;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.ItemType;
|
||||
import io.anuke.mindustry.type.Zone;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
import io.anuke.mindustry.ui.ItemsDisplay;
|
||||
import io.anuke.mindustry.ui.TreeLayout;
|
||||
import io.anuke.mindustry.ui.TreeLayout.TreeNode;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class DeployDialog extends FloatingDialog{
|
||||
private final float nodeSize = Unit.dp.scl(210f);
|
||||
private ObjectSet<ZoneNode> nodes = new ObjectSet<>();
|
||||
private ZoneInfoDialog info = new ZoneInfoDialog();
|
||||
|
||||
public DeployDialog(){
|
||||
super("$play");
|
||||
super("");
|
||||
|
||||
shown(this::setup);
|
||||
}
|
||||
ZoneNode root = new ZoneNode(Zones.groundZero, null);
|
||||
|
||||
void setup(){
|
||||
buttons.clear();
|
||||
cont.clear();
|
||||
TreeLayout layout = new TreeLayout();
|
||||
layout.gapBetweenLevels = layout.gapBetweenNodes = Unit.dp.scl(50f);
|
||||
layout.layout(root);
|
||||
|
||||
addCloseButton();
|
||||
buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f);
|
||||
|
||||
cont.stack(new Table(){{
|
||||
top().left().margin(10);
|
||||
shown(this::setup);
|
||||
}
|
||||
|
||||
ObjectIntMap<Item> items = data.items();
|
||||
for(Item item : content.items()){
|
||||
if(item.type == ItemType.material && data.isUnlocked(item)){
|
||||
label(() -> items.get(item, 0) + "").left();
|
||||
addImage(item.region).size(8*4).pad(4);
|
||||
add("[LIGHT_GRAY]" + item.localizedName()).left();
|
||||
row();
|
||||
}
|
||||
}
|
||||
public void setup(){
|
||||
cont.clear();
|
||||
titleTable.remove();
|
||||
margin(0f).marginBottom(8);
|
||||
|
||||
}}, new ScrollPane(new Table(){{
|
||||
if(!Core.settings.getBool("zone-info", false)){
|
||||
Core.app.post(() -> ui.showInfoText("TEMPORARY GUIDE ON HOW TO PLAY ZONES", "- deploy to zones by selecting them here\n- most zones require items to deploy\n- once you survive a set amount of waves, you can launch all the resources in your core\n- use these items to research in the tech tree or uncover new zones"));
|
||||
|
||||
if(control.saves.getZoneSlot() == null){
|
||||
Core.settings.put("zone-info", true);
|
||||
Core.settings.save();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for(Zone zone : content.zones()){
|
||||
table(t -> {
|
||||
TextButton button = t.addButton("", () -> {
|
||||
if(!data.isUnlocked(zone)){
|
||||
data.removeItems(zone.itemRequirements);
|
||||
data.unlockContent(zone);
|
||||
setup();
|
||||
}else{
|
||||
data.removeItems(zone.deployCost);
|
||||
hide();
|
||||
world.playZone(zone);
|
||||
}
|
||||
}).size(250f).disabled(b -> !canUnlock(zone)).get();
|
||||
cont.stack(control.saves.getZoneSlot() == null ? new View() : new Table(){{
|
||||
SaveSlot slot = control.saves.getZoneSlot();
|
||||
|
||||
button.clearChildren();
|
||||
TextButton[] b = {null};
|
||||
|
||||
if(data.isUnlocked(zone)){
|
||||
button.table(title -> {
|
||||
title.addImage("icon-zone").padRight(3);
|
||||
title.add(zone.localizedName());
|
||||
});
|
||||
button.row();
|
||||
TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> {
|
||||
if(b[0].childrenPressed()) return;
|
||||
|
||||
if(data.getWaveScore(zone) > 0){
|
||||
button.add(Core.bundle.format("bestwave", data.getWaveScore(zone)));
|
||||
}
|
||||
|
||||
button.row();
|
||||
|
||||
button.add("$launch").color(Color.LIGHT_GRAY).pad(4);
|
||||
button.row();
|
||||
button.table(req -> {
|
||||
for(ItemStack stack : zone.deployCost){
|
||||
req.addImage(stack.item.region).size(8 * 3);
|
||||
req.add(stack.amount + "").left();
|
||||
}
|
||||
}).pad(3).growX();
|
||||
}else{
|
||||
button.addImage("icon-zone-locked");
|
||||
button.row();
|
||||
button.add("$locked").padBottom(6);
|
||||
|
||||
if(!hidden(zone)){
|
||||
button.row();
|
||||
|
||||
button.table(req -> {
|
||||
req.defaults().left();
|
||||
|
||||
if(zone.zoneRequirements.length > 0){
|
||||
req.table(r -> {
|
||||
r.add("$complete").colspan(2).left();
|
||||
r.row();
|
||||
for(Zone other : zone.zoneRequirements){
|
||||
r.addImage("icon-zone").padRight(4);
|
||||
r.add(other.localizedName()).color(Color.LIGHT_GRAY);
|
||||
r.addImage(data.isCompleted(zone) ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(data.isCompleted(zone) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
req.row();
|
||||
|
||||
if(zone.itemRequirements.length > 0){
|
||||
req.table(r -> {
|
||||
for(ItemStack stack : zone.itemRequirements){
|
||||
r.addImage(stack.item.region).size(8 * 3).padRight(4);
|
||||
r.add(Math.min(data.getItem(stack.item), stack.amount) + "/" + stack.amount)
|
||||
.color(stack.amount > data.getItem(stack.item) ? Color.SCARLET : Color.LIGHT_GRAY).left();
|
||||
r.row();
|
||||
}
|
||||
}).padTop(10);
|
||||
}
|
||||
|
||||
req.row();
|
||||
|
||||
if(zone.blockRequirements.length > 0){
|
||||
req.table(r -> {
|
||||
r.add("$research.list").colspan(2).left();
|
||||
r.row();
|
||||
for(Block block : zone.blockRequirements){
|
||||
r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4);
|
||||
r.add(block.formalName).color(Color.LIGHT_GRAY);
|
||||
r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
|
||||
}).padTop(10);
|
||||
}
|
||||
}).growX();
|
||||
}
|
||||
}
|
||||
}).pad(4);
|
||||
|
||||
if(++i % 2 == 0){
|
||||
row();
|
||||
hide();
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
control.saves.getZoneSlot().load();
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){ //make sure to handle any save load errors!
|
||||
e.printStackTrace();
|
||||
if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete();
|
||||
Core.app.post(() -> ui.showInfo("$save.corrupted"));
|
||||
show();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
SaveSlot slot = control.saves.getZoneSlot();
|
||||
});
|
||||
}).size(230f).get();
|
||||
b[0] = button;
|
||||
|
||||
TextButton b[] = {null};
|
||||
String color = "[lightgray]";
|
||||
|
||||
TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> {
|
||||
if(b[0].childrenPressed()) return;
|
||||
button.defaults().colspan(2);
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
button.row();
|
||||
button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
button.row();
|
||||
button.add().grow();
|
||||
button.row();
|
||||
|
||||
hide();
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
control.saves.getZoneSlot().load();
|
||||
state.set(State.playing);
|
||||
}catch(SaveException e){ //make sure to handle any save load errors!
|
||||
e.printStackTrace();
|
||||
if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete();
|
||||
ui.showInfo("$save.corrupted");
|
||||
show();
|
||||
}
|
||||
});
|
||||
}).size(200f).get();
|
||||
b[0] = button;
|
||||
button.addButton("$abandon", () -> {
|
||||
ui.showConfirm("$warning", "$abandon.text", () -> {
|
||||
slot.delete();
|
||||
setup();
|
||||
});
|
||||
}).growX().height(50f).pad(-12).padTop(10);
|
||||
|
||||
String color = "[lightgray]";
|
||||
|
||||
button.defaults().colspan(2);
|
||||
button.row();
|
||||
button.add(Core.bundle.format("save.wave", color + slot.getWave()));
|
||||
button.row();
|
||||
button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime()));
|
||||
button.row();
|
||||
button.add().grow();
|
||||
button.row();
|
||||
|
||||
button.addButton("$abandon", () -> {
|
||||
ui.showConfirm("$warning", "$abandon.text", () -> {
|
||||
slot.delete();
|
||||
setup();
|
||||
});
|
||||
}).growX().height(50f).pad(-12).padTop(10);
|
||||
}
|
||||
}})).grow();
|
||||
}}, new ItemsDisplay()).grow();
|
||||
}
|
||||
|
||||
boolean hidden(Zone zone){
|
||||
@@ -204,19 +108,81 @@ public class DeployDialog extends FloatingDialog{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canUnlock(Zone zone){
|
||||
for(Zone other : zone.zoneRequirements){
|
||||
if(!data.isCompleted(other)){
|
||||
return false;
|
||||
@Override
|
||||
protected void drawBackground(float x, float y){
|
||||
drawDefaultBackground(x, y);
|
||||
}
|
||||
|
||||
void buildButton(Zone zone, TextButton button){
|
||||
button.setDisabled(() -> hidden(zone));
|
||||
button.clicked(() -> info.show(zone));
|
||||
|
||||
if(zone.unlocked()){
|
||||
button.addImage("icon-zone").padRight(3);
|
||||
button.labelWrap(zone.localizedName()).width(140).growX();
|
||||
}else{
|
||||
button.addImage("icon-zone-locked");
|
||||
button.row();
|
||||
button.add("$locked");
|
||||
}
|
||||
}
|
||||
|
||||
//should be static variables of View, but that's impossible
|
||||
static float panX = 0, panY = -200;
|
||||
|
||||
class View extends Group{
|
||||
|
||||
{
|
||||
for(ZoneNode node : nodes){
|
||||
TextButton button = new TextButton("", "node");
|
||||
button.setSize(node.width, node.height);
|
||||
button.update(() -> {
|
||||
button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center);
|
||||
});
|
||||
button.clearChildren();
|
||||
buildButton(node.zone, button);
|
||||
addChild(button);
|
||||
}
|
||||
|
||||
dragged((x, y) -> {
|
||||
panX += x;
|
||||
panY += y;
|
||||
});
|
||||
}
|
||||
|
||||
for(Block other : zone.blockRequirements){
|
||||
if(!data.isUnlocked(other)){
|
||||
return false;
|
||||
@Override
|
||||
public void draw(){
|
||||
float offsetX = panX + width/2f + x, offsetY = panY + height/2f + y;
|
||||
|
||||
for(ZoneNode node : nodes){
|
||||
for(ZoneNode child : node.children){
|
||||
Lines.stroke(Unit.dp.scl(3f), node.zone.locked() || child.zone.locked() ? Pal.locked : Pal.accent);
|
||||
Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class ZoneNode extends TreeNode<ZoneNode>{
|
||||
final Array<Zone> arr = new Array<>();
|
||||
final Zone zone;
|
||||
|
||||
ZoneNode(Zone zone, ZoneNode parent){
|
||||
this.zone = zone;
|
||||
this.parent = parent;
|
||||
this.width = this.height = nodeSize;
|
||||
this.height /= 2f;
|
||||
nodes.add(this);
|
||||
|
||||
arr.selectFrom(content.zones(), other -> Structs.contains(other.zoneRequirements, zone));
|
||||
|
||||
children = new ZoneNode[arr.size];
|
||||
for(int i = 0; i < children.length; i++){
|
||||
children[i] = new ZoneNode(arr.get(i), this);
|
||||
}
|
||||
}
|
||||
|
||||
return data.hasItems(zone.itemRequirements);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.arc.scene.ui.Dialog;
|
||||
|
||||
import static io.anuke.mindustry.Vars.discordURL;
|
||||
@@ -33,7 +33,7 @@ public class DiscordDialog extends Dialog{
|
||||
i.addImage("icon-discord").size(14 * 3);
|
||||
}).size(h).left();
|
||||
|
||||
t.add("$discord").color(Palette.accent).growX().padLeft(10f);
|
||||
t.add("$discord").color(Pal.accent).growX().padLeft(10f);
|
||||
}).size(470f, h).pad(10f);
|
||||
|
||||
buttons.defaults().size(170f, 50);
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.EventType.ResizeEvent;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.scene.ui.Dialog;
|
||||
@@ -22,7 +22,7 @@ public class FloatingDialog extends Dialog{
|
||||
setFillParent(true);
|
||||
this.title.setAlignment(Align.center);
|
||||
titleTable.row();
|
||||
titleTable.addImage("white", Palette.accent)
|
||||
titleTable.addImage("white", Pal.accent)
|
||||
.growX().height(3f).pad(4f);
|
||||
|
||||
hidden(() -> {
|
||||
@@ -63,7 +63,7 @@ public class FloatingDialog extends Dialog{
|
||||
|
||||
@Override
|
||||
public void addCloseButton(){
|
||||
buttons.addImageTextButton("$back", "icon-arrow-left", 30f, this::hide).size(230f, 64f);
|
||||
buttons.addImageTextButton("$back", "icon-arrow-left", 30f, this::hide).size(210f, 64f);
|
||||
|
||||
keyDown(key -> {
|
||||
if(key == KeyCode.ESCAPE || key == KeyCode.BACK) {
|
||||
|
||||
@@ -2,8 +2,10 @@ package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.Stats.RankResult;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -60,12 +62,18 @@ public class GameOverDialog extends FloatingDialog{
|
||||
if(state.stats.itemsDelivered.get(item, 0) > 0){
|
||||
cont.table(items -> {
|
||||
items.add(" [LIGHT_GRAY]" + state.stats.itemsDelivered.get(item, 0));
|
||||
items.addImage(item.region).size(8 *3).pad(4);
|
||||
items.addImage(item.icon(Icon.medium)).size(8 *3).pad(4);
|
||||
}).left();
|
||||
cont.row();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(world.isZone()){
|
||||
RankResult result = state.stats.calculateRank(world.getZone(), state.launched);
|
||||
cont.add(Core.bundle.format("stat.rank", result.rank + result.modifier));
|
||||
cont.row();
|
||||
}
|
||||
}).pad(12);
|
||||
|
||||
if(world.isZone()){
|
||||
|
||||
@@ -6,7 +6,7 @@ import io.anuke.arc.scene.ui.ImageButton;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -14,7 +14,7 @@ import io.anuke.arc.util.Strings;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.Platform;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.game.Version;
|
||||
import io.anuke.mindustry.net.Host;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Scaling;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
|
||||
import static io.anuke.mindustry.Vars.control;
|
||||
import static io.anuke.mindustry.Vars.players;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class MapsDialog extends FloatingDialog{
|
||||
TextButton button = maps.addButton("", "clear", () -> showMapInfo(map)).width(mapsize).pad(8).get();
|
||||
button.clearChildren();
|
||||
button.margin(9);
|
||||
button.add(map.meta.tags.get("name", map.name)).growX().center().get().setEllipsis(true);
|
||||
button.add(map.meta.tags.get("name", map.name)).width(mapsize - 18f).center().get().setEllipsis(true);
|
||||
button.row();
|
||||
button.addImage("white").growX().pad(4).color(Color.GRAY);
|
||||
button.row();
|
||||
@@ -138,8 +138,6 @@ public class MapsDialog extends FloatingDialog{
|
||||
t.add(map.meta.description()).growX().wrap().padTop(2);
|
||||
t.row();
|
||||
t.add("$editor.oregen.info").padRight(10).color(Color.GRAY);
|
||||
t.row();
|
||||
t.add(map.meta.hasOreGen() ? "$on" : "$off").padTop(2);
|
||||
}).height(mapsize).width(mapsize);
|
||||
|
||||
table.row();
|
||||
|
||||
@@ -40,7 +40,11 @@ public class PausedDialog extends FloatingDialog{
|
||||
cont.addButton("$back", this::hide).colspan(2).width(dw*2 + 20f);
|
||||
|
||||
cont.row();
|
||||
cont.addButton("database", ui.database::show);
|
||||
if(world.isZone()){
|
||||
cont.addButton("$techtree", ui.tech::show);
|
||||
}else{
|
||||
cont.addButton("$database", ui.database::show);
|
||||
}
|
||||
cont.addButton("$settings", ui.settings::show);
|
||||
|
||||
if(!world.isZone()){
|
||||
@@ -76,6 +80,8 @@ public class PausedDialog extends FloatingDialog{
|
||||
cont.row();
|
||||
|
||||
cont.addRowImageTextButton("$load", "icon-load", isize, load::show).disabled(b -> Net.active());
|
||||
}else{
|
||||
cont.row();
|
||||
}
|
||||
|
||||
cont.addRowImageTextButton("$hostserver.mobile", "icon-host", isize, ui.host::show).disabled(b -> Net.active());
|
||||
|
||||
@@ -14,7 +14,7 @@ import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@@ -49,7 +49,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
title.setAlignment(Align.center);
|
||||
titleTable.row();
|
||||
titleTable.add(new Image("white"))
|
||||
.growX().height(3f).pad(4f).get().setColor(Palette.accent);
|
||||
.growX().height(3f).pad(4f).get().setColor(Pal.accent);
|
||||
|
||||
cont.clearChildren();
|
||||
cont.remove();
|
||||
@@ -120,6 +120,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
void addSettings(){
|
||||
//TODO add when sound works again
|
||||
//sound.volumePrefs();
|
||||
sound.add("[LIGHT_GRAY]there is no sound implemented in v4 yet");
|
||||
|
||||
game.screenshakePref();
|
||||
game.checkPref("effects", true);
|
||||
@@ -194,8 +195,8 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
|
||||
graphics.checkPref("fps", false);
|
||||
graphics.checkPref("indicators", true);
|
||||
graphics.checkPref("animatedwater", !mobile);
|
||||
graphics.checkPref("lasers", true);
|
||||
graphics.checkPref("minimap", !mobile); //minimap is disabled by default on mobile devices
|
||||
}
|
||||
|
||||
private void back(){
|
||||
|
||||
@@ -4,67 +4,52 @@ import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectSet;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.math.Interpolation;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.arc.scene.Element;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.actions.Actions;
|
||||
import io.anuke.arc.scene.event.InputEvent;
|
||||
import io.anuke.arc.scene.event.InputListener;
|
||||
import io.anuke.arc.scene.event.Touchable;
|
||||
import io.anuke.arc.scene.style.TextureRegionDrawable;
|
||||
import io.anuke.arc.scene.ui.ImageButton;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.arc.util.Log;
|
||||
import io.anuke.arc.util.Structs;
|
||||
import io.anuke.mindustry.content.TechTree;
|
||||
import io.anuke.mindustry.content.TechTree.TechNode;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.ui.ItemsDisplay;
|
||||
import io.anuke.mindustry.ui.TreeLayout;
|
||||
import io.anuke.mindustry.ui.TreeLayout.TreeNode;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class TechTreeDialog extends FloatingDialog{
|
||||
private final float nodeSize = Unit.dp.scl(60f);
|
||||
private ObjectSet<TechTreeNode> nodes = new ObjectSet<>();
|
||||
private TechTreeNode root = new TechTreeNode(TechTree.root, null);
|
||||
private static final float nodeSize = 60f;
|
||||
private ItemsDisplay items;
|
||||
|
||||
public TechTreeDialog(){
|
||||
super("");
|
||||
|
||||
cont.setFillParent(true);
|
||||
titleTable.remove();
|
||||
margin(0f).marginBottom(8);
|
||||
cont.stack(new View(), items = new ItemsDisplay()).grow();
|
||||
|
||||
TreeLayout layout = new TreeLayout();
|
||||
layout.gapBetweenLevels = 60f;
|
||||
layout.gapBetweenNodes = 40f;
|
||||
layout.layout(root);
|
||||
|
||||
cont.add(new View()).grow();
|
||||
|
||||
{ //debug code; TODO remove
|
||||
ObjectSet<Block> used = new ObjectSet<Block>().select(t -> true);
|
||||
for(TechTreeNode node : nodes){
|
||||
used.add(node.node.block);
|
||||
}
|
||||
Array<Block> recipes = content.blocks().select(r -> r.isVisible() && !used.contains(r));
|
||||
recipes.sort(Structs.comparing(r -> r.buildCost));
|
||||
|
||||
if(recipes.size > 0){
|
||||
Log.info("Recipe tree coverage: {0}%", (int)((float)nodes.size / content.blocks().select(Block::isVisible).size * 100));
|
||||
Log.info("Missing items: ");
|
||||
recipes.forEach(r -> Log.info(" {0}", r));
|
||||
}
|
||||
}
|
||||
|
||||
shown(() -> checkNodes(root));
|
||||
shown(() -> {
|
||||
checkNodes(root);
|
||||
treeLayout();
|
||||
});
|
||||
hidden(ui.deploy::setup);
|
||||
addCloseButton();
|
||||
|
||||
buttons.addImageTextButton("$database", "icon-database", 14*2, () -> {
|
||||
hide();
|
||||
ui.database.show();
|
||||
}).size(210f, 64f);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,52 +57,70 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
drawDefaultBackground(x, y);
|
||||
}
|
||||
|
||||
void checkNodes(TechTreeNode node){
|
||||
boolean locked = locked(node);
|
||||
if(!locked) node.visible = true;
|
||||
for(TreeNode child : node.children){
|
||||
TechTreeNode l = (TechTreeNode)child;
|
||||
l.visible = !locked && l.node.block.isVisible();
|
||||
checkNodes(l);
|
||||
void treeLayout(){
|
||||
TreeLayout layout = new TreeLayout();
|
||||
layout.gapBetweenLevels = Unit.dp.scl(60f);
|
||||
layout.gapBetweenNodes = Unit.dp.scl(40f);
|
||||
LayoutNode node = new LayoutNode(root, null);
|
||||
layout.layout(node);
|
||||
copyInfo(node);
|
||||
}
|
||||
|
||||
void copyInfo(LayoutNode node){
|
||||
node.node.x = node.x;
|
||||
node.node.y = node.y;
|
||||
if(node.children != null){
|
||||
for(LayoutNode child : node.children){
|
||||
copyInfo(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showToast(String info){
|
||||
int maxIndex = 0;
|
||||
|
||||
for(Element e : Core.scene.root.getChildren()){
|
||||
if("toast".equals(e.getName())){
|
||||
maxIndex = Math.max(maxIndex, (Integer)e.getUserObject() + 1);
|
||||
}
|
||||
void checkNodes(TechTreeNode node){
|
||||
boolean locked = locked(node.node);
|
||||
if(!locked) node.visible = true;
|
||||
for(TechTreeNode l : node.children){
|
||||
l.visible = !locked;
|
||||
checkNodes(l);
|
||||
}
|
||||
|
||||
int m = maxIndex;
|
||||
items.rebuild();
|
||||
}
|
||||
|
||||
void showToast(String info){
|
||||
Table table = new Table();
|
||||
table.actions(Actions.fadeOut(7f, Interpolation.fade), Actions.removeActor());
|
||||
table.actions(Actions.fadeOut(0.5f, Interpolation.fade), Actions.removeActor());
|
||||
table.top().add(info);
|
||||
table.setName("toast");
|
||||
table.setUserObject(maxIndex);
|
||||
table.update(() -> {
|
||||
table.toFront();
|
||||
table.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight() - 21 - m*20f, Align.top);
|
||||
table.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight() - 21, Align.top);
|
||||
});
|
||||
Core.scene.add(table);
|
||||
}
|
||||
|
||||
boolean locked(TreeNode node){
|
||||
return locked(((TechTreeNode)node).node);
|
||||
}
|
||||
|
||||
boolean locked(TechNode node){
|
||||
return !data.isUnlocked(node.block);
|
||||
return node.block.locked();
|
||||
}
|
||||
|
||||
class TechTreeNode extends TreeNode{
|
||||
class LayoutNode extends TreeNode<LayoutNode>{
|
||||
final TechTreeNode node;
|
||||
|
||||
LayoutNode(TechTreeNode node, LayoutNode parent){
|
||||
this.node = node;
|
||||
this.parent = parent;
|
||||
this.width = this.height = nodeSize;
|
||||
if(node.children != null){
|
||||
children = Array.with(node.children).select(n -> n.visible).map(t -> new LayoutNode(t, this)).toArray(LayoutNode.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TechTreeNode extends TreeNode<TechTreeNode>{
|
||||
final TechNode node;
|
||||
boolean visible = true;
|
||||
|
||||
public TechTreeNode(TechNode node, TreeNode parent){
|
||||
TechTreeNode(TechNode node, TechTreeNode parent){
|
||||
this.node = node;
|
||||
this.parent = parent;
|
||||
this.width = this.height = nodeSize;
|
||||
@@ -134,7 +137,6 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
class View extends Group{
|
||||
float panX = 0, panY = -200;
|
||||
boolean moved = false;
|
||||
Rectangle clip = new Rectangle();
|
||||
ImageButton hoverNode;
|
||||
Table infoTable = new Table();
|
||||
|
||||
@@ -143,11 +145,12 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
|
||||
for(TechTreeNode node : nodes){
|
||||
ImageButton button = new ImageButton(node.node.block.icon(Icon.medium), "node");
|
||||
button.visible(() -> node.visible);
|
||||
button.clicked(() -> {
|
||||
if(mobile){
|
||||
hoverNode = button;
|
||||
rebuild();
|
||||
}else if(data.hasItems(node.node.requirements) && locked(node)){
|
||||
}else if(data.hasItems(node.node.requirements) && locked(node.node)){
|
||||
unlock(node.node);
|
||||
}
|
||||
});
|
||||
@@ -158,7 +161,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
}
|
||||
});
|
||||
button.exited(() -> {
|
||||
if(hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){
|
||||
if(!mobile && hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){
|
||||
hoverNode = null;
|
||||
rebuild();
|
||||
}
|
||||
@@ -166,44 +169,34 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
button.touchable(() -> !node.visible ? Touchable.disabled : Touchable.enabled);
|
||||
button.setUserObject(node.node);
|
||||
button.tapped(() -> moved = false);
|
||||
button.setSize(nodeSize, nodeSize);
|
||||
button.setSize(nodeSize);
|
||||
button.update(() -> {
|
||||
button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center);
|
||||
button.getStyle().up = Core.scene.skin.getDrawable(!locked(node) ? "content-background" : "content-background-locked");
|
||||
float offset = (Core.graphics.getHeight() % 2) / 2f;
|
||||
button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f + offset, Align.center);
|
||||
button.getStyle().up = Core.scene.skin.getDrawable(!locked(node.node) ? "content-background" : "content-background-locked");
|
||||
((TextureRegionDrawable)button.getStyle().imageUp)
|
||||
.setRegion(node.visible ? node.node.block.icon(Icon.medium) : Core.atlas.find("icon-tree-locked"));
|
||||
button.getImage().setColor(!locked(node) ? Color.WHITE : Color.GRAY);
|
||||
button.getImage().setColor(!locked(node.node) ? Color.WHITE : Color.GRAY);
|
||||
});
|
||||
addChild(button);
|
||||
}
|
||||
|
||||
addListener(new InputListener(){
|
||||
float lastX, lastY;
|
||||
@Override
|
||||
public void touchDragged(InputEvent event, float mx, float my, int pointer){
|
||||
panX -= lastX - mx;
|
||||
panY -= lastY - my;
|
||||
lastX = mx;
|
||||
lastY = my;
|
||||
moved = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
return true;
|
||||
}
|
||||
dragged((x, y) -> {
|
||||
moved = true;
|
||||
panX += x;
|
||||
panY += y;
|
||||
});
|
||||
}
|
||||
|
||||
void unlock(TechNode node){
|
||||
data.unlockContent(node.block);
|
||||
data.removeItems(node.requirements);
|
||||
showToast(Core.bundle.format("researched", node.block.formalName));
|
||||
showToast(Core.bundle.format("researched", node.block.localizedName));
|
||||
checkNodes(root);
|
||||
hoverNode = null;
|
||||
treeLayout();
|
||||
rebuild();
|
||||
Core.scene.act();
|
||||
}
|
||||
|
||||
void rebuild(){
|
||||
@@ -235,7 +228,7 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
|
||||
infoTable.table(desc -> {
|
||||
desc.left().defaults().left();
|
||||
desc.add(node.block.formalName);
|
||||
desc.add(node.block.localizedName);
|
||||
desc.row();
|
||||
if(locked(node)){
|
||||
desc.table(t -> {
|
||||
@@ -245,8 +238,8 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
list.left();
|
||||
list.addImage(req.item.getContentIcon()).size(8 * 3).padRight(3);
|
||||
list.add(req.item.localizedName()).color(Color.LIGHT_GRAY);
|
||||
list.add(" " + Math.min(data.items().get(req.item, 0), req.amount) + " / " + req.amount)
|
||||
.color(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET);
|
||||
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
|
||||
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.LIGHT_GRAY : Color.SCARLET));
|
||||
}).fillX().left();
|
||||
t.row();
|
||||
}
|
||||
@@ -270,14 +263,17 @@ public class TechTreeDialog extends FloatingDialog{
|
||||
public void draw(){
|
||||
float offsetX = panX + width/2f + x, offsetY = panY + height/2f + y;
|
||||
|
||||
for(TreeNode node : nodes){
|
||||
for(TreeNode child : node.children){
|
||||
Lines.stroke(3f, locked(node) || locked(child) ? Palette.locked : Palette.accent);
|
||||
for(TechTreeNode node : nodes){
|
||||
if(!node.visible) continue;
|
||||
for(TechTreeNode child : node.children){
|
||||
if(!child.visible) continue;
|
||||
|
||||
Lines.stroke(Unit.dp.scl(3f), locked(node.node) || locked(child.node) ? Pal.locked : Pal.accent);
|
||||
Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class TraceDialog extends FloatingDialog{
|
||||
table.row();
|
||||
table.add(Core.bundle.format("trace.structureblocksbroken", info.structureBlocksBroken));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("trace.lastblockbroken", info.lastBlockBroken.formalName));
|
||||
table.add(Core.bundle.format("trace.lastblockbroken", info.lastBlockBroken.localizedName));
|
||||
table.row();
|
||||
|
||||
table.add().pad(5);
|
||||
@@ -45,7 +45,7 @@ public class TraceDialog extends FloatingDialog{
|
||||
|
||||
table.add(Core.bundle.format("trace.totalblocksplaced", info.totalBlocksPlaced));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("trace.lastblockplaced", info.lastBlockPlaced.formalName));
|
||||
table.add(Core.bundle.format("trace.lastblockplaced", info.lastBlockPlaced.localizedName));
|
||||
table.row();
|
||||
|
||||
cont.add(table);
|
||||
|
||||
221
core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java
Normal file
221
core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java
Normal file
@@ -0,0 +1,221 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.scene.ui.Button;
|
||||
import io.anuke.arc.scene.ui.TextButton;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.type.ItemType;
|
||||
import io.anuke.mindustry.type.Zone;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class ZoneInfoDialog extends FloatingDialog{
|
||||
|
||||
public ZoneInfoDialog(){
|
||||
super("");
|
||||
|
||||
titleTable.remove();
|
||||
addCloseButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackground(float x, float y){
|
||||
drawDefaultBackground(x, y);
|
||||
}
|
||||
|
||||
public void show(Zone zone){
|
||||
setup(zone);
|
||||
show();
|
||||
}
|
||||
|
||||
private void setup(Zone zone){
|
||||
cont.clear();
|
||||
|
||||
Table iteminfo = new Table();
|
||||
Runnable rebuildItems = () -> {
|
||||
int i = 0;
|
||||
iteminfo.clear();
|
||||
ItemStack[] stacks = zone.unlocked() ? zone.getLaunchCost() : zone.itemRequirements;
|
||||
for(ItemStack stack : stacks){
|
||||
if(stack.amount == 0) continue;
|
||||
|
||||
if(i++ % 2 == 0){
|
||||
iteminfo.row();
|
||||
}
|
||||
iteminfo.addImage(stack.item.icon(Item.Icon.medium)).size(8*3).padRight(1);
|
||||
iteminfo.add(stack.amount + "").color(Color.LIGHT_GRAY).padRight(5);
|
||||
}
|
||||
};
|
||||
|
||||
rebuildItems.run();
|
||||
|
||||
cont.table(cont -> {
|
||||
if(zone.locked()){
|
||||
cont.addImage("icon-zone-locked");
|
||||
cont.row();
|
||||
cont.add("$locked").padBottom(6);
|
||||
cont.row();
|
||||
|
||||
cont.table(req -> {
|
||||
req.defaults().left();
|
||||
|
||||
if(zone.zoneRequirements.length > 0){
|
||||
req.table(r -> {
|
||||
r.add("$complete").colspan(2).left();
|
||||
r.row();
|
||||
for(Zone other : zone.zoneRequirements){
|
||||
r.addImage("icon-zone").padRight(4);
|
||||
r.add(other.localizedName()).color(Color.LIGHT_GRAY);
|
||||
r.addImage(other.isCompleted() ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(other.isCompleted() ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
req.row();
|
||||
|
||||
if(zone.blockRequirements.length > 0){
|
||||
req.table(r -> {
|
||||
r.add("$research.list").colspan(2).left();
|
||||
r.row();
|
||||
for(Block block : zone.blockRequirements){
|
||||
r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4);
|
||||
r.add(block.localizedName).color(Color.LIGHT_GRAY);
|
||||
r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3);
|
||||
r.row();
|
||||
}
|
||||
|
||||
}).padTop(10);
|
||||
}
|
||||
}).growX();
|
||||
|
||||
}else{
|
||||
cont.add(zone.localizedName()).color(Pal.accent).growX().center();
|
||||
cont.row();
|
||||
cont.addImage("white").color(Pal.accent).height(3).pad(6).growX();
|
||||
cont.row();
|
||||
cont.table(res -> {
|
||||
res.add("$zone.resources").padRight(6);
|
||||
if(zone.resources.length > 0){
|
||||
for(Item item : zone.resources){
|
||||
res.addImage(item.icon(Item.Icon.medium)).size(8 * 3);
|
||||
}
|
||||
}else{
|
||||
res.add("$none");
|
||||
}
|
||||
});
|
||||
|
||||
if(zone.bestWave() > 0){
|
||||
cont.row();
|
||||
cont.add(Core.bundle.format("bestwave", zone.bestWave()));
|
||||
}
|
||||
|
||||
Table load = new Table();
|
||||
//thanks java, absolutely brilliant syntax here
|
||||
Runnable[] rebuildLoadout = {null};
|
||||
rebuildLoadout[0] = () -> {
|
||||
load.clear();
|
||||
float bsize = 40f;
|
||||
int step = 100;
|
||||
|
||||
load.left();
|
||||
for(ItemStack stack : zone.getStartingItems()){
|
||||
load.addButton("-", () -> {
|
||||
stack.amount = Math.max(stack.amount - step, 0);
|
||||
zone.updateLaunchCost();
|
||||
rebuildItems.run();
|
||||
}).size(bsize).pad(2);
|
||||
load.addButton("+", () -> {
|
||||
stack.amount = Math.min(stack.amount + step, zone.loadout.core().itemCapacity);
|
||||
zone.updateLaunchCost();
|
||||
rebuildItems.run();
|
||||
}).size(bsize).pad(2);
|
||||
|
||||
load.addImage(stack.item.icon(Item.Icon.medium)).size(8 * 3).padRight(4);
|
||||
load.label(() -> stack.amount + "").left();
|
||||
|
||||
load.row();
|
||||
}
|
||||
|
||||
load.addButton("$add", () -> {
|
||||
FloatingDialog dialog = new FloatingDialog("");
|
||||
dialog.setFillParent(false);
|
||||
for(Item item : content.items().select(item -> data.getItem(item) > 0 && item.type == ItemType.material && zone.getStartingItems().find(stack -> stack.item == item) == null)){
|
||||
TextButton button = dialog.cont.addButton("", () -> {
|
||||
zone.getStartingItems().add(new ItemStack(item, 0));
|
||||
zone.updateLaunchCost();
|
||||
rebuildLoadout[0].run();
|
||||
dialog.hide();
|
||||
}).size(300f, 35f).pad(1).get();
|
||||
button.clearChildren();
|
||||
button.left();
|
||||
button.addImage(item.icon(Item.Icon.medium)).size(8*3).pad(4);
|
||||
button.add(item.localizedName);
|
||||
dialog.cont.row();
|
||||
}
|
||||
dialog.show();
|
||||
}).colspan(4).size(100f, bsize).left().disabled(b -> !content.items().contains(item -> data.getItem(item) > 0 && item.type == ItemType.material && !zone.getStartingItems().contains(stack -> stack.item == item)));
|
||||
};
|
||||
|
||||
rebuildLoadout[0].run();
|
||||
|
||||
cont.row();
|
||||
cont.table(zone.canConfigure() ? "button" : "button-disabled", t -> {
|
||||
t.left();
|
||||
t.add(!zone.canConfigure() ? Core.bundle.format("configure.locked", zone.configureWave) : "$configure").growX().wrap();
|
||||
if(zone.canConfigure()){
|
||||
t.row();
|
||||
t.pane(load).pad(2).growX().left();
|
||||
}
|
||||
}).width(300f).pad(4).left();
|
||||
}
|
||||
});
|
||||
|
||||
cont.row();
|
||||
|
||||
Button button = cont.addButton(zone.locked() ? "$uncover" : "$launch", () -> {
|
||||
if(!data.isUnlocked(zone)){
|
||||
data.removeItems(zone.itemRequirements);
|
||||
data.unlockContent(zone);
|
||||
ui.deploy.setup();
|
||||
setup(zone);
|
||||
}else{
|
||||
ui.deploy.hide();
|
||||
data.removeItems(zone.getLaunchCost());
|
||||
hide();
|
||||
world.playZone(zone);
|
||||
}
|
||||
}).minWidth(150f).margin(13f).padTop(5).disabled(b -> zone.locked() ? !canUnlock(zone) : !data.hasItems(zone.getLaunchCost())).get();
|
||||
|
||||
button.row();
|
||||
button.add(iteminfo);
|
||||
}
|
||||
|
||||
private boolean canUnlock(Zone zone){
|
||||
if(data.isUnlocked(zone)){
|
||||
return true;
|
||||
}
|
||||
|
||||
for(Zone other : zone.zoneRequirements){
|
||||
if(!other.isCompleted()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(Block other : zone.blockRequirements){
|
||||
if(!data.isUnlocked(other)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return data.hasItems(zone.itemRequirements);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ public class BlockConfigFragment extends Fragment{
|
||||
|
||||
@Override
|
||||
public void build(Group parent){
|
||||
table.visible(false);
|
||||
parent.addChild(table);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,11 @@ import io.anuke.arc.util.Align;
|
||||
import io.anuke.arc.util.Strings;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.input.InputHandler;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Item.Icon;
|
||||
import io.anuke.mindustry.ui.ItemImage;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
@@ -49,7 +50,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
|
||||
int removed = tile.block().removeStack(tile, item, amount);
|
||||
|
||||
player.inventory.addItem(item, removed);
|
||||
player.addItem(item, removed);
|
||||
for(int j = 0; j < Mathf.clamp(removed / 3, 1, 8); j++){
|
||||
Time.run(j * 3f, () -> Call.transferItemEffect(item, tile.drawx(), tile.drawy(), player));
|
||||
}
|
||||
@@ -65,6 +66,10 @@ public class BlockInventoryFragment extends Fragment{
|
||||
}
|
||||
|
||||
public void showFor(Tile t){
|
||||
if(this.tile == t.target()){
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
this.tile = t.target();
|
||||
if(tile == null || tile.entity == null || !tile.block().isAccessible() || tile.entity.items.total() == 0)
|
||||
return;
|
||||
@@ -97,7 +102,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
holdTime += Time.delta();
|
||||
|
||||
if(holdTime >= holdWithdraw){
|
||||
int amount = Math.min(tile.entity.items.get(lastItem), player.inventory.itemCapacityUsed(lastItem));
|
||||
int amount = Math.min(tile.entity.items.get(lastItem), player.maxAccepted(lastItem));
|
||||
Call.requestItem(player, tile, lastItem, amount);
|
||||
holding = false;
|
||||
holdTime = 0f;
|
||||
@@ -120,7 +125,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
int row = 0;
|
||||
|
||||
table.margin(6f);
|
||||
table.defaults().size(16 * 2.5f).space(6f);
|
||||
table.defaults().size(8 * 5).space(6f);
|
||||
|
||||
if(tile.block().hasItems){
|
||||
|
||||
@@ -130,12 +135,12 @@ public class BlockInventoryFragment extends Fragment{
|
||||
|
||||
container.add(i);
|
||||
|
||||
BooleanProvider canPick = () -> player.inventory.canAcceptItem(item);
|
||||
BooleanProvider canPick = () -> player.acceptsItem(item) && !state.isPaused();
|
||||
|
||||
HandCursorListener l = new HandCursorListener();
|
||||
l.setEnabled(canPick);
|
||||
|
||||
ItemImage image = new ItemImage(item.region, () -> {
|
||||
ItemImage image = new ItemImage(item.icon(Icon.xlarge), () -> {
|
||||
if(tile == null || tile.entity == null){
|
||||
return "";
|
||||
}
|
||||
@@ -147,11 +152,13 @@ public class BlockInventoryFragment extends Fragment{
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||
if(!canPick.get() || !tile.entity.items.has(item)) return false;
|
||||
int amount = Math.min(1, player.inventory.itemCapacityUsed(item));
|
||||
Call.requestItem(player, tile, item, amount);
|
||||
lastItem = item;
|
||||
holding = true;
|
||||
holdTime = 0f;
|
||||
int amount = Math.min(1, player.maxAccepted(item));
|
||||
if(amount > 0){
|
||||
Call.requestItem(player, tile, item, amount);
|
||||
lastItem = item;
|
||||
holding = true;
|
||||
holdTime = 0f;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,34 +15,32 @@ import io.anuke.arc.scene.ui.ImageButton;
|
||||
import io.anuke.arc.scene.ui.TextButton;
|
||||
import io.anuke.arc.scene.ui.layout.Stack;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.arc.scene.utils.Elements;
|
||||
import io.anuke.arc.util.Align;
|
||||
import io.anuke.arc.util.Scaling;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.Tmp;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.game.EventType.StateChangeEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.UnlockableContent;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.input.Binding;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.Packets.AdminAction;
|
||||
import io.anuke.mindustry.ui.Bar;
|
||||
import io.anuke.mindustry.ui.IntFormat;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class HudFragment extends Fragment{
|
||||
public final PlacementFragment blockfrag = new PlacementFragment();
|
||||
|
||||
private ImageButton menu, flip;
|
||||
private Stack wavetable;
|
||||
private Table infolabel;
|
||||
private ImageButton flip;
|
||||
private Table lastUnlockTable;
|
||||
private Table lastUnlockLayout;
|
||||
private boolean shown = true;
|
||||
private float dsize = 58;
|
||||
private float dsize = 59;
|
||||
private float isize = 40;
|
||||
|
||||
private float coreAttackTime;
|
||||
@@ -53,7 +51,6 @@ public class HudFragment extends Fragment{
|
||||
|
||||
//menu at top left
|
||||
parent.fill(cont -> {
|
||||
|
||||
cont.top().left().visible(() -> !state.is(State.menu));
|
||||
|
||||
if(mobile){
|
||||
@@ -61,7 +58,7 @@ public class HudFragment extends Fragment{
|
||||
select.left();
|
||||
select.defaults().size(dsize).left();
|
||||
|
||||
menu = select.addImageButton("icon-menu", "clear", isize, ui.paused::show).get();
|
||||
select.addImageButton("icon-menu", "clear", isize, ui.paused::show);
|
||||
flip = select.addImageButton("icon-arrow-up", "clear", isize, this::toggleMenus).get();
|
||||
|
||||
select.addImageButton("icon-pause", "clear", isize, () -> {
|
||||
@@ -86,6 +83,8 @@ public class HudFragment extends Fragment{
|
||||
}else{
|
||||
ui.chatfrag.toggle();
|
||||
}
|
||||
}else if(world.isZone()){
|
||||
ui.tech.show();
|
||||
}else{
|
||||
ui.database.show();
|
||||
}
|
||||
@@ -93,15 +92,15 @@ public class HudFragment extends Fragment{
|
||||
if(Net.active() && mobile){
|
||||
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-chat");
|
||||
}else{
|
||||
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-unlocks");
|
||||
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database-small");
|
||||
}
|
||||
}).get();
|
||||
|
||||
select.addImage("blank").color(Palette.accent).width(6f).fillY();
|
||||
});
|
||||
select.addImage("blank").color(Pal.accent).width(3f).fillY();
|
||||
}).left();
|
||||
|
||||
cont.row();
|
||||
cont.addImage("blank").height(6f).color(Palette.accent).fillX();
|
||||
cont.addImage("blank").height(3f).color(Pal.accent).fillX();
|
||||
cont.row();
|
||||
}
|
||||
|
||||
@@ -111,45 +110,57 @@ public class HudFragment extends Fragment{
|
||||
}
|
||||
});
|
||||
|
||||
Stack stack = new Stack();
|
||||
TextButton waves = new TextButton("", "wave");
|
||||
Table btable = new Table().margin(0);
|
||||
cont.table(stuff -> {
|
||||
stuff.left();
|
||||
Stack stack = new Stack();
|
||||
TextButton waves = new TextButton("", "wave");
|
||||
Table btable = new Table().margin(0);
|
||||
|
||||
stack.add(waves);
|
||||
stack.add(btable);
|
||||
stack.add(waves);
|
||||
stack.add(btable);
|
||||
|
||||
wavetable = stack;
|
||||
|
||||
addWaveTable(waves);
|
||||
addPlayButton(btable);
|
||||
cont.add(stack).width(dsize * 4 + 6f);
|
||||
|
||||
cont.row();
|
||||
|
||||
//fps display
|
||||
infolabel = cont.table(t -> {
|
||||
IntFormat fps = new IntFormat("fps");
|
||||
IntFormat ping = new IntFormat("ping");
|
||||
t.label(() -> fps.get(Core.graphics.getFramesPerSecond())).padRight(10);
|
||||
t.row();
|
||||
if(Net.hasClient()){
|
||||
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
|
||||
}
|
||||
}).size(-1).visible(() -> Core.settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())))).get();
|
||||
|
||||
//make wave box appear below rest of menu
|
||||
if(mobile){
|
||||
cont.swapActor(wavetable, menu.getParent());
|
||||
}
|
||||
addWaveTable(waves);
|
||||
addPlayButton(btable);
|
||||
stuff.add(stack).width(dsize * 4 + 3f);
|
||||
stuff.row();
|
||||
stuff.table("button", t -> t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE))
|
||||
.grow()).fillX().visible(() -> world.isZone() && state.boss() != null).height(60f).get();
|
||||
stuff.row();
|
||||
}).visible(() -> shown);
|
||||
});
|
||||
|
||||
//minimap
|
||||
//parent.fill(t -> t.top().right().add(new Minimap()).visible(() -> !state.is(State.menu) && Core.settings.getBool("minimap")));
|
||||
|
||||
//paused table
|
||||
//fps display
|
||||
parent.fill(info -> {
|
||||
info.top().right().margin(4).visible(() -> Core.settings.getBool("fps") && !state.is(State.menu));
|
||||
IntFormat fps = new IntFormat("fps");
|
||||
IntFormat ping = new IntFormat("ping");
|
||||
info.label(() -> fps.get(Core.graphics.getFramesPerSecond())).right();
|
||||
info.row();
|
||||
info.label(() -> ping.get(Net.getPing())).visible(Net::client).right();
|
||||
});
|
||||
|
||||
//spawner warning
|
||||
parent.fill(t -> {
|
||||
t.top().visible(() -> state.is(State.paused) && !Net.active());
|
||||
t.table("button", top -> top.add("$paused").pad(6f));
|
||||
t.touchable(Touchable.disabled);
|
||||
t.visible(() -> !state.is(State.menu));
|
||||
t.table("flat", c -> c.add("$nearpoint")
|
||||
.update(l -> l.setColor(Tmp.c1.set(Color.WHITE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 10f, 1f))))
|
||||
.get().setAlignment(Align.center, Align.center))
|
||||
.margin(6).update(u -> u.color.a = Mathf.lerpDelta(u.color.a, Mathf.num(world.spawner.playerNear()), 0.1f)).get().color.a = 0f;
|
||||
});
|
||||
|
||||
//out of bounds warning
|
||||
parent.fill(t -> {
|
||||
t.touchable(Touchable.disabled);
|
||||
t.visible(() -> !state.is(State.menu));
|
||||
t.table("flat", c -> c.add("")
|
||||
.update(l ->{
|
||||
l.setColor(Tmp.c1.set(Color.WHITE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 10f, 1f)));
|
||||
l.setText(Core.bundle.format("outofbounds", (int)((boundsCountdown - players[0].destructTime) / 60f)));
|
||||
}).get().setAlignment(Align.center, Align.center)).margin(6).update(u -> {
|
||||
u.color.a = Mathf.lerpDelta(u.color.a, Mathf.num(players[0].isOutOfBounds()), 0.1f);
|
||||
}).get().color.a = 0f;
|
||||
});
|
||||
|
||||
parent.fill(t -> {
|
||||
@@ -196,8 +207,45 @@ public class HudFragment extends Fragment{
|
||||
.update(label -> label.getColor().set(Color.ORANGE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 2f, 1f))));
|
||||
});
|
||||
|
||||
parent.fill(t -> t.top().right().addRowImageTextButton("$launch", "icon-arrow-up", 8*3, () -> world.launchZone())
|
||||
.size(94f, 70f).visible(() -> world.isZone() && world.getZone().metCondition()));
|
||||
//launch button
|
||||
parent.fill(t -> {
|
||||
t.top().visible(() -> !state.is(State.menu));
|
||||
|
||||
TextButton button = Elements.newButton("$launch", () -> ui.showConfirm("$launch", "$launch.confirm", Call::launchZone));
|
||||
|
||||
button.getStyle().disabledFontColor = Color.WHITE;
|
||||
button.visible(() ->
|
||||
world.isZone() &&
|
||||
world.getZone().metCondition() &&
|
||||
!Net.client() &&
|
||||
state.wave % world.getZone().launchPeriod == 0 &&
|
||||
state.wavetime < state.rules.waveSpacing * launchWaveMultiplier - 70);
|
||||
|
||||
button.update(() -> {
|
||||
if(world.getZone() == null){
|
||||
button.setText("");
|
||||
return;
|
||||
}
|
||||
|
||||
button.setText(state.enemies() > 0 ? Core.bundle.format("launch.unable", state.enemies()) : Core.bundle.get("launch") + "\n" +
|
||||
Core.bundle.format("launch.next", state.wave + world.getZone().launchPeriod));
|
||||
|
||||
button.getLabel().setColor(Tmp.c1.set(Color.WHITE).lerp(state.enemies() > 0 ? Color.WHITE : Pal.accent,
|
||||
Mathf.absin(Time.time(), 7f, 1f)));
|
||||
});
|
||||
|
||||
button.setDisabled(() -> state.enemies() > 0);
|
||||
|
||||
button.getLabelCell().left().get().setAlignment(Align.left, Align.left);
|
||||
|
||||
t.add(button).size(350f, 80f);
|
||||
});
|
||||
|
||||
//paused table
|
||||
parent.fill(t -> {
|
||||
t.top().visible(() -> state.is(State.paused) && !Net.active());
|
||||
t.table("button", top -> top.add("$paused").pad(6f));
|
||||
});
|
||||
|
||||
//'saving' indicator
|
||||
parent.fill(t -> {
|
||||
@@ -229,6 +277,10 @@ public class HudFragment extends Fragment{
|
||||
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.removeActor())));
|
||||
}
|
||||
|
||||
public boolean shown(){
|
||||
return shown;
|
||||
}
|
||||
|
||||
/** Show unlock notification for a new recipe. */
|
||||
public void showUnlock(UnlockableContent content){
|
||||
//some content may not have icons... yet
|
||||
@@ -314,38 +366,25 @@ public class HudFragment extends Fragment{
|
||||
}
|
||||
}
|
||||
|
||||
public void showTextDialog(String str){
|
||||
new FloatingDialog("$mission.info"){{
|
||||
shouldPause = true;
|
||||
setFillParent(false);
|
||||
getCell(cont).growX();
|
||||
cont.margin(15).add(str).width(400f).wrap().get().setAlignment(Align.left, Align.left);
|
||||
buttons.addButton("$continue", this::hide).size(140, 60).pad(4);
|
||||
}}.show();
|
||||
public void showLaunch(){
|
||||
Image image = new Image("white");
|
||||
image.getColor().a = 0f;
|
||||
image.setFillParent(true);
|
||||
image.actions(Actions.fadeIn(40f / 60f));
|
||||
image.update(() -> {
|
||||
if(state.is(State.menu)){
|
||||
image.remove();
|
||||
}
|
||||
});
|
||||
Core.scene.add(image);
|
||||
}
|
||||
|
||||
private void toggleMenus(){
|
||||
wavetable.clearActions();
|
||||
infolabel.clearActions();
|
||||
|
||||
float dur = 0.3f;
|
||||
Interpolation in = Interpolation.pow3Out;
|
||||
|
||||
if(flip != null){
|
||||
flip.getStyle().imageUp = Core.scene.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up");
|
||||
}
|
||||
|
||||
if(shown){
|
||||
shown = false;
|
||||
blockfrag.toggle(dur, in);
|
||||
wavetable.actions(Actions.translateBy(0, (wavetable.getHeight() + Unit.dp.scl(dsize) + Unit.dp.scl(6)) - wavetable.getTranslation().y, dur, in));
|
||||
infolabel.actions(Actions.translateBy(0, (wavetable.getHeight()) - wavetable.getTranslation().y, dur, in));
|
||||
}else{
|
||||
shown = true;
|
||||
blockfrag.toggle(dur, in);
|
||||
wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in));
|
||||
infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in));
|
||||
}
|
||||
shown = !shown;
|
||||
}
|
||||
|
||||
private void addWaveTable(TextButton table){
|
||||
@@ -391,12 +430,8 @@ public class HudFragment extends Fragment{
|
||||
}else{
|
||||
state.wavetime = 0f;
|
||||
}
|
||||
}).growY().fillX().right().width(40f).update(l -> {
|
||||
boolean vis = !state.rules.waveTimer && ((Net.server() || players[0].isAdmin) || !Net.active());
|
||||
boolean paused = state.is(State.paused) || !vis;
|
||||
|
||||
l.getStyle().imageUp = Core.scene.skin.getDrawable(vis ? "icon-play" : "clear");
|
||||
l.touchable(!paused ? Touchable.enabled : Touchable.disabled);
|
||||
}).visible(() -> !state.rules.waveTimer && ((Net.server() || players[0].isAdmin) || !Net.active()) && unitGroups[Team.red.ordinal()].size() == 0);
|
||||
}).growY().fillX().right().width(40f)
|
||||
.visible(() -> state.rules.waves && ((Net.server() || players[0].isAdmin) || !Net.active()) && state.enemies() == 0
|
||||
&& (state.wavetime < state.rules.waveSpacing - 60 || !state.rules.waveTimer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.anuke.mindustry.ui.fragments;
|
||||
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.event.Touchable;
|
||||
import io.anuke.arc.scene.ui.Label;
|
||||
@@ -18,11 +18,11 @@ public class LoadingFragment extends Fragment{
|
||||
t.touchable(Touchable.enabled);
|
||||
t.add().height(70f).row();
|
||||
|
||||
t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Palette.accent);
|
||||
t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Pal.accent);
|
||||
t.row();
|
||||
t.add("$loading").name("namelabel").pad(10f);
|
||||
t.row();
|
||||
t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Palette.accent);
|
||||
t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Pal.accent);
|
||||
t.row();
|
||||
|
||||
button = t.addButton("$cancel", () -> {}).pad(20).size(250f, 70f).visible(false).get();
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.anuke.mindustry.game.EventType.ResizeEvent;
|
||||
import io.anuke.mindustry.game.Version;
|
||||
import io.anuke.mindustry.ui.MenuButton;
|
||||
import io.anuke.mindustry.ui.MobileButton;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class MenuFragment extends Fragment{
|
||||
}
|
||||
|
||||
//version info
|
||||
parent.fill(c -> c.bottom().left().add(Strings.formatArgs("Mindustry v{0} {1}-{2} {3}{4}", Version.number, Version.modifier, Version.type,
|
||||
parent.fill(c -> c.bottom().left().add(Strings.format("Mindustry v{0} {1}-{2} {3}{4}", Version.number, Version.modifier, Version.type,
|
||||
(Version.build == -1 ? "custom build" : "build " + Version.build), Version.revision == 0 ? "" : "." + Version.revision))
|
||||
.visible(() -> state.is(State.menu)));
|
||||
}
|
||||
@@ -56,19 +57,18 @@ public class MenuFragment extends Fragment{
|
||||
container.defaults().size(size).pad(5).padTop(4f);
|
||||
|
||||
MobileButton
|
||||
play = new MobileButton("icon-play-2", isize, "$play", this::showPlaySelect),
|
||||
play = new MobileButton("icon-play-2", isize, "$play", ui.deploy::show),
|
||||
maps = new MobileButton("icon-map", isize, "$maps", ui.maps::show),
|
||||
load = new MobileButton("icon-load", isize, "$load", ui.load::show),
|
||||
custom = new MobileButton("icon-play-custom", isize, "$customgame", this::showCustomSelect),
|
||||
join = new MobileButton("icon-add", isize, "$joingame", ui.join::show),
|
||||
editor = new MobileButton("icon-editor", isize, "$editor", () -> ui.loadAnd(ui.editor::show)),
|
||||
tools = new MobileButton("icon-tools", isize, "$settings", ui.settings::show),
|
||||
unlocks = new MobileButton("icon-unlocks", isize, "database", ui.database::show),
|
||||
donate = new MobileButton("icon-donate", isize, "$donate", Platform.instance::openDonations);
|
||||
|
||||
if(Core.graphics.getWidth() > Core.graphics.getHeight()){
|
||||
container.add(play);
|
||||
container.add(join);
|
||||
container.add(load);
|
||||
container.add(custom);
|
||||
container.add(maps);
|
||||
container.row();
|
||||
|
||||
@@ -77,7 +77,6 @@ public class MenuFragment extends Fragment{
|
||||
|
||||
table.add(editor);
|
||||
table.add(tools);
|
||||
table.add(unlocks);
|
||||
|
||||
if(Platform.instance.canDonate()) table.add(donate);
|
||||
}).colspan(4);
|
||||
@@ -85,7 +84,7 @@ public class MenuFragment extends Fragment{
|
||||
container.add(play);
|
||||
container.add(maps);
|
||||
container.row();
|
||||
container.add(load);
|
||||
container.add(custom);
|
||||
container.add(join);
|
||||
container.row();
|
||||
container.add(editor);
|
||||
@@ -95,8 +94,6 @@ public class MenuFragment extends Fragment{
|
||||
container.table(table -> {
|
||||
table.defaults().set(container.defaults());
|
||||
|
||||
table.add(unlocks);
|
||||
|
||||
if(Platform.instance.canDonate()) table.add(donate);
|
||||
}).colspan(2);
|
||||
}
|
||||
@@ -111,7 +108,13 @@ public class MenuFragment extends Fragment{
|
||||
out.margin(16);
|
||||
out.defaults().size(w, 66f).padTop(5).padRight(5);
|
||||
|
||||
out.add(new MenuButton("icon-play-2", "$play", MenuFragment.this::showPlaySelect)).width(bw).colspan(2);
|
||||
out.add(new MenuButton("icon-play-2", "$play", ui.deploy::show)).width(bw).colspan(2);
|
||||
|
||||
out.row();
|
||||
|
||||
out.add(new MenuButton("icon-add", "$joingame", ui.join::show));
|
||||
|
||||
out.add(new MenuButton("icon-play-custom", "$customgame", this::showCustomSelect));
|
||||
|
||||
out.row();
|
||||
|
||||
@@ -131,40 +134,20 @@ public class MenuFragment extends Fragment{
|
||||
});
|
||||
}
|
||||
|
||||
private void showPlaySelect(){
|
||||
ui.deploy.show();
|
||||
|
||||
/*
|
||||
float w = 220f;
|
||||
float bw = w * 2f + 10f;
|
||||
|
||||
private void showCustomSelect(){
|
||||
FloatingDialog dialog = new FloatingDialog("$play");
|
||||
dialog.setFillParent(false);
|
||||
dialog.addCloseButton();
|
||||
dialog.cont.defaults().height(66f).width(w).padRight(5f);
|
||||
|
||||
dialog.cont.add(new MenuButton("icon-play-2", "$map.random", () -> {
|
||||
dialog.hide();
|
||||
world.generator.playRandomMap();
|
||||
})).width(bw).colspan(2);
|
||||
dialog.cont.row();
|
||||
|
||||
dialog.cont.add(new MenuButton("icon-add", "$joingame", () -> {
|
||||
ui.join.show();
|
||||
dialog.cont.defaults().size(230f, 64f);
|
||||
dialog.cont.add(new MenuButton("icon-editor", "$newgame", () -> {
|
||||
dialog.hide();
|
||||
ui.custom.show();
|
||||
}));
|
||||
|
||||
dialog.cont.add(new MenuButton("icon-editor", "$customgame", () -> {
|
||||
dialog.hide();
|
||||
ui.levels.show();
|
||||
}));
|
||||
|
||||
dialog.cont.row();
|
||||
|
||||
dialog.cont.add(new MenuButton("icon-load", "$loadgame", () -> {
|
||||
ui.load.show();
|
||||
dialog.hide();
|
||||
})).width(bw).colspan(2);
|
||||
|
||||
dialog.show();*/
|
||||
}));
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,22 +5,23 @@ import io.anuke.arc.Events;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.math.Interpolation;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.scene.Group;
|
||||
import io.anuke.arc.scene.actions.Actions;
|
||||
import io.anuke.arc.scene.event.Touchable;
|
||||
import io.anuke.arc.scene.style.TextureRegionDrawable;
|
||||
import io.anuke.arc.scene.ui.ButtonGroup;
|
||||
import io.anuke.arc.scene.ui.Image;
|
||||
import io.anuke.arc.scene.ui.ImageButton;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.type.TileEntity;
|
||||
import io.anuke.mindustry.game.EventType.UnlockEvent;
|
||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.input.Binding;
|
||||
import io.anuke.mindustry.input.InputHandler;
|
||||
import io.anuke.mindustry.type.Category;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
@@ -33,12 +34,13 @@ public class PlacementFragment extends Fragment{
|
||||
final int rowWidth = 4;
|
||||
|
||||
Array<Block> returnArray = new Array<>();
|
||||
Array<Category> returnCatArray = new Array<>();
|
||||
boolean[] categoryEmpty = new boolean[Category.values().length];
|
||||
Category currentCategory = Category.distribution;
|
||||
Block hovered, lastDisplay;
|
||||
Tile lastHover;
|
||||
Tile hoverTile;
|
||||
Table blockTable, toggler, topTable;
|
||||
boolean shown = true;
|
||||
boolean lastGround;
|
||||
|
||||
//TODO make this configurable
|
||||
@@ -56,14 +58,41 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
public PlacementFragment(){
|
||||
Events.on(WorldLoadEvent.class, event -> {
|
||||
currentCategory = Category.turret;
|
||||
Group group = toggler.getParent();
|
||||
toggler.remove();
|
||||
build(group);
|
||||
control.input(0).block = null;
|
||||
rebuild();
|
||||
});
|
||||
|
||||
Events.on(UnlockEvent.class, event -> {
|
||||
if(event.content instanceof Block){
|
||||
rebuild();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void rebuild(){
|
||||
currentCategory = Category.turret;
|
||||
Group group = toggler.getParent();
|
||||
int index = toggler.getZIndex();
|
||||
toggler.remove();
|
||||
build(group);
|
||||
toggler.setZIndex(index);
|
||||
}
|
||||
|
||||
boolean gridUpdate(InputHandler input){
|
||||
if(Core.input.keyDown(Binding.pick)){ //mouse eyedropper select
|
||||
Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
Block tryRecipe = tile.block();
|
||||
if(tryRecipe.isVisible() && unlocked(tryRecipe)){
|
||||
input.block = tryRecipe;
|
||||
currentCategory = input.block.buildCategory;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!Core.input.keyDown(Binding.gridMode) || ui.chatfrag.chatOpen()) return false;
|
||||
if(Core.input.keyDown(Binding.gridModeShift)){ //select category
|
||||
int i = 0;
|
||||
@@ -75,24 +104,12 @@ public class PlacementFragment extends Fragment{
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}else if(Core.input.keyDown(Binding.select)){ //mouse eyedropper select
|
||||
Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
|
||||
if(tile != null){
|
||||
tile = tile.target();
|
||||
Block tryRecipe = tile.block();
|
||||
if(tryRecipe.isVisible() && data.isUnlocked(tryRecipe)){
|
||||
input.block = tryRecipe;
|
||||
currentCategory = input.block.buildCategory;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else{ //select block
|
||||
int i = 0;
|
||||
Array<Block> recipes = getByCategory(currentCategory);
|
||||
for(KeyCode key : inputGrid){
|
||||
if(Core.input.keyDown(key))
|
||||
input.block = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null;
|
||||
input.block = (i < recipes.size && unlocked(recipes.get(i))) ? recipes.get(i) : null;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -103,7 +120,7 @@ public class PlacementFragment extends Fragment{
|
||||
public void build(Group parent){
|
||||
parent.fill(full -> {
|
||||
toggler = full;
|
||||
full.bottom().right().visible(() -> !state.is(State.menu));
|
||||
full.bottom().right().visible(() -> !state.is(State.menu) && ui.hudfrag.shown());
|
||||
|
||||
full.table(frame -> {
|
||||
InputHandler input = control.input(0);
|
||||
@@ -119,34 +136,28 @@ public class PlacementFragment extends Fragment{
|
||||
group.setMinCheckCount(0);
|
||||
|
||||
for(Block block : getByCategory(currentCategory)){
|
||||
|
||||
if(index++ % rowWidth == 0){
|
||||
blockTable.row();
|
||||
}
|
||||
|
||||
boolean[] unlocked = {false};
|
||||
if(!unlocked(block)){
|
||||
blockTable.add().size(46);
|
||||
continue;
|
||||
}
|
||||
|
||||
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> {
|
||||
if(data.isUnlocked(block)){
|
||||
if(unlocked(block)){
|
||||
input.block = input.block == block ? null : block;
|
||||
}
|
||||
}).size(46f).group(group).get();
|
||||
|
||||
button.getStyle().imageUp = new TextureRegionDrawable(block.icon(Icon.medium));
|
||||
|
||||
button.update(() -> { //color unplacable things gray
|
||||
boolean ulock = data.isUnlocked(block);
|
||||
TileEntity core = players[0].getClosestCore();
|
||||
Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE;
|
||||
Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : Color.GRAY;
|
||||
button.forEach(elem -> elem.setColor(color));
|
||||
button.setChecked(input.block == block);
|
||||
|
||||
if(ulock == unlocked[0]) return;
|
||||
unlocked[0] = ulock;
|
||||
|
||||
if(!ulock){
|
||||
button.replaceImage(new Image("icon-locked"));
|
||||
}else{
|
||||
button.replaceImage(new Image(block.icon(Icon.medium)));
|
||||
}
|
||||
});
|
||||
|
||||
button.hovered(() -> hovered = block);
|
||||
@@ -165,7 +176,7 @@ public class PlacementFragment extends Fragment{
|
||||
top.add(new Table()).growX().update(topTable -> {
|
||||
//don't refresh unnecessarily
|
||||
if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround)
|
||||
|| (tileDisplayBlock() != null && lastHover == hoverTile && lastGround))
|
||||
|| (tileDisplayBlock() != null && lastHover == hoverTile && lastDisplay == tileDisplayBlock() && lastGround))
|
||||
return;
|
||||
|
||||
topTable.clear();
|
||||
@@ -181,10 +192,10 @@ public class PlacementFragment extends Fragment{
|
||||
topTable.table(header -> {
|
||||
header.left();
|
||||
header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4);
|
||||
header.labelWrap(() -> !data.isUnlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName)
|
||||
header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.localizedName)
|
||||
.left().width(190f).padLeft(5);
|
||||
header.add().growX();
|
||||
if(data.isUnlocked(lastDisplay)){
|
||||
if(unlocked(lastDisplay)){
|
||||
header.addButton("?", "clear-partial", () -> ui.content.show(lastDisplay))
|
||||
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
|
||||
}
|
||||
@@ -197,7 +208,7 @@ public class PlacementFragment extends Fragment{
|
||||
for(ItemStack stack : lastDisplay.buildRequirements){
|
||||
req.table(line -> {
|
||||
line.left();
|
||||
line.addImage(stack.item.region).size(8 * 2);
|
||||
line.addImage(stack.item.icon(Item.Icon.small)).size(8 * 2);
|
||||
line.add(stack.item.localizedName()).color(Color.LIGHT_GRAY).padLeft(2).left();
|
||||
line.labelWrap(() -> {
|
||||
TileEntity core = players[0].getClosestCore();
|
||||
@@ -231,7 +242,7 @@ public class PlacementFragment extends Fragment{
|
||||
});
|
||||
}).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled);
|
||||
frame.row();
|
||||
frame.addImage("blank").color(Palette.accent).colspan(3).height(3).growX();
|
||||
frame.addImage("blank").color(Pal.accent).colspan(3).height(3).growX();
|
||||
frame.row();
|
||||
frame.table("pane-2", blocksSelect -> {
|
||||
blocksSelect.margin(4).marginTop(0);
|
||||
@@ -244,15 +255,25 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
||||
|
||||
//update category empty values
|
||||
for(Category cat : Category.values()){
|
||||
if(getByCategory(cat).isEmpty()) continue;
|
||||
Array<Block> blocks = getByCategory(cat);
|
||||
categoryEmpty[cat.ordinal()] = blocks.isEmpty() || !unlocked(blocks.first());
|
||||
}
|
||||
|
||||
int f = 0;
|
||||
for(Category cat : getCategories()){
|
||||
if(f++ % 2 == 0) categories.row();
|
||||
|
||||
if(categoryEmpty[cat.ordinal()]){
|
||||
categories.addImage("flat");
|
||||
continue;
|
||||
}
|
||||
|
||||
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> {
|
||||
currentCategory = cat;
|
||||
rebuildCategory.run();
|
||||
}).group(group).update(i -> i.setChecked(currentCategory == cat));
|
||||
|
||||
if(cat.ordinal() % 2 == 1) categories.row();
|
||||
}
|
||||
}).touchable(Touchable.enabled);
|
||||
|
||||
@@ -263,6 +284,13 @@ public class PlacementFragment extends Fragment{
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Array<Category> getCategories(){
|
||||
returnCatArray.clear();
|
||||
returnCatArray.addAll(Category.values());
|
||||
returnCatArray.sort((c1, c2) -> Boolean.compare(categoryEmpty[c1.ordinal()], categoryEmpty[c2.ordinal()]));
|
||||
return returnCatArray;
|
||||
}
|
||||
|
||||
Array<Block> getByCategory(Category cat){
|
||||
returnArray.clear();
|
||||
@@ -271,9 +299,14 @@ public class PlacementFragment extends Fragment{
|
||||
returnArray.add(block);
|
||||
}
|
||||
}
|
||||
returnArray.sort((b1, b2) -> -Boolean.compare(unlocked(b1), unlocked(b2)));
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
boolean unlocked(Block block){
|
||||
return !world.isZone() || data.isUnlocked(block);
|
||||
}
|
||||
|
||||
/** Returns the currently displayed block in the top box. */
|
||||
Block getSelected(){
|
||||
Block toDisplay = null;
|
||||
@@ -309,16 +342,4 @@ public class PlacementFragment extends Fragment{
|
||||
Block tileDisplayBlock(){
|
||||
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null;
|
||||
}
|
||||
|
||||
/** Show or hide the placement menu. */
|
||||
void toggle(float t, Interpolation ip){
|
||||
toggler.clearActions();
|
||||
if(shown){
|
||||
shown = false;
|
||||
toggler.actions(Actions.translateBy(toggler.getTranslation().x + toggler.getWidth(), 0, t, ip));
|
||||
}else{
|
||||
shown = true;
|
||||
toggler.actions(Actions.translateBy(-toggler.getTranslation().x, 0, t, ip));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import io.anuke.arc.scene.ui.layout.Unit;
|
||||
import io.anuke.arc.util.Interval;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.gen.Call;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetConnection;
|
||||
import io.anuke.mindustry.net.Packets.AdminAction;
|
||||
@@ -82,7 +82,7 @@ public class PlayerListFragment extends Fragment{
|
||||
@Override
|
||||
public void draw(){
|
||||
super.draw();
|
||||
Draw.color(Palette.accent);
|
||||
Draw.color(Pal.accent);
|
||||
Draw.alpha(parentAlpha);
|
||||
Lines.stroke(Unit.dp.scl(3f));
|
||||
Lines.rect(x, y, width, height);
|
||||
@@ -136,7 +136,7 @@ public class PlayerListFragment extends Fragment{
|
||||
|
||||
content.add(button).padBottom(-6).width(350f).maxHeight(h + 14);
|
||||
content.row();
|
||||
content.addImage("blank").height(3f).color(state.rules.pvp ? player.getTeam().color : Palette.accent).growX();
|
||||
content.addImage("blank").height(3f).color(state.rules.pvp ? player.getTeam().color : Pal.accent).growX();
|
||||
content.row();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user