Switch to using an int[] for storing precomputed data, and also use lazy loading
This commit is contained in:
parent
8d480cefb9
commit
fdcdcbb85f
@ -27,27 +27,73 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static baritone.pathing.movement.MovementHelper.isFlowing;
|
import static baritone.pathing.movement.MovementHelper.isFlowing;
|
||||||
import static baritone.pathing.movement.MovementHelper.isWater;
|
import static baritone.pathing.movement.MovementHelper.isWater;
|
||||||
|
|
||||||
public class PrecomputedData { // TODO add isFullyPassable
|
public class PrecomputedData { // TODO add isFullyPassable
|
||||||
|
private final int[] data = new int[Block.BLOCK_STATE_IDS.size()]; // Has to be of type boolean due to otherwise it has a generic type
|
||||||
|
|
||||||
PrecomputedDataForBlockState canWalkOn;
|
private final int completedMask = 0b1;
|
||||||
PrecomputedDataForBlockState canWalkThrough;
|
private final int canWalkOnMask = 0b10;
|
||||||
|
private final int canWalkOnSpecialMask = 0b100;
|
||||||
|
private final int canWalkThroughMask = 0b1000;
|
||||||
|
private final int canWalkThroughSpecialMask = 0b10000;
|
||||||
|
|
||||||
public PrecomputedData() {
|
public PrecomputedData() {
|
||||||
canWalkOn = new PrecomputedDataForBlockState(MovementHelper::canWalkOnBlockState, MovementHelper::canWalkOnPosition);
|
Arrays.fill(data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
canWalkThrough = new PrecomputedDataForBlockState(MovementHelper::canWalkThroughBlockState, MovementHelper::canWalkThroughPosition);
|
private void fillData(int id, IBlockState state) {
|
||||||
|
Optional<Boolean> canWalkOnState = MovementHelper.canWalkOnBlockState(state);
|
||||||
|
if (canWalkOnState.isPresent()) {
|
||||||
|
if (canWalkOnState.get()) {
|
||||||
|
data[id] = data[id] | canWalkOnMask;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data[id] = data[id] | canWalkOnSpecialMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Boolean> canWalkThroughState = MovementHelper.canWalkThroughBlockState(state);
|
||||||
|
if (canWalkThroughState.isPresent()) {
|
||||||
|
if (canWalkThroughState.get()) {
|
||||||
|
data[id] = data[id] | canWalkThroughMask;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data[id] = data[id] | canWalkThroughSpecialMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data[id] = data[id] | completedMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
public boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||||
return canWalkOn.get(bsi, x, y, z, state);
|
int id = Block.BLOCK_STATE_IDS.get(state);
|
||||||
|
|
||||||
|
if ((data[id] & completedMask) == 0) { // we need to fill in the data
|
||||||
|
fillData(id, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data[id] & canWalkOnSpecialMask) != 0) {
|
||||||
|
return MovementHelper.canWalkOnPosition(bsi, x, y, z, state);
|
||||||
|
} else {
|
||||||
|
return (data[id] & canWalkOnMask) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
public boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||||
return canWalkThrough.get(bsi, x, y, z, state);
|
int id = Block.BLOCK_STATE_IDS.get(state);
|
||||||
|
|
||||||
|
if ((data[id] & completedMask) == 0) { // we need to fill in the data
|
||||||
|
fillData(id, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data[id] & canWalkThroughSpecialMask) != 0) {
|
||||||
|
return MovementHelper.canWalkOnPosition(bsi, x, y, z, state);
|
||||||
|
} else {
|
||||||
|
return (data[id] & canWalkThroughMask) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.pathing.precompute;
|
|
||||||
|
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.world.IBlockAccess;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class PrecomputedDataForBlockState {
|
|
||||||
boolean[] dataPerBlockState = new boolean[Block.BLOCK_STATE_IDS.size()]; // Has to be of type boolean due to otherwise it has a generic type
|
|
||||||
boolean[] specialCases = new boolean[Block.BLOCK_STATE_IDS.size()]; // We can also be certain that size will return the highest as it fills in all positions with null until we get to the highest block state
|
|
||||||
|
|
||||||
private final SpecialCaseFunction specialCaseHandler;
|
|
||||||
private final Function<IBlockState, Optional<Boolean>> precomputer;
|
|
||||||
|
|
||||||
public PrecomputedDataForBlockState(Function<IBlockState, Optional<Boolean>> precomputer, SpecialCaseFunction specialCaseHandler) {
|
|
||||||
this.specialCaseHandler = specialCaseHandler;
|
|
||||||
this.precomputer = precomputer;
|
|
||||||
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh() {
|
|
||||||
for (Iterator<IBlockState> it = Block.BLOCK_STATE_IDS.iterator(); it.hasNext(); ) { // Can be replaced with an enhanced for because that breaks github actions for some reason I can't be bothered to dig into
|
|
||||||
IBlockState state = it.next(); // state should never be null
|
|
||||||
Optional<Boolean> applied = precomputer.apply(state);
|
|
||||||
|
|
||||||
int id = Block.BLOCK_STATE_IDS.get(state);
|
|
||||||
|
|
||||||
if (applied.isPresent()) {
|
|
||||||
dataPerBlockState[id] = applied.get();
|
|
||||||
specialCases[id] = false;
|
|
||||||
} else {
|
|
||||||
dataPerBlockState[id] = false;
|
|
||||||
specialCases[id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean get(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
|
||||||
int id = Block.BLOCK_STATE_IDS.get(state);
|
|
||||||
if (specialCases[id]) {
|
|
||||||
return specialCaseHandler.apply(bsi, x, y, z, state);
|
|
||||||
} else {
|
|
||||||
return dataPerBlockState[id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SpecialCaseFunction {
|
|
||||||
public boolean apply(BlockStateInterface bsi, int x, int y, int z, IBlockState blockState);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user