FloodLightCalculation class

Пакет: com.hypixel.hytale.server.core.universe.world.lighting

Файл: com/hypixel/hytale/server/core/universe/world/lighting/FloodLightCalculation.java

implements: LightCalculation

Поля (180)

МодификаторыТипИмя
break
final ChunkLightingManager chunkLightingManager
int columnx
return
return
FluidSection var10
long var10
int var10
BlockSection var10
short var10
int var10
byte var10
int var10
int var10
short var10
Opacity var10
CalculationResult var11
ChunkLightDataBuilder var11
int var11
short var11
byte var11
Vector3ic var11
int var11
BlockType var11
byte var11
short var11
boolean var12
BitSet var12
int var12
byte var12
byte var12
int var12
BlockType var12
Opacity var12
byte var12
byte var12
var12
boolean var13
var13
ChunkLightDataBuilder var13
var13
var13
long var13
int var13
byte var13
int var13
byte var13
int var13
Opacity var13
short var13
byte var13
byte var13
var13
long var14
int var14
byte var14
byte var14
int var14
short var14
byte var14
byte var14
byte var14
var14
BlockSection var15
long var15
boolean var15
short var15
var15
var15
var15
byte var15
WorldChunk var15
byte var15
byte var15
byte var15
byte var15
var15
CalculationResult var16
long var16
int var16
byte var16
BlockSection var16
byte var16
byte var16
byte var16
short var16
var16
var16
var16
long var17
BlockType var17
int var17
BlockSection var17
byte var17
byte var17
byte var17
int var18
ColorLight var18
int var18
byte var18
byte var18
byte var18
int var19
int var19
int var19
byte var19
byte var19
int var2
int var2
int var20
Fluid var20
byte var20
byte var20
byte var21
ColorLight var21
byte var21
byte var21
IntSet var22
byte var22
int var23
var23
var23
int var24
int var24
IntIterator var25
int var25
int var26
int var26
int var27
int var28
byte var29
int var3
WorldChunk var3
int var3
int var4
int var4
int var4
var4
var4
BlockSection[] var4
BlockSection[] var4
BlockSection[] var4
BlockSection var5
WorldChunk var5
WorldChunk var5
ChunkLightDataBuilder var5
int var5
int var5
int var5
int var5
int var5
AtomicLong var6
BitSet var6
ChunkLightDataBuilder var6
BlockType var6
Vector3ic[][] var6
boolean var7
BitSet var7
Opacity var7
ChunkLightData var7
ChunkLightData var7
ChunkLightData var7
LocalCachedChunkAccessor var8
int var8
Ref var8
int var8
short var8
BlockSection[] var8
BlockType var8
BlockSection var9
long var9
int var9
Ref var9
int var9
boolean var9
byte var9
Vector3ic[] var9
int var9
Opacity var9
BlockType var9

Методы (102)

