コード例 #1
0
        public static ThinkResult TryIssueJobPackage2(ThinkNode_Priority __instance, Pawn pawn, JobIssueParams jobParams)
        {
            int count = __instance.subNodes.Count;

            for (int index = 0; index < count; ++index)
            {
                ThinkResult thinkResult = ThinkResult.NoJob;
                try
                {
                    ThinkNode thinkNode = __instance.subNodes[index];
                    if (thinkNode == null)
                    {
                        return(thinkResult);
                    }
                    thinkResult = thinkNode.TryIssueJobPackage(pawn, jobParams);
                }
                catch (Exception ex)
                {
                    Log.Error("Exception in " + __instance.GetType() + " TryIssueJobPackage: " + ex.ToString());
                }
                if (thinkResult.IsValid)
                {
                    return(thinkResult);
                }
            }
            return(ThinkResult.NoJob);
        }
コード例 #2
0
 public static void AssignSingleKey(ThinkNode node, int startHash)
 {
     Rand.PushState();
     Rand.Seed = startHash;
     node.SetUniqueSaveKey(ThinkTreeKeyAssigner.NextUnusedKey());
     Rand.PopState();
 }
コード例 #3
0
 public static void Start(ThinkNode __instance, MethodBase __originalMethod, ref Profiler __state)
 {
     if (p.isActive)
     {
         __state = p.Start(__originalMethod.DeclaringType.Name, __originalMethod);
     }
 }
コード例 #4
0
        public bool TryGetThinkNodeWithSaveKey(int key, out ThinkNode outNode)
        {
            outNode = null;
            bool result;

            if (key == -1)
            {
                result = false;
            }
            else if (key == this.thinkRoot.UniqueSaveKey)
            {
                outNode = this.thinkRoot;
                result  = true;
            }
            else
            {
                foreach (ThinkNode thinkNode in this.thinkRoot.ChildrenRecursive)
                {
                    if (thinkNode.UniqueSaveKey == key)
                    {
                        outNode = thinkNode;
                        return(true);
                    }
                }
                result = false;
            }
            return(result);
        }
コード例 #5
0
 public static void AssignKeys(ThinkNode rootNode, int startHash)
 {
     Rand.PushState(startHash);
     foreach (ThinkNode item in rootNode.ThisAndChildrenRecursive)
     {
         item.SetUniqueSaveKey(NextUnusedKeyFor(item));
     }
     Rand.PopState();
 }
コード例 #6
0
 public static void AssignKeys(ThinkNode rootNode, int startHash)
 {
     Rand.PushState();
     Rand.Seed = startHash;
     foreach (ThinkNode item in rootNode.ThisAndChildrenRecursive)
     {
         item.SetUniqueSaveKey(ThinkTreeKeyAssigner.NextUnusedKey());
     }
     Rand.PopState();
 }
コード例 #7
0
 static IEnumerable <ThinkNode> GetChildren([NotNull] ThinkNode node)
 {
     if (node is ThinkNode_SubtreesByTag)
     {
         return(Enumerable.Empty <ThinkNode>());
     }
     if (node is ThinkNode_Subtree)
     {
         return(Enumerable.Empty <ThinkNode>());
     }
     return(node.subNodes.MakeSafe());
 }
コード例 #8
0
ファイル: ThinkTreeDef.cs プロジェクト: KraigXu/GameProject
 private void ResolveParentNodes(ThinkNode node)
 {
     for (int i = 0; i < node.subNodes.Count; i++)
     {
         if (node.subNodes[i].parent != null)
         {
             Log.Warning("Think node " + node.subNodes[i] + " from think tree " + defName + " already has a parent node (" + node.subNodes[i].parent + "). This means that it's referenced by more than one think tree (should have been copied instead).");
             continue;
         }
         node.subNodes[i].parent = node;
         ResolveParentNodes(node.subNodes[i]);
     }
 }
コード例 #9
0
 public static void                  ReplaceThinkNodeClass(this ThinkNode node, Type oldClass, Type newClass)
 {
     if (node.subNodes.NullOrEmpty())
     {
         return;
     }
     // Do replacement in this node
     node.ReplaceSubNodeClass(oldClass, newClass);
     // Now check nodes subnodes
     foreach (var subNode in node.subNodes)
     {
         subNode.ReplaceThinkNodeClass(oldClass, newClass);
     }
 }
