예제 #1
0
        void SetupTerminationDefinition(string name)
        {
            m_StateTerminationDefinition            = ScriptableObject.CreateInstance <StateTerminationDefinition>();
            m_StateTerminationDefinition.Parameters = new[]
            {
                new ParameterDefinition()
                {
                    Name           = "ParameterA",
                    RequiredTraits = new[]
                    {
                        m_TraitDefinition
                    }
                }
            };

            m_StateTerminationDefinition.Criteria = new[]
            {
                new Operation()
                {
                    Operator           = nameof(Operation.SpecialOperators.Custom),
                    CustomOperatorType = "CustomTerminationPrecondition"
                }
            };

            SaveAsset(m_StateTerminationDefinition, Path.Combine(k_AssetsPath, name));
        }
        bool IsTerminationAssetValid(StateTerminationDefinition termination, Type[] customTypes)
        {
            bool terminationValid = true;

            // Check if custom reward types used exist in the assembly and are valid
            if (termination.CustomRewards != null)
            {
                terminationValid = CheckTerminationCustomReward(termination, termination.CustomRewards, customTypes);
            }

            foreach (var precondition in termination.Criteria)
            {
                if (precondition.IsSpecialOperator(Operation.SpecialOperators.Custom))
                {
                    var preconditionType = customTypes?.FirstOrDefault(t => t.FullName == precondition.CustomOperatorType);
                    if (preconditionType == null)
                    {
                        errorLogged?.Invoke($"Couldn't resolve termination precondition type {precondition.CustomOperatorType}.", termination);
                        terminationValid = false;
                    }
                }
            }

            return(terminationValid);
        }
        void GenerateTermination(StateTerminationDefinition termination, string planName, Type[] customTypes, string outputPath, bool includeEnums)
        {
            var terminationName = termination.Name;

            var parameters = termination.Parameters.Select(p => new
            {
                @name             = p.Name,
                required_traits   = p.RequiredTraits,
                prohibited_traits = p.ProhibitedTraits,
            });

            var terminationCriteria = termination.Criteria.Where(p => !p.IsSpecialOperator(Operation.SpecialOperators.Custom));
            var criteriaTraits      = terminationCriteria.Where(c => c.OperandA.Trait != null).Select(c => c.OperandA.Trait.name)
                                      .Concat(terminationCriteria.Where(c => c.OperandB.Trait != null).Select(c => c.OperandB.Trait.name))
                                      .Distinct();

            var customCriteriaList = termination.Criteria.Where(p => p.IsSpecialOperator(Operation.SpecialOperators.Custom));
            var customCriteria     = customCriteriaList.Select(p => p.CustomOperatorType);

            var parameterNames = parameters.Select(p => p.@name).ToList();
            var criteria       = terminationCriteria.Select(p => new
            {
                @operator  = p.Operator,
                operand_a  = GetPreconditionOperandString(p.OperandA, p.Operator, parameterNames),
                operand_b  = GetPreconditionOperandString(p.OperandB, p.Operator, parameterNames),
                loop_index = Mathf.Max(parameterNames.FindIndex(name => name == p.OperandA.Parameter)
                                       , parameterNames.FindIndex(name => name == p.OperandB.Parameter))
            });

            var customRewards = termination.CustomRewards.Select(c =>
            {
                var customRewardType = customTypes.FirstOrDefault(t => t.FullName == c.Typename);
                if (customRewardType != null)
                {
                    return(new
                    {
                        @operator = c.Operator,
                        typename = customRewardType.FullName,
                        parameters = c.Parameters.Select((p, index) => new
                        {
                            index = parameterNames.IndexOf(p),
                            type = customRewardType.GetMethod("RewardModifier")?.GetParameters()[index].ParameterType
                        })
                    });
                }
                else
                {
                    Debug.LogError($"Couldn't resolve custom type {c.Typename} for termination {termination.Name}");
                }

                return(null);
            }).Where(c => c != null);

            var result = m_CodeRenderer.RenderTemplate(PlannerResources.instance.TemplateTermination, new
            {
                @namespace      = $"{TypeHelper.PlansQualifier}.{planName}",
                plan_name       = planName,
                name            = terminationName,
                parameter_list  = parameters,
                criteria_traits = criteriaTraits.ToArray(),
                criteria_list   = criteria.ToArray(),
                custom_criteria = customCriteria,
                reward_value    = termination.TerminalReward,
                custom_rewards  = customRewards,
                include_enums   = includeEnums,
                state_representation_qualifier = TypeHelper.StateRepresentationQualifier
            });

            SaveToFile(Path.Combine(outputPath, TypeHelper.PlansQualifier, planName, $"{terminationName}.cs"), result);
        }