mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-14 09:47:24 +07:00
Bugfixes
This commit is contained in:
@ -17,7 +17,7 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Pathfinder implements Runnable{
|
||||
private static final long maxUpdate = Time.millisToNanos(4);
|
||||
private static final long maxUpdate = Time.millisToNanos(6);
|
||||
private static final int updateFPS = 60;
|
||||
private static final int updateInterval = 1000 / updateFPS;
|
||||
private static final int impassable = -1;
|
||||
@ -37,6 +37,7 @@ public class Pathfinder implements Runnable{
|
||||
private ObjectMap<Position, PathTarget> targetCache = new ObjectMap<>();
|
||||
/** Current pathfinding thread */
|
||||
private @Nullable Thread thread;
|
||||
private IntArray tmpArray = new IntArray();
|
||||
|
||||
public Pathfinder(){
|
||||
Events.on(WorldLoadEvent.class, event -> {
|
||||
@ -198,14 +199,20 @@ public class Pathfinder implements Runnable{
|
||||
if(target.refreshRate() > 0 && Time.timeSinceMillis(data.lastUpdateTime) > target.refreshRate()){
|
||||
data.lastUpdateTime = Time.millis();
|
||||
|
||||
tmpArray.clear();
|
||||
data.target.getPositions(data.team, tmpArray);
|
||||
|
||||
synchronized(data.targets){
|
||||
//make sure the position actually changed
|
||||
if(!(data.targets.size == 1 && tmpArray.size == 1 && data.targets.first() == tmpArray.first())){
|
||||
data.targets.clear();
|
||||
data.target.getPositions(data.team, data.targets);
|
||||
}
|
||||
|
||||
//queue an update
|
||||
queue.post(() -> updateTargets(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int[][] values = data.weights;
|
||||
int value = values[tile.x][tile.y];
|
||||
@ -279,7 +286,7 @@ public class Pathfinder implements Runnable{
|
||||
int tx = Point2.x(pos), ty = Point2.y(pos);
|
||||
|
||||
path.weights[tx][ty] = 0;
|
||||
path.searches[tx][ty] = (short)path.search;
|
||||
path.searches[tx][ty] = path.search;
|
||||
path.frontier.addFirst(pos);
|
||||
}
|
||||
}
|
||||
@ -417,7 +424,7 @@ public class Pathfinder implements Runnable{
|
||||
|
||||
@Override
|
||||
public int refreshRate(){
|
||||
return 1000 * 2;
|
||||
return 900;
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,7 +444,7 @@ public class Pathfinder implements Runnable{
|
||||
/** costs of getting to a specific tile */
|
||||
final int[][] weights;
|
||||
/** search IDs of each position - the highest, most recent search is prioritized and overwritten */
|
||||
final short[][] searches;
|
||||
final int[][] searches;
|
||||
/** search frontier, these are Pos objects */
|
||||
final IntQueue frontier = new IntQueue();
|
||||
/** all target positions; these positions have a cost of 0, and must be synchronized on! */
|
||||
@ -452,7 +459,7 @@ public class Pathfinder implements Runnable{
|
||||
this.target = target;
|
||||
|
||||
this.weights = new int[width][height];
|
||||
this.searches = new short[width][height];
|
||||
this.searches = new int[width][height];
|
||||
this.frontier.ensureCapacity((width + height) * 3);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,11 @@ public class FormationAI extends AIController implements FormationMember{
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(leader.dead()){
|
||||
unit.resetController();
|
||||
return;
|
||||
}
|
||||
|
||||
unit.controlWeapons(leader.isRotate(), leader.isShooting());
|
||||
// unit.moveAt(Tmp.v1.set(deltaX, deltaY).limit(unit.type().speed));
|
||||
if(leader.isShooting()){
|
||||
@ -45,6 +50,11 @@ public class FormationAI extends AIController implements FormationMember{
|
||||
unit.moveAt(realtarget.sub(unit).limit(unit.type().speed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Unitc unit){
|
||||
formation.removeMember(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeingControlled(Unitc player){
|
||||
return leader == player;
|
||||
|
@ -71,6 +71,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
return controller;
|
||||
}
|
||||
|
||||
public void resetController(){
|
||||
controller(type.createController());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(UnitType def, UnitController controller){
|
||||
type(type);
|
||||
@ -125,6 +129,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
@Override
|
||||
public void remove(){
|
||||
teamIndex.updateCount(team(), -1);
|
||||
controller.removed(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,6 +15,10 @@ public interface UnitController{
|
||||
|
||||
}
|
||||
|
||||
default void removed(Unitc unit){
|
||||
|
||||
}
|
||||
|
||||
default boolean isBeingControlled(Unitc player){
|
||||
return false;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ public enum Binding implements KeyBind{
|
||||
pickupCargo(KeyCode.leftBracket),
|
||||
dropCargo(KeyCode.rightBracket),
|
||||
|
||||
command(KeyCode.g),
|
||||
|
||||
clear_building(KeyCode.q),
|
||||
pause_building(KeyCode.e),
|
||||
rotate(new Axis(KeyCode.scroll)),
|
||||
|
@ -4,7 +4,6 @@ import arc.*;
|
||||
import arc.Graphics.*;
|
||||
import arc.Graphics.Cursor.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.scene.*;
|
||||
@ -211,31 +210,6 @@ public class DesktopInput extends InputHandler{
|
||||
Call.onUnitClear(player);
|
||||
controlledType = null;
|
||||
}
|
||||
|
||||
//TODO this is for debugging, remove later
|
||||
if(Core.input.keyTap(KeyCode.g) && !player.dead() && player.unit() instanceof Commanderc){
|
||||
Commanderc commander = (Commanderc)player.unit();
|
||||
|
||||
if(commander.isCommanding()){
|
||||
commander.clearCommand();
|
||||
}else{
|
||||
|
||||
FormationPattern pattern = new SquareFormation();
|
||||
Formation formation = new Formation(new Vec3(player.x(), player.y(), player.unit().rotation()), pattern);
|
||||
formation.slotAssignmentStrategy = new DistanceAssignmentStrategy(pattern);
|
||||
|
||||
units.clear();
|
||||
|
||||
Fx.commandSend.at(player);
|
||||
Units.nearby(player.team(), player.x(), player.y(), 200f, u -> {
|
||||
if(u.isAI()){
|
||||
units.add(u);
|
||||
}
|
||||
});
|
||||
|
||||
commander.command(formation, units);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
|
||||
@ -628,5 +602,33 @@ public class DesktopInput extends InputHandler{
|
||||
pay.dropLastPayload();
|
||||
}
|
||||
}
|
||||
|
||||
if(unit instanceof Commanderc){
|
||||
Commanderc commander = (Commanderc)unit;
|
||||
|
||||
if(Core.input.keyTap(Binding.command)){
|
||||
if(commander.isCommanding()){
|
||||
commander.clearCommand();
|
||||
}else{
|
||||
FormationPattern pattern = new SquareFormation();
|
||||
Formation formation = new Formation(new Vec3(player.x(), player.y(), player.unit().rotation()), pattern);
|
||||
formation.slotAssignmentStrategy = new DistanceAssignmentStrategy(pattern);
|
||||
|
||||
units.clear();
|
||||
|
||||
Fx.commandSend.at(player);
|
||||
Units.nearby(player.team(), player.x(), player.y(), 200f, u -> {
|
||||
if(u.isAI()){
|
||||
units.add(u);
|
||||
}
|
||||
});
|
||||
|
||||
units.sort(u -> u.dst2(player.unit()));
|
||||
units.truncate(unit.type().commandLimit);
|
||||
|
||||
commander.command(formation, units);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ public class UnitType extends UnlockableContent{
|
||||
public boolean canBoost = false;
|
||||
public float sway = 1f;
|
||||
public int payloadCapacity = 1;
|
||||
public int commandLimit = 24;
|
||||
|
||||
public int legCount = 4;
|
||||
public float legLength = 24f, legSpeed = 0.1f, legTrns = 1f;
|
||||
|
Reference in New Issue
Block a user