From f336cb82e5e6f29d931998d1c4317f7d6aa7be99 Mon Sep 17 00:00:00 2001 From: Sharlotte <60801210+Sharlottes@users.noreply.github.com> Date: Thu, 15 Sep 2022 00:12:27 +0900 Subject: [PATCH] refactoring, add weapon ui --- assets/mod.json | 2 +- src/informatis/ui/window/UnitWindow.java | 324 ++++++++++------------- 2 files changed, 141 insertions(+), 185 deletions(-) diff --git a/assets/mod.json b/assets/mod.json index 9b92ee6..e01470d 100644 --- a/assets/mod.json +++ b/assets/mod.json @@ -5,7 +5,7 @@ "description": "The mod displays more information in-game, such as unit/building, wave, core, tile, item/unit total info etc", "version": "1.6", "main": "informatis.core.Main", - "minGameVersion": "137", + "minGameVersion": "138", "dependencies": [], "hidden": true, "java": true diff --git a/src/informatis/ui/window/UnitWindow.java b/src/informatis/ui/window/UnitWindow.java index 7a18910..2010dbc 100644 --- a/src/informatis/ui/window/UnitWindow.java +++ b/src/informatis/ui/window/UnitWindow.java @@ -1,7 +1,6 @@ package informatis.ui.window; import arc.*; -import arc.func.*; import arc.math.*; import arc.scene.*; import informatis.core.*; @@ -24,6 +23,8 @@ import mindustry.ui.*; import mindustry.world.blocks.*; import mindustry.world.blocks.payloads.*; +import java.util.Objects; + import static informatis.SVars.*; import static informatis.SUtils.*; import static mindustry.Vars.*; @@ -32,166 +33,57 @@ public class UnitWindow extends Window { int barSize = 6; float usedPayload; float barScrollPos; + float lastWidth; final Seq lastColors = new Seq<>(); final Bits statuses = new Bits(); - Teamc latestTarget; - ScrollPane barPane; + Teamc lastTarget; - public UnitWindow() { - super(Icon.units, "unit"); - } + public UnitWindow() { super(Icon.units, "unit"); } - //TODO: add weapons @Override protected void build(Table table) { - table.top().background(Styles.black8); - table.table(profile -> { - profile.table(title -> { - title.center(); - Image image = RectWidget.build(); - image.update(()->{ - TextureRegion region = clear; - if (target instanceof Unit u && u.type != null) region = u.type.uiIcon; - else if (target instanceof Building b) { - if (b instanceof ConstructBlock.ConstructBuild cb) region = cb.current.uiIcon; - else if (b.block != null) region = b.block.uiIcon; - } - image.setDrawable(region); - }); - image.clicked(()->{ - if(target == getTarget()) locked = !locked; - target = getTarget(); - }); - title.add(image).size(iconMed).padRight(12f); - Label label = title.label(() -> { - if (target instanceof Unit u && u.type != null) return u.type.localizedName; - if (target instanceof Building b && b.block != null) { - if (target instanceof ConstructBlock.ConstructBuild cb) return cb.current.localizedName; - return b.block.localizedName; - } - return ""; - }).color(Pal.accent).get(); - label.clicked(() -> moveCamera(target)); - }).tooltip(tool -> { - tool.table(Styles.black6, to -> { - to.label(() -> target instanceof Unit u ? u.isPlayer() ? u.getPlayer().name : "AI" : "").visible(target instanceof Unit).row(); - to.label(() -> target.tileX() + ", " + target.tileY()).row(); - to.label(() -> target instanceof Unit u ? "[accent]"+ Strings.fixed(u.armor, 0) + "[] Armor" : "").visible(target instanceof Unit); - }); - }); - profile.table(weapon -> { - weapon.add(new WeaponDisplay()); - }); - }).margin(12f).row(); - table.image().color((target == null ? player.unit() : target).team().color).visible(()-> { - if(target instanceof Payloadc payload) return payload.payloads().size > 0; - if(target instanceof Statusc status) { - Bits applied = status.statusBits(); - return applied == null || Vars.content.statusEffects().contains(effect -> applied.get(effect.id) && !effect.isHidden()); + Image profileImage = RectWidget.build(); + profileImage.update(() -> { + TextureRegion region = clear; + if (target instanceof Unit u && u.type != null) region = u.type.uiIcon; + else if (target instanceof Building b) { + if (b instanceof ConstructBlock.ConstructBuild cb) region = cb.current.uiIcon; + else if (b.block != null) region = b.block.uiIcon; } - return false; - }).height(4f).growX().row(); + profileImage.setDrawable(region); + }); + profileImage.clicked(() -> { + if (target == getTarget()) locked = !locked; + target = getTarget(); + }); + Label profileLabel = new Label(() -> { + if (target instanceof Unit u && u.type != null) return u.type.localizedName; + if (target instanceof Building b && b.block != null) { + if (target instanceof ConstructBlock.ConstructBuild cb) return cb.current.localizedName; + return b.block.localizedName; + } + return ""; + }); + profileLabel.clicked(() -> moveCamera(target)); - table.table(state -> { - state.left(); - final Cons rebuildPayload = t -> { - t.left(); - if (target instanceof Payloadc payloader) { - Seq payloads = payloader.payloads(); - for (int i = 0, m = payloader.payloads().size; i < m; i++) { - Payload payload = payloads.get(i); - Image image = new Image(payload.icon()); - image.clicked(()->ui.content.show(payload.content())); - image.hovered(()->image.setColor(Tmp.c1.set(image.color).lerp(Color.lightGray, Mathf.clamp(Time.delta)))); - image.exited(()->image.setColor(Tmp.c1.set(image.color).lerp(Color.white, Mathf.clamp(Time.delta)))); - t.add(image).size(iconSmall).tooltip(l -> l.label(() -> payload.content().localizedName).style(Styles.outlineLabel)); - if ((i + 1) % Math.max(6, Math.round((window.getWidth() - 24) / iconSmall)) == 0) t.row(); - } - } - }; - - final Cons
rebuildStatus = t -> { - t.top().left(); - if (target instanceof Statusc st) { - Bits applied = st.statusBits(); - if (applied == null) return; - Seq contents = Vars.content.statusEffects(); - for (int i = 0, m = Vars.content.statusEffects().size; i < m; i++) { - StatusEffect effect = contents.get(i); - if (applied.get(effect.id) && !effect.isHidden()) { - Image image = new Image(effect.uiIcon); - image.clicked(()->ui.content.show(effect)); - image.hovered(()->image.setColor(Tmp.c1.set(image.color).lerp(Color.lightGray, Mathf.clamp(Time.delta)))); - image.exited(()->image.setColor(Tmp.c1.set(image.color).lerp(Color.white, Mathf.clamp(Time.delta)))); - t.add(image).size(iconSmall).tooltip(l -> l.label(() -> effect.localizedName + " [lightgray]" + UI.formatTime(st.getDuration(effect))).style(Styles.outlineLabel)); - if (i + 1 % Math.max(6, Math.round((window.getWidth() - 24) / iconSmall)) == 0) t.row(); - } - } - } - }; - - final float[] lastWidth1 = {0}; - state.table(rebuildPayload).update(t -> { - t.left(); - if (lastWidth1[0] != window.getWidth()) { - lastWidth1[0] = window.getWidth(); - t.clear(); - rebuildPayload.get(t); - } else if (target instanceof Payloadc payload) { - if (usedPayload != payload.payloadUsed()) { - usedPayload = payload.payloadUsed(); - t.clear(); - rebuildPayload.get(t); - } - } else { - usedPayload = -1; - t.clear(); - rebuildPayload.get(t); - } - }).grow().row(); - - final float[] lastWidth2 = {0}; - state.table(rebuildStatus).update(t -> { - t.left(); - if (lastWidth2[0] != window.getWidth()) { - lastWidth2[0] = window.getWidth(); - t.clear(); - rebuildStatus.get(t); - } else if (target instanceof Statusc st) { - Bits applied = st.statusBits(); - if (applied != null && !statuses.equals(applied)) { - statuses.set(applied); - t.clear(); - rebuildStatus.get(t); - } - } else { - statuses.clear(); - t.clear(); - rebuildStatus.get(t); - } - }).grow(); - }).minHeight(0).growX().row(); - - table.image().color((target == null ? player.unit() : target).team().color).height(4f).growX().row(); - - barPane = new ScrollPane(buildBarList(), Styles.noBarPane); + ScrollPane barPane = new ScrollPane(buildBarList(), Styles.noBarPane); barPane.update(() -> { - //rebuild whole bar table - if(latestTarget != target) { + if (lastTarget != target) { + lastTarget = target; for (int i = 0; i < barSize; i++) { Color color = i >= BarInfo.data.size ? Color.clear : BarInfo.data.get(i).color; if (i >= lastColors.size) lastColors.add(color); else lastColors.set(i, color); } - - if(((Table) barPane.getWidget()).getChildren().size-1 != barSize) { - latestTarget = target; - barPane.setWidget(buildBarList()); - } } - if(barPane.hasScroll()){ + + if (((Table) barPane.getWidget()).getChildren().size - 1 != barSize) { + barPane.setWidget(buildBarList()); + } + + if (barPane.hasScroll()) { Element result = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); - if(result == null || !result.isDescendantOf(barPane)){ + if (result == null || !result.isDescendantOf(barPane)) { Core.scene.setScrollFocus(null); } } @@ -200,11 +92,113 @@ public class UnitWindow extends Window { barPane.setScrollingDisabledX(true); barPane.setScrollYForce(barScrollPos); + table.top().background(Styles.black8); + table.table(profile -> profile + .table(title -> { + title.center(); + title.add(profileImage).size(iconMed); + title.add(profileLabel).padLeft(12f).padRight(12f).color(Pal.accent); + }) + .tooltip(tool -> { + tool.background(Styles.black6); + tool.label(() -> target instanceof Unit u ? u.isPlayer() ? u.getPlayer().name : "AI" : "").visible(target instanceof Unit).row(); + tool.label(() -> target.tileX() + ", " + target.tileY()).row(); + tool.label(() -> target instanceof Unit u ? "[accent]"+ Strings.fixed(u.armor, 0) + "[] Armor" : "").visible(target instanceof Unit); + }).get() + ).margin(3f).growX().row(); + table.table().update(tt -> { + tt.clear(); + if(getTarget() instanceof Unit u && u.type != null && u.hasWeapons()) { + for(int r = 0; r < u.type.weapons.size; r++){ + Weapon weapon = u.type.weapons.get(r); + WeaponMount mount = u.mounts[r]; + tt.table(ttt -> { + ttt.left(); + ttt.stack( + new Table(o -> { + o.left(); + o.add(new Image(Core.atlas.isFound(weapon.region) ? weapon.region : u.type.uiIcon){ + @Override + public void draw(){ + y -= (mount.reload) / weapon.reload * weapon.recoil; + super.draw(); + } + }).size(iconLarge).scaling(Scaling.bounded); + }), + new Table(h -> { + h.defaults().growX().height(9f).width(iconLarge).padTop(18f); + h.add(new SBar( + () -> "", + () -> Pal.accent.cpy().lerp(Color.orange, mount.reload / weapon.reload), + () -> mount.reload / weapon.reload).rect().init()); + h.pack(); + }) + ); + }).pad(4); + if((r + 1) % 4 == 0) tt.row(); + } + } + }).margin(4f).growX().row(); + table.table(state -> { + state.left(); + state.table().update(t -> { + if (!(target instanceof Payloadc payloader)) { + t.clear(); + usedPayload = -1; + return; + } + + if(usedPayload == payloader.payloadUsed() && lastWidth == window.getWidth()) return; + if(usedPayload != payloader.payloadUsed()) usedPayload = payloader.payloadUsed(); + if(lastWidth != window.getWidth()) lastWidth = window.getWidth(); + + t.clear(); + t.top().left(); + Seq payloads = payloader.payloads(); + for (int i = 0, m = payloads.size; i < m; i++) { + Payload payload = payloads.get(i); + Image image = new Image(payload.icon()); + image.clicked(() -> ui.content.show(payload.content())); + image.hovered(() -> image.setColor(Tmp.c1.set(image.color).lerp(Color.lightGray, Mathf.clamp(Time.delta)))); + image.exited(() -> image.setColor(Tmp.c1.set(image.color).lerp(Color.white, Mathf.clamp(Time.delta)))); + t.add(image).size(iconSmall).tooltip(l -> l.label(() -> payload.content().localizedName).style(Styles.outlineLabel)); + if ((i + 1) % Math.max(6, Math.round((window.getWidth() - 24) / iconSmall)) == 0) t.row(); + } + }); + + state.table().update(t -> { + if (!(target instanceof Statusc st)) { + t.clear(); + statuses.clear(); + return; + } + Bits applied = st.statusBits(); + + if((applied == null || statuses.equals(st.statusBits())) && lastWidth == window.getWidth()) return; + if(!statuses.equals(st.statusBits())) statuses.set(applied); + if(lastWidth != window.getWidth()) lastWidth = window.getWidth(); + + t.clear(); + t.top().left(); + Seq contents = Vars.content.statusEffects(); + for (int i = 0, m = Vars.content.statusEffects().size; i < m; i++) { + StatusEffect effect = contents.get(i); + if (Objects.requireNonNull(applied).get(effect.id) && !effect.isHidden()) { + Image image = new Image(effect.uiIcon); + image.clicked(() -> ui.content.show(effect)); + image.hovered(() -> image.setColor(Tmp.c1.set(image.color).lerp(Color.lightGray, Mathf.clamp(Time.delta)))); + image.exited(() -> image.setColor(Tmp.c1.set(image.color).lerp(Color.white, Mathf.clamp(Time.delta)))); + t.add(image).size(iconSmall).tooltip(l -> l.label(() -> effect.localizedName + " [lightgray]" + UI.formatTime(st.getDuration(effect))).style(Styles.outlineLabel)); + if (i + 1 % Math.max(6, Math.round((window.getWidth() - 24) / iconSmall)) == 0) t.row(); + } + } + }); + }).growX().row(); + table.image().color((target == null ? player.unit() : target).team().color).height(4f).growX().row(); table.add(barPane).grow().padTop(12f); } boolean show; - Teamc targetCache; Table buildBarList() { show = false; return new Table(table -> { @@ -252,42 +246,4 @@ public class UnitWindow extends Window { bar.add(icon).size(iconMed * 0.75f).padLeft(8f); }); } - - static class WeaponDisplay extends Table { - WeaponDisplay() { - table().update(tt -> { - tt.clear(); - if(getTarget() instanceof Unit u && u.type != null && u.hasWeapons()) { - for(int r = 0; r < u.type.weapons.size; r++){ - Weapon weapon = u.type.weapons.get(r); - WeaponMount mount = u.mounts[r]; - tt.table(ttt -> { - ttt.left(); - ttt.stack( - new Table(o -> { - o.left(); - o.add(new Image(weapon.region){ - @Override - public void draw(){ - y -= (mount.reload) / weapon.reload * weapon.recoil; - super.draw(); - } - }).size(iconLarge).scaling(Scaling.bounded); - }), - new Table(h -> { - h.defaults().growX().height(9f).width(iconLarge).padTop(18f); - h.add(new SBar( - () -> "", - () -> Pal.accent.cpy().lerp(Color.orange, mount.reload / weapon.reload), - () -> mount.reload / weapon.reload).rect().init()); - h.pack(); - }) - ); - }).pad(4); - if(r % 4 == 0) tt.row(); - } - } - }); - } - } }