示例#1
0
        public void CreateMiniMap(GUIComponent parent, IEnumerable <Entity> pointsOfInterest = null, bool ignoreOutpost = false)
        {
            Rectangle worldBorders = GetDockedBorders();

            worldBorders.Location += WorldPosition.ToPoint();

            //create a container that has the same "aspect ratio" as the sub
            float aspectRatio       = worldBorders.Width / (float)worldBorders.Height;
            float parentAspectRatio = parent.Rect.Width / (float)parent.Rect.Height;

            float scale = 0.9f;

            GUIFrame hullContainer = new GUIFrame(new RectTransform(
                                                      (parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
                                                      parent.RectTransform, Anchor.Center),
                                                  style: null)
            {
                UserData = "hullcontainer"
            };

            var connectedSubs = GetConnectedSubs();

            HashSet <Hull> hullList = Hull.hullList.Where(hull => hull.Submarine == this || connectedSubs.Contains(hull.Submarine)).Where(hull => !ignoreOutpost || IsEntityFoundOnThisSub(hull, true)).ToHashSet();

            Dictionary <Hull, HashSet <Hull> > combinedHulls = new Dictionary <Hull, HashSet <Hull> >();

            foreach (Hull hull in hullList)
            {
                if (combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull)))
                {
                    continue;
                }

                List <Hull> linkedHulls = new List <Hull>();
                MiniMap.GetLinkedHulls(hull, linkedHulls);

                linkedHulls.Remove(hull);

                foreach (Hull linkedHull in linkedHulls)
                {
                    if (!combinedHulls.ContainsKey(hull))
                    {
                        combinedHulls.Add(hull, new HashSet <Hull>());
                    }

                    combinedHulls[hull].Add(linkedHull);
                }
            }

            foreach (Hull hull in hullList)
            {
                Vector2 relativeHullPos = new Vector2(
                    (hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
                    (worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height);
                Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height);

                bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull));

                if (hideHull)
                {
                    continue;
                }

                Color color = Color.DarkCyan * 0.8f;

                var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform)
                {
                    RelativeOffset = relativeHullPos
                }, style: "MiniMapRoom", color: color)
                {
                    UserData = hull
                };

                new GUIFrame(new RectTransform(Vector2.One, hullFrame.RectTransform), style: "ScanLines", color: color);
            }

            foreach (var(mainHull, linkedHulls) in combinedHulls)
            {
                MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);

                Vector2 relativeHullPos = new Vector2(
                    (data.Bounds.X - worldBorders.X) / worldBorders.Width,
                    (worldBorders.Y - data.Bounds.Y) / worldBorders.Height);

                Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height);

                Color color = Color.DarkCyan * 0.8f;

                float highestY = 0f,
                      highestX = 0f;

                foreach (var(r, _) in data.RectDatas)
                {
                    float y = r.Y - -r.Height,
                          x = r.X;

                    if (y > highestY)
                    {
                        highestY = y;
                    }
                    if (x > highestX)
                    {
                        highestX = x;
                    }
                }

                HashSet <GUIFrame> frames = new HashSet <GUIFrame>();

                foreach (var(snappredRect, hull) in data.RectDatas)
                {
                    RectangleF rect = snappredRect;
                    rect.Height = -rect.Height;
                    rect.Y     -= rect.Height;

                    var(parentW, parentH) = hullContainer.Rect.Size.ToVector2();
                    Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH);
                    // TODO this won't be required if we some day switch RectTransform to use RectangleF
                    Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH);

                    GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform)
                    {
                        RelativeOffset = pos
                    }, style: "ScanLinesSeamless", color: color)
                    {
                        UserData = hull,
                        UVOffset = new Vector2(highestX - rect.X, highestY - rect.Y)
                    };

                    frames.Add(hullFrame);
                }

                new GUICustomComponent(new RectTransform(relativeHullSize, hullContainer.RectTransform)
                {
                    RelativeOffset = relativeHullPos
                }, (spriteBatch, component) =>
                {
                    foreach (List <Vector2> list in data.Polygon)
                    {
                        spriteBatch.DrawPolygonInner(hullContainer.Rect.Location.ToVector2(), list, component.Color, 2f);
                    }
                }, (deltaTime, component) =>
                {
                    if (component.Parent.Rect.Size != data.ParentSize)
                    {
                        data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
                    }
                })
                {
                    UserData     = frames,
                    Color        = color,
                    CanBeFocused = false
                };
            }

            if (pointsOfInterest != null)
            {
                foreach (Entity entity in pointsOfInterest)
                {
                    Vector2 relativePos = new Vector2(
                        (entity.WorldPosition.X - worldBorders.X) / worldBorders.Width,
                        (worldBorders.Y - entity.WorldPosition.Y) / worldBorders.Height);
                    new GUIFrame(new RectTransform(new Point(1, 1), hullContainer.RectTransform)
                    {
                        RelativeOffset = relativePos
                    }, style: null)
                    {
                        CanBeFocused = false,
                        UserData     = entity
                    };
                }
            }
        }