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.LookList(ref _saveableQueue, "Queue", LookMode.Def); if (Scribe.mode == LoadSaveMode.PostLoadInit) { // initialize the tree if not initialized if (!Tree.Initialized) { Tree.Initialize(); } // initialize the queue foreach (ResearchProjectDef research in _saveableQueue) { // find a node that matches the research - or null if none found ResearchNode node = research.Node(); // enqueue the node if (node != null) { Enqueue(node, true); } } } }
public static List <Node> CreateDummyNodes(ResearchNode parent, ResearchNode child) { // decouple parent and child parent.Below.Remove(child); child.Above.Remove(parent); // create dummy nodes int n = child.X - parent.X; var dummies = new List <Node>(n); Node last = parent; for (var i = 1; i < n; i++) { // create empty dummy var dummy = new DummyNode(); dummies.Add(dummy); // hook up the chain last.Below.Add(dummy); dummy.Above.Add(last); dummy.X = last.X + 1; // this is now last last = dummy; } // hook up child last.Below.Add(child); child.Above.Add(last); // done! return(dummies); }
public override void PreOpen() { base.PreOpen(); if (!Tree.Initialized) { // initialize tree Tree.Initialize(); // spit out debug info #if DEBUG Log.Message("ResearchTree :: duplicated positions:\n " + string.Join("\n", Tree.Leaves.Where(n => Tree.Leaves.Any(n2 => n != n2 && n.X == n2.X && n.Y == n2.Y)).Select(n => n.X + ", " + n.Y + ": " + n.Label).ToArray())); Log.Message("ResearchTree :: out-of-bounds nodes:\n" + string.Join("\n", Tree.Leaves.Where(n => n.X < 1 || n.Y < 1).Select(n => n.ToString()).ToArray())); Log.Message(Tree.ToString()); #endif } // clear node availability caches ResearchNode.ClearCaches(); // set to topleft (for some reason vanilla alignment overlaps bottom buttons). windowRect.x = 0f; windowRect.y = 0f; windowRect.width = Screen.width; windowRect.height = Screen.height - 35f; }
private static void CreateEdges() { Log.Debug("Creating edges."); Profiler.Start(); // create links between nodes if (_edges.NullOrEmpty()) { _edges = new List <Edge <Node, Node> >(); } foreach (var 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(); }
public static void TryDequeue(ResearchNode node) { if (_instance._queue.Contains(node)) { Dequeue(node); } }
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 Dequeue(ResearchNode node) { _queue.Remove(node); List <ResearchNode> followUps = _queue.Where(n => n.GetMissingRequiredRecursive().Contains(node)).ToList(); foreach (ResearchNode followUp in followUps) { _queue.Remove(followUp); } }
public static bool TryStartNext(out ResearchNode next) { if (_queue.Count > 0) { next = _queue.First(); Find.ResearchManager.currentProj = next.Research; return(true); } next = null; Find.ResearchManager.currentProj = null; return(false); }
static void SyncResearchNode(SyncWorker worker, ref ResearchNode node) { Log.Debug($"Syncing"); if (worker.isWriting) { Log.Debug($"writing"); worker.Write(node.Research.defName); } else { Log.Debug($"reading"); string researchDef = worker.Read <string>(); node = (DefDatabase <ResearchProjectDef> .GetNamed(researchDef)).ResearchNode(); } }
public override void PreOpen() { base.PreOpen(); SetRects(); if (!Tree.Initialized) { // initialize tree Tree.Initialize(); } // clear node availability caches ResearchNode.ClearCaches(); _dragging = false; closeOnClickedOutside = false; }
public static void Dequeue(ResearchNode node) { // remove this node _queue.Remove(node); // remove all nodes that depend on it List <ResearchNode> followUps = _queue.Where(n => n.GetMissingRequiredRecursive().Contains(node)).ToList(); foreach (ResearchNode followUp in followUps) { _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 Enqueue(ResearchNode node, bool add) { // if we're not adding, clear the current queue and current research project if (!add) { _queue.Clear(); Find.ResearchManager.currentProj = null; } // add to the queue if not already in it if (!_queue.Contains(node)) { _queue.Add(node); } // try set the first research in the queue to be the current project. ResearchNode next = _queue.First(); Find.ResearchManager.currentProj = next?.Research; // null if next is null. }
public static bool IsQueued(ResearchNode node) { return(_queue.Contains(node)); }
public void ResearchPerformed(float amount, Pawn researcher) { // get research manager instance ResearchManager manager = Find.ResearchManager; if (manager.currentProj == null) { Log.Error("Researched without having an active project."); return; } amount *= GlobalProgressFactor; if (researcher != null && researcher.Faction != null) { amount /= manager.currentProj.CostFactor(researcher.Faction.def.techLevel); } if (DebugSettings.fastResearch) { amount *= 500f; } researcher?.records.AddTo(RecordDefOf.ResearchPointsResearched, amount); Dictionary <ResearchProjectDef, float> progress = Progress; progress[manager.currentProj] = manager.GetProgress(manager.currentProj) + amount; // if not finished we're done if (!manager.currentProj.IsFinished) { return; } // otherwise, do some additional stuff; manager.ReapplyAllMods(); // remove current from queue ResearchNode completed = Queue.Pop; if (researcher != null) { TaleRecorder.RecordTale(TaleDefOf.FinishedResearchProject, researcher, completed.Research); } // message string label = "ResearchFinished".Translate(completed.Research.LabelCap); string text = "ResearchFinished".Translate(completed.Research.LabelCap) + "\n\n" + completed.Research.DescriptionDiscovered; // if there's something on the queue start it, and push an appropriate message ResearchNode next; if (Queue.TryStartNext(out next)) { text += "\n\n" + "NextInQueue".Translate(next.Research.LabelCap); Find.LetterStack.ReceiveLetter(label, text, LetterType.Good); } else { text += "\n\n" + "NextInQueue".Translate("none".Translate()); Find.LetterStack.ReceiveLetter(label, text, LetterType.BadNonUrgent); } }