Search in sources :

Example 6 with IMultipartContainer

use of mcmultipart.multipart.IMultipartContainer in project Charset by CharsetMC.

the class PartWireNormal method propagate.

@Override
public void propagate(int color) {
    if (DEBUG) {
        System.out.println("--- PROPAGATE " + getPos().toString() + " " + location.name() + " (" + getWorld().getTotalWorldTime() + ") ---");
    }
    int maxSignal = 0;
    int oldSignal = signalLevel;
    int[] neighborLevel = new int[7];
    boolean[] isWire = new boolean[7];
    boolean hasRedstoneWire = false;
    PartWireBase.PROPAGATING = true;
    if (type == WireKind.NORMAL) {
        if (location != WireFace.CENTER) {
            EnumFacing facing = location.facing;
            BlockPos pos = getPos().offset(facing);
            IBlockState state = getWorld().getBlockState(pos);
            int power = WireUtils.getRedstoneLevel(getWorld(), pos, state, facing, location, false);
            if (power > 0) {
                neighborLevel[facing.ordinal()] = Math.min(15, power) << 8 | 0xFF;
            }
        }
    }
    if (internalConnections > 0) {
        for (WireFace location : WireFace.VALUES) {
            if (connectsInternal(location)) {
                isWire[location.ordinal()] = true;
                neighborLevel[location.ordinal()] = getRedstoneLevel(getContainer(), location);
            }
        }
    }
    for (EnumFacing facing : EnumFacing.VALUES) {
        int facidx = facing.ordinal();
        if (facing == location.facing && type == WireKind.NORMAL) {
            BlockPos pos = getPos().offset(facing);
            int i = 0;
            for (EnumFacing enumfacing : EnumFacing.values()) {
                if (enumfacing == facing.getOpposite()) {
                    continue;
                }
                IBlockState state = getWorld().getBlockState(pos.offset(enumfacing));
                Block block = state.getBlock();
                if (!(block instanceof BlockRedstoneWire)) {
                    int power = WireUtils.getRedstoneLevel(getWorld(), pos.offset(enumfacing), state, enumfacing, location, true);
                    if (power >= 15) {
                        i = 15;
                        break;
                    }
                    if (power > i) {
                        i = power;
                    }
                }
            }
            if (i > 0) {
                neighborLevel[facidx] = (i << 8) | 0xFF;
            }
        } else if (connectsExternal(facing)) {
            BlockPos pos = getPos().offset(facing);
            IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), pos);
            if (WireUtils.getWire(container, location) != null) {
                isWire[facidx] = true;
                neighborLevel[facidx] = getRedstoneLevel(container, location);
            } else {
                IBlockState state = getWorld().getBlockState(pos);
                int power = WireUtils.getRedstoneLevel(getWorld(), pos, state, facing, location, true);
                if (state.getBlock() instanceof BlockRedstoneWire) {
                    isWire[facidx] = true;
                    hasRedstoneWire = true;
                    power--;
                }
                if (power > 0) {
                    neighborLevel[facidx] = (Math.min(power, 15) << 8) | 0xFF;
                }
            }
        } else if (connectsCorner(facing)) {
            IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), getPos().offset(facing).offset(location.facing));
            if (container != null) {
                isWire[facidx] = true;
                neighborLevel[facidx] = getRedstoneLevel(container, WireFace.get(facing.getOpposite()));
            }
        }
    }
    PartWireBase.PROPAGATING = false;
    int maxSignalNonWire = 0;
    for (int i = 0; i < 7; i++) {
        if (neighborLevel[i] > maxSignal) {
            maxSignal = neighborLevel[i];
        }
        if (!isWire[i] && neighborLevel[i] > maxSignalNonWire) {
            maxSignalNonWire = neighborLevel[i];
        }
    }
    if (DEBUG) {
        System.out.println("ConnectionCache: " + Integer.toBinaryString(internalConnections) + " " + Integer.toBinaryString(externalConnections) + " " + Integer.toBinaryString(cornerConnections));
        System.out.println("Levels: " + Arrays.toString(neighborLevel));
    }
    if (maxSignal > signalLevel) {
        signalLevel = maxSignal - 1;
        if ((signalLevel & 0xFF) == 0 || (signalLevel & 0xFF) == 0xFF) {
            signalLevel = 0;
        }
    } else {
        signalLevel = maxSignalNonWire;
    }
    if (oldSignal == signalLevel) {
        return;
    }
    if (DEBUG) {
        System.out.println("Switch: " + oldSignal + " -> " + signalLevel);
    }
    if (signalLevel == 0) {
        for (WireFace nLoc : WireFace.VALUES) {
            if (connectsInternal(nLoc)) {
                if (neighborLevel[nLoc.ordinal()] > 0) {
                    WireUtils.getWire(getContainer(), nLoc).onSignalChanged(type.color());
                }
            } else if (nLoc != WireFace.CENTER) {
                EnumFacing facing = nLoc.facing;
                if (connectsExternal(facing)) {
                    IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), getPos().offset(facing));
                    if (container == null || WireUtils.getWire(container, location) == null || neighborLevel[facing.ordinal()] > 0) {
                        propagateNotify(facing, type.color());
                    }
                } else if (connectsCorner(facing)) {
                    if (neighborLevel[nLoc.ordinal()] > 0) {
                        propagateNotifyCorner(location.facing, facing, type.color());
                    }
                } else if (type == WireKind.NORMAL && facing.getOpposite() != location.facing) {
                    TileEntity nt = getWorld().getTileEntity(getPos().offset(facing));
                    if (!(nt instanceof IRedstoneReceiver)) {
                        getWorld().notifyBlockOfStateChange(getPos().offset(facing), MCMultiPartMod.multipart);
                    }
                }
            }
        }
    } else {
        for (WireFace nLoc : WireFace.VALUES) {
            if (neighborLevel[nLoc.ordinal()] < signalLevel - 1 || neighborLevel[nLoc.ordinal()] > (signalLevel + 1)) {
                if (connectsInternal(nLoc)) {
                    WireUtils.getWire(getContainer(), nLoc).onSignalChanged(type.color());
                } else if (nLoc != WireFace.CENTER) {
                    EnumFacing facing = nLoc.facing;
                    if (connectsExternal(facing)) {
                        propagateNotify(facing, type.color());
                    } else if (connectsCorner(facing)) {
                        propagateNotifyCorner(location.facing, facing, type.color());
                    } else if (type == WireKind.NORMAL && facing.getOpposite() != location.facing) {
                        TileEntity nt = getWorld().getTileEntity(getPos().offset(facing));
                        if (!(nt instanceof IRedstoneReceiver)) {
                            getWorld().notifyBlockOfStateChange(getPos().offset(facing), MCMultiPartMod.multipart);
                        }
                    }
                }
            }
        }
    }
    if (type == WireKind.NORMAL) {
        if ((oldSignal & 0xF00) != (signalLevel & 0xF00)) {
            scheduleRenderUpdate();
            if (location != WireFace.CENTER) {
                BlockPos uPos = getPos().offset(location.facing);
                getWorld().notifyNeighborsOfStateExcept(uPos, MCMultiPartMod.multipart, location.facing.getOpposite());
            }
        }
    } else {
        if ((oldSignal & 0xF00) != (signalLevel & 0xF00)) {
            if (location != WireFace.CENTER) {
                getWorld().notifyBlockOfStateChange(getPos().offset(location.facing), MCMultiPartMod.multipart);
            }
        }
    }
    finishPropagation();
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) IMultipartContainer(mcmultipart.multipart.IMultipartContainer) EnumFacing(net.minecraft.util.EnumFacing) WireFace(pl.asie.charset.api.wires.WireFace) TileEntity(net.minecraft.tileentity.TileEntity) Block(net.minecraft.block.Block) BlockPos(net.minecraft.util.BlockPos) IRedstoneReceiver(pl.asie.charset.api.wires.IRedstoneReceiver) BlockRedstoneWire(net.minecraft.block.BlockRedstoneWire)

