예제 #1
0
        protected ParseErrorExpression BuildTriggerCondition(TriggerBuilderContext context, InterpreterScope scope, ExpressionBase condition)
        {
            var            builder = new ScriptInterpreterAchievementBuilder();
            ExpressionBase result;

            if (!TriggerBuilderContext.ProcessAchievementConditions(builder, condition, scope, out result))
            {
                switch (condition.Type)
                {
                case ExpressionType.Conditional:
                case ExpressionType.Comparison:
                    // allowed constructs should only report the inner error
                    return((ParseErrorExpression)result);

                default:
                    // non-allowed construct
                    return(new ParseErrorExpression("comparison did not evaluate to a valid comparison", condition)
                    {
                        InnerError = (ParseErrorExpression)result
                    });
                }
            }

            var error = builder.CollapseForSubClause();

            if (error != null)
            {
                return(new ParseErrorExpression(error.Message, condition));
            }

            error = ModifyRequirements(builder);
            if (error != null)
            {
                return(new ParseErrorExpression(error.Message, condition));
            }

            foreach (var requirement in builder.CoreRequirements)
            {
                context.Trigger.Add(requirement);
            }

            return(null);
        }
예제 #2
0
        public override ParseErrorExpression BuildTrigger(TriggerBuilderContext context, InterpreterScope scope, FunctionCallExpression functionCall)
        {
            var error = base.BuildTrigger(context, scope, functionCall);

            if (error != null)
            {
                return(error);
            }

            ExpressionBase result;
            var            format = functionCall.Parameters.ElementAt(2);

            if (!format.ReplaceVariables(scope, out result))
            {
                return((ParseErrorExpression)result);
            }

            StringConstantExpression formatStr = result as StringConstantExpression;

            if (formatStr == null)
            {
                return(new ParseErrorExpression("format is not a string", format));
            }

            if (formatStr.Value != "raw")
            {
                if (scope.GetContext <ValueBuilderContext>() != null)
                {
                    return(new ParseErrorExpression("Value fields only support raw measured values", format));
                }

                if (formatStr.Value == "percent")
                {
                    context.LastRequirement.Type = RequirementType.MeasuredPercent;
                }
                else
                {
                    return(new ParseErrorExpression("Unknown format: " + formatStr.Value, format));
                }
            }

            var when = functionCall.Parameters.ElementAt(1);

            var builder = new ScriptInterpreterAchievementBuilder();

            if (!TriggerBuilderContext.ProcessAchievementConditions(builder, when, scope, out result))
            {
                return new ParseErrorExpression("when did not evaluate to a valid comparison", when)
                       {
                           InnerError = (ParseErrorExpression)result
                       }
            }
            ;

            error = builder.CollapseForSubClause();
            if (error != null)
            {
                return(error);
            }

            if (builder.CoreRequirements.Count != 1 || builder.CoreRequirements.First().Evaluate() != true)
            {
                foreach (var requirement in builder.CoreRequirements)
                {
                    if (requirement.Type == RequirementType.None || requirement.Type == RequirementType.AndNext)
                    {
                        requirement.Type = RequirementType.MeasuredIf;
                    }

                    context.Trigger.Add(requirement);
                }
            }

            return(null);
        }
    }
예제 #3
0
        public override ParseErrorExpression BuildTrigger(TriggerBuilderContext context, InterpreterScope scope, FunctionCallExpression functionCall)
        {
            var until = functionCall.Parameters.ElementAt(1);

            // build the reset next clause
            var            builder = new ScriptInterpreterAchievementBuilder();
            ExpressionBase result;

            if (!TriggerBuilderContext.ProcessAchievementConditions(builder, until, scope, out result))
            {
                return new ParseErrorExpression("until did not evaluate to a valid comparison", until)
                       {
                           InnerError = (ParseErrorExpression)result
                       }
            }
            ;

            var error = builder.CollapseForSubClause();

            if (error != null)
            {
                return(new ParseErrorExpression(error.Message, until));
            }

            var resetNextClause = new List <Requirement>();

            if (builder.CoreRequirements.Count > 0 && builder.CoreRequirements.First().Evaluate() != false)
            {
                foreach (var requirement in builder.CoreRequirements)
                {
                    if (requirement.Type == RequirementType.None)
                    {
                        requirement.Type = RequirementType.AndNext;
                    }

                    resetNextClause.Add(requirement);
                }

                resetNextClause.Last().Type = RequirementType.ResetNextIf;
            }

            // build the when clause
            var whenContext = new TriggerBuilderContext {
                Trigger = new List <Requirement>()
            };

            error = base.BuildTrigger(whenContext, scope, functionCall);
            if (error != null)
            {
                return(error);
            }

            // 'reset next' clause first
            foreach (var resetRequirement in resetNextClause)
            {
                context.Trigger.Add(resetRequirement);
            }

            // then 'when' clause. make sure to insert the 'reset next' clause after each addhits/subhits
            // as they break up the 'reset next' scope.
            foreach (var whenRequirement in whenContext.Trigger)
            {
                context.Trigger.Add(whenRequirement);

                switch (whenRequirement.Type)
                {
                case RequirementType.AddHits:
                case RequirementType.SubHits:
                    foreach (var resetRequirement in resetNextClause)
                    {
                        context.Trigger.Add(resetRequirement);
                    }
                    break;

                default:
                    break;
                }
            }

            // disable_when is a pause lock - if a hitcount was not specified assume the first hit is enough
            if (context.LastRequirement.HitCount == 0)
            {
                context.LastRequirement.HitCount = 1;
            }

            return(null);
        }
    }