示例#1
0
 public virtual string GetString(ISpecies species)
 {
     return(GetString((ITaxon)species, species.IsExtinct()));
 }
示例#2
0
        public async Task <IPaginatedMessage> BuildSpeciesMessageAsync(ISpecies species)
        {
            if (!species.IsValid())
            {
                return(null);
            }

            Discord.Messaging.Embed embed = new Discord.Messaging.Embed {
                Title = species.GetFullName()
            };

            if (species.CommonNames.Count() > 0)
            {
                embed.Title += string.Format(" ({0})", string.Join(", ", species.CommonNames.Select(name => name.ToTitle())));
            }

            if (Config.GenerationsEnabled)
            {
                // Add a field for the generation.

                IGeneration gen = await Db.GetGenerationByDateAsync(species.CreationDate);

                embed.AddField("Gen", gen is null ? "???" : gen.Number.ToString(), inline: true);
            }

            // Add a field for the species owner.

            embed.AddField("Owner", await GetCreatorAsync(species.Creator), inline: true);

            // Add a field for the species' zones.

            IEnumerable <ISpeciesZoneInfo> speciesZoneList = (await Db.GetZonesAsync(species))
                                                             .Where(info => !info.Zone.Flags.HasFlag(ZoneFlags.Retired));

            string zonesFieldValue = speciesZoneList.ToString(ZoneListToStringOptions.Default, DiscordUtilities.MaxFieldLength);

            embed.AddField("Zone(s)", string.IsNullOrEmpty(zonesFieldValue) ? "None" : zonesFieldValue, inline: true);

            // Add the species' description.

            StringBuilder descriptionBuilder = new StringBuilder();

            if (species.IsExtinct())
            {
                embed.Title = "[EXTINCT] " + embed.Title;

                if (!string.IsNullOrEmpty(species.Status.Reason))
                {
                    descriptionBuilder.AppendLine(string.Format("**Extinct ({0}):** _{1}_\n", await BotUtils.TimestampToDateStringAsync(DateUtilities.GetTimestampFromDate((DateTimeOffset)species.Status.Date), BotContext), species.Status.Reason));
                }
            }

            descriptionBuilder.Append(species.GetDescriptionOrDefault());

            embed.Description = descriptionBuilder.ToString();

            // Add the species' picture.

            embed.ThumbnailUrl = species.GetPictureUrl();

            if (!string.IsNullOrEmpty(Config.WikiUrlFormat))
            {
                // Discord automatically encodes certain characters in URIs, which doesn't allow us to update the config via Discord when we have "{0}" in the URL.
                // Replace this with the proper string before attempting to call string.Format.

                string format = Config.WikiUrlFormat.Replace("%7B0%7D", "{0}");

                embed.Url = string.Format(format, Uri.EscapeUriString(WikiUtilities.GetWikiPageTitle(species)));
            }

            // Create embed pages.

            IEnumerable <Discord.Messaging.IEmbed> embedPages = EmbedUtilities.CreateEmbedPages(embed, EmbedPaginationOptions.AddPageNumbers | EmbedPaginationOptions.CopyFields);
            IPaginatedMessage paginatedMessage = new PaginatedMessage(embedPages);

            if (speciesZoneList.Count() > 0)
            {
                paginatedMessage.SetColor((await Db.GetZoneTypeAsync(speciesZoneList.GroupBy(x => x.Zone.TypeId).OrderBy(x => x.Count()).Last().Key)).Color);
            }

            if (species.IsExtinct())
            {
                paginatedMessage.SetColor(Color.Red);
            }

            return(paginatedMessage);
        }
        // Public members

        public async override Task ApplyAsync(ISearchContext context, ISearchResult result)
        {
            /* Filter all species that don't compete with the given species.
             *
             * A species is considered a competitor if:
             *
             * (1) It shares a zone with the given species, and
             * (2) It eats the same prey items, and
             * (3) It is currently extant
             *
             * This is very similar to the "status:endangered" filter, without the requirement that one species derive from the other.
             */

            ISpecies        species = (await context.Database.GetSpeciesAsync(Value)).FirstOrDefault();
            List <ISpecies> competitorSpeciesList = new List <ISpecies>();

            if (species.IsValid())
            {
                IEnumerable <ISpecies> preySpecies = (await context.Database.GetPreyAsync(species)).Select(info => info.Species).Where(sp => !sp.IsExtinct());

                // Create a list of all species that exist in the same zone as the given species.

                List <ISpecies> sharedZoneSpeciesList = new List <ISpecies>();

                foreach (IZone zone in (await context.Database.GetZonesAsync(species, GetZoneOptions.IdsOnly)).Select(info => info.Zone))
                {
                    sharedZoneSpeciesList.AddRange((await context.Database.GetSpeciesAsync(zone)).Where(sp => !sp.IsExtinct()));
                }

                if (preySpecies.Any())
                {
                    // If the species has prey, find all species that have the same prey.

                    foreach (ISpecies candidateSpecies in sharedZoneSpeciesList)
                    {
                        IEnumerable <ISpecies> candidateSpeciesPreySpecies =
                            (await context.Database.GetPreyAsync(candidateSpecies)).Select(info => info.Species).Where(sp => !sp.IsExtinct());

                        if (candidateSpeciesPreySpecies.Any() && candidateSpeciesPreySpecies.All(sp1 => preySpecies.Any(sp2 => sp1.Id.Equals(sp2.Id))))
                        {
                            competitorSpeciesList.Add(candidateSpecies);
                        }
                    }
                }
                else
                {
                    // If the species does not have prey, find all species with the same roles.

                    IEnumerable <IRole> roles = await context.Database.GetRolesAsync(species);

                    if (roles.Any())
                    {
                        foreach (ISpecies candidateSpecies in sharedZoneSpeciesList)
                        {
                            if ((await context.Database.GetRolesAsync(candidateSpecies)).All(role1 => roles.Any(role2 => role1.Id.Equals(role2.Id))))
                            {
                                competitorSpeciesList.Add(candidateSpecies);
                            }
                        }
                    }
                }
            }

            // Filter all species that aren't in the competitor species list.

            await result.FilterByAsync(async (s) => {
                return(await Task.FromResult(!species.IsValid() || species.IsExtinct() || s.Id.Equals(species.Id) || !competitorSpeciesList.Any(sp => sp.Id.Equals(s.Id))));
            }, Invert);
        }