diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index 42ada5e..530af76 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -72,24 +72,22 @@ setting.elementdebug.description = Show all Element outline setting.hiddenElem.name = Display hidden element setting.hiddenElem.description = display hidden element outline too. -setting.shar-title = UnitInfo Settings +setting.shar-title = unitinfo Settings setting.shar-ui = Overlay UI Settings setting.shar-draw = Overdrawing Settings #Hud hud.schematic-list = Schematic List -hud.unit = Unit Info -hud.wave = Wave Info -hud.item = Resource Info -hud.cancel = Hidden -hud.enabled = [accent]Enabled[] -hud.disabled = [gray]Disabled[] -hud.pathline = Path Line -hud.unitline = Unit Line -hud.logicline = Logic Line + +#Window +window.unit.name = Unit Display +window.wave.name = Wave Display +window.core.name = Core Display +window.player.name = Player Display +window.tool.name = Tool Display [red](WIP)[] +window.editor.name = Map Editor Display [red](WIP)[] #Other -sec = sec default-bar = default bar th-bar = th bar empty = [lightgray][] diff --git a/assets/bundles/bundle_ko.properties b/assets/bundles/bundle_ko.properties index 141c07a..529fe18 100644 --- a/assets/bundles/bundle_ko.properties +++ b/assets/bundles/bundle_ko.properties @@ -89,7 +89,7 @@ setting.hiddenElem.description = 숨겨진 요소의 외곽선도 표시합니 setting.autoShooting.name = 자동 사격 활성화 setting.autoShooting.description = -setting.shar-title = UnitInfo 설정 +setting.shar-title = unitinfo 설정 setting.shar-ui = 정보UI 설정 setting.shar-range = 자동 사거리 설정 setting.shar-opacity = 투명도 설정 diff --git a/assets/bundles/bundle_ru.properties b/assets/bundles/bundle_ru.properties index b7acc9b..b97cee9 100644 --- a/assets/bundles/bundle_ru.properties +++ b/assets/bundles/bundle_ru.properties @@ -77,7 +77,7 @@ setting.distanceLine.description = display dotted lines and numbers how far away setting.autoShooting.name = Включить автострельбу. setting.autoShooting.description = [red]не читери, не будь какахой -setting.shar-title = Настройки UnitInfo +setting.shar-title = Настройки unitinfo setting.shar-wave = InfoTap Setting setting.shar-range = AutoRange Setting setting.shar-opacity = Opacity Setting diff --git a/assets/bundles/bundle_tr.properties b/assets/bundles/bundle_tr.properties index 61d672f..c1c0569 100644 --- a/assets/bundles/bundle_tr.properties +++ b/assets/bundles/bundle_tr.properties @@ -83,7 +83,7 @@ setting.spawnerarrow.description = setting.autoShooting.name = Enable Auto Shooting setting.autoShooting.description = no don't do hack -setting.shar-title = UnitInfo Ayarları +setting.shar-title = unitinfo Ayarları setting.shar-ui = Arayüz Ayarları setting.shar-range = Oto-Uzaklık Ayarları setting.shar-opacity = Opaklık Ayarları diff --git a/assets/bundles/bundle_uk_UA.properties b/assets/bundles/bundle_uk_UA.properties index 1e20e10..4131a6b 100644 --- a/assets/bundles/bundle_uk_UA.properties +++ b/assets/bundles/bundle_uk_UA.properties @@ -86,7 +86,7 @@ setting.spawnerarrow.description = Показує стрілку, направл setting.autoShooting.name = Увімкнути автострільбу setting.autoShooting.description = Не треба, ти ж не гакер. -setting.shar-title = Налаштування UnitInfo +setting.shar-title = Налаштування unitinfo setting.shar-ui = Налаштування накладання інтерфейсу setting.shar-range = Налаштування автоматичного діапазону setting.shar-opacity = Налаштування прозорості diff --git a/assets/mod.json b/assets/mod.json index b1a68d5..7f2697a 100644 --- a/assets/mod.json +++ b/assets/mod.json @@ -4,7 +4,7 @@ "author": "Sharlotte", "description": "The mod displays more information in-game, such as unit/building, wave, core, tile, item/unit total info etc", "version": "1.5.5", - "main": "UnitInfo.core.Main", + "main": "unitinfo.core.Main", "minGameVersion": "135", "dependencies": [], "hidden": true, diff --git a/gradle.properties b/gradle.properties index 154521a..fd22e4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Filename of output file (dexify prepends 'dexed-') (people will hate you if it isn't .jar) -pArtifactFilename = UnitInfo.jar +pArtifactFilename = unitinfo.jar # Group of project (should line up with dirs in src/) pGroup = sharlotte # Version of Mindustry to use (if not working, consult jitpack.io) diff --git a/src/UnitInfo/ui/HUDFragment.java b/src/UnitInfo/ui/HUDFragment.java deleted file mode 100644 index b1d34c7..0000000 --- a/src/UnitInfo/ui/HUDFragment.java +++ /dev/null @@ -1,41 +0,0 @@ -package UnitInfo.ui; - -import arc.scene.*; -import mindustry.ui.fragments.*; - -import static UnitInfo.ui.windows.WindowTables.*; - -public class HUDFragment extends Fragment{ - @Override - public void build(Group parent){ - parent.fill(t -> { - t.name = "Windows"; - t.visible(() -> parent.visible); - - t.center().left(); - // sidebar - t.add(new TaskbarTable( - unitTable, - waveTable, - coreTable, - playerTable, - toolTable, - editorTable - )).visible(TaskbarTable.visibility); - - // windows (totally not a copyright violation) - t.add(unitTable).size(250f).visible(false); - t.add(waveTable).size(250f).visible(false); - t.add(coreTable).size(250f).visible(false); - t.add(playerTable).size(250f).visible(false); - t.add(toolTable).size(250f).visible(false); - t.add(editorTable).size(250f).visible(false); - - t.update(()->{ - for (Element child : t.getChildren()) { - if(child instanceof Updatable u) u.update(); - } - }); - }); - }; -} \ No newline at end of file diff --git a/src/UnitInfo/ui/MindowsTex.java b/src/UnitInfo/ui/MindowsTex.java deleted file mode 100644 index ccbbbb4..0000000 --- a/src/UnitInfo/ui/MindowsTex.java +++ /dev/null @@ -1,12 +0,0 @@ -package UnitInfo.ui; - -import arc.*; -import arc.scene.style.*; - -public class MindowsTex{ - public static Drawable sidebar; - - public static void init(){ - sidebar = Core.atlas.drawable("unitinfo-sidebar"); - } -} \ No newline at end of file diff --git a/src/UnitInfo/ui/TaskbarTable.java b/src/UnitInfo/ui/TaskbarTable.java deleted file mode 100644 index b1ea186..0000000 --- a/src/UnitInfo/ui/TaskbarTable.java +++ /dev/null @@ -1,24 +0,0 @@ -package UnitInfo.ui; - -import UnitInfo.ui.windows.WindowTable; -import arc.func.*; -import arc.scene.ui.layout.*; -import mindustry.*; -import mindustry.ui.*; - -public class TaskbarTable extends Table{ - public static Boolp visibility = () -> Vars.ui.hudfrag.shown && !Vars.ui.minimapfrag.shown(); - - public TaskbarTable(WindowTable... items){ - visible = true; - table(MindowsTex.sidebar, t -> { - t.top().center(); - for(WindowTable w : items){ - t.button(w.icon, Styles.emptyi, () -> { - w.visible(visibility); - }).disabled(b -> w.visible).size(40f).padRight(5f); - t.row(); - } - }).left().center().width(40f); - } -} \ No newline at end of file diff --git a/src/UnitInfo/ui/windows/MapEditorDisplay.java b/src/UnitInfo/ui/windows/MapEditorDisplay.java deleted file mode 100644 index ce11b51..0000000 --- a/src/UnitInfo/ui/windows/MapEditorDisplay.java +++ /dev/null @@ -1,335 +0,0 @@ -package UnitInfo.ui.windows; - -import UnitInfo.ui.EditorTool; -import UnitInfo.ui.OverScrollPane; -import UnitInfo.ui.Updatable; -import arc.Core; -import arc.Events; -import arc.func.Boolf; -import arc.func.Cons; -import arc.func.Prov; -import arc.graphics.Color; -import arc.input.KeyCode; -import arc.math.Mathf; -import arc.math.geom.Point2; -import arc.math.geom.Vec2; -import arc.scene.event.Touchable; -import arc.scene.style.TextureRegionDrawable; -import arc.scene.ui.*; -import arc.scene.ui.layout.Scl; -import arc.scene.ui.layout.Table; -import arc.scene.utils.Elem; -import arc.struct.IntSeq; -import arc.struct.Seq; -import arc.util.*; -import mindustry.Vars; -import mindustry.content.Blocks; -import mindustry.editor.DrawOperation; -import mindustry.game.EventType; -import mindustry.game.Team; -import mindustry.gen.Icon; -import mindustry.gen.Tex; -import mindustry.gen.TileOp; -import mindustry.graphics.Pal; -import mindustry.ui.Styles; -import mindustry.world.Block; -import mindustry.world.Tile; - -import static mindustry.Vars.*; - -public class MapEditorDisplay extends WindowTable implements Updatable { - Vec2 scrollPos = new Vec2(0, 0); - TextField search; - Table window; - float heat; - float brushSize = -1; - UnitInfo.ui.EditorTool tool; - - public static Team drawTeam = Team.sharded; - public static Block selected = Blocks.router; - - public MapEditorDisplay() { - super("Map Editor Display", Icon.map, t -> {}); - } - - @Override - public void build() { - scrollPos = new Vec2(0, 0); - search = Elem.newField(null, f->{}); - search.setMessageText("Search..."); - - top(); - topBar(); - - table(Styles.black8, table -> { - window=table; - table.table(t->{ - t.left().background(Tex.underline2); - t.label(()->"[accent]"+selected.localizedName+"[] "+selected.emoji()); - t.add(search).growX().pad(8).name("search"); - }).growX().row(); - table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("editor-pane"); - }).top().right().grow().get().parent = null; - - resizeButton(); - } - - boolean hold = false; - int pastX, pastY; - @Override - public void update() { - heat += Time.delta; - if(heat >= 60f) { - heat = 0f; - resetPane(); - } - if(tool != null) { - if(Core.input.isTouched()) { - if(!(!mobile&&Core.input.keyDown(KeyCode.mouseLeft))) return; - if(tool== EditorTool.line) { - if(!hold) { - pastX = (int) player.mouseX / 8; - pastY = (int) player.mouseY / 8; - } - hold = true; - } - else { - pastX = (int) player.mouseX / 8; - pastY = (int) player.mouseY / 8; - } - - tool.touched(pastX, pastY); - } - else if(tool== EditorTool.line) { - if(hold&&pastX>=0&&pastY>=0) tool.touchedLine(pastX, pastY, (int) player.mouseX/8, (int) player.mouseY/8); - hold = false; - pastX = -1; - pastY = -1; - } - } - } - - void resetPane() { - ScrollPane pane = find("editor-pane"); - pane.setWidget(rebuild()); - } - - public Table rebuild() { - return new Table(table-> { - table.top(); - Seq blocks = Vars.content.blocks().copy(); - if(search.getText().length() > 0){ - blocks.filter(p -> p.name.toLowerCase().contains(search.getText().toLowerCase())||p.localizedName.toLowerCase().contains(search.getText().toLowerCase())); - } - table.table(select->buildTable(Blocks.boulder, select, blocks, ()->selected, block->selected=block, false)).marginTop(16f).marginBottom(16f).row(); - table.image().height(4f).color(Pal.gray).growX().row(); - table.table(body-> { - body.table(tools -> { - tools.top().left(); - tools.table(title -> title.left().background(Tex.underline2).add("Tools [accent]"+(tool==null?"":tool.name())+"[]")).growX().row(); - tools.table(bt->{ - Cons addTool = tool -> { - ImageButton button = new ImageButton(ui.getIcon(tool.name()), Styles.clearTogglei); - button.clicked(() -> { - button.toggle(); - if(this.tool==tool) this.tool = null; - else this.tool = tool; - resetPane(); - }); - button.update(()->button.setChecked(this.tool == tool)); - - Label mode = new Label(""); - mode.setColor(Pal.remove); - mode.update(() -> mode.setText(tool.mode == -1 ? "" : "M" + (tool.mode + 1) + " ")); - mode.setAlignment(Align.bottomRight, Align.bottomRight); - mode.touchable = Touchable.disabled; - - bt.stack(button, mode); - }; - - addTool.get(UnitInfo.ui.EditorTool.line); - addTool.get(UnitInfo.ui.EditorTool.pencil); - addTool.get(UnitInfo.ui.EditorTool.eraser); - addTool.get(UnitInfo.ui.EditorTool.fill); - addTool.get(UnitInfo.ui.EditorTool.spray); - }); - tools.row(); - Slider slider = new Slider(1, 16, 1, false); - slider.moved(size->brushSize=size); - slider.setValue(brushSize); - Label label = new Label("Brush: "+brushSize); - label.touchable = Touchable.disabled; - tools.stack(slider, label).width(window.getWidth()/5).center(); - }).left().width(window.getWidth() / 2).margin(8f).growY(); - body.image().width(4f).height(body.getHeight()).color(Pal.gray).growY(); - body.table(options -> { - options.top().left(); - options.table(title -> title.left().background(Tex.underline2).add("Options [accent]"+(tool!=null&&tool.mode>=0&&tool.mode { - option.defaults().size(300f, 70f).left(); - if(tool==null) return; - - for (int i = 0; i < tool.altModes.length; i++) { - int mode = i; - String name = tool.altModes[i]; - - option.button(b -> { - b.left().marginLeft(6); - b.setStyle(Styles.clearTogglet); - b.add(Core.bundle.get("toolmode." + name)).left().row(); - b.add(Core.bundle.get("toolmode." + name + ".description")).color(Color.lightGray).left(); - }, () -> { - tool.mode = (tool.mode == mode ? -1 : mode); - }).update(b -> b.setChecked(tool.mode == mode)); - option.row(); - } - }); - }).left().width(window.getWidth() / 2).margin(8f).growY(); - }).grow(); - }); - } - - void buildTable(@Nullable Block block, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ - ButtonGroup group = new ButtonGroup<>(); - group.setMinCheckCount(0); - Table cont = new Table(); - cont.defaults().size(40); - - int i = 0; - int max = Math.max(4, Math.round(window.getWidth()/64)); - - for(T item : items){ - if(!item.unlockedNow()) continue; - - ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> { - if(closeSelect) control.input.frag.config.hideConfig(); - }).group(group).tooltip(t->t.background(Styles.black8).add(item.localizedName)).get(); - button.changed(() -> consumer.get(button.isChecked() ? item : null)); - button.getStyle().imageUp = new TextureRegionDrawable(item.uiIcon); - button.update(() -> button.setChecked(holder.get() == item)); - - if(i++ % max == max-1){ - cont.row(); - } - } - - //add extra blank spaces so it looks nice - if(i % max != 0){ - int remaining = max - (i % max); - for(int j = 0; j < remaining; j++){ - cont.image(Styles.black6); - } - } - - ScrollPane pane = new ScrollPane(cont, Styles.smallPane); - pane.setScrollingDisabled(true, false); - - if(block != null){ - pane.setScrollYForce(block.selectScroll); - pane.update(() -> { - block.selectScroll = pane.getScrollY(); - }); - } - - pane.setOverscroll(false, false); - table.add(pane).maxHeight(Scl.scl(40 * 5)); - } - - public void drawBlocksReplace(int x, int y){ - drawBlocks(x, y, tile -> tile.block() != Blocks.air || selected.isFloor()); - } - - public void drawBlocks(int x, int y){ - drawBlocks(x, y, false, tile -> true); - } - - public void drawBlocks(int x, int y, Boolf tester){ - drawBlocks(x, y, false, tester); - } - - int rotation = 0; - public void drawBlocks(int x, int y, boolean square, Boolf tester){ - if(selected.isMultiblock()){ - x = Mathf.clamp(x, (selected.size - 1) / 2, world.width() - selected.size / 2 - 1); - y = Mathf.clamp(y, (selected.size - 1) / 2, world.height() - selected.size / 2 - 1); - if(!hasOverlap(x, y)){ - world.tile(x, y).setBlock(selected, drawTeam, rotation); - } - }else{ - boolean isFloor = selected.isFloor() && selected != Blocks.air; - - Cons drawer = tile -> { - if(!tester.get(tile)) return; - - if(isFloor){ - tile.setFloor(selected.asFloor()); - }else if(!(tile.block().isMultiblock() && !selected.isMultiblock())){ - tile.setBlock(selected, drawTeam, rotation); - } - }; - - if(square){ - drawSquare(x, y, drawer); - }else{ - drawCircle(x, y, drawer); - } - } - } - - public void drawCircle(int x, int y, Cons drawer){ - int clamped = (int)brushSize; - for(int rx = -clamped; rx <= clamped; rx++){ - for(int ry = -clamped; ry <= clamped; ry++){ - if(Mathf.within(rx, ry, brushSize - 0.5f + 0.0001f)){ - int wx = x + rx, wy = y + ry; - - if(wx < 0 || wy < 0 || wx >= world.width() || wy >= world.height()){ - continue; - } - - drawer.get(world.tile(wx, wy)); - } - } - } - } - - public void drawSquare(int x, int y, Cons drawer){ - int clamped = (int)brushSize; - for(int rx = -clamped; rx <= clamped; rx++){ - for(int ry = -clamped; ry <= clamped; ry++){ - int wx = x + rx, wy = y + ry; - - if(wx < 0 || wy < 0 || wx >= world.width() || wy >= world.height()){ - continue; - } - - drawer.get(world.tile(wx, wy)); - } - } - } - - boolean hasOverlap(int x, int y){ - Tile tile = world.tile(x, y); - //allow direct replacement of blocks of the same size - if(tile != null && tile.isCenter() && tile.block() != selected && tile.block().size == selected.size && tile.x == x && tile.y == y){ - return false; - } - - //else, check for overlap - int offsetx = -(selected.size - 1) / 2; - int offsety = -(selected.size - 1) / 2; - for(int dx = 0; dx < selected.size; dx++){ - for(int dy = 0; dy < selected.size; dy++){ - int worldx = dx + offsetx + x; - int worldy = dy + offsety + y; - Tile other = world.tile(worldx, worldy); - - if(other != null && other.block().isMultiblock()){ - return true; - } - } - } - - return false; - } -} diff --git a/src/UnitInfo/ui/windows/UnitDisplay.java b/src/UnitInfo/ui/windows/UnitDisplay.java deleted file mode 100644 index d551570..0000000 --- a/src/UnitInfo/ui/windows/UnitDisplay.java +++ /dev/null @@ -1,404 +0,0 @@ -package UnitInfo.ui.windows; - -import UnitInfo.SVars; -import UnitInfo.core.BarInfo; -import UnitInfo.ui.SBar; -import UnitInfo.ui.SIcons; -import UnitInfo.ui.Updatable; -import UnitInfo.ui.windows.WindowTable; -import arc.Core; -import arc.func.Prov; -import arc.graphics.Color; -import arc.graphics.g2d.*; -import arc.input.KeyCode; -import arc.math.Mathf; -import arc.math.geom.Rect; -import arc.math.geom.Vec2; -import arc.math.geom.Vec3; -import arc.scene.Element; -import arc.scene.style.*; -import arc.scene.ui.*; -import arc.scene.ui.layout.*; -import arc.struct.Bits; -import arc.struct.Seq; -import arc.util.*; -import mindustry.Vars; -import mindustry.ai.formations.FormationPattern; -import mindustry.core.UI; -import mindustry.entities.units.WeaponMount; -import mindustry.gen.*; -import mindustry.graphics.Pal; -import mindustry.type.StatusEffect; -import mindustry.type.Weapon; -import mindustry.ui.Styles; -import mindustry.world.blocks.ConstructBlock; -import mindustry.world.blocks.defense.ForceProjector; -import mindustry.world.blocks.defense.turrets.*; -import mindustry.world.blocks.distribution.MassDriver; -import mindustry.world.blocks.payloads.Payload; -import mindustry.world.blocks.power.*; - -import static UnitInfo.SVars.*; -import static UnitInfo.SUtils.*; -import static arc.Core.*; -import static mindustry.Vars.*; - -public class UnitDisplay extends WindowTable implements Updatable { - static Seq lastColors = Seq.with(Color.clear,Color.clear,Color.clear,Color.clear,Color.clear,Color.clear); - static final Rect scissor = new Rect(); - float scrollPos; - - public UnitDisplay() { - super("Unit Display", Icon.units, t -> {}); - } - - @Override - public void build() { - top(); - topBar(); - - //TODO: add new UnitInfoDisplay(), new WeaponDisplay(); - table(Styles.black8, t -> { - t.table(Tex.underline2, tt -> { - tt.stack( - new Table(ttt -> { - Prov reg = () -> { - TextureRegion region = clear; - Teamc target = getTarget(); - if (target instanceof Unit u && u.type != null) region = u.type.uiIcon; - else if (target instanceof Building b) { - if (target instanceof ConstructBlock.ConstructBuild cb) - region = cb.current.uiIcon; - else if (b.block != null) region = b.block.uiIcon; - } - return new TextureRegionDrawable(region); - }; - Drawable img = reg.get(); - ImageButton imagebt = new ImageButton(img, img); - - imagebt.hovered(() -> { - Time.run(60 * 2, () -> { - if (imagebt.isOver()) lockTarget(); - }); - }); - imagebt.clicked(() -> { - Teamc target = getTarget(); - if (target instanceof Unit u && u.type != null) ui.content.show(u.type); - else if (target instanceof Building b && b.block != null) ui.content.show(b.block); - }); - ttt.add(imagebt).update((i) -> { - i.getStyle().imageUp = reg.get().tint(Tmp.c1.set(locked ? Color.red.cpy().shiftHue(2 * Time.time) : Color.white)); - i.getStyle().imageDown = reg.get().tint(Tmp.c1.mul(Color.darkGray)); - i.layout(); - }).size(4 * 8f).get().parent = null; - }), - new Table(ttt -> { - ttt.stack( - new Table(temp -> { - temp.image(new ScaledNinePatchDrawable(new NinePatch(Icon.defenseSmall.getRegion()), 1)); - temp.visibility = () -> getTarget() instanceof Unit; - }), - new Table(temp -> { - Label label = new Label(() -> (getTarget() instanceof Unit u && u.type != null ? (int) u.type.armor + "" : "")); - label.setColor(Pal.surge); - temp.add(label).center(); - temp.pack(); - }) - ).padLeft(2 * 8f).padBottom(2 * 8f).get().parent = null; - }) - ); - - tt.label(() -> { - String name = ""; - Teamc target = getTarget(); - if (target instanceof Unit u && u.type != null) - name = u.type.localizedName; - if (target instanceof Building b && b.block != null) { - if (target instanceof ConstructBlock.ConstructBuild cb) - name = cb.current.localizedName; - else name = b.block.localizedName; - } - return "[accent]" + (name.length() > 13 ? name.substring(0, 13) + "..." : name) + "[]"; - }).get().parent = null; - - tt.addListener(new Tooltip(to -> { - Teamc target = getTarget(); - - to.background(Styles.black6); - - to.table(Tex.underline2, tool2 -> { - tool2.label(() -> { - if (target instanceof Unit u) return u.type.localizedName; - else if (target instanceof Building b) return b.block.localizedName; - else return ""; - }); - }).row(); - to.label(() -> target instanceof Unit u && u.isPlayer() ? u.getPlayer().name() : "AI").row(); - to.label(() -> target == null - ? "(" + 0 + ", " + 0 + ")" - : "(" + Strings.fixed(target.x() / tilesize, 2) + ", " + Strings.fixed(target.y() / tilesize, 2) + ")").row(); - })); - tt.update(() -> tt.setBackground(((NinePatchDrawable) Tex.underline2).tint(getTarget() == null ? Color.gray : getTarget().team().color))).parent = null; - }).row(); - ScrollPane pane = t.pane(Styles.nonePane, new Table(tt -> { - for (int i = 0; i < 6; i++) { - addBar(tt, i); - tt.row(); - } - }).left()).top().right().grow().get(); - pane.parent = null; - pane.update(() -> { - Element result = scene.hit(input.mouseX(), input.mouseY(), true); - if(pane.hasScroll() && (result == null || !result.isDescendantOf(pane))) - scene.setScrollFocus(null); - scrollPos = pane.getScrollY(); - }); - - pane.setOverscroll(false, false); - pane.setScrollingDisabled(true, false); - pane.setScrollYForce(scrollPos); - }).top().right().grow().get().parent = null; - resizeButton(); - } - - public void lockTarget() { - locked = !locked; - target = locked ? getTarget() : null; - } - - public void showMoving() { - Table table = new Table(Styles.black3).margin(4); - Vec2 pos = input.mouse(); - table.update(() -> { - if(Vars.state.isMenu()) table.remove(); - Vec2 vec = Core.camera.project(pos.x, pos.y); - table.setPosition(vec.x, vec.y, Align.center); - }); - - table.add("hello world").style(Styles.defaultLabel); - table.pack(); - } - - float angle = 360; - @Override - public void update() { - if((input.keyDown(KeyCode.shiftRight) || input.keyDown(KeyCode.shiftLeft))) { - if(input.keyTap(KeyCode.f)) { - showMoving(); - } - if(input.keyTap(KeyCode.r)) lockTarget(); - if(input.keyTap(KeyCode.r)) { - player.unit().commandNearby(new FormationPattern() { - @Override - public Vec3 calculateSlotLocation(Vec3 out, int slot) { - angle+=0.3f; - float radian = angle / 360 * slot/slots * Mathf.degRad; - float sizeScaling = 0.25f; - float rotateSpeed = 0.01f; - - out.set(Tmp.v1.set(this.spacing * (sizeScaling * 5 * Mathf.cos(2 * radian) + sizeScaling * 2 * Mathf.cos(3 * radian)), this.spacing * (sizeScaling * 2 * Mathf.sin(3 * radian) - sizeScaling * 5 * Mathf.sin(2 * radian))).rotateRad(Time.time * rotateSpeed), 0); - return out; - } - }); - } - } - } - - public TextureRegion getRegions(int i){ - Teamc target = getTarget(); - TextureRegion region = clear; - - if(i == 0){ - if(target instanceof Healthc) region = SIcons.health; - } else if(i == 1){ - if(target instanceof Turret.TurretBuild || - target instanceof MassDriver.MassDriverBuild){ - region = SIcons.reload; - } else if((target instanceof Unit unit && unit.type != null) || - target instanceof ForceProjector.ForceBuild){ - region = SIcons.shield; - } else if(target instanceof PowerNode.PowerNodeBuild || - target instanceof PowerGenerator.GeneratorBuild){ - region = SIcons.power; - } - } else if(i == 2){ - if(target instanceof ItemTurret.ItemTurretBuild){ - region = SIcons.ammo; - } else if(target instanceof LiquidTurret.LiquidTurretBuild){ - region = SIcons.liquid; - } else if(target instanceof PowerTurret.PowerTurretBuild || - target instanceof PowerNode.PowerNodeBuild){ - region = SIcons.power; - } else if((target instanceof Building b && b.block.hasItems) || - (target instanceof Unit unit && unit.type != null)){ - region = SIcons.item; - } - } else if(i == 3){ - if(target instanceof PowerNode.PowerNodeBuild){ - region = SIcons.power; - } - } else if(i == 4){ - if(target instanceof PowerNode.PowerNodeBuild){ - region = SIcons.power; - } else if(target instanceof Building b && b.block.hasLiquids){ - region = SIcons.liquid; - } - } else if(i == 5){ - if(target instanceof Unit unit && state.rules.unitAmmo && unit.type != null){ - region = SIcons.ammo; - }else if(target instanceof PowerNode.PowerNodeBuild || - (target instanceof Building b && b.block.consumes.hasPower())){ - region = SIcons.power; - } - } - - return region; - } - - public void addBar(Table table, int i){ - table.add(new SBar( - () -> BarInfo.strings.get(i), - () -> { - if (BarInfo.colors.get(i) != Color.clear) lastColors.set(i, BarInfo.colors.get(i)); - return lastColors.get(i); - }, - () -> BarInfo.numbers.get(i) - )).height(4 * 8f).growX().left(); - table.add(new Image(){ - @Override - public void draw() { - validate(); - - float x = this.x; - float y = this.y; - float scaleX = this.scaleX; - float scaleY = this.scaleY; - Draw.color(Color.white); - Draw.alpha(parentAlpha * color.a); - - TextureRegionDrawable region = new TextureRegionDrawable(getRegions(i)); - float rotation = getRotation(); - if(scaleX != 1 || scaleY != 1 || rotation != 0){ - region.draw(x + imageX, y + imageY, originX - imageX, originY - imageY, - imageWidth, imageHeight, scaleX, scaleY, rotation); - return; - } - region.draw(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); - - Draw.color(BarInfo.colors.get(i)); - if(ScissorStack.push(scissor.set(x, y, imageWidth * scaleX, imageHeight * scaleY * BarInfo.numbers.get(i)))){ - region.draw(x, y, imageWidth * scaleX, imageHeight * scaleY); - ScissorStack.pop(); - } - Draw.reset(); - } - }).size(iconMed * 0.75f).left(); - } - - - static class WeaponDisplay extends Table { - public WeaponDisplay() { - table().update(tt -> { - tt.clear(); - if(getTarget() instanceof Unit u && u.type != null && u.hasWeapons()) { - for(int r = 0; r < u.type.weapons.size; r++){ - Weapon weapon = u.type.weapons.get(r); - WeaponMount mount = u.mounts[r]; - int finalR = r; - tt.table(ttt -> { - ttt.left(); - if((1 + finalR) % 4 == 0) ttt.row(); - ttt.stack( - new Table(o -> { - o.left(); - o.add(new Image(!weapon.name.equals("") && weapon.outlineRegion.found() ? weapon.outlineRegion : u.type.uiIcon){ - @Override - public void draw(){ - validate(); - float x = this.x; - float y = this.y; - float scaleX = this.scaleX; - float scaleY = this.scaleY; - Draw.color(color); - Draw.alpha(parentAlpha * color.a); - - if(getDrawable() instanceof TransformDrawable){ - float rotation = getRotation(); - if(scaleX != 1 || scaleY != 1 || rotation != 0){ - getDrawable().draw(x + imageX, y + imageY, originX - imageX, originY - imageY, imageWidth, imageHeight, scaleX, scaleY, rotation); - return; - } - } - y -= (mount.reload) / weapon.reload * weapon.recoil; - if(getDrawable() != null) - getDrawable().draw(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); - } - }).size(iconLarge); - }), - new Table(h -> { - h.defaults().growX().height(9f).width(iconLarge).padTop(18f); - h.add(new SBar( - () -> "", - () -> Pal.accent.cpy().lerp(Color.orange, mount.reload / weapon.reload), - () -> mount.reload / weapon.reload).rect().init()); - h.pack(); - }) - ); - }).pad(4); - } - } - }); - } - } - static class UnitInfoDisplay extends Table { - public UnitInfoDisplay() { - top(); - float[] count = new float[]{-1}; - table().update(t -> { - if(getTarget() instanceof Payloadc payload){ - if(count[0] != payload.payloadUsed()){ - t.clear(); - t.top().left(); - - float pad = 0; - float items = payload.payloads().size; - if(8 * 2 * items + pad * items > 275f){ - pad = (275f - (8 * 2) * items) / items; - } - int i = 0; - for(Payload p : payload.payloads()){ - t.image(p.icon()).size(8 * 2).padRight(pad); - if(++i % 12 == 0) t.row(); - } - - count[0] = payload.payloadUsed(); - } - }else{ - count[0] = -1; - t.clear(); - } - }).growX().visible(() -> getTarget() instanceof Payloadc p && p.payloadUsed() > 0).colspan(2).row(); - - Bits statuses = new Bits(); - table().update(t -> { - t.left(); - if(getTarget() instanceof Statusc st){ - Bits applied = st.statusBits(); - if(!statuses.equals(applied)){ - t.clear(); - - if(applied != null){ - for(StatusEffect effect : Vars.content.statusEffects()){ - if(applied.get(effect.id) && !effect.isHidden()){ - t.image(effect.uiIcon).size(iconSmall).get() - .addListener(new Tooltip(l -> l.label(() -> effect.localizedName + " [lightgray]" + UI.formatTime(st.getDuration(effect))).style(Styles.outlineLabel))); - } - } - statuses.set(applied); - } - } - } - }).left(); - } - } -} diff --git a/src/UnitInfo/ui/windows/WaveDisplay.java b/src/UnitInfo/ui/windows/WaveDisplay.java deleted file mode 100644 index c4115c6..0000000 --- a/src/UnitInfo/ui/windows/WaveDisplay.java +++ /dev/null @@ -1,143 +0,0 @@ -package UnitInfo.ui.windows; - -import UnitInfo.ui.OverScrollPane; -import arc.Events; -import arc.graphics.Color; -import arc.input.KeyCode; -import arc.math.Mathf; -import arc.math.geom.Vec2; -import arc.scene.event.HandCursorListener; -import arc.scene.event.Touchable; -import arc.scene.ui.*; -import arc.scene.ui.layout.*; -import arc.struct.*; -import arc.util.*; -import mindustry.content.StatusEffects; -import mindustry.game.EventType; -import mindustry.game.SpawnGroup; -import mindustry.gen.*; -import mindustry.graphics.Pal; -import mindustry.ui.*; - -import static arc.Core.*; -import static arc.Core.settings; -import static mindustry.Vars.*; - - -public class WaveDisplay extends WindowTable { - static Vec2 scrollPos = new Vec2(0, 0); - - public WaveDisplay() { - super("Wave Display", Icon.waves, t -> {}); - } - - @Override - public void build() { - top(); - topBar(); - - table(Styles.black8, t -> { - ScrollPane pane = new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false); - t.add(pane); - Events.on(EventType.WorldLoadEvent.class, e -> { - pane.clearChildren(); - pane.setWidget(rebuild()); - }); - Events.on(EventType.WaveEvent.class, e -> { - pane.clearChildren(); - pane.setWidget(rebuild()); - }); - }).top().right().grow().get().parent = null; - - resizeButton(); - } - - public ObjectIntMap getWaveGroup(int index) { - ObjectIntMap groups = new ObjectIntMap<>(); - for (SpawnGroup group : state.rules.spawns) { - if (group.getSpawned(index) <= 0) continue; - SpawnGroup sameTypeKey = groups.keys().toArray().find(g -> g.type == group.type && g.effect != StatusEffects.boss); - if (sameTypeKey != null) groups.increment(sameTypeKey, sameTypeKey.getSpawned(index)); - else groups.put(group, group.getSpawned(index)); - } - Seq groupSorted = groups.keys().toArray().copy().sort((g1, g2) -> { - int boss = Boolean.compare(g1.effect != StatusEffects.boss, g2.effect != StatusEffects.boss); - if (boss != 0) return boss; - int hitSize = Float.compare(-g1.type.hitSize, -g2.type.hitSize); - if (hitSize != 0) return hitSize; - return Integer.compare(-g1.type.id, -g2.type.id); - }); - ObjectIntMap groupsTmp = new ObjectIntMap<>(); - groupSorted.each(g -> groupsTmp.put(g, groups.get(g))); - - return groupsTmp; - } - - public Table rebuild(){ - return new Table(table -> { - table.touchable = Touchable.enabled; - for (int i = settings.getBool("pastwave") ? 1 : state.wave; - i <= Math.min(state.wave + settings.getInt("wavemax"), (state.isCampaign() && state.rules.winWave > 0 ? state.rules.winWave : Integer.MAX_VALUE)); - i++) { - final int index = i; - - table.table(waveRow -> { - waveRow.background(Tex.underline); - waveRow.add(index+"").update(label -> { - Color color = Pal.accent; - if (state.wave == index) color = Color.red; - else if (state.wave - 1 == index && state.enemies > 0) color = Color.red.cpy().shiftHue(Time.time); - - label.setColor(label.color.cpy().lerp(color, Time.delta)); - }); - waveRow.table(t -> { - if (state.rules.spawns.find(g -> g.getSpawned(index-1) > 0) == null) { - if (settings.getBool("emptywave")) t.add(bundle.get("empty")).center(); - return; - } - - ObjectIntMap groups = getWaveGroup(index-1); - - int row = 0; - for (SpawnGroup group : groups.keys()) { - int spawners = state.rules.waveTeam.cores().size + (group.type.flying ? spawner.countFlyerSpawns() : spawner.countGroundSpawns()); - int amount = groups.get(group); - t.stack( - new Table(ttt -> { - ttt.center(); - ttt.image(group.type.uiIcon).size(iconMed); - ttt.pack(); - }), - - new Table(ttt -> { - ttt.bottom().left(); - ttt.add(amount + "").padTop(2f).fontScale(0.9f); - ttt.add("[gray]x" + spawners).padTop(10f).fontScale(0.7f); - ttt.pack(); - }), - - new Table(ttt -> { - ttt.top().right(); - ttt.image(Icon.warning.getRegion()).update(img -> img.setColor(Tmp.c2.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f)))).size(12f); - ttt.visible(() -> group.effect == StatusEffects.boss); - ttt.pack(); - }) - ).pad(2f).get().addListener(new Tooltip(to -> { - to.background(Styles.black6); - to.margin(4f).left(); - to.add("[stat]" + group.type.localizedName + "[]").row(); - to.row(); - to.add(bundle.format("shar-stat-waveAmount", amount + " [lightgray]x" + spawners + "[]")).row(); - to.add(bundle.format("shar-stat-waveShield", group.getShield(index-1))).row(); - if (group.effect != null && group.effect != StatusEffects.none) - to.add(bundle.get("shar-stat.waveStatus") + group.effect.emoji() + "[stat]" + group.effect.localizedName).row(); - })); - if (++row % 4 == 0) t.row(); - } - }); - }); - table.row(); - } - }); - } -} diff --git a/src/UnitInfo/ui/windows/WindowTables.java b/src/UnitInfo/ui/windows/WindowTables.java deleted file mode 100644 index fddda4e..0000000 --- a/src/UnitInfo/ui/windows/WindowTables.java +++ /dev/null @@ -1,16 +0,0 @@ -package UnitInfo.ui.windows; - -public class WindowTables { - public static WindowTable - unitTable, waveTable, coreTable, playerTable, toolTable; - public static MapEditorDisplay editorTable; - - public static void init() { - unitTable = new UnitDisplay(); - waveTable = new WaveDisplay(); - coreTable = new CoreDisplay(); - playerTable = new PlayerDisplay(); - toolTable = new ToolDisplay(); - editorTable = new MapEditorDisplay(); - } -} diff --git a/src/UnitInfo/SUtils.java b/src/unitinfo/SUtils.java similarity index 96% rename from src/UnitInfo/SUtils.java rename to src/unitinfo/SUtils.java index 0c31c70..3c86426 100644 --- a/src/UnitInfo/SUtils.java +++ b/src/unitinfo/SUtils.java @@ -1,4 +1,4 @@ -package UnitInfo; +package unitinfo; import arc.graphics.g2d.*; import arc.math.Mathf; @@ -21,8 +21,8 @@ import mindustry.world.Tile; import java.lang.reflect.*; -import static UnitInfo.SVars.locked; -import static UnitInfo.SVars.target; +import static unitinfo.SVars.locked; +import static unitinfo.SVars.target; import static arc.Core.input; import static arc.Core.settings; import static mindustry.Vars.player; @@ -32,7 +32,7 @@ public class SUtils { public static T getTarget(){ if(locked && target != null) { if(settings.getBool("deadTarget") && !Groups.all.contains(e -> e == target)) { - target = null; + target = player.unit(); locked = false; } else return (T) target; //if there is locked target, return it first. diff --git a/src/UnitInfo/SVars.java b/src/unitinfo/SVars.java similarity index 72% rename from src/UnitInfo/SVars.java rename to src/unitinfo/SVars.java index f81862a..0da5c2c 100644 --- a/src/UnitInfo/SVars.java +++ b/src/unitinfo/SVars.java @@ -1,16 +1,14 @@ -package UnitInfo; +package unitinfo; -import UnitInfo.core.*; -import UnitInfo.shaders.LineShader; -import UnitInfo.shaders.RangeShader; +import unitinfo.core.*; +import unitinfo.shaders.LineShader; +import unitinfo.shaders.RangeShader; import arc.graphics.g2d.TextureRegion; import mindustry.gen.Teamc; import static arc.Core.atlas; -import static arc.Core.settings; public class SVars { - public static HudUi hud = new HudUi(); public static TextureRegion clear = atlas.find("clear"); public static TextureRegion error = atlas.find("error"); public static RangeShader turretRange; diff --git a/src/UnitInfo/core/BarInfo.java b/src/unitinfo/core/BarInfo.java similarity index 99% rename from src/UnitInfo/core/BarInfo.java rename to src/unitinfo/core/BarInfo.java index d7bfc88..bbd783c 100644 --- a/src/UnitInfo/core/BarInfo.java +++ b/src/unitinfo/core/BarInfo.java @@ -1,4 +1,4 @@ -package UnitInfo.core; +package unitinfo.core; import arc.graphics.*; import arc.math.*; @@ -25,7 +25,7 @@ import mindustry.world.consumers.*; import java.lang.reflect.*; -import static UnitInfo.SUtils.floatFormat; +import static unitinfo.SUtils.floatFormat; import static arc.Core.*; import static mindustry.Vars.*; diff --git a/src/UnitInfo/core/ContentJSON.java b/src/unitinfo/core/ContentJSON.java similarity index 98% rename from src/UnitInfo/core/ContentJSON.java rename to src/unitinfo/core/ContentJSON.java index fd90449..e56624c 100644 --- a/src/UnitInfo/core/ContentJSON.java +++ b/src/unitinfo/core/ContentJSON.java @@ -1,4 +1,4 @@ -package UnitInfo.core; +package unitinfo.core; import arc.Core; import arc.struct.Seq; @@ -98,7 +98,7 @@ public class ContentJSON { data.add(name, obj); }); try { - modDirectory.child("UnitInfo").child(content.peek().getContentType().toString() + ".json").writeString(data.toString(Stringify.FORMATTED)); + modDirectory.child("unitinfo").child(content.peek().getContentType().toString() + ".json").writeString(data.toString(Stringify.FORMATTED)); } catch (Throwable e){ Log.warn(e.getMessage()); } diff --git a/src/UnitInfo/core/Main.java b/src/unitinfo/core/Main.java similarity index 59% rename from src/UnitInfo/core/Main.java rename to src/unitinfo/core/Main.java index 579e8f2..a3d1a89 100644 --- a/src/UnitInfo/core/Main.java +++ b/src/unitinfo/core/Main.java @@ -1,19 +1,22 @@ -package UnitInfo.core; +package unitinfo.core; -import UnitInfo.shaders.*; -import UnitInfo.ui.*; -import UnitInfo.ui.draws.OverDraws; -import UnitInfo.ui.windows.*; +import arc.input.KeyCode; +import arc.scene.ui.layout.Table; +import unitinfo.shaders.*; +import unitinfo.ui.*; +import unitinfo.ui.draws.OverDraws; +import unitinfo.ui.windows.*; import arc.*; import arc.struct.*; import mindustry.*; import mindustry.game.EventType.*; import mindustry.mod.*; -import static UnitInfo.SVars.*; +import static unitinfo.SVars.*; import static arc.Core.*; import static mindustry.Vars.*; -import static UnitInfo.SUtils.*; +import static unitinfo.SUtils.*; +import static unitinfo.ui.windows.WindowManager.windows; public class Main extends Mod { @Override @@ -36,17 +39,22 @@ public class Main extends Mod { } }); - Events.on(ClientLoadEvent.class, e -> { - SettingS.init(); - MindowsTex.init(); - WindowTables.init(); - OverDraws.init(); + Events.run(Trigger.update, () -> { + target = getTarget(); - new HUDFragment().build(Vars.ui.hudGroup); - hud = new HudUi(); - hud.addWaveInfoTable(); - hud.addSchemTable(); - hud.setEvents(); + for (Window window : windows) { + if(window instanceof Updatable u) u.update(); + } + if((input.keyDown(KeyCode.shiftRight) || input.keyDown(KeyCode.shiftLeft))) { + if(input.keyTap(KeyCode.r)) lockTarget(); + } + }); + + Events.on(ClientLoadEvent.class, e -> { + Windows.load(); + SettingS.init(); + WindowManager.init(); + OverDraws.init(); OverDrawer.setEvent(); Seq.with(scene.root, @@ -56,11 +64,16 @@ public class Main extends Mod { ui.planet, ui.research, ui.mods, ui.schematics, ui.logic ).each(dialog-> dialog.addChild(new ElementDisplay(dialog))); + Table table = ((Table) scene.find("minimap/position")).row(); + table.add(new SchemDisplay()); + new WaveInfoDisplay().addWaveInfoTable(); + if(jsonGen) ContentJSON.save(); }); + } - Events.on(WorldLoadEvent.class, e -> { - ((CoreDisplay) WindowTables.coreTable).resetUsed(); - }); + public static void lockTarget() { + if(target==getTarget()) locked = !locked; + target = getTarget(); } } diff --git a/src/UnitInfo/core/OverDrawer.java b/src/unitinfo/core/OverDrawer.java similarity index 96% rename from src/UnitInfo/core/OverDrawer.java rename to src/unitinfo/core/OverDrawer.java index ba86625..9a9c19c 100644 --- a/src/UnitInfo/core/OverDrawer.java +++ b/src/unitinfo/core/OverDrawer.java @@ -1,7 +1,6 @@ -package UnitInfo.core; +package unitinfo.core; -import UnitInfo.ui.draws.OverDraw; -import UnitInfo.ui.draws.OverDraws; +import unitinfo.ui.draws.*; import arc.*; import arc.graphics.*; import arc.graphics.g2d.*; @@ -13,7 +12,7 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.ui.*; -import static UnitInfo.SVars.*; +import static unitinfo.SVars.*; import static arc.Core.*; import static mindustry.Vars.*; diff --git a/src/UnitInfo/core/SettingS.java b/src/unitinfo/core/SettingS.java similarity index 99% rename from src/UnitInfo/core/SettingS.java rename to src/unitinfo/core/SettingS.java index 2e17597..24bc994 100644 --- a/src/UnitInfo/core/SettingS.java +++ b/src/unitinfo/core/SettingS.java @@ -1,4 +1,4 @@ -package UnitInfo.core; +package unitinfo.core; import arc.*; import arc.func.*; diff --git a/src/UnitInfo/core/SharSetting.java b/src/unitinfo/core/SharSetting.java similarity index 95% rename from src/UnitInfo/core/SharSetting.java rename to src/unitinfo/core/SharSetting.java index b61ae42..2e2874b 100644 --- a/src/UnitInfo/core/SharSetting.java +++ b/src/unitinfo/core/SharSetting.java @@ -1,4 +1,4 @@ -package UnitInfo.core; +package unitinfo.core; import arc.Core; import arc.scene.ui.layout.Table; diff --git a/src/UnitInfo/shaders/LineShader.java b/src/unitinfo/shaders/LineShader.java similarity index 96% rename from src/UnitInfo/shaders/LineShader.java rename to src/unitinfo/shaders/LineShader.java index 3f48b08..3584b4b 100644 --- a/src/UnitInfo/shaders/LineShader.java +++ b/src/unitinfo/shaders/LineShader.java @@ -1,4 +1,4 @@ -package UnitInfo.shaders; +package unitinfo.shaders; import arc.Core; import arc.graphics.gl.Shader; diff --git a/src/UnitInfo/shaders/RangeShader.java b/src/unitinfo/shaders/RangeShader.java similarity index 96% rename from src/UnitInfo/shaders/RangeShader.java rename to src/unitinfo/shaders/RangeShader.java index d70f10d..5f20101 100644 --- a/src/UnitInfo/shaders/RangeShader.java +++ b/src/unitinfo/shaders/RangeShader.java @@ -1,4 +1,4 @@ -package UnitInfo.shaders; +package unitinfo.shaders; import arc.Core; import arc.graphics.gl.Shader; diff --git a/src/UnitInfo/ui/EditorTool.java b/src/unitinfo/ui/EditorTool.java similarity index 93% rename from src/UnitInfo/ui/EditorTool.java rename to src/unitinfo/ui/EditorTool.java index a10bfe3..d3bc14c 100644 --- a/src/UnitInfo/ui/EditorTool.java +++ b/src/unitinfo/ui/EditorTool.java @@ -1,6 +1,5 @@ -package UnitInfo.ui; +package unitinfo.ui; -import UnitInfo.ui.windows.WindowTables; import arc.func.Boolf; import arc.func.Cons; import arc.input.KeyCode; @@ -13,10 +12,11 @@ import mindustry.content.Blocks; import mindustry.game.Team; import mindustry.world.Block; import mindustry.world.Tile; +import unitinfo.ui.windows.MapEditorDisplay; -import static UnitInfo.ui.windows.MapEditorDisplay.drawTeam; -import static UnitInfo.ui.windows.MapEditorDisplay.selected; -import static UnitInfo.ui.windows.WindowTables.editorTable; +import static unitinfo.ui.windows.MapEditorDisplay.drawTeam; +import static unitinfo.ui.windows.MapEditorDisplay.drawBlock; +import static unitinfo.ui.windows.Windows.editorTable; import static mindustry.Vars.world; public enum EditorTool{ @@ -26,7 +26,7 @@ public enum EditorTool{ if(!Structs.inBounds(x, y, world.width(), world.height())) return; Tile tile = world.tile(x, y); - selected = tile.block() == Blocks.air || !tile.block().inEditor ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block(); + drawBlock = tile.block() == Blocks.air || !tile.block().inEditor ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block(); } }, line(KeyCode.l, "replace", "orthogonal"){ @@ -114,7 +114,7 @@ public enum EditorTool{ Boolf tester; Cons setter; - Block drawBlock = selected; + Block drawBlock = MapEditorDisplay.drawBlock; if(drawBlock.isOverlay()){ Block dest = tile.overlay(); @@ -217,10 +217,10 @@ public enum EditorTool{ @Override public void touched(int x, int y){ //floor spray - if(selected.isFloor()){ + if(drawBlock.isFloor()){ editorTable.drawCircle(x, y, tile -> { if(Mathf.chance(chance)){ - tile.setFloor(selected.asFloor()); + tile.setFloor(drawBlock.asFloor()); } }); }else if(mode == 0){ //replace-only mode, doesn't affect air diff --git a/src/UnitInfo/ui/ElementDisplay.java b/src/unitinfo/ui/ElementDisplay.java similarity index 98% rename from src/UnitInfo/ui/ElementDisplay.java rename to src/unitinfo/ui/ElementDisplay.java index 3df6afa..0b24c3b 100644 --- a/src/UnitInfo/ui/ElementDisplay.java +++ b/src/unitinfo/ui/ElementDisplay.java @@ -1,4 +1,4 @@ -package UnitInfo.ui; +package unitinfo.ui; import arc.graphics.g2d.Draw; import arc.graphics.g2d.Lines; diff --git a/src/UnitInfo/ui/FreeBar.java b/src/unitinfo/ui/FreeBar.java similarity index 99% rename from src/UnitInfo/ui/FreeBar.java rename to src/unitinfo/ui/FreeBar.java index 18401ea..91c5cf4 100644 --- a/src/UnitInfo/ui/FreeBar.java +++ b/src/unitinfo/ui/FreeBar.java @@ -1,4 +1,4 @@ -package UnitInfo.ui; +package unitinfo.ui; import arc.graphics.g2d.*; import arc.math.*; diff --git a/src/UnitInfo/ui/OverScrollPane.java b/src/unitinfo/ui/OverScrollPane.java similarity index 97% rename from src/UnitInfo/ui/OverScrollPane.java rename to src/unitinfo/ui/OverScrollPane.java index 5228523..af3388c 100644 --- a/src/UnitInfo/ui/OverScrollPane.java +++ b/src/unitinfo/ui/OverScrollPane.java @@ -1,4 +1,4 @@ -package UnitInfo.ui; +package unitinfo.ui; import arc.math.geom.Vec2; import arc.scene.Element; diff --git a/src/UnitInfo/ui/SBar.java b/src/unitinfo/ui/SBar.java similarity index 99% rename from src/UnitInfo/ui/SBar.java rename to src/unitinfo/ui/SBar.java index 707149a..1487e76 100644 --- a/src/UnitInfo/ui/SBar.java +++ b/src/unitinfo/ui/SBar.java @@ -1,6 +1,6 @@ -package UnitInfo.ui; +package unitinfo.ui; -import UnitInfo.SUtils; +import unitinfo.SUtils; import arc.*; import arc.func.*; import arc.graphics.*; diff --git a/src/UnitInfo/ui/SIcons.java b/src/unitinfo/ui/SIcons.java similarity index 96% rename from src/UnitInfo/ui/SIcons.java rename to src/unitinfo/ui/SIcons.java index b23da0f..39effcb 100644 --- a/src/UnitInfo/ui/SIcons.java +++ b/src/unitinfo/ui/SIcons.java @@ -1,4 +1,4 @@ -package UnitInfo.ui; +package unitinfo.ui; import arc.Core; import arc.graphics.g2d.TextureRegion; diff --git a/src/UnitInfo/ui/windows/SchemDisplay.java b/src/unitinfo/ui/SchemDisplay.java similarity index 98% rename from src/UnitInfo/ui/windows/SchemDisplay.java rename to src/unitinfo/ui/SchemDisplay.java index 244b437..3adaa15 100644 --- a/src/UnitInfo/ui/windows/SchemDisplay.java +++ b/src/unitinfo/ui/SchemDisplay.java @@ -1,6 +1,6 @@ -package UnitInfo.ui.windows; +package unitinfo.ui; -import UnitInfo.SUtils; +import unitinfo.SUtils; import arc.Core; import arc.func.Cons; import arc.func.Floatf; @@ -25,17 +25,26 @@ import static arc.Core.*; import static mindustry.Vars.*; import static mindustry.Vars.ui; -public class SchemDisplay extends Table { +public class SchemDisplay extends Table implements Updatable { static float schemScrollPos, tagScrollPos; static boolean schemShown; static Schematic firstSchematic; static final Seq selectedTags = new Seq<>(); static Runnable rebuildList = () -> {}; + float heat; public SchemDisplay() { setSchemTable(); } + @Override + public void update() { + heat += Time.delta; + if(heat>=60f) { + heat = 0; + setSchemTable(); + } + } public void setSchemTable() { clear(); diff --git a/src/UnitInfo/ui/Updatable.java b/src/unitinfo/ui/Updatable.java similarity index 70% rename from src/UnitInfo/ui/Updatable.java rename to src/unitinfo/ui/Updatable.java index c596931..24fc78c 100644 --- a/src/UnitInfo/ui/Updatable.java +++ b/src/unitinfo/ui/Updatable.java @@ -1,4 +1,4 @@ -package UnitInfo.ui; +package unitinfo.ui; public interface Updatable { void update(); diff --git a/src/UnitInfo/core/HudUi.java b/src/unitinfo/ui/WaveInfoDisplay.java similarity index 85% rename from src/UnitInfo/core/HudUi.java rename to src/unitinfo/ui/WaveInfoDisplay.java index 8267b71..f8d0e4e 100644 --- a/src/UnitInfo/core/HudUi.java +++ b/src/unitinfo/ui/WaveInfoDisplay.java @@ -1,46 +1,19 @@ -package UnitInfo.core; +package unitinfo.ui; -import UnitInfo.ui.windows.*; - -import arc.*; -import arc.graphics.*; -import arc.math.*; -import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.util.*; - -import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.Pal; import mindustry.ui.*; -import static UnitInfo.SUtils.*; -import static UnitInfo.SVars.*; +import static unitinfo.SUtils.*; +import static unitinfo.SVars.*; import static arc.Core.*; import static mindustry.Vars.*; -public class HudUi { - public SchemDisplay schemTable; +public class WaveInfoDisplay { public boolean waveShown; - float heat = 0; - public void setEvents() { - Events.run(EventType.Trigger.update, ()->{ - target = getTarget(); - heat += Time.delta; - if(heat > 60) { - heat = 0; - schemTable.setSchemTable(); - } - }); - } - - public void addSchemTable() { - Table table = ((Table) scene.find("minimap/position")).row(); - schemTable = new SchemDisplay(); - table.add(schemTable); - } - public void addWaveInfoTable() { Table waveInfoTable = new Table(Tex.buttonEdge4, table -> { table.center(); diff --git a/src/UnitInfo/ui/draws/BlockDraw.java b/src/unitinfo/ui/draws/BlockDraw.java similarity index 72% rename from src/UnitInfo/ui/draws/BlockDraw.java rename to src/unitinfo/ui/draws/BlockDraw.java index 0ba5f38..9dbd612 100644 --- a/src/UnitInfo/ui/draws/BlockDraw.java +++ b/src/unitinfo/ui/draws/BlockDraw.java @@ -1,14 +1,9 @@ -package UnitInfo.ui.draws; +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; +import static unitinfo.core.OverDrawer.isInCamera; import static arc.Core.settings; public class BlockDraw extends OverDraw { diff --git a/src/UnitInfo/ui/draws/LinkDraw.java b/src/unitinfo/ui/draws/LinkDraw.java similarity index 97% rename from src/UnitInfo/ui/draws/LinkDraw.java rename to src/unitinfo/ui/draws/LinkDraw.java index f3318e7..f3f3e70 100644 --- a/src/UnitInfo/ui/draws/LinkDraw.java +++ b/src/unitinfo/ui/draws/LinkDraw.java @@ -1,14 +1,11 @@ -package UnitInfo.ui.draws; +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; @@ -19,14 +16,13 @@ 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 arc.Core.settings; import static mindustry.Vars.*; -import static UnitInfo.SVars.*; +import static unitinfo.SVars.*; public class LinkDraw extends OverDraw { Seq linkedMasses = new Seq<>(); diff --git a/src/UnitInfo/ui/draws/OverDraw.java b/src/unitinfo/ui/draws/OverDraw.java similarity index 96% rename from src/UnitInfo/ui/draws/OverDraw.java rename to src/unitinfo/ui/draws/OverDraw.java index d5dbba0..f6e189b 100644 --- a/src/UnitInfo/ui/draws/OverDraw.java +++ b/src/unitinfo/ui/draws/OverDraw.java @@ -1,10 +1,9 @@ -package UnitInfo.ui.draws; +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 arc.struct.ObjectMap; import arc.struct.Seq; import mindustry.ui.Styles; diff --git a/src/UnitInfo/ui/draws/OverDraws.java b/src/unitinfo/ui/draws/OverDraws.java similarity index 95% rename from src/UnitInfo/ui/draws/OverDraws.java rename to src/unitinfo/ui/draws/OverDraws.java index f030304..008bbc1 100644 --- a/src/UnitInfo/ui/draws/OverDraws.java +++ b/src/unitinfo/ui/draws/OverDraws.java @@ -1,4 +1,4 @@ -package UnitInfo.ui.draws; +package unitinfo.ui.draws; import mindustry.gen.Icon; diff --git a/src/UnitInfo/ui/draws/RangeDraw.java b/src/unitinfo/ui/draws/RangeDraw.java similarity index 93% rename from src/UnitInfo/ui/draws/RangeDraw.java rename to src/unitinfo/ui/draws/RangeDraw.java index 70030dd..b186f51 100644 --- a/src/UnitInfo/ui/draws/RangeDraw.java +++ b/src/unitinfo/ui/draws/RangeDraw.java @@ -1,24 +1,20 @@ -package UnitInfo.ui.draws; +package unitinfo.ui.draws; import arc.graphics.Color; import arc.graphics.g2d.*; import arc.graphics.gl.FrameBuffer; -import arc.scene.Element; 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.*; 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 unitinfo.SVars.turretRange; +import static unitinfo.core.OverDrawer.isInCamera; import static arc.Core.*; import static mindustry.Vars.player; diff --git a/src/UnitInfo/ui/draws/UnitDraw.java b/src/unitinfo/ui/draws/UnitDraw.java similarity index 93% rename from src/UnitInfo/ui/draws/UnitDraw.java rename to src/unitinfo/ui/draws/UnitDraw.java index f99f43c..837a729 100644 --- a/src/UnitInfo/ui/draws/UnitDraw.java +++ b/src/unitinfo/ui/draws/UnitDraw.java @@ -1,18 +1,13 @@ -package UnitInfo.ui.draws; +package unitinfo.ui.draws; -import UnitInfo.ui.FreeBar; -import arc.Core; +import unitinfo.ui.FreeBar; 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; @@ -21,19 +16,17 @@ 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 unitinfo.core.OverDrawer.isInCamera; +import static unitinfo.core.OverDrawer.isOutCamera; import static arc.Core.settings; import static mindustry.Vars.*; diff --git a/src/UnitInfo/ui/draws/UtilDraw.java b/src/unitinfo/ui/draws/UtilDraw.java similarity index 90% rename from src/UnitInfo/ui/draws/UtilDraw.java rename to src/unitinfo/ui/draws/UtilDraw.java index 80c83c8..2b50490 100644 --- a/src/UnitInfo/ui/draws/UtilDraw.java +++ b/src/unitinfo/ui/draws/UtilDraw.java @@ -1,26 +1,13 @@ -package UnitInfo.ui.draws; +package unitinfo.ui.draws; -import arc.Events; -import arc.func.Boolf; -import arc.func.Cons; import arc.input.KeyCode; import arc.math.Angles; import arc.math.geom.Geometry; -import arc.math.geom.Point2; import arc.scene.style.TextureRegionDrawable; -import arc.scene.ui.Button; -import arc.scene.ui.CheckBox; -import arc.scene.ui.layout.Table; -import arc.struct.IntSeq; -import arc.util.Structs; -import mindustry.content.Blocks; import mindustry.entities.Units; -import mindustry.game.EventType; import mindustry.game.Team; import mindustry.gen.*; import mindustry.logic.Ranged; -import mindustry.world.Block; -import mindustry.world.Tile; import mindustry.world.blocks.ControlBlock; import mindustry.world.blocks.defense.turrets.Turret; diff --git a/src/UnitInfo/ui/windows/CoreDisplay.java b/src/unitinfo/ui/windows/CoreDisplay.java similarity index 85% rename from src/UnitInfo/ui/windows/CoreDisplay.java rename to src/unitinfo/ui/windows/CoreDisplay.java index 1d8b30c..23eefff 100644 --- a/src/UnitInfo/ui/windows/CoreDisplay.java +++ b/src/unitinfo/ui/windows/CoreDisplay.java @@ -1,13 +1,13 @@ -package UnitInfo.ui.windows; +package unitinfo.ui.windows; -import UnitInfo.ui.*; +import arc.Events; +import mindustry.game.EventType; +import unitinfo.ui.*; import arc.Core; import arc.graphics.Color; import arc.math.Mathf; import arc.math.geom.Vec2; -import arc.scene.Element; import arc.scene.event.HandCursorListener; -import arc.scene.style.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; @@ -26,29 +26,25 @@ import mindustry.world.blocks.storage.CoreBlock; import static mindustry.Vars.*; -public class CoreDisplay extends WindowTable implements Updatable { +public class CoreDisplay extends Window implements Updatable { Vec2 scrollPos = new Vec2(0, 0); - ObjectMap itemData = new ObjectMap<>(); + Table window; float heat; + ObjectMap itemData = new ObjectMap<>(); public CoreDisplay() { - super("Core Display", Icon.list, t -> {}); + super(Icon.list, "core"); resetUsed(); } @Override - public void build() { + public void build(Table table) { + window = table; scrollPos = new Vec2(0, 0); - top(); - topBar(); - - table(Styles.black8, t -> { - ScrollPane pane = new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false); - t.add(pane).name("core-pane"); - }).top().right().grow().get().parent = null; - - resizeButton(); + table.background(Styles.black8).top(); + table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("core-pane"); + Events.on(EventType.WorldLoadEvent.class, e -> resetUsed()); } @Override @@ -65,13 +61,19 @@ public class CoreDisplay extends WindowTable implements Updatable { } } - public Table rebuild() { + Table rebuild() { return new Table(table -> { + table.top(); for(Team team : getTeams()) { - table.add(setTable(team).background(((NinePatchDrawable)Tex.underline2).tint(team.color))).row(); + table.table(row-> { + row.center(); + row.add(setTable(team)).margin(8f).row(); + row.image().height(4f).color(team.color).growX(); + }).growX().row(); } }); } + public Seq getTeams(){ return Seq.with(Team.all).filter(Team::active); } @@ -85,6 +87,7 @@ public class CoreDisplay extends WindowTable implements Updatable { public Table setTable(Team team){ return new Table(table -> { table.add(team.name).color(team.color).row(); + int max = Math.max(1, Math.round(window.getWidth()/2/60)); table.table(coretable -> { int row = 0; @@ -120,7 +123,9 @@ public class CoreDisplay extends WindowTable implements Updatable { label.setFontScale(0.75f); tt.add(label); }).padTop(2).padLeft(4).padRight(4); - if(++row % 5 == 0) coretable.row(); + if(row++ % max == max-1){ + coretable.row(); + } } }).row(); @@ -145,7 +150,9 @@ public class CoreDisplay extends WindowTable implements Updatable { ttt.add(label).bottom().right().padTop(16f); ttt.pack(); })).padRight(3).left(); - if(++row % 5 == 0) itemTable.row(); + if(row++ % max == max-1){ + itemTable.row(); + } } }).row(); @@ -159,7 +166,9 @@ public class CoreDisplay extends WindowTable implements Updatable { tt.image(unit.uiIcon).size(iconSmall).padRight(3).tooltip(ttt -> ttt.background(Styles.black6).add(unit.localizedName).style(Styles.outlineLabel).margin(2f)); tt.add(UI.formatAmount(Groups.unit.count(u -> u.team == team && u.type == unit))).padRight(3).minWidth(5 * 8f).left(); }); - if(++row % 5 == 0) unitTable.row(); + if(row++ % max == max-1){ + unitTable.row(); + } } } }); diff --git a/src/unitinfo/ui/windows/MapEditorDisplay.java b/src/unitinfo/ui/windows/MapEditorDisplay.java new file mode 100644 index 0000000..f874685 --- /dev/null +++ b/src/unitinfo/ui/windows/MapEditorDisplay.java @@ -0,0 +1,435 @@ +package unitinfo.ui.windows; + +import arc.Events; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Lines; +import arc.math.geom.Geometry; +import mindustry.editor.MapEditor; +import mindustry.game.EventType; +import mindustry.graphics.Layer; +import unitinfo.ui.*; +import arc.Core; +import arc.func.*; +import arc.graphics.Color; +import arc.input.KeyCode; +import arc.math.Mathf; +import arc.math.geom.Vec2; +import arc.scene.event.Touchable; +import arc.scene.style.TextureRegionDrawable; +import arc.scene.ui.*; +import arc.scene.ui.layout.*; +import arc.scene.utils.Elem; +import arc.struct.Seq; +import arc.util.*; +import mindustry.Vars; +import mindustry.content.Blocks; +import mindustry.game.Team; +import mindustry.gen.*; +import mindustry.graphics.Pal; +import mindustry.ui.Styles; +import mindustry.world.*; + +import static mindustry.Vars.*; + +public class MapEditorDisplay extends Window implements Updatable { + Vec2 scrollPos = new Vec2(0, 0); + Table window; + TextField search; + EditorTool tool; + final Vec2[][] brushPolygons = new Vec2[MapEditor.brushSizes.length][0]; + float heat; + float brushSize = -1; + boolean hold = false; + int pastX, pastY; + + public static Team drawTeam = Team.sharded; + public static Block drawBlock = Blocks.router; + + public MapEditorDisplay() { + super(Icon.map, "editor"); + + for(int i = 0; i < MapEditor.brushSizes.length; i++){ + float size = MapEditor.brushSizes[i]; + float mod = size % 1f; + brushPolygons[i] = Geometry.pixelCircle(size, (index, x, y) -> Mathf.dst(x, y, index - mod, index - mod) <= size - 0.5f); + } + Events.run(EventType.Trigger.draw, ()->{ + float cx = Core.camera.position.x, cy = Core.camera.position.y; + float scaling = 8; + + Draw.z(Layer.max); + + if(Core.settings.getBool("grid")){ + Lines.stroke(1f); + Draw.color(Pal.accent); + for(int i = (int)(-0.5f*Core.camera.height/8); i < (int)(0.5f*Core.camera.height/8); i++) { + Lines.line(Mathf.floor((cx-0.5f*Core.camera.width)/8)*8+4, Mathf.floor((cy + i*8)/8)*8+4, Mathf.floor((cx+0.5f*Core.camera.width)/8)*8+4,Mathf.floor((cy + i*8)/8)*8+4); + } + for(int i = (int)(-0.5f*Core.camera.width/8); i < (int)(0.5f*Core.camera.width/8); i++) { + Lines.line(Mathf.floor((cx + i*8)/8)*8+4, Mathf.floor((cy+0.5f*Core.camera.height)/8)*8+4, Mathf.floor((cx + i*8)/8)*8+4,Mathf.floor((cy-0.5f*Core.camera.height)/8)*8+4); + } + Draw.reset(); + } + + + if(tool==null) return; + int index = 0; + for(int i = 0; i < MapEditor.brushSizes.length; i++){ + if(brushSize == MapEditor.brushSizes[i]){ + index = i; + break; + } + } + Lines.stroke(Scl.scl(2f), Pal.accent); + + if((!drawBlock.isMultiblock() || tool == EditorTool.eraser) && tool != EditorTool.fill){ + if(tool == EditorTool.line && hold){ + Vec2 v = Core.input.mouseWorld(); + Lines.poly(brushPolygons[index], pastX, pastY, scaling); + float vx = Mathf.floor(v.x/8)*8-4, vy = Mathf.floor(v.y/8)*8-4; + Lines.poly(brushPolygons[index], vx, vy, scaling); + } + + if((tool.edit || (tool == EditorTool.line && !hold)) && (!mobile || hold)){ + //pencil square outline + Vec2 v = Core.input.mouseWorld(); + float vx = Mathf.floor(v.x/8)*8-4, vy = Mathf.floor(v.y/8)*8-4; + if(tool == EditorTool.pencil && tool.mode == 1){ + Lines.square(vx, vy, scaling * (brushSize + 0.5f)); + }else{ + Lines.poly(brushPolygons[index], vx, vy, scaling); + } + } + }else{ + if((tool.edit || tool == EditorTool.line) && (!mobile || hold)){ + Vec2 v = Core.input.mouseWorld(); + float vx = Mathf.floor(v.x/8)*8-4, vy = Mathf.floor(v.y/8)*8-4; + float offset = (drawBlock.size % 2 == 0 ? scaling / 2f : 0f); + Lines.square( + vx + scaling / 2f + offset, + vy + scaling / 2f + offset, + scaling * drawBlock.size / 2f); + } + } + }); + } + + @Override + public void build(Table table) { + scrollPos = new Vec2(0, 0); + search = Elem.newField(null, f->{}); + search.setMessageText(Core.bundle.get("players.search")+"..."); + window = table; + + table.top().background(Styles.black8); + table.table(t->{ + t.left().background(Tex.underline2); + t.label(()-> drawBlock ==null?"[gray]None[]":"[accent]"+ drawBlock.localizedName+"[] "+ drawBlock.emoji()); + t.add(search).growX().pad(8).name("search"); + }).growX().row(); + table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("editor-pane").row(); + } + + @Override + public void update() { + heat += Time.delta; + if(heat >= 60f) { + heat = 0f; + resetPane(); + } + if(tool != null && drawBlock != null && !hasMouse()) { + if(Core.input.isTouched()) { + if(!(!mobile&&Core.input.keyDown(KeyCode.mouseLeft))) return; + if(tool== EditorTool.line) { + if(!hold) { + pastX = Mathf.round(Core.input.mouseWorldX() / 8); + pastY = Mathf.round(Core.input.mouseWorldY() / 8); + } + hold = true; + } + else { + pastX = Mathf.round(Core.input.mouseWorldX() / 8); + pastY = Mathf.round(Core.input.mouseWorldY() / 8); + } + + tool.touched(pastX, pastY); + } + else if(tool== EditorTool.line) { + if(hold&&pastX>=0&&pastY>=0) tool.touchedLine(pastX, pastY, Mathf.round(Core.input.mouseWorldX() / 8), Mathf.round(Core.input.mouseWorldY() / 8)); + hold = false; + pastX = -1; + pastY = -1; + } + } + } + + void resetPane() { + ScrollPane pane = find("editor-pane"); + pane.setWidget(rebuild()); + } + + Table rebuild() { + return new Table(table-> { + table.top(); + Seq blocks = Vars.content.blocks().copy(); + if(search.getText().length() > 0){ + blocks.filter(p -> p.name.toLowerCase().contains(search.getText().toLowerCase())||p.localizedName.toLowerCase().contains(search.getText().toLowerCase())); + } + table.table(select-> this.buildBlockSelection(null, select, blocks, ()-> drawBlock, block-> drawBlock =block, false)).marginTop(16f).marginBottom(16f).row(); + table.image().height(4f).color(Pal.gray).growX().row(); + table.table(select-> this.buildTeamSelection(player.team(), select, Seq.with(Team.all), ()->drawTeam, block->drawTeam=block, false)).marginTop(16f).marginBottom(16f).row(); + table.image().height(4f).color(Pal.gray).growX().row(); + table.table(body-> { + body.table(tools -> { + tools.top().left(); + tools.table(title -> title.left().background(Tex.underline2).add("Tools [accent]"+(tool==null?"":tool.name())+"[]")).growX().row(); + tools.table(bt->{ + Cons addTool = tool -> { + ImageButton button = new ImageButton(ui.getIcon(tool.name()), Styles.clearTogglei); + button.clicked(() -> { + button.toggle(); + if(this.tool==tool) this.tool = null; + else this.tool = tool; + resetPane(); + }); + button.update(()->button.setChecked(this.tool == tool)); + + Label mode = new Label(""); + mode.setColor(Pal.remove); + mode.update(() -> mode.setText(tool.mode == -1 ? "" : "M" + (tool.mode + 1) + " ")); + mode.setAlignment(Align.bottomRight, Align.bottomRight); + mode.touchable = Touchable.disabled; + + bt.stack(button, mode); + }; + + addTool.get(unitinfo.ui.EditorTool.line); + addTool.get(unitinfo.ui.EditorTool.pencil); + addTool.get(unitinfo.ui.EditorTool.eraser); + addTool.get(unitinfo.ui.EditorTool.fill); + addTool.get(unitinfo.ui.EditorTool.spray); + + ImageButton grid = new ImageButton(Icon.grid, Styles.clearTogglei); + grid.clicked(() -> { + grid.toggle(); + Core.settings.put("grid", !Core.settings.getBool("grid")); + }); + grid.update(()->grid.setChecked(Core.settings.getBool("grid"))); + bt.add(grid); + }); + tools.row(); + Slider slider = new Slider(0, MapEditor.brushSizes.length - 1, 1, false); + slider.moved(f -> brushSize = MapEditor.brushSizes[(int)f]); + for(int j = 0; j < MapEditor.brushSizes.length; j++){ + if(MapEditor.brushSizes[j] == brushSize){ + slider.setValue(j); + } + } + Label label = new Label("Brush: "+brushSize); + label.touchable = Touchable.disabled; + tools.stack(slider, label).width(window.getWidth()/5).center(); + }).left().width(window.getWidth() / 2).margin(8f).growY(); + body.image().width(4f).height(body.getHeight()).color(Pal.gray).growY(); + body.table(options -> { + options.top().left(); + options.table(title -> title.left().background(Tex.underline2).add("Options [accent]"+(tool!=null&&tool.mode>=0&&tool.mode { + if(tool==null) return; + + option.top().left(); + for (int i = 0; i < tool.altModes.length; i++) { + int mode = i; + String name = tool.altModes[i]; + + option.button(b -> { + b.left().marginLeft(6); + b.setStyle(Styles.clearTogglet); + b.add(Core.bundle.get("toolmode." + name)).left().row(); + b.add(Core.bundle.get("toolmode." + name + ".description")).color(Color.lightGray).left(); + }, () -> tool.mode = (tool.mode == mode ? -1 : mode)).update(b -> b.setChecked(tool.mode == mode)).margin(12f).growX().row(); + } + }).grow(); + }).left().width(window.getWidth() / 2).margin(8f).growY(); + }).grow(); + }); + } + + void buildBlockSelection(@Nullable Block block, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ + ButtonGroup group = new ButtonGroup<>(); + group.setMinCheckCount(0); + Table cont = new Table(); + cont.defaults().size(40); + + int i = 0; + int row = 4; + int max = Math.max(row, Math.round(window.getWidth()/2/8/row)); + + for(T item : items){ + if(!item.unlockedNow()) continue; + + ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> { + if(closeSelect) control.input.frag.config.hideConfig(); + }).group(group).tooltip(t->t.background(Styles.black8).add(item.localizedName.replace(search.getText(), "[accent]"+search.getText()+"[]"))).get(); + button.changed(() -> consumer.get(button.isChecked() ? item : null)); + button.getStyle().imageUp = new TextureRegionDrawable(item.uiIcon); + button.update(() -> button.setChecked(holder.get() == item)); + + if(i++ % max == max-1){ + cont.row(); + } + } + + //add extra blank spaces so it looks nice + if(i % max != 0){ + int remaining = max - (i % max); + for(int j = 0; j < remaining; j++){ + cont.image(Styles.black6); + } + } + + ScrollPane pane = new ScrollPane(cont, Styles.smallPane); + pane.setScrollingDisabled(true, false); + pane.setScrollYForce(blockScroll); + pane.update(() -> blockScroll = pane.getScrollY()); + pane.setOverscroll(false, false); + table.add(pane).maxHeight(Scl.scl(row * 10 * 5)); + } + float blockScroll; + + void buildTeamSelection(@Nullable Team team, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ + ButtonGroup group = new ButtonGroup<>(); + group.setMinCheckCount(0); + Table cont = new Table(); + cont.defaults().size(40); + + int i = 0; + int row = 2; + int max = Math.max(row, Math.round(window.getWidth()/2/8/row/2)); + + for(T item : items){ + ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> { + if(closeSelect) control.input.frag.config.hideConfig(); + }).group(group).tooltip(t->t.background(Styles.black8).add(item.localized().replace(search.getText(), "[accent]"+search.getText()+"[]"))).with(img -> img.getStyle().imageUpColor = item.color).get(); + button.changed(() -> consumer.get(button.isChecked() ? item : null)); + button.update(() -> button.setChecked(holder.get() == item)); + + if(i++ % max == max-1){ + cont.row(); + } + } + + //add extra blank spaces so it looks nice + if(i % max != 0){ + int remaining = max - (i % max); + for(int j = 0; j < remaining; j++){ + cont.image(Styles.black6); + } + } + + ScrollPane pane = new ScrollPane(cont, Styles.smallPane); + pane.setScrollingDisabled(true, false); + pane.setScrollYForce(teamScroll); + pane.update(() -> teamScroll = pane.getScrollY()); + pane.setOverscroll(false, false); + table.add(pane).maxHeight(Scl.scl(row * 10 * 5)); + } + float teamScroll; + + public void drawBlocksReplace(int x, int y){ + drawBlocks(x, y, tile -> tile.block() != Blocks.air || drawBlock.isFloor()); + } + + public void drawBlocks(int x, int y){ + drawBlocks(x, y, false, tile -> true); + } + + public void drawBlocks(int x, int y, Boolf tester){ + drawBlocks(x, y, false, tester); + } + + int rotation = 0; + public void drawBlocks(int x, int y, boolean square, Boolf tester){ + if(drawBlock.isMultiblock()){ + x = Mathf.clamp(x, (drawBlock.size - 1) / 2, world.width() - drawBlock.size / 2 - 1); + y = Mathf.clamp(y, (drawBlock.size - 1) / 2, world.height() - drawBlock.size / 2 - 1); + if(!hasOverlap(x, y)){ + world.tile(x, y).setBlock(drawBlock, drawTeam, rotation); + } + }else{ + boolean isFloor = drawBlock.isFloor() && drawBlock != Blocks.air; + + Cons drawer = tile -> { + if(!tester.get(tile)) return; + + if(isFloor){ + tile.setFloor(drawBlock.asFloor()); + }else if(!(tile.block().isMultiblock() && !drawBlock.isMultiblock())){ + tile.setBlock(drawBlock, drawTeam, rotation); + } + }; + + if(square){ + drawSquare(x, y, drawer); + }else{ + drawCircle(x, y, drawer); + } + } + } + + public void drawCircle(int x, int y, Cons drawer){ + int clamped = (int)brushSize; + for(int rx = -clamped; rx <= clamped; rx++){ + for(int ry = -clamped; ry <= clamped; ry++){ + if(Mathf.within(rx, ry, brushSize - 0.5f + 0.0001f)){ + int wx = x + rx, wy = y + ry; + + if(wx < 0 || wy < 0 || wx >= world.width() || wy >= world.height()){ + continue; + } + + drawer.get(world.tile(wx, wy)); + } + } + } + } + + public void drawSquare(int x, int y, Cons drawer){ + int clamped = (int)brushSize; + for(int rx = -clamped; rx <= clamped; rx++){ + for(int ry = -clamped; ry <= clamped; ry++){ + int wx = x + rx, wy = y + ry; + + if(wx < 0 || wy < 0 || wx >= world.width() || wy >= world.height()){ + continue; + } + + drawer.get(world.tile(wx, wy)); + } + } + } + + boolean hasOverlap(int x, int y){ + Tile tile = world.tile(x, y); + //allow direct replacement of blocks of the same size + if(tile != null && tile.isCenter() && tile.block() != drawBlock && tile.block().size == drawBlock.size && tile.x == x && tile.y == y){ + return false; + } + + //else, check for overlap + int offsetx = -(drawBlock.size - 1) / 2; + int offsety = -(drawBlock.size - 1) / 2; + for(int dx = 0; dx < drawBlock.size; dx++){ + for(int dy = 0; dy < drawBlock.size; dy++){ + int worldx = dx + offsetx + x; + int worldy = dy + offsety + y; + Tile other = world.tile(worldx, worldy); + + if(other != null && other.block().isMultiblock()){ + return true; + } + } + } + + return false; + } +} diff --git a/src/UnitInfo/ui/windows/PlayerDisplay.java b/src/unitinfo/ui/windows/PlayerDisplay.java similarity index 83% rename from src/UnitInfo/ui/windows/PlayerDisplay.java rename to src/unitinfo/ui/windows/PlayerDisplay.java index a273038..b10b290 100644 --- a/src/UnitInfo/ui/windows/PlayerDisplay.java +++ b/src/unitinfo/ui/windows/PlayerDisplay.java @@ -1,7 +1,7 @@ -package UnitInfo.ui.windows; +package unitinfo.ui.windows; -import UnitInfo.ui.OverScrollPane; -import UnitInfo.ui.Updatable; +import unitinfo.ui.OverScrollPane; +import unitinfo.ui.Updatable; import arc.Core; import arc.graphics.Color; import arc.graphics.g2d.Draw; @@ -20,7 +20,7 @@ import mindustry.ui.*; import static mindustry.Vars.*; -public class PlayerDisplay extends WindowTable implements Updatable { +public class PlayerDisplay extends Window implements Updatable { Vec2 scrollPos = new Vec2(0, 0); TextField search; ImageButton.ImageButtonStyle ustyle; @@ -28,11 +28,11 @@ public class PlayerDisplay extends WindowTable implements Updatable { float heat; public PlayerDisplay() { - super("Player Display", Icon.players, t -> {}); + super(Icon.players, "player"); } @Override - public void build() { + public void build(Table table) { scrollPos = new Vec2(0, 0); search = Elem.newField(null, f->{}); search.setMessageText(Core.bundle.get("players.search")); @@ -45,16 +45,10 @@ public class PlayerDisplay extends WindowTable implements Updatable { imageOverColor = Color.lightGray; }}; - top(); - topBar(); - - table(Styles.black8, table -> { - table.label(()-> Core.bundle.format(Groups.player.size() == 1 ? "players.single" : "players", Groups.player.size())).row(); - table.add(search).growX().pad(8).name("search").maxTextLength(maxNameLength).row(); - table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("player-pane"); - }).top().right().grow().get().parent = null; - - resizeButton(); + table.background(Styles.black8).top(); + table.label(()-> Core.bundle.format(Groups.player.size() == 1 ? "players.single" : "players", Groups.player.size())).row(); + table.add(search).growX().pad(8).name("search").maxTextLength(maxNameLength).row(); + table.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).grow().name("player-pane"); } @Override diff --git a/src/UnitInfo/ui/windows/ToolDisplay.java b/src/unitinfo/ui/windows/ToolDisplay.java similarity index 62% rename from src/UnitInfo/ui/windows/ToolDisplay.java rename to src/unitinfo/ui/windows/ToolDisplay.java index e5c9f5f..651ff12 100644 --- a/src/UnitInfo/ui/windows/ToolDisplay.java +++ b/src/unitinfo/ui/windows/ToolDisplay.java @@ -1,50 +1,39 @@ -package UnitInfo.ui.windows; +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 unitinfo.ui.OverScrollPane; +import unitinfo.ui.Updatable; +import unitinfo.ui.draws.OverDraw; +import unitinfo.ui.draws.OverDraws; 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 { +public class ToolDisplay extends Window implements Updatable { Vec2 scrollPos = new Vec2(0, 0); OverDraw selected; float heat; public ToolDisplay() { - super("Tool Display", Icon.edit, t -> { - }); + super(Icon.edit, "tool"); } @Override - public void build() { + public void build(Table table) { 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(); + table.background(Styles.black8).top().left(); + table.table(pane->{ + pane.add(new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false)).name("tool-pane"); + }).top().marginLeft(4f).marginRight(12f); + table.table(stats->{ + stats.top(); + stats.add(rebuildStats()).name("tool-stats"); + }).growY(); } @Override diff --git a/src/unitinfo/ui/windows/UnitDisplay.java b/src/unitinfo/ui/windows/UnitDisplay.java new file mode 100644 index 0000000..f119c81 --- /dev/null +++ b/src/unitinfo/ui/windows/UnitDisplay.java @@ -0,0 +1,280 @@ +package unitinfo.ui.windows; + +import unitinfo.core.*; +import unitinfo.ui.*; +import arc.graphics.Color; +import arc.graphics.g2d.*; +import arc.math.geom.*; +import arc.scene.style.*; +import arc.scene.ui.*; +import arc.scene.ui.layout.*; +import arc.struct.Bits; +import arc.struct.*; +import arc.util.*; +import mindustry.Vars; +import mindustry.core.UI; +import mindustry.entities.units.WeaponMount; +import mindustry.gen.*; +import mindustry.graphics.Pal; +import mindustry.type.StatusEffect; +import mindustry.type.Weapon; +import mindustry.ui.Styles; +import mindustry.world.blocks.ConstructBlock; +import mindustry.world.blocks.defense.ForceProjector; +import mindustry.world.blocks.defense.turrets.*; +import mindustry.world.blocks.distribution.MassDriver; +import mindustry.world.blocks.payloads.Payload; +import mindustry.world.blocks.power.*; + +import static unitinfo.SVars.*; +import static unitinfo.SUtils.*; +import static mindustry.Vars.*; + +class UnitDisplay extends Window { + final Seq lastColors = Seq.with(Color.clear,Color.clear,Color.clear,Color.clear,Color.clear,Color.clear); + final Rect scissor = new Rect(); + Vec2 scrollPos; + + public UnitDisplay() { + super(Icon.units, "unit"); + } + + //TODO: add new UnitInfoDisplay(), new WeaponDisplay(); + @Override + protected void build(Table table) { + scrollPos = new Vec2(0,0); + + table.top().background(Styles.black8); + table.table(tt -> { + tt.center(); + Image image = new Image() { + @Override + public void draw() { + super.draw(); + + int offset = 8; + Draw.color(locked?Pal.accent:Pal.gray); + Draw.alpha(parentAlpha); + Lines.stroke(Scl.scl(3f)); + Lines.rect(x-offset/2f, y-offset/2f, width+offset, height+offset); + Draw.reset(); + } + }; + image.update(()->{ + TextureRegion region = clear; + if (target instanceof Unit u && u.type != null) region = u.type.uiIcon; + else if (target instanceof Building b) { + if (target instanceof ConstructBlock.ConstructBuild cb) region = cb.current.uiIcon; + else if (b.block != null) region = b.block.uiIcon; + } + image.setDrawable(region); + }); + image.clicked(Main::lockTarget); + + tt.add(image).size(iconMed).padRight(12f); + tt.label(() -> { + if (target instanceof Unit u && u.type != null) return u.type.localizedName; + if (target instanceof Building b && b.block != null) { + if (target instanceof ConstructBlock.ConstructBuild cb) return cb.current.localizedName; + return b.block.localizedName; + } + return ""; + }).color(Pal.accent); + }).tooltip((to -> { + to.background(Styles.black6); + to.label(() -> target instanceof Unit u && u.isPlayer() ? u.getPlayer().name() : "AI").row(); + to.label(() -> target == null ? "(" + 0 + ", " + 0 + ")" : "(" + Strings.fixed(target.x() / tilesize, 2) + ", " + Strings.fixed(target.y() / tilesize, 2) + ")").row(); + to.label(() -> target instanceof Unit u ? "[accent]"+ Strings.fixed(u.armor, 0) + "[] Armor" : ""); + })).margin(12f).row(); + table.image().height(4f).color(player.team().color).growX().row(); + table.add(new OverScrollPane(new Table(bars -> { + bars.top(); + for (int i = 0; i < 6; i++) { + int index = i; + bars.table(bar -> { + bar.add(new SBar( + () -> BarInfo.strings.get(index), + () -> { + if (BarInfo.colors.get(index) != Color.clear) lastColors.set(index, BarInfo.colors.get(index)); + return lastColors.get(index); + }, + () -> BarInfo.numbers.get(index) + )).height(4 * 8f).growX(); + bar.add(new Image(){ + @Override + public void draw() { + validate(); + + Draw.color(Color.white); + Draw.alpha(parentAlpha * color.a); + TextureRegionDrawable region = new TextureRegionDrawable(getRegions(index)); + region.draw(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); + Draw.color(BarInfo.colors.get(index)); + if(ScissorStack.push(scissor.set(x, y, imageWidth * scaleX, imageHeight * scaleY * BarInfo.numbers.get(index)))){ + region.draw(x, y, imageWidth * scaleX, imageHeight * scaleY); + ScissorStack.pop(); + } + } + }).size(iconMed * 0.75f).padLeft(8f); + }).growX().row(); + } + }), Styles.nonePane, scrollPos).disableScroll(true, false)).growX().padTop(12f); + } + + //do not ask me WHAT THE FUCK IS THIS + TextureRegion getRegions(int i){ + TextureRegion region = clear; + + if(i == 0){ + if(target instanceof Healthc) region = SIcons.health; + } else if(i == 1){ + if(target instanceof Turret.TurretBuild || + target instanceof MassDriver.MassDriverBuild){ + region = SIcons.reload; + } else if((target instanceof Unit unit && unit.type != null) || + target instanceof ForceProjector.ForceBuild){ + region = SIcons.shield; + } else if(target instanceof PowerNode.PowerNodeBuild || + target instanceof PowerGenerator.GeneratorBuild){ + region = SIcons.power; + } + } else if(i == 2){ + if(target instanceof ItemTurret.ItemTurretBuild){ + region = SIcons.ammo; + } else if(target instanceof LiquidTurret.LiquidTurretBuild){ + region = SIcons.liquid; + } else if(target instanceof PowerTurret.PowerTurretBuild || + target instanceof PowerNode.PowerNodeBuild){ + region = SIcons.power; + } else if((target instanceof Building b && b.block.hasItems) || + (target instanceof Unit unit && unit.type != null)){ + region = SIcons.item; + } + } else if(i == 3){ + if(target instanceof PowerNode.PowerNodeBuild){ + region = SIcons.power; + } + } else if(i == 4){ + if(target instanceof PowerNode.PowerNodeBuild){ + region = SIcons.power; + } else if(target instanceof Building b && b.block.hasLiquids){ + region = SIcons.liquid; + } + } else if(i == 5){ + if(target instanceof Unit unit && state.rules.unitAmmo && unit.type != null){ + region = SIcons.ammo; + }else if(target instanceof PowerNode.PowerNodeBuild || + (target instanceof Building b && b.block.consumes.hasPower())){ + region = SIcons.power; + } + } + + return region; + } + + static class WeaponDisplay extends Table { + WeaponDisplay() { + table().update(tt -> { + tt.clear(); + if(getTarget() instanceof Unit u && u.type != null && u.hasWeapons()) { + for(int r = 0; r < u.type.weapons.size; r++){ + Weapon weapon = u.type.weapons.get(r); + WeaponMount mount = u.mounts[r]; + int finalR = r; + tt.table(ttt -> { + ttt.left(); + if((1 + finalR) % 4 == 0) ttt.row(); + ttt.stack( + new Table(o -> { + o.left(); + o.add(new Image(!weapon.name.equals("") && weapon.outlineRegion.found() ? weapon.outlineRegion : u.type.uiIcon){ + @Override + public void draw(){ + validate(); + float x = this.x; + float y = this.y; + float scaleX = this.scaleX; + float scaleY = this.scaleY; + Draw.color(color); + Draw.alpha(parentAlpha * color.a); + + if(getDrawable() instanceof TransformDrawable){ + float rotation = getRotation(); + if(scaleX != 1 || scaleY != 1 || rotation != 0){ + getDrawable().draw(x + imageX, y + imageY, originX - imageX, originY - imageY, imageWidth, imageHeight, scaleX, scaleY, rotation); + return; + } + } + y -= (mount.reload) / weapon.reload * weapon.recoil; + if(getDrawable() != null) + getDrawable().draw(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); + } + }).size(iconLarge); + }), + new Table(h -> { + h.defaults().growX().height(9f).width(iconLarge).padTop(18f); + h.add(new SBar( + () -> "", + () -> Pal.accent.cpy().lerp(Color.orange, mount.reload / weapon.reload), + () -> mount.reload / weapon.reload).rect().init()); + h.pack(); + }) + ); + }).pad(4); + } + } + }); + } + } + static class UnitInfoDisplay extends Table { + UnitInfoDisplay() { + top(); + float[] count = new float[]{-1}; + table().update(t -> { + if(getTarget() instanceof Payloadc payload){ + if(count[0] != payload.payloadUsed()){ + t.clear(); + t.top().left(); + + float pad = 0; + float items = payload.payloads().size; + if(8 * 2 * items + pad * items > 275f){ + pad = (275f - (8 * 2) * items) / items; + } + int i = 0; + for(Payload p : payload.payloads()){ + t.image(p.icon()).size(8 * 2).padRight(pad); + if(++i % 12 == 0) t.row(); + } + + count[0] = payload.payloadUsed(); + } + }else{ + count[0] = -1; + t.clear(); + } + }).growX().visible(() -> getTarget() instanceof Payloadc p && p.payloadUsed() > 0).colspan(2).row(); + + Bits statuses = new Bits(); + table().update(t -> { + t.left(); + if(getTarget() instanceof Statusc st){ + Bits applied = st.statusBits(); + if(!statuses.equals(applied)){ + t.clear(); + + if(applied != null){ + for(StatusEffect effect : Vars.content.statusEffects()){ + if(applied.get(effect.id) && !effect.isHidden()){ + t.image(effect.uiIcon).size(iconSmall).get() + .addListener(new Tooltip(l -> l.label(() -> effect.localizedName + " [lightgray]" + UI.formatTime(st.getDuration(effect))).style(Styles.outlineLabel))); + } + } + statuses.set(applied); + } + } + } + }).left(); + } + } +} diff --git a/src/unitinfo/ui/windows/WaveDisplay.java b/src/unitinfo/ui/windows/WaveDisplay.java new file mode 100644 index 0000000..303fcda --- /dev/null +++ b/src/unitinfo/ui/windows/WaveDisplay.java @@ -0,0 +1,159 @@ +package unitinfo.ui.windows; + +import mindustry.game.Team; +import unitinfo.ui.OverScrollPane; +import arc.Events; +import arc.graphics.Color; +import arc.math.Mathf; +import arc.math.geom.Vec2; +import arc.scene.event.Touchable; +import arc.scene.ui.*; +import arc.scene.ui.layout.*; +import arc.struct.*; +import arc.util.*; +import mindustry.content.StatusEffects; +import mindustry.game.EventType; +import mindustry.game.SpawnGroup; +import mindustry.gen.*; +import mindustry.graphics.Pal; +import mindustry.ui.*; +import unitinfo.ui.Updatable; + +import static arc.Core.*; +import static arc.Core.settings; +import static mindustry.Vars.*; + + +public class WaveDisplay extends Window implements Updatable { + static Vec2 scrollPos = new Vec2(0, 0); + Table window; + float heat; + + public WaveDisplay() { + super(Icon.waves, "wave"); + } + + @Override + public void build(Table table) { + window = table; + + table.top().background(Styles.black8); + + ScrollPane pane = new OverScrollPane(rebuild(), Styles.nonePane, scrollPos).disableScroll(true, false); + table.add(pane).grow().name("wave-pane"); + Events.on(EventType.WorldLoadEvent.class, e -> { + pane.clearChildren(); + pane.setWidget(rebuild()); + }); + Events.on(EventType.WaveEvent.class, e -> { + pane.clearChildren(); + pane.setWidget(rebuild()); + }); + } + + @Override + public void update() { + heat += Time.delta; + if(heat >= 60f) { + heat = 0f; + ScrollPane pane = find("wave-pane"); + pane.setWidget(rebuild()); + } + } + + public ObjectIntMap getWaveGroup(int index) { + ObjectIntMap groups = new ObjectIntMap<>(); + for (SpawnGroup group : state.rules.spawns) { + if (group.getSpawned(index) <= 0) continue; + SpawnGroup sameTypeKey = groups.keys().toArray().find(g -> g.type == group.type && g.effect != StatusEffects.boss); + if (sameTypeKey != null) groups.increment(sameTypeKey, sameTypeKey.getSpawned(index)); + else groups.put(group, group.getSpawned(index)); + } + Seq groupSorted = groups.keys().toArray().copy().sort((g1, g2) -> { + int boss = Boolean.compare(g1.effect != StatusEffects.boss, g2.effect != StatusEffects.boss); + if (boss != 0) return boss; + int hitSize = Float.compare(-g1.type.hitSize, -g2.type.hitSize); + if (hitSize != 0) return hitSize; + return Integer.compare(-g1.type.id, -g2.type.id); + }); + ObjectIntMap groupsTmp = new ObjectIntMap<>(); + groupSorted.each(g -> groupsTmp.put(g, groups.get(g))); + + return groupsTmp; + } + + Table rebuild(){ + return new Table(table -> { + table.touchable = Touchable.enabled; + table.table(body->{ + body.center(); + for (int i = settings.getBool("pastwave") ? 1 : state.wave; i <= Math.min(state.wave + settings.getInt("wavemax"), (state.isCampaign() && state.rules.winWave > 0 ? state.rules.winWave : Integer.MAX_VALUE)); i++) { + final int index = i; + + body.table(waveRow -> { + waveRow.left(); + + waveRow.add(index+"").update(label -> { + Color color = Pal.accent; + if (state.wave == index) color = Color.red; + else if (state.wave - 1 == index && state.enemies > 0) color = Color.red.cpy().shiftHue(Time.time); + + label.setColor(color); + }); + waveRow.table(unitTable -> { + unitTable.center(); + + if (state.rules.spawns.find(g -> g.getSpawned(index-1) > 0) == null) { + if (settings.getBool("emptywave")) unitTable.add(bundle.get("empty")); + return; + } + + ObjectIntMap groups = getWaveGroup(index-1); + + int row = 0; + int max = Math.max(1, Math.round(window.getWidth()/2/8)); + for (SpawnGroup group : groups.keys()) { + int spawners = state.rules.waveTeam.cores().size + (group.type.flying ? spawner.countFlyerSpawns() : spawner.countGroundSpawns()); + int amount = groups.get(group); + unitTable.stack( + new Table(ttt -> { + ttt.center(); + ttt.image(group.type.uiIcon).size(iconMed); + ttt.pack(); + }), + + new Table(ttt -> { + ttt.bottom().left(); + ttt.add(amount + "").padTop(2f).fontScale(0.9f); + ttt.add("[gray]x" + spawners).padTop(10f).fontScale(0.7f); + ttt.pack(); + }), + + new Table(ttt -> { + ttt.top().right(); + ttt.image(Icon.warning.getRegion()).update(img -> img.setColor(Tmp.c2.set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time, 2f, 1f)))).size(12f); + ttt.visible(() -> group.effect == StatusEffects.boss); + ttt.pack(); + }) + ).pad(2f).get().addListener(new Tooltip(to -> { + to.background(Styles.black6); + to.margin(4f).left(); + to.add("[stat]" + group.type.localizedName + "[]").row(); + to.row(); + to.add(bundle.format("shar-stat-waveAmount", amount + " [lightgray]x" + spawners + "[]")).row(); + to.add(bundle.format("shar-stat-waveShield", group.getShield(index-1))).row(); + if (group.effect != null && group.effect != StatusEffects.none) + to.add(bundle.get("shar-stat.waveStatus") + group.effect.emoji() + "[stat]" + group.effect.localizedName).row(); + })); + if(row++ % max == max-1){ + unitTable.row(); + } + } + }).growX().margin(12f); + }).growX().row(); + body.image().height(4f).color(Pal.gray).growX().row(); + } + }).grow().margin(40f); + }); + } +} diff --git a/src/UnitInfo/ui/windows/WindowTable.java b/src/unitinfo/ui/windows/Window.java similarity index 57% rename from src/UnitInfo/ui/windows/WindowTable.java rename to src/unitinfo/ui/windows/Window.java index 4a9ad1c..7883ad2 100644 --- a/src/UnitInfo/ui/windows/WindowTable.java +++ b/src/unitinfo/ui/windows/Window.java @@ -1,5 +1,6 @@ -package UnitInfo.ui.windows; +package unitinfo.ui.windows; +import arc.*; import arc.func.*; import arc.input.*; import arc.math.geom.*; @@ -10,56 +11,60 @@ import arc.util.*; import mindustry.gen.*; import mindustry.ui.*; -import java.awt.*; - -public class WindowTable extends Table{ - public Cons content, onClose; +public class Window extends Table{ public TextureRegionDrawable icon; - public float maxWindowHeight, maxWindowWidth; - public boolean maxWidthEnabled = false, maxHeightEnabled = false; + public int id; + public Cons
content; + public boolean shown = false; - public WindowTable() { - this("none", Icon.none, c->{}); + public float minWindowWidth = 160, minWindowHeight = 60; + public float maxWindowWidth = Float.MAX_VALUE, maxWindowHeight = Float.MAX_VALUE; + + public Window(TextureRegionDrawable icon, String name){ + this(icon, name, null); } - public WindowTable(String title, TextureRegionDrawable icon, Cons
content){ - this(title, icon, content, t -> t.visible(() -> false)); - } - - public WindowTable(String title, TextureRegionDrawable icon, Cons
content, Cons
onClose){ - this.name = title; - this.icon = icon; + public Window(TextureRegionDrawable icon, String name, Cons
content){ this.content = content; - this.onClose = onClose; - build(); + this.name = name; + this.icon = icon; + + titleBar(); + pane(t -> { + t.setBackground(Styles.black5); + t.top().left(); + build(t); + }).grow().top().left().get().setScrollingDisabled(true, true); + bottomBar(); + + setPosition(Core.graphics.getWidth() / 2f - getWidth() / 2f, Core.graphics.getHeight() / 2f - getHeight() / 2f); + id = WindowManager.register(this); + + visible(() -> shown); } - public void build(){ - top(); - topBar(); - - // window contents - table(Styles.black5, t -> { - content.get(t); - }).grow(); - - resizeButton(); + protected void build(Table t){ + if(content != null) content.get(t); } - public void topBar(){ + protected void titleBar(){ table(t -> { + // icon and title t.table(Tex.buttonEdge1, b -> { b.top().left(); - b.image(icon).size(20f).padLeft(15).top().left(); + b.image(() -> icon == null ? Icon.none.getRegion() : icon.getRegion()).size(20f).padLeft(15).top().left(); b.pane(Styles.nonePane, p -> { p.top().left(); - p.labelWrap(name).padLeft(20).top().left().get().setAlignment(Align.topLeft); - }).top().left().height(40f).growX().get().setScrollingDisabled(true, true); + p.labelWrap(() -> Core.bundle.get("window."+name+".name")).padLeft(20).top().left().get().setAlignment(Align.topLeft); + }).left().height(40f).growX().get().setScrollingDisabled(true, true); }).maxHeight(40f).grow(); + + // exit button t.table(Tex.buttonEdge3, b -> { - b.button(Icon.cancel, Styles.emptyi, () -> onClose.get(this)); + b.button(Icon.cancel, Styles.emptyi, () -> shown = false); }).maxHeight(40f).width(80f).growY(); + // handles the dragging. t.touchable = Touchable.enabled; t.addListener(new InputListener(){ float lastX, lastY; @@ -68,15 +73,16 @@ public class WindowTable extends Table{ Vec2 v = t.localToStageCoordinates(Tmp.v1.set(x, y)); lastX = v.x; lastY = v.y; - t.toFront(); + toFront(); return true; } @Override - public void touchDragged(InputEvent event, float x, float y, int pointer) { - Vec2 v = t.localToStageCoordinates(Tmp.v1.set(x, y)); + public void touchDragged(InputEvent event, float dx, float dy, int pointer) { + Vec2 v = t.localToStageCoordinates(Tmp.v1.set(dx, dy)); + + setPosition( x + (v.x - lastX), y + (v.y - lastY)); - moveBy(v.x - lastX, v.y - lastY); lastX = v.x; lastY = v.y; } @@ -85,7 +91,7 @@ public class WindowTable extends Table{ row(); } - public void resizeButton(){ + protected void bottomBar(){ row(); table(Styles.black5, t -> { t.table().growX(); @@ -110,8 +116,8 @@ public class WindowTable extends Table{ // will softlock if initial size is smaller than minimum // so don't do that! - if(getWidth() + w < 160f || (getWidth() + w > maxWindowWidth && maxWidthEnabled)) w = 0; - if(getHeight() - h < 160f || (getHeight() - h > maxWindowHeight && maxHeightEnabled)) h = 0; + if(getWidth() + w < minWindowWidth || getWidth() + w > maxWindowWidth) w = 0; + if(getHeight() - h < minWindowHeight || getHeight() - h > maxWindowHeight) h = 0; sizeBy(w, -h); moveBy(0, h); lastX = v.x; @@ -122,13 +128,7 @@ public class WindowTable extends Table{ }).height(20f).growX(); } - public void setMaxWindowWidth(float maxWindowWidth){ - this.maxWindowWidth = maxWindowWidth; - maxWidthEnabled = true; + public void toggle(){ + shown = !shown; } - - public void setMaxWindowHeight(float maxWindowHeight){ - this.maxWindowHeight = maxWindowHeight; - maxHeightEnabled = true; - } -} \ No newline at end of file +} diff --git a/src/unitinfo/ui/windows/WindowManager.java b/src/unitinfo/ui/windows/WindowManager.java new file mode 100644 index 0000000..daaaa35 --- /dev/null +++ b/src/unitinfo/ui/windows/WindowManager.java @@ -0,0 +1,55 @@ +package unitinfo.ui.windows; + +import arc.*; +import arc.struct.*; +import arc.util.*; +import mindustry.*; +import mindustry.ui.*; + +public class WindowManager { + public static Seq windows = new Seq<>(); + + public static void init(){ + Log.info(windows.size); + + Vars.ui.hudGroup.fill(t -> { + t.name = "Windows"; + for(Window window : windows){ + t.add(window); + } + }); + + Vars.ui.hudGroup.fill(t -> { + t.center().left(); + t.table(Core.atlas.drawable("unitinfo-sidebar"), b -> { + b.name = "Window Buttons"; + b.left(); + + for(Window window : windows){ + b.button(window.icon, Styles.emptyi, () -> { + window.toggle(); + + // Disabling the parent's layout fixes issues with updating elements inside windows. + // However, it also disables the layout of all its children, so we need to re-enable them. + window.parent.setLayoutEnabled(false); + window.setLayoutEnabled(true); + for(Window w : windows){ + w.setLayoutEnabled(true); + } + }).disabled(window.shown) + .size(40f) + .tooltip(tt -> { + tt.setBackground(Styles.black6); + tt.label(() -> Core.bundle.get("window."+window.name+".name")).pad(2f); + }); + b.row(); + } + }).left(); + }); + } + + public static int register(Window window){ + windows.add(window); + return windows.size - 1; + } +} diff --git a/src/unitinfo/ui/windows/Windows.java b/src/unitinfo/ui/windows/Windows.java new file mode 100644 index 0000000..8ed8bfa --- /dev/null +++ b/src/unitinfo/ui/windows/Windows.java @@ -0,0 +1,25 @@ +package unitinfo.ui.windows; + +import arc.util.*; +import mindustry.gen.*; +import unitinfo.ui.windows.*; + +public class Windows { + public static MapEditorDisplay editorTable; + + public static void load(){ + new UnitDisplay(); + new WaveDisplay(); + new CoreDisplay(); + new PlayerDisplay(); + new ToolDisplay(); + editorTable = new MapEditorDisplay(); + new Window(Icon.box, "test-window", t -> { + t.labelWrap(() -> t.parent.x + ", " + t.parent.y).top().right().growX(); + t.row(); + t.labelWrap(() -> t.parent.getWidth() + ", " + t.parent.getHeight()).top().right().growX(); + t.row(); + t.labelWrap(() -> "T: " + Time.time).top().right().growX(); + }); + } +}