Bugfixes / Pathfinding 'improvements'
This commit is contained in:
@@ -2,7 +2,7 @@ package io.anuke.mindustry.ai;
|
|||||||
|
|
||||||
import io.anuke.arc.Events;
|
import io.anuke.arc.Events;
|
||||||
import io.anuke.arc.collection.IntArray;
|
import io.anuke.arc.collection.IntArray;
|
||||||
import io.anuke.arc.collection.Queue;
|
import io.anuke.arc.collection.IntQueue;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.Geometry;
|
||||||
import io.anuke.arc.math.geom.Point2;
|
import io.anuke.arc.math.geom.Point2;
|
||||||
import io.anuke.arc.util.Structs;
|
import io.anuke.arc.util.Structs;
|
||||||
@@ -19,7 +19,7 @@ import static io.anuke.mindustry.Vars.state;
|
|||||||
import static io.anuke.mindustry.Vars.world;
|
import static io.anuke.mindustry.Vars.world;
|
||||||
|
|
||||||
public class Pathfinder{
|
public class Pathfinder{
|
||||||
private long maxUpdate = Time.millisToNanos(4);
|
private static final long maxUpdate = Time.millisToNanos(4);
|
||||||
private PathData[] paths;
|
private PathData[] paths;
|
||||||
private IntArray blocked = new IntArray();
|
private IntArray blocked = new IntArray();
|
||||||
|
|
||||||
@@ -39,10 +39,6 @@ public class Pathfinder{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void activateTeamPath(Team team){
|
|
||||||
createFor(team);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
if(Net.client() || paths == null) return;
|
if(Net.client() || paths == null) return;
|
||||||
|
|
||||||
@@ -110,7 +106,7 @@ public class Pathfinder{
|
|||||||
for(Tile other : world.indexer.getEnemy(team, BlockFlag.target)){
|
for(Tile other : world.indexer.getEnemy(team, BlockFlag.target)){
|
||||||
path.weights[other.x][other.y] = 0;
|
path.weights[other.x][other.y] = 0;
|
||||||
path.searches[other.x][other.y] = (short)path.search;
|
path.searches[other.x][other.y] = (short)path.search;
|
||||||
path.frontier.addFirst(other);
|
path.frontier.addFirst(other.pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +126,7 @@ public class Pathfinder{
|
|||||||
|
|
||||||
if(state.teams.areEnemies(tile.getTeam(), team)
|
if(state.teams.areEnemies(tile.getTeam(), team)
|
||||||
&& tile.block().flags.contains(BlockFlag.target)){
|
&& tile.block().flags.contains(BlockFlag.target)){
|
||||||
path.frontier.addFirst(tile);
|
path.frontier.addFirst(tile.pos());
|
||||||
path.weights[x][y] = 0;
|
path.weights[x][y] = 0;
|
||||||
path.searches[x][y] = (short)path.search;
|
path.searches[x][y] = (short)path.search;
|
||||||
}else{
|
}else{
|
||||||
@@ -148,9 +144,15 @@ public class Pathfinder{
|
|||||||
long start = Time.nanos();
|
long start = Time.nanos();
|
||||||
|
|
||||||
while(path.frontier.size > 0 && (nsToRun < 0 || Time.timeSinceNanos(start) <= nsToRun)){
|
while(path.frontier.size > 0 && (nsToRun < 0 || Time.timeSinceNanos(start) <= nsToRun)){
|
||||||
Tile tile = path.frontier.removeLast();
|
Tile tile = world.tile(path.frontier.removeLast());
|
||||||
float cost = path.weights[tile.x][tile.y];
|
float cost = path.weights[tile.x][tile.y];
|
||||||
|
|
||||||
|
//pathfinding overflowed for some reason, time to bail. the next block update will handle this, hopefully
|
||||||
|
if(path.frontier.size >= world.width() * world.height()){
|
||||||
|
path.frontier.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(cost < Float.MAX_VALUE){
|
if(cost < Float.MAX_VALUE){
|
||||||
for(Point2 point : Geometry.d4){
|
for(Point2 point : Geometry.d4){
|
||||||
|
|
||||||
@@ -160,7 +162,7 @@ public class Pathfinder{
|
|||||||
if(other != null && (path.weights[dx][dy] > cost + other.cost || path.searches[dx][dy] < path.search)
|
if(other != null && (path.weights[dx][dy] > cost + other.cost || path.searches[dx][dy] < path.search)
|
||||||
&& passable(other, team)){
|
&& passable(other, team)){
|
||||||
if(other.cost < 0) throw new IllegalArgumentException("Tile cost cannot be negative! " + other);
|
if(other.cost < 0) throw new IllegalArgumentException("Tile cost cannot be negative! " + other);
|
||||||
path.frontier.addFirst(world.tile(dx, dy));
|
path.frontier.addFirst(world.tile(dx, dy).pos());
|
||||||
path.weights[dx][dy] = cost + other.cost;
|
path.weights[dx][dy] = cost + other.cost;
|
||||||
path.searches[dx][dy] = (short)path.search;
|
path.searches[dx][dy] = (short)path.search;
|
||||||
}
|
}
|
||||||
@@ -190,6 +192,6 @@ public class Pathfinder{
|
|||||||
short[][] searches;
|
short[][] searches;
|
||||||
int search = 0;
|
int search = 0;
|
||||||
long lastSearchTime;
|
long lastSearchTime;
|
||||||
Queue<Tile> frontier = new Queue<>();
|
IntQueue frontier = new IntQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,30 +2,38 @@ package io.anuke.mindustry.entities.effect;
|
|||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.graphics.g2d.Draw;
|
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.Mathf;
|
||||||
|
|
||||||
public class RubbleDecal extends Decal{
|
public class RubbleDecal extends Decal{
|
||||||
private int size;
|
private static TextureRegion[][] regions = new TextureRegion[16][0];
|
||||||
|
private TextureRegion region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a rubble effect at a position. Provide a block size to use.
|
* Creates a rubble effect at a position. Provide a block size to use.
|
||||||
*/
|
*/
|
||||||
public static void create(float x, float y, int size){
|
public static void create(float x, float y, int size){
|
||||||
|
if(regions[size].length == 0){
|
||||||
|
int i = 0;
|
||||||
|
for(; i < 2; i++){
|
||||||
|
if(!Core.atlas.has("rubble-" + size + "-" + i)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
regions[size] = new TextureRegion[i + 1];
|
||||||
|
for(int j = 0; j <= i; j++){
|
||||||
|
regions[size][j] = Core.atlas.find("rubble-" + size + "-" + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RubbleDecal decal = new RubbleDecal();
|
RubbleDecal decal = new RubbleDecal();
|
||||||
decal.size = size;
|
decal.region = regions[size][Mathf.clamp(Mathf.randomSeed(decal.id, 0, 1), 0, regions[size].length - 1)];
|
||||||
decal.set(x, y);
|
decal.set(x, y);
|
||||||
decal.add();
|
decal.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawDecal(){
|
public void drawDecal(){
|
||||||
String region = "rubble-" + size + "-" + Mathf.randomSeed(id, 0, 1);
|
|
||||||
|
|
||||||
if(!Core.atlas.has(region)){
|
|
||||||
remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw.rect(region, x, y, Mathf.randomSeed(id, 0, 4) * 90);
|
Draw.rect(region, x, y, Mathf.randomSeed(id, 0, 4) * 90);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import io.anuke.mindustry.type.ContentType;
|
|||||||
public class DatabaseDialog extends FloatingDialog{
|
public class DatabaseDialog extends FloatingDialog{
|
||||||
|
|
||||||
public DatabaseDialog(){
|
public DatabaseDialog(){
|
||||||
super("database");
|
super("$database");
|
||||||
|
|
||||||
shouldPause = true;
|
shouldPause = true;
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
|
|||||||
@@ -129,12 +129,13 @@ public class HudFragment extends Fragment{
|
|||||||
|
|
||||||
Table healthTable = cont.table("button", t ->
|
Table healthTable = cont.table("button", t ->
|
||||||
t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE)).grow()
|
t.margin(10f).add(new Bar("boss.health", Pal.health, () -> state.boss() == null ? 0f : state.boss().healthf()).blink(Color.WHITE)).grow()
|
||||||
).fillX().visible(() -> world.isZone() && state.boss() != null).height(60f).update(t -> t.getTranslation().set(wavetable.getTranslation())).get();
|
).fillX().visible(() -> world.isZone() && state.boss() != null).height(60f).update(t -> t.getTranslation().set(0, Unit.dp.scl(wavetable.getTranslation().y))).get();
|
||||||
|
|
||||||
cont.row();
|
cont.row();
|
||||||
|
|
||||||
//fps display
|
//fps display
|
||||||
infolabel = new Table();
|
infolabel = new Table();
|
||||||
|
infolabel.marginLeft(10f);
|
||||||
IntFormat fps = new IntFormat("fps");
|
IntFormat fps = new IntFormat("fps");
|
||||||
IntFormat ping = new IntFormat("ping");
|
IntFormat ping = new IntFormat("ping");
|
||||||
infolabel.label(() -> fps.get(Core.graphics.getFramesPerSecond())).padRight(10);
|
infolabel.label(() -> fps.get(Core.graphics.getFramesPerSecond())).padRight(10);
|
||||||
@@ -144,7 +145,7 @@ public class HudFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
infolabel.visible(() -> Core.settings.getBool("fps")).update(() ->
|
infolabel.visible(() -> Core.settings.getBool("fps")).update(() ->
|
||||||
infolabel.setPosition(0,
|
infolabel.setPosition(0,
|
||||||
healthTable.isVisible() ? healthTable.getY() + healthTable.getTranslation().y : waves.isVisible() ? wavetable.getY() : Core.graphics.getHeight(),
|
healthTable.isVisible() ? healthTable.getY() + healthTable.getTranslation().y : waves.isVisible() ? Math.min(wavetable.getY(), Core.graphics.getHeight()) : Core.graphics.getHeight(),
|
||||||
Align.topLeft));
|
Align.topLeft));
|
||||||
|
|
||||||
infolabel.pack();
|
infolabel.pack();
|
||||||
|
|||||||
@@ -331,15 +331,15 @@ public class Tile implements Position, TargetTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(occluded){
|
if(occluded){
|
||||||
cost += 1;
|
cost += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target().synthetic()){
|
if(target().synthetic()){
|
||||||
cost += Mathf.clamp(target().block().health / 10f, 0, 28);
|
cost += Mathf.clamp(target().block().health / 10f, 0, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(floor.isLiquid){
|
if(floor.isLiquid){
|
||||||
cost += 80;
|
cost += 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,10 @@ public class ItemBridge extends Block{
|
|||||||
protected int range;
|
protected int range;
|
||||||
protected float transportTime = 2f;
|
protected float transportTime = 2f;
|
||||||
protected IntArray removals = new IntArray();
|
protected IntArray removals = new IntArray();
|
||||||
|
|
||||||
protected TextureRegion endRegion, bridgeRegion, arrowRegion;
|
protected TextureRegion endRegion, bridgeRegion, arrowRegion;
|
||||||
|
|
||||||
|
private static int lastPlaced = Pos.invalid;
|
||||||
|
|
||||||
public ItemBridge(String name){
|
public ItemBridge(String name){
|
||||||
super(name);
|
super(name);
|
||||||
update = true;
|
update = true;
|
||||||
@@ -85,9 +86,15 @@ public class ItemBridge extends Block{
|
|||||||
if(linkValid(tile, link)){
|
if(linkValid(tile, link)){
|
||||||
Call.linkItemBridge(null, link, tile);
|
Call.linkItemBridge(null, link, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastPlaced = tile.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile findLink(int x, int y){
|
public Tile findLink(int x, int y){
|
||||||
|
if(linkValid(world.tile(x, y), world.tile(lastPlaced))){
|
||||||
|
return world.tile(lastPlaced);
|
||||||
|
}
|
||||||
|
|
||||||
for(int j = 0; j < 4; j ++){
|
for(int j = 0; j < 4; j ++){
|
||||||
Point2 p = Geometry.d4(j + 1);
|
Point2 p = Geometry.d4(j + 1);
|
||||||
for(int i = 1; i <= range; i++){
|
for(int i = 1; i <= range; i++){
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class CoreBlock extends StorageBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBreak(Tile tile){
|
public boolean canBreak(Tile tile){
|
||||||
return state.teams.get(tile.getTeam()).cores.size > 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user