Merge branch 'master' into schematic
This commit is contained in:
@@ -63,7 +63,7 @@ public class Bar extends Element{
|
||||
if(fraction == null) return;
|
||||
|
||||
float computed = Mathf.clamp(fraction.get());
|
||||
if(!Mathf.equal(lastValue, computed)){
|
||||
if(lastValue > computed){
|
||||
blink = 1f;
|
||||
lastValue = computed;
|
||||
}
|
||||
@@ -80,11 +80,11 @@ public class Bar extends Element{
|
||||
Drawable top = Tex.barTop;
|
||||
float topWidth = width * value;
|
||||
|
||||
if(topWidth > Core.atlas.find("bar-top").getWidth()){
|
||||
if(topWidth > Core.atlas.find("bar-top").width){
|
||||
top.draw(x, y, topWidth, height);
|
||||
}else{
|
||||
if(ScissorStack.push(scissor.set(x, y, topWidth, height))){
|
||||
top.draw(x, y, Core.atlas.find("bar-top").getWidth(), height);
|
||||
top.draw(x, y, Core.atlas.find("bar-top").width, height);
|
||||
ScissorStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import arc.struct.*;
|
||||
import arc.graphics.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
@@ -129,7 +130,7 @@ public class ContentDisplay{
|
||||
|
||||
public static void displayUnit(Table table, UnitType unit){
|
||||
table.table(title -> {
|
||||
title.image(unit.icon(Cicon.xlarge)).size(8 * 6);
|
||||
title.image(unit.icon(Cicon.xlarge));
|
||||
title.add("[accent]" + unit.localizedName).padLeft(5);
|
||||
});
|
||||
|
||||
@@ -149,10 +150,16 @@ public class ContentDisplay{
|
||||
|
||||
table.left().defaults().fillX();
|
||||
|
||||
table.add(Core.bundle.format("unit.health", unit.health));
|
||||
table.row();
|
||||
table.add(Core.bundle.format("unit.speed", Strings.fixed(unit.speed, 1)));
|
||||
table.row();
|
||||
Unit inst = unit.constructor.get();
|
||||
|
||||
//TODO more stats
|
||||
table.add(Core.bundle.format("unit.health", unit.health)).row();
|
||||
table.add(Core.bundle.format("unit.speed", Strings.fixed(unit.speed, 1))).row();
|
||||
table.add(Core.bundle.format("unit.itemcapacity", unit.itemCapacity)).row();
|
||||
|
||||
if(inst instanceof Minerc) table.add(Core.bundle.format("unit.minespeed", (int)(unit.mineSpeed * 100f))).row();
|
||||
if(inst instanceof Builderc) table.add(Core.bundle.format("unit.buildspeed", (int)(unit.buildSpeed * 100f))).row();
|
||||
|
||||
table.row();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import static mindustry.Vars.*;
|
||||
|
||||
public class CoreItemsDisplay extends Table{
|
||||
private final ObjectSet<Item> usedItems = new ObjectSet<>();
|
||||
private CoreBuild core;
|
||||
|
||||
public CoreItemsDisplay(){
|
||||
rebuild();
|
||||
@@ -26,7 +27,7 @@ public class CoreItemsDisplay extends Table{
|
||||
margin(4);
|
||||
|
||||
update(() -> {
|
||||
CoreBuild core = Vars.player.team().core();
|
||||
core = Vars.player.team().core();
|
||||
|
||||
if(content.items().contains(item -> core != null && core.items.get(item) > 0 && usedItems.add(item))){
|
||||
rebuild();
|
||||
@@ -35,11 +36,11 @@ public class CoreItemsDisplay extends Table{
|
||||
|
||||
int i = 0;
|
||||
|
||||
CoreBuild core = Vars.player.team().core();
|
||||
for(Item item : content.items()){
|
||||
if(usedItems.contains(item)){
|
||||
image(item.icon(Cicon.small)).padRight(3);
|
||||
label(() -> core == null ? "0" : UI.formatAmount(core.items.get(item))).padRight(3);
|
||||
//TODO leaks garbage
|
||||
label(() -> core == null ? "0" : UI.formatAmount(core.items.get(item))).padRight(3).left();
|
||||
|
||||
if(++i % 4 == 0){
|
||||
row();
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Fonts{
|
||||
|
||||
public static void loadContentIcons(){
|
||||
Seq<Font> fonts = Seq.with(Fonts.chat, Fonts.def, Fonts.outline);
|
||||
Texture uitex = Core.atlas.find("logo").getTexture();
|
||||
Texture uitex = Core.atlas.find("logo").texture;
|
||||
int size = (int)(Fonts.def.getData().lineHeight/Fonts.def.getData().scaleY);
|
||||
|
||||
try(Scanner scan = new Scanner(Core.files.internal("icons/icons.properties").read(512))){
|
||||
@@ -84,7 +84,7 @@ public class Fonts{
|
||||
int ch = Integer.parseInt(character);
|
||||
TextureRegion region = Core.atlas.find(texture);
|
||||
|
||||
if(region.getTexture() != uitex){
|
||||
if(region.texture != uitex){
|
||||
continue;
|
||||
//throw new IllegalArgumentException("Font icon '" + texture + "' is not in the UI texture.");
|
||||
}
|
||||
@@ -98,10 +98,10 @@ public class Fonts{
|
||||
glyph.srcY = 0;
|
||||
glyph.width = size;
|
||||
glyph.height = size;
|
||||
glyph.u = region.getU();
|
||||
glyph.v = region.getV2();
|
||||
glyph.u2 = region.getU2();
|
||||
glyph.v2 = region.getV();
|
||||
glyph.u = region.u;
|
||||
glyph.v = region.v2;
|
||||
glyph.u2 = region.u2;
|
||||
glyph.v2 = region.v;
|
||||
glyph.xoffset = 0;
|
||||
glyph.yoffset = -size;
|
||||
glyph.xadvance = size;
|
||||
@@ -115,7 +115,9 @@ public class Fonts{
|
||||
|
||||
/** Called from a static context for use in the loading screen.*/
|
||||
public static void loadDefaultFont(){
|
||||
UI.packer = new PixmapPacker(2048, 2048, Format.rgba8888, 2, true);
|
||||
int max = Gl.getInt(Gl.maxTextureSize);
|
||||
|
||||
UI.packer = new PixmapPacker(max >= 4096 ? 4096 : 2048, 2048, Format.rgba8888, 2, true);
|
||||
FileHandleResolver resolver = new InternalFileHandleResolver();
|
||||
Core.assets.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
|
||||
Core.assets.setLoader(Font.class, null, new FreetypeFontLoader(resolver){
|
||||
@@ -160,21 +162,21 @@ public class Fonts{
|
||||
//grab all textures from the ui page, remove all the regions assigned to it, then copy them over to Fonts.packer and replace the texture in this atlas.
|
||||
|
||||
//grab old UI texture and regions...
|
||||
Texture texture = atlas.find("logo").getTexture();
|
||||
Texture texture = atlas.find("logo").texture;
|
||||
|
||||
Page page = UI.packer.getPages().first();
|
||||
|
||||
Seq<AtlasRegion> regions = atlas.getRegions().select(t -> t.getTexture() == texture);
|
||||
Seq<AtlasRegion> regions = atlas.getRegions().select(t -> t.texture == texture);
|
||||
for(AtlasRegion region : regions){
|
||||
//get new pack rect
|
||||
page.setDirty(false);
|
||||
Rect rect = UI.packer.pack(region.name + (region.splits != null ? ".9" : ""), atlas.getPixmap(region));
|
||||
//set new texture
|
||||
region.setTexture(UI.packer.getPages().first().getTexture());
|
||||
region.texture = UI.packer.getPages().first().getTexture();
|
||||
//set its new position
|
||||
region.set((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
|
||||
//add old texture
|
||||
atlas.getTextures().add(region.getTexture());
|
||||
atlas.getTextures().add(region.texture);
|
||||
}
|
||||
|
||||
//remove old texture, it will no longer be used
|
||||
@@ -191,7 +193,7 @@ public class Fonts{
|
||||
if(g == null) throw new IllegalArgumentException("No glyph: " + glyph + " (" + (int)glyph + ")");
|
||||
|
||||
float size = Math.max(g.width, g.height);
|
||||
TextureRegionDrawable draw = new TextureRegionDrawable(new TextureRegion(font.getRegion().getTexture(), g.u, g.v2, g.u2, g.v)){
|
||||
TextureRegionDrawable draw = new TextureRegionDrawable(new TextureRegion(font.getRegion().texture, g.u, g.v2, g.u2, g.v)){
|
||||
@Override
|
||||
public void draw(float x, float y, float width, float height){
|
||||
Draw.color(Tmp.c1.set(tint).mul(Draw.getColor()).toFloatBits());
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ItemDisplay extends Table{
|
||||
}
|
||||
|
||||
public ItemDisplay(Item item, int amount, boolean showName){
|
||||
add(new ItemImage(new ItemStack(item, amount))).size(8 * 4).padRight(amount > 99 ? 12 : 0);
|
||||
add(new ItemImage(new ItemStack(item, amount)));
|
||||
if(showName) add(item.localizedName).padLeft(4 + amount > 99 ? 4 : 0);
|
||||
|
||||
this.item = item;
|
||||
|
||||
@@ -8,11 +8,17 @@ import mindustry.type.*;
|
||||
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);
|
||||
add(new Table(o -> {
|
||||
o.left();
|
||||
o.add(new Image(region)).size(32f);
|
||||
}));
|
||||
|
||||
add(new Table(t -> {
|
||||
t.left().bottom();
|
||||
t.add(amount + "");
|
||||
t.pack();
|
||||
}));
|
||||
}
|
||||
|
||||
public ItemImage(TextureRegion region){
|
||||
@@ -23,12 +29,18 @@ public class ItemImage extends Stack{
|
||||
}
|
||||
|
||||
public ItemImage(ItemStack stack){
|
||||
add(new Image(stack.item.icon(Cicon.medium)));
|
||||
|
||||
add(new Table(o -> {
|
||||
o.left();
|
||||
o.add(new Image(stack.item.icon(Cicon.medium))).size(32f);
|
||||
}));
|
||||
|
||||
if(stack.amount != 0){
|
||||
Table t = new Table().left().bottom();
|
||||
t.add(stack.amount + "").name("item-label").style(Styles.outlineLabel);
|
||||
add(t);
|
||||
add(new Table(t -> {
|
||||
t.left().bottom();
|
||||
t.add(stack.amount + "").style(Styles.outlineLabel);
|
||||
t.pack();
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ public class Styles{
|
||||
}};
|
||||
|
||||
waveb = new ButtonStyle(){{
|
||||
up = buttonEdge4;
|
||||
over = buttonEdgeOver4;
|
||||
disabled = buttonEdge4;
|
||||
up = wavepane;
|
||||
over = wavepane; //TODO wrong
|
||||
disabled = wavepane;
|
||||
}};
|
||||
|
||||
defaultt = new TextButtonStyle(){{
|
||||
@@ -183,6 +183,9 @@ public class Styles{
|
||||
over = buttonRightOver;
|
||||
down = buttonRightDown;
|
||||
up = buttonRight;
|
||||
disabled = buttonRightDisabled;
|
||||
imageDisabledColor = Color.clear;
|
||||
imageUpColor = Color.white;
|
||||
}};
|
||||
emptyi = new ImageButtonStyle(){{
|
||||
imageDownColor = Pal.accent;
|
||||
|
||||
@@ -3,19 +3,24 @@ package mindustry.ui.dialogs;
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.style.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.ImageButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.type.Weather.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import static arc.util.Time.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class CustomRulesDialog extends BaseDialog{
|
||||
@@ -144,6 +149,7 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
|
||||
main.button("@configure",
|
||||
() -> loadoutDialog.show(Blocks.coreShard.itemCapacity, rules.loadout,
|
||||
i -> true,
|
||||
() -> rules.loadout.clear().add(new ItemStack(Items.copper, 100)),
|
||||
() -> {}, () -> {}
|
||||
)).left().width(300f);
|
||||
@@ -160,10 +166,12 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
|
||||
title("@rules.title.enemy");
|
||||
check("@rules.attack", b -> rules.attackMode = b, () -> rules.attackMode);
|
||||
check("@rules.buildai", b -> rules.waveTeam.rules().ai = b, () -> rules.waveTeam.rules().ai);
|
||||
number("@rules.enemycorebuildradius", f -> rules.enemyCoreBuildRadius = f * tilesize, () -> Math.min(rules.enemyCoreBuildRadius / tilesize, 200));
|
||||
|
||||
title("@rules.title.environment");
|
||||
number("@rules.solarpowermultiplier", f -> rules.solarPowerMultiplier = f, () -> rules.solarPowerMultiplier);
|
||||
check("@rules.explosions", b -> rules.damageExplosions = b, () -> rules.damageExplosions);
|
||||
check("@rules.fire", b -> rules.fire = b, () -> rules.fire);
|
||||
check("@rules.lighting", b -> rules.lighting = b, () -> rules.lighting);
|
||||
|
||||
main.button(b -> {
|
||||
@@ -174,8 +182,9 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
}}).grow();
|
||||
}).margin(4).size(50f).padRight(10);
|
||||
b.add("@rules.ambientlight");
|
||||
}, () -> ui.picker.show(rules.ambientLight, rules.ambientLight::set)).left().width(250f);
|
||||
main.row();
|
||||
}, () -> ui.picker.show(rules.ambientLight, rules.ambientLight::set)).left().width(250f).row();
|
||||
|
||||
main.button("@rules.weather", this::weatherDialog).width(250f).left().row();
|
||||
|
||||
//TODO add weather patterns
|
||||
}
|
||||
@@ -212,4 +221,120 @@ public class CustomRulesDialog extends BaseDialog{
|
||||
main.image().color(Pal.accent).height(3f).padRight(100f).padBottom(20);
|
||||
main.row();
|
||||
}
|
||||
|
||||
Cell<TextField> field(Table table, float value, Floatc setter){
|
||||
return table.field(Strings.autoFixed(value, 2), v -> setter.get(Strings.parseFloat(v)))
|
||||
.valid(Strings::canParsePositiveFloat)
|
||||
.size(90f, 40f).pad(2f).addInputDialog();
|
||||
}
|
||||
|
||||
void weatherDialog(){
|
||||
BaseDialog dialog = new BaseDialog("@rules.weather");
|
||||
Runnable[] rebuild = {null};
|
||||
|
||||
dialog.cont.pane(base -> {
|
||||
|
||||
rebuild[0] = () -> {
|
||||
base.clearChildren();
|
||||
int cols = Math.max(1, Core.graphics.getWidth() / 460);
|
||||
int idx = 0;
|
||||
|
||||
for(WeatherEntry entry : rules.weather){
|
||||
base.top();
|
||||
//main container
|
||||
base.table(Tex.pane, c -> {
|
||||
c.margin(0);
|
||||
|
||||
//icons to perform actions
|
||||
c.table(Tex.whiteui, t -> {
|
||||
t.setColor(Pal.gray);
|
||||
|
||||
t.top().left();
|
||||
t.add(entry.weather.localizedName).left().padLeft(6);
|
||||
|
||||
t.add().growX();
|
||||
|
||||
ImageButtonStyle style = Styles.geni;
|
||||
t.defaults().size(42f);
|
||||
|
||||
t.button(Icon.cancel, style, () -> {
|
||||
rules.weather.remove(entry);
|
||||
rebuild[0].run();
|
||||
});
|
||||
}).growX();
|
||||
|
||||
c.row();
|
||||
|
||||
//all the options
|
||||
c.table(f -> {
|
||||
f.marginLeft(4);
|
||||
f.left().top();
|
||||
|
||||
f.defaults().padRight(4).left();
|
||||
|
||||
f.add("@rules.weather.duration");
|
||||
field(f, entry.minDuration / toMinutes, v -> entry.minDuration = v * toMinutes);
|
||||
f.add("@waves.to");
|
||||
field(f, entry.maxDuration / toMinutes, v -> entry.maxDuration = v * toMinutes);
|
||||
f.add("@unit.minutes");
|
||||
|
||||
f.row();
|
||||
|
||||
f.add("@rules.weather.frequency");
|
||||
field(f, entry.minFrequency / toMinutes, v -> entry.minFrequency = v * toMinutes);
|
||||
f.add("@waves.to");
|
||||
field(f, entry.maxFrequency / toMinutes, v -> entry.maxFrequency = v * toMinutes);
|
||||
f.add("@unit.minutes");
|
||||
|
||||
//intensity can't currently be customized
|
||||
|
||||
}).grow().left().pad(6).top();
|
||||
}).width(410f).pad(3).top().left().fillY();
|
||||
|
||||
if(++idx % cols == 0){
|
||||
base.row();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rebuild[0].run();
|
||||
}).grow();
|
||||
|
||||
dialog.addCloseButton();
|
||||
|
||||
dialog.buttons.button("@add", Icon.add, () -> {
|
||||
BaseDialog addd = new BaseDialog("@add");
|
||||
addd.cont.pane(t -> {
|
||||
t.background(Tex.button);
|
||||
int i = 0;
|
||||
for(Weather weather : content.<Weather>getBy(ContentType.weather)){
|
||||
|
||||
t.button(weather.localizedName, Styles.cleart, () -> {
|
||||
rules.weather.add(new WeatherEntry(weather));
|
||||
rebuild[0].run();
|
||||
|
||||
addd.hide();
|
||||
}).size(140f, 50f);
|
||||
if(++i % 2 == 0) t.row();
|
||||
}
|
||||
});
|
||||
addd.addCloseButton();
|
||||
addd.show();
|
||||
}).width(170f);
|
||||
|
||||
//reset cooldown to random number
|
||||
dialog.hidden(() -> {
|
||||
float sum = 0;
|
||||
Seq<WeatherEntry> sh = rules.weather.copy();
|
||||
sh.shuffle();
|
||||
|
||||
for(WeatherEntry w : sh){
|
||||
//add the previous cooldowns to the sum so weather events are staggered and don't happen all at once.
|
||||
w.cooldown = sum + Mathf.random(w.minFrequency, w.maxFrequency);
|
||||
sum += w.cooldown;
|
||||
}
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package mindustry.ui.dialogs;
|
||||
|
||||
import arc.*;
|
||||
import arc.input.*;
|
||||
import arc.struct.*;
|
||||
import arc.graphics.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ctype.*;
|
||||
@@ -14,7 +15,7 @@ import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
import static mindustry.Vars.ui;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class DatabaseDialog extends BaseDialog{
|
||||
|
||||
@@ -49,14 +50,13 @@ public class DatabaseDialog extends BaseDialog{
|
||||
table.table(list -> {
|
||||
list.left();
|
||||
|
||||
int maxWidth = Core.graphics.isPortrait() ? 7 : 13;
|
||||
|
||||
int cols = Mathf.clamp((Core.graphics.getWidth() - 30) / (32 + 10), 1, 18);
|
||||
int count = 0;
|
||||
|
||||
for(int i = 0; i < array.size; i++){
|
||||
UnlockableContent unlock = (UnlockableContent)array.get(i);
|
||||
|
||||
Image image = unlocked(unlock) ? new Image(unlock.icon(Cicon.medium)) : new Image(Icon.lock, Pal.gray);
|
||||
Image image = unlocked(unlock) ? new Image(unlock.icon(Cicon.medium)).setScaling(Scaling.fit) : new Image(Icon.lock, Pal.gray);
|
||||
list.add(image).size(8*4).pad(3);
|
||||
ClickListener listener = new ClickListener();
|
||||
image.addListener(listener);
|
||||
@@ -77,7 +77,7 @@ public class DatabaseDialog extends BaseDialog{
|
||||
image.addListener(new Tooltip(t -> t.background(Tex.button).add(unlock.localizedName)));
|
||||
}
|
||||
|
||||
if((++count) % maxWidth == 0){
|
||||
if((++count) % cols == 0){
|
||||
list.row();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,14 +262,10 @@ public class JoinDialog extends BaseDialog{
|
||||
cont.clear();
|
||||
cont.table(t -> {
|
||||
t.add("@name").padRight(10);
|
||||
if(!steam){
|
||||
t.field(Core.settings.getString("name"), text -> {
|
||||
player.name(text);
|
||||
Core.settings.put("name", text);
|
||||
}).grow().pad(8).addInputDialog(maxNameLength);
|
||||
}else{
|
||||
t.add(player.name).update(l -> l.setColor(player.color())).grow().pad(8);
|
||||
}
|
||||
t.field(Core.settings.getString("name"), text -> {
|
||||
player.name(text);
|
||||
Core.settings.put("name", text);
|
||||
}).grow().pad(8).addInputDialog(maxNameLength);
|
||||
|
||||
ImageButton button = t.button(Tex.whiteui, Styles.clearFulli, 40, () -> {
|
||||
new PaletteDialog().show(color -> {
|
||||
@@ -410,7 +406,7 @@ public class JoinDialog extends BaseDialog{
|
||||
void safeConnect(String ip, int port, int version){
|
||||
if(version != Version.build && Version.build != -1 && version != -1){
|
||||
ui.showInfo("[scarlet]" + (version > Version.build ? KickReason.clientOutdated : KickReason.serverOutdated).toString() + "\n[]" +
|
||||
Core.bundle.format("server.versions", Version.build, version));
|
||||
Core.bundle.format("server.versions", Version.build, version));
|
||||
}else{
|
||||
connect(ip, port);
|
||||
}
|
||||
@@ -431,7 +427,7 @@ public class JoinDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
//get servers
|
||||
Core.net.httpGet(becontrol.active() ? serverJsonBeURL : serverJsonURL, result -> {
|
||||
Core.net.httpGet(becontrol.active() ? serverJsonBeURL : serverJsonV6URL, result -> {
|
||||
try{
|
||||
Jval val = Jval.read(result.getResultAsString());
|
||||
Core.app.post(() -> {
|
||||
|
||||
@@ -5,6 +5,7 @@ import arc.func.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
@@ -17,10 +18,8 @@ import static mindustry.Vars.*;
|
||||
/** Dialog for selecting loadout at sector launch. */
|
||||
public class LaunchLoadoutDialog extends BaseDialog{
|
||||
LoadoutDialog loadout = new LoadoutDialog();
|
||||
//total as a map
|
||||
ObjectIntMap<Item> totalMap = new ObjectIntMap<>();
|
||||
//total required items
|
||||
Seq<ItemStack> total = new Seq<>();
|
||||
ItemSeq total = new ItemSeq();
|
||||
//currently selected schematic
|
||||
Schematic selected;
|
||||
//validity of loadout items
|
||||
@@ -33,21 +32,14 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
public void show(CoreBlock core, Building build, Runnable confirm){
|
||||
cont.clear();
|
||||
buttons.clear();
|
||||
totalMap.clear();
|
||||
|
||||
Seq<ItemStack> stacks = universe.getLaunchResources();
|
||||
|
||||
addCloseButton();
|
||||
|
||||
//updates sum requirements
|
||||
Runnable update = () -> {
|
||||
totalMap.clear();
|
||||
total.clear();
|
||||
selected.requirements().each(i -> totalMap.increment(i.item, i.amount));
|
||||
universe.getLaunchResources().each(i -> totalMap.increment(i.item, i.amount));
|
||||
for(Item item : content.items()){
|
||||
if(totalMap.containsKey(item)) total.add(new ItemStack(item, totalMap.get(item)));
|
||||
}
|
||||
selected.requirements().each(total::add);
|
||||
universe.getLaunchResources().each(total::add);
|
||||
valid = build.items.has(total);
|
||||
};
|
||||
|
||||
@@ -55,10 +47,18 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
table.clearChildren();
|
||||
int i = 0;
|
||||
|
||||
ItemSeq schems = selected.requirements();
|
||||
ItemSeq launches = universe.getLaunchResources();
|
||||
|
||||
for(ItemStack s : total){
|
||||
table.image(s.item.icon(Cicon.small)).left();
|
||||
table.add((build.items.has(s.item, s.amount)) ? "[lightgray]" + s.amount + "" :
|
||||
"[scarlet]" + (Math.min(build.items.get(s.item), s.amount) + "[lightgray]/" + s.amount)).padLeft(2).left().padRight(4);
|
||||
int as = schems.get(s.item), al = launches.get(s.item);
|
||||
|
||||
String amountStr = "[lightgray]" + (al + " + [accent]" + as + "[lightgray]");
|
||||
|
||||
table.add(
|
||||
build.items.has(s.item, s.amount) ? amountStr :
|
||||
"[scarlet]" + (Math.min(build.items.get(s.item), s.amount) + "[lightgray]/" + amountStr)).padLeft(2).left().padRight(4);
|
||||
|
||||
if(++i % 4 == 0){
|
||||
table.row();
|
||||
@@ -71,8 +71,11 @@ public class LaunchLoadoutDialog extends BaseDialog{
|
||||
Runnable rebuildItems = () -> rebuild.get(items);
|
||||
|
||||
buttons.button("@resources", Icon.terrain, () -> {
|
||||
loadout.show(core.itemCapacity, stacks, stacks::clear, () -> {}, () -> {
|
||||
universe.updateLaunchResources(stacks);
|
||||
ItemSeq stacks = universe.getLaunchResources();
|
||||
Seq<ItemStack> out = stacks.toSeq();
|
||||
|
||||
loadout.show(core.itemCapacity, out, UnlockableContent::unlocked, out::clear, () -> {}, () -> {
|
||||
universe.updateLaunchResources(new ItemSeq(out));
|
||||
update.run();
|
||||
rebuildItems.run();
|
||||
});
|
||||
|
||||
@@ -104,7 +104,7 @@ public class LoadDialog extends BaseDialog{
|
||||
|
||||
button.left().add(new BorderImage(def, 4f)).update(im -> {
|
||||
TextureRegionDrawable draw = (TextureRegionDrawable)im.getDrawable();
|
||||
if(draw.getRegion().getTexture().isDisposed()){
|
||||
if(draw.getRegion().texture.isDisposed()){
|
||||
draw.setRegion(def);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package mindustry.ui.dialogs;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.func.*;
|
||||
import arc.input.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
@@ -15,8 +16,10 @@ public class LoadoutDialog extends BaseDialog{
|
||||
private Runnable hider;
|
||||
private Runnable resetter;
|
||||
private Runnable updater;
|
||||
//TODO use itemseqs
|
||||
private Seq<ItemStack> stacks = new Seq<>();
|
||||
private Seq<ItemStack> originalStacks = new Seq<>();
|
||||
private Boolf<Item> validator = i -> true;
|
||||
private Table items;
|
||||
private int capacity;
|
||||
|
||||
@@ -51,13 +54,14 @@ public class LoadoutDialog extends BaseDialog{
|
||||
}).size(210f, 64f);
|
||||
}
|
||||
|
||||
public void show(int capacity, Seq<ItemStack> stacks, Runnable reseter, Runnable updater, Runnable hider){
|
||||
public void show(int capacity, Seq<ItemStack> stacks, Boolf<Item> validator, Runnable reseter, Runnable updater, Runnable hider){
|
||||
this.originalStacks = stacks;
|
||||
reseed();
|
||||
this.validator = validator;
|
||||
this.resetter = reseter;
|
||||
this.updater = updater;
|
||||
this.capacity = capacity;
|
||||
this.hider = hider;
|
||||
reseed();
|
||||
show();
|
||||
}
|
||||
|
||||
@@ -106,7 +110,7 @@ public class LoadoutDialog extends BaseDialog{
|
||||
|
||||
private void reseed(){
|
||||
this.stacks = originalStacks.map(ItemStack::copy);
|
||||
this.stacks.addAll(content.items().select(i -> !stacks.contains(stack -> stack.item == i)).map(i -> new ItemStack(i, 0)));
|
||||
this.stacks.addAll(content.items().select(i -> validator.get(i) && !stacks.contains(stack -> stack.item == i)).map(i -> new ItemStack(i, 0)));
|
||||
this.stacks.sort(Structs.comparingInt(s -> s.item.id));
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MapsDialog extends BaseDialog{
|
||||
Runnable show = () -> ui.loadAnd(() -> {
|
||||
hide();
|
||||
ui.editor.show();
|
||||
ui.editor.editor.getTags().put("name", text);
|
||||
ui.editor.editor.tags.put("name", text);
|
||||
Events.fire(new MapMakeEvent());
|
||||
});
|
||||
|
||||
|
||||
@@ -162,11 +162,17 @@ public class ModsDialog extends BaseDialog{
|
||||
}}).size(h - 8f).padTop(-8f).padLeft(-8f).padRight(8f);
|
||||
|
||||
title.table(text -> {
|
||||
text.add("" + mod.meta.displayName() + "\n[lightgray]v" + mod.meta.version + (mod.enabled() ? "" : "\n" + Core.bundle.get("mod.disabled") + ""))
|
||||
boolean hideDisabled = !mod.isSupported() || mod.hasUnmetDependencies() || mod.hasContentErrors();
|
||||
|
||||
text.add("" + mod.meta.displayName() + "\n[lightgray]v" + mod.meta.version + (mod.enabled() || hideDisabled ? "" : "\n" + Core.bundle.get("mod.disabled") + ""))
|
||||
.wrap().top().width(300f).growX().left();
|
||||
|
||||
text.row();
|
||||
if(!mod.isSupported()){
|
||||
|
||||
if(mod.isOutdated()){
|
||||
text.labelWrap("@mod.outdated").growX();
|
||||
text.row();
|
||||
}else if(!mod.isSupported()){
|
||||
text.labelWrap(Core.bundle.format("mod.requiresversion", mod.meta.minGameVersion)).growX();
|
||||
text.row();
|
||||
}else if(mod.hasUnmetDependencies()){
|
||||
|
||||
@@ -88,7 +88,7 @@ public class PausedDialog extends BaseDialog{
|
||||
cont.buttonRow("@launchcore", Icon.up, () -> {
|
||||
hide();
|
||||
ui.planet.show(state.getSector(), player.team().core());
|
||||
}).disabled(b -> player.team().core() == null || !player.team().core().items.has(player.team().core().block.requirements));
|
||||
}).disabled(b -> player.team().core() == null);
|
||||
|
||||
cont.row();
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
}
|
||||
|
||||
public void show(Sector sector, CoreBuild launcher){
|
||||
if(launcher == null) return;
|
||||
|
||||
this.launcher = launcher;
|
||||
selected = null;
|
||||
hovered = null;
|
||||
@@ -127,10 +129,11 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
|
||||
//draw all sector stuff
|
||||
for(Sector sec : planet.sectors){
|
||||
|
||||
if(selectAlpha > 0.01f){
|
||||
if(canLaunch(sec) || sec.unlocked()){
|
||||
if(sec.baseCoverage > 0){
|
||||
planets.fill(sec, Tmp.c1.set(Team.crux.color).a(0.1f * sec.baseCoverage * selectAlpha), -0.002f);
|
||||
planets.fill(sec, Tmp.c1.set(Team.crux.color).a(0.5f * sec.baseCoverage * selectAlpha), -0.002f);
|
||||
}
|
||||
|
||||
Color color =
|
||||
@@ -290,7 +293,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
selectAlpha = Mathf.lerpDelta(selectAlpha, Mathf.num(planets.zoom < 1.9f), 0.1f);
|
||||
}
|
||||
|
||||
//TODO localize
|
||||
void updateSelected(){
|
||||
Sector sector = selected;
|
||||
|
||||
@@ -305,29 +307,43 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
|
||||
stable.add("[accent]" + (sector.preset == null ? sector.id : sector.preset.localizedName)).row();
|
||||
stable.image().color(Pal.accent).fillX().height(3f).pad(3f).row();
|
||||
stable.add(sector.save != null ? sector.save.getPlayTime() : "[lightgray]Unexplored").row();
|
||||
stable.add(sector.save != null ? sector.save.getPlayTime() : "@sectors.unexplored").row();
|
||||
if(sector.hasWaves() || sector.hasEnemyBase()){
|
||||
stable.add("[accent]Difficulty: " + (int)(sector.baseCoverage * 10)).row();
|
||||
}
|
||||
|
||||
if(sector.hasBase() && sector.hasWaves()){
|
||||
//TODO localize when finalized
|
||||
//these mechanics are likely to change and as such are not added to the bundle
|
||||
stable.add("[scarlet]Under attack!");
|
||||
stable.row();
|
||||
stable.add("[accent]" + Mathf.ceil(sectorDestructionTurns - (sector.getSecondsPassed() * 60) / turnDuration) + " turn(s)\nuntil destruction");
|
||||
stable.row();
|
||||
}
|
||||
|
||||
stable.add("Resources:").row();
|
||||
stable.table(t -> {
|
||||
t.left();
|
||||
int idx = 0;
|
||||
int max = 5;
|
||||
for(UnlockableContent c : sector.data.resources){
|
||||
t.image(c.icon(Cicon.small)).padRight(3);
|
||||
if(++idx % max == 0) t.row();
|
||||
}
|
||||
}).fillX().row();
|
||||
if(sector.save != null){
|
||||
stable.add("@sectors.resources").row();
|
||||
stable.table(t -> {
|
||||
|
||||
if(sector.save != null && sector.save.meta.secinfo != null && sector.save.meta.secinfo.resources.any()){
|
||||
t.left();
|
||||
int idx = 0;
|
||||
int max = 5;
|
||||
for(UnlockableContent c : sector.save.meta.secinfo.resources){
|
||||
t.image(c.icon(Cicon.small)).padRight(3);
|
||||
if(++idx % max == 0) t.row();
|
||||
}
|
||||
}else{
|
||||
t.add("@unknown").color(Color.lightGray);
|
||||
}
|
||||
|
||||
|
||||
}).fillX().row();
|
||||
}
|
||||
|
||||
//production
|
||||
if(sector.hasBase() && sector.save.meta.hasProduction){
|
||||
stable.add("Production:").row();
|
||||
stable.add("@sectors.production").row();
|
||||
stable.table(t -> {
|
||||
t.left();
|
||||
|
||||
@@ -335,7 +351,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
int total = (int)(stat.mean * 60);
|
||||
if(total > 1){
|
||||
t.image(item.icon(Cicon.small)).padRight(3);
|
||||
t.add(UI.formatAmount(total) + " /min").color(Color.lightGray);
|
||||
t.add(UI.formatAmount(total) + " " + Core.bundle.get("unit.perminute")).color(Color.lightGray);
|
||||
t.row();
|
||||
}
|
||||
});
|
||||
@@ -344,7 +360,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
|
||||
//stored resources
|
||||
if(sector.hasBase() && sector.save.meta.secinfo.coreItems.size > 0){
|
||||
stable.add("Stored:").row();
|
||||
stable.add("@sectors.stored").row();
|
||||
stable.table(t -> {
|
||||
t.left();
|
||||
|
||||
@@ -367,7 +383,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
stable.row();
|
||||
|
||||
if((sector.hasBase() && mode == look) || canLaunch(sector) || (sector.preset != null && sector.preset.alwaysUnlocked)){
|
||||
stable.button(sector.hasBase() ? "Resume" : "Launch", Styles.transt, () -> {
|
||||
stable.button(sector.hasBase() ? "@sectors.resume" : "@sectors.launch", Styles.transt, () -> {
|
||||
|
||||
boolean shouldHide = true;
|
||||
|
||||
@@ -397,7 +413,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
}
|
||||
|
||||
if(shouldHide) hide();
|
||||
}).growX().padTop(2f).height(50f).minWidth(170f);
|
||||
}).growX().padTop(2f).height(50f).minWidth(170f).disabled(b -> state.rules.sector == sector && !state.isMenu());
|
||||
}
|
||||
|
||||
stable.pack();
|
||||
|
||||
@@ -134,7 +134,9 @@ public class ResearchDialog extends BaseDialog{
|
||||
}
|
||||
});
|
||||
|
||||
view.addListener(new ElementGestureListener(){
|
||||
touchable = Touchable.enabled;
|
||||
|
||||
addCaptureListener(new ElementGestureListener(){
|
||||
@Override
|
||||
public void zoom(InputEvent event, float initialDistance, float distance){
|
||||
if(view.lastZoom < 0){
|
||||
@@ -338,7 +340,7 @@ public class ResearchDialog extends BaseDialog{
|
||||
button.update(() -> {
|
||||
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 = !locked(node.node) ? Tex.buttonOver : selectable(node.node) && !canSpend(node.node) ? Tex.buttonRed : Tex.button;
|
||||
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !selectable(node.node) || !canSpend(node.node) ? Tex.buttonRed : Tex.button;
|
||||
|
||||
((TextureRegionDrawable)button.getStyle().imageUp).setRegion(node.selectable ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
|
||||
button.getImage().setColor(!locked(node.node) ? Color.white : node.selectable ? Color.gray : Pal.gray);
|
||||
@@ -375,8 +377,18 @@ public class ResearchDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
boolean canSpend(TechNode node){
|
||||
//can spend when there's at least 1 item that can be spent
|
||||
return selectable(node) && (node.requirements.length == 0 || Structs.contains(node.requirements, i -> items.has(i.item)));
|
||||
if(!selectable(node)) return false;
|
||||
|
||||
if(node.requirements.length == 0) return true;
|
||||
|
||||
//can spend when there's at least 1 item that can be spent (non complete)
|
||||
for(int i = 0; i < node.requirements.length; i++){
|
||||
if(node.finishedRequirements[i].amount < node.requirements[i].amount && items.has(node.requirements[i].item)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void spend(TechNode node){
|
||||
|
||||
@@ -10,7 +10,6 @@ import arc.scene.ui.*;
|
||||
import arc.scene.ui.ImageButton.*;
|
||||
import arc.scene.ui.TextButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.Vars;
|
||||
import mindustry.game.*;
|
||||
@@ -342,7 +341,7 @@ public class SchematicsDialog extends BaseDialog{
|
||||
cont.add(new SchematicImage(schem)).maxSize(800f);
|
||||
cont.row();
|
||||
|
||||
Seq<ItemStack> arr = schem.requirements();
|
||||
ItemSeq arr = schem.requirements();
|
||||
cont.table(r -> {
|
||||
int i = 0;
|
||||
for(ItemStack s : arr){
|
||||
|
||||
@@ -86,7 +86,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
dataDialog.addCloseButton();
|
||||
|
||||
dataDialog.cont.table(Tex.button, t -> {
|
||||
t.defaults().size(270f, 60f).left();
|
||||
t.defaults().size(280f, 60f).left();
|
||||
TextButtonStyle style = Styles.cleart;
|
||||
|
||||
t.button("@settings.cleardata", Icon.trash, style, () -> ui.showConfirm("@confirm", "@settings.clearall.confirm", () -> {
|
||||
@@ -419,6 +419,9 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
|
||||
zipped.walk(f -> f.copyTo(base.child(f.path())));
|
||||
dest.delete();
|
||||
|
||||
//load data so it's saved on exit
|
||||
settings.load();
|
||||
}
|
||||
|
||||
private void back(){
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BlockConfigFragment extends Fragment{
|
||||
}
|
||||
|
||||
table.setOrigin(Align.center);
|
||||
if(configTile == null || configTile.block() == Blocks.air || !configTile.isValid()){
|
||||
if(configTile == null || configTile.block == Blocks.air || !configTile.isValid()){
|
||||
hideConfig();
|
||||
}else{
|
||||
configTile.updateTableAlign(table);
|
||||
|
||||
@@ -44,10 +44,12 @@ public class BlockInventoryFragment extends Fragment{
|
||||
|
||||
@Remote(called = Loc.server, targets = Loc.both, forward = true)
|
||||
public static void requestItem(Player player, Building tile, Item item, int amount){
|
||||
if(player == null || tile == null || !tile.interactable(player.team())) return;
|
||||
amount = Mathf.clamp(amount, 0, player.unit().itemCapacity());
|
||||
if(player == null || tile == null || !tile.interactable(player.team()) || !player.within(tile, buildingRange)) return;
|
||||
amount = Math.min(player.unit().maxAccepted(item), amount);
|
||||
int fa = amount;
|
||||
|
||||
if(amount == 0) return;
|
||||
|
||||
if(net.server() && (!Units.canInteract(player, tile) ||
|
||||
!netServer.admins.allowAction(player, ActionType.withdrawItem, tile.tile(), action -> {
|
||||
action.item = item;
|
||||
@@ -77,7 +79,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
return;
|
||||
}
|
||||
this.tile = t;
|
||||
if(tile == null || !tile.block().isAccessible() || tile.items.total() == 0)
|
||||
if(tile == null || !tile.block.isAccessible() || tile.items.total() == 0)
|
||||
return;
|
||||
rebuild(true);
|
||||
}
|
||||
@@ -106,7 +108,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
table.touchable = Touchable.enabled;
|
||||
table.update(() -> {
|
||||
|
||||
if(state.isMenu() || tile == null || !tile.isValid() || !tile.block().isAccessible() || emptyTime >= holdShrink){
|
||||
if(state.isMenu() || tile == null || !tile.isValid() || !tile.block.isAccessible() || emptyTime >= holdShrink){
|
||||
hide();
|
||||
}else{
|
||||
if(tile.items.total() == 0){
|
||||
@@ -129,7 +131,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
}
|
||||
|
||||
updateTablePosition();
|
||||
if(tile.block().hasItems){
|
||||
if(tile.block.hasItems){
|
||||
boolean dirty = false;
|
||||
if(shrinkHoldTimes.length != content.items().size) shrinkHoldTimes = new float[content.items().size];
|
||||
|
||||
@@ -155,7 +157,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
table.margin(4f);
|
||||
table.defaults().size(8 * 5).pad(4f);
|
||||
|
||||
if(tile.block().hasItems){
|
||||
if(tile.block.hasItems){
|
||||
|
||||
for(int i = 0; i < content.items().size; i++){
|
||||
Item item = content.item(i);
|
||||
@@ -163,7 +165,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
|
||||
container.add(i);
|
||||
|
||||
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused();
|
||||
Boolp canPick = () -> player.unit().acceptsItem(item) && !state.isPaused() && player.within(tile, itemTransferRange);
|
||||
|
||||
HandCursorListener l = new HandCursorListener();
|
||||
l.setEnabled(canPick);
|
||||
@@ -231,7 +233,7 @@ public class BlockInventoryFragment extends Fragment{
|
||||
}
|
||||
|
||||
private void updateTablePosition(){
|
||||
Vec2 v = Core.input.mouseScreen(tile.x + tile.block().size * tilesize / 2f, tile.y + tile.block().size * tilesize / 2f);
|
||||
Vec2 v = Core.input.mouseScreen(tile.x + tile.block.size * tilesize / 2f, tile.y + tile.block.size * tilesize / 2f);
|
||||
table.pack();
|
||||
table.setPosition(v.x, v.y, Align.topLeft);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ChatFragment extends Table{
|
||||
}
|
||||
}
|
||||
|
||||
return net.active();
|
||||
return net.active() && ui.hudfrag.shown();
|
||||
});
|
||||
|
||||
update(() -> {
|
||||
@@ -227,6 +227,7 @@ public class ChatFragment extends Table{
|
||||
}
|
||||
|
||||
public void addMessage(String message, String sender){
|
||||
if(sender == null && message == null) return;
|
||||
messages.insert(0, new ChatMessage(message, sender));
|
||||
|
||||
fadetime += 1f;
|
||||
@@ -244,7 +245,7 @@ public class ChatFragment extends Table{
|
||||
this.message = message;
|
||||
this.sender = sender;
|
||||
if(sender == null){ //no sender, this is a server message?
|
||||
formattedMessage = message;
|
||||
formattedMessage = message == null ? "" : message;
|
||||
}else{
|
||||
formattedMessage = "[coral][[" + sender + "[coral]]:[white] " + message;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package mindustry.ui.fragments;
|
||||
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.scene.*;
|
||||
@@ -29,10 +31,14 @@ import mindustry.ui.dialogs.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class HudFragment extends Fragment{
|
||||
private static final float dsize = 47f;
|
||||
private static final float dsize = 65f;
|
||||
|
||||
public final PlacementFragment blockfrag = new PlacementFragment();
|
||||
|
||||
//TODO localize
|
||||
public String sectorText = "Out of sector time.";
|
||||
public Seq<Sector> attackedSectors = new Seq<>();
|
||||
|
||||
private ImageButton flip;
|
||||
private Table lastUnlockTable;
|
||||
private Table lastUnlockLayout;
|
||||
@@ -64,16 +70,25 @@ public class HudFragment extends Fragment{
|
||||
coreItems.clear();
|
||||
});
|
||||
|
||||
Events.on(TurnEvent.class, e -> {
|
||||
ui.announce("[accent][[ Turn " + universe.turn() + " ]");
|
||||
});
|
||||
|
||||
//paused table
|
||||
parent.fill(t -> {
|
||||
t.top().visible(() -> state.isPaused() && !state.isOutOfTime()).touchable = Touchable.disabled;
|
||||
t.table(Styles.black5, top -> top.add("@paused").style(Styles.outlineLabel).pad(8f)).growX();
|
||||
});
|
||||
|
||||
//minimap + position
|
||||
parent.fill(t -> {
|
||||
t.visible(() -> Core.settings.getBool("minimap") && !state.rules.tutorial && shown);
|
||||
//minimap
|
||||
t.add(new Minimap());
|
||||
t.row();
|
||||
//position
|
||||
t.label(() -> player.tileX() + "," + player.tileY())
|
||||
.visible(() -> Core.settings.getBool("position") && !state.rules.tutorial)
|
||||
.touchable(Touchable.disabled);
|
||||
t.top().right();
|
||||
});
|
||||
|
||||
//TODO tear this all down
|
||||
//menu at top left
|
||||
parent.fill(cont -> {
|
||||
@@ -147,48 +162,54 @@ public class HudFragment extends Fragment{
|
||||
|
||||
cont.stack(wavesMain = new Table(), editorMain = new Table()).height(wavesMain.getPrefHeight());
|
||||
|
||||
{
|
||||
wavesMain.visible(() -> shown && !state.isEditor());
|
||||
wavesMain.top().left();
|
||||
Stack stack = new Stack();
|
||||
Button waves = new Button(Styles.waveb);
|
||||
Table btable = new Table().margin(0);
|
||||
wavesMain.visible(() -> shown && !state.isEditor());
|
||||
wavesMain.top().left();
|
||||
|
||||
stack.add(waves);
|
||||
stack.add(btable);
|
||||
wavesMain.table(s -> {
|
||||
//wave info button with text
|
||||
s.add(makeStatusTable()).grow();
|
||||
|
||||
addWaveTable(waves);
|
||||
addPlayButton(btable);
|
||||
wavesMain.add(stack).width(dsize * 5 + 4f);
|
||||
wavesMain.row();
|
||||
wavesMain.table(Tex.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(() -> state.rules.waves && state.boss() != null).height(60f).get();
|
||||
wavesMain.row();
|
||||
}
|
||||
//table with button to skip wave
|
||||
s.button(Icon.play, Styles.righti, 30f, () -> {
|
||||
if(net.client() && player.admin){
|
||||
Call.adminRequest(player, AdminAction.wave);
|
||||
}else if(inLaunchWave()){
|
||||
ui.showConfirm("@confirm", "@launch.skip.confirm", () -> !canSkipWave(), () -> logic.skipWave());
|
||||
}else{
|
||||
logic.skipWave();
|
||||
}
|
||||
}).growY().fillX().right().width(40f).disabled(b -> !canSkipWave()).visible(() -> state.rules.waves);
|
||||
}).width(dsize * 5 + 4f);
|
||||
|
||||
{
|
||||
editorMain.table(Tex.buttonEdge4, t -> {
|
||||
//t.margin(0f);
|
||||
t.add("@editor.teams").growX().left();
|
||||
t.row();
|
||||
t.table(teams -> {
|
||||
teams.left();
|
||||
int i = 0;
|
||||
for(Team team : Team.baseTeams){
|
||||
ImageButton button = teams.button(Tex.whiteui, Styles.clearTogglePartiali, 40f, () -> Call.setPlayerTeamEditor(player, team))
|
||||
.size(50f).margin(6f).get();
|
||||
button.getImageCell().grow();
|
||||
button.getStyle().imageUpColor = team.color;
|
||||
button.update(() -> button.setChecked(player.team() == team));
|
||||
wavesMain.row();
|
||||
|
||||
if(++i % 3 == 0){
|
||||
teams.row();
|
||||
}
|
||||
wavesMain.table(Tex.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(() -> state.rules.waves && state.boss() != null).height(60f).get();
|
||||
|
||||
wavesMain.row();
|
||||
|
||||
editorMain.table(Tex.buttonEdge4, t -> {
|
||||
//t.margin(0f);
|
||||
t.add("@editor.teams").growX().left();
|
||||
t.row();
|
||||
t.table(teams -> {
|
||||
teams.left();
|
||||
int i = 0;
|
||||
for(Team team : Team.baseTeams){
|
||||
ImageButton button = teams.button(Tex.whiteui, Styles.clearTogglePartiali, 40f, () -> Call.setPlayerTeamEditor(player, team))
|
||||
.size(50f).margin(6f).get();
|
||||
button.getImageCell().grow();
|
||||
button.getStyle().imageUpColor = team.color;
|
||||
button.update(() -> button.setChecked(player.team() == team));
|
||||
|
||||
if(++i % 3 == 0){
|
||||
teams.row();
|
||||
}
|
||||
}).left();
|
||||
}).width(dsize * 5 + 4f);
|
||||
editorMain.visible(() -> shown && state.isEditor());
|
||||
}
|
||||
}
|
||||
}).left();
|
||||
}).width(dsize * 5 + 4f);
|
||||
editorMain.visible(() -> shown && state.isEditor());
|
||||
|
||||
|
||||
//fps display
|
||||
cont.table(info -> {
|
||||
@@ -204,22 +225,10 @@ public class HudFragment extends Fragment{
|
||||
}).top().left();
|
||||
});
|
||||
|
||||
parent.fill(t -> {
|
||||
t.visible(() -> Core.settings.getBool("minimap") && !state.rules.tutorial && shown);
|
||||
//minimap
|
||||
t.add(new Minimap());
|
||||
t.row();
|
||||
//position
|
||||
t.label(() -> player.tileX() + "," + player.tileY())
|
||||
.visible(() -> Core.settings.getBool("position") && !state.rules.tutorial)
|
||||
.touchable(Touchable.disabled);
|
||||
t.top().right();
|
||||
});
|
||||
|
||||
//core items
|
||||
parent.fill(t -> {
|
||||
t.top().add(coreItems);
|
||||
t.visible(() -> Core.settings.getBool("coreitems") && !mobile && !state.isPaused());
|
||||
t.visible(() -> Core.settings.getBool("coreitems") && !mobile && !state.isPaused() && shown);
|
||||
});
|
||||
|
||||
//spawner warning
|
||||
@@ -272,20 +281,30 @@ public class HudFragment extends Fragment{
|
||||
parent.fill(t -> {
|
||||
t.top().visible(() -> state.isOutOfTime());
|
||||
t.table(Styles.black5, top -> {
|
||||
//TODO localize when done
|
||||
top.add("Out of sector time.").style(Styles.outlineLabel).color(Pal.accent).update(l -> l.color.a = Mathf.absin(Time.globalTime(), 7f, 1f)).colspan(2);
|
||||
//TODO localize
|
||||
top.add(sectorText).style(Styles.outlineLabel).color(Pal.accent).update(l -> {
|
||||
l.color.a = Mathf.absin(Time.globalTime(), 7f, 1f);
|
||||
l.setText(sectorText);
|
||||
}).colspan(2);
|
||||
top.row();
|
||||
|
||||
top.defaults().pad(2).size(150f, 54f);
|
||||
top.button("Next Turn", () -> {
|
||||
//TODO localize
|
||||
top.button("Skip", () -> {
|
||||
universe.runTurn();
|
||||
state.set(State.playing);
|
||||
|
||||
//announce turn info only when something is skipped.
|
||||
ui.announce("[accent][[ Turn " + universe.turn() + " ]\n[scarlet]" + attackedSectors.size + "[lightgray] sector(s) attacked.");
|
||||
});
|
||||
|
||||
top.button("Back to Planet", () -> {
|
||||
//TODO localize
|
||||
top.button("Switch Sectors", () -> {
|
||||
ui.paused.runExitSave();
|
||||
ui.planet.show();
|
||||
});
|
||||
|
||||
//switch to first attacked sector
|
||||
control.playSector(attackedSectors.first());
|
||||
}).disabled(b -> attackedSectors.isEmpty());
|
||||
}).margin(8).growX();
|
||||
});
|
||||
|
||||
@@ -331,6 +350,7 @@ public class HudFragment extends Fragment{
|
||||
});
|
||||
|
||||
//TODO DEBUG: rate table
|
||||
if(false)
|
||||
parent.fill(t -> {
|
||||
t.bottom().left();
|
||||
t.table(Styles.black6, c -> {
|
||||
@@ -598,7 +618,9 @@ public class HudFragment extends Fragment{
|
||||
shown = !shown;
|
||||
}
|
||||
|
||||
private void addWaveTable(Button table){
|
||||
private Table makeStatusTable(){
|
||||
Button table = new Button(Styles.waveb);
|
||||
|
||||
StringBuilder ibuild = new StringBuilder();
|
||||
|
||||
IntFormat wavef = new IntFormat("wave");
|
||||
@@ -625,6 +647,106 @@ public class HudFragment extends Fragment{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
table.name = "waves";
|
||||
|
||||
table.marginTop(0).marginBottom(4).marginLeft(4);
|
||||
|
||||
class SideBar extends Element{
|
||||
public final Floatp amount;
|
||||
public final boolean flip;
|
||||
public final Boolp flash;
|
||||
|
||||
float last, blink, value;
|
||||
|
||||
public SideBar(Floatp amount, Boolp flash, boolean flip){
|
||||
this.amount = amount;
|
||||
this.flip = flip;
|
||||
this.flash = flash;
|
||||
|
||||
setColor(Pal.health);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
float next = amount.get();
|
||||
|
||||
if(next < last && flash.get()){
|
||||
blink = 1f;
|
||||
}
|
||||
|
||||
blink = Mathf.lerpDelta(blink, 0f, 0.2f);
|
||||
value = Mathf.lerpDelta(value, next, 0.15f);
|
||||
last = next;
|
||||
|
||||
drawInner(Pal.darkishGray);
|
||||
|
||||
Draw.beginStencil();
|
||||
|
||||
Fill.crect(x, y, width, height * value);
|
||||
|
||||
Draw.beginStenciled();
|
||||
|
||||
drawInner(Tmp.c1.set(color).lerp(Color.white, blink));
|
||||
|
||||
Draw.endStencil();
|
||||
}
|
||||
|
||||
void drawInner(Color color){
|
||||
if(flip){
|
||||
x += width;
|
||||
width = -width;
|
||||
}
|
||||
|
||||
float stroke = width * 0.35f;
|
||||
float bh = height/2f;
|
||||
Draw.color(color);
|
||||
|
||||
Fill.quad(
|
||||
x, y,
|
||||
x + stroke, y,
|
||||
x + width, y + bh,
|
||||
x + width - stroke, y + bh
|
||||
);
|
||||
|
||||
Fill.quad(
|
||||
x + width, y + bh,
|
||||
x + width - stroke, y + bh,
|
||||
x, y + height,
|
||||
x + stroke, y + height
|
||||
);
|
||||
|
||||
Draw.reset();
|
||||
|
||||
if(flip){
|
||||
width = -width;
|
||||
x -= width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.stack(
|
||||
new Element(){
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.color(Pal.darkerGray);
|
||||
Fill.poly(x + width/2f, y + height/2f, 6, height / Mathf.sqrt3);
|
||||
Draw.reset();
|
||||
Drawf.shadow(x + width/2f, y + height/2f, height * 1.13f);
|
||||
}
|
||||
},
|
||||
new Table(t -> {
|
||||
float bw = 40f;
|
||||
float pad = -20;
|
||||
t.margin(0);
|
||||
|
||||
t.add(new SideBar(() -> player.unit().healthf(), () -> true, true)).width(bw).growY().padRight(pad);
|
||||
t.image(() -> player.icon()).scaling(Scaling.bounded).grow().maxWidth(54f);
|
||||
t.add(new SideBar(() -> player.dead() ? 0f : player.displayAmmo() ? player.unit().ammof() : player.unit().healthf(), () -> !player.displayAmmo(), false)).width(bw).growY().padLeft(pad).update(b -> {
|
||||
b.color.set(player.displayAmmo() ? Pal.ammo : Pal.health);
|
||||
});
|
||||
|
||||
t.getChildren().get(1).toFront();
|
||||
})).size(120f, 80).padRight(4);
|
||||
|
||||
table.labelWrap(() -> {
|
||||
builder.setLength(0);
|
||||
builder.append(wavef.get(state.wave));
|
||||
@@ -671,22 +793,12 @@ public class HudFragment extends Fragment{
|
||||
showLaunchConfirm();
|
||||
}
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private boolean canSkipWave(){
|
||||
return state.rules.waves && ((net.server() || player.admin) || !net.active()) && state.enemies == 0 && !spawner.isSpawning() && !state.rules.tutorial;
|
||||
}
|
||||
|
||||
private void addPlayButton(Table table){
|
||||
table.right().button(Icon.play, Styles.righti, 30f, () -> {
|
||||
if(net.client() && player.admin){
|
||||
Call.adminRequest(player, AdminAction.wave);
|
||||
}else if(inLaunchWave()){
|
||||
ui.showConfirm("@confirm", "@launch.skip.confirm", () -> !canSkipWave(), () -> logic.skipWave());
|
||||
}else{
|
||||
logic.skipWave();
|
||||
}
|
||||
}).growY().fillX().right().width(40f)
|
||||
.visible(this::canSkipWave);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,12 @@ public class MenuFragment extends Fragment{
|
||||
}));
|
||||
}
|
||||
|
||||
String versionText = "[#ffffffba]" + ((Version.build == -1) ? "[#fc8140aa]custom build" : (Version.type.equals("official") ? Version.modifier : Version.type) + " build " + Version.build + (Version.revision == 0 ? "" : "." + Version.revision));
|
||||
|
||||
String versionText = ((Version.build == -1) ? "[#fc8140aa]" : "[#ffffffba]") + Version.combined();
|
||||
parent.fill((x, y, w, h) -> {
|
||||
TextureRegion logo = Core.atlas.find("logo");
|
||||
float logoscl = Scl.scl(1);
|
||||
float logow = Math.min(logo.getWidth() * logoscl, Core.graphics.getWidth() - Scl.scl(20));
|
||||
float logoh = logow * (float)logo.getHeight() / logo.getWidth();
|
||||
float logow = Math.min(logo.width * logoscl, Core.graphics.getWidth() - Scl.scl(20));
|
||||
float logoh = logow * (float)logo.height / logo.width;
|
||||
|
||||
float fx = (int)(Core.graphics.getWidth() / 2f);
|
||||
float fy = (int)(Core.graphics.getHeight() - 6 - logoh) + logoh / 2 - (Core.graphics.isPortrait() ? Scl.scl(30f) : 0f);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class MinimapFragment extends Fragment{
|
||||
|
||||
if(renderer.minimap.getTexture() != null){
|
||||
Draw.color();
|
||||
float ratio = (float)renderer.minimap.getTexture().getHeight() / renderer.minimap.getTexture().getWidth();
|
||||
float ratio = (float)renderer.minimap.getTexture().height / renderer.minimap.getTexture().getWidth();
|
||||
TextureRegion reg = Draw.wrap(renderer.minimap.getTexture());
|
||||
Draw.rect(reg, w/2f + panx*zoom, h/2f + pany*zoom, size, size * ratio);
|
||||
renderer.minimap.drawEntities(w/2f + panx*zoom - size/2f, h/2f + pany*zoom - size/2f * ratio, size, size * ratio, zoom, true);
|
||||
@@ -113,7 +113,7 @@ public class MinimapFragment extends Fragment{
|
||||
public void toggle(){
|
||||
if(Core.settings.getBool("mapcenter")){
|
||||
float size = baseSize * zoom * world.width();
|
||||
float ratio = (float)renderer.minimap.getTexture().getHeight() / renderer.minimap.getTexture().getWidth();
|
||||
float ratio = (float)renderer.minimap.getTexture().height / renderer.minimap.getTexture().getWidth();
|
||||
panx = (size/2f - player.x() / (world.width() * tilesize) * size) / zoom;
|
||||
pany = (size*ratio/2f - player.y() / (world.height() * tilesize) * size*ratio) / zoom;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.BuildBlock.*;
|
||||
import mindustry.world.blocks.ConstructBlock.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class PlacementFragment extends Fragment{
|
||||
final int rowWidth = 4;
|
||||
|
||||
public Category currentCategory = Category.distribution;
|
||||
Seq<Block> returnArray = new Seq<>();
|
||||
Seq<Block> returnArray = new Seq<>(), returnArray2 = new Seq<>();
|
||||
Seq<Category> returnCatArray = new Seq<>();
|
||||
boolean[] categoryEmpty = new boolean[Category.all.length];
|
||||
ObjectMap<Category,Block> selectedBlocks = new ObjectMap<>();
|
||||
@@ -95,7 +95,7 @@ public class PlacementFragment extends Fragment{
|
||||
|
||||
if(Core.input.keyDown(Binding.pick) && player.isBuilder()){ //mouse eyedropper select
|
||||
Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
Block tryRecipe = tile == null ? null : tile.block() instanceof BuildBlock ? ((BuildEntity)tile).cblock : tile.block;
|
||||
Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block;
|
||||
Object tryConfig = tile == null ? null : tile.config();
|
||||
|
||||
for(BuildPlan req : player.builder().plans()){
|
||||
@@ -422,7 +422,7 @@ public class PlacementFragment extends Fragment{
|
||||
}
|
||||
|
||||
Seq<Block> getUnlockedByCategory(Category cat){
|
||||
return returnArray.selectFrom(content.blocks(), block -> block.category == cat && block.isVisible() && unlocked(block)).sort((b1, b2) -> Boolean.compare(!b1.isPlaceable(), !b2.isPlaceable()));
|
||||
return returnArray2.selectFrom(content.blocks(), block -> block.category == cat && block.isVisible() && unlocked(block)).sort((b1, b2) -> Boolean.compare(!b1.isPlaceable(), !b2.isPlaceable()));
|
||||
}
|
||||
|
||||
Block getSelectedBlock(Category cat){
|
||||
|
||||
Reference in New Issue
Block a user