add ToolDisplay

This commit is contained in:
sharlottes
2022-04-17 17:35:55 +09:00
parent 78f3b2d782
commit 81b2215c9a
15 changed files with 626 additions and 350 deletions

View File

@@ -4,6 +4,7 @@ import UnitInfo.core.*;
import UnitInfo.shaders.LineShader; import UnitInfo.shaders.LineShader;
import UnitInfo.shaders.RangeShader; import UnitInfo.shaders.RangeShader;
import arc.graphics.g2d.TextureRegion; import arc.graphics.g2d.TextureRegion;
import mindustry.gen.Teamc;
import static arc.Core.atlas; import static arc.Core.atlas;
import static arc.Core.settings; import static arc.Core.settings;
@@ -11,10 +12,11 @@ import static arc.Core.settings;
public class SVars { public class SVars {
public static HudUi hud = new HudUi(); public static HudUi hud = new HudUi();
public static float modUiScale = settings.getInt("infoUiScale"); 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 clear = atlas.find("clear");
public static TextureRegion error = atlas.find("error"); public static TextureRegion error = atlas.find("error");
public static RangeShader turretRange; public static RangeShader turretRange;
public static LineShader lineShader; public static LineShader lineShader;
public static Teamc target;
public static boolean locked;
public static boolean jsonGen = false; public static boolean jsonGen = false;
} }

View File

