Search in sources :

Example 1 with IPartComponent

use of com.lowdragmc.multiblocked.api.tile.part.IPartComponent 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 IPartComponent

use of com.lowdragmc.multiblocked.api.tile.part.IPartComponent in project Multiblocked by Low-Drag-MC.

the class ControllerTileEntity method onStructureInvalid.

public void onStructureInvalid() {
    if (recipeLogic != null) {
        recipeLogic.inValid();
    }
    recipeLogic = null;
    setStatus("unformed");
    // invalid parts
    if (parts != null) {
        for (Long pos : parts) {
            TileEntity tileEntity = level.getBlockEntity(BlockPos.of(pos));
            if (tileEntity instanceof IPartComponent) {
                ((IPartComponent) tileEntity).removedFromController(this);
            }
        }
        parts = null;
    }
    capabilities = null;
    writeCustomData(-1, this::writeState);
    if (Multiblocked.isKubeJSLoaded()) {
        new StructureInvalidEvent(this).post(ScriptType.SERVER, StructureInvalidEvent.ID, getSubID());
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) IPartComponent(com.lowdragmc.multiblocked.api.tile.part.IPartComponent)

Example 3 with IPartComponent

use of com.lowdragmc.multiblocked.api.tile.part.IPartComponent in project Multiblocked by Low-Drag-MC.

the class ControllerTileEntity method onStructureFormed.

/**
 * Called when its formed, server side only.
 */
public void onStructureFormed() {
    if (recipeLogic == null) {
        recipeLogic = new RecipeLogic(this);
    }
    if (status.equals("unformed")) {
        setStatus("idle");
    }
    // init capabilities
    Map<Long, EnumMap<IO, Set<MultiblockCapability<?>>>> capabilityMap = state.getMatchContext().get("capabilities");
    if (capabilityMap != null) {
        capabilities = Tables.newCustomTable(new EnumMap<>(IO.class), Object2ObjectOpenHashMap::new);
        for (Map.Entry<Long, EnumMap<IO, Set<MultiblockCapability<?>>>> entry : capabilityMap.entrySet()) {
            TileEntity tileEntity = level.getBlockEntity(BlockPos.of(entry.getKey()));
            if (tileEntity != null) {
                if (settings != null) {
                    Map<MultiblockCapability<?>, Tuple<IO, Direction>> caps = settings.get(entry.getKey());
                    if (caps != null) {
                        for (Map.Entry<MultiblockCapability<?>, Tuple<IO, Direction>> ioEntry : caps.entrySet()) {
                            MultiblockCapability<?> capability = ioEntry.getKey();
                            Tuple<IO, Direction> tuple = ioEntry.getValue();
                            if (tuple == null || capability == null)
                                continue;
                            IO io = tuple.getA();
                            Direction facing = tuple.getB();
                            if (capability.isBlockHasCapability(io, tileEntity)) {
                                if (!capabilities.contains(io, capability)) {
                                    capabilities.put(io, capability, new Long2ObjectOpenHashMap<>());
                                }
                                CapabilityProxy<?> proxy = capability.createProxy(io, tileEntity);
                                proxy.facing = facing;
                                capabilities.get(io, capability).put(entry.getKey().longValue(), proxy);
                            }
                        }
                    }
                } else {
                    entry.getValue().forEach((io, set) -> {
                        for (MultiblockCapability<?> capability : set) {
                            if (capability.isBlockHasCapability(io, tileEntity)) {
                                if (!capabilities.contains(io, capability)) {
                                    capabilities.put(io, capability, new Long2ObjectOpenHashMap<>());
                                }
                                CapabilityProxy<?> proxy = capability.createProxy(io, tileEntity);
                                capabilities.get(io, capability).put(entry.getKey().longValue(), proxy);
                            }
                        }
                    });
                }
            }
        }
    }
    settings = null;
    // init parts
    parts = state.getMatchContext().get("parts");
    if (parts != null) {
        for (Long pos : parts) {
            TileEntity tileEntity = level.getBlockEntity(BlockPos.of(pos));
            if (tileEntity instanceof IPartComponent) {
                ((IPartComponent) tileEntity).addedToController(this);
            }
        }
    }
    writeCustomData(-1, this::writeState);
    if (Multiblocked.isKubeJSLoaded()) {
        new StructureFormedEvent(this).post(ScriptType.SERVER, StructureFormedEvent.ID, getSubID());
    }
}
Also used : IPartComponent(com.lowdragmc.multiblocked.api.tile.part.IPartComponent) MultiblockCapability(com.lowdragmc.multiblocked.api.capability.MultiblockCapability) IO(com.lowdragmc.multiblocked.api.capability.IO) Direction(net.minecraft.util.Direction) TileEntity(net.minecraft.tileentity.TileEntity) RecipeLogic(com.lowdragmc.multiblocked.api.recipe.RecipeLogic) EnumMap(java.util.EnumMap) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) Map(java.util.Map) EnumMap(java.util.EnumMap) HashMap(java.util.HashMap) Tuple(net.minecraft.util.Tuple)