МодификаторыВозвратСигнатура
for for(int var4 = 0; var4 < 10; var4++)
for for(int var14 = 0; var14 < 10; var14++)
for for(int var6 = var2 - 1; var6 <= var2 + 1; var6++)
for for(int var7 = var3 - 1; var7 <= var3 + 1; var7++)
for for(int var8 = var5 - 1; var8 >= var4; var8--)
for for(int var6 = var2 - 1; var6 <= var2 + 1; var6++)
for for(int var7 = var3 - 1; var7 <= var3 + 1; var7++)
for for(int var9 = var5 - 1; var9 >= var4; var9--)
for for(int var7 = 0; var7 < 32; var7++)
for for(int var8 = 0; var8 < 32; var8++)
for for(int var11 = 0; var11 < 32; var11++)
for for(int var30 = 1; var30 < 32; var30++)
for for(Vector2ic var17 : Vector2iUtil.DIRECTIONS)
for for(int var8 = 0; var8 < 32; var8++)
for for(int var9 = 0; var9 < 32; var9++)
for for(int var12 = 0; var12 < 32; var12++)
for for(Vector3ic var23 : Vector3iUtil.BLOCK_SIDES)
for for(int var7 = 0; var7 < this.fromSections.length; var7++)
for for(int var10 = 0; var10 < var9.length; var10++)
for for(int var8 = 0; var8 < 32; var8++)
for for(int var9 = 0; var9 < 32; var9++)
for for(int var8 = 0; var8 < 32; var8++)
protected byte getSkyValuebyte getSkyValue(WorldChunk var1, int var2, int var3, int var4, int var5, int var6, int var7)
if if(var3 != null)
if if(var5 != null)
if if(var3 < 9)
if if(var3 > 0)
if if(var5 == null)
if if(var10 == null)
if if(var7)
if if(var13)
if if(BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA)
if if(var12)
if if(var9)
if if(var12)
if if(var8)
if if(var9 != null)
if if(var10 != null)
if if(var6 == var2 && var7 == var3)
if if(BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA)
if if(var8 != null)
if if(var9 >= 0 && var9 < 10)
if if(var4 > var10)
if if(var24 == -1)
if if(var13 >= 1)
if if(var18 >= 0 && var18 < 32 && var19 >= 0 && var19 < 32)
if if(var21 < var13)
if if(var13 > 1)
if if(var18 != null && var21 != null)
if if(var15 != 0)
if if(var5 == -1)
if if(var7 != Opacity.Solid)
if if(var9 >= 2 || var10 >= 2 || var11 >= 2 || var12 >= 2)
if if(var7 == Opacity.Semitransparent || var7 == Opacity.Cutout)
if if(var13 >= 1 || var14 >= 1 || var15 >= 1 || var16 >= 1)
if if(var24 >= 0 && var24 < 32)
if if(var25 >= 0 && var25 < 32)
if if(var26 >= 0 && var26 < 32)
if if(var13 >= 0 && var13 < 10)
if if(var12 == var3 && var14 == var5)
if if(var15 == null)
if if(var2 != null)
if if(var13 != Opacity.Solid)
if if(var15 >= 2 || var16 >= 2 || var17 >= 2 || var18 >= 2)
if if(var13 == Opacity.Semitransparent || var13 == Opacity.Cutout)
if if(var19 >= 1 || var20 >= 1 || var21 >= 1 || var22 >= 1)
if if(var2 != null)
if if(var12 != Opacity.Solid)
if if(var14 >= 3 || var15 >= 3 || var16 >= 3 || var17 >= 3)
if if(var12 == Opacity.Semitransparent || var12 == Opacity.Cutout)
if if(var18 >= 1 || var19 >= 1 || var20 >= 1 || var21 >= 1)
if if(var2 != null)
if if(var9 != Opacity.Solid)
if if(var11 >= 4 || var12 >= 4 || var13 >= 4 || var14 >= 4)
if if(var9 == Opacity.Semitransparent || var9 == Opacity.Cutout)
if if(var15 >= 1 || var16 >= 1 || var17 >= 1 || var18 >= 1)
if if(var10 == Opacity.Cutout)
if if(var2 >= 1 || var3 >= 1 || var4 >= 1 || var5 >= 1)
if if(var12 < var2)
if if(var13 < var3)
if if(var14 < var4)
if if(var15 < var5)
private void initChunkvoid initChunk(int var1, int var2)
private void initChunkvoid initChunk(@Nonnull WorldChunk var1, int var2, int var3)
private void initNeighbourSectionsvoid initNeighbourSections(@Nonnull LocalCachedChunkAccessor var1, int var2, int var3, int var4)
private void initNeighboursvoid initNeighbours(int var1, int var2)
private void initNeighboursvoid initNeighbours(@Nonnull LocalCachedChunkAccessor var1, int var2, int var3, int var4)
private void initSectionvoid initSection(@Nonnull WorldChunk var1, int var2, int var3, int var4)
private void invalidateLightingForvoid invalidateLightingFor(@Nonnull ChunkStore var1, int var2, int var3, int var4, int var5)
private void propagateCornervoid propagateCorner(@Nonnull BitSet var1, @Nullable BlockSection var2, @Nonnull BlockSection var3, @Nonnull ChunkLightDataBuilder var4, int var5, int var6)
public void propagateCornersvoid propagateCorners(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3)
private void propagateEdgevoid propagateEdge(@Nonnull BitSet var1, @Nullable BlockSection var2, @Nonnull BlockSection var3, @Nonnull ChunkLightDataBuilder var4, @Nonnull Int2IntFunction var5, @Nonnull Int2IntFunction var6)
public void propagateEdgesvoid propagateEdges(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3)
private void propagateLightvoid propagateLight(@Nonnull BitSet var1, @Nonnull BlockSection var2, @Nonnull ChunkLightDataBuilder var3)
private void propagateLightvoid propagateLight(@Nonnull BitSet var1, byte var2, byte var3, byte var4, byte var5, @Nonnull BlockSection var6, @Nonnull ChunkLightDataBuilder var7, int var8)
private void propagateSidevoid propagateSide(@Nonnull BitSet var1, @Nullable BlockSection var2, @Nonnull BlockSection var3, @Nonnull ChunkLightDataBuilder var4, @Nonnull IntBinaryOperator var5, @Nonnull IntBinaryOperator var6)
public void propagateSidesvoid propagateSides(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3)
switch switch(var11)
switch switch(var16)
public boolean testNeighboursForLocalLightboolean testNeighboursForLocalLight(@Nonnull LocalCachedChunkAccessor var1, @Nonnull WorldChunk var2, int var3, int var4, int var5)
while while(true)
while while(true)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world.lighting;

class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector2iUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3iUtil;
class="kw">import com.hypixel.hytale.metrics.metric.AverageCollector;
class="kw">import com.hypixel.hytale.protocol.ColorLight;
class="kw">import com.hypixel.hytale.protocol.Opacity;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.LocalCachedChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkLightData;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkLightDataBuilder;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.FluidSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntFunction;
class="kw">import it.unimi.dsi.fastutil.ints.IntIterator;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import java.util.Arrays;
class="kw">import java.util.BitSet;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.atomic.AtomicLong;
class="kw">import java.util.function.IntBinaryOperator;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector2ic;
class="kw">import org.joml.Vector3i;
class="kw">import org.joml.Vector3ic;

class="kw">public class FloodLightCalculation class="kw">implements LightCalculation {
   class="kw">protected class="kw">final ChunkLightingManager chunkLightingManager;
   class="kw">protected class="kw">final AverageCollector emptyAvg = new AverageCollector();
   class="kw">protected class="kw">final AverageCollector blocksAvg = new AverageCollector();
   class="kw">protected class="kw">final AverageCollector borderAvg = new AverageCollector();
   class="kw">protected class="kw">final AverageCollector avgChunk = new AverageCollector();
   class="kw">protected class="kw">final BlockSection[][] fromSections = new BlockSection[][]{
      new BlockSection[Vector3iUtil.BLOCK_SIDES.length], new BlockSection[Vector3iUtil.BLOCK_EDGES.length], new BlockSection[Vector3iUtil.BLOCK_CORNERS.length]
   };

