mirror of
https://github.com/yawaflua/Informatis.git
synced 2025-12-10 12:09:27 +02:00
add ToolDisplay
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
48
src/UnitInfo/ui/draws/BlockDraw.java
Normal file
48
src/UnitInfo/ui/draws/BlockDraw.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
183
src/UnitInfo/ui/draws/LinkDraw.java
Normal file
183
src/UnitInfo/ui/draws/LinkDraw.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/UnitInfo/ui/draws/OverDraw.java
Normal file
20
src/UnitInfo/ui/draws/OverDraw.java
Normal 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) {}
|
||||||
|
}
|
||||||
|
|
||||||
16
src/UnitInfo/ui/draws/OverDraws.java
Normal file
16
src/UnitInfo/ui/draws/OverDraws.java
Normal 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};
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/UnitInfo/ui/draws/RangeDraw.java
Normal file
109
src/UnitInfo/ui/draws/RangeDraw.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
141
src/UnitInfo/ui/draws/UnitDraw.java
Normal file
141
src/UnitInfo/ui/draws/UnitDraw.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
85
src/UnitInfo/ui/windows/ToolDisplay.java
Normal file
85
src/UnitInfo/ui/windows/ToolDisplay.java
Normal 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"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user