Example 4 with IPartComponent

use of com.lowdragmc.multiblocked.api.tile.part.IPartComponent in project Multiblocked by Low-Drag-MC.

the class GTRenderer method renderModel.

@Override
@OnlyIn(Dist.CLIENT)
public List<BakedQuad> renderModel(IBlockDisplayReader level, BlockPos pos, BlockState state, Direction side, Random rand, IModelData modelData) {
    TileEntity te = level.getBlockEntity(pos);
    if (formedAsController && te instanceof IPartComponent) {
        IPartComponent part = (IPartComponent) te;
        for (IControllerComponent controller : part.getControllers()) {
            if (controller.isFormed() && controller.getRenderer() instanceof GTRenderer) {
                IBakedModel model = getModel(((GTRenderer) controller.getRenderer()).baseTexture).bake(ModelLoader.instance(), ModelLoader.defaultTextureGetter(), ModelFactory.getRotation(part.getFrontFacing()), modelLocation);
                if (model == null)
                    return Collections.emptyList();
                model = new CustomBakedModel(model);
                if (!((CustomBakedModel) model).shouldRenderInLayer(state, rand))
                    return Collections.emptyList();
                return model.getQuads(state, side, rand, modelData);
            }
        }
    }
    return super.renderModel(level, pos, state, side, rand, modelData);
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) IPartComponent(com.lowdragmc.multiblocked.api.tile.part.IPartComponent) IControllerComponent(com.lowdragmc.multiblocked.api.tile.IControllerComponent) IBakedModel(net.minecraft.client.renderer.model.IBakedModel) CustomBakedModel(com.lowdragmc.lowdraglib.client.model.custommodel.CustomBakedModel) OnlyIn(net.minecraftforge.api.distmarker.OnlyIn)

Aggregations

IPartComponent (com.lowdragmc.multiblocked.api.tile.part.IPartComponent)4 TileEntity (net.minecraft.tileentity.TileEntity)4 IO (com.lowdragmc.multiblocked.api.capability.IO)2 MultiblockCapability (com.lowdragmc.multiblocked.api.capability.MultiblockCapability)2 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)2 EnumMap (java.util.EnumMap)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Direction (net.minecraft.util.Direction)2 CustomBakedModel (com.lowdragmc.lowdraglib.client.model.custommodel.CustomBakedModel)1 BlockInfo (com.lowdragmc.lowdraglib.utils.BlockInfo)1 BlockComponent (com.lowdragmc.multiblocked.api.block.BlockComponent)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 PatternMatchContext (com.lowdragmc.multiblocked.api.pattern.util.PatternMatchContext)1 RelativeDirection (com.lowdragmc.multiblocked.api.pattern.util.RelativeDirection)1 RecipeLogic (com.lowdragmc.multiblocked.api.recipe.RecipeLogic)1 ComponentTileEntity (com.lowdragmc.multiblocked.api.tile.ComponentTileEntity)1