コード例 #1
0
        public static WorkTarget Closest(IEnumerable <WorkTarget> targets, Pawn pawn, float maxSearchDistance = 9999f)
        {
            WorkTarget best         = null;
            float      bestDistance = float.MaxValue;
            float      bestPriority = float.MinValue;
            float      maxDistance  = maxSearchDistance * maxSearchDistance;

            foreach (var target in targets)
            {
                var distance    = target.Distance;
                var priority    = target.Priority;
                var prioritized = target.WorkGiver.Prioritized;
                if (distance < maxDistance &&
                    // higher priority
                    (prioritized && priority > bestPriority ||
                     // not prioritized or same priority, and smaller distance
                     (!prioritized || priority == bestPriority) && distance < bestDistance) &&
                    target.Valid)
                {
                    best         = target;
                    bestDistance = distance;
                    bestPriority = priority;
                }
            }

            return(best);
        }
コード例 #2
0
        private ThinkResult GetJobFromBatch(Pawn pawn, List <WorkGiver_Scanner> batch, bool debug = false)
        {
            var priorityBatches = batch
                                  .SelectMany(wg => PotentialTargets(wg, pawn))
                                  .GroupBy(wt => new
            {
                spatialPriority = wt.SpatialPriority,
                workGiver       = wt.WorkGiver.def,
            })
                                  .OrderByDescending(g => g.Key.spatialPriority)
                                  .ThenByDescending(g => g.Key.workGiver.priorityInType);

            if (debug)
            {
                Debug.Log("batch: " + batch.Select(wg => wg.def.defName).StringJoin(", "));
            }

            // step 4; iterate over priorities until a job is found
            foreach (var priorityBatch in priorityBatches)
            {
                if (debug)
                {
                    Debug.Log($"priority {priorityBatch.Key.spatialPriority} " +
                              $"| {priorityBatch.Key.workGiver.priorityInType}:\n  " +
                              $"{priorityBatch.Select( wt => $"{wt.WorkGiver.def.defName} :: {wt.LocalTarget} :: {( wt.Valid ? "Valid" : "Invalid" )} :: {( wt.Job != null ? "HasJob" : "NO JOB" )} :: {wt.WorkGiver.GetPriority( pawn, wt.Target )}" ).StringJoin( "\n  " )}");
                }

                var target = WorkTarget.Closest(priorityBatch, pawn);
                if (target != null)
                {
                    // we found a target!
                    pawn.mindState.lastGivenWorkType = target.WorkGiver.def.workType;
                    var job = target.Job;
                    if (job == null)
                    {
                        Log.Error(string.Concat(target.WorkGiver, " provided target ", target.Target,
                                                " but yielded no actual job for pawn ", pawn,
                                                ". The CanGiveJob and JobOnX methods may not be synchronized."));
                    }
                    else
                    {
                        return(new ThinkResult(job, this, target.WorkGiver.def.tagToGive));
                    }
                }
            }
            return(ThinkResult.NoJob);
        }