Example 7 with IMultipartContainer

use of mcmultipart.multipart.IMultipartContainer in project Charset by CharsetMC.

the class PartWireBase method updateConnections.

public void updateConnections() {
    Set<WireFace> validSides = EnumSet.noneOf(WireFace.class);
    Set<WireFace> invalidCornerSides = EnumSet.noneOf(WireFace.class);
    for (WireFace facing : WireFace.VALUES) {
        if (facing == location) {
            continue;
        }
        if (facing != WireFace.CENTER && location != WireFace.CENTER && location.facing.getAxis() == facing.facing.getAxis()) {
            continue;
        }
        validSides.add(facing);
    }
    int oldConnectionCache = internalConnections << 12 | externalConnections << 6 | cornerConnections;
    internalConnections = externalConnections = cornerConnections = occludedSides = cornerOccludedSides = 0;
    // Occlusion test
    EnumFacing[] connFaces = WireUtils.getConnectionsForRender(location);
    List<IMultipart> parts = new ArrayList<IMultipart>();
    for (IMultipart p : getContainer().getParts()) {
        if (p != this && p instanceof IOccludingPart && !(p instanceof PartWireBase)) {
            parts.add(p);
        }
    }
    if (parts.size() > 0) {
        for (int i = 0; i < connFaces.length; i++) {
            WireFace face = WireFace.get(connFaces[i]);
            if (validSides.contains(face)) {
                boolean found = false;
                AxisAlignedBB mask = getBox(i + 1);
                if (mask != null) {
                    if (!OcclusionHelper.occlusionTest(parts, this, mask)) {
                        occludedSides |= 1 << connFaces[i].ordinal();
                        validSides.remove(face);
                        found = true;
                    }
                }
                if (!found && location != WireFace.CENTER) {
                    BlockPos cPos = getPos().offset(connFaces[i]);
                    AxisAlignedBB cornerMask = getCornerBox(i ^ 1);
                    if (cornerMask != null) {
                        IMultipartContainer cornerContainer = MultipartHelper.getPartContainer(getWorld(), cPos);
                        if (cornerContainer != null) {
                            if (!OcclusionHelper.occlusionTest(cornerContainer.getParts(), cornerMask)) {
                                cornerOccludedSides |= 1 << connFaces[i].ordinal();
                                invalidCornerSides.add(face);
                            }
                        } else {
                            List<AxisAlignedBB> boxes = new ArrayList<AxisAlignedBB>();
                            IBlockState cState = getWorld().getBlockState(cPos);
                            cState.getBlock().addCollisionBoxesToList(getWorld(), cPos, cState, cornerMask.offset(cPos.getX(), cPos.getY(), cPos.getZ()), boxes, null);
                            if (boxes.size() > 0) {
                                cornerOccludedSides |= 1 << connFaces[i].ordinal();
                                invalidCornerSides.add(face);
                            }
                        }
                    }
                }
            }
        }
    }
    if (validSides.contains(WireFace.CENTER)) {
        AxisAlignedBB mask = getCenterBox(1 + location.ordinal());
        if (mask != null) {
            if (!OcclusionHelper.occlusionTest(parts, this, mask)) {
                occludedSides |= 1 << 6;
                validSides.remove(WireFace.CENTER);
            }
        }
    }
    for (WireFace facing : validSides) {
        if (WireUtils.canConnectInternal(this, facing)) {
            internalConnections |= 1 << facing.ordinal();
        } else if (facing != WireFace.CENTER) {
            if (WireUtils.canConnectExternal(this, facing.facing)) {
                externalConnections |= 1 << facing.ordinal();
            } else if (location != WireFace.CENTER && !invalidCornerSides.contains(facing) && WireUtils.canConnectCorner(this, facing.facing)) {
                cornerConnections |= 1 << facing.ordinal();
            }
        }
    }
    int newConnectionCache = internalConnections << 12 | externalConnections << 6 | cornerConnections;
    if (oldConnectionCache != newConnectionCache) {
        scheduleNeighborUpdate((oldConnectionCache ^ newConnectionCache) >> 6);
        schedulePropagationUpdate();
        scheduleRenderUpdate();
    }
}
Also used : AxisAlignedBB(net.minecraft.util.AxisAlignedBB) IBlockState(net.minecraft.block.state.IBlockState) IMultipartContainer(mcmultipart.multipart.IMultipartContainer) EnumFacing(net.minecraft.util.EnumFacing) ArrayList(java.util.ArrayList) WireFace(pl.asie.charset.api.wires.WireFace) BlockPos(net.minecraft.util.BlockPos) IMultipart(mcmultipart.multipart.IMultipart) IOccludingPart(mcmultipart.multipart.IOccludingPart)

