traverse block placing and rendering
This commit is contained in:
parent
0fd11f80f5
commit
4caf6a8265
@ -46,7 +46,7 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
* @param forced Whether or not the state is being forced
|
* @param forced Whether or not the state is being forced
|
||||||
*/
|
*/
|
||||||
public final void setInputForceState(Input input, boolean forced) {
|
public final void setInputForceState(Input input, boolean forced) {
|
||||||
if(!forced)
|
if (!forced)
|
||||||
System.out.println(input);
|
System.out.println(input);
|
||||||
inputForceStateMap.put(input.getKeyBinding(), forced);
|
inputForceStateMap.put(input.getKeyBinding(), forced);
|
||||||
}
|
}
|
||||||
@ -108,7 +108,13 @@ public final class InputOverrideHandler implements Helper {
|
|||||||
/**
|
/**
|
||||||
* The jump input
|
* The jump input
|
||||||
*/
|
*/
|
||||||
JUMP(mc.gameSettings.keyBindJump);
|
JUMP(mc.gameSettings.keyBindJump),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sneak input
|
||||||
|
*/
|
||||||
|
SNEAK(mc.gameSettings.keyBindSneak);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual game {@link KeyBinding} being forced.
|
* The actual game {@link KeyBinding} being forced.
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +42,7 @@ public class PathingBehavior extends Behavior {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
if(event.getType() == TickEvent.Type.OUT || current == null) {
|
if (event.getType() == TickEvent.Type.OUT || current == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
current.onTick(event);
|
current.onTick(event);
|
||||||
@ -137,6 +137,14 @@ public class PathingBehavior extends Behavior {
|
|||||||
|
|
||||||
// Render the current path, if there is one
|
// Render the current path, if there is one
|
||||||
getPath().ifPresent(path -> drawPath(path, player(), partialTicks, Color.RED));
|
getPath().ifPresent(path -> drawPath(path, player(), partialTicks, Color.RED));
|
||||||
|
getPath().ifPresent(path -> {
|
||||||
|
for (BlockPos pos : path.getBlocksToBreak()) {
|
||||||
|
drawSelectionBox(player(), pos, partialTicks, Color.RED);
|
||||||
|
}
|
||||||
|
for (BlockPos pos : path.getBlocksToPlace()) {
|
||||||
|
drawSelectionBox(player(), pos, partialTicks, Color.GREEN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// If there is a path calculation currently running, render the path calculation process
|
// If there is a path calculation currently running, render the path calculation process
|
||||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(currentlyRunning -> {
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(currentlyRunning -> {
|
||||||
|
@ -5,8 +5,10 @@ import baritone.bot.pathing.movement.Movement;
|
|||||||
import baritone.bot.pathing.path.IPath;
|
import baritone.bot.pathing.path.IPath;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node based implementation of IPath
|
* A node based implementation of IPath
|
||||||
@ -113,16 +115,6 @@ class Path implements IPath {
|
|||||||
return Collections.unmodifiableList(path);
|
return Collections.unmodifiableList(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<BlockPos> getBlocksToBreak() {
|
|
||||||
return movements.stream().map(move -> move.positionsToBreak).flatMap(Arrays::stream).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<BlockPos> getBlocksToPlace() {
|
|
||||||
return movements.stream().map(move -> move.positionsToPlace).flatMap(Arrays::stream).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNumNodesConsidered() {
|
public int getNumNodesConsidered() {
|
||||||
return numNodes;
|
return numNodes;
|
||||||
|
@ -6,11 +6,12 @@ import baritone.bot.behavior.impl.LookBehaviorUtils;
|
|||||||
import baritone.bot.pathing.movement.MovementState.MovementStatus;
|
import baritone.bot.pathing.movement.MovementState.MovementStatus;
|
||||||
import baritone.bot.utils.BlockStateInterface;
|
import baritone.bot.utils.BlockStateInterface;
|
||||||
import baritone.bot.utils.Helper;
|
import baritone.bot.utils.Helper;
|
||||||
|
import baritone.bot.utils.Rotation;
|
||||||
import baritone.bot.utils.ToolSet;
|
import baritone.bot.utils.ToolSet;
|
||||||
import baritone.bot.utils.*;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static baritone.bot.InputOverrideHandler.Input;
|
import static baritone.bot.InputOverrideHandler.Input;
|
||||||
@ -131,7 +132,7 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (BlockPos blockPos : positionsToBreak) {
|
for (BlockPos blockPos : positionsToBreak) {
|
||||||
if(!MovementHelper.canWalkThrough(blockPos, BlockStateInterface.get(blockPos))) {
|
if (!MovementHelper.canWalkThrough(blockPos, BlockStateInterface.get(blockPos))) {
|
||||||
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
||||||
if (reachable.isPresent()) {
|
if (reachable.isPresent()) {
|
||||||
state.setTarget(new MovementState.MovementTarget(reachable.get())).setInput(Input.CLICK_LEFT, true);
|
state.setTarget(new MovementState.MovementTarget(reachable.get())).setInput(Input.CLICK_LEFT, true);
|
||||||
@ -185,4 +186,24 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<BlockPos> toBreak() {
|
||||||
|
ArrayList<BlockPos> result = new ArrayList<>();
|
||||||
|
for (BlockPos positionsToBreak1 : positionsToBreak) {
|
||||||
|
if (!MovementHelper.canWalkThrough(positionsToBreak1, BlockStateInterface.get(positionsToBreak1))) {
|
||||||
|
result.add(positionsToBreak1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<BlockPos> toPlace() {
|
||||||
|
ArrayList<BlockPos> result = new ArrayList<>();
|
||||||
|
for (BlockPos positionsToPlace1 : positionsToPlace) {
|
||||||
|
if (!MovementHelper.canWalkOn(positionsToPlace1)) {
|
||||||
|
result.add(positionsToPlace1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,17 @@ import baritone.bot.utils.ToolSet;
|
|||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,6 +88,10 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return state.isBlockNormalCube() && !BlockStateInterface.isLava(block);
|
return state.isBlockNormalCube() && !BlockStateInterface.isLava(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean canWalkOn(BlockPos pos) {
|
||||||
|
return canWalkOn(pos, BlockStateInterface.get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static boolean canFall(BlockPos pos) {
|
static boolean canFall(BlockPos pos) {
|
||||||
return BlockStateInterface.get(pos).getBlock() instanceof BlockFalling;
|
return BlockStateInterface.get(pos).getBlock() instanceof BlockFalling;
|
||||||
@ -144,4 +154,31 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
|
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
|
||||||
mc.player.inventory.currentItem = ts.getBestSlot(b);
|
mc.player.inventory.currentItem = ts.getBestSlot(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean switchtothrowaway() {
|
||||||
|
List<Item> ACCEPTABLE_THROWAWAY_ITEMS = Arrays.asList(new Item[]{Item.getByNameOrId("minecraft:dirt"), Item.getByNameOrId("minecraft:cobblestone")});
|
||||||
|
EntityPlayerSP p = Minecraft.getMinecraft().player;
|
||||||
|
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||||
|
for (byte i = 0; i < 9; i++) {
|
||||||
|
ItemStack item = inv.get(i);
|
||||||
|
if (ACCEPTABLE_THROWAWAY_ITEMS.contains(item.getItem())) {
|
||||||
|
p.inventory.currentItem = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean hasthrowaway() {
|
||||||
|
List<Item> ACCEPTABLE_THROWAWAY_ITEMS = Arrays.asList(new Item[]{Item.getByNameOrId("minecraft:dirt"), Item.getByNameOrId("minecraft:cobblestone")});
|
||||||
|
EntityPlayerSP p = Minecraft.getMinecraft().player;
|
||||||
|
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||||
|
for (byte i = 0; i < 9; i++) {
|
||||||
|
ItemStack item = inv.get(i);
|
||||||
|
if (ACCEPTABLE_THROWAWAY_ITEMS.contains(item.getItem())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package baritone.bot.pathing.movement.movements;
|
package baritone.bot.pathing.movement.movements;
|
||||||
|
|
||||||
import baritone.bot.InputOverrideHandler;
|
import baritone.bot.InputOverrideHandler;
|
||||||
|
import baritone.bot.behavior.impl.LookBehaviorUtils;
|
||||||
import baritone.bot.pathing.movement.Movement;
|
import baritone.bot.pathing.movement.Movement;
|
||||||
import baritone.bot.pathing.movement.MovementHelper;
|
import baritone.bot.pathing.movement.MovementHelper;
|
||||||
import baritone.bot.pathing.movement.MovementState;
|
import baritone.bot.pathing.movement.MovementState;
|
||||||
@ -14,7 +15,11 @@ import net.minecraft.block.BlockVine;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MovementTraverse extends Movement {
|
public class MovementTraverse extends Movement {
|
||||||
|
|
||||||
@ -56,10 +61,6 @@ public class MovementTraverse extends Movement {
|
|||||||
//Out.log("Can't walk through " + blocksToBreak[0] + " (hardness" + hardness1 + ") or " + blocksToBreak[1] + " (hardness " + hardness2 + ")");
|
//Out.log("Can't walk through " + blocksToBreak[0] + " (hardness" + hardness1 + ") or " + blocksToBreak[1] + " (hardness " + hardness2 + ")");
|
||||||
return WC + getTotalHardnessOfBlocksToBreak(ts);
|
return WC + getTotalHardnessOfBlocksToBreak(ts);
|
||||||
} else {//this is a bridge, so we need to place a block
|
} else {//this is a bridge, so we need to place a block
|
||||||
if (true) {
|
|
||||||
System.out.println(src + " " + dest);
|
|
||||||
return COST_INF;//TODO
|
|
||||||
}
|
|
||||||
//return 1000000;
|
//return 1000000;
|
||||||
Block f = BlockStateInterface.get(src.down()).getBlock();
|
Block f = BlockStateInterface.get(src.down()).getBlock();
|
||||||
if (f instanceof BlockLadder || f instanceof BlockVine) {
|
if (f instanceof BlockLadder || f instanceof BlockVine) {
|
||||||
@ -80,6 +81,8 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean wasTheBridgeBlockAlwaysThere = true;//did we have to place a bridge block or was it always there
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MovementState updateState(MovementState state) {
|
public MovementState updateState(MovementState state) {
|
||||||
super.updateState(state);
|
super.updateState(state);
|
||||||
@ -92,16 +95,86 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
case WAITING:
|
case WAITING:
|
||||||
case RUNNING:
|
case RUNNING:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
Block fd = BlockStateInterface.get(src.down()).getBlock();
|
||||||
|
boolean ladder = fd instanceof BlockLadder || fd instanceof BlockVine;
|
||||||
|
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(positionsToPlace[0]) || ladder;
|
||||||
|
BlockPos whereAmI = playerFeet();
|
||||||
|
if (whereAmI.getY() != dest.getY() && !ladder) {
|
||||||
|
System.out.println("Wrong Y coordinate");
|
||||||
|
if (whereAmI.getY() < dest.getY()) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.JUMP, true);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
if (isTheBridgeBlockThere) {
|
||||||
if (playerFeet().equals(dest)) {
|
if (playerFeet().equals(dest)) {
|
||||||
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
state.setStatus(MovementState.MovementStatus.SUCCESS);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
if (wasTheBridgeBlockAlwaysThere) {
|
||||||
|
player().setSprinting(true);
|
||||||
|
}
|
||||||
Rotation rotationToBlock = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world()));
|
Rotation rotationToBlock = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world()));
|
||||||
return state.setTarget(new MovementState.MovementTarget(rotationToBlock))
|
return state.setTarget(new MovementState.MovementTarget(rotationToBlock)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||||
.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
} else {
|
||||||
|
wasTheBridgeBlockAlwaysThere = false;
|
||||||
|
for (BlockPos against1 : against) {
|
||||||
|
if (BlockStateInterface.get(against1).isBlockNormalCube()) {
|
||||||
|
if (!MovementHelper.switchtothrowaway()) {//get ready to place a throwaway block
|
||||||
|
displayChatMessageRaw("bb pls get me some blocks. dirt or cobble");
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
|
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
|
||||||
|
double faceY = (dest.getY() + against1.getY()) * 0.5D;
|
||||||
|
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
||||||
|
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ))));
|
||||||
|
|
||||||
default:
|
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
|
||||||
|
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && Minecraft.getMinecraft().player.isSneaking()) {
|
||||||
|
if (LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionsToPlace[0])) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
|
||||||
|
} else {
|
||||||
|
//Out.gui("Wrong. " + side + " " + LookBehaviorUtils.getSelectedBlock().get().offset(side) + " " + positionsToPlace[0], Out.Mode.Debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
displayChatMessageRaw("Trying to look at " + against1 + ", actually looking at" + LookBehaviorUtils.getSelectedBlock());
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
|
if (whereAmI.equals(dest)) {
|
||||||
|
//if we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of
|
||||||
|
//Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
|
||||||
|
if (!MovementHelper.switchtothrowaway()) {//get ready to place a throwaway block
|
||||||
|
displayChatMessageRaw("bb pls get me some blocks. dirt or cobble");
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
|
||||||
|
double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D;
|
||||||
|
double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D;
|
||||||
|
//faceX,faceY,faceZ is the middle of the face between from and to
|
||||||
|
BlockPos goalLook = src.down();//this is the block we were just standing on, and the one we want to place against
|
||||||
|
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ))));
|
||||||
|
|
||||||
|
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
|
||||||
|
state.setInput(InputOverrideHandler.Input.SNEAK, true);
|
||||||
|
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), goalLook)) {
|
||||||
|
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);//wait to right click until we are able to place
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
//Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
|
||||||
|
return state;
|
||||||
|
} else {
|
||||||
|
Rotation rotationToBlock = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world()));
|
||||||
|
return state.setTarget(new MovementState.MovementTarget(rotationToBlock)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||||
|
//TODO MovementManager.moveTowardsBlock(to);//move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,11 @@ import baritone.bot.utils.Utils;
|
|||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
@ -96,14 +99,18 @@ public interface IPath {
|
|||||||
*
|
*
|
||||||
* @return an unordered collection of positions
|
* @return an unordered collection of positions
|
||||||
*/
|
*/
|
||||||
Collection<BlockPos> getBlocksToBreak();
|
default Collection<BlockPos> getBlocksToBreak() {
|
||||||
|
return movements().stream().map(Movement::toBreak).flatMap(ArrayList::stream).collect(Collectors.toCollection(HashSet::new));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For rendering purposes, what blocks should be highlighted in green
|
* For rendering purposes, what blocks should be highlighted in green
|
||||||
*
|
*
|
||||||
* @return an unordered collection of positions
|
* @return an unordered collection of positions
|
||||||
*/
|
*/
|
||||||
Collection<BlockPos> getBlocksToPlace();
|
default Collection<BlockPos> getBlocksToPlace() {
|
||||||
|
return movements().stream().map(Movement::toPlace).flatMap(ArrayList::stream).collect(Collectors.toCollection(HashSet::new));
|
||||||
|
}
|
||||||
|
|
||||||
int getNumNodesConsidered();
|
int getNumNodesConsidered();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user