コード例 #10
0
        static IEnumerable <ThinkNode> GetChildren([NotNull] ThinkNode node)
        {
            if (node is ThinkNode_SubtreesByTag sNode)
            {
                var allDefs = DefDatabase <ThinkTreeDef> .AllDefs.Where(d => d.insertTag == sNode.insertTag && d.thinkRoot != null);

                return(allDefs.Select(d => d.thinkRoot));
            }
            if (node is ThinkNode_Subtree)
            {
                return(Enumerable.Empty <ThinkNode>());
            }
            return(node.subNodes.MakeSafe());
        }
コード例 #11
0
 private void ResolveParentNodes(ThinkNode node)
 {
     for (int i = 0; i < node.subNodes.Count; i++)
     {
         if (node.subNodes[i].parent != null)
         {
             Log.Warning(string.Concat("Think node ", node.subNodes[i], " from think tree ", defName, " already has a parent node (", node.subNodes[i].parent, "). This means that it's referenced by more than one think tree (should have been copied instead)."));
         }
         else
         {
             node.subNodes[i].parent = node;
             ResolveParentNodes(node.subNodes[i]);
         }
     }
 }
コード例 #12
0
        static string GetNodeLabel([NotNull] ThinkNode node)
        {
            var tLabel = node.GetType().Name;

            if (node is ThinkNode_SubtreesByTag streeTag)
            {
                return(tLabel + "-" + streeTag.insertTag);
            }

            if (node is ThinkNode_Subtree sTree)
            {
                var fInfo = typeof(ThinkNode_Subtree).GetField("treeDef", BindingFlags.Instance | BindingFlags.NonPublic);
                var def   = (Def)fInfo.GetValue(sTree);

                return(tLabel + "-" + def.defName);
            }

            return(tLabel);
        }
        private ThinkNode                   HighestPriorityNode(Pawn pawn)
        {
            if (matchedTrees.NullOrEmpty())
            {
                return(null);
            }
            var       priority = 0.0f;
            ThinkNode node     = null;

            for (var index = 0; index < matchedTrees.Count; ++index)
            {
                var nodePriority = matchedTrees[index].thinkRoot.GetPriority(pawn);
                if (nodePriority > priority)
                {
                    priority = nodePriority;
                    node     = matchedTrees[index].thinkRoot;
                }
            }
            return(node);
        }
コード例 #14
0
 public static void                  ReplaceSubNodeClass(this ThinkNode node, Type oldClass, Type newClass)
 {
     if (node.subNodes.NullOrEmpty())
     {
         return;
     }
     for (int i = node.subNodes.Count - 1; i >= 0; --i)
     {
         var subNode = node.subNodes[i];
         if (subNode.GetType() == oldClass)
         {
             // Remove old node
             node.subNodes.Remove(subNode);
             // Create new node
             subNode = (ThinkNode)Activator.CreateInstance(newClass);
             // Place new node in same place as old node
             node.subNodes.Insert(i, subNode);
         }
     }
 }
コード例 #15
0
            static bool Prefix(ref Pawn_JobTracker_Crutch __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue)
            {
                if (__instance == null || __instance._pawn == null || newJob == null || newJob.def == null)
                {
                    return(true);
                }

                if (Settings.fun_police && __instance._pawn.needs.joy != null && __instance._pawn.needs.joy.CurLevel < 0.8f)
                {
                    CompJoyToppedOff c = __instance._pawn.TryGetComp <CompJoyToppedOff>();
                    if (c != null)
                    {
                        c.JoyToppedOff = false;
                    }
                }

                if (!Settings.clean_before_work && !Settings.hauling_over_bills)
                {
                    return(true);
                }

                if (!newJob.def.allowOpportunisticPrefix)
                {
                    return(true);
                }

                Job job = null;

                if (newJob.def == JobDefOf.DoBill)
                {
                    if (Settings.hauling_over_bills)
                    {
                        job = Hauling_Opportunity(newJob, __instance._pawn);
                    }
                }
                else if (!newJob.playerForced && newJob.targetA != null && newJob.targetA.Cell != null)
                {
                    IntVec3 cell = newJob.targetA.Cell;

                    if (!cell.IsValid || cell.IsForbidden(__instance._pawn) || __instance._pawn.Downed)
                    {
                        return(true);
                    }

                    if (Settings.clean_before_work && (newJob.targetA.Thing != null && newJob.targetA.Thing.GetType().IsSubclassOf(typeof(Building)) || newJob.def.joyKind != null))
                    {
                        job = Cleaning_Opportunity(newJob, cell, __instance._pawn, 20);
                    }
                }

                if (job != null)
                {
                    if (Settings.add_to_que)
                    {
                        __instance.jobQueue.EnqueueFirst(newJob);
                    }
                    __instance.jobQueue.EnqueueFirst(job);
                    __instance.curJob    = null;
                    __instance.curDriver = null;
                    return(false);
                }
                return(true);
            }
