use of com.lowdragmc.multiblocked.api.pattern.error.PatternStringError in project Multiblocked by Low-Drag-MC.
the class BlockPattern method checkPatternAt.
public boolean checkPatternAt(MultiblockState worldState, boolean savePredicate) {
ControllerTileEntity controller = worldState.getController();
if (controller == null) {
worldState.setError(new PatternStringError("no controller found"));
return false;
}
BlockPos centerPos = controller.getBlockPos();
Direction frontFacing = controller.getFrontFacing();
Set<MultiblockCapability<?>> inputCapabilities = controller.getDefinition().recipeMap.inputCapabilities;
Set<MultiblockCapability<?>> outputCapabilities = controller.getDefinition().recipeMap.outputCapabilities;
Direction[] facings = controller.getDefinition().allowRotate ? new Direction[] { frontFacing } : new Direction[] { Direction.SOUTH, Direction.NORTH, Direction.EAST, Direction.WEST };
for (Direction facing : facings) {
if (checkPatternAt(worldState, centerPos, facing, savePredicate, inputCapabilities, outputCapabilities)) {
return true;
}
}
return false;
}
use of com.lowdragmc.multiblocked.api.pattern.error.PatternStringError in project Multiblocked by Low-Drag-MC.
the class BlockPattern method checkPatternAt.
private boolean checkPatternAt(MultiblockState worldState, BlockPos centerPos, Direction facing, boolean savePredicate, Set<MultiblockCapability<?>> inputCapabilities, Set<MultiblockCapability<?>> outputCapabilities) {
boolean findFirstAisle = false;
int minZ = -centerOffset[4];
worldState.clean();
PatternMatchContext matchContext = worldState.matchContext;
Map<SimplePredicate, Integer> globalCount = worldState.globalCount;
// Checking aisles
for (int c = 0, z = minZ++, r; c < this.fingerLength; c++) {
// Checking repeatable slices
loop: for (r = 0; (findFirstAisle ? r < aisleRepetitions[c][1] : z <= -centerOffset[3]); r++) {
// Checking single slice
for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) {
for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) {
worldState.setError(null);
TraceabilityPredicate predicate = this.blockMatches[c][b][a];
BlockPos pos = setActualRelativeOffset(x, y, z, facing).offset(centerPos.getX(), centerPos.getY(), centerPos.getZ());
if (!worldState.update(pos, predicate)) {
return false;
}
if (!predicate.isAny()) {
worldState.addPosCache(pos);
if (savePredicate) {
worldState.getMatchContext().getOrCreate("predicates", (Supplier<HashMap<BlockPos, TraceabilityPredicate>>) HashMap::new).put(pos, predicate);
}
}
boolean canPartShared = true;
TileEntity tileEntity = worldState.getTileEntity();
if (tileEntity instanceof IPartComponent) {
// add detected parts
if (!predicate.isAny()) {
IPartComponent part = (IPartComponent) tileEntity;
if (part.isFormed() && !part.canShared() && !part.hasController(worldState.controllerPos)) {
// check part can be shared
canPartShared = false;
worldState.setError(new PatternStringError("multiblocked.pattern.error.share"));
} else {
worldState.getMatchContext().getOrCreate("parts", LongOpenHashSet::new).add(worldState.getPos().asLong());
}
}
}
if (!predicate.test(worldState) || !canPartShared) {
// matching failed
if (findFirstAisle) {
if (r < aisleRepetitions[c][0]) {
// retreat to see if the first aisle can start later
r = c = 0;
z = minZ++;
matchContext.reset();
findFirstAisle = false;
}
} else {
// continue searching for the first aisle
z++;
}
continue loop;
}
if (tileEntity != null && !predicate.isAny()) {
Map<Long, EnumMap<IO, Set<MultiblockCapability<?>>>> capabilities = worldState.getMatchContext().getOrCreate("capabilities", Long2ObjectOpenHashMap::new);
if (!capabilities.containsKey(worldState.getPos().asLong()) && worldState.io != null) {
// if predicate has no specific capability requirements. we will check abilities of every blocks
Set<MultiblockCapability<?>> bothFound = new HashSet<>();
for (MultiblockCapability<?> capability : inputCapabilities) {
// IN
if (worldState.io == IO.BOTH && outputCapabilities.contains(capability) && capability.isBlockHasCapability(IO.BOTH, tileEntity)) {
bothFound.add(capability);
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.BOTH, xx -> new HashSet<>()).add(capability);
} else if (worldState.io != IO.OUT && capability.isBlockHasCapability(IO.IN, tileEntity)) {
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.IN, xx -> new HashSet<>()).add(capability);
}
}
if (worldState.io != IO.IN) {
for (MultiblockCapability<?> capability : outputCapabilities) {
// OUT
if (!bothFound.contains(capability) && capability.isBlockHasCapability(IO.OUT, tileEntity)) {
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.OUT, xx -> new HashSet<>()).add(capability);
}
}
}
}
}
}
}
findFirstAisle = true;
z++;
}
// Repetitions out of range
if (r < aisleRepetitions[c][0] || !worldState.isFormed() || !findFirstAisle) {
if (worldState.isFormed()) {
worldState.setError(new PatternError());
}
return false;
}
}
// Check count matches amount
for (Map.Entry<SimplePredicate, Integer> entry : globalCount.entrySet()) {
if (entry.getValue() < entry.getKey().minCount) {
worldState.setError(new SinglePredicateError(entry.getKey(), 1));
return false;
}
}
worldState.setError(null);
return true;
}
use of com.lowdragmc.multiblocked.api.pattern.error.PatternStringError in project Multiblocked by Low-Drag-MC.
the class PredicateAnyCapability method checkCapability.
private static boolean checkCapability(IO io, MultiblockCapability<?> capability, MultiblockState state) {
if (io != null) {
TileEntity tileEntity = state.getTileEntity();
if (tileEntity != null && capability.isBlockHasCapability(io, tileEntity)) {
Map<Long, EnumMap<IO, Set<MultiblockCapability<?>>>> capabilities = state.getMatchContext().getOrCreate("capabilities", Long2ObjectOpenHashMap::new);
capabilities.computeIfAbsent(state.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(io, x -> new HashSet<>()).add(capability);
return true;
}
}
state.setError(new PatternStringError(LocalizationUtils.format("multiblocked.pattern.error.capability", LocalizationUtils.format(capability.getUnlocalizedName()), io == null ? "NULL" : io.name())));
return false;
}
use of com.lowdragmc.multiblocked.api.pattern.error.PatternStringError in project Multiblocked by Low-Drag-MC.
the class SimplePredicate method checkInnerConditions.
private boolean checkInnerConditions(MultiblockState blockWorldState) {
if (disableRenderFormed) {
blockWorldState.getMatchContext().getOrCreate("renderMask", LongOpenHashSet::new).add(blockWorldState.getPos().asLong());
}
if (io != IO.BOTH) {
if (blockWorldState.io == IO.BOTH) {
blockWorldState.io = io;
} else if (blockWorldState.io != io) {
blockWorldState.io = null;
}
}
if (nbtParser != null && !blockWorldState.world.isClientSide) {
TileEntity te = blockWorldState.getTileEntity();
if (te != null) {
CompoundNBT nbt = te.serializeNBT();
if (Pattern.compile(nbtParser).matcher(nbt.toString()).find()) {
return true;
}
}
blockWorldState.setError(new PatternStringError("The NBT fails to match"));
return false;
}
return true;
}
Aggregations