This repository has been archived by the owner on Sep 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
/
0080-lithium-block.moving_block_shapes.patch
164 lines (158 loc) · 8.59 KB
/
0080-lithium-block.moving_block_shapes.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <2No2Name@web.de>
Date: Fri, 21 Jan 2022 08:41:34 -0500
Subject: [PATCH] lithium: block.moving_block_shapes
Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 7c59d44a3bafdc65f453d77ff3e25cffb742ad6c..636721a111cad13e7329f1157981ca03a8f339b3 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -52,6 +52,74 @@ public class PistonMovingBlockEntity extends BlockEntity {
this.extending = extending;
this.isSourcePiston = source;
}
+ // JettPack start - lithium: block.moving_block_shapes
+ private static final VoxelShape[] PISTON_BASE_WITH_MOVING_HEAD_SHAPES = precomputePistonBaseWithMovingHeadShapes();
+
+ /**
+ * We cache the offset and simplified VoxelShapes that are otherwise constructed on every call of getCollisionShape.
+ * For each offset direction and distance (6 directions, 2 distances each, and no direction with 0 distance) we
+ * store the offset and simplified VoxelShapes in the original VoxelShape when they are accessed the first time.
+ * We use safe publication, because both the Render and Server thread are using the cache.
+ *
+ * @param blockShape the original shape, must not be modified after passing it as an argument to this method
+ * @param offset the offset distance
+ * @param direction the offset direction
+ * @return blockShape offset and simplified
+ */
+ private static VoxelShape getOffsetAndSimplified(VoxelShape blockShape, float offset, Direction direction) {
+ VoxelShape offsetSimplifiedShape = blockShape.getOffsetSimplifiedShape(offset, direction);
+ if (offsetSimplifiedShape == null) {
+ //create the offset shape and store it for later use
+ offsetSimplifiedShape = blockShape.move(direction.getStepX() * offset, direction.getStepY() * offset, direction.getStepZ() * offset).optimize();
+ blockShape.setShape(offset, direction, offsetSimplifiedShape);
+ }
+ return offsetSimplifiedShape;
+ }
+
+ /**
+ * Precompute all 18 possible configurations for the merged piston base and head shape.
+ *
+ * @return The array of the merged VoxelShapes, indexed by {@link PistonBlockEntityMixin#getIndexForMergedShape(float, Direction)}
+ */
+ private static VoxelShape[] precomputePistonBaseWithMovingHeadShapes() {
+ float[] offsets = {0f, 0.5f, 1f};
+ Direction[] directions = Direction.values();
+
+ VoxelShape[] mergedShapes = new VoxelShape[offsets.length * directions.length];
+
+ for (Direction facing : directions) {
+ VoxelShape baseShape = Blocks.PISTON.defaultBlockState().setValue(PistonBaseBlock.EXTENDED, true)
+ .setValue(PistonBaseBlock.FACING, facing).getCollisionShape(null, null);
+ for (float offset : offsets) {
+ //this cache is only required for the merged piston head + base shape.
+ //this shape is only used when !this.extending
+ //here: isShort = this.extending != 1.0F - this.progress < 0.25F can be simplified to:
+ //isShort = f < 0.25F , because f = getAmountExtended(this.progress) can be simplified to f == 1.0F - this.progress
+ //therefore isShort is dependent on the offset:
+ boolean isShort = offset < 0.25f;
+
+ VoxelShape headShape = (Blocks.PISTON_HEAD.defaultBlockState().setValue(PistonHeadBlock.FACING, facing))
+ .setValue(PistonHeadBlock.SHORT, isShort).getCollisionShape(null, null);
+
+ VoxelShape offsetHead = headShape.move(facing.getStepX() * offset,
+ facing.getStepY() * offset,
+ facing.getStepZ() * offset);
+ mergedShapes[getIndexForMergedShape(offset, facing)] = Shapes.or(baseShape, offsetHead);
+ }
+
+ }
+
+ return mergedShapes;
+ }
+
+ private static int getIndexForMergedShape(float offset, Direction direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ return -1;
+ }
+ //shape of offset 0 is still dependent on the direction, due to piston head and base being directional blocks
+ return (int) (2 * offset) + (3 * direction.get3DDataValue());
+ }
+ // JettPack end
@Override
public CompoundTag getUpdateTag() {
@@ -351,10 +419,27 @@ public class PistonMovingBlockEntity extends BlockEntity {
}
float f = this.getExtendedProgress(this.progress);
+ // JettPack start - lithium: block.moving_block_shapes
+ if (this.extending || !this.isSourcePiston || !(this.movedState.getBlock() instanceof PistonBaseBlock)) {
+ //here voxelShape2.isEmpty() is guaranteed, vanilla code would call union() which calls simplify()
+ VoxelShape blockShape = blockState.getCollisionShape(world, pos);
+
+ //we cache the simplified shapes, as the simplify() method costs a lot of CPU time and allocates several objects
+ VoxelShape offsetAndSimplified = getOffsetAndSimplified(blockShape, Math.abs(f), f < 0f ? this.direction.getOpposite() : this.direction);
+ return offsetAndSimplified;
+ } else {
+ //retracting piston heads have to act like their base as well, as the base block is replaced with the moving block
+ //f >= 0f is guaranteed (assuming no other mod interferes)
+ int index = getIndexForMergedShape(f, this.direction);
+ return PISTON_BASE_WITH_MOVING_HEAD_SHAPES[index];
+ }
+ /*
double d = (double)((float)this.direction.getStepX() * f);
double e = (double)((float)this.direction.getStepY() * f);
double g = (double)((float)this.direction.getStepZ() * f);
return Shapes.or(voxelShape, blockState.getCollisionShape(world, pos).move(d, e, g));
+ */
+ // JettPack end
}
}
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
index 2182afd1b95acf14c55bddfeec17dae0a63e1f00..461ac9a464c4a66e302798032c6019bb60f6862b 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
@@ -26,6 +26,44 @@ public abstract class VoxelShape {
}
// Paper end
+ // JettPack start - lithium: block.moving_block_shapes
+ private volatile VoxelShape[] offsetAndSimplified;
+
+ public void setShape(float offset, Direction direction, VoxelShape offsetShape) {
+ if (offsetShape == null) {
+ throw new IllegalArgumentException("offsetShape must not be null!");
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ VoxelShape[] offsetAndSimplifiedShapes = this.offsetAndSimplified;
+ if (offsetAndSimplifiedShapes == null) {
+ offsetAndSimplifiedShapes = new VoxelShape[1 + 2 * 6];
+ } else {
+ offsetAndSimplifiedShapes = offsetAndSimplifiedShapes.clone();
+ }
+ offsetAndSimplifiedShapes[index] = offsetShape;
+ this.offsetAndSimplified = offsetAndSimplifiedShapes;
+ }
+
+ public VoxelShape getOffsetSimplifiedShape(float offset, Direction direction) {
+ VoxelShape[] offsetAndSimplified = this.offsetAndSimplified;
+ if (offsetAndSimplified == null) {
+ return null;
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ return offsetAndSimplified[index];
+ }
+
+ private static int getIndexForOffsetSimplifiedShapes(float offset, Direction direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ throw new IllegalArgumentException("offset must be one of {0f, 0.5f, 1f}");
+ }
+ if (offset == 0f) {
+ return 0; //can treat offsetting by 0 in all directions the same
+ }
+ return (int) (2 * offset) + 2 * direction.get3DDataValue();
+ }
+ // JettPack end
+
protected VoxelShape(DiscreteVoxelShape voxels) { // Paper - protected
this.shape = voxels;
}