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); } } } }
public static void TryDequeue(ResearchNode node) { if (_queue.Contains(node)) { Dequeue(node); } }
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))); }
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(); }
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); } }
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; }
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; }
public void Finish(ResearchNode node) { foreach (var n in node.MissingPrerequisitesInc()) { _queue.Remove(n); Find.ResearchManager.FinishProject(n.Research); } }
public static RelatedNodeHighlightSet HoverOn(ResearchNode node) { var instance = new RelatedNodeHighlightSet( node, Highlighting.Reason.HoverPrimary, Highlighting.Reason.HoverSecondary); instance._relatedNodes = RelatedNodes(node); return(instance); }
public void Prepend(ResearchNode node) { if (CantResearch(node)) { return; } UnsafeConcatFront(node.MissingPrerequisitesInc()); UpdateCurrentResearch(); }
public bool Append(ResearchNode node) { if (_queue.Contains(node) || CantResearch(node)) { return(false); } UnsafeAppend(node); return(true); }
public static RelatedNodeHighlightSet FixHighlight(ResearchNode node) { var instance = new RelatedNodeHighlightSet( node, Highlighting.Reason.FixedPrimary, Highlighting.Reason.FixedSecondary); instance._relatedNodes = RelatedNodes(node); return(instance); }
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); }
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); }
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; } }
// 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); } }
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); } }
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]); }
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. }
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); }
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(); }
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); }
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); } }
public static bool IsQueued(ResearchNode node) { return(_instance._queue.Contains(node)); }
public static List <ResearchNode> RelatedNodes(ResearchNode node) { return(RelatedPrerequisites(node).Concat(node.DirectChildren()).ToList()); }
static List <ResearchNode> FindHighlightsFrom(ResearchNode node) { return(node.MissingPrerequisites() .Concat(node.Children.Where(c => !c.Completed())) .ToList()); }
public virtual Color InEdgeColor(ResearchNode from) { return(Color); }
static void OverrideHighlight(ResearchNode node) { hoverHighlightSet?.Stop(); hoverHighlightSet = RelatedNodeHighlightSet.HoverOn(node); hoverHighlightSet.Start(); }