protected override void GetDisplayContent(DiscordTarget target, out List <Tuple <string, DiscordLinkEmbed> > tagAndContent)
        {
            tagAndContent = new List <Tuple <string, DiscordLinkEmbed> >();
            DiscordLinkEmbed embed = new DiscordLinkEmbed();

            embed.WithFooter(MessageBuilder.Discord.GetStandardEmbedFooter());
            foreach (Election election in EcoUtil.ActiveElections)
            {
                string tag = $"{BaseTag} [{election.Id}]";
                embed.WithTitle(MessageUtil.StripTags(election.Name));

                // Proposer name
                embed.AddField("Proposer", election.Creator.Name);

                // Time left
                embed.AddField("Time Left", TimeFormatter.FormatSpan(election.TimeLeft));

                // Process
                embed.AddField("Process", MessageUtil.StripTags(election.Process.Name));

                // Choices
                if (!election.BooleanElection && election.Choices.Count > 0)
                {
                    string choiceDesc = string.Empty;
                    foreach (ElectionChoice choice in election.Choices)
                    {
                        choiceDesc += $"{choice.Name}\n";
                    }
                    embed.AddField("Choices", choiceDesc);
                }

                // Votes
                string voteDesc = string.Empty;
                if (!election.Process.AnonymousVoting)
                {
                    foreach (RunoffVote vote in election.Votes)
                    {
                        string topChoiceName = null;
                        int    topChoiceID   = vote.RankedVotes.FirstOrDefault();
                        foreach (ElectionChoice choice in election.Choices)
                        {
                            if (choice.ID == topChoiceID)
                            {
                                topChoiceName = choice.Name;
                                break;
                            }
                        }
                        voteDesc += $"{vote.Voter.Name} : {topChoiceName}\n";
                    }
                }
                else
                {
                    voteDesc = "--- Anonymous Voting ---";
                }

                if (string.IsNullOrEmpty(voteDesc))
                {
                    voteDesc = "--- No Votes Recorded ---";
                }

                embed.AddField($"Votes ({election.TotalVotes})", voteDesc);

                if (embed.Fields.Count > 0)
                {
                    tagAndContent.Add(new Tuple <string, DiscordLinkEmbed>(tag, new DiscordLinkEmbed(embed)));
                }

                embed.ClearFields();
            }
        }
        protected override void GetDisplayContent(DiscordTarget target, out List <Tuple <string, DiscordLinkEmbed> > tagAndContent)
        {
            tagAndContent = new List <Tuple <string, DiscordLinkEmbed> >();
            DiscordLinkEmbed embed       = new DiscordLinkEmbed();
            List <WorkParty> workParties = Registrars.Get <WorkParty>().All <WorkParty>().NonNull().Where(x => x.State == ProposableState.Active).ToList();

            foreach (WorkParty workParty in workParties)
            {
                string tag = $"{BaseTag} [{workParty.Id}]";
                embed.WithTitle(MessageUtil.StripTags(workParty.Name));
                embed.WithFooter(MessageBuilder.Discord.GetStandardEmbedFooter());

                // Workers
                string workersDesc = string.Empty;
                foreach (Laborer laborer in workParty.Laborers)
                {
                    if (laborer.Citizen == null)
                    {
                        continue;
                    }
                    string creator = (laborer.Citizen == workParty.Creator) ? "Creator" : string.Empty;
                    workersDesc += $"{laborer.Citizen.Name} ({creator})\n";
                }

                if (string.IsNullOrWhiteSpace(workersDesc))
                {
                    workersDesc += "--- No Workers Registered ---";
                }
                embed.AddField("Workers", workersDesc);

                // Work
                foreach (Work work in workParty.Work)
                {
                    string        workDesc    = string.Empty;
                    string        workType    = string.Empty;
                    List <string> workEntries = new List <string>();
                    switch (work)
                    {
                    case LaborWork laborWork:
                    {
                        if (!string.IsNullOrEmpty(laborWork.ShortDescriptionRemainingWork))
                        {
                            workType = $"Labor for {laborWork.Order.Recipe.RecipeName}";
                            workEntries.Add(MessageUtil.StripTags(laborWork.ShortDescriptionRemainingWork));
                        }
                        break;
                    }

                    case WorkOrderWork orderWork:
                    {
                        workType = $"Materials for {orderWork.Order.Recipe.RecipeName}";
                        foreach (TagStack stack in orderWork.Order.MissingIngredients)
                        {
                            string itemName = string.Empty;
                            if (stack.Item != null)
                            {
                                itemName = stack.Item.DisplayName;
                            }
                            else if (stack.StackObject != null)
                            {
                                itemName = stack.StackObject.DisplayName;
                            }
                            workEntries.Add($"{itemName} ({stack.Quantity})");
                        }
                        break;
                    }

                    default:
                        break;
                    }

                    if (workEntries.Count > 0)
                    {
                        foreach (string material in workEntries)
                        {
                            workDesc += $"- {material}\n";
                        }

                        if (!string.IsNullOrWhiteSpace(workDesc))
                        {
                            string percentDone = (work.PercentDone * 100.0f).ToString("N1", CultureInfo.InvariantCulture).Replace(".0", "");
                            embed.AddField($"\n {workType} (Weight: {work.Weight.ToString("F1")}) ({percentDone}% completed) \n", workDesc);
                        }
                    }
                }

                // Payment
                string paymentDesc = string.Empty;
                foreach (Payment payment in workParty.Payment)
                {
                    string desc = string.Empty;
                    switch (payment)
                    {
                    case CurrencyPayment currencyPayment:
                    {
                        float currencyAmountLeft = currencyPayment.Amount - currencyPayment.AmountPaid;
                        if (currencyAmountLeft > 0.0f)
                        {
                            desc = $"Receive **{currencyAmountLeft.ToString("F1")} {currencyPayment.Currency.Name}**"
                                   + (currencyPayment.PayType == PayType.SplitByWorkPercent ? ", split based on work performed" : ", split evenly")
                                   + (currencyPayment.PayAsYouGo ? ", paid as work is performed." : ", paid when the project finishes.");
                        }
                        break;
                    }

                    case GrantTitlePayment titlePayment:
                    {
                        desc = $"Receive title `{MessageUtil.StripTags(titlePayment.Title.Name)}` if work contributed is at least *{titlePayment.MinContributedPercent.ToString("F1")}%*.";
                        break;
                    }

                    case KnowledgeSharePayment knowledgePayment:
                    {
                        if (knowledgePayment.Skills.Entries.Count > 0)
                        {
                            desc = $"Receive knowledge of `{MessageUtil.StripTags(knowledgePayment.ShortDescription())}` if work contributed is at least *{knowledgePayment.MinContributedPercent.ToString("F1")}%*.";
                        }
                        break;
                    }

                    case ReputationPayment reputationPayment:
                    {
                        float reputationAmountLeft = reputationPayment.Amount - reputationPayment.AmountPaid;
                        desc = $"Receive **{reputationAmountLeft.ToString("F1")} reputation** from *{workParty.Creator.Name}*"
                               + (reputationPayment.PayType == PayType.SplitByWorkPercent ? ", split based on work performed" : ", split evenly")
                               + (reputationPayment.PayAsYouGo ? ", paid as work is performed." : ", paid when the project finishes.");
                        break;
                    }

                    default:
                        break;
                    }

                    if (!string.IsNullOrEmpty(desc))
                    {
                        paymentDesc += $"- {desc}\n";
                    }
                }

                if (!string.IsNullOrWhiteSpace(paymentDesc))
                {
                    embed.AddField("Payment", paymentDesc);
                }

                if (embed.Fields.Count > 0)
                {
                    tagAndContent.Add(new Tuple <string, DiscordLinkEmbed>(tag, new DiscordLinkEmbed(embed)));
                }

                embed.ClearFields();
            }
        }