   class="kw">public FloodLightCalculation(ChunkLightingManager var1) {
      this.chunkLightingManager = var1;
   }

   @Override
   class="kw">public void init(@Nonnull WorldChunk var1) {
      this.chunkLightingManager.getWorld().debugAssertInTickingThread();
      int var2 = var1.getX();
      int var3 = var1.getZ();
      this.initChunk(var1, var2, var3);
      this.initNeighbours(var2, var3);
   }

   class="kw">private void initChunk(int var1, int var2) {
      WorldChunk var3 = this.chunkLightingManager.getWorld().getChunkIfInMemory(ChunkUtil.indexChunk(var1, var2));
      if (var3 != null) {
         this.initChunk(var3, var1, var2);
      }
   }

   class="kw">private void initChunk(@Nonnull WorldChunk var1, int var2, int var3) {
      for (int var4 = 0; var4 < 10; var4++) {
         this.initSection(var1, var2, var4, var3);
      }
   }

   class="kw">private void initNeighbours(int var1, int var2) {
      this.initChunk(var1 - 1, var2 - 1);
      this.initChunk(var1 - 1, var2 + 1);
      this.initChunk(var1 + 1, var2 - 1);
      this.initChunk(var1 + 1, var2 + 1);
      this.initChunk(var1 - 1, var2);
      this.initChunk(var1 + 1, var2);
      this.initChunk(var1, var2 - 1);
      this.initChunk(var1, var2 + 1);
   }

   class="kw">private void initSection(@Nonnull WorldChunk var1, int var2, int var3, int var4) {
      BlockSection var5 = var1.getBlockChunk().getSectionAtIndex(var3);
      if (!var5.hasLocalLight()) {
         this.chunkLightingManager.getLogger().at(Level.FINEST).log("Init chunk %d, %d, %d because doesn't have local light", var2, var3, var4);
      } else {
         if (var5.hasGlobalLight()) {
            class="kw">return;
         }

         this.chunkLightingManager.getLogger().at(Level.FINEST).log("Init chunk %d, %d, %d because doesn't have global light", var2, var3, var4);
      }

      this.chunkLightingManager.addToQueue(new Vector3i(var2, var3, var4));
   }

   class="kw">private void initNeighbours(@Nonnull LocalCachedChunkAccessor var1, int var2, int var3, int var4) {
      this.initNeighbourSections(var1, var2 - 1, var3, var4 - 1);
      this.initNeighbourSections(var1, var2 - 1, var3, var4 + 1);
      this.initNeighbourSections(var1, var2 + 1, var3, var4 - 1);
      this.initNeighbourSections(var1, var2 + 1, var3, var4 + 1);
      this.initNeighbourSections(var1, var2 - 1, var3, var4);
      this.initNeighbourSections(var1, var2 + 1, var3, var4);
      this.initNeighbourSections(var1, var2, var3, var4 - 1);
      this.initNeighbourSections(var1, var2, var3, var4 + 1);
   }

   class="kw">private void initNeighbourSections(@Nonnull LocalCachedChunkAccessor var1, int var2, int var3, int var4) {
      WorldChunk var5 = var1.getChunkIfInMemory(var2, var4);
      if (var5 != null) {
         if (var3 < 9) {
            this.initSection(var5, var2, var3 + 1, var4);
         }

         if (var3 > 0) {
            this.initSection(var5, var2, var3 - 1, var4);
         }
      }
   }

   @Nonnull
   @Override
   class="kw">public CalculationResult calculateLight(@Nonnull Vector3i var1) {
      int var2 = var1.x;
      int var3 = var1.y;
      int var4 = var1.z;
      WorldChunk var5 = this.chunkLightingManager.getWorld().getChunkIfInMemory(ChunkUtil.indexChunk(var2, var4));
      if (var5 == null) {
         class="kw">return CalculationResult.NOT_LOADED;
      }

      AtomicLong var6 = var5.chunkLightTiming;
      boolean var7 = this.chunkLightingManager.getLogger().at(Level.FINE).isEnabled();
      LocalCachedChunkAccessor var8 = LocalCachedChunkAccessor.atChunkCoords(this.chunkLightingManager.getWorld(), var2, var4, 1);
      var8.overwrite(var5);
      CompletableFuture.runAsync(var8::cacheChunksInRadius, this.chunkLightingManager.getWorld()).join();
      BlockSection var9 = var5.getBlockChunk().getSectionAtIndex(var3);
      FluidSection var10 = CompletableFuture.<FluidSection>supplyAsync(() -> {
         Ref var4 = this.chunkLightingManager.getWorld().getChunkStore().getChunkSectionReference(var2, var3, var4);
         class="kw">return var4 == null ? null : var4.getStore().getComponent(var4, FluidSection.getComponentType());
      }, this.chunkLightingManager.getWorld()).join();
      if (var10 == null) {
         class="kw">return CalculationResult.NOT_LOADED;
      }

      if (var9.hasLocalLight() && var9.hasGlobalLight()) {
         this.initNeighbours(var8, var2, var3, var4);
         class="kw">return CalculationResult.DONE;
      }

