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.util.math.BlockPos;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static baritone.pathing.movement.MovementHelper.isFlowing;
|
||||
import static baritone.pathing.movement.MovementHelper.isWater;
|
||||
|
||||
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;
|
||||
PrecomputedDataForBlockState canWalkThrough;
|
||||
private final int completedMask = 0b1;
|
||||
private final int canWalkOnMask = 0b10;
|
||||
private final int canWalkOnSpecialMask = 0b100;
|
||||
private final int canWalkThroughMask = 0b1000;
|
||||
private final int canWalkThroughSpecialMask = 0b10000;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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