예제 #3
0
        public static List <DiscordEmbed> BuildDiscordEmbeds(DiscordLinkEmbed fullEmbed)
        {
            List <DiscordEmbed> resultEmbeds = new List <DiscordEmbed>();

            if (fullEmbed == null)
            {
                return(resultEmbeds);
            }

            // Count chars needed for title and footer
            int titleFooterCharCount = 0;

            if (fullEmbed.Title != null)
            {
                titleFooterCharCount += fullEmbed.Title.Length;
            }
            if (fullEmbed.Footer != null)
            {
                titleFooterCharCount += fullEmbed.Footer.Length;
            }

            int totalCharsCount = titleFooterCharCount;

            // Count chars needed for fields and track fields that are too long
            List <bool> needsSplitFields = Enumerable.Repeat(false, fullEmbed.Fields.Count).ToList();

            for (int i = 0; i < fullEmbed.Fields.Count; ++i)
            {
                DiscordLinkEmbedField field = fullEmbed.Fields[i];
                int length = field.Title.Length + field.Text.Length;
                if (length > DLConstants.DISCORD_EMBED_FIELD_CHARACTER_LIMIT)
                {
                    needsSplitFields[i] = true;
                }

                totalCharsCount += length;
            }

            // Early escape if no splitting is needed
            if (totalCharsCount <= DLConstants.DISCORD_EMBED_TOTAL_CHARACTER_LIMIT && needsSplitFields.Count <= 0)
            {
                resultEmbeds.Add(BuildDiscordEmbed(fullEmbed));
                return(resultEmbeds);
            }

            // Split too long fields
            List <DiscordLinkEmbedField> splitFields = new List <DiscordLinkEmbedField>();

            for (int i = 0; i < fullEmbed.Fields.Count; ++i)
            {
                DiscordLinkEmbedField field = fullEmbed.Fields[i];
                if (needsSplitFields[i] == true)
                {
                    IEnumerable <string> splits = SplitStringBySize(field.Text, DLConstants.DISCORD_EMBED_FIELD_CHARACTER_LIMIT);
                    int partCount = 1;
                    foreach (string fieldSplit in splits)
                    {
                        splitFields.Add(new DiscordLinkEmbedField($"{field.Title} ({partCount})", fieldSplit));
                        ++partCount;
                    }
                }
                else
                {
                    splitFields.Add(new DiscordLinkEmbedField(fullEmbed.Fields[i].Title, fullEmbed.Fields[i].Text));
                }
            }

            // Create new embeds that fit within the char limits
            List <DiscordLinkEmbed> splitEmbeds       = new List <DiscordLinkEmbed>();
            DiscordLinkEmbed        splitEmbedBuilder = new DiscordLinkEmbed(fullEmbed);

            splitEmbedBuilder.ClearFields();
            int characterCount = 0;
            int fieldCount     = 0;

            foreach (DiscordLinkEmbedField field in splitFields)
            {
                // If adding the next field would bring us over a limit, split into new embeds
                if (characterCount + field.Text.Length > DLConstants.DISCORD_EMBED_TOTAL_CHARACTER_LIMIT || fieldCount + 1 > DLConstants.DISCORD_EMBED_FIELD_COUNT_LIMIT)
                {
                    splitEmbeds.Add(new DiscordLinkEmbed(splitEmbedBuilder));
                    splitEmbedBuilder.ClearFields();
                    characterCount = 0;
                    fieldCount     = 0;
                }

                splitEmbedBuilder.AddField(field.Title, field.Text);
                characterCount += field.Text.Length;
                ++fieldCount;
            }
            splitEmbeds.Add(splitEmbedBuilder);

            // Convert embeds to actual DSharp Discord embeds
            foreach (DiscordLinkEmbed embedData in splitEmbeds)
            {
                resultEmbeds.Add(BuildDiscordEmbed(embedData));
            }

            return(resultEmbeds);
        }