コード例 #16
0
 public static void AssignSingleKey(ThinkNode node, int startHash)
 {
     Rand.PushState(startHash);
     node.SetUniqueSaveKey(NextUnusedKeyFor(node));
     Rand.PopState();
 }
コード例 #17
0
ファイル: ThinkNode_Subtree.cs プロジェクト: potsh/RimWorld
 protected override void ResolveSubnodes()
 {
     subtreeNode = treeDef.thinkRoot.DeepCopy();
     subNodes.Add(subtreeNode);
 }
コード例 #18
0
ファイル: ModInit.cs プロジェクト: achan1989/Dehydration
        private void InjectDehydrationThink(ThinkNode colonistTree)
        {
            bool failed = true;
            var dehydrationThink = DefDatabase<ThinkTreeDef>.GetNamed(defnameGetWater);

            if (dehydrationThink != null)
            {
                // Inject into the colonist tree, more important than food.
                int starvingIndex = colonistTree.subNodes.FindIndex(node =>
                    node is ThinkNode_ConditionalStarving);
                if (starvingIndex != -1)
                {
                    colonistTree.subNodes.Insert(starvingIndex, dehydrationThink.thinkRoot);
                    Log.Message(string.Format("Dehydration injected {0}", defnameGetWater));
                    failed = false;
                }
            }

            if (failed)
            {
                Log.Error(string.Format("Dehydration can't inject {0}", defnameGetWater));
            }
        }
コード例 #19
0
ファイル: ModInit.cs プロジェクト: achan1989/Dehydration
        private void InjectExitMapOnThirsty(ThinkNode parent)
        {
            bool failed = true;
            var exitThink = DefDatabase<ThinkTreeDef>.GetNamed(defnameExitMapThirsty);

            if (exitThink != null)
            {
                parent.subNodes.Insert(0, new ThinkNode_Subtree() {treeDef = exitThink});
                Log.Message(string.Format("Dehydration injected {0}", defnameExitMapThirsty));
                failed = false;
            }
            else { Log.Error("No exit map think."); }

            if (failed)
            {
                Log.Error(string.Format("Dehydration can't inject {0}", defnameExitMapThirsty));
            }
        }
コード例 #20
0
ファイル: ModInit.cs プロジェクト: achan1989/Dehydration
        private void InjectPackWaterThink(ThinkNode colonistTree)
        {
            bool failed = true;
            var packThink = DefDatabase<ThinkTreeDef>.GetNamed(defnamePackWater);

            if (packThink != null)
            {
                int packFoodIndex = colonistTree.subNodes.FindIndex(node =>
                    node is ThinkNode_ConditionalNeedAbove &&
                    node.subNodes.Exists(subnode => subnode is JobGiver_PackFood));
                if (packFoodIndex != -1)
                {
                    colonistTree.subNodes.Insert(packFoodIndex, packThink.thinkRoot);
                    Log.Message(string.Format("Dehydration injected {0}", defnamePackWater));
                    failed = false;
                }
            }

            if (failed)
            {
                Log.Error(string.Format("Dehydration can't inject {0}", defnamePackWater));
            }
        }
