Fixed plans being canceled by blocked units

This commit is contained in:
Anuken
2024-10-30 19:17:36 -04:00
parent 1558783b7d
commit 1d68f99c75
5 changed files with 48 additions and 29 deletions

View File

@@ -977,7 +977,7 @@ public class Blocks{
consumeItems(with(Items.thorium, 4, Items.sand, 10));
consumePower(5f);
itemCapacity = 20;
itemCapacity = 30;
}};
surgeSmelter = new GenericCrafter("surge-smelter"){{

View File

@@ -63,7 +63,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
Tile tile = world.tile(plan.x, plan.y);
boolean isSameDerelict = (tile != null && tile.build != null && tile.block() == plan.block && tile.build.tileX() == plan.x && tile.build.tileY() == plan.y && tile.team() == Team.derelict);
if(tile == null || (plan.breaking && tile.block() == Blocks.air) || (!plan.breaking && ((tile.build != null && tile.build.rotation == plan.rotation && !isSameDerelict) || !plan.block.rotate) &&
//th block must be the same, but not derelict and the same
//the block must be the same, but not derelict and the same
((tile.block() == plan.block && !isSameDerelict) ||
//same floor or overlay
(plan.block != null && (plan.block.isOverlay() && plan.block == tile.overlay() || (plan.block.isFloor() && plan.block == tile.floor())))))){
@@ -137,24 +137,31 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
}
if(!(tile.build instanceof ConstructBuild cb)){
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){
boolean hasAll = infinite || current.isRotation(team) ||
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation, true)){
if(Build.checkNoUnitOverlap(current.block, current.x, current.y)){
boolean hasAll = infinite || current.isRotation(team) ||
//derelict repair
(tile.team() == Team.derelict && tile.block() == current.block && tile.build != null && tile.block().allowDerelictRepair && state.rules.derelictRepair) ||
//make sure there's at least 1 item of each type first
!Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item, Math.min(Mathf.round(i.amount * state.rules.buildCostMultiplier), 1)));
if(hasAll){
Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation);
if(hasAll){
Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation);
if(current.block.instantBuild){
if(plans.size > 0){
plans.removeFirst();
if(current.block.instantBuild){
if(plans.size > 0){
plans.removeFirst();
}
continue;
}
continue;
}else{
current.stuck = true;
}
}else{
current.stuck = true;
//there's a unit blocking the plan, skip it
plans.removeFirst();
plans.addLast(current);
continue;
}
}else if(!current.initialized && current.breaking && Build.validBreak(team, current.x, current.y)){
Call.beginBreak(self(), team, current.x, current.y);

View File

@@ -827,15 +827,18 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
if(player.isBuilder()){
if(player.unit() != lastUnit && player.unit().plans.size <= 1){
player.unit().plans.ensureCapacity(lastPlans.size);
var playerPlans = player.unit().plans;
if(player.unit() != lastUnit && playerPlans.size <= 1){
playerPlans.ensureCapacity(lastPlans.size);
for(var plan : lastPlans){
player.unit().plans.addLast(plan);
playerPlans.addLast(plan);
}
}
lastPlans.clear();
for(var plan : player.unit().plans){
lastPlans.addLast(plan);
if(lastPlans.size != playerPlans.size || (lastPlans.size > 0 && playerPlans.size > 0 && lastPlans.first() != playerPlans.first())){
lastPlans.clear();
for(var plan : playerPlans){
lastPlans.addLast(plan);
}
}
}
@@ -1465,7 +1468,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
protected void flushSelectPlans(Seq<BuildPlan> plans){
for(BuildPlan plan : plans){
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation)){
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation, null, true)){
BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null);
if(other == null){
selectPlans.add(plan.copy());
@@ -1481,7 +1484,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//reversed iteration.
for(int i = plans.size - 1; i >= 0; i--){
var plan = plans.get(i);
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation)){
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation, null, true)){
BuildPlan copy = plan.copy();
plan.block.onNewPlan(copy);
player.unit().addBuild(copy, false);
@@ -1491,7 +1494,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
protected void flushPlans(Seq<BuildPlan> plans){
for(var plan : plans){
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation)){
if(plan.block != null && validPlace(plan.x, plan.y, plan.block, plan.rotation, null, true)){
BuildPlan copy = plan.copy();
plan.block.onNewPlan(copy);
player.unit().addBuild(copy);
@@ -1988,8 +1991,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public boolean validPlace(int x, int y, Block type, int rotation){
return validPlace(x, y, type, rotation, null);
}
public boolean validPlace(int x, int y, Block type, int rotation, @Nullable BuildPlan ignore){
return validPlace(x, y, type, rotation, ignore, false);
}
public boolean validPlace(int x, int y, Block type, int rotation, BuildPlan ignore){
public boolean validPlace(int x, int y, Block type, int rotation, @Nullable BuildPlan ignore, boolean ignoreUnits){
if(player.unit().plans.size > 0){
Tmp.r1.setCentered(x * tilesize + type.offset, y * tilesize + type.offset, type.size * tilesize);
plansOut.clear();
@@ -2006,7 +2012,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
}
return Build.validPlace(type, player.team(), x, y, rotation);
return ignoreUnits ? Build.validPlaceIgnoreUnits(type, player.team(), x, y, rotation, true) : Build.validPlace(type, player.team(), x, y, rotation);
}
public boolean validBreak(int x, int y){

View File

@@ -234,7 +234,7 @@ public class MobileInput extends InputHandler implements GestureListener{
//actually place/break all selected blocks
if(tile != null){
if(!plan.breaking){
if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){
if(validPlace(plan.x, plan.y, plan.block, plan.rotation, null, true)){
BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null);
BuildPlan copy = plan.copy();

View File

@@ -157,22 +157,28 @@ public class Build{
result.placeBegan(tile, previous, unit);
}
/** Returns whether a tile can be placed at this location by this team. */
/** @return whether a tile can be placed at this location by this team. */
public static boolean validPlace(Block type, Team team, int x, int y, int rotation){
return validPlace(type, team, x, y, rotation, true);
}
/** Returns whether a tile can be placed at this location by this team. */
/** @return whether a tile can be placed at this location by this team. */
public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
return validPlaceIgnoreUnits(type, team, x, y, rotation, checkVisible) && checkNoUnitOverlap(type, x, y);
}
/** @return whether a tile can be placed at this location by this team. */
public static boolean checkNoUnitOverlap(Block type, int x, int y){
return (!type.solid && !type.solidifes) || !Units.anyEntities(x * tilesize + type.offset - type.size * tilesize / 2f, y * tilesize + type.offset - type.size * tilesize / 2f, type.size * tilesize, type.size * tilesize);
}
/** Returns whether a tile can be placed at this location by this team. Ignores units at this location. */
public static boolean validPlaceIgnoreUnits(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
//the wave team can build whatever they want as long as it's visible - banned blocks are not applicable
if(type == null || (!state.rules.editor && (checkVisible && (!type.environmentBuildable() || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible())))))){
return false;
}
if((type.solid || type.solidifes) && Units.anyEntities(x * tilesize + type.offset - type.size*tilesize/2f, y * tilesize + type.offset - type.size*tilesize/2f, type.size * tilesize, type.size*tilesize)){
return false;
}
if(!state.rules.editor){
//find closest core, if it doesn't match the team, placing is not legal
if(state.rules.polygonCoreProtection){