use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.
the class SpongeTeleportHelper method getBlockLocations.
private Stream<Vector3i> getBlockLocations(ServerLocation worldLocation, int height, int width) {
// We don't want to warp outside of the world border, so we want to check that we're within it.
final WorldBorder.Settings worldBorder = (WorldBorder.Settings) worldLocation.world().properties().worldBorder();
final double radius = worldBorder.getSize() / 2.0D;
int worldBorderMinX = GenericMath.floor(worldBorder.getCenterX() - radius);
int worldBorderMinZ = GenericMath.floor(worldBorder.getCenterZ() - radius);
int worldBorderMaxX = GenericMath.floor(worldBorder.getCenterX() + radius);
int worldBorderMaxZ = GenericMath.floor(worldBorder.getCenterZ() + radius);
// Get the World and get the maximum Y value.
int worldMaxY = worldLocation.world().max().y();
Vector3i vectorLocation = worldLocation.blockPosition();
// We use clamp to remain within the world confines, so we don't waste time checking blocks outside of the
// world border and the world height.
int minY = GenericMath.clamp(vectorLocation.y() - height, 0, worldMaxY);
int maxY = GenericMath.clamp(vectorLocation.y() + height, 0, worldMaxY);
int minX = GenericMath.clamp(vectorLocation.x() - width, worldBorderMinX, worldBorderMaxX);
int maxX = GenericMath.clamp(vectorLocation.x() + width, worldBorderMinX, worldBorderMaxX);
int minZ = GenericMath.clamp(vectorLocation.z() - width, worldBorderMinZ, worldBorderMaxZ);
int maxZ = GenericMath.clamp(vectorLocation.z() + width, worldBorderMinZ, worldBorderMaxZ);
// We now iterate over all possible x, y and z positions to get all possible vectors.
List<Vector3i> vectors = new ArrayList<>();
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
vectors.add(new Vector3i(x, y, z));
}
}
}
Comparator<Vector3i> c = Comparator.comparingInt(vectorLocation::distanceSquared);
// The compiler seems to need this to be a new line.
// We check to see what the y location is, preferring changes in Y over X and Z, and higher over lower locations.
c = c.thenComparing(x -> -Math.abs(vectorLocation.y() - x.y())).thenComparing(x -> -x.y());
// Sort them according to the distance to the provided worldLocation.
return vectors.stream().sorted(c);
}
use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.
the class VolumeStreamUtils method getBiomeStream.
@SuppressWarnings("unchecked")
public static <R extends Region<R>> VolumeStream<R, org.spongepowered.api.world.biome.Biome> getBiomeStream(final LevelReader reader, final Vector3i min, final Vector3i max, final StreamOptions options) {
VolumeStreamUtils.validateStreamArgs(Objects.requireNonNull(min, "min"), Objects.requireNonNull(max, "max"), Objects.requireNonNull(options, "options"));
final boolean shouldCarbonCopy = options.carbonCopy();
final Vector3i size = max.sub(min).add(1, 1, 1);
@MonotonicNonNull final ObjectArrayMutableBiomeBuffer backingVolume;
if (shouldCarbonCopy) {
final Registry<Biome> biomeRegistry;
if (reader instanceof Level) {
biomeRegistry = ((Level) reader).registryAccess().registry(Registry.BIOME_REGISTRY).get();
} else {
biomeRegistry = BuiltinRegistries.BIOME;
}
backingVolume = new ObjectArrayMutableBiomeBuffer(min, size, VolumeStreamUtils.nativeToSpongeRegistry(biomeRegistry));
} else {
backingVolume = null;
}
return VolumeStreamUtils.<R, org.spongepowered.api.world.biome.Biome, net.minecraft.world.level.biome.Biome, ChunkAccess, BlockPos>generateStream(min, max, options, // Ref
(R) reader, // IdentityFunction
(pos, biome) -> {
if (shouldCarbonCopy) {
backingVolume.setBiome(pos, biome);
}
}, // ChunkAccessor
VolumeStreamUtils.getChunkAccessorByStatus(reader, options.loadingStyle().generateArea()), // Biome by key
(key, biome) -> key, // Entity Accessor
VolumeStreamUtils.getBiomesForChunkByPos(reader, min, max), // Filtered Position Entity Accessor
(blockPos, world) -> {
final net.minecraft.world.level.biome.Biome biome = shouldCarbonCopy ? backingVolume.getNativeBiome(blockPos.getX(), blockPos.getY(), blockPos.getZ()) : ((LevelReader) world).getBiome(blockPos);
return new Tuple<>(blockPos, biome);
});
}
use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.
the class VolumeStreamUtils method getElementByPosition.
private static <T> Function<ChunkAccess, Stream<Map.Entry<BlockPos, T>>> getElementByPosition(final TriFunction<ChunkAccess, LevelChunkSection, BlockPos, T> elementAccessor, final Vector3i min, final Vector3i max) {
// Build the min and max
final ChunkCursor minCursor = new ChunkCursor(min);
final ChunkCursor maxCursor = new ChunkCursor(max);
return chunk -> {
final ChunkPos pos = chunk.getPos();
final int xStart = pos.x == minCursor.chunkX ? minCursor.xOffset : 0;
// 16 because IntStream.range is upper range exclusive
final int xEnd = pos.x == maxCursor.chunkX ? maxCursor.xOffset + 1 : 16;
final int zStart = pos.z == minCursor.chunkZ ? minCursor.zOffset : 0;
// 16 because IntStream.range is upper range exclusive
final int zEnd = pos.z == maxCursor.chunkZ ? maxCursor.zOffset + 1 : 16;
final int chunkMinX = pos.x << 4;
final int chunkMinZ = pos.z << 4;
return Arrays.stream(chunk.getSections()).filter(Objects::nonNull).filter(chunkSection -> chunkSection.bottomBlockY() >= minCursor.ySection && chunkSection.bottomBlockY() <= maxCursor.ySection).flatMap(chunkSection -> IntStream.range(zStart, zEnd).mapToObj(z -> IntStream.range(xStart, xEnd).mapToObj(x -> {
final int sectionY = chunkSection.bottomBlockY();
final int yStart = sectionY == minCursor.ySection ? minCursor.yOffset : 0;
// plus 1 because of IntStream range exclusive
final int yEnd = sectionY == maxCursor.ySection ? maxCursor.yOffset + 1 : 16;
return IntStream.range(yStart, yEnd).mapToObj(y -> {
final int adjustedX = x + chunkMinX;
final int adjustedY = y + sectionY;
final int adjustedZ = z + chunkMinZ;
final BlockPos blockPos = new BlockPos(adjustedX, adjustedY, adjustedZ);
final T apply = Objects.requireNonNull(elementAccessor.apply(chunk, chunkSection, blockPos), "Element cannot be null");
return new AbstractMap.SimpleEntry<>(blockPos, apply);
});
})).flatMap(Function.identity()).flatMap(Function.identity()));
};
}
use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.
the class AbstractReferentArchetypeVolume method removeBlockEntity.
@Override
public void removeBlockEntity(final int x, final int y, final int z) {
final Vector3i transformed = this.inverseTransform(x, y, z);
this.consumeReference(a -> a.removeBlockEntity(transformed.x(), transformed.y(), transformed.z()));
}
use of org.spongepowered.math.vector.Vector3i in project SpongeCommon by SpongePowered.
the class AbstractReferentArchetypeVolume method applyTransformationsToStream.
private <T> VolumeStream<ArchetypeVolume, T> applyTransformationsToStream(final Vector3i min, final Vector3i max, final StreamOptions options, final StreamCreator<A, T> streamCreator, final VolumeStreamUtils.TriFunction<VolumeElement<ArchetypeVolume, T>, Supplier<Rotation>, Supplier<Mirror>, T> elementTransform) {
final Vector3i transformedMin = this.min();
final Vector3i transformedMax = this.max();
VolumeStreamUtils.validateStreamArgs(min, max, transformedMin, transformedMax, options);
final Vector3i minDiff = min.sub(transformedMin);
final Vector3i maxDiff = transformedMax.sub(max);
final boolean xMirror = this.transformation.mirror(Axis.X);
final boolean zMirror = this.transformation.mirror(Axis.Z);
final Supplier<Mirror> mirror = xMirror ? Mirrors.FRONT_BACK : zMirror ? Mirrors.LEFT_RIGHT : Mirrors.NONE;
return this.applyReference(a -> streamCreator.createStream(a, a.min().add(minDiff), a.max().sub(maxDiff), options)).transform(e -> VolumeElement.of(this, elementTransform.apply(e, this.transformation::rotation, mirror), this.transformStreamBlockPosition(e.position().add(VolumePositionTranslators.BLOCK_OFFSET)).sub(VolumePositionTranslators.BLOCK_OFFSET)));
}
Aggregations