/// <summary> ///Load terrain, saved changes and resets ///the light for an empty chunk /// </summary> /// <param name="chunk">The chunk to generate and load for</param> protected virtual void GenAndLoadChunk(Chunk chunk) { if (chunk.pos.y == Config.Env.WorldMaxY) { terrainGen.GenerateTerrainForChunkColumn(chunk.pos); for (int i = Config.Env.WorldMinY; i < Config.Env.WorldMaxY; i += Config.Env.ChunkSize) { Serialization.Load(GetChunk(new BlockPos(chunk.pos.x, i, chunk.pos.z))); } if (Config.Toggle.LightSceneOnStart) { BlockLight.ResetLightChunkColumn(this, chunk); } } chunk.SetFlag(Chunk.Flag.terrainGenerated, true); }
public static bool SetBlock(RaycastHit hit, Block block, bool adjacent = false) { Chunk chunk = hit.collider.GetComponent <Chunk>(); if (chunk == null) { return(false); } BlockPos pos = GetBlockPos(hit, adjacent); chunk.world.SetBlock(pos, block, !Config.Toggle.BlockLighting); if (Config.Toggle.BlockLighting) { BlockLight.LightArea(chunk.world, pos); } return(true); }
void LoadChunkColumnInner(BlockPos columnPosition) { Chunk chunk; // Terrain generation can happen in another thread meaning that we will reach this point before the //thread completes, we need to wait for all the chunks we depend on to finish generating before we //can calculate any light spread or render the chunk if (Config.Toggle.UseMultiThreading) { for (int y = Config.Env.WorldMaxY; y >= Config.Env.WorldMinY; y -= Config.Env.ChunkSize) { for (int x = -Config.Env.ChunkSize; x <= Config.Env.ChunkSize; x += Config.Env.ChunkSize) { for (int z = -Config.Env.ChunkSize; z <= Config.Env.ChunkSize; z += Config.Env.ChunkSize) { chunk = world.GetChunk(columnPosition.Add(x, y, z)); while (!chunk.terrainGenerated) { Thread.Sleep(0); } } } } } //Render chunk for (int y = Config.Env.WorldMaxY; y >= Config.Env.WorldMinY; y -= Config.Env.ChunkSize) { chunk = world.GetChunk(columnPosition.Add(0, y, 0)); if (Config.Toggle.LightSceneOnStart) { BlockLight.FloodLightChunkColumn(world, chunk); } chunk.UpdateChunk(); } }
public static bool SetBlock(BlockPos pos, Block block, World world = null) { if (!world) { world = World.instance; } Chunk chunk = world.GetChunk(pos); if (chunk == null) { return(false); } chunk.world.SetBlock(pos, block, !Config.Toggle.BlockLighting); if (Config.Toggle.BlockLighting) { BlockLight.LightArea(world, pos); } return(true); }
/// <summary> /// Updates internal managers if underlying data, such as TileEntities, have been modified outside of the container. /// </summary> public void Refresh() { _lightManager = new BlockLight(this); _fluidManager = new BlockFluid(this); _tileEntityManager = new BlockTileEntities(_blocks, _tileEntities); }
public Color SampleLight(List <BlockLight> lightList, BlockSpacePosition samplePosition, CubeSide sampleSide) { float ambientPercentage = (samplePosition.y - Configuration.AMBIENT_SUBTERRANEAN_FULL_HEIGHT) / Configuration.AMBIENT_SUBTERRANEAN_START_HEIGHT; ambientPercentage = Mathf.Clamp(ambientPercentage, 0.0f, 1.0f); float calcHue = Mathf.Lerp(Configuration.AMBIENT_LIGHT_HUE_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_HUE, ambientPercentage); float calcSaturation = Mathf.Lerp(Configuration.AMBIENT_LIGHT_SATURATION_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_SATURATION, ambientPercentage); float calcValue = Mathf.Lerp(Configuration.AMBIENT_LIGHT_VALUE_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_VALUE, ambientPercentage); HSBColor hsbColor; hsbColor.a = 1.0f; hsbColor.h = calcHue / 255.0f; hsbColor.s = calcSaturation / 255.0f; hsbColor.b = calcValue / 255.0f; Color calcColor = hsbColor.ToColor(); // Calculate sunlight Vector3 startPosition; startPosition.x = samplePosition.x; startPosition.y = samplePosition.y; startPosition.z = samplePosition.z; Vector3 sunPosition = startPosition + (Configuration.SUN_ANGLE * Configuration.HEIGHT); BlockSpacePosition blockSunPosition; blockSunPosition.x = (int)sunPosition.x; blockSunPosition.y = (int)sunPosition.y; blockSunPosition.z = (int)sunPosition.z; byte sunlightHue; byte sunlightSaturation; byte sunlightValue; bool sunlight = !RaytraceLightBeam(blockSunPosition, samplePosition, sampleSide, Configuration.SUNLIGHT_HUE, Configuration.SUNLIGHT_SATURATION, Configuration.SUNLIGHT_VALUE, out sunlightHue, out sunlightSaturation, out sunlightValue); if (sunlight && LightCanAffectFace(samplePosition, blockSunPosition, sampleSide)) { calcColor = AddLightSample(calcColor, sunlightHue, sunlightSaturation, sunlightValue); } // Calculate artificial light int lightListCount = lightList.Count; for (int i = 0; i < lightListCount; i++) { BlockLight light = lightList[i]; BlockSpacePosition worldLightPosition = light.chunkPosition.GetBlockSpacePosition(light.chunk); if (worldLightPosition.x == samplePosition.x && worldLightPosition.y == samplePosition.y && worldLightPosition.z == samplePosition.z) { // Emitter - Full light calcValue = 255; } else { bool lightFace = LightCanAffectFace(samplePosition, worldLightPosition, sampleSide); float distance = Vector3.Distance(worldLightPosition.GetVector3(), samplePosition.GetVector3()); BlockDefinition lightBlock = light.blockDefinition; if (distance < lightBlock.LightEmitRadius()) { byte lightHue = lightBlock.LightEmitHue(); byte lightSaturation = lightBlock.LightEmitSaturation(); byte lightValue = lightBlock.LightEmitValue(); if (lightFace) { lightFace = RaytraceLightBeam(worldLightPosition, samplePosition, sampleSide, lightBlock.LightEmitHue(), lightBlock.LightEmitSaturation(), lightBlock.LightEmitValue(), out lightHue, out lightSaturation, out lightValue) == false; } if (lightFace) { byte effectiveLightValue = (byte)Mathf.Min(lightValue * (1.0f - distance / lightBlock.LightEmitRadius())); calcColor = AddLightSample(calcColor, lightHue, lightSaturation, effectiveLightValue); } #if INEXPENSIVE_FAKE_GLOBAL_ILLUMINATION else { byte effectiveLightValue = (byte)Mathf.Min(calcValue + lightValue / 2.0f * ((1 - distance / lightBlock.LightEmitRadius()) * 0.4f), 254); calcColor = AddLightSample(calcColor, lightHue, lightSaturation, effectiveLightValue); } #endif } } } return(calcColor); }