diff --git a/core/src/io/anuke/mindustry/Control.java b/core/src/io/anuke/mindustry/Control.java index 8971952089..9b6e040870 100644 --- a/core/src/io/anuke/mindustry/Control.java +++ b/core/src/io/anuke/mindustry/Control.java @@ -35,7 +35,7 @@ import io.anuke.ucore.util.Mathf; public class Control extends Module{ int targetscale = baseCameraScale; - Tutorial tutorial = new Tutorial(); + public Tutorial tutorial = new Tutorial(); boolean hiscore = false; final Array weapons = new Array<>(); diff --git a/core/src/io/anuke/mindustry/UI.java b/core/src/io/anuke/mindustry/UI.java index 1382edbd72..f6586bcf7f 100644 --- a/core/src/io/anuke/mindustry/UI.java +++ b/core/src/io/anuke/mindustry/UI.java @@ -13,33 +13,29 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.GameState.State; -import io.anuke.mindustry.input.AndroidInput; -import io.anuke.mindustry.input.PlaceMode; -import io.anuke.mindustry.resource.*; +import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.ui.*; -import io.anuke.mindustry.world.Map; +import io.anuke.mindustry.ui.fragments.*; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.*; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.function.StringSupplier; import io.anuke.ucore.function.VisibilityProvider; import io.anuke.ucore.modules.SceneModule; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Skin; import io.anuke.ucore.scene.actions.Actions; -import io.anuke.ucore.scene.builders.*; +import io.anuke.ucore.scene.builders.build; +import io.anuke.ucore.scene.builders.label; +import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.Window.WindowStyle; -import io.anuke.ucore.scene.ui.layout.Stack; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; -import io.anuke.ucore.util.Mathf; public class UI extends SceneModule{ - Table itemtable, weapontable, tools, loadingtable, desctable, respawntable, configtable; + Table itemtable, weapontable, loadingtable, desctable, respawntable, configtable; MindustrySettingsDialog prefs; MindustryKeybindDialog keys; Dialog about, restart, levels, upgrades, load, settingserror; @@ -48,6 +44,14 @@ public class UI extends SceneModule{ Tile configTile; Array statlist = new Array<>(); boolean wasPaused = false; + + private Fragment blockfrag = new BlocksFragment(), + menufrag = new MenuFragment(), + profilefrag = new ProfilerFragment(), + toolfrag = new ToolFragment(), + hudfrag = new HudFragment(), + placefrag = new PlacementFragment(), + weaponfrag = new WeaponFragment(); VisibilityProvider play = () -> !GameState.is(State.menu); VisibilityProvider nplay = () -> GameState.is(State.menu); @@ -244,364 +248,22 @@ public class UI extends SceneModule{ control.reset(); }).size(200, 50).pad(3).units(Unit.dp); - weapontable = fill(); - weapontable.bottom().left(); - weapontable.setVisible(play); - - if(android){ - weapontable.remove(); - } - build.begin(scene); - - new table(){{ - abottom(); - aright(); - - new table("button"){{ - visible(()->player.recipe != null); - desctable = get(); - fillX(); - }}.end().uniformX(); - - row(); - - new table("pane"){{ - - int rows = 4; - int maxcol = 0; - float size = 48; - - Stack stack = new Stack(); - ButtonGroup group = new ButtonGroup<>(); - Array recipes = new Array(); - - for(Section sec : Section.values()){ - recipes.clear(); - Recipe.getBy(sec, recipes); - maxcol = Math.max((int)((float)recipes.size/rows+1), maxcol); - } - - for(Section sec : Section.values()){ - recipes.clear(); - Recipe.getBy(sec, recipes); - - Table table = new Table(); - - ImageButton button = new ImageButton("icon-"+sec.name(), "toggle"); - button.clicked(()->{ - if(!table.isVisible() && player.recipe != null){ - player.recipe = null; - } - }); - button.setName("sectionbutton" + sec.name()); - add(button).growX().height(54).padTop(sec.ordinal() <= 2 ? -10 : -5).units(Unit.dp); - button.getImageCell().size(40).padBottom(4).padTop(2).units(Unit.dp); - group.add(button); - - if(sec.ordinal() % 3 == 2 && sec.ordinal() > 0){ - row(); - } - - table.pad(4); - table.top().left(); - - int i = 0; - - for(Recipe r : recipes){ - TextureRegion region = Draw.hasRegion(r.result.name() + "-icon") ? - Draw.region(r.result.name() + "-icon") : Draw.region(r.result.name()); - ImageButton image = new ImageButton(region, "select"); - - image.clicked(()->{ - if(player.recipe == r){ - player.recipe = null; - }else{ - player.recipe = r; - updateRecipe(); - } - }); - - table.add(image).size(size+8).pad(2).units(Unit.dp); - image.getImageCell().size(size).units(Unit.dp); - - image.update(()->{ - - boolean canPlace = !control.tutorial.active() || control.tutorial.canPlace(); - boolean has = control.hasItems(r.requirements) && canPlace; - //image.setDisabled(!has); - image.setChecked(player.recipe == r); - image.setTouchable(canPlace ? Touchable.enabled : Touchable.disabled); - image.getImage().setColor(has ? Color.WHITE : Color.DARK_GRAY); - }); - - if(i % rows == rows-1) - table.row(); - - i++; - } - - table.setVisible(()-> button.isChecked()); - - stack.add(table); - } - - - row(); - add(stack).colspan(Section.values().length); - get().pad(10f); - - get().padLeft(0f); - get().padRight(0f); - - end(); - }}.right().bottom().uniformX(); - - visible(play); - - }}.end(); - - new table(){{ - atop(); - aleft(); - - new table(){{ - left(); - defaults().size(66).units(Unit.dp).left(); - float isize = Unit.dp.inPixels(40); - - new imagebutton("icon-menu", isize, ()->{ - showMenu(); - }); - - new imagebutton("icon-settings", isize, ()->{ - prefs.show(); - }); - - new imagebutton("icon-pause", isize, ()->{ - GameState.set(GameState.is(State.paused) ? State.playing : State.paused); - }){{ - get().update(()->{ - get().getStyle().imageUp = Core.skin.getDrawable(GameState.is(State.paused) ? "icon-play" : "icon-pause"); - }); - }}; - }}.end(); - - row(); - - itemtable = new table("button").end().top().left().fillX().size(-1).get(); - - get().setVisible(play); - - Label fps = new Label(()->(Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") : "")); - row(); - add(fps).size(-1); - - }}.end(); - new table(){{ - control.tutorial.buildUI(this); - - visible(()->control.tutorial.active()); - }}.end(); - - //paused table - new table(){{ - visible(()->GameState.is(State.paused)); - atop(); - - new table("pane"){{ - new label("[orange]< paused >").scale(Unit.dp.inPixels(0.75f)).pad(6).units(Unit.dp); - }}.end(); - }}.end(); + weaponfrag.build(); - //wave table... - new table(){{ - atop(); - aright(); - - new table("button"){{ - - new label(()->"[orange]Wave " + control.getWave()).scale(fontscale*2f).left(); - - row(); - - new label(()-> control.getEnemiesRemaining() > 0 ? - control.getEnemiesRemaining() + " Enemies remaining" : - control.tutorial.active() ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f)) - .minWidth(150); - - get().pad(Unit.dp.inPixels(12)); - }}; - - get().setVisible(play); - }}.end(); + blockfrag.build(); - if(!android){ - //menu table - new table(){{ - - new table(){{ - float scale = 4f; - defaults().size(100*scale, 21*scale).pad(-10f).units(Unit.dp); - - add(new MenuButton("text-play", ()-> levels.show())); - row(); - - add(new MenuButton("text-tutorial", ()-> control.playMap(Map.tutorial))); - row(); - - if(!gwt){ - add(new MenuButton("text-load", ()-> load.show())); - row(); - } - - add(new MenuButton("text-settings", ()-> prefs.show())); - row(); - - if(!gwt){ - add(new MenuButton("text-exit", ()-> Gdx.app.exit())); - } - get().pad(Unit.dp.inPixels(16)); - }}; - - visible(nplay); - }}.end(); - }else{ - new table(){{ - defaults().size(120f).pad(5).units(Unit.dp); - float isize = Unit.dp.inPixels(14f*4); - - new imagebutton("icon-play-2", isize, () -> { - levels.show(); - }).text("Play").padTop(4f); - - new imagebutton("icon-tutorial", isize, ()->{ - control.playMap(Map.tutorial); - }).text("Tutorial").padTop(4f); - - new imagebutton("icon-load", isize, () -> { - load.show(); - }).text("Load").padTop(4f); - - new imagebutton("icon-tools", isize, () -> { - prefs.show(scene); - }).text("Settings").padTop(4f); - - visible(nplay); - }}.end(); - } + hudfrag.build(); - //settings icon - new table(){{ - atop().aright(); - new imagebutton("icon-info", Unit.dp.inPixels(30f), ()->{ - about.show(); - }).get().pad(14); - }}.end().visible(nplay); + menufrag.build(); - if(debug){ - new table(){{ - abottom(); - aleft(); - new label((StringSupplier)()->"[purple]entities: " + Entities.amount()).left(); - row(); - new label("[red]DEBUG MODE").scale(0.5f).left(); - }}.end(); - - new table(){{ - atop(); - new table("button"){{ - defaults().left().growX(); - atop(); - aleft(); - new label((StringSupplier)()->"[red]total: " - + String.format("%.1f", (float)Profiler.total/Profiler.total*100f)+ "% - " + Profiler.total).left(); - row(); - new label((StringSupplier)()->"[yellow]draw: " - + String.format("%.1f", (float)Profiler.draw/Profiler.total*100f)+ "% - " + Profiler.draw).left(); - row(); - new label((StringSupplier)()->"[green]blockDraw: " - + String.format("%.1f", (float)Profiler.blockDraw/Profiler.total*100f)+ "% - " + Profiler.blockDraw).left(); - row(); - new label((StringSupplier)()->"[blue]entityDraw: " - + String.format("%.1f", (float)Profiler.entityDraw/Profiler.total*100f)+ "% - " + Profiler.entityDraw).left(); - row(); - new label((StringSupplier)()->"[purple]entityUpdate: " - + String.format("%.1f", (float)Profiler.entityUpdate/Profiler.total*100f)+ "% - " + Profiler.entityUpdate).left(); - row(); - }}.width(400f).end(); - }}.end(); - } + profilefrag.build(); - //respawn background table - new table("white"){{ - respawntable = get(); - respawntable.setColor(Color.CLEAR); - - }}.end(); - - //respawn table - new table(){{ - new table("pane"){{ - - new label(()->"[orange]Respawning in " + (int)(control.getRespawnTime()/60)).scale(0.75f).pad(10); - - visible(()->control.getRespawnTime() > 0 && !GameState.is(State.menu)); - - }}.end(); - }}.end(); - - if(android){ - //placement table - new table(){{ - visible(()->player.recipe != null && !GameState.is(State.menu)); - abottom(); - aleft(); - - - new table("pane"){{ - new label(()->"Placement Mode: [orange]" + AndroidInput.mode.name()).pad(4).units(Unit.dp); - row(); - - aleft(); - - new table(){{ - aleft(); - ButtonGroup group = new ButtonGroup<>(); - - defaults().size(58, 62).pad(6).units(Unit.dp); - - for(PlaceMode mode : PlaceMode.values()){ - new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{ - AndroidInput.mode = mode; - }){{ - group.add(get()); - }}; - } - - new imagebutton("icon-cancel", Unit.dp.inPixels(14*3), ()->{ - player.recipe = null; - }).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch); - - new imagebutton("icon-rotate-arrow", Unit.dp.inPixels(14*3), ()->{ - player.rotation ++; - player.rotation %= 4; - }).update(i->{ - i.getImage().setOrigin(Align.center); - i.getImage().setRotation(player.rotation*90); - }).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch - && player.recipe.result.rotate); - - }}.left().end(); - }}.end(); - }}.end(); - - } + placefrag.build(); loadingtable = new table("loadDim"){{ get().setTouchable(Touchable.enabled); - //new table(){{ get().addImage("white").growX() .height(3f).pad(4f).growX().units(Unit.dp).get().setColor(Color.ORANGE); row(); @@ -611,192 +273,25 @@ public class UI extends SceneModule{ row(); get().addImage("white").growX() .height(3f).pad(4f).growX().units(Unit.dp).get().setColor(Color.ORANGE); - //}}.end(); }}.end().get(); loadingtable.setVisible(false); - tools = new Table(); - tools.addIButton("icon-cancel", Unit.dp.inPixels(42), ()->{ - player.recipe = null; - }); - - tools.addIButton("icon-rotate", Unit.dp.inPixels(42), ()->{ - player.rotation ++; - player.rotation %= 4; - }); - - tools.addIButton("icon-check", Unit.dp.inPixels(42), ()->{ - AndroidInput.place(); - }); - - scene.add(tools); - - tools.setVisible(()-> - !GameState.is(State.menu) && android && player.recipe != null && control.hasItems(player.recipe.requirements) && - AndroidInput.mode == PlaceMode.cursor - ); - - tools.update(()->{ - tools.setPosition(AndroidInput.mousex, Gdx.graphics.getHeight()-AndroidInput.mousey-15*Core.cameraScale, Align.top); - }); + toolfrag.build(); updateItems(); build.end(); } + public void updateWeapons(){ + ((WeaponFragment)weaponfrag).updateWeapons(); + } + public void fadeRespawn(boolean in){ respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f)); } - void updateRecipe(){ - Recipe recipe = player.recipe; - desctable.clear(); - - desctable.defaults().left(); - desctable.left(); - desctable.pad(Unit.dp.inPixels(12)); - - Table header = new Table(); - - desctable.add(header).left(); - - desctable.row(); - - TextureRegion region = Draw.hasRegion(recipe.result.name() + "-icon") ? - Draw.region(recipe.result.name() + "-icon") : Draw.region(recipe.result.name()); - - header.addImage(region).size(8*5).padTop(4).units(Unit.dp); - Label nameLabel = new Label(recipe.result.formalName); - nameLabel.setWrap(true); - header.add(nameLabel).padLeft(4).width(135f).units(Unit.dp); - - //extra info - if(recipe.result.fullDescription != null){ - header.addButton("?", ()->{ - statlist.clear(); - recipe.result.getStats(statlist); - - Label desclabel = new Label(recipe.result.fullDescription); - desclabel.setWrap(true); - - boolean wasPaused = GameState.is(State.paused); - GameState.set(State.paused); - - FloatingDialog d = new FloatingDialog("Block Info"); - Table top = new Table(); - top.left(); - top.add(new Image(Draw.region(recipe.result.name))).size(8*5 * recipe.result.width).units(Unit.dp); - top.add("[orange]"+recipe.result.formalName).padLeft(6f).units(Unit.dp); - d.content().add(top).fill().left(); - d.content().row(); - d.content().add(desclabel).width(600).units(Unit.dp); - d.content().row(); - - if(statlist.size > 0){ - d.content().add("[coral][[extra block info]:").padTop(6).padBottom(5).left(); - d.content().row(); - } - - for(String s : statlist){ - d.content().add(s).left(); - d.content().row(); - } - - d.buttons().addButton("OK", ()->{ - if(!wasPaused) GameState.set(State.playing); - d.hide(); - }).size(110, 50).pad(10f).units(Unit.dp); - - d.show(); - }).expandX().padLeft(4).top().right().size(36f, 40f).units(Unit.dp); - } - - - desctable.add().pad(2).units(Unit.dp); - - Table requirements = new Table(); - - desctable.row(); - - desctable.add(requirements); - desctable.left(); - - for(ItemStack stack : recipe.requirements){ - ItemStack fs = stack; - requirements.addImage(Draw.region("icon-"+stack.item.name())).size(8*3).units(Unit.dp); - Label reqlabel = new Label(""); - - reqlabel.update(()->{ - int current = control.getAmount(fs.item); - String text = Mathf.clamp(current, 0, stack.amount) + "/" + stack.amount; - - reqlabel.setColor(current < stack.amount ? Colors.get("missingitems") : Color.WHITE); - - reqlabel.setText(text); - }); - - requirements.add(reqlabel).left(); - requirements.row(); - } - - desctable.row(); - - Label label = new Label("[health]health: " + recipe.result.health + (recipe.result.description == null ? - "" : ("\n[]" + recipe.result.description))); - label.setWrap(true); - desctable.add(label).width(200).padTop(4).padBottom(2).units(Unit.dp); - - } - - public void updateWeapons(){ - weapontable.clearChildren(); - - ButtonGroup group = new ButtonGroup(); - - weapontable.defaults().size(58, 62); - - for(Weapon weapon : control.getWeapons()){ - ImageButton button = new ImageButton(Draw.region(weapon.name()), "toggle"); - button.getImageCell().size(8*5); - - group.add(button); - - button.clicked(()->{ - if(weapon == player.weapon) return; - player.weapon = weapon; - button.setChecked(true); - }); - - button.setChecked(weapon == player.weapon); - - weapontable.add(button); - - Table tiptable = new Table(); - String description = weapon.description; - - tiptable.background("button"); - tiptable.add("" + weapon.name(), 0.5f).left().padBottom(3f); - - tiptable.row(); - tiptable.row(); - tiptable.add("[GRAY]" + description).left(); - tiptable.pad(14f); - - Tooltip tip = new Tooltip(tiptable); - - tip.setInstant(true); - - button.addListener(tip); - - } - - weapontable.addIButton("icon-menu", 8*4, ()->{ - upgrades.show(); - }); - } - public void showConfig(Tile tile){ configTile = tile; @@ -855,6 +350,14 @@ public class UI extends SceneModule{ keys.show(); } + public void showLevels(){ + levels.show(); + } + + public void showLoadGame(){ + load.show(); + } + public void showMenu(){ menu.show(); } @@ -875,6 +378,14 @@ public class UI extends SceneModule{ if(tooltip != null) tooltip.hide(); } + + public void showAbout(){ + about.show(); + } + + public void showUpgrades(){ + upgrades.show(); + } public void updateItems(){ itemtable.clear(); diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 918ddf426d..4ff780f182 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.ai; import com.badlogic.gdx.ai.pfa.PathFinder; +import com.badlogic.gdx.ai.pfa.PathFinderRequest; import com.badlogic.gdx.ai.pfa.PathSmoother; import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder; import com.badlogic.gdx.math.Vector2; @@ -67,6 +68,12 @@ public class Pathfind{ } } + //TODO + PathFinderRequest request = new PathFinderRequest(); + request.startNode = World.spawnpoints.get(0); + request.endNode = World.core; + passpathfinder.search(request, 1000); + for(int i = 0; i < paths.size; i ++){ SmoothGraphPath path = paths.get(i); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java new file mode 100644 index 0000000000..7cbe121784 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -0,0 +1,237 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Colors; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.utils.Array; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.resource.ItemStack; +import io.anuke.mindustry.resource.Recipe; +import io.anuke.mindustry.resource.Section; +import io.anuke.mindustry.ui.FloatingDialog; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.scene.builders.table; +import io.anuke.ucore.scene.event.Touchable; +import io.anuke.ucore.scene.ui.*; +import io.anuke.ucore.scene.ui.layout.Stack; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.scene.ui.layout.Unit; +import io.anuke.ucore.util.Mathf; + +public class BlocksFragment implements Fragment{ + private Table desctable; + private Array statlist = new Array<>(); + + public void build(){ + new table(){{ + abottom(); + aright(); + + new table("button"){{ + visible(()->player.recipe != null); + desctable = get(); + fillX(); + }}.end().uniformX(); + + row(); + + new table("pane"){{ + + int rows = 4; + int maxcol = 0; + float size = 48; + + Stack stack = new Stack(); + ButtonGroup group = new ButtonGroup<>(); + Array recipes = new Array(); + + for(Section sec : Section.values()){ + recipes.clear(); + Recipe.getBy(sec, recipes); + maxcol = Math.max((int)((float)recipes.size/rows+1), maxcol); + } + + for(Section sec : Section.values()){ + recipes.clear(); + Recipe.getBy(sec, recipes); + + Table table = new Table(); + + ImageButton button = new ImageButton("icon-"+sec.name(), "toggle"); + button.clicked(()->{ + if(!table.isVisible() && player.recipe != null){ + player.recipe = null; + } + }); + button.setName("sectionbutton" + sec.name()); + add(button).growX().height(54).padTop(sec.ordinal() <= 2 ? -10 : -5).units(Unit.dp); + button.getImageCell().size(40).padBottom(4).padTop(2).units(Unit.dp); + group.add(button); + + if(sec.ordinal() % 3 == 2 && sec.ordinal() > 0){ + row(); + } + + table.pad(4); + table.top().left(); + + int i = 0; + + for(Recipe r : recipes){ + TextureRegion region = Draw.hasRegion(r.result.name() + "-icon") ? + Draw.region(r.result.name() + "-icon") : Draw.region(r.result.name()); + ImageButton image = new ImageButton(region, "select"); + + image.clicked(()->{ + if(player.recipe == r){ + player.recipe = null; + }else{ + player.recipe = r; + updateRecipe(); + } + }); + + table.add(image).size(size+8).pad(2).units(Unit.dp); + image.getImageCell().size(size).units(Unit.dp); + + image.update(()->{ + + boolean canPlace = !control.tutorial.active() || control.tutorial.canPlace(); + boolean has = control.hasItems(r.requirements) && canPlace; + //image.setDisabled(!has); + image.setChecked(player.recipe == r); + image.setTouchable(canPlace ? Touchable.enabled : Touchable.disabled); + image.getImage().setColor(has ? Color.WHITE : Color.DARK_GRAY); + }); + + if(i % rows == rows-1) + table.row(); + + i++; + } + + table.setVisible(()-> button.isChecked()); + + stack.add(table); + } + + + row(); + add(stack).colspan(Section.values().length); + get().pad(10f); + + get().padLeft(0f); + get().padRight(0f); + + end(); + }}.right().bottom().uniformX(); + + visible(()->!GameState.is(State.menu)); + + }}.end(); + } + + void updateRecipe(){ + Recipe recipe = player.recipe; + desctable.clear(); + + desctable.defaults().left(); + desctable.left(); + desctable.pad(Unit.dp.inPixels(12)); + + Table header = new Table(); + + desctable.add(header).left(); + + desctable.row(); + + TextureRegion region = Draw.hasRegion(recipe.result.name() + "-icon") ? + Draw.region(recipe.result.name() + "-icon") : Draw.region(recipe.result.name()); + + header.addImage(region).size(8*5).padTop(4).units(Unit.dp); + Label nameLabel = new Label(recipe.result.formalName); + nameLabel.setWrap(true); + header.add(nameLabel).padLeft(4).width(135f).units(Unit.dp); + + //extra info + if(recipe.result.fullDescription != null){ + header.addButton("?", ()->{ + statlist.clear(); + recipe.result.getStats(statlist); + + Label desclabel = new Label(recipe.result.fullDescription); + desclabel.setWrap(true); + + boolean wasPaused = GameState.is(State.paused); + GameState.set(State.paused); + + FloatingDialog d = new FloatingDialog("Block Info"); + Table top = new Table(); + top.left(); + top.add(new Image(Draw.region(recipe.result.name))).size(8*5 * recipe.result.width).units(Unit.dp); + top.add("[orange]"+recipe.result.formalName).padLeft(6f).units(Unit.dp); + d.content().add(top).fill().left(); + d.content().row(); + d.content().add(desclabel).width(600).units(Unit.dp); + d.content().row(); + + if(statlist.size > 0){ + d.content().add("[coral][[extra block info]:").padTop(6).padBottom(5).left(); + d.content().row(); + } + + for(String s : statlist){ + d.content().add(s).left(); + d.content().row(); + } + + d.buttons().addButton("OK", ()->{ + if(!wasPaused) GameState.set(State.playing); + d.hide(); + }).size(110, 50).pad(10f).units(Unit.dp); + + d.show(); + }).expandX().padLeft(4).top().right().size(36f, 40f).units(Unit.dp); + } + + + desctable.add().pad(2).units(Unit.dp); + + Table requirements = new Table(); + + desctable.row(); + + desctable.add(requirements); + desctable.left(); + + for(ItemStack stack : recipe.requirements){ + ItemStack fs = stack; + requirements.addImage(Draw.region("icon-"+stack.item.name())).size(8*3).units(Unit.dp); + Label reqlabel = new Label(""); + + reqlabel.update(()->{ + int current = control.getAmount(fs.item); + String text = Mathf.clamp(current, 0, stack.amount) + "/" + stack.amount; + + reqlabel.setColor(current < stack.amount ? Colors.get("missingitems") : Color.WHITE); + + reqlabel.setText(text); + }); + + requirements.add(reqlabel).left(); + requirements.row(); + } + + desctable.row(); + + Label label = new Label("[health]health: " + recipe.result.health + (recipe.result.description == null ? + "" : ("\n[]" + recipe.result.description))); + label.setWrap(true); + desctable.add(label).width(200).padTop(4).padBottom(2).units(Unit.dp); + + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/Fragment.java b/core/src/io/anuke/mindustry/ui/fragments/Fragment.java new file mode 100644 index 0000000000..ab80d929dc --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/Fragment.java @@ -0,0 +1,5 @@ +package io.anuke.mindustry.ui.fragments; + +public interface Fragment{ + public void build(); +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java new file mode 100644 index 0000000000..4e3184632a --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -0,0 +1,126 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.ucore.core.Core; +import io.anuke.ucore.core.Settings; +import io.anuke.ucore.scene.builders.imagebutton; +import io.anuke.ucore.scene.builders.label; +import io.anuke.ucore.scene.builders.table; +import io.anuke.ucore.scene.ui.Label; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.scene.ui.layout.Unit; + +public class HudFragment implements Fragment{ + private Table itemtable, respawntable; + + public void build(){ + new table(){{ + atop(); + aleft(); + + new table(){{ + left(); + defaults().size(66).units(Unit.dp).left(); + float isize = Unit.dp.inPixels(40); + + new imagebutton("icon-menu", isize, ()->{ + ui.showMenu(); + }); + + new imagebutton("icon-settings", isize, ()->{ + ui.showPrefs(); + }); + + new imagebutton("icon-pause", isize, ()->{ + GameState.set(GameState.is(State.paused) ? State.playing : State.paused); + }){{ + get().update(()->{ + get().getStyle().imageUp = Core.skin.getDrawable(GameState.is(State.paused) ? "icon-play" : "icon-pause"); + }); + }}; + }}.end(); + + row(); + + itemtable = new table("button").end().top().left().fillX().size(-1).get(); + + get().setVisible(()->!GameState.is(State.menu)); + + Label fps = new Label(()->(Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") : "")); + row(); + add(fps).size(-1); + + }}.end(); + + //ui table + new table(){{ + control.tutorial.buildUI(this); + + visible(()->control.tutorial.active()); + }}.end(); + + //paused table + new table(){{ + visible(()->GameState.is(State.paused)); + atop(); + + new table("pane"){{ + new label("[orange]< paused >").scale(Unit.dp.inPixels(0.75f)).pad(6).units(Unit.dp); + }}.end(); + }}.end(); + + //wave table... + new table(){{ + atop(); + aright(); + + new table("button"){{ + + new label(()->"[orange]Wave " + control.getWave()).scale(fontscale*2f).left(); + + row(); + + new label(()-> control.getEnemiesRemaining() > 0 ? + control.getEnemiesRemaining() + " Enemies remaining" : + control.tutorial.active() ? "waiting..." : "New wave in " + (int) (control.getWaveCountdown() / 60f)) + .minWidth(150); + + get().pad(Unit.dp.inPixels(12)); + }}; + + visible(()->!GameState.is(State.menu)); + }}.end(); + + //settings icon + new table(){{ + atop().aright(); + new imagebutton("icon-info", Unit.dp.inPixels(30f), ()->{ + ui.showAbout(); + }).get().pad(14); + }}.end().visible(()->GameState.is(State.menu)); + + //respawn background table + new table("white"){{ + respawntable = get(); + respawntable.setColor(Color.CLEAR); + + }}.end(); + + //respawn table + new table(){{ + new table("pane"){{ + + new label(()->"[orange]Respawning in " + (int)(control.getRespawnTime()/60)).scale(0.75f).pad(10); + + visible(()->control.getRespawnTime() > 0 && !GameState.is(State.menu)); + + }}.end(); + }}.end(); + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java new file mode 100644 index 0000000000..9f95337639 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -0,0 +1,67 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import com.badlogic.gdx.Gdx; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.ui.MenuButton; +import io.anuke.mindustry.world.Map; +import io.anuke.ucore.scene.builders.imagebutton; +import io.anuke.ucore.scene.builders.table; +import io.anuke.ucore.scene.ui.layout.Unit; + +public class MenuFragment implements Fragment{ + + public void build(){ + if(!android){ + //menu table + new table(){{ + + new table(){{ + float scale = 4f; + defaults().size(100*scale, 21*scale).pad(-10f).units(Unit.dp); + + add(new MenuButton("text-play", ()-> ui.showLevels())); + row(); + + add(new MenuButton("text-tutorial", ()-> control.playMap(Map.tutorial))); + row(); + + if(!gwt){ + add(new MenuButton("text-load", ()-> ui.showLoadGame())); + row(); + } + + add(new MenuButton("text-settings", ()-> ui.showPrefs())); + row(); + + if(!gwt){ + add(new MenuButton("text-exit", ()-> Gdx.app.exit())); + } + get().pad(Unit.dp.inPixels(16)); + }}; + + visible(()->GameState.is(State.menu)); + }}.end(); + }else{ + new table(){{ + defaults().size(120f).pad(5).units(Unit.dp); + float isize = Unit.dp.inPixels(14f*4); + + new imagebutton("icon-play-2", isize, () -> ui.showLevels()).text("Play").padTop(4f); + + new imagebutton("icon-tutorial", isize, ()->{ + control.playMap(Map.tutorial); + }).text("Tutorial").padTop(4f); + + new imagebutton("icon-load", isize, () -> ui.showLoadGame()).text("Load").padTop(4f); + + new imagebutton("icon-tools", isize, () -> ui.showPrefs()).text("Settings").padTop(4f); + + visible(()->GameState.is(State.menu)); + }}.end(); + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java new file mode 100644 index 0000000000..a2834b5af0 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -0,0 +1,68 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import com.badlogic.gdx.utils.Align; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.input.AndroidInput; +import io.anuke.mindustry.input.PlaceMode; +import io.anuke.ucore.scene.builders.imagebutton; +import io.anuke.ucore.scene.builders.label; +import io.anuke.ucore.scene.builders.table; +import io.anuke.ucore.scene.ui.ButtonGroup; +import io.anuke.ucore.scene.ui.ImageButton; +import io.anuke.ucore.scene.ui.layout.Unit; + +public class PlacementFragment implements Fragment{ + + public void build(){ + if(android){ + //placement table + new table(){{ + visible(()->player.recipe != null && !GameState.is(State.menu)); + abottom(); + aleft(); + + + new table("pane"){{ + new label(()->"Placement Mode: [orange]" + AndroidInput.mode.name()).pad(4).units(Unit.dp); + row(); + + aleft(); + + new table(){{ + aleft(); + ButtonGroup group = new ButtonGroup<>(); + + defaults().size(58, 62).pad(6).units(Unit.dp); + + for(PlaceMode mode : PlaceMode.values()){ + new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{ + AndroidInput.mode = mode; + }){{ + group.add(get()); + }}; + } + + new imagebutton("icon-cancel", Unit.dp.inPixels(14*3), ()->{ + player.recipe = null; + }).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch); + + new imagebutton("icon-rotate-arrow", Unit.dp.inPixels(14*3), ()->{ + player.rotation ++; + player.rotation %= 4; + }).update(i->{ + i.getImage().setOrigin(Align.center); + i.getImage().setRotation(player.rotation*90); + }).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch + && player.recipe.result.rotate); + + }}.left().end(); + }}.end(); + }}.end(); + + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/ProfilerFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ProfilerFragment.java new file mode 100644 index 0000000000..f8c11fa164 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/ProfilerFragment.java @@ -0,0 +1,48 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.debug; + +import io.anuke.mindustry.Profiler; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.function.StringSupplier; +import io.anuke.ucore.scene.builders.label; +import io.anuke.ucore.scene.builders.table; + +public class ProfilerFragment implements Fragment{ + + public void build(){ + if(debug){ + new table(){{ + abottom(); + aleft(); + new label((StringSupplier)()->"[purple]entities: " + Entities.amount()).left(); + row(); + new label("[red]DEBUG MODE").scale(0.5f).left(); + }}.end(); + + new table(){{ + atop(); + new table("button"){{ + defaults().left().growX(); + atop(); + aleft(); + new label((StringSupplier)()->"[red]total: " + + String.format("%.1f", (float)Profiler.total/Profiler.total*100f)+ "% - " + Profiler.total).left(); + row(); + new label((StringSupplier)()->"[yellow]draw: " + + String.format("%.1f", (float)Profiler.draw/Profiler.total*100f)+ "% - " + Profiler.draw).left(); + row(); + new label((StringSupplier)()->"[green]blockDraw: " + + String.format("%.1f", (float)Profiler.blockDraw/Profiler.total*100f)+ "% - " + Profiler.blockDraw).left(); + row(); + new label((StringSupplier)()->"[blue]entityDraw: " + + String.format("%.1f", (float)Profiler.entityDraw/Profiler.total*100f)+ "% - " + Profiler.entityDraw).left(); + row(); + new label((StringSupplier)()->"[purple]entityUpdate: " + + String.format("%.1f", (float)Profiler.entityUpdate/Profiler.total*100f)+ "% - " + Profiler.entityUpdate).left(); + row(); + }}.width(400f).end(); + }}.end(); + } + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java new file mode 100644 index 0000000000..7a572ae4e8 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java @@ -0,0 +1,45 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.Align; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.input.AndroidInput; +import io.anuke.mindustry.input.PlaceMode; +import io.anuke.ucore.core.Core; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.scene.ui.layout.Unit; + +public class ToolFragment implements Fragment{ + private Table tools; + + public void build(){ + tools = new Table(); + tools.addIButton("icon-cancel", Unit.dp.inPixels(42), ()->{ + player.recipe = null; + }); + + tools.addIButton("icon-rotate", Unit.dp.inPixels(42), ()->{ + player.rotation ++; + player.rotation %= 4; + }); + + tools.addIButton("icon-check", Unit.dp.inPixels(42), ()->{ + AndroidInput.place(); + }); + + Core.scene.add(tools); + + tools.setVisible(()-> + !GameState.is(State.menu) && android && player.recipe != null && control.hasItems(player.recipe.requirements) && + AndroidInput.mode == PlaceMode.cursor + ); + + tools.update(()->{ + tools.setPosition(AndroidInput.mousex, Gdx.graphics.getHeight()-AndroidInput.mousey-15*Core.cameraScale, Align.top); + }); + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java b/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java new file mode 100644 index 0000000000..635f3f5503 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/fragments/WeaponFragment.java @@ -0,0 +1,74 @@ +package io.anuke.mindustry.ui.fragments; + +import static io.anuke.mindustry.Vars.*; + +import io.anuke.mindustry.GameState; +import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.resource.Weapon; +import io.anuke.ucore.core.Core; +import io.anuke.ucore.core.Draw; +import io.anuke.ucore.scene.ui.ButtonGroup; +import io.anuke.ucore.scene.ui.ImageButton; +import io.anuke.ucore.scene.ui.Tooltip; +import io.anuke.ucore.scene.ui.layout.Table; + +public class WeaponFragment implements Fragment{ + Table weapontable; + + public void build(){ + weapontable = Core.scene.table(); + weapontable.bottom().left(); + weapontable.setVisible(()->!GameState.is(State.menu)); + + if(android){ + weapontable.remove(); + } + } + + public void updateWeapons(){ + weapontable.clearChildren(); + + ButtonGroup group = new ButtonGroup(); + + weapontable.defaults().size(58, 62); + + for(Weapon weapon : control.getWeapons()){ + ImageButton button = new ImageButton(Draw.region(weapon.name()), "toggle"); + button.getImageCell().size(8*5); + + group.add(button); + + button.clicked(()->{ + if(weapon == player.weapon) return; + player.weapon = weapon; + button.setChecked(true); + }); + + button.setChecked(weapon == player.weapon); + + weapontable.add(button); + + Table tiptable = new Table(); + String description = weapon.description; + + tiptable.background("button"); + tiptable.add("" + weapon.name(), 0.5f).left().padBottom(3f); + + tiptable.row(); + tiptable.row(); + tiptable.add("[GRAY]" + description).left(); + tiptable.pad(14f); + + Tooltip tip = new Tooltip(tiptable); + + tip.setInstant(true); + + button.addListener(tip); + + } + + weapontable.addIButton("icon-menu", 8*4, ()->{ + ui.showUpgrades(); + }); + } +} diff --git a/desktop/mindustry-saves/0.mins b/desktop/mindustry-saves/0.mins index e7e476f70c..487788e77d 100644 Binary files a/desktop/mindustry-saves/0.mins and b/desktop/mindustry-saves/0.mins differ diff --git a/desktop/mindustry-saves/3.mins b/desktop/mindustry-saves/3.mins index 3fe1e6e8ec..2b036dbabe 100644 Binary files a/desktop/mindustry-saves/3.mins and b/desktop/mindustry-saves/3.mins differ