use of net.minecraft.world.chunk.ChunkSection in project roadrunner by MaxNeedsSnacks.
the class LandPathNodeMakerMixin method getNodeTypeFromNeighbors.
/**
* @reason Use optimized implementation which avoids scanning blocks for dangers where possible
* @author JellySquid
*/
@Overwrite
public static PathNodeType getNodeTypeFromNeighbors(BlockView world, BlockPos.Mutable pos, PathNodeType type) {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
ChunkSection section = null;
// reads to just one chunk and avoid hits against the server chunk manager.
if (world instanceof CollisionView && WorldHelper.areNeighborsWithinSameChunk(pos)) {
// if the cached chunk section was initialized will early-exit.
if (!World.isOutOfBuildLimitVertically(y)) {
// This cast is always safe and is necessary to obtain direct references to chunk sections.
Chunk chunk = (Chunk) ((CollisionView) world).getExistingChunk(x >> 4, z >> 4);
// An empty chunk or section will never pose any danger sources, which will be caught later.
if (chunk != null) {
section = chunk.getSectionArray()[y >> 4];
}
}
// against this chunk section will always fail, allowing us to fast-exit.
if (ChunkSection.isEmpty(section) || PathNodeCache.isSectionSafeAsNeighbor(section)) {
return type;
}
}
int xStart = x - 1;
int yStart = y - 1;
int zStart = z - 1;
int xEnd = x + 1;
int yEnd = y + 1;
int zEnd = z + 1;
// Vanilla iteration order is XYZ
for (int adjX = xStart; adjX <= xEnd; adjX++) {
for (int adjY = yStart; adjY <= yEnd; adjY++) {
for (int adjZ = zStart; adjZ <= zEnd; adjZ++) {
// Skip the vertical column of the origin block
if (adjX == x && adjZ == z) {
continue;
}
BlockState state;
// retrieval by calling upon the cached chunk directly.
if (section != null) {
state = section.getBlockState(adjX & 15, adjY & 15, adjZ & 15);
} else {
state = world.getBlockState(pos.set(adjX, adjY, adjZ));
}
// Ensure that the block isn't air first to avoid expensive hash table accesses
if (state.isAir()) {
continue;
}
PathNodeType neighborType = PathNodeCache.getNeighborPathNodeType(state);
if (neighborType != PathNodeType.OPEN) {
return neighborType;
}
}
}
}
return type;
}
use of net.minecraft.world.chunk.ChunkSection in project roadrunner by MaxNeedsSnacks.
the class ExplosionMixin method traverseBlock.
/**
* Called for every step made by a ray being cast by an explosion.
*
* @param strength The strength of the ray during this step
* @param blockX The x-coordinate of the block the ray is inside of
* @param blockY The y-coordinate of the block the ray is inside of
* @param blockZ The z-coordinate of the block the ray is inside of
* @return The resistance of the current block space to the ray
*/
private float traverseBlock(float strength, int blockX, int blockY, int blockZ, LongOpenHashSet touched) {
BlockPos pos = this.cachedPos.set(blockX, blockY, blockZ);
// Early-exit if the y-coordinate is out of bounds.
if (World.isOutOfBuildLimitVertically(blockY)) {
Optional<Float> blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, Blocks.AIR.getDefaultState(), Fluids.EMPTY.getDefaultState());
// noinspection OptionalIsPresent
if (blastResistance.isPresent()) {
return (blastResistance.get() + 0.3F) * 0.3F;
}
return 0.0F;
}
int chunkX = blockX >> 4;
int chunkZ = blockZ >> 4;
// Avoid calling into the chunk manager as much as possible through managing chunks locally
if (this.prevChunkX != chunkX || this.prevChunkZ != chunkZ) {
this.prevChunk = this.world.getChunk(chunkX, chunkZ);
this.prevChunkX = chunkX;
this.prevChunkZ = chunkZ;
}
final Chunk chunk = this.prevChunk;
BlockState blockState = Blocks.AIR.getDefaultState();
float totalResistance = 0.0F;
Optional<Float> blastResistance;
labelGetBlastResistance: {
// If the chunk is missing or out of bounds, assume that it is air
if (chunk != null) {
// We operate directly on chunk sections to avoid interacting with BlockPos and to squeeze out as much
// performance as possible here
ChunkSection section = chunk.getSectionArray()[blockY >> 4];
// If the section doesn't exist or it's empty, assume that the block is air
if (section != null && !section.isEmpty()) {
// Retrieve the block state from the chunk section directly to avoid associated overhead
blockState = section.getBlockState(blockX & 15, blockY & 15, blockZ & 15);
// If the block state is air, it cannot have fluid or any kind of resistance, so just leave
if (blockState.getBlock() != Blocks.AIR) {
// Rather than query the fluid state from the container as we just did with the block state, we can
// simply ask the block state we retrieved what fluid it has. This is exactly what the call would
// do anyways, except that it would have to retrieve the block state a second time, adding overhead.
FluidState fluidState = blockState.getFluidState();
// Get the explosion resistance like vanilla
blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, blockState, fluidState);
break labelGetBlastResistance;
}
}
}
blastResistance = this.behavior.getBlastResistance((Explosion) (Object) this, this.world, pos, Blocks.AIR.getDefaultState(), Fluids.EMPTY.getDefaultState());
}
// Calculate how much this block will resist an explosion's ray
if (blastResistance.isPresent()) {
totalResistance = (blastResistance.get() + 0.3F) * 0.3F;
}
// Check if this ray is still strong enough to break blocks, and if so, add this position to the set
// of positions to destroy
float reducedStrength = strength - totalResistance;
if (reducedStrength > 0.0F && (this.explodeAirBlocks || !blockState.isAir())) {
if (this.behavior.canDestroyBlock((Explosion) (Object) this, this.world, pos, blockState, reducedStrength)) {
touched.add(pos.asLong());
}
}
return totalResistance;
}
use of net.minecraft.world.chunk.ChunkSection in project polymer-core by teampolymer.
the class VirtualChunk method setBlockState.
@Override
public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) {
int x = pos.getX() & 15;
int y = pos.getY();
int z = pos.getZ() & 15;
ChunkSection chunksection = this.getSections()[y >> 4];
if (chunksection == EMPTY_SECTION) {
if (state.isAir()) {
return null;
}
chunksection = new ChunkSection(y >> 4 << 4);
this.getSections()[y >> 4] = chunksection;
}
if (!state.isAir()) {
this.isEmpty = false;
}
BlockState oldState = chunksection.setBlockState(x, y & 15, z, state);
if (oldState == state) {
return null;
} else {
Block newBlock = state.getBlock();
Block oldBlock = oldState.getBlock();
this.getOrCreateHeightmapUnprimed(Heightmap.Type.MOTION_BLOCKING).update(x, y, z, state);
this.getOrCreateHeightmapUnprimed(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, state);
this.getOrCreateHeightmapUnprimed(Heightmap.Type.OCEAN_FLOOR).update(x, y, z, state);
this.getOrCreateHeightmapUnprimed(Heightmap.Type.WORLD_SURFACE).update(x, y, z, state);
if ((oldBlock != newBlock || !state.hasTileEntity()) && oldState.hasTileEntity()) {
// this.world.removeTileEntity(pos);
}
if (!chunksection.getBlockState(x, y & 15, z).is(newBlock)) {
return null;
} else {
if (oldState.hasTileEntity()) {
TileEntity tileentity = this.getBlockEntity(pos, Chunk.CreateEntityType.CHECK);
if (tileentity != null) {
tileentity.clearCache();
}
}
if (state.hasTileEntity()) {
TileEntity te = this.getBlockEntity(pos, Chunk.CreateEntityType.CHECK);
if (te == null) {
te = state.createTileEntity(this.getLevel());
// this.world.setTileEntity(pos, te);
} else {
te.clearCache();
}
}
this.markUnsaved();
return oldState;
}
}
}
use of net.minecraft.world.chunk.ChunkSection in project polymer-core by teampolymer.
the class VirtualChunk method getBlockState.
@Override
@NotNull
public BlockState getBlockState(BlockPos pos) {
int x = pos.getX() & 0xF;
int y = pos.getY();
int z = pos.getZ() & 0xF;
int cy = y >> 4;
ChunkSection[] sections = this.getSections();
if (cy >= 0 && cy < sections.length) {
ChunkSection chunkSection = sections[cy];
if (!ChunkSection.isEmpty(chunkSection)) {
return chunkSection.getBlockState(x, y & 0xF, z);
}
}
return AIR;
}
use of net.minecraft.world.chunk.ChunkSection in project lithium-fabric by CaffeineMC.
the class ChunkCacheMixin method getBlockState.
/**
* @reason Use optimized function
* @author JellySquid
*/
@Overwrite
public BlockState getBlockState(BlockPos pos) {
int y = pos.getY();
if (!(y < this.bottomY || y >= this.topY)) {
int x = pos.getX();
int z = pos.getZ();
int chunkX = (Pos.ChunkCoord.fromBlockCoord(x)) - this.minX;
int chunkZ = (Pos.ChunkCoord.fromBlockCoord(z)) - this.minZ;
if (chunkX >= 0 && chunkX < this.xLen && chunkZ >= 0 && chunkZ < this.zLen) {
Chunk chunk = this.chunksFlat[(chunkX * this.zLen) + chunkZ];
// Avoid going through Chunk#getBlockState
if (chunk != null) {
ChunkSection section = chunk.getSectionArray()[Pos.SectionYIndex.fromBlockCoord(this, y)];
if (section != null) {
return section.getBlockState(x & 15, y & 15, z & 15);
}
}
}
}
return DEFAULT_BLOCK;
}
Aggregations