Search in sources :

Example 1 with StructureSpawnContext

use of ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext in project RecurrentComplex by Ivorforce.

the class TransformerNaturalAir method transform.

@Override
public void transform(InstanceData instanceData, Phase phase, StructureSpawnContext context, IvWorldData worldData, RunTransformer transformer) {
    super.transform(instanceData, phase, context, worldData, transformer);
    if (phase == Phase.AFTER) {
        WorldServer world = context.environment.world;
        IvBlockCollection blockCollection = worldData.blockCollection;
        int[] areaSize = new int[] { blockCollection.width, blockCollection.height, blockCollection.length };
        BlockPos lowerCoord = StructureBoundingBoxes.min(context.boundingBox);
        // Remove dying foliage
        HashSet<BlockPos> check = instanceData.cloud.keySet().stream().flatMap(pos -> new BlockArea(pos.subtract(new Vec3i(2, 2, 2)), pos.add(new Vec3i(2, 2, 2))).stream()).filter(pos -> !instanceData.cloud.containsKey(pos)).map(pos -> context.transform.apply(pos, areaSize).add(lowerCoord)).collect(Collectors.toCollection(HashSet::new));
        Set<BlockPos> remove = new HashSet<>();
        HashSet<BlockPos> start = new HashSet<>();
        // Do each one separately, since each block needs to be connected to floor separately
        check.forEach(checking -> {
            start.add(checking);
            if (visitRecursively(start, (changed, pos) -> {
                IBlockState state = world.getBlockState(pos);
                boolean isFoliage = RCBlockLogic.isFoliage(state, world, pos);
                if (!RCBlockLogic.canStay(state, world, pos))
                    context.setBlock(pos, Blocks.AIR.getDefaultState(), 2);
                else if (!isFoliage && !state.getBlock().isReplaceable(world, pos))
                    return false;
                else if (isFoliage && remove.size() < MAX_TREE_SIZE && remove.add(pos))
                    neighbors(pos).forEach(changed::add);
                return true;
            })) {
                remove.forEach(pos -> context.setBlock(pos, Blocks.AIR.getDefaultState(), 2));
            }
            start.clear();
            remove.clear();
        });
    }
}
Also used : IvBlockCollection(ivorius.ivtoolkit.blocks.IvBlockCollection) BlockExpression(ivorius.reccomplex.utils.expression.BlockExpression) Blocks(net.minecraft.init.Blocks) StructureSpawnContext(ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext) BlockAreas(ivorius.ivtoolkit.blocks.BlockAreas) TableDataSource(ivorius.reccomplex.gui.table.datasource.TableDataSource) TableDataSourceBTNaturalAir(ivorius.reccomplex.gui.editstructure.transformers.TableDataSourceBTNaturalAir) Environment(ivorius.reccomplex.world.gen.feature.structure.Environment) StructureBoundingBoxes(ivorius.ivtoolkit.world.chunk.gen.StructureBoundingBoxes) HashSet(java.util.HashSet) BlockArea(ivorius.ivtoolkit.blocks.BlockArea) Vec3i(net.minecraft.util.math.Vec3i) Side(net.minecraftforge.fml.relauncher.Side) RecurrentComplex(ivorius.reccomplex.RecurrentComplex) SideOnly(net.minecraftforge.fml.relauncher.SideOnly) PositionedBlockExpression(ivorius.reccomplex.utils.expression.PositionedBlockExpression) WorldServer(net.minecraft.world.WorldServer) JsonUtils(ivorius.reccomplex.json.JsonUtils) Nullable(javax.annotation.Nullable) IvWorldData(ivorius.ivtoolkit.tools.IvWorldData) ExpressionCache(ivorius.reccomplex.utils.algebra.ExpressionCache) StructureLoadContext(ivorius.reccomplex.world.gen.feature.structure.context.StructureLoadContext) StructurePrepareContext(ivorius.reccomplex.world.gen.feature.structure.context.StructurePrepareContext) NBTBase(net.minecraft.nbt.NBTBase) Set(java.util.Set) BlockPos(net.minecraft.util.math.BlockPos) RCBlocks(ivorius.reccomplex.block.RCBlocks) Collectors(java.util.stream.Collectors) MCRegistry(ivorius.ivtoolkit.tools.MCRegistry) TableNavigator(ivorius.reccomplex.gui.table.TableNavigator) IBlockState(net.minecraft.block.state.IBlockState) Stream(java.util.stream.Stream) RCBlockLogic(ivorius.reccomplex.utils.RCBlockLogic) Type(java.lang.reflect.Type) TableDelegate(ivorius.reccomplex.gui.table.TableDelegate) com.google.gson(com.google.gson) BlockArea(ivorius.ivtoolkit.blocks.BlockArea) Vec3i(net.minecraft.util.math.Vec3i) IBlockState(net.minecraft.block.state.IBlockState) WorldServer(net.minecraft.world.WorldServer) BlockPos(net.minecraft.util.math.BlockPos) IvBlockCollection(ivorius.ivtoolkit.blocks.IvBlockCollection) HashSet(java.util.HashSet)

