minecraft-src/net/minecraft/world/level/levelgen/feature/rootplacers/MangroveRootPlacer.java
2025-07-04 01:41:11 +03:00

133 lines
4.7 KiB
Java

package net.minecraft.world.level.levelgen.feature.rootplacers;
import com.google.common.collect.Lists;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.util.valueproviders.IntProvider;
import net.minecraft.world.level.LevelSimulatedReader;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
public class MangroveRootPlacer extends RootPlacer {
public static final int ROOT_WIDTH_LIMIT = 8;
public static final int ROOT_LENGTH_LIMIT = 15;
public static final MapCodec<MangroveRootPlacer> CODEC = RecordCodecBuilder.mapCodec(
instance -> rootPlacerParts(instance)
.and(MangroveRootPlacement.CODEC.fieldOf("mangrove_root_placement").forGetter(mangroveRootPlacer -> mangroveRootPlacer.mangroveRootPlacement))
.apply(instance, MangroveRootPlacer::new)
);
private final MangroveRootPlacement mangroveRootPlacement;
public MangroveRootPlacer(
IntProvider trunkOffset, BlockStateProvider rootProvider, Optional<AboveRootPlacement> aboveRootPlacement, MangroveRootPlacement mangroveRootPlacement
) {
super(trunkOffset, rootProvider, aboveRootPlacement);
this.mangroveRootPlacement = mangroveRootPlacement;
}
@Override
public boolean placeRoots(
LevelSimulatedReader level,
BiConsumer<BlockPos, BlockState> blockSetter,
RandomSource random,
BlockPos pos,
BlockPos trunkOrigin,
TreeConfiguration treeConfig
) {
List<BlockPos> list = Lists.<BlockPos>newArrayList();
BlockPos.MutableBlockPos mutableBlockPos = pos.mutable();
while (mutableBlockPos.getY() < trunkOrigin.getY()) {
if (!this.canPlaceRoot(level, mutableBlockPos)) {
return false;
}
mutableBlockPos.move(Direction.UP);
}
list.add(trunkOrigin.below());
for (Direction direction : Direction.Plane.HORIZONTAL) {
BlockPos blockPos = trunkOrigin.relative(direction);
List<BlockPos> list2 = Lists.<BlockPos>newArrayList();
if (!this.simulateRoots(level, random, blockPos, direction, trunkOrigin, list2, 0)) {
return false;
}
list.addAll(list2);
list.add(trunkOrigin.relative(direction));
}
for (BlockPos blockPos2 : list) {
this.placeRoot(level, blockSetter, random, blockPos2, treeConfig);
}
return true;
}
private boolean simulateRoots(
LevelSimulatedReader level, RandomSource random, BlockPos pos, Direction direction, BlockPos trunkOrigin, List<BlockPos> roots, int length
) {
int i = this.mangroveRootPlacement.maxRootLength();
if (length != i && roots.size() <= i) {
for (BlockPos blockPos : this.potentialRootPositions(pos, direction, random, trunkOrigin)) {
if (this.canPlaceRoot(level, blockPos)) {
roots.add(blockPos);
if (!this.simulateRoots(level, random, blockPos, direction, trunkOrigin, roots, length + 1)) {
return false;
}
}
}
return true;
} else {
return false;
}
}
protected List<BlockPos> potentialRootPositions(BlockPos pos, Direction direction, RandomSource random, BlockPos trunkOrigin) {
BlockPos blockPos = pos.below();
BlockPos blockPos2 = pos.relative(direction);
int i = pos.distManhattan(trunkOrigin);
int j = this.mangroveRootPlacement.maxRootWidth();
float f = this.mangroveRootPlacement.randomSkewChance();
if (i > j - 3 && i <= j) {
return random.nextFloat() < f ? List.of(blockPos, blockPos2.below()) : List.of(blockPos);
} else if (i > j) {
return List.of(blockPos);
} else if (random.nextFloat() < f) {
return List.of(blockPos);
} else {
return random.nextBoolean() ? List.of(blockPos2) : List.of(blockPos);
}
}
@Override
protected boolean canPlaceRoot(LevelSimulatedReader level, BlockPos pos) {
return super.canPlaceRoot(level, pos) || level.isStateAtPosition(pos, blockState -> blockState.is(this.mangroveRootPlacement.canGrowThrough()));
}
@Override
protected void placeRoot(
LevelSimulatedReader level, BiConsumer<BlockPos, BlockState> blockSetter, RandomSource random, BlockPos pos, TreeConfiguration treeConfig
) {
if (level.isStateAtPosition(pos, blockStatex -> blockStatex.is(this.mangroveRootPlacement.muddyRootsIn()))) {
BlockState blockState = this.mangroveRootPlacement.muddyRootsProvider().getState(random, pos);
blockSetter.accept(pos, this.getPotentiallyWaterloggedState(level, pos, blockState));
} else {
super.placeRoot(level, blockSetter, random, pos, treeConfig);
}
}
@Override
protected RootPlacerType<?> type() {
return RootPlacerType.MANGROVE_ROOT_PLACER;
}
}