Tree-based zone layout
This commit is contained in:
@@ -237,7 +237,5 @@ public class Zones implements ContentList{
|
||||
waveSpacing = 60 * 80;
|
||||
}};
|
||||
}};
|
||||
|
||||
frozenForest.zoneRequirements = new Zone[]{frozenForest};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.game;
|
||||
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.mindustry.Vars;
|
||||
|
||||
/**Base interface for an unlockable content type.*/
|
||||
public abstract class UnlockableContent extends MappableContent{
|
||||
@@ -26,4 +27,12 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
public boolean alwaysUnlocked(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public final boolean unlocked(){
|
||||
return Vars.data.isUnlocked(this);
|
||||
}
|
||||
|
||||
public final boolean locked(){
|
||||
return !unlocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,8 @@ import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectIntMap;
|
||||
import io.anuke.arc.collection.ObjectSet;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.input.KeyCode;
|
||||
import io.anuke.arc.graphics.g2d.Lines;
|
||||
import io.anuke.arc.scene.Group;
|
||||
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.ScrollPane;
|
||||
import io.anuke.arc.scene.ui.TextButton;
|
||||
import io.anuke.arc.scene.ui.layout.Table;
|
||||
import io.anuke.arc.util.Align;
|
||||
@@ -20,6 +14,7 @@ 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.Palette;
|
||||
import io.anuke.mindustry.io.SaveIO.SaveException;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
@@ -27,7 +22,6 @@ import io.anuke.mindustry.type.ItemType;
|
||||
import io.anuke.mindustry.type.Zone;
|
||||
import io.anuke.mindustry.ui.TreeLayout;
|
||||
import io.anuke.mindustry.ui.TreeLayout.TreeNode;
|
||||
import io.anuke.mindustry.ui.dialogs.TechTreeDialog.TechTreeNode;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Block.Icon;
|
||||
|
||||
@@ -51,7 +45,10 @@ public class DeployDialog extends FloatingDialog{
|
||||
cont.setFillParent(true);
|
||||
cont.add(new View()).grow();
|
||||
|
||||
shown(this::setup);
|
||||
addCloseButton();
|
||||
buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f);
|
||||
|
||||
//shown(this::setup);
|
||||
}
|
||||
|
||||
public void setup(){
|
||||
@@ -74,153 +71,48 @@ public class DeployDialog extends FloatingDialog{
|
||||
}
|
||||
}
|
||||
|
||||
}}, new ScrollPane(new Table(){{
|
||||
}}, new Table(){{
|
||||
SaveSlot slot = control.saves.getZoneSlot();
|
||||
|
||||
if(control.saves.getZoneSlot() == null){
|
||||
TextButton[] b = {null};
|
||||
|
||||
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();
|
||||
TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> {
|
||||
if(b[0].childrenPressed()) return;
|
||||
|
||||
button.clearChildren();
|
||||
|
||||
if(data.isUnlocked(zone)){
|
||||
button.table(title -> {
|
||||
title.addImage("icon-zone").padRight(3);
|
||||
title.add(zone.localizedName());
|
||||
});
|
||||
button.row();
|
||||
|
||||
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(other) ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(data.isCompleted(other) ? 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();
|
||||
ui.showInfo("$save.corrupted");
|
||||
show();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
SaveSlot slot = control.saves.getZoneSlot();
|
||||
});
|
||||
}).size(200f).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();
|
||||
}}).grow();
|
||||
}
|
||||
|
||||
boolean hidden(Zone zone){
|
||||
@@ -257,24 +149,112 @@ public class DeployDialog extends FloatingDialog{
|
||||
return data.hasItems(zone.itemRequirements);
|
||||
}
|
||||
|
||||
static Array<Zone> arr = new Array<>();
|
||||
void buildButton(Zone zone, TextButton button){
|
||||
button.setDisabled(() -> !canUnlock(zone));
|
||||
button.clicked(() -> {
|
||||
if(!data.isUnlocked(zone)){
|
||||
data.removeItems(zone.itemRequirements);
|
||||
data.unlockContent(zone);
|
||||
setup();
|
||||
}else{
|
||||
data.removeItems(zone.deployCost);
|
||||
hide();
|
||||
world.playZone(zone);
|
||||
}
|
||||
});
|
||||
|
||||
if(zone.unlocked()){
|
||||
button.table(title -> {
|
||||
title.addImage("icon-zone").padRight(3);
|
||||
title.add(zone.localizedName());
|
||||
});
|
||||
button.row();
|
||||
|
||||
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(other) ? "icon-check-2" : "icon-cancel-2")
|
||||
.color(data.isCompleted(other) ? 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class View extends Group{
|
||||
float panX = 0, panY = -200;
|
||||
|
||||
{
|
||||
|
||||
for(ZoneNode node : nodes){
|
||||
ImageButton button = new ImageButton("", "node");
|
||||
|
||||
TextButton button = new TextButton("", "node");
|
||||
button.setSize(nodeSize, 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.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.node) ? Color.WHITE : Color.GRAY);
|
||||
});
|
||||
button.clearChildren();
|
||||
buildButton(node.zone, button);
|
||||
addChild(button);
|
||||
}
|
||||
|
||||
@@ -283,9 +263,24 @@ public class DeployDialog extends FloatingDialog{
|
||||
panY += y;
|
||||
});
|
||||
}
|
||||
|
||||
@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(3f, node.zone.locked() || child.zone.locked() ? Palette.locked : Palette.accent);
|
||||
Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class ZoneNode extends TreeNode<ZoneNode>{
|
||||
final Array<Zone> arr = new Array<>();
|
||||
final Zone zone;
|
||||
|
||||
ZoneNode(Zone zone, ZoneNode parent){
|
||||
|
||||
Reference in New Issue
Block a user