예제 #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.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);
                    }
                }
            }
        }
예제 #2
0
        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;
        }
예제 #4
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 (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();
        }
예제 #5
0
 public static void TryDequeue(ResearchNode node)
 {
     if (_instance._queue.Contains(node))
     {
         Dequeue(node);
     }
 }
예제 #6
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);
                    }
                }
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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;
        }
예제 #11
0
        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;
            }
        }
예제 #12
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);
            }
        }
예제 #13
0
        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.
        }
예제 #14
0
 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);
            }
        }