示例#1
0
        public async Task GetInfo(string name)
        {
            // Prioritize species first.

            Species[] species = await BotUtils.GetSpeciesFromDb("", name);

            if (species.Count() > 0)
            {
                if (await BotUtils.ReplyValidateSpeciesAsync(Context, species))
                {
                    await SpeciesCommands.ShowSpeciesInfoAsync(Context, species[0]);
                }
            }
            else
            {
                // Otherwise, show other taxon.

                Taxon[] taxa = await BotUtils.GetTaxaFromDb(name);

                if (taxa.Count() <= 0)
                {
                    // This command was traditionally used with species, so show the user species suggestions in the event of no matches.
                    await BotUtils.ReplyAsync_SpeciesSuggestions(Context, "", name, async (BotUtils.ConfirmSuggestionArgs args) => await GetInfo(args.Suggestion));
                }
                else if (await BotUtils.ReplyAsync_ValidateTaxa(Context, taxa))
                {
                    await BotUtils.Command_ShowTaxon(Context, taxa[0].type, name);
                }
            }
        }
示例#2
0
        public async Task AppendDescription(string arg0, string arg1)
        {
            // Possible input:
            // +desc <genus> <species>
            // +desc <species> <description>

            Species[] species_list = await BotUtils.GetSpeciesFromDb(arg0, arg1);

            if (species_list.Count() <= 0)
            {
                // We weren't able to find a species with the given genus and name, so perhaps the user provided a species and description.
                // The following method call will handle this situation, as well as the situation where the species was invalid.
                await AppendDescription("", species : arg0, description : arg1);
            }
            else if (await BotUtils.ReplyValidateSpeciesAsync(Context, species_list))
            {
                // Initialize a multistage update for the given species.

                Species species = species_list[0];

                // Ensure that the user has necessary privileges to use this command.
                if (!await BotUtils.ReplyHasPrivilegeOrOwnershipAsync(Context, PrivilegeLevel.ServerModerator, species))
                {
                    return;
                }

                await _appendDescriptionAsync(species);
            }
        }
示例#3
0
        public async Task SetSpeciesDescription(string speciesOrGenus, string descriptionOrSpecies)
        {
            // Either the user provided a species and a description, or they provided a genus and species and want to use the two-part command.
            // If the species exists, we'll use the two-part command version. If it doesn't, we'll assume the user was providing a description directly.

            Species[] species_list = await BotUtils.GetSpeciesFromDb(speciesOrGenus, descriptionOrSpecies);

            if (species_list.Count() <= 0)
            {
                // No such species exists for the given genus/species. We have two possibilities.

                if (!string.IsNullOrEmpty(speciesOrGenus))
                {
                    // The user passed in a species and a description, so attempt to update the description for that species.
                    await SetSpeciesDescription(string.Empty, speciesOrGenus, descriptionOrSpecies);
                }
                else
                {
                    // The user passed in a blank genus and a non-existent species, so reply with some suggestions.
                    await BotUtils.ReplyAsync_SpeciesSuggestions(Context, speciesOrGenus, descriptionOrSpecies);
                }
            }
            else if (await BotUtils.ReplyValidateSpeciesAsync(Context, species_list))
            {
                // A species exists with the given genus/species, so initiate a two-part command.

                // Ensure that the user has necessary privileges to use this command.
                if (!await BotUtils.ReplyHasPrivilegeOrOwnershipAsync(Context, PrivilegeLevel.ServerModerator, species_list[0]))
                {
                    return;
                }

                await _setSpeciesDescriptionAsync(species_list[0]);
            }
        }