コード例 #21
0
ファイル: ModInit.cs プロジェクト: achan1989/Dehydration
        private void InjectGetWaterThink(ThinkNode mainBehaviours)
        {
            bool failed = true;
            var drinkThink = DefDatabase<ThinkTreeDef>.GetNamed(defnameGetWater);

            if (drinkThink != null)
            {
                int foodIndex = mainBehaviours.subNodes.FindIndex(node =>
                    node is JobGiver_GetFood);
                if (foodIndex != -1)
                {
                    mainBehaviours.subNodes.Insert(foodIndex, drinkThink.thinkRoot.subNodes[0]);
                    Log.Message(string.Format("Dehydration injected {0}", defnameGetWater));
                    failed = false;
                }
                else { Log.Error("No foodIndex"); }
            }
            else { Log.Error("No drinkThink"); }

            if (failed)
            {
                Log.Error(string.Format("Dehydration can't inject {0}", defnameGetWater));
            }
        }
コード例 #22
0
 public static bool StartJob(Pawn_JobTracker __instance,
                             Job newJob,
                             JobCondition lastJobEndCondition = JobCondition.None,
                             ThinkNode jobGiver          = null,
                             bool resumeCurJobAfterwards = false,
                             bool cancelBusyStances      = true,
                             ThinkTreeDef thinkTree      = null,
                             JobTag?tag                 = null,
                             bool fromQueue             = false,
                             bool canReturnCurJobToPool = false)
 {
     __instance.startingNewJob = true;
     try
     {
         if (!fromQueue && (!Find.TickManager.Paused || __instance.lastJobGivenAtFrame == RealTime.frameCount))
         {
             ++__instance.jobsGivenThisTick;
             if (Prefs.DevMode)
             {
                 __instance.jobsGivenThisTickTextual = __instance.jobsGivenThisTickTextual + "(" + newJob.ToString() + ") ";
             }
         }
         __instance.lastJobGivenAtFrame = RealTime.frameCount;
         if (__instance.jobsGivenThisTick > 10)
         {
             string givenThisTickTextual = __instance.jobsGivenThisTickTextual;
             __instance.jobsGivenThisTick        = 0;
             __instance.jobsGivenThisTickTextual = "";
             __instance.startingNewJob           = false;
             __instance.pawn.ClearReservationsForJob(newJob);
             JobUtility.TryStartErrorRecoverJob(__instance.pawn, __instance.pawn.ToStringSafe <Pawn>() + " started 10 jobs in one tick. newJob=" + newJob.ToStringSafe <Job>() + " jobGiver=" + jobGiver.ToStringSafe <ThinkNode>() + " jobList=" + givenThisTickTextual);
         }
         else
         {
             if (__instance.debugLog)
             {
                 __instance.DebugLogEvent("StartJob [" + (object)newJob + "] lastJobEndCondition=" + (object)lastJobEndCondition + ", jobGiver=" + (object)jobGiver + ", cancelBusyStances=" + cancelBusyStances.ToString());
             }
             Pawn_StanceTracker stances = __instance.pawn.stances;             //changed
             if (cancelBusyStances && stances != null && stances.FullBodyBusy) //changed
             {
                 stances.CancelBusyStanceHard();
             }
             if (__instance.curJob != null)
             {
                 if (lastJobEndCondition == JobCondition.None)
                 {
                     Log.Warning(__instance.pawn.ToString() + " starting job " + (object)newJob + " from JobGiver " + (object)newJob.jobGiver + " while already having job " + (object)__instance.curJob + " without a specific job end condition.");
                     lastJobEndCondition = JobCondition.InterruptForced;
                 }
                 if (resumeCurJobAfterwards && __instance.curJob.def.suspendable)
                 {
                     __instance.jobQueue.EnqueueFirst(__instance.curJob);
                     if (__instance.debugLog)
                     {
                         __instance.DebugLogEvent("   JobQueue EnqueueFirst curJob: " + (object)__instance.curJob);
                     }
                     __instance.CleanupCurrentJob(lastJobEndCondition, false, cancelBusyStances);
                 }
                 else
                 {
                     __instance.CleanupCurrentJob(lastJobEndCondition, true, cancelBusyStances, canReturnCurJobToPool);
                 }
             }
             if (newJob == null)
             {
                 Log.Warning(__instance.pawn.ToString() + " tried to start doing a null job.");
             }
             else
             {
                 newJob.startTick = Find.TickManager.TicksGame;
                 if (__instance.pawn.Drafted || newJob.playerForced)
                 {
                     newJob.ignoreForbidden    = true;
                     newJob.ignoreDesignations = true;
                 }
                 __instance.curJob = newJob;
                 __instance.curJob.jobGiverThinkTree = thinkTree;
                 __instance.curJob.jobGiver          = jobGiver;
                 JobDriver cDriver = __instance.curJob.MakeDriver(__instance.pawn); //changed
                 __instance.curDriver = cDriver;                                    //changed
                 bool flag = fromQueue;
                 if (__instance.curDriver.TryMakePreToilReservations(!flag))
                 {
                     Job newJob1 = __instance.TryOpportunisticJob(newJob);
                     if (newJob1 != null)
                     {
                         __instance.jobQueue.EnqueueFirst(newJob);
                         __instance.curJob    = (Job)null;
                         __instance.curDriver = (JobDriver)null;
                         __instance.StartJob(newJob1);
                     }
                     else
                     {
                         if (tag.HasValue)
                         {
                             __instance.pawn.mindState.lastJobTag = tag.Value;
                         }
                         cDriver.SetInitialPosture(); //changed
                         cDriver.Notify_Starting();   //changed
                         cDriver.SetupToils();        //changed
                         cDriver.ReadyForNextToil();  //changed
                     }
                 }
                 else if (flag)
                 {
                     __instance.EndCurrentJob(JobCondition.QueuedNoLongerValid);
                 }
                 else
                 {
                     Log.Warning("TryMakePreToilReservations() returned false for a non-queued job right after StartJob(). This should have been checked before. curJob=" + __instance.curJob.ToStringSafe <Job>());
                     __instance.EndCurrentJob(JobCondition.Errored);
                 }
             }
         }
     }
     finally
     {
         __instance.startingNewJob = false;
     }
     return(false);
 }
