Search in sources :

Example 6 with WireFace

use of pl.asie.charset.api.wires.WireFace 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 WireFace

use of pl.asie.charset.api.wires.WireFace 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 WireFace

use of pl.asie.charset.api.wires.WireFace in project Charset by CharsetMC.

the class TileWire method readNBTData.

@Override
public void readNBTData(NBTTagCompound nbt, boolean isClient) {
    if (nbt.hasKey("f")) {
        WireProvider factory = WireManager.REGISTRY.getValue(nbt.getByte("f"));
        if (factory != null) {
            WireFace location = WireFace.VALUES[nbt.getByte("l")];
            wire = factory.create(this, location);
            wire.readNBTData(nbt, isClient);
        }
        if (isClient) {
            markBlockForRenderUpdate();
        }
    } else {
        if (wire != null) {
            wire = null;
            if (isClient) {
                markBlockForRenderUpdate();
            }
        }
    }
}
Also used : WireFace(pl.asie.charset.api.wires.WireFace)

Example 9 with WireFace

use of pl.asie.charset.api.wires.WireFace in project Charset by CharsetMC.

the class ItemWire method placeBlockAtTested.

@Override
public boolean placeBlockAtTested(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, IBlockState newState) {
    WireProvider factory = WireManager.REGISTRY.getValue(stack.getMetadata() >> 1);
    WireFace location = (stack.getMetadata() & 1) != 0 ? WireFace.CENTER : WireFace.get(facing.getOpposite());
    if (!factory.canPlace(world, pos, location)) {
        return false;
    }
    if (factory.canProvidePower()) {
        newState = newState.withProperty(BlockWire.REDSTONE, true);
    }
    if (super.placeBlockAtTested(stack, player, world, pos, facing, hitX, hitY, hitZ, newState)) {
        TileEntity tileEntity = world.getTileEntity(pos);
        if (tileEntity instanceof TileWire) {
            ((TileWire) tileEntity).onPlacedBy(WireFace.get(facing != null ? facing.getOpposite() : null), stack);
        }
        return true;
    } else {
        return false;
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) WireFace(pl.asie.charset.api.wires.WireFace)

Example 10 with WireFace

use of pl.asie.charset.api.wires.WireFace 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)

Aggregations

WireFace (pl.asie.charset.api.wires.WireFace)11 EnumFacing (net.minecraft.util.EnumFacing)6 IMultipartContainer (mcmultipart.multipart.IMultipartContainer)4 IBlockState (net.minecraft.block.state.IBlockState)3 TileEntity (net.minecraft.tileentity.TileEntity)3 BlockPos (net.minecraft.util.BlockPos)3 Block (net.minecraft.block.Block)2 ItemStack (net.minecraft.item.ItemStack)2 AxisAlignedBB (net.minecraft.util.math.AxisAlignedBB)2 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 List (java.util.List)1 Nullable (javax.annotation.Nullable)1 IPartInfo (mcmultipart.api.container.IPartInfo)1 IMultipart (mcmultipart.api.multipart.IMultipart)1 EnumCenterSlot (mcmultipart.api.slot.EnumCenterSlot)1 EnumFaceSlot (mcmultipart.api.slot.EnumFaceSlot)1 IPartSlot (mcmultipart.api.slot.IPartSlot)1 IMultipartWorld (mcmultipart.api.world.IMultipartWorld)1 IMultipart (mcmultipart.multipart.IMultipart)1