Skip to content

Commit 71977a5

Browse files
authored
Merge pull request #1124 from HYPER1208-max/HYPER1208-max-patch-1
Hyper1208 max patch 1
2 parents 80c2efb + bb4497e commit 71977a5

File tree

4 files changed

+466
-147
lines changed

4 files changed

+466
-147
lines changed

src/main/java/com/ferreusveritas/dynamictrees/block/branch/ThickBranchBlock.java

Lines changed: 150 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import com.ferreusveritas.dynamictrees.init.DTRegistries;
88
import com.ferreusveritas.dynamictrees.systems.BranchConnectables;
99
import com.ferreusveritas.dynamictrees.util.CoordUtils;
10-
import com.ferreusveritas.dynamictrees.util.CoordUtils.Surround;
10+
import com.ferreusveritas.dynamictrees.util.CoordUtils.ShellDirection;
1111
import net.minecraft.core.BlockPos;
1212
import net.minecraft.core.Direction;
1313
import net.minecraft.resources.ResourceLocation;
@@ -16,6 +16,7 @@
1616
import net.minecraft.world.level.Level;
1717
import net.minecraft.world.level.LevelAccessor;
1818
import net.minecraft.world.level.block.Block;
19+
import net.minecraft.world.level.block.Blocks;
1920
import net.minecraft.world.level.block.state.BlockState;
2021
import net.minecraft.world.level.block.state.StateDefinition;
2122
import net.minecraft.world.level.block.state.properties.IntegerProperty;
@@ -31,10 +32,14 @@
3132

3233
public class ThickBranchBlock extends BasicBranchBlock implements Musable {
3334

34-
public static final int MAX_RADIUS_THICK = 24;
35+
public static final int MAX_RADIUS_THICK = 56;
36+
public static final int RADIUS_TO_INNER_SHELL = 8; // > 8 needs 3×3
37+
public static final int RADIUS_TO_OUTER_SHELL = 24; // > 24 needs 5×5
38+
public static final int RADIUS_TO_OUTERMOST_SHELL = 40; // > 40 needs 7×7
3539

36-
protected static final IntegerProperty RADIUS_DOUBLE = IntegerProperty.create("radius", 1, MAX_RADIUS_THICK); //39 ?
40+
protected static final IntegerProperty RADIUS_DOUBLE = IntegerProperty.create("radius", 1, MAX_RADIUS_THICK);
3741

42+
@Deprecated
3843
public ThickBranchBlock(ResourceLocation name, MapColor mapColor) {
3944
this(name, Properties.of().mapColor(mapColor));
4045
}
@@ -52,8 +57,8 @@ public void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState
5257
builder.add(RADIUS_DOUBLE).add(WATERLOGGED);
5358
}
5459

55-
///////////////////////////////////////////
56-
// GROWTH
60+
///////////////////////////////////////////
61+
// GROWTH
5762
///////////////////////////////////////////
5863

5964
@Override
@@ -69,7 +74,7 @@ public int setRadius(LevelAccessor level, BlockPos pos, int radius, @Nullable Di
6974
if (this.updateTrunkShells(level, pos, radius, flags)) {
7075
return super.setRadius(level, pos, radius, originDir, flags);
7176
}
72-
return super.setRadius(level, pos, MAX_RADIUS, originDir, flags);
77+
return super.setRadius(level, pos, getRadius(level.getBlockState(pos)), originDir, flags);
7378
}
7479

7580
@Override
@@ -79,74 +84,118 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block b
7984
}
8085

