mirror of
https://github.com/yawaflua/Informatis.git
synced 2025-12-15 17:56:24 +02:00
refactoring
This commit is contained in:
70
src/UnitInfo/ui/windows/CoreDisplay.java
Normal file
70
src/UnitInfo/ui/windows/CoreDisplay.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import UnitInfo.SVars;
|
||||
import arc.scene.Element;
|
||||
import arc.scene.style.*;
|
||||
import arc.scene.ui.ScrollPane;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.Tex;
|
||||
import mindustry.ui.Styles;
|
||||
|
||||
import static UnitInfo.SVars.modUiScale;
|
||||
import static arc.Core.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class CoreDisplay extends Table {
|
||||
static float itemScrollPos, heat;
|
||||
static Table table = new Table();
|
||||
|
||||
public CoreDisplay() {
|
||||
fillParent = true;
|
||||
visibility = () -> 2 == SVars.hud.uiIndex;
|
||||
|
||||
left().defaults().height(35f * 8f * Scl.scl(modUiScale));
|
||||
table(Tex.button, t -> {
|
||||
ScrollPane pane = t.pane(Styles.nonePane, rebuild()).get();
|
||||
pane.update(() -> {
|
||||
Element result = scene.hit(input.mouseX(), input.mouseY(), true);
|
||||
if(pane.hasScroll() && (result == null || !result.isDescendantOf(pane)))
|
||||
scene.setScrollFocus(null);
|
||||
itemScrollPos = pane.getScrollY();
|
||||
});
|
||||
pane.setOverscroll(false, false);
|
||||
pane.setScrollingDisabled(true, false);
|
||||
pane.setScrollYForce(itemScrollPos);
|
||||
|
||||
t.update(() -> {
|
||||
NinePatchDrawable patch = (NinePatchDrawable)Tex.button;
|
||||
t.setBackground(patch.tint(Tmp.c1.set(patch.getPatch().getColor()).a(settings.getInt("uiopacity") / 100f)));
|
||||
});
|
||||
}).padRight(Scl.scl(modUiScale) * 39 * 8f);
|
||||
}
|
||||
|
||||
public void setEvent() {
|
||||
heat += Time.delta;
|
||||
|
||||
if(heat > 60f) {
|
||||
heat = 0f;
|
||||
rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
public Table rebuild() {
|
||||
table.clear();
|
||||
table.table(t -> {
|
||||
for(int i = 0; i < CoresItemsDisplay.tables.size; i++){
|
||||
if((state.rules.pvp && CoresItemsDisplay.teams[i] != player.team()) || CoresItemsDisplay.teams[i].cores().isEmpty()) continue;
|
||||
int finalI = i;
|
||||
t.table(tt -> {
|
||||
tt.center().defaults().width(Scl.scl(modUiScale) * 44 * 8f);
|
||||
CoresItemsDisplay.tables.get(finalI).setBackground(((NinePatchDrawable)Tex.underline2).tint(CoresItemsDisplay.teams[finalI].color));
|
||||
tt.add(CoresItemsDisplay.tables.get(finalI)).left();
|
||||
}).pad(4);
|
||||
t.row();
|
||||
}
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
199
src/UnitInfo/ui/windows/CoresItemsDisplay.java
Normal file
199
src/UnitInfo/ui/windows/CoresItemsDisplay.java
Normal file
@@ -0,0 +1,199 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import UnitInfo.ui.SBar;
|
||||
import arc.Core;
|
||||
import arc.graphics.Color;
|
||||
import arc.math.Mathf;
|
||||
import arc.scene.event.HandCursorListener;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.Strings;
|
||||
import arc.util.Time;
|
||||
import arc.util.Tmp;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.Pal;
|
||||
import mindustry.input.DesktopInput;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.blocks.storage.*;
|
||||
|
||||
import static UnitInfo.SVars.*;
|
||||
import static arc.Core.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class CoresItemsDisplay {
|
||||
static final ObjectMap<Team, ObjectSet<Item>> usedItems = new ObjectMap<>();
|
||||
static final ObjectMap<Team, ObjectSet<UnitType>> usedUnits = new ObjectMap<>();
|
||||
static final ObjectMap<Team, Seq<ItemStack>> prevItems = new ObjectMap<>();
|
||||
static final ObjectMap<Team, Seq<ItemStack>> updateItems = new ObjectMap<>();
|
||||
static final ObjectIntMap<Team> coreAmount = new ObjectIntMap<>();
|
||||
static CoreBlock.CoreBuild core;
|
||||
public static Seq<Table> tables = new Seq<>();
|
||||
|
||||
public static Team[] teams;
|
||||
static float heat;
|
||||
|
||||
public CoresItemsDisplay() {
|
||||
resetUsed();
|
||||
}
|
||||
|
||||
public void resetUsed(){
|
||||
usedItems.clear();
|
||||
usedUnits.clear();
|
||||
updateItems.clear();
|
||||
prevItems.clear();
|
||||
coreAmount.clear();
|
||||
teams = Team.baseTeams;
|
||||
for(Team team : teams) {
|
||||
usedItems.put(team, new ObjectSet<>());
|
||||
usedUnits.put(team, new ObjectSet<>());
|
||||
Seq<ItemStack> stacks = new Seq<ItemStack>();
|
||||
content.items().each(i -> stacks.add(new ItemStack(i, 0)));
|
||||
updateItems.put(team, stacks);
|
||||
prevItems.put(team, stacks);
|
||||
coreAmount.put(team, team.cores().size);
|
||||
}
|
||||
tables.each(t->t.background(null));
|
||||
rebuild();
|
||||
}
|
||||
|
||||
public void updateItem(Team team){
|
||||
if(prevItems.get(team) != null && core != null) for(Item item : content.items()){
|
||||
updateItems.get(team).get(item.id).set(item, core.items.get(item) - prevItems.get(team).get(item.id).amount);
|
||||
prevItems.get(team).get(item.id).set(item, core.items.get(item));
|
||||
}
|
||||
prevItems.clear();
|
||||
Seq<ItemStack> stacks = new Seq<ItemStack>();
|
||||
if(core != null) content.items().each(i -> stacks.add(new ItemStack(i, core.items.get(i))));
|
||||
prevItems.put(team, stacks);
|
||||
|
||||
}
|
||||
|
||||
public Table setTable(Team team){
|
||||
return new Table(t -> {
|
||||
t.update(() -> {
|
||||
core = team.core();
|
||||
|
||||
if(settings.getBool("itemcal")) {
|
||||
heat += Time.delta;
|
||||
|
||||
if(heat >= settings.getInt("coreItemCheckRate")) {
|
||||
heat = 0;
|
||||
updateItem(team);
|
||||
}
|
||||
}
|
||||
|
||||
if(coreAmount.get(team) != team.cores().size){
|
||||
coreAmount.put(team, team.cores().size);
|
||||
rebuild();
|
||||
}
|
||||
});
|
||||
|
||||
Label label1 = new Label(() -> "[#" + team.color.toString() + "]" + team.name + "[]");
|
||||
label1.setFontScale(modUiScale);
|
||||
t.add(label1).row();
|
||||
t.table(coretable -> {
|
||||
final int[] i = {0};
|
||||
for(CoreBlock.CoreBuild core : team.cores()) {
|
||||
coretable.table(tt -> {
|
||||
tt.stack(
|
||||
new Table(s -> {
|
||||
s.center();
|
||||
Image image = new Image(core.block.uiIcon);
|
||||
image.clicked(() -> {
|
||||
if(control.input instanceof DesktopInput)
|
||||
((DesktopInput) control.input).panning = true;
|
||||
Core.camera.position.set(core.x, core.y);
|
||||
});
|
||||
if(!mobile) {
|
||||
HandCursorListener listener1 = new HandCursorListener();
|
||||
image.addListener(listener1);
|
||||
image.update(() -> {
|
||||
image.color.lerp(!listener1.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta));
|
||||
});
|
||||
}
|
||||
image.addListener(new Tooltip(tttt -> {
|
||||
Label label = new Label(() -> "([#" + Tmp.c1.set(Color.green).lerp(Color.red, 1 - core.healthf()).toString() + "]" + Strings.fixed(core.health, 2) + "[]/" + Strings.fixed(core.block.health, 2) + ")");
|
||||
label.setFontScale(Scl.scl(modUiScale));
|
||||
tttt.background(Tex.button).add(label);
|
||||
}));
|
||||
s.add(image).size(iconLarge * modUiScale);
|
||||
}),
|
||||
new Table(h -> {
|
||||
h.bottom().defaults().height(Scl.scl(modUiScale) * 9f).width(Scl.scl(modUiScale) * iconLarge * 1.5f).growX();
|
||||
h.add(new SBar(() -> "", () -> Pal.health, () -> core.health / core.block.health).rect().init());
|
||||
h.pack();
|
||||
})
|
||||
);
|
||||
tt.row();
|
||||
Label label = new Label(() -> "(" + (int) core.x / 8 + ", " + (int) core.y / 8 + ")");
|
||||
label.setFontScale(Scl.scl(modUiScale) * 0.75f);
|
||||
tt.add(label);
|
||||
}).padTop(Scl.scl(modUiScale) * 2).padLeft(Scl.scl(modUiScale) * 4).padRight(Scl.scl(modUiScale) * 4);
|
||||
if(++i[0] % 4 == 0) coretable.row();
|
||||
}
|
||||
});
|
||||
t.row();
|
||||
t.table().update(itemTable -> {
|
||||
itemTable.clear();
|
||||
final int[] i = {0};
|
||||
for(Item item : content.items()){
|
||||
if(team.core() != null && team.core().items.has(item)) {
|
||||
Table table1 = new Table(ttt -> {
|
||||
ttt.image(item.uiIcon).size(iconSmall * modUiScale).tooltip(tttt -> tttt.background(Styles.black6).margin(2f * modUiScale).add(item.localizedName).style(Styles.outlineLabel));
|
||||
Label label = new Label(() -> core == null ? "0" : UI.formatAmount(core.items.get(item)));
|
||||
label.setFontScale(modUiScale);
|
||||
ttt.add(label).minWidth(5 * 8f * modUiScale).left();
|
||||
});
|
||||
|
||||
|
||||
if(settings.getBool("itemcal")) {
|
||||
Table table2 = new Table(ttt -> {
|
||||
ttt.bottom().right();
|
||||
Label label = new Label(() -> {
|
||||
int amount = (int)(updateItems.get(team).get(item.id).amount / ((settings.getInt("coreItemCheckRate") * 1f) / 60f));
|
||||
return (amount > 0 ? "[green]+" : amount == 0 ? "[orange]" : "[red]") + amount + "/s[]";
|
||||
});
|
||||
label.setFontScale(0.65f * modUiScale);
|
||||
ttt.add(label).bottom().right().padTop(16f * modUiScale);
|
||||
ttt.pack();
|
||||
});
|
||||
|
||||
itemTable.stack(table1, table2).padRight(3 * modUiScale).left();
|
||||
}
|
||||
else itemTable.add(table1).padRight(3 * modUiScale).left();
|
||||
if(++i[0] % 5 == 0) itemTable.row();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.row();
|
||||
t.table().update(unitTable -> {
|
||||
unitTable.clear();
|
||||
final int[] i = {0};
|
||||
for(UnitType unit : content.units()){
|
||||
if(unit != UnitTypes.block && Groups.unit.contains(u -> u.type == unit && u.team == team)){
|
||||
unitTable.table(tt -> {
|
||||
tt.center();
|
||||
tt.image(unit.uiIcon).size(iconSmall * modUiScale).padRight(3 * modUiScale).tooltip(ttt -> ttt.background(Styles.black6).margin(2f * modUiScale).add(unit.localizedName).style(Styles.outlineLabel));
|
||||
Label label = new Label(() -> core == null ? "0" : UI.formatAmount(Groups.unit.count(u -> u.team == team && u.type == unit)));
|
||||
label.setFontScale(modUiScale);
|
||||
tt.add(label).padRight(3 * modUiScale).minWidth(5 * 8f * modUiScale).left();
|
||||
});
|
||||
if(++i[0] % 5 == 0) unitTable.row();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void rebuild(){
|
||||
tables.clear();
|
||||
for(Team team : teams) {
|
||||
tables.add(setTable(team));
|
||||
}
|
||||
}
|
||||
}
|
||||
488
src/UnitInfo/ui/windows/SchemDisplay.java
Normal file
488
src/UnitInfo/ui/windows/SchemDisplay.java
Normal file
@@ -0,0 +1,488 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import UnitInfo.SUtils;
|
||||
import arc.Core;
|
||||
import arc.func.Cons;
|
||||
import arc.func.Floatf;
|
||||
import arc.graphics.Color;
|
||||
import arc.input.KeyCode;
|
||||
import arc.scene.Element;
|
||||
import arc.scene.style.TextureRegionDrawable;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.scene.utils.Elem;
|
||||
import arc.struct.Seq;
|
||||
import arc.util.Align;
|
||||
import arc.util.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.Pal;
|
||||
import mindustry.ui.Styles;
|
||||
import mindustry.ui.dialogs.*;
|
||||
|
||||
import static arc.Core.*;
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.Vars.ui;
|
||||
|
||||
public class SchemDisplay extends Table {
|
||||
static float schemScrollPos, tagScrollPos;
|
||||
static boolean schemShown;
|
||||
static Schematic firstSchematic;
|
||||
static final Seq<String> selectedTags = new Seq<>();
|
||||
static Runnable rebuildList = () -> {};
|
||||
|
||||
public SchemDisplay() {
|
||||
setSchemTable();
|
||||
}
|
||||
|
||||
|
||||
public void setSchemTable() {
|
||||
clear();
|
||||
if(!settings.getBool(("schem"))) return;
|
||||
right();
|
||||
button(bundle.get("hud.schematic-list"), Icon.downOpen, Styles.squareTogglet, () -> schemShown = !schemShown).width(160f).height(60f).checked(b -> {
|
||||
Image image = (Image)b.getCells().first().get();
|
||||
image.setDrawable(schemShown ? Icon.upOpen : Icon.downOpen);
|
||||
return schemShown;
|
||||
}).row();
|
||||
collapser(t -> {
|
||||
t.background(Styles.black8).defaults().maxHeight(72 * 8f).maxWidth(160f);
|
||||
rebuildList = () -> {
|
||||
t.clearChildren();
|
||||
ScrollPane pane1 = t.pane(Styles.nonePane, p -> {
|
||||
p.left().defaults().pad(2).height(42f);
|
||||
try {
|
||||
for(String tag : (Seq<String>)SUtils.invoke(ui.schematics, "tags")){
|
||||
p.button(tag, Styles.togglet, () -> {
|
||||
if(selectedTags.contains(tag)){
|
||||
selectedTags.remove(tag);
|
||||
}else{
|
||||
selectedTags.add(tag);
|
||||
}
|
||||
rebuildList.run();
|
||||
}).checked(selectedTags.contains(tag)).with(c -> c.getLabel().setWrap(false));
|
||||
}
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).fillX().height(42f).get();
|
||||
pane1.update(() -> {
|
||||
Element result = scene.hit(input.mouseX(), input.mouseY(), true);
|
||||
if(pane1.hasScroll() && (result == null || !result.isDescendantOf(pane1)))
|
||||
scene.setScrollFocus(null);
|
||||
tagScrollPos = pane1.getScrollX();
|
||||
});
|
||||
|
||||
pane1.setOverscroll(false, false);
|
||||
pane1.setScrollingDisabled(false, true);
|
||||
pane1.setScrollXForce(tagScrollPos);
|
||||
|
||||
t.row();
|
||||
|
||||
ScrollPane pane = t.pane(Styles.nonePane, p -> {
|
||||
p.table(tt -> {
|
||||
firstSchematic = null;
|
||||
|
||||
tt.button("@editor.import", Icon.download, this::showImport).width(160f).height(64f).row();
|
||||
for(Schematic s : schematics.all()){
|
||||
if(selectedTags.any() && !s.labels.containsAll(selectedTags)) continue;
|
||||
if(firstSchematic == null) firstSchematic = s;
|
||||
|
||||
Button[] sel = {null};
|
||||
sel[0] = tt.button(b -> {
|
||||
b.top();
|
||||
b.margin(0f);
|
||||
b.table(buttons -> {
|
||||
buttons.left();
|
||||
buttons.defaults().size(162/4f);
|
||||
|
||||
ImageButton.ImageButtonStyle style = Styles.clearPartiali;
|
||||
|
||||
buttons.button(Icon.info, style, () -> showInfo(s));
|
||||
buttons.button(Icon.upload, style, () -> showExport(s));
|
||||
buttons.button(Icon.pencil, style, () -> {
|
||||
new Dialog("@schematic.rename"){{
|
||||
setFillParent(true);
|
||||
|
||||
cont.margin(30);
|
||||
|
||||
cont.add("@schematic.tags").padRight(6f);
|
||||
cont.table(tags -> buildTags(s, tags, false)).maxWidth(400f).fillX().left().row();
|
||||
|
||||
cont.margin(30).add("@name").padRight(6f);
|
||||
TextField nameField = cont.field(s.name(), null).size(400f, 55f).left().get();
|
||||
|
||||
cont.row();
|
||||
|
||||
cont.margin(30).add("@editor.description").padRight(6f);
|
||||
TextField descField = cont.area(s.description(), Styles.areaField, t -> {}).size(400f, 140f).left().get();
|
||||
|
||||
Runnable accept = () -> {
|
||||
s.tags.put("name", nameField.getText());
|
||||
s.tags.put("description", descField.getText());
|
||||
s.save();
|
||||
hide();
|
||||
setSchemTable();
|
||||
};
|
||||
|
||||
buttons.defaults().size(120, 54).pad(4);
|
||||
buttons.button("@ok", accept).disabled(b -> nameField.getText().isEmpty());
|
||||
buttons.button("@cancel", this::hide);
|
||||
|
||||
keyDown(KeyCode.enter, () -> {
|
||||
if(!nameField.getText().isEmpty() && Core.scene.getKeyboardFocus() != descField){
|
||||
accept.run();
|
||||
}
|
||||
});
|
||||
keyDown(KeyCode.escape, this::hide);
|
||||
keyDown(KeyCode.back, this::hide);
|
||||
show();
|
||||
}};
|
||||
});
|
||||
|
||||
if(s.hasSteamID()){
|
||||
buttons.button(Icon.link, style, () -> platform.viewListing(s));
|
||||
}else{
|
||||
buttons.button(Icon.trash, style, () -> {
|
||||
if(s.mod != null){
|
||||
ui.showInfo(Core.bundle.format("mod.item.remove", s.mod.meta.displayName()));
|
||||
}else{
|
||||
ui.showConfirm("@confirm", "@schematic.delete.confirm", () -> {
|
||||
schematics.remove(s);
|
||||
setSchemTable();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}).growX().height(50f);
|
||||
b.row();
|
||||
b.stack(new SchematicsDialog.SchematicImage(s).setScaling(Scaling.fit), new Table(n -> {
|
||||
n.top();
|
||||
n.table(Styles.black3, c -> {
|
||||
Label label = c.add(s.name()).style(Styles.outlineLabel).color(Color.white).top().growX().maxWidth(200f - 8f).get();
|
||||
label.setEllipsis(true);
|
||||
label.setAlignment(Align.center);
|
||||
}).growX().margin(1).pad(4).maxWidth(Scl.scl(160f - 8f)).padBottom(0);
|
||||
})).size(160f);
|
||||
}, () -> {
|
||||
if(sel[0].childrenPressed()) return;
|
||||
control.input.useSchematic(s);
|
||||
|
||||
}).pad(4).style(Styles.cleari).get();
|
||||
|
||||
sel[0].getStyle().up = Tex.pane;
|
||||
tt.row();
|
||||
}
|
||||
|
||||
if(firstSchematic == null){
|
||||
tt.add(bundle.get("none"));
|
||||
}
|
||||
});
|
||||
}).grow().get();
|
||||
|
||||
pane.update(() -> {
|
||||
Element result = scene.hit(input.mouseX(), input.mouseY(), true);
|
||||
if(pane.hasScroll() && (result == null || !result.isDescendantOf(pane)))
|
||||
scene.setScrollFocus(null);
|
||||
schemScrollPos = pane.getScrollY();
|
||||
});
|
||||
|
||||
pane.setOverscroll(false, false);
|
||||
pane.setScrollingDisabled(true, false);
|
||||
pane.setScrollYForce(schemScrollPos);
|
||||
};
|
||||
rebuildList.run();
|
||||
}, true, () -> schemShown);
|
||||
}
|
||||
|
||||
void showInfo(Schematic schematic){
|
||||
try {
|
||||
((SchematicsDialog.SchematicInfoDialog) SUtils.invoke(ui.schematics, "info")).show(schematic);
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void checkTags(Schematic s){
|
||||
boolean any = false;
|
||||
Seq<String> seq = null;
|
||||
try {
|
||||
seq = (Seq<String>) SUtils.invoke(ui.schematics, "tags");
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(seq == null) return;
|
||||
for(var tag : s.labels){
|
||||
if(!seq.contains(tag)){
|
||||
seq.add(tag);
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
if(any) setSchemTable();
|
||||
}
|
||||
|
||||
void showImport(){
|
||||
BaseDialog dialog = new BaseDialog("@editor.export");
|
||||
dialog.cont.pane(p -> {
|
||||
p.margin(10f);
|
||||
p.table(Tex.button, t -> {
|
||||
TextButton.TextButtonStyle style = Styles.cleart;
|
||||
t.defaults().size(280f, 60f).left();
|
||||
t.row();
|
||||
t.button("@schematic.copy.import", Icon.copy, style, () -> {
|
||||
dialog.hide();
|
||||
try{
|
||||
Schematic s = Schematics.readBase64(Core.app.getClipboardText());
|
||||
s.removeSteamID();
|
||||
schematics.add(s);
|
||||
setSchemTable();
|
||||
ui.showInfoFade("@schematic.saved");
|
||||
checkTags(s);
|
||||
showInfo(s);
|
||||
}catch(Throwable e){
|
||||
ui.showException(e);
|
||||
}
|
||||
}).marginLeft(12f).disabled(b -> Core.app.getClipboardText() == null || !Core.app.getClipboardText().startsWith(schematicBaseStart));
|
||||
t.row();
|
||||
t.button("@schematic.importfile", Icon.download, style, () -> platform.showFileChooser(true, schematicExtension, file -> {
|
||||
dialog.hide();
|
||||
|
||||
try{
|
||||
Schematic s = Schematics.read(file);
|
||||
s.removeSteamID();
|
||||
schematics.add(s);
|
||||
setSchemTable();
|
||||
showInfo(s);
|
||||
checkTags(s);
|
||||
}catch(Exception e){
|
||||
ui.showException(e);
|
||||
}
|
||||
})).marginLeft(12f);
|
||||
t.row();
|
||||
if(steam){
|
||||
t.button("@schematic.browseworkshop", Icon.book, style, () -> {
|
||||
dialog.hide();
|
||||
platform.openWorkshop();
|
||||
}).marginLeft(12f);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
dialog.addCloseButton();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
void showExport(Schematic s){
|
||||
BaseDialog dialog = new BaseDialog("@editor.export");
|
||||
dialog.cont.pane(p -> {
|
||||
p.margin(10f);
|
||||
p.table(Tex.button, t -> {
|
||||
TextButton.TextButtonStyle style = Styles.cleart;
|
||||
t.defaults().size(280f, 60f).left();
|
||||
if(steam && !s.hasSteamID()){
|
||||
t.button("@schematic.shareworkshop", Icon.book, style,
|
||||
() -> platform.publish(s)).marginLeft(12f);
|
||||
t.row();
|
||||
dialog.hide();
|
||||
}
|
||||
t.button("@schematic.copy", Icon.copy, style, () -> {
|
||||
dialog.hide();
|
||||
ui.showInfoFade("@copied");
|
||||
Core.app.setClipboardText(schematics.writeBase64(s));
|
||||
}).marginLeft(12f);
|
||||
t.row();
|
||||
t.button("@schematic.exportfile", Icon.export, style, () -> {
|
||||
dialog.hide();
|
||||
platform.export(s.name(), schematicExtension, file -> Schematics.write(s, file));
|
||||
}).marginLeft(12f);
|
||||
});
|
||||
});
|
||||
|
||||
dialog.addCloseButton();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
void tagsChanged(){
|
||||
rebuildList.run();
|
||||
Seq<String> tags = null;
|
||||
try {
|
||||
tags = (Seq<String>) SUtils.invoke(ui.schematics, "tags");
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(tags == null) return;
|
||||
Core.settings.putJson("schematic-tags", String.class, tags);
|
||||
}
|
||||
|
||||
void addTag(Schematic s, String tag){
|
||||
s.labels.add(tag);
|
||||
s.save();
|
||||
tagsChanged();
|
||||
}
|
||||
|
||||
void removeTag(Schematic s, String tag){
|
||||
s.labels.remove(tag);
|
||||
s.save();
|
||||
tagsChanged();
|
||||
}
|
||||
|
||||
//shows a dialog for creating a new tag
|
||||
void showNewTag(Cons<String> result){
|
||||
Seq<String> tags = null;
|
||||
try {
|
||||
tags = (Seq<String>) SUtils.invoke(ui.schematics, "tags");
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(tags == null) return;
|
||||
Seq<String> finalTags = tags;
|
||||
ui.showTextInput("@schematic.addtag", "", "", out -> {
|
||||
if(finalTags.contains(out)){
|
||||
ui.showInfo("@schematic.tagexists");
|
||||
}else{
|
||||
finalTags.add(out);
|
||||
tagsChanged();
|
||||
result.get(out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void showNewIconTag(Cons<String> cons){
|
||||
Seq<String> tags = null;
|
||||
try {
|
||||
tags = (Seq<String>) SUtils.invoke(ui.schematics, "tags");
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(tags == null) return;
|
||||
Seq<String> finalTags = tags;
|
||||
new Dialog(){{
|
||||
closeOnBack();
|
||||
setFillParent(true);
|
||||
|
||||
cont.pane(t ->
|
||||
resized(true, () -> {
|
||||
t.clearChildren();
|
||||
t.marginRight(19f);
|
||||
t.defaults().size(48f);
|
||||
|
||||
int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f));
|
||||
|
||||
for(ContentType ctype : defaultContentIcons){
|
||||
t.row();
|
||||
t.image().colspan(cols).growX().width(Float.NEGATIVE_INFINITY).height(3f).color(Pal.accent);
|
||||
t.row();
|
||||
|
||||
int i = 0;
|
||||
for(UnlockableContent u : content.getBy(ctype).<UnlockableContent>as()){
|
||||
if(!u.isHidden() && u.unlockedNow() && u.hasEmoji() && !finalTags.contains(u.emoji())){
|
||||
t.button(new TextureRegionDrawable(u.uiIcon), Styles.cleari, iconMed, () -> {
|
||||
String out = u.emoji() + "";
|
||||
|
||||
finalTags.add(out);
|
||||
tagsChanged();
|
||||
cons.get(out);
|
||||
|
||||
hide();
|
||||
});
|
||||
|
||||
if(++i % cols == 0) t.row();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
|
||||
}}.show();
|
||||
}
|
||||
|
||||
void buildTags(Schematic schem, Table t, boolean name){
|
||||
t.clearChildren();
|
||||
t.left();
|
||||
Seq<String> tags = null;
|
||||
try {
|
||||
tags = (Seq<String>) SUtils.invoke(ui.schematics, "tags");
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(tags == null) return;
|
||||
|
||||
//sort by order in the main target array. the complexity of this is probably awful
|
||||
Seq<String> finalTags = tags;
|
||||
schem.labels.sort((Floatf<String>) finalTags::indexOf);
|
||||
|
||||
if(name) t.add("@schematic.tags").padRight(4);
|
||||
t.pane(s -> {
|
||||
s.left();
|
||||
s.defaults().pad(3).height(42f);
|
||||
for(var tag : schem.labels){
|
||||
s.table(Tex.button, i -> {
|
||||
i.add(tag).padRight(4).height(42f).labelAlign(Align.center);
|
||||
i.button(Icon.cancelSmall, Styles.emptyi, () -> {
|
||||
removeTag(schem, tag);
|
||||
buildTags(schem, t, name);
|
||||
}).size(42f).padRight(-9f).padLeft(-9f);
|
||||
});
|
||||
}
|
||||
|
||||
}).fillX().left().height(42f).scrollY(false);
|
||||
|
||||
Seq<String> finalTags1 = tags;
|
||||
t.button(Icon.addSmall, () -> {
|
||||
var dialog = new BaseDialog("@schematic.addtag");
|
||||
dialog.addCloseButton();
|
||||
dialog.cont.pane(p -> {
|
||||
p.clearChildren();
|
||||
|
||||
float sum = 0f;
|
||||
Table current = new Table().left();
|
||||
for(var tag : finalTags1){
|
||||
if(schem.labels.contains(tag)) continue;
|
||||
|
||||
var next = Elem.newButton(tag, () -> {
|
||||
addTag(schem, tag);
|
||||
buildTags(schem, t, name);
|
||||
dialog.hide();
|
||||
});
|
||||
next.getLabel().setWrap(false);
|
||||
|
||||
next.pack();
|
||||
float w = next.getPrefWidth() + Scl.scl(6f);
|
||||
|
||||
if(w + sum >= Core.graphics.getWidth() * (Core.graphics.isPortrait() ? 1f : 0.8f)){
|
||||
p.add(current).row();
|
||||
current = new Table();
|
||||
current.left();
|
||||
current.add(next).height(42f).pad(2);
|
||||
sum = 0;
|
||||
}else{
|
||||
current.add(next).height(42f).pad(2);
|
||||
}
|
||||
|
||||
sum += w;
|
||||
}
|
||||
|
||||
if(sum > 0){
|
||||
p.add(current).row();
|
||||
}
|
||||
|
||||
Cons<String> handleTag = res -> {
|
||||
dialog.hide();
|
||||
addTag(schem, res);
|
||||
buildTags(schem, t, name);
|
||||
};
|
||||
|
||||
p.row();
|
||||
|
||||
p.table(v -> {
|
||||
v.left().defaults().fillX().height(42f).pad(2);
|
||||
v.button("@schematic.texttag", Icon.add, () -> showNewTag(handleTag)).wrapLabel(false).get().getLabelCell().padLeft(4);
|
||||
v.button("@schematic.icontag", Icon.add, () -> showNewIconTag(handleTag)).wrapLabel(false).get().getLabelCell().padLeft(4);
|
||||
});
|
||||
});
|
||||
dialog.show();
|
||||
}).size(42f).tooltip("@schematic.addtag");
|
||||
}
|
||||
}
|
||||
170
src/UnitInfo/ui/windows/WaveDisplay.java
Normal file
170
src/UnitInfo/ui/windows/WaveDisplay.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import UnitInfo.SVars;
|
||||
import arc.graphics.Color;
|
||||
import arc.input.KeyCode;
|
||||
import arc.math.Mathf;
|
||||
import arc.scene.Element;
|
||||
import arc.scene.event.HandCursorListener;
|
||||
import arc.scene.style.NinePatchDrawable;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.ObjectIntMap;
|
||||
import arc.struct.Seq;
|
||||
import arc.util.Scaling;
|
||||
import arc.util.Time;
|
||||
import arc.util.Tmp;
|
||||
import mindustry.content.StatusEffects;
|
||||
import mindustry.game.SpawnGroup;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.Pal;
|
||||
import mindustry.ui.*;
|
||||
|
||||
import static UnitInfo.SVars.modUiScale;
|
||||
import static arc.Core.*;
|
||||
import static arc.Core.settings;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
|
||||
public class WaveDisplay extends Table {
|
||||
static float waveScrollPos;
|
||||
static Table table = new Table();
|
||||
|
||||
public WaveDisplay() {
|
||||
fillParent = true;
|
||||
visibility = () -> 1 == SVars.hud.uiIndex;
|
||||
|
||||
defaults().size(Scl.scl(modUiScale) * 35 * 8f);
|
||||
table(Tex.button, t -> {
|
||||
ScrollPane pane = t.pane(Styles.nonePane, rebuild()).get();
|
||||
pane.update(() -> {
|
||||
if (pane.hasScroll()) {
|
||||
Element result = scene.hit(input.mouseX(), input.mouseY(), true);
|
||||
if (result == null || !result.isDescendantOf(pane)) {
|
||||
scene.setScrollFocus(null);
|
||||
}
|
||||
}
|
||||
waveScrollPos = pane.getScrollY();
|
||||
});
|
||||
pane.setOverscroll(false, false);
|
||||
pane.setScrollingDisabled(true, false);
|
||||
pane.setScrollYForce(waveScrollPos);
|
||||
|
||||
update(() -> {
|
||||
NinePatchDrawable patch = (NinePatchDrawable) Tex.button;
|
||||
t.setBackground(patch.tint(Tmp.c1.set(patch.getPatch().getColor()).a(settings.getInt("uiopacity") / 100f)));
|
||||
});
|
||||
}).padRight(Scl.scl(modUiScale) * 70 * 8f);
|
||||
}
|
||||
|
||||
public Table rebuild(){
|
||||
table.clear();
|
||||
int winWave = state.isCampaign() && state.rules.winWave > 0 ? state.rules.winWave : Integer.MAX_VALUE;
|
||||
for(int i = settings.getBool("pastwave") ? 0 : state.wave - 1; i <= Math.min(state.wave + settings.getInt("wavemax"), winWave - 2); i++){
|
||||
final int j = i;
|
||||
if(!settings.getBool("emptywave") && state.rules.spawns.find(g -> g.getSpawned(j) > 0) == null) continue;
|
||||
table.table(table1 -> {
|
||||
table1.stack(
|
||||
new Table(t -> {
|
||||
Label label = new Label(() -> "[#" + (state.wave == j ? Color.red.toString() : Pal.accent.toString()) + "]" + j + "[]");
|
||||
label.setFontScale(Scl.scl(modUiScale));
|
||||
t.add(label).padRight(Scl.scl(modUiScale) * 24 * 8f);
|
||||
}),
|
||||
new Table(Tex.underline, t -> {
|
||||
t.marginLeft(Scl.scl(modUiScale) * 3 * 8f);
|
||||
if(settings.getBool("emptywave") && state.rules.spawns.find(g -> g.getSpawned(j) > 0) == null) {
|
||||
t.center();
|
||||
Label label = new Label(bundle.get("empty"));
|
||||
label.setFontScale(Scl.scl(modUiScale));
|
||||
t.add(label);
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectIntMap<SpawnGroup> groups = new ObjectIntMap<>();
|
||||
for(SpawnGroup group : state.rules.spawns) {
|
||||
if(group.getSpawned(j) <= 0) continue;
|
||||
SpawnGroup sameTypeKey = groups.keys().toArray().find(g -> g.type == group.type && g.effect != StatusEffects.boss);
|
||||
if(sameTypeKey != null) groups.increment(sameTypeKey, sameTypeKey.getSpawned(j));
|
||||
else groups.put(group, group.getSpawned(j));
|
||||
}
|
||||
Seq<SpawnGroup> groupSorted = groups.keys().toArray().copy().sort((g1, g2) -> {
|
||||
int boss = Boolean.compare(g1.effect != StatusEffects.boss, g2.effect != StatusEffects.boss);
|
||||
if(boss != 0) return boss;
|
||||
int hitSize = Float.compare(-g1.type.hitSize, -g2.type.hitSize);
|
||||
if(hitSize != 0) return hitSize;
|
||||
return Integer.compare(-g1.type.id, -g2.type.id);
|
||||
});
|
||||
ObjectIntMap<SpawnGroup> groupsTmp = new ObjectIntMap<>();
|
||||
groupSorted.each(g -> groupsTmp.put(g, groups.get(g)));
|
||||
|
||||
int row = 0;
|
||||
for(SpawnGroup group : groupsTmp.keys()){
|
||||
int spawners = state.rules.waveTeam.cores().size + (group.type.flying ? spawner.countFlyerSpawns() : spawner.countGroundSpawns());
|
||||
int amount = groupsTmp.get(group);
|
||||
t.table(tt -> {
|
||||
Image image = new Image(group.type.uiIcon).setScaling(Scaling.fit);
|
||||
tt.stack(
|
||||
new Table(ttt -> {
|
||||
ttt.center();
|
||||
ttt.add(image).size(iconMed * Scl.scl(modUiScale));
|
||||
ttt.pack();
|
||||
}),
|
||||
|
||||
new Table(ttt -> {
|
||||
ttt.bottom().left();
|
||||
Label label = new Label(() -> amount + "");
|
||||
label.setFontScale(Scl.scl(modUiScale) * 0.9f);
|
||||
Label multi = new Label(() -> "[gray]x" + spawners);
|
||||
multi.setFontScale(Scl.scl(modUiScale) * 0.7f);
|
||||
ttt.add(label).padTop(2f);
|
||||
ttt.add(multi).padTop(10f);
|
||||
ttt.pack();
|
||||
}),
|
||||
|
||||
new Table(ttt -> {
|
||||
ttt.top().right();
|
||||
Image image1 = new Image(Icon.warning.getRegion()).setScaling(Scaling.fit);
|
||||
image1.update(() -> {
|
||||
image1.setColor(Tmp.c2.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f)));
|
||||
});
|
||||
ttt.add(image1).size(Scl.scl(modUiScale) * 12f);
|
||||
ttt.visible(() -> group.effect == StatusEffects.boss);
|
||||
ttt.pack();
|
||||
})
|
||||
).pad(2f * Scl.scl(modUiScale));
|
||||
tt.clicked(() -> {
|
||||
if(input.keyDown(KeyCode.shiftLeft) && Fonts.getUnicode(group.type.name) != 0){
|
||||
app.setClipboardText((char)Fonts.getUnicode(group.type.name) + "");
|
||||
ui.showInfoFade("@copied");
|
||||
}else{
|
||||
ui.content.show(group.type);
|
||||
}
|
||||
});
|
||||
if(!mobile){
|
||||
HandCursorListener listener = new HandCursorListener();
|
||||
tt.addListener(listener);
|
||||
tt.update(() -> {
|
||||
image.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta));
|
||||
});
|
||||
}
|
||||
tt.addListener(new Tooltip(ttt -> ttt.table(Styles.black6, to -> {
|
||||
to.margin(4f).left();
|
||||
to.add("[stat]" + group.type.localizedName + "[]").row();
|
||||
to.row();
|
||||
to.add(bundle.format("shar-stat-waveAmount", amount + " [lightgray]x" + spawners + "[]")).row();
|
||||
to.add(bundle.format("shar-stat-waveShield", group.getShield(j))).row();
|
||||
if(group.effect != null && group.effect != StatusEffects.none)
|
||||
to.add(bundle.get("shar-stat.waveStatus") + group.effect.emoji() + "[stat]" + group.effect.localizedName).row();
|
||||
})));
|
||||
});
|
||||
if(++row % 4 == 0) t.row();
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
table.row();
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
134
src/UnitInfo/ui/windows/WindowTable.java
Normal file
134
src/UnitInfo/ui/windows/WindowTable.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.input.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.style.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class WindowTable extends Table{
|
||||
public Cons<Table> content, onClose;
|
||||
public TextureRegionDrawable icon;
|
||||
public float maxWindowHeight, maxWindowWidth;
|
||||
public boolean maxWidthEnabled = false, maxHeightEnabled = false;
|
||||
|
||||
public WindowTable() {
|
||||
this("none", Icon.none, c->{});
|
||||
}
|
||||
|
||||
public WindowTable(String title, TextureRegionDrawable icon, Cons<Table> content){
|
||||
this(title, icon, content, t -> t.visible(() -> false));
|
||||
}
|
||||
|
||||
public WindowTable(String title, TextureRegionDrawable icon, Cons<Table> content, Cons<Table> onClose){
|
||||
this.name = title;
|
||||
this.icon = icon;
|
||||
this.content = content;
|
||||
this.onClose = onClose;
|
||||
build();
|
||||
}
|
||||
|
||||
public void build(){
|
||||
top();
|
||||
topBar();
|
||||
|
||||
// window contents
|
||||
table(Styles.black5, t -> {
|
||||
content.get(t);
|
||||
}).grow();
|
||||
|
||||
resizeButton();
|
||||
}
|
||||
|
||||
public void topBar(){
|
||||
table(t -> {
|
||||
t.table(Tex.buttonEdge1, b -> {
|
||||
b.top().left();
|
||||
b.image(icon).size(20f).padLeft(15).top().left();
|
||||
b.pane(Styles.nonePane, p -> {
|
||||
p.top().left();
|
||||
p.labelWrap(name).padLeft(20).top().left().get().setAlignment(Align.topLeft);
|
||||
}).top().left().height(40f).growX().get().setScrollingDisabled(true, true);
|
||||
}).maxHeight(40f).grow();
|
||||
t.table(Tex.buttonEdge3, b -> {
|
||||
b.button(Icon.cancel, Styles.emptyi, () -> onClose.get(this));
|
||||
}).maxHeight(40f).width(80f).growY();
|
||||
|
||||
t.touchable = Touchable.enabled;
|
||||
t.addListener(new InputListener(){
|
||||
float lastX, lastY;
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button) {
|
||||
Vec2 v = t.localToStageCoordinates(Tmp.v1.set(x, y));
|
||||
lastX = v.x;
|
||||
lastY = v.y;
|
||||
t.toFront();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchDragged(InputEvent event, float x, float y, int pointer) {
|
||||
Vec2 v = t.localToStageCoordinates(Tmp.v1.set(x, y));
|
||||
|
||||
moveBy(v.x - lastX, v.y - lastY);
|
||||
lastX = v.x;
|
||||
lastY = v.y;
|
||||
}
|
||||
});
|
||||
}).top().height(40f).growX();
|
||||
row();
|
||||
}
|
||||
|
||||
public void resizeButton(){
|
||||
row();
|
||||
table(Styles.black5, t -> {
|
||||
t.table().growX();
|
||||
t.table(Icon.resizeSmall, r -> {
|
||||
r.bottom().left();
|
||||
r.touchable = Touchable.enabled;
|
||||
r.addListener(new InputListener(){
|
||||
float lastX, lastY;
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button) {
|
||||
Vec2 v = r.localToStageCoordinates(Tmp.v1.set(x, y));
|
||||
lastX = v.x;
|
||||
lastY = v.y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchDragged(InputEvent event, float x, float y, int pointer) {
|
||||
Vec2 v = r.localToStageCoordinates(Tmp.v1.set(x, y));
|
||||
float w = v.x - lastX;
|
||||
float h = v.y - lastY;
|
||||
|
||||
// will softlock if initial size is smaller than minimum
|
||||
// so don't do that!
|
||||
if(getWidth() + w < 160f || (getWidth() + w > maxWindowWidth && maxWidthEnabled)) w = 0;
|
||||
if(getHeight() - h < 160f || (getHeight() - h > maxWindowHeight && maxHeightEnabled)) h = 0;
|
||||
sizeBy(w, -h);
|
||||
moveBy(0, h);
|
||||
lastX = v.x;
|
||||
lastY = v.y;
|
||||
}
|
||||
});
|
||||
}).size(20f).left();
|
||||
}).height(20f).growX();
|
||||
}
|
||||
|
||||
public void setMaxWindowWidth(float maxWindowWidth){
|
||||
this.maxWindowWidth = maxWindowWidth;
|
||||
maxWidthEnabled = true;
|
||||
}
|
||||
|
||||
public void setMaxWindowHeight(float maxWindowHeight){
|
||||
this.maxWindowHeight = maxWindowHeight;
|
||||
maxHeightEnabled = true;
|
||||
}
|
||||
}
|
||||
7
src/UnitInfo/ui/windows/WindowTables.java
Normal file
7
src/UnitInfo/ui/windows/WindowTables.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package UnitInfo.ui.windows;
|
||||
|
||||
import UnitInfo.ui.UnitDisplay;
|
||||
|
||||
public class WindowTables {
|
||||
public static WindowTable unitTable = new UnitDisplay();
|
||||
}
|
||||
Reference in New Issue
Block a user