Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.dreamlands.common.world.feature.tree;
- import com.dreamlands.common.block.CloverBlock;
- import com.dreamlands.common.block.DreamLeavesBlock;
- import com.dreamlands.common.block.WisteriaBlock;
- import com.dreamlands.common.world.feature.config.DreamTreeConfiguration;
- import com.dreamlands.init.DreamBlocks;
- import com.mojang.serialization.Codec;
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.tags.BlockTags;
- import net.minecraft.util.RandomSource;
- import net.minecraft.world.level.LevelAccessor;
- import net.minecraft.world.level.WorldGenLevel;
- import net.minecraft.world.level.block.state.BlockState;
- import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
- import java.util.ArrayList;
- import java.util.List;
- public class WisteriaTreeFeature extends DreamTreeFeature {
- public WisteriaTreeFeature(Codec<DreamTreeConfiguration> codec) {
- super(codec);
- }
- @Override
- public boolean place(FeaturePlaceContext<DreamTreeConfiguration> context) {
- WorldGenLevel level = context.level();
- RandomSource random = context.random();
- BlockPos initialPos = context.origin();
- DreamTreeConfiguration config = context.config();
- int trunkHeight = config.minimumHeight + random.nextInt(config.additionalHeight);
- for (int currentY = 0; currentY <= trunkHeight; currentY++) {
- this.placeTrunk(level, initialPos, random, config, currentY, false);
- if (currentY == trunkHeight) {
- this.generateLeaves(level, initialPos.above(currentY), random, config, 2, 2, 48);
- }
- if (currentY == trunkHeight - 4) {
- Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random);
- this.generateBranch(level, this.getBranchPos(initialPos.above(currentY), direction, random, false), random, config, direction, 3);
- if (trunkHeight > 8) {
- this.generateBranch(level, this.getBranchPos(initialPos.below().above(currentY), direction.getOpposite(), random, false), random, config, direction.getOpposite(), 2);
- }
- }
- }
- /// place wisteria petals beneath the tree.
- this.placeFallenPetals(level, initialPos, random, 5);
- return level.getBlockState(initialPos.below()).is(BlockTags.DIRT);
- }
- protected void generateBranch(LevelAccessor level, BlockPos branchPos, RandomSource random, DreamTreeConfiguration config, Direction direction, int branchLength) {
- BlockPos.MutableBlockPos mutablePos = branchPos.mutable();
- mutablePos.set(branchPos);
- BlockPos branchEndPos = branchPos.relative(direction, branchLength).above(2);
- for (int i = 0; i < branchLength - 1; ++i) {
- mutablePos.set(branchPos.relative(direction, i));
- this.placeLog(level, mutablePos, random, config, direction.getAxis());
- }
- Direction verticalDirection = branchEndPos.getY() > mutablePos.getY() ? Direction.UP : Direction.DOWN;
- while (true) {
- int distanceToTarget = mutablePos.distManhattan(branchEndPos);
- if (distanceToTarget == 0) {
- this.placeLog(level, mutablePos.above(), random, config, Direction.Axis.Y);
- this.generateLeaves(level, mutablePos, random, config, 1, 2, 28);
- return;
- }
- float f = (float) Math.abs(branchEndPos.getY() - mutablePos.getY()) / (float) distanceToTarget;
- boolean flag = random.nextFloat() < f;
- mutablePos.move(flag ? verticalDirection : direction);
- this.placeLog(level, mutablePos, random, config, flag ? verticalDirection.getAxis() : direction.getAxis());
- }
- }
- protected void generateLeaves(LevelAccessor level, BlockPos pos, RandomSource random, DreamTreeConfiguration config, int foliageRadius, int foliageHeight, int attempts) {
- List<BlockPos> leavesPositions = new ArrayList<>();
- for (int height = 0; height <= foliageHeight; height++) {
- for (int radius = 0; radius <= foliageRadius; radius++) { /// create the core middle blob of leaves for the tree.
- for (Direction direction : Direction.Plane.HORIZONTAL) {
- BlockPos relativePos = pos.above(height).relative(direction, radius);
- this.placeLeaves(level, pos.above(height), random, config, leavesPositions);
- this.placeLeaves(level, relativePos, random, config, leavesPositions);
- this.placeLeaves(level, relativePos.relative(direction.getClockWise()), random, config, leavesPositions);
- this.placeLeaves(level, relativePos.relative(direction.getCounterClockWise()), random, config, leavesPositions);
- }
- }
- BlockPos.MutableBlockPos mutablePos = pos.mutable();
- for (int i = 0; i < attempts; i++) {
- int radius = !(height <= 0) && height != foliageHeight ? 2 : 1; /// make random foliage radius wider only in the midsection of the tree.
- mutablePos.setWithOffset(pos, random.nextInt(foliageRadius + radius) - random.nextInt(foliageRadius + radius), random.nextInt(foliageHeight), random.nextInt(foliageRadius + radius) - random.nextInt(foliageRadius + radius));
- for (Direction direction : Direction.Plane.HORIZONTAL) {
- if (level.getBlockState(mutablePos.relative(direction)).is(BlockTags.LEAVES)) {
- this.placeLeaves(level, mutablePos.above(height), random, config, leavesPositions);
- }
- }
- }
- }
- for (BlockPos leafPos : leavesPositions) { /// place hanging wisteria under the trees leaves.
- this.placeHangingWisteria(level, leafPos, random);
- }
- }
- /**
- * temporary fix for placing a tree decorator, this gets all the leaves being placed for the tree to be able to be sorted through.
- */
- private void placeLeaves(LevelAccessor level, BlockPos pos, RandomSource random, DreamTreeConfiguration config, List<BlockPos> list) {
- this.placeLeaves(level, pos, random, config);
- list.add(pos);
- }
- private void placeHangingWisteria(LevelAccessor level, BlockPos pos, RandomSource random) {
- BlockPos belowPos = pos.below();
- if (level.getBlockState(belowPos).isAir() && (level.getBlockState(belowPos.below()).isAir() || level.getBlockState(belowPos.below()).is(BlockTags.LOGS))) {
- level.setBlock(belowPos, DreamBlocks.WISTERIA_BLOSSOMS.get().defaultBlockState().setValue(DreamLeavesBlock.DISTANCE, 1), 2);
- int length = 2 + random.nextInt(random.nextDouble() < 0.4D ? 2 : 1);
- BlockPos currentPos = belowPos;
- for (int i = 0; i < length; i++) {
- currentPos = currentPos.below();
- if (!level.getBlockState(currentPos).isAir()) {
- if (level.isEmptyBlock(currentPos.above())) {
- level.setBlock(currentPos.above(), DreamBlocks.WISTERIA.get().defaultBlockState().setValue(WisteriaBlock.AGE, 25), 2);
- }
- return;
- }
- level.setBlock(currentPos, DreamBlocks.WISTERIA_PLANT.get().defaultBlockState(), 2);
- }
- if (level.isEmptyBlock(currentPos.below())) {
- level.setBlock(currentPos.below(), DreamBlocks.WISTERIA.get().defaultBlockState().setValue(WisteriaBlock.AGE, 25), 2);
- }
- }
- }
- private void placeFallenPetals(LevelAccessor level, BlockPos pos, RandomSource random, int radius) {
- for (int x = -radius; x <= radius; ++x) {
- for (int z = -radius; z <= radius; ++z) {
- for (int y = -radius; y <= radius; ++y) {
- if (Math.abs(x) < radius && Math.abs(z) < radius && Math.abs(y) < radius) {
- BlockPos offsetPos = pos.offset(x, y, z);
- if (random.nextDouble() < 0.8D && level.isEmptyBlock(offsetPos) && level.getBlockState(offsetPos.below()).is(BlockTags.DIRT)) {
- Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random);
- int amount = random.nextInt(4);
- for (int i = 2; i <= amount; ++i) {
- level.setBlock(offsetPos, DreamBlocks.WISTERIA_PETALS.get().defaultBlockState().setValue(CloverBlock.AMOUNT, i).setValue(CloverBlock.FACING, direction), 3);
- }
- }
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement