mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-22 21:57:58 +07:00
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.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.Point2;
|
||||
import io.anuke.arc.util.Structs;
|
||||
@ -19,7 +19,7 @@ import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Pathfinder{
|
||||
private long maxUpdate = Time.millisToNanos(4);
|
||||
private static final long maxUpdate = Time.millisToNanos(4);
|
||||
private PathData[] paths;
|
||||
private IntArray blocked = new IntArray();
|
||||
|
||||
@ -39,10 +39,6 @@ public class Pathfinder{
|
||||
});
|
||||
}
|
||||
|
||||
public void activateTeamPath(Team team){
|
||||
createFor(team);
|
||||
}
|
||||
|
||||
public void update(){
|
||||
if(Net.client() || paths == null) return;
|
||||
|
||||
@ -110,7 +106,7 @@ public class Pathfinder{
|
||||
for(Tile other : world.indexer.getEnemy(team, BlockFlag.target)){
|
||||
path.weights[other.x][other.y] = 0;
|
||||
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)
|
||||
&& tile.block().flags.contains(BlockFlag.target)){
|
||||
path.frontier.addFirst(tile);
|
||||
path.frontier.addFirst(tile.pos());
|
||||
path.weights[x][y] = 0;
|
||||
path.searches[x][y] = (short)path.search;
|
||||
}else{
|
||||
@ -148,9 +144,15 @@ public class Pathfinder{
|
||||
long start = Time.nanos();
|
||||
|
||||
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];
|
||||
|
||||
//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){
|
||||
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)
|
||||
&& passable(other, team)){
|
||||
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.searches[dx][dy] = (short)path.search;
|
||||
}
|
||||
@ -190,6 +192,6 @@ public class Pathfinder{
|
||||
short[][] searches;
|
||||
int search = 0;
|
||||
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.graphics.g2d.Draw;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
|
||||
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.
|
||||
*/
|
||||
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();
|
||||
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.add();
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import io.anuke.mindustry.type.ContentType;
|
||||
public class DatabaseDialog extends FloatingDialog{
|
||||
|
||||
public DatabaseDialog(){
|
||||
super("database");
|
||||
super("$database");
|
||||
|
||||
shouldPause = true;
|
||||
addCloseButton();
|
||||
|
@ -129,12 +129,13 @@ public class HudFragment extends Fragment{
|
||||
|
||||
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()
|
||||
).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();
|
||||
|
||||
//fps display
|
||||
infolabel = new Table();
|
||||
infolabel.marginLeft(10f);
|
||||
IntFormat fps = new IntFormat("fps");
|
||||
IntFormat ping = new IntFormat("ping");
|
||||
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.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));
|
||||
|
||||
infolabel.pack();
|
||||
|
@ -331,15 +331,15 @@ public class Tile implements Position, TargetTrait{
|
||||
}
|
||||
|
||||
if(occluded){
|
||||
cost += 1;
|
||||
cost += 2;
|
||||
}
|
||||
|
||||
if(target().synthetic()){
|
||||
cost += Mathf.clamp(target().block().health / 10f, 0, 28);
|
||||
cost += Mathf.clamp(target().block().health / 10f, 0, 20);
|
||||
}
|
||||
|
||||
if(floor.isLiquid){
|
||||
cost += 80;
|
||||
cost += 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,9 +36,10 @@ public class ItemBridge extends Block{
|
||||
protected int range;
|
||||
protected float transportTime = 2f;
|
||||
protected IntArray removals = new IntArray();
|
||||
|
||||
protected TextureRegion endRegion, bridgeRegion, arrowRegion;
|
||||
|
||||
private static int lastPlaced = Pos.invalid;
|
||||
|
||||
public ItemBridge(String name){
|
||||
super(name);
|
||||
update = true;
|
||||
@ -85,9 +86,15 @@ public class ItemBridge extends Block{
|
||||
if(linkValid(tile, link)){
|
||||
Call.linkItemBridge(null, link, tile);
|
||||
}
|
||||
|
||||
lastPlaced = tile.pos();
|
||||
}
|
||||
|
||||
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 ++){
|
||||
Point2 p = Geometry.d4(j + 1);
|
||||
for(int i = 1; i <= range; i++){
|
||||
|
@ -74,7 +74,7 @@ public class CoreBlock extends StorageBlock{
|
||||
|
||||
@Override
|
||||
public boolean canBreak(Tile tile){
|
||||
return state.teams.get(tile.getTeam()).cores.size > 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user