mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-01-03 13:30:25 +07:00
Proper pathfinding fixes
This commit is contained in:
parent
ba475b681c
commit
49a39d42e7
@ -1,6 +1,7 @@
|
|||||||
package mindustry.annotations.impl;
|
package mindustry.annotations.impl;
|
||||||
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.annotations.*;
|
import mindustry.annotations.*;
|
||||||
@ -63,23 +64,28 @@ public class StructProcess extends BaseProcessor{
|
|||||||
int size = varSize(var);
|
int size = varSize(var);
|
||||||
TypeName varType = var.tname();
|
TypeName varType = var.tname();
|
||||||
String varName = var.name();
|
String varName = var.name();
|
||||||
|
boolean isBool = varType == TypeName.BOOLEAN;
|
||||||
|
|
||||||
//add val param to constructor
|
//add val param to constructor
|
||||||
constructor.addParameter(varType, varName);
|
constructor.addParameter(varType, varName);
|
||||||
|
|
||||||
//[get] field(structType) : fieldType
|
//[get] field(structType) : fieldType
|
||||||
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.name().toString())
|
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.name())
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
.returns(varType)
|
.returns(varType)
|
||||||
.addParameter(structType, structParam);
|
.addParameter(structType, structParam);
|
||||||
//[set] field(structType, fieldType) : structType
|
//[set] field(structType, fieldType) : structType
|
||||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.name().toString())
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.name())
|
||||||
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
.returns(structType)
|
.returns(structType)
|
||||||
.addParameter(structType, structParam).addParameter(varType, "value");
|
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||||
|
|
||||||
|
//field for offset
|
||||||
|
classBuilder.addField(FieldSpec.builder(structType, "bitMask" + Strings.capitalize(varName), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||||
|
.initializer(!isBool ? "($T)($L)" : "($T)(1L << $L)", structType, isBool ? offset : bitString(offset, size, structTotalSize)).build());
|
||||||
|
|
||||||
//[getter]
|
//[getter]
|
||||||
if(varType == TypeName.BOOLEAN){
|
if(isBool){
|
||||||
//bools: single bit, is simplified
|
//bools: single bit, is simplified
|
||||||
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
||||||
}else if(varType == TypeName.FLOAT){
|
}else if(varType == TypeName.FLOAT){
|
||||||
@ -124,7 +130,7 @@ public class StructProcess extends BaseProcessor{
|
|||||||
classBuilder.addJavadoc(doc.toString());
|
classBuilder.addJavadoc(doc.toString());
|
||||||
|
|
||||||
//add constructor final statement + add to class and build
|
//add constructor final statement + add to class and build
|
||||||
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
constructor.addStatement("return ($T)($L)", structType, cons.substring(3));
|
||||||
classBuilder.addMethod(constructor.build());
|
classBuilder.addMethod(constructor.build());
|
||||||
|
|
||||||
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
|
||||||
|
@ -298,13 +298,27 @@ public class ControlPathfinder{
|
|||||||
if(avoid(type, x + y * wwidth)) return true;
|
if(avoid(type, x + y * wwidth)) return true;
|
||||||
if(x == x2 && y == y2) return false;
|
if(x == x2 && y == y2) return false;
|
||||||
|
|
||||||
//no diagonals
|
//TODO no diagonals???? is this a good idea?
|
||||||
|
/*
|
||||||
|
//no diagonal ver
|
||||||
if(2 * err + dy > dx - 2 * err){
|
if(2 * err + dy > dx - 2 * err){
|
||||||
err -= dy;
|
err -= dy;
|
||||||
x += sx;
|
x += sx;
|
||||||
}else{
|
}else{
|
||||||
err += dx;
|
err += dx;
|
||||||
y += sy;
|
y += sy;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//diagonal ver
|
||||||
|
e2 = 2 * err;
|
||||||
|
if(e2 > -dy){
|
||||||
|
err -= dy;
|
||||||
|
x += sx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e2 < dx){
|
||||||
|
err += dx;
|
||||||
|
y += sy;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public class Pathfinder implements Runnable{
|
|||||||
|
|
||||||
for(int i = 0; i < tiles.length; i++){
|
for(int i = 0; i < tiles.length; i++){
|
||||||
Tile tile = world.tiles.geti(i);
|
Tile tile = world.tiles.geti(i);
|
||||||
tiles[i] = packTile(tile);
|
tiles[i] = packTile(tile, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
preloadPath(getField(state.rules.waveTeam, costGround, fieldCore));
|
preloadPath(getField(state.rules.waveTeam, costGround, fieldCore));
|
||||||
@ -108,6 +108,34 @@ public class Pathfinder implements Runnable{
|
|||||||
Events.on(ResetEvent.class, event -> stop());
|
Events.on(ResetEvent.class, event -> stop());
|
||||||
|
|
||||||
Events.on(TileChangeEvent.class, event -> updateTile(event.tile));
|
Events.on(TileChangeEvent.class, event -> updateTile(event.tile));
|
||||||
|
|
||||||
|
//remove nearSolid flag for tiles
|
||||||
|
Events.on(TilePreChangeEvent.class, event -> {
|
||||||
|
Tile tile = event.tile;
|
||||||
|
|
||||||
|
if(tile.solid()){
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
Tile other = tile.nearby(i);
|
||||||
|
if(other != null){
|
||||||
|
//other tile needs to update its nearSolid to be false if it's not solid and this tile just got un-solidified
|
||||||
|
if(!other.solid()){
|
||||||
|
boolean otherNearSolid = false;
|
||||||
|
for(int j = 0; j < 4; j++){
|
||||||
|
Tile othernear = other.nearby(i);
|
||||||
|
if(othernear != null && othernear.solid()){
|
||||||
|
otherNearSolid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//the other tile is no longer near solid, remove the solid bit
|
||||||
|
if(!otherNearSolid){
|
||||||
|
tiles[other.array()] &= ~(PathTile.bitMaskNearSolid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearCache(){
|
private void clearCache(){
|
||||||
@ -115,17 +143,23 @@ public class Pathfinder implements Runnable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Packs a tile into its internal representation. */
|
/** Packs a tile into its internal representation. */
|
||||||
private int packTile(Tile tile){
|
private int packTile(Tile tile, int prev){
|
||||||
boolean nearLiquid = false, nearSolid = false, nearGround = false, solid = tile.solid(), allDeep = tile.floor().isDeep();
|
boolean nearLiquid = false, nearSolid = false, nearGround = false, solid = tile.solid(), allDeep = tile.floor().isDeep();
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
Tile other = tile.nearby(i);
|
Tile other = tile.nearby(i);
|
||||||
if(other != null){
|
if(other != null){
|
||||||
Floor floor = other.floor();
|
Floor floor = other.floor();
|
||||||
|
boolean osolid = other.solid();
|
||||||
if(floor.isLiquid) nearLiquid = true;
|
if(floor.isLiquid) nearLiquid = true;
|
||||||
if(other.solid()) nearSolid = true;
|
if(osolid) nearSolid = true;
|
||||||
if(!floor.isLiquid) nearGround = true;
|
if(!floor.isLiquid) nearGround = true;
|
||||||
if(!floor.isDeep()) allDeep = false;
|
if(!floor.isDeep()) allDeep = false;
|
||||||
|
|
||||||
|
//other tile is now near solid
|
||||||
|
if(solid){
|
||||||
|
tiles[other.array()] |= PathTile.bitMaskNearSolid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +207,7 @@ public class Pathfinder implements Runnable{
|
|||||||
tile.getLinkedTiles(t -> {
|
tile.getLinkedTiles(t -> {
|
||||||
int pos = t.array();
|
int pos = t.array();
|
||||||
if(pos < tiles.length){
|
if(pos < tiles.length){
|
||||||
tiles[pos] = packTile(t);
|
tiles[pos] = packTile(t, tiles[pos]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public class CommandAI extends AIController{
|
|||||||
faceTarget();
|
faceTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attackTarget == null && unit.within(targetPos, Math.max(5f, unit.hitSize) / 2.5f)){
|
if(attackTarget == null && unit.within(targetPos, Math.max(5f, unit.hitSize / 2.5f))){
|
||||||
targetPos = null;
|
targetPos = null;
|
||||||
}
|
}
|
||||||
}else if(target != null){
|
}else if(target != null){
|
||||||
|
@ -253,6 +253,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
|||||||
if(other != null){
|
if(other != null){
|
||||||
if(pass == 0){
|
if(pass == 0){
|
||||||
//first pass: delete existing blocks - this should automatically trigger removal if overlap exists
|
//first pass: delete existing blocks - this should automatically trigger removal if overlap exists
|
||||||
|
//TODO pointless setting air to air?
|
||||||
other.setBlock(Blocks.air);
|
other.setBlock(Blocks.air);
|
||||||
}else{
|
}else{
|
||||||
//second pass: assign changed data
|
//second pass: assign changed data
|
||||||
|
Loading…
Reference in New Issue
Block a user