      if (!var9.hasLocalLight()) {
         CalculationResult var11 = this.updateLocalLight(var8, var5, var2, var3, var4, var9, var10, var6, var7);
         class="kw">switch (var11) {
            case NOT_LOADED:
            case INVALIDATED:
            case WAITING_FOR_NEIGHBOUR:
               class="kw">return var11;
            case DONE:
            class="kw">default:
               this.initNeighbours(var8, var2, var3, var4);
         }
      }

      if (!var9.hasGlobalLight()) {
         CalculationResult var16 = this.updateGlobalLight(var8, var5, var2, var3, var4, var9, var6, var7);
         class="kw">switch (var16) {
            case NOT_LOADED:
            case INVALIDATED:
            case WAITING_FOR_NEIGHBOUR:
               class="kw">return var16;
            case DONE:
         }
      }

      if (var7) {
         long var17 = var6.get();
         boolean var13 = var17 != 0L;

         for (int var14 = 0; var14 < 10; var14++) {
            BlockSection var15 = var5.getBlockChunk().getSectionAtIndex(var14);
            var13 = var13 && var15.hasLocalLight() && var15.hasGlobalLight();
         }

         if (var13) {
            this.avgChunk.add(var17);
            this.chunkLightingManager
               .getLogger()
               .at(Level.FINE)
               .log(
                  "Flood Chunk: Took %s at %d, %d - Avg: %s", FormatUtil.nanosToString(var17), var2, var4, FormatUtil.nanosToString((long)this.avgChunk.get())
               );
         }
      }

      if (BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA) {
         var5.getBlockChunk().invalidateChunkSection(var3);
      }

      class="kw">return CalculationResult.DONE;
   }

   @Nonnull
   class="kw">public CalculationResult updateLocalLight(
      LocalCachedChunkAccessor var1,
      @Nonnull WorldChunk var2,
      int var3,
      int var4,
      int var5,
      @Nonnull BlockSection var6,
      @Nonnull FluidSection var7,
      @Nonnull AtomicLong var8,
      boolean var9
   ) {
      long var10 = System.nanoTime();
      boolean var12 = var6.isSolidAir() && var7.isEmpty();
      ChunkLightDataBuilder var13;
      if (var12) {
         var13 = this.floodEmptyChunkSection(var2, var6.getLocalChangeCounter(), var4);
      } else {
         var13 = this.floodChunkSection(var2, var6, var7, var4);
      }

      var6.setLocalLight(var13);
      var2.markNeedsSaving();
      if (var9) {
         long var14 = System.nanoTime();
         long var16 = var14 - var10;
         if (var12) {
            this.emptyAvg.add(var16);
         } else {
            this.blocksAvg.add(var16);
         }

         var8.addAndGet(var16);
         this.chunkLightingManager
            .getLogger()
            .at(Level.FINER)
            .log(
               "Flood Chunk Section (local): Took %s at %d, %d, %d - %s Avg: %s",
               FormatUtil.nanosToString(var16),
               var3,
               var4,
               var5,
               var12 ? "air" : "blocks",
               FormatUtil.nanosToString((long)(var12 ? this.emptyAvg.get() : this.blocksAvg.get()))
            );
      }

      if (!var6.hasLocalLight()) {
         this.chunkLightingManager
            .getLogger()
            .at(Level.FINEST)
            .log(
               "Chunk Section still needs relight! (local) %d, %d, %d - %d != %d (counter != id)",
               var3,
               var4,
               var5,
               var6.getLocalChangeCounter(),
               var6.getLocalLight().getChangeId()
            );
         class="kw">return CalculationResult.INVALIDATED;
      } else {
         class="kw">return CalculationResult.DONE;
      }
   }

   @Nonnull
   class="kw">public CalculationResult updateGlobalLight(
      @Nonnull LocalCachedChunkAccessor var1,
      @Nonnull WorldChunk var2,
      int var3,
      int var4,
      int var5,
      @Nonnull BlockSection var6,
      @Nonnull AtomicLong var7,
      boolean var8
   ) {
      long var9 = System.nanoTime();
      if (this.testNeighboursForLocalLight(var1, var2, var3, var4, var5)) {
         class="kw">return CalculationResult.WAITING_FOR_NEIGHBOUR;
      }

      ChunkLightDataBuilder var11 = new ChunkLightDataBuilder(var6.getLocalLight(), var6.getGlobalChangeCounter());
      BitSet var12 = new BitSet(32768);
      this.propagateSides(var6, var11, var12);
      this.propagateEdges(var6, var11, var12);
      this.propagateCorners(var6, var11, var12);
      this.propagateLight(var12, var6, var11);
      var6.setGlobalLight(var11);
      var2.markNeedsSaving();
      if (var8) {
         long var13 = System.nanoTime();
         long var15 = var13 - var9;
         var7.addAndGet(var15);
         this.borderAvg.add(var15);
         this.chunkLightingManager
            .getLogger()
            .at(Level.FINER)
            .log(
               "Flood Chunk Section (global): Took %s at %d, %d, %d - Avg: %s",
               FormatUtil.nanosToString(var15),
               var3,
               var4,
               var5,
               FormatUtil.nanosToString((long)this.borderAvg.get())
            );
      }

      if (!var6.hasGlobalLight()) {
         this.chunkLightingManager
            .getLogger()
            .at(Level.FINEST)
            .log(
               "Chunk Section still needs relight! (global) %d, %d, %d - %d != %d (counter != id)",
               var3,
               var4,
               var5,
               var6.getGlobalChangeCounter(),
               var6.getGlobalLight().getChangeId()
            );
         class="kw">return CalculationResult.INVALIDATED;
      } else {
         class="kw">return CalculationResult.DONE;
      }
   }

