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();
}
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();
}
}
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);
}
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();
}
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;
}
}
Aggregations