@@ -66,8 +66,7 @@ public class HudUi {
float heat = 0; float heat = 0;
public void setEvents() { public void setEvents() {
Events.run(EventType.Trigger.update, ()->{ Events.run(EventType.Trigger.update, ()->{
OverDrawer.target = getTarget(); target = getTarget();
OverDrawer.locked = locked;
if(settings.getBool("deadTarget") && locked && lockedTarget != null && !Groups.all.contains(e -> e == lockedTarget)) { if(settings.getBool("deadTarget") && locked && lockedTarget != null && !Groups.all.contains(e -> e == lockedTarget)) {
lockedTarget = null; lockedTarget = null;
locked = false; 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 waveTable = (Table) scene.find("waves");
Table infoTable = (Table) scene.find("infotable"); Table infoTable = (Table) scene.find("infotable");
waveTable.removeChild(infoTable); waveTable.removeChild(infoTable);
waveTable.row(); waveTable.row();
waveTable.stack( 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 -> { new Table(tt -> tt.button(Icon.downOpen, Styles.clearToggleTransi, () -> waveShown = !waveShown).size(4 * 8f).checked(b -> {
b.getImage().setDrawable(waveShown ? Icon.upOpen : Icon.downOpen); b.getImage().setDrawable(waveShown ? Icon.upOpen : Icon.downOpen);
return waveShown; return waveShown;

View File

@@ -2,6 +2,7 @@ package UnitInfo.core;
import UnitInfo.shaders.*; import UnitInfo.shaders.*;
import UnitInfo.ui.*; import UnitInfo.ui.*;
import UnitInfo.ui.draws.OverDraws;
import UnitInfo.ui.windows.*; import UnitInfo.ui.windows.*;
import arc.*; import arc.*;
import arc.scene.ui.Dialog; import arc.scene.ui.Dialog;
@@ -42,6 +43,7 @@ public class Main extends Mod {
SettingS.init(); SettingS.init();
MindowsTex.init(); MindowsTex.init();
WindowTables.init(); WindowTables.init();
OverDraws.init();
new HUDFragment().build(Vars.ui.hudGroup); new HUDFragment().build(Vars.ui.hudGroup);
hud = new HudUi(); hud = new HudUi();

View File

@@ -1,6 +1,8 @@
package UnitInfo.core; package UnitInfo.core;
import UnitInfo.ui.*; import UnitInfo.ui.*;
import UnitInfo.ui.draws.OverDraw;
import UnitInfo.ui.draws.OverDraws;
import arc.*; import arc.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
@@ -13,7 +15,6 @@ import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.ai.*; import mindustry.ai.*;
import mindustry.ai.types.*; import mindustry.ai.types.*;
import mindustry.core.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -22,8 +23,6 @@ import mindustry.logic.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.defense.turrets.*; 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.storage.*;
import mindustry.world.blocks.units.*; import mindustry.world.blocks.units.*;
@@ -34,23 +33,13 @@ import static arc.Core.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class OverDrawer { public class OverDrawer {
public static Teamc target;
public static Seq<MassDriver.MassDriverBuild> linkedMasses = new Seq<>();
public static Seq<PayloadMassDriver.PayloadDriverBuild> linkedPayloadMasses = new Seq<>();
public static Seq<Building> linkedNodes = new Seq<>();
public static Seq<Tile> pathTiles = new Seq<>();
public static FrameBuffer effectBuffer = new FrameBuffer();
public static int otherCores;
public static boolean locked;
public static ObjectMap<Team, Seq<BaseTurret.BaseTurretBuild>> tmpbuildobj = new ObjectMap<>();
public static void setEvent(){ public static void setEvent(){
Events.run(EventType.Trigger.draw, () -> { Events.run(EventType.Trigger.draw, () -> {
float sin = Mathf.absin(Time.time, 6f, 1f); float sin = Mathf.absin(Time.time, 6f, 1f);
effectBuffer.resize(graphics.getWidth(), graphics.getHeight());
Draw.z(Layer.max); Draw.z(Layer.max);
//local drawing, drawn on player/camera position //local drawing, drawn on player/camera position
if(settings.getBool("spawnerarrow")) { if(settings.getBool("spawnerarrow")) {
float leng = (player.unit() != null && player.unit().hitSize > 4 * 8f ? player.unit().hitSize * 1.5f : 4 * 8f) + sin; 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 //global drawing, which needs camera-clipping
Core.camera.bounds(Tmp.r1); Core.camera.bounds(Tmp.r1);
Groups.unit.each(u-> isInCamera(u.x, u.y, u.hitSize), u -> { for(OverDraw drawer : OverDraws.all) drawer.draw();
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);
}
}
});
}
}); });
} }
static boolean isOutCamera(float x, float y) { public static boolean isOutCamera(float x, float y) {
return !isInCamera(x, y, 0); 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); Tmp.r2.setCentered(x, y, size);
return Tmp.r1.overlaps(Tmp.r2); 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);
}
}
}
} }

View File

@@ -116,10 +116,11 @@ public class SettingS {
addGraphicCheckSetting("itemcal", false, tapSeq); addGraphicCheckSetting("itemcal", false, tapSeq);
addGraphicCheckSetting("schem", !mobile, tapSeq); addGraphicCheckSetting("schem", !mobile, tapSeq);
//TODO: remove all drawing settings
Seq<SharSetting> rangeSeq = new Seq<>(); Seq<SharSetting> rangeSeq = new Seq<>();
addGraphicTypeSetting("rangeRadius", 0, 500, 70, true, () -> true, s -> s + "tiles", rangeSeq); //addGraphicTypeSetting("rangeRadius", 0, 500, 70, true, () -> true, s -> s + "tiles", rangeSeq);
addGraphicCheckSetting("rangeNearby", true, rangeSeq); //addGraphicCheckSetting("rangeNearby", true, rangeSeq);
addGraphicCheckSetting("allTargetRange", false, rangeSeq); //addGraphicCheckSetting("allTargetRange", false, rangeSeq);
addGraphicCheckSetting("aliceRange", false, rangeSeq); addGraphicCheckSetting("aliceRange", false, rangeSeq);
addGraphicCheckSetting("RangeShader", false, rangeSeq); addGraphicCheckSetting("RangeShader", false, rangeSeq);
@@ -130,6 +131,7 @@ public class SettingS {
addGraphicSlideSetting("softRangeOpacity", 60, 0, 100, 10, s -> s + "%", opacitySeq); addGraphicSlideSetting("softRangeOpacity", 60, 0, 100, 10, s -> s + "%", opacitySeq);
Seq<SharSetting> drawSeq = new Seq<>(); Seq<SharSetting> drawSeq = new Seq<>();
/*
addGraphicTypeSetting("pathlinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq); addGraphicTypeSetting("pathlinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq);
addGraphicTypeSetting("unitlinelimit", 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); addGraphicTypeSetting("logiclinelimit", 0, 5000, 50, true, () -> true, s -> s + "lines", drawSeq);
@@ -139,8 +141,9 @@ public class SettingS {
addGraphicCheckSetting("blockfont", false, drawSeq); addGraphicCheckSetting("blockfont", false, drawSeq);
addGraphicCheckSetting("linkedMass", true, drawSeq); addGraphicCheckSetting("linkedMass", true, drawSeq);
addGraphicCheckSetting("linkedNode", false, drawSeq); addGraphicCheckSetting("linkedNode", false, drawSeq);
addGraphicCheckSetting("select", false, drawSeq);
addGraphicCheckSetting("deadTarget", false, drawSeq); addGraphicCheckSetting("deadTarget", false, drawSeq);
*/
addGraphicCheckSetting("select", false, drawSeq);
addGraphicCheckSetting("distanceLine", false, drawSeq); addGraphicCheckSetting("distanceLine", false, drawSeq);
addGraphicCheckSetting("spawnerarrow", false, drawSeq); addGraphicCheckSetting("spawnerarrow", false, drawSeq);
addGraphicCheckSetting("elementdebug", false, drawSeq); addGraphicCheckSetting("elementdebug", false, drawSeq);

View File

@@ -19,7 +19,7 @@ public class HUDFragment extends Fragment{
waveTable, waveTable,
coreTable, coreTable,
playerTable, playerTable,
commandTable toolTable
)).visible(TaskbarTable.visibility); )).visible(TaskbarTable.visibility);
// windows (totally not a copyright violation) // windows (totally not a copyright violation)
@@ -27,7 +27,7 @@ public class HUDFragment extends Fragment{
t.add(waveTable).size(250f).visible(false); t.add(waveTable).size(250f).visible(false);
t.add(coreTable).size(250f).visible(false); t.add(coreTable).size(250f).visible(false);
t.add(playerTable).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(()->{ t.update(()->{
for (Element child : t.getChildren()) { for (Element child : t.getChildren()) {

View File

@@ -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 <T> 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);
}
}
}
}

View File

@@ -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<MassDriver.MassDriverBuild> linkedMasses = new Seq<>();
Seq<PayloadMassDriver.PayloadDriverBuild> linkedPayloadMasses = new Seq<>();
Seq<Building> 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 <T> 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);
}
}
}
}

View File

@@ -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 <T> void onEnabled(T param) {}
}

View File

@@ -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};
}
}

View File

@@ -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<Team, Seq<BaseTurret.BaseTurretBuild>> 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 <T> 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);
}
}
}
}

View File

@@ -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<Tile> 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 <T> 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);
}
}
}
}

View File

@@ -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<TextField> 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();
}
});
}
}

View File

@@ -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"));
});
});
}
}

View File

@@ -2,13 +2,13 @@ package UnitInfo.ui.windows;
public class WindowTables { public class WindowTables {
public static WindowTable public static WindowTable
unitTable, waveTable, coreTable, playerTable, commandTable; unitTable, waveTable, coreTable, playerTable, toolTable;
public static void init() { public static void init() {
unitTable = new UnitDisplay(); unitTable = new UnitDisplay();
waveTable = new WaveDisplay(); waveTable = new WaveDisplay();
coreTable = new CoreDisplay(); coreTable = new CoreDisplay();
playerTable = new PlayerDisplay(); playerTable = new PlayerDisplay();
commandTable = new CommandDisplay(); toolTable = new ToolDisplay();
} }
} }