Example #1
0
        /// <summary>
        /// Converts a PLightShape into this mod's namespace.
        /// </summary>
        /// <param name="otherShape">The shape from the shared data.</param>
        /// <returns>An equivalent shape in this mod's namespace.</returns>
        private static PLightShape LightToInstance(object otherShape)
        {
            var shape = otherShape as PLightShape;

            if (shape == null)
            {
                var trLight = Traverse.Create(otherShape);
                // Retrieve the ID, handler, and identifier
                int id = trLight.GetProperty <int>("ShapeID");
                if (id > 0)
                {
                    string identifer = trLight.GetProperty <string>("Identifier") ??
                                       ("LightShape" + id);
                    shape = new PLightShape(id, identifer, new CrossModLightWrapper(trLight).
                                            CastLight);
                }
                else
                {
                    // Some invalid object got in there somehow
                    PUtil.LogWarning("Found light shape {0} with bad ID {1:D}!".F(otherShape,
                                                                                  id));
                }
            }
            return(shape);
        }
Example #2
0
        /// <summary>
        /// Adds an octant of light.
        /// </summary>
        /// <param name="range">The range of the light.</param>
        /// <param name="octant">The octant to scan.</param>
        /// <returns>This object, for call chaining.</returns>
        public OctantBuilder AddOctant(int range, Octant octant)
        {
            var points = ListPool <int, OctantBuilder> .Allocate();

            OCTANT_SCAN?.Invoke(null, new object[] {
                Grid.CellToXY(SourceCell), range, 1, octant, 1.0, 0.0, points
            });
            // Transfer to our array using:
            foreach (int cell in points)
            {
                float intensity;
                if (SmoothLight)
                {
                    // Better, not rounded falloff
                    intensity = PLightShape.GetSmoothFalloff(Falloff, cell, SourceCell);
                }
                else
                {
                    // Default falloff
                    intensity = PLightShape.GetDefaultFalloff(Falloff, cell, SourceCell);
                }
                destination[cell] = intensity;
            }
            points.Recycle();
            return(this);
        }
Example #3
0
        /// <summary>
        /// Converts a PLightShape into this mod's namespace.
        /// </summary>
        /// <param name="otherShape">The shape from the shared data.</param>
        /// <returns>An equivalent shape in this mod's namespace.</returns>
        private static PLightShape LightToInstance(object otherShape)
        {
            var shape = otherShape as PLightShape;

            if (shape == null)
            {
                var otherType = otherShape.GetType();
                // Retrieve properties via reflection
                var propID = otherType.GetPropertySafe <int>(nameof(PLightShape.ShapeID),
                                                             false);
                var propName = otherType.GetPropertySafe <string>(nameof(PLightShape.
                                                                         Identifier), false);
                var fillLight = otherType.CreateDelegate <FillLightFunc>(nameof(PLightShape.
                                                                                FillLight), otherShape, typeof(GameObject), typeof(int), typeof(int),
                                                                         typeof(BrightnessDict));
                try {
                    // Retrieve the ID, handler, and identifier
                    if (fillLight == null)
                    {
                        PUtil.LogWarning("PLightSource handler has invalid method signature!");
                    }
                    else if (propID.GetValue(otherShape, null) is int id && id > 0)
                    {
                        shape = new PLightShape(id, (propName.GetValue(otherShape, null) as
                                                     string) ?? ("LightShape" + id), new CrossModLightWrapper(
                                                    fillLight).CastLight);
                    }
                    else
                    {
                        // Some invalid object got in there somehow
                        PUtil.LogWarning("Found light shape {0} with bad ID!".F(otherShape));
                    }
                } catch (TargetInvocationException e) {
Example #4
0
        /// <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);
        }
Example #5
0
        /// <summary>
        /// Registers a light shape handler.
        /// </summary>
        /// <param name="identifier">A unique identifier for this shape. If another mod has
        /// already registered that identifier, the previous mod will take precedence.</param>
        /// <param name="handler">The handler for that shape.</param>
        /// <returns>The light shape which can be used.</returns>
        public static PLightShape Register(string identifier, CastLight handler)
        {
            PLightShape lightShape;

            // In case this call is used before the library was initialized
            if (!PUtil.PLibInit)
            {
                PUtil.InitLibrary(false);
                PUtil.LogWarning("PUtil.InitLibrary was not called before using " +
                                 "PLightShape.Register!");
            }
            lock (PSharedData.GetLock(PRegistry.KEY_LIGHTING_LOCK)) {
                // Get list holding lighting information
                var list = PSharedData.GetData <IList <object> >(PRegistry.KEY_LIGHTING_TABLE);
                if (list == null)
                {
                    PSharedData.PutData(PRegistry.KEY_LIGHTING_TABLE, list =
                                            new List <object>(8));
                }
                // Try to find a match for this identifier
                object ls = null;
                int    n = list.Count, index = 0;
                for (int i = 0; i < n; i++)
                {
                    var light = list[i];
                    // Might be from another assembly so the types may or may not be compatible
                    if (light != null && light.ToString() == identifier && light.GetType().
                        Name == typeof(PLightShape).Name)
                    {
                        index = i;
                        break;
                    }
                }
                if (ls == null)
                {
                    // Not currently existing
                    lightShape = new PLightShape(n + 1, identifier, handler);
                    PUtil.LogDebug("Registered new light shape: " + identifier);
                    list.Add(lightShape);
                }
                else
                {
                    // Exists already
                    PUtil.LogDebug("Found existing light shape: " + identifier);
                    lightShape = new PLightShape(n + 1, identifier, null);
                }
            }
            return(lightShape);
        }
Example #6
0
        /// <summary>
        /// Registers a light shape handler.
        /// </summary>
        /// <param name="identifier">A unique identifier for this shape. If another mod has
        /// already registered that identifier, the previous mod will take precedence.</param>
        /// <param name="handler">The handler for that shape.</param>
        /// <param name="rayMode">The type of visual rays that are displayed from the light.</param>
        /// <returns>The light shape which can be used.</returns>
        public ILightShape Register(string identifier, CastLightDelegate handler,
                                    LightShape rayMode = (LightShape)(-1))
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentNullException(nameof(identifier));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            ILightShape lightShape = null;

            RegisterForForwarding();
            // Try to find a match for this identifier
            var registered = GetSharedData(EMPTY_SHAPES);
            int n          = registered.Count;

            foreach (var obj in registered)
            {
                var light = PRemoteLightWrapper.LightToInstance(obj);
                // Might be from another assembly so the types may or may not be compatible
                if (light != null && light.Identifier == identifier)
                {
                    LogLightingDebug("Found existing light shape: " + identifier + " from " +
                                     (obj.GetType().Assembly.GetNameSafe() ?? "?"));
                    lightShape = light;
                    break;
                }
            }
            if (lightShape == null)
            {
                // Not currently existing
                lightShape = new PLightShape(n + 1, identifier, handler, rayMode);
                LogLightingDebug("Registered new light shape: " + identifier);
                registered.Add(lightShape);
            }
            return(lightShape);
        }