Added spatial indexing of tile targets, many bugfixes

This commit is contained in:
Anuken
2018-06-20 22:56:53 -04:00
parent 45da578756
commit ca30f49481
11 changed files with 105 additions and 52 deletions
@@ -662,7 +662,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
if(local){
int index = stream.readByte();
players[index].readSaveSuper(stream);
dead = false;
players[index].dead = false;
}
}
+12 -33
View File
@@ -10,10 +10,8 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityPhysics;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*;
@@ -91,43 +89,24 @@ public class Units {
/**Returns the neareset ally tile in a range.*/
public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> !state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
for(Team enemy : state.teams.alliesOf(team)){
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
if(entity != null){
return entity;
}
}
return null;
}
/**Returns the neareset enemy tile in a range.*/
public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate<Tile> pred){
return findTile(x, y, range, tile -> state.teams.areEnemies(team, tile.getTeam()) && pred.test(tile));
}
//TODO optimize, spatial caching of tiles
/**Returns the neareset tile entity in a range.*/
public static TileEntity findTile(float x, float y, float range, Predicate<Tile> pred){
Entity closest = null;
float dst = 0;
int rad = (int)(range/tilesize)+1;
int tilex = Mathf.scl2(x, tilesize);
int tiley = Mathf.scl2(y, tilesize);
for(int rx = -rad; rx <= rad; rx ++){
for(int ry = -rad; ry <= rad; ry ++){
Tile other = world.tile(rx+tilex, ry+tiley);
if(other != null) other = other.target();
if(other == null || other.entity == null || !pred.test(other)) continue;
TileEntity e = other.entity;
float ndst = Vector2.dst(x, y, e.x, e.y);
if(ndst < range && (closest == null || ndst < dst)){
dst = ndst;
closest = e;
}
for(Team enemy : state.teams.enemiesOf(team)){
TileEntity entity = world.indexer().findTile(enemy, x, y, range, pred);
if(entity != null){
return entity;
}
}
return (TileEntity) closest;
return null;
}
/**Iterates over all units on all teams, including players.*/
@@ -5,6 +5,7 @@ import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
@@ -113,7 +114,7 @@ public abstract class BaseUnit extends Unit{
public void targetClosest(){
if(target != null) return;
//target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
target = Units.getClosestTarget(team, x, y, inventory.getAmmoRange());
}
public UnitState getStartState(){
@@ -254,12 +255,14 @@ public abstract class BaseUnit extends Unit{
public void writeSave(DataOutput stream) throws IOException {
super.writeSave(stream);
stream.writeByte(type.id);
stream.writeBoolean(isWave);
}
@Override
public void readSave(DataInput stream) throws IOException {
super.readSave(stream);
byte type = stream.readByte();
this.isWave = stream.readBoolean();
this.type = UnitType.getByID(type);
add();
@@ -53,7 +53,7 @@ public abstract class GroundUnit extends BaseUnit {
public void update() {
super.update();
if(target == null){
if(!velocity.isZero(0.001f) && (target == null || (inventory.hasAmmo() && distanceTo(target) <= inventory.getAmmoRange()))){
rotation = Mathf.lerpDelta(rotation, velocity.angle(), 0.2f);
}
}
@@ -104,7 +104,6 @@ public abstract class GroundUnit extends BaseUnit {
super.updateTargeting();
if(Units.invalidateTarget(target, team, x, y, Float.MAX_VALUE)){
if(target != null) Log.info("Invalidating target {0}", target);
target = null;
}
}