Esempio n. 1
0
        // Draw icons in city resources (surplus < 0 is hunger)
        public static void CityResources(Graphics g, City city, int cityZoom, Point dest)
        {
            var fontSize = cityZoom == -1 ? 4 : (cityZoom == 0 ? 9 : 13);

            using var _font = new Font("Arial", fontSize, FontStyle.Bold);

            // Get normal zoom from city zoom (-1/0/1)
            int zoom = cityZoom * 4;

            // FOOD
            // Text
            var _txtFrame = new Rectangle(dest.X + 203.ZoomScale(4 * cityZoom), dest.Y + 61.ZoomScale(4 * cityZoom), 228.ZoomScale(4 * cityZoom), 12.ZoomScale(4 * cityZoom));

            Draw.Text(g, $"Food: {city.Food}", _font, Color.FromArgb(87, 171, 39), _txtFrame, FormattedTextAlignment.Left, Colors.Black, 1, 1);
            Draw.Text(g, $"Surplus: {city.SurplusHunger}", _font, Color.FromArgb(63, 139, 31), _txtFrame, FormattedTextAlignment.Right, Colors.Black, 1, 1);
            // Number of food+surplus/hunger icons determines spacing between icons
            int spacing;

            switch (city.Food + Math.Abs(city.SurplusHunger))
            {
            case int n when(n >= 1 && n <= 15): spacing = 15; break;         // norm=15, big=23, gap=1px

            case int n when(n == 16 || n == 17): spacing = 13; break;        // norm=13, big=20, overlap=1px

            case int n when(n == 18 || n == 19): spacing = 11; break;        // norm=11, big=17, overlap=3px

            case int n when(n == 20 || n == 21): spacing = 10; break;        // norm=10, big=15, overlap=4px

            case int n when(n == 22 || n == 23): spacing = 9; break;         // norm=9, big=14, overlap=5px

            case int n when(n == 24 || n == 25): spacing = 8; break;         // norm=8, big=12, overlap=6px

            case int n when(n >= 26 && n <= 29): spacing = 7; break;         // norm=7, big=11, overlap=7px

            case int n when(n >= 30 && n <= 33): spacing = 6; break;         // norm=6, big=9, overlap=8px

            case int n when(n >= 34 && n <= 37): spacing = 5; break;         // norm=5, big=8, overlap=9px

            case int n when(n >= 38 && n <= 49): spacing = 4; break;         // norm=4, big=6, overlap=10px

            case int n when(n >= 50 && n <= 65): spacing = 3; break;         // norm=3, big=5, overlap=11px

            case int n when(n >= 66): spacing = 2; break;                    // norm=2, big=3, overlap=12px

            default: spacing = 2; break;
            }
            spacing = (int)(spacing * (1 + ((float)zoom / 8.0)));   // Make spacing city zoom dependent
            // TODO: Draw background rectangle
            //g.FillRectangle(new SolidBrush(Color.FromArgb(71, 147, 31)), 0, 0, spacing * city.Food + 21 - spacing + 6, 23); // Background square for food
            //g.FillRectangle(new SolidBrush(Color.FromArgb(55, 123, 23)), x_size - (spacing * Math.Abs(city.SurplusHunger) + 21 - spacing + 3),
            //    0, spacing * Math.Abs(city.SurplusHunger) + 21 - spacing + 6, 23); // Background square for surplus/hunger
            // Icons
            for (int i = 0; i < city.Food; i++)
            {
                g.DrawImage(CityImages.FoodBig.Resize(zoom), dest.X + 206 * (2 + cityZoom) / 2 + i * spacing, dest.Y + 76 * (2 + cityZoom) / 2);
            }
            for (int i = 0; i < Math.Abs(city.SurplusHunger); i++)
            {
                if (city.SurplusHunger < 0)
                {
                    g.DrawImage(CityImages.HungerBig.Resize(zoom), dest.X + (431 - (spacing * Math.Abs(city.SurplusHunger) + 14 - spacing) + i * spacing) * (2 + cityZoom) / 2, dest.Y + 76 * (2 + cityZoom) / 2);                         // Hunger
                }
                else
                {
                    g.DrawImage(CityImages.FoodBig.Resize(zoom), dest.X + (431 - (spacing * Math.Abs(city.SurplusHunger) + 14 - spacing) + i * spacing) * (2 + cityZoom) / 2, dest.Y + 76 * (2 + cityZoom) / 2);  // Surplus
                }
            }

            // TRADE
            // Text
            _txtFrame = new Rectangle(dest.X + 203 * (2 + cityZoom) / 2, dest.Y + 102 * (2 + cityZoom) / 2, 228 * (2 + cityZoom) / 2, 12 * (2 + cityZoom) / 2);
            Draw.Text(g, $"Trade: {city.Trade}", _font, Color.FromArgb(239, 159, 7), _txtFrame, FormattedTextAlignment.Left, Colors.Black, 1, 1);
            Draw.Text(g, $"Corruption: {city.Corruption}", _font, Color.FromArgb(227, 83, 15), _txtFrame, FormattedTextAlignment.Right, Colors.Black, 1, 1);
            // Spacing between icons
            switch (city.Trade + city.Corruption)
            {
            case int n when(n >= 1 && n <= 15): spacing = 15; break;         // norm=15, big=23, gap=1px

            case int n when(n == 16 || n == 17): spacing = 13; break;        // norm=13, big=20, overlap=1px

            case int n when(n == 18 || n == 19): spacing = 11; break;        // norm=11, big=17, overlap=3px

            case int n when(n == 20 || n == 21): spacing = 10; break;        // norm=10, big=15, overlap=4px

            case int n when(n == 22 || n == 23): spacing = 9; break;         // norm=9, big=14, overlap=5px

            case int n when(n == 24 || n == 25): spacing = 8; break;         // norm=8, big=12, overlap=6px

            case int n when(n >= 26 && n <= 29): spacing = 7; break;         // norm=7, big=11, overlap=7px

            case int n when(n >= 30 && n <= 33): spacing = 6; break;         // norm=6, big=9, overlap=8px

            case int n when(n >= 34 && n <= 37): spacing = 5; break;         // norm=5, big=8, overlap=9px

            case int n when(n >= 38 && n <= 49): spacing = 4; break;         // norm=4, big=6, overlap=10px

            case int n when(n >= 50 && n <= 65): spacing = 3; break;         // norm=3, big=5, overlap=11px

            case int n when(n >= 66): spacing = 2; break;                    // norm=2, big=3, overlap=12px

            default: spacing = 2; break;
            }
            spacing = (int)(spacing * (1 + ((float)zoom / 8.0)));   // Make spacing city zoom dependent
            // TODO: Draw background rectangle
            //g.FillRectangle(new SolidBrush(Color.FromArgb(71, 147, 31)), 0, 0, spacing * foodIcons + 21 - spacing + 6, 23); //background square for food
            //g.FillRectangle(new SolidBrush(Color.FromArgb(55, 123, 23)), x_size - (spacing * Math.Abs(surplusIcons) + 21 - spacing + 3), 0, spacing * Math.Abs(surplusIcons) + 21 - spacing + 6, 23); //background square for surplus/hunger
            // Icons
            for (int i = 0; i < city.Trade; i++)
            {
                g.DrawImage(CityImages.TradeBig.Resize(zoom), dest.X + 206 * (2 + cityZoom) / 2 + i * spacing, dest.Y + 117 * (2 + cityZoom) / 2);
            }
            for (int i = 0; i < city.Corruption; i++)
            {
                g.DrawImage(CityImages.CorruptBig.Resize(zoom), dest.X + (431 - (spacing * city.Corruption + 14 - spacing) + i * spacing) * (2 + cityZoom) / 2, dest.Y + 117 * (2 + cityZoom) / 2);
            }

            // TAX+LUX+SCI
            // Text
            _txtFrame = new Rectangle(dest.X + 204 * (2 + cityZoom) / 2, dest.Y + 156 * (2 + cityZoom) / 2, 228 * (2 + cityZoom) / 2, 12 * (2 + cityZoom) / 2);
            Draw.Text(g, $"50% Tax: {city.Tax}", _font, Color.FromArgb(239, 159, 7), _txtFrame, FormattedTextAlignment.Left, Colors.Black, 1, 1);
            Draw.Text(g, $"0% Lux: {city.Lux}", _font, Colors.White, _txtFrame, FormattedTextAlignment.Center, Colors.Black, 1, 1);
            Draw.Text(g, $"50% Sci: {city.Science}", _font, Color.FromArgb(63, 187, 199), _txtFrame, FormattedTextAlignment.Right, Colors.Black, 1, 1);
            // Spacing between icons
            switch (city.Tax + city.Lux + city.Science)
            {
            case int n when(n >= 1 && n <= 15): spacing = 15; break;         // norm=15, big=23, gap=1px

            case int n when(n == 16 || n == 17): spacing = 13; break;        // norm=13, big=20, overlap=1px

            case int n when(n == 18 || n == 19): spacing = 11; break;        // norm=11, big=17, overlap=3px

            case int n when(n == 20 || n == 21): spacing = 10; break;        // norm=10, big=15, overlap=4px

            case int n when(n == 22 || n == 23): spacing = 9; break;         // norm=9, big=14, overlap=5px

            case int n when(n == 24 || n == 25): spacing = 8; break;         // norm=8, big=12, overlap=6px

            case int n when(n >= 26 && n <= 29): spacing = 7; break;         // norm=7, big=11, overlap=7px

            case int n when(n >= 30 && n <= 33): spacing = 6; break;         // norm=6, big=9, overlap=8px

            case int n when(n >= 34 && n <= 37): spacing = 5; break;         // norm=5, big=8, overlap=9px

            case int n when(n >= 38 && n <= 49): spacing = 4; break;         // norm=4, big=6, overlap=10px

            case int n when(n >= 50 && n <= 65): spacing = 3; break;         // norm=3, big=5, overlap=11px

            case int n when(n >= 66): spacing = 2; break;                    // norm=2, big=3, overlap=12px

            default: spacing = 2; break;
            }
            spacing = (int)(spacing * (1 + ((float)zoom / 8.0)));   // Make spacing city zoom dependent
            // TODO: Draw background rectangle
            //g.FillRectangle(new SolidBrush(Color.FromArgb(71, 147, 31)), 0, 0, spacing * foodIcons + 21 - spacing + 6, 23); //background square for food
            //g.FillRectangle(new SolidBrush(Color.FromArgb(55, 123, 23)), x_size - (spacing * Math.Abs(surplusIcons) + 21 - spacing + 3), 0, spacing * Math.Abs(surplusIcons) + 21 - spacing + 6, 23); //background square for surplus/hunger
            // Icons
            for (int i = 0; i < city.Tax; i++)
            {
                g.DrawImage(CityImages.TaxBig.Resize(zoom), dest.X + 206 * (2 + cityZoom) / 2 + i * spacing, dest.Y + 141 * (2 + cityZoom) / 2);
            }
            for (int i = 0; i < city.Lux; i++)
            {
                g.DrawImage(CityImages.LuxBig.Resize(zoom), dest.X + 290 * (2 + cityZoom) / 2 + i * spacing, dest.Y + 141 * (2 + cityZoom) / 2);
            }
            for (int i = 0; i < city.Science; i++)
            {
                g.DrawImage(CityImages.SciBig.Resize(zoom), dest.X + (431 - (spacing * city.Science + 14 - spacing) + i * spacing) * (2 + cityZoom) / 2, dest.Y + 141 * (2 + cityZoom) / 2);
            }

            // SUPPORT+PRODUCTION
            // Text
            _txtFrame = new Rectangle(dest.X + 204 * (2 + cityZoom) / 2, dest.Y + 196 * (2 + cityZoom) / 2, 228 * (2 + cityZoom) / 2, 12 * (2 + cityZoom) / 2);
            Draw.Text(g, $"Support: {city.Support}", _font, Color.FromArgb(63, 79, 167), _txtFrame, FormattedTextAlignment.Left, Colors.Black, 1, 1);
            Draw.Text(g, $"Production: {city.Production}", _font, Color.FromArgb(7, 11, 103), _txtFrame, FormattedTextAlignment.Right, Colors.Black, 1, 1);
            // Spacing between icons
            switch (city.Support + city.Production)
            {
            case int n when(n >= 1 && n <= 15): spacing = 15; break;         // norm=15, big=23, gap=1px

            case int n when(n == 16 || n == 17): spacing = 13; break;        // norm=13, big=20, overlap=1px

            case int n when(n == 18 || n == 19): spacing = 11; break;        // norm=11, big=17, overlap=3px

            case int n when(n == 20 || n == 21): spacing = 10; break;        // norm=10, big=15, overlap=4px

            case int n when(n == 22 || n == 23): spacing = 9; break;         // norm=9, big=14, overlap=5px

            case int n when(n == 24 || n == 25): spacing = 8; break;         // norm=8, big=12, overlap=6px

            case int n when(n >= 26 && n <= 29): spacing = 7; break;         // norm=7, big=11, overlap=7px

            case int n when(n >= 30 && n <= 33): spacing = 6; break;         // norm=6, big=9, overlap=8px

            case int n when(n >= 34 && n <= 37): spacing = 5; break;         // norm=5, big=8, overlap=9px

            case int n when(n >= 38 && n <= 49): spacing = 4; break;         // norm=4, big=6, overlap=10px

            case int n when(n >= 50 && n <= 65): spacing = 3; break;         // norm=3, big=5, overlap=11px

            case int n when(n >= 66): spacing = 2; break;                    // norm=2, big=3, overlap=12px

            default: spacing = 2; break;
            }
            spacing = (int)(spacing * (1 + ((float)zoom / 8.0)));   // Make spacing city zoom dependent
            // TODO: Draw background rectangle
            //g.FillRectangle(new SolidBrush(Color.FromArgb(71, 147, 31)), 0, 0, spacing * foodIcons + 21 - spacing + 6, 23); //background square for food
            //g.FillRectangle(new SolidBrush(Color.FromArgb(55, 123, 23)), x_size - (spacing * Math.Abs(surplusIcons) + 21 - spacing + 3), 0, spacing * Math.Abs(surplusIcons) + 21 - spacing + 6, 23); //background square for surplus/hunger
            // Icons
            for (int i = 0; i < city.Support; i++)
            {
                g.DrawImage(CityImages.SupportBig.Resize(zoom), dest.X + 206 * (2 + cityZoom) / 2 + i * spacing, dest.Y + 181 * (2 + cityZoom) / 2);
            }
            for (int i = 0; i < city.Production; i++)
            {
                g.DrawImage(CityImages.SupportBig.Resize(zoom), dest.X + (431 - (spacing * city.Production + 14 - spacing) + i * spacing) * (2 + cityZoom) / 2, dest.Y + 181 * (2 + cityZoom) / 2);
            }
        }
