Allow Schematicannon to defer blocks to print at end

This commit is contained in:
reidbhuntley 2021-05-21 16:57:01 -04:00
parent ff5984a48e
commit 68b3ba7215
2 changed files with 68 additions and 28 deletions

View file

@ -34,6 +34,8 @@ import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTProcessors; import com.simibubi.create.foundation.utility.NBTProcessors;
import net.minecraft.block.AbstractRailBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.PistonHeadBlock; import net.minecraft.block.PistonHeadBlock;
@ -81,6 +83,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
STOPPED, PAUSED, RUNNING; STOPPED, PAUSED, RUNNING;
} }
public enum PrintStage {
BLOCKS, DEFERRED_BLOCKS, ENTITIES
}
// Inventory // Inventory
public SchematicannonInventory inventory; public SchematicannonInventory inventory;
@ -101,12 +107,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
private int skipsLeft; private int skipsLeft;
private boolean blockSkipped; private boolean blockSkipped;
private int printingEntityIndex; private int printingEntityIndex;
private PrintStage printStage;
public BlockPos target; public BlockPos target;
public BlockPos previousTarget; public BlockPos previousTarget;
public LinkedHashSet<LazyOptional<IItemHandler>> attachedInventories; public LinkedHashSet<LazyOptional<IItemHandler>> attachedInventories;
public List<LaunchedItem> flyingBlocks; public List<LaunchedItem> flyingBlocks;
public MaterialChecklist checklist; public MaterialChecklist checklist;
public List<BlockPos> deferredBlocks;
// Gui information // Gui information
public float fuelLevel; public float fuelLevel;
@ -144,7 +152,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
inventory = new SchematicannonInventory(this); inventory = new SchematicannonInventory(this);
statusMsg = "idle"; statusMsg = "idle";
state = State.STOPPED; state = State.STOPPED;
printingEntityIndex = -1; printingEntityIndex = 0;
printStage = PrintStage.BLOCKS;
deferredBlocks = new LinkedList<>();
replaceMode = 2; replaceMode = 2;
checklist = new MaterialChecklist(); checklist = new MaterialChecklist();
} }
@ -200,8 +210,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
replaceTileEntities = options.getBoolean("ReplaceTileEntities"); replaceTileEntities = options.getBoolean("ReplaceTileEntities");
// Printer & Flying Blocks // Printer & Flying Blocks
if (compound.contains("PrintStage"))
printStage = PrintStage.valueOf(compound.getString("PrintStage"));
if (compound.contains("Target")) if (compound.contains("Target"))
target = NBTUtil.readBlockPos(compound.getCompound("Target")); target = NBTUtil.readBlockPos(compound.getCompound("Target"));
if (compound.contains("DeferredBlocks"))
compound.getList("DeferredBlocks", 10).stream()
.map(p -> NBTUtil.readBlockPos((CompoundNBT) p))
.collect(Collectors.toCollection(() -> deferredBlocks));
if (compound.contains("FlyingBlocks")) if (compound.contains("FlyingBlocks"))
readFlyingBlocks(compound); readFlyingBlocks(compound);
@ -275,12 +291,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
compound.put("Options", options); compound.put("Options", options);
// Printer & Flying Blocks // Printer & Flying Blocks
compound.putString("PrintStage", printStage.name());
if (target != null) if (target != null)
compound.put("Target", NBTUtil.writeBlockPos(target)); compound.put("Target", NBTUtil.writeBlockPos(target));
ListNBT tagBlocks = new ListNBT();
ListNBT tagDeferredBlocks = new ListNBT();
for (BlockPos p : deferredBlocks)
tagDeferredBlocks.add(NBTUtil.writeBlockPos(p));
compound.put("DeferredBlocks", tagDeferredBlocks);
ListNBT tagFlyingBlocks = new ListNBT();
for (LaunchedItem b : flyingBlocks) for (LaunchedItem b : flyingBlocks)
tagBlocks.add(b.serializeNBT()); tagFlyingBlocks.add(b.serializeNBT());
compound.put("FlyingBlocks", tagBlocks); compound.put("FlyingBlocks", tagFlyingBlocks);
super.write(compound, clientPacket); super.write(compound, clientPacket);
} }
@ -390,7 +414,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
target = schematicAnchor.add(currentPos); target = schematicAnchor.add(currentPos);
} }
boolean entityMode = printingEntityIndex >= 0; boolean entityMode = printStage == PrintStage.ENTITIES;
// Check block // Check block
if (!getWorld().isAreaLoaded(target, 0)) { if (!getWorld().isAreaLoaded(target, 0)) {
@ -573,7 +597,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
schematicLoaded = true; schematicLoaded = true;
state = State.PAUSED; state = State.PAUSED;
statusMsg = "ready"; statusMsg = "ready";
printingEntityIndex = -1; printingEntityIndex = 0;
printStage = PrintStage.BLOCKS;
deferredBlocks.clear();
updateChecklist(); updateChecklist();
sendUpdate = true; sendUpdate = true;
blocksToPlace += blocksPlaced; blocksToPlace += blocksPlaced;
@ -659,22 +685,33 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
protected void advanceCurrentPos() { protected void advanceCurrentPos() {
List<Entity> entities = blockReader.getEntities() List<Entity> entities = blockReader.getEntities()
.collect(Collectors.toList()); .collect(Collectors.toList());
if (printingEntityIndex != -1) {
printingEntityIndex++;
// End of entities reached if (printStage == PrintStage.BLOCKS) {
if (printingEntityIndex >= entities.size()) { MutableBoundingBox bounds = blockReader.getBounds();
finishedPrinting(); while (tryAdvanceCurrentPos(bounds, entities)) {
return; deferredBlocks.add(currentPos);
} }
currentPos = entities.get(printingEntityIndex)
.getBlockPos()
.subtract(schematicAnchor);
return;
} }
MutableBoundingBox bounds = blockReader.getBounds(); if (printStage == PrintStage.DEFERRED_BLOCKS) {
if (deferredBlocks.isEmpty()) {
printStage = PrintStage.ENTITIES;
} else {
currentPos = deferredBlocks.remove(0);
}
}
if (printStage == PrintStage.ENTITIES) {
if (printingEntityIndex < entities.size()) {
currentPos = entities.get(printingEntityIndex).getBlockPos().subtract(schematicAnchor);
printingEntityIndex++;
} else {
finishedPrinting();
}
}
}
protected boolean tryAdvanceCurrentPos(MutableBoundingBox bounds, List<Entity> entities) {
currentPos = currentPos.offset(Direction.EAST); currentPos = currentPos.offset(Direction.EAST);
BlockPos posInBounds = currentPos.add(-bounds.minX, -bounds.minY, -bounds.minZ); BlockPos posInBounds = currentPos.add(-bounds.minX, -bounds.minY, -bounds.minZ);
@ -685,15 +722,16 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
// End of blocks reached // End of blocks reached
if (currentPos.getY() > bounds.getYSize()) { if (currentPos.getY() > bounds.getYSize()) {
printingEntityIndex = 0; printStage = PrintStage.DEFERRED_BLOCKS;
if (entities.isEmpty()) { return false;
finishedPrinting();
return;
}
currentPos = entities.get(0)
.getBlockPos()
.subtract(schematicAnchor);
} }
return shouldDeferBlock(blockReader.getBlockState(schematicAnchor.add(currentPos)));
}
public static boolean shouldDeferBlock(BlockState state) {
Block block = state.getBlock();
return block instanceof AbstractRailBlock || block.is(AllBlocks.GANTRY_CARRIAGE.get());
} }
public void finishedPrinting() { public void finishedPrinting() {
@ -715,10 +753,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
blockReader = null; blockReader = null;
missingItem = null; missingItem = null;
sendUpdate = true; sendUpdate = true;
printingEntityIndex = -1; printingEntityIndex = 0;
printStage = PrintStage.BLOCKS;
schematicProgress = 0; schematicProgress = 0;
blocksPlaced = 0; blocksPlaced = 0;
blocksToPlace = 0; blocksToPlace = 0;
deferredBlocks.clear();
} }
protected boolean shouldPlace(BlockPos pos, BlockState state) { protected boolean shouldPlace(BlockPos pos, BlockState state) {

View file

@ -296,7 +296,7 @@ public class BlockHelper {
return; return;
} }
if (BlockTags.RAILS.contains(state.getBlock())) { if (state.getBlock() instanceof AbstractRailBlock) {
placeRailWithoutUpdate(world, state, target); placeRailWithoutUpdate(world, state, target);
} else { } else {
world.setBlockState(target, state, 18); world.setBlockState(target, state, 18);