@@ -58,13 +58,6 @@ public final class StructureDamageEngine {
5858 */
5959 private static final int GAP_TOLERANCE = 6 ;
6060
61- /**
62- * The least of its voxel a block is ever treated as filling. A pane is not a wall and should not
63- * cost like one, but nothing is free either: a body still has to break the thing off its mounting,
64- * and a floor here is what stops a torch or a tripwire from being a hole in a hull.
65- */
66- private static final double MIN_OCCUPANCY = 0.1D ;
67-
6861 /** One whole voxel at the origin — the box a block is asked to report its collision shape within. */
6962 private static final AxisAlignedBB FULL_VOXEL = new AxisAlignedBB (0.0D , 0.0D , 0.0D , 1.0D , 1.0D , 1.0D );
7063
@@ -419,7 +412,7 @@ public static int stageCost(World world, BlockPos pos, double areaFactor, Impact
419412 }
420413
421414 /**
422- * How much of its voxel this block actually fills, in {@code [MIN_OCCUPANCY , 1]}.
415+ * How much of its voxel this block actually fills, in {@code [0 , 1]}.
423416 *
424417 * <h3>Why a price has to know this at all</h3>
425418 * <p>The law is an energy per unit of VOLUME removed — that is the whole of why the mechanical and
@@ -437,6 +430,18 @@ public static int stageCost(World world, BlockPos pos, double areaFactor, Impact
437430 * states its real shape, box by box, so that is what is summed. Overlapping boxes would double
438431 * count, which is why the sum is clamped: over-counting can only ever produce "a full cube", the
439432 * answer we started from.</p>
433+ *
434+ * <h3>There is no floor under it, and nothing is free anyway</h3>
435+ * <p>A floor was tried and removed: it was a MULTIPLIER, so it priced "the least a block can cost"
436+ * out of that block's own material, and what it was meant to represent — the work of breaking a
437+ * thing off its mounting — has nothing to do with what the thing is made of. What actually keeps a
438+ * near-empty voxel from being free is {@code STAGE_COST_BASE}, which is material-independent and
439+ * already inside the product: a standing torch answers 0.024 here and still costs 6 against the
440+ * 1000 a full block of stone costs. Below that the price itself floors at 1.</p>
441+ *
442+ * <p>The floor's stated reason — that a torch must not be a hole in a hull — does not survive
443+ * being looked at: a voxel holding a torch is a voxel holding no hull block. The hole is the
444+ * builder's, and pricing it dearly does not fill it.</p>
440445 */
441446 private static double occupancyOf (World world , BlockPos pos ) {
442447 if (world == null || pos == null ) {
@@ -451,17 +456,19 @@ private static double occupancyOf(World world, BlockPos pos) {
451456 volume += (box .maxX - box .minX ) * (box .maxY - box .minY ) * (box .maxZ - box .minZ );
452457 }
453458 if (volume > 0.0D ) {
454- return Math .max ( MIN_OCCUPANCY , Math . min (1.0D , volume ) );
459+ return Math .min (1.0D , volume );
455460 }
456461 // No collision at all — a torch, a plant, a tripwire. It is still SOMETHING, so it falls
457462 // back to the shape it draws itself with rather than to nothing.
458463 AxisAlignedBB drawn = state .getBoundingBox (world , pos );
459464 if (drawn == null ) {
460- return MIN_OCCUPANCY ;
465+ // It states no shape at all. The price floors at 1 rather than at nothing, which is
466+ // the whole of what "still SOMETHING" needs to mean here.
467+ return 0.0D ;
461468 }
462469 double drawnVolume = (drawn .maxX - drawn .minX ) * (drawn .maxY - drawn .minY )
463470 * (drawn .maxZ - drawn .minZ );
464- return Math .max ( MIN_OCCUPANCY , Math . min (1.0D , drawnVolume ) );
471+ return Math .min (1.0D , drawnVolume );
465472 } catch (RuntimeException blockDidNotLikeBeingAsked ) {
466473 // A block may compute its shape from neighbours it expects to be loaded. It costs a full
467474 // cube rather than throwing, which is the answer that changes nothing.
0 commit comments