예제 #1
0
        public async Task <SatisfactionStatus> EvaluateCondition(Condition condition)
        {
            IEnumerable <string> requiredFactIds = condition.GetRequiredFactIds();

            List <Task <Fact> > requestFactTasks = requiredFactIds
                                                   .Where(fact => !mFactContainer.IsCached(fact, EngineClock.Default.Now()))
                                                   .Select(fact => mFactSourceContainer.RequestNonGenericFact(fact))
                                                   .ToList();

            await Task.WhenAll(requestFactTasks);

            List <Fact> generatedFacts = requestFactTasks
                                         .Select(task => task.Result)
                                         .ToList();

            mFactContainer.AddFactRange(requestFactTasks.Select(t => t.Result));

            SatisfactionStatus result = SatisfactionStatus.Unknown;

            using (EvaluationContext ctx = condition.StartEvaluation(mFactContainer))
            {
                result = await ctx.Evaluate();
            }

            if (result != SatisfactionStatus.Unknown)
            {
                return(result);
            }

            throw new Exception(
                      $"Got a SatisfactionStatus.Unknown after finishing evaluation!");
        }
예제 #2
0
    private void Start()
    {
        agent = GetComponent <NavMeshAgent>();
        currentSatisfactionStatus = SatisfactionStatus.IDLE;
        currentMovementStatus     = MovementStatus.IDLE;
        currentSatisfier          = null;

        EntertainmentSatisfaction = 100f;
        FoodSatisfaction          = 100f;
        BathroomSatisfaction      = 100f;
    }
예제 #3
0
        public override async Task <SatisfactionStatus> GetSatisfactionStatus()
        {
            SatisfactionStatus status = SatisfactionStatus.Unknown;

            foreach (Condition condition in mChildrenConditions)
            {
                status |= await condition.GetSatisfactionStatus();

                if ((status & SatisfactionStatus.Failed) == SatisfactionStatus.Failed)
                {
                    return(SatisfactionStatus.Failed);
                }
            }

            return(status);
        }
예제 #4
0
    void DecideStatus()
    {
        if (currentMovementStatus == MovementStatus.CANT_REACH)
        {
            // retry movement
            Need(currentSatisfactionStatus);
        }

        // TODO: Check other status?
        switch (currentSatisfactionStatus)
        {
        case SatisfactionStatus.IDLE:
            currentSatisfactionStatus = SatisfactionStatus.WORK;
            Need(SatisfactionStatus.WORK);
            break;
        }
    }
예제 #5
0
    private void Need(SatisfactionStatus need)
    {
        // Are we moving towards something? (AKA: Are we trying to satisfy a need?)
        if (currentMovementStatus == MovementStatus.MOVING || currentMovementStatus == MovementStatus.SATISFYING)
        {
            // Don't update anything.
            return;
        }

        // Set need, and move to the nearest satisfier
        currentSatisfactionStatus = need;

        // Do we need to work? if so, go to our station, no need to find nearest one.
        if (currentSatisfactionStatus == SatisfactionStatus.WORK)
        {
            if (Workstation == null)
            {
                // We didn't set workstation or it was removed...
                Debug.LogError("Workstation not found");
                currentMovementStatus = MovementStatus.CANT_REACH;
                return;
            }
            currentMovementStatus = MovementStatus.MOVING;
            currentSatisfier      = Workstation;
            MoveTo(Workstation.satisfierStandPlace.position);
            return;
        }

        // Find the nearest need satisfaction and go there
        NeedSatisfier satisfier = SatisfierLocationDictionary.Instance.GetNearestSatisfier(need, transform.position);

        if (satisfier == null)
        {
            // No satisfier available
            currentMovementStatus = MovementStatus.CANT_REACH;
            Debug.LogError("No Satisfier Available");
            FindObjectOfType <UIUpdater>().ShowHint("An employee can't reach location for " + need.ToString());
            Anger += 15;
            return;
        }

        currentMovementStatus = MovementStatus.MOVING;
        currentSatisfier      = satisfier;
        MoveTo(satisfier.waitingQueue.position);
    }