示例#4
0
        public async Task Predates(string genus, string species = "")
        {
            // If the species parameter was not provided, assume the user only provided the species.
            if (string.IsNullOrEmpty(species))
            {
                species = genus;
                genus   = string.Empty;
            }

            Species sp = await BotUtils.ReplyFindSpeciesAsync(Context, genus, species);

            if (sp is null)
            {
                return;
            }

            EmbedBuilder embed = new EmbedBuilder();

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Predates WHERE eats_id=$eats_id AND species_id NOT IN (SELECT species_id FROM Extinctions);")) {
                cmd.Parameters.AddWithValue("$eats_id", sp.Id);

                using (DataTable rows = await Database.GetRowsAsync(cmd)) {
                    if (rows.Rows.Count <= 0)
                    {
                        await BotUtils.ReplyAsync_Info(Context, string.Format("**{0}** has no extant natural predators.", sp.ShortName));
                    }
                    else
                    {
                        List <string> lines = new List <string>();

                        foreach (DataRow row in rows.Rows)
                        {
                            Species s = await BotUtils.GetSpeciesFromDb(row.Field <long>("species_id"));

                            string notes = row.Field <string>("notes");

                            string line_text = s.ShortName;

                            if (!string.IsNullOrEmpty(notes))
                            {
                                line_text += string.Format(" ({0})", notes.ToLower());
                            }

                            lines.Add(s.IsExtinct ? string.Format("~~{0}~~", line_text) : line_text);
                        }

                        lines.Sort();

                        embed.WithTitle(string.Format("Predators of {0} ({1})", sp.ShortName, lines.Count()));
                        embed.WithDescription(string.Join(Environment.NewLine, lines));

                        await ReplyAsync("", false, embed.Build());
                    }
                }
            }
        }
        public async Task Roles(string nameOrSpecies)
        {
            // If a role with this name exists, that's what we'll prioritize (users can use the genus + species overload if they need to).
            // If no such role exists, check for a species with this name instead.

            Role role = await BotUtils.GetRoleFromDb(nameOrSpecies);

            if (role is null)
            {
                // No such role exists, so check if a species exists with the given name instead.

                Species[] matching_species = await BotUtils.GetSpeciesFromDb("", nameOrSpecies);

                if (matching_species.Count() == 1)
                {
                    // If only one species was returned, show the roles assigned to that species.
                    await Roles(matching_species[0]);
                }

                else if (matching_species.Count() > 1)
                {
                    // If multiple species were returned, provide a list of matching species for the user to choose from.
                    await BotUtils.ReplyValidateSpeciesAsync(Context, matching_species);
                }

                if (matching_species.Count() > 0)
                {
                    return;
                }
            }

            // If we got here, the role is eiher not null, or it is null, but no species with the given name exists.
            // In this case, proceed to validate the role, and display its information if possible.

            if (!await BotUtils.ReplyAsync_ValidateRole(Context, role))
            {
                return;
            }

            // List all extant species with this role.

            List <Species> species_list = new List <Species>(await BotUtils.GetSpeciesFromDbByRole(role));

            species_list.RemoveAll(x => x.IsExtinct);
            species_list.Sort((lhs, rhs) => lhs.ShortName.CompareTo(rhs.ShortName));

            Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder(EmbedUtils.SpeciesListToEmbedPages(species_list,
                                                                                                                   fieldName: string.Format("Extant species with this role ({0}):", species_list.Count())));

            embed.SetTitle(string.Format("Role: {0}", StringUtils.ToTitleCase(role.name)));
            embed.SetDescription(role.GetDescriptionOrDefault());

            await Bot.DiscordUtils.SendMessageAsync(Context, embed.Build());
        }
        public async Task Size(string genusOrSpecies, string speciesOrUnits)
        {
            // This command can be used in a number of ways:
            // <genus> <species>    -> returns size for that species
            // <species> <units>    -> returns size for that species, using the given units

            Species    species = null;
            LengthUnit units   = LengthUnit.Unknown;

            // Attempt to get the specified species, assuming the user passed in <genus> <species>.

            Species[] species_array = await BotUtils.GetSpeciesFromDb(genusOrSpecies, speciesOrUnits);

            if (species_array.Count() > 1)
            {
                await BotUtils.ReplyValidateSpeciesAsync(Context, species_array);
            }
            else if (species_array.Count() == 1)
            {
                species = species_array[0];
            }
            else if (species_array.Count() <= 0)
            {
                // If we didn't get any species by treating the arguments as <genus> <species>, attempt to get the species by <species> only.
                species = await BotUtils.ReplyFindSpeciesAsync(Context, "", genusOrSpecies);

                // If this still fails, there's nothing left to do.

                if (species is null)
                {
                    return;
                }

                // Assume the second argument was the desired units.
                // Make sure the units given are valid.

                units = new Length(0.0, speciesOrUnits).Units;

                if (units == LengthUnit.Unknown)
                {
                    await BotUtils.ReplyAsync_Error(Context, string.Format("Invalid units (\"{0}\").", speciesOrUnits));

                    return;
                }
            }

            if (!(species is null))
            {
                await Size(species, units);
            }
        }
        public async Task AddSpecies(string genus, string species, string zone = "", string description = "")
        {
            // Check if the species already exists before attempting to add it.

            if ((await BotUtils.GetSpeciesFromDb(genus, species)).Count() > 0)
            {
                await BotUtils.ReplyAsync_Warning(Context, string.Format("The species \"{0}\" already exists.", BotUtils.GenerateSpeciesName(genus, species)));

                return;
            }

            await BotUtils.AddGenusToDb(genus);

            Taxon genus_info = await BotUtils.GetGenusFromDb(genus);

            using (SQLiteCommand cmd = new SQLiteCommand("INSERT INTO Species(name, description, genus_id, owner, timestamp, user_id) VALUES($name, $description, $genus_id, $owner, $timestamp, $user_id);")) {
                cmd.Parameters.AddWithValue("$name", species.ToLower());
                cmd.Parameters.AddWithValue("$description", description);
                cmd.Parameters.AddWithValue("$genus_id", genus_info.id);
                cmd.Parameters.AddWithValue("$owner", Context.User.Username);
                cmd.Parameters.AddWithValue("$user_id", Context.User.Id);
                cmd.Parameters.AddWithValue("$timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds());

                await Database.ExecuteNonQuery(cmd);
            }

            Species[] sp_list = await BotUtils.GetSpeciesFromDb(genus, species);

            Species sp         = sp_list.Count() > 0 ? sp_list[0] : null;
            long    species_id = sp == null ? -1 : sp.Id;

            if (species_id < 0)
            {
                await BotUtils.ReplyAsync_Error(Context, "Failed to add species (invalid Species ID).");

                return;
            }

            // Add to all given zones.
            await _plusZone(sp, zone, string.Empty, onlyShowErrors : true);

            // Add the user to the trophy scanner queue in case their species earned them any new trophies.

            if (OurFoodChainBot.Instance.Config.TrophiesEnabled)
            {
                await Global.TrophyScanner.AddToQueueAsync(Context, Context.User.Id);
            }

            await BotUtils.ReplyAsync_Success(Context, string.Format("Successfully created new species, **{0}**.", BotUtils.GenerateSpeciesName(genus, species)));
        }
        public async Task Gallery(string speciesOrTaxon)
        {
            // Prioritize species galleries first.

            Species[] species = await BotUtils.GetSpeciesFromDb("", speciesOrTaxon);

            if (species is null || species.Count() <= 0)
            {
                // No such species exists, so check if a taxon exists.

                Taxon taxon = await BotUtils.GetTaxonFromDb(speciesOrTaxon);

                if (taxon is null)
                {
                    // If no such taxon exists, show species recommendations to the user.
                    await BotUtils.ReplyAsync_SpeciesSuggestions(Context, "", speciesOrTaxon);
                }
                else
                {
                    // The taxon does exist, so we'll generate a gallery from this taxon.
                    // First, images for this taxon will be added, followed by the galleries for all species under it.

                    List <Picture> pictures = new List <Picture>();

                    if (!string.IsNullOrEmpty(taxon.pics))
                    {
                        pictures.Add(new Picture(taxon.pics));
                    }

                    foreach (Species sp in await BotUtils.GetSpeciesInTaxonFromDb(taxon))
                    {
                        pictures.AddRange(await SpeciesUtils.GetPicturesAsync(sp));
                    }

                    await ShowGalleryAsync(Context, taxon.GetName(), pictures.ToArray());
                }
            }
        public async Task SetAncestor(string genus, string species, string ancestorGenus, string ancestorSpecies)
        {
            // Get the descendant and ancestor species.

            Species[] descendant_list = await BotUtils.GetSpeciesFromDb(genus, species);

            Species[] ancestor_list = await BotUtils.GetSpeciesFromDb(ancestorGenus, ancestorSpecies);

            if (descendant_list.Count() > 1)
            {
                await BotUtils.ReplyAsync_Error(Context, string.Format("The child species \"{0}\" is too vague (there are multiple matches). Try including the genus.", species));
            }
            else if (ancestor_list.Count() > 1)
            {
                await BotUtils.ReplyAsync_Error(Context, string.Format("The ancestor species \"{0}\" is too vague (there are multiple matches). Try including the genus.", ancestorSpecies));
            }
            else if (descendant_list.Count() == 0)
            {
                await BotUtils.ReplyAsync_Error(Context, "The child species does not exist.");
            }
            else if (ancestor_list.Count() == 0)
            {
                await BotUtils.ReplyAsync_Error(Context, "The parent species does not exist.");
            }
            else if (descendant_list[0].Id == ancestor_list[0].Id)
            {
                await BotUtils.ReplyAsync_Error(Context, "A species cannot be its own ancestor.");
            }
            else
            {
                Species descendant = descendant_list[0];
                Species ancestor   = ancestor_list[0];

                // Check if an ancestor has already been set for this species. If so, update the ancestor, but we'll show a different message later notifying the user of the change.

                Species existing_ancestor_sp = null;

                using (SQLiteCommand cmd = new SQLiteCommand("SELECT ancestor_id FROM Ancestors WHERE species_id=$species_id;")) {
                    cmd.Parameters.AddWithValue("$species_id", descendant.Id);

                    DataRow row = await Database.GetRowAsync(cmd);

                    if (!(row is null))
                    {
                        long ancestor_id = row.Field <long>("ancestor_id");

                        existing_ancestor_sp = await BotUtils.GetSpeciesFromDb(ancestor_id);
                    }
                }

                // If the ancestor has already been set to the species specified, quit.

                if (!(existing_ancestor_sp is null) && existing_ancestor_sp.Id == ancestor.Id)
                {
                    await BotUtils.ReplyAsync_Warning(Context, string.Format("**{0}** has already been set as the ancestor of **{1}**.", ancestor.ShortName, descendant.ShortName));

                    return;
                }

                // Insert the new relationship into the database.

                using (SQLiteCommand cmd = new SQLiteCommand("INSERT OR REPLACE INTO Ancestors(species_id, ancestor_id) VALUES($species_id, $ancestor_id);")) {
                    cmd.Parameters.AddWithValue("$species_id", descendant.Id);
                    cmd.Parameters.AddWithValue("$ancestor_id", ancestor.Id);

                    await Database.ExecuteNonQuery(cmd);
                }

                if (existing_ancestor_sp is null)
                {
                    await BotUtils.ReplyAsync_Success(Context, string.Format("**{0}** has been set as the ancestor of **{1}**.", ancestor.ShortName, descendant.ShortName));
                }
                else
                {
                    await BotUtils.ReplyAsync_Success(Context, string.Format("**{0}** has replaced **{1}** as the ancestor of **{2}**.", ancestor.ShortName, existing_ancestor_sp.ShortName, descendant.ShortName));
                }
            }
        }
示例#10
0
        public async Task SetTaxonDescription(string taxonNameOrGenus, string descriptionOrSpecies)
        {
            // Either the user provided a taxon and a description, or they provided a genus and species and want to use a two-part command sequence.
            // If the species exists, we'll use the two-part command version. If it doesn't, we'll assume the user was providing a description directly.

            Species[] species_list = await BotUtils.GetSpeciesFromDb(taxonNameOrGenus, descriptionOrSpecies);

            if (species_list.Count() <= 0)
            {
                // No such species exists for the given genus/species, so look for the taxon instead and try to update its description directly.

                Taxon[] taxa = await BotUtils.GetTaxaFromDb(taxonNameOrGenus);

                // If we didn't get any matches, show the user species suggestions.

                if (taxa.Count() <= 0)
                {
                    await BotUtils.ReplyFindSpeciesAsync(Context, "", taxonNameOrGenus);
                }

                else
                {
                    // Make sure we have one, and only one taxon to update.

                    if (!await BotUtils.ReplyAsync_ValidateTaxa(Context, taxa))
                    {
                        return;
                    }

                    Taxon taxon = taxa[0];

                    if (taxon.type == TaxonRank.Species)
                    {
                        // If the taxon is a species, use the species update procedure.
                        await _setSpeciesDescriptionAsync(await BotUtils.GetSpeciesFromDb(taxon.id), descriptionOrSpecies);
                    }

                    else
                    {
                        // Update the taxon in the DB.
                        await BotUtils.Command_SetTaxonDescription(Context, taxon, descriptionOrSpecies);
                    }
                }
            }
            else if (await BotUtils.ReplyValidateSpeciesAsync(Context, species_list))
            {
                // A species exists with the given genus/species, so initiate a two-part command.

                // Ensure that the user has necessary privileges to use this command.
                if (!await BotUtils.ReplyHasPrivilegeOrOwnershipAsync(Context, PrivilegeLevel.ServerModerator, species_list[0]))
                {
                    return;
                }

                Bot.MultiPartMessage p = new Bot.MultiPartMessage(Context)
                {
                    UserData = new string[] { taxonNameOrGenus, descriptionOrSpecies },
                    Callback = async(args) => {
                        Species[] species = await BotUtils.GetSpeciesFromDb(args.Message.UserData[0], args.Message.UserData[1]);

                        if (await BotUtils.ReplyValidateSpeciesAsync(args.Message.Context, species))
                        {
                            await _setSpeciesDescriptionAsync(species[0], args.ResponseContent);
                        }
                    }
                };

                await Bot.DiscordUtils.SendMessageAsync(Context, p,
                                                        string.Format("Reply with the description for **{0}**.\nTo cancel the update, reply with \"cancel\".", species_list[0].ShortName));
            }
        }
示例#11
0
        public async Task Prey(string genus, string species = "")
        {
            // If no species argument was provided, assume the user omitted the genus.
            if (string.IsNullOrEmpty(species))
            {
                species = genus;
                genus   = string.Empty;
            }

            // Get the specified species.

            Species sp = await BotUtils.ReplyFindSpeciesAsync(Context, genus, species);

            if (sp is null)
            {
                return;
            }

            // Get the preyed-upon species.

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Predates WHERE species_id=$species_id;")) {
                cmd.Parameters.AddWithValue("$species_id", sp.Id);

                using (DataTable rows = await Database.GetRowsAsync(cmd)) {
                    if (rows.Rows.Count <= 0)
                    {
                        await BotUtils.ReplyAsync_Info(Context, string.Format("**{0}** does not prey upon any other species.", sp.ShortName));
                    }
                    else
                    {
                        List <Tuple <Species, string> > prey_list = new List <Tuple <Species, string> >();

                        foreach (DataRow row in rows.Rows)
                        {
                            prey_list.Add(new Tuple <Species, string>(
                                              await BotUtils.GetSpeciesFromDb(row.Field <long>("eats_id")),
                                              row.Field <string>("notes")));
                        }

                        prey_list.Sort((lhs, rhs) => lhs.Item1.ShortName.CompareTo(rhs.Item1.ShortName));

                        List <string> lines = new List <string>();

                        foreach (Tuple <Species, string> prey in prey_list)
                        {
                            string line = prey.Item1.IsExtinct ? BotUtils.Strikeout(prey.Item1.ShortName) : prey.Item1.ShortName;

                            if (!string.IsNullOrEmpty(prey.Item2))
                            {
                                line += (string.Format(" ({0})", prey.Item2.ToLower()));
                            }

                            lines.Add(line);
                        }

                        PaginatedMessageBuilder embed = new PaginatedMessageBuilder();

                        embed.AddPages(EmbedUtils.LinesToEmbedPages(lines));

                        embed.SetTitle(string.Format("Species preyed upon by {0} ({1})", sp.ShortName, prey_list.Count()));
                        embed.AddPageNumbers();

                        await DiscordUtils.SendMessageAsync(Context, embed.Build());
                    }
                }
            }
        }
示例#12
0
        public async Task Relationships(string genus, string species)
        {
            // Get the species from the DB.

            Species sp = await BotUtils.ReplyFindSpeciesAsync(Context, genus, species);

            if (sp is null)
            {
                return;
            }

            // Get relationships and build the embed.

            SortedDictionary <string, List <string> > items = new SortedDictionary <string, List <string> >();

            // Get relationships where this species is the one acting upon another.

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM SpeciesRelationships LEFT JOIN Relationships ON SpeciesRelationships.relationship_id = Relationships.id WHERE species1_id=$species_id;")) {
                cmd.Parameters.AddWithValue("$species_id", sp.Id);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        long    other_species_id = row.Field <long>("species2_id");
                        Species other_species    = await BotUtils.GetSpeciesFromDb(other_species_id);

                        Relationship relationship = Relationship.FromDataRow(row);

                        if (other_species is null)
                        {
                            continue;
                        }

                        if (!items.ContainsKey(relationship.BeneficiaryName(plural: true)))
                        {
                            items[relationship.BeneficiaryName(plural: true)] = new List <string>();
                        }

                        items[relationship.BeneficiaryName(plural: true)].Add(other_species.IsExtinct ? string.Format("~~{0}~~", other_species.ShortName) : other_species.ShortName);
                    }
            }

            // Get relationships where this species is the one being acted upon.

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM SpeciesRelationships LEFT JOIN Relationships ON SpeciesRelationships.relationship_id = Relationships.id WHERE species2_id=$species_id;")) {
                cmd.Parameters.AddWithValue("$species_id", sp.Id);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        long    other_species_id = row.Field <long>("species1_id");
                        Species other_species    = await BotUtils.GetSpeciesFromDb(other_species_id);

                        Relationship relationship = Relationship.FromDataRow(row);

                        if (other_species is null)
                        {
                            continue;
                        }

                        if (!items.ContainsKey(relationship.BenefactorName(plural: true)))
                        {
                            items[relationship.BenefactorName(plural: true)] = new List <string>();
                        }

                        items[relationship.BenefactorName(plural: true)].Add(other_species.IsExtinct ? string.Format("~~{0}~~", other_species.ShortName) : other_species.ShortName);
                    }
            }

            // Get any prey/predator relationships.

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Predates WHERE species_id=$species_id;")) {
                cmd.Parameters.AddWithValue("$species_id", sp.Id);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        long    other_species_id = row.Field <long>("eats_id");
                        Species other_species    = await BotUtils.GetSpeciesFromDb(other_species_id);

                        if (other_species is null)
                        {
                            continue;
                        }

                        if (!items.ContainsKey("prey"))
                        {
                            items["prey"] = new List <string>();
                        }

                        items["prey"].Add(other_species.IsExtinct ? string.Format("~~{0}~~", other_species.ShortName) : other_species.ShortName);
                    }
            }

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Predates WHERE eats_id=$species_id;")) {
                cmd.Parameters.AddWithValue("$species_id", sp.Id);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        long    other_species_id = row.Field <long>("species_id");
                        Species other_species    = await BotUtils.GetSpeciesFromDb(other_species_id);

                        if (other_species is null)
                        {
                            continue;
                        }

                        if (!items.ContainsKey("predators"))
                        {
                            items["predators"] = new List <string>();
                        }

                        items["predators"].Add(other_species.IsExtinct ? string.Format("~~{0}~~", other_species.ShortName) : other_species.ShortName);
                    }
            }

            // If the species does not have any relationships with other species, state so.

            if (items.Count() <= 0)
            {
                await BotUtils.ReplyAsync_Info(Context, string.Format("**{0}** does not have any relationships with other species.", sp.ShortName));

                return;
            }

            // Build the embed.

            EmbedBuilder embed = new EmbedBuilder();
            int          relationship_count = 0;

            foreach (string key in items.Keys)
            {
                items[key].Sort((lhs, rhs) => lhs.CompareTo(rhs));

                embed.AddField(string.Format("{0} ({1})", StringUtils.ToTitleCase(key), items[key].Count()), string.Join(Environment.NewLine, items[key]), inline: true);

                relationship_count += items[key].Count();
            }

            embed.WithTitle(string.Format("Relationships involving {0} ({1})", sp.ShortName, relationship_count));

            await ReplyAsync("", false, embed.Build());
        }