Example 8 with IMultipartContainer

use of mcmultipart.multipart.IMultipartContainer in project Charset by CharsetMC.

the class WireUtils method canConnectInternal.

public static boolean canConnectInternal(PartWireBase wire, WireFace side) {
    WireFace location = wire.location;
    IMultipartContainer container = wire.getContainer();
    if (side == location) {
        return false;
    }
    if (side != WireFace.CENTER && location != WireFace.CENTER) {
        if (isBlockingPart(container, PartSlot.getEdgeSlot(side.facing, location.facing))) {
            return false;
        }
    }
    PartWireBase wire2 = getWire(container, side);
    return wire2 != null && wire2.type.connects(wire.type);
}
Also used : PartWireBase(pl.asie.charset.wires.logic.PartWireBase) IMultipartContainer(mcmultipart.multipart.IMultipartContainer) WireFace(pl.asie.charset.api.wires.WireFace)

Example 9 with IMultipartContainer

use of mcmultipart.multipart.IMultipartContainer in project Charset by CharsetMC.

the class PartWireBundled method propagate.

private void propagate(int color, byte[][] nValues) {
    int maxSignal = 0;
    int[] neighborLevel = new int[7];
    boolean[] isWire = new boolean[7];
    PartWireBase.PROPAGATING = true;
    if (internalConnections > 0) {
        for (WireFace location : WireFace.VALUES) {
            if (connectsInternal(location)) {
                isWire[location.ordinal()] = true;
                neighborLevel[location.ordinal()] = WireUtils.getBundledWireLevel(getContainer(), location, color);
            }
        }
    }
    for (EnumFacing facing : EnumFacing.VALUES) {
        if (connectsExternal(facing)) {
            if (nValues[facing.ordinal()] != null) {
                int v = nValues[facing.ordinal()][color] << 8;
                if (v != 0) {
                    neighborLevel[facing.ordinal()] = v | 0xFF;
                }
            } else {
                IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), getPos().offset(facing));
                if (container != null) {
                    isWire[facing.ordinal()] = true;
                    neighborLevel[facing.ordinal()] = WireUtils.getBundledWireLevel(container, location, color);
                }
            }
        } else if (connectsCorner(facing)) {
            BlockPos cornerPos = getPos().offset(facing).offset(location.facing);
            IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), cornerPos);
            if (container != null) {
                isWire[facing.ordinal()] = true;
                neighborLevel[facing.ordinal()] = WireUtils.getBundledWireLevel(container, WireFace.get(facing.getOpposite()), color);
            }
        }
    }
    PartWireBase.PROPAGATING = false;
    int newSignal = 0;
    for (int j = 0; j < 7; j++) {
        if (neighborLevel[j] > maxSignal) {
            maxSignal = neighborLevel[j];
        }
        if (!isWire[j] && neighborLevel[j] > newSignal) {
            newSignal = neighborLevel[j];
        }
    }
    if (DEBUG) {
        System.out.println("[" + color + "] Levels: " + Arrays.toString(neighborLevel));
    }
    if (maxSignal > signalLevel[color] && maxSignal > 1) {
        newSignal = maxSignal - 1;
        if ((newSignal & 0xFF) == 0 || (newSignal & 0xFF) == 0xFF) {
            newSignal = 0;
        }
    }
    if (newSignal == signalLevel[color]) {
        return;
    }
    signalLevel[color] = newSignal;
    signalValue[color] = (byte) (newSignal >> 8);
    if (newSignal == 0) {
        for (WireFace nLoc : WireFace.VALUES) {
            if (connectsInternal(nLoc)) {
                if (neighborLevel[nLoc.ordinal()] > 0) {
                    WireUtils.getWire(getContainer(), nLoc).onSignalChanged(color);
                }
            } else if (nLoc != WireFace.CENTER) {
                EnumFacing facing = nLoc.facing;
                if (connectsExternal(facing)) {
                    IMultipartContainer container = MultipartHelper.getPartContainer(getWorld(), getPos().offset(facing));
                    if (container == null || WireUtils.getWire(container, location) == null || neighborLevel[facing.ordinal()] > 0) {
                        propagateNotify(facing, color);
                    }
                } else if (connectsCorner(facing)) {
                    if (neighborLevel[facing.ordinal()] > 0) {
                        propagateNotifyCorner(location.facing, facing, color);
                    }
                }
            }
        }
    } else {
        for (WireFace nLoc : WireFace.VALUES) {
            if (neighborLevel[nLoc.ordinal()] < newSignal - 1 || neighborLevel[nLoc.ordinal()] > (newSignal + 1)) {
                if (connectsInternal(nLoc)) {
                    WireUtils.getWire(getContainer(), nLoc).onSignalChanged(color);
                } else if (nLoc != WireFace.CENTER) {
                    EnumFacing facing = nLoc.facing;
                    if (connectsExternal(facing)) {
                        propagateNotify(facing, color);
                    } else if (connectsCorner(facing)) {
                        propagateNotifyCorner(location.facing, facing, color);
                    }
                }
            }
        }
    }
    finishPropagation();
}
Also used : IMultipartContainer(mcmultipart.multipart.IMultipartContainer) EnumFacing(net.minecraft.util.EnumFacing) BlockPos(net.minecraft.util.BlockPos) WireFace(pl.asie.charset.api.wires.WireFace)

