From 4fd6d5975349a93f8e54b59bfa61d376433cfea2 Mon Sep 17 00:00:00 2001 From: sharlottes Date: Mon, 21 Nov 2022 07:36:33 +0900 Subject: [PATCH] overdraw refactoring --- assets/bundles/bundle.properties | 19 ++- assets/bundles/bundle_ko.properties | 19 ++- assets/bundles/bundle_ru.properties | 8 +- assets/bundles/bundle_tr.properties | 8 +- assets/bundles/bundle_uk_UA.properties | 10 +- assets/bundles/bundle_zh_CN.properties | 12 +- src/informatis/SUtils.java | 37 +++++- src/informatis/core/OverDrawer.java | 4 - src/informatis/draws/AutoShootDraw.java | 73 +++++++++++ src/informatis/draws/BlockBarDraw.java | 61 +++++++++ src/informatis/draws/BlockDraw.java | 85 ------------- src/informatis/draws/BlockRangeDraw.java | 57 +++++++++ src/informatis/draws/BlockStatusDraw.java | 30 +++++ src/informatis/draws/CommandLineDraw.java | 19 +++ src/informatis/draws/LogicLineDraw.java | 25 ++++ src/informatis/draws/MagicCursorDraw.java | 24 ++++ .../{LinkDraw.java => MassLinkDraw.java} | 94 +++----------- src/informatis/draws/OverDraw.java | 62 ++++----- src/informatis/draws/OverDrawCategory.java | 21 ++++ src/informatis/draws/OverDraws.java | 88 +++++++++++-- src/informatis/draws/PathLineDraw.java | 26 ++++ src/informatis/draws/PlayerRangeDraw.java | 23 ++++ src/informatis/draws/PowerNodeDraw.java | 56 +++++++++ src/informatis/draws/RangeDraw.java | 118 ------------------ src/informatis/draws/UnitBarDraw.java | 15 +++ src/informatis/draws/UnitCargoLinkDraw.java | 30 +++++ src/informatis/draws/UnitDraw.java | 104 --------------- src/informatis/draws/UnitItemDraw.java | 27 ++++ src/informatis/draws/UnitPathLineDraw.java | 32 +++++ src/informatis/draws/UnitRangeDraw.java | 45 +++++++ src/informatis/draws/UtilDraw.java | 92 -------------- src/informatis/ui/windows/ToolWindow.java | 71 ++++++++--- 32 files changed, 818 insertions(+), 577 deletions(-) create mode 100644 src/informatis/draws/AutoShootDraw.java create mode 100644 src/informatis/draws/BlockBarDraw.java delete mode 100644 src/informatis/draws/BlockDraw.java create mode 100644 src/informatis/draws/BlockRangeDraw.java create mode 100644 src/informatis/draws/BlockStatusDraw.java create mode 100644 src/informatis/draws/CommandLineDraw.java create mode 100644 src/informatis/draws/LogicLineDraw.java create mode 100644 src/informatis/draws/MagicCursorDraw.java rename src/informatis/draws/{LinkDraw.java => MassLinkDraw.java} (58%) create mode 100644 src/informatis/draws/OverDrawCategory.java create mode 100644 src/informatis/draws/PathLineDraw.java create mode 100644 src/informatis/draws/PlayerRangeDraw.java create mode 100644 src/informatis/draws/PowerNodeDraw.java delete mode 100644 src/informatis/draws/RangeDraw.java create mode 100644 src/informatis/draws/UnitBarDraw.java create mode 100644 src/informatis/draws/UnitCargoLinkDraw.java delete mode 100644 src/informatis/draws/UnitDraw.java create mode 100644 src/informatis/draws/UnitItemDraw.java create mode 100644 src/informatis/draws/UnitPathLineDraw.java create mode 100644 src/informatis/draws/UnitRangeDraw.java delete mode 100644 src/informatis/draws/UtilDraw.java diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index b84b379..977aee1 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -36,8 +36,10 @@ setting.blockBar.description = display block health bar setting.powerNode.name = enable Power Node setting.powerNode.description = display power node link lines -setting.massDriver.name = enable Mass Driver -setting.massDriver.description = display mass driver link lines +setting.massLink.name = enable Mass Driver +setting.massLink.description = display mass driver link lines +setting.unitCargoLink.name = Display unit-cargo link +setting.unitCargoLink.description = display unit cargo block's link line setting.blockRange.name = Display Block Range setting.blockRange.description = Displays every available turrets range @@ -51,6 +53,8 @@ setting.groundRange.name = Display Ground range setting.groundRange.description = display every available turrets/units which can target ground units or blocks setting.aliceRange.name = Display Alice Range setting.aliceRange.description = Displays alice turret/unit range +setting.playerRange.name = Display Player range +setting.playerRange.description = Displays player turret/unit range setting.RangeShader.name = Enable Animation setting.RangeShader.description = Use animation shader for make it ease to see @@ -58,16 +62,16 @@ setting.pathLine.name = enable Path Line setting.pathLine.description = display wave ground unit's ai path lineline setting.logicLine.name = enable Logic Line setting.logicLine.description = display lines between logic processor and controlled units -setting.unitLine.name = enable Unit Line -setting.unitLine.description = display ai path each ground unit +setting.unitPathLine.name = enable Unit Line +setting.unitPathLine.description = display ai path each ground unit setting.commandLine.name = enable Command Line setting.cocmmandLine.description = display unit path line, controlled by rts command setting.unitItem.name = enable Unit Item setting.unitItem.description = display item amount under each unit setting.unitBar.name = enable Unit Bar setting.unitBar.description = display health bar under each unit -setting.autoShooting.name = Enable Auto Shooting -setting.autoShooting.description = no don't do hack +setting.autoShoot.name = Enable Auto Shooting +setting.autoShoot.description = no don't do hack setting.spawnerarrow.name = Indicate Wave Spawn-Point setting.spawnerarrow.description = Displays arrow pointing to wave spawn-points. @@ -80,6 +84,9 @@ setting.elementdebug.description = Show all Element outline setting.hiddenElem.name = Display hidden element setting.hiddenElem.description = display hidden element outline too. +setting.gaycursor.name = Magic Cursor +setting.gaycursor.description = makes your cursor more fency! + setting.shar-title = Informatis Settings setting.shar-ui = Overlay UI Settings setting.shar-draw = Overdrawing Settings diff --git a/assets/bundles/bundle_ko.properties b/assets/bundles/bundle_ko.properties index 9ba54f9..f358fe3 100644 --- a/assets/bundles/bundle_ko.properties +++ b/assets/bundles/bundle_ko.properties @@ -36,8 +36,10 @@ setting.blockBar.description = 블록 체력바를 표시합니다. setting.powerNode.name = 노드 연결선 표시 setting.powerNode.description = 선택한 블록과 전기적으로 연결된 블록들을 선으로 이어서 표시합니다. -setting.massDriver.name = 매스 드라이버 연결선 표시 -setting.massDriver.description = 선택한 매스 드라이버와 연결된 매스 드라이버들을 선으로 이어서 표시합니다. +setting.massLink.name = 매스 드라이버 연결선 표시 +setting.massLink.description = 선택한 매스 드라이버와 연결된 매스 드라이버들을 선으로 이어서 표시합니다. +setting.unitCargoLink.name = 기체 화물 적제소 연결선 표시 +setting.unitCargoLink.description = 모든 기체 화물 적제소의 매니폴트의 이동 경로를 표시합니다. setting.blockRange.name = 블록 사거리 표시 setting.blockRange.description = 가능한 모든 포탑 사거리를 표시합니다 @@ -51,6 +53,8 @@ setting.groundRange.name = 지상 사거리 표시 setting.groundRange.description = 지상 유닛을 공격할 수 있는 가능한 모든 포탑/유닛 사거리를 표시합니다 setting.aliceRange.name = 아군 사거리 표시 setting.aliceRange.description = 가능한 모든 아군 포탑/유닛 사거리를 표시합니다 +setting.playerRange.name = 플레이어 사거리 표시 +setting.playerRange.description = 플레이어의 사거리를 표시합니다. setting.RangeShader.name = 애니메이션 활성화 setting.RangeShader.description = 사거리를 더 쉽게 보기 위한 애니메이션 쉐이더를 활성화합니다. 비활성화 시 점선이 표시됩니다. @@ -58,16 +62,16 @@ setting.pathLine.name = 단계 길 표시 setting.pathLine.description = 단계 지상/해상 유닛들의 ai 길찾기를 가시화합니다. setting.logicLine.name = 로직 조종선 표시 setting.logicLine.description = 프로세서와 조종중인 유닛의 관계를 가시화합니다. -setting.unitLine.name = 유닛 길 표시 -setting.unitLine.description = 지상/해상 유닛들의 AI 길찾기를 가시화합니다. 단계 길보다 더 정확합니다. +setting.unitPathLine.name = 유닛 길 표시 +setting.unitPathLine.description = 지상/해상 유닛들의 AI 길찾기를 가시화합니다. 단계 길보다 더 정확합니다. setting.commandLine.name = 지휘 길 표시 setting.commandLine.description = 자동 길찾기 대신 직접 지휘로 인해 이동중인 유닛들의 경로를 가시화합니다. setting.unitItem.name = 유닛 아이템 표시 setting.unitItem.description = 유닛이 들고 있는 아이템의 수량을 표시합니다. setting.unitBar.name = 유닛 바 표시 setting.unitBar.description = 각 유닛의 체력, 탄약, 방어막, 상태이상, 화물에 대해서 간략하게 표시합니다. -setting.autoShooting.name = 자동 사격 활성화 -setting.autoShooting.description = 데스크톱에서 모바일의 자동 사격을 사용할 수 있게 됩니다. +setting.autoShoot.name = 자동 사격 활성화 +setting.autoShoot.description = 데스크톱에서 모바일의 자동 사격을 사용할 수 있게 됩니다. setting.spawnerarrow.name = 스폰포인트 화살표 setting.spawnerarrow.description = 적 단계 생성지점을 가르키는 화살표를 표시합니다. @@ -80,6 +84,9 @@ setting.elementdebug.description = 모든 UI 요소의 외곽선을 표시합니 setting.hiddenElem.name = 숨겨진 요소 표시 setting.hiddenElem.description = 숨겨진 요소의 외곽선도 표시합니다. +setting.gaycursor.name = 마법 커서 +setting.gaycursor.description = 커서를 마법적이게 만듭니다. + setting.shar-title = Informatis 설정 setting.shar-ui = 정보UI 설정 setting.shar-draw = 덧그리기 설정 diff --git a/assets/bundles/bundle_ru.properties b/assets/bundles/bundle_ru.properties index aa1932f..683b2e7 100644 --- a/assets/bundles/bundle_ru.properties +++ b/assets/bundles/bundle_ru.properties @@ -57,8 +57,8 @@ setting.uiopacity.description = set opacity of ui background. setting.softRangeOpacity.name = Soft Range Opacity setting.softRangeOpacity.description = set opacity of soft range. -setting.unitlinelimit.name = Лимит отображения путей -setting.unitlinelimit.description = слишком большое число путей может создавать лаги. Рекомендуется настроить под свое устройство. +setting.unitPathLinelimit.name = Лимит отображения путей +setting.unitPathLinelimit.description = слишком большое число путей может создавать лаги. Рекомендуется настроить под свое устройство. setting.gaycursor.name = Включить след курсора setting.gaycursor.description = Создает радужный эффект, следующий за курсором. setting.unithealthui.name = Отображать панель юнита @@ -74,8 +74,8 @@ setting.deadTarget.description = продолжать отображение к setting.distanceLine.name = Display distance line from info target setting.distanceLine.description = display dotted lines and numbers how far away the target is. -setting.autoShooting.name = Включить автострельбу. -setting.autoShooting.description = [red]не читери, не будь какахой +setting.autoShoot.name = Включить автострельбу. +setting.autoShoot.description = [red]не читери, не будь какахой setting.shar-title = Настройки informatis setting.shar-wave = InfoTap Setting diff --git a/assets/bundles/bundle_tr.properties b/assets/bundles/bundle_tr.properties index ffc64dc..18628d0 100644 --- a/assets/bundles/bundle_tr.properties +++ b/assets/bundles/bundle_tr.properties @@ -55,8 +55,8 @@ setting.softRangeOpacity.description = Alan çemberinin opaklığını ayarlar. setting.pathlinelimit.name = Yol Çizgisi Sınırı setting.pathlinelimit.description = Yüksek çizgi miktarı performans düşüşüne sebep olabilir. \nBu ayarlar cihaza uygun dereceye ayarlanmalıdır. -setting.unitlinelimit.name = Birlik Çizgisi Sınırı -setting.unitlinelimit.description = Yüksek çizgi miktarı performans düşüşüne sebep olabilir. \nBu ayarlar cihaza uygun dereceye ayarlanmalıdır. +setting.unitPathLinelimit.name = Birlik Çizgisi Sınırı +setting.unitPathLinelimit.description = Yüksek çizgi miktarı performans düşüşüne sebep olabilir. \nBu ayarlar cihaza uygun dereceye ayarlanmalıdır. setting.logiclinelimit.name = İşlem Çizgisi Sınırı setting.logiclinelimit.description = Yüksek çizgi miktarı performans düşüşüne sebep olabilir. \nBu ayarlar cihaza uygun dereceye ayarlanmalıdır. setting.spawnarrowlimit.name = Doğum Çizgisi Sınırı @@ -80,8 +80,8 @@ setting.distanceLine.description = Hedef ile oyuncu arasındaki mesafeyi kesikli setting.spawnerarrow.name = Dalga Başlangıç Noktasını Göster setting.spawnerarrow.description = -setting.autoShooting.name = Enable Auto Shooting -setting.autoShooting.description = no don't do hack +setting.autoShoot.name = Enable Auto Shooting +setting.autoShoot.description = no don't do hack setting.shar-title = informatis Ayarları setting.shar-ui = Arayüz Ayarları diff --git a/assets/bundles/bundle_uk_UA.properties b/assets/bundles/bundle_uk_UA.properties index 59f6b89..595ded5 100644 --- a/assets/bundles/bundle_uk_UA.properties +++ b/assets/bundles/bundle_uk_UA.properties @@ -58,8 +58,8 @@ setting.softRangeOpacity.description = Установлює прозорість setting.pathlinelimit.name = Обмеження ліній шляху setting.pathlinelimit.description = Забагато рядків можуть спричинити значні підвисання пристрою.\nНалаштовуйте опираючись на можливості пристроя. -setting.unitlinelimit.name = Ліміт позначення шляхів -setting.unitlinelimit.description = Забагато рядків можуть спричинити значні підвисання пристрою.\nНалаштовуйте опираючись на можливості пристроя. +setting.unitPathLinelimit.name = Ліміт позначення шляхів +setting.unitPathLinelimit.description = Забагато рядків можуть спричинити значні підвисання пристрою.\nНалаштовуйте опираючись на можливості пристроя. setting.logiclinelimit.name = Обмеження ліній логіки setting.logiclinelimit.description = Забагато рядків можуть спричинити значні підвисання пристрою.\nНалаштовуйте опираючись на можливості пристроя. setting.spawnarrowlimit.name = Обмеження стрілок появи @@ -83,8 +83,8 @@ setting.distanceLine.description = Показує пунктирні лінії setting.spawnerarrow.name = Вказує точку появи хвиль. setting.spawnerarrow.description = Показує стрілку, направлену на точку появи хвиль. -setting.autoShooting.name = Увімкнути автострільбу -setting.autoShooting.description = Не треба, ти ж не гакер. +setting.autoShoot.name = Увімкнути автострільбу +setting.autoShoot.description = Не треба, ти ж не гакер. setting.shar-title = Налаштування informatis setting.shar-ui = Налаштування накладання інтерфейсу @@ -102,7 +102,7 @@ hud.cancel = Сховано hud.enabled = [accent]Увімкнено[] hud.disabled = [gray]Вимкнено[] hud.pathline = Лінія шляху -hud.unitline = Лінія одиниць +hud.unitPathLine = Лінія одиниць hud.logicline = Лінія логіки #Other diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 7a68766..1c2ad59 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -36,8 +36,8 @@ setting.blockBar.description = 显示方块生命栏 setting.powerNode.name = 启用电力节点 setting.powerNode.description = 显示电力节点连接线 -setting.massDriver.name = 启用质量驱动器 -setting.massDriver.description = 显示质量驱动器连接线 +setting.massLink.name = 启用质量驱动器 +setting.massLink.description = 显示质量驱动器连接线 setting.blockRange.name = 显示方块范围 setting.blockRange.description = 显示每个可用炮塔的范围 @@ -58,16 +58,16 @@ setting.pathLine.name = 启用路径线 setting.pathLine.description = 显示波次中地面单位AI的路径 setting.logicLine.name = 启用逻辑线 setting.logicLine.description = 在逻辑处理器和受控单位之间显示连接线 -setting.unitLine.name = 启用单位线 -setting.unitLine.description = 显示地面单位的AI路径 +setting.unitPathLine.name = 启用单位线 +setting.unitPathLine.description = 显示地面单位的AI路径 setting.commandLine.name = 启用命令线 setting.cocmmandLine.description = 显示由RTS命令控制的单位的行进路径线 setting.unitItem.name = 启用单位物品 setting.unitItem.description = 显示单位的物品数量 setting.unitBar.name = 启用单位栏 setting.unitBar.description = 显示单位的生命栏 -setting.autoShooting.name = 启用自动射击 -setting.autoShooting.description = 不,不要做黑客 +setting.autoShoot.name = 启用自动射击 +setting.autoShoot.description = 不,不要做黑客 setting.spawnerarrow.name = 指示波次生成点 setting.spawnerarrow.description = 显示指向波次生成点的箭头. diff --git a/src/informatis/SUtils.java b/src/informatis/SUtils.java index 6acfb6c..b356acf 100644 --- a/src/informatis/SUtils.java +++ b/src/informatis/SUtils.java @@ -7,9 +7,11 @@ import arc.math.geom.Position; import arc.scene.style.*; import arc.struct.Seq; import arc.util.*; +import informatis.core.Pathfinder; import mindustry.Vars; import mindustry.core.UI; import mindustry.entities.bullet.*; +import mindustry.game.Team; import mindustry.gen.*; import mindustry.input.DesktopInput; import mindustry.type.UnitType; @@ -20,8 +22,7 @@ import java.lang.reflect.*; import static informatis.SVars.*; import static arc.Core.*; -import static mindustry.Vars.control; -import static mindustry.Vars.player; +import static mindustry.Vars.*; public class SUtils { /** @@ -76,6 +77,38 @@ public class SUtils { return Strings.fixed(number.floatValue(), step); } + public static Seq generatePathTiles() { + Seq pathTiles = new Seq<>(); + + spawner.getSpawns().each(tile -> pathTiles.addAll(generatePathTiles(tile))); + + return pathTiles; + } + public static Seq generatePathTiles(Tile startTile) { + Seq pathTiles = new Seq<>(); + + for(int p = 0; p < 3; p++) { + getNextTile(startTile, SVars.pathfinder.getField(state.rules.waveTeam, p, Pathfinder.fieldCore), pathTiles); + } + + return pathTiles; + } + + public static Seq generatePathTiles(Tile startTile, Team team, int type) { + Seq pathTiles = new Seq<>(); + + getNextTile(startTile, SVars.pathfinder.getField(team, type, Pathfinder.fieldCore), pathTiles); + + return pathTiles; + } + + static void getNextTile(Tile tile, Pathfinder.Flowfield field, Seq pathTiles) { + Tile nextTile = SVars.pathfinder.getTargetTile(tile, field); + pathTiles.add(nextTile); + if(nextTile == tile || nextTile == null) return; + getNextTile(nextTile, field, pathTiles); + } + public static float bulletRange(BulletType b) { float a = 0; float n = 1; diff --git a/src/informatis/core/OverDrawer.java b/src/informatis/core/OverDrawer.java index ace6ed8..724518a 100644 --- a/src/informatis/core/OverDrawer.java +++ b/src/informatis/core/OverDrawer.java @@ -73,10 +73,6 @@ public class OverDrawer { Pal.accent, 0.25f, false, Align.center); } } - - //global drawing, which needs camera-clipping - Core.camera.bounds(Tmp.r1); - for(OverDraw drawer : OverDraws.all) drawer.draw(); Draw.reset(); }); } diff --git a/src/informatis/draws/AutoShootDraw.java b/src/informatis/draws/AutoShootDraw.java new file mode 100644 index 0000000..d6d4373 --- /dev/null +++ b/src/informatis/draws/AutoShootDraw.java @@ -0,0 +1,73 @@ +package informatis.draws; + +import arc.input.KeyCode; +import arc.math.Angles; +import arc.math.geom.Geometry; +import mindustry.entities.Units; +import mindustry.game.Team; +import mindustry.gen.*; +import mindustry.logic.Ranged; +import mindustry.world.blocks.ControlBlock; +import mindustry.world.blocks.defense.turrets.Turret; + +import static arc.Core.*; +import static mindustry.Vars.*; + +public class AutoShootDraw extends OverDraw { + Teamc shotTarget; + + AutoShootDraw() { + super("autoShoot", OverDrawCategory.Util); + } + + @Override + public void update() { + Unit unit = player.unit(); + if (unit.type == null) return; + boolean omni = unit.type.omniMovement; + boolean validHealTarget = unit.type.canHeal && shotTarget instanceof Building b && b.isValid() && b.damaged() && shotTarget.team() == unit.team && shotTarget.within(unit, unit.type.range); + boolean boosted = (unit instanceof Mechc && unit.isFlying()); + if ((unit.type != null && Units.invalidateTarget(shotTarget, unit, unit.type.range) && !validHealTarget) || state.isEditor()) { + shotTarget = null; + } + + float mouseAngle = unit.angleTo(unit.aimX(), unit.aimY()); + boolean aimCursor = omni && player.shooting && unit.type.hasWeapons() && unit.type.faceTarget && !boosted && unit.type.rotateToBuilding; + unit.lookAt(aimCursor ? mouseAngle : unit.prefRotation()); + + //update shooting if not building + not mining + if(!player.unit().activelyBuilding() && player.unit().mineTile == null) { + if(input.keyDown(KeyCode.mouseLeft)) { + player.shooting = !boosted; + unit.aim(player.mouseX = input.mouseWorldX(), player.mouseY = input.mouseWorldY()); + } else if(shotTarget == null) { + player.shooting = false; + if(unit instanceof BlockUnitUnit b) { + if(b.tile() instanceof ControlBlock c && !c.shouldAutoTarget()) { + Building build = b.tile(); + float range = build instanceof Ranged ? ((Ranged) build).range() : 0f; + boolean targetGround = build instanceof Turret.TurretBuild && ((Turret) build.block).targetAir; + boolean targetAir = build instanceof Turret.TurretBuild && ((Turret) build.block).targetGround; + shotTarget = Units.closestTarget(build.team, build.x, build.y, range, u -> u.checkTarget(targetAir, targetGround), u -> targetGround); + } + else shotTarget = null; + } else if(unit.type != null) { + float range = unit.hasWeapons() ? unit.range() : 0f; + shotTarget = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(unit.type.targetAir, unit.type.targetGround), u -> unit.type.targetGround); + + if(unit.type.canHeal && shotTarget == null) { + shotTarget = Geometry.findClosest(unit.x, unit.y, indexer.getDamaged(Team.sharded)); + if (shotTarget != null && !unit.within(shotTarget, range)) { + shotTarget = null; + } + } + } + } else { + player.shooting = !boosted; + unit.rotation(Angles.angle(unit.x, unit.y, shotTarget.x(), shotTarget.y())); + unit.aim(shotTarget.x(), shotTarget.y()); + } + } + unit.controlWeapons(player.shooting && !boosted); + } +} diff --git a/src/informatis/draws/BlockBarDraw.java b/src/informatis/draws/BlockBarDraw.java new file mode 100644 index 0000000..7e0eeb3 --- /dev/null +++ b/src/informatis/draws/BlockBarDraw.java @@ -0,0 +1,61 @@ +package informatis.draws; + +import arc.graphics.Color; +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Fill; +import mindustry.Vars; +import mindustry.gen.Building; +import mindustry.graphics.Pal; +import mindustry.world.Tile; +import mindustry.world.blocks.ConstructBlock; +import mindustry.world.blocks.defense.turrets.Turret; +import mindustry.world.blocks.units.Reconstructor; +import mindustry.world.blocks.units.UnitFactory; + +import static arc.Core.settings; +import static informatis.SUtils.isInCamera; + +public class BlockBarDraw extends OverDraw { + public BlockBarDraw() { + super("blockBar", OverDrawCategory.Block); + } + + @Override + public void onTile(Tile tile) { + if(!isInCamera(tile.worldx(), tile.worldy(), 8) || tile.build == null) return; + + Building b = tile.build; + + if(settings.getBool("blockBar")) { + drawBar(b, 0, -(b.block.size * 4 - 2), b.healthf(), Pal.health); + + if (b instanceof Turret.TurretBuild turretBuild) { + drawBar(b, 0, b.block.size * 4 - 2, turretBuild.reloadCounter / ((Turret) b.block).reload, Pal.ammo); + } + if(b instanceof ConstructBlock.ConstructBuild constructBuild) + drawBar(b, 0, b.block.size * 4 - 2, constructBuild.progress(), b.team.color); + if(b instanceof Reconstructor.ReconstructorBuild reconstructorBuild) + drawBar(b, 0, b.block.size * 4 - 2, reconstructorBuild.fraction(), b.team.color); + if(b instanceof UnitFactory.UnitFactoryBuild factoryBuild) + drawBar(b, 0, b.block.size * 4 - 2, factoryBuild.fraction(), b.team.color); + } + } + + void drawBar(Building b, float offsetX, float offsetY, float progress, Color color) { + float bx = b.x + offsetX, by = b.y + offsetY; + float width = b.block.size * 7.5f, height = 2; + Draw.color(Pal.gray); + Fill.quad( + bx - width/2, by + height/2, + bx - width/2, by - height/2, + bx + width/2, by - height/2, + bx + width/2, by + height/2); + Draw.color(color); + width = b.block.size * 7.5f - 0.5f; height = 2 - 0.5f; + Fill.quad( + bx - width/2, by + height/2, + bx - width/2, by - height/2, + bx - width/2 + width * progress, by - height/2, + bx - width/2 + width * progress, by + height/2); + } +} diff --git a/src/informatis/draws/BlockDraw.java b/src/informatis/draws/BlockDraw.java deleted file mode 100644 index f174a9a..0000000 --- a/src/informatis/draws/BlockDraw.java +++ /dev/null @@ -1,85 +0,0 @@ -package informatis.draws; - -import arc.graphics.Color; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.Fill; -import arc.scene.style.TextureRegionDrawable; -import mindustry.Vars; -import mindustry.gen.Building; -import mindustry.gen.Groups; -import mindustry.graphics.Pal; -import mindustry.world.Tile; -import mindustry.world.blocks.ConstructBlock; -import mindustry.world.blocks.defense.turrets.Turret; -import mindustry.world.blocks.units.Reconstructor; -import mindustry.world.blocks.units.UnitFactory; - -import static informatis.SUtils.*; -import static arc.Core.settings; - -public class BlockDraw extends OverDraw { - BlockDraw(String name, TextureRegionDrawable icon) { - super(name, icon); - registerOption("blockBar"); - registerOption("blockstatus"); - } - - @Override - public void draw() { - super.draw(); - - if(!enabled) return; - Groups.build.each(b -> { - if(!isInCamera(b.x, b.y, b.block.size/2f)) return; - if(settings.getBool("blockstatus") && b.team != Vars.player.team() && b.block.consumers.length > 0) { - float multiplier = b.block.size > 1 ? 1.0F : 0.64F; - float brcx = b.x + (float)(b.block.size * 8) / 2.0F - 8.0F * multiplier / 2.0F; - float brcy = b.y - (float)(b.block.size * 8) / 2.0F + 8.0F * multiplier / 2.0F; - Draw.z(71.0F); - Draw.color(Pal.gray); - Fill.square(brcx, brcy, 2.5F * multiplier, 45.0F); - Draw.color(b.status().color); - Fill.square(brcx, brcy, 1.5F * multiplier, 45.0F); - Draw.color(); - } - - }); - for (Tile tile : Vars.world.tiles) { - if(!isInCamera(tile.worldx(), tile.worldy(), 8) || tile.build == null) continue; - - Building b = tile.build; - - if(settings.getBool("blockBar")) { - drawBar(b, 0, -(b.block.size * 4 - 2), b.healthf(), Pal.health); - - if (b instanceof Turret.TurretBuild turretBuild) { - drawBar(b, 0, b.block.size * 4 - 2, turretBuild.reloadCounter / ((Turret) b.block).reload, Pal.ammo); - } - if(b instanceof ConstructBlock.ConstructBuild constructBuild) - drawBar(b, 0, b.block.size * 4 - 2, constructBuild.progress(), b.team.color); - if(b instanceof Reconstructor.ReconstructorBuild reconstructorBuild) - drawBar(b, 0, b.block.size * 4 - 2, reconstructorBuild.fraction(), b.team.color); - if(b instanceof UnitFactory.UnitFactoryBuild factoryBuild) - drawBar(b, 0, b.block.size * 4 - 2, factoryBuild.fraction(), b.team.color); - } - } - } - - void drawBar(Building b, float offsetX, float offsetY, float progress, Color color) { - float bx = b.x + offsetX, by = b.y + offsetY; - float width = b.block.size * 7.5f, height = 2; - Draw.color(Pal.gray); - Fill.quad( - bx - width/2, by + height/2, - bx - width/2, by - height/2, - bx + width/2, by - height/2, - bx + width/2, by + height/2); - Draw.color(color); - width = b.block.size * 7.5f - 0.5f; height = 2 - 0.5f; - Fill.quad( - bx - width/2, by + height/2, - bx - width/2, by - height/2, - bx - width/2 + width * progress, by - height/2, - bx - width/2 + width * progress, by + height/2); - } -} diff --git a/src/informatis/draws/BlockRangeDraw.java b/src/informatis/draws/BlockRangeDraw.java new file mode 100644 index 0000000..2765b00 --- /dev/null +++ b/src/informatis/draws/BlockRangeDraw.java @@ -0,0 +1,57 @@ +package informatis.draws; + +import arc.graphics.g2d.*; +import mindustry.game.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.world.blocks.defense.turrets.*; + +import static arc.Core.settings; +import static informatis.SUtils.isInCamera; +import static mindustry.Vars.player; + +public class BlockRangeDraw extends OverDraw { + public BlockRangeDraw() { + super("blockRange", OverDrawCategory.Range); + } + + @Override + public void onBuilding(Building build) { + Unit playerUnit = player.unit(); + + boolean includeInvalid = settings.getBool("invalidRange", true), + includeAir = settings.getBool("airRange", true), isAir = playerUnit == null || playerUnit.isFlying(), + includeGround = settings.getBool("groundRange", true), isGround = playerUnit == null || !playerUnit.isFlying(), + includeAlice = settings.getBool("aliceRange", true), + shader = settings.getBool("RangeShader", true); + + if(!((includeAlice || player.team() != build.team) + && build instanceof BaseTurret.BaseTurretBuild turret && isInCamera(build.x, build.y, turret.range() * 2))) return; + + boolean valid = false; + if (build instanceof Turret.TurretBuild turretBuild) { + Turret block = (Turret) turretBuild.block; + if ((build.team == player.team() + || (block.targetAir && isAir && includeAir) + || (block.targetGround && isGround && includeGround)) + && turretBuild.hasAmmo() && turretBuild.canConsume()) valid = true; + } else if (build instanceof TractorBeamTurret.TractorBeamBuild tractorBeamBuild) { + TractorBeamTurret block = (TractorBeamTurret) tractorBeamBuild.block; + if ((build.team == player.team() + || (block.targetAir && isAir && includeAir) + || (block.targetGround && isGround && includeGround)) + && tractorBeamBuild.canConsume()) valid = true; + } + + if(!includeInvalid && !valid) return; + + //non-base teams are considered as crux + int index = valid ? build.team.id > 5 ? 2 : build.team.id : 0; + float range = turret.range(); + Draw.color(Team.baseTeams[index].color); + if (shader) { + Draw.z(166+(Team.baseTeams.length-index)*3); + Fill.poly(build.x, build.y, Lines.circleVertices(range), range); + } else Drawf.dashCircle(build.x, build.y, range, Team.baseTeams[index].color); + } +} diff --git a/src/informatis/draws/BlockStatusDraw.java b/src/informatis/draws/BlockStatusDraw.java new file mode 100644 index 0000000..73012ff --- /dev/null +++ b/src/informatis/draws/BlockStatusDraw.java @@ -0,0 +1,30 @@ +package informatis.draws; + +import arc.graphics.g2d.Draw; +import arc.graphics.g2d.Fill; +import mindustry.Vars; +import mindustry.gen.Building; +import mindustry.graphics.Pal; + +import static informatis.SUtils.isInCamera; + +public class BlockStatusDraw extends OverDraw { + public BlockStatusDraw() { + super("blockstatus", OverDrawCategory.Block); + } + @Override + public void onBuilding(Building build) { + if(!isInCamera(build.x, build.y, build.block.size/2f)) return; + if(build.team != Vars.player.team() && build.block.consumers.length > 0) { + float multiplier = build.block.size > 1 ? 1.0F : 0.64F; + float brcx = build.x + (float)(build.block.size * 8) / 2.0F - 8.0F * multiplier / 2.0F; + float brcy = build.y - (float)(build.block.size * 8) / 2.0F + 8.0F * multiplier / 2.0F; + Draw.z(71.0F); + Draw.color(Pal.gray); + Fill.square(brcx, brcy, 2.5F * multiplier, 45.0F); + Draw.color(build.status().color); + Fill.square(brcx, brcy, 1.5F * multiplier, 45.0F); + Draw.color(); + } + } +} diff --git a/src/informatis/draws/CommandLineDraw.java b/src/informatis/draws/CommandLineDraw.java new file mode 100644 index 0000000..4efe4b6 --- /dev/null +++ b/src/informatis/draws/CommandLineDraw.java @@ -0,0 +1,19 @@ +package informatis.draws; + +import arc.graphics.g2d.Lines; +import mindustry.ai.types.CommandAI; +import mindustry.gen.Unit; + +public class CommandLineDraw extends OverDraw { + public CommandLineDraw() { + super("commandLine", OverDrawCategory.Unit); + } + + @Override + public void onUnit(Unit unit) { + if(unit.controller() instanceof CommandAI com && com.hasCommand()) { + Lines.stroke(1, unit.team.color); + Lines.line(unit.x(), unit.y(), com.targetPos.x, com.targetPos.y); + } + } +} diff --git a/src/informatis/draws/LogicLineDraw.java b/src/informatis/draws/LogicLineDraw.java new file mode 100644 index 0000000..2e81e43 --- /dev/null +++ b/src/informatis/draws/LogicLineDraw.java @@ -0,0 +1,25 @@ +package informatis.draws; + +import arc.graphics.g2d.Lines; +import arc.math.Mathf; +import arc.util.Tmp; +import mindustry.ai.types.LogicAI; +import mindustry.gen.Unit; +import mindustry.graphics.Pal; +import mindustry.logic.LUnitControl; + +public class LogicLineDraw extends OverDraw { + public LogicLineDraw() { + super("logicLine", OverDrawCategory.Unit); + } + + @Override + public void onUnit(Unit unit) { + if(unit.controller() instanceof LogicAI ai && (ai.control == LUnitControl.approach || ai.control == LUnitControl.move)) { + Lines.stroke(1, unit.team.color); + Lines.line(unit.x(), unit.y(), ai.moveX, ai.moveY); + Lines.stroke(0.5f + Mathf.absin(6f, 0.5f), Tmp.c1.set(Pal.logicOperations).lerp(Pal.sap, Mathf.absin(6f, 0.5f))); + Lines.line(unit.x(), unit.y(), ai.controller.x, ai.controller.y); + } + } +} diff --git a/src/informatis/draws/MagicCursorDraw.java b/src/informatis/draws/MagicCursorDraw.java new file mode 100644 index 0000000..c91523e --- /dev/null +++ b/src/informatis/draws/MagicCursorDraw.java @@ -0,0 +1,24 @@ +package informatis.draws; + +import arc.Core; +import arc.graphics.Color; +import arc.util.Time; +import arc.util.Tmp; +import mindustry.Vars; +import mindustry.content.Fx; + +import static arc.Core.settings; +import static mindustry.Vars.mobile; + +public class MagicCursorDraw extends OverDraw { + public MagicCursorDraw() { + super("gaycursor", OverDrawCategory.Util); + } + + @Override + public void draw() { + if(!mobile && !Vars.state.isPaused()) { + Fx.mine.at(Core.input.mouseWorldX(), Core.input.mouseWorldY(), Tmp.c2.set(Color.red).shiftHue(Time.time * 1.5f)); + } + } +} diff --git a/src/informatis/draws/LinkDraw.java b/src/informatis/draws/MassLinkDraw.java similarity index 58% rename from src/informatis/draws/LinkDraw.java rename to src/informatis/draws/MassLinkDraw.java index 3b41059..bb99ded 100644 --- a/src/informatis/draws/LinkDraw.java +++ b/src/informatis/draws/MassLinkDraw.java @@ -1,86 +1,46 @@ package informatis.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.style.TextureRegionDrawable; -import arc.struct.IntSeq; import arc.struct.Seq; import arc.util.Time; import arc.util.Tmp; -import mindustry.ai.types.CargoAI; -import mindustry.core.Renderer; -import mindustry.entities.units.UnitController; import mindustry.gen.Building; import mindustry.gen.Groups; import mindustry.gen.Teamc; -import mindustry.gen.Unit; import mindustry.graphics.Drawf; -import mindustry.graphics.Layer; import mindustry.graphics.Pal; -import mindustry.world.Build; import mindustry.world.blocks.distribution.MassDriver; import mindustry.world.blocks.payloads.PayloadMassDriver; -import mindustry.world.blocks.units.UnitCargoLoader; -import static arc.Core.atlas; -import static arc.Core.settings; import static informatis.SUtils.getTarget; -import static mindustry.Vars.*; -import static informatis.SVars.*; +import static mindustry.Vars.tilesize; +import static mindustry.Vars.world; -public class LinkDraw extends OverDraw { +public class MassLinkDraw extends OverDraw { Seq linkedMasses = new Seq<>(); Seq linkedPayloadMasses = new Seq<>(); - Seq linkedNodes = new Seq<>(); - LinkDraw(String name, TextureRegionDrawable icon) { - super(name, icon); - registerOption("powerNode"); - registerOption("massDriver"); + public MassLinkDraw() { + super("massLink", OverDrawCategory.Link); } + @Override public void draw() { - if(!enabled) return; Teamc target = getTarget(); - Draw.z(Layer.max); - - Groups.build.each(building -> { - if(building instanceof UnitCargoLoader.UnitTransportSourceBuild build) { - Unit unit = build.unit; - if(unit != null && unit.item() != null && unit.controller() instanceof CargoAI ai && ai.unloadTarget != null) { - Building targetBuild = ai.unloadTarget; - - Lines.stroke(2); - Draw.color(build.team.color); - Draw.alpha(0.5f); - Lines.line(build.x, build.y, unit.x, unit.y); - Draw.color(unit.item().color); - Draw.alpha(0.5f); - Lines.line(unit.x, unit.y, targetBuild.x, targetBuild.y); - } - } - }); - if(target instanceof Building b){ - if(settings.getBool("powerNode") && enabled) { - linkedNodes.clear(); - drawNodeLink(b); - } - if(settings.getBool("massDriver") && enabled) { - if (target instanceof MassDriver.MassDriverBuild mass) { - linkedMasses.clear(); - drawMassLink(mass); - } else if (target instanceof PayloadMassDriver.PayloadDriverBuild mass) { - linkedPayloadMasses.clear(); - drawMassPayloadLink(mass); - } + if(target instanceof Building build) { + if (target instanceof MassDriver.MassDriverBuild mass) { + linkedMasses.clear(); + drawMassLink(mass); + } else if (target instanceof PayloadMassDriver.PayloadDriverBuild mass) { + linkedPayloadMasses.clear(); + drawMassPayloadLink(mass); } } } + void drawMassPayloadLink(PayloadMassDriver.PayloadDriverBuild from){ float sin = Mathf.absin(Time.time, 6f, 1f); @@ -154,30 +114,4 @@ public class LinkDraw extends OverDraw { } } } - - IntSeq getPowerLinkedBuilds(Building build) { - IntSeq seq = new IntSeq(build.power.links); - seq.addAll(build.proximity().mapInt(Building::pos)); - return seq; - } - - void drawNodeLink(Building node) { - if(node.power == null) return; - if(!linkedNodes.contains(node)) { - linkedNodes.add(node); - int[] builds = getPowerLinkedBuilds(node).items; - for(int i : builds) { - Building other = world.build(i); - if(other == null || other.power == null) return; - float angle1 = Angles.angle(node.x, node.y, other.x, other.y), - vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1), - len1 = node.block.size * tilesize / 2f - 1.5f, len2 = other.block.size * tilesize / 2f - 1.5f; - Draw.color(Color.white, Color.valueOf("98ff98"), (1f - node.power.graph.getSatisfaction()) * 0.86f + Mathf.absin(3f, 0.1f)); - Draw.alpha(Renderer.laserOpacity); - Drawf.laser(atlas.find("informatis-Slaser"), atlas.find("informatis-Slaser"), atlas.find("informatis-Slaser-end"), node.x + vx * len1, node.y + vy * len1, other.x - vx * len2, other.y - vy * len2, 0.25f); - - drawNodeLink(other); - } - } - } } diff --git a/src/informatis/draws/OverDraw.java b/src/informatis/draws/OverDraw.java index 49c43b8..6dee436 100644 --- a/src/informatis/draws/OverDraw.java +++ b/src/informatis/draws/OverDraw.java @@ -5,54 +5,46 @@ import arc.scene.style.TextureRegionDrawable; import arc.scene.ui.CheckBox; import arc.scene.ui.layout.Table; import arc.struct.Seq; +import mindustry.gen.Building; +import mindustry.gen.Unit; import mindustry.ui.Styles; +import mindustry.world.Tile; import static arc.Core.bundle; import static arc.Core.settings; public class OverDraw { - public TextureRegionDrawable icon; public String name; - public boolean enabled = false; - public Seq options = new Seq<>(); - OverDraw(String name, TextureRegionDrawable icon) { + OverDraw(String name, OverDrawCategory category) { this.name = name; - this.icon = icon; + + OverDraws.getDraws().get(category, new Seq<>()).add(this); } - public void displayStats(Table parent) { - if(options.isEmpty()) return; - parent.background(Styles.squarei.up); - parent.left(); - options.each(name-> parent - .check(bundle.get("setting."+name+".name"), settings.getBool(name), b->settings.put(name, b)) - .tooltip(t-> { - if(bundle.has("setting."+name+".description")) - t.background(Styles.black8).add(bundle.get("setting."+name+".description")); - }) - .disabled(!enabled) - .left().row()); - } + /** + * Groups.build 에서 각 건물에 대한 그리기를 처리합니다. + * @param build 각 Building 엔티티 + */ + public void onBuilding(Building build) { } + /** + * Groups.unit 에서 각 유닛에 대한 그리기를 처리합니다. + * @param unit 각 Unit 엔티티 + */ + public void onUnit(Unit unit) { } + + /** + * Vars.world.tiles 에서 각 타일에 대한 그리기를 처리합니다. + * @param tile 각 Tile 엔티티 + */ + public void onTile(Tile tile) { } + + /** + * 매 프레임에 대한 그리기를 처리합니다. + */ public void draw() {} - public void onEnabled(T param) { - if(param instanceof Table t) { - for (int i = 0; i < t.getChildren().size; i++) { - Element elem = t.getChildren().get(i); - if (elem instanceof CheckBox cb) cb.setDisabled(!enabled); - } - } - } - - public void registerOption(String name) { - registerOption(name, settings.has(name) && settings.getBool(name)); - } - - public void registerOption(String name, boolean defaults) { - options.add(name); - settings.put(name, defaults); - } + public void update() {} } diff --git a/src/informatis/draws/OverDrawCategory.java b/src/informatis/draws/OverDrawCategory.java new file mode 100644 index 0000000..a245710 --- /dev/null +++ b/src/informatis/draws/OverDrawCategory.java @@ -0,0 +1,21 @@ +package informatis.draws; + +import arc.scene.style.Drawable; +import mindustry.gen.Icon; + +public enum OverDrawCategory { + Range("Range", Icon.commandRally), + Link("Link", Icon.line), + Unit("Unit", Icon.units), + Block("Block", Icon.crafting), + Util("Util", Icon.github); + + public final String name; + public final Drawable icon; + public boolean enabled = false; + + OverDrawCategory(String name, Drawable icon) { + this.name = name; + this.icon = icon; + } +} diff --git a/src/informatis/draws/OverDraws.java b/src/informatis/draws/OverDraws.java index 637bca4..fc66ae1 100644 --- a/src/informatis/draws/OverDraws.java +++ b/src/informatis/draws/OverDraws.java @@ -1,17 +1,87 @@ package informatis.draws; -import mindustry.gen.Icon; +import arc.Core; +import arc.Events; +import arc.func.Cons; +import arc.graphics.Color; +import arc.graphics.g2d.Draw; +import arc.graphics.gl.FrameBuffer; +import arc.struct.*; +import arc.util.Tmp; +import mindustry.Vars; +import mindustry.game.EventType; +import mindustry.game.Team; +import mindustry.gen.Groups; +import mindustry.world.Tile; + +import static arc.Core.graphics; +import static informatis.SVars.turretRange; public class OverDraws { - public static OverDraw range, link, unit, block, util; - public static OverDraw[] all = {}; + public static OverDraw + blockBar = new BlockBarDraw(), + blockStatus = new BlockStatusDraw(), + powerNode = new PowerNodeDraw(), + unitCargoLink = new UnitCargoLinkDraw(), + massLink = new MassLinkDraw(), + blockRange = new BlockRangeDraw(), + unitRange = new UnitRangeDraw(), + playerRange = new PlayerRangeDraw(), + pathLine = new PathLineDraw(), + logicLine = new LogicLineDraw(), + commandLine = new CommandLineDraw(), + unitPathLine = new UnitPathLineDraw(), + unitItem = new UnitItemDraw(), + unitBar = new UnitBarDraw(), + magicCursor = new MagicCursorDraw(), + autoShoot = new AutoShootDraw(); + static ObjectMap> draws; + static FrameBuffer effectBuffer = new FrameBuffer(); public static void init() { - range = new RangeDraw("Range Draws", Icon.commandRally); - link = new LinkDraw("Link Draws", Icon.line); - unit = new UnitDraw("Unit Draws", Icon.units); - block = new BlockDraw("Block Draws", Icon.crafting); - util = new UtilDraw("Utils", Icon.github); - all = new OverDraw[]{range, link, unit, block, util}; + Events.run(EventType.Trigger.draw, () -> { + Core.camera.bounds(Tmp.r1); + effectBuffer.resize(graphics.getWidth(), graphics.getHeight()); + for(Team team : Team.baseTeams) { + Draw.drawRange(166 + (Team.baseTeams.length-team.id) * 3, 1, () -> effectBuffer.begin(Color.clear), () -> { + effectBuffer.end(); + effectBuffer.blit(turretRange); + }); + } + + Groups.build.each(building -> + eachDraws(draw -> draw.onBuilding(building)) + ); + Groups.unit.each(unit -> + eachDraws(draw -> draw.onUnit(unit)) + ); + for(Tile tile : Vars.world.tiles) { + eachDraws(draw -> draw.onTile(tile)); + } + eachDraws(OverDraw::draw); + }); + + Events.run(EventType.Trigger.update, () -> { + eachDraws(OverDraw::update); + }); + } + + public static ObjectMap> getDraws() { + if(draws == null) { + draws = new ObjectMap<>(); + for(OverDrawCategory category : OverDrawCategory.values()) { + draws.put(category, new Seq<>()); + } + } + return draws; + } + + static void eachDraws(Cons runner) { + OverDraws.draws.entries().forEach(draws -> { + if(draws.key.enabled) draws.value.each(draw -> { + if(Core.settings.getBool(draw.name, false)) runner.get(draw); + Draw.reset(); + }); + }); } } diff --git a/src/informatis/draws/PathLineDraw.java b/src/informatis/draws/PathLineDraw.java new file mode 100644 index 0000000..e66c7af --- /dev/null +++ b/src/informatis/draws/PathLineDraw.java @@ -0,0 +1,26 @@ +package informatis.draws; + +import arc.graphics.g2d.Lines; +import arc.struct.Seq; +import informatis.SUtils; +import mindustry.world.Tile; + +import static mindustry.Vars.state; + +public class PathLineDraw extends OverDraw { + public PathLineDraw() { + super("pathLine", OverDrawCategory.Unit); + } + + @Override + public void draw() { + Seq pathTiles = SUtils.generatePathTiles(); + + Lines.stroke(1, state.rules.waveTeam.color); + for(int i = 0; i < pathTiles.size - 1; i++) { + Tile from = pathTiles.get(i), to = pathTiles.get(i + 1); + if(from == null || to == null) continue; + Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); + } + } +} diff --git a/src/informatis/draws/PlayerRangeDraw.java b/src/informatis/draws/PlayerRangeDraw.java new file mode 100644 index 0000000..6171b20 --- /dev/null +++ b/src/informatis/draws/PlayerRangeDraw.java @@ -0,0 +1,23 @@ +package informatis.draws; + +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.world.blocks.defense.turrets.*; + +import static informatis.SUtils.getTarget; + +public class PlayerRangeDraw extends OverDraw { + public PlayerRangeDraw() { + super("playerRange", OverDrawCategory.Range); + } + + @Override + public void draw() { + Teamc selected = getTarget(); + if(selected instanceof BaseTurret.BaseTurretBuild turretBuild) { + Drawf.dashCircle(turretBuild.x, turretBuild.y, turretBuild.range(), turretBuild.team.color); + } else if(selected instanceof Unit unit) { + Drawf.dashCircle(unit.x, unit.y, unit.range(), unit.team.color); + } + } +} diff --git a/src/informatis/draws/PowerNodeDraw.java b/src/informatis/draws/PowerNodeDraw.java new file mode 100644 index 0000000..de459c7 --- /dev/null +++ b/src/informatis/draws/PowerNodeDraw.java @@ -0,0 +1,56 @@ +package informatis.draws; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.struct.*; +import mindustry.core.*; +import mindustry.gen.*; +import mindustry.graphics.*; + +import static arc.Core.atlas; +import static informatis.SUtils.getTarget; +import static mindustry.Vars.tilesize; +import static mindustry.Vars.world; + +public class PowerNodeDraw extends OverDraw { + Seq linkedNodes = new Seq<>(); + + public PowerNodeDraw() { + super("powerNode", OverDrawCategory.Link); + } + + @Override + public void draw() { + if(getTarget() instanceof Building build) { + linkedNodes.clear(); + drawNodeLink(build); + } + } + + IntSeq getPowerLinkedBuilds(Building build) { + IntSeq seq = new IntSeq(build.power.links); + seq.addAll(build.proximity().mapInt(Building::pos)); + return seq; + } + + void drawNodeLink(Building node) { + if(node.power == null) return; + if(!linkedNodes.contains(node)) { + linkedNodes.add(node); + int[] builds = getPowerLinkedBuilds(node).items; + for(int i : builds) { + Building other = world.build(i); + if(other == null || other.power == null) return; + float angle1 = Angles.angle(node.x, node.y, other.x, other.y), + vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1), + len1 = node.block.size * tilesize / 2f - 1.5f, len2 = other.block.size * tilesize / 2f - 1.5f; + Draw.color(Color.white, Color.valueOf("98ff98"), (1f - node.power.graph.getSatisfaction()) * 0.86f + Mathf.absin(3f, 0.1f)); + Draw.alpha(Renderer.laserOpacity); + Drawf.laser(atlas.find("informatis-Slaser"), atlas.find("informatis-Slaser"), atlas.find("informatis-Slaser-end"), node.x + vx * len1, node.y + vy * len1, other.x - vx * len2, other.y - vy * len2, 0.25f); + + drawNodeLink(other); + } + } + } +} diff --git a/src/informatis/draws/RangeDraw.java b/src/informatis/draws/RangeDraw.java deleted file mode 100644 index 5f8df50..0000000 --- a/src/informatis/draws/RangeDraw.java +++ /dev/null @@ -1,118 +0,0 @@ -package informatis.draws; - -import arc.graphics.Color; -import arc.graphics.g2d.*; -import arc.graphics.gl.FrameBuffer; -import arc.scene.style.TextureRegionDrawable; -import mindustry.game.Team; -import mindustry.gen.*; -import mindustry.graphics.Drawf; -import mindustry.world.blocks.defense.turrets.*; - -import static informatis.SVars.turretRange; -import static informatis.SUtils.*; -import static arc.Core.*; -import static mindustry.Vars.player; - -public class RangeDraw extends OverDraw { - FrameBuffer effectBuffer = new FrameBuffer(); - - RangeDraw(String name, TextureRegionDrawable icon) { - super(name, icon); - registerOption("blockRange"); - registerOption("unitRange"); - registerOption("aliceRange"); - registerOption("invalidRange"); - registerOption("airRange"); - registerOption("groundRange"); - } - - @Override - public void draw() { - if(!enabled) return; - - Unit target = player.unit(); - - effectBuffer.resize(graphics.getWidth(), graphics.getHeight()); - for(Team team : Team.baseTeams) { - Draw.drawRange(166 + (Team.baseTeams.length-team.id) * 3, 1, () -> effectBuffer.begin(Color.clear), () -> { - effectBuffer.end(); - effectBuffer.blit(turretRange); - }); - } - - boolean includeBlock = settings.getBool("blockRange"), - includeUnit = settings.getBool("unitRange"), - includeInvalid = settings.getBool("invalidRange"), - includeAir = settings.getBool("airRange"), isAir = target == null || target.isFlying(), - includeGround = settings.getBool("groundRange"), isGround = target == null || !target.isFlying(), - includeAlice = settings.getBool("aliceRange"), - shader = settings.getBool("RangeShader"); - - Teamc selected = getTarget(); - if(selected instanceof BaseTurret.BaseTurretBuild turretBuild) { - Drawf.dashCircle(turretBuild.x, turretBuild.y, turretBuild.range(), turretBuild.team.color); - } else if(selected instanceof Unit unit) { - Drawf.dashCircle(unit.x, unit.y, unit.range(), unit.team.color); - } - - if(includeBlock) { - for(Building building : Groups.build) { - if(!((includeAlice || player.team() != building.team) - && building instanceof BaseTurret.BaseTurretBuild turret && isInCamera(building.x, building.y, turret.range() * 2))) continue; - - boolean valid = false; - if (building instanceof Turret.TurretBuild turretBuild) { - Turret block = (Turret) turretBuild.block; - if ((building.team == player.team() - || (block.targetAir && isAir && includeAir) - || (block.targetGround && isGround && includeGround)) - && turretBuild.hasAmmo() && turretBuild.canConsume()) valid = true; - } else if (building instanceof TractorBeamTurret.TractorBeamBuild tractorBeamBuild) { - TractorBeamTurret block = (TractorBeamTurret) tractorBeamBuild.block; - if ((building.team == player.team() - || (block.targetAir && isAir && includeAir) - || (block.targetGround && isGround && includeGround)) - && tractorBeamBuild.canConsume()) valid = true; - } - - if(!includeInvalid && !valid) continue; - - //non-base teams are considered as crux - int index = valid ? building.team.id > 5 ? 2 : building.team.id : 0; - float range = turret.range(); - Draw.color(Team.baseTeams[index].color); - if (shader) { - Draw.z(166+(Team.baseTeams.length-index)*3); - Fill.poly(building.x, building.y, Lines.circleVertices(range), range); - } else Drawf.dashCircle(building.x, building.y, range, Team.baseTeams[index].color); - Draw.reset(); - } - } - - if(includeUnit) { - for(Unit unit : Groups.unit) { - if(!((includeAlice || player.team() != unit.team) && isInCamera(unit.x, unit.y, unit.range() * 2))) continue; - - boolean valid = false; - if (target == null) valid = true; - else if ((unit.team == player.team() - || (unit.type.targetAir && isAir && includeAir) - || (unit.type.targetGround && isGround && includeGround)) - && unit.canShoot()) valid = true; - - if(!includeInvalid && !valid) continue; - - //non-base teams are considered as crux - int index = valid ? unit.team.id > 5 ? 2 : unit.team.id : 0; - float range = unit.range(); - Draw.color(Team.baseTeams[index].color.cpy().shiftSaturation(0.25f)); - if (shader) { - Draw.z(166 + (Team.baseTeams.length - index) * 3); - Fill.poly(unit.x, unit.y, Lines.circleVertices(range), range); - } else Drawf.dashCircle(unit.x, unit.y, range, Team.baseTeams[index].color); - Draw.color(); - } - } - } -} diff --git a/src/informatis/draws/UnitBarDraw.java b/src/informatis/draws/UnitBarDraw.java new file mode 100644 index 0000000..5bd946e --- /dev/null +++ b/src/informatis/draws/UnitBarDraw.java @@ -0,0 +1,15 @@ +package informatis.draws; + +import informatis.ui.FreeBar; +import mindustry.gen.Unit; + +public class UnitBarDraw extends OverDraw { + public UnitBarDraw() { + super("unitBar", OverDrawCategory.Unit); + } + + @Override + public void onUnit(Unit unit) { + FreeBar.draw(unit); + } +} diff --git a/src/informatis/draws/UnitCargoLinkDraw.java b/src/informatis/draws/UnitCargoLinkDraw.java new file mode 100644 index 0000000..0e4a969 --- /dev/null +++ b/src/informatis/draws/UnitCargoLinkDraw.java @@ -0,0 +1,30 @@ +package informatis.draws; + +import arc.graphics.g2d.*; +import mindustry.ai.types.CargoAI; +import mindustry.gen.*; +import mindustry.world.blocks.units.*; + +public class UnitCargoLinkDraw extends OverDraw { + public UnitCargoLinkDraw() { + super("unitCargoLink", OverDrawCategory.Link); + } + + @Override + public void onBuilding(Building building) { + if(building instanceof UnitCargoLoader.UnitTransportSourceBuild build) { + Unit unit = build.unit; + if(unit != null && unit.item() != null && unit.controller() instanceof CargoAI ai && ai.unloadTarget != null) { + Building targetBuild = ai.unloadTarget; + + Lines.stroke(2); + Draw.color(build.team.color); + Draw.alpha(0.5f); + Lines.line(build.x, build.y, unit.x, unit.y); + Draw.color(unit.item().color); + Draw.alpha(0.5f); + Lines.line(unit.x, unit.y, targetBuild.x, targetBuild.y); + } + } + } +} diff --git a/src/informatis/draws/UnitDraw.java b/src/informatis/draws/UnitDraw.java deleted file mode 100644 index 125626f..0000000 --- a/src/informatis/draws/UnitDraw.java +++ /dev/null @@ -1,104 +0,0 @@ -package informatis.draws; - -import informatis.SVars; -import informatis.core.Pathfinder; -import informatis.ui.*; -import arc.graphics.g2d.*; -import arc.math.*; -import arc.scene.style.*; -import arc.scene.ui.layout.*; -import arc.struct.*; -import arc.util.*; -import mindustry.ai.types.*; -import mindustry.entities.units.*; -import mindustry.gen.*; -import mindustry.graphics.*; -import mindustry.logic.*; -import mindustry.ui.*; -import mindustry.world.*; -import mindustry.world.blocks.storage.*; - -import static informatis.SUtils.*; -import static arc.Core.settings; -import static mindustry.Vars.*; - -public class UnitDraw extends OverDraw { - Seq pathTiles = new Seq<>(); - Seq otherCores; - - UnitDraw(String name, TextureRegionDrawable icon) { - super(name, icon); - registerOption("pathLine"); - registerOption("logicLine"); - registerOption("commandLine"); - registerOption("unitLine"); - registerOption("unitItem"); - registerOption("unitBar"); - } - - @Override - public void draw() { - if(!enabled) return; - - Groups.unit.each(u -> { - UnitController c = u.controller(); - - if(settings.getBool("commandLine") && c instanceof CommandAI com && com.hasCommand()) { - Lines.stroke(1, u.team.color); - Lines.line(u.x(), u.y(), com.targetPos.x, com.targetPos.y); - } - - if(settings.getBool("logicLine") && c instanceof LogicAI ai && (ai.control == LUnitControl.approach || ai.control == LUnitControl.move)) { - Lines.stroke(1, u.team.color); - Lines.line(u.x(), u.y(), ai.moveX, ai.moveY); - Lines.stroke(0.5f + Mathf.absin(6f, 0.5f), Tmp.c1.set(Pal.logicOperations).lerp(Pal.sap, Mathf.absin(6f, 0.5f))); - Lines.line(u.x(), u.y(), ai.controller.x, ai.controller.y); - } - - if(settings.getBool("unitLine") && u.team == state.rules.waveTeam && !u.type.flying && !(c instanceof MinerAI || c instanceof BuilderAI || c instanceof RepairAI || c instanceof DefenderAI || c instanceof FlyingAI)) { - Lines.stroke(1, u.team.color); - - pathTiles.clear(); - otherCores = Groups.build.copy(new Seq<>()).filter(b -> b instanceof CoreBlock.CoreBuild && b.team != u.team); - getNextTile(u.tileOn(), SVars.pathfinder.getField(u.team, u.controller() instanceof SuicideAI ? 0 : u.pathType(), Pathfinder.fieldCore)); - for(int i = 0; i < pathTiles.size - 1; i++) { - Tile from = pathTiles.get(i), to = pathTiles.get(i + 1); - if(from == null || to == null) continue; - Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); - } - } - - if(isInCamera(u.x, u.y, u.hitSize)) { - if (settings.getBool("unitBar")) FreeBar.draw(u); - if (settings.getBool("unitItem") && !renderer.pixelator.enabled() && u.item() != null && u.itemTime > 0.01f) - Fonts.outline.draw(String.valueOf(u.stack.amount), - u.x + Angles.trnsx(u.rotation + 180f, u.type.itemOffsetY), - u.y + Angles.trnsy(u.rotation + 180f, u.type.itemOffsetY) - 3, - Pal.accent, 0.25f * u.itemTime / Scl.scl(1f), false, Align.center); - } - }); - - if(settings.getBool("pathLine")) { - pathTiles.clear(); - otherCores = Groups.build.copy(new Seq<>()).filter(b -> b instanceof CoreBlock.CoreBuild && b.team != state.rules.waveTeam); - spawner.getSpawns().each(t -> { - for(int p = 0; p < 3; p++) { - getNextTile(t, SVars.pathfinder.getField(state.rules.waveTeam, p, Pathfinder.fieldCore)); - } - }); - Lines.stroke(1, state.rules.waveTeam.color); - for(int i = 0; i < pathTiles.size - 1; i++) { - Tile from = pathTiles.get(i), to = pathTiles.get(i + 1); - if(from == null || to == null) continue; - Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); - } - } - } - - void getNextTile(Tile tile, Pathfinder.Flowfield field) { - Tile nextTile = SVars.pathfinder.getTargetTile(tile, field); - pathTiles.add(nextTile); - if(nextTile == tile || nextTile == null) return; - getNextTile(nextTile, field); - } -} diff --git a/src/informatis/draws/UnitItemDraw.java b/src/informatis/draws/UnitItemDraw.java new file mode 100644 index 0000000..af873c9 --- /dev/null +++ b/src/informatis/draws/UnitItemDraw.java @@ -0,0 +1,27 @@ +package informatis.draws; + +import arc.math.Angles; +import arc.scene.ui.layout.Scl; +import arc.util.Align; +import mindustry.gen.Unit; +import mindustry.graphics.Pal; +import mindustry.ui.Fonts; + +import static informatis.SUtils.isInCamera; +import static mindustry.Vars.renderer; + +public class UnitItemDraw extends OverDraw { + public UnitItemDraw() { + super("unitItem", OverDrawCategory.Unit); + } + + @Override + public void onUnit(Unit unit) { + if(isInCamera(unit.x, unit.y, unit.hitSize) && !renderer.pixelator.enabled() && unit.item() != null && unit.itemTime > 0.01f) { + Fonts.outline.draw(String.valueOf(unit.stack.amount), + unit.x + Angles.trnsx(unit.rotation + 180f, unit.type.itemOffsetY), + unit.y + Angles.trnsy(unit.rotation + 180f, unit.type.itemOffsetY) - 3, + Pal.accent, 0.25f * unit.itemTime / Scl.scl(1f), false, Align.center); + } + } +} diff --git a/src/informatis/draws/UnitPathLineDraw.java b/src/informatis/draws/UnitPathLineDraw.java new file mode 100644 index 0000000..7d276fd --- /dev/null +++ b/src/informatis/draws/UnitPathLineDraw.java @@ -0,0 +1,32 @@ +package informatis.draws; + +import arc.graphics.g2d.Lines; +import arc.struct.Seq; +import informatis.SUtils; +import mindustry.ai.types.*; +import mindustry.entities.units.UnitController; +import mindustry.gen.Unit; +import mindustry.world.Tile; + +import static mindustry.Vars.state; + +public class UnitPathLineDraw extends OverDraw { + public UnitPathLineDraw() { + super("unitPathLine", OverDrawCategory.Unit); + } + + @Override + public void onUnit(Unit unit) { + UnitController c = unit.controller(); + if(unit.team == state.rules.waveTeam && !unit.type.flying && !(c instanceof MinerAI || c instanceof BuilderAI || c instanceof RepairAI || c instanceof DefenderAI || c instanceof FlyingAI)) { + Lines.stroke(1, unit.team.color); + + Seq pathTiles = SUtils.generatePathTiles(unit.tileOn(),unit.team, unit.controller() instanceof SuicideAI ? 0 : unit.pathType()); + for(int i = 0; i < pathTiles.size - 1; i++) { + Tile from = pathTiles.get(i), to = pathTiles.get(i + 1); + if(from == null || to == null) continue; + Lines.line(from.worldx(), from.worldy(), to.worldx(), to.worldy()); + } + } + } +} diff --git a/src/informatis/draws/UnitRangeDraw.java b/src/informatis/draws/UnitRangeDraw.java new file mode 100644 index 0000000..62cfb4b --- /dev/null +++ b/src/informatis/draws/UnitRangeDraw.java @@ -0,0 +1,45 @@ +package informatis.draws; + +import arc.graphics.g2d.*; +import mindustry.game.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import static arc.Core.settings; +import static informatis.SUtils.isInCamera; +import static mindustry.Vars.player; + +public class UnitRangeDraw extends OverDraw { + public UnitRangeDraw() { + super("unitRange", OverDrawCategory.Range); + } + + @Override + public void onUnit(Unit unit) { + Unit playerUnit = player.unit(); + + boolean includeInvalid = settings.getBool("invalidRange", true), + includeAir = settings.getBool("airRange", true), isAir = playerUnit == null || playerUnit.isFlying(), + includeGround = settings.getBool("groundRange", true), isGround = playerUnit == null || !playerUnit.isFlying(), + includeAlice = settings.getBool("aliceRange", true), + shader = settings.getBool("RangeShader", true); + if(!((includeAlice || player.team() != unit.team) && isInCamera(unit.x, unit.y, unit.range() * 2))) return; + + boolean valid = false; + if (player.unit() == null) valid = true; + else if ((unit.team == player.team() + || (unit.type.targetAir && isAir && includeAir) + || (unit.type.targetGround && isGround && includeGround)) + && unit.canShoot()) valid = true; + + if(!includeInvalid && !valid) return; + + //non-base teams are considered as crux + int index = valid ? unit.team.id > 5 ? 2 : unit.team.id : 0; + float range = unit.range(); + Draw.color(Team.baseTeams[index].color.cpy().shiftSaturation(0.25f)); + if (shader) { + Draw.z(166 + (Team.baseTeams.length - index) * 3); + Fill.poly(unit.x, unit.y, Lines.circleVertices(range), range); + } else Drawf.dashCircle(unit.x, unit.y, range, Team.baseTeams[index].color); + } +} diff --git a/src/informatis/draws/UtilDraw.java b/src/informatis/draws/UtilDraw.java deleted file mode 100644 index 8176df6..0000000 --- a/src/informatis/draws/UtilDraw.java +++ /dev/null @@ -1,92 +0,0 @@ -package informatis.draws; - -import arc.Core; -import arc.graphics.Color; -import arc.input.KeyCode; -import arc.math.Angles; -import arc.math.geom.Geometry; -import arc.scene.style.TextureRegionDrawable; -import arc.util.Time; -import arc.util.Tmp; -import mindustry.Vars; -import mindustry.content.Fx; -import mindustry.entities.Units; -import mindustry.game.Team; -import mindustry.gen.*; -import mindustry.logic.Ranged; -import mindustry.world.blocks.ControlBlock; -import mindustry.world.blocks.defense.turrets.Turret; - -import static arc.Core.*; -import static mindustry.Vars.*; - -public class UtilDraw extends OverDraw { - Teamc shotTarget; - - UtilDraw(String name, TextureRegionDrawable icon) { - super(name, icon); - registerOption("autoShooting"); - - } - - @Override - public void draw() { - super.draw(); - - if(!enabled) return; - - if(!mobile && !Vars.state.isPaused() && settings.getBool("gaycursor")) - Fx.mine.at(Core.input.mouseWorldX(), Core.input.mouseWorldY(), Tmp.c2.set(Color.red).shiftHue(Time.time * 1.5f)); - - if(settings.getBool("autoShooting")) { - Unit unit = player.unit(); - if (unit.type == null) return; - boolean omni = unit.type.omniMovement; - boolean validHealTarget = unit.type.canHeal && shotTarget instanceof Building b && b.isValid() && b.damaged() && shotTarget.team() == unit.team && shotTarget.within(unit, unit.type.range); - boolean boosted = (unit instanceof Mechc && unit.isFlying()); - if ((unit.type != null && Units.invalidateTarget(shotTarget, unit, unit.type.range) && !validHealTarget) || state.isEditor()) { - shotTarget = null; - } - - float mouseAngle = unit.angleTo(unit.aimX(), unit.aimY()); - boolean aimCursor = omni && player.shooting && unit.type.hasWeapons() && unit.type.faceTarget && !boosted && unit.type.rotateToBuilding; - unit.lookAt(aimCursor ? mouseAngle : unit.prefRotation()); - - //update shooting if not building + not mining - if(!player.unit().activelyBuilding() && player.unit().mineTile == null) { - if(input.keyDown(KeyCode.mouseLeft)) { - player.shooting = !boosted; - unit.aim(player.mouseX = input.mouseWorldX(), player.mouseY = input.mouseWorldY()); - } else if(shotTarget == null) { - player.shooting = false; - if(unit instanceof BlockUnitUnit b) { - if(b.tile() instanceof ControlBlock c && !c.shouldAutoTarget()) { - Building build = b.tile(); - float range = build instanceof Ranged ? ((Ranged) build).range() : 0f; - boolean targetGround = build instanceof Turret.TurretBuild && ((Turret) build.block).targetAir; - boolean targetAir = build instanceof Turret.TurretBuild && ((Turret) build.block).targetGround; - shotTarget = Units.closestTarget(build.team, build.x, build.y, range, u -> u.checkTarget(targetAir, targetGround), u -> targetGround); - } - else shotTarget = null; - } else if(unit.type != null) { - float range = unit.hasWeapons() ? unit.range() : 0f; - shotTarget = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.checkTarget(unit.type.targetAir, unit.type.targetGround), u -> unit.type.targetGround); - - if(unit.type.canHeal && shotTarget == null) { - shotTarget = Geometry.findClosest(unit.x, unit.y, indexer.getDamaged(Team.sharded)); - if (shotTarget != null && !unit.within(shotTarget, range)) { - shotTarget = null; - } - } - } - } else { - player.shooting = !boosted; - unit.rotation(Angles.angle(unit.x, unit.y, shotTarget.x(), shotTarget.y())); - unit.aim(shotTarget.x(), shotTarget.y()); - } - } - unit.controlWeapons(player.shooting && !boosted); - } - } - -} diff --git a/src/informatis/ui/windows/ToolWindow.java b/src/informatis/ui/windows/ToolWindow.java index bf2ccff..b63c84b 100644 --- a/src/informatis/ui/windows/ToolWindow.java +++ b/src/informatis/ui/windows/ToolWindow.java @@ -1,6 +1,9 @@ package informatis.ui.windows; import arc.Events; +import arc.scene.Element; +import arc.struct.ObjectMap; +import arc.struct.Seq; import informatis.ui.*; import informatis.draws.*; import arc.math.geom.*; @@ -12,9 +15,12 @@ import mindustry.gen.*; import mindustry.graphics.*; import mindustry.ui.*; +import static arc.Core.bundle; +import static arc.Core.settings; + public class ToolWindow extends Window { Vec2 scrollPos = new Vec2(0, 0); - OverDraw selected; + OverDrawCategory selected; float heat; public ToolWindow() { @@ -34,38 +40,69 @@ public class ToolWindow extends Window { public void build(Table table) { scrollPos = new Vec2(0, 0); - table.background(Styles.black8).top().left(); - table.table(pane->{ + table.background(Styles.black8) + .top() + .left(); + table.table(pane -> { pane.add(new OverScrollPane(rebuild(), Styles.noBarPane, scrollPos).disableScroll(true, false)).name("tool-pane"); - }).top().marginLeft(4f).marginRight(12f); - table.table(stats->{ + }) + .top() + .marginLeft(4f) + .marginRight(12f); + table.table(stats -> { stats.top(); stats.add(rebuildStats()).name("tool-stats"); }).growY(); } Table rebuild() { - return new Table(icons->{ - for(OverDraw draw : OverDraws.all) { - icons.button(draw.icon, ()->{ - selected=draw; + return new Table(icons -> { + for(OverDrawCategory category : OverDrawCategory.values()) { + icons.button(category.icon, () -> { + selected = category; Table table = find("tool-stats"); table.clearChildren(); table.add(rebuildStats()); - }).grow().tooltip(t->t.background(Styles.black8).add(draw.name).color(Pal.accent)).row(); + }) + .grow() + .tooltip(t -> t + .background(Styles.black8) + .add(category.name) + .color(Pal.accent) + ) + .row(); } }); } Table rebuildStats() { - return new Table(tool->{ - if(selected==null) return; + return new Table(tool -> { + if(selected == null) return; tool.top(); - tool.table(Tex.underline2, label->label.add(selected.name).color(Pal.accent)).row(); - tool.table(des-> selected.displayStats(des)).name("unit-stats").left().row(); - tool.check("@mod.enable", selected.enabled, c->{ - selected.enabled=c; - selected.onEnabled(find("unit-stats")); + tool.table(Tex.underline2, label -> + label.add(selected.name).color(Pal.accent) + ).row(); + tool.table(desc -> { + desc.background(Styles.squarei.up).left(); + for(OverDraw draw : OverDraws.getDraws().get(selected, new Seq<>())) { + desc.check(bundle.get("setting."+draw.name+".name"), settings.getBool(draw.name), b->settings.put(draw.name, b)) + .tooltip(t -> { + t.background(Styles.black8).add(bundle.get("setting."+draw.name+".description")); + }) + .disabled(!selected.enabled) + .left() + .row(); + } + }) + .name("unit-stats") + .left() + .row(); + tool.check("@mod.enable", selected.enabled, c -> { + selected.enabled = c; + Table table = find("unit-stats"); + for (Element elem : table.getChildren()) { + if (elem instanceof CheckBox cb) cb.setDisabled(!c); + } }); }); }