Exemple #1
0
        /// <summary>
        /// Unpacks this applying language rules to expand and add articles/verbs where needed
        /// </summary>
        /// <param name="overridingContext">The full lexical context</param>
        /// <returns>A long description</returns>
        public IEnumerable <ILexica> Unpack(MessagingType sensoryType, short strength, LexicalContext overridingContext = null)
        {
            if (overridingContext != null)
            {
                IGlobalConfig globalConfig = ConfigDataCache.Get <IGlobalConfig>(new ConfigDataCacheKey(typeof(IGlobalConfig), "LiveSettings", ConfigDataType.GameWorld));

                //Sentence must maintain the same language, tense and personage
                Context.Language    = overridingContext.Language ?? Context.Language ?? globalConfig.BaseLanguage;
                Context.Tense       = overridingContext.Tense;
                Context.Perspective = overridingContext.Perspective;
                Context.Elegance    = overridingContext.Elegance;
                Context.Severity    = overridingContext.Severity;
                Context.Quality     = overridingContext.Quality;
            }

            ILexica newLex = Mutate(sensoryType, strength);

            foreach (IWordRule wordRule in Context.Language.WordRules.Where(rul => rul.Matches(newLex))
                     .OrderByDescending(rul => rul.RuleSpecificity()))
            {
                if (wordRule.NeedsArticle && (!wordRule.WhenPositional || Context.Position != LexicalPosition.None) &&
                    !newLex.Modifiers.Any(mod => (mod.Type == LexicalType.Article && !wordRule.WhenPositional && mod.Context.Position == LexicalPosition.None) ||
                                          (mod.Type == LexicalType.Preposition && wordRule.WhenPositional && mod.Context.Position != LexicalPosition.None)))
                {
                    LexicalContext articleContext = Context.Clone();

                    //Make it determinant if the word is plural
                    articleContext.Determinant = Context.Plural || articleContext.Determinant;

                    IDictata article = null;
                    if (wordRule.SpecificAddition != null)
                    {
                        article = wordRule.SpecificAddition;
                    }
                    else
                    {
                        article = Thesaurus.GetWord(articleContext, wordRule.WhenPositional ? LexicalType.Preposition : LexicalType.Article);
                    }

                    if (article != null && !newLex.Modifiers.Any(lx => article.Name.Equals(lx.Phrase, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        ILexica newArticle = newLex.TryModify(wordRule.WhenPositional ? LexicalType.Preposition : LexicalType.Article
                                                              , GrammaticalType.Descriptive, article.Name, false);

                        if (!wordRule.WhenPositional)
                        {
                            newArticle.Context.Position = LexicalPosition.None;
                        }
                    }
                }
                else if (wordRule.SpecificAddition != null && !newLex.Modifiers.Any(lx => wordRule.SpecificAddition.Equals(lx.GetDictata())))
                {
                    newLex.TryModify(wordRule.SpecificAddition.WordType, GrammaticalType.Descriptive, wordRule.SpecificAddition.Name);
                }

                if (!string.IsNullOrWhiteSpace(wordRule.AddPrefix) && !newLex.Phrase.StartsWith(wordRule.AddPrefix))
                {
                    newLex.Phrase = string.Format("{0}{1}", wordRule.AddPrefix, newLex.Phrase.Trim());
                }

                if (!string.IsNullOrWhiteSpace(wordRule.AddSuffix) && !newLex.Phrase.EndsWith(wordRule.AddSuffix))
                {
                    newLex.Phrase = string.Format("{1}{0}", wordRule.AddSuffix, newLex.Phrase.Trim());
                }
            }

            //Placement ordering
            List <Tuple <ILexica, int> > modifierList = new List <Tuple <ILexica, int> >
            {
                new Tuple <ILexica, int>(newLex, 0)
            };

            //modification rules ordered by specificity
            List <ILexica> currentModifiers = new List <ILexica>(newLex.Modifiers);

            foreach (ILexica modifier in currentModifiers)
            {
                foreach (IWordPairRule wordRule in Context.Language.WordPairRules.Where(rul => rul.Matches(newLex, modifier))
                         .OrderByDescending(rul => rul.RuleSpecificity()))
                {
                    if (wordRule.NeedsArticle && (!wordRule.WhenPositional || Context.Position != LexicalPosition.None) &&
                        !newLex.Modifiers.Any(mod => (mod.Type == LexicalType.Article && !wordRule.WhenPositional && mod.Context.Position == LexicalPosition.None) ||
                                              (mod.Type == LexicalType.Preposition && wordRule.WhenPositional && mod.Context.Position != LexicalPosition.None)))
                    {
                        LexicalContext articleContext = Context.Clone();

                        //Make it determinant if the word is plural
                        articleContext.Determinant = Context.Plural || articleContext.Determinant;

                        IDictata article = null;
                        if (wordRule.SpecificAddition != null)
                        {
                            article = wordRule.SpecificAddition;
                        }
                        else
                        {
                            article = Thesaurus.GetWord(articleContext, wordRule.WhenPositional ? LexicalType.Preposition : LexicalType.Article);
                        }

                        if (article != null && !newLex.Modifiers.Any(lx => article.Name.Equals(lx.Phrase, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            ILexica newArticle = newLex.TryModify(wordRule.WhenPositional ? LexicalType.Preposition : LexicalType.Article
                                                                  , GrammaticalType.Descriptive, article.Name, false);

                            if (!wordRule.WhenPositional)
                            {
                                newArticle.Context.Position = LexicalPosition.None;
                            }
                        }
                    }
                    else if (wordRule.SpecificAddition != null && !newLex.Modifiers.Any(lx => wordRule.SpecificAddition.Equals(lx.GetDictata())))
                    {
                        newLex.TryModify(wordRule.SpecificAddition.WordType, GrammaticalType.Descriptive, wordRule.SpecificAddition.Name);
                    }


                    if (!string.IsNullOrWhiteSpace(wordRule.AddPrefix) && !newLex.Phrase.StartsWith(wordRule.AddPrefix))
                    {
                        newLex.Phrase = string.Format("{0}{1}", wordRule.AddPrefix, newLex.Phrase.Trim());
                    }

                    if (!string.IsNullOrWhiteSpace(wordRule.AddSuffix) && !newLex.Phrase.EndsWith(wordRule.AddSuffix))
                    {
                        newLex.Phrase = string.Format("{1}{0}", wordRule.AddSuffix, newLex.Phrase.Trim());
                    }
                }
            }

            foreach (ILexica modifier in newLex.Modifiers)
            {
                IWordPairRule rule = Context.Language.WordPairRules.OrderByDescending(rul => rul.RuleSpecificity())
                                     .FirstOrDefault(rul => rul.Matches(newLex, modifier));

                if (rule != null)
                {
                    int i = 0;
                    foreach (ILexica subModifier in modifier.Unpack(sensoryType, strength, overridingContext ?? Context).Distinct())
                    {
                        modifierList.Add(new Tuple <ILexica, int>(subModifier, rule.ModificationOrder + i++));
                    }
                }
            }

            return(modifierList.OrderBy(tup => tup.Item2).Select(tup => tup.Item1));
        }