예제 #1
0
        /// <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);
        }