diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 205d06b30a..4937c13805 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -33,11 +33,25 @@ public class Pathfind{ enemy.findClosestNode(); } + Tile[] path = enemy.path; + + + if(enemy.idletime > Enemy.maxIdle){ + //TODO reverse + Tile target = path[enemy.node]; + if(Vars.world.raycastWorld(enemy.x, enemy.y, target.worldx(), target.worldy()) != null){ + if(enemy.node > 1) + enemy.node = enemy.node - 1; + }else{ + //what's the problem, then? + } + + enemy.idletime = 0; + } + //-1 is only possible here if both pathfindings failed, which should NOT happen //check graph code - Tile[] path = enemy.path; - Tile prev = path[enemy.node - 1]; Tile target = path[enemy.node]; diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 1ecbfa51b1..09b687c297 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -36,9 +36,14 @@ public class Player extends DestructibleEntity{ heal(); } + @Override + public void damage(int amount){ + if(!Vars.debug) + super.damage(amount); + } + @Override public void onDeath(){ - if(Vars.debug) return; remove(); Effects.effect(Fx.explosion, this); diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index bb7b703b97..cb22aefc7f 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -18,6 +18,7 @@ import io.anuke.ucore.util.Tmp; public class Enemy extends DestructibleEntity{ public final static Color[] tierColors = { Color.valueOf("ffe451"), Color.valueOf("f48e20"), Color.valueOf("ff6757"), Color.valueOf("ff2d86") }; public final static int maxtier = 4; + public final static float maxIdle = 60*3f; protected float speed = 0.4f; protected float reload = 32; @@ -35,7 +36,8 @@ public class Enemy extends DestructibleEntity{ protected boolean targetCore = false; protected boolean stopNearCore = true; protected float mass = 1f; - + + public float idletime = 0f; public int spawn; public int node = -1; public Tile[] path; @@ -68,13 +70,14 @@ public class Enemy extends DestructibleEntity{ if(targetCore) target = core.entity; }else{ vec = Vars.world.pathfinder().find(this); - vec.sub(x, y).setLength(speed); + vec.sub(x, y).limit(speed); } Vector2 shift = Tmp.v3.setZero(); - float shiftRange = hitbox.width + 3f; - float avoidRange = 16f; - float avoidSpeed = 0.1f; + float shiftRange = hitbox.width + 2f; + float avoidRange = shiftRange + 4f; + float attractRange = avoidRange + 7f; + float avoidSpeed = this.speed/2.7f; Entities.getNearby(Entities.getGroup(Enemy.class), x, y, range, other -> { Enemy enemy = (Enemy)other; @@ -87,7 +90,10 @@ public class Enemy extends DestructibleEntity{ shift.add((x - other.x) * scl, (y - other.y) * scl); }else if(dst < avoidRange){ Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed); - shift.add(Tmp.v2); + shift.add(Tmp.v2.scl(1.1f)); + }else if(dst < attractRange && !nearCore){ + Tmp.v2.set((x - other.x), (y - other.y)).setLength(avoidSpeed); + shift.add(Tmp.v2.scl(-1)); } }); @@ -214,6 +220,14 @@ public class Enemy extends DestructibleEntity{ xvelocity = (x - lastx) / Timers.delta(); yvelocity = (y - lasty) / Timers.delta(); + + float minv = 0.001f; + + if(xvelocity < minv && yvelocity < minv && node > 0){ + idletime += Timers.delta(); + }else{ + idletime = 0; + } if(target == null || alwaysRotate){ angle = Mathf.slerp(angle, 180f+Mathf.atan2(xvelocity, yvelocity), rotatespeed * Timers.delta()); diff --git a/core/src/io/anuke/mindustry/world/World.java b/core/src/io/anuke/mindustry/world/World.java index ba31bbf780..5769a500b2 100644 --- a/core/src/io/anuke/mindustry/world/World.java +++ b/core/src/io/anuke/mindustry/world/World.java @@ -438,11 +438,16 @@ public class World extends Module{ return (TileEntity) closest; } + public GridPoint2 raycastWorld(float x, float y, float x2, float y2){ + return raycast(Mathf.scl2(x, tilesize), Mathf.scl2(y, tilesize), + Mathf.scl2(x2, tilesize), Mathf.scl2(y2, tilesize)); + } + /** * Input is in block coordinates, not world coordinates. * @return null if no collisions found, block position otherwise. */ - public Vector2 raycast(int x0f, int y0f, int x1f, int y1f){ + public GridPoint2 raycast(int x0f, int y0f, int x1f, int y1f){ int x0 = (int)x0f; int y0 = (int)y0f; int x1 = (int)x1f; @@ -458,7 +463,7 @@ public class World extends Module{ while(true){ if(solid(x0, y0)){ - return Tmp.v3.set(x0, y0); + return Tmp.g1.set(x0, y0); } if(x0 == x1 && y0 == y1) break;