Merge branches 'avoidance-optimization' and 'master' of https://github.com/Anuken/Mindustry
This commit is contained in:
@@ -65,7 +65,7 @@ public class Pathfinder{
|
|||||||
Tile other = world.tile(dx, dy);
|
Tile other = world.tile(dx, dy);
|
||||||
if(other == null) continue;
|
if(other == null) continue;
|
||||||
|
|
||||||
if(values[dx][dy] < value && (target == null || values[dx][dy] < tl) &&
|
if(values[dx][dy] < value && (target == null || values[dx][dy]< tl) &&
|
||||||
!other.solid() &&
|
!other.solid() &&
|
||||||
!(point.x != 0 && point.y != 0 && (world.solid(tile.x + point.x, tile.y) || world.solid(tile.x, tile.y + point.y)))){ //diagonal corner trap
|
!(point.x != 0 && point.y != 0 && (world.solid(tile.x + point.x, tile.y) || world.solid(tile.x, tile.y + point.y)))){ //diagonal corner trap
|
||||||
target = other;
|
target = other;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.anuke.arc.function.Predicate;
|
|||||||
import io.anuke.arc.graphics.Camera;
|
import io.anuke.arc.graphics.Camera;
|
||||||
import io.anuke.arc.math.geom.Rectangle;
|
import io.anuke.arc.math.geom.Rectangle;
|
||||||
import io.anuke.mindustry.entities.traits.DrawTrait;
|
import io.anuke.mindustry.entities.traits.DrawTrait;
|
||||||
|
import io.anuke.mindustry.entities.traits.Entity;
|
||||||
|
|
||||||
public class EntityDraw{
|
public class EntityDraw{
|
||||||
private static final Rectangle viewport = new Rectangle();
|
private static final Rectangle viewport = new Rectangle();
|
||||||
@@ -42,15 +43,12 @@ public class EntityDraw{
|
|||||||
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
|
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
group.forEach(e -> {
|
for(Entity e : group.all()){
|
||||||
if(!(e instanceof DrawTrait)) return;
|
if(!(e instanceof DrawTrait) || !toDraw.test((T)e) || !e.isAdded()) continue;
|
||||||
T t = (T) e;
|
|
||||||
|
|
||||||
if(!toDraw.test(t) || !e.isAdded()) return;
|
|
||||||
|
|
||||||
if(!clip || rect.setSize(((DrawTrait) e).drawSize()).setCenter(e.getX(), e.getY()).overlaps(viewport)){
|
if(!clip || rect.setSize(((DrawTrait) e).drawSize()).setCenter(e.getX(), e.getY()).overlaps(viewport)){
|
||||||
cons.accept(t);
|
cons.accept((T)e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ public abstract class GroundUnit extends BaseUnit{
|
|||||||
|
|
||||||
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
|
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
|
||||||
if(Units.invalidateTarget(target, this)){
|
if(Units.invalidateTarget(target, this)){
|
||||||
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
|
rotation = Mathf.slerpDelta(rotation, baseRotation, type.rotatespeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +240,6 @@ public abstract class GroundUnit extends BaseUnit{
|
|||||||
float angle = angleTo(targetTile);
|
float angle = angleTo(targetTile);
|
||||||
|
|
||||||
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
|
velocity.add(vec.trns(angleTo(targetTile), type.speed*Time.delta()));
|
||||||
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
|
rotation = Mathf.slerpDelta(rotation, baseRotation, type.rotatespeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import io.anuke.arc.graphics.g2d.Draw;
|
|||||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.Geometry;
|
||||||
import io.anuke.arc.math.geom.Rectangle;
|
|
||||||
import io.anuke.arc.math.geom.Vector2;
|
import io.anuke.arc.math.geom.Vector2;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
import io.anuke.arc.util.Tmp;
|
import io.anuke.arc.util.Tmp;
|
||||||
@@ -15,7 +14,6 @@ import io.anuke.mindustry.content.Blocks;
|
|||||||
import io.anuke.mindustry.content.Fx;
|
import io.anuke.mindustry.content.Fx;
|
||||||
import io.anuke.mindustry.entities.Damage;
|
import io.anuke.mindustry.entities.Damage;
|
||||||
import io.anuke.mindustry.entities.Effects;
|
import io.anuke.mindustry.entities.Effects;
|
||||||
import io.anuke.mindustry.entities.Units;
|
|
||||||
import io.anuke.mindustry.entities.effect.ScorchDecal;
|
import io.anuke.mindustry.entities.effect.ScorchDecal;
|
||||||
import io.anuke.mindustry.entities.impl.DestructibleEntity;
|
import io.anuke.mindustry.entities.impl.DestructibleEntity;
|
||||||
import io.anuke.mindustry.entities.traits.*;
|
import io.anuke.mindustry.entities.traits.*;
|
||||||
@@ -49,9 +47,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
public static final float maxAbsVelocity = 127f / velocityPercision;
|
public static final float maxAbsVelocity = 127f / velocityPercision;
|
||||||
public static final int noSpawner = Pos.get(-1, 1);
|
public static final int noSpawner = Pos.get(-1, 1);
|
||||||
|
|
||||||
private static final Rectangle queryRect = new Rectangle();
|
|
||||||
private static final Vector2 moveVector = new Vector2();
|
private static final Vector2 moveVector = new Vector2();
|
||||||
|
|
||||||
|
private int lastWeightTile = Pos.invalid, lastWeightDelta;
|
||||||
|
private boolean wasFlying = false;
|
||||||
|
|
||||||
public float rotation;
|
public float rotation;
|
||||||
|
|
||||||
protected final Interpolator interpolator = new Interpolator();
|
protected final Interpolator interpolator = new Interpolator();
|
||||||
@@ -140,6 +140,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removed(){
|
||||||
|
Tile tile = world.tile(lastWeightTile);
|
||||||
|
|
||||||
|
if(tile != null){
|
||||||
|
tile.weight -= Math.max(lastWeightDelta, tile.weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(){
|
public boolean isValid(){
|
||||||
return !isDead() && isAdded();
|
return !isDead() && isAdded();
|
||||||
@@ -190,8 +199,8 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void clampPosition(){
|
protected void clampPosition(){
|
||||||
x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize);
|
x = Mathf.clamp(x, 0, world.width() * tilesize - tilesize);
|
||||||
y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize);
|
y = Mathf.clamp(y, 0, world.height() * tilesize - tilesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kill(){
|
public void kill(){
|
||||||
@@ -219,17 +228,56 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
|||||||
return status.hasEffect(effect);
|
return status.hasEffect(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO optimize
|
|
||||||
public void avoidOthers(float scaling){
|
public void avoidOthers(float scaling){
|
||||||
hitbox(queryRect);
|
boolean flying = isFlying();
|
||||||
queryRect.setSize(queryRect.getWidth() * scaling);
|
|
||||||
|
|
||||||
Units.getNearby(queryRect, t -> {
|
if(lastWeightTile != Pos.invalid){
|
||||||
if(t == this || t.isFlying() != isFlying()) return;
|
Tile tile = world.tile(lastWeightTile);
|
||||||
float dst = dst(t);
|
|
||||||
moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / queryRect.getWidth())));
|
if(tile != null){
|
||||||
applyImpulse(moveVector.x, moveVector.y);
|
int dec = Math.min(lastWeightDelta, wasFlying ? tile.airWeight : tile.weight);
|
||||||
});
|
if(!wasFlying){
|
||||||
|
tile.weight -= dec;
|
||||||
|
}else{
|
||||||
|
tile.airWeight -= dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int rad = 2;
|
||||||
|
|
||||||
|
moveVector.setZero();
|
||||||
|
for(int cx = -rad; cx <= rad; cx++){
|
||||||
|
for(int cy = -rad; cy <= rad; cy++){
|
||||||
|
Tile tile = world.tileWorld(x + cx*tilesize, y + cy*tilesize);
|
||||||
|
if(tile == null) continue;
|
||||||
|
int weight = flying ? tile.airWeight : tile.weight;
|
||||||
|
float scl = (rad - Mathf.dst(tile.worldx(), tile.worldy(), x, y)/(8f * 1.2f * Mathf.sqrt2)) * 0.1f;
|
||||||
|
|
||||||
|
moveVector.add(Mathf.sign(x - tile.worldx()) * scaling * weight * scl, Mathf.sign(y - tile.worldy()) * scaling * weight * scl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveVector.limit(flying ? 0.1f : 0.2f);
|
||||||
|
|
||||||
|
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
|
||||||
|
|
||||||
|
Tile tile = world.tileWorld(x, y);
|
||||||
|
|
||||||
|
if(tile != null){
|
||||||
|
int tw = flying ? tile.airWeight : tile.weight;
|
||||||
|
lastWeightDelta = Math.min((int)(mass()), 127 - tw);
|
||||||
|
lastWeightTile = tile.pos();
|
||||||
|
if(!flying){
|
||||||
|
tile.weight += lastWeightDelta;
|
||||||
|
}else{
|
||||||
|
tile.airWeight += lastWeightDelta;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
lastWeightTile = Pos.invalid;
|
||||||
|
}
|
||||||
|
wasFlying = flying;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileEntity getClosestCore(){
|
public TileEntity getClosestCore(){
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public class Tile implements Position, TargetTrait{
|
|||||||
public byte link = 0;
|
public byte link = 0;
|
||||||
/** Tile traversal cost. */
|
/** Tile traversal cost. */
|
||||||
public byte cost = 1;
|
public byte cost = 1;
|
||||||
|
/** Weight of [ground] units on this tile.*/
|
||||||
|
public byte weight, airWeight = 0;
|
||||||
/** Tile entity, usually null. */
|
/** Tile entity, usually null. */
|
||||||
public TileEntity entity;
|
public TileEntity entity;
|
||||||
public short x, y;
|
public short x, y;
|
||||||
|
|||||||
Reference in New Issue
Block a user