예제 #1
0
        public void MappingFinished(Entity target, bool wasInterrupted)
        {
            previousPlans     = currentPlans;
            previousPlanIndex = CurrentPlanIndex;

            if (wasInterrupted)
            {
                Debug.Log(agent.name + ":" + CurrentMapping.ToString() + " was interrupted and not completed");

                currentPlans.statuses[CurrentPlanIndex] = Plans.Status.Interrupted;
                PreviousMapping = CurrentMapping;
                CurrentMapping  = null;
                currentPlans    = null;

                isActing = false;
                if (PreviousMapping.mappingType.actionType.noWaitOnInterrupt)
                {
                    agent.RunEarly();
                }
            }
            else if (CurrentMapping != null && CurrentPlanIndex != -1 && currentPlans.rootMappings.Count > CurrentPlanIndex)
            {
                Debug.Log(agent.name + ": " + CurrentMapping.ToString() + " on root mapping " + currentPlans.rootMappings[CurrentPlanIndex] + " has completed.");

                deciderType.MappingFinished(agent, CurrentMapping);

                // Move to the next mapping in the mapping tree
                PreviousMapping = CurrentMapping;
                CurrentMapping  = CurrentMapping.NextMapping();

                if (CurrentMapping == null)
                {
                    Debug.Log(agent.name + ": Plan (" + currentPlans.rootMappings[CurrentPlanIndex] + ") Finished - Took " + (Time.time - PlanStartTime) + " seconds.");

                    // Plan has completed
                    currentPlans.statuses[CurrentPlanIndex] = Plans.Status.Finished;
                    currentPlans = null;

                    isActing = false;
                    if (PreviousMapping.mappingType.actionType.noWaitOnFinishNoNextMapping)
                    {
                        agent.RunEarly();
                    }
                }
                else if (PreviousMapping.mappingType.actionType.noWaitOnFinishHasNextMapping)
                {
                    Debug.Log("*********** RunEarly **************");
                    isActing = false;
                    agent.RunEarly();
                }
                else
                {
                    isActing = false;
                }
            }
            else
            {
                isActing = false;
            }
        }
예제 #2
0
        // What should agent do when they have no valid plans?
        public virtual Dictionary <DriveType, Plans> DefaultPlans(Agent agent, out DriveType currentDriveType, out Mapping newMapping)
        {
            if (agent.noneDriveType != null && agent.noPlansMappingType != null)
            {
                currentDriveType = agent.noneDriveType;
                newMapping       = new Mapping(agent.noPlansMappingType)
                {
                    isComplete = true
                };
                Plans plans = new Plans(currentDriveType, newMapping)
                {
                    statuses = new List <Plans.Status>()
                    {
                        Plans.Status.Complete
                    }
                };
                return(new Dictionary <DriveType, Plans>()
                {
                    { currentDriveType, plans }
                });
            }

            currentDriveType = null;
            newMapping       = null;
            return(null);
        }
예제 #3
0
        // Returns the rootMapping that has the highest utility out of all rootMappings that are complete (all leaves have all inputs)
        // Use force to allow plans with negative or zero drive rate changes
        protected virtual Mapping GetBestPlan(Agent agent, Plans plans, out float bestUtility, bool force = true)
        {
            // TODO: Move this to top of DeciderType - be nice to be able to set this in the TAI Settings
            bool verboseLogging = false;

            Mapping best = null;

            bestUtility = -1000;
            foreach (Mapping rootMapping in plans.GetCompletePlans())
            {
                if (verboseLogging)
                {
                    Debug.Log(agent.name + ": *** GetBestPlan checking " + rootMapping.mappingType.name + " ***");
                }

                // Returns driveAmount, timeEst, sideEffectsUtility in the float array (only go through tree once)
                float[] planInfo = new float[3];
                rootMapping.CalcUtilityInfoForTree(agent, plans.driveType, planInfo);

                float driveAmount        = planInfo[0];
                float timeEst            = planInfo[1];
                float sideEffectsUtility = planInfo[2];
                //float driveAmount = rootMapping.CalcDriveChangeForTree(agent, plans.driveType);
                //float timeEst = rootMapping.CalcTimeToCompleteForTree(agent);
                //float sideEffectsUtility = rootMapping.CalcSideEffectsUtilityForTree(agent, plans.driveType);

                float utility = agent.utilityFunction.Evaluate(agent, rootMapping, plans.driveType, driveAmount, timeEst, sideEffectsUtility);

                // TODO: For logging - Maybe move this into UFT?  Should this even be in Plans?
                int rootMappingIndex = plans.rootMappings.IndexOf(rootMapping);
                plans.driveAmountEstimates[rootMappingIndex] = driveAmount;
                plans.timeEstimates[rootMappingIndex]        = timeEst;
                plans.sideEffectsUtility[rootMappingIndex]   = sideEffectsUtility;
                plans.utility[rootMappingIndex] = utility;

                if (!force && driveAmount >= 0)
                {
                    Debug.Log("DriveType change is greater than or equal to zero (" + driveAmount + ") - skipping it.");
                }
                else
                {
                    if (utility > bestUtility)
                    {
                        best        = rootMapping;
                        bestUtility = utility;
                    }
                }

                if (verboseLogging)
                {
                    Debug.Log("Utility Score = " + utility);
                    Debug.Log("Side Effects Utility = " + plans.sideEffectsUtility[rootMappingIndex]);
                    Debug.Log("Time To Complete = " + plans.timeEstimates[rootMappingIndex]);
                    Debug.Log("DriveType Reduction = " + plans.driveAmountEstimates[rootMappingIndex]);
                    Debug.Log(agent.name + ": *** GetBestPlan done checking " + rootMapping.mappingType.name + " ***");
                }
            }
            return(best);
        }