示例#13
0
        public static async Task <Bot.PaginatedMessageBuilder> BuildRecentEventsEmbedAsync(long startTimestamp, long endTimestamp, TimeUnits timeUnit = 0)
        {
            // Get all species created within the given timespan.

            List <Species> new_species = new List <Species>();
            TimeAmount     time_amount = new TimeAmount(endTimestamp - startTimestamp, TimeUnits.Seconds);

            if (timeUnit != 0)
            {
                time_amount = time_amount.ConvertTo(timeUnit);
            }
            else
            {
                time_amount = time_amount.Reduce();
            }

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Species WHERE timestamp >= $start_ts AND timestamp < $end_ts")) {
                cmd.Parameters.AddWithValue("$start_ts", startTimestamp);
                cmd.Parameters.AddWithValue("$end_ts", endTimestamp);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        new_species.Add(await SpeciesUtils.SpeciesFromDataRow(row));
                    }
            }

            new_species.Sort();

            // Get all extinctions that occurred recently.

            List <Species> extinct_species = new List <Species>();

            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Extinctions WHERE timestamp >= $start_ts AND timestamp < $end_ts")) {
                cmd.Parameters.AddWithValue("$start_ts", startTimestamp);
                cmd.Parameters.AddWithValue("$end_ts", endTimestamp);

                using (DataTable table = await Database.GetRowsAsync(cmd))
                    foreach (DataRow row in table.Rows)
                    {
                        extinct_species.Add(await BotUtils.GetSpeciesFromDb(row.Field <long>("species_id")));
                    }
            }

            extinct_species.Sort();

            // Build embed.

            Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder();
            List <EmbedBuilder>         pages = new List <EmbedBuilder>();
            List <string> field_lines         = new List <string>();

            if (new_species.Count() > 0)
            {
                foreach (Species sp in new_species)
                {
                    field_lines.Add(sp.FullName);
                }

                EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("New species ({0})", new_species.Count()));

                field_lines.Clear();
            }

            if (extinct_species.Count() > 0)
            {
                foreach (Species sp in extinct_species)
                {
                    field_lines.Add(sp.FullName);
                }

                EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("Extinctions ({0})", extinct_species.Count()));

                field_lines.Clear();
            }

            embed.AddPages(pages);

            embed.SetTitle(string.Format("Recent events ({0})", time_amount.ToString()));
            embed.SetFooter(string.Empty); // remove page numbers added automatically
            embed.AddPageNumbers();

            if (embed.FieldCount <= 0)
            {
                embed.SetDescription("No events");
            }

            return(embed);
        }
