From 32e1734db4a880b3abfd20602a950f13565642f7 Mon Sep 17 00:00:00 2001 From: sharlotte Date: Thu, 26 Aug 2021 16:35:02 +0900 Subject: [PATCH] size match yey --- src/UnitInfo/SVars.java | 1 - src/UnitInfo/core/BarInfo.java | 11 +- src/UnitInfo/core/HudUi.java | 341 ++++++++++++++---------------- src/UnitInfo/core/Main.java | 169 --------------- src/UnitInfo/core/OverDrawer.java | 186 +++++++++++++++- 5 files changed, 351 insertions(+), 357 deletions(-) diff --git a/src/UnitInfo/SVars.java b/src/UnitInfo/SVars.java index 20aeefe..7a780cb 100644 --- a/src/UnitInfo/SVars.java +++ b/src/UnitInfo/SVars.java @@ -20,7 +20,6 @@ public class SVars { public static HudUi hud = new HudUi(); public static float modUiScale = settings.getInt("infoUiScale") / 100f == 0 ? 1 : settings.getInt("infoUiScale") / 100f; public static boolean pathLine = false, unitLine = false, logicLine = false; - public static Seq pathTiles = new Seq<>(); public static TextureRegion clear = atlas.find("clear"); public static TextureRegion error = atlas.find("error"); } diff --git a/src/UnitInfo/core/BarInfo.java b/src/UnitInfo/core/BarInfo.java index 174fe96..40ed90e 100644 --- a/src/UnitInfo/core/BarInfo.java +++ b/src/UnitInfo/core/BarInfo.java @@ -1,13 +1,10 @@ package UnitInfo.core; -import UnitInfo.*; -import arc.*; import arc.graphics.*; import arc.math.*; import arc.struct.*; import arc.util.*; import mindustry.ai.types.*; -import mindustry.core.*; import mindustry.ctype.*; import mindustry.entities.*; import mindustry.entities.abilities.*; @@ -18,11 +15,9 @@ import mindustry.ui.*; import mindustry.world.blocks.*; import mindustry.world.blocks.defense.*; import mindustry.world.blocks.defense.turrets.*; -import mindustry.world.blocks.distribution.MassDriver; +import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.environment.*; -import mindustry.world.blocks.power.PowerGenerator; -import mindustry.world.blocks.power.PowerNode; -import mindustry.world.blocks.power.ThermalGenerator; +import mindustry.world.blocks.power.*; import mindustry.world.blocks.production.*; import mindustry.world.blocks.storage.*; import mindustry.world.blocks.units.*; @@ -244,7 +239,7 @@ public class BarInfo { } else if(target instanceof Building build){ if(target instanceof PowerNode.PowerNodeBuild node){ - strings.set(4, bundle.format("shar-stat.powerOut", floatFormat(node.power.graph.getLastScaledPowerOut() * 60f))); + strings.set(4, bundle.format("shar-stat.powerOut", "-" + floatFormat(node.power.graph.getLastScaledPowerOut() * 60f))); colors.set(4, Pal.powerBar); numbers.set(4, node.power.graph.getLastScaledPowerOut() / node.power.graph.getLastScaledPowerIn()); } diff --git a/src/UnitInfo/core/HudUi.java b/src/UnitInfo/core/HudUi.java index f921859..ad9c739 100644 --- a/src/UnitInfo/core/HudUi.java +++ b/src/UnitInfo/core/HudUi.java @@ -1,6 +1,5 @@ package UnitInfo.core; -import UnitInfo.SVars; import UnitInfo.ui.*; import arc.*; import arc.graphics.*; @@ -17,39 +16,25 @@ import arc.scene.utils.*; import arc.struct.*; import arc.util.*; import mindustry.*; -import mindustry.ai.Astar; import mindustry.content.*; import mindustry.core.*; -import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.input.*; -import mindustry.logic.*; -import mindustry.maps.SectorDamage; import mindustry.type.*; -import mindustry.type.ammo.*; import mindustry.ui.*; import mindustry.world.*; import mindustry.world.blocks.*; -import mindustry.world.blocks.defense.ForceProjector; -import mindustry.world.blocks.defense.MendProjector; -import mindustry.world.blocks.defense.OverdriveProjector; +import mindustry.world.blocks.defense.*; import mindustry.world.blocks.defense.turrets.*; -import mindustry.world.blocks.distribution.MassDriver; -import mindustry.world.blocks.payloads.Payload; -import mindustry.world.blocks.payloads.PayloadMassDriver; -import mindustry.world.blocks.power.PowerGenerator; -import mindustry.world.blocks.power.PowerNode; -import mindustry.world.blocks.power.ThermalGenerator; -import mindustry.world.blocks.production.AttributeCrafter; -import mindustry.world.blocks.production.Drill; -import mindustry.world.blocks.production.GenericCrafter; -import mindustry.world.blocks.production.SolidPump; -import mindustry.world.blocks.storage.CoreBlock; -import mindustry.world.blocks.units.Reconstructor; -import mindustry.world.blocks.units.UnitFactory; +import mindustry.world.blocks.distribution.*; +import mindustry.world.blocks.payloads.*; +import mindustry.world.blocks.power.*; +import mindustry.world.blocks.production.*; +import mindustry.world.blocks.storage.*; +import mindustry.world.blocks.units.*; import static UnitInfo.SVars.*; import static arc.Core.*; @@ -286,7 +271,7 @@ public class HudUi { fontColor = Color.white; background = Styles.black8; }}); - label.setFontScale(modUiScale); + label.setFontScale(Scl.scl(modUiScale)); Table labelTable = new Table(t -> t.add(label).left().padRight(Scl.scl(modUiScale) * 40 * 8f)); table.table(t -> { @@ -584,9 +569,9 @@ public class HudUi { if(getTarget() instanceof ConstructBlock.ConstructBuild cb) name = cb.current.localizedName; else name = b.block.localizedName; } - return "[accent]" + (name.length() > 9 ? name.substring(0, 9) + "..." : name) + "[]"; + return "[accent]" + (name.length() > 12 ? name.substring(0, 12) + "..." : name) + "[]"; }); - label.setFontScale(modUiScale); + label.setFontScale(Scl.scl(modUiScale)); TextButton button = Elem.newButton("?", Styles.clearPartialt, () -> { if(getTarget() instanceof Unit u && u.type != null) @@ -629,12 +614,12 @@ public class HudUi { else if(getTarget() instanceof Building b) return b.block.localizedName; return ""; }); - label2.setFontScale(modUiScale); + label2.setFontScale(Scl.scl(modUiScale)); tool2.add(label2); }); to.row(); Label label2 = new Label(()->getTarget() == null ? "(" + 0 + ", " + 0 + ")" : "(" + Strings.fixed(getTarget().x() / tilesize, 2) + ", " + Strings.fixed(getTarget().y() / tilesize, 2) + ")"); - label2.setFontScale(modUiScale); + label2.setFontScale(Scl.scl(modUiScale)); to.add(label2); }))); tt.update(() -> { @@ -659,7 +644,7 @@ public class HudUi { t.setBackground(patch.tint(Tmp.c1.set(patch.getPatch().getColor()).a(settings.getInt("uiopacity") / 100f))); }); }); - table.table(t -> t.stack(table1, addInfoTable(t))).padLeft(3.5f * 8f); + table.table(t -> t.stack(table1, addInfoTable(t))).padLeft(3f * 8f); table.update(() -> { if(!Core.settings.getBool("infoui")) return; @@ -678,145 +663,148 @@ public class HudUi { } public void setWave(Table table){ + table.defaults().minWidth(Scl.scl(modUiScale) * 46 * 8f); int winWave = state.isCampaign() && state.rules.winWave > 0 ? state.rules.winWave : Integer.MAX_VALUE; waveamount = settings.getInt("wavemax"); for(int i = settings.getBool("pastwave") ? 0 : state.wave - 1; i <= Math.min(state.wave + waveamount, winWave - 2); i++){ final int j = i; if(!settings.getBool("emptywave") && state.rules.spawns.find(g -> g.getSpawned(j) > 0) == null) continue; - table.table(t -> { - table.center(); - Label label = new Label(() -> "[#" + (state.wave == j+1 ? Color.red.toString() : Pal.accent.toString()) + "]" + (j+1) + "[]"); - label.setFontScale(modUiScale); - t.add(label); - }).size(Scl.scl(modUiScale) * 4 * 8f); - - table.table(Tex.underline, tx -> { - if(settings.getBool("emptywave") && state.rules.spawns.find(g -> g.getSpawned(j) > 0) == null) { - tx.center(); - Label label = new Label("[lightgray][]"); - label.setFontScale(modUiScale); - tx.add(label); - return; - } - - ObjectIntMap 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 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); + table.table(table1 -> { + table1.left(); + table1.table(t -> { + Label label = new Label(() -> "[#" + (state.wave == j+1 ? Color.red.toString() : Pal.accent.toString()) + "]" + (j+1) + "[]"); + label.setFontScale(Scl.scl(modUiScale)); + t.add(label); }); - ObjectIntMap groupsTmp = new ObjectIntMap<>(); - groupSorted.each(g -> groupsTmp.put(g, groups.get(g))); + table1.table(Tex.underline, tx -> { + tx.defaults().marginRight(2 * 8f); + tx.fillParent = true; + if(settings.getBool("emptywave") && state.rules.spawns.find(g -> g.getSpawned(j) > 0) == null) { + tx.center(); + Label label = new Label("[lightgray][]"); + label.setFontScale(Scl.scl(modUiScale)); + tx.add(label); + return; + } - int row = 0; - for(SpawnGroup group : groupsTmp.keys()){ - int amount = groupsTmp.get(group); - tx.table(tt -> { - tt.right(); - 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(); - }), + ObjectIntMap 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 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 groupsTmp = new ObjectIntMap<>(); + groupSorted.each(g -> groupsTmp.put(g, groups.get(g))); - new Table(ttt -> { - ttt.bottom().left(); - Label label = new Label(() -> amount + ""); - label.setFontScale(Scl.scl(modUiScale) * 0.85f); - ttt.add(label); - ttt.pack(); - }), + int row = 0; + for(SpawnGroup group : groupsTmp.keys()){ + int amount = groupsTmp.get(group); + tx.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.top().right(); - Image image1 = new Image(Icon.warning.getRegion()).setScaling(Scaling.fit); - image1.update(() -> { - if(!Core.settings.getBool("infoui")) return; - 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 listener1 = new HandCursorListener(); - tt.addListener(listener1); - tt.update(() -> { - if(!Core.settings.getBool("infoui")) return; - image.color.lerp(!listener1.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)); - }); - } - tt.addListener(new Tooltip(t -> t.background(Tex.button).table(to -> { - to.left(); - to.table(Tex.underline2, tot -> tot.add("[stat]" + group.type.localizedName + "[]")).row(); - to.add(bundle.format("shar-stat-waveAmount", amount)).row(); - to.add(bundle.format("shar-stat-waveShield", group.getShield(j))).row(); - if(group.effect != null) { - if(group.effect == StatusEffects.none) return; - Image status = new Image(group.effect.uiIcon).setScaling(Scaling.fit); - if(group.effect == StatusEffects.boss){ - status = new Image(Icon.warning.getRegion()).setScaling(Scaling.fit); - Image finalStatus = status; - status.update(() -> { + new Table(ttt -> { + ttt.bottom().left(); + Label label = new Label(() -> amount + ""); + label.setFontScale(Scl.scl(modUiScale) * 0.85f); + ttt.add(label); + ttt.pack(); + }), + + new Table(ttt -> { + ttt.top().right(); + Image image1 = new Image(Icon.warning.getRegion()).setScaling(Scaling.fit); + image1.update(() -> { if(!Core.settings.getBool("infoui")) return; - finalStatus.setColor(Tmp.c2.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f))); + 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); } - Image finalStatus = status; - to.table(tot -> { - tot.left(); - tot.add(bundle.get("shar-stat.waveStatus")); - tot.add(finalStatus).size(Scl.scl(modUiScale) * 3 * 8f); - if(!mobile){ - HandCursorListener listener = new HandCursorListener(); - finalStatus.addListener(listener); - finalStatus.update(() -> { + }); + if(!mobile){ + HandCursorListener listener1 = new HandCursorListener(); + tt.addListener(listener1); + tt.update(() -> { + if(!Core.settings.getBool("infoui")) return; + image.color.lerp(!listener1.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)); + }); + } + tt.addListener(new Tooltip(t -> t.background(Tex.button).table(to -> { + to.left(); + to.table(Tex.underline2, tot -> tot.add("[stat]" + group.type.localizedName + "[]")).row(); + to.add(bundle.format("shar-stat-waveAmount", amount)).row(); + to.add(bundle.format("shar-stat-waveShield", group.getShield(j))).row(); + if(group.effect != null) { + if(group.effect == StatusEffects.none) return; + Image status = new Image(group.effect.uiIcon).setScaling(Scaling.fit); + if(group.effect == StatusEffects.boss){ + status = new Image(Icon.warning.getRegion()).setScaling(Scaling.fit); + Image finalStatus = status; + status.update(() -> { if(!Core.settings.getBool("infoui")) return; - finalStatus.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)); + finalStatus.setColor(Tmp.c2.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f))); }); } - tot.add("[stat]" + group.effect.localizedName); - }).size(iconMed * Scl.scl(modUiScale)); - to.row(); - } - if(group.items != null) { - to.table(tot -> { - tot.left(); - ItemStack stack = group.items; - tot.add(bundle.get("shar-stat.waveItem")); - tot.add(new ItemImage(stack)).size(Scl.scl(modUiScale) * 3 * 8f); - if(!mobile){ - HandCursorListener listener = new HandCursorListener(); - tot.addListener(listener); - tot.update(() -> tot.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta))); - } - tot.add("[stat]" + stack.item.localizedName); - }).size(iconMed * Scl.scl(modUiScale)); - to.row(); - } - }))); - }); - if(++row % 4 == 0) tx.row(); - } + Image finalStatus = status; + to.table(tot -> { + tot.left(); + tot.add(bundle.get("shar-stat.waveStatus")); + tot.add(finalStatus).size(Scl.scl(modUiScale) * 3 * 8f); + if(!mobile){ + HandCursorListener listener = new HandCursorListener(); + finalStatus.addListener(listener); + finalStatus.update(() -> { + if(!Core.settings.getBool("infoui")) return; + finalStatus.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta)); + }); + } + tot.add("[stat]" + group.effect.localizedName); + }).size(iconMed * Scl.scl(modUiScale)); + to.row(); + } + if(group.items != null) { + to.table(tot -> { + tot.left(); + ItemStack stack = group.items; + tot.add(bundle.get("shar-stat.waveItem")); + tot.add(new ItemImage(stack)).size(Scl.scl(modUiScale) * 3 * 8f); + if(!mobile){ + HandCursorListener listener = new HandCursorListener(); + tot.addListener(listener); + tot.update(() -> tot.color.lerp(!listener.isOver() ? Color.lightGray : Color.white, Mathf.clamp(0.4f * Time.delta))); + } + tot.add("[stat]" + stack.item.localizedName); + }).size(iconMed * Scl.scl(modUiScale)); + to.row(); + } + }))); + }); + if(++row % 8 == 0) tx.row(); + } + }); }); table.row(); } @@ -824,31 +812,29 @@ public class HudUi { public void addWaveTable(){ if(uiIndex != 1) return; - ScrollPane wavePane = new ScrollPane(new Image(clear).setScaling(Scaling.fit), new ScrollPane.ScrollPaneStyle(){{ - vScroll = Tex.clear; - vScrollKnob = new ScaledNinePatchDrawable(new NinePatch(((TextureRegionDrawable) scrollKnobVerticalThin).getRegion()), modUiScale); - }}); - wavePane.setScrollingDisabled(true, false); - wavePane.setScrollYForce(waveScrollPos); - wavePane.update(() -> { - if(!Core.settings.getBool("infoui")) return; - if(wavePane.hasScroll()){ - Element result = scene.hit(input.mouseX(), input.mouseY(), true); - if(result == null || !result.isDescendantOf(wavePane)){ - scene.setScrollFocus(null); - } - } - waveScrollPos = wavePane.getScrollY(); - if(waveamount != settings.getInt("wavemax")) - wavePane.setWidget(new Table(tx -> tx.table(this::setWave).left())); - }); - wavePane.setOverscroll(false, false); - wavePane.setWidget(new Table(tx -> tx.table(this::setWave).left())); - waveTable = new Table(table -> { - table.left().defaults().width(Scl.scl(modUiScale) * 35 * 8f).maxHeight(Scl.scl(modUiScale) * 32 * 8f).align(Align.left); + table.defaults().width(Scl.scl(modUiScale) * 54 * 8f).height(unitTable.getHeight()); table.add(new Table(Tex.button, t -> { - t.add(wavePane); + ScrollPane pane = t.pane(new ScrollPane.ScrollPaneStyle(){{ + vScroll = Tex.clear; + vScrollKnob = new ScaledNinePatchDrawable(new NinePatch(((TextureRegionDrawable) scrollKnobVerticalThin).getRegion()), modUiScale); + }}, new Table(this::setWave)).get(); + pane.update(() -> { + if(!Core.settings.getBool("infoui")) return; + if(pane.hasScroll()){ + Element result = scene.hit(input.mouseX(), input.mouseY(), true); + if(result == null || !result.isDescendantOf(pane)){ + scene.setScrollFocus(null); + } + } + waveScrollPos = pane.getScrollY(); + if(waveamount != settings.getInt("wavemax")) + pane.setWidget(new Table(this::setWave)); + }); + pane.setOverscroll(false, false); + pane.setScrollingDisabled(true, false); + pane.setScrollYForce(waveScrollPos); + t.update(() -> { NinePatchDrawable patch = (NinePatchDrawable)Tex.button; t.setBackground(patch.tint(Tmp.c1.set(patch.getPatch().getColor()).a(settings.getInt("uiopacity") / 100f))); @@ -861,14 +847,13 @@ public class HudUi { } public void setItem(Table table){ - table.left().defaults().minWidth(Scl.scl(modUiScale) * 54 * 8f).align(Align.center); table.table().update(t -> { t.clear(); for(int i = 0; i < coreItems.tables.size; i++){ if((state.rules.pvp && coreItems.teams[i] != player.team()) || coreItems.teams[i].cores().isEmpty()) continue; int finalI = i; t.table(tt -> { - tt.center().defaults().minWidth(Scl.scl(modUiScale) * 54 * 8f); + tt.center().defaults().width(Scl.scl(modUiScale) * 46 * 8f); coreItems.tables.get(finalI).setBackground(((NinePatchDrawable)Tex.underline2).tint(coreItems.teams[finalI].color)); tt.add(coreItems.tables.get(finalI)).left(); }).pad(4); @@ -880,7 +865,7 @@ public class HudUi { public void addItemTable(){ if(uiIndex != 2) return; itemTable = new Table(table -> { - table.left().defaults().minWidth(Scl.scl(modUiScale) * 54 * 8f).height(Scl.scl(modUiScale) * 32 * 8f).align(Align.left); + table.left().defaults().width(Scl.scl(modUiScale) * 54 * 8f).height(unitTable.getHeight()); table.table(Tex.button, t -> { ScrollPane pane = t.pane(new ScrollPane.ScrollPaneStyle(){{ vScroll = Tex.clear; diff --git a/src/UnitInfo/core/Main.java b/src/UnitInfo/core/Main.java index d733e5f..8875202 100644 --- a/src/UnitInfo/core/Main.java +++ b/src/UnitInfo/core/Main.java @@ -31,18 +31,6 @@ import static arc.Core.*; import static mindustry.Vars.*; public class Main extends Mod { - int otherCores; - - public Tile getNextTile(Tile tile, int cost, Team team, int finder) { - Pathfinder.Flowfield field = pathfinder.getField(team, cost, Mathf.clamp(finder, 0, 1)); - Tile tile1 = pathfinder.getTargetTile(tile, field); - pathTiles.add(tile1); - if(tile1 == tile || tile1 == null || - (finder == 0 && (otherCores != Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != team) || tile1.build instanceof CoreBlock.CoreBuild)) || - (finder == 1 && tile1.build instanceof CommandCenter.CommandBuild)) //so many ififififififif. - return tile1; - return getNextTile(tile1, cost, team, finder); - } @Override public void init(){ @@ -74,162 +62,5 @@ public class Main extends Mod { hud = new HudUi(); hud.addWaveTable(); }); - - Events.run(Trigger.draw, () -> { - int[] units = {0}; - if(pathLine || unitLine || logicLine) Groups.unit.each(u -> { - Team team = u.team; - UnitController c = u.controller(); - UnitCommand com = team.data().command; - - if(c instanceof LogicAI ai){ - if(logicLine && (ai.control == LUnitControl.approach || ai.control == LUnitControl.move)) { - Lines.stroke(1, team.color); - Lines.line(u.x(), u.y(), ai.moveX, ai.moveY); - Lines.stroke(0.5f + Mathf.absin(6f, 0.5f), Tmp.c1.set(Pal.logicOperations).lerp(Pal.sap, Mathf.absin(6f, 0.5f))); - Lines.line(u.x(), u.y(), ai.controller.x, ai.controller.y); - } - return; - } - - if(++units[0] > settings.getInt("unitlinelimit") || //prevent lag - !unitLine || //disabled - u.type.flying || //not flying - c instanceof MinerAI || //not mono - c instanceof BuilderAI || //not poly - c instanceof RepairAI || //not mega - c instanceof DefenderAI || //not oct - c instanceof FormationAI || //not commanded unit by player - c instanceof FlyingAI || //not flying anyway - com == UnitCommand.idle) return; //not idle - - otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != team); - getNextTile(u.tileOn(), u.pathType(), team, com.ordinal()); - pathTiles.filter(Objects::nonNull); - for(int i = 1; i < pathTiles.size; i++) { - if(i + 1 >= pathTiles.size) continue; //prevent IndexOutException - Tile tile1 = pathTiles.get(i); - Tile tile2 = pathTiles.get(i + 1); - Draw.z(Layer.overlayUI); - Lines.stroke(1, team.color); - Lines.line(tile1.worldx(), tile1.worldy(), tile2.worldx(), tile2.worldy()); - } - pathTiles.clear(); - }); - - if(pathLine) spawner.getSpawns().each(t -> { - Team enemyTeam = state.rules.waveTeam; - for(int p = 0; p < 3; p++) { - otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != enemyTeam); - if(otherCores == 0) return; //must have target core - - getNextTile(t, p, enemyTeam, Pathfinder.fieldCore); - pathTiles.filter(Objects::nonNull); - for(int i = 1; i < pathTiles.size; i++) { - if(i + 1 >= pathTiles.size) continue; //prevent IndexOutException - Tile tile1 = pathTiles.get(i); - Tile tile2 = pathTiles.get(i + 1); - Draw.z(Layer.overlayUI); - Lines.stroke(1, enemyTeam.color); - Lines.line(tile1.worldx(), tile1.worldy(), tile2.worldx(), tile2.worldy()); - } - pathTiles.clear(); - } - }); - - if(settings.getBool("blockstatus")) Groups.build.each(build -> { - if(Vars.player != null && Vars.player.team() == build.team) return; - - Block block = build.block; - if(block.enableDrawStatus && block.consumes.any()){ - float multiplier = block.size > 1 ? 1 : 0.64f; - float brcx = build.x + (block.size * tilesize / 2f) - (tilesize * multiplier / 2f); - float brcy = build.y - (block.size * tilesize / 2f) + (tilesize * multiplier / 2f); - - Draw.z(Layer.power + 1); - Draw.color(Pal.gray); - Fill.square(brcx, brcy, 2.5f * multiplier, 45); - Draw.color(build.status().color); - Fill.square(brcx, brcy, 1.5f * multiplier, 45); - Draw.color(); - } - }); - - if(Core.settings.getBool("unithealthui")) - Groups.unit.each(unit -> new FreeBar().draw(unit)); - - if(!mobile && !Vars.state.isPaused() && settings.getBool("gaycursor")) - Fx.mine.at(Core.input.mouseWorldX(), Core.input.mouseWorldY(), Tmp.c2.set(Color.red).shiftHue(Time.time * 1.5f)); - - if(!renderer.pixelator.enabled()) Groups.unit.each(unit -> unit.item() != null && unit.itemTime > 0.01f, unit -> { - Fonts.outline.draw(unit.stack.amount + "", - unit.x + Angles.trnsx(unit.rotation + 180f, unit.type.itemOffsetY), - unit.y + Angles.trnsy(unit.rotation + 180f, unit.type.itemOffsetY) - 3, - Pal.accent, 0.25f * unit.itemTime / Scl.scl(1f), false, Align.center); - Draw.reset(); - }); - - // Turret Ranges - if(settings.getBool("rangeNearby") && player != null) { - Team team = player.team(); - Unit unit = player.unit(); - Groups.build.each(e -> { - if(!settings.getBool("allTeamRange") && e.team == team) return; // Don't draw own turrets - if(!(e instanceof BaseTurret.BaseTurretBuild)) return; // Not a turret - if((e instanceof Turret.TurretBuild t && !t.hasAmmo()) || !e.cons.valid()) return; // No ammo - - boolean canHit = e.block instanceof Turret t ? unit.isFlying() ? t.targetAir : t.targetGround : - e.block instanceof TractorBeamTurret tu && (unit.isFlying() ? tu.targetAir : tu.targetGround); - float range = ((BaseTurret.BaseTurretBuild) e).range(); - float max = range + settings.getInt("rangeRadius") * tilesize + e.block.offset; - float dst = Mathf.dst(control.input.getMouseX(), control.input.getMouseY(), e.x, e.y); - - if(control.input.block != null && dst <= max) canHit = e.block instanceof Turret t && t.targetGround; - if(player.dst(e) <= max || (control.input.block != null && dst <= max)) { - if(canHit || settings.getBool("allTargetRange")){ - if(settings.getBool("softRangeDrawing")){ - Lines.stroke(Scl.scl(), Tmp.c1.set(canHit ? e.team.color : Team.derelict.color).a(0.5f)); - Lines.poly(e.x, e.y, Lines.circleVertices(range), range); - Fill.light(e.x, e.y, Lines.circleVertices(range), range, Color.clear, Tmp.c1.a(Mathf.clamp(1-((control.input.block != null && dst <= max ? dst : player.dst(e))/max), 0, settings.getInt("softRangeOpacity")/100f))); - } - else Drawf.dashCircle(e.x, e.y, range, canHit ? e.team.color : Team.derelict.color); - } - } - }); - - // Unit Ranges (Only works when turret ranges are enabled) - if(settings.getBool("unitRange") || (settings.getBool("allTeamRange") && player.unit() != null)) { - Groups.unit.each(u -> { - if(!settings.getBool("unitRange") && settings.getBool("allTeamRange") && player.unit() != u) return; //player unit rule - if(!settings.getBool("allTeamRange") && u.team == team) return; // Don't draw own units - if(u.controller() instanceof AIController ai && (ai instanceof BuilderAI || ai instanceof MinerAI)) return; //don't draw poly and mono - boolean canHit = unit.isFlying() ? u.type.targetAir : u.type.targetGround; - float range = u.range(); - float max = range + settings.getInt("rangeRadius") * tilesize; - - if(Vars.player.dst(u) <= max) { - if (canHit || settings.getBool("allTargetRange")) // Same as above - if(settings.getBool("softRangeDrawing")){ - Lines.stroke(Scl.scl(), Tmp.c1.set(canHit ? u.team.color : Team.derelict.color).a(0.5f)); - Lines.poly(u.x, u.y, Lines.circleVertices(range), range); - Fill.light(u.x, u.y, Lines.circleVertices(range), range, Color.clear, Tmp.c1.a(Math.min(settings.getInt("softRangeOpacity")/100f, 1-Vars.player.dst(u)/max))); - } - else Drawf.dashCircle(u.x, u.y, range, canHit ? u.team.color : Team.derelict.color); - } - }); - } - } - - if(!state.rules.polygonCoreProtection && settings.getBool("coreRange") && player != null){ - state.teams.eachEnemyCore(player.team(), core -> { - if(Core.camera.bounds(Tmp.r1).overlaps(Tmp.r2.setCentered(core.x, core.y, state.rules.enemyCoreBuildRadius * 2f))){ - Draw.color(Color.darkGray); - Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius); - Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time, 10f, 0.5f)); - Lines.circle(core.x, core.y, state.rules.enemyCoreBuildRadius); - } - }); - } - }); } } diff --git a/src/UnitInfo/core/OverDrawer.java b/src/UnitInfo/core/OverDrawer.java index 1fe160f..173be26 100644 --- a/src/UnitInfo/core/OverDrawer.java +++ b/src/UnitInfo/core/OverDrawer.java @@ -1,27 +1,45 @@ package UnitInfo.core; +import UnitInfo.ui.FreeBar; import arc.*; import arc.graphics.Color; import arc.graphics.g2d.*; import arc.input.KeyCode; import arc.math.*; import arc.math.geom.Geometry; +import arc.scene.ui.layout.Scl; import arc.struct.Seq; import arc.util.*; +import mindustry.Vars; +import mindustry.ai.Pathfinder; +import mindustry.ai.types.*; +import mindustry.content.Fx; import mindustry.core.Renderer; import mindustry.entities.*; +import mindustry.entities.units.AIController; +import mindustry.entities.units.UnitCommand; +import mindustry.entities.units.UnitController; import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.logic.LUnitControl; import mindustry.logic.Ranged; import mindustry.ui.Fonts; +import mindustry.world.Block; +import mindustry.world.Tile; import mindustry.world.blocks.ControlBlock; +import mindustry.world.blocks.defense.turrets.BaseTurret; +import mindustry.world.blocks.defense.turrets.TractorBeamTurret; import mindustry.world.blocks.defense.turrets.Turret; import mindustry.world.blocks.distribution.MassDriver; import mindustry.world.blocks.payloads.PayloadMassDriver; import mindustry.world.blocks.power.PowerNode; +import mindustry.world.blocks.storage.CoreBlock; +import mindustry.world.blocks.units.CommandCenter; -import static UnitInfo.SVars.hud; +import java.util.Objects; + +import static UnitInfo.SVars.*; import static arc.Core.*; import static arc.Core.input; import static mindustry.Vars.*; @@ -32,6 +50,8 @@ public class OverDrawer { public static Seq linkedMasses = new Seq<>(); public static Seq linkedPayloadMasses = new Seq<>(); public static Seq linkedNodes = new Seq<>(); + public static int otherCores; + public static Seq pathTiles = new Seq<>(); @SuppressWarnings("unchecked") public static T getTarget(){ @@ -40,6 +60,159 @@ public class OverDrawer { public static void setEvent(){ Events.run(EventType.Trigger.draw, () -> { + int[] units = {0}; + if(pathLine || unitLine || logicLine) Groups.unit.each(u -> { + UnitController c = u.controller(); + UnitCommand com = u.team.data().command; + + if(c instanceof LogicAI ai){ + if(logicLine && (ai.control == LUnitControl.approach || ai.control == LUnitControl.move)) { + Lines.stroke(1, u.team.color); + Lines.line(u.x(), u.y(), ai.moveX, ai.moveY); + Lines.stroke(0.5f + Mathf.absin(6f, 0.5f), Tmp.c1.set(Pal.logicOperations).lerp(Pal.sap, Mathf.absin(6f, 0.5f))); + Lines.line(u.x(), u.y(), ai.controller.x, ai.controller.y); + } + return; + } + + if(++units[0] > settings.getInt("unitlinelimit") || //prevent lag + !unitLine || //disabled + u.type.flying || //not flying + c instanceof MinerAI || //not mono + c instanceof BuilderAI || //not poly + c instanceof RepairAI || //not mega + c instanceof DefenderAI || //not oct + c instanceof FormationAI || //not commanded unit by player + c instanceof FlyingAI || //not flying anyway + com == UnitCommand.idle) return; //not idle + + otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != u.team); + getNextTile(u.tileOn(), u.pathType(), u.team, com.ordinal()); + pathTiles.filter(Objects::nonNull); + for(int i = 1; i < pathTiles.size; i++) { + if(i + 1 >= pathTiles.size) continue; //prevent IndexOutException + Tile tile1 = pathTiles.get(i); + Tile tile2 = pathTiles.get(i + 1); + Draw.z(Layer.overlayUI); + Lines.stroke(1, u.team.color); + Lines.line(tile1.worldx(), tile1.worldy(), tile2.worldx(), tile2.worldy()); + } + pathTiles.clear(); + }); + + if(pathLine) spawner.getSpawns().each(t -> { + Team enemyTeam = state.rules.waveTeam; + for(int p = 0; p < 3; p++) { + otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != enemyTeam); + + getNextTile(t, p, enemyTeam, Pathfinder.fieldCore); + pathTiles.filter(Objects::nonNull); + for(int i = 1; i < pathTiles.size; i++) { + if(i + 1 >= pathTiles.size) continue; //prevent IndexOutException + Tile tile1 = pathTiles.get(i); + Tile tile2 = pathTiles.get(i + 1); + Draw.z(Layer.overlayUI); + Lines.stroke(1, enemyTeam.color); + Lines.line(tile1.worldx(), tile1.worldy(), tile2.worldx(), tile2.worldy()); + } + pathTiles.clear(); + } + }); + + if(settings.getBool("blockstatus")) Groups.build.each(build -> { + if(Vars.player != null && Vars.player.team() == build.team) return; + + Block block = build.block; + if(block.enableDrawStatus && block.consumes.any()){ + float multiplier = block.size > 1 ? 1 : 0.64f; + float brcx = build.x + (block.size * tilesize / 2f) - (tilesize * multiplier / 2f); + float brcy = build.y - (block.size * tilesize / 2f) + (tilesize * multiplier / 2f); + + Draw.z(Layer.power + 1); + Draw.color(Pal.gray); + Fill.square(brcx, brcy, 2.5f * multiplier, 45); + Draw.color(build.status().color); + Fill.square(brcx, brcy, 1.5f * multiplier, 45); + Draw.color(); + } + }); + + if(Core.settings.getBool("unithealthui")) + Groups.unit.each(unit -> new FreeBar().draw(unit)); + + if(!mobile && !Vars.state.isPaused() && settings.getBool("gaycursor")) + Fx.mine.at(Core.input.mouseWorldX(), Core.input.mouseWorldY(), Tmp.c2.set(Color.red).shiftHue(Time.time * 1.5f)); + + if(!renderer.pixelator.enabled()) Groups.unit.each(unit -> unit.item() != null && unit.itemTime > 0.01f, unit -> { + Fonts.outline.draw(unit.stack.amount + "", + unit.x + Angles.trnsx(unit.rotation + 180f, unit.type.itemOffsetY), + unit.y + Angles.trnsy(unit.rotation + 180f, unit.type.itemOffsetY) - 3, + Pal.accent, 0.25f * unit.itemTime / Scl.scl(1f), false, Align.center); + Draw.reset(); + }); + + // Turret Ranges + if(settings.getBool("rangeNearby") && player != null) { + Team team = player.team(); + Unit unit = player.unit(); + Groups.build.each(e -> { + if(!settings.getBool("allTeamRange") && e.team == team) return; // Don't draw own turrets + if(!(e instanceof BaseTurret.BaseTurretBuild)) return; // Not a turret + if((e instanceof Turret.TurretBuild t && !t.hasAmmo()) || !e.cons.valid()) return; // No ammo + + boolean canHit = e.block instanceof Turret t ? unit.isFlying() ? t.targetAir : t.targetGround : + e.block instanceof TractorBeamTurret tu && (unit.isFlying() ? tu.targetAir : tu.targetGround); + float range = ((BaseTurret.BaseTurretBuild) e).range(); + float max = range + settings.getInt("rangeRadius") * tilesize + e.block.offset; + float dst = Mathf.dst(control.input.getMouseX(), control.input.getMouseY(), e.x, e.y); + + if(control.input.block != null && dst <= max) canHit = e.block instanceof Turret t && t.targetGround; + if(player.dst(e) <= max || (control.input.block != null && dst <= max)) { + if(canHit || settings.getBool("allTargetRange")){ + if(settings.getBool("softRangeDrawing")){ + Lines.stroke(Scl.scl(), Tmp.c1.set(canHit ? e.team.color : Team.derelict.color).a(0.5f)); + Lines.poly(e.x, e.y, Lines.circleVertices(range), range); + Fill.light(e.x, e.y, Lines.circleVertices(range), range, Color.clear, Tmp.c1.a(Mathf.clamp(1-((control.input.block != null && dst <= max ? dst : player.dst(e))/max), 0, settings.getInt("softRangeOpacity")/100f))); + } + else Drawf.dashCircle(e.x, e.y, range, canHit ? e.team.color : Team.derelict.color); + } + } + }); + + // Unit Ranges (Only works when turret ranges are enabled) + if(settings.getBool("unitRange") || (settings.getBool("allTeamRange") && player.unit() != null)) { + Groups.unit.each(u -> { + if(!settings.getBool("unitRange") && settings.getBool("allTeamRange") && player.unit() != u) return; //player unit rule + if(!settings.getBool("allTeamRange") && u.team == team) return; // Don't draw own units + if(u.controller() instanceof AIController ai && (ai instanceof BuilderAI || ai instanceof MinerAI)) return; //don't draw poly and mono + boolean canHit = unit.isFlying() ? u.type.targetAir : u.type.targetGround; + float range = u.range(); + float max = range + settings.getInt("rangeRadius") * tilesize; + + if(Vars.player.dst(u) <= max) { + if (canHit || settings.getBool("allTargetRange")) // Same as above + if(settings.getBool("softRangeDrawing")){ + Lines.stroke(Scl.scl(), Tmp.c1.set(canHit ? u.team.color : Team.derelict.color).a(0.5f)); + Lines.poly(u.x, u.y, Lines.circleVertices(range), range); + Fill.light(u.x, u.y, Lines.circleVertices(range), range, Color.clear, Tmp.c1.a(Math.min(settings.getInt("softRangeOpacity")/100f, 1-Vars.player.dst(u)/max))); + } + else Drawf.dashCircle(u.x, u.y, range, canHit ? u.team.color : Team.derelict.color); + } + }); + } + } + + if(!state.rules.polygonCoreProtection && settings.getBool("coreRange") && player != null){ + state.teams.eachEnemyCore(player.team(), core -> { + if(Core.camera.bounds(Tmp.r1).overlaps(Tmp.r2.setCentered(core.x, core.y, state.rules.enemyCoreBuildRadius * 2f))){ + Draw.color(Color.darkGray); + Lines.circle(core.x, core.y - 2, state.rules.enemyCoreBuildRadius); + Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time, 10f, 0.5f)); + Lines.circle(core.x, core.y, state.rules.enemyCoreBuildRadius); + } + }); + } + if(settings.getBool("linkedMass")){ if(getTarget() instanceof MassDriver.MassDriverBuild mass) { linkedMasses.clear(); @@ -143,6 +316,17 @@ public class OverDrawer { }); } + public static Tile getNextTile(Tile tile, int cost, Team team, int finder) { + Pathfinder.Flowfield field = pathfinder.getField(team, cost, Mathf.clamp(finder, 0, 1)); + Tile tile1 = pathfinder.getTargetTile(tile, field); + pathTiles.add(tile1); + if(tile1 == tile || tile1 == null || + (finder == 0 && (otherCores != Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != team) || tile1.build instanceof CoreBlock.CoreBuild)) || + (finder == 1 && tile1.build instanceof CommandCenter.CommandBuild)) + return tile1; + return getNextTile(tile1, cost, team, finder); + } + public static void drawMassPayloadLink(PayloadMassDriver.PayloadDriverBuild from){ Groups.build.each(b -> b instanceof PayloadMassDriver.PayloadDriverBuild fromMass && world.build(fromMass.link) == from &&