@@ -83,6 +83,182 @@ public Surround getOpposite() {
8383 }
8484 }
8585
86+ /**
87+ * Unified shell direction enum for TrunkShellBlock.
88+ * Contains all 24 positions: 8 inner (distance 1) + 16 outer (distance 2)
89+ */
90+ /**
91+ * Unified shell direction enum for TrunkShellBlock.
92+ * Contains all 48 positions: 8 inner (distance 1) + 16 outer (distance 2) + 24 outermost (distance 3)
93+ */
94+ public enum ShellDirection implements StringRepresentable {
95+ // Inner ring (distance 1) - 8 positions
96+ N (0 , -1 , 1 ),
97+ NE (1 , -1 , 1 ),
98+ E (1 , 0 , 1 ),
99+ SE (1 , 1 , 1 ),
100+ S (0 , 1 , 1 ),
101+ SW (-1 , 1 , 1 ),
102+ W (-1 , 0 , 1 ),
103+ NW (-1 , -1 , 1 ),
104+
105+ // Outer ring (distance 2) - 16 positions
106+ N2 (0 , -2 , 2 ),
107+ NE2 (1 , -2 , 2 ),
108+ E2 (2 , 0 , 2 ),
109+ SE2 (1 , 2 , 2 ),
110+ S2 (0 , 2 , 2 ),
111+ SW2 (-1 , 2 , 2 ),
112+ W2 (-2 , 0 , 2 ),
113+ NW2 (-1 , -2 , 2 ),
114+ NNE (2 , -2 , 2 ),
115+ ENE (2 , -1 , 2 ),
116+ ESE (2 , 1 , 2 ),
117+ SSE (2 , 2 , 2 ),
118+ SSW (-2 , 2 , 2 ),
119+ WSW (-2 , 1 , 2 ),
120+ WNW (-2 , -1 , 2 ),
121+ NNW (-2 , -2 , 2 ),
122+
123+ // Outermost ring (distance 3) - 24 positions
124+ N3 (0 , -3 , 3 ),
125+ E3 (3 , 0 , 3 ),
126+ S3 (0 , 3 , 3 ),
127+ W3 (-3 , 0 , 3 ),
128+ CORNER_NE (3 , -3 , 3 ),
129+ CORNER_SE (3 , 3 , 3 ),
130+ CORNER_SW (-3 , 3 , 3 ),
131+ CORNER_NW (-3 , -3 , 3 ),
132+ N3E (1 , -3 , 3 ),
133+ N3EE (2 , -3 , 3 ),
134+ N3W (-1 , -3 , 3 ),
135+ N3WW (-2 , -3 , 3 ),
136+ E3N (3 , -1 , 3 ),
137+ E3NN (3 , -2 , 3 ),
138+ E3S (3 , 1 , 3 ),
139+ E3SS (3 , 2 , 3 ),
140+ S3E (1 , 3 , 3 ),
141+ S3EE (2 , 3 , 3 ),
142+ S3W (-1 , 3 , 3 ),
143+ S3WW (-2 , 3 , 3 ),
144+ W3N (-3 , -1 , 3 ),
145+ W3NN (-3 , -2 , 3 ),
146+ W3S (-3 , 1 , 3 ),
147+ W3SS (-3 , 2 , 3 );
148+
149+ private static final ShellDirection [] INNER = {N , NE , E , SE , S , SW , W , NW };
150+ private static final ShellDirection [] OUTER = {N2 , NE2 , E2 , SE2 , S2 , SW2 , W2 , NW2 , NNE , ENE , ESE , SSE , SSW , WSW , WNW , NNW };
151+ private static final ShellDirection [] OUTERMOST = {N3 , E3 , S3 , W3 , CORNER_NE , CORNER_SE , CORNER_SW , CORNER_NW , N3E , N3EE , N3W , N3WW , E3N , E3NN , E3S , E3SS , S3E , S3EE , S3W , S3WW , W3N , W3NN , W3S , W3SS };
152+
153+ private final BlockPos offset ;
154+ private final String name ;
155+ private final int shellLevel ;
156+
157+ ShellDirection (int x , int z , int shellLevel ) {
158+ this .offset = new BlockPos (x , 0 , z );
159+ this .name = name ().toLowerCase (java .util .Locale .ROOT );
160+ this .shellLevel = shellLevel ;
161+ }
162+
163+ public BlockPos getOffset () {
164+ return offset ;
165+ }
166+
167+ /** Returns 1 for inner, 2 for outer, 3 for outermost */
168+ public int getShellLevel () {
169+ return shellLevel ;
170+ }
171+
172+ public boolean isInner () {
173+ return shellLevel == 1 ;
174+ }
175+
176+ public boolean isOuter () {
177+ return shellLevel == 2 ;
178+ }
179+
180+ public boolean isOutermost () {
181+ return shellLevel == 3 ;
182+ }
183+
184+ @ Override
185+ @ Nonnull
186+ public String getSerializedName () {
187+ return name ;
188+ }
189+
190+ public ShellDirection getOpposite () {
191+ return switch (this ) {
192+ // Inner ring
193+ case N -> S ;
194+ case NE -> SW ;
195+ case E -> W ;
196+ case SE -> NW ;
197+ case S -> N ;
198+ case SW -> NE ;
199+ case W -> E ;
200+ case NW -> SE ;
201+ // Outer ring
202+ case N2 -> S2 ;
203+ case NE2 -> SW2 ;
204+ case E2 -> W2 ;
205+ case SE2 -> NW2 ;
206+ case S2 -> N2 ;
207+ case SW2 -> NE2 ;
208+ case W2 -> E2 ;
209+ case NW2 -> SE2 ;
210+ case NNE -> SSW ;
211+ case ENE -> WSW ;
212+ case ESE -> WNW ;
213+ case SSE -> NNW ;
214+ case SSW -> NNE ;
215+ case WSW -> ENE ;
216+ case WNW -> ESE ;
217+ case NNW -> SSE ;
218+ // Outermost ring
219+ case N3 -> S3 ;
220+ case E3 -> W3 ;
221+ case S3 -> N3 ;
222+ case W3 -> E3 ;
223+ case CORNER_NE -> CORNER_SW ;
224+ case CORNER_SE -> CORNER_NW ;
225+ case CORNER_SW -> CORNER_NE ;
226+ case CORNER_NW -> CORNER_SE ;
227+ case N3E -> S3W ;
228+ case N3EE -> S3WW ;
229+ case N3W -> S3E ;
230+ case N3WW -> S3EE ;
231+ case E3N -> W3S ;
232+ case E3NN -> W3SS ;
233+ case E3S -> W3N ;
234+ case E3SS -> W3NN ;
235+ case S3E -> N3W ;
236+ case S3EE -> N3WW ;
237+ case S3W -> N3E ;
238+ case S3WW -> N3EE ;
239+ case W3N -> E3S ;
240+ case W3NN -> E3SS ;
241+ case W3S -> E3N ;
242+ case W3SS -> E3NN ;
243+ };
244+ }
245+
246+ /** Get inner ring directions only (8 positions at distance 1) */
247+ public static ShellDirection [] innerValues () {
248+ return INNER ;
249+ }
250+
251+ /** Get outer ring directions only (16 positions at distance 2) */
252+ public static ShellDirection [] outerValues () {
253+ return OUTER ;
254+ }
255+
256+ /** Get outermost ring directions only (24 positions at distance 3) */
257+ public static ShellDirection [] outermostValues () {
258+ return OUTERMOST ;
259+ }
260+ }
261+
86262 public static boolean isSurroundedByLoadedChunks (Level level , BlockPos pos ) {
87263 for (Surround surr : CoordUtils .Surround .values ()) {
88264 Vec3i dir = surr .getOffset ();
0 commit comments