Added content unlock menu

This commit is contained in:
Anuken
2018-06-29 19:47:47 -04:00
parent b4151a256b
commit bebc1a22f3
25 changed files with 946 additions and 704 deletions

View File

@@ -1,8 +1,6 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import com.badlogic.gdx.utils.OrderedSet;
import com.badlogic.gdx.utils.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.content.blocks.*;
import io.anuke.mindustry.content.bullets.*;
@@ -28,6 +26,7 @@ import io.anuke.ucore.util.Log;
public class ContentLoader {
private static boolean loaded = false;
private static ObjectSet<Array<? extends Content>> contentSet = new OrderedSet<>();
private static OrderedMap<String, Array<Content>> contentMap = new OrderedMap<>();
private static ContentList[] content = {
//effects
new BlockFx(),
@@ -104,6 +103,15 @@ public class ContentLoader {
}
for (ContentList list : content){
if(list.getAll().size != 0){
String type = list.getAll().first().getContentTypeName();
if(!contentMap.containsKey(type)){
contentMap.put(type, new Array<>());
}
contentMap.get(type).addAll(list.getAll());
}
contentSet.add(list.getAll());
}
@@ -134,6 +142,10 @@ public class ContentLoader {
//TODO clear all content.
}
public static OrderedMap<String, Array<Content>> getContentMap(){
return contentMap;
}
/**Registers sync IDs for all types of sync entities.
* Do not register units here!*/
private static void registerTypes(){

View File

@@ -57,6 +57,8 @@ public class UI extends SceneModule{
public RollbackDialog rollback;
public ChangelogDialog changelog;
public LocalPlayerDialog localplayers;
public UnlocksDialog unlocks;
public ContentInfoDialog content;
public final MenuFragment menufrag = new MenuFragment();
public final HudFragment hudfrag = new HudFragment();
@@ -72,10 +74,10 @@ public class UI extends SceneModule{
Dialog.setShowAction(()-> sequence(
alpha(0f),
originCenter(),
moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center),
moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2, Align.center),
scaleTo(0.0f, 1f),
parallel(
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
fadeIn(0.1f, Interpolation.fade)
)
));
@@ -173,6 +175,8 @@ public class UI extends SceneModule{
rollback = new RollbackDialog();
maps = new MapsDialog();
localplayers = new LocalPlayerDialog();
unlocks = new UnlocksDialog();
content = new ContentInfoDialog();
build.begin(scene);

View File

@@ -8,8 +8,11 @@ import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
//TODO merge unit type with mech
public class UnitType implements UnlockableContent{
@@ -54,6 +57,21 @@ public class UnitType implements UnlockableContent{
TypeTrait.registerType(type, mainConstructor);
}
@Override
public void displayInfo(Table table) {
ContentDisplay.displayUnit(table, this);
}
@Override
public String localizedName() {
return Bundles.get("unit." + name + ".name");
}
@Override
public TextureRegion getContentIcon() {
return iconRegion;
}
@Override
public void load() {
iconRegion = Draw.region("unit-icon-" + name);

View File

@@ -1,5 +1,8 @@
package io.anuke.mindustry.game;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.ucore.scene.ui.layout.Table;
/**Base interface for an unlockable content type.*/
public interface UnlockableContent extends Content{
@@ -8,4 +11,12 @@ public interface UnlockableContent extends Content{
* Do not use IDs for names! Make sure this string stays constant with each update unless removed.
* (e.g. having a recipe and a block, both with name "wall" is fine, as they are different types).*/
String getContentName();
/**Returns the localized name of this content.*/
String localizedName();
TextureRegion getContentIcon();
/**This should show all necessary info about this content in the specified table.*/
void displayInfo(Table table);
}

View File

@@ -17,7 +17,7 @@ public class BundleLoader {
public static void load(){
Settings.defaults("locale", "default");
Settings.load("io.anuke.mindustry");
Settings.load(headless ? "io.anuke.mindustry.server" : "io.anuke.mindustry");
loadBundle();
}

View File

@@ -6,7 +6,9 @@ import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
public class Item implements Comparable<Item>, UnlockableContent{
@@ -47,10 +49,21 @@ public class Item implements Comparable<Item>, UnlockableContent{
this.region = Draw.region("item-" + name);
}
@Override
public void displayInfo(Table table) {
ContentDisplay.displayItem(table, this);
}
@Override
public String localizedName(){
return Bundles.get("item." + this.name + ".name");
}
@Override
public TextureRegion getContentIcon() {
return region;
}
@Override
public String toString() {
return localizedName();

View File

@@ -1,10 +1,14 @@
package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
public class Liquid implements UnlockableContent{
@@ -40,10 +44,21 @@ public class Liquid implements UnlockableContent{
Liquid.liquids.add(this);
}
@Override
public void displayInfo(Table table) {
ContentDisplay.displayLiquid(table, this);
}
@Override
public String localizedName(){
return Bundles.get("liquid."+ this.name + ".name");
}
@Override
public TextureRegion getContentIcon() {
return Draw.region("liquid-icon");
}
@Override
public String toString(){
return localizedName();

View File

@@ -3,10 +3,13 @@ package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
//TODO merge unit type with mech
public class Mech extends Upgrade {
public class Mech extends Upgrade implements UnlockableContent{
public boolean flying;
public float speed = 1.1f;
@@ -37,6 +40,26 @@ public class Mech extends Upgrade {
this.flying = flying;
}
@Override
public void displayInfo(Table table) {
ContentDisplay.displayMech(table, this);
}
@Override
public TextureRegion getContentIcon() {
return iconRegion;
}
@Override
public String getContentName() {
return name;
}
@Override
public String getContentTypeName() {
return "mech";
}
@Override
public void load() {
if (!flying){

View File

@@ -1,11 +1,14 @@
package io.anuke.mindustry.type;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings;
@@ -57,6 +60,21 @@ public class Recipe implements UnlockableContent{
return this;
}
@Override
public void displayInfo(Table table) {
ContentDisplay.displayRecipe(table, this);
}
@Override
public String localizedName() {
return result.formalName;
}
@Override
public TextureRegion getContentIcon() {
return result.getEditorIcon();
}
@Override
public void init() {
if(!Bundles.has("block." + result.name + ".name")) {

View File

@@ -2,12 +2,11 @@ package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Bundles;
public abstract class Upgrade implements UnlockableContent{
public abstract class Upgrade implements Content{
private static Array<Upgrade> upgrades = new Array<>();
private static byte lastid;
@@ -23,23 +22,13 @@ public abstract class Upgrade implements UnlockableContent{
upgrades.add(this);
}
public String localized(){
public String localizedName(){
return Bundles.get("upgrade." + name + ".name");
}
@Override
public String toString(){
return localized();
}
@Override
public String getContentName() {
return name;
}
@Override
public String getContentTypeName() {
return "upgrade";
return localizedName();
}
@Override

View File

@@ -61,7 +61,12 @@ public class Weapon extends Upgrade {
region = Draw.region(name);
}
public void update(ShooterTrait shooter, float pointerX, float pointerY){
@Override
public String getContentTypeName() {
return "weapon";
}
public void update(ShooterTrait shooter, float pointerX, float pointerY){
update(shooter, true, pointerX, pointerY);
update(shooter, false, pointerX, pointerY);
}

View File

@@ -2,10 +2,9 @@ package io.anuke.mindustry.type;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
//TODO implement this class
public class WeatherEvent implements UnlockableContent{
public class WeatherEvent implements Content{
private static final Array<WeatherEvent> all = new Array<>();
private static int lastid;
@@ -19,11 +18,6 @@ public class WeatherEvent implements UnlockableContent{
all.add(this);
}
@Override
public String getContentName() {
return name;
}
@Override
public String getContentTypeName() {
return "weatherevent";

View File

@@ -0,0 +1,90 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.defense.turrets.Turret;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.BlockStats;
import io.anuke.mindustry.world.meta.StatCategory;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.layout.Table;
public class ContentDisplay {
public static void displayRecipe(Table table, Recipe recipe){
Block block = recipe.result;
FloatingDialog dialog = new FloatingDialog("$text.blocks.blockinfo");
dialog.addCloseButton();
table.table(title -> {
int size = 8*6;
if(block instanceof Turret){
size = (8 * block.size + 2) * (7 - block.size*2);
}
title.addImage(Draw.region("block-icon-" + block.name)).size(size);
title.add("[accent]" + block.formalName).padLeft(5);
});
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
if(block.fullDescription != null){
table.add(block.fullDescription).padLeft(5).padRight(5).width(400f).wrap().fillX();
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
}
BlockStats stats = block.stats;
for(StatCategory cat : stats.toMap().keys()){
OrderedMap<BlockStat, StatValue> map = stats.toMap().get(cat);
if(map.size == 0) continue;
table.add("$text.category." + cat.name()).color(Palette.accent).fillX();
table.row();
for (BlockStat stat : map.keys()){
table.table(inset -> {
inset.left();
inset.add("[LIGHT_GRAY]" + stat.localized() + ":[] ");
map.get(stat).display(inset);
}).fillX().padLeft(10);
table.row();
}
}
}
public static void displayItem(Table table, Item item){
}
public static void displayLiquid(Table table, Liquid liquid){
}
public static void displayMech(Table table, Mech mech){
}
public static void displayUnit(Table table, UnitType unit){
}
}

View File

@@ -13,7 +13,7 @@ public class MenuButton extends TextButton{
public MenuButton(String icon, String text, String description, Listenable clicked){
super("default");
float s = 70f;
float s = 66f;
clicked(clicked);

View File

@@ -0,0 +1,28 @@
package io.anuke.mindustry.ui.dialogs;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.layout.Table;
public class ContentInfoDialog extends FloatingDialog {
public ContentInfoDialog(){
super("$text.info");
addCloseButton();
}
public void show(UnlockableContent content){
content().clear();
Table table = new Table();
table.margin(10);
content.displayInfo(table);
ScrollPane pane = new ScrollPane(table, "clear-black");
content().add(pane);
show();
}
}

View File

@@ -0,0 +1,75 @@
package io.anuke.mindustry.ui.dialogs;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.ContentLoader;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.Tooltip;
import io.anuke.ucore.scene.ui.layout.Table;
import static io.anuke.mindustry.Vars.control;
public class UnlocksDialog extends FloatingDialog {
public UnlocksDialog() {
super("$text.unlocks");
addCloseButton();
shown(this::rebuild);
}
void rebuild(){
content().clear();
Table table = new Table();
table.margin(20);
ScrollPane pane = new ScrollPane(table, "clear-black");
OrderedMap<String, Array<Content>> allContent = ContentLoader.getContentMap();
//allContent.orderedKeys().reverse();
for(String key : allContent.orderedKeys()){
Array<Content> array = allContent.get(key);
if(array.size == 0 || !(array.first() instanceof UnlockableContent)) continue;
table.add("$content." +key + ".name").growX().left().color(Palette.accent);
table.row();
table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Palette.accent);
table.row();
table.table(list -> {
list.left();
int maxWidth = 14;
int size = 8*6;
for (int i = 0; i < array.size; i++) {
UnlockableContent unlock = (UnlockableContent)array.get(i);
Image image = control.database().isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-locked");
list.add(image).size(size).pad(3);
if(control.database().isUnlocked(unlock)) {
image.clicked(() -> Vars.ui.content.show(unlock));
image.addListener(new Tooltip<>(new Table("clear"){{
add(unlock.localizedName());
margin(4);
}}));
}
if((i+1) % maxWidth == 0){
list.row();
}
}
}).growX().left().padBottom(10);
table.row();
}
content().add(pane);
}
}

View File

@@ -4,25 +4,15 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.type.Category;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.defense.turrets.Turret;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.BlockStats;
import io.anuke.mindustry.world.meta.StatCategory;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.actions.Actions;
@@ -327,7 +317,7 @@ public class BlocksFragment implements Fragment{
nameLabel.setWrap(true);
header.add(nameLabel).padLeft(2).width(120f);
header.addButton("?", () -> showBlockInfo(recipe.result)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2);
header.addButton("?", () -> ui.content.show(recipe)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2);
descTable.add().pad(2);
@@ -357,62 +347,6 @@ public class BlocksFragment implements Fragment{
descTable.row();
}
private void showBlockInfo(Block block){
FloatingDialog dialog = new FloatingDialog("$text.blocks.blockinfo");
dialog.addCloseButton();
Table table = new Table();
ScrollPane pane = new ScrollPane(table, "clear");
table.table(title -> {
int size = 8*6;
if(block instanceof Turret){
size = (8 * block.size + 2) * (7 - block.size*2);
}
title.addImage(Draw.region("block-icon-" + block.name)).size(size);
title.add("[accent]" + block.formalName).padLeft(5);
});
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
if(block.fullDescription != null){
table.add(block.fullDescription).padLeft(5).padRight(5).width(400f).wrap().fillX();
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
}
BlockStats stats = block.stats;
for(StatCategory cat : stats.toMap().keys()){
OrderedMap<BlockStat, StatValue> map = stats.toMap().get(cat);
if(map.size == 0) continue;
table.add("$text.category." + cat.name()).color(Palette.accent).fillX();
table.row();
for (BlockStat stat : map.keys()){
table.table(inset -> {
inset.left();
inset.add("[LIGHT_GRAY]" + stat.localized() + ":[] ");
map.get(stat).display(inset);
}).fillX().padLeft(10);
table.row();
}
}
dialog.content().add(pane).grow();
dialog.show();
}
String format(int number){
if(number >= 1000000) {
return Strings.toFixed(number/1000000f, 1) + "[gray]mil[]";

View File

@@ -25,7 +25,7 @@ public class MenuFragment implements Fragment{
float w = 200f;
float bw = w * 2f + 10f;
defaults().size(w, 70f).padTop(5).padRight(5);
defaults().size(w, 66f).padTop(5).padRight(5);
add(new MenuButton("icon-play-2", "$text.play", MenuFragment.this::showPlaySelect)).width(bw).colspan(2);
@@ -41,6 +41,12 @@ public class MenuFragment implements Fragment{
add(new MenuButton("icon-tools", "$text.settings", ui.settings::show));
row();
add(new MenuButton("icon-menu", "$text.changelog.title", ui.changelog::show));
add(new MenuButton("icon-unlocks", "$text.unlocks", ui.unlocks::show));
row();
if(!gwt){

View File

@@ -14,7 +14,6 @@ import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.effect.Puddle;
import io.anuke.mindustry.entities.effect.RubbleDecal;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.graphics.CacheLayer;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
@@ -34,7 +33,7 @@ import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*;
public class Block extends BaseBlock implements UnlockableContent{
public class Block extends BaseBlock implements Content{
private static int lastid;
private static Array<Block> blocks = new Array<>(140);
private static ObjectMap<String, Block> map = new ObjectMap<>();
@@ -456,11 +455,6 @@ public class Block extends BaseBlock implements UnlockableContent{
);
}
@Override
public String getContentName() {
return name;
}
@Override
public String getContentTypeName() {
return "block";