Example 2 with StructureSpawnContext

use of ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext in project RecurrentComplex by Ivorforce.

the class StructureGenerator method generate.

/**
 * @return null when creation failed, empty when no entry was created and an entry when there was
 */
@Nonnull
public GenerationResult generate() {
    Optional<S> optionalInstanceData = instanceData();
    if (!optionalInstanceData.isPresent())
        return failGenerate(GenerationResult.Failure.placement);
    S instanceData = optionalInstanceData.get();
    StructureSpawnContext spawn = spawn().get();
    Structure<S> structure = structure();
    String structureID = structureID();
    boolean firstTime = spawn.generateMaturity.isFirstTime();
    WorldServer world = spawn.environment.world;
    StructureBoundingBox boundingBox = spawn.boundingBox;
    if (maturity().isSuggest()) {
        if (boundingBox.minY < MIN_DIST_TO_LIMIT || boundingBox.maxY > world.getHeight() - 1 - MIN_DIST_TO_LIMIT) {
            return failGenerate(GenerationResult.Failure.outOfBounds);
        }
        if (RCConfig.avoidOverlappingGeneration && !allowOverlaps && !WorldStructureGenerationData.get(world).entriesAt(boundingBox).noneMatch(WorldStructureGenerationData.Entry::blocking)) {
            return failGenerate(GenerationResult.Failure.structureOverlap);
        }
        if (RCEventBus.INSTANCE.post(new StructureGenerationEvent.Suggest(structure, spawn)) || (structureID != null && MinecraftForge.EVENT_BUS.post(new StructureGenerationEventLite.Suggest(world, structureID, boundingBox, spawn.generationLayer, firstTime)))) {
            return failGenerate(GenerationResult.Failure.cancel);
        }
    }
    if (firstTime) {
        RCEventBus.INSTANCE.post(new StructureGenerationEvent.Pre(structure, spawn));
        if (structureID != null)
            MinecraftForge.EVENT_BUS.post(new StructureGenerationEventLite.Pre(world, structureID, boundingBox, spawn.generationLayer, firstTime));
    }
    RCWorldgenMonitor.start("generating " + structureID());
    try {
        structure.generate(spawn, instanceData, foreignTransformer());
    } catch (Exception e) {
        return failGenerate(new GenerationResult.Failure.Exception(e));
    } finally {
        RCWorldgenMonitor.stop();
    }
    if (!firstTime)
        return GenerationResult.Success.complement;
    RecurrentComplex.logger.trace(String.format("Generated structure '%s' in %s (%d)", name(structureID), boundingBox, world.provider.getDimension()));
    RCEventBus.INSTANCE.post(new StructureGenerationEvent.Post(structure, spawn));
    if (structureID != null)
        MinecraftForge.EVENT_BUS.post(new StructureGenerationEventLite.Post(world, structureID, boundingBox, spawn.generationLayer, firstTime));
    if (structureID == null || !memorize)
        return GenerationResult.Success.contemporary;
    String generationInfoID = generationType != null ? generationType.id() : null;
    WorldStructureGenerationData.StructureEntry structureEntry = WorldStructureGenerationData.StructureEntry.complete(structureID, generationInfoID, boundingBox, spawn.transform, !partially);
    structureEntry.blocking = structure.isBlocking();
    // Been there done that
    structureEntry.firstTime = false;
    structureEntry.seed = seed();
    try {
        structureEntry.instanceData = instanceData.writeToNBT();
    } catch (Exception e) {
        RecurrentComplex.logger.error(String.format("Error saving instance data for structure %s in %s", structure, boundingBox), e);
    }
    Collection<ChunkPos> existingChunks = Sets.newHashSet(WorldStructureGenerationData.get(world).addEntry(structureEntry));
    // Complement in all chunks that already exist
    if (partially) {
        maturity(StructureSpawnContext.GenerateMaturity.COMPLEMENT);
        StructureBoundingBox oldBB = generationBB;
        for (ChunkPos existingChunk : existingChunks) {
            generationBB(Structures.chunkBoundingBox(existingChunk, true));
            if (oldBB.intersectsWith(generationBB))
                // Skip those that we just generated in, especially the same chunk
                continue;
            RCWorldgenMonitor.start("pre-complementing " + structureID());
            structure.generate(spawn().get(), instanceData, RCConfig.getUniversalTransformer());
            RCWorldgenMonitor.stop();
        }
        generationBB(oldBB);
    }
    return new GenerationResult.Success.New(structureEntry);
}
Also used : StructureBoundingBox(net.minecraft.world.gen.structure.StructureBoundingBox) StructureGenerationEvent(ivorius.reccomplex.events.StructureGenerationEvent) WorldServer(net.minecraft.world.WorldServer) ChunkPos(net.minecraft.util.math.ChunkPos) StructureSpawnContext(ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext) Nonnull(javax.annotation.Nonnull)

