示例#1
0
        public override void ExposeData()
        {
            base.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 queue
                foreach (ResearchProjectDef research in _saveableQueue)
                {
                    // find a node that matches the research - or null if none found
                    ResearchNode node = research.ResearchNode();

                    // enqueue the node
                    if (node != null)
                    {
                        Log.Debug("Adding {0} to queue", node.Research.LabelCap);
                        Enqueue(node, true);
                    }
                    else
                    {
                        Log.Debug("Could not find node for {0}", research.LabelCap);
                    }
                }
            }
        }
示例#2
0
 public static void TryDequeue(ResearchNode node)
 {
     if (_queue.Contains(node))
     {
         Dequeue(node);
     }
 }
示例#3
0
        private static List <Edge <Node, Node> > CreateEdges(List <ResearchNode> nodes)
        {
            Log.Debug("Creating edges.");
            Profiler.Start();
            // create links between nodes
            var edges = new List <Edge <Node, Node> >();

            foreach (var node in nodes)
            {
                if (node.Research.prerequisites.NullOrEmpty())
                {
                    continue;
                }
                foreach (var prerequisite in node.Research.prerequisites)
                {
                    ResearchNode prerequisiteNode = nodes.Find(n => n.Research == prerequisite);
                    if (prerequisiteNode == null)
                    {
                        continue;
                    }
                    var edge = new Edge <Node, Node>(prerequisiteNode, node);
                    edges.Add(edge);
                    node.InEdges.Add(edge);
                    prerequisiteNode.OutEdges.Add(edge);
                    Log.Trace("\tCreated edge {0}", edge);
                }
            }

            Profiler.End();
            return(edges);
        }
 private static IEnumerable <ResearchNode> RelatedPrerequisites(ResearchNode node)
 {
     return(node.DirectPrerequisites().Concat(
                node.DirectPrerequisites()
                .Where(n => !n.Completed())
                .SelectMany(RelatedPrerequisites)));
 }
示例#5
0
        private static void CreateEdges()
        {
            Log.Debug("Creating edges.");
            Profiler.Start();
            // create links between nodes
            if (_edges.NullOrEmpty())
            {
                _edges = new List <Edge <Node, Node> >();
            }

            foreach (ResearchNode node in Nodes.OfType <ResearchNode>())
            {
                if (node.Research.prerequisites.NullOrEmpty())
                {
                    continue;
                }
                foreach (var prerequisite in node.Research.prerequisites)
                {
                    ResearchNode prerequisiteNode = prerequisite;
                    if (prerequisiteNode == null)
                    {
                        continue;
                    }
                    var edge = new Edge <Node, Node>(prerequisiteNode, node);
                    Edges.Add(edge);
                    node.InEdges.Add(edge);
                    prerequisiteNode.OutEdges.Add(edge);
                    Log.Trace("\tCreated edge {0}", edge);
                }
            }
            Profiler.End();
        }
示例#6
0
        private void DoMove(ResearchNode node, int from, int to)
        {
            List <ResearchNode> movingNodes = new List <ResearchNode>();

            to = Math.Max(0, Math.Min(Count(), to));
            if (to > from)
            {
                movingNodes.Add(node);
                int dest = --to;
                for (int i = from + 1; i <= to; ++i)
                {
                    if (_queue[i].MissingPrerequisites().Contains(node))
                    {
                        movingNodes.Add(_queue[i]);
                        --dest;
                    }
                }
                movingNodes.ForEach(n => _queue.Remove(n));
                _queue.InsertRange(dest, movingNodes);
            }
            else if (to < from)
            {
                var prerequisites = node.MissingPrerequisites().ToList();
                for (int i = to; i < from; ++i)
                {
                    if (prerequisites.Contains(_queue[i]))
                    {
                        movingNodes.Add(_queue[i]);
                    }
                }
                movingNodes.Add(node);
                UnsafeInsert(movingNodes, to);
            }
        }
示例#7
0
        public override void PreOpen()
        {
            base.PreOpen();

            SetRects();

            // settings changed, notify...
            if (Tree.shouldSeparateByTechLevels != Settings.shouldSeparateByTechLevels)
            {
                Messages.Message(ResourceBank.String.NeedsRestart, MessageTypeDefOf.CautionInput, false);
            }

            if (Settings.shouldPause)
            {
                forcePause = Settings.shouldPause;
            }

            if (Settings.shouldReset)
            {
                _query          = "";
                _scrollPosition = Vector2.zero;
                ZoomLevel       = 1f;
            }

            // clear node availability caches
            ResearchNode.ClearCaches();

            _dragging             = false;
            closeOnClickedOutside = false;
        }
