diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java
index 993d116..c6a18fa 100644
--- a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java
+++ b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java
@@ -106,7 +106,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
VoxelShape newShape = partState.getBoundingShape(null);
for (Entry e : parts) {
VoxelShape existingShape = e.state.getBoundingShape(e);
- if (ShapeUtils.intersect(newShape, existingShape)) {
+ if (ShapeUtils.intersect(newShape, existingShape) && !(partState.canIntersectWith(e.state) && e.state.canIntersectWith(partState))) {
return false;
}
}
diff --git a/src/main/java/net/shadowfacts/simplemultipart/multipart/Multipart.java b/src/main/java/net/shadowfacts/simplemultipart/multipart/Multipart.java
index 102f5ab..240f7d5 100644
--- a/src/main/java/net/shadowfacts/simplemultipart/multipart/Multipart.java
+++ b/src/main/java/net/shadowfacts/simplemultipart/multipart/Multipart.java
@@ -95,6 +95,20 @@ public abstract class Multipart {
@Deprecated
public abstract VoxelShape getBoundingShape(MultipartState state, /*@Nullable*/ MultipartView view);
+ /**
+ * Determines if this multipart can be placed in the same block as another part, even if their bounding boxes intersect.
+ *
+ * Can be overriden, should only be called via {@link MultipartState#canIntersectWith(MultipartState)}
+ *
+ * @param self The state for this part.
+ * @param other The other part that already exists.
+ * @return If the multiparts can coexist.
+ */
+ @Deprecated
+ public boolean canIntersectWith(MultipartState self, MultipartState other) {
+ return false;
+ }
+
/**
* @return The loot table ID used for to determine the drops by the default {@link Multipart#getDroppedStacks(MultipartView, LootContext.Builder)} implementation.
*/
@@ -146,6 +160,9 @@ public abstract class Multipart {
/**
* Called after this multipart (and it's entity, if there is one) has been added to the container.
+ *
+ * Can be overriden, should only be called via {@link MultipartState#onPartAdded(MultipartView)}
+ *
* @param view The view of this part.
*/
@Deprecated
@@ -154,6 +171,9 @@ public abstract class Multipart {
/**
* Called after this part has been removed from its container.
+ *
+ * Can be overriden, should only be called via {@link MultipartState#onPartRemoved(MultipartView)}
+ *
* @param view The view of this part.
* The multipart entity and container in this view are still present, but the part is no longer in the container.
*/
diff --git a/src/main/java/net/shadowfacts/simplemultipart/multipart/MultipartState.java b/src/main/java/net/shadowfacts/simplemultipart/multipart/MultipartState.java
index b7adf3a..1cb3152 100644
--- a/src/main/java/net/shadowfacts/simplemultipart/multipart/MultipartState.java
+++ b/src/main/java/net/shadowfacts/simplemultipart/multipart/MultipartState.java
@@ -41,6 +41,14 @@ public class MultipartState extends AbstractPropertyContainer