diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index e4c580eff2..839b453867 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -356,30 +356,23 @@ public class World{ } public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){ - int x0 = x0f; - int y0 = y0f; - int dx = Math.abs(x1 - x0); - int dy = Math.abs(y1 - y0); + int x0 = x0f, dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int y0 = y0f, dy = Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int e2, err = dx - dy; - int sx = x0 < x1 ? 1 : -1; - int sy = y0 < y1 ? 1 : -1; - - int err = dx - dy; - int e2; while(true){ - if(cons.accept(x0, y0)) break; if(x0 == x1 && y0 == y1) break; e2 = 2 * err; if(e2 > -dy){ - err = err - dy; - x0 = x0 + sx; + err -= dy; + x0 += sx; } if(e2 < dx){ - err = err + dx; - y0 = y0 + sy; + err += dx; + y0 += sy; } } } diff --git a/core/src/mindustry/entities/EntityCollisions.java b/core/src/mindustry/entities/EntityCollisions.java index ce492bc95d..e6651a420f 100644 --- a/core/src/mindustry/entities/EntityCollisions.java +++ b/core/src/mindustry/entities/EntityCollisions.java @@ -1,5 +1,6 @@ package mindustry.entities; +import arc.func.*; import arc.math.*; import arc.math.geom.*; import arc.struct.*; @@ -23,7 +24,9 @@ public class EntityCollisions{ private Rect r2 = new Rect(); //entity collisions - private Seq arrOut = new Seq<>(); + private Seq arrOut = new Seq<>(Hitboxc.class); + private Cons hitCons = this::updateCollision; + private Cons treeCons = tree -> tree.intersect(r2, arrOut); public void moveCheck(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){ if(!solidCheck.solid(entity.tileX(), entity.tileY())){ @@ -36,7 +39,7 @@ public class EntityCollisions{ } public void move(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){ - if(Math.abs(deltax) < 0.0001f & Math.abs(deltay) < 0.0001f) return; + if(Math.abs(deltax) < 0.0001f & Math.abs(deltay) < 0.0001f) return; boolean movedx = false; @@ -213,28 +216,34 @@ public class EntityCollisions{ @SuppressWarnings("unchecked") public void collide(EntityGroup groupa){ - groupa.each(solid -> { - solid.hitbox(r1); - r1.x += (solid.lastX() - solid.getX()); - r1.y += (solid.lastY() - solid.getY()); + groupa.each((Cons)hitCons); + } - solid.hitbox(r2); - r2.merge(r1); + private void updateCollision(Hitboxc solid){ + solid.hitbox(r1); + r1.x += (solid.lastX() - solid.getX()); + r1.y += (solid.lastY() - solid.getY()); - arrOut.clear(); + solid.hitbox(r2); + r2.merge(r1); - //get all targets based on what entity wants to collide with - solid.getCollisions(tree -> tree.intersect(r2, arrOut)); + arrOut.clear(); - for(Hitboxc sc : arrOut){ - sc.hitbox(r1); - if(r2.overlaps(r1)){ - checkCollide(solid, sc); - //break out of loop when this object hits something - if(!solid.isAdded()) return; - } + //get all targets based on what entity wants to collide with + solid.getCollisions(treeCons); + + var items = arrOut.items; + int size = arrOut.size; + + for(int i = 0; i < size; i++){ + Hitboxc sc = items[i]; + sc.hitbox(r1); + if(r2.overlaps(r1)){ + checkCollide(solid, sc); + //break out of loop when this object hits something + if(!solid.isAdded()) return; } - }); + } } public interface SolidPred{ diff --git a/core/src/mindustry/entities/comp/BulletComp.java b/core/src/mindustry/entities/comp/BulletComp.java index 3d4f209734..27a92be992 100644 --- a/core/src/mindustry/entities/comp/BulletComp.java +++ b/core/src/mindustry/entities/comp/BulletComp.java @@ -118,36 +118,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw type.update(self()); if(type.collidesTiles && type.collides && type.collidesGround){ - world.raycastEach(World.toTile(lastX()), World.toTile(lastY()), tileX(), tileY(), (x, y) -> { - - Building build = world.build(x, y); - if(build == null || !isAdded()) return false; - - if(build.collide(self()) && type.testCollision(self(), build) && !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){ - boolean remove = false; - - float health = build.health; - - if(build.team != team){ - remove = build.collision(self()); - } - - if(remove || type.collidesTeam){ - if(!type.pierceBuilding){ - hit = true; - remove(); - }else{ - collided.add(build.id); - } - } - - type.hitTile(self(), build, health, true); - - return !type.pierceBuilding; - } - - return false; - }); + tileRaycast(World.toTile(lastX()), World.toTile(lastY()), tileX(), tileY()); } if(type.pierceCap != -1 && collided.size >= type.pierceCap){ @@ -156,6 +127,55 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw } } + //copy-paste of World#raycastEach, inlined for lambda capture performance. + @Override + public void tileRaycast(int x0f, int y0f, int x1, int y1){ + int x = x0f, dx = Math.abs(x1 - x), sx = x < x1 ? 1 : -1; + int y = y0f, dy = Math.abs(y1 - y), sy = y < y1 ? 1 : -1; + int e2, err = dx - dy; + + while(true){ + Building build = world.build(x, y); + if(build != null && isAdded() && build.collide(self()) && type.testCollision(self(), build) + && !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){ + + boolean remove = false; + float health = build.health; + + if(build.team != team){ + remove = build.collision(self()); + } + + if(remove || type.collidesTeam){ + if(!type.pierceBuilding){ + hit = true; + remove(); + }else{ + collided.add(build.id); + } + } + + type.hitTile(self(), build, health, true); + + //stop raycasting when building is hit + if(type.pierceBuilding) return; + } + + if(x == x1 && y == y1) break; + + e2 = 2 * err; + if(e2 > -dy){ + err -= dy; + x += sx; + } + + if(e2 < dx){ + err += dx; + y += sy; + } + } + } + @Override public void draw(){ Draw.z(type.layer); diff --git a/core/src/mindustry/entities/comp/PuddleComp.java b/core/src/mindustry/entities/comp/PuddleComp.java index 38df428c41..c14c49a826 100644 --- a/core/src/mindustry/entities/comp/PuddleComp.java +++ b/core/src/mindustry/entities/comp/PuddleComp.java @@ -40,8 +40,8 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{ @Import int id; @Import float x, y; + @Import boolean added; - transient private boolean mismatch = false; transient float accepting, updateTime, lastRipple = Time.time + Mathf.random(40f); float amount; Tile tile; @@ -79,9 +79,12 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{ return; } - if(Puddles.get(tile) != self()){ - mismatch = true; - remove(); + if(Puddles.get(tile) != self() && added){ + //force removal without pool free + Groups.all.remove(self()); + Groups.draw.remove(self()); + Groups.puddle.remove(self()); + added = false; return; } @@ -134,9 +137,7 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{ @Override public void remove(){ - if(!mismatch){ - Puddles.remove(tile); - } + Puddles.remove(tile); } @Override diff --git a/core/src/mindustry/game/Teams.java b/core/src/mindustry/game/Teams.java index 97638ed1e2..f6f284ab35 100644 --- a/core/src/mindustry/game/Teams.java +++ b/core/src/mindustry/game/Teams.java @@ -48,11 +48,11 @@ public class Teams{ return Geometry.findClosest(x, y, get(team).cores); } - public boolean eachEnemyCore(Team team, Boolf ret){ + public boolean anyEnemyCoresWithin(Team team, float x, float y, float radius){ for(TeamData data : active){ if(team != data.team){ for(CoreBuild tile : data.cores){ - if(ret.get(tile)){ + if(tile.within(x, y, radius)){ return true; } } diff --git a/core/src/mindustry/world/Build.java b/core/src/mindustry/world/Build.java index d5bb888f7a..0f6c13d9be 100644 --- a/core/src/mindustry/world/Build.java +++ b/core/src/mindustry/world/Build.java @@ -151,7 +151,7 @@ public class Build{ if(closest != null && closest.team != team){ return false; } - }else if(state.teams.eachEnemyCore(team, core -> Mathf.dst(x * tilesize + type.offset, y * tilesize + type.offset, core.x, core.y) < state.rules.enemyCoreBuildRadius + type.size * tilesize / 2f)){ + }else if(state.teams.anyEnemyCoresWithin(team, x * tilesize + type.offset, y * tilesize + type.offset, state.rules.enemyCoreBuildRadius + tilesize)){ return false; } } diff --git a/gradle.properties b/gradle.properties index bdc683c767..2689175f1f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ android.useAndroidX=true #used for slow jitpack builds; TODO see if this actually works http.socketTimeout=80000 http.connectionTimeout=80000 -archash=6b77c7f375e42e3049ab60b47bd0654becb5eab4 +archash=f4e8a35c46e28dc68bb2cab17e42ef6db15ae72f