/// <summary> /// Generate a stats image for the given Country, showing production /// output percentages and damage/output graphs. /// </summary> /// <param name="imgmap">An ImageMap on which to add tooltips.</param> /// <param name="country">The reference Country.</param> /// <returns>The image to display.</returns> private Image GenerateImage(ImageMap.ImageMap imgmap, Country country) { // get sorted list of factories to display List <Factory> countryFactorys = new List <Factory>(); foreach (Factory factory in game.Factories.Values) { if (factory.Country == country) { countryFactorys.Add(factory); } } countryFactorys.Sort(); // determine wether to show RDP info bool showRDP = true; if (country.RDPGoal <= 0) { showRDP = false; } else { foreach (Factory factory in countryFactorys) { if (factory.TotalProduced == 0 || factory.Ticks.Count == 0) { showRDP = false; } } } // create bitmap, graphics objects const int width = 334; int height = 25 * countryFactorys.Count; if (showRDP) { height += 20; } Bitmap bitmap = new Bitmap(width, height); Graphics g = Graphics.FromImage(bitmap); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int y = -22; imgmap.RemoveAll(); // remove previous tooltips // create graphics resources Brush brushHead = new SolidBrush(Color.FromArgb(224, 224, 224)); Brush brushMain = new SolidBrush(Color.FromArgb(192, 192, 192)); Brush brushPieLight = Brushes.CornflowerBlue; Brush brushPieDark = Brushes.MediumBlue; Font fontMain = new Font("Tahoma", 8.25F); Font fontHead = new Font("Tahoma", 8.25F, FontStyle.Bold); Font fontRDP = new Font("Tahoma", 7.5F); Pen penLine = new Pen(Color.FromArgb(75, 75, 75)); StringFormat alignCenter = new StringFormat { Alignment = StringAlignment.Center }; // rdp summary if (showRDP) { y += 20; // calc percent complete int totalPointsCampaign = 0; foreach (Factory factory in countryFactorys) { totalPointsCampaign += factory.TotalProduced; } int totalPointsThisCycle = totalPointsCampaign - country.RDPPrevCyclePoints; if (totalPointsThisCycle > country.RDPGoal) { totalPointsThisCycle = country.RDPGoal; // cycle finished } float percentComplete = ((float)totalPointsThisCycle / (float)country.RDPGoal) * 100; // calc eta int totalPointsRemaining = country.RDPGoal - totalPointsThisCycle; DateTime cycleCompleted = CalcRdpEstimatedCompletion(countryFactorys, totalPointsRemaining); // draw stuff, add tooltips g.DrawLine(penLine, 0, 20, 334, 20); if (cycleCompleted == DateTime.MaxValue) // never { g.DrawString(String.Format(Language.FactoryStatus_RDPCycleNoEta, country.NextRDPCycle, percentComplete.ToString("0.00")), fontHead, brushMain, 167, 3, alignCenter); imgmap.AddRectangle(Language.FactoryStatus_Tooltip_AllFactoriesCaptured, new Rectangle(230, 5, 90, 10)); } else { g.DrawString(String.Format(Language.FactoryStatus_RDPCycle, country.NextRDPCycle, percentComplete.ToString("0.00"), Misc.MinsUntilShort(cycleCompleted)), fontHead, brushMain, 167, 3, alignCenter); imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_EstimatedCompletion, cycleCompleted.ToString("ddd, d MMM, h:mm tt")), new Rectangle(230, 5, 90, 10)); } imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_RdpPoints, totalPointsThisCycle, country.RDPGoal), new Rectangle(110, 5, 100, 10)); } // factory loop foreach (Factory factory in countryFactorys) { y += 25; // draw heading/parent chokepoint int x_indent = 0; if (factory.Owner.Side != country.Side) // not original side, indent and draw flag { x_indent = 15; g.DrawImage(factory.Owner.CountryFlag, 2F, y + 3.5F, 12, 7.125F); } string factoryName = Regex.Replace(factory.Name, @"^\S+\s", ""); // remove eg, "British " g.DrawString(factoryName, fontHead, brushHead, x_indent, y); g.DrawString(factory.ChokePoint.Name, fontMain, brushMain, x_indent + 10, y + 11); if (factory.Ticks.Count == 0) { continue; // skip if no data } // draw rdp output percent pie & bar graph g.FillRectangle(brushPieDark, 137, y + 1, 6, 20); float rdpBarHeight = (factory.OutputPercentPastDay * 20F) / 100F; g.FillRectangle(brushPieLight, 137, y + 1 + 20 - rdpBarHeight, 6, rdpBarHeight); imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_OutputDay, factory.OutputPercentPastDay), new Rectangle(137, y + 1, 6, 20)); g.FillEllipse(brushPieDark, 147, y + 1, 20, 20); int angle = (int)((factory.OutputPercentCampaign * 360F) / 100F); g.FillPie(brushPieLight, 147, y + 1, 20, 20, -90, angle); imgmap.AddElipse(String.Format(Language.FactoryStatus_Tooltip_OutputCampaign, factory.OutputPercentCampaign), 157, y + 11, 10); // draw rdp output percentages g.DrawString(factory.OutputPercentPastDay + "%", fontMain, brushMain, 185, y, alignCenter); g.DrawString(factory.OutputPercentCampaign + "%", fontMain, brushPieLight, 185, y + 11, alignCenter); imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_OutputDay, factory.OutputPercentPastDay), new Rectangle(171, y + 2, 29, 10)); imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_OutputCampaign, factory.OutputPercentCampaign), new Rectangle(171, y + 13, 29, 10)); // draw damage & rdp 24-hour graph int rdpHeight = -1; // 0-5, rdp=1 => ++, rdp=0 => -- for (int i = 0; i < factory.Ticks.Count; i++) // should be <= 96 { // damage graph float damagePercent = factory.Ticks[i].Damage / 100F; float barHeight = 10F - (10F * damagePercent); Pen penDamage = new Pen(Misc.BlendColour(Color.FromArgb(0, 150, 0), Color.Red, damagePercent)); g.DrawLine(penDamage, 204 + i, y + 12, 204 + i, y + 12 - barHeight); // rdp graph if (rdpHeight == -1) // first tick { rdpHeight = factory.Ticks[i].RDP == 0 ? 0 : 5; } else if (factory.Ticks[i].RDP == 0 && rdpHeight > 0) { rdpHeight--; } else if (factory.Ticks[i].RDP == 1 && rdpHeight < 5) { rdpHeight++; } g.DrawLine(Pens.Gray, 204 + i, y + 21, 204 + i, y + 21 - rdpHeight); g.DrawLine(Pens.White, 204 + i, y + 21 - rdpHeight, 204 + i, y + 21 - rdpHeight - 1); } imgmap.AddRectangle(Language.FactoryStatus_Tooltip_GraphDamage, new Rectangle(204, y + 2, 96, 11)); imgmap.AddRectangle(Language.FactoryStatus_Tooltip_GraphOutput, new Rectangle(204, y + 15, 96, 7)); // draw damage percent, rdp flag g.DrawString(factory.CurrentHealth + "%", fontMain, brushMain, 317, y, alignCenter); imgmap.AddRectangle(String.Format(Language.FactoryStatus_Tooltip_CurrentHealth, factory.CurrentHealth), new Rectangle(303, y + 2, 29, 10)); Brush brushRDP = new SolidBrush(factory.CurrentRDP ? Color.FromArgb(0, 150, 0) : Color.Red); g.DrawString("RDP", fontRDP, brushRDP, 317, y + 12, alignCenter); imgmap.AddRectangle((factory.CurrentRDP ? Language.FactoryStatus_Tooltip_RdpOn : Language.FactoryStatus_Tooltip_RdpOff), new Rectangle(307, y + 14, 20, 10)); } // end factory loop g.Dispose(); return(bitmap); }