Esempio n. 2
0
        private void Surface_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.AntiAlias = false;

            // Inner wallpaper
            e.Graphics.DrawImage(Images.ExtractBitmap(DLLs.Tiles, "defenseMinWallpaper").CropImage(new Rectangle(0, 0, 600, 400)),
                                 new Rectangle(11, 11, 600, 400));

            // Text
            var font1     = new Font("Times New Roman", 14);
            var cycleText = showCasualties ? "Casualties" : "Statistics";

            Draw.Text(e.Graphics, $"DEFENSE MINISTER: {cycleText}", font1, Color.FromArgb(223, 223, 223),
                      new Point(300, 24), true, true, Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"Holy Empire of the {Game.GetActiveCiv.Adjective}", font1, Color.FromArgb(223, 223, 223),
                      new Point(300, 45), true, true, Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"{Game.GetActiveCiv.LeaderTitle} {Game.GetActiveCiv.LeaderName}: {Game.GetGameYearString}",
                      font1, Color.FromArgb(223, 223, 223), new Point(300, 66), true, true, Color.FromArgb(67, 67, 67), 2, 1);

            if (!showCasualties)
            {
                // Unit types
                var drawnUnits = unitStatDefs.Skip(barVal0).Take(12).ToList();
                for (int i = 0; i < drawnUnits.Count; i++)
                {
                    var unitDef = drawnUnits[i];
                    var font    = new Font("Times New Roman", 11, FontStyle.Bold);

                    // Unit image
                    Draw.UnitShield(e.Graphics, unitDef.Type, Game.GetActiveCiv.Id, OrderType.NoOrders, false, 100, 100, 0,
                                    new Point(13 + 64 * ((barVal0 + i + 1) % 2), 78 + 24 * i));
                    Draw.UnitSprite(e.Graphics, unitDef.Type, false, false, 0, new Point(13 + 64 * ((barVal0 + i + 1) % 2), 78 + 24 * i));

                    // Unit name
                    Draw.Text(e.Graphics, unitDef.Name, font, Color.FromArgb(223, 223, 223),
                              new Point(149, 95 + 24 * i), false, false, Color.FromArgb(67, 67, 67), 1, 1);

                    // Stats
                    Draw.Text(e.Graphics, $"{unitDef.Attack}/{unitDef.Defense}/{unitDef.Move / 3}", font, Color.FromArgb(223, 223, 223),
                              new Point(245, 95 + 24 * i), false, false, Color.FromArgb(67, 67, 67), 1, 1);
                    Draw.Text(e.Graphics, $"{unitDef.Hitp / 10}/{unitDef.Firepwr}", font, Color.FromArgb(223, 223, 223),
                              new Point(300, 95 + 24 * i), false, false, Color.FromArgb(67, 67, 67), 1, 1);

                    var unitNo = Game.GetActiveCiv.Units.Where(u => u.Type == unitDef.Type).Count();
                    Draw.Text(e.Graphics, $"{unitNo} active", font, Color.FromArgb(255, 223, 79),
                              new Point(332, 95 + 24 * i), false, false, Colors.Black, 1, 1);

                    var unitInProdNo = Game.GetActiveCiv.Cities.Where(c => c.ItemInProduction.Type == ItemType.Unit &&
                                                                      Game.Rules.UnitTypes[c.ItemInProduction.ImageIndex].Type == unitDef.Type).Count();
                    if (unitInProdNo > 0)
                    {
                        Draw.Text(e.Graphics, $"{unitInProdNo} in prod", font, Color.FromArgb(63, 187, 199),
                                  new Point(393, 95 + 24 * i), false, false, Colors.Black, 1, 1);
                    }

                    // TODO: Add extra flags description
                }
            }
            else
            {
            }
        }
        private void Surface_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.AntiAlias = false;

            // Inner wallpaper
            e.Graphics.DrawImage(Images.ExtractBitmap(DLLs.Tiles, "attitudeAdvWallpaper").CropImage(new Rectangle(0, 0, 600, 400)), new Rectangle(11, 11, 600, 400));

            // Text
            var font1 = new Font("Times New Roman", 14);

            Draw.Text(e.Graphics, "ATTITUDE ADVISOR", font1, Color.FromArgb(223, 223, 223), new Point(300, 24), true, true, Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"Holy Empire of the {Game.GetActiveCiv.Adjective}", font1, Color.FromArgb(223, 223, 223),
                      new Point(300, 45), true, true, Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"{Game.GetActiveCiv.LeaderTitle} {Game.GetActiveCiv.LeaderName}: {Game.GetGameYearString}", font1, Color.FromArgb(223, 223, 223),
                      new Point(300, 66), true, true, Color.FromArgb(67, 67, 67), 2, 1);


            // Cities
            var drawnCities = Game.GetActiveCiv.Cities.Skip(barVal0).Take(9).ToList();

            for (int i = 0; i < drawnCities.Count; i++)
            {
                var city = drawnCities[i];
                var font = new Font("Times New Roman", 11, FontStyle.Bold);

                // City image
                Draw.City(e.Graphics, city, true, 0, new Point(13 + 64 * ((barVal0 + i + 1) % 2), 78 + 32 * i));

                // City name
                Draw.Text(e.Graphics, city.Name, font, Color.FromArgb(223, 223, 223),
                          new Point(149, 87 + 32 * i), false, false, Color.FromArgb(67, 67, 67), 1, 1);

                // People
                var spacing = city.Size switch
                {
                    int n when(n <= 10) => 28,
                    int n when(n == 11) => 27,
                    int n when(n == 12) => 25,
                    int n when(n == 13) => 23,
                    int n when(n == 14) => 21,
                    int n when(n == 15) => 19,
                    int n when(n == 16) => 18,
                    int n when(n == 17) => 17,
                    int n when(n == 18 || n == 19) => 15,
                    int n when(n == 20) => 14,
                    int n when(n == 21 || n == 22) => 13,
                    int n when(n == 23 || n == 24) => 12,
                    int n when(n == 25 || n == 26) => 11,
                    int n when(n == 27 || n == 28) => 10,
                    int n when(n >= 29 && n <= 31) => 9,
                    int n when(n >= 32 && n <= 35) => 8,
                    int n when(n >= 36 && n <= 40) => 7,
                    int n when(n >= 41 && n <= 47) => 6,
                    int n when(n >= 48 && n <= 56) => 5,
                    int n when(n >= 57 && n <= 70) => 4,
                    int n when(n >= 71 && n <= 93) => 3,
                    int n when(n >= 94) => 2,
                    _ => 28,
                };

                PeopleType[] peoples = city.People;
                var          offsetX = 254;
                int          drawIndex;
                for (int p = 0; p < city.Size; p++)
                {
                    drawIndex = (int)peoples[p];
                    if (p % 2 == 1 && (drawIndex == 0 || drawIndex == 2 || drawIndex == 4 || drawIndex == 6))
                    {
                        drawIndex++;  // Change men/woman appearance
                    }
                    var plpPic = CityImages.PeopleLarge[drawIndex, (int)city.Owner.Epoch];
                    e.Graphics.DrawImage(plpPic, offsetX + 5 + p * spacing, 81 + 32 * i);
                }
            }
        }
