/// <summary> /// Applied to LightGridEmitter to update lit cells upon a lighting request. /// </summary> private static bool UpdateLitCells_Prefix(LightGridEmitter __instance, List <int> ___litCells, LightGridEmitter.State ___state) { var lm = PLightManager.Instance; return(lm == null || !lm.UpdateLitCells(__instance, ___state, ___litCells)); }
/// <summary> /// Applied to LightGridEmitter to compute the lux values properly. /// </summary> private static bool ComputeLux_Prefix(LightGridEmitter __instance, int cell, LightGridEmitter.State ___state, ref int __result) { var lm = PLightManager.Instance; return(lm == null || !lm.GetBrightness(__instance, cell, ___state, out __result)); }
/// <summary> /// Updates the lit cells list. /// </summary> /// <param name="source">The source of the light.</param> /// <param name="state">The light emitter state.</param> /// <param name="litCells">The location where lit cells will be placed.</param> /// <returns>true if the lighting was handled, or false otherwise.</returns> internal bool UpdateLitCells(LightGridEmitter source, LightGridEmitter.State state, IList <int> litCells) { bool handled = false; int index; if (source == null) { throw new ArgumentNullException("source"); } if ((index = state.shape - LightShape.Cone - 1) >= 0 && index < shapes.Count && litCells != null) { var ps = shapes[index]; CacheEntry cacheEntry; lock (brightCache) { // Look up in cache, in a thread safe way if (!brightCache.TryGetValue(source, out cacheEntry)) { cacheEntry = new CacheEntry(CallingObject, state.intensity); brightCache.Add(source, cacheEntry); } } var brightness = cacheEntry.Intensity; // Proper owner found brightness.Clear(); ps.FillLight(cacheEntry.Owner, state.origin, (int)state.radius, brightness); foreach (var point in cacheEntry.Intensity) { litCells.Add(point.Key); } handled = true; } return(handled); }
/// <summary> /// Updates the lit cells list. /// </summary> /// <param name="source">The source of the light.</param> /// <param name="state">The light emitter state.</param> /// <param name="litCells">The location where lit cells will be placed.</param> /// <returns>true if the lighting was handled, or false otherwise.</returns> internal bool UpdateLitCells(LightGridEmitter source, LightGridEmitter.State state, IList <int> litCells) { bool handled = false; int index; if (source == null) { throw new ArgumentNullException(nameof(source)); } if ((index = state.shape - LightShape.Cone - 1) >= 0 && index < shapes.Count && litCells != null) { var ps = shapes[index]; var cacheEntry = brightCache.GetOrAdd(source, (_) => new CacheEntry( CallingObject, state.intensity)); var brightness = cacheEntry.Intensity; // Proper owner found brightness.Clear(); ps.FillLight(new LightingArgs(cacheEntry.Owner, state.origin, (int)state. radius, brightness)); foreach (var point in cacheEntry.Intensity) { litCells.Add(point.Key); } handled = true; } return(handled); }
/// <summary> /// Gets the brightness at a given cell for the specified light source. /// </summary> /// <param name="source">The source of the light.</param> /// <param name="location">The location to check.</param> /// <param name="state">The lighting state.</param> /// <param name="result">The brightness there.</param> /// <returns>true if that brightness is valid, or false otherwise.</returns> internal bool GetBrightness(LightGridEmitter source, int location, LightGridEmitter.State state, out int result) { bool valid; CacheEntry cacheEntry; var shape = state.shape; if (shape != LightShape.Cone && shape != LightShape.Circle) { lock (brightCache) { // Shared access to the cache valid = brightCache.TryGetValue(source, out cacheEntry); } if (valid) { valid = cacheEntry.Intensity.TryGetValue(location, out float ratio); if (valid) { result = Mathf.RoundToInt(cacheEntry.BaseLux * ratio); } else { #if DEBUG PUtil.LogDebug("GetBrightness for invalid cell at {0:D}".F(location)); #endif result = 0; } } else { #if DEBUG PUtil.LogDebug("GetBrightness for invalid emitter at {0:D}".F(location)); #endif result = 0; valid = false; } } else if (ForceSmoothLight) { // Use smooth light even for vanilla Cone and Circle result = Mathf.RoundToInt(state.intensity * PLightShape.GetSmoothFalloff( state.falloffRate, location, state.origin)); valid = true; } else { // Stock result = 0; valid = false; } return(valid); }