예제 #4
0
        public virtual PlansLog FindPlansLogFromPlans(Agent agent, Plans plans)
        {
            int num = agentsPlansLogs[agent].Count;

            if (num == 0)
            {
                return(null);
            }

            return(agentsPlansLogs[agent].Find(x => x.allPlans.Values.Contains(plans)));
        }
예제 #5
0
        private void StartPlan(DriveType selectedDriveType, int newPlanIndex, float newPlanUtility, Mapping newMapping)
        {
            // Starting new plan - either because there was no plan or it decided to change plans between actions
            CurrentDriveType   = selectedDriveType;
            currentPlans       = AllCurrentPlans[selectedDriveType];
            PreviousMapping    = CurrentMapping;
            CurrentMapping     = newMapping;
            CurrentPlanIndex   = newPlanIndex;
            currentPlanUtility = newPlanUtility;
            PlanStartTime      = Time.time;

            currentPlans.statuses[CurrentPlanIndex] = Plans.Status.Running;

            // This is for the drive modifyBonus for continuing to reduce the same drive
            PreviousDriveType = CurrentDriveType;
        }
예제 #6
0
        public virtual bool GetPlans(Agent agent, Plans previousPlans, int previousPlansIndex, bool previouslyInterrupted,
                                     out DriveType currentDriveType, out Dictionary <DriveType, float> currentDriveTypesRanked,
                                     out Dictionary <DriveType, Plans> allPlans)
        {
            currentDriveType = null;
            Plans currentPlans = null;

            // Find mapping for highest priority drive
            currentDriveTypesRanked = RankDrives(agent.ActiveDrives());

            allPlans = new Dictionary <DriveType, Plans>();
            foreach (DriveType driveType in currentDriveTypesRanked.Keys)
            {
                currentPlans = plannerTypes[0].CreatePlansForDriveType(agent, driveType, false);
                if (currentPlans == null)
                {
                    return(false);
                }

                allPlans.Add(driveType, currentPlans);

                //Debug.Log(agent.name + ": GetPlans for " + driveType.name + " found " + currentPlans.rootMappings.Count + " plans.");

                // If there is at least one complete plan we quit early
                // TODO: Improve this - planner should mark the Plans statuses
                // TODO: Add a minimum utility threshold so it doesn't quit and go with a bad plan
                List <Mapping> excludeRootMappings = null;
                if (previouslyInterrupted && previousPlans != null)
                {
                    excludeRootMappings = new List <Mapping>()
                    {
                        previousPlans.rootMappings[previousPlansIndex]
                    }
                }
                ;
                if (currentPlans.GetCompletePlans(excludeRootMappings).Count > 0)
                {
                    //Debug.Log(agent.name + ": GetPlans for " + driveType.name + " found a completed plan.");
                    currentDriveType = driveType;
                    return(true);
                }
            }
            return(false);
        }
