diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index b18ee6062f..c17d5a2ec6 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -95,6 +95,8 @@ public class Vars implements Loadable{ public static final float finalWorldBounds = 250; /** default range for building */ public static final float buildingRange = 220f; + /** scaling for unit circle collider radius, based on hitbox size */ + public static final float unitCollisionRadiusScale = 0.6f; /** range for moving items */ public static final float itemTransferRange = 220f; /** range for moving items for logic units */ diff --git a/core/src/mindustry/ai/UnitGroup.java b/core/src/mindustry/ai/UnitGroup.java index 8973c3e2fb..0c0366cf29 100644 --- a/core/src/mindustry/ai/UnitGroup.java +++ b/core/src/mindustry/ai/UnitGroup.java @@ -18,7 +18,7 @@ public class UnitGroup{ public int collisionLayer; public volatile float[] positions, originalPositions; public volatile boolean valid; - + public void calculateFormation(Vec2 dest, int collisionLayer){ this.collisionLayer = collisionLayer; @@ -72,7 +72,7 @@ public class UnitGroup{ positions[a * 2] = v1.x; positions[a * 2 + 1] = v1.y; - float rad = units.get(a).hitSize/2f; + float rad = units.get(a).hitSize * Vars.unitCollisionRadiusScale; maxDst = Math.max(maxDst, v1.dst(0f, 0f) + rad); totalArea += Mathf.PI * rad * rad; diff --git a/core/src/mindustry/async/PhysicsProcess.java b/core/src/mindustry/async/PhysicsProcess.java index 183d126217..a38f28eeb2 100644 --- a/core/src/mindustry/async/PhysicsProcess.java +++ b/core/src/mindustry/async/PhysicsProcess.java @@ -45,7 +45,7 @@ public class PhysicsProcess implements AsyncProcess{ body.x = entity.x; body.y = entity.y; body.mass = entity.mass(); - body.radius = entity.hitSize / 2f; + body.radius = entity.hitSize * Vars.unitCollisionRadiusScale; PhysicRef ref = new PhysicRef(entity, body); refs.add(ref); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 1f752a375a..5f455783b7 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -255,7 +255,7 @@ public class UnitTypes{ reign = new UnitType("reign"){{ speed = 0.4f; - hitSize = 26f; + hitSize = 30f; rotateSpeed = 1.65f; health = 24000; armor = 18f; @@ -1012,7 +1012,7 @@ public class UnitTypes{ accel = 0.08f; drag = 0.016f; flying = true; - hitSize = 10f; + hitSize = 11f; targetAir = false; engineOffset = 7.8f; range = 140f; diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 22d5e017b0..c544e8bba2 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -339,6 +339,8 @@ public class Renderer implements ApplicationListener{ Draw.draw(Layer.effect + 0.02f, bloom::render); } + control.input.drawCommanded(); + Draw.draw(Layer.plans, overlays::drawBottom); if(animateShields && Shaders.shield != null){ diff --git a/core/src/mindustry/graphics/Drawf.java b/core/src/mindustry/graphics/Drawf.java index db7db61dd5..e9d371fbf9 100644 --- a/core/src/mindustry/graphics/Drawf.java +++ b/core/src/mindustry/graphics/Drawf.java @@ -306,7 +306,7 @@ public class Drawf{ Draw.rect(region, x, y); Draw.color(); } - + public static void shadow(TextureRegion region, float x, float y, float width, float height, float rotation){ Draw.color(Pal.shadow); Draw.rect(region, x, y, width, height, rotation); @@ -361,6 +361,14 @@ public class Drawf{ Draw.reset(); } + public static void poly(float x, float y, int sides, float radius, float rotation, Color color){ + Lines.stroke(3f, Pal.gray); + Lines.poly(x, y, sides, radius + 1f, rotation); + Lines.stroke(1f, color); + Lines.poly(x, y, sides, radius + 1f, rotation); + Draw.reset(); + } + public static void square(float x, float y, float radius, float rotation){ square(x, y, radius, rotation, Pal.accent); } @@ -436,7 +444,7 @@ public class Drawf{ public static void construct(float x, float y, TextureRegion region, float rotation, float progress, float alpha, float time){ construct(x, y, region, Pal.accent, rotation, progress, alpha, time); } - + public static void construct(float x, float y, TextureRegion region, Color color, float rotation, float progress, float alpha, float time){ Shaders.build.region = region; Shaders.build.progress = progress; @@ -458,7 +466,7 @@ public class Drawf{ public static void construct(Building t, TextureRegion region, Color color, float rotation, float progress, float alpha, float time){ construct(t, region, color, rotation, progress, alpha, time, t.block.size * tilesize - 4f); } - + public static void construct(Building t, TextureRegion region, Color color, float rotation, float progress, float alpha, float time, float size){ Shaders.build.region = region; Shaders.build.progress = progress; @@ -477,7 +485,7 @@ public class Drawf{ Draw.reset(); } - + /** Draws a sprite that should be light-wise correct, when rotated. Provided sprite must be symmetrical in shape. */ public static void spinSprite(TextureRegion region, float x, float y, float r){ float a = Draw.getColorAlpha(); diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 8346eb94d6..3aa4be1bf8 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -151,6 +151,7 @@ public class OverlayRenderer{ } input.drawTop(); + input.drawUnitSelection(); buildFade = Mathf.lerpDelta(buildFade, input.isPlacing() || input.isUsingSchematic() ? 1f : 0f, 0.06f); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 0563b27754..78ac0604a7 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -132,9 +132,6 @@ public class DesktopInput extends InputHandler{ } } - - drawCommanded(); - Draw.reset(); } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 0be2e02705..c614309778 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -1070,23 +1070,36 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } public void drawCommand(Unit sel){ - Drawf.square(sel.x, sel.y, sel.hitSize / 1.4f + Mathf.absin(4f, 1f), selectedUnits.contains(sel) ? Pal.remove : Pal.accent); + Drawf.poly(sel.x, sel.y, 6, sel.hitSize / 1.1f + Mathf.absin(4f, 1f), 0f, selectedUnits.contains(sel) ? Pal.remove : Pal.accent); } public void drawCommanded(){ + Draw.draw(Layer.plans, () -> { + drawCommanded(true); + }); + + Draw.draw(Layer.groundUnit - 1, () -> { + drawCommanded(false); + }); + } + + public void drawCommanded(boolean flying){ + float lineLimit = 6.5f; + if(commandMode){ //happens sometimes selectedUnits.removeAll(u -> !u.isCommandable()); //draw command overlay UI for(Unit unit : selectedUnits){ + if(unit.isFlying() != flying) continue; CommandAI ai = unit.command(); Position lastPos = ai.attackTarget != null ? ai.attackTarget : ai.targetPos; //draw target line if(ai.targetPos != null && ai.currentCommand().drawTarget){ Position lineDest = ai.attackTarget != null ? ai.attackTarget : ai.targetPos; - Drawf.limitLine(unit, lineDest, unit.hitSize / 2f, 3.5f); + Drawf.limitLine(unit, lineDest, unit.hitSize / 1.1f + 1f, lineLimit); if(ai.attackTarget == null){ Drawf.square(lineDest.getX(), lineDest.getY(), 3.5f); @@ -1100,7 +1113,23 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } - Drawf.square(unit.x, unit.y, unit.hitSize / 1.4f + 1f); + float rad = unit.hitSize / 1.1f + 1f; + int sides = 6; + + Fill.lightInner(unit.x, unit.y, sides, + Math.max(0f, unit.hitSize / 1.1f + 1f - 4f), + rad, + 0f, + Tmp.c3.set(Pal.accent).a(0f), + Tmp.c2.set(Pal.accent).a(0.7f) + ); + + Lines.stroke(1f); + Draw.color(Pal.accent); + Lines.poly(unit.x, unit.y, sides, rad + 0.5f); + //Draw.color(Pal.gray); + //Lines.poly(unit.x, unit.y, sides, rad + 1.5f); + Draw.reset(); if(ai.attackTarget != null && ai.currentCommand().drawTarget){ Drawf.target(ai.attackTarget.getX(), ai.attackTarget.getY(), 6f, Pal.remove); @@ -1113,7 +1142,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ //draw command queue if(ai.currentCommand().drawTarget && ai.commandQueue.size > 0){ for(var next : ai.commandQueue){ - Drawf.limitLine(lastPos, next, 3.5f, 3.5f); + Drawf.limitLine(lastPos, next, lineLimit, lineLimit); lastPos = next; if(next instanceof Vec2 vec){ @@ -1139,14 +1168,16 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } - for(var commandBuild : commandBuildings){ - if(commandBuild != null){ - Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f); - var cpos = commandBuild.getCommandPosition(); + if(flying){ + for(var commandBuild : commandBuildings){ + if(commandBuild != null){ + Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f); + var cpos = commandBuild.getCommandPosition(); - if(cpos != null){ - Drawf.limitLine(commandBuild, cpos, commandBuild.hitSize() / 2f, 3.5f); - Drawf.square(cpos.x, cpos.y, 3.5f); + if(cpos != null){ + Drawf.limitLine(commandBuild, cpos, commandBuild.hitSize() / 2f, lineLimit); + Drawf.square(cpos.x, cpos.y, 3.5f); + } } } } @@ -1154,27 +1185,29 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(commandMode && !commandRect){ Unit sel = selectedCommandUnit(input.mouseWorldX(), input.mouseWorldY()); - if(sel != null && !(!multiUnitSelect() && selectedUnits.size == 1 && selectedUnits.contains(sel))){ + if(sel != null && sel.isFlying() == flying && !(!multiUnitSelect() && selectedUnits.size == 1 && selectedUnits.contains(sel))){ drawCommand(sel); } } - - if(commandRect){ - float x2 = input.mouseWorldX(), y2 = input.mouseWorldY(); - var units = selectedCommandUnits(commandRectX, commandRectY, x2 - commandRectX, y2 - commandRectY); - for(var unit : units){ - drawCommand(unit); - } - - Draw.color(Pal.accent, 0.3f); - Fill.crect(commandRectX, commandRectY, x2 - commandRectX, y2 - commandRectY); - } } Draw.reset(); } + public void drawUnitSelection(){ + if(commandRect && commandMode){ + float x2 = input.mouseWorldX(), y2 = input.mouseWorldY(); + var units = selectedCommandUnits(commandRectX, commandRectY, x2 - commandRectX, y2 - commandRectY); + for(var unit : units){ + drawCommand(unit); + } + + Draw.color(Pal.accent, 0.3f); + Fill.crect(commandRectX, commandRectY, x2 - commandRectX, y2 - commandRectY); + } + } + public void drawBottom(){ } diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index 37ec6c9ec9..20490ccd5c 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -391,8 +391,6 @@ public class MobileInput extends InputHandler implements GestureListener{ }else if(mode == rebuildSelect){ drawRebuildSelection(lineStartX, lineStartY, lastLineX, lastLineY); } - - drawCommanded(); } @Override diff --git a/gradle.properties b/gradle.properties index e0b5eeff4d..f65d8c10f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=ed5dd285b7 +archash=ae657a7db3