예제 #1
0
        public override void ExposeData()
        {
            // store research defs as these are the defining elements
            if (Scribe.mode == LoadSaveMode.Saving)
            {
                _saveableQueue = _queue.Select(node => node.Research).ToList();
            }

            Scribe_Collections.Look(ref _saveableQueue, "Queue", LookMode.Def);

            if (Scribe.mode == LoadSaveMode.PostLoadInit)
            {
                // initialize the tree if not initialized
                if (!ResearchTree.Initialized)
                {
                    ResearchTree.Initialize();
                }

                // initialize the queue
                foreach (ResearchProjectDef research in _saveableQueue)
                {
                    // find a node that matches the research - or null if none found
                    Node node = ResearchTree.Forest.FirstOrDefault(n => n.Research == research);

                    // enqueue the node
                    if (node != null)
                    {
                        Enqueue(node, true);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        ///     Draw the node, including interactions.
        /// </summary>
        public override void Draw(Rect visibleRect, bool forceDetailedMode = false)
        {
            if (!IsVisible(visibleRect))
            {
                Highlighted = false;
                return;
            }

            var detailedMode = forceDetailedMode ||
                               MainTabWindow_ResearchTree.Instance.ZoomLevel < DetailedModeZoomLevelCutoff;
            var mouseOver = Mouse.IsOver(Rect);

            if (Event.current.type == EventType.Repaint)
            {
                // researches that are completed or could be started immediately, and that have the required building(s) available
                GUI.color = mouseOver ? GenUI.MouseoverColor : Color;

                if (mouseOver || Highlighted)
                {
                    GUI.DrawTexture(Rect, Assets.ButtonActive);
                }
                else
                {
                    GUI.DrawTexture(Rect, Assets.Button);
                }

                // grey out center to create a progress bar effect, completely greying out research not started.
                if (Available)
                {
                    var progressBarRect = Rect.ContractedBy(3f);
                    GUI.color             = Assets.ColorAvailable[Research.techLevel];
                    progressBarRect.xMin += Research.ProgressPercent * progressBarRect.width;
                    GUI.DrawTexture(progressBarRect, BaseContent.WhiteTex);
                }

                Highlighted = false;


                // draw the research label
                if (!Completed && !Available)
                {
                    GUI.color = Color.grey;
                }
                else
                {
                    GUI.color = Color.white;
                }

                if (detailedMode)
                {
                    Text.Anchor   = TextAnchor.UpperLeft;
                    Text.WordWrap = false;
                    Text.Font     = _largeLabel ? GameFont.Tiny : GameFont.Small;
                    Widgets.Label(LabelRect, Research.LabelCap);
                }
                else
                {
                    Text.Anchor   = TextAnchor.MiddleCenter;
                    Text.WordWrap = false;
                    Text.Font     = GameFont.Medium;
                    Widgets.Label(Rect, Research.LabelCap);
                }

                // draw research cost and icon
                if (detailedMode)
                {
                    Text.Anchor = TextAnchor.UpperRight;
                    Text.Font   = Research.CostApparent > 1000000 ? GameFont.Tiny : GameFont.Small;
                    Widgets.Label(CostLabelRect, Research.CostApparent.ToStringByStyle(ToStringStyle.Integer));
                    GUI.DrawTexture(CostIconRect, !Completed && !Available ? Assets.Lock : Assets.ResearchIcon,
                                    ScaleMode.ScaleToFit);
                }

                Text.WordWrap = true;

                // attach description and further info to a tooltip
                TooltipHandler.TipRegion(Rect, GetResearchTooltipString, Research.GetHashCode());
                if (!BuildingPresent())
                {
                    TooltipHandler.TipRegion(Rect,
                                             ResourceBank.String.MissingFacilities(string.Join(", ",
                                                                                               MissingFacilities().Select(td => td.LabelCap).ToArray())));
                }
                else if (!TechprintAvailable())
                {
                    TooltipHandler.TipRegion(Rect,
                                             ResourceBank.String.MissingTechprints(Research.TechprintsApplied, Research.techprintCount));
                }


                // draw unlock icons
                if (detailedMode)
                {
                    var unlocks = Research.GetUnlockDefsAndDescs();
                    for (var i = 0; i < unlocks.Count; i++)
                    {
                        var iconRect = new Rect(
                            IconsRect.xMax - (i + 1) * (IconSize.x + 4f),
                            IconsRect.yMin + (IconsRect.height - IconSize.y) / 2f,
                            IconSize.x,
                            IconSize.y);

                        if (iconRect.xMin - IconSize.x < IconsRect.xMin &&
                            i + 1 < unlocks.Count)
                        {
                            // stop the loop if we're about to overflow and have 2 or more unlocks yet to print.
                            iconRect.x = IconsRect.x + 4f;
                            GUI.DrawTexture(iconRect, Assets.MoreIcon, ScaleMode.ScaleToFit);
                            var tip = string.Join("\n",
                                                  unlocks.GetRange(i, unlocks.Count - i).Select(p => p.Second)
                                                  .ToArray());
                            TooltipHandler.TipRegion(iconRect, tip);
                            // new TipSignal( tip, Settings.TipID, TooltipPriority.Pawn ) );
                            break;
                        }

                        // draw icon
                        unlocks[i].First.DrawColouredIcon(iconRect);

                        // tooltip
                        TooltipHandler.TipRegion(iconRect, unlocks[i].Second);
                    }
                }

                if (mouseOver)
                {
                    // highlight prerequisites if research available
                    if (Available)
                    {
                        Highlighted = true;
                        foreach (var prerequisite in GetMissingRequiredRecursive())
                        {
                            prerequisite.Highlighted = true;
                        }
                    }
                    // highlight children if completed
                    else if (Completed)
                    {
                        foreach (var child in Children)
                        {
                            child.Highlighted = true;
                        }
                    }
                }
            }

            // if clicked and not yet finished, queue up this research and all prereqs.
            if (Widgets.ButtonInvisible(Rect) && Available)
            {
                // LMB is queue operations, RMB is info
                if (Event.current.button == 0 && !Research.IsFinished)
                {
                    if (DebugSettings.godMode && Event.current.control)
                    {
                        var nodes = GetMissingRequiredRecursive()
                                    .Concat(new List <ResearchNode>(new[] { this }))
                                    .Distinct().Reverse();
                        foreach (ResearchNode n in nodes)
                        {
                            if (Queue.IsQueued(n))
                            {
                                Queue.Dequeue(n);
                            }

                            if (!n.Research.IsFinished)
                            {
                                Find.ResearchManager.FinishProject(n.Research, false);
                            }
                        }
                        if (nodes.Any())
                        {
                            Messages.Message(ResourceBank.String.FinishedResearch(Research.LabelCap), MessageTypeDefOf.SilentInput, false);
                            Queue.Notify_InstantFinished();
                        }
                    }
                    else if (!Queue.IsQueued(this))
                    {
                        // if shift is held, add to queue, otherwise replace queue
                        var queue = GetMissingRequiredRecursive()
                                    .Concat(new List <ResearchNode>(new[] { this }))
                                    .Distinct();
                        Queue.EnqueueRange(queue, Event.current.shift);
                    }
                    else
                    {
                        Queue.Dequeue(this);
                    }
                }
                else if (Event.current.button == 1)
                {
                    ResearchTree.JumpToHelp(Research);
                }
            }
        }
        public void DrawTree(Rect canvas)
        {
            // get total size of Research Tree
            int maxDepth = 0, totalWidth = 0;

            if (ResearchTree.Trees.Any())
            {
                maxDepth   = ResearchTree.Trees.Max(tree => tree.MaxDepth);
                totalWidth = ResearchTree.Trees.Sum(tree => tree.Width);
            }

            maxDepth    = Math.Max(maxDepth, ResearchTree.Orphans.MaxDepth);
            totalWidth += ResearchTree.Orphans.Width;

            float width  = (maxDepth + 1) * (Settings.NodeSize.x + Settings.NodeMargins.x);    // zero based
            float height = totalWidth * (Settings.NodeSize.y + Settings.NodeMargins.y);

            // main view rect
            Rect view = new Rect(0f, 0f, width, height);

            Widgets.BeginScrollView(canvas, ref _scrollPosition, view);
            GUI.BeginGroup(view);

            Text.Anchor = TextAnchor.MiddleCenter;

            // draw regular connections, not done first to better highlight done.
            foreach (Pair <Node, Node> connection in connections.Where(pair => !pair.Second.Research.IsFinished))
            {
                ResearchTree.DrawLine(connection, connection.First.Tree.GreyedColor);
            }

            // draw connections from completed nodes
            foreach (Pair <Node, Node> connection in connections.Where(pair => pair.Second.Research.IsFinished))
            {
                ResearchTree.DrawLine(connection, connection.First.Tree.MediumColor);
            }
            connections.Clear();

            // draw highlight connections on top
            foreach (Pair <Node, Node> connection in highlightedConnections)
            {
                ResearchTree.DrawLine(connection, GenUI.MouseoverColor, true);
            }
            highlightedConnections.Clear();

            // draw nodes on top of lines
            foreach (Node node in nodes)
            {
                node.Draw();
            }
            nodes.Clear();

            // register hub tooltips
            foreach (KeyValuePair <Rect, List <string> > pair in hubTips)
            {
                string text = string.Join("\n", pair.Value.ToArray());
                TooltipHandler.TipRegion(pair.Key, text);
            }
            hubTips.Clear();

            // draw Queue labels
            Queue.DrawLabels();

            // reset anchor
            Text.Anchor = TextAnchor.UpperLeft;

            GUI.EndGroup();
            Widgets.EndScrollView();
        }
        public void DrawTree(Rect canvas)
        {
            // get total size of Research Tree
            int maxDepth = 0, totalWidth = 0;

            if (ResearchTree.Trees.Any())
            {
                maxDepth   = ResearchTree.Trees.Max(tree => tree.MaxDepth);
                totalWidth = ResearchTree.Trees.Sum(tree => tree.Width);
            }

            maxDepth    = Math.Max(maxDepth, ResearchTree.Orphans.MaxDepth);
            totalWidth += ResearchTree.Orphans.Width;

            float width  = (maxDepth + 1) * (Settings.NodeSize.x + Settings.NodeMargins.x);    // zero based
            float height = (totalWidth - 1) * (Settings.NodeSize.y + Settings.NodeMargins.y);

            // main view rect
            Rect view = new Rect(0f, 0f, width, height);

            // create the scroll area below the search box (plus a small margin) so it stays on top
            Widgets.BeginScrollView(new Rect(canvas.x,
                                             canvas.y + filterManager.Height + Settings.NodeMargins.y,
                                             canvas.width, canvas.height - filterManager.Height - Settings.NodeMargins.y),
                                    ref _scrollPosition, view);
            GUI.BeginGroup(view);
            Text.Anchor = TextAnchor.MiddleCenter;

            // draw regular connections, not done first to better highlight done.
            foreach (Pair <Node, Node> connection in connections.Where(pair => !pair.Second.Research.IsFinished))
            {
                ResearchTree.DrawLine(connection,
                                      filterManager.FilterPhrase.NullOrEmpty() ? connection.First.Tree.GreyedColor : ColorHelper.AdjustAlpha(connection.First.Tree.GreyedColor, Settings.FilterNonMatchAlpha));
            }

            // draw connections from completed nodes
            foreach (Pair <Node, Node> connection in connections.Where(pair => pair.Second.Research.IsFinished))
            {
                if (!filterManager.FilterPhrase.NullOrEmpty())
                {
                    ResearchTree.DrawLine(connection, ColorHelper.AdjustAlpha(connection.First.Tree.GreyedColor, Settings.FilterNonMatchAlpha));
                }
                else
                {
                    ResearchTree.DrawLine(connection, connection.First.Tree.MediumColor);
                }
            }
            connections.Clear();

            // draw highlight connections on top
            foreach (Pair <Node, Node> connection in highlightedConnections)
            {
                ResearchTree.DrawLine(connection, GenUI.MouseoverColor, true);
            }
            highlightedConnections.Clear();

            // draw nodes on top of lines
            bool reqScroll    = true;
            Node scrollToNode = null;

            foreach (Node node in nodes)
            {
                // draw the node
                bool visible = node.Draw();

                // ensure that at least one matching node is visible, prioritize highest on the screen
                if (filterManager.FilterDirty)
                {
                    if (node.FilterMatch.IsValidMatch())
                    {
                        if (!reqScroll)
                        {
                            continue;
                        }

                        // this node is a match and is currently visible, we don't need to scroll
                        if (visible)
                        {
                            reqScroll    = false;
                            scrollToNode = null;
                        }
                        else
                        {
                            // this node is a match, but isn't visible. if it's the highest node then we'll scroll to it
                            if (scrollToNode == null || node.Pos.z < scrollToNode.Pos.z)
                            {
                                scrollToNode = node;
                            }
                        }
                    }
                }
            }

            if (filterManager.FilterDirty)
            {
                // scroll to a matching node if necessary
                if (scrollToNode != null)
                {
                    // scale the focus area to ensure it all fits on the screen
                    Rect r = scrollToNode.Rect.ScaledBy(2.0f);
                    _scrollPosition = new Vector2(r.xMin, r.yMin);
                }
                else if (filterManager.FilterPhrase == "")
                {
                    _scrollPosition = Vector2.zero;
                }
            }
            nodes.Clear();

            // register hub tooltips
            foreach (KeyValuePair <Rect, List <string> > pair in hubTips)
            {
                string text = string.Join("\n", pair.Value.ToArray());
                TooltipHandler.TipRegion(pair.Key, text);
            }
            hubTips.Clear();

            // draw Queue labels
            Queue.DrawLabels();

            // reset anchor
            Text.Anchor = TextAnchor.UpperLeft;

            GUI.EndGroup();
            Widgets.EndScrollView();
        }