예제 #7
0
        public override bool GetPlans(Agent agent, Plans previousPlans, int previousPlansIndex, bool previouslyInterrupted,
                                      out DriveType currentDriveType, out Dictionary <DriveType, float> currentDriveTypesRanked,
                                      out Dictionary <DriveType, Plans> allPlans)
        {
            currentDriveType        = defaultDriveType;
            currentDriveTypesRanked = new Dictionary <DriveType, float>()
            {
                { defaultDriveType, 1f }
            };
            allPlans = new Dictionary <DriveType, Plans>();
            Plans currentPlans = null;

            currentPlans = plannerTypes[0].CreatePlansForDriveType(agent, defaultDriveType, false);
            if (currentPlans == null)
            {
                return(false);
            }

            allPlans.Add(defaultDriveType, currentPlans);

            //Debug.Log(agent.name + ": GetPlans for " + driveType.name + " found " + currentPlans.rootMappings.Count + " plans.");

            List <Mapping> excludeRootMappings = null;

            if (previouslyInterrupted && previousPlans != null)
            {
                excludeRootMappings = new List <Mapping>()
                {
                    previousPlans.rootMappings[previousPlansIndex]
                }
            }
            ;

            // TODO: Figure out the statuses mess - when should they be set?
            if (currentPlans.GetCompletePlans(excludeRootMappings).Count > 0)
            {
                return(true);
            }

            return(false);
        }
예제 #8
0
        public Decider(Agent agent, DeciderType deciderType)
        {
            currentPlans          = null;
            previousPlans         = null;
            CurrentPlanIndex      = -1;
            CurrentMapping        = null;
            PreviousMapping       = null;
            CurrentDriveType      = null;
            isActing              = false;
            previouslyInterrupted = false;
            lastReplanTime        = 0;
            currentPlanUtility    = -1000;
            animationEventCount   = 0;

            this.agent       = agent;
            this.deciderType = deciderType;
            if (deciderType != null)
            {
                deciderType.Setup(agent);
            }
        }
예제 #9
0
        // Returns the rootMapping that has the highest utility out of all rootMappings that are complete (all leaves have all inputs)
        // Use force to allow plans with negative or zero drive rate changes
        protected override Mapping GetBestPlan(Agent agent, Plans plans, out float bestUtility, bool force = true)
        {
            // TODO: Move this to top of DeciderType - be nice to be able to set this in the TAI Settings
            bool verboseLogging = true;

            Mapping best = null;

            bestUtility = -1000;
            foreach (Mapping rootMapping in plans.rootMappings)
            {
                float utility = agent.utilityFunction.Evaluate(agent, rootMapping, plans.driveType, 0f, 0f, 0f);

                // TODO: For logging - Maybe move this into UFT?  Should this even be in Plans?
                int rootMappingIndex = plans.rootMappings.IndexOf(rootMapping);
                plans.driveAmountEstimates[rootMappingIndex] = 0f;
                plans.timeEstimates[rootMappingIndex]        = 0f;
                plans.sideEffectsUtility[rootMappingIndex]   = 0f;
                plans.utility[rootMappingIndex] = utility;

                if (!force && utility <= 0)
                {
                    Debug.Log("UtilityAIPT.GetBestPlan for " + rootMapping.mappingType.name + " - Utility is <= 0 (" + utility + ") - skipping it.");
                }
                else
                {
                    if (utility > bestUtility)
                    {
                        best        = rootMapping;
                        bestUtility = utility;
                    }
                    if (verboseLogging)
                    {
                        Debug.Log("UtilityAIPT.GetBestPlan for " + rootMapping.mappingType.name + " - Utility Score = " + utility);
                    }
                }
            }
            return(best);
        }
