/// <summary> /// Sets the light value at the coordinate. If enumskyblock is set to sky it sets it in the skylightmap and if its a /// block then into the blocklightmap. Args enumSkyBlock, x, y, z, lightValue /// </summary> public virtual void SetLightValue(SkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { ExtendedBlockStorage extendedblockstorage = storageArrays[par3 >> 4]; if (extendedblockstorage == null) { extendedblockstorage = storageArrays[par3 >> 4] = new ExtendedBlockStorage((par3 >> 4) << 4); GenerateSkylightMap(); } IsModified = true; if (par1EnumSkyBlock == SkyBlock.Sky) { if (!WorldObj.WorldProvider.HasNoSky) { extendedblockstorage.SetExtSkylightValue(par2, par3 & 0xf, par4, par5); } } else if (par1EnumSkyBlock == SkyBlock.Block) { extendedblockstorage.SetExtBlocklightValue(par2, par3 & 0xf, par4, par5); } else { return; } }
/// <summary> /// Initiates the recalculation of both the block-light and sky-light for a given block inside a chunk. /// </summary> private void RelightBlock(int par1, int par2, int par3) { int i = HeightMap[par3 << 4 | par1] & 0xff; int j = i; if (par2 > i) { j = par2; } for (; j > 0 && GetBlockLightOpacity(par1, j - 1, par3) == 0; j--) { } if (j == i) { return; } WorldObj.MarkBlocksDirtyVertical(par1, par3, j, i); HeightMap[par3 << 4 | par1] = j; int k = XPosition * 16 + par1; int l = ZPosition * 16 + par3; if (!WorldObj.WorldProvider.HasNoSky) { if (j < i) { for (int i1 = j; i1 < i; i1++) { ExtendedBlockStorage extendedblockstorage = storageArrays[i1 >> 4]; if (extendedblockstorage != null) { extendedblockstorage.SetExtSkylightValue(par1, i1 & 0xf, par3, 15); WorldObj.Func_48464_p((XPosition << 4) + par1, i1, (ZPosition << 4) + par3); } } } else { for (int j1 = i; j1 < j; j1++) { ExtendedBlockStorage extendedblockstorage1 = storageArrays[j1 >> 4]; if (extendedblockstorage1 != null) { extendedblockstorage1.SetExtSkylightValue(par1, j1 & 0xf, par3, 0); WorldObj.Func_48464_p((XPosition << 4) + par1, j1, (ZPosition << 4) + par3); } } } int k1 = 15; do { if (j <= 0 || k1 <= 0) { break; } j--; int i2 = GetBlockLightOpacity(par1, j, par3); if (i2 == 0) { i2 = 1; } k1 -= i2; if (k1 < 0) { k1 = 0; } ExtendedBlockStorage extendedblockstorage2 = storageArrays[j >> 4]; if (extendedblockstorage2 != null) { extendedblockstorage2.SetExtSkylightValue(par1, j & 0xf, par3, k1); } }while (true); } int l1 = HeightMap[par3 << 4 | par1]; int j2 = i; int k2 = l1; if (k2 < j2) { int l2 = j2; j2 = k2; k2 = l2; } if (!WorldObj.WorldProvider.HasNoSky) { UpdateSkylightNeighborHeight(k - 1, l, j2, k2); UpdateSkylightNeighborHeight(k + 1, l, j2, k2); UpdateSkylightNeighborHeight(k, l - 1, j2, k2); UpdateSkylightNeighborHeight(k, l + 1, j2, k2); UpdateSkylightNeighborHeight(k, l, j2, k2); } IsModified = true; }
/// <summary> /// Generates the initial skylight map for the chunk upon generation or load. /// </summary> public virtual void GenerateSkylightMap() { int i = GetTopFilledSegment(); for (int j = 0; j < 16; j++) { for (int l = 0; l < 16; l++) { PrecipitationHeightMap[j + (l << 4)] = -999; int j1 = (i + 16) - 1; do { if (j1 <= 0) { break; } if (GetBlockLightOpacity(j, j1 - 1, l) != 0) { HeightMap[l << 4 | j] = j1; break; } j1--; }while (true); if (WorldObj.WorldProvider.HasNoSky) { continue; } j1 = 15; int k1 = (i + 16) - 1; do { j1 -= GetBlockLightOpacity(j, k1, l); if (j1 > 0) { ExtendedBlockStorage extendedblockstorage = storageArrays[k1 >> 4]; if (extendedblockstorage != null) { extendedblockstorage.SetExtSkylightValue(j, k1 & 0xf, l, j1); WorldObj.Func_48464_p((XPosition << 4) + j, k1, (ZPosition << 4) + l); } } }while (--k1 > 0 && j1 > 0); } } IsModified = true; for (int k = 0; k < 16; k++) { for (int i1 = 0; i1 < 16; i1++) { PropagateSkylightOcclusion(k, i1); } } }