diff --git a/core/src/mindustry/ai/types/CommandAI.java b/core/src/mindustry/ai/types/CommandAI.java index ce0c4ed2b1..637ade5f29 100644 --- a/core/src/mindustry/ai/types/CommandAI.java +++ b/core/src/mindustry/ai/types/CommandAI.java @@ -17,7 +17,7 @@ import static mindustry.Vars.*; public class CommandAI extends AIController{ protected static final int maxCommandQueueSize = 50, avoidInterval = 10; - protected static final Vec2 vecOut = new Vec2(), vecMovePos = new Vec2(), movePos = new Vec2(); + protected static final Vec2 moveTarget = new Vec2(), offsetedDestination = new Vec2(), currentDestination = new Vec2(); protected static final UnitPayload tmpPayload = new UnitPayload(null); protected static final int transferStateNone = 0, transferStateLoad = 1, transferStateUnload = 2; @@ -276,31 +276,31 @@ public class CommandAI extends AIController{ if(targetPos != null){ boolean move = true, isFinalPoint = commandQueue.size == 0; - //workaround to let ground units pathfind into targeted solid payenter blocks - boolean isSolidPayload = false; - movePos.set(targetPos); + //actual final point that it needs to go to + currentDestination.set(targetPos); targetBuild = world.buildWorld(targetPos.x, targetPos.y); if(unit.isGrounded() && targetBuild != null && targetBuild.tile.solid() && targetBuild.block.acceptsUnitPayloads && unit.type.pathCostId != ControlPathfinder.costIdLegs && !ramming){ Tile best = targetBuild.findClosestEdge(unit, Tile::solid); if(best != null){ - movePos.set(best); - isSolidPayload = true; + currentDestination.set(best); } } - vecOut.set(movePos); - vecMovePos.set(movePos); + //target straight-line point it is currently moving to; can include pathfinding sub-waypoints + moveTarget.set(currentDestination); + //destination + formation offset + offsetedDestination.set(currentDestination); //the enter payload command requires an exact position if(group != null && group.valid && groupIndex < group.units.size && command != UnitCommand.enterPayloadCommand){ - vecMovePos.add(group.positions[groupIndex * 2], group.positions[groupIndex * 2 + 1]); + offsetedDestination.add(group.positions[groupIndex * 2], group.positions[groupIndex * 2 + 1]); } Building targetBuild = world.buildWorld(targetPos.x, targetPos.y); if( (hasStance(UnitStance.patrol) && !hasStance(UnitStance.pursueTarget) && target != null && unit.within(target, unit.type.range - 2f) && !unit.type.circleTarget) || - (command == UnitCommand.enterPayloadCommand && unit.within(movePos, 4f) || (targetBuild != null && !unit.type.circleTarget && unit.within(targetBuild, targetBuild.block.size * tilesize/2f * 0.9f))) || - (command == UnitCommand.loopPayloadCommand && unit.within(vecMovePos, 10f)) + (command == UnitCommand.enterPayloadCommand && unit.within(currentDestination, 4f) || (targetBuild != null && !unit.type.circleTarget && unit.within(targetBuild, targetBuild.block.size * tilesize/2f * 0.9f))) || + (command == UnitCommand.loopPayloadCommand && unit.within(offsetedDestination, 10f)) ){ move = false; } @@ -339,27 +339,27 @@ public class CommandAI extends AIController{ //TODO maybe stop moving too? if(withinAttackRange){ move = true; - vecOut.set(vecMovePos); + moveTarget.set(offsetedDestination); }else{ - var result = controlPath.getPathPosition(unit, movePos, isSolidPayload ? movePos : targetPos); + var result = controlPath.getPathPosition(unit, offsetedDestination, currentDestination); unreachable = result.unreachable; move &= result.move && (!blockingUnit || timeSpentBlocked > maxBlockTime); - if(result.move) vecOut.set(result.dest); + if(result.move) moveTarget.set(result.dest); //do not wiggle in place - if(unit.type.naval && result.next != null && !unit.canPass(result.next.x, result.next.y) && move && unit.tileOn() == world.tileWorld(vecOut.x, vecOut.y)){ + if(unit.type.naval && result.next != null && !unit.canPass(result.next.x, result.next.y) && move && unit.tileOn() == world.tileWorld(moveTarget.x, moveTarget.y)){ move = false; } } //rare case where unit must be perfectly aligned (happens with 1-tile gaps) - alwaysArrive = vecOut.epsilonEquals(unit.tileX() * tilesize, unit.tileY() * tilesize); + alwaysArrive = moveTarget.epsilonEquals(unit.tileX() * tilesize, unit.tileY() * tilesize); //we've reached the final point if the returned coordinate is equal to the supplied input - isFinalPoint &= vecMovePos.epsilonEquals(vecOut, 4.1f); + isFinalPoint &= offsetedDestination.epsilonEquals(moveTarget, 4.1f); //if the path is invalid, stop trying and record the end as unreachable - if(unit.team.isAI() && (unreachable || unit.isPathImpassable(World.toTile(vecMovePos.x), World.toTile(vecMovePos.y)))){ + if(unit.team.isAI() && (unreachable || unit.isPathImpassable(World.toTile(offsetedDestination.x), World.toTile(offsetedDestination.y)))){ if(attackTarget instanceof Building build){ unreachableBuildings.addUnique(build.pos()); } @@ -368,7 +368,7 @@ public class CommandAI extends AIController{ return; } }else{ - vecOut.set(vecMovePos); + moveTarget.set(offsetedDestination); } if(command == UnitCommand.loopPayloadCommand){ @@ -380,7 +380,7 @@ public class CommandAI extends AIController{ target = attackTarget; circleAttack(unit.type.circleTargetRadius); }else{ - moveTo(vecOut, + moveTo(moveTarget, withinAttackRange ? engageRange : unit.isGrounded() ? 0f : attackTarget != null && !ramming ? engageRange : 0f, @@ -394,20 +394,20 @@ public class CommandAI extends AIController{ } if(unit.isFlying() && move && !(unit.type.circleTarget && !unit.type.omniMovement) && (attackTarget == null || !unit.within(attackTarget, unit.type.range))){ - unit.lookAt(vecMovePos); + unit.lookAt(offsetedDestination); }else{ faceTarget(); } //reached destination, end pathfinding - if(attackTarget == null && (unit.within(vecMovePos, command.exactArrival && commandQueue.size == 0 ? 1f : Math.max(5f, unit.hitSize / 2f)) || + if(attackTarget == null && (unit.within(offsetedDestination, command.exactArrival && commandQueue.size == 0 ? 1f : Math.max(5f, unit.hitSize / 2f)) || //for circling units, it doesn't need to reach the exact waypoint. - (!unit.type.omniMovement && unit.type.flying && !unit.type.rotateMoveFirst && !command.exactArrival && Angles.angleDist(unit.angleTo(vecMovePos), unit.rotation) > 60f && - unit.within(vecMovePos, Math.min(50f, 360f / unit.type.rotateSpeed * unit.type.speed / (Mathf.pi * 2f)))))){ + (!unit.type.omniMovement && unit.type.flying && !unit.type.rotateMoveFirst && !command.exactArrival && Angles.angleDist(unit.angleTo(offsetedDestination), unit.rotation) > 60f && + unit.within(offsetedDestination, Math.min(50f, 360f / unit.type.rotateSpeed * unit.type.speed / (Mathf.pi * 2f)))))){ finishPath(); } - if(stopWhenInRange && targetPos != null && unit.within(vecMovePos, engageRange * 0.9f)){ + if(stopWhenInRange && targetPos != null && unit.within(offsetedDestination, engageRange * 0.9f)){ finishPath(); stopWhenInRange = false; } diff --git a/core/src/mindustry/entities/comp/MinerComp.java b/core/src/mindustry/entities/comp/MinerComp.java index d39c920c9e..85230def1b 100644 --- a/core/src/mindustry/entities/comp/MinerComp.java +++ b/core/src/mindustry/entities/comp/MinerComp.java @@ -85,10 +85,11 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{ mineTile = null; mineTimer = 0f; }else if(mining() && item != null){ - mineTimer += Time.delta * type.mineSpeed * state.rules.unitMineSpeed(team()); + float rate = Time.delta * type.mineSpeed * state.rules.unitMineSpeed(team()); + mineTimer += rate; - if(Mathf.chance(0.08 * Time.delta)){ - Fx.unitMine.at(mineTile.worldx() + Mathf.range(tilesize / 2f), mineTile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color); + if(Mathf.chance(0.035f * rate)){ + Fx.unitMine.at(mineTile.worldx() + Mathf.range(2f), mineTile.worldy() + Mathf.range(2f), 0f, item.color); } if(mineTimer >= 50f + (type.mineHardnessScaling ? item.hardness*15f : 15f)){ diff --git a/gradle.properties b/gradle.properties index 5314e27e02..bbd44e58a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=c4c3707ae8 +archash=3eb7d633a3