Entity cleanup
This commit is contained in:
@@ -6,8 +6,7 @@ import io.anuke.arc.files.FileHandle;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.util.Structs;
|
||||
import io.anuke.mindustry.core.*;
|
||||
import io.anuke.mindustry.entities.Entities;
|
||||
import io.anuke.mindustry.entities.EntityGroup;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
import io.anuke.mindustry.entities.effect.Fire;
|
||||
import io.anuke.mindustry.entities.effect.Puddle;
|
||||
@@ -70,22 +69,22 @@ public class Vars{
|
||||
public static final int tilesize = 8;
|
||||
/** all choosable player colors in join/host dialog */
|
||||
public static final Color[] playerColors = {
|
||||
Color.valueOf("82759a"),
|
||||
Color.valueOf("c0c1c5"),
|
||||
Color.valueOf("fff0e7"),
|
||||
Color.valueOf("7d2953"),
|
||||
Color.valueOf("ff074e"),
|
||||
Color.valueOf("ff072a"),
|
||||
Color.valueOf("ff76a6"),
|
||||
Color.valueOf("a95238"),
|
||||
Color.valueOf("ffa108"),
|
||||
Color.valueOf("feeb2c"),
|
||||
Color.valueOf("ffcaa8"),
|
||||
Color.valueOf("008551"),
|
||||
Color.valueOf("00e339"),
|
||||
Color.valueOf("423c7b"),
|
||||
Color.valueOf("4b5ef1"),
|
||||
Color.valueOf("2cabfe"),
|
||||
Color.valueOf("82759a"),
|
||||
Color.valueOf("c0c1c5"),
|
||||
Color.valueOf("fff0e7"),
|
||||
Color.valueOf("7d2953"),
|
||||
Color.valueOf("ff074e"),
|
||||
Color.valueOf("ff072a"),
|
||||
Color.valueOf("ff76a6"),
|
||||
Color.valueOf("a95238"),
|
||||
Color.valueOf("ffa108"),
|
||||
Color.valueOf("feeb2c"),
|
||||
Color.valueOf("ffcaa8"),
|
||||
Color.valueOf("008551"),
|
||||
Color.valueOf("00e339"),
|
||||
Color.valueOf("423c7b"),
|
||||
Color.valueOf("4b5ef1"),
|
||||
Color.valueOf("2cabfe"),
|
||||
};
|
||||
/** default server port */
|
||||
public static final int port = 6567;
|
||||
@@ -120,6 +119,7 @@ public class Vars{
|
||||
public static ContentLoader content;
|
||||
public static GameState state;
|
||||
public static GlobalData data;
|
||||
public static EntityCollisions collisions;
|
||||
|
||||
public static Control control;
|
||||
public static Logic logic;
|
||||
@@ -165,6 +165,8 @@ public class Vars{
|
||||
content.setVerbose();
|
||||
}
|
||||
|
||||
collisions = new EntityCollisions();
|
||||
|
||||
playerGroup = Entities.addGroup(Player.class).enableMapping();
|
||||
tileGroup = Entities.addGroup(TileEntity.class, false);
|
||||
bulletGroup = Entities.addGroup(Bullet.class).enableMapping();
|
||||
|
||||
@@ -6,7 +6,6 @@ import io.anuke.arc.graphics.Color;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.mindustry.entities.Effects;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
@@ -103,7 +102,6 @@ public class Mechs implements ContentList{
|
||||
float healRange = 60f;
|
||||
float healAmount = 10f;
|
||||
float healReload = 160f;
|
||||
Rectangle rect = new Rectangle();
|
||||
boolean wasHealed;
|
||||
|
||||
{
|
||||
@@ -137,15 +135,12 @@ public class Mechs implements ContentList{
|
||||
if(player.timer.get(Player.timerAbility, healReload)){
|
||||
wasHealed = false;
|
||||
|
||||
rect.setSize(healRange * 2f).setCenter(player.x, player.y);
|
||||
Units.getNearby(player.getTeam(), rect, unit -> {
|
||||
if(unit.dst(player) <= healRange){
|
||||
if(unit.health < unit.maxHealth()){
|
||||
Effects.effect(Fx.heal, unit);
|
||||
wasHealed = true;
|
||||
}
|
||||
unit.healBy(healAmount);
|
||||
Units.nearby(player.getTeam(), player.x, player.y, healRange, unit -> {
|
||||
if(unit.health < unit.maxHealth()){
|
||||
Effects.effect(Fx.heal, unit);
|
||||
wasHealed = true;
|
||||
}
|
||||
unit.healBy(healAmount);
|
||||
});
|
||||
|
||||
if(wasHealed){
|
||||
|
||||
@@ -12,7 +12,6 @@ import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.Effects;
|
||||
import io.anuke.mindustry.entities.EntityQuery;
|
||||
import io.anuke.mindustry.entities.type.Player;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.game.EventType.*;
|
||||
@@ -230,8 +229,6 @@ public class Control implements ApplicationListener{
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
EntityQuery.init();
|
||||
|
||||
Platform.instance.updateRPC();
|
||||
|
||||
if(!Core.settings.getBool("4.0-warning-2", false)){
|
||||
|
||||
@@ -42,8 +42,7 @@ public class Logic implements ApplicationListener{
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
EntityQuery.init();
|
||||
EntityQuery.collisions().setCollider(tilesize, (x, y) -> {
|
||||
collisions.setCollider(tilesize, (x, y) -> {
|
||||
Tile tile = world.tile(x, y);
|
||||
return tile != null && tile.solid();
|
||||
});
|
||||
@@ -157,10 +156,6 @@ public class Logic implements ApplicationListener{
|
||||
runWave();
|
||||
}
|
||||
|
||||
if(!Entities.defaultGroup().isEmpty()){
|
||||
throw new IllegalArgumentException("Do not add anything to the default group!");
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
Entities.update(effectGroup);
|
||||
Entities.update(groundEffectGroup);
|
||||
@@ -185,11 +180,11 @@ public class Logic implements ApplicationListener{
|
||||
for(EntityGroup group : unitGroups){
|
||||
if(group.isEmpty()) continue;
|
||||
|
||||
EntityQuery.collideGroups(bulletGroup, group);
|
||||
collisions.collideGroups(bulletGroup, group);
|
||||
}
|
||||
|
||||
EntityQuery.collideGroups(bulletGroup, playerGroup);
|
||||
EntityQuery.collideGroups(playerGroup, playerGroup);
|
||||
collisions.collideGroups(bulletGroup, playerGroup);
|
||||
collisions.collideGroups(playerGroup, playerGroup);
|
||||
|
||||
world.pathfinder.update();
|
||||
}
|
||||
|
||||
@@ -202,13 +202,13 @@ public class Renderer implements ApplicationListener{
|
||||
overlays.drawBottom();
|
||||
drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests);
|
||||
|
||||
if(EntityDraw.countInBounds(shieldGroup) > 0){
|
||||
if(Entities.countInBounds(shieldGroup) > 0){
|
||||
if(settings.getBool("animatedshields")){
|
||||
Draw.flush();
|
||||
shieldBuffer.begin();
|
||||
graphics.clear(Color.CLEAR);
|
||||
EntityDraw.draw(shieldGroup);
|
||||
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
|
||||
Entities.draw(shieldGroup);
|
||||
Entities.draw(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver());
|
||||
Draw.flush();
|
||||
shieldBuffer.end();
|
||||
Draw.shader(Shaders.shield);
|
||||
@@ -217,7 +217,7 @@ public class Renderer implements ApplicationListener{
|
||||
Draw.color();
|
||||
Draw.shader();
|
||||
}else{
|
||||
EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawSimple());
|
||||
Entities.draw(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawSimple());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ public class Renderer implements ApplicationListener{
|
||||
}
|
||||
|
||||
public <T extends DrawTrait> void drawAndInterpolate(EntityGroup<T> group, Predicate<T> toDraw, Consumer<T> drawer){
|
||||
EntityDraw.drawWith(group, toDraw, drawer);
|
||||
Entities.draw(group, toDraw, drawer);
|
||||
}
|
||||
|
||||
public void scaleCamera(float amount){
|
||||
|
||||
@@ -11,7 +11,7 @@ import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.ai.*;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
import io.anuke.mindustry.entities.EntityQuery;
|
||||
import io.anuke.mindustry.entities.Entities;
|
||||
import io.anuke.mindustry.game.EventType.TileChangeEvent;
|
||||
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
@@ -176,7 +176,7 @@ public class World implements ApplicationListener{
|
||||
|
||||
addDarkness(tiles);
|
||||
|
||||
EntityQuery.resizeTree(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2);
|
||||
Entities.getAllGroups().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2));
|
||||
|
||||
generating = false;
|
||||
Events.fire(new WorldLoadEvent());
|
||||
|
||||
@@ -131,7 +131,7 @@ public class Damage{
|
||||
}
|
||||
};
|
||||
|
||||
Units.getNearbyEnemies(team, rect, cons);
|
||||
Units.nearbyEnemies(team, rect, cons);
|
||||
}
|
||||
|
||||
/** Damages all entities and blocks in a radius that are enemies of the team. */
|
||||
@@ -149,9 +149,9 @@ public class Damage{
|
||||
|
||||
rect.setSize(size * 2).setCenter(x, y);
|
||||
if(team != null){
|
||||
Units.getNearbyEnemies(team, rect, cons);
|
||||
Units.nearbyEnemies(team, rect, cons);
|
||||
}else{
|
||||
Units.getNearby(rect, cons);
|
||||
Units.nearby(rect, cons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +180,9 @@ public class Damage{
|
||||
|
||||
rect.setSize(radius * 2).setCenter(x, y);
|
||||
if(team != null){
|
||||
Units.getNearbyEnemies(team, rect, cons);
|
||||
Units.nearbyEnemies(team, rect, cons);
|
||||
}else{
|
||||
Units.getNearby(rect, cons);
|
||||
Units.nearby(rect, cons);
|
||||
}
|
||||
|
||||
if(!complete){
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.IntMap;
|
||||
import io.anuke.arc.function.Consumer;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.graphics.Camera;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.traits.DrawTrait;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
|
||||
public class Entities{
|
||||
public static final int maxLeafObjects = 5;
|
||||
private static final EntityGroup<Entity> defaultGroup;
|
||||
public static final int maxLeafObjects = 4;
|
||||
private static final Array<EntityGroup<?>> groupArray = new Array<>();
|
||||
private static final IntMap<EntityGroup<?>> groups = new IntMap<>();
|
||||
|
||||
static{
|
||||
defaultGroup = addGroup(Entity.class);
|
||||
}
|
||||
private static final Rectangle viewport = new Rectangle();
|
||||
private static final boolean clip = true;
|
||||
private static int count = 0;
|
||||
|
||||
public static void clear(){
|
||||
for(EntityGroup group : groupArray){
|
||||
@@ -20,20 +25,12 @@ public class Entities{
|
||||
}
|
||||
}
|
||||
|
||||
public static Iterable<Entity> all(){
|
||||
return defaultGroup.all();
|
||||
}
|
||||
|
||||
public static EntityGroup<?> getGroup(int id){
|
||||
return groups.get(id);
|
||||
}
|
||||
|
||||
public static Iterable<EntityGroup<?>> getAllGroups(){
|
||||
return groups.values();
|
||||
}
|
||||
|
||||
public static EntityGroup<Entity> defaultGroup(){
|
||||
return defaultGroup;
|
||||
public static Array<EntityGroup<?>> getAllGroups(){
|
||||
return groupArray;
|
||||
}
|
||||
|
||||
public static <T extends Entity> EntityGroup<T> addGroup(Class<T> type){
|
||||
@@ -47,20 +44,46 @@ public class Entities{
|
||||
return group;
|
||||
}
|
||||
|
||||
public static void update(){
|
||||
update(defaultGroup());
|
||||
EntityQuery.collideGroups(defaultGroup(), defaultGroup());
|
||||
}
|
||||
|
||||
public static void update(EntityGroup<?> group){
|
||||
group.updateEvents();
|
||||
|
||||
if(group.useTree()){
|
||||
EntityQuery.collisions().updatePhysics(group);
|
||||
Vars.collisions.updatePhysics(group);
|
||||
}
|
||||
|
||||
for(Entity e : group.all()){
|
||||
e.update();
|
||||
}
|
||||
}
|
||||
|
||||
public static int countInBounds(EntityGroup<?> group){
|
||||
count = 0;
|
||||
draw(group, e -> true, e -> count++);
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void draw(EntityGroup<?> group){
|
||||
draw(group, e -> true);
|
||||
}
|
||||
|
||||
public static <T extends DrawTrait> void draw(EntityGroup<?> group, Predicate<T> toDraw){
|
||||
draw(group, toDraw, DrawTrait::draw);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends DrawTrait> void draw(EntityGroup<?> group, Predicate<T> toDraw, Consumer<T> cons){
|
||||
if(clip){
|
||||
Camera cam = Core.camera;
|
||||
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
|
||||
}
|
||||
|
||||
for(Entity e : group.all()){
|
||||
if(!(e instanceof DrawTrait) || !toDraw.test((T)e) || !e.isAdded()) continue;
|
||||
DrawTrait draw = (DrawTrait)e;
|
||||
|
||||
if(!clip || viewport.overlaps(draw.getX() - draw.drawSize()/2f, draw.getY() - draw.drawSize()/2f, draw.drawSize(), draw.drawSize())){
|
||||
cons.accept((T)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class EntityCollisions{
|
||||
|
||||
while(Math.abs(deltax) > 0 || !movedx){
|
||||
movedx = true;
|
||||
moveInternal(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true);
|
||||
moveDelta(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true);
|
||||
|
||||
if(Math.abs(deltax) >= seg){
|
||||
deltax -= seg * Mathf.sign(deltax);
|
||||
@@ -56,7 +56,7 @@ public class EntityCollisions{
|
||||
|
||||
while(Math.abs(deltay) > 0 || !movedy){
|
||||
movedy = true;
|
||||
moveInternal(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false);
|
||||
moveDelta(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false);
|
||||
|
||||
if(Math.abs(deltay) >= seg){
|
||||
deltay -= seg * Mathf.sign(deltay);
|
||||
@@ -66,7 +66,7 @@ public class EntityCollisions{
|
||||
}
|
||||
}
|
||||
|
||||
public void moveInternal(SolidTrait entity, float deltax, float deltay, boolean x){
|
||||
public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){
|
||||
if(collider == null)
|
||||
throw new IllegalArgumentException("No tile collider specified! Call setCollider() first.");
|
||||
|
||||
@@ -124,6 +124,7 @@ public class EntityCollisions{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Entity> void updatePhysics(EntityGroup<T> group){
|
||||
collided.clear();
|
||||
|
||||
@@ -218,6 +219,7 @@ public class EntityCollisions{
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
|
||||
collided.clear();
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.function.Consumer;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.graphics.Camera;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.mindustry.entities.traits.DrawTrait;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
|
||||
public class EntityDraw{
|
||||
private static final Rectangle viewport = new Rectangle();
|
||||
private static final Rectangle rect = new Rectangle();
|
||||
private static boolean clip = true;
|
||||
private static int count = 0;
|
||||
|
||||
public static void setClip(boolean clip){
|
||||
EntityDraw.clip = clip;
|
||||
}
|
||||
|
||||
public static int countInBounds(EntityGroup<?> group){
|
||||
count = 0;
|
||||
drawWith(group, e -> true, e -> count++);
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void draw(){
|
||||
draw(Entities.defaultGroup());
|
||||
}
|
||||
|
||||
public static void draw(EntityGroup<?> group){
|
||||
draw(group, e -> true);
|
||||
}
|
||||
|
||||
public static <T extends DrawTrait> void draw(EntityGroup<?> group, Predicate<T> toDraw){
|
||||
drawWith(group, toDraw, DrawTrait::draw);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends DrawTrait> void drawWith(EntityGroup<?> group, Predicate<T> toDraw, Consumer<T> cons){
|
||||
if(clip){
|
||||
Camera cam = Core.camera;
|
||||
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
|
||||
}
|
||||
|
||||
for(Entity e : group.all()){
|
||||
if(!(e instanceof DrawTrait) || !toDraw.test((T)e) || !e.isAdded()) continue;
|
||||
|
||||
if(!clip || rect.setSize(((DrawTrait)e).drawSize()).setCenter(e.getX(), e.getY()).overlaps(viewport)){
|
||||
cons.accept((T)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,10 @@ public class EntityGroup<T extends Entity>{
|
||||
this.useTree = useTree;
|
||||
this.id = lastid++;
|
||||
this.type = type;
|
||||
|
||||
if(useTree){
|
||||
tree = new QuadTree<>(Entities.maxLeafObjects, new Rectangle(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean useTree(){
|
||||
@@ -105,12 +109,22 @@ public class EntityGroup<T extends Entity>{
|
||||
}
|
||||
}
|
||||
|
||||
public void intersect(float x, float y, float width, float height, Consumer<? super T> out){
|
||||
//don't waste time for empty groups
|
||||
if(isEmpty()) return;
|
||||
tree().getIntersect(out, x, y, width, height);
|
||||
}
|
||||
|
||||
public QuadTree tree(){
|
||||
if(!useTree) throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it.");
|
||||
return tree;
|
||||
}
|
||||
|
||||
public void setTree(float x, float y, float w, float h){
|
||||
tree = new QuadTree<>(Entities.maxLeafObjects, new Rectangle(x, y, w, h));
|
||||
/** Resizes the internal quadtree, if it is enabled.*/
|
||||
public void resize(float x, float y, float w, float h){
|
||||
if(useTree){
|
||||
tree = new QuadTree<>(Entities.maxLeafObjects, new Rectangle(x, y, w, h));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
@@ -184,11 +198,4 @@ public class EntityGroup<T extends Entity>{
|
||||
public Array<T> all(){
|
||||
return entityArray;
|
||||
}
|
||||
|
||||
public void forEach(Consumer<T> cons){
|
||||
|
||||
for(T t : entityArray){
|
||||
cons.accept(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.function.Consumer;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
import io.anuke.mindustry.entities.traits.SolidTrait;
|
||||
|
||||
import static io.anuke.mindustry.entities.Entities.defaultGroup;
|
||||
|
||||
public class EntityQuery{
|
||||
private static final EntityCollisions collisions = new EntityCollisions();
|
||||
private static final Array<SolidTrait> array = new Array<>();
|
||||
private static final Rectangle r1 = new Rectangle();
|
||||
|
||||
public static EntityCollisions collisions(){
|
||||
return collisions;
|
||||
}
|
||||
|
||||
public static void init(float x, float y, float w, float h){
|
||||
|
||||
for(EntityGroup group : Entities.getAllGroups()){
|
||||
if(group.useTree()){
|
||||
group.setTree(x, y, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(){
|
||||
init(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public static void resizeTree(float x, float y, float w, float h){
|
||||
init(x, y, w, h);
|
||||
}
|
||||
|
||||
public static void getNearby(EntityGroup<?> group, Rectangle rect, Consumer<SolidTrait> out){
|
||||
|
||||
if(!group.useTree())
|
||||
throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it.");
|
||||
group.tree().getIntersect(out, rect);
|
||||
}
|
||||
|
||||
public static Array<SolidTrait> getNearby(EntityGroup<?> group, Rectangle rect){
|
||||
|
||||
array.clear();
|
||||
if(!group.useTree())
|
||||
throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it.");
|
||||
group.tree().getIntersect(array, rect);
|
||||
return array;
|
||||
}
|
||||
|
||||
public static void getNearby(float x, float y, float size, Consumer<SolidTrait> out){
|
||||
getNearby(defaultGroup(), r1.setSize(size).setCenter(x, y), out);
|
||||
}
|
||||
|
||||
public static void getNearby(EntityGroup<?> group, float x, float y, float size, Consumer<SolidTrait> out){
|
||||
getNearby(group, r1.setSize(size).setCenter(x, y), out);
|
||||
}
|
||||
|
||||
public static Array<SolidTrait> getNearby(float x, float y, float size){
|
||||
return getNearby(defaultGroup(), r1.setSize(size).setCenter(x, y));
|
||||
}
|
||||
|
||||
public static Array<SolidTrait> getNearby(EntityGroup<?> group, float x, float y, float size){
|
||||
return getNearby(group, r1.setSize(size).setCenter(x, y));
|
||||
}
|
||||
|
||||
public static <T extends Entity> T getClosest(EntityGroup<T> group, float x, float y, float range, Predicate<T> pred){
|
||||
|
||||
T closest = null;
|
||||
float cdist = 0f;
|
||||
Array<SolidTrait> entities = getNearby(group, x, y, range * 2f);
|
||||
for(int i = 0; i < entities.size; i++){
|
||||
T e = (T)entities.get(i);
|
||||
if(!pred.test(e))
|
||||
continue;
|
||||
|
||||
float dist = Mathf.dst(e.getX(), e.getY(), x, y);
|
||||
if(dist < range)
|
||||
if(closest == null || dist < cdist){
|
||||
closest = e;
|
||||
cdist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
public static void collideGroups(EntityGroup<?> groupa, EntityGroup<?> groupb){
|
||||
collisions().collideGroups(groupa, groupb);
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,12 @@ import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.mindustry.entities.type.*;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/**
|
||||
* Utility class for unit and team interactions.
|
||||
*/
|
||||
/** Utility class for unit and team interactions.*/
|
||||
public class Units{
|
||||
private static Rectangle rect = new Rectangle();
|
||||
private static Rectangle hitrect = new Rectangle();
|
||||
private static Unit result;
|
||||
private static float cdist;
|
||||
@@ -34,7 +30,7 @@ public class Units{
|
||||
* @return whether the target is invalid
|
||||
*/
|
||||
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y, float range){
|
||||
return target == null || (range != Float.MAX_VALUE && target.dst(x, y) > range) || target.getTeam() == team || !target.isValid();
|
||||
return target == null || (range != Float.MAX_VALUE && !target.withinDst(x, y, range)) || target.getTeam() == team || !target.isValid();
|
||||
}
|
||||
|
||||
/** See {@link #invalidateTarget(TargetTrait, Team, float, float, float)} */
|
||||
@@ -49,23 +45,19 @@ public class Units{
|
||||
|
||||
/** Returns whether there are any entities on this tile. */
|
||||
public static boolean anyEntities(Tile tile){
|
||||
Block type = tile.block();
|
||||
rect.setSize(type.size * tilesize, type.size * tilesize);
|
||||
rect.setCenter(tile.drawx(), tile.drawy());
|
||||
|
||||
return anyEntities(rect);
|
||||
float size = tile.block().size * tilesize;
|
||||
return anyEntities(tile.drawx() - size/2f, tile.drawy() - size/2f, size, size);
|
||||
}
|
||||
|
||||
/** Can be called from any thread. */
|
||||
public static boolean anyEntities(Rectangle rect){
|
||||
public static boolean anyEntities(float x, float y, float width, float height){
|
||||
boolResult = false;
|
||||
|
||||
Units.getNearby(rect, unit -> {
|
||||
nearby(x, y, width, height, unit -> {
|
||||
if(boolResult) return;
|
||||
if(!unit.isFlying()){
|
||||
unit.hitbox(hitrect);
|
||||
|
||||
if(hitrect.overlaps(rect)){
|
||||
if(hitrect.overlaps(x, y, width, height)){
|
||||
boolResult = true;
|
||||
}
|
||||
}
|
||||
@@ -74,28 +66,6 @@ public class Units{
|
||||
return boolResult;
|
||||
}
|
||||
|
||||
/** Returns whether there are any entities on this tile, with the hitbox expanded. */
|
||||
public static boolean anyEntities(Tile tile, float expansion, Predicate<Unit> pred){
|
||||
Block type = tile.block();
|
||||
rect.setSize(type.size * tilesize + expansion, type.size * tilesize + expansion);
|
||||
rect.setCenter(tile.drawx(), tile.drawy());
|
||||
|
||||
boolean[] value = new boolean[1];
|
||||
|
||||
Units.getNearby(rect, unit -> {
|
||||
if(value[0] || !pred.test(unit) || unit.isDead()) return;
|
||||
if(!unit.isFlying()){
|
||||
unit.hitbox(hitrect);
|
||||
|
||||
if(hitrect.overlaps(rect)){
|
||||
value[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return value[0];
|
||||
}
|
||||
|
||||
/** Returns the neareset damaged tile. */
|
||||
public static TileEntity findDamagedTile(Team team, float x, float y){
|
||||
Tile tile = Geometry.findClosest(x, y, world.indexer.getDamaged(team));
|
||||
@@ -120,36 +90,19 @@ public class Units{
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Iterates over all units on all teams, including players. */
|
||||
public static void allUnits(Consumer<Unit> cons){
|
||||
//check all unit groups first
|
||||
for(EntityGroup<BaseUnit> group : unitGroups){
|
||||
if(!group.isEmpty()){
|
||||
for(BaseUnit unit : group.all()){
|
||||
cons.accept(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//then check all player groups
|
||||
for(Player player : playerGroup.all()){
|
||||
cons.accept(player);
|
||||
}
|
||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||
public static TargetTrait closestTarget(Team team, float x, float y, float range){
|
||||
return closestTarget(team, x, y, range, Unit::isValid);
|
||||
}
|
||||
|
||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||
public static TargetTrait getClosestTarget(Team team, float x, float y, float range){
|
||||
return getClosestTarget(team, x, y, range, Unit::isValid);
|
||||
public static TargetTrait closestTarget(Team team, float x, float y, float range, Predicate<Unit> unitPred){
|
||||
return closestTarget(team, x, y, range, unitPred, t -> true);
|
||||
}
|
||||
|
||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||
public static TargetTrait getClosestTarget(Team team, float x, float y, float range, Predicate<Unit> unitPred){
|
||||
return getClosestTarget(team, x, y, range, unitPred, t -> true);
|
||||
}
|
||||
|
||||
/** Returns the closest target enemy. First, units are checked, then tile entities. */
|
||||
public static TargetTrait getClosestTarget(Team team, float x, float y, float range, Predicate<Unit> unitPred, Predicate<Tile> tilePred){
|
||||
Unit unit = getClosestEnemy(team, x, y, range, unitPred);
|
||||
public static TargetTrait closestTarget(Team team, float x, float y, float range, Predicate<Unit> unitPred, Predicate<Tile> tilePred){
|
||||
Unit unit = closestEnemy(team, x, y, range, unitPred);
|
||||
if(unit != null){
|
||||
return unit;
|
||||
}else{
|
||||
@@ -158,24 +111,19 @@ public class Units{
|
||||
}
|
||||
|
||||
/** Returns the closest enemy of this team. Filter by predicate. */
|
||||
public static Unit getClosestEnemy(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||
public static Unit closestEnemy(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||
if(team == Team.none) return null;
|
||||
|
||||
result = null;
|
||||
cdist = 0f;
|
||||
|
||||
rect.setSize(range * 2f).setCenter(x, y);
|
||||
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
|
||||
if(e.isDead() || !predicate.test(e)) return;
|
||||
|
||||
getNearbyEnemies(team, rect, e -> {
|
||||
if(e.isDead() || !predicate.test(e))
|
||||
return;
|
||||
|
||||
float dist = Mathf.dst(e.x, e.y, x, y);
|
||||
if(dist < range){
|
||||
if(result == null || dist < cdist){
|
||||
result = e;
|
||||
cdist = dist;
|
||||
}
|
||||
float dst2 = Mathf.dst2(e.x, e.y, x, y);
|
||||
if(dst2 < range*range && (result == null || dst2 < cdist)){
|
||||
result = e;
|
||||
cdist = dst2;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,22 +131,17 @@ public class Units{
|
||||
}
|
||||
|
||||
/** Returns the closest ally of this team. Filter by predicate. */
|
||||
public static Unit getClosest(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||
public static Unit closest(Team team, float x, float y, float range, Predicate<Unit> predicate){
|
||||
result = null;
|
||||
cdist = 0f;
|
||||
|
||||
rect.setSize(range * 2f).setCenter(x, y);
|
||||
nearby(team, x, y, range, e -> {
|
||||
if(!predicate.test(e)) return;
|
||||
|
||||
getNearby(team, rect, e -> {
|
||||
if(!predicate.test(e))
|
||||
return;
|
||||
|
||||
float dist = Mathf.dst(e.x, e.y, x, y);
|
||||
if(dist < range){
|
||||
if(result == null || dist < cdist){
|
||||
result = e;
|
||||
cdist = dist;
|
||||
}
|
||||
float dist = Mathf.dst2(e.x, e.y, x, y);
|
||||
if(result == null || dist < cdist){
|
||||
result = e;
|
||||
cdist = dist;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -206,87 +149,71 @@ public class Units{
|
||||
}
|
||||
|
||||
/** Iterates over all units in a rectangle. */
|
||||
public static void getNearby(Team team, Rectangle rect, Consumer<Unit> cons){
|
||||
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
EntityQuery.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
|
||||
//now check all players
|
||||
EntityQuery.getNearby(playerGroup, rect, player -> {
|
||||
if(((Unit)player).getTeam() == team) cons.accept((Unit)player);
|
||||
public static void nearby(Team team, float x, float y, float width, float height, Consumer<Unit> cons){
|
||||
unitGroups[team.ordinal()].intersect(x, y, width, height, cons);
|
||||
playerGroup.intersect(x, y, width, height, player -> {
|
||||
if(player.getTeam() == team){
|
||||
cons.accept(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Iterates over all units in a circle around this position. */
|
||||
public static void getNearby(Team team, float x, float y, float radius, Consumer<Unit> cons){
|
||||
rect.setSize(radius * 2).setCenter(x, y);
|
||||
public static void nearby(Team team, float x, float y, float radius, Consumer<Unit> cons){
|
||||
unitGroups[team.ordinal()].intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
|
||||
if(unit.withinDst(x, y, radius)){
|
||||
cons.accept(unit);
|
||||
}
|
||||
});
|
||||
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
EntityQuery.getNearby(group, rect, entity -> {
|
||||
if(entity.dst(x, y) <= radius){
|
||||
cons.accept((Unit)entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//now check all players
|
||||
EntityQuery.getNearby(playerGroup, rect, player -> {
|
||||
if(((Unit)player).getTeam() == team && player.dst(x, y) <= radius){
|
||||
cons.accept((Unit)player);
|
||||
playerGroup.intersect(x - radius, y - radius, radius*2f, radius*2f, unit -> {
|
||||
if(unit.getTeam() == team && unit.withinDst(x, y, radius)){
|
||||
cons.accept(unit);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Iterates over all units in a rectangle. */
|
||||
public static void getNearby(Rectangle rect, Consumer<Unit> cons){
|
||||
|
||||
public static void nearby(float x, float y, float width, float height, Consumer<Unit> cons){
|
||||
for(Team team : Team.all){
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
EntityQuery.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
unitGroups[team.ordinal()].intersect(x, y, width, height, cons);
|
||||
}
|
||||
|
||||
//now check all players
|
||||
EntityQuery.getNearby(playerGroup, rect, player -> cons.accept((Unit)player));
|
||||
playerGroup.intersect(x, y, width, height, cons);
|
||||
}
|
||||
|
||||
/** Iterates over all units in a rectangle. */
|
||||
public static void nearby(Rectangle rect, Consumer<Unit> cons){
|
||||
nearby(rect.x, rect.y, rect.width, rect.height, cons);
|
||||
}
|
||||
|
||||
/** Iterates over all units that are enemies of this team. */
|
||||
public static void getNearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
|
||||
public static void nearbyEnemies(Team team, float x, float y, float width, float height, Consumer<Unit> cons){
|
||||
EnumSet<Team> targets = state.teams.enemiesOf(team);
|
||||
|
||||
for(Team other : targets){
|
||||
EntityGroup<BaseUnit> group = unitGroups[other.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
EntityQuery.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
unitGroups[other.ordinal()].intersect(x, y, width, height, cons);
|
||||
}
|
||||
|
||||
//now check all enemy players
|
||||
EntityQuery.getNearby(playerGroup, rect, player -> {
|
||||
if(targets.contains(((Player)player).getTeam())){
|
||||
cons.accept((Unit)player);
|
||||
playerGroup.intersect(x, y, width, height, player -> {
|
||||
if(targets.contains(player.getTeam())){
|
||||
cons.accept(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Iterates over all units that are enemies of this team. */
|
||||
public static void nearbyEnemies(Team team, Rectangle rect, Consumer<Unit> cons){
|
||||
nearbyEnemies(team, rect.x, rect.y, rect.width, rect.height, cons);
|
||||
}
|
||||
|
||||
/** Iterates over all units. */
|
||||
public static void getAllUnits(Consumer<Unit> cons){
|
||||
|
||||
public static void all(Consumer<Unit> cons){
|
||||
for(Team team : Team.all){
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
for(Unit unit : group.all()){
|
||||
cons.accept(unit);
|
||||
}
|
||||
unitGroups[team.ordinal()].all().each(cons);
|
||||
}
|
||||
|
||||
//now check all enemy players
|
||||
for(Unit unit : playerGroup.all()){
|
||||
cons.accept(unit);
|
||||
}
|
||||
playerGroup.all().each(cons);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public abstract class BulletType extends Content{
|
||||
public void update(Bullet b){
|
||||
|
||||
if(homingPower > 0.0001f){
|
||||
TargetTrait target = Units.getClosestTarget(b.getTeam(), b.x, b.y, homingRange);
|
||||
TargetTrait target = Units.closestTarget(b.getTeam(), b.x, b.y, homingRange);
|
||||
if(target != null){
|
||||
b.velocity().setAngle(Mathf.slerpDelta(b.velocity().angle(), b.angleTo(target), 0.08f));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public abstract class FlakBulletType extends BasicBulletType{
|
||||
if(b.getData() instanceof Integer) return;
|
||||
|
||||
if(b.timer.get(2, 6)){
|
||||
Units.getNearbyEnemies(b.getTeam(), rect.setSize(explodeRange * 2f).setCenter(b.x, b.y), unit -> {
|
||||
Units.nearbyEnemies(b.getTeam(), rect.setSize(explodeRange * 2f).setCenter(b.x, b.y), unit -> {
|
||||
if(b.getData() instanceof Float) return;
|
||||
|
||||
if(unit.dst(b) < explodeRange){
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time
|
||||
rect.setSize(hitRange).setCenter(x, y);
|
||||
entities.clear();
|
||||
if(hit.size < maxChain){
|
||||
Units.getNearbyEnemies(team, rect, u -> {
|
||||
Units.nearbyEnemies(team, rect, u -> {
|
||||
if(!hit.contains(u.getID())){
|
||||
entities.add(u);
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
|
||||
|
||||
//effects-only code
|
||||
if(amount >= maxLiquid / 2f && updateTime <= 0f){
|
||||
Units.getNearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
|
||||
Units.nearby(rect.setSize(Mathf.clamp(amount / (maxLiquid / 1.5f)) * 10f).setCenter(x, y), unit -> {
|
||||
if(unit.isFlying()) return;
|
||||
|
||||
unit.hitbox(rect2);
|
||||
|
||||
@@ -5,9 +5,12 @@ import io.anuke.arc.util.pooling.Pool.Poolable;
|
||||
import io.anuke.arc.util.pooling.Pools;
|
||||
import io.anuke.mindustry.entities.Effects;
|
||||
import io.anuke.mindustry.entities.Effects.Effect;
|
||||
import io.anuke.mindustry.entities.EntityGroup;
|
||||
import io.anuke.mindustry.entities.traits.DrawTrait;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
|
||||
import static io.anuke.mindustry.Vars.effectGroup;
|
||||
|
||||
public class EffectEntity extends TimedEntity implements Poolable, DrawTrait{
|
||||
public Effect effect;
|
||||
public Color color = new Color(Color.WHITE);
|
||||
@@ -27,6 +30,12 @@ public class EffectEntity extends TimedEntity implements Poolable, DrawTrait{
|
||||
this.poffsety = y - parent.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityGroup targetGroup(){
|
||||
//this should never actually be called
|
||||
return effectGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float lifetime(){
|
||||
return effect.lifetime;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.mindustry.entities.Entities;
|
||||
import io.anuke.mindustry.entities.EntityGroup;
|
||||
|
||||
public interface Entity extends MoveTrait{
|
||||
@@ -18,9 +17,7 @@ public interface Entity extends MoveTrait{
|
||||
default void added(){
|
||||
}
|
||||
|
||||
default EntityGroup targetGroup(){
|
||||
return Entities.defaultGroup();
|
||||
}
|
||||
EntityGroup targetGroup();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default void add(){
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.arc.math.geom.*;
|
||||
import io.anuke.arc.math.geom.QuadTree.QuadTreeObject;
|
||||
import io.anuke.mindustry.entities.EntityQuery;
|
||||
import io.anuke.mindustry.Vars;
|
||||
|
||||
public interface SolidTrait extends QuadTreeObject, MoveTrait, VelocityTrait, Entity, Position{
|
||||
|
||||
@@ -33,6 +33,6 @@ public interface SolidTrait extends QuadTreeObject, MoveTrait, VelocityTrait, En
|
||||
}
|
||||
|
||||
default void move(float x, float y){
|
||||
EntityQuery.collisions().move(this, x, y);
|
||||
Vars.collisions.move(this, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
}
|
||||
|
||||
public void targetClosest(){
|
||||
TargetTrait newTarget = Units.getClosestTarget(team, x, y, Math.max(getWeapon().bullet.range(), type.range), u -> type.targetAir || !u.isFlying());
|
||||
TargetTrait newTarget = Units.closestTarget(team, x, y, Math.max(getWeapon().bullet.range(), type.range), u -> type.targetAir || !u.isFlying());
|
||||
if(newTarget != null){
|
||||
target = newTarget;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
@Override
|
||||
public void move(float x, float y){
|
||||
if(!mech.flying){
|
||||
EntityQuery.collisions().move(this, x, y);
|
||||
collisions.move(this, x, y);
|
||||
}else{
|
||||
moveBy(x, y);
|
||||
}
|
||||
@@ -687,7 +687,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
rect.width += expansion * 2f;
|
||||
rect.height += expansion * 2f;
|
||||
|
||||
isBoosting = EntityQuery.collisions().overlapsTile(rect) || dst(targetX, targetY) > 85f;
|
||||
isBoosting = collisions.overlapsTile(rect) || dst(targetX, targetY) > 85f;
|
||||
|
||||
velocity.add(movement.scl(Time.delta()));
|
||||
|
||||
@@ -715,7 +715,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
if(target == null){
|
||||
isShooting = false;
|
||||
if(Core.settings.getBool("autotarget")){
|
||||
target = Units.getClosestTarget(team, x, y, getWeapon().bullet.range(), u -> u.getTeam() != Team.none, u -> u.getTeam() != Team.none);
|
||||
target = Units.closestTarget(team, x, y, getWeapon().bullet.range(), u -> u.getTeam() != Team.none, u -> u.getTeam() != Team.none);
|
||||
|
||||
if(mech.canHeal && target == null){
|
||||
target = Geometry.findClosest(x, y, world.indexer.getDamaged(Team.blue));
|
||||
|
||||
@@ -208,9 +208,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
|
||||
public void avoidOthers(){
|
||||
float radScl = 1.5f;
|
||||
float fsize = getSize() / radScl;
|
||||
moveVector.setZero();
|
||||
|
||||
Units.getNearby(Tmp.r3.setSize(getSize()/radScl).setCenter(x, y), en -> {
|
||||
Units.nearby(x - fsize/2f, y - fsize/2f, fsize, fsize, en -> {
|
||||
if(en == this || en.isFlying() != isFlying()) return;
|
||||
float dst = dst(en);
|
||||
float scl = Mathf.clamp(1f - dst / (getSize()/(radScl*2f) + en.getSize()/(radScl*2f)));
|
||||
|
||||
@@ -124,9 +124,8 @@ public class MinimapRenderer implements Disposable{
|
||||
dx = Mathf.clamp(dx, sz, world.width() - sz);
|
||||
dy = Mathf.clamp(dy, sz, world.height() - sz);
|
||||
|
||||
rect.set((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize);
|
||||
units.clear();
|
||||
Units.getNearby(rect, units::add);
|
||||
Units.nearby((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize, units::add);
|
||||
}
|
||||
|
||||
private int colorFor(Tile tile){
|
||||
|
||||
@@ -50,7 +50,7 @@ public class OverlayRenderer{
|
||||
}
|
||||
}
|
||||
|
||||
Units.allUnits(unit -> {
|
||||
Units.all(unit -> {
|
||||
if(unit != player && unit.getTeam() != player.getTeam() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f).setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x, unit.y)){
|
||||
Tmp.v1.set(unit.x, unit.y).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
/** Check and assign targets for a specific position. */
|
||||
void checkTargets(float x, float y){
|
||||
Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead());
|
||||
Unit unit = Units.closestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead());
|
||||
|
||||
if(unit != null){
|
||||
player.setMineTile(null);
|
||||
|
||||
@@ -40,7 +40,7 @@ public class AdminsDialog extends FloatingDialog{
|
||||
res.addImageButton("icon-cancel", 14 * 3, () -> {
|
||||
ui.showConfirm("$confirm", "$confirmunadmin", () -> {
|
||||
netServer.admins.unAdminPlayer(info.id);
|
||||
playerGroup.forEach(player -> {
|
||||
playerGroup.all().each(player -> {
|
||||
if(player != null && player.uuid != null && player.uuid.equals(info.id)){
|
||||
player.isAdmin = false;
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ public class PlayerListFragment extends Fragment{
|
||||
float h = 74f;
|
||||
|
||||
playerGroup.all().sort((p1, p2) -> p1.getTeam().compareTo(p2.getTeam()));
|
||||
|
||||
playerGroup.forEach(user -> {
|
||||
playerGroup.all().each(user -> {
|
||||
NetConnection connection = user.con;
|
||||
|
||||
if(connection == null && Net.server() && !user.isLocal) return;
|
||||
|
||||
@@ -117,8 +117,7 @@ public class Build{
|
||||
return false;
|
||||
}
|
||||
|
||||
if((type.solid || type.solidifes) &&
|
||||
Units.anyEntities(rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()))){
|
||||
if((type.solid || type.solidifes) && Units.anyEntities(x * tilesize + type.offset() - type.size*tilesize/2f, y * tilesize + type.offset() - type.size*tilesize/2f, type.size * tilesize, type.size*tilesize)){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ public class ForceProjector extends Block{
|
||||
private static Tile paramTile;
|
||||
private static ForceProjector paramBlock;
|
||||
private static ForceEntity paramEntity;
|
||||
private static Consumer<SolidTrait> shieldConsumer = bullet -> {
|
||||
AbsorbTrait trait = (AbsorbTrait)bullet;
|
||||
private static Consumer<AbsorbTrait> shieldConsumer = trait -> {
|
||||
if(trait.canBeAbsorbed() && trait.getTeam() != paramTile.getTeam() && paramBlock.isInsideHexagon(trait.getX(), trait.getY(), paramBlock.realRadius(paramEntity) * 2f, paramTile.drawx(), paramTile.drawy())){
|
||||
trait.absorb();
|
||||
Effects.effect(Fx.absorb, trait);
|
||||
@@ -173,7 +172,7 @@ public class ForceProjector extends Block{
|
||||
paramTile = tile;
|
||||
paramEntity = entity;
|
||||
paramBlock = this;
|
||||
EntityQuery.getNearby(bulletGroup, tile.drawx(), tile.drawy(), realRadius * 2f, shieldConsumer);
|
||||
bulletGroup.intersect(tile.drawx() - realRadius, tile.drawy() - realRadius, realRadius*2f, realRadius * 2f, shieldConsumer);
|
||||
}
|
||||
|
||||
float realRadius(ForceEntity entity){
|
||||
|
||||
@@ -195,7 +195,7 @@ public abstract class Turret extends Block{
|
||||
protected void findTarget(Tile tile){
|
||||
TurretEntity entity = tile.entity();
|
||||
|
||||
entity.target = Units.getClosestTarget(tile.getTeam(),
|
||||
entity.target = Units.closestTarget(tile.getTeam(),
|
||||
tile.drawx(), tile.drawy(), range, e -> !e.isDead() && (!e.isFlying() || targetAir) && (e.isFlying() || targetGround));
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class RepairPoint extends Block{
|
||||
|
||||
if(entity.timer.get(timerTarget, 20)){
|
||||
rect.setSize(repairRadius * 2).setCenter(tile.drawx(), tile.drawy());
|
||||
entity.target = Units.getClosest(tile.getTeam(), tile.drawx(), tile.drawy(), repairRadius,
|
||||
entity.target = Units.closest(tile.getTeam(), tile.drawx(), tile.drawy(), repairRadius,
|
||||
unit -> unit.health < unit.maxHealth());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user