Merge branch 'master' of https://github.com/Anuken/Mindustry into wave-pathfind-avoidance

This commit is contained in:
Anuken
2025-07-06 13:13:55 -04:00
47 changed files with 334 additions and 94 deletions

View File

@@ -202,6 +202,8 @@ public class Vars implements Loadable{
/** Whether to draw shadows of blocks at map edges and static blocks.
* Do not change unless you know exactly what you are doing.*/
public static boolean enableDarkness = true;
/** Whether to draw debug lines for collisions. */
public static boolean drawDebugHitboxes = false;
/** application data directory, equivalent to {@link Settings#getDataDirectory()} */
public static Fi dataDirectory;
/** data subdirectory used for screenshots */

View File

@@ -288,7 +288,7 @@ public class Pathfinder implements Runnable{
nearSolid,
nearLegSolid,
tile.floor().isDeep(),
tile.floor().damageTaken > 0.00001f,
tile.floor().damages(),
allDeep,
nearDeep,
tile.block().teamPassable

View File

@@ -415,6 +415,10 @@ public class Renderer implements ApplicationListener{
Groups.draw.draw(Drawc::draw);
if(drawDebugHitboxes){
DebugCollisionRenderer.draw();
}
Draw.reset();
Draw.flush();
Draw.sort(false);

View File

@@ -0,0 +1,86 @@
package mindustry.graphics;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.core.*;
import mindustry.gen.*;
import mindustry.world.*;
import static arc.Core.*;
import static mindustry.Vars.*;
public class DebugCollisionRenderer{
static final float[] edges = {
1, -1,
1, 1,
-1, 1,
-1, -1,
};
public static void draw(){
Rect rect = camera.bounds(new Rect());
Draw.draw(Layer.overlayUI, () -> {
//hitboxes
Draw.color(Color.green, 0.3f);
Groups.draw.each(d -> {
if(d instanceof Hitboxc h && rect.overlaps(Tmp.r1.setCentered(d.x(), d.y(), d.clipSize()))){
Fill.square(d.x(), d.y(), h.hitSize()/2f);
}
});
//tile hitboxes for units
Lines.stroke(0.4f, Color.magenta);
int rx = Mathf.clamp((int)(Core.camera.width / tilesize / 2) + 1, 0, world.width()/2);
int ry = Mathf.clamp((int)(Core.camera.height / tilesize / 2) + 1, 0, world.height()/2);
for(int x = -rx; x <= rx; x++){
for(int y = -ry; y <= ry; y++){
int wx = World.toTile(Core.camera.position.x) + x;
int wy = World.toTile(Core.camera.position.y) + y;
Tile tile = world.tile(wx, wy);
if(tile != null && tile.solid()){
for(int i = 0; i < 4; i++){
Tile other = tile.nearby(i);
if(other == null || !other.solid()){
Lines.line(
wx * tilesize + edges[i*2] * tilesize/2f,
wy * tilesize + edges[i*2+1] * tilesize/2f,
wx * tilesize + edges[((i + 1) % 4)*2] * tilesize/2f,
wy * tilesize + edges[((i + 1) % 4)*2+1] * tilesize/2f
);
}
}
}
}
}
Groups.draw.each(d -> {
if(d instanceof Unit u && rect.overlaps(Tmp.r1.setCentered(u.x, u.y, d.clipSize())) && !u.isFlying()){
u.hitboxTile(Tmp.r1);
Lines.rect(Tmp.r1);
}
});
//physics hitboxes
Lines.stroke(0.5f);
Draw.color(Color.red, 0.5f);
Groups.draw.each(d -> {
if(d instanceof Unit u && rect.overlaps(Tmp.r1.setCentered(u.x, u.y, u.clipSize()))){
Lines.circle(u.x, u.y, u.hitSize * unitCollisionRadiusScale);
}
});
Draw.reset();
});
Draw.reset();
}
}

View File

@@ -35,7 +35,6 @@ public class Binding{
schematicFlipY = KeyBind.add("schematic_flip_y", KeyCode.x),
schematicMenu = KeyBind.add("schematic_menu", KeyCode.t),
commandMode = KeyBind.add("command_mode", KeyCode.shiftLeft, "command"),
commandQueue = KeyBind.add("command_queue", KeyCode.mouseMiddle),
createControlGroup = KeyBind.add("create_control_group", KeyCode.controlLeft),
@@ -103,7 +102,8 @@ public class Binding{
chatHistoryNext = KeyBind.add("chat_history_next", KeyCode.down),
chatScroll = KeyBind.add("chat_scroll", new Axis(KeyCode.scroll)),
chatMode = KeyBind.add("chat_mode", KeyCode.tab),
console = KeyBind.add("console", KeyCode.f8)
console = KeyBind.add("console", KeyCode.f8),
debugHitboxes = KeyBind.add("debug_hitboxes", KeyCode.unset)
;
//dummy static class initializer

View File

@@ -234,6 +234,10 @@ public class DesktopInput extends InputHandler{
boolean detached = settings.getBool("detach-camera", false);
if(!scene.hasField() && !scene.hasDialog()){
if(input.keyTap(Binding.debugHitboxes)){
drawDebugHitboxes = !drawDebugHitboxes;
}
if(input.keyTap(Binding.detachCamera)){
settings.put("detach-camera", detached = !detached);
if(!detached){

View File

@@ -516,7 +516,7 @@ public class LExecutor{
@Override
public void run(LExecutor exec){
Object obj = target.obj();
if(obj instanceof Building b && (exec.privileged || (b.team == exec.team && exec.linkIds.contains(b.id)))){
if(obj instanceof Building b && (exec.privileged || (exec.build != null && exec.build.validLink(b)))){
if(type == LAccess.enabled){
if(p1.bool()){

View File

@@ -474,6 +474,9 @@ public class SettingsMenuDialog extends BaseDialog{
}
graphics.checkPref("minimap", !mobile);
graphics.checkPref("smoothcamera", true);
if(!mobile){
graphics.checkPref("detach-camera", false);
}
graphics.checkPref("position", false);
if(!mobile){
graphics.checkPref("mouseposition", false);

View File

@@ -379,6 +379,11 @@ public class Floor extends Block{
return (other.realBlendId(otherTile) > realBlendId(tile) || edges(tile.x, tile.y) == null);
}
/** @return whether being on this floor can damage a unit */
public boolean damages(){
return damageTaken > 0f || (status != null && status.damage > 0f);
}
public static class UpdateRenderState{
public Tile tile;
public Floor floor;

View File

@@ -206,11 +206,7 @@ public class LogicBlock extends Block{
String name = stream.readUTF();
short x = stream.readShort(), y = stream.readShort();
Tmp.p2.set((int)(offset / (tilesize/2)), (int)(offset / (tilesize/2)));
transformer.get(Tmp.p1.set(x * 2, y * 2).sub(Tmp.p2));
Tmp.p1.add(Tmp.p2);
Tmp.p1.x /= 2;
Tmp.p1.y /= 2;
transformer.get(Tmp.p1.set(x, y));
links.add(new LogicLink(Tmp.p1.x, Tmp.p1.y, name, true));
}