示例#8
0
 static void HandleHoverHighlight(ResearchNode node, Vector2 mousePos)
 {
     if (node.MouseOver(mousePos))
     {
         OverrideHighlight(node);
     }
 }
 private RelatedNodeHighlightSet(
     ResearchNode causer, Highlighting.Reason causerR,
     Highlighting.Reason relatedR)
 {
     _causer        = causer;
     _causerReason  = causerR;
     _relatedReason = relatedR;
 }
示例#10
0
 public void Finish(ResearchNode node)
 {
     foreach (var n in node.MissingPrerequisitesInc())
     {
         _queue.Remove(n);
         Find.ResearchManager.FinishProject(n.Research);
     }
 }
示例#11
0
        public static RelatedNodeHighlightSet HoverOn(ResearchNode node)
        {
            var instance = new RelatedNodeHighlightSet(
                node, Highlighting.Reason.HoverPrimary,
                Highlighting.Reason.HoverSecondary);

            instance._relatedNodes = RelatedNodes(node);
            return(instance);
        }
示例#12
0
 public void Prepend(ResearchNode node)
 {
     if (CantResearch(node))
     {
         return;
     }
     UnsafeConcatFront(node.MissingPrerequisitesInc());
     UpdateCurrentResearch();
 }
示例#13
0
 public bool Append(ResearchNode node)
 {
     if (_queue.Contains(node) || CantResearch(node))
     {
         return(false);
     }
     UnsafeAppend(node);
     return(true);
 }
示例#14
0
        public static RelatedNodeHighlightSet FixHighlight(ResearchNode node)
        {
            var instance = new RelatedNodeHighlightSet(
                node, Highlighting.Reason.FixedPrimary,
                Highlighting.Reason.FixedSecondary);

            instance._relatedNodes = RelatedNodes(node);
            return(instance);
        }