   @Override
   class="kw">public boolean invalidateLightAtBlock(@Nonnull ChunkStore var1, int var2, int var3, int var4, @Nonnull BlockType var5, int var6, int var7) {
      int var8 = ChunkUtil.chunkCoordinate(var2);
      int var9 = ChunkUtil.chunkCoordinate(var3);
      int var10 = ChunkUtil.chunkCoordinate(var4);
      int var11 = var6 >> 5;
      int var12 = var7 >> 5;
      int var13 = Math.max(MathUtil.minValue(var11, var12, var9), 0);
      int var14 = MathUtil.maxValue(var11, var12, var9) + 1;
      boolean var15 = this.invalidateLightInChunkSections(var1, var8, var10, var13, var14);
      this.chunkLightingManager
         .getLogger()
         .at(Level.FINER)
         .log("updateLightAtBlock(%d, %d, %d, %s): %d, %d, %d", var2, var3, var4, var5.getId(), var8, var9, var10);
      class="kw">return var15;
   }

   class="kw">private void invalidateLightingFor(@Nonnull ChunkStore var1, int var2, int var3, int var4, int var5) {
      for (int var6 = var2 - 1; var6 <= var2 + 1; var6++) {
         for (int var7 = var3 - 1; var7 <= var3 + 1; var7++) {
            for (int var8 = var5 - 1; var8 >= var4; var8--) {
               Ref var9 = var1.getChunkSectionReference(var6, var8, var7);
               if (var9 != null) {
                  BlockSection var10 = var1.getStore().getComponent(var9, BlockSection.getComponentType());
                  if (var10 != null) {
                     if (var6 == var2 && var7 == var3) {
                        var10.invalidateLocalLight();
                     } else {
                        var10.invalidateGlobalLight();
                     }

                     if (BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA) {
                        var10.invalidate();
                     }
                  }
               }
            }
         }
      }
   }

   @Override
   class="kw">public boolean invalidateLightInChunkSections(@Nonnull ChunkStore var1, int var2, int var3, int var4, int var5) {
      if (!var1.getWorld().isInThread()) {
         CompletableFuture.runAsync(() -> this.invalidateLightingFor(var1, var2, var3, var4, var5), var1.getWorld()).join();
      } else {
         this.invalidateLightingFor(var1, var2, var3, var4, var5);
      }

      for (int var6 = var2 - 1; var6 <= var2 + 1; var6++) {
         for (int var7 = var3 - 1; var7 <= var3 + 1; var7++) {
            Ref var8 = var1.getChunkReference(ChunkUtil.indexChunk(var6, var7));
            if (var8 != null) {
               for (int var9 = var5 - 1; var9 >= var4; var9--) {
                  if (var9 >= 0 && var9 < 10) {
                     this.chunkLightingManager.addToQueue(new Vector3i(var6, var9, var7));
                  }
               }
            }
         }
      }

      class="kw">return false;
   }

   @Nonnull
   class="kw">private ChunkLightDataBuilder floodEmptyChunkSection(@Nonnull WorldChunk var1, short var2, int var3) {
      int var4 = var3 * 32;
      ChunkLightDataBuilder var5 = new ChunkLightDataBuilder(var2);
      BitSet var6 = new BitSet(1024);

      for (int var7 = 0; var7 < 32; var7++) {
         for (int var8 = 0; var8 < 32; var8++) {
            int var9 = ChunkUtil.indexColumn(var7, var8);
            short var10 = var1.getHeight(var9);
            if (var4 > var10) {
               for (int var11 = 0; var11 < 32; var11++) {
                  var5.setLight(ChunkUtil.indexBlockFromColumn(var9, var11), 3, (byte)15);
               }

               var6.set(var9);
            }
         }
      }

      if (var6.cardinality() < 1024) {
         IntSet var22 = new IntOpenHashSet(1024);
         int var23 = 0;

         while (true) {
            int var24 = var6.nextSetBit(var23);
            if (var24 == -1) {
               if (var6.isEmpty()) {
                  IntIterator var25 = var22.iterator();

                  while (var25.hasNext()) {
                     int columnx = var25.nextInt();
                     byte var29 = var5.getLight(columnx, 3);

                     for (int var30 = 1; var30 < 32; var30++) {
                        var5.setLight(ChunkUtil.indexBlockFromColumn(columnx, var30), 3, var29);
                     }
                  }
                  break;
               }

               var23 = 0;
            } else {
               var6.clear(var24);
               var23 = var24;
               int var26 = ChunkUtil.xFromColumn(var24);
               int var28 = ChunkUtil.zFromColumn(var24);
               byte var12 = var5.getLight(var24, 3);
               byte var13 = (byte)(var12 - 1);
               if (var13 >= 1) {
                  for (Vector2ic var17 : Vector2iUtil.DIRECTIONS) {
                     int var18 = var26 + var17.x();
                     int var19 = var28 + var17.y();
                     if (var18 >= 0 && var18 < 32 && var19 >= 0 && var19 < 32) {
                        int var20 = ChunkUtil.indexColumn(var18, var19);
                        byte var21 = var5.getLight(var20, 3);
                        if (var21 < var13) {
                           var5.setLight(var20, 3, var13);
                           var22.add(var20);
                           if (var13 > 1) {
                              var6.set(var20);
                           }
                        }
                     }
                  }
               }
            }
         }
      }

