public static bool InvalidCell(IntVec3 c, IntVec3 center, Rot4 rot, Building_Window window, bool AllCells = false)
        {
            if (!c.InBounds(window.Map))
            {
                return(true); // out of map
            }
            if (!AllCells)
            {
                if (!rot.IsHorizontal && ((window.WindowComp.facing == LinkDirections.Up && c.z < center.z) || (window.WindowComp.facing == LinkDirections.Down && c.z > center.z)))
                {
                    return(true);
                }

                if (rot.IsHorizontal && ((window.WindowComp.facing == LinkDirections.Right && c.x < center.x) || (window.WindowComp.facing == LinkDirections.Left && c.x > center.x)))
                {
                    return(true);
                }
            }

            if ((!rot.IsHorizontal && c.z == center.z) || (rot.IsHorizontal && c.x == center.x))
            {
                return(true); // we are inline of the window
            }
            return(false);
        }
 public void DeRegisterWindow(Building_Window window)
 {
     if (windows.Contains(window))
     {
         windows.Remove(window);
         UpdateWindowCells(window, false);
     }
 }
 public void RegisterWindow(Building_Window window)
 {
     if (!windows.Contains(window))
     {
         windows.Add(window);
         // when we attempt to resolve the facing, we also query cells, and push them to the calculation
         if (window.WindowComp.facing == LinkDirections.None)
         {
             window.Cells = WindowUtility.CalculateWindowLightCells(window, window.WindowComp.TryResolveFacing());
         }
         UpdateWindowCells(window, true);
     }
 }
        public static List <IntVec3> CalculateWindowLightCells(Building_Window window, IntVec2 size, IntVec3 center, Rot4 rot, Map map, List <IntVec3> cells = null)
        {
            List <IntVec3> returnVec = new List <IntVec3>();

            if (window.WindowComp.facing == LinkDirections.None)
            {
                return(returnVec);
            }

            if (cells == null)
            {
                foreach (IntVec3 c in GetWindowCells(window, center, rot, size, map))
                {
                    ValidateCell(c);
                }
            }
            else
            {
                foreach (IntVec3 c in cells)
                {
                    ValidateCell(c);
                }
            }


            void ValidateCell(IntVec3 c)
            {
                bool flag = false;

                foreach (var cell in window.OccupiedRect())
                {
                    if (LightReaches(c, cell, map))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag)
                {
                    returnVec.Add(c);
                }
            }

            return(returnVec);
        }
        public void UpdateWindowCells(Building_Window window, bool register)
        {
            foreach (IntVec3 c in window.Cells)
            {
                if (register)
                {
                    if (WindowCells.ContainsKey(c)) // if we already have a window here (crossover) add our window to the list
                    {
                        WindowCells[c].Add(window);
                    }
                    else
                    {
                        WindowCells.Add(c, new List <Building_Window>()
                        {
                            window
                        });
                    }
                }
                else
                {
                    if (WindowCells.ContainsKey(c))
                    {
                        if (WindowCells[c].Count != 1) // if we have multiple entries, simply remove our current window from the list
                        {
                            WindowCells[c].Remove(window);
                        }
                        else // else just remove the entry entirely
                        {
                            WindowCells.Remove(c);
                        }
                    }
                }
            }

            LightingOverlay_Regenerate.dirty = true;
        }
        private static List <IntVec3> GetWindowCells(Building_Window window, IntVec3 center, Rot4 rot, IntVec2 size, Map map, bool forceAll = false)
        {
            if (window.WindowComp.state == State.Closed)
            {
                return(new List <IntVec3>());
            }

            List <IntVec3> returnVec = new List <IntVec3>();

            var extent = (size.x > size.z) ? size.x : size.z;
            var props  = window.WindowComp.Props;

            size = new IntVec2(extent, extent);
            if (props.radius != 0)
            {
                size += new IntVec2(props.radius, props.radius);
            }
            else
            {
                size += new IntVec2(props.x, props.y);
            }


            switch (ElifsDecorationsSettings.focalType)
            {
            case WindowFocalType.Custom:
                foreach (IntVec3 c in GenAdj.OccupiedRect(center, rot, size))
                {
                    if (InvalidCell(c, center, rot, window, forceAll))
                    {
                        continue;
                    }

                    returnVec.Add(c);
                }
                break;

            case WindowFocalType.Circular:
                foreach (var c in GenRadial.RadialCellsAround(center, extent, true))
                {
                    if (InvalidCell(c, center, rot, window, forceAll))
                    {
                        continue;
                    }

                    returnVec.Add(c);
                }
                break;

            case WindowFocalType.Rectangular:
                foreach (IntVec3 c in GenAdj.OccupiedRect(center, rot, size))
                {
                    if (InvalidCell(c, center, rot, window, forceAll))
                    {
                        continue;
                    }

                    returnVec.Add(c);
                }
                break;
            }

            return(returnVec);
        }
 public static List <IntVec3> GetWindowCells(Building_Window window, bool forceAll = false)
 {
     return(GetWindowCells(window, window.Position, window.Rotation, window.def.Size, window.Map, forceAll));
 }
 public static List <IntVec3> CalculateWindowLightCells(Building_Window window, List <IntVec3> cells = null)
 {
     return(CalculateWindowLightCells(window, window.def.size, window.Position, window.Rotation, window.Map, cells));
 }