예제 #10
0
        // TODO: Are agent.isAlive checks needed?
        public void Run()
        {
            // Everytime decider runs it can do nothing, check to see if it should switch plans, or if doing nothing start a plan
            float lastPlannedAt = lastReplanTime;

            if (isActing && !previouslyInterrupted && deciderType.ShouldInterrupt(agent, CurrentMapping, CurrentDriveType, currentPlanUtility,
                                                                                  lastReplanTime, out lastPlannedAt))
            {
                // End Action and then plan next time - this allows action to end before starting new plan
                InterruptMapping(false);

                // This will allow decider to not choose the same Mapping next time around
                previouslyInterrupted = true;
                return;
            }
            else if (!isActing && deciderType.ShouldPlan(CurrentMapping))
            {
                lastPlannedAt = Time.time;
                System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
                bool foundCompletedPlan            = deciderType.GetPlans(agent, previousPlans, previousPlanIndex, previouslyInterrupted,
                                                                          out DriveType selectedDriveType, out currentDriveTypesRanked,
                                                                          out Dictionary <DriveType, Plans> plans);
                AllCurrentPlans = plans;
                watch.Stop();
                long timeToPlan = watch.ElapsedMilliseconds;

                // If no current plan see if there is a default (idle) plan
                if (selectedDriveType == null && currentPlans == null)
                {
                    PreviousDriveType = null;

                    // TODO: Put this in to prevent AllCurrentPlans from getting wiped for the Tree Plan Editor
                    if (agent.noPlansMappingType != null)
                    {
                        AllCurrentPlans = deciderType.DefaultPlans(agent, out selectedDriveType, out Mapping newMapping);
                        if (selectedDriveType != null && newMapping != null)
                        {
                            StartPlan(selectedDriveType, 0, 0, newMapping);
                        }
                    }
                }
                else if (selectedDriveType != null)
                {
                    int     newPlanIndex = -1;
                    float   newPlanUtility;
                    Mapping newMapping = null;
                    if (currentPlans != null)
                    {
                        // TODO: Change plans when between Mappings of a plan - this is NOT TESTED - deciderType.ShouldPlan never does this
                        newPlanIndex = deciderType.MaybeChangePlan(agent, CurrentMapping, selectedDriveType, AllCurrentPlans, timeToPlan,
                                                                   out selectedDriveType, out newMapping, out newPlanUtility);
                    }
                    else
                    {
                        newPlanIndex = deciderType.ChooseNewPlan(agent, CurrentMapping, selectedDriveType, AllCurrentPlans, timeToPlan,
                                                                 out selectedDriveType, out newMapping, out newPlanUtility);
                    }

                    if (newPlanIndex != -1)
                    {
                        StartPlan(selectedDriveType, newPlanIndex, newPlanUtility, newMapping);
                    }
                    else
                    {
                        // Unable to find anything to do - do default MappingType
                        PreviousDriveType = null;

                        // TODO: Put this in to prevent AllCurrentPlans from getting wiped for the Tree Plan Editor
                        if (agent.noPlansMappingType != null)
                        {
                            AllCurrentPlans = deciderType.DefaultPlans(agent, out selectedDriveType, out Mapping defaultMapping);
                            if (selectedDriveType != null && defaultMapping != null)
                            {
                                StartPlan(selectedDriveType, 0, 0, defaultMapping);
                            }
                        }
                    }
                }

                previouslyInterrupted = false;
            }

            lastReplanTime = lastPlannedAt;

            if (CurrentMapping != null && !isActing)
            {
                // Don't need to recheck conditions if we just started plan
                if (PlanStartTime == Time.time || deciderType.RecheckInputConditions(agent, CurrentMapping))
                {
                    // See if we want to revaluate the current targets before maybe adding a GoTo and starting the Mapping
                    deciderType.ReevaluateTargets(agent, CurrentMapping);

                    // Adds a GoTo Mapping child if needed
                    CurrentMapping = deciderType.MaybeAddGoToMapping(agent, CurrentMapping);

                    // TODO: This currently always returns true - can it ever return false?
                    isActing = deciderType.StartMapping(agent, CurrentMapping);
                    if (isActing)
                    {
                        mappingStartTime = Time.time;

                        // Will return an empty Dictionary if there are no Repeating and no AfterGameMinutesOCs
                        lastUpdateTimes     = CurrentMapping.mappingType.InitLastUpdateTimes();
                        animationEventCount = 0;
                    }
                    else
                    {
                        Debug.Log(agent.name + ": deciderType.StartAction - Failed: " + CurrentMapping);
                    }
                }
                else
                {
                    // Recheck IC failed
                    currentPlans.SetSelectedPlanStatus(Plans.Status.Interrupted, CurrentPlanIndex);
                    currentPlans    = null;
                    PreviousMapping = CurrentMapping;
                    CurrentMapping  = null;
                }
            }
        }
예제 #11
0
파일: NoneHT.cs 프로젝트: ming81/TotalAI
 public override PlansLog FindPlansLogFromPlans(Agent agent, Plans plans)
 {
     return(null);
 }
예제 #12
0
 // This allows plannerTypes to save chosen Mapping when Decider Interrupts
 public abstract void NotifyOfInterrupt(Agent agent, Plans plans, Mapping rootMapping);