      class="kw">return var5;
   }

   @Nonnull
   class="kw">private ChunkLightDataBuilder floodChunkSection(@Nonnull WorldChunk var1, @Nonnull BlockSection var2, @Nonnull FluidSection var3, int var4) {
      int var5 = var4 * 32;
      ChunkLightDataBuilder var6 = new ChunkLightDataBuilder(var2.getLocalChangeCounter());
      BitSet var7 = new BitSet(32768);

      for (int var8 = 0; var8 < 32; var8++) {
         for (int var9 = 0; var9 < 32; var9++) {
            int var10 = ChunkUtil.indexColumn(var8, var9);
            short var11 = var1.getHeight(var10);

            for (int var12 = 0; var12 < 32; var12++) {
               int var13 = ChunkUtil.indexBlockFromColumn(var10, var12);
               byte var14 = this.getSkyValue(var1, var4, var8, var12, var9, var5, var11);
               short var15 = (short)(var14 << 12);
               int var16 = var2.get(var13);
               BlockType var17 = BlockType.getAssetMap().getAsset(var16);
               ColorLight var18 = var17.getLight();
               int var19 = var3.getFluidId(var13);
               Fluid var20 = Fluid.getAssetMap().getAsset(var19);
               ColorLight var21 = var20.getLight();
               if (var18 != null && var21 != null) {
                  var15 = ChunkLightData.combineLightValues(
                     (byte)Math.max(var18.red, var21.red), (byte)Math.max(var18.green, var21.green), (byte)Math.max(var18.blue, var21.blue), var14
                  );
               } else if (var21 != null) {
                  var15 = ChunkLightData.combineLightValues(var21.red, var21.green, var21.blue, var14);
               } else if (var18 != null) {
                  var15 = ChunkLightData.combineLightValues(var18.red, var18.green, var18.blue, var14);
               }

               if (var15 != 0) {
                  var6.setLightRaw(var13, var15);
                  var7.set(var13);
               }
            }
         }
      }

      this.propagateLight(var7, var2, var6);
      class="kw">return var6;
   }

   class="kw">protected byte getSkyValue(WorldChunk var1, int var2, int var3, int var4, int var5, int var6, int var7) {
      int var8 = var6 + var4;
      boolean var9 = var8 >= var7;
      class="kw">return (byte)(var9 ? 15 : 0);
   }

   class="kw">private void propagateLight(@Nonnull BitSet var1, @Nonnull BlockSection var2, @Nonnull ChunkLightDataBuilder var3) {
      int var4 = 0;

