123 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.level.lighting;
 | |
| 
 | |
| import com.google.common.annotations.VisibleForTesting;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Direction;
 | |
| import net.minecraft.core.SectionPos;
 | |
| import net.minecraft.world.level.ChunkPos;
 | |
| import net.minecraft.world.level.block.Blocks;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.chunk.LightChunk;
 | |
| import net.minecraft.world.level.chunk.LightChunkGetter;
 | |
| 
 | |
| public final class BlockLightEngine extends LightEngine<BlockLightSectionStorage.BlockDataLayerStorageMap, BlockLightSectionStorage> {
 | |
| 	private final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
 | |
| 
 | |
| 	public BlockLightEngine(LightChunkGetter chunkSource) {
 | |
| 		this(chunkSource, new BlockLightSectionStorage(chunkSource));
 | |
| 	}
 | |
| 
 | |
| 	@VisibleForTesting
 | |
| 	public BlockLightEngine(LightChunkGetter chunkSource, BlockLightSectionStorage storage) {
 | |
| 		super(chunkSource, storage);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void checkNode(long packedPos) {
 | |
| 		long l = SectionPos.blockToSection(packedPos);
 | |
| 		if (this.storage.storingLightForSection(l)) {
 | |
| 			BlockState blockState = this.getState(this.mutablePos.set(packedPos));
 | |
| 			int i = this.getEmission(packedPos, blockState);
 | |
| 			int j = this.storage.getStoredLevel(packedPos);
 | |
| 			if (i < j) {
 | |
| 				this.storage.setStoredLevel(packedPos, 0);
 | |
| 				this.enqueueDecrease(packedPos, LightEngine.QueueEntry.decreaseAllDirections(j));
 | |
| 			} else {
 | |
| 				this.enqueueDecrease(packedPos, PULL_LIGHT_IN_ENTRY);
 | |
| 			}
 | |
| 
 | |
| 			if (i > 0) {
 | |
| 				this.enqueueIncrease(packedPos, LightEngine.QueueEntry.increaseLightFromEmission(i, isEmptyShape(blockState)));
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void propagateIncrease(long packedPos, long queueEntry, int lightLevel) {
 | |
| 		BlockState blockState = null;
 | |
| 
 | |
| 		for (Direction direction : PROPAGATION_DIRECTIONS) {
 | |
| 			if (LightEngine.QueueEntry.shouldPropagateInDirection(queueEntry, direction)) {
 | |
| 				long l = BlockPos.offset(packedPos, direction);
 | |
| 				if (this.storage.storingLightForSection(SectionPos.blockToSection(l))) {
 | |
| 					int i = this.storage.getStoredLevel(l);
 | |
| 					int j = lightLevel - 1;
 | |
| 					if (j > i) {
 | |
| 						this.mutablePos.set(l);
 | |
| 						BlockState blockState2 = this.getState(this.mutablePos);
 | |
| 						int k = lightLevel - this.getOpacity(blockState2);
 | |
| 						if (k > i) {
 | |
| 							if (blockState == null) {
 | |
| 								blockState = LightEngine.QueueEntry.isFromEmptyShape(queueEntry) ? Blocks.AIR.defaultBlockState() : this.getState(this.mutablePos.set(packedPos));
 | |
| 							}
 | |
| 
 | |
| 							if (!this.shapeOccludes(blockState, blockState2, direction)) {
 | |
| 								this.storage.setStoredLevel(l, k);
 | |
| 								if (k > 1) {
 | |
| 									this.enqueueIncrease(l, LightEngine.QueueEntry.increaseSkipOneDirection(k, isEmptyShape(blockState2), direction.getOpposite()));
 | |
| 								}
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void propagateDecrease(long packedPos, long lightLevel) {
 | |
| 		int i = LightEngine.QueueEntry.getFromLevel(lightLevel);
 | |
| 
 | |
| 		for (Direction direction : PROPAGATION_DIRECTIONS) {
 | |
| 			if (LightEngine.QueueEntry.shouldPropagateInDirection(lightLevel, direction)) {
 | |
| 				long l = BlockPos.offset(packedPos, direction);
 | |
| 				if (this.storage.storingLightForSection(SectionPos.blockToSection(l))) {
 | |
| 					int j = this.storage.getStoredLevel(l);
 | |
| 					if (j != 0) {
 | |
| 						if (j <= i - 1) {
 | |
| 							BlockState blockState = this.getState(this.mutablePos.set(l));
 | |
| 							int k = this.getEmission(l, blockState);
 | |
| 							this.storage.setStoredLevel(l, 0);
 | |
| 							if (k < j) {
 | |
| 								this.enqueueDecrease(l, LightEngine.QueueEntry.decreaseSkipOneDirection(j, direction.getOpposite()));
 | |
| 							}
 | |
| 
 | |
| 							if (k > 0) {
 | |
| 								this.enqueueIncrease(l, LightEngine.QueueEntry.increaseLightFromEmission(k, isEmptyShape(blockState)));
 | |
| 							}
 | |
| 						} else {
 | |
| 							this.enqueueIncrease(l, LightEngine.QueueEntry.increaseOnlyOneDirection(j, false, direction.getOpposite()));
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private int getEmission(long packedPos, BlockState state) {
 | |
| 		int i = state.getLightEmission();
 | |
| 		return i > 0 && this.storage.lightOnInSection(SectionPos.blockToSection(packedPos)) ? i : 0;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void propagateLightSources(ChunkPos chunkPos) {
 | |
| 		this.setLightEnabled(chunkPos, true);
 | |
| 		LightChunk lightChunk = this.chunkSource.getChunkForLighting(chunkPos.x, chunkPos.z);
 | |
| 		if (lightChunk != null) {
 | |
| 			lightChunk.findBlockLightSources((blockPos, blockState) -> {
 | |
| 				int i = blockState.getLightEmission();
 | |
| 				this.enqueueIncrease(blockPos.asLong(), LightEngine.QueueEntry.increaseLightFromEmission(i, isEmptyShape(blockState)));
 | |
| 			});
 | |
| 		}
 | |
| 	}
 | |
| }
 |