Example 10 with IMultipartContainer

use of mcmultipart.multipart.IMultipartContainer in project Charset by CharsetMC.

the class PipeUtils method getPipe.

public static PartPipe getPipe(World world, BlockPos blockPos, EnumFacing side) {
    IMultipartContainer container = MultipartHelper.getPartContainer(world, blockPos);
    if (container == null) {
        return null;
    }
    if (side != null) {
        ISlottedPart part = container.getPartInSlot(PartSlot.getFaceSlot(side));
        if (part instanceof IMicroblock.IFaceMicroblock && !((IMicroblock.IFaceMicroblock) part).isFaceHollow()) {
            return null;
        }
    }
    ISlottedPart part = container.getPartInSlot(PartSlot.CENTER);
    if (part instanceof PartPipe) {
        return (PartPipe) part;
    } else {
        return null;
    }
}
Also used : IMultipartContainer(mcmultipart.multipart.IMultipartContainer) IMicroblock(mcmultipart.microblock.IMicroblock) ISlottedPart(mcmultipart.multipart.ISlottedPart)

Aggregations

IMultipartContainer (mcmultipart.multipart.IMultipartContainer)14 BlockPos (net.minecraft.util.BlockPos)7 EnumFacing (net.minecraft.util.EnumFacing)6 Block (net.minecraft.block.Block)4 BlockRedstoneWire (net.minecraft.block.BlockRedstoneWire)4 IBlockState (net.minecraft.block.state.IBlockState)4 TileEntity (net.minecraft.tileentity.TileEntity)4 WireFace (pl.asie.charset.api.wires.WireFace)4 PartWireBase (pl.asie.charset.wires.logic.PartWireBase)4 IMultipart (mcmultipart.multipart.IMultipart)3 ArrayList (java.util.ArrayList)2 World (net.minecraft.world.World)2 UUID (java.util.UUID)1 IMicroblock (mcmultipart.microblock.IMicroblock)1 IOccludingPart (mcmultipart.multipart.IOccludingPart)1 IRedstonePart (mcmultipart.multipart.IRedstonePart)1 ISlottedPart (mcmultipart.multipart.ISlottedPart)1 BlockBasePressurePlate (net.minecraft.block.BlockBasePressurePlate)1 BlockButton (net.minecraft.block.BlockButton)1 BlockDaylightDetector (net.minecraft.block.BlockDaylightDetector)1