      while (true) {
         int var5 = var1.nextSetBit(var4);
         if (var5 == -1) {
            if (var1.isEmpty()) {
               class="kw">return;
            }

            var4 = 0;
         } else {
            var1.clear(var5);
            var4 = var5;
            BlockType var6 = BlockType.getAssetMap().getAsset(var2.get(var5));
            Opacity var7 = var6.getOpacity();
            if (var7 != Opacity.Solid) {
               short var8 = var3.getLightRaw(var5);
               byte var9 = ChunkLightData.getLightValue(var8, 0);
               byte var10 = ChunkLightData.getLightValue(var8, 1);
               byte var11 = ChunkLightData.getLightValue(var8, 2);
               byte var12 = ChunkLightData.getLightValue(var8, 3);
               if (var9 >= 2 || var10 >= 2 || var11 >= 2 || var12 >= 2) {
                  byte var13 = (byte)(var9 - 1);
                  byte var14 = (byte)(var10 - 1);
                  byte var15 = (byte)(var11 - 1);
                  byte var16 = (byte)(var12 - 1);
                  if (var7 == Opacity.Semitransparent || var7 == Opacity.Cutout) {
                     var13--;
                     var14--;
                     var15--;
                     var16--;
                  }

                  if (var13 >= 1 || var14 >= 1 || var15 >= 1 || var16 >= 1) {
                     int var17 = ChunkUtil.xFromIndex(var5);
                     int var18 = ChunkUtil.yFromIndex(var5);
                     int var19 = ChunkUtil.zFromIndex(var5);

                     for (Vector3ic var23 : Vector3iUtil.BLOCK_SIDES) {
                        int var24 = var17 + var23.x();
                        if (var24 >= 0 && var24 < 32) {
                           int var25 = var18 + var23.y();
                           if (var25 >= 0 && var25 < 32) {
                              int var26 = var19 + var23.z();
                              if (var26 >= 0 && var26 < 32) {
                                 int var27 = ChunkUtil.indexBlock(var24, var25, var26);
                                 this.propagateLight(var1, var13, var14, var15, var16, var2, var3, var27);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   class="kw">public boolean testNeighboursForLocalLight(@Nonnull LocalCachedChunkAccessor var1, @Nonnull WorldChunk var2, int var3, int var4, int var5) {
      Vector3ic[][] var6 = Vector3iUtil.BLOCK_PARTS;

      for (int var7 = 0; var7 < this.fromSections.length; var7++) {
         BlockSection[] var8 = this.fromSections[var7];
         Arrays.fill(var8, null);
         Vector3ic[] var9 = var6[var7];

         for (int var10 = 0; var10 < var9.length; var10++) {
            Vector3ic var11 = var9[var10];
            int var12 = var3 + var11.x();
            int var13 = var4 + var11.y();
            int var14 = var5 + var11.z();
            if (var13 >= 0 && var13 < 10) {
               if (var12 == var3 && var14 == var5) {
                  BlockSection var17 = var2.getBlockChunk().getSectionAtIndex(var13);
                  if (!var17.hasLocalLight()) {
                     class="kw">return true;
                  }

                  var8[var10] = var17;
               } else {
                  WorldChunk var15 = var1.getChunkIfInMemory(var12, var14);
                  if (var15 == null) {
                     class="kw">return true;
                  }

                  BlockSection var16 = var15.getBlockChunk().getSectionAtIndex(var13);
                  if (!var16.hasLocalLight()) {
                     class="kw">return true;
                  }

                  var8[var10] = var16;
               }
            }
         }
      }

      class="kw">return false;
   }

   class="kw">public void propagateSides(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3) {
      BlockSection[] var4 = this.fromSections[0];
      int var5 = 0;
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(var0, 0, var1x), (var0, var1x) -> ChunkUtil.indexBlock(var0, 31, var1x)
      );
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(var0, 31, var1x), (var0, var1x) -> ChunkUtil.indexBlock(var0, 0, var1x)
      );
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(var0, var1x, 31), (var0, var1x) -> ChunkUtil.indexBlock(var0, var1x, 0)
      );
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(var0, var1x, 0), (var0, var1x) -> ChunkUtil.indexBlock(var0, var1x, 31)
      );
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(31, var0, var1x), (var0, var1x) -> ChunkUtil.indexBlock(0, var0, var1x)
      );
      this.propagateSide(
         var3, var4[var5++], var1, var2, (var0, var1x) -> ChunkUtil.indexBlock(0, var0, var1x), (var0, var1x) -> ChunkUtil.indexBlock(31, var0, var1x)
      );
   }

   class="kw">private void propagateSide(
      @Nonnull BitSet var1,
      @Nullable BlockSection var2,
      @Nonnull BlockSection var3,
      @Nonnull ChunkLightDataBuilder var4,
      @Nonnull IntBinaryOperator var5,
      @Nonnull IntBinaryOperator var6
   ) {
      if (var2 != null) {
         ChunkLightData var7 = var2.getLocalLight();

         for (int var8 = 0; var8 < 32; var8++) {
            for (int var9 = 0; var9 < 32; var9++) {
               int var10 = var5.applyAsInt(var8, var9);
               int var11 = var6.applyAsInt(var8, var9);
               BlockType var12 = BlockType.getAssetMap().getAsset(var2.get(var10));
               Opacity var13 = var12.getOpacity();
               if (var13 != Opacity.Solid) {
                  short var14 = var7.getLightRaw(var10);
                  byte var15 = ChunkLightData.getLightValue(var14, 0);
                  byte var16 = ChunkLightData.getLightValue(var14, 1);
                  byte var17 = ChunkLightData.getLightValue(var14, 2);
                  byte var18 = ChunkLightData.getLightValue(var14, 3);
                  if (var15 >= 2 || var16 >= 2 || var17 >= 2 || var18 >= 2) {
                     byte var19 = (byte)(var15 - 1);
                     byte var20 = (byte)(var16 - 1);
                     byte var21 = (byte)(var17 - 1);
                     byte var22 = (byte)(var18 - 1);
                     if (var13 == Opacity.Semitransparent || var13 == Opacity.Cutout) {
                        var19--;
                        var20--;
                        var21--;
                        var22--;
                     }

                     if (var19 >= 1 || var20 >= 1 || var21 >= 1 || var22 >= 1) {
                        this.propagateLight(var1, var19, var20, var21, var22, var3, var4, var11);
                     }
                  }
               }
            }
         }
      }
   }

   class="kw">public void propagateEdges(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3) {
      BlockSection[] var4 = this.fromSections[1];
      int var5 = 0;
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(var0, 0, 31), var0 -> ChunkUtil.indexBlock(var0, 31, 0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(var0, 31, 31), var0 -> ChunkUtil.indexBlock(var0, 0, 0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(var0, 0, 0), var0 -> ChunkUtil.indexBlock(var0, 31, 31));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(var0, 31, 0), var0 -> ChunkUtil.indexBlock(var0, 0, 31));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(31, 0, var0), var0 -> ChunkUtil.indexBlock(0, 31, var0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(31, 31, var0), var0 -> ChunkUtil.indexBlock(0, 0, var0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(0, 0, var0), var0 -> ChunkUtil.indexBlock(31, 31, var0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(0, 31, var0), var0 -> ChunkUtil.indexBlock(31, 0, var0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(31, var0, 31), var0 -> ChunkUtil.indexBlock(0, var0, 0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(0, var0, 31), var0 -> ChunkUtil.indexBlock(31, var0, 0));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(31, var0, 0), var0 -> ChunkUtil.indexBlock(0, var0, 31));
      this.propagateEdge(var3, var4[var5++], var1, var2, var0 -> ChunkUtil.indexBlock(0, var0, 0), var0 -> ChunkUtil.indexBlock(31, var0, 31));
   }

   class="kw">private void propagateEdge(
      @Nonnull BitSet var1,
      @Nullable BlockSection var2,
      @Nonnull BlockSection var3,
      @Nonnull ChunkLightDataBuilder var4,
      @Nonnull Int2IntFunction var5,
      @Nonnull Int2IntFunction var6
   ) {
      if (var2 != null) {
         ChunkLightData var7 = var2.getLocalLight();

         for (int var8 = 0; var8 < 32; var8++) {
            int var9 = var5.applyAsInt(var8);
            int var10 = var6.applyAsInt(var8);
            BlockType var11 = BlockType.getAssetMap().getAsset(var2.get(var9));
            Opacity var12 = var11.getOpacity();
            if (var12 != Opacity.Solid) {
               short var13 = var7.getLightRaw(var9);
               byte var14 = ChunkLightData.getLightValue(var13, 0);
               byte var15 = ChunkLightData.getLightValue(var13, 1);
               byte var16 = ChunkLightData.getLightValue(var13, 2);
               byte var17 = ChunkLightData.getLightValue(var13, 3);
               if (var14 >= 3 || var15 >= 3 || var16 >= 3 || var17 >= 3) {
                  byte var18 = (byte)(var14 - 2);
                  byte var19 = (byte)(var15 - 2);
                  byte var20 = (byte)(var16 - 2);
                  byte var21 = (byte)(var17 - 2);
                  if (var12 == Opacity.Semitransparent || var12 == Opacity.Cutout) {
                     var18--;
                     var19--;
                     var20--;
                     var21--;
                  }

                  if (var18 >= 1 || var19 >= 1 || var20 >= 1 || var21 >= 1) {
                     this.propagateLight(var1, var18, var19, var20, var21, var3, var4, var10);
                  }
               }
            }
         }
      }
   }

   class="kw">public void propagateCorners(@Nonnull BlockSection var1, @Nonnull ChunkLightDataBuilder var2, @Nonnull BitSet var3) {
      BlockSection[] var4 = this.fromSections[2];
      int var5 = 0;
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(31, 0, 31), ChunkUtil.indexBlock(0, 31, 0));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(0, 0, 31), ChunkUtil.indexBlock(31, 31, 0));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(31, 31, 31), ChunkUtil.indexBlock(0, 0, 0));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(0, 31, 31), ChunkUtil.indexBlock(31, 0, 0));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(31, 0, 0), ChunkUtil.indexBlock(0, 31, 31));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(0, 0, 0), ChunkUtil.indexBlock(31, 31, 31));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(31, 31, 0), ChunkUtil.indexBlock(0, 0, 31));
      this.propagateCorner(var3, var4[var5++], var1, var2, ChunkUtil.indexBlock(0, 31, 0), ChunkUtil.indexBlock(31, 0, 31));
   }

