use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.
the class VolumeStreamUtils method getBlockEntityStream.
public static <R extends Region<R>> VolumeStream<R, BlockEntity> getBlockEntityStream(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 ObjectArrayMutableBlockEntityBuffer backingVolume;
if (shouldCarbonCopy) {
backingVolume = new ObjectArrayMutableBlockEntityBuffer(min, size);
} else {
backingVolume = null;
}
return VolumeStreamUtils.<R, BlockEntity, net.minecraft.world.level.block.entity.BlockEntity, ChunkAccess, BlockPos>generateStream(min, max, options, // Ref
(R) reader, // IdentityFunction
VolumeStreamUtils.getBlockEntityOrCloneToBackingVolume(shouldCarbonCopy, backingVolume, reader instanceof Level ? (Level) reader : null), // ChunkAccessor
VolumeStreamUtils.getChunkAccessorByStatus(reader, options.loadingStyle().generateArea()), // TileEntity by block pos
(key, tileEntity) -> key, // TileEntity Accessor
(chunk) -> chunk instanceof LevelChunk ? ((LevelChunk) chunk).getBlockEntities().entrySet().stream().filter(entry -> VecHelper.inBounds(entry.getKey(), min, max)) : Stream.empty(), // Filtered Position TileEntity Accessor
(blockPos, world) -> {
final net.minecraft.world.level.block.entity.@Nullable BlockEntity tileEntity = shouldCarbonCopy ? backingVolume.getTileEntity(blockPos) : ((LevelReader) world).getBlockEntity(blockPos);
return new Tuple<>(blockPos, tileEntity);
});
}
use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method bridge$createSnapshot.
@Override
public SpongeBlockSnapshot bridge$createSnapshot(final net.minecraft.world.level.block.state.BlockState state, final BlockPos pos, final BlockChangeFlag updateFlag) {
final SpongeBlockSnapshot.BuilderImpl builder = SpongeBlockSnapshot.BuilderImpl.pooled();
builder.reset();
builder.blockState(state).world((ServerLevel) (Object) this).position(VecHelper.toVector3i(pos));
final LevelChunk chunk = this.shadow$getChunkAt(pos);
if (chunk == null) {
return builder.flag(updateFlag).build();
}
final Optional<UUID> creator = ((LevelChunkBridge) chunk).bridge$getBlockCreatorUUID(pos);
final Optional<UUID> notifier = ((LevelChunkBridge) chunk).bridge$getBlockNotifierUUID(pos);
creator.ifPresent(builder::creator);
notifier.ifPresent(builder::notifier);
final boolean hasTileEntity = ((BlockStateBridge) state).bridge$hasTileEntity();
final net.minecraft.world.level.block.entity.BlockEntity tileEntity = chunk.getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
if (hasTileEntity || tileEntity != null) {
// We MUST only check to see if a TE exists to avoid creating a new one.
if (tileEntity != null) {
// TODO - custom data.
final CompoundTag nbt = new CompoundTag();
// Some mods like OpenComputers assert if attempting to save robot while moving
try {
tileEntity.save(nbt);
builder.addUnsafeCompound(nbt);
} catch (final Throwable t) {
// ignore
}
}
}
builder.flag(updateFlag);
return builder.build();
}
use of net.minecraft.world.level.chunk.LevelChunk in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method shadow$neighborChanged.
@Override
public void shadow$neighborChanged(final BlockPos pos, final Block blockIn, final BlockPos fromPos) {
final BlockPos immutableTarget = pos.immutable();
final BlockPos immutableFrom = fromPos.immutable();
// Sponge Start - Check asynchronicity,
// if not on the server thread and we're a server world, we've got problems...
final PhaseTracker server = PhaseTracker.SERVER;
if (server.getSidedThread() != Thread.currentThread()) {
// lol no, report the block change properly
new PrettyPrinter(60).add("Illegal Async PhaseTracker Access").centre().hr().addWrapped(PhasePrinter.ASYNC_TRACKER_ACCESS).add().add(new Exception("Async Block Notifcation Detected")).log(SpongeCommon.logger(), Level.ERROR);
// Maybe? I don't think this is wise to try and sync back a notification on the main thread.
return;
}
// world that Sponge isn't directly managing, so we'll just ignore trying to record on those.
if (this.bridge$isFake()) {
// If we're fake, well, we could effectively call this without recording on worlds we don't
// want to care about.
super.shadow$neighborChanged(immutableTarget, blockIn, immutableFrom);
return;
}
// Otherwise, we continue with recording, maybe.
final LevelChunk targetChunk = this.shadow$getChunkAt(immutableTarget);
final BlockState targetBlockState = targetChunk.getBlockState(immutableTarget);
// Sponge - Shortcircuit if the block has no neighbor logic
if (!((TrackableBlockBridge) targetBlockState.getBlock()).bridge$overridesNeighborNotificationLogic()) {
return;
}
// Sponge End
// Sponge start - prepare notification
final PhaseContext<@NonNull ?> peek = server.getPhaseContext();
// try { // Vanilla - We need to push the effect transactor so that it always pops
try {
final Supplier<ServerLevel> worldSupplier = VolumeStreamUtils.createWeaklyReferencedSupplier((ServerLevel) (Object) this, "ServerWorld");
final net.minecraft.world.level.block.entity.@Nullable BlockEntity existingTile = targetChunk.getBlockEntity(immutableTarget, LevelChunk.EntityCreationType.CHECK);
peek.getTransactor().logNeighborNotification(worldSupplier, immutableFrom, blockIn, immutableTarget, targetBlockState, existingTile);
peek.associateNeighborStateNotifier(immutableFrom, targetBlockState.getBlock(), immutableTarget, ((ServerLevel) (Object) this), PlayerTracker.Type.NOTIFIER);
// Sponge End
targetBlockState.neighborChanged(((ServerLevel) (Object) this), immutableTarget, blockIn, immutableFrom, false);
} catch (final Throwable throwable) {
final CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours");
final CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated");
crashreportcategory.setDetail("Source block type", () -> {
try {
return String.format("ID #%d (%s // %s)", Registry.BLOCK.getId(blockIn), blockIn.getDescriptionId(), blockIn.getClass().getCanonicalName());
} catch (final Throwable var2) {
return "ID #" + Registry.BLOCK.getId(blockIn);
}
});
CrashReportCategory.populateBlockDetails(crashreportcategory, immutableTarget, targetBlockState);
throw new ReportedException(crashreport);
}
}
use of net.minecraft.world.level.chunk.LevelChunk in project Denizen-For-Bukkit by DenizenScript.
the class ChunkHelperImpl method setAllBiomes.
@Override
public void setAllBiomes(Chunk chunk, BiomeNMS biome) {
Biome nmsBiome = ((BiomeNMSImpl) biome).biomeBase;
LevelChunk nmsChunk = ((CraftChunk) chunk).getHandle();
ChunkBiomeContainer biomeContainer = nmsChunk.getBiomes();
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 64; y++) {
for (int z = 0; z < 4; z++) {
biomeContainer.setBiome(x, y, z, nmsBiome);
}
}
}
nmsChunk.markUnsaved();
}
use of net.minecraft.world.level.chunk.LevelChunk in project Denizen-For-Bukkit by DenizenScript.
the class ItemHelperImpl method renderFullMap.
/**
* Copied from MapItem.update, redesigned slightly to render totally rather than just relative to a player.
* Some variables manually renamed for readability.
* Also contains reflection fixes for Spigot's FluidState bug.
*/
public static void renderFullMap(MapItemSavedData worldmap, int xMin, int zMin, int xMax, int zMax) {
Level world = ((CraftWorld) worldmap.mapView.getWorld()).getHandle();
int scale = 1 << worldmap.scale;
int mapX = worldmap.x;
int mapZ = worldmap.z;
for (int x = xMin; x < xMax; x++) {
double d0 = 0.0D;
for (int z = zMin; z < zMax; z++) {
int k2 = (mapX / scale + x - 64) * scale;
int l2 = (mapZ / scale + z - 64) * scale;
Multiset<MaterialColor> multiset = LinkedHashMultiset.create();
LevelChunk chunk = world.getChunkAt(new BlockPos(k2, 0, l2));
if (!chunk.isEmpty()) {
ChunkPos chunkcoordintpair = chunk.getPos();
int i3 = k2 & 15;
int j3 = l2 & 15;
int k3 = 0;
double d1 = 0.0D;
if (world.dimensionType().hasCeiling()) {
int l3 = k2 + l2 * 231871;
l3 = l3 * l3 * 31287121 + l3 * 11;
if ((l3 >> 20 & 1) == 0) {
multiset.add(Blocks.DIRT.defaultBlockState().getMapColor(world, BlockPos.ZERO), 10);
} else {
multiset.add(Blocks.STONE.defaultBlockState().getMapColor(world, BlockPos.ZERO), 100);
}
d1 = 100.0D;
} else {
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
BlockPos.MutableBlockPos blockposition_mutableblockposition1 = new BlockPos.MutableBlockPos();
for (int i4 = 0; i4 < scale; ++i4) {
for (int j4 = 0; j4 < scale; ++j4) {
int k4 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i4 + i3, j4 + j3) + 1;
BlockState iblockdata;
if (k4 <= world.getMinBuildHeight() + 1) {
iblockdata = Blocks.BEDROCK.defaultBlockState();
} else {
do {
--k4;
blockposition_mutableblockposition.set(chunkcoordintpair.getMinBlockX() + i4 + i3, k4, chunkcoordintpair.getMinBlockZ() + j4 + j3);
iblockdata = chunk.getBlockState(blockposition_mutableblockposition);
} while (iblockdata.getMapColor(world, blockposition_mutableblockposition) == MaterialColor.NONE && k4 > world.getMinBuildHeight());
if (k4 > world.getMinBuildHeight() && !blockStateFluidIsEmpty(iblockdata)) {
int l4 = k4 - 1;
blockposition_mutableblockposition1.set(blockposition_mutableblockposition);
BlockState iblockdata1;
do {
blockposition_mutableblockposition1.t(l4--);
iblockdata1 = chunk.getBlockState(blockposition_mutableblockposition1);
k3++;
} while (l4 > world.getMinBuildHeight() && !blockStateFluidIsEmpty(iblockdata1));
iblockdata = getCorrectStateForFluidBlock(world, iblockdata, blockposition_mutableblockposition);
}
}
worldmap.checkBanners(world, chunkcoordintpair.getMinBlockX() + i4 + i3, chunkcoordintpair.getMinBlockZ() + j4 + j3);
d1 += (double) k4 / (double) (scale * scale);
multiset.add(iblockdata.getMapColor(world, blockposition_mutableblockposition));
}
}
}
k3 /= scale * scale;
double d2 = (d1 - d0) * 4.0D / (double) (scale + 4) + ((double) (x + z & 1) - 0.5D) * 0.4D;
byte b0 = 1;
if (d2 > 0.6D) {
b0 = 2;
}
if (d2 < -0.6D) {
b0 = 0;
}
MaterialColor materialmapcolor = Iterables.getFirst(Multisets.copyHighestCountFirst(multiset), MaterialColor.NONE);
if (materialmapcolor == MaterialColor.WATER) {
d2 = (double) k3 * 0.1D + (double) (x + z & 1) * 0.2D;
b0 = 1;
if (d2 < 0.5D) {
b0 = 2;
}
if (d2 > 0.9D) {
b0 = 0;
}
}
d0 = d1;
worldmap.updateColor(x, z, (byte) (materialmapcolor.id * 4 + b0));
}
}
}
}
Aggregations