Esempio n. 4
0
        private void Surface_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.AntiAlias = false;

            // Paint outer wallpaper
            var imgSize = MapImages.PanelOuterWallpaper.Size;

            for (int row = 0; row < this.Height / imgSize.Height + 1; row++)
            {
                for (int col = 0; col < this.Width / imgSize.Width + 1; col++)
                {
                    e.Graphics.DrawImage(MapImages.PanelOuterWallpaper, col * imgSize.Width, row * imgSize.Height);
                }
            }

            // Paint panel borders
            // Outer border
            using var _pen1 = new Pen(Color.FromArgb(227, 227, 227));
            using var _pen2 = new Pen(Color.FromArgb(105, 105, 105));
            using var _pen3 = new Pen(Color.FromArgb(255, 255, 255));
            using var _pen4 = new Pen(Color.FromArgb(160, 160, 160));
            using var _pen5 = new Pen(Color.FromArgb(240, 240, 240));
            using var _pen6 = new Pen(Color.FromArgb(223, 223, 223));
            using var _pen7 = new Pen(Color.FromArgb(67, 67, 67));
            e.Graphics.DrawLine(_pen1, 0, 0, this.Width - 2, 0);   // 1st layer of border
            e.Graphics.DrawLine(_pen1, 0, 0, 0, this.Height - 2);
            e.Graphics.DrawLine(_pen2, this.Width - 1, 0, this.Width - 1, this.Height - 1);
            e.Graphics.DrawLine(_pen2, 0, this.Height - 1, this.Width - 1, this.Height - 1);
            e.Graphics.DrawLine(_pen3, 1, 1, this.Width - 3, 1);   // 2nd layer of border
            e.Graphics.DrawLine(_pen3, 1, 1, 1, this.Height - 3);
            e.Graphics.DrawLine(_pen4, this.Width - 2, 1, this.Width - 2, this.Height - 2);
            e.Graphics.DrawLine(_pen4, 1, this.Height - 2, this.Width - 2, this.Height - 2);
            e.Graphics.DrawLine(_pen5, 2, 2, this.Width - 4, 2);   // 3rd layer of border
            e.Graphics.DrawLine(_pen5, 2, 2, 2, this.Height - 4);
            e.Graphics.DrawLine(_pen5, this.Width - 3, 2, this.Width - 3, this.Height - 3);
            e.Graphics.DrawLine(_pen5, 2, this.Height - 3, this.Width - 3, this.Height - 3);
            e.Graphics.DrawLine(_pen6, 3, 3, this.Width - 5, 3);   // 4th layer of border
            e.Graphics.DrawLine(_pen6, 3, 3, 3, this.Height - 5);
            e.Graphics.DrawLine(_pen7, this.Width - 4, 3, this.Width - 4, this.Height - 4);
            e.Graphics.DrawLine(_pen7, 3, this.Height - 4, this.Width - 4, this.Height - 4);
            e.Graphics.DrawLine(_pen6, 4, 4, this.Width - 6, 4);   // 5th layer of border
            e.Graphics.DrawLine(_pen6, 4, 4, 4, this.Height - 6);
            e.Graphics.DrawLine(_pen7, this.Width - 5, 4, this.Width - 5, this.Height - 5);
            e.Graphics.DrawLine(_pen7, 4, this.Height - 5, this.Width - 5, this.Height - 5);

            // Inner border
            e.Graphics.DrawLine(_pen7, 9, _paddingTop - 1, 9 + (Width - 18 - 1), _paddingTop - 1);   // 1st layer of border
            e.Graphics.DrawLine(_pen7, 10, _paddingTop - 1, 10, Height - _paddingBtm - 1);
            e.Graphics.DrawLine(_pen6, Width - 11, _paddingTop - 1, Width - 11, Height - _paddingBtm - 1);
            e.Graphics.DrawLine(_pen6, 9, Height - _paddingBtm, Width - 9 - 1, Height - _paddingBtm);
            e.Graphics.DrawLine(_pen7, 10, _paddingTop - 2, 9 + (Width - 18 - 2), _paddingTop - 2);   // 2nd layer of border
            e.Graphics.DrawLine(_pen7, 9, _paddingTop - 2, 9, Height - _paddingBtm);
            e.Graphics.DrawLine(_pen6, Width - 10, _paddingTop - 2, Width - 10, Height - _paddingBtm);
            e.Graphics.DrawLine(_pen6, 9, Height - _paddingBtm + 1, Width - 9 - 1, Height - _paddingBtm + 1);

            // Paint inner wallpaper
            imgSize = MapImages.PanelInnerWallpaper.Size;
            Rectangle rectS;

            for (int row = 0; row < (this.Height - _paddingTop - _paddingBtm) / imgSize.Height + 1; row++)
            {
                for (int col = 0; col < (this.Width - 2 * 11) / imgSize.Width + 1; col++)
                {
                    rectS = new Rectangle(0, 0, Math.Min(this.Width - 2 * 11 - col * imgSize.Width, imgSize.Width), Math.Min(this.Height - _paddingBtm - _paddingTop - row * imgSize.Height, imgSize.Height));
                    e.Graphics.DrawImage(MapImages.PanelInnerWallpaper, rectS, new Point(col * imgSize.Width + 11, row * imgSize.Height + _paddingTop));
                }
            }

            // Paint title (if it exists)
            if (_title != null)
            {
                Draw.Text(e.Graphics, _title, new Font("Times new roman", 17, FontStyle.Bold), Color.FromArgb(135, 135, 135), new Point(this.Width / 2, _paddingTop / 2), true, true, Colors.Black, 1, 1);
            }
        }
        private void UnitPanel_Paint(object sender, PaintEventArgs e)
        {
            // Paint wallpaper
            var imgSize = Images.PanelInnerWallpaper.Size;

            for (int row = 0; row < this.Height / imgSize.Height + 1; row++)
            {
                for (int col = 0; col < this.Width / imgSize.Width + 1; col++)
                {
                    e.Graphics.DrawImage(Images.PanelInnerWallpaper, col * imgSize.Width, row * imgSize.Height);
                }
            }
            using var _font = new Font("Times new roman", 12, FontStyle.Bold);
            var          _frontColor      = Color.FromArgb(51, 51, 51);
            var          _backColor       = Color.FromArgb(191, 191, 191);
            List <IUnit> _unitsOnThisTile = Game.UnitsHere(Map.ActiveXY[0], Map.ActiveXY[1]);

            string _cityName, _wholeText, _roadText, _irrigText, _airbaseText;
            int    _column;

            // View piece mode
            if (Map.ViewPieceMode)
            {
                Draw.Text(e.Graphics, "Viewing Pieces", _font, Colors.White, new Point(119, 10), true, true, Colors.Black, 1, 0);

                // Draw location & tile type on active square
                Draw.Text(e.Graphics, $"Loc: ({Map.ActiveXY[0]}, {Map.ActiveXY[1]}) {Map.Tile[(Map.ActiveXY[0] - Map.ActiveXY[1] % 2) / 2, Map.ActiveXY[1]].Island}", _font, _frontColor, new Point(5, 27), false, false, _backColor, 1, 1);
                Draw.Text(e.Graphics, $"({Map.Tile[(Map.ActiveXY[0] - Map.ActiveXY[1] % 2) / 2, Map.ActiveXY[1]].Type})", _font, _frontColor, new Point(5, 45), false, false, _backColor, 1, 1);

                //int count;
                //for (count = 0; count < Math.Min(_unitsOnThisTile.Count, maxUnitsToDraw); count++)
                //{
                //    //e.Graphics.DrawImage(ModifyImage.Resize(Draw.Unit(UnitsOnThisTile[count], false, 0), (int)Math.Round(64 * 1.15), (int)Math.Round(48 * 1.15)), 6, 70 + count * 56);
                //    //e.Graphics.DrawImage(ModifyImage.Resize(Draw.Unit(UnitsOnThisTile[count], false, 0), 0), 6, 70 + count * 56);  // TODO: do this again!!!
                //    Draw.Text(e.Graphics, _unitsOnThisTile[count].HomeCity.Name, _font, StringAlignment.Near, StringAlignment.Near, _frontColor, new Point(79, 70 + count * 56), _backColor, 1, 1);
                //    Draw.Text(e.Graphics, _unitsOnThisTile[count].Order.ToString(), _font, StringAlignment.Near, StringAlignment.Near, _frontColor, new Point(79, 88 + count * 56), _backColor, 1, 1); // TODO: give proper conversion of orders to string
                //    Draw.Text(e.Graphics, _unitsOnThisTile[count].Name, _font, StringAlignment.Near, StringAlignment.Near, _frontColor, new Point(79, 106 + count * 56), _backColor, 1, 1);
                //}
                //if (count < _unitsOnThisTile.Count)
                //{
                //    string _moreUnits = (_unitsOnThisTile.Count - count == 1) ? "More Unit" : "More Units";
                //    Draw.Text(e.Graphics, $"({_unitsOnThisTile.Count() - count} {_moreUnits})", _font, StringAlignment.Near, StringAlignment.Near, _frontColor, new Point(5, UnitPanel.Height - 27), _backColor, 1, 1);
                //}
            }
            // Moving units mode
            else
            {
                Draw.Text(e.Graphics, "Moving Units", _font, Colors.White, new Point(119, 10), true, true, Colors.Black, 1, 0);

                // Show active unit info
                Draw.Unit(e.Graphics, Game.GetActiveUnit, false, 1, new Point(7, 27));
                // Show move points correctly
                int    _fullMovPts = Game.GetActiveUnit.MovePoints / 3;
                int    _remMovPts  = Game.GetActiveUnit.MovePoints % 3;
                string _text       = $"Moves: {_fullMovPts} {_remMovPts}/3";
                if (_remMovPts == 0)
                {
                    _text = $"Moves: {_fullMovPts}";
                }
                Draw.Text(e.Graphics, _text, _font, _frontColor, new Point(79, 25), false, false, _backColor, 1, 1);
                // Show other unit info
                _cityName = (Game.GetActiveUnit.HomeCity == null) ? "NONE" : Game.GetActiveUnit.HomeCity.Name;
                Draw.Text(e.Graphics, _cityName, _font, _frontColor, new Point(79, 43), false, false, _backColor, 1, 1);
                Draw.Text(e.Graphics, Game.GetActiveCiv.Adjective, _font, _frontColor, new Point(79, 61), false, false, _backColor, 1, 1);
                _column = 83;
                Draw.Text(e.Graphics, Game.GetActiveUnit.Name, _font, _frontColor, new Point(5, _column), false, false, _backColor, 1, 1);
                _column += 18;
                Draw.Text(e.Graphics, $"({Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Type})", _font, _frontColor, new Point(5, _column), false, false, _backColor, 1, 1);
                // If road/railroad/irrigation/farmland/mine present
                _wholeText = null;
                _roadText  = null;
                _irrigText = null;
                if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Road || Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Railroad || Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Irrigation || Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Farmland || Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Mining)
                {
                    _column += 18;
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Road)
                    {
                        _roadText = "Road";
                    }
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Railroad)
                    {
                        _roadText = "Railroad";
                    }
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Irrigation)
                    {
                        _irrigText = "Irrigation";
                    }
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Farmland)
                    {
                        _irrigText = "Farmland";
                    }
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Mining)
                    {
                        _irrigText = "Mining";
                    }
                    if (_roadText != null && _irrigText == null)
                    {
                        _wholeText = $"({_roadText})";
                    }
                    else if (_roadText == null && _irrigText != null)
                    {
                        _wholeText = $"({_irrigText})";
                    }
                    else if (_roadText != null && _irrigText != null)
                    {
                        _wholeText = $"({_roadText}, {_irrigText})";
                    }
                    Draw.Text(e.Graphics, _wholeText, _font, _frontColor, new Point(5, _column), false, false, _backColor, 1, 1);
                }
                // If airbase/fortress present
                _airbaseText = null;
                if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Airbase || Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Fortress)
                {
                    _column += 18;
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Fortress)
                    {
                        _airbaseText = "Fortress";
                    }
                    if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Airbase)
                    {
                        _airbaseText = "Airbase";
                    }
                    Draw.Text(e.Graphics, $"({_airbaseText})", _font, _frontColor, new Point(5, _column), false, false, _backColor, 1, 1);
                }
                // If pollution present
                if (Map.TileC2(Map.ActiveXY[0], Map.ActiveXY[1]).Pollution)
                {
                    _column += 18;
                    Draw.Text(e.Graphics, "(Pollution)", _font, _frontColor, new Point(5, _column), false, false, _backColor, 1, 1);
                }
                _column += 5;

                // Show info for other units on the tile
                int drawCount = 0;
                foreach (IUnit unit in _unitsOnThisTile.Where(u => u != Game.GetActiveUnit))
                {
                    // First check if there is vertical space still left for drawing in panel
                    if (_column + 69 > unitPanel.Height)
                    {
                        break;
                    }

                    // Draw unit
                    Draw.Unit(e.Graphics, unit, false, 1, new Point(7, _column + 27));
                    // Show other unit info
                    _column  += 20;
                    _cityName = (unit.HomeCity == null) ? "NONE" : Game.GetActiveUnit.HomeCity.Name;
                    Draw.Text(e.Graphics, _cityName, _font, _frontColor, new Point(80, _column), false, false, _backColor, 1, 1);
                    _column += 18;
                    Draw.Text(e.Graphics, Order2string(unit.Order), _font, _frontColor, new Point(80, _column), false, false, _backColor, 1, 1);
                    _column += 18;
                    Draw.Text(e.Graphics, unit.Name, _font, _frontColor, new Point(80, _column), false, false, _backColor, 1, 1);

                    //System.Diagnostics.Debug.WriteLine($"{unit.Name} drawn");

                    drawCount++;
                }

                // If not all units were drawn print a message
                if (_unitsOnThisTile.Count - 1 != drawCount)    // -1 because you must not count in active unit
                {
                    _column += 22;
                    _text    = _unitsOnThisTile.Count - 1 - drawCount == 1 ? "Unit" : "Units";
                    Draw.Text(e.Graphics, $"({_unitsOnThisTile.Count - 1 - drawCount} More {_text})", _font, _frontColor, new Point(9, _column), false, false, _backColor, 1, 1);
                }
            }

            //// Blinking "end of turn" message
            //if (WaitingAtEndOfTurn)
            //{
            //    using var _font2 = new Font("Times New Roman", 12, FontStyle.Bold);
            //    Color _EoTcolor = BoolSwitcher ? Color.White : Color.FromArgb(135, 135, 135);
            //    Draw.Text(e.Graphics, "End of Turn", _font2, StringAlignment.Near, StringAlignment.Near, _EoTcolor, new Point(5, UnitPanel.Height - 51), Color.Black, 1, 0);
            //    Draw.Text(e.Graphics, "(Press ENTER)", _font2, StringAlignment.Near, StringAlignment.Near, _EoTcolor, new Point(10, UnitPanel.Height - 33), Color.Black, 1, 0);
            //}
        }
        private void MainPanel_Paint(object sender, PaintEventArgs e)
        {
            // Paint wallpaper
            var imgSize = Images.PanelOuterWallpaper.Size;

            for (int row = 0; row < this.Height / imgSize.Height + 1; row++)
            {
                for (int col = 0; col < this.Width / imgSize.Width + 1; col++)
                {
                    e.Graphics.DrawImage(Images.PanelOuterWallpaper, col * imgSize.Width, row * imgSize.Height);
                }
            }
            // Paint title
            Draw.Text(e.Graphics, "Status", new Font("Times new roman", 17, FontStyle.Bold), Color.FromArgb(135, 135, 135), new Point(this.Width / 2, 38 / 2), true, true, Colors.Black, 1, 1);
            // Paint panel borders
            // Outer border
            using var _pen1 = new Pen(Color.FromArgb(227, 227, 227));
            using var _pen2 = new Pen(Color.FromArgb(105, 105, 105));
            using var _pen3 = new Pen(Color.FromArgb(255, 255, 255));
            using var _pen4 = new Pen(Color.FromArgb(160, 160, 160));
            using var _pen5 = new Pen(Color.FromArgb(240, 240, 240));
            using var _pen6 = new Pen(Color.FromArgb(223, 223, 223));
            using var _pen7 = new Pen(Color.FromArgb(67, 67, 67));
            e.Graphics.DrawLine(_pen1, 0, 0, this.Width - 2, 0);   // 1st layer of border
            e.Graphics.DrawLine(_pen1, 0, 0, 0, this.Height - 2);
            e.Graphics.DrawLine(_pen2, this.Width - 1, 0, this.Width - 1, this.Height - 1);
            e.Graphics.DrawLine(_pen2, 0, this.Height - 1, this.Width - 1, this.Height - 1);
            e.Graphics.DrawLine(_pen3, 1, 1, this.Width - 3, 1);   // 2nd layer of border
            e.Graphics.DrawLine(_pen3, 1, 1, 1, this.Height - 3);
            e.Graphics.DrawLine(_pen4, this.Width - 2, 1, this.Width - 2, this.Height - 2);
            e.Graphics.DrawLine(_pen4, 1, this.Height - 2, this.Width - 2, this.Height - 2);
            e.Graphics.DrawLine(_pen5, 2, 2, this.Width - 4, 2);   // 3rd layer of border
            e.Graphics.DrawLine(_pen5, 2, 2, 2, this.Height - 4);
            e.Graphics.DrawLine(_pen5, this.Width - 3, 2, this.Width - 3, this.Height - 3);
            e.Graphics.DrawLine(_pen5, 2, this.Height - 3, this.Width - 3, this.Height - 3);
            e.Graphics.DrawLine(_pen6, 3, 3, this.Width - 5, 3);   // 4th layer of border
            e.Graphics.DrawLine(_pen6, 3, 3, 3, this.Height - 5);
            e.Graphics.DrawLine(_pen7, this.Width - 4, 3, this.Width - 4, this.Height - 4);
            e.Graphics.DrawLine(_pen7, 3, this.Height - 4, this.Width - 4, this.Height - 4);
            e.Graphics.DrawLine(_pen6, 4, 4, this.Width - 6, 4);   // 5th layer of border
            e.Graphics.DrawLine(_pen6, 4, 4, 4, this.Height - 6);
            e.Graphics.DrawLine(_pen7, this.Width - 5, 4, this.Width - 5, this.Height - 5);
            e.Graphics.DrawLine(_pen7, 4, this.Height - 5, this.Width - 5, this.Height - 5);
            // Draw line borders of stats panel
            e.Graphics.DrawLine(_pen7, 9, 36, 252, 36);   // 1st layer of border
            e.Graphics.DrawLine(_pen7, 9, 36, 9, 98);
            e.Graphics.DrawLine(_pen6, 9, 99, 252, 99);
            e.Graphics.DrawLine(_pen6, 252, 36, 252, 99);
            e.Graphics.DrawLine(_pen7, 10, 37, 250, 37);   // 2nd layer of border
            e.Graphics.DrawLine(_pen7, 10, 38, 10, 97);
            e.Graphics.DrawLine(_pen6, 10, 98, 251, 98);
            e.Graphics.DrawLine(_pen6, 251, 37, 251, 98);
            // Draw line borders of unit panel
            e.Graphics.DrawLine(_pen7, 9, 104, 252, 104);   // 1st layer of border
            e.Graphics.DrawLine(_pen7, 9, 104, 9, 106 + unitPanel.Height);
            e.Graphics.DrawLine(_pen6, 9, 107 + unitPanel.Height, 252, 107 + unitPanel.Height);
            e.Graphics.DrawLine(_pen6, 252, 104, 252, 105 + unitPanel.Height);
            e.Graphics.DrawLine(_pen7, 9, 105, 250, 105);   // 2nd layer of border
            e.Graphics.DrawLine(_pen7, 10, 104, 10, 105 + unitPanel.Height);
            e.Graphics.DrawLine(_pen6, 10, 106 + unitPanel.Height, 252, 106 + unitPanel.Height);
            e.Graphics.DrawLine(_pen6, 251, 105, 251, 105 + unitPanel.Height);
        }