use of net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager in project BYG by AOCAWOL.
the class SmallPineTree method place.
public boolean place(WorldGenLevel world, ChunkGenerator generator, Random rand, BlockPos pos, NoneFeatureConfiguration config) {
if (pos.getX() == -4 && pos.getZ() == -4) {
for (int checkX = pos.getX() + -16; checkX <= pos.getX() + 16; checkX++) {
for (int checkY = pos.getY(); checkY <= 25; checkY++) {
for (int checkZ = pos.getZ() + -16; checkZ <= pos.getZ() + 16; checkZ++) {
BlockPos.MutableBlockPos block = new BlockPos.MutableBlockPos(checkX, checkY, checkZ);
world.setBlock(block, Blocks.AIR.defaultBlockState(), 2);
}
}
}
StructureManager templatemanager = world.getLevel().getStructureManager();
Optional<StructureTemplate> structureTemplate = templatemanager.get(BYG.createLocation(":features/trees/withering_oak_tree5"));
if (structureTemplate.isEmpty()) {
BYG.LOGGER.warn("NBT does not exist!");
return false;
}
StructureTemplate template = structureTemplate.get();
StructurePlaceSettings placementsettings = (new StructurePlaceSettings()).setMirror(Mirror.NONE).setRotation(Rotation.NONE).setIgnoreEntities(false);
template.placeInWorld(world, pos, pos, placementsettings, rand, 2);
return true;
}
return false;
}
use of net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager in project BYG by AOCAWOL.
the class TreeFromStructureNBTFeature method place.
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> featurePlaceContext) {
BlockStateProvider stateProvider = BlockStateProvider.simple(BYGBlocks.MANGROVE_LOG);
BlockStateProvider leavesProvider = BlockStateProvider.simple(BYGBlocks.MANGROVE_LEAVES);
WorldGenLevel level = featurePlaceContext.level();
StructureManager templateManager = level.getLevel().getStructureManager();
ResourceLocation baseLocation = BYG.createLocation("features/trees/mangrove_tree3_base");
Optional<StructureTemplate> baseTemplateOptional = templateManager.get(baseLocation);
ResourceLocation canopyLocation = BYG.createLocation("features/trees/mangrove_tree3_canopy");
Optional<StructureTemplate> canopyTemplateOptional = templateManager.get(canopyLocation);
if (baseTemplateOptional.isEmpty()) {
throw noTreePartPresent(baseLocation);
}
if (canopyTemplateOptional.isEmpty()) {
throw noTreePartPresent(canopyLocation);
}
StructureTemplate baseTemplate = baseTemplateOptional.get();
StructureTemplate canopyTemplate = canopyTemplateOptional.get();
List<StructureTemplate.Palette> basePalettes = ((StructureTemplateAccess) baseTemplate).byg_getPalettes();
List<StructureTemplate.Palette> canopyPalettes = ((StructureTemplateAccess) canopyTemplate).byg_getPalettes();
BlockPos origin = featurePlaceContext.origin();
StructurePlaceSettings placeSettings = new StructurePlaceSettings();
StructureTemplate.Palette randomBasePalette = placeSettings.getRandomPalette(basePalettes, origin);
StructureTemplate.Palette randomCanopyPalette = placeSettings.getRandomPalette(canopyPalettes, origin);
List<StructureTemplate.StructureBlockInfo> leaves = randomCanopyPalette.blocks(BYGBlocks.MANGROVE_LEAVES);
List<StructureTemplate.StructureBlockInfo> canopyLogs = randomCanopyPalette.blocks(BYGBlocks.MANGROVE_LOG);
List<StructureTemplate.StructureBlockInfo> logs = randomBasePalette.blocks(BYGBlocks.MANGROVE_LOG);
List<StructureTemplate.StructureBlockInfo> logBuilders = randomBasePalette.blocks(Blocks.RED_WOOL);
List<StructureTemplate.StructureBlockInfo> trunkBuilder = randomBasePalette.blocks(Blocks.YELLOW_WOOL);
int trunkLength = 15;
for (StructureTemplate.StructureBlockInfo logBuilder : logBuilders) {
BlockPos pos = logBuilder.pos.offset(origin);
int maxTrunkBuildingDepth = 5;
int yDifference = pos.getY() - level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, pos.getX(), pos.getZ());
if (yDifference > maxTrunkBuildingDepth) {
return false;
}
}
for (StructureTemplate.StructureBlockInfo logBuilder : logBuilders) {
BlockPos pos = logBuilder.pos.offset(origin);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos().set(pos);
while (!level.getBlockState(mutableBlockPos).canOcclude()) {
level.setBlock(mutableBlockPos, stateProvider.getState(level.getRandom(), mutableBlockPos), 2);
mutableBlockPos.move(Direction.DOWN);
}
}
for (StructureTemplate.StructureBlockInfo trunk : logs) {
BlockPos pos = trunk.pos.offset(origin);
level.setBlock(pos, stateProvider.getState(featurePlaceContext.random(), pos), 2);
}
for (StructureTemplate.StructureBlockInfo trunk : trunkBuilder) {
BlockPos pos = trunk.pos.offset(origin);
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos().set(pos);
for (int i = 0; i < trunkLength; i++) {
level.setBlock(mutable, stateProvider.getState(featurePlaceContext.random(), mutable), 2);
mutable.move(Direction.UP);
}
}
BlockPos canopyPos = origin.offset(0, trunkLength, 0);
for (StructureTemplate.StructureBlockInfo canopyLog : canopyLogs) {
BlockPos pos = canopyLog.pos.offset(canopyPos);
level.setBlock(pos, stateProvider.getState(featurePlaceContext.random(), pos), 2);
}
List<Runnable> leavesPostApply = new ArrayList<>(leaves.size());
for (StructureTemplate.StructureBlockInfo leaf : leaves) {
BlockPos pos = leaf.pos.offset(canopyPos);
BlockState state = leavesProvider.getState(featurePlaceContext.random(), pos);
if (level.getBlockState(pos).isAir()) {
level.setBlock(pos, state, 2);
Runnable postProcess = () -> {
BlockState blockState = LeavesBlockAccess.byg_invokeUpdateDistance(state, level, pos);
if (blockState.getValue(LeavesBlock.DISTANCE) < LeavesBlock.DECAY_DISTANCE) {
level.setBlock(pos, blockState, 2);
BlockPos below = pos.below();
if (level.getBlockState(below).isAir()) {
// Bottom positions here
}
} else {
level.removeBlock(pos, false);
}
};
leavesPostApply.add(postProcess);
}
leavesPostApply.forEach(Runnable::run);
}
return false;
}
use of net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager in project RepurposedStructures by TelepathicGrunt.
the class NbtDungeon method place.
@Override
public boolean place(FeaturePlaceContext<NbtDungeonConfig> context) {
if (GeneralUtils.isBlacklistedForWorld(context.level(), context.config().cfID))
return false;
BlockPos position = context.origin().above(-1);
ResourceLocation nbtRL = GeneralUtils.getRandomEntry(context.config().nbtResourcelocationsAndWeights, context.random());
StructureManager structureManager = context.level().getLevel().getStructureManager();
Optional<StructureTemplate> template = structureManager.get(nbtRL);
if (template.isEmpty()) {
RepurposedStructures.LOGGER.error("Identifier to the specified nbt file was not found! : {}", nbtRL);
return false;
}
Rotation rotation = Rotation.getRandom(context.random());
BlockPos size = new BlockPos(template.get().getSize());
// For proper offsetting the dungeon so it rotate properly around position parameter.
BlockPos halfLengths = new BlockPos(size.getX() / 2, size.getY() / 2, size.getZ() / 2);
// Rotated blockpos for the nbt's sizes to be used later.
BlockPos fullLengths = new BlockPos(Math.abs(size.rotate(rotation).getX()), Math.abs(size.rotate(rotation).getY()), Math.abs(size.rotate(rotation).getZ()));
// For post processing spawners and chests for rotated dungeon.
BlockPos halfLengthsRotated = new BlockPos(fullLengths.getX() / 2, fullLengths.getY() / 2, fullLengths.getZ() / 2);
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos().set(position);
ChunkAccess cachedChunk = context.level().getChunk(mutable);
int xMin = -halfLengthsRotated.getX();
int xMax = halfLengthsRotated.getX();
int zMin = -halfLengthsRotated.getZ();
int zMax = halfLengthsRotated.getZ();
int wallOpenings = 0;
int ceilingOpenings = 0;
int ceiling = size.getY();
for (int x = xMin; x <= xMax; x++) {
for (int z = zMin; z <= zMax; z++) {
for (int y = 0; y <= ceiling; y++) {
mutable.set(position).move(x, y, z);
if (mutable.getX() >> 4 != cachedChunk.getPos().x || mutable.getZ() >> 4 != cachedChunk.getPos().z)
cachedChunk = context.level().getChunk(mutable);
BlockState state = cachedChunk.getBlockState(mutable);
// Dungeons cannot touch fluids if set to air mode and reverse if opposite
if (context.config().airRequirementIsNowWater ? state.isAir() || state.getFluidState().is(FluidTags.LAVA) : !state.getFluidState().isEmpty()) {
return false;
} else // Floor must be complete
if (!GeneralUtils.isFullCube(context.level(), mutable, state)) {
if (y == 0 && !state.getMaterial().isSolid()) {
return false;
} else if (state.is(BlockTags.LEAVES)) {
// ignore leaves
continue;
} else if (y == ceiling) {
ceilingOpenings++;
}
}
// Check only along wall bottoms for openings
if ((x == xMin || x == xMax || z == zMin || z == zMax) && y == 1 && isValidNonSolidBlock(context.config(), state)) {
BlockState aboveState = cachedChunk.getBlockState(mutable);
if (context.config().airRequirementIsNowWater ? !aboveState.getFluidState().isEmpty() : aboveState.isAir()) {
wallOpenings++;
}
}
// Too much open space. Quit
if (wallOpenings > context.config().maxAirSpace || ceilingOpenings > context.config().maxAirSpace) {
return false;
}
}
}
}
// Check if we meet minimum for open space.
if (wallOpenings >= context.config().minAirSpace) {
// offset the dungeon such as ocean dungeons down 1
position = position.above(context.config().structureYOffset);
// RepurposedStructures.LOGGER.log(Level.INFO, nbtRL + " at X: "+position.getX() +", "+position.getY()+", "+position.getZ());
StructurePlaceSettings placementsettings = (new StructurePlaceSettings()).setRotation(rotation).setRotationPivot(halfLengths).setIgnoreEntities(false);
Optional<StructureProcessorList> processor = context.level().getLevel().getServer().registryAccess().registryOrThrow(Registry.PROCESSOR_LIST_REGISTRY).getOptional(context.config().processor);
// add all processors
processor.orElse(ProcessorLists.EMPTY.value()).list().forEach(placementsettings::addProcessor);
BlockPos finalPos = mutable.set(position).move(-halfLengths.getX(), 0, -halfLengths.getZ());
template.get().placeInWorld(context.level(), finalPos, finalPos, placementsettings, context.random(), Block.UPDATE_CLIENTS);
// Post-processors
// For all processors that are sensitive to neighboring blocks such as vines.
// Post processors will place the blocks themselves so we will not do anything with the return of Structure.process
placementsettings.clearProcessors();
Optional<StructureProcessorList> postProcessor = context.level().getLevel().getServer().registryAccess().registryOrThrow(Registry.PROCESSOR_LIST_REGISTRY).getOptional(context.config().postProcessor);
// add all post processors
postProcessor.orElse(ProcessorLists.EMPTY.value()).list().forEach(placementsettings::addProcessor);
List<StructureTemplate.StructureBlockInfo> list = placementsettings.getRandomPalette(((TemplateAccessor) template.get()).repurposedstructures_getPalettes(), mutable).blocks();
StructureTemplate.processBlockInfos(context.level(), mutable, mutable, placementsettings, list, template.get());
spawnLootBlocks(context.level(), context.random(), position, context.config(), fullLengths, halfLengthsRotated, mutable);
return true;
}
return false;
}
use of net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager in project RepurposedStructures by TelepathicGrunt.
the class NbtFeature method place.
@Override
public boolean place(FeaturePlaceContext<NbtFeatureConfig> context) {
if (GeneralUtils.isBlacklistedForWorld(context.level(), context.config().cfID))
return false;
// move to top land block below position
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos().set(context.origin());
for (mutable.move(Direction.UP); context.level().isEmptyBlock(mutable) && mutable.getY() > 2; ) {
mutable.move(Direction.DOWN);
}
// check to make sure spot is valid and not a single block ledge
if (!context.level().getBlockState(mutable).isAir() && !context.level().isEmptyBlock(mutable.below()) && !context.level().isEmptyBlock(mutable.below(2))) {
// Creates the well centered on our spot
mutable.move(Direction.DOWN);
} else {
return false;
}
// Person wants an empty feature for some reason.
if (context.config().nbtResourcelocationsAndWeights.size() == 0) {
return false;
}
BlockPos.MutableBlockPos blockpos$Mutable = new BlockPos.MutableBlockPos();
StructureManager templatemanager = context.level().getLevel().getServer().getStructureManager();
ResourceLocation nbtRL = GeneralUtils.getRandomEntry(context.config().nbtResourcelocationsAndWeights, context.random());
Optional<StructureTemplate> template = templatemanager.get(nbtRL);
if (template.isEmpty()) {
RepurposedStructures.LOGGER.warn(context.config().nbtResourcelocationsAndWeights.toString() + " NTB does not exist!");
return false;
}
int radius = template.get().getSize().getX() / 2;
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
if ((x * x) + (z * z) < radius * radius + 1) {
blockpos$Mutable.set(context.origin()).move(x, 0, z);
// Makes sure it doesn't generate in liquid if stated to not to.
if (!context.config().allowInWater && !context.level().getFluidState(blockpos$Mutable).isEmpty()) {
return false;
} else // No spawning on slopes
if (context.level().getBlockState(blockpos$Mutable.move(Direction.UP)).canOcclude() || !context.level().getBlockState(blockpos$Mutable.move(Direction.DOWN, 3)).canOcclude()) {
return false;
}
// context.getWorld().setBlockState(blockpos$Mutable.up(), Blocks.REDSTONE_BLOCK.getDefaultState(), 2);
}
}
}
BlockPos halfLengths = new BlockPos(template.get().getSize().getX() / 2, 0, template.get().getSize().getZ() / 2);
placementsettings.setRotation(Rotation.getRandom(context.random())).setRotationPivot(halfLengths).setIgnoreEntities(false);
if (context.config().processor != null) {
context.level().registryAccess().registryOrThrow(Registry.PROCESSOR_LIST_REGISTRY).getOptional(context.config().processor).ifPresent(processor -> processor.list().forEach(placementsettings::addProcessor));
}
blockpos$Mutable.set(context.origin());
BlockPos offset = new BlockPos(-template.get().getSize().getX() / 2, context.config().heightOffset, -template.get().getSize().getZ() / 2);
template.get().placeInWorld(context.level(), blockpos$Mutable.offset(offset), blockpos$Mutable.offset(offset), placementsettings, context.random(), Block.UPDATE_CLIENTS);
return true;
}
use of net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager in project SolarCraftRepository by FINDERFEED.
the class MoltenForestAmbience method place.
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> ctx) {
BlockPos pos = ctx.origin();
WorldGenLevel world = ctx.level();
Random random = ctx.random();
Rotation rot = Rotation.getRandom(random);
StructureManager manager = world.getLevel().getStructureManager();
List<ResourceLocation> list = new ArrayList<>();
list.add(TREE);
list.add(TREE2);
StructureTemplate templ = manager.getOrCreate(list.get(random.nextInt(2)));
StructurePlaceSettings set = new StructurePlaceSettings().addProcessor(BlockIgnoreProcessor.AIR).setRandom(random).setRotation(rot).setBoundingBox(BoundingBox.infinite());
BlockPos pos1 = findFlatChunkPosition(world, pos, 4, Blocks.GRASS_BLOCK);
if (!pos1.equals(Helpers.NULL_POS)) {
BlockPos blockpos1 = templ.getZeroPositionWithTransform(pos1.offset(0, 1, 0), Mirror.NONE, rot);
templ.placeInWorld(world, blockpos1, blockpos1, set, random, 4);
}
return true;
}
Aggregations