示例#14
0
        private async Task _endBattle(ICommandContext context)
        {
            PlayerState winner = player1.Gotchi.Stats.Hp <= 0.0 ? player2 : player1;
            PlayerState loser  = player1.Gotchi.Stats.Hp <= 0.0 ? player1 : player2;

            // Calculate the amount of EXP awarded to the winner.
            // The loser will get 50% of the winner's EXP.

            double exp = _getExpEarned(winner.Gotchi.Gotchi, loser.Gotchi.Gotchi, won: true);

            double exp1 = player2.Gotchi.Stats.Hp <= 0.0 ? exp : exp * .5;
            double exp2 = player1.Gotchi.Stats.Hp <= 0.0 ? exp : exp * .5;

            long levels1 = player1.Gotchi.Stats.AddExperience((int)exp1);
            long levels2 = player2.Gotchi.Stats.AddExperience((int)exp2);

            StringBuilder sb = new StringBuilder();

            sb.AppendLine(battleText);

            // Show the winner's accomplishments, then the loser's.

            if (!IsCpuGotchi(winner.Gotchi.Gotchi))
            {
                double winner_exp    = winner.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? exp1 : exp2;
                long   winner_levels = winner.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? levels1 : levels2;
                long   winner_g      = (long)Math.Round(loser.Gotchi.Stats.Level * (BotUtils.RandomInteger(150, 200) / 100.0));

                sb.AppendLine(string.Format("🏆 **{0}** won the battle! Earned **{1} EXP** and **{2}G**.",
                                            winner.Gotchi.Gotchi.Name,
                                            winner_exp,
                                            winner_g));

                if (winner_levels > 0)
                {
                    sb.AppendLine(string.Format("🆙 **{0}** leveled up to level **{1}**!", winner.Gotchi.Gotchi.Name, winner.Gotchi.Stats.Level));
                }

                if (((winner.Gotchi.Stats.Level - winner_levels) / 10) < (winner.Gotchi.Stats.Level / 10))
                {
                    if (await GotchiUtils.EvolveAndUpdateGotchiAsync(winner.Gotchi.Gotchi))
                    {
                        Species sp = await BotUtils.GetSpeciesFromDb(winner.Gotchi.Gotchi.SpeciesId);

                        sb.AppendLine(string.Format("🚩 Congratulations, **{0}** evolved into **{1}**!", winner.Gotchi.Gotchi.Name, sp.ShortName));
                    }
                }

                // Update the winner's G.

                GotchiUserInfo user_data = await GotchiUtils.GetUserInfoAsync(winner.Gotchi.Gotchi.OwnerId);

                user_data.G += winner_g;

                await GotchiUtils.UpdateUserInfoAsync(user_data);

                sb.AppendLine();
            }

            if (!IsCpuGotchi(loser.Gotchi.Gotchi))
            {
                double loser_exp    = loser.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? exp1 : exp2;
                long   loser_levels = loser.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? levels1 : levels2;

                sb.AppendLine(string.Format("💀 **{0}** lost the battle... Earned **{1} EXP**.", loser.Gotchi.Gotchi.Name, loser_exp));

                if (loser_levels > 0)
                {
                    sb.AppendLine(string.Format("🆙 **{0}** leveled up to level **{1}**!", loser.Gotchi.Gotchi.Name, loser.Gotchi.Stats.Level));
                }

                if (((loser.Gotchi.Stats.Level - loser_levels) / 10) < (loser.Gotchi.Stats.Level / 10))
                {
                    if (await GotchiUtils.EvolveAndUpdateGotchiAsync(loser.Gotchi.Gotchi))
                    {
                        Species sp = await BotUtils.GetSpeciesFromDb(loser.Gotchi.Gotchi.SpeciesId);

                        sb.AppendLine(string.Format("🚩 Congratulations, **{0}** evolved into **{1}**!", loser.Gotchi.Gotchi.Name, sp.ShortName));
                    }
                }
            }

            // Update exp in the database.

            using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Gotchi SET level=$level, exp=$exp WHERE id=$id;")) {
                cmd.Parameters.AddWithValue("$id", player1.Gotchi.Gotchi.Id);
                cmd.Parameters.AddWithValue("$level", DBNull.Value);
                cmd.Parameters.AddWithValue("$exp", player1.Gotchi.Stats.Experience);

                await Database.ExecuteNonQuery(cmd);
            }

            if (!IsCpuGotchi(player2.Gotchi.Gotchi))
            {
                using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Gotchi SET level=$level, exp=$exp WHERE id=$id;")) {
                    cmd.Parameters.AddWithValue("$id", player2.Gotchi.Gotchi.Id);
                    cmd.Parameters.AddWithValue("$level", DBNull.Value);
                    cmd.Parameters.AddWithValue("$exp", player2.Gotchi.Stats.Experience);

                    await Database.ExecuteNonQuery(cmd);
                }
            }

            // Deregister the battle state.

            DeregisterBattle(context.User.Id);

            battleText = sb.ToString();
        }
        public static async Task <bool> EvolveAndUpdateGotchiAsync(Gotchi gotchi, string desiredEvo)
        {
            bool evolved = false;

            if (string.IsNullOrEmpty(desiredEvo))
            {
                // Find all descendatants of this species.

                using (SQLiteCommand cmd = new SQLiteCommand("SELECT species_id FROM Ancestors WHERE ancestor_id=$ancestor_id;")) {
                    List <long> descendant_ids = new List <long>();

                    cmd.Parameters.AddWithValue("$ancestor_id", gotchi.SpeciesId);

                    using (DataTable rows = await Database.GetRowsAsync(cmd))
                        foreach (DataRow row in rows.Rows)
                        {
                            descendant_ids.Add(row.Field <long>("species_id"));
                        }

                    // Pick an ID at random.

                    if (descendant_ids.Count > 0)
                    {
                        gotchi.SpeciesId = descendant_ids[BotUtils.RandomInteger(descendant_ids.Count)];

                        evolved = true;
                    }
                }
            }
            else
            {
                // Get the desired evo.
                Species[] sp = await BotUtils.GetSpeciesFromDb("", desiredEvo);

                if (sp is null || sp.Length != 1)
                {
                    return(false);
                }

                // Ensure that the species evolves into the desired evo.

                using (SQLiteCommand cmd = new SQLiteCommand("SELECT COUNT(*) FROM Ancestors WHERE ancestor_id = $ancestor_id AND species_id = $species_id")) {
                    cmd.Parameters.AddWithValue("$ancestor_id", gotchi.SpeciesId);
                    cmd.Parameters.AddWithValue("$species_id", sp[0].Id);

                    if (await Database.GetScalar <long>(cmd) <= 0)
                    {
                        return(false);
                    }

                    gotchi.SpeciesId = sp[0].Id;

                    evolved = true;
                }
            }

            // Update the gotchi in the database.

            using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Gotchi SET species_id=$species_id, evolved_ts=$evolved_ts WHERE id=$id;")) {
                cmd.Parameters.AddWithValue("$species_id", gotchi.SpeciesId);

                // The "last evolved" timestamp is now only updated in the event the gotchi evolves (in order to make the "IsEvolved" check work correctly).
                // Note that this means that the background service will attempt to evolve the gotchi at every iteration (unless it evolves by leveling).

                if (evolved)
                {
                    cmd.Parameters.AddWithValue("$evolved_ts", DateTimeOffset.UtcNow.ToUnixTimeSeconds());
                }

                cmd.Parameters.AddWithValue("$id", gotchi.Id);

                await Database.ExecuteNonQuery(cmd);
            }

            return(evolved);
        }