|
| 1 | +package mindustryX.features; |
| 2 | + |
| 3 | +import arc.*; |
| 4 | +import arc.graphics.g2d.*; |
| 5 | +import arc.math.*; |
| 6 | +import arc.math.geom.*; |
| 7 | +import arc.struct.*; |
| 8 | +import arc.util.*; |
| 9 | +import mindustry.ctype.*; |
| 10 | +import mindustry.entities.bullet.*; |
| 11 | +import mindustry.game.*; |
| 12 | +import mindustry.gen.*; |
| 13 | +import mindustry.graphics.*; |
| 14 | +import mindustry.type.*; |
| 15 | +import mindustry.world.blocks.defense.turrets.*; |
| 16 | + |
| 17 | +import static mindustry.Vars.*; |
| 18 | + |
| 19 | +//move from mindustry.arcModule.draw.ARCBuilds |
| 20 | +public class ArcBuilds{ |
| 21 | + private static boolean targetAir = false, targetGround = false, canShoot = false; |
| 22 | + private static boolean turretForceShowRange = false; |
| 23 | + private static int turretShowRange = 0, turretAlertRange; |
| 24 | + private static boolean showTurretAmmo = false, showTurretAmmoAmount = false; |
| 25 | + private static boolean blockWeaponTargetLine = false, blockWeaponTargetLineWhenIdle = false; |
| 26 | + |
| 27 | + static{ |
| 28 | + // 减少性能开销 |
| 29 | + Events.run(EventType.Trigger.update, () -> { |
| 30 | + turretForceShowRange = Core.settings.getBool("turretForceShowRange"); |
| 31 | + turretShowRange = Core.settings.getInt("turretShowRange"); |
| 32 | + |
| 33 | + turretAlertRange = Core.settings.getInt("turretAlertRange") * tilesize; |
| 34 | + |
| 35 | + showTurretAmmo = Core.settings.getBool("showTurretAmmo"); |
| 36 | + showTurretAmmoAmount = Core.settings.getBool("showTurretAmmoAmount"); |
| 37 | + |
| 38 | + blockWeaponTargetLine = Core.settings.getBool("blockWeaponTargetLine"); |
| 39 | + blockWeaponTargetLineWhenIdle = Core.settings.getBool("blockWeaponTargetLineWhenIdle"); |
| 40 | + }); |
| 41 | + } |
| 42 | + |
| 43 | + private static void drawRange(BaseTurret.BaseTurretBuild build){ |
| 44 | + Draw.z(Layer.turret - 0.8f); |
| 45 | + //Draw.color(build.team.color, 0.05f); |
| 46 | + //Fill.circle(build.x, build.y, build.range()); |
| 47 | + Draw.color(build.team.color, 0.6f); |
| 48 | + Lines.circle(build.x, build.y, build.range()); |
| 49 | + Draw.reset(); |
| 50 | + } |
| 51 | + |
| 52 | + public static void arcTurret(BaseTurret.BaseTurretBuild build){ |
| 53 | + if(build == null || !(build.team == player.team() || RenderExt.showOtherInfo)) return; |
| 54 | + Draw.z(Layer.turret); |
| 55 | + |
| 56 | + Vec2 targetPos = Vec2.ZERO; |
| 57 | + if(build.block instanceof Turret t){ |
| 58 | + targetAir = t.targetAir; |
| 59 | + targetGround = t.targetGround; |
| 60 | + targetPos = ((Turret.TurretBuild)build).targetPos; |
| 61 | + canShoot = ((Turret.TurretBuild)build).hasAmmo(); |
| 62 | + }else if(build.block instanceof TractorBeamTurret t){ |
| 63 | + targetAir = t.targetAir; |
| 64 | + targetGround = t.targetGround; |
| 65 | + Unit target = ((TractorBeamTurret.TractorBeamBuild)build).target; |
| 66 | + if(target != null){ |
| 67 | + targetPos = Tmp.v1.set(target.x, target.y); |
| 68 | + } |
| 69 | + canShoot = build.potentialEfficiency > 0; |
| 70 | + } |
| 71 | + if(build instanceof PowerTurret.PowerTurretBuild){ |
| 72 | + canShoot = build.efficiency > 0; |
| 73 | + } |
| 74 | + |
| 75 | + if(turretForceShowRange || canShoot){ |
| 76 | + if((turretShowRange == 3 || (turretShowRange == 2 && targetAir) || (turretShowRange == 1 && targetGround))) |
| 77 | + drawRange(build); |
| 78 | + else if(turretAlertRange > 0 && build.team != player.team()){ |
| 79 | + boolean canHitPlayer = !player.dead() && player.unit().hittable() && (player.unit().isFlying() ? targetAir : targetGround) |
| 80 | + && build.within(player.unit().x, player.unit().y, build.range() + turretAlertRange); |
| 81 | + boolean canHitMouse = build.within(Core.input.mouseWorldX(), Core.input.mouseWorldY(), build.range() + turretAlertRange); |
| 82 | + boolean canHitCommand = control.input.commandMode && ((ArcUnits.selectedUnitsFlyer && targetAir) || (ArcUnits.selectedUnitsLand && targetGround)); |
| 83 | + boolean canHitPlans = (control.input.block != null || control.input.selectPlans.size > 0) && targetGround; |
| 84 | + if(canHitPlayer || (canHitMouse && (canHitCommand || canHitPlans))) drawRange(build); |
| 85 | + } |
| 86 | + |
| 87 | + if(showTurretAmmo && build instanceof ItemTurret.ItemTurretBuild it && it.ammo.any()){ |
| 88 | + //lc参考miner代码 |
| 89 | + ItemTurret.ItemEntry entry = (ItemTurret.ItemEntry)it.ammo.peek(); |
| 90 | + Item lastAmmo = entry.item; |
| 91 | + |
| 92 | + Draw.z(Layer.turret + 0.1f); |
| 93 | + |
| 94 | + float size = Math.max(4f, build.block.size * tilesize / 2.5f); |
| 95 | + float ammoX = build.x - (build.block.size * tilesize / 2.0F) + (size / 2); |
| 96 | + float ammoY = build.y - (build.block.size * tilesize / 2.0F) + (size / 2); |
| 97 | + |
| 98 | + Draw.rect(lastAmmo.fullIcon, ammoX, ammoY, size, size); |
| 99 | + |
| 100 | + float leftAmmo = Mathf.lerp(0, 1, Math.min(1f, (float)entry.amount / ((ItemTurret)it.block).maxAmmo)); |
| 101 | + if(leftAmmo < 0.75f && showTurretAmmoAmount){ |
| 102 | + Draw.alpha(0.5f); |
| 103 | + Draw.color(lastAmmo.color); |
| 104 | + Lines.stroke(Lines.getStroke() * build.block.size * 0.5f); |
| 105 | + Lines.arc(ammoX, ammoY, size * 0.5f, leftAmmo); |
| 106 | + } |
| 107 | + |
| 108 | + Draw.reset(); |
| 109 | + } |
| 110 | + if(targetPos.x != 0 && targetPos.y != 0 && blockWeaponTargetLine && Mathf.len(targetPos.x - build.x, targetPos.y - build.y) <= 1500f){ |
| 111 | + if(!(build instanceof Turret.TurretBuild) || ((Turret.TurretBuild)build).isShooting() || ((Turret.TurretBuild)build).isControlled()){ |
| 112 | + Draw.color(1f, 0.2f, 0.2f, 0.8f); |
| 113 | + Lines.stroke(1.5f); |
| 114 | + Lines.line(build.x, build.y, targetPos.x, targetPos.y); |
| 115 | + Lines.dashCircle(targetPos.x, targetPos.y, 8); |
| 116 | + }else if(blockWeaponTargetLineWhenIdle){ |
| 117 | + Draw.color(1f, 1f, 1f, 0.3f); |
| 118 | + Lines.stroke(1.5f); |
| 119 | + Lines.line(build.x, build.y, targetPos.x, targetPos.y); |
| 120 | + Lines.dashCircle(targetPos.x, targetPos.y, 8); |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + public static void turretPlaceDraw(float x, float y, BaseTurret block){ |
| 127 | + float oldZ = Draw.z(); |
| 128 | + Draw.z(oldZ+0.1f);//MDTX: There no replace for Icon.power, so we offset the layer. |
| 129 | + float iconSize = 6f + 2f * block.size, range = block.range; |
| 130 | + ObjectMap<? extends UnlockableContent, BulletType> ammoTypes; |
| 131 | + if(block instanceof ContinuousLiquidTurret t){ |
| 132 | + ammoTypes = t.ammoTypes; |
| 133 | + }else if(block instanceof LiquidTurret t){ |
| 134 | + ammoTypes = t.ammoTypes; |
| 135 | + }else if(block instanceof ItemTurret t){ |
| 136 | + ammoTypes = t.ammoTypes; |
| 137 | + }else if(block instanceof PowerTurret){ |
| 138 | + turretBulletDraw(x, y, Icon.power.getRegion(), iconSize, range, 0f); |
| 139 | + return; |
| 140 | + }else return; |
| 141 | + |
| 142 | + int drawIndex = 0; |
| 143 | + for(var e : ammoTypes.entries()){ |
| 144 | + var item = e.key; |
| 145 | + var bulletType = e.value; |
| 146 | + drawIndex += 1; |
| 147 | + if(!item.unlockedNow()) return; |
| 148 | + if(bulletType.rangeChange > 0) Drawf.dashCircle(x, y, range + bulletType.rangeChange, Pal.placing); |
| 149 | + turretBulletDraw(x, y, item.uiIcon, iconSize, range + bulletType.rangeChange, (float)drawIndex / ammoTypes.size); |
| 150 | + } |
| 151 | + Draw.z(oldZ); |
| 152 | + } |
| 153 | + |
| 154 | + private static void turretBulletDraw(float x, float y, TextureRegion icon, float iconSize, float range, float rotOffset){ |
| 155 | + for(int i = 0; i < 4; i++){ |
| 156 | + float rot = (i + rotOffset) * 90f + Time.time * 0.5f; |
| 157 | + Draw.rect(icon, |
| 158 | + x + (Mathf.sin((float)Math.toRadians(rot)) * (range )), |
| 159 | + y + (Mathf.cos((float)Math.toRadians(rot)) * (range )), |
| 160 | + iconSize, iconSize, -rot); |
| 161 | + } |
| 162 | + } |
| 163 | +} |
0 commit comments