Fix some bugs with schematics

This commit is contained in:
Logan Darklock 2019-09-03 08:35:16 -07:00
parent 1413bd2f05
commit 991283182c
No known key found for this signature in database
GPG Key ID: B8C37CEDE1AC60EA
10 changed files with 128 additions and 29 deletions

View File

@ -1,13 +1,30 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractSchematic implements ISchematic { public abstract class AbstractSchematic implements ISchematic {
protected final IBaritone baritone;
protected final IPlayerContext ctx;
protected int x; protected int x;
protected int y; protected int y;
protected int z; protected int z;
public AbstractSchematic(int x, int y, int z) { public AbstractSchematic(@Nullable IBaritone baritone, int x, int y, int z) {
this.baritone = baritone;
this.ctx = baritone == null ? null : baritone.getPlayerContext();
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -27,4 +44,33 @@ public abstract class AbstractSchematic implements ISchematic {
public int lengthZ() { public int lengthZ() {
return z; return z;
} }
protected IBlockState[] approxPlaceable() {
EntityPlayerSP player = ctx.player();
NonNullList<ItemStack> inventory = player.inventory.mainInventory;
List<IBlockState> placeable = new ArrayList<>();
placeable.add(Blocks.AIR.getDefaultState());
// 27 + 9
for (int i = 0; i < 36; i++) {
ItemStack stack = inventory.get(i);
if (!stack.isEmpty() && stack.getItem() instanceof ItemBlock) {
// <toxic cloud>
placeable.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(
ctx.world(),
ctx.playerFeet(),
EnumFacing.UP,
(float) player.posX,
(float) player.posY,
(float) player.posZ,
stack.getItem().getMetadata(stack.getMetadata()),
player
));
// </toxic cloud>
}
}
return placeable.toArray(new IBlockState[0]);
}
} }

View File

@ -1,5 +1,6 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
@ -20,8 +21,8 @@ public class CompositeSchematic extends AbstractSchematic {
} }
} }
public CompositeSchematic(int x, int y, int z) { public CompositeSchematic(IBaritone baritone, int x, int y, int z) {
super(x, y, z); super(baritone, x, y, z);
schematics = new ArrayList<>(); schematics = new ArrayList<>();
recalcArr(); recalcArr();
} }

View File

