Search in sources :

Example 1 with PatternMatchContext

use of com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext 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;
}
Also used : PatternError(com.lowdragmc.multiblocked.api.pattern.error.PatternError) ComponentTileEntity(com.lowdragmc.multiblocked.api.tile.ComponentTileEntity) Array(java.lang.reflect.Array) BlockComponent(com.lowdragmc.multiblocked.api.block.BlockComponent) BiFunction(java.util.function.BiFunction) ArrayUtils(org.apache.commons.lang3.ArrayUtils) HashMap(java.util.HashMap) SinglePredicateError(com.lowdragmc.multiblocked.api.pattern.error.SinglePredicateError) Direction(net.minecraft.util.Direction) MultiblockCapability(com.lowdragmc.multiblocked.api.capability.MultiblockCapability) Supplier(java.util.function.Supplier) ControllerTileEntity(com.lowdragmc.multiblocked.api.tile.ControllerTileEntity) ArrayList(java.util.ArrayList) RelativeDirection(com.lowdragmc.multiblocked.api.pattern.util.RelativeDirection) HashSet(java.util.HashSet) ItemStack(net.minecraft.item.ItemStack) BlockInfo(com.lowdragmc.lowdraglib.utils.BlockInfo) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) Map(java.util.Map) IO(com.lowdragmc.multiblocked.api.capability.IO) Hand(net.minecraft.util.Hand) BlockState(net.minecraft.block.BlockState) PatternStringError(com.lowdragmc.multiblocked.api.pattern.error.PatternStringError) PatternMatchContext(com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext) PlayerEntity(net.minecraft.entity.player.PlayerEntity) CycleBlockStateRenderer(com.lowdragmc.multiblocked.client.renderer.impl.CycleBlockStateRenderer) EnumMap(java.util.EnumMap) World(net.minecraft.world.World) IPartComponent(com.lowdragmc.multiblocked.api.tile.part.IPartComponent) Set(java.util.Set) BlockPos(net.minecraft.util.math.BlockPos) BlockItemUseContext(net.minecraft.item.BlockItemUseContext) Blocks(net.minecraft.block.Blocks) BlockRayTraceResult(net.minecraft.util.math.BlockRayTraceResult) Consumer(java.util.function.Consumer) List(java.util.List) LongOpenHashSet(it.unimi.dsi.fastutil.longs.LongOpenHashSet) BlockItem(net.minecraft.item.BlockItem) SimplePredicate(com.lowdragmc.multiblocked.api.pattern.predicates.SimplePredicate) TileEntity(net.minecraft.tileentity.TileEntity) DirectionProperty(net.minecraft.state.DirectionProperty) BlockStateProperties(net.minecraft.state.properties.BlockStateProperties) HashSet(java.util.HashSet) Set(java.util.Set) LongOpenHashSet(it.unimi.dsi.fastutil.longs.LongOpenHashSet) HashMap(java.util.HashMap) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) PatternMatchContext(com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext) ComponentTileEntity(com.lowdragmc.multiblocked.api.tile.ComponentTileEntity) ControllerTileEntity(com.lowdragmc.multiblocked.api.tile.ControllerTileEntity) TileEntity(net.minecraft.tileentity.TileEntity) BlockPos(net.minecraft.util.math.BlockPos) LongOpenHashSet(it.unimi.dsi.fastutil.longs.LongOpenHashSet) EnumMap(java.util.EnumMap) HashSet(java.util.HashSet) LongOpenHashSet(it.unimi.dsi.fastutil.longs.LongOpenHashSet) IPartComponent(com.lowdragmc.multiblocked.api.tile.part.IPartComponent) MultiblockCapability(com.lowdragmc.multiblocked.api.capability.MultiblockCapability) IO(com.lowdragmc.multiblocked.api.capability.IO) SimplePredicate(com.lowdragmc.multiblocked.api.pattern.predicates.SimplePredicate) PatternError(com.lowdragmc.multiblocked.api.pattern.error.PatternError) PatternStringError(com.lowdragmc.multiblocked.api.pattern.error.PatternStringError) HashMap(java.util.HashMap) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) Map(java.util.Map) EnumMap(java.util.EnumMap) SinglePredicateError(com.lowdragmc.multiblocked.api.pattern.error.SinglePredicateError)

Example 2 with PatternMatchContext

use of com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext in project Multiblocked by Low-Drag-MC.

the class MultiblockState method clean.

public void clean() {
    this.matchContext = new PatternMatchContext();
    this.globalCount = new HashMap<>();
    cache = new LongOpenHashSet();
}
Also used : LongOpenHashSet(it.unimi.dsi.fastutil.longs.LongOpenHashSet) PatternMatchContext(com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext)

Aggregations

PatternMatchContext (com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext)2 LongOpenHashSet (it.unimi.dsi.fastutil.longs.LongOpenHashSet)2 BlockInfo (com.lowdragmc.lowdraglib.utils.BlockInfo)1 BlockComponent (com.lowdragmc.multiblocked.api.block.BlockComponent)1 IO (com.lowdragmc.multiblocked.api.capability.IO)1 MultiblockCapability (com.lowdragmc.multiblocked.api.capability.MultiblockCapability)1 PatternError (com.lowdragmc.multiblocked.api.pattern.error.PatternError)1 PatternStringError (com.lowdragmc.multiblocked.api.pattern.error.PatternStringError)1 SinglePredicateError (com.lowdragmc.multiblocked.api.pattern.error.SinglePredicateError)1 SimplePredicate (com.lowdragmc.multiblocked.api.pattern.predicates.SimplePredicate)1 RelativeDirection (com.lowdragmc.multiblocked.api.pattern.util.RelativeDirection)1 ComponentTileEntity (com.lowdragmc.multiblocked.api.tile.ComponentTileEntity)1 ControllerTileEntity (com.lowdragmc.multiblocked.api.tile.ControllerTileEntity)1 IPartComponent (com.lowdragmc.multiblocked.api.tile.part.IPartComponent)1 CycleBlockStateRenderer (com.lowdragmc.multiblocked.client.renderer.impl.CycleBlockStateRenderer)1 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)1 Array (java.lang.reflect.Array)1 ArrayList (java.util.ArrayList)1 EnumMap (java.util.EnumMap)1 HashMap (java.util.HashMap)1