コード例 #23
0
            static bool Prefix(ref Pawn_JobTracker_Crutch __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue)
            {
                try
                {
                    if (__instance == null || __instance._pawn == null || !__instance._pawn.IsColonistPlayerControlled || newJob == null || newJob.def == null)
                    {
                        return(true);
                    }

                    if (Settings.fun_police && __instance._pawn.needs.joy != null && __instance._pawn.needs.joy.CurLevel < 0.8f)
                    {
                        CompJoyToppedOff c = __instance._pawn.TryGetComp <CompJoyToppedOff>();
                        if (c != null)
                        {
                            c.JoyToppedOff = false;
                        }
                    }

                    if (!Settings.clean_before_work && !Settings.hauling_over_bills)
                    {
                        return(true);
                    }

                    if (!newJob.def.allowOpportunisticPrefix)
                    {
                        return(true);
                    }

                    Job job = null;

                    if (newJob.def == JobDefOf.DoBill)
                    {
                        if (Settings.hauling_over_bills)
                        {
                            job = Hauling_Opportunity(newJob, __instance._pawn);
                        }
                    }
                    else if (!newJob.playerForced && newJob.targetA != null && newJob.targetA.Cell != null)
                    {
                        IntVec3 cell = newJob.targetA.Cell;

                        if (!cell.IsValid || cell.IsForbidden(__instance._pawn) || __instance._pawn.Downed)
                        {
                            return(true);
                        }

                        if (Settings.clean_before_work && (newJob.targetA.Thing != null &&
                                                           newJob.targetA.Thing.GetType().IsSubclassOf(typeof(Building)) && newJob.def != JobDefOf.PlaceNoCostFrame && newJob.def != JobDefOf.FinishFrame ||
                                                           newJob.def.joyKind != null) &&
                            !HealthAIUtility.ShouldBeTendedNowByPlayer(__instance._pawn))
                        {
                            job = Cleaning_Opportunity(newJob, cell, __instance._pawn, Settings.op_clean_num);
                        }
                    }

                    //Log.Message($"pawn={__instance._pawn},job={newJob},enque={job}, limit = {Settings.op_clean_num}");
                    if (job != null)
                    {
                        if (Settings.add_to_que)
                        {
                            newJob.playerForced = true;
                            __instance.jobQueue.EnqueueFirst(newJob);
                        }
                        __instance.jobQueue.EnqueueFirst(job);
                        //__instance.curJob = null;
                        //__instance.curDriver = null;
                        return(false);
                    }
                }
                catch (Exception e)
                {
                    Log.Error($"CommonSense: opportunistic task skipped due to error ({e.Message})");
                }
                return(true);
            }