@ -1,13 +1,15 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.BlockOptionalMeta; import baritone.api.utils.BlockOptionalMeta;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
public class FillBomSchematic extends AbstractSchematic { public class FillBomSchematic extends AbstractSchematic {
private final BlockOptionalMeta bom; private final BlockOptionalMeta bom;
public FillBomSchematic(int x, int y, int z, BlockOptionalMeta bom) { public FillBomSchematic(IBaritone baritone, int x, int y, int z, BlockOptionalMeta bom) {
super(x, y, z); super(baritone, x, y, z);
this.bom = bom; this.bom = bom;
} }
@ -19,8 +21,16 @@ public class FillBomSchematic extends AbstractSchematic {
public IBlockState desiredState(int x, int y, int z, IBlockState current) { public IBlockState desiredState(int x, int y, int z, IBlockState current) {
if (bom.matches(current)) { if (bom.matches(current)) {
return current; return current;
} else if (current.getBlock() != Blocks.AIR) {
return Blocks.AIR.getDefaultState();
} }
return bom.getAnyBlockState(); for (IBlockState placeable : approxPlaceable()) {
if (bom.matches(placeable)) {
return placeable;
}
}
throw new IllegalStateException("Couldn't find desired state");
} }
} }

View File

@ -1,13 +1,14 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
public abstract class MaskSchematic extends AbstractSchematic { public abstract class MaskSchematic extends AbstractSchematic {
private final ISchematic schematic; private final ISchematic schematic;
public MaskSchematic(ISchematic schematic) { public MaskSchematic(IBaritone baritone, ISchematic schematic) {
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ()); super(baritone, schematic.widthX(), schematic.heightY(), schematic.lengthZ());
this.schematic = schematic; this.schematic = schematic;
} }

View File

@ -0,0 +1,21 @@
package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
public class ReplaceSchematic extends MaskSchematic {
private final BlockOptionalMetaLookup filter;
private final boolean[][][] cache;
public ReplaceSchematic(IBaritone baritone, ISchematic schematic, BlockOptionalMetaLookup filter) {
super(baritone, schematic);
this.filter = filter;
this.cache = new boolean[lengthZ()][heightY()][widthX()];
}
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return cache[x][y][z] || (cache[x][y][z] = filter.has(currentState));
}
}

View File

@ -1,11 +1,12 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
public class ShellSchematic extends MaskSchematic { public class ShellSchematic extends MaskSchematic {
public ShellSchematic(ISchematic schematic) { public ShellSchematic(IBaritone baritone, ISchematic schematic) {
super(schematic); super(baritone, schematic);
} }
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {

View File

@ -1,11 +1,12 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.IBaritone;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
public class WallsSchematic extends MaskSchematic { public class WallsSchematic extends MaskSchematic {
public WallsSchematic(ISchematic schematic) { public WallsSchematic(IBaritone baritone, ISchematic schematic) {
super(schematic); super(baritone, schematic);
} }
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {

View File

@ -322,12 +322,4 @@ public final class BlockOptionalMeta {
//noinspection deprecation //noinspection deprecation
return Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getMetadata()); return Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getMetadata());
} }
public IBlockState getAnyBlockState() {
if (blockstates.size() > 0) {
return blockstates.iterator().next();
}
return null;
}
} }

View File

@ -21,12 +21,14 @@ import baritone.api.Settings;
import baritone.api.event.events.RenderEvent; import baritone.api.event.events.RenderEvent;
import baritone.api.schematic.CompositeSchematic; import baritone.api.schematic.CompositeSchematic;
import baritone.api.schematic.FillBomSchematic; import baritone.api.schematic.FillBomSchematic;
import baritone.api.schematic.ReplaceSchematic;
import baritone.api.schematic.ShellSchematic; import baritone.api.schematic.ShellSchematic;
import baritone.api.schematic.WallsSchematic; import baritone.api.schematic.WallsSchematic;
import baritone.api.selection.ISelection; import baritone.api.selection.ISelection;
import baritone.api.selection.ISelectionManager; import baritone.api.selection.ISelectionManager;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.BlockOptionalMeta; import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.IRenderer; import baritone.api.utils.IRenderer;
import baritone.api.utils.ISchematic; import baritone.api.utils.ISchematic;
import baritone.api.utils.command.Command; import baritone.api.utils.command.Command;
@ -43,6 +45,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -104,11 +107,26 @@ public class SelCommand extends Command {
logDirect("Undid pos2"); logDirect("Undid pos2");
} }
} }
} else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA) { } else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) {
BlockOptionalMeta type = action == Action.CLEARAREA BlockOptionalMeta type = action == Action.CLEARAREA
? new BlockOptionalMeta(Blocks.AIR) ? new BlockOptionalMeta(Blocks.AIR)
: args.getDatatypeFor(ForBlockOptionalMeta.class); : args.getDatatypeFor(ForBlockOptionalMeta.class);
args.requireMax(0); BlockOptionalMetaLookup replaces = null;
if (action == Action.REPLACE) {
args.requireMin(1);
List<BlockOptionalMeta> replacesList = new ArrayList<>();
while (args.has()) {
replacesList.add(args.getDatatypeFor(ForBlockOptionalMeta.class));
}
replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0]));
} else {
args.requireMax(0);
}
ISelection[] selections = manager.getSelections(); ISelection[] selections = manager.getSelections();
if (selections.length == 0) { if (selections.length == 0) {
@ -116,7 +134,7 @@ public class SelCommand extends Command {
} }
BetterBlockPos origin = selections[0].min(); BetterBlockPos origin = selections[0].min();
CompositeSchematic composite = new CompositeSchematic(0, 0, 0); CompositeSchematic composite = new CompositeSchematic(baritone, 0, 0, 0);
for (ISelection selection : selections) { for (ISelection selection : selections) {
BetterBlockPos min = selection.min(); BetterBlockPos min = selection.min();
@ -131,12 +149,14 @@ public class SelCommand extends Command {
Vec3i size = selection.size(); Vec3i size = selection.size();
BetterBlockPos min = selection.min(); BetterBlockPos min = selection.min();
ISchematic schematic = new FillBomSchematic(size.getX(), size.getY(), size.getZ(), type); ISchematic schematic = new FillBomSchematic(baritone, size.getX(), size.getY(), size.getZ(), type);
if (action == Action.WALLS) { if (action == Action.WALLS) {
schematic = new WallsSchematic(schematic); schematic = new WallsSchematic(baritone, schematic);
} else if (action == Action.SHELL) { } else if (action == Action.SHELL) {
schematic = new ShellSchematic(schematic); schematic = new ShellSchematic(baritone, schematic);
} else if (action == Action.REPLACE) {
schematic = new ReplaceSchematic(baritone, schematic, replaces);
} }
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z); composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
@ -193,8 +213,12 @@ public class SelCommand extends Command {
if (args.hasAtMost(3)) { if (args.hasAtMost(3)) {
return args.tabCompleteDatatype(RelativeBlockPos.class); return args.tabCompleteDatatype(RelativeBlockPos.class);
} }
} else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA) { } else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA || action == Action.REPLACE) {
if (args.hasExactlyOne()) { if (args.hasExactlyOne() || action == Action.REPLACE) {
while (args.has(2)) {
args.get();
}
return args.tabCompleteDatatype(ForBlockOptionalMeta.class); return args.tabCompleteDatatype(ForBlockOptionalMeta.class);
} }
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) { } else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
@ -239,6 +263,7 @@ public class SelCommand extends Command {
"> sel walls/w [block] - Fill in the walls of the selection with a specified block.", "> sel walls/w [block] - Fill in the walls of the selection with a specified block.",
"> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.", "> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.",
"> sel cleararea/ca - Basically 'set air'.", "> sel cleararea/ca - Basically 'set air'.",
"> sel replace/r <place> <break...> - Replaces, with 'place', all blocks listed after it.",
"", "",
"> sel expand <target> <direction> <blocks> - Expand the targets.", "> sel expand <target> <direction> <blocks> - Expand the targets.",
"> sel contract <target> <direction> <blocks> - Contract the targets.", "> sel contract <target> <direction> <blocks> - Contract the targets.",
@ -257,6 +282,7 @@ public class SelCommand extends Command {
WALLS("walls", "w"), WALLS("walls", "w"),
SHELL("shell", "shl"), SHELL("shell", "shl"),
CLEARAREA("cleararea", "ca"), CLEARAREA("cleararea", "ca"),
REPLACE("replace", "r"),
EXPAND("expand", "ex"), EXPAND("expand", "ex"),
CONTRACT("contract", "ct"), CONTRACT("contract", "ct"),

View File

@ -522,7 +522,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
int blockX = x + origin.getX(); int blockX = x + origin.getX();
int blockY = y + origin.getY(); int blockY = y + origin.getY();
int blockZ = z + origin.getZ(); int blockZ = z + origin.getZ();
IBlockState current = bcc.bsi.get0(x, y, z); IBlockState current = bcc.bsi.get0(blockX, blockY, blockZ);
if (!schematic.inSchematic(x, y, z, current)) { if (!schematic.inSchematic(x, y, z, current)) {
continue; continue;
} }