Example 3 with StructureSpawnContext

use of ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext in project RecurrentComplex by Ivorforce.

the class WorldScriptHolder method generate.

@Override
public void generate(StructureSpawnContext context, RunTransformer transformer, NBTNone instanceData, BlockPos pos) {
    if (worldData == null) {
        return;
    }
    GenericStructure structure = new GenericStructure();
    structure.worldDataCompound = worldData.copy();
    int[] strucSize = structure.size();
    BlockPos strucCoord = context.transform.apply(origin, new int[] { 1, 1, 1 }).subtract(context.transform.apply(BlockPos.ORIGIN, strucSize)).add(pos);
    new StructureGenerator<>(structure).asChild(context).transformer(transformer).lowerCoord(strucCoord).generationPredicate(p -> !p.equals(pos)).generate();
    context.setBlock(pos, replaceState, 2);
}
Also used : RunTransformer(ivorius.reccomplex.world.gen.feature.structure.generic.transformers.RunTransformer) GenericStructure(ivorius.reccomplex.world.gen.feature.structure.generic.GenericStructure) Blocks(net.minecraft.init.Blocks) StructureSpawnContext(ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext) TableDataSource(ivorius.reccomplex.gui.table.datasource.TableDataSource) TableDataSourceWorldScriptHolder(ivorius.reccomplex.gui.worldscripts.TableDataSourceWorldScriptHolder) StructureGenerator(ivorius.reccomplex.world.gen.feature.StructureGenerator) NBTNone(ivorius.reccomplex.nbt.NBTNone) Block(net.minecraft.block.Block) Side(net.minecraftforge.fml.relauncher.Side) RecurrentComplex(ivorius.reccomplex.RecurrentComplex) SideOnly(net.minecraftforge.fml.relauncher.SideOnly) Nullable(javax.annotation.Nullable) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) StructureLoadContext(ivorius.reccomplex.world.gen.feature.structure.context.StructureLoadContext) StructurePrepareContext(ivorius.reccomplex.world.gen.feature.structure.context.StructurePrepareContext) NBTBase(net.minecraft.nbt.NBTBase) BlockPositions(ivorius.ivtoolkit.blocks.BlockPositions) BlockStates(ivorius.ivtoolkit.blocks.BlockStates) BlockPos(net.minecraft.util.math.BlockPos) MCRegistry(ivorius.ivtoolkit.tools.MCRegistry) TableNavigator(ivorius.reccomplex.gui.table.TableNavigator) IBlockState(net.minecraft.block.state.IBlockState) ResourceLocation(net.minecraft.util.ResourceLocation) TableDelegate(ivorius.reccomplex.gui.table.TableDelegate) BlockPos(net.minecraft.util.math.BlockPos) GenericStructure(ivorius.reccomplex.world.gen.feature.structure.generic.GenericStructure)

Aggregations

StructureSpawnContext (ivorius.reccomplex.world.gen.feature.structure.context.StructureSpawnContext)3 MCRegistry (ivorius.ivtoolkit.tools.MCRegistry)2 RecurrentComplex (ivorius.reccomplex.RecurrentComplex)2 TableDelegate (ivorius.reccomplex.gui.table.TableDelegate)2 TableNavigator (ivorius.reccomplex.gui.table.TableNavigator)2 TableDataSource (ivorius.reccomplex.gui.table.datasource.TableDataSource)2 StructureLoadContext (ivorius.reccomplex.world.gen.feature.structure.context.StructureLoadContext)2 StructurePrepareContext (ivorius.reccomplex.world.gen.feature.structure.context.StructurePrepareContext)2 Nullable (javax.annotation.Nullable)2 IBlockState (net.minecraft.block.state.IBlockState)2 Blocks (net.minecraft.init.Blocks)2 NBTBase (net.minecraft.nbt.NBTBase)2 BlockPos (net.minecraft.util.math.BlockPos)2 WorldServer (net.minecraft.world.WorldServer)2 Side (net.minecraftforge.fml.relauncher.Side)2 SideOnly (net.minecraftforge.fml.relauncher.SideOnly)2 com.google.gson (com.google.gson)1 BlockArea (ivorius.ivtoolkit.blocks.BlockArea)1 BlockAreas (ivorius.ivtoolkit.blocks.BlockAreas)1 BlockPositions (ivorius.ivtoolkit.blocks.BlockPositions)1