use of ivorius.ivtoolkit.blocks.IvBlockCollection in project RecurrentComplex by Ivorforce.
the class TransformerEnsureBlocks method mayGenerate.
@Override
public boolean mayGenerate(NBTNone instanceData, StructurePrepareContext context, IvWorldData worldData, RunTransformer transformer) {
IvBlockCollection blockCollection = worldData.blockCollection;
int[] areaSize = new int[] { blockCollection.width, blockCollection.height, blockCollection.length };
BlockPos lowerCoord = StructureBoundingBoxes.min(context.boundingBox);
BlockPos.MutableBlockPos worldCoord = new BlockPos.MutableBlockPos();
for (BlockPos sourcePos : BlockAreas.mutablePositions(blockCollection.area())) {
IvMutableBlockPos.add(context.transform.applyOn(sourcePos, worldCoord, areaSize), lowerCoord);
IBlockState state = blockCollection.getBlockState(sourcePos);
if (sourceMatcher.test(state) && !(destMatcher.expressionIsEmpty() || destMatcher.evaluate(() -> PositionedBlockExpression.Argument.at(context.environment.world, worldCoord))))
return false;
}
return true;
}
use of ivorius.ivtoolkit.blocks.IvBlockCollection in project RecurrentComplex by Ivorforce.
the class FactorMatch method consider.
@Override
public List<Pair<LineSelection, Float>> consider(WorldCache cache, LineSelection considerable, @Nullable IvBlockCollection blockCollection, StructurePlaceContext context) {
if (blockCollection == null)
throw new IllegalArgumentException("Missing a block collection!");
List<Pair<LineSelection, Float>> consideration = new ArrayList<>();
int[] size = StructureBoundingBoxes.size(context.boundingBox);
BlockPos lowerCoord = StructureBoundingBoxes.min(context.boundingBox);
Set<BlockPos.MutableBlockPos> sources = BlockAreas.streamMutablePositions(blockCollection.area()).filter(p -> sourceMatcher.evaluate(() -> blockCollection.getBlockState(p))).map(p -> new BlockPos.MutableBlockPos(context.transform.apply(p, size).add(lowerCoord.getX(), 0, lowerCoord.getZ()))).collect(Collectors.toSet());
for (IntegerRange range : (Iterable<IntegerRange>) considerable.streamSections(null, true)::iterator) {
Float curConformity = null;
int lastY = range.getMax();
int end = range.getMin();
for (int y = lastY; y >= end; y--) {
int finalY = y;
sources.forEach(p -> p.move(EnumFacing.UP, finalY));
float conformity = weight(cache, sources, requiredConformity);
sources.forEach(p -> p.move(EnumFacing.DOWN, finalY));
if (curConformity == null) {
curConformity = conformity;
lastY = y;
} else if (!DoubleMath.fuzzyEquals(conformity, curConformity, 0.01)) {
consideration.add(Pair.of(LineSelection.fromRange(IntegerRanges.from(lastY, y + 1), true), weight(curConformity)));
curConformity = conformity;
lastY = y;
}
}
if (curConformity != null)
consideration.add(Pair.of(LineSelection.fromRange(IntegerRanges.from(lastY, end), true), weight(curConformity)));
}
return consideration;
}
use of ivorius.ivtoolkit.blocks.IvBlockCollection in project RecurrentComplex by Ivorforce.
the class TransformerEnsureBlocks method mayGenerate.
@Override
public boolean mayGenerate(NBTNone instanceData, StructurePrepareContext context, IvWorldData worldData) {
IvBlockCollection blockCollection = worldData.blockCollection;
int[] areaSize = new int[] { blockCollection.width, blockCollection.height, blockCollection.length };
BlockPos lowerCoord = StructureBoundingBoxes.min(context.boundingBox);
BlockPos.MutableBlockPos worldCoord = new BlockPos.MutableBlockPos();
for (BlockPos sourcePos : BlockAreas.mutablePositions(blockCollection.area())) {
if (sourceMatcher.test(blockCollection.getBlockState(sourcePos))) {
IvMutableBlockPos.add(context.transform.applyOn(sourcePos, worldCoord, areaSize), lowerCoord);
if (!(destMatcher.expressionIsEmpty() || destMatcher.evaluate(() -> PositionedBlockExpression.Argument.at(context.environment.world, worldCoord))))
return false;
}
}
return true;
}
use of ivorius.ivtoolkit.blocks.IvBlockCollection 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();
});
}
}
use of ivorius.ivtoolkit.blocks.IvBlockCollection in project RecurrentComplex by Ivorforce.
the class GenericStructure method generate.
@Override
public void generate(@Nonnull final StructureSpawnContext context, @Nonnull InstanceData instanceData, @Nonnull TransformerMulti foreignTransformer) {
WorldServer world = context.environment.world;
IvWorldData worldData = constructWorldData();
boolean asSource = context.generateAsSource;
RunTransformer transformer = getRunTransformer(instanceData, foreignTransformer, asSource);
instanceData.variableDomain.fill(context.environment.variables);
// The world initializes the block event array after it generates the world - in the constructor
// This hackily sets the field to a temporary value. Yay.
// Hax
RCAccessorWorldServer.ensureBlockEventArray(world);
IvBlockCollection blockCollection = worldData.blockCollection;
int[] areaSize = new int[] { blockCollection.width, blockCollection.height, blockCollection.length };
BlockPos origin = StructureBoundingBoxes.min(context.boundingBox);
Map<BlockPos, NBTTagCompound> tileEntityCompounds = new HashMap<>();
for (NBTTagCompound tileEntityCompound : worldData.tileEntities) {
BlockPos src = RCMover.getTileEntityPos(tileEntityCompound);
tileEntityCompounds.put(src, tileEntityCompound);
}
if (transformer != null)
transformer.transformer.transform(transformer.instanceData, Transformer.Phase.BEFORE, context, worldData, transformer);
StructureBoundingBox relevantSourceArea = context.sourceIntersection(BlockAreas.toBoundingBox(blockCollection.area()));
if (// Why did we get asked to generate again?
relevantSourceArea != null) {
context.freezeHeightMap(relevantSourceArea);
BlockPos.MutableBlockPos worldPos = new BlockPos.MutableBlockPos();
for (int pass = 0; pass < 2; pass++) {
for (BlockPos sourcePos : RCStructureBoundingBoxes.mutablePositions(relevantSourceArea)) {
IvMutableBlockPos.add(context.transform.applyOn(sourcePos, worldPos, areaSize), origin);
if (context.includesComplex(worldPos)) {
IBlockState state = PosTransformer.transformBlockState(blockCollection.getBlockState(sourcePos), context.transform);
if (pass == getPass(state) && (transformer == null || !transformer.transformer.skipGeneration(transformer.instanceData, context, worldPos, state, worldData, sourcePos))) {
setBlock(context, areaSize, worldPos, state, () -> tileEntityCompounds.get(sourcePos));
}
}
}
}
context.meltHeightMap();
}
if (transformer != null)
transformer.transformer.transform(transformer.instanceData, Transformer.Phase.AFTER, context, worldData, transformer);
for (NBTTagCompound entityCompound : worldData.entities) {
double[] transformedEntityPos = context.transform.applyOn(getEntityPos(entityCompound), areaSize);
if (context.includes(new Vec3i(transformedEntityPos[0] + origin.getX(), transformedEntityPos[1] + origin.getY(), transformedEntityPos[2] + origin.getZ()))) {
Entity entity = EntityList.createEntityFromNBT(entityCompound, world);
if (entity != null) {
PosTransformer.transformEntityPos(entity, context.transform, areaSize);
Mover.moveEntity(entity, origin);
RCAccessorEntity.setEntityUniqueID(entity, UUID.randomUUID());
generateEntityContents(context, entity);
world.spawnEntity(entity);
} else {
RecurrentComplex.logger.error("Error loading entity with ID '" + entityCompound.getString("id") + "'");
}
}
}
}
Aggregations