   class="kw">private void propagateCorner(
      @Nonnull BitSet var1, @Nullable BlockSection var2, @Nonnull BlockSection var3, @Nonnull ChunkLightDataBuilder var4, int var5, int var6
   ) {
      if (var2 != null) {
         ChunkLightData var7 = var2.getLocalLight();
         BlockType var8 = BlockType.getAssetMap().getAsset(var2.get(var5));
         Opacity var9 = var8.getOpacity();
         if (var9 != Opacity.Solid) {
            short var10 = var7.getLightRaw(var5);
            byte var11 = ChunkLightData.getLightValue(var10, 0);
            byte var12 = ChunkLightData.getLightValue(var10, 1);
            byte var13 = ChunkLightData.getLightValue(var10, 2);
            byte var14 = ChunkLightData.getLightValue(var10, 3);
            if (var11 >= 4 || var12 >= 4 || var13 >= 4 || var14 >= 4) {
               byte var15 = (byte)(var11 - 3);
               byte var16 = (byte)(var12 - 3);
               byte var17 = (byte)(var13 - 3);
               byte var18 = (byte)(var14 - 3);
               if (var9 == Opacity.Semitransparent || var9 == Opacity.Cutout) {
                  var15--;
                  var16--;
                  var17--;
                  var18--;
               }

               if (var15 >= 1 || var16 >= 1 || var17 >= 1 || var18 >= 1) {
                  this.propagateLight(var1, var15, var16, var17, var18, var3, var4, var6);
               }
            }
         }
      }
   }

   class="kw">private void propagateLight(
      @Nonnull BitSet var1, byte var2, byte var3, byte var4, byte var5, @Nonnull BlockSection var6, @Nonnull ChunkLightDataBuilder var7, int var8
   ) {
      BlockType var9 = BlockType.getAssetMap().getAsset(var6.get(var8));
      Opacity var10 = var9.getOpacity();
      if (var10 == Opacity.Cutout) {
         var2--;
         var3--;
         var4--;
         var5--;
      }

      if (var2 >= 1 || var3 >= 1 || var4 >= 1 || var5 >= 1) {
         short var11 = var7.getLightRaw(var8);
         byte var12 = ChunkLightData.getLightValue(var11, 0);
         byte var13 = ChunkLightData.getLightValue(var11, 1);
         byte var14 = ChunkLightData.getLightValue(var11, 2);
         byte var15 = ChunkLightData.getLightValue(var11, 3);
         if (var12 < var2) {
            var12 = var2;
         }

         if (var13 < var3) {
            var13 = var3;
         }

         if (var14 < var4) {
            var14 = var4;
         }

         if (var15 < var5) {
            var15 = var5;
         }

         short var16 = (short)((var12 & 15) << 0);
         var16 = (short)(var16 | (var13 & 15) << 4);
         var16 = (short)(var16 | (var14 & 15) << 8);
         var16 = (short)(var16 | (var15 & 15) << 12);
         var7.setLightRaw(var8, var16);
         if (var16 != var11 && (var2 > 1 || var3 > 1 || var4 > 1 || var5 > 1)) {
            var1.set(var8);
         }
      }
   }
}