예제 #6
0
    public void SatisfiedNeed(SatisfactionStatus need)
    {
        switch (need)
        {
        case SatisfactionStatus.WORK:
            GameManager.Instance.UpdateProgress(5f);
            break;

        case SatisfactionStatus.ENTERTAINMENT:
            EntertainmentSatisfaction = 100;
            break;

        case SatisfactionStatus.COFFEE:
            FoodSatisfaction = 100;
            break;

        case SatisfactionStatus.RESTROOM:
            BathroomSatisfaction = 100;
            break;
        }
        currentSatisfactionStatus = SatisfactionStatus.IDLE;
        currentMovementStatus     = MovementStatus.IDLE;
    }
예제 #7
0
        public async Task <RuleEvaluationResult> EvaluateRule(IRule rule)
        {
            SatisfactionStatus ruleConditionSatisfaction =
                await EvaluateCondition(rule.Condition);

            if (!IsSatisfied(ruleConditionSatisfaction))
            {
                return(RuleEvaluationResult.NotEvaluated);
            }

            Type       ruleType = rule.GetType();
            MethodInfo notAsyncFireMethodInfo = ruleType.GetMethod("Fire");
            MethodInfo asyncFireMethodInfo    = ruleType.GetMethod("FireAsync");

            if (notAsyncFireMethodInfo == null && asyncFireMethodInfo == null)
            {
                throw new Exception(
                          $"{ruleType} does not implement a 'Fire' or 'FireAsync' method!");
            }

            if (notAsyncFireMethodInfo != null && asyncFireMethodInfo != null)
            {
                throw new Exception(
                          $"{ruleType} cannot implement both 'Fire' and 'FireAsync' at the same time!");
            }

            (MethodInfo fireMethodInfo, bool bIsAsync) =
                notAsyncFireMethodInfo == null
                    ? (asyncFireMethodInfo, true)
                    : (notAsyncFireMethodInfo, false);

            Type returnType = bIsAsync
                ? typeof(Task <RuleEvaluationResult>)
                : typeof(RuleEvaluationResult);

            if (!fireMethodInfo.ReturnType.Equals(returnType))
            {
                throw new Exception(
                          $"Method '{fireMethodInfo}' should return '{returnType}'!");
            }

            ParameterInfo[] fireMethodParameters =
                notAsyncFireMethodInfo.GetParameters();

            Type          factParamAttrType = typeof(FactParam);
            List <string> requiredFactIds   = fireMethodParameters
                                              .Select(p => p.GetCustomAttribute(factParamAttrType) as FactParam)
                                              .Select(attr => attr.FactId)
                                              .ToList();

            List <Task <Fact> > requestFactTasks = requiredFactIds
                                                   .Where(fact => !mFactContainer.IsCached(fact, EngineClock.Default.Now()))
                                                   .Select(fact => mFactSourceContainer.RequestNonGenericFact(fact))
                                                   .ToList();

            await Task.WhenAll(requestFactTasks);

            mFactContainer.AddFactRange(requestFactTasks.Select(t => t.Result));

            List <Fact> factsForInvocation = requiredFactIds
                                             .Select(fact => mFactContainer.PullFact(fact))
                                             .ToList();

            object[] objectsForInvocation = factsForInvocation
                                            .Select(f => f.GetType().GetProperty("Data").GetValue(f))
                                            .ToArray();

            if (bIsAsync)
            {
                Task <RuleEvaluationResult> resultTask =
                    fireMethodInfo.Invoke(rule, objectsForInvocation) as Task <RuleEvaluationResult>;
                return(await resultTask);
            }

            RuleEvaluationResult?result =
                fireMethodInfo.Invoke(rule, objectsForInvocation) as RuleEvaluationResult?;

            return(result.Value);
        }
예제 #8
0
 static bool IsSatisfied(SatisfactionStatus status)
 => (status & SatisfactionStatus.Satisfied) == SatisfactionStatus.Satisfied;