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!"); }
private void Start() { agent = GetComponent <NavMeshAgent>(); currentSatisfactionStatus = SatisfactionStatus.IDLE; currentMovementStatus = MovementStatus.IDLE; currentSatisfier = null; EntertainmentSatisfaction = 100f; FoodSatisfaction = 100f; BathroomSatisfaction = 100f; }
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); }
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; } }
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); }
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; }
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); }
static bool IsSatisfied(SatisfactionStatus status) => (status & SatisfactionStatus.Satisfied) == SatisfactionStatus.Satisfied;