示例#15
0
 public bool HighlightInEdge(ResearchNode from)
 {
     foreach (var r1 in HighlightReasons())
     {
         foreach (var r2 in from.HighlightReasons())
         {
             if (Highlighting.Similar(r1, r2))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
示例#16
0
 static private void FilteredTopoSortRec(
     ResearchNode cur, Func <ResearchNode, bool> p,
     List <ResearchNode> result, HashSet <ResearchNode> visited)
 {
     if (visited.Contains(cur))
     {
         return;
     }
     foreach (var next in cur.InNodes.OfType <ResearchNode>().Where(p))
     {
         FilteredTopoSortRec(next, p, result, visited);
     }
     result.Add(cur);
     visited.Add(cur);
 }
示例#17
0
        public static void Dequeue(ResearchNode node)
        {
            // remove this node
            _instance._queue.Remove(node);

            // remove all nodes that depend on it
            var followUps = _instance._queue.Where(n => n.GetMissingRequiredRecursive().Contains(node)).ToList();

            foreach (var followUp in followUps)
            {
                _instance._queue.Remove(followUp);
            }

            // if currently researching this node, stop that
            if (Find.ResearchManager.currentProj == node.Research)
            {
                Find.ResearchManager.currentProj = null;
            }
        }
示例#18
0
        // We only care about the research, no new nodes will be created or moved.
        static void HandleResearchNode(SyncWorker sw, ref ResearchNode node)
        {
            // Bind commands are in the order they are placed
            // So if you write a Def first, you must read it first and so on
            if (sw.isWriting)
            {
                // We are writing, node is the outgoing object
                sw.Bind(ref node.Research);
            }
            else
            {
                ResearchProjectDef research = null;

                sw.Bind(ref research);

                // We are reading, node is null, we must set it. So we look it up
                // research is unique in the Tree
                node = Lookup(research);
            }
        }
示例#19
0
        public static void HandleFixedHighlight(ResearchNode node)
        {
            var i = fixedHighlightSets.FirstIndexOf(s => s.Causer() == node);

            if (i < fixedHighlightSets.Count())
            {
                fixedHighlightSets[i].Stop();
                fixedHighlightSets.RemoveAt(i);
            }
            else
            {
                var hl = RelatedNodeHighlightSet.FixHighlight(node);
                hl.Start();
                if (!Event.current.shift)
                {
                    StopFixedHighlights();
                }
                fixedHighlightSets.Add(hl);
            }
        }
示例#20
0
 public override Color InEdgeColor(ResearchNode from)
 {
     if (HighlightInEdge(from))
     {
         return(Assets.NormalHighlightColor);
     }
     if (MainTabWindow_ResearchTree.Instance.SearchActive())
     {
         return(Assets.ColorUnmatched[Research.techLevel]);
     }
     if (Completed())
     {
         return(Assets.ColorEdgeCompleted[Research.techLevel]);
     }
     if (Available())
     {
         return(Assets.ColorAvailable[Research.techLevel]);
     }
     return(Assets.ColorUnavailable[Research.techLevel]);
 }
示例#21
0
        public static void Enqueue(ResearchNode node, bool add)
        {
            Log.Debug($"Enqueuing: {node.Research.defName}");

            // if we're not adding, clear the current queue and current research project
            if (!add)
            {
                _instance._queue.Clear();
                Find.ResearchManager.currentProj = null;
            }

            // add to the queue if not already in it
            if (!_instance._queue.Contains(node))
            {
                _instance._queue.Add(node);
            }

            // try set the first research in the queue to be the current project.
            var next = _instance._queue.First();

            Find.ResearchManager.currentProj = next?.Research; // null if next is null.
        }
示例#22
0
        public static bool BuildingPresent(ResearchNode node)
        {
            var research = node.Research;

            if (DebugSettings.godMode && Prefs.DevMode)
            {
                return(true);
            }

            // try get from cache
            bool result;

            if (_buildingPresentCache.TryGetValue(research, out result))
            {
                return(result);
            }

            // do the work manually
            if (research.requiredResearchBuilding == null)
            {
                result = true;
            }
            else
            {
                result = Find.Maps.SelectMany(map => map.listerBuildings.allBuildingsColonist)
                         .OfType <Building_ResearchBench>()
                         .Any(b => research.CanBeResearchedAt(b, true));
            }

            if (result)
            {
                result = node.MissingPrerequisites().All(BuildingPresent);
            }

            // update cache
            _buildingPresentCache.Add(research, result);
            return(result);
        }
示例#23
0
        public void Insert(ResearchNode node, int pos)
        {
            if (CantResearch(node))
            {
                return;
            }
            pos = Math.Max(0, Math.Min(Count(), pos));
            var idx = _queue.IndexOf(node);

            if (idx == pos)
            {
                return;
            }
            if (idx != -1)
            {
                DoMove(node, idx, pos);
            }
            else
            {
                UnsafeInsert(node.MissingPrerequisitesInc(), pos);
            }
            UpdateCurrentResearch();
        }
示例#24
0
        public bool Remove(ResearchNode node)
        {
            if (node.Completed())
            {
                return(_queue.Remove(node));
            }
            List <ResearchNode> shouldRemove = new List <ResearchNode>();
            var idx = _queue.IndexOf(node);

            if (idx == -1)
            {
                return(false);
            }
            MarkShouldRemove(idx, shouldRemove);
            foreach (var n in shouldRemove)
            {
                _queue.Remove(n);
            }
            if (idx == 0)
            {
                UpdateCurrentResearch();
            }
            return(true);
        }
示例#25
0
        private void ReleaseNodeAt(ResearchNode node, int dropIdx)
        {
            if (dropIdx == -1)
            {
                Remove(node);
            }
            var tab = MainTabWindow_ResearchTree.Instance;

            if (_queue.IndexOf(node) == dropIdx)
            {
                if (tab.DraggingTime() < 0.2f)
                {
                    node.LeftClick();
                }
            }
            else
            {
                if (DraggingFromQueue() && dropIdx > _queue.IndexOf(node))
                {
                    ++dropIdx;
                }
                Insert(node, dropIdx);
            }
        }
示例#26
0
 public static bool IsQueued(ResearchNode node)
 {
     return(_instance._queue.Contains(node));
 }
示例#27
0
 public static List <ResearchNode> RelatedNodes(ResearchNode node)
 {
     return(RelatedPrerequisites(node).Concat(node.DirectChildren()).ToList());
 }
示例#28
0
 static List <ResearchNode> FindHighlightsFrom(ResearchNode node)
 {
     return(node.MissingPrerequisites()
            .Concat(node.Children.Where(c => !c.Completed()))
            .ToList());
 }
示例#29
0
 public virtual Color InEdgeColor(ResearchNode from)
 {
     return(Color);
 }
示例#30
0
 static void OverrideHighlight(ResearchNode node)
 {
     hoverHighlightSet?.Stop();
     hoverHighlightSet = RelatedNodeHighlightSet.HoverOn(node);
     hoverHighlightSet.Start();
 }