From 81b2215c9a2a62f85ed37eece82cde9f95b80e9c Mon Sep 17 00:00:00 2001 From: sharlottes Date: Sun, 17 Apr 2022 17:35:55 +0900 Subject: [PATCH] add ToolDisplay --- src/UnitInfo/SVars.java | 4 +- src/UnitInfo/core/HudUi.java | 35 +-- src/UnitInfo/core/Main.java | 2 + src/UnitInfo/core/OverDrawer.java | 250 +------------------- src/UnitInfo/core/SettingS.java | 11 +- src/UnitInfo/ui/HUDFragment.java | 4 +- src/UnitInfo/ui/draws/BlockDraw.java | 48 ++++ src/UnitInfo/ui/draws/LinkDraw.java | 183 ++++++++++++++ src/UnitInfo/ui/draws/OverDraw.java | 20 ++ src/UnitInfo/ui/draws/OverDraws.java | 16 ++ src/UnitInfo/ui/draws/RangeDraw.java | 109 +++++++++ src/UnitInfo/ui/draws/UnitDraw.java | 141 +++++++++++ src/UnitInfo/ui/windows/CommandDisplay.java | 64 ----- src/UnitInfo/ui/windows/ToolDisplay.java | 85 +++++++ src/UnitInfo/ui/windows/WindowTables.java | 4 +- 15 files changed, 626 insertions(+), 350 deletions(-) create mode 100644 src/UnitInfo/ui/draws/BlockDraw.java create mode 100644 src/UnitInfo/ui/draws/LinkDraw.java create mode 100644 src/UnitInfo/ui/draws/OverDraw.java create mode 100644 src/UnitInfo/ui/draws/OverDraws.java create mode 100644 src/UnitInfo/ui/draws/RangeDraw.java create mode 100644 src/UnitInfo/ui/draws/UnitDraw.java delete mode 100644 src/UnitInfo/ui/windows/CommandDisplay.java create mode 100644 src/UnitInfo/ui/windows/ToolDisplay.java diff --git a/src/UnitInfo/SVars.java b/src/UnitInfo/SVars.java index bc57f30..9440bc8 100644 --- a/src/UnitInfo/SVars.java +++ b/src/UnitInfo/SVars.java @@ -4,6 +4,7 @@ import UnitInfo.core.*; import UnitInfo.shaders.LineShader; import UnitInfo.shaders.RangeShader; import arc.graphics.g2d.TextureRegion; +import mindustry.gen.Teamc; import static arc.Core.atlas; import static arc.Core.settings; @@ -11,10 +12,11 @@ import static arc.Core.settings; public class SVars { public static HudUi hud = new HudUi(); public static float modUiScale = settings.getInt("infoUiScale"); - public static boolean pathLine = false, unitLine = false, logicLine = false; public static TextureRegion clear = atlas.find("clear"); public static TextureRegion error = atlas.find("error"); public static RangeShader turretRange; public static LineShader lineShader; + public static Teamc target; + public static boolean locked; public static boolean jsonGen = false; } diff --git a/src/UnitInfo/core/HudUi.java b/src/UnitInfo/core/HudUi.java index afbd883..51d94b0 100644 --- a/src/UnitInfo/core/HudUi.java +++ b/src/UnitInfo/core/HudUi.java @@ -66,8 +66,7 @@ public class HudUi { float heat = 0; public void setEvents() { Events.run(EventType.Trigger.update, ()->{ - OverDrawer.target = getTarget(); - OverDrawer.locked = locked; + target = getTarget(); if(settings.getBool("deadTarget") && locked && lockedTarget != null && !Groups.all.contains(e -> e == lockedTarget)) { lockedTarget = null; locked = false; @@ -217,42 +216,12 @@ public class HudUi { }); }); - Table pathlineTable = new Table(t -> { - t.right(); - - Button pathBtn = new ImageButton(new ScaledNinePatchDrawable(new NinePatch(Icon.grid.getRegion()), 0.5f), Styles.clearToggleTransi); - Button unitBtn = new ImageButton(new ScaledNinePatchDrawable(new NinePatch(Icon.grid.getRegion()), 0.5f), Styles.clearToggleTransi); - Button logicBtn = new ImageButton(new ScaledNinePatchDrawable(new NinePatch(Icon.grid.getRegion()), 0.5f), Styles.clearToggleTransi); - - pathBtn.addListener(new Tooltip(l -> l.label(() -> bundle.get("hud.pathline") + " " + (pathLine ? bundle.get("hud.enabled") : bundle.get("hud.disabled"))))); - pathBtn.clicked(() -> { - pathLine = !pathLine; - pathBtn.setChecked(pathLine); - }); - - unitBtn.addListener(new Tooltip(l -> l.label(() -> bundle.get("hud.unitline") + " " + (unitLine ? bundle.get("hud.enabled") : bundle.get("hud.disabled"))))); - unitBtn.clicked(() -> { - unitLine = !unitLine; - unitBtn.setChecked(unitLine); - }); - - logicBtn.addListener(new Tooltip(l -> l.label(() -> bundle.get("hud.logicline") + " " + (logicLine ? bundle.get("hud.enabled") : bundle.get("hud.disabled"))))); - logicBtn.clicked(() -> { - logicLine = !logicLine; - logicBtn.setChecked(logicLine); - }); - - t.add(pathBtn).padLeft(4 * 8f).size(3 * 8f).row(); - t.add(unitBtn).padLeft(4 * 8f).size(3 * 8f).row(); - t.add(logicBtn).padLeft(4 * 8f).size(3 * 8f).row(); - }); - Table waveTable = (Table) scene.find("waves"); Table infoTable = (Table) scene.find("infotable"); waveTable.removeChild(infoTable); waveTable.row(); waveTable.stack( - new Table(tt -> tt.collapser(t -> t.stack(waveInfoTable, infoTable, pathlineTable).growX(), true, () -> waveShown).growX()).top(), + new Table(tt -> tt.collapser(t -> t.stack(waveInfoTable, infoTable).growX(), true, () -> waveShown).growX()).top(), new Table(tt -> tt.button(Icon.downOpen, Styles.clearToggleTransi, () -> waveShown = !waveShown).size(4 * 8f).checked(b -> { b.getImage().setDrawable(waveShown ? Icon.upOpen : Icon.downOpen); return waveShown; diff --git a/src/UnitInfo/core/Main.java b/src/UnitInfo/core/Main.java index 4590be0..71316e7 100644 --- a/src/UnitInfo/core/Main.java +++ b/src/UnitInfo/core/Main.java @@ -2,6 +2,7 @@ package UnitInfo.core; import UnitInfo.shaders.*; import UnitInfo.ui.*; +import UnitInfo.ui.draws.OverDraws; import UnitInfo.ui.windows.*; import arc.*; import arc.scene.ui.Dialog; @@ -42,6 +43,7 @@ public class Main extends Mod { SettingS.init(); MindowsTex.init(); WindowTables.init(); + OverDraws.init(); new HUDFragment().build(Vars.ui.hudGroup); hud = new HudUi(); diff --git a/src/UnitInfo/core/OverDrawer.java b/src/UnitInfo/core/OverDrawer.java index c25cc12..7e00baa 100644 --- a/src/UnitInfo/core/OverDrawer.java +++ b/src/UnitInfo/core/OverDrawer.java @@ -1,6 +1,8 @@ package UnitInfo.core; import UnitInfo.ui.*; +import UnitInfo.ui.draws.OverDraw; +import UnitInfo.ui.draws.OverDraws; import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; @@ -13,7 +15,6 @@ import arc.util.*; import mindustry.*; import mindustry.ai.*; import mindustry.ai.types.*; -import mindustry.core.*; import mindustry.entities.units.*; import mindustry.game.*; import mindustry.gen.*; @@ -22,8 +23,6 @@ import mindustry.logic.*; import mindustry.ui.*; import mindustry.world.*; import mindustry.world.blocks.defense.turrets.*; -import mindustry.world.blocks.distribution.*; -import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.storage.*; import mindustry.world.blocks.units.*; @@ -34,23 +33,13 @@ import static arc.Core.*; import static mindustry.Vars.*; public class OverDrawer { - public static Teamc target; - public static Seq linkedMasses = new Seq<>(); - public static Seq linkedPayloadMasses = new Seq<>(); - public static Seq linkedNodes = new Seq<>(); - public static Seq pathTiles = new Seq<>(); - public static FrameBuffer effectBuffer = new FrameBuffer(); - public static int otherCores; - public static boolean locked; - public static ObjectMap> tmpbuildobj = new ObjectMap<>(); public static void setEvent(){ Events.run(EventType.Trigger.draw, () -> { + float sin = Mathf.absin(Time.time, 6f, 1f); - effectBuffer.resize(graphics.getWidth(), graphics.getHeight()); Draw.z(Layer.max); - //local drawing, drawn on player/camera position if(settings.getBool("spawnerarrow")) { float leng = (player.unit() != null && player.unit().hitSize > 4 * 8f ? player.unit().hitSize * 1.5f : 4 * 8f) + sin; @@ -93,243 +82,16 @@ public class OverDrawer { //global drawing, which needs camera-clipping Core.camera.bounds(Tmp.r1); - Groups.unit.each(u-> isInCamera(u.x, u.y, u.hitSize), u -> { - UnitController c = u.controller(); - UnitCommand com = u.team.data().command; - - if(logicLine && c instanceof LogicAI ai && (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); - } - - if(unitLine && !u.type.flying && com != UnitCommand.idle && !(c instanceof MinerAI || c instanceof BuilderAI || c instanceof RepairAI || c instanceof DefenderAI || c instanceof FormationAI || c instanceof FlyingAI)) { - Lines.stroke(1, u.team.color); - - otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != u.team); - getNextTile(u.tileOn(), u.controller() instanceof SuicideAI ? 0 : u.pathType(), u.team, com.ordinal()); - pathTiles.filter(Objects::nonNull); - for(int i = 0; i < pathTiles.size; i++) { - Tile from = pathTiles.get(i); - Tile to = pathTiles.get(i + 1); - if(isOutCamera(from.x, from.y)) continue; - Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); - } - pathTiles.clear(); - } - - if(Core.settings.getBool("unithealthui")) - FreeBar.draw(u); - - if(!renderer.pixelator.enabled() && u.item() != null && u.itemTime > 0.01f) - Fonts.outline.draw(u.stack.amount + "", - u.x + Angles.trnsx(u.rotation + 180f, u.type.itemOffsetY), - u.y + Angles.trnsy(u.rotation + 180f, u.type.itemOffsetY) - 3, - Pal.accent, 0.25f * u.itemTime / Scl.scl(1f), false, Align.center); - }); - - if(pathLine) spawner.getSpawns().each(t -> { - Team enemyTeam = state.rules.waveTeam; - Lines.stroke(1, enemyTeam.color); - for(int p = 0; p < (Vars.state.rules.spawns.count(g->g.type.naval)>0?3:2); 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 = 0; i < pathTiles.size; i++) { - Tile from = pathTiles.get(i); - Tile to = pathTiles.get(i + 1); - if(isOutCamera(from.x, from.y)) continue; - Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); - } - pathTiles.clear(); - } - }); - - if(settings.getBool("blockstatus")) //display enemy block status - Groups.build.each(b->isInCamera(b.x, b.y, b.block.size/2f) && Vars.player.team() == b.team, Building::drawStatus); - - if(settings.getBool("linkedNode") && target instanceof Building node){ - linkedNodes.clear(); - Draw.z(Layer.max); - drawNodeLink(node); - } - - if(settings.getBool("linkedMass")){ - if(target instanceof MassDriver.MassDriverBuild mass) { - linkedMasses.clear(); - drawMassLink(mass); - } - else if(target instanceof PayloadMassDriver.PayloadDriverBuild mass) { - linkedPayloadMasses.clear(); - drawMassPayloadLink(mass); - } - } - - if(settings.getBool("rangeNearby")) { - Unit unit = player.unit(); - tmpbuildobj.clear(); - for(Team team : Team.baseTeams) { - Draw.drawRange(166 + (Team.baseTeams.length-team.id) * 3, 1, () -> effectBuffer.begin(Color.clear), () -> { - effectBuffer.end(); - effectBuffer.blit(turretRange); - }); - tmpbuildobj.put(team, new Seq<>()); - } - - Groups.build.each(b-> settings.getBool("aliceRange") || player.team() != b.team, b -> { - if(b instanceof BaseTurret.BaseTurretBuild turret) { - float range = turret.range(); - if (isInCamera(b.x, b.y, range)) { - int index = b.team.id; - Draw.color(b.team.color); - - boolean valid = false; - if (unit == null) valid = true; - else if (b instanceof Turret.TurretBuild build) { - Turret t = (Turret) build.block; - if((unit.isFlying() ? t.targetAir : t.targetGround)) valid = true; - if(!build.hasAmmo() || !build.cons.valid()) index = 0; - } else if (b instanceof TractorBeamTurret.TractorBeamBuild build) { - TractorBeamTurret t = (TractorBeamTurret) build.block; - if((unit.isFlying() ? t.targetAir : t.targetGround)) valid = true; - if(!build.cons.valid()) index = 0; - } - - if(!valid) return; - - if(b.team==player.team()) index = b.team.id; - - Draw.color(Team.baseTeams[index].color); - if (settings.getBool("RangeShader")) { - Draw.z(166+(Team.baseTeams.length-index)*3); - Fill.poly(b.x, b.y, Lines.circleVertices(range), range); - } else Drawf.dashCircle(b.x, b.y, range, b.team.color); - } - } - }); - } + for(OverDraw drawer : OverDraws.all) drawer.draw(); }); } - static boolean isOutCamera(float x, float y) { + public static boolean isOutCamera(float x, float y) { return !isInCamera(x, y, 0); } - static boolean isInCamera(float x, float y, float size) { + public static boolean isInCamera(float x, float y, float size) { Tmp.r2.setCentered(x, y, size); return Tmp.r1.overlaps(Tmp.r2); } - - 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){ - float sin = Mathf.absin(Time.time, 6f, 1f); - - //call every mass drivers that link to this driver - for(Building b : Groups.build) { - if (b != from && b instanceof PayloadMassDriver.PayloadDriverBuild fromMass && world.build(fromMass.link) == from && !linkedPayloadMasses.contains(fromMass)) { - linkedPayloadMasses.add(fromMass); - drawMassPayloadLink(fromMass); - } - } - - //get and draw line between this mass driver and linked one - Building target = world.build(from.link); - if(target instanceof PayloadMassDriver.PayloadDriverBuild targetDriver) { - Tmp.v1.set(from.x + from.block.offset, from.y + from.block.offset).sub(targetDriver.x, targetDriver.y).limit(from.block.size * tilesize + sin + 0.5f); - float x2 = from.x - Tmp.v1.x, y2 = from.y - Tmp.v1.y, x1 = targetDriver.x + Tmp.v1.x, y1 = targetDriver.y + Tmp.v1.y; - int segs = (int) (targetDriver.dst(from.x, from.y) / tilesize); - Lines.stroke(4f, Pal.gray); - Lines.dashLine(x1, y1, x2, y2, segs); - Lines.stroke(2f, Pal.placing); - Lines.dashLine(x1, y1, x2, y2, segs); - Lines.stroke(1f, Pal.accent); - Drawf.circles(from.x, from.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); - Drawf.arrow(from.x, from.y, targetDriver.x, targetDriver.y, from.block.size * tilesize + sin, 4f + sin); - for (Building shooter : from.waitingShooters) { - Drawf.circles(shooter.x, shooter.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f); - Drawf.arrow(shooter.x, shooter.y, from.x, from.y, from.block.size * tilesize + sin, 4f + sin); - } - - //call method again when target links to another mass driver which isn't stored in array - if(!linkedPayloadMasses.contains(targetDriver)) { - linkedPayloadMasses.add(targetDriver); - drawMassPayloadLink(targetDriver); - } - } - } - - static void drawMassLink(MassDriver.MassDriverBuild from){ - float sin = Mathf.absin(Time.time, 6f, 1f); - - //call every mass drivers that link to this driver - for(Building b : Groups.build) { - if (b != from && b instanceof MassDriver.MassDriverBuild fromMass && world.build(fromMass.link) == from && !linkedMasses.contains(fromMass)) { - linkedMasses.add(fromMass); - drawMassLink(fromMass); - } - } - - //get and draw line between this mass driver and linked one - Building target = world.build(from.link); - if(target instanceof MassDriver.MassDriverBuild targetDriver) { - Tmp.v1.set(from.x + from.block.offset, from.y + from.block.offset).sub(targetDriver.x, targetDriver.y).limit(from.block.size * tilesize + sin + 0.5f); - float x2 = from.x - Tmp.v1.x, y2 = from.y - Tmp.v1.y, x1 = targetDriver.x + Tmp.v1.x, y1 = targetDriver.y + Tmp.v1.y; - int segs = (int) (targetDriver.dst(from.x, from.y) / tilesize); - Lines.stroke(4f, Pal.gray); - Lines.dashLine(x1, y1, x2, y2, segs); - Lines.stroke(2f, Pal.placing); - Lines.dashLine(x1, y1, x2, y2, segs); - Lines.stroke(1f, Pal.accent); - Drawf.circles(from.x, from.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); - Drawf.arrow(from.x, from.y, targetDriver.x, targetDriver.y, from.block.size * tilesize + sin, 4f + sin); - for (Building shooter : from.waitingShooters) { - Drawf.circles(shooter.x, shooter.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f); - Drawf.arrow(shooter.x, shooter.y, from.x, from.y, from.block.size * tilesize + sin, 4f + sin); - } - - //call method again when target links to another mass driver which isn't stored in array - if(!linkedMasses.contains(targetDriver)) { - linkedMasses.add(targetDriver); - drawMassLink(targetDriver); - } - } - } - - public static IntSeq getPowerLinkedBuilds(Building build) { - IntSeq seq = new IntSeq(build.power.links); - seq.addAll(build.proximity().mapInt(Building::pos)); - return seq; - } - - public static void drawNodeLink(Building node) { - if(node.power == null) return; - if(!linkedNodes.contains(node)) { - linkedNodes.add(node); - int[] builds = getPowerLinkedBuilds(node).items; - for(int i : builds) { - Building other = world.build(i); - if(other == null || other.power == null) return; - float angle1 = Angles.angle(node.x, node.y, other.x, other.y), - vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1), - len1 = node.block.size * tilesize / 2f - 1.5f, len2 = other.block.size * tilesize / 2f - 1.5f; - Draw.color(Color.white, Color.valueOf("98ff98"), (1f - node.power.graph.getSatisfaction()) * 0.86f + Mathf.absin(3f, 0.1f)); - Draw.alpha(Renderer.laserOpacity); - Drawf.laser(node.team, atlas.find("unitinfo-Slaser"), atlas.find("unitinfo-Slaser-end"), node.x + vx * len1, node.y + vy * len1, other.x - vx * len2, other.y - vy * len2, 0.25f); - - drawNodeLink(other); - } - } - } } diff --git a/src/UnitInfo/core/SettingS.java b/src/UnitInfo/core/SettingS.java index 37829d2..40ace74 100644 --- a/src/UnitInfo/core/SettingS.java +++ b/src/UnitInfo/core/SettingS.java @@ -116,10 +116,11 @@ public class SettingS { addGraphicCheckSetting("itemcal", false, tapSeq); addGraphicCheckSetting("schem", !mobile, tapSeq); + //TODO: remove all drawing settings Seq rangeSeq = new Seq<>(); - addGraphicTypeSetting("rangeRadius", 0, 500, 70, true, () -> true, s -> s + "tiles", rangeSeq); - addGraphicCheckSetting("rangeNearby", true, rangeSeq); - addGraphicCheckSetting("allTargetRange", false, rangeSeq); + //addGraphicTypeSetting("rangeRadius", 0, 500, 70, true, () -> true, s -> s + "tiles", rangeSeq); + //addGraphicCheckSetting("rangeNearby", true, rangeSeq); + //addGraphicCheckSetting("allTargetRange", false, rangeSeq); addGraphicCheckSetting("aliceRange", false, rangeSeq); addGraphicCheckSetting("RangeShader", false, rangeSeq); @@ -130,6 +131,7 @@ public class SettingS { addGraphicSlideSetting("softRangeOpacity", 60, 0, 100, 10, s -> s + "%", opacitySeq); Seq drawSeq = new Seq<>(); + /* addGraphicTypeSetting("pathlinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq); addGraphicTypeSetting("unitlinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq); addGraphicTypeSetting("logiclinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq); @@ -139,8 +141,9 @@ public class SettingS { addGraphicCheckSetting("blockfont", false, drawSeq); addGraphicCheckSetting("linkedMass", true, drawSeq); addGraphicCheckSetting("linkedNode", false, drawSeq); - addGraphicCheckSetting("select", false, drawSeq); addGraphicCheckSetting("deadTarget", false, drawSeq); + */ + addGraphicCheckSetting("select", false, drawSeq); addGraphicCheckSetting("distanceLine", false, drawSeq); addGraphicCheckSetting("spawnerarrow", false, drawSeq); addGraphicCheckSetting("elementdebug", false, drawSeq); diff --git a/src/UnitInfo/ui/HUDFragment.java b/src/UnitInfo/ui/HUDFragment.java index 461eb4a..d669795 100644 --- a/src/UnitInfo/ui/HUDFragment.java +++ b/src/UnitInfo/ui/HUDFragment.java @@ -19,7 +19,7 @@ public class HUDFragment extends Fragment{ waveTable, coreTable, playerTable, - commandTable + toolTable )).visible(TaskbarTable.visibility); // windows (totally not a copyright violation) @@ -27,7 +27,7 @@ public class HUDFragment extends Fragment{ t.add(waveTable).size(250f).visible(false); t.add(coreTable).size(250f).visible(false); t.add(playerTable).size(250f).visible(false); - t.add(commandTable).size(250f).visible(false); + t.add(toolTable).size(250f).visible(false); t.update(()->{ for (Element child : t.getChildren()) { diff --git a/src/UnitInfo/ui/draws/BlockDraw.java b/src/UnitInfo/ui/draws/BlockDraw.java new file mode 100644 index 0000000..116a267 --- /dev/null +++ b/src/UnitInfo/ui/draws/BlockDraw.java @@ -0,0 +1,48 @@ +package UnitInfo.ui.draws; + +import arc.scene.Element; +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.CheckBox; +import arc.scene.ui.layout.Table; +import mindustry.Vars; +import mindustry.gen.Groups; +import mindustry.ui.Styles; + +import static UnitInfo.core.OverDrawer.isInCamera; + +public class BlockDraw extends OverDraw { + boolean status = false; + + BlockDraw(String name, TextureRegionDrawable icon) { + super(name, icon); + } + + @Override + public void draw() { + super.draw(); + Groups.build.each(b->{ + if(isInCamera(b.x, b.y, b.block.size/2f) && Vars.player.team() == b.team) b.drawStatus(); + }); + } + + @Override + public void displayStats(Table parent) { + super.displayStats(parent); + + parent.background(Styles.squaret.up); + + parent.check("enable block status", status&&enabled, b->status=b&&enabled).disabled(!enabled); + } + + @Override + public void onEnabled(T param) { + super.onEnabled(param); + + if(param instanceof Table t) { + for (int i = 0; i < t.getChildren().size; i++) { + Element elem = t.getChildren().get(i); + if (elem instanceof CheckBox cb) cb.setDisabled(!enabled); + } + } + } +} diff --git a/src/UnitInfo/ui/draws/LinkDraw.java b/src/UnitInfo/ui/draws/LinkDraw.java new file mode 100644 index 0000000..87875cf --- /dev/null +++ b/src/UnitInfo/ui/draws/LinkDraw.java @@ -0,0 +1,183 @@ +package UnitInfo.ui.draws; + +import arc.graphics.Color; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Lines; +import arc.math.Angles; +import arc.math.Mathf; +import arc.scene.Element; +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.CheckBox; +import arc.scene.ui.layout.Table; +import arc.struct.IntSeq; +import arc.struct.Seq; +import arc.util.Time; +import arc.util.Tmp; +import mindustry.core.Renderer; +import mindustry.gen.Building; +import mindustry.gen.Groups; +import mindustry.graphics.Drawf; +import mindustry.graphics.Layer; +import mindustry.graphics.Pal; +import mindustry.ui.Styles; +import mindustry.world.blocks.distribution.MassDriver; +import mindustry.world.blocks.payloads.PayloadMassDriver; + +import static arc.Core.atlas; +import static mindustry.Vars.*; +import static UnitInfo.SVars.*; + +public class LinkDraw extends OverDraw { + Seq linkedMasses = new Seq<>(); + Seq linkedPayloadMasses = new Seq<>(); + Seq linkedNodes = new Seq<>(); + boolean node = false, mass = false; + + LinkDraw(String name, TextureRegionDrawable icon) { + super(name, icon); + } + + @Override + public void draw() { + if(!enabled) return; + + Draw.z(Layer.max); + if(target instanceof Building b){ + if(node) { + linkedNodes.clear(); + drawNodeLink(b); + } + if(mass) { + if (target instanceof MassDriver.MassDriverBuild mass) { + linkedMasses.clear(); + drawMassLink(mass); + } else if (target instanceof PayloadMassDriver.PayloadDriverBuild mass) { + linkedPayloadMasses.clear(); + drawMassPayloadLink(mass); + } + } + } + } + + @Override + public void displayStats(Table parent) { + super.displayStats(parent); + + parent.background(Styles.squaret.up); + + parent.check("enable power node", node&&enabled, b->node=b&&enabled).disabled(!enabled).row(); + parent.check("enable mass driver", mass&&enabled, b->mass=b&&enabled).disabled(!enabled).row(); + } + + @Override + public void onEnabled(T param) { + super.onEnabled(param); + + if(param instanceof Table t) { + for (int i = 0; i < t.getChildren().size; i++) { + Element elem = t.getChildren().get(i); + if (elem instanceof CheckBox cb) cb.setDisabled(!enabled); + } + } + } + + void drawMassPayloadLink(PayloadMassDriver.PayloadDriverBuild from){ + float sin = Mathf.absin(Time.time, 6f, 1f); + + //call every mass drivers that link to this driver + for(Building b : Groups.build) { + if (b != from && b instanceof PayloadMassDriver.PayloadDriverBuild fromMass && world.build(fromMass.link) == from && !linkedPayloadMasses.contains(fromMass)) { + linkedPayloadMasses.add(fromMass); + drawMassPayloadLink(fromMass); + } + } + + //get and draw line between this mass driver and linked one + Building target = world.build(from.link); + if(target instanceof PayloadMassDriver.PayloadDriverBuild targetDriver) { + Tmp.v1.set(from.x + from.block.offset, from.y + from.block.offset).sub(targetDriver.x, targetDriver.y).limit(from.block.size * tilesize + sin + 0.5f); + float x2 = from.x - Tmp.v1.x, y2 = from.y - Tmp.v1.y, x1 = targetDriver.x + Tmp.v1.x, y1 = targetDriver.y + Tmp.v1.y; + int segs = (int) (targetDriver.dst(from.x, from.y) / tilesize); + Lines.stroke(4f, Pal.gray); + Lines.dashLine(x1, y1, x2, y2, segs); + Lines.stroke(2f, Pal.placing); + Lines.dashLine(x1, y1, x2, y2, segs); + Lines.stroke(1f, Pal.accent); + Drawf.circles(from.x, from.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); + Drawf.arrow(from.x, from.y, targetDriver.x, targetDriver.y, from.block.size * tilesize + sin, 4f + sin); + for (Building shooter : from.waitingShooters) { + Drawf.circles(shooter.x, shooter.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f); + Drawf.arrow(shooter.x, shooter.y, from.x, from.y, from.block.size * tilesize + sin, 4f + sin); + } + + //call method again when target links to another mass driver which isn't stored in array + if(!linkedPayloadMasses.contains(targetDriver)) { + linkedPayloadMasses.add(targetDriver); + drawMassPayloadLink(targetDriver); + } + } + } + + void drawMassLink(MassDriver.MassDriverBuild from){ + float sin = Mathf.absin(Time.time, 6f, 1f); + + //call every mass drivers that link to this driver + for(Building b : Groups.build) { + if (b != from && b instanceof MassDriver.MassDriverBuild fromMass && world.build(fromMass.link) == from && !linkedMasses.contains(fromMass)) { + linkedMasses.add(fromMass); + drawMassLink(fromMass); + } + } + + //get and draw line between this mass driver and linked one + Building target = world.build(from.link); + if(target instanceof MassDriver.MassDriverBuild targetDriver) { + Tmp.v1.set(from.x + from.block.offset, from.y + from.block.offset).sub(targetDriver.x, targetDriver.y).limit(from.block.size * tilesize + sin + 0.5f); + float x2 = from.x - Tmp.v1.x, y2 = from.y - Tmp.v1.y, x1 = targetDriver.x + Tmp.v1.x, y1 = targetDriver.y + Tmp.v1.y; + int segs = (int) (targetDriver.dst(from.x, from.y) / tilesize); + Lines.stroke(4f, Pal.gray); + Lines.dashLine(x1, y1, x2, y2, segs); + Lines.stroke(2f, Pal.placing); + Lines.dashLine(x1, y1, x2, y2, segs); + Lines.stroke(1f, Pal.accent); + Drawf.circles(from.x, from.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f, Pal.accent); + Drawf.arrow(from.x, from.y, targetDriver.x, targetDriver.y, from.block.size * tilesize + sin, 4f + sin); + for (Building shooter : from.waitingShooters) { + Drawf.circles(shooter.x, shooter.y, (from.tile.block().size / 2f + 1) * tilesize + sin - 2f); + Drawf.arrow(shooter.x, shooter.y, from.x, from.y, from.block.size * tilesize + sin, 4f + sin); + } + + //call method again when target links to another mass driver which isn't stored in array + if(!linkedMasses.contains(targetDriver)) { + linkedMasses.add(targetDriver); + drawMassLink(targetDriver); + } + } + } + + IntSeq getPowerLinkedBuilds(Building build) { + IntSeq seq = new IntSeq(build.power.links); + seq.addAll(build.proximity().mapInt(Building::pos)); + return seq; + } + + void drawNodeLink(Building node) { + if(node.power == null) return; + if(!linkedNodes.contains(node)) { + linkedNodes.add(node); + int[] builds = getPowerLinkedBuilds(node).items; + for(int i : builds) { + Building other = world.build(i); + if(other == null || other.power == null) return; + float angle1 = Angles.angle(node.x, node.y, other.x, other.y), + vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1), + len1 = node.block.size * tilesize / 2f - 1.5f, len2 = other.block.size * tilesize / 2f - 1.5f; + Draw.color(Color.white, Color.valueOf("98ff98"), (1f - node.power.graph.getSatisfaction()) * 0.86f + Mathf.absin(3f, 0.1f)); + Draw.alpha(Renderer.laserOpacity); + Drawf.laser(node.team, atlas.find("unitinfo-Slaser"), atlas.find("unitinfo-Slaser-end"), node.x + vx * len1, node.y + vy * len1, other.x - vx * len2, other.y - vy * len2, 0.25f); + + drawNodeLink(other); + } + } + } +} diff --git a/src/UnitInfo/ui/draws/OverDraw.java b/src/UnitInfo/ui/draws/OverDraw.java new file mode 100644 index 0000000..31b7cc7 --- /dev/null +++ b/src/UnitInfo/ui/draws/OverDraw.java @@ -0,0 +1,20 @@ +package UnitInfo.ui.draws; + +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.layout.Table; + +public class OverDraw { + public TextureRegionDrawable icon; + public String name; + public boolean enabled =false; + + OverDraw(String name, TextureRegionDrawable icon) { + this.name = name; + this.icon = icon; + } + + public void displayStats(Table parent) {} + public void draw() {} + public void onEnabled(T param) {} +} + diff --git a/src/UnitInfo/ui/draws/OverDraws.java b/src/UnitInfo/ui/draws/OverDraws.java new file mode 100644 index 0000000..53151c9 --- /dev/null +++ b/src/UnitInfo/ui/draws/OverDraws.java @@ -0,0 +1,16 @@ +package UnitInfo.ui.draws; + +import mindustry.gen.Icon; + +public class OverDraws { + public static OverDraw range, link, unit, block; + public static OverDraw[] all = {}; + + public static void init() { + range = new RangeDraw("Range Draws", Icon.commandRally); + link = new LinkDraw("Link Draws", Icon.line); + unit = new UnitDraw("Unit Draws", Icon.units); + block = new BlockDraw("Block Draws", Icon.crafting); + all = new OverDraw[]{range, link, unit, block}; + } +} diff --git a/src/UnitInfo/ui/draws/RangeDraw.java b/src/UnitInfo/ui/draws/RangeDraw.java new file mode 100644 index 0000000..249b9ec --- /dev/null +++ b/src/UnitInfo/ui/draws/RangeDraw.java @@ -0,0 +1,109 @@ +package UnitInfo.ui.draws; + +import arc.graphics.Color; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Fill; +import arc.graphics.g2d.Lines; +import arc.graphics.gl.FrameBuffer; +import arc.scene.Element; +import arc.scene.Group; +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.CheckBox; +import arc.scene.ui.layout.Table; +import arc.struct.ObjectMap; +import arc.struct.Seq; +import mindustry.game.Team; +import mindustry.gen.Groups; +import mindustry.gen.Unit; +import mindustry.graphics.Drawf; +import mindustry.ui.Styles; +import mindustry.world.blocks.defense.turrets.BaseTurret; +import mindustry.world.blocks.defense.turrets.TractorBeamTurret; +import mindustry.world.blocks.defense.turrets.Turret; + +import static UnitInfo.SVars.turretRange; +import static UnitInfo.core.OverDrawer.isInCamera; +import static arc.Core.graphics; +import static arc.Core.settings; +import static mindustry.Vars.player; + +public class RangeDraw extends OverDraw { + FrameBuffer effectBuffer = new FrameBuffer(); + ObjectMap> tmpbuildobj = new ObjectMap<>(); + boolean ground = false, air = false; + + RangeDraw(String name, TextureRegionDrawable icon) { + super(name, icon); + } + + @Override + public void draw() { + if(!enabled) return; + + effectBuffer.resize(graphics.getWidth(), graphics.getHeight()); + + Unit unit = player.unit(); + tmpbuildobj.clear(); + for(Team team : Team.baseTeams) { + Draw.drawRange(166 + (Team.baseTeams.length-team.id) * 3, 1, () -> effectBuffer.begin(Color.clear), () -> { + effectBuffer.end(); + effectBuffer.blit(turretRange); + }); + tmpbuildobj.put(team, new Seq<>()); + } + + Groups.build.each(b-> settings.getBool("aliceRange") || player.team() != b.team, b -> { + if(b instanceof BaseTurret.BaseTurretBuild turret) { + float range = turret.range(); + if (isInCamera(b.x, b.y, range)) { + int index = b.team.id; + Draw.color(b.team.color); + + boolean valid = false; + if (unit == null) valid = true; + else if (b instanceof Turret.TurretBuild build) { + Turret t = (Turret) build.block; + if(t.targetAir&&!air||t.targetGround&&!ground) return; + if((unit.isFlying() ? t.targetAir : t.targetGround) && build.hasAmmo() && build.cons.valid()) valid = true; + } else if (b instanceof TractorBeamTurret.TractorBeamBuild build) { + TractorBeamTurret t = (TractorBeamTurret) build.block; + if(t.targetAir&&!air||t.targetGround&&!ground) return; + if((unit.isFlying() ? t.targetAir : t.targetGround) && build.cons.valid()) valid = true; + } + + if(!valid) index = 0; + + if(b.team==player.team()) index = b.team.id; + + Draw.color(Team.baseTeams[index].color); + if (settings.getBool("RangeShader")) { + Draw.z(166+(Team.baseTeams.length-index)*3); + Fill.poly(b.x, b.y, Lines.circleVertices(range), range); + } else Drawf.dashCircle(b.x, b.y, range, b.team.color); + } + } + }); + } + + @Override + public void displayStats(Table parent) { + super.displayStats(parent); + + parent.background(Styles.squaret.up); + + parent.check("enable ground", ground&&enabled, b->ground=b&&enabled).disabled(!enabled).row(); + parent.check("enable air", air&&enabled, b->air=b&&enabled).disabled(!enabled).row(); + } + + @Override + public void onEnabled(T param) { + super.onEnabled(param); + + if(param instanceof Table t) { + for (int i = 0; i < t.getChildren().size; i++) { + Element elem = t.getChildren().get(i); + if (elem instanceof CheckBox cb) cb.setDisabled(!enabled); + } + } + } +} diff --git a/src/UnitInfo/ui/draws/UnitDraw.java b/src/UnitInfo/ui/draws/UnitDraw.java new file mode 100644 index 0000000..d3282aa --- /dev/null +++ b/src/UnitInfo/ui/draws/UnitDraw.java @@ -0,0 +1,141 @@ +package UnitInfo.ui.draws; + +import UnitInfo.ui.FreeBar; +import arc.Core; +import arc.graphics.g2d.Lines; +import arc.math.Angles; +import arc.math.Mathf; +import arc.scene.Element; +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.CheckBox; +import arc.scene.ui.layout.Scl; +import arc.scene.ui.layout.Table; +import arc.struct.Seq; +import arc.util.Align; +import arc.util.Log; +import arc.util.Tmp; +import mindustry.Vars; +import mindustry.ai.Pathfinder; +import mindustry.ai.types.*; +import mindustry.entities.units.UnitCommand; +import mindustry.entities.units.UnitController; +import mindustry.game.Team; +import mindustry.gen.Groups; +import mindustry.gen.Tex; +import mindustry.graphics.Pal; +import mindustry.logic.LUnitControl; +import mindustry.ui.Fonts; +import mindustry.ui.Styles; +import mindustry.world.Tile; +import mindustry.world.blocks.storage.CoreBlock; +import mindustry.world.blocks.units.CommandCenter; + +import java.util.Objects; + +import static UnitInfo.core.OverDrawer.isInCamera; +import static UnitInfo.core.OverDrawer.isOutCamera; +import static mindustry.Vars.*; + +public class UnitDraw extends OverDraw { + Seq pathTiles = new Seq<>(); + int otherCores; + boolean pathLine = false, unitLine = false, logicLine = false, bar = false, item = false; + + UnitDraw(String name, TextureRegionDrawable icon) { + super(name, icon); + } + + @Override + public void draw() { + if(!enabled) return; + + Groups.unit.each(u-> isInCamera(u.x, u.y, u.hitSize), u -> { + UnitController c = u.controller(); + UnitCommand com = u.team.data().command; + + if(logicLine && c instanceof LogicAI ai && (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); + } + + if(unitLine && !u.type.flying && com != UnitCommand.idle && !(c instanceof MinerAI || c instanceof BuilderAI || c instanceof RepairAI || c instanceof DefenderAI || c instanceof FormationAI || c instanceof FlyingAI)) { + Lines.stroke(1, u.team.color); + + otherCores = Groups.build.count(b -> b instanceof CoreBlock.CoreBuild && b.team != u.team); + pathTiles.clear(); + getNextTile(u.tileOn(), u.controller() instanceof SuicideAI ? 0 : u.pathType(), u.team, com.ordinal()); + pathTiles.filter(Objects::nonNull); + for(int i = 0; i < pathTiles.size-1; i++) { + Tile from = pathTiles.get(i); + Tile to = pathTiles.get(i + 1); + if(isOutCamera(from.worldx(), from.worldy())) continue; + Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); + } + } + + if(bar) FreeBar.draw(u); + + if(item && !renderer.pixelator.enabled() && u.item() != null && u.itemTime > 0.01f) + Fonts.outline.draw(u.stack.amount + "", + u.x + Angles.trnsx(u.rotation + 180f, u.type.itemOffsetY), + u.y + Angles.trnsy(u.rotation + 180f, u.type.itemOffsetY) - 3, + Pal.accent, 0.25f * u.itemTime / Scl.scl(1f), false, Align.center); + }); + + if(pathLine) spawner.getSpawns().each(t -> { + Team enemyTeam = state.rules.waveTeam; + Lines.stroke(1, enemyTeam.color); + for(int p = 0; p < (Vars.state.rules.spawns.count(g->g.type.naval)>0?3:2); p++) { + pathTiles.clear(); + 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 = 0; i < pathTiles.size-1; i++) { + Tile from = pathTiles.get(i); + Tile to = pathTiles.get(i + 1); + if(isOutCamera(from.worldx(), from.worldy())) continue; + Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); + } + } + }); + } + + 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); + } + + @Override + public void displayStats(Table parent) { + super.displayStats(parent); + + parent.background(Styles.squaret.up); + + parent.check("enable path line", pathLine&&enabled, b->pathLine=b&&enabled).disabled(!enabled).row(); + parent.check("enable logic line", logicLine&&enabled, b->logicLine=b&&enabled).disabled(!enabled).row(); + parent.check("enable unit line", unitLine&&enabled, b->unitLine=b&&enabled).disabled(!enabled).row(); + parent.check("enable unit item", item&&enabled, b->item=b&&enabled).disabled(!enabled).row(); + parent.check("enable unit bar", bar&&enabled, b->bar=b&&enabled).disabled(!enabled).row(); + } + + @Override + public void onEnabled(T param) { + super.onEnabled(param); + + if(param instanceof Table t) { + for (int i = 0; i < t.getChildren().size; i++) { + Element elem = t.getChildren().get(i); + if (elem instanceof CheckBox cb) cb.setDisabled(!enabled); + } + } + } +} diff --git a/src/UnitInfo/ui/windows/CommandDisplay.java b/src/UnitInfo/ui/windows/CommandDisplay.java deleted file mode 100644 index 2cccd81..0000000 --- a/src/UnitInfo/ui/windows/CommandDisplay.java +++ /dev/null @@ -1,64 +0,0 @@ -package UnitInfo.ui.windows; - -import UnitInfo.ui.OverScrollPane; -import arc.Core; -import arc.math.geom.Vec2; -import arc.scene.ui.TextField; -import arc.scene.ui.layout.Table; -import arc.scene.utils.Elem; -import arc.struct.Seq; -import arc.util.CommandHandler; -import mindustry.Vars; -import mindustry.gen.Icon; -import mindustry.graphics.Pal; -import mindustry.ui.Styles; - -public class CommandDisplay extends WindowTable { - Vec2 scrollPos = new Vec2(0, 0); - - public CommandDisplay() { - super("Command Display", Icon.commandRally, t -> { - }); - } - - @Override - public void build() { - scrollPos = new Vec2(0, 0); - top(); - topBar(); - - table(Styles.black8, table -> { - table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("player-pane"); - }).top().right().grow().get().parent = null; - - resizeButton(); - } - - public Table rebuild() { - return new Table(table -> { - for(CommandHandler.Command cmd : Vars.netServer.clientCommands.getCommandList()) { - table.table(cmdtable-> { - Seq fields = new Seq<>(); - cmdtable.table(body->{ - body.left(); - body.table(main->{ - main.add(cmd.text); - for(CommandHandler.CommandParam param : cmd.params) { - TextField field = main.field(null, f->{}).get(); - field.setMessageText(param.name); - fields.add(field); - } - }).left().row(); - body.add(cmd.description).color(Pal.gray).left().row(); - }).minWidth(400f).left(); - cmdtable.button(Icon.play, ()->{ - final String[] params = {""}; - fields.each(f-> params[0] +=" "+f.getText()); - Vars.netServer.clientCommands.handleMessage(Vars.netServer.clientCommands.getPrefix()+cmd.text+params[0], Vars.player); - }); - }).row(); - table.image().height(4f).color(Pal.gray).growX().row(); - } - }); - } -} \ No newline at end of file diff --git a/src/UnitInfo/ui/windows/ToolDisplay.java b/src/UnitInfo/ui/windows/ToolDisplay.java new file mode 100644 index 0000000..e5c9f5f --- /dev/null +++ b/src/UnitInfo/ui/windows/ToolDisplay.java @@ -0,0 +1,85 @@ +package UnitInfo.ui.windows; + +import UnitInfo.ui.OverScrollPane; +import UnitInfo.ui.Updatable; +import UnitInfo.ui.draws.OverDraw; +import UnitInfo.ui.draws.OverDraws; +import UnitInfo.ui.draws.UnitDraw; +import arc.math.Scaled; +import arc.math.geom.Vec2; +import arc.scene.ui.ScrollPane; +import arc.scene.ui.layout.Table; +import arc.util.Scaling; +import arc.util.Time; +import mindustry.gen.Icon; +import mindustry.gen.Tex; +import mindustry.graphics.Pal; +import mindustry.ui.Styles; + +public class ToolDisplay extends WindowTable implements Updatable { + Vec2 scrollPos = new Vec2(0, 0); + OverDraw selected; + float heat; + + public ToolDisplay() { + super("Tool Display", Icon.edit, t -> { + }); + } + + @Override + public void build() { + scrollPos = new Vec2(0, 0); + + top(); + topBar(); + + table(Styles.black8, t -> { + t.left(); + t.table(pane->{ + pane.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).name("tool-pane"); + }).top().marginLeft(4f).marginRight(12f); + t.table(stats->{ + stats.top(); + stats.add(rebuildStats()).name("tool-stats"); + }).growY(); + }).top().right().grow().get().parent = null; + + resizeButton(); + } + + @Override + public void update() { + heat += Time.delta; + if(heat >= 60f) { + heat = 0f; + ScrollPane pane = find("tool-pane"); + pane.setWidget(rebuild()); + } + } + + Table rebuild() { + return new Table(icons->{ + for(OverDraw draw : OverDraws.all) { + icons.button(draw.icon, ()->{ + selected=draw; + Table table = find("tool-stats"); + table.clearChildren(); + table.add(rebuildStats()); + }).grow().tooltip(t->t.background(Styles.black8).add(draw.name).color(Pal.accent)).row(); + } + }); + } + + Table rebuildStats() { + return new Table(tool->{ + if(selected==null) return; + tool.top(); + tool.table(Tex.underline2, label->label.add(selected.name).color(Pal.accent)).row(); + tool.table(des-> selected.displayStats(des)).name("unit-stats").row(); + tool.check("enable", selected.enabled, c->{ + selected.enabled=c; + selected.onEnabled(find("unit-stats")); + }); + }); + } +} \ No newline at end of file diff --git a/src/UnitInfo/ui/windows/WindowTables.java b/src/UnitInfo/ui/windows/WindowTables.java index 0f6af6a..8d9df67 100644 --- a/src/UnitInfo/ui/windows/WindowTables.java +++ b/src/UnitInfo/ui/windows/WindowTables.java @@ -2,13 +2,13 @@ package UnitInfo.ui.windows; public class WindowTables { public static WindowTable - unitTable, waveTable, coreTable, playerTable, commandTable; + unitTable, waveTable, coreTable, playerTable, toolTable; public static void init() { unitTable = new UnitDisplay(); waveTable = new WaveDisplay(); coreTable = new CoreDisplay(); playerTable = new PlayerDisplay(); - commandTable = new CommandDisplay(); + toolTable = new ToolDisplay(); } }