8186
private boolean updateTrunkShells(LevelAccessor level, BlockPos pos, int radius, int flags) {
82-
// If the radius is <= 8 then we can just set the block as normal and move on.
83-
if (radius <= MAX_RADIUS) {
87+
boolean needsInnerRing = radius > RADIUS_TO_INNER_SHELL; // > 8
88+
boolean needsOuterRing = radius > RADIUS_TO_OUTER_SHELL; // > 24
89+
boolean needsOutermostRing = radius > RADIUS_TO_OUTERMOST_SHELL; // > 40
90+
91+
// No shells needed
92+
if (!needsInnerRing) {
8493
return true;
8594
}
8695

87-
boolean setable = true;
88-
final ReplaceableState[] repStates = new ReplaceableState[8];
89-
90-
for (Surround dir : Surround.values()) {
91-
final BlockPos dPos = pos.offset(dir.getOffset());
92-
final ReplaceableState rep = getReplaceability(level, dPos, pos);
93-
94-
repStates[dir.ordinal()] = rep;
95-
96+
// === Check inner ring ===
97+
final ReplaceableState[] innerRepStates = new ReplaceableState[8];
98+
ShellDirection[] innerDirs = ShellDirection.innerValues();
99+
for (int i = 0; i < innerDirs.length; i++) {
100+
ShellDirection dir = innerDirs[i];
101+
BlockPos dPos = pos.offset(dir.getOffset());
102+
ReplaceableState rep = getReplaceability(level, dPos, pos, 1);
103+
innerRepStates[i] = rep;
96104
if (rep == ReplaceableState.BLOCKING) {
97-
setable = false;
98-
break;
105+
return false;
99106
}
100107
}
101108

102-
if (setable) {
103-
BlockState trunkState = level.getBlockState(pos);
104-
boolean isWaterlogged = trunkState.hasProperty(WATERLOGGED) && trunkState.getValue(WATERLOGGED);
105-
for (Surround dir : Surround.values()) {
106-
final BlockPos dPos = pos.offset(dir.getOffset());
107-
final ReplaceableState rep = repStates[dir.ordinal()];
108-
final boolean replacingWater = isWaterlogged || level.getBlockState(dPos).getFluidState() == Fluids.WATER.getSource(false);
109+
// === Check outer ring (if needed) ===
110+
final ReplaceableState[] outerRepStates = new ReplaceableState[16];
111+
ShellDirection[] outerDirs = ShellDirection.outerValues();
112+
if (needsOuterRing) {
113+
for (int i = 0; i < outerDirs.length; i++) {
114+
ShellDirection dir = outerDirs[i];
115+
BlockPos dPos = pos.offset(dir.getOffset());
116+
ReplaceableState rep = getReplaceability(level, dPos, pos, 2);
117+
outerRepStates[i] = rep;
118+
if (rep == ReplaceableState.BLOCKING) {
119+
return false;
120+
}
121+
}
122+
}
109123

110-
if (rep == ReplaceableState.REPLACEABLE) {
111-
level.setBlock(dPos, getTrunkShell().defaultBlockState().setValue(TrunkShellBlock.CORE_DIR, dir.getOpposite()).setValue(TrunkShellBlock.WATERLOGGED, replacingWater), flags);
124+
// === Check outermost ring (if needed) ===
125+
final ReplaceableState[] outermostRepStates = new ReplaceableState[24];
126+
ShellDirection[] outermostDirs = ShellDirection.outermostValues();
127+
if (needsOutermostRing) {
128+
for (int i = 0; i < outermostDirs.length; i++) {
129+
ShellDirection dir = outermostDirs[i];
130+
BlockPos dPos = pos.offset(dir.getOffset());
131+
ReplaceableState rep = getReplaceability(level, dPos, pos, 3);
132+
outermostRepStates[i] = rep;
133+
if (rep == ReplaceableState.BLOCKING) {
134+
return false;
112135
}
113136
}
114-
return true;
115137
}
116-
return false;
117-
}
118138

119-
@Override
120-
public int getRadiusForConnection(BlockState state, BlockGetter level, BlockPos pos, BranchBlock from, Direction side, int fromRadius) {
121-
if (from instanceof ThickBranchBlock) {
122-
return getRadius(state);
139+
// === Place shells ===
140+
BlockState trunkState = level.getBlockState(pos);
141+
boolean isWaterlogged = trunkState.hasProperty(WATERLOGGED) && trunkState.getValue(WATERLOGGED);
142+
143+
// Place inner ring
144+
for (int i = 0; i < innerDirs.length; i++) {
145+
ShellDirection dir = innerDirs[i];
146+
BlockPos dPos = pos.offset(dir.getOffset());
147+
ReplaceableState rep = innerRepStates[i];
148+
boolean replacingWater = isWaterlogged || level.getBlockState(dPos).getFluidState() == Fluids.WATER.getSource(false);
149+
150+
if (rep == ReplaceableState.REPLACEABLE) {
151+
level.setBlock(dPos, getTrunkShell().defaultBlockState()
152+
.setValue(TrunkShellBlock.CORE_DIR, dir.getOpposite())
153+
.setValue(TrunkShellBlock.WATERLOGGED, replacingWater), flags);
154+
}
123155
}
124-
return Math.min(getRadius(state), MAX_RADIUS);
125-
}
126156

127-
@Override
128-
protected int getSideConnectionRadius(BlockGetter level, BlockPos pos, int radius, Direction side) {
129-
final BlockPos deltaPos = pos.relative(side);
130-
final BlockState blockState = CoordUtils.getStateSafe(level, deltaPos);
157+
// Place outer ring (if needed)
158+
if (needsOuterRing) {
159+
for (int i = 0; i < outerDirs.length; i++) {
160+
ShellDirection dir = outerDirs[i];
161+
BlockPos dPos = pos.offset(dir.getOffset());
162+
ReplaceableState rep = outerRepStates[i];
163+
boolean replacingWater = isWaterlogged || level.getBlockState(dPos).getFluidState() == Fluids.WATER.getSource(false);
131164

132-
if (blockState == null) {
133-
return 0;
165+
if (rep == ReplaceableState.REPLACEABLE) {
166+
level.setBlock(dPos, getTrunkShell().defaultBlockState()
167+
.setValue(TrunkShellBlock.CORE_DIR, dir.getOpposite())
168+
.setValue(TrunkShellBlock.WATERLOGGED, replacingWater), flags);
169+
}
170+
}
134171
}
135172

136-
final int connectionRadius = TreeHelper.getTreePart(blockState).getRadiusForConnection(blockState, level, deltaPos, this, side, radius);
173+
// Place outermost ring (if needed)
174+
if (needsOutermostRing) {
175+
for (int i = 0; i < outermostDirs.length; i++) {
176+
ShellDirection dir = outermostDirs[i];
177+
BlockPos dPos = pos.offset(dir.getOffset());
178+
ReplaceableState rep = outermostRepStates[i];
179+
boolean replacingWater = isWaterlogged || level.getBlockState(dPos).getFluidState() == Fluids.WATER.getSource(false);
137180

138-
return Math.min(MAX_RADIUS, connectionRadius);
139-
}
181+
if (rep == ReplaceableState.REPLACEABLE) {
182+
level.setBlock(dPos, getTrunkShell().defaultBlockState()
183+
.setValue(TrunkShellBlock.CORE_DIR, dir.getOpposite())
184+
.setValue(TrunkShellBlock.WATERLOGGED, replacingWater), flags);
185+
}
186+
}
187+
}
140188

141-
public ReplaceableState getReplaceability(LevelAccessor level, BlockPos pos, BlockPos corePos) {
189+
return true;
190+
}
142191

192+
public ReplaceableState getReplaceability(LevelAccessor level, BlockPos pos, BlockPos corePos, int ringLevel) {
143193
final BlockState state = level.getBlockState(pos);
144194
final Block block = state.getBlock();
145195

146196
if (block instanceof TrunkShellBlock) {
147-
// Determine if this shell belongs to the trunk. Block otherwise.
148-
Surround surr = state.getValue(TrunkShellBlock.CORE_DIR);
149-
return pos.offset(surr.getOffset()).equals(corePos) ? ReplaceableState.SHELL : ReplaceableState.BLOCKING;
197+
ShellDirection dir = state.getValue(TrunkShellBlock.CORE_DIR);
198+
return pos.offset(dir.getOffset()).equals(corePos) ? ReplaceableState.SHELL : ReplaceableState.BLOCKING;
150199
}
151200

152201
if (state.canBeReplaced() || state.is(DTBlockTags.FOLIAGE)) {
@@ -165,32 +214,74 @@ public ReplaceableState getReplaceability(LevelAccessor level, BlockPos pos, Blo
165214
return ReplaceableState.TREEPART;
166215
}
167216

168-
if (block instanceof FruitBlock || block instanceof PodBlock){
217+
if (block instanceof FruitBlock || block instanceof PodBlock) {
169218
return ReplaceableState.TREEPART;
170219
}
171220

172221
if (this.getFamily().getCommonSpecies().isAcceptableSoilForWorldgen(level, pos, state)) {
173222
return ReplaceableState.REPLACEABLE;
174223
}
175224

225+
if (ringLevel == 1) {
226+
float hardness = state.getDestroySpeed(level, pos);
227+
if (hardness >= 0 && hardness < 1) {
228+
return ReplaceableState.REPLACEABLE;
229+
}
230+
}
231+
232+
if (ringLevel == 2) {
233+
float hardness = state.getDestroySpeed(level, pos);
234+
if (hardness >= 0 && hardness < 3) {
235+
return ReplaceableState.REPLACEABLE;
236+
}
237+
}
238+
239+
// Outermost ring can break most hard blocks
240+
if (ringLevel == 3) {
241+
float hardness = state.getDestroySpeed(level, pos);
242+
if (hardness >= 0 && hardness < 5) {
243+
return ReplaceableState.REPLACEABLE;
244+
}
245+
}
246+
176247
return ReplaceableState.BLOCKING;
177248
}
178249

179250
enum ReplaceableState {
180-
SHELL, // This indicates that the block is already a shell.
181-
REPLACEABLE, // This indicates that the block is truly replaceable and will be erased.
182-
BLOCKING, // This indicates that the block is not replaceable, will NOT be erased, and will prevent the tree from growing.
183-
TREEPART // This indicates that the block is part of a tree, will NOT be erase, and will NOT prevent the tree from growing.
251+
SHELL,
252+
REPLACEABLE,
253+
BLOCKING,
254+
TREEPART
255+
}
256+
257+
@Override
258+
public int getRadiusForConnection(BlockState state, BlockGetter level, BlockPos pos, BranchBlock from, Direction side, int fromRadius) {
259+
if (from instanceof ThickBranchBlock) {
260+
return getRadius(state);
261+
}
262+
return Math.min(getRadius(state), MAX_RADIUS);
263+
}
264+
265+
@Override
266+
protected int getSideConnectionRadius(BlockGetter level, BlockPos pos, int radius, Direction side) {
267+
final BlockPos deltaPos = pos.relative(side);
268+
final BlockState blockState = CoordUtils.getStateSafe(level, deltaPos);
269+
270+
if (blockState == null) {
271+
return 0;
272+
}
273+
274+
final int connectionRadius = TreeHelper.getTreePart(blockState).getRadiusForConnection(blockState, level, deltaPos, this, side, radius);
275+
return Math.min(MAX_RADIUS, connectionRadius);
184276
}
185277

186278
@Override
187279
public int getMaxRadius() {
188280
return MAX_RADIUS_THICK;
189281
}
190282

191-
192-
///////////////////////////////////////////
193-
// PHYSICAL BOUNDS
283+
///////////////////////////////////////////
284+
// PHYSICAL BOUNDS
194285
///////////////////////////////////////////
195286

196287
@Nonnull
@@ -209,5 +300,4 @@ public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, Co
209300
public boolean isMusable(BlockGetter level, BlockState state, BlockPos pos) {
210301
return getRadius(state) > 8;
211302
}
212-
213-
}
303+
}

0 commit comments

Comments
 (0)