Fixed many pathfinding issues
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
@@ -34,12 +34,16 @@ public class Vars{
|
|||||||
public static boolean debug = false;
|
public static boolean debug = false;
|
||||||
//whether to debug openGL info
|
//whether to debug openGL info
|
||||||
public static boolean debugGL = false;
|
public static boolean debugGL = false;
|
||||||
|
//whether profiling is shown
|
||||||
|
public static boolean profile = false;
|
||||||
|
//whether the player can clip through walls
|
||||||
|
public static boolean noclip = false;
|
||||||
//whether to draw chunk borders
|
//whether to draw chunk borders
|
||||||
public static boolean debugChunks = false;
|
public static boolean debugChunks = false;
|
||||||
//whether turrets have infinite ammo (only with debug)
|
//whether turrets have infinite ammo (only with debug)
|
||||||
public static boolean infiniteAmmo = true;
|
public static boolean infiniteAmmo = true;
|
||||||
//whether to show paths of enemies
|
//whether to show paths of enemies
|
||||||
public static boolean showPaths = false;
|
public static boolean showPaths = true;
|
||||||
//number of save slots-- increasing may lead to layout issues
|
//number of save slots-- increasing may lead to layout issues
|
||||||
//TODO named save slots, possibly with a scroll dialog
|
//TODO named save slots, possibly with a scroll dialog
|
||||||
public static final int saveSlots = 4;
|
public static final int saveSlots = 4;
|
||||||
|
|||||||
@@ -4,22 +4,29 @@ import com.badlogic.gdx.ai.pfa.Heuristic;
|
|||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.World;
|
||||||
|
|
||||||
public class MHueristic implements Heuristic<Tile>{
|
public class MHueristic implements Heuristic<Tile>{
|
||||||
//so this means that the cost of going through solids is 10x going through non solids
|
//so this means that the cost of going through solids is 10x going through non solids
|
||||||
float multiplier = 10f;
|
static float multiplier = 10f;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float estimate(Tile node, Tile other){
|
public float estimate(Tile node, Tile other){
|
||||||
|
return estimateStatic(node, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float estimateStatic(Tile node, Tile other){
|
||||||
float cost = Math.abs(node.worldx() - other.worldx()) + Math.abs(node.worldy() - other.worldy());
|
float cost = Math.abs(node.worldx() - other.worldx()) + Math.abs(node.worldy() - other.worldy());
|
||||||
|
|
||||||
//TODO balance multiplier
|
//TODO balance multiplier
|
||||||
if(node.breakable() && node.block().solid) cost += Vars.tilesize*multiplier;
|
if(node.breakable() && node.block().solid) cost += Vars.tilesize*multiplier;
|
||||||
if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier;
|
if(other.breakable() && other.block().solid) cost += Vars.tilesize*multiplier;
|
||||||
for(Tile tile : node.getNearby()){
|
for(int dx = -1; dx <= 1; dx ++){
|
||||||
if(tile != null && tile.solid()){
|
for(int dy = -1; dy <= 1; dy ++){
|
||||||
//don't go near solid tiles!
|
Tile tile = World.tile(node.x + dx, node.y + dy);
|
||||||
cost += Vars.tilesize*3;
|
if(tile != null && tile.solid()){
|
||||||
|
cost += Vars.tilesize*5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
|
|||||||
@@ -1,57 +1,88 @@
|
|||||||
package io.anuke.mindustry.ai;
|
package io.anuke.mindustry.ai;
|
||||||
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
import com.badlogic.gdx.ai.pfa.PathFinder;
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
import com.badlogic.gdx.ai.pfa.PathSmoother;
|
||||||
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.entities.effect.Fx;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.World;
|
import io.anuke.mindustry.world.World;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Effects;
|
||||||
|
import io.anuke.ucore.util.Angles;
|
||||||
|
import io.anuke.ucore.util.Tmp;
|
||||||
public class Pathfind{
|
public class Pathfind{
|
||||||
static MHueristic heuristic = new MHueristic();
|
static MHueristic heuristic = new MHueristic();
|
||||||
static PassTileGraph graph = new PassTileGraph();
|
static PassTileGraph passgraph = new PassTileGraph();
|
||||||
static PathFinder<Tile> finder = new IndexedAStarPathFinder<Tile>(graph);
|
static PathFinder<Tile> passpathfinder;
|
||||||
|
static Array<SmoothGraphPath> paths = new Array<>();
|
||||||
|
static Tile[][] pathSequences;
|
||||||
static PathSmoother<Tile, Vector2> smoother = new PathSmoother<Tile, Vector2>(new Raycaster());
|
static PathSmoother<Tile, Vector2> smoother = new PathSmoother<Tile, Vector2>(new Raycaster());
|
||||||
static Vector2 vector = new Vector2();
|
static Vector2 vector = new Vector2();
|
||||||
|
|
||||||
static public Vector2 find(Enemy enemy){
|
static public Vector2 find(Enemy enemy){
|
||||||
findNode(enemy);
|
if(enemy.node == -1){
|
||||||
|
findNode(enemy);
|
||||||
if(enemy.node <= -1) return vector.set(enemy.x, enemy.y);
|
}
|
||||||
|
|
||||||
//-1 is only possible here if both pathfindings failed, which should NOT happen
|
//-1 is only possible here if both pathfindings failed, which should NOT happen
|
||||||
//check graph code
|
//check graph code
|
||||||
|
|
||||||
//Tile[] path = enemy.path;
|
Tile[] path = enemy.path;
|
||||||
Array<Tile> path = enemy.gpath.nodes;
|
|
||||||
|
|
||||||
Tile target = path.get(enemy.node);
|
Tile prev = path[enemy.node - 1];
|
||||||
|
|
||||||
|
Tile target = path[enemy.node];
|
||||||
|
|
||||||
|
float projectLen = Vector2.dst(prev.worldx(), prev.worldy(), target.worldx(), target.worldy()) / 6f;
|
||||||
|
|
||||||
|
Vector2 projection = projectPoint(prev.worldx(), prev.worldy(),
|
||||||
|
target.worldx(), target.worldy(), enemy.x, enemy.y);
|
||||||
|
|
||||||
|
boolean canProject = true;
|
||||||
|
|
||||||
|
if(projectLen < 8 || !onLine(projection, prev.worldx(), prev.worldy(), target.worldx(), target.worldy())){
|
||||||
|
canProject = false;
|
||||||
|
}else{
|
||||||
|
projection.add(Angles.translation(Angles.angle(prev.worldx(), prev.worldy(),
|
||||||
|
target.worldx(), target.worldy()), projectLen));
|
||||||
|
}
|
||||||
|
|
||||||
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
float dst = Vector2.dst(enemy.x, enemy.y, target.worldx(), target.worldy());
|
||||||
|
|
||||||
if(dst < 2){
|
if(dst < 8){
|
||||||
if(enemy.node <= path.size-2)
|
if(enemy.node <= path.length-2)
|
||||||
enemy.node ++;
|
enemy.node ++;
|
||||||
|
|
||||||
target = path.get(enemy.node);
|
target = path[enemy.node];
|
||||||
}
|
}
|
||||||
|
|
||||||
//near the core, stop
|
if(canProject && projection.dst(enemy.x, enemy.y) < Vector2.dst(target.x, target.y, enemy.x, enemy.y)){
|
||||||
if(enemy.node == path.size - 1){
|
vector.set(projection);
|
||||||
|
}else{
|
||||||
vector.set(target.worldx(), target.worldy());
|
vector.set(target.worldx(), target.worldy());
|
||||||
}
|
}
|
||||||
|
|
||||||
return vector.set(target.worldx(), target.worldy());
|
//near the core, stop
|
||||||
|
if(enemy.node == path.length - 1){
|
||||||
|
vector.set(target.worldx(), target.worldy());
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void updatePath(){
|
static public void reset(){
|
||||||
|
paths.clear();
|
||||||
|
pathSequences = null;
|
||||||
|
passpathfinder = new IndexedAStarPathFinder<Tile>(passgraph);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
static public void updatePath(){
|
||||||
if(paths.size == 0 || paths.size != World.spawnpoints.size){
|
if(paths.size == 0 || paths.size != World.spawnpoints.size){
|
||||||
paths.clear();
|
paths.clear();
|
||||||
pathSequences = new Tile[World.spawnpoints.size][0];
|
pathSequences = new Tile[World.spawnpoints.size][0];
|
||||||
@@ -61,6 +92,13 @@ public class Pathfind{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO make this work?
|
||||||
|
/*
|
||||||
|
PathFinderRequest<Tile> request = new PathFinderRequest<Tile>();
|
||||||
|
request.startNode = World.spawnpoints.get(0);
|
||||||
|
request.endNode = World.core;
|
||||||
|
passpathfinder.search(request, 1000); */
|
||||||
|
|
||||||
for(int i = 0; i < paths.size; i ++){
|
for(int i = 0; i < paths.size; i ++){
|
||||||
SmoothGraphPath path = paths.get(i);
|
SmoothGraphPath path = paths.get(i);
|
||||||
|
|
||||||
@@ -85,47 +123,18 @@ public class Pathfind{
|
|||||||
Effects.effect(Fx.ind, tile.worldx(), tile.worldy());
|
Effects.effect(Fx.ind, tile.worldx(), tile.worldy());
|
||||||
}
|
}
|
||||||
|
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findNode(Enemy enemy){
|
static void findNode(Enemy enemy){
|
||||||
/*
|
|
||||||
enemy.path = pathSequences[enemy.spawn];
|
enemy.path = pathSequences[enemy.spawn];
|
||||||
Tile[] path = enemy.path;
|
Tile[] path = enemy.path;
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(enemy.node == -1 || (Timers.get(enemy, "pathfind", 120) && enemy.request.pathFound)){
|
|
||||||
|
|
||||||
enemy.gpath = new SmoothGraphPath();
|
|
||||||
enemy.finder = new IndexedAStarPathFinder<Tile>(graph);
|
|
||||||
enemy.gpath.clear();
|
|
||||||
|
|
||||||
enemy.request = new PathFinderRequest<Tile>(World.tileWorld(enemy.x, enemy.y),
|
|
||||||
World.core,
|
|
||||||
heuristic, enemy.gpath);
|
|
||||||
enemy.request.statusChanged = true;
|
|
||||||
|
|
||||||
enemy.node = -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(enemy.gpath != null && !enemy.request.pathFound){
|
|
||||||
enemy.request.executionFrames ++;
|
|
||||||
if(enemy.finder.search(enemy.request, 1000000 / 5)){
|
|
||||||
smoother.smoothPath(enemy.gpath);
|
|
||||||
enemy.node = 1;
|
|
||||||
//UCore.log("done in " + enemy.request.executionFrames + " frames with path of size " + enemy.gpath.getCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Tile closest = null;
|
Tile closest = null;
|
||||||
float ldst = 0f;
|
float ldst = 0f;
|
||||||
int cindex = -1;
|
int cindex = -1;
|
||||||
|
|
||||||
for(int i = 0; i < path.size; i ++){
|
for(int i = 0; i < path.length; i ++){
|
||||||
Tile tile = path.get(i);
|
Tile tile = path[i];
|
||||||
float dst = Vector2.dst(tile.worldx(), tile.worldy(), enemy.x, enemy.y);
|
float dst = Vector2.dst(tile.worldx(), tile.worldy(), enemy.x, enemy.y);
|
||||||
|
|
||||||
if(closest == null || dst < ldst){
|
if(closest == null || dst < ldst){
|
||||||
@@ -134,6 +143,17 @@ public class Pathfind{
|
|||||||
cindex = i;
|
cindex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enemy.node = cindex;*/
|
enemy.node = Math.max(cindex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean onLine(Vector2 vector, float x1, float y1, float x2, float y2){
|
||||||
|
return MathUtils.isEqual(vector.dst(x1, y1) + vector.dst(x2, y2), Vector2.dst(x1, y1, x2, y2), 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector2 projectPoint(float x1, float y1, float x2, float y2, float pointx, float pointy){
|
||||||
|
float px = x2-x1, py = y2-y1, dAB = px*px + py*py;
|
||||||
|
float u = ((pointx - x1) * px + (pointy - y1) * py) / dAB;
|
||||||
|
float x = x1 + u * px, y = y1 + u * py;
|
||||||
|
return Tmp.v3.set(x, y); //this is D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.badlogic.gdx.ai.pfa.Connection;
|
|||||||
|
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
public class TileConnection implements Connection{
|
public class TileConnection implements Connection<Tile>{
|
||||||
Tile a, b;
|
Tile a, b;
|
||||||
|
|
||||||
public TileConnection(Tile a, Tile b){
|
public TileConnection(Tile a, Tile b){
|
||||||
@@ -14,16 +14,16 @@ public class TileConnection implements Connection{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getCost(){
|
public float getCost(){
|
||||||
return Math.abs(a.worldx() - b.worldx()) + Math.abs(a.worldy() - b.worldy());
|
return MHueristic.estimateStatic(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getFromNode(){
|
public Tile getFromNode(){
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getToNode(){
|
public Tile getToNode(){
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public class Control extends Module{
|
|||||||
|
|
||||||
for(int i = 0; i < spawnamount; i ++){
|
for(int i = 0; i < spawnamount; i ++){
|
||||||
int index = i;
|
int index = i;
|
||||||
float range = 8f;
|
float range = 12f;
|
||||||
|
|
||||||
Timers.run(index*50f, ()->{
|
Timers.run(index*50f, ()->{
|
||||||
try{
|
try{
|
||||||
@@ -419,6 +419,10 @@ public class Control extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Inputs.keyUp(Keys.O)){
|
||||||
|
Vars.noclip = !Vars.noclip;
|
||||||
|
}
|
||||||
|
|
||||||
if(Inputs.keyUp(Keys.Y)){
|
if(Inputs.keyUp(Keys.Y)){
|
||||||
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
if(Inputs.keyDown(Keys.SHIFT_LEFT)){
|
||||||
new HealerEnemy(0).set(player.x, player.y).add();
|
new HealerEnemy(0).set(player.x, player.y).add();
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class Player extends DestructibleEntity{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(){
|
public void onDeath(){
|
||||||
|
if(Vars.debug) return;
|
||||||
|
|
||||||
remove();
|
remove();
|
||||||
Effects.effect(Fx.explosion, this);
|
Effects.effect(Fx.explosion, this);
|
||||||
Effects.shake(4f, 5f, this);
|
Effects.shake(4f, 5f, this);
|
||||||
@@ -85,7 +87,12 @@ public class Player extends DestructibleEntity{
|
|||||||
|
|
||||||
vector.limit(speed);
|
vector.limit(speed);
|
||||||
|
|
||||||
move(vector.x*Timers.delta(), vector.y*Timers.delta());
|
if(!Vars.noclip){
|
||||||
|
move(vector.x*Timers.delta(), vector.y*Timers.delta());
|
||||||
|
}else{
|
||||||
|
x += vector.x*Timers.delta();
|
||||||
|
y += vector.y*Timers.delta();
|
||||||
|
}
|
||||||
|
|
||||||
if(!shooting){
|
if(!shooting){
|
||||||
direction.add(vector);
|
direction.add(vector);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package io.anuke.mindustry.entities.enemies;
|
package io.anuke.mindustry.entities.enemies;
|
||||||
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinder;
|
|
||||||
import com.badlogic.gdx.ai.pfa.PathFinderRequest;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
@@ -9,7 +7,6 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.ai.Pathfind;
|
import io.anuke.mindustry.ai.Pathfind;
|
||||||
import io.anuke.mindustry.ai.SmoothGraphPath;
|
|
||||||
import io.anuke.mindustry.entities.Bullet;
|
import io.anuke.mindustry.entities.Bullet;
|
||||||
import io.anuke.mindustry.entities.BulletType;
|
import io.anuke.mindustry.entities.BulletType;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
@@ -23,7 +20,12 @@ import io.anuke.ucore.util.Mathf;
|
|||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
public class Enemy extends DestructibleEntity{
|
public class Enemy extends DestructibleEntity{
|
||||||
public final static Color[] tierColors = {Color.YELLOW, Color.ORANGE, Color.RED, Color.MAGENTA};
|
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 int maxtier = 4;
|
||||||
|
|
||||||
protected float speed = 0.3f;
|
protected float speed = 0.3f;
|
||||||
@@ -37,11 +39,9 @@ public class Enemy extends DestructibleEntity{
|
|||||||
protected String shootsound = "enemyshoot";
|
protected String shootsound = "enemyshoot";
|
||||||
protected int damage;
|
protected int damage;
|
||||||
|
|
||||||
public PathFinderRequest<Tile> request = new PathFinderRequest<>();;
|
|
||||||
public SmoothGraphPath gpath;
|
|
||||||
public int spawn;
|
public int spawn;
|
||||||
public int node = -1;
|
public int node = -1;
|
||||||
public PathFinder<Tile> finder;
|
public Tile[] path;
|
||||||
|
|
||||||
public Vector2 direction = new Vector2();
|
public Vector2 direction = new Vector2();
|
||||||
public float xvelocity, yvelocity;
|
public float xvelocity, yvelocity;
|
||||||
@@ -80,16 +80,23 @@ public class Enemy extends DestructibleEntity{
|
|||||||
|
|
||||||
Vector2 shift = Tmp.v3.setZero();
|
Vector2 shift = Tmp.v3.setZero();
|
||||||
float shiftRange = hitbox.width + 3f;
|
float shiftRange = hitbox.width + 3f;
|
||||||
|
float avoidRange = 16f;
|
||||||
|
float avoidSpeed = 0.1f;
|
||||||
|
|
||||||
for(SolidEntity other : entities){
|
for(SolidEntity other : entities){
|
||||||
float dst = other.distanceTo(this);
|
float dst = other.distanceTo(this);
|
||||||
if(other != this && other instanceof Enemy && dst < shiftRange){
|
if(other != this && other instanceof Enemy){
|
||||||
float scl = Mathf.clamp(1.4f - dst/shiftRange);
|
if(dst < shiftRange){
|
||||||
shift.add((x - other.x) * scl, (y - other.y) * scl);
|
float scl = Mathf.clamp(1.4f - dst/shiftRange);
|
||||||
|
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.nor();
|
shift.limit(1f);
|
||||||
vec.add(shift.scl(0.5f));
|
vec.add(shift.scl(0.5f));
|
||||||
|
|
||||||
move(vec.x*Timers.delta(), vec.y*Timers.delta());
|
move(vec.x*Timers.delta(), vec.y*Timers.delta());
|
||||||
@@ -127,7 +134,6 @@ public class Enemy extends DestructibleEntity{
|
|||||||
|
|
||||||
public void findClosestNode(){
|
public void findClosestNode(){
|
||||||
Pathfind.find(this);
|
Pathfind.find(this);
|
||||||
/*
|
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int cindex = -1;
|
int cindex = -1;
|
||||||
@@ -143,6 +149,8 @@ public class Enemy extends DestructibleEntity{
|
|||||||
index ++;
|
index ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = Math.max(cindex, 1);
|
||||||
|
|
||||||
//set node to that index
|
//set node to that index
|
||||||
node = cindex;
|
node = cindex;
|
||||||
|
|
||||||
@@ -153,7 +161,7 @@ public class Enemy extends DestructibleEntity{
|
|||||||
Timers.run(Mathf.random(15f), ()->{
|
Timers.run(Mathf.random(15f), ()->{
|
||||||
set(x2 * Vars.tilesize, y2 * Vars.tilesize);
|
set(x2 * Vars.tilesize, y2 * Vars.tilesize);
|
||||||
});
|
});
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public enum Weapon{
|
|||||||
|
|
||||||
bullet(p, p.x, p.y, ang + Mathf.range(8));
|
bullet(p, p.x, p.y, ang + Mathf.range(8));
|
||||||
|
|
||||||
Effects.effect(Fx.shoot, p.x + vector.x, p.y+vector.y);
|
Effects.effect(Fx.shoot2, p.x + vector.x, p.y+vector.y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
flamer(5, BulletType.flame, "Shoots a stream of fire.", stack(Item.steel, 60), stack(Item.coal, 60)){
|
flamer(5, BulletType.flame, "Shoots a stream of fire.", stack(Item.steel, 60), stack(Item.coal, 60)){
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
import io.anuke.mindustry.Mindustry;
|
import io.anuke.mindustry.Mindustry;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState;
|
import io.anuke.mindustry.core.GameState;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
@@ -141,18 +142,22 @@ public class HudFragment implements Fragment{
|
|||||||
aleft();
|
aleft();
|
||||||
new label((StringSupplier)()->"[purple]entities: " + Entities.amount()).left();
|
new label((StringSupplier)()->"[purple]entities: " + Entities.amount()).left();
|
||||||
row();
|
row();
|
||||||
|
new label((StringSupplier)()->"[orange]noclip: " + Vars.noclip).left();
|
||||||
|
row();
|
||||||
new label("[red]DEBUG MODE").scale(0.5f).left();
|
new label("[red]DEBUG MODE").scale(0.5f).left();
|
||||||
}}.end();
|
}}.end();
|
||||||
|
|
||||||
new table(){{
|
if(profile){
|
||||||
atop();
|
new table(){{
|
||||||
new table("button"){{
|
|
||||||
defaults().left().growX();
|
|
||||||
atop();
|
atop();
|
||||||
aleft();
|
new table("button"){{
|
||||||
new label((StringSupplier)()->Profiler.formatDisplayTimes());
|
defaults().left().growX();
|
||||||
}}.width(400f).end();
|
atop();
|
||||||
}}.end();
|
aleft();
|
||||||
|
new label((StringSupplier)()->Profiler.formatDisplayTimes());
|
||||||
|
}}.width(400f).end();
|
||||||
|
}}.end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ public class World{
|
|||||||
World.seed = seed;
|
World.seed = seed;
|
||||||
Generator.generate(mapPixmaps[map.ordinal()]);
|
Generator.generate(mapPixmaps[map.ordinal()]);
|
||||||
|
|
||||||
|
Pathfind.reset();
|
||||||
|
|
||||||
//TODO multiblock core
|
//TODO multiblock core
|
||||||
placeBlock(core.x, core.y, ProductionBlocks.core, 0);
|
placeBlock(core.x, core.y, ProductionBlocks.core, 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user