Tree-based zone layout

This commit is contained in:
Anuken
2019-01-25 21:48:03 -05:00
parent 89e29bce62
commit ead0547d59
4 changed files with 161 additions and 159 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ ButtonStyle: {
}, },
TextButtonStyle: { TextButtonStyle: {
default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: gray, down: button-down, up: button}, default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: gray, down: button-down, up: button},
node: {disabled: content-background, font: default-font, fontColor: white, disabledFontColor: gray, up: content-background, over: content-background-over}, node: {disabled: content-background-locked, font: default-font, fontColor: white, disabledFontColor: gray, up: content-background, over: content-background-over},
right: {over: button-right-over, font: default-font, fontColor: white, disabledFontColor: gray, down: button-right-down, up: button-right}, right: {over: button-right-over, font: default-font, fontColor: white, disabledFontColor: gray, down: button-right-down, up: button-right},
wave: {font: default-font, fontColor: white, disabledFontColor: gray, up: button-edge-4}, wave: {font: default-font, fontColor: white, disabledFontColor: gray, up: button-edge-4},
clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: flat-over, up: flat}, clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: flat-over, up: flat},
@@ -237,7 +237,5 @@ public class Zones implements ContentList{
waveSpacing = 60 * 80; 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.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.Vars;
/**Base interface for an unlockable content type.*/ /**Base interface for an unlockable content type.*/
public abstract class UnlockableContent extends MappableContent{ public abstract class UnlockableContent extends MappableContent{
@@ -26,4 +27,12 @@ public abstract class UnlockableContent extends MappableContent{
public boolean alwaysUnlocked(){ public boolean alwaysUnlocked(){
return false; 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.ObjectIntMap;
import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.collection.ObjectSet;
import io.anuke.arc.graphics.Color; 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.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.TextButton;
import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.util.Align; 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.content.Zones;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.game.Saves.SaveSlot; import io.anuke.mindustry.game.Saves.SaveSlot;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.io.SaveIO.SaveException; import io.anuke.mindustry.io.SaveIO.SaveException;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack; 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.type.Zone;
import io.anuke.mindustry.ui.TreeLayout; import io.anuke.mindustry.ui.TreeLayout;
import io.anuke.mindustry.ui.TreeLayout.TreeNode; 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;
import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Block.Icon;
@@ -51,7 +45,10 @@ public class DeployDialog extends FloatingDialog{
cont.setFillParent(true); cont.setFillParent(true);
cont.add(new View()).grow(); 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(){ public void setup(){
@@ -74,14 +71,87 @@ 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; TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> {
for(Zone zone : content.zones()){ if(b[0].childrenPressed()) return;
table(t -> {
TextButton button = t.addButton("", () -> { 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;
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();
}
boolean hidden(Zone zone){
for(Zone other : zone.zoneRequirements){
if(!data.isUnlocked(other)){
return true;
}
}
return false;
}
@Override
protected void drawBackground(float x, float y){
drawDefaultBackground(x, y);
}
boolean canUnlock(Zone zone){
if(data.isUnlocked(zone)){
return true;
}
for(Zone other : zone.zoneRequirements){
if(!data.isCompleted(other)){
return false;
}
}
for(Block other : zone.blockRequirements){
if(!data.isUnlocked(other)){
return false;
}
}
return data.hasItems(zone.itemRequirements);
}
void buildButton(Zone zone, TextButton button){
button.setDisabled(() -> !canUnlock(zone));
button.clicked(() -> {
if(!data.isUnlocked(zone)){ if(!data.isUnlocked(zone)){
data.removeItems(zone.itemRequirements); data.removeItems(zone.itemRequirements);
data.unlockContent(zone); data.unlockContent(zone);
@@ -91,11 +161,9 @@ public class DeployDialog extends FloatingDialog{
hide(); hide();
world.playZone(zone); world.playZone(zone);
} }
}).size(250f).disabled(b -> !canUnlock(zone)).get(); });
button.clearChildren(); if(zone.unlocked()){
if(data.isUnlocked(zone)){
button.table(title -> { button.table(title -> {
title.addImage("icon-zone").padRight(3); title.addImage("icon-zone").padRight(3);
title.add(zone.localizedName()); title.add(zone.localizedName());
@@ -173,108 +241,20 @@ public class DeployDialog extends FloatingDialog{
}).growX(); }).growX();
} }
} }
}).pad(4);
if(++i % 2 == 0){
row();
} }
}
}else{
SaveSlot slot = control.saves.getZoneSlot();
TextButton b[] = {null};
TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> {
if(b[0].childrenPressed()) return;
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;
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();
}
boolean hidden(Zone zone){
for(Zone other : zone.zoneRequirements){
if(!data.isUnlocked(other)){
return true;
}
}
return false;
}
@Override
protected void drawBackground(float x, float y){
drawDefaultBackground(x, y);
}
boolean canUnlock(Zone zone){
if(data.isUnlocked(zone)){
return true;
}
for(Zone other : zone.zoneRequirements){
if(!data.isCompleted(other)){
return false;
}
}
for(Block other : zone.blockRequirements){
if(!data.isUnlocked(other)){
return false;
}
}
return data.hasItems(zone.itemRequirements);
}
static Array<Zone> arr = new Array<>();
class View extends Group{ class View extends Group{
float panX = 0, panY = -200; float panX = 0, panY = -200;
{ {
for(ZoneNode node : nodes){ for(ZoneNode node : nodes){
ImageButton button = new ImageButton("", "node"); TextButton button = new TextButton("", "node");
button.setSize(nodeSize, nodeSize); button.setSize(nodeSize, nodeSize);
button.update(() -> { button.update(() -> {
button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center); 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); addChild(button);
} }
@@ -283,9 +263,24 @@ public class DeployDialog extends FloatingDialog{
panY += y; 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>{ class ZoneNode extends TreeNode<ZoneNode>{
final Array<Zone> arr = new Array<>();
final Zone zone; final Zone zone;
ZoneNode(Zone zone, ZoneNode parent){ ZoneNode(Zone zone, ZoneNode parent){