switch to builder pattern for block state cached data
This commit is contained in:
@@ -126,6 +126,9 @@ public class Baritone implements IBaritone {
|
||||
Main.main();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable th) {
|
||||
th.printStackTrace();
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package baritone.builder;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Information about an IBlockState
|
||||
@@ -27,72 +27,48 @@ import java.util.*;
|
||||
*/
|
||||
public final class BlockStateCachedData {
|
||||
|
||||
private static final BlockStateCachedData[] PER_STATE = Main.DATA_PROVIDER.all();
|
||||
public static final BlockStateCachedData SCAFFOLDING = new BlockStateCachedData(false, true, true, Half.EITHER, false);
|
||||
private static final BlockStateCachedData[] PER_STATE = Main.DATA_PROVIDER.allNullable();
|
||||
public static final BlockStateCachedData SCAFFOLDING = new BlockStateCachedData(new BlockStateCachedDataBuilder().normalFullBlock());
|
||||
|
||||
public final boolean canWalkOn;
|
||||
public final boolean fullyWalkableTop;
|
||||
public final boolean isAir;
|
||||
|
||||
|
||||
public final boolean mustSneakWhenPlacingAgainstMe;
|
||||
private final boolean[] presentsTopHalfFaceForPlacement;
|
||||
private final boolean[] presentsBottomHalfFaceForPlacement;
|
||||
private final List<BlockStatePlacementOption> options;
|
||||
|
||||
public final List<BlockStatePlacementOption> options;
|
||||
|
||||
public static BlockStateCachedData get(int state) {
|
||||
return PER_STATE[state];
|
||||
}
|
||||
|
||||
public BlockStateCachedData(boolean isAir, boolean canPlaceAgainstAtAll, boolean canWalkOn, Half half, boolean mustSneakWhenPlacingAgainstMe) {
|
||||
this.isAir = isAir;
|
||||
this.canWalkOn = canWalkOn;
|
||||
this.mustSneakWhenPlacingAgainstMe = mustSneakWhenPlacingAgainstMe;
|
||||
this.options = Collections.unmodifiableList(calcOptions(canPlaceAgainstAtAll, half));
|
||||
this.presentsTopHalfFaceForPlacement = new boolean[Face.VALUES.length];
|
||||
this.presentsBottomHalfFaceForPlacement = new boolean[Face.VALUES.length];
|
||||
setupFacesPresented(canPlaceAgainstAtAll, half);
|
||||
if (mustSneakWhenPlacingAgainstMe && half != Half.EITHER) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
public BlockStateCachedData(BlockStateCachedDataBuilder builder) {
|
||||
builder.sanityCheck();
|
||||
this.isAir = builder.isAir();
|
||||
this.fullyWalkableTop = builder.isFullyWalkableTop();
|
||||
this.mustSneakWhenPlacingAgainstMe = builder.isMustSneakWhenPlacingAgainstMe();
|
||||
this.options = builder.howCanIBePlaced();
|
||||
|
||||
private void setupFacesPresented(boolean canPlaceAgainstAtAll, Half half) {
|
||||
if (!canPlaceAgainstAtAll) {
|
||||
return;
|
||||
}
|
||||
Arrays.fill(presentsBottomHalfFaceForPlacement, true);
|
||||
Arrays.fill(presentsTopHalfFaceForPlacement, true);
|
||||
// TODO support case for placing against nub of stair on the one faced side
|
||||
switch (half) {
|
||||
case EITHER: {
|
||||
return;
|
||||
}
|
||||
case TOP: {
|
||||
// i am a top slab, or an upside down stair
|
||||
presentsBottomHalfFaceForPlacement[Face.DOWN.index] = false;
|
||||
presentsTopHalfFaceForPlacement[Face.DOWN.index] = false;
|
||||
for (Face face : Face.HORIZONTALS) {
|
||||
presentsBottomHalfFaceForPlacement[face.index] = false; // top slab = can't place against the bottom half
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOTTOM: {
|
||||
// i am a bottom slab, or an normal stair
|
||||
presentsBottomHalfFaceForPlacement[Face.UP.index] = false;
|
||||
presentsTopHalfFaceForPlacement[Face.UP.index] = false;
|
||||
for (Face face : Face.HORIZONTALS) {
|
||||
presentsTopHalfFaceForPlacement[face.index] = false; // bottom slab = can't place against the top half
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean[][] presented = builder.facesIPresentForPlacementAgainst();
|
||||
this.presentsTopHalfFaceForPlacement = presented[1];
|
||||
this.presentsBottomHalfFaceForPlacement = presented[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PlaceAgainstData presentsFace(Face face, Half half) {
|
||||
if ((face == Face.UP || face == Face.DOWN) && half != Half.EITHER) {
|
||||
public PlaceAgainstData tryAgainstMe(BlockStatePlacementOption placement) {
|
||||
if (Main.fakePlacementForPerformanceTesting) {
|
||||
return Main.RAND.nextInt(10) < 8 ? PlaceAgainstData.EITHER : null;
|
||||
}
|
||||
|
||||
Face myFace = placement.against.opposite();
|
||||
Half theirHalf = placement.half;
|
||||
if ((myFace == Face.UP || myFace == Face.DOWN) && theirHalf != Half.EITHER) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
boolean top = presentsTopHalfFaceForPlacement[face.index] && (half == Half.EITHER || half == Half.TOP);
|
||||
boolean bottom = presentsBottomHalfFaceForPlacement[face.index] && (half == Half.EITHER || half == Half.BOTTOM);
|
||||
boolean top = presentsTopHalfFaceForPlacement[myFace.index] && (theirHalf == Half.EITHER || theirHalf == Half.TOP);
|
||||
boolean bottom = presentsBottomHalfFaceForPlacement[myFace.index] && (theirHalf == Half.EITHER || theirHalf == Half.BOTTOM);
|
||||
Half intersectedHalf; // the half that both we present, and they accept. not necessarily equal to either. slab-against-block and block-against-slab will both have this as top/bottom, not either.
|
||||
if (top && bottom) {
|
||||
intersectedHalf = Half.EITHER;
|
||||
@@ -105,48 +81,4 @@ public final class BlockStateCachedData {
|
||||
}
|
||||
return PlaceAgainstData.get(intersectedHalf, mustSneakWhenPlacingAgainstMe);
|
||||
}
|
||||
|
||||
private List<BlockStatePlacementOption> calcOptions(boolean canPlaceAgainstAtAll, Half half) {
|
||||
if (canPlaceAgainstAtAll) {
|
||||
List<BlockStatePlacementOption> ret = new ArrayList<>();
|
||||
for (Face face : Face.VALUES) {
|
||||
if (Main.STRICT_Y && face == Face.UP) {
|
||||
continue;
|
||||
}
|
||||
Half overrideHalf = half;
|
||||
if (face == Face.DOWN) {
|
||||
if (half == Half.TOP) {
|
||||
continue;
|
||||
} else {
|
||||
overrideHalf = Half.EITHER;
|
||||
}
|
||||
}
|
||||
if (face == Face.UP) {
|
||||
if (half == Half.BOTTOM) {
|
||||
continue;
|
||||
} else {
|
||||
overrideHalf = Half.EITHER;
|
||||
}
|
||||
}
|
||||
ret.add(BlockStatePlacementOption.get(face, overrideHalf, Optional.empty()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public PlaceAgainstData canBeDoneAgainstMe(BlockStatePlacementOption placement) {
|
||||
if (Main.fakePlacementForPerformanceTesting) {
|
||||
return Main.RAND.nextInt(10) < 8 ? PlaceAgainstData.EITHER : null;
|
||||
}
|
||||
|
||||
Face myFace = placement.against.opposite();
|
||||
return presentsFace(myFace, placement.half);
|
||||
}
|
||||
|
||||
public List<BlockStatePlacementOption> placementOptions() {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
212
src/main/java/baritone/builder/BlockStateCachedDataBuilder.java
Normal file
212
src/main/java/baritone/builder/BlockStateCachedDataBuilder.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.builder;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BlockStateCachedDataBuilder {
|
||||
|
||||
// should all these be optionals? like maybe Boolean? that start as null? and each has to be set explicitly?
|
||||
private boolean isAir;
|
||||
private boolean canPlaceAgainstMe;
|
||||
private boolean fullyWalkableTop;
|
||||
private boolean mustSneakWhenPlacingAgainstMe;
|
||||
/**
|
||||
* Examples:
|
||||
* <p>
|
||||
* Upside down stairs must be placed against TOP
|
||||
* <p>
|
||||
* Bottom slabs must be placed against BOTTOM
|
||||
* <p>
|
||||
* Normal blocks must be placed against EITHER
|
||||
*/
|
||||
private Half mustBePlacedAgainst = Half.EITHER;
|
||||
private boolean stair;
|
||||
private Face playerMustBeFacingInOrderToPlaceMe;
|
||||
private double height = Double.NaN;
|
||||
|
||||
public BlockStateCachedDataBuilder() {
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder normalFullBlock() {
|
||||
return fullyWalkableTop().height(1).canPlaceAgainstMe();
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder stair(boolean rightsideUp, Face facing) {
|
||||
stair = true;
|
||||
playerMustBeFacingInOrderToPlaceMe = facing;
|
||||
return slab(rightsideUp);
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder slab(boolean bottom) {
|
||||
mustBePlacedAgainst = bottom ? Half.BOTTOM : Half.TOP;
|
||||
return bottom ? this : fullyWalkableTop().height(1).canPlaceAgainstMe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Really just air. This is a fully open block that won't collide with object mouse over raytrace.
|
||||
*/
|
||||
public BlockStateCachedDataBuilder air() {
|
||||
isAir = true;
|
||||
mustBePlacedAgainst = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isAir() {
|
||||
return isAir;
|
||||
}
|
||||
|
||||
/**
|
||||
* does the top face of this block fully support the player from 0.0,0.0 to 1.0,1.0? true for most normal blocks. false for, for example, fences
|
||||
*/
|
||||
public BlockStateCachedDataBuilder fullyWalkableTop() {
|
||||
fullyWalkableTop = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isFullyWalkableTop() {
|
||||
return fullyWalkableTop;
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder height(double y) {
|
||||
if (!isFullyWalkableTop()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
height = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double supportedPlayerY() { // e.g. slabs are 0.5, soul sand is 0.875, normal blocks are 1, fences are 1.5
|
||||
if (!isFullyWalkableTop() || Double.isNaN(height)) {
|
||||
throw new IllegalStateException(); // e.g. rightside-up stairs aren't fully supporting of the player so this doesn't count for them
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder mustSneakWhenPlacingAgainstMe() {
|
||||
mustSneakWhenPlacingAgainstMe = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isMustSneakWhenPlacingAgainstMe() {
|
||||
return mustSneakWhenPlacingAgainstMe;
|
||||
}
|
||||
|
||||
public BlockStateCachedDataBuilder canPlaceAgainstMe() {
|
||||
canPlaceAgainstMe = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<BlockStatePlacementOption> howCanIBePlaced() {
|
||||
if (mustBePlacedAgainst == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<BlockStatePlacementOption> ret = new ArrayList<>();
|
||||
for (Face face : Face.VALUES) {
|
||||
if (Main.STRICT_Y && face == Face.UP) {
|
||||
continue;
|
||||
}
|
||||
if (playerMustBeFacingInOrderToPlaceMe == face.opposite()) { // obv, this won't happen if playerMustBeFacing is null
|
||||
continue;
|
||||
}
|
||||
Half overrideHalf = mustBePlacedAgainst;
|
||||
if (face == Face.DOWN) {
|
||||
if (mustBePlacedAgainst == Half.TOP) {
|
||||
continue;
|
||||
} else {
|
||||
overrideHalf = Half.EITHER;
|
||||
}
|
||||
}
|
||||
if (face == Face.UP) {
|
||||
if (mustBePlacedAgainst == Half.BOTTOM) {
|
||||
continue;
|
||||
} else {
|
||||
overrideHalf = Half.EITHER;
|
||||
}
|
||||
}
|
||||
ret.add(BlockStatePlacementOption.get(face, overrideHalf, Optional.ofNullable(playerMustBeFacingInOrderToPlaceMe)));
|
||||
}
|
||||
return Collections.unmodifiableList(ret);
|
||||
}
|
||||
|
||||
public boolean[][] facesIPresentForPlacementAgainst() {
|
||||
boolean[] presentsBottomHalfFaceForPlacement = new boolean[Face.VALUES.length];
|
||||
boolean[] presentsTopHalfFaceForPlacement = new boolean[Face.VALUES.length];
|
||||
if (canPlaceAgainstMe) {
|
||||
Arrays.fill(presentsBottomHalfFaceForPlacement, true);
|
||||
Arrays.fill(presentsTopHalfFaceForPlacement, true);
|
||||
switch (mustBePlacedAgainst) {
|
||||
case EITHER: {
|
||||
break;
|
||||
}
|
||||
case TOP: {
|
||||
// i am a top slab, or an upside down stair
|
||||
presentsBottomHalfFaceForPlacement[Face.DOWN.index] = false;
|
||||
presentsTopHalfFaceForPlacement[Face.DOWN.index] = false;
|
||||
for (Face face : Face.HORIZONTALS) {
|
||||
if (stair && face == playerMustBeFacingInOrderToPlaceMe) {
|
||||
continue; // little nub of the stair on the faced side
|
||||
}
|
||||
presentsBottomHalfFaceForPlacement[face.index] = false; // top slab = can't place against the bottom half
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOTTOM: {
|
||||
// i am a bottom slab, or an normal stair
|
||||
presentsBottomHalfFaceForPlacement[Face.UP.index] = false;
|
||||
presentsTopHalfFaceForPlacement[Face.UP.index] = false;
|
||||
for (Face face : Face.HORIZONTALS) {
|
||||
if (stair && face == playerMustBeFacingInOrderToPlaceMe) {
|
||||
continue; // little nub of the stair on the faced side
|
||||
}
|
||||
presentsTopHalfFaceForPlacement[face.index] = false; // bottom slab = can't place against the top half
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new boolean[][]{presentsBottomHalfFaceForPlacement, presentsTopHalfFaceForPlacement};
|
||||
}
|
||||
|
||||
public void sanityCheck() {
|
||||
if (isAir()) {
|
||||
if (!howCanIBePlaced().isEmpty()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (isFullyWalkableTop()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
if (mustBePlacedAgainst == null ^ isAir()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (isMustSneakWhenPlacingAgainstMe() && mustBePlacedAgainst != Half.EITHER) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (stair ^ (playerMustBeFacingInOrderToPlaceMe != null && mustBePlacedAgainst != Half.EITHER)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (isFullyWalkableTop() == Double.isNaN(height)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
new BlockStateCachedDataBuilder().sanityCheck();
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,8 @@ public class BlockStatePlacementOption {
|
||||
*/
|
||||
private static final double LOOSE_CENTER_DISTANCE = 0.15;
|
||||
|
||||
public List<Raytracer.Raytrace> computeTraceOptions(Half againstHalf, int playerSupportingX, double playerEyeY, int playerSupportingZ, PlayerVantage vantage, double blockReachDistance) {
|
||||
if (againstHalf != half && half != Half.EITHER) { // narrowing is ok (EITHER -> TOP/BOTTOM) but widening isn't (TOP/BOTTOM -> EITHER)
|
||||
public List<Raytracer.Raytrace> computeTraceOptions(PlaceAgainstData placingAgainst, int playerSupportingX, double playerEyeY, int playerSupportingZ, PlayerVantage vantage, double blockReachDistance) {
|
||||
if (placingAgainst.half != half && half != Half.EITHER) { // narrowing is ok (EITHER -> TOP/BOTTOM) but widening isn't (TOP/BOTTOM -> EITHER)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
List<Vec2d> acceptableVantages = new ArrayList<>();
|
||||
@@ -95,14 +95,13 @@ public class BlockStatePlacementOption {
|
||||
.map(playerEyeXZ -> new Vec3d(playerEyeXZ.x, playerEyeY, playerEyeXZ.z))
|
||||
.flatMap(eye ->
|
||||
Stream.of(FACE_PROJECTION_CACHE[against.index])
|
||||
.filter(this::hitOk)
|
||||
.filter(hit -> hitOk(placingAgainst, hit))
|
||||
.filter(hit -> eye.distSq(hit) < blockReachDistance * blockReachDistance)
|
||||
.filter(hit -> directionOk(eye, hit))
|
||||
.<Supplier<Optional<Raytracer.Raytrace>>>map(hit -> () -> Raytracer.runTrace(eye, placeAgainstPos, against.opposite(), hit))
|
||||
)
|
||||
.collect(Collectors.toList())
|
||||
// TODO switch back to parallelStream
|
||||
.stream() // wrap it like this because flatMap forces .sequential() on the interior child stream, defeating the point
|
||||
.parallelStream() // wrap it like this because flatMap forces .sequential() on the interior child stream, defeating the point
|
||||
.map(Supplier::get)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
@@ -110,15 +109,15 @@ public class BlockStatePlacementOption {
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private boolean hitOk(Vec3d hit) {
|
||||
if (half == Half.EITHER) {
|
||||
private static boolean hitOk(PlaceAgainstData placingAgainst, Vec3d hit) {
|
||||
if (placingAgainst.half == Half.EITHER) {
|
||||
return true;
|
||||
} else if (hit.y == 0.1) {
|
||||
return half == Half.BOTTOM;
|
||||
return placingAgainst.half == Half.BOTTOM;
|
||||
} else if (hit.y == 0.5) {
|
||||
return false;
|
||||
} else if (hit.y == 0.9) {
|
||||
return half == Half.TOP;
|
||||
return placingAgainst.half == Half.TOP;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@@ -226,7 +225,7 @@ public class BlockStatePlacementOption {
|
||||
for (PlayerVantage vantage : new PlayerVantage[]{PlayerVantage.STRICT_CENTER, PlayerVantage.LOOSE_CENTER}) {
|
||||
for (Face playerFacing : new Face[]{Face.NORTH, Face.EAST, Face.WEST}) {
|
||||
sanity.append(vantage).append(playerFacing);
|
||||
List<Raytracer.Raytrace> traces = BlockStatePlacementOption.get(Face.NORTH, Half.BOTTOM, Optional.of(playerFacing)).computeTraceOptions(Half.BOTTOM, 1, 1.62, 0, vantage, 4);
|
||||
List<Raytracer.Raytrace> traces = BlockStatePlacementOption.get(Face.NORTH, Half.BOTTOM, Optional.of(playerFacing)).computeTraceOptions(PlaceAgainstData.get(Half.BOTTOM, false), 1, 1.62, 0, vantage, 4);
|
||||
sanity.append(traces.size());
|
||||
sanity.append(" ");
|
||||
if (!traces.isEmpty()) {
|
||||
|
||||
@@ -18,16 +18,21 @@
|
||||
package baritone.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IBlockStateDataProvider {
|
||||
|
||||
int numStates();
|
||||
|
||||
BlockStateCachedData get(int i);
|
||||
Optional<BlockStateCachedDataBuilder> getBuilder(int i);
|
||||
|
||||
default BlockStateCachedData[] all() {
|
||||
default BlockStateCachedData getNullable(int i) {
|
||||
return getBuilder(i).map(BlockStateCachedData::new).orElse(null);
|
||||
}
|
||||
|
||||
default BlockStateCachedData[] allNullable() {
|
||||
BlockStateCachedData[] ret = new BlockStateCachedData[numStates()];
|
||||
Arrays.setAll(ret, this::get);
|
||||
Arrays.setAll(ret, this::getNullable);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +156,9 @@ public class Main {
|
||||
.collect(Collectors.toList()).parallelStream()
|
||||
.forEach(x -> System.out.println(x + ""));
|
||||
}
|
||||
{
|
||||
BlockStateCachedData.get(0);
|
||||
}
|
||||
{
|
||||
BlockStatePlacementOption.sanityCheck();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PlaceOrderDependencyGraph {
|
||||
}
|
||||
|
||||
private void compute(long pos) {
|
||||
for (BlockStatePlacementOption option : data(pos).placementOptions()) {
|
||||
for (BlockStatePlacementOption option : data(pos).options) {
|
||||
if (Main.STRICT_Y && option.against == Face.UP) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public class PlaceOrderDependencyGraph {
|
||||
} else {
|
||||
against = BlockStateCachedData.SCAFFOLDING;
|
||||
}
|
||||
if (against.canBeDoneAgainstMe(option) != null) {
|
||||
if (against.tryAgainstMe(option) != null) {
|
||||
edges.set(bitIndex(pos, option.against));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
|
||||
package baritone.builder.mc;
|
||||
|
||||
import baritone.builder.BlockStateCachedData;
|
||||
import baritone.builder.Half;
|
||||
import baritone.builder.BlockStateCachedDataBuilder;
|
||||
import baritone.builder.Face;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
/**
|
||||
* I expect this class to get extremely complicated.
|
||||
@@ -31,13 +34,27 @@ import net.minecraft.init.Blocks;
|
||||
*/
|
||||
public class BlockStatePropertiesExtractor {
|
||||
|
||||
public static BlockStateCachedData getData(IBlockState state) {
|
||||
public static BlockStateCachedDataBuilder getData(IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
BlockStateCachedDataBuilder builder = new BlockStateCachedDataBuilder();
|
||||
|
||||
if (block instanceof BlockAir) {
|
||||
return new BlockStateCachedData(true, false, false, Half.EITHER, false);
|
||||
return builder.air();
|
||||
}
|
||||
boolean normal = block == Blocks.COBBLESTONE || block == Blocks.DIRT;
|
||||
return new BlockStateCachedData(false, normal, normal, Half.EITHER, false);
|
||||
if (block instanceof BlockStairs) {
|
||||
boolean rightsideUp = state.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.BOTTOM; // true if normal stair, false if upside down stair
|
||||
EnumFacing facing = state.getValue(BlockStairs.FACING);
|
||||
return builder.stair(rightsideUp, Face.fromMC(facing));
|
||||
}
|
||||
if (block instanceof BlockSlab) {
|
||||
if (((BlockSlab) block).isDouble()) {
|
||||
return builder.normalFullBlock();
|
||||
}
|
||||
return builder.slab(state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM);
|
||||
}
|
||||
if (block == Blocks.COBBLESTONE || block == Blocks.DIRT) {
|
||||
builder.normalFullBlock();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.builder.mc;
|
||||
|
||||
import baritone.builder.BlockStateCachedData;
|
||||
import baritone.builder.BlockStateCachedDataBuilder;
|
||||
import baritone.builder.IBlockStateDataProvider;
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class VanillaBlockStateDataProvider implements IBlockStateDataProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateCachedData get(int i) {
|
||||
return Optional.ofNullable(Block.BLOCK_STATE_IDS.getByValue(i)).map(BlockStatePropertiesExtractor::getData).orElse(null);
|
||||
public Optional<BlockStateCachedDataBuilder> getBuilder(int i) {
|
||||
return Optional.ofNullable(Block.BLOCK_STATE_IDS.getByValue(i)).map(BlockStatePropertiesExtractor::getData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user