Esempio n. 1
0
        public IBook WriteBook(Ability topic, string name, Ability exposureAbility, double desiredLevel = 0)
        {
            // grant exposure experience
            List <Ability> abilityList = new List <Ability>(_writingAbilities);

            abilityList.Add(topic);
            GetAbility(exposureAbility).AddExperience(2);

            // TODO: When should books moved from the owned list to the covenant library?
            if (desiredLevel == 1000)
            {
                Tractatus t = WriteTractatus(topic, name);
                _booksOwned.Add(t);
                return(t);
            }
            else
            {
                Summa s = WriteSumma(topic, name, desiredLevel);
                if (s != null)
                {
                    _booksOwned.Add(s);
                }
                return(s);
            }
        }
Esempio n. 2
0
        protected Tractatus WriteTractatus(Ability topic, string name)
        {
            Tractatus t = new Tractatus
            {
                Author  = this,
                Quality = this.GetAttribute(AttributeType.Communication).Value + 6,
                Topic   = topic,
                Title   = name
            };

            _booksWritten.Add(t);
            return(t);
        }
Esempio n. 3
0
        public override bool Equals(object obj)
        {
            if (obj.GetType() != typeof(Tractatus))
            {
                return(false);
            }
            Tractatus otherBook = (Tractatus)obj;

            return
                (this.Author == otherBook.Author &&
                 this.Quality == otherBook.Quality &&
                 this.Title == otherBook.Title &&
                 this.Topic == otherBook.Topic);
        }
Esempio n. 4
0
        protected override void DoAction(Character character)
        {
            double scribeAbilityValue = character.GetAbility(Abilities.Scribing).Value;

            if (Book.Level == 1000)
            {
                Tractatus tract = new Tractatus
                {
                    Author  = Book.Author,
                    Quality = Book.Quality,
                    Title   = Book.Title,
                    Topic   = Book.Topic
                };
                character.AddBookToCollection(tract);
            }
            else
            {
                // TODO: implement logic for copying summae
            }
        }
Esempio n. 5
0
 protected override void DoAction(Character character)
 {
     double scribeAbilityValue = character.GetAbility(Abilities.Scribing).Value;
     if(Book.Level == 1000)
     {
         Tractatus tract = new Tractatus
         {
             Author = Book.Author,
             Quality = Book.Quality,
             Title = Book.Title,
             Topic = Book.Topic
         };
         character.AddBookToCollection(tract);
     }
     else
     {
         // TODO: implement logic for copying summae
     }
 }
Esempio n. 6
0
 protected Tractatus WriteTractatus(Ability topic, string name)
 {
     Tractatus t = new Tractatus
     {
         Author = this,
         Quality = this.GetAttribute(AttributeType.Communication).Value + 6,
         Topic = topic,
         Title = name
     };
     _booksWritten.Add(t);
     return t;
 }
