/// <summary> /// Popup a tool tip for the provided skill, above the given point. /// </summary> /// <param name="skill">Skill to display</param> public void Display(QueuedSkill skill, Point pt) { string format = "{0} {1}\n Start{2}\t{3}\n Ends\t{4}"; string skillName = skill.SkillName; string skillLevel = Skill.GetRomanForInt(skill.Level); string skillStart = (skill.Owner.IsTraining ? skill.StartTime.ToLocalTime().ToAbsoluteDateTimeDescription(DateTimeKind.Local) : "Paused"); string skillEnd = (skill.Owner.IsTraining ? skill.EndTime.ToLocalTime().ToAbsoluteDateTimeDescription(DateTimeKind.Local) : "Paused"); string startText = (skill.StartTime < DateTime.UtcNow ? "ed" : "s"); string text = String.Format(CultureConstants.DefaultCulture, format, skillName, skillLevel, startText, skillStart, skillEnd); Display(text, pt); }
/// <summary> /// Creates a TXT format file for character exportation. /// </summary> /// <param name="character"></param> /// <param name="plan"></param> public static string ExportAsText(Character character, Plan plan) { string Separator = "======================================================================="; string SubSeparator = "-----------------------------------------------------------------------"; StringBuilder builder = new StringBuilder(); builder.AppendLine("BASIC INFO"); builder.AppendLine(Separator); builder.AppendFormat(CultureConstants.DefaultCulture, " Name: {0}{1}", character.Name, Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Gender: {0}{1}", character.Gender, Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Race: {0}{1}", character.Race, Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, "Bloodline: {0}{1}", character.Bloodline, Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Balance: {0} ISK{1}", character.Balance.ToString("#,##0.00"), Environment.NewLine); builder.AppendLine(); builder.AppendFormat(CultureConstants.DefaultCulture, "Intelligence: {0}{1}", character.Intelligence.EffectiveValue.ToString("#0.00").PadLeft(5), Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Charisma: {0}{1}", character.Charisma.EffectiveValue.ToString("#0.00").PadLeft(5), Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Perception: {0}{1}", character.Perception.EffectiveValue.ToString("#0.00").PadLeft(5), Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Memory: {0}{1}", character.Memory.EffectiveValue.ToString("#0.00").PadLeft(5), Environment.NewLine); builder.AppendFormat(CultureConstants.DefaultCulture, " Willpower: {0}{1}", character.Willpower.EffectiveValue.ToString("#0.00").PadLeft(5), Environment.NewLine); builder.AppendLine(); // Implants var implants = character.CurrentImplants.Where(x => x != Implant.None && (int)x.Slot < 5); if (implants.Count() > 0) { builder.AppendLine("IMPLANTS"); builder.AppendLine(Separator); foreach (var implant in implants) { builder.AppendFormat(CultureConstants.DefaultCulture, "+{0} {1} : {2}{3}", implant.Bonus, implant.Slot.ToString().PadRight(13), implant.Name, Environment.NewLine); } builder.AppendLine(); } // Skill groups builder.AppendLine("SKILLS"); builder.AppendLine(Separator); foreach (var skillGroup in character.SkillGroups) { int count = skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x))).Select(x => GetMergedSkill(plan, x)).Count(); int skillGroupTotalSP = skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x))).Select(x => GetMergedSkill(plan, x)).Sum(x => x.Skillpoints); // Skill Group builder.AppendFormat(CultureConstants.DefaultCulture, "{0}, {1} Skill{2}, {3} Points{4}", skillGroup.Name, count, count > 1 ? "s" : String.Empty, skillGroupTotalSP.ToString("#,##0"), Environment.NewLine); // Skills foreach (var skill in skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x)))) { var mergedSkill = GetMergedSkill(plan, skill); string skillDesc = String.Format(CultureConstants.DefaultCulture, "{0} ({1})", skill.ToString(), skill.Rank.ToString()); builder.AppendFormat(CultureConstants.DefaultCulture, ": {0} L{1} {2}/{3} Points{4}", skillDesc.PadRight(45), mergedSkill.Level.ToString().PadRight(5), mergedSkill.Skillpoints.ToString("#,##0"), skill.StaticData.GetPointsRequiredForLevel(5).ToString("#,##0"), Environment.NewLine); // If the skill is in training... if (skill.IsTraining) { DateTime adjustedEndTime = character.CurrentlyTrainingSkill.EndTime.ToLocalTime(); builder.AppendFormat(CultureConstants.DefaultCulture, ": (Currently training to level {0}, completes {1}){2}", Skill.GetRomanForInt(character.CurrentlyTrainingSkill.Level), adjustedEndTime, Environment.NewLine); } } builder.AppendLine(SubSeparator); } return(builder.ToString()); }
/// <summary> /// Creates a HTML format file for character exportation. /// </summary> /// <param name="character"></param> /// <param name="plan"></param> public static string ExportAsHTML(Character character, Plan plan) { // Retrieves a XML representation of this character var serial = new OutputCharacter(); serial.Name = character.Name; serial.Balance = character.Balance; serial.CorporationName = character.CorporationName; serial.CharacterID = character.CharacterID; serial.BloodLine = character.Bloodline; serial.Gender = character.Gender; serial.Race = character.Race; serial.Intelligence = character.Intelligence.EffectiveValue; serial.Perception = character.Perception.EffectiveValue; serial.Willpower = character.Willpower.EffectiveValue; serial.Charisma = character.Charisma.EffectiveValue; serial.Memory = character.Memory.EffectiveValue; // Attributes enhancers foreach (var implant in character.CurrentImplants.Where(x => x != Implant.None && (int)x.Slot < 5)) { serial.AttributeEnhancers.Add(new OutputAttributeEnhancer { Attribute = implant.Slot, Bonus = implant.Bonus, Name = implant.Name }); } // Certificates foreach (var certClass in character.CertificateClasses) { var cert = certClass.HighestClaimedGrade; if (cert == null) { continue; } serial.Certificates.Add(new OutputCertificate { Name = certClass.Name, Grade = cert.Grade.ToString() }); } // Skills (grouped by skill groups) foreach (var skillGroup in character.SkillGroups) { int count = skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x))).Select(x => GetMergedSkill(plan, x)).Count(); int skillGroupTotalSP = skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x))).Select(x => GetMergedSkill(plan, x)).Sum(x => x.Skillpoints); var outGroup = new OutputSkillGroup { Name = skillGroup.Name, SkillsCount = count, TotalSP = skillGroupTotalSP }; foreach (var skill in skillGroup.Where(x => x.IsKnown || (plan != null && plan.IsPlanned(x)))) { var mergedSkill = GetMergedSkill(plan, skill); outGroup.Skills.Add(new OutputSkill { Name = mergedSkill.Name, Rank = skill.Rank, Level = mergedSkill.Level, SkillPoints = mergedSkill.Skillpoints, RomanLevel = Skill.GetRomanForInt(mergedSkill.Level), MaxSkillPoints = skill.StaticData.GetPointsRequiredForLevel(5) }); } if (outGroup.Skills.Count != 0) { serial.SkillGroups.Add(outGroup); } } // Serializes to XML and apply a XSLT to generate the HTML doc var doc = Util.SerializeToXmlDocument(typeof(OutputCharacter), serial); var xslt = Util.LoadXSLT(Properties.Resources.XmlToHtmlXslt); var htmlDoc = Util.Transform(doc, xslt); // Returns the string representation of the generated doc return(Util.GetXMLStringRepresentation(htmlDoc)); }
/// <summary> /// Notifies a character finished training a skill. /// </summary> /// <param name="account"></param> internal void NotifySkillCompletion(CCPCharacter character, QueuedSkill skill) { var notification = new Notification(NotificationCategory.SkillCompletion, character); notification.Description = String.Format("{0} {1} completed.", skill.Skill.Name, Skill.GetRomanForInt(skill.Level)); notification.Behaviour = NotificationBehaviour.Cohabitate; notification.Priority = NotificationPriority.Information; Notify(notification); }
/// <summary> /// Sends a mail alert for a skill completion /// </summary> /// <param name="queueList">Current Skill Queue</param> /// <param name="skill">Skill that has just completed</param> /// <param name="character">Character affected</param> /// <returns></returns> public static bool SendSkillCompletionMail(IList <QueuedSkill> queueList, QueuedSkill skill, Character character) { CCPCharacter ccpCharacter = character as CCPCharacter; // Current character isn't a CCP character, so can't have a Queue. if (ccpCharacter == null) { return(false); } string charName = character.Name; string skillName = skill.SkillName; string skillLevelString = Skill.GetRomanForInt(skill.Level); var skillQueueEndTime = ccpCharacter.SkillQueue.EndTime; bool freeTime = skillQueueEndTime < DateTime.UtcNow.AddHours(24); TimeSpan timeLeft = DateTime.UtcNow.AddHours(24).Subtract(skillQueueEndTime); string timeLeftText = timeLeft.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas, false); // Message's first line StringBuilder body = new StringBuilder(); body.AppendFormat(CultureConstants.DefaultCulture, "{0} has finished training {1} {2}.{3}{3}", charName, skillName, skillLevelString, Environment.NewLine); // Next skills in queue if (queueList[0] != null) { body.AppendFormat(CultureConstants.DefaultCulture, "Next skill{0} in queue:{1}", (queueList.Count > 1 ? "s" : String.Empty), Environment.NewLine); foreach (var qskill in queueList) { body.AppendFormat(CultureConstants.DefaultCulture, "- {0}{1}", qskill, Environment.NewLine); } body.AppendLine(); } else { body.AppendFormat(CultureConstants.DefaultCulture, "Character is not training.{0}{0}", Environment.NewLine); } // Free room in skill queue if (freeTime) { body.AppendFormat(CultureConstants.DefaultCulture, "There is also {0} free room in skill queue.{1}", timeLeftText, Environment.NewLine); } // Short format (also for SMS) if (Settings.Notifications.UseEmailShortFormat) { return(SendMail(Settings.Notifications, String.Format(CultureConstants.DefaultCulture, "[STC] {0} :: {1} {2}", charName, skillName, skillLevelString), body.ToString())); } // Long format if (character.Plans.Count > 0) { body.AppendFormat(CultureConstants.DefaultCulture, "Next skills listed in plans:{0}{0}", Environment.NewLine); } foreach (var plan in character.Plans) { if (plan.Count > 0) { // Print plan name CharacterScratchpad scratchpad = new CharacterScratchpad(character); body.AppendFormat(CultureConstants.DefaultCulture, "{0}:{1}", plan.Name, Environment.NewLine); // Scroll through entries int i = 0; int minDays = 1; foreach (PlanEntry entry in plan) { TimeSpan trainTime = scratchpad.GetTrainingTime(entry.Skill, entry.Level, TrainingOrigin.FromPreviousLevelOrCurrent); // Only print the first three skills, and the very long skills // (first limit is one day, then we add skills duration) if (++i <= 3 || trainTime.Days > minDays) { if (i > 3) { // Print long message once if (minDays == 1) { body.AppendFormat(CultureConstants.DefaultCulture, "{1}Longer skills from {0}:{1}", plan.Name, Environment.NewLine); } minDays = trainTime.Days + minDays; } body.AppendFormat(CultureConstants.DefaultCulture, "\t{0}", entry); // Notes if (entry.Notes != null && entry.Notes.Length > 0) { body.AppendFormat(CultureConstants.DefaultCulture, " ({0})", entry.Notes); } // Training time if (trainTime.Days > 0) { body.AppendFormat(CultureConstants.DefaultCulture, " - {0}d, {1}", trainTime.Days, trainTime); } else { body.AppendFormat(CultureConstants.DefaultCulture, " - {0}", trainTime); } body.AppendLine(); } } body.AppendLine(); } } string subject = String.Format(CultureConstants.DefaultCulture, "{0} has finished training {1} {2}", charName, skillName, skillLevelString); return(SendMail(Settings.Notifications, subject, body.ToString())); }
/// <summary> /// Gets a string representation of this skill /// </summary> /// <returns></returns> public override string ToString() { return(String.Format("{0} {1}", SkillName, Skill.GetRomanForInt(m_level))); }
/// <summary> /// Exports the plan under a text format. /// </summary> /// <param name="planToExport"></param> /// <param name="settings"></param> /// <param name="exportActions"></param> /// <returns></returns> public static string ExportAsText(Plan planToExport, PlanExportSettings settings, ExportPlanEntryActions exportActions) { var plan = new PlanScratchpad(planToExport.Character, planToExport); plan.Sort(planToExport.SortingPreferences); plan.UpdateStatistics(); var builder = new StringBuilder(); var timeFormat = DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText; var character = (Character)plan.Character; // Initialize constants string lineFeed = Environment.NewLine; string boldStart = String.Empty; string boldEnd = String.Empty; switch (settings.Markup) { default: break; case MarkupType.Forum: boldStart = "[b]"; boldEnd = "[/b]"; break; case MarkupType.Html: lineFeed = String.Format(CultureInfo.InvariantCulture, "<br />{0}", Environment.NewLine); boldStart = "<b>"; boldEnd = "</b>"; break; } // Header if (settings.IncludeHeader) { builder.Append(boldStart); if (settings.ShoppingList) { builder.AppendFormat(CultureConstants.DefaultCulture, "Shopping list for {0}", character.Name); } else { builder.AppendFormat(CultureConstants.DefaultCulture, "Skill plan for {0}", character.Name); } builder.Append(boldEnd); builder.Append(lineFeed); builder.Append(lineFeed); } // Scroll through entries int index = 0; DateTime endTime = DateTime.Now; foreach (PlanEntry entry in plan) { // Remapping point if (!settings.ShoppingList && entry.Remapping != null) { builder.AppendFormat(CultureConstants.DefaultCulture, "***{0}***", entry.Remapping); builder.Append(lineFeed); } // Skip is we're only build a shopping list bool shoppingListCandidate = !(entry.CharacterSkill.IsKnown || entry.Level != 1 || entry.CharacterSkill.IsOwned); if (settings.ShoppingList && !shoppingListCandidate) { continue; } // Entry's index index++; if (settings.EntryNumber) { builder.AppendFormat(CultureConstants.DefaultCulture, "{0}. ", index); } // Name builder.Append(boldStart); if (settings.Markup.Equals(MarkupType.Html)) { if (!settings.ShoppingList) { builder.AppendFormat(CultureConstants.DefaultCulture, "<a href=\"\" onclick=\"CCPEVE.showInfo({0})\">", entry.Skill.ID); } else { builder.AppendFormat(CultureConstants.DefaultCulture, "<a href=\"\" onclick=\"CCPEVE.showMarketDetails({0})\">", entry.Skill.ID); } } builder.Append(entry.Skill.Name); if (settings.Markup == MarkupType.Html) { builder.Append("</a>"); } if (!settings.ShoppingList) { builder.AppendFormat(CultureConstants.DefaultCulture, " {0}", Skill.GetRomanForInt(entry.Level)); } builder.Append(boldEnd); // Training time if (settings.EntryTrainingTimes || settings.EntryStartDate || settings.EntryFinishDate || (settings.EntryCost && shoppingListCandidate)) { builder.Append(" ("); bool needComma = false; // Training time if (settings.EntryTrainingTimes) { needComma = true; builder.Append(entry.TrainingTime.ToDescriptiveText(timeFormat)); } // Training start date if (settings.EntryStartDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Start: {0}", entry.StartTime); } // Training end date if (settings.EntryFinishDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Finish: {0}", entry.EndTime); } // Skill cost if (settings.EntryCost && shoppingListCandidate) { if (needComma) { builder.Append("; "); } needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "{0} ISK", entry.Skill.FormattedCost); } builder.Append(')'); } if (exportActions != null) { exportActions(builder, entry, settings); } builder.Append(lineFeed); // End time endTime = entry.EndTime; } // Footer if (settings.FooterCount || settings.FooterTotalTime || settings.FooterDate || settings.FooterCost) { builder.AppendLine(lineFeed); bool needComma = false; // Skills count if (settings.FooterCount) { builder.AppendFormat(CultureConstants.DefaultCulture, "{0}{1}{2}", boldStart, index, boldEnd); builder.Append((index == 1 ? " skill" : " skills")); needComma = true; } // Plan's training duration if (settings.FooterTotalTime) { if (needComma) { builder.Append("; "); } needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Total time: {0}{1}{2}", boldStart, plan.GetTotalTime(null, true).ToDescriptiveText(timeFormat), boldEnd); } // End training date if (settings.FooterDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.AppendFormat(CultureConstants.DefaultCulture, "Completion: {0}{1}{2}", boldStart, endTime, boldEnd); } // Total books cost if (settings.FooterCost) { if (needComma) { builder.Append("; "); } needComma = true; string formattedIsk = String.Format(CultureConstants.TidyInteger, "{0:n}", plan.NotKnownSkillBooksCost); builder.AppendFormat(CultureConstants.DefaultCulture, "Cost: {0}{1}{2}", boldStart, formattedIsk, boldEnd); } // Warning about skill costs builder.Append(lineFeed); if (settings.FooterCost || settings.EntryCost) { builder.Append("N.B. Skill costs are based on CCP's database and are indicative only"); } } // Returns the text representation. return(builder.ToString()); }
/// <summary> /// Sens a mail alert for a skill completion /// </summary> /// <param name="skillLevel"></param> /// <param name="skillName"></param> /// <param name="character"></param> /// <returns></returns> public static bool SendSkillCompletionMail(int skillLevel, string skillName, Character character) { string charName = character.Name; string skillLevelString = Skill.GetRomanForInt(skillLevel); // Message's first line StringBuilder messageText = new StringBuilder(); messageText.Append(charName + " has finished training " + skillName + " "); // Short format (also for SMS) if (Settings.Notifications.UseEmailShortFormat) { return(SendMail(Settings.Notifications, "[STC] " + charName + " :: " + skillName + " " + skillLevelString, messageText.ToString())); } // Long format messageText.Append("\r\n\r\nNext skills listed in plans:\r\n\r\n"); foreach (var plan in character.Plans) { if (plan.Count > 0) { // Print plan name CharacterScratchpad scratchpad = new CharacterScratchpad(character); messageText.Append(plan.Name + ":\r\n"); // Scroll through entries int i = 0; int minDays = 1; foreach (PlanEntry entry in plan) { TimeSpan trainTime = scratchpad.GetTrainingTime(entry.Skill, entry.Level, TrainingOrigin.FromPreviousLevelOrCurrent); // Only print the first three skills, and the very long skills (first limit is one day, then we add skills duration if (++i <= 3 || trainTime.Days > minDays) { if (i > 3) { // Print long message once if (minDays == 1) { messageText.Append("\r\n" + "Longer skills from " + plan.Name + ":\r\n"); } minDays = trainTime.Days + minDays; } messageText.Append("\t" + entry.ToString()); // Notes if (entry.Notes != null && entry.Notes.Length > 0) { messageText.Append(" (" + entry.Notes + ")"); } // Training time string timeText = String.Format("{0:00}:{1:00}:{2:00}", trainTime.Hours, trainTime.Minutes, trainTime.Seconds); if (trainTime.Days > 0) { messageText.Append(" - " + trainTime.Days + "d, " + timeText); } else { messageText.Append(" - " + timeText); } messageText.Append("\r\n"); } } messageText.Append("\r\n"); } } return(SendMail(Settings.Notifications, charName + " has finished training " + skillName + " " + skillLevelString, messageText.ToString())); }
/// <summary> /// Gets a string representation of this skill /// </summary> /// <returns></returns> public override string ToString() { return(SkillName + " " + Skill.GetRomanForInt(m_level)); }
/// <summary> /// /// </summary> /// <param name="character"></param> public static string ExportAsText(Character character) { StringBuilder builder = new StringBuilder(); builder.AppendLine("BASIC INFO"); builder.AppendLine(Separator); builder.AppendLine(String.Format(" Name: {0}", character.Name)); builder.AppendLine(String.Format(" Gender: {0}", character.Gender)); builder.AppendLine(String.Format(" Race: {0}", character.Race)); builder.AppendLine(String.Format("Bloodline: {0}", character.Bloodline)); builder.AppendLine(String.Format(" Balance: {0} ISK", character.Balance.ToString("#,##0.00"))); builder.AppendLine(); builder.AppendLine(String.Format("Intelligence: {0}", character.Intelligence.ToString("#0.00").PadLeft(5))); builder.AppendLine(String.Format(" Charisma: {0}", character.Charisma.ToString("#0.00").PadLeft(5))); builder.AppendLine(String.Format(" Perception: {0}", character.Perception.ToString("#0.00").PadLeft(5))); builder.AppendLine(String.Format(" Memory: {0}", character.Memory.ToString("#0.00").PadLeft(5))); builder.AppendLine(String.Format(" Willpower: {0}", character.Willpower.ToString("#0.00").PadLeft(5))); builder.AppendLine(); // Implants var implants = character.CurrentImplants.Where(x => x != Implant.None && (int)x.Slot < 5); if (implants.Count() > 0) { builder.AppendLine("IMPLANTS"); builder.AppendLine(Separator); foreach (var implant in implants) { builder.AppendLine(String.Format("+{0} {1} : {2}", implant.Bonus, implant.Slot.ToString().PadRight(13), implant.Name)); } builder.AppendLine(); } // Skill groups builder.AppendLine("SKILLS"); builder.AppendLine(Separator); foreach (var skillGroup in character.SkillGroups) { builder.AppendLine(String.Format("{0}, {1} Skill{2}, {3} Points", skillGroup.Name, skillGroup.Count, skillGroup.Count > 1 ? "s" : "", skillGroup.TotalSP.ToString("#,##0"))); // Skills foreach (var skill in skillGroup) { string skillDesc = skill.ToString() + " (" + skill.Rank.ToString() + ")"; builder.AppendLine(String.Format(": {0} {1}/{2} Points", skillDesc.PadRight(40), skill.SkillPoints.ToString("#,##0"), skill.StaticData.GetPointsRequiredForLevel(5).ToString("#,##0"))); // If the skill is in training... if (skill.IsTraining) { DateTime adjustedEndTime = character.CurrentlyTrainingSkill.EndTime.ToLocalTime(); builder.AppendLine(String.Format(": (Currently training to level {0}, completes {1})", Skill.GetRomanForInt(character.CurrentlyTrainingSkill.Level), adjustedEndTime)); } } builder.AppendLine(SubSeparator); } return(builder.ToString()); }
/// <summary> /// Exports the plan under a text format. /// </summary> /// <param name="planToExport"></param> /// <param name="settings"></param> /// <returns></returns> public static string ExportAsText(Plan planToExport, PlanExportSettings settings) { var plan = new PlanScratchpad(planToExport.Character, planToExport); plan.Sort(planToExport.SortingPreferences); plan.UpdateStatistics(); var builder = new StringBuilder(); var timeFormat = DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText; var character = (Character)plan.Character; // Initialize constants string lineFeed = ""; string boldStart = ""; string boldEnd = ""; switch (settings.Markup) { default: break; case MarkupType.Forum: boldStart = "[b]"; boldEnd = "[/b]"; break; case MarkupType.Html: lineFeed = "<br />"; boldStart = "<b>"; boldEnd = "</b>"; break; } // Header if (settings.IncludeHeader) { builder.Append(boldStart); if (settings.ShoppingList) { builder.Append("Shopping list for ").Append(character.Name); } else { builder.Append("Skill plan for ").Append(character.Name); } builder.Append(boldEnd); builder.AppendLine(lineFeed); builder.AppendLine(lineFeed); } // Scroll through entries int index = 0; DateTime endTime = DateTime.Now; foreach (PlanEntry entry in plan) { // Remapping point if (!settings.ShoppingList && entry.Remapping != null) { builder.Append("***").Append(entry.Remapping.ToString()).Append("***"); builder.AppendLine(lineFeed); } // Skip is we're only build a shopping list bool shoppingListCandidate = !(entry.CharacterSkill.IsKnown || entry.Level != 1 || entry.CharacterSkill.IsOwned); if (settings.ShoppingList && !shoppingListCandidate) { continue; } // Entry's index index++; if (settings.EntryNumber) { builder.Append(index.ToString()).Append(". "); } // Name builder.Append(boldStart); if (settings.Markup == MarkupType.Html) { builder.Append("<a href=\"\" onclick=\"CCPEVE.showInfo(").Append(entry.Skill.ID.ToString()).Append(")\">"); } builder.Append(entry.Skill.Name); if (settings.Markup == MarkupType.Html) { builder.Append("</a>"); } if (!settings.ShoppingList) { builder.Append(' ').Append(Skill.GetRomanForInt(entry.Level)); } builder.Append(boldEnd); // Training time if (settings.EntryTrainingTimes || settings.EntryStartDate || settings.EntryFinishDate || (settings.EntryCost && shoppingListCandidate)) { builder.Append(" ("); bool needComma = false; // Training time if (settings.EntryTrainingTimes) { needComma = true; builder.Append(Skill.TimeSpanToDescriptiveText(entry.TrainingTime, timeFormat)); } // Training start date if (settings.EntryStartDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Start: ").Append(entry.StartTime.ToString()); } // Training end date if (settings.EntryFinishDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Finish: ").Append(entry.EndTime.ToString()); } // Skill cost if (settings.EntryCost && shoppingListCandidate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append(entry.Skill.FormattedCost + " ISK"); } builder.Append(')'); } builder.AppendLine(lineFeed); // End time endTime = entry.EndTime; } // Footer if (settings.FooterCount || settings.FooterTotalTime || settings.FooterDate || settings.FooterCost) { builder.AppendLine(lineFeed); bool needComma = false; // Skills count if (settings.FooterCount) { builder.Append(boldStart).Append(index.ToString()).Append(boldEnd); builder.Append((index == 1 ? " skill" : " skills")); needComma = true; } // Plan's training duration if (settings.FooterTotalTime) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Total time: "); builder.Append(boldStart); builder.Append(Skill.TimeSpanToDescriptiveText(plan.GetTotalTime(null, true), timeFormat)); builder.Append(boldEnd); } // End training date if (settings.FooterDate) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Completion: "); builder.Append(boldStart).Append(endTime.ToString()).Append(boldEnd); } // Total books cost if (settings.FooterCost) { if (needComma) { builder.Append("; "); } needComma = true; builder.Append("Cost: "); builder.Append(boldStart); builder.Append((plan.TotalBooksCost == 0 ? "0 ISK" : String.Format("{0:0,0,0} ISK", plan.TotalBooksCost))); builder.Append(boldEnd); } // Warning about skill costs builder.AppendLine(lineFeed); if (settings.FooterCost || settings.EntryCost) { builder.Append("N.B. Skill costs are based on CCP's database and are indicative only"); builder.AppendLine(lineFeed); } } // Returns the text representation. return(builder.ToString()); }