Esempio n. 7
0
        public override IBook GetBestBookToWrite()
        {
            double        currentBestBookValue = 0;
            IBook         bestBook             = null;
            HashSet <int> consideredTopics     = new HashSet <int>();

            // since the value of a tractatus is independent of topic,
            // calculate the value of writing a tractatus now, so that we don't have to keep doing it
            double tractatusValue     = (6 + GetAttributeValue(AttributeType.Communication)) * GlobalEconomy.GlobalTractatusValue / 6;
            double writingRate        = GetAttributeValue(AttributeType.Communication) + GetAbility(_writingLanguage).Value;
            var    unneededBookTopics = GetUnneededBooksFromCollection().Select(b => b.Topic).Distinct();

            foreach (BookDesire bookDesire in GlobalEconomy.DesiredBooksList)
            {
                // if we already have a suitable book for this topic, let's not try to write another
                if (unneededBookTopics.Contains(bookDesire.Ability))
                {
                    continue;
                }
                // check to see if we could even write a summa of a level that would meet this desire
                if (GetAbility(bookDesire.Ability).Value > bookDesire.CurrentLevel * 2)
                {
                    CharacterAbility buyerAbility = new CharacterAbility(bookDesire.Ability);
                    buyerAbility.Experience = buyerAbility.GetExperienceUntilLevel(bookDesire.CurrentLevel);

                    // see if we have started a summa on this topic
                    var relatedIncompleteBooks = _incompleteBooks.Where(b => b.Topic == bookDesire.Ability && b.Level > bookDesire.CurrentLevel);
                    if (relatedIncompleteBooks.Any())
                    {
                        foreach (Summa incompleteBook in relatedIncompleteBooks)
                        {
                            // the effective value is based on time to finish, not time already invested
                            double experienceValue  = buyerAbility.GetExperienceUntilLevel(incompleteBook.Level);
                            double seasonsOfStudy   = Math.Ceiling(experienceValue / incompleteBook.Quality);
                            double effectiveQuality = experienceValue / seasonsOfStudy;
                            // at a minimum, the book is worth the vis it would take, on average, to gain that experience
                            double visUsedPerStudySeason = 0.5 + ((buyerAbility.Value + (buyerAbility.GetValueGain(experienceValue) / 2)) / 10.0);
                            double studySeasons          = experienceValue / VisStudyRate;
                            double visNeeded             = studySeasons * visUsedPerStudySeason;
                            // scale visNeeded according to vis type
                            if (MagicArts.IsTechnique(bookDesire.Ability))
                            {
                                visNeeded *= 4;
                            }
                            else if (MagicArts.IsArt(bookDesire.Ability) && bookDesire.Ability != MagicArts.Vim)
                            {
                                visNeeded *= 2;
                            }

                            // for now, scale vis according to quality of book vs. quality of vis study
                            visNeeded *= incompleteBook.Quality / VisStudyRate;

                            // divide this visNeed valuation by how many seasons are left for writing
                            double writingNeeded = incompleteBook.GetWritingPointsNeeded() - incompleteBook.PointsComplete;
                            double seasonsLeft   = Math.Ceiling(writingNeeded / writingRate);
                            double writingValue  = visNeeded / seasonsLeft;
                            if (writingValue > currentBestBookValue)
                            {
                                // continue writing this summa
                                bestBook = incompleteBook;
                            }
                        }
                    }
                    else
                    {
                        // NOTE: this could lead us down a strange rabbit hole of starting a bunch of
                        // summae on a subject of varying levels, but I think that's unlikely enough
                        // to not try and protect from for now
                        double maxLevel = GetAbility(bookDesire.Ability).Value / 2.0;

                        for (double l = maxLevel; l > bookDesire.CurrentLevel; l--)
                        {
                            double q = 6 + maxLevel - l;
                            // the effective value is based on time to finish, not time already invested
                            double experienceValue  = buyerAbility.GetExperienceUntilLevel(l);
                            double seasonsOfStudy   = Math.Ceiling(experienceValue / q);
                            double effectiveQuality = experienceValue / seasonsOfStudy;
                            // at a minimum, the book is worth the vis it would take, on average, to gain that experience
                            double visUsedPerStudySeason = 0.5 + ((buyerAbility.Value + (buyerAbility.GetValueGain(experienceValue) / 2)) / 10.0);
                            double studySeasons          = experienceValue / VisStudyRate;
                            double visNeeded             = studySeasons * visUsedPerStudySeason;
                            // scale visNeeded according to vis type
                            if (MagicArts.IsTechnique(bookDesire.Ability))
                            {
                                visNeeded *= 4;
                            }
                            else if (MagicArts.IsArt(bookDesire.Ability) && bookDesire.Ability != MagicArts.Vim)
                            {
                                visNeeded *= 2;
                            }

                            // for now, scale vis according to quality of book vs. quality of vis study
                            visNeeded *= q / VisStudyRate;

                            // divide this visNeed valuation by how many seasons are left for writing
                            double seasonsLeft  = Math.Ceiling(l / writingRate);
                            double writingValue = visNeeded / seasonsLeft;
                            if (writingValue > currentBestBookValue)
                            {
                                // write this summa
                                bestBook = new Summa
                                {
                                    Quality = q,
                                    Level   = l,
                                    Topic   = bookDesire.Ability,
                                    Title   = bookDesire.Ability.AbilityName + " Summa for Dummies by " + Name,
                                    Value   = writingValue
                                };
                                currentBestBookValue = writingValue;
                            }
                        }
                    }
                }

                // consider the value of writing a tractatus
                var charAbility = GetAbility(bookDesire.Ability);
                if (!consideredTopics.Contains(bookDesire.Ability.AbilityId) && tractatusValue > currentBestBookValue && CanWriteTractatus(charAbility))
                {
                    ushort previouslyWrittenCount = GetTractatiiWrittenOnTopic(bookDesire.Ability);
                    string name = Name + " " + bookDesire.Ability.AbilityName + " T" + previouslyWrittenCount.ToString();
                    bestBook = new Tractatus
                    {
                        Topic = bookDesire.Ability,
                        Title = name,
                        Value = tractatusValue
                    };
                    currentBestBookValue = tractatusValue;
                }
                consideredTopics.Add(bookDesire.Ability.AbilityId);
            }

            return(bestBook);
        }