private void DrawPanel_Paint(object sender, PaintEventArgs e)
        {
            // Text
            string bcad = (_game.GameYear < 0) ? "B.C." : "A.D.";

            using var font1 = new Font("Times New Roman", 14);
            Draw.Text(e.Graphics, "CITY STATUS", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 3), Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"Kingdom of the {_game.ActiveCiv.TribeName}", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 24), Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"King {_game.ActiveCiv.LeaderName} : {Math.Abs(_game.GameYear)} {bcad}", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 45), Color.FromArgb(67, 67, 67), 2, 1);

            // Cities
            int count = 0;

            foreach (City city in _game.GetCities.Where(n => n.Owner == _game.ActiveCiv))
            {
                // City image
                Draw.City(e.Graphics, city, true, 0, new Point(4 + 64 * ((count + 1) % 2), 69 + 24 * count));
                //e.Graphics.DrawImage(city.Graphic(true, 0), new Point(4 + 64 * ((count + 1) % 2), 69 + 24 * count));  // OLD

                // City name
                using var font2 = new Font("Times New Roman", 11, FontStyle.Bold);
                Draw.Text(e.Graphics, city.Name, font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(142, 82 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);

                // Food production
                Draw.Text(e.Graphics, city.Food.ToString(), font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(255, 82 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                e.Graphics.DrawImage(Images.CityFoodBig, new Point(265, 85 + 24 * count));

                // Shields
                Draw.Text(e.Graphics, city.ShieldProduction.ToString(), font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(292, 82 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                e.Graphics.DrawImage(Images.CitySupportBig, new Point(297, 85 + 24 * count));

                // Trade
                Draw.Text(e.Graphics, city.Trade.ToString(), font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(329, 82 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                e.Graphics.DrawImage(Images.CityTradeBig, new Point(335, 85 + 24 * count));

                // Item in production
                int item = city.ItemInProduction;
                if (city.ItemInProduction < 62) // Unit is in production
                {
                    Draw.Text(e.Graphics, $"{_game.Rules.UnitName[item]} ( + {city.ShieldsProgress} / {10 * _game.Rules.UnitCost[item]} )", font2, StringAlignment.Near, StringAlignment.Near, Color.FromArgb(255, 223, 79), new Point(367, 82 + 24 * count), Color.Black, 1, 1);
                }
                // Improvement
                else
                {
                    Draw.Text(e.Graphics, $"{_game.Rules.ImprovementName[item - 62 + 1]} ( {city.ShieldsProgress} / {10 * _game.Rules.ImprovementCost[item - 62 + 1]} )", font2, StringAlignment.Near, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(367, 82 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                }
                count++;
            }
        }
        // civId
        // = 0...7 for 8 civs (including barbarians with civId=7)
        // = 8 for revealed map
        //public static Bitmap DrawMap(int civ, bool flatEarth)   // Draw for normal zoom level
        //{
        //    // Define a bitmap for drawing
        //    var mapPic = new Bitmap(32 * (2 * Map.Xdim + 1), 16 * (2 * Map.Ydim + 1));

        //    // Draw map
        //    int zoom = 0;   // Default zoom
        //    using (Graphics g = Graphics.FromImage(mapPic))
        //    {
        //        // Define starting and ending coords for drawing
        //        int colStart, colEnd;
        //        if (flatEarth)
        //        {
        //            colStart = 0;
        //            colEnd = Map.Xdim;
        //        }
        //        else    // Round world --> go few tiles beyond E and W borders in order to fill up blank space at map edge
        //        {
        //            colStart = -2;
        //            colEnd = Map.Xdim + 2;
        //        }

        //        // Draw
        //        for (int _row = 0; _row < Map.Ydim; _row++)
        //        {
        //            for (int _col = colStart; _col < colEnd; _col++)
        //            {
        //                // Determine column index in civ2-style coords
        //                int col = 2 * _col + (_row % 2);
        //                int row = _row;

        //                // Draw only if the tile is visible for each civ (index=8...whole map visible)
        //                if ((civ < 8 && Map.IsTileVisibleC2(col, row, civ)) || civ == 8)
        //                {
        //                    // Tiles
        //                    g.DrawImage(Map.TileC2(col, row).Graphic, 32 * col, 16 * row);

        //                    // Implement dithering in all 4 directions where non-visible tiles are
        //                    if (civ != 8)
        //                    {
        //                        int[] offset = new int[] { -1, 1 };
        //                        for (int tileX = 0; tileX < 2; tileX++)
        //                        {
        //                            for (int tileY = 0; tileY < 2; tileY++)
        //                            {
        //                                int colNew = col + offset[tileX];
        //                                int rowNew = row + offset[tileY];
        //                                if (colNew >= 0 && colNew < 2 * Map.Xdim && rowNew >= 0 && rowNew < Map.Ydim)   // Don't observe outside map limits
        //                                {
        //                                    if (!Map.IsTileVisibleC2(colNew, rowNew, civ))   // Surrounding tile is not visible -> dither
        //                                        g.DrawImage(Images.DitherDots[tileX, tileY], 32 * (col + tileX), 16 * (row + tileY));
        //                                }
        //                            }
        //                        }
        //                    }

        //                    // Units
        //                    List<IUnit> unitsHere = Game.GetUnits.Where(u => u.X == col && u.Y == row).ToList();
        //                    if (unitsHere.Count > 0)
        //                    {
        //                        IUnit unit = unitsHere.Last();
        //                        if (!unit.IsInCity)
        //                        {
        //                            Draw.Unit(g, unit, unitsHere.Count > 1, zoom, new Point(32 * col, 16 * row - 16));
        //                        }
        //                    }

        //                    // Cities
        //                    City city = Game.GetCities.Find(c => c.X == col && c.Y == row);
        //                    if (city != null)
        //                    {
        //                        Draw.City(g, city, true, zoom, new Point(32 * col, 16 * row - 16));
        //                    }
        //                }
        //            }
        //        }

        //        // City name text is drawn last
        //        foreach (City city in Game.GetCities)
        //        {
        //            //int[] ColRow = Ext.Civ2xy(new int[] { city.X, city.Y });  // Real coords from civ2 coords
        //            if ((civ < 8 && Map.IsTileVisibleC2(city.X, city.Y, civ)) || civ == 8)
        //            {
        //                //Bitmap cityNameBitmap = Draw.CityName(city, zoom);
        //                //g.DrawImage(cityNameBitmap, 32 * city.X + 32 - (cityNameBitmap.Width / 2), 16 * city.Y + 3 * 8);
        //            }
        //        }
        //    }

        //    return mapPic;
        //}

        public static Bitmap MapPart(int civ, int startX, int startY, int width, int height, int zoom, bool flatEarth)
        {
            // Define a bitmap for drawing
            var mapPic = new Bitmap(Game.Xpx * (2 * width + 1), Game.Ypx * (height + 1));

            // Draw map
            var cityList = new List <City>(); // Make a list of cities on visible map + their locations so you can draw city names

            using (var g = Graphics.FromImage(mapPic))
            {
                // Draw
                for (int _row = 0; _row < height; _row++)
                {
                    for (int _col = 0; _col < width; _col++)
                    {
                        // Determine column index in civ2-style coords
                        int col = 2 * _col + (_row % 2);
                        int row = _row;

                        // Draw only if the tile is visible for each civ (index=8...whole map visible)
                        if ((civ < 8 && Map.IsTileVisibleC2(startX + col, startY + row, civ)) || civ == 8)
                        {
                            // Tiles
                            Draw.Tile(g, startX + col, startY + row, zoom, new Point(4 * (8 + zoom) * col, 2 * (8 + zoom) * row));

                            // Implement dithering in all 4 directions where non-visible tiles are
                            if (civ != 8)
                            {
                                int[] offset = new int[] { -1, 1 };
                                for (int tileX = 0; tileX < 2; tileX++)
                                {
                                    for (int tileY = 0; tileY < 2; tileY++)
                                    {
                                        int colNew = col + offset[tileX];
                                        int rowNew = row + offset[tileY];
                                        if (colNew >= 0 && colNew < 2 * Map.Xdim && rowNew >= 0 && rowNew < Map.Ydim) // Don't observe outside map limits
                                        {
                                            if (!Map.IsTileVisibleC2(colNew, rowNew, civ))                            // Surrounding tile is not visible -> dither
                                            {
                                                g.DrawImage(Images.DitherDots[tileX, tileY], 4 * (8 + zoom) * (col + tileX), 2 * (8 + zoom) * (row + tileY));
                                            }
                                        }
                                    }
                                }
                            }

                            // Units
                            List <IUnit> unitsHere = Game.GetUnits.Where(u => u.X == startX + col && u.Y == startY + row).ToList();
                            if (unitsHere.Count > 0)
                            {
                                IUnit unit = unitsHere.Last();
                                if (!unit.IsInCity)
                                {
                                    Draw.Unit(g, unit, unitsHere.Count > 1, zoom, new Point(4 * (8 + zoom) * col, 2 * (8 + zoom) * (row - 1)));
                                }
                            }

                            // Cities
                            City city = Game.GetCities.Find(c => c.X == startX + col && c.Y == startY + row);
                            if (city != null)
                            {
                                Draw.City(g, city, true, zoom, new Point(4 * (8 + zoom) * col, 2 * (8 + zoom) * (row - 1)));
                                // Add city drawn on map & its position to list for drawing city names
                                cityList.Add(city);
                            }
                        }
                    }
                }

                // Grid
                if (Game.Options.Grid)
                {
                    for (int _row = 0; _row < height; _row++)
                    {
                        for (int _col = 0; _col < width; _col++)
                        {
                            // Determine column index in civ2-style coords
                            int col = 2 * _col + (_row % 2);
                            int row = _row;

                            // Draw only if the tile is visible for each civ (index=8...whole map visible)
                            if ((civ < 8 && Map.IsTileVisibleC2(startX + col, startY + row, civ)) || civ == 8)
                            {
                                Draw.Grid(g, zoom, new Point(4 * (8 + zoom) * col, 2 * (8 + zoom) * row));
                                //g.DrawImage(ModifyImage.Resize(Images.GridLines, zoom), 4 * (8 + zoom) * col, 2 * (8 + zoom) * row);
                            }
                        }
                    }
                }

                // City name text is drawn last
                foreach (City city in cityList)
                {
                    int[] destSq = new int[] { city.X - startX, city.Y - startY };
                    Draw.CityName(g, city, zoom, destSq);
                }
            }

            return(mapPic);
        }
示例#3
0
        private void DrawPanel_Paint(object sender, PaintEventArgs e)
        {
            // Text
            string bcad = (_game.GameYear < 0) ? "B.C." : "A.D.";

            using var font1 = new Font("Times New Roman", 14);
            using var font2 = new Font("Times New Roman", 11, FontStyle.Bold);
            using var font3 = new Font("Times New Roman", 13);
            Draw.Text(e.Graphics, "TRADE ADVISOR", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 3), Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"Kingdom of the {_game.ActiveCiv.TribeName}", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 24), Color.FromArgb(67, 67, 67), 2, 1);
            Draw.Text(e.Graphics, $"King {_game.ActiveCiv.LeaderName} : {Math.Abs(_game.GameYear)} {bcad}", font1, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(302, 45), Color.FromArgb(67, 67, 67), 2, 1);

            // Trade & maintenance text
            Draw.Text(e.Graphics, "City Trade", font3, StringAlignment.Near, StringAlignment.Near, Color.White, new Point(140, 80), Color.Black, 1, 1);
            Draw.Text(e.Graphics, "Maintenance Costs", font3, StringAlignment.Center, StringAlignment.Near, Color.White, new Point(355, 80), Color.Black, 1, 1);

            // Cities
            int count = 0;

            foreach (City city in _game.GetCities.Where(n => n.Owner == _game.ActiveCiv))
            {
                // City image
                Draw.City(e.Graphics, city, true, 0, new Point(4 + 64 * ((count + 1) % 2), 95 + 24 * count));

                // City name
                Draw.Text(e.Graphics, city.Name, font2, StringAlignment.Near, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(142, 105 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);

                // CITY TRADE
                // Trade
                Draw.Text(e.Graphics, city.Trade.ToString(), font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(255, 108 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                e.Graphics.DrawImage(Images.CityTaxBig, new Point(260, 111 + 24 * count));

                // Science
                Draw.Text(e.Graphics, city.Science.ToString(), font2, StringAlignment.Center, StringAlignment.Near, Color.FromArgb(223, 223, 223), new Point(290, 108 + 24 * count), Color.FromArgb(67, 67, 67), 1, 1);
                e.Graphics.DrawImage(Images.CitySciBig, new Point(295, 111 + 24 * count));
                count++;
            }

            // MAINTENTANCE COSTS
            // Individual costs
            count = 0;
            for (int i = 0; i < 67; i++)
            {
                if ((_noOfImprovements[i] > 0) && (_game.Rules.ImprovementUpkeep[i] > 0))  // Only show improvements with upkeep > 0
                {
                    Draw.Text(e.Graphics, $"{_noOfImprovements[i]} {_game.Rules.ImprovementName[i]} (Cost: {_upkeepOfImprovements[i]})", font2, StringAlignment.Near, StringAlignment.Near, Color.FromArgb(255, 223, 79), new Point(355, 105 + 24 * count), Color.Black, 1, 1);
                    count++;
                }
            }
            Draw.Text(e.Graphics, $"Total Cost : {_totalCost}", font2, StringAlignment.Near, StringAlignment.Near, Color.FromArgb(255, 223, 79), new Point(355, 300), Color.Black, 1, 1);

            // TOTALS
            // Total cost
            Draw.Text(e.Graphics, $"Total Cost: {_totalCost}", font2, StringAlignment.Near, StringAlignment.Near, Color.White, new Point(142, 270), Color.Black, 1, 1);
            e.Graphics.DrawImage(Images.CityTaxBig, new Point(245, 270));

            // Total income
            Draw.Text(e.Graphics, $"Total Income: {_totalIncome}", font3, StringAlignment.Near, StringAlignment.Near, Color.White, new Point(142, 295), Color.Black, 1, 1);
            e.Graphics.DrawImage(Images.CityTaxBig, new Point(245, 295));

            // Total science
            Draw.Text(e.Graphics, $"Total Science: {_totalScience}", font3, StringAlignment.Near, StringAlignment.Near, Color.White, new Point(142, 320), Color.Black, 1, 1);
            e.Graphics.DrawImage(Images.CitySciBig, new Point(245, 320));

            // Discoveries
            Draw.Text(e.Graphics, $"Discoveries: {_discoveries} Turns", font3, StringAlignment.Near, StringAlignment.Near, Color.White, new Point(142, 345), Color.Black, 1, 1);
        }
        // Get animation frames for waiting unit
        public static List <Bitmap> UnitWaiting(bool viewPieceMode)
        {
            var animationFrames = new List <Bitmap>();

            // Get coords of central tile & which squares are to be drawn
            int[] centralCoords          = Game.ActiveXY; // Either from active unit or moving pieces
            var   coordsOffsetsToBeDrawn = new List <int[]>
            {
                new int[] { 0, -2 },
                new int[] { -1, -1 },
                new int[] { 1, -1 },
                new int[] { 0, 0 },
                new int[] { -1, 1 },
                new int[] { 1, 1 },
                new int[] { 0, 2 }
            };

            // Get 2 frames (one with and other without the active unit/moving piece)
            int[] coordsOffsetsPx;
            int   x, y;

            for (int frame = 0; frame < 2; frame++)
            {
                var _bitmap = new Bitmap(2 * Game.Xpx, 3 * Game.Ypx);
                using (var g = Graphics.FromImage(_bitmap))
                {
                    // Fill bitmap with black (necessary for correct drawing if image is on upper map edge)
                    g.FillRectangle(Brushes.Black, new Rectangle(0, 0, 2 * Game.Xpx, 3 * Game.Ypx));


                    foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                    {
                        // Change coords of central offset
                        x = centralCoords[0] + coordsOffsets[0];
                        y = centralCoords[1] + coordsOffsets[1];
                        coordsOffsetsPx = new int[] { coordsOffsets[0] * Game.Xpx, coordsOffsets[1] * Game.Ypx };

                        if (x < 0 || y < 0 || x >= 2 * Map.Xdim || y >= Map.Ydim)
                        {
                            break;                                                          // Make sure you're not drawing tiles outside map bounds
                        }
                        // Tiles
                        Draw.Tile(g, x, y, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] + Game.Ypx));

                        // Units
                        List <IUnit> unitsHere = Game.GetUnits.Where(u => u.X == x && u.Y == y).ToList();
                        if (unitsHere.Count > 0)
                        {
                            IUnit unit;
                            // If this is not tile with active unit or viewing piece, draw last unit on stack
                            if (x != Game.ActiveXY[0] && y != Game.ActiveXY[1])
                            {
                                unit = unitsHere.Last();
                                if (!unit.IsInCity)
                                {
                                    Draw.Unit(g, unit, unit.IsInStack, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                                }
                            }
                            // This tile has active unit/viewing piece
                            else
                            {
                                // Viewing piece mode is enabled, so draw last unit on stack
                                if (viewPieceMode)
                                {
                                    unit = unitsHere.Last();
                                    if (!unit.IsInCity)
                                    {
                                        Draw.Unit(g, unit, unit.IsInStack, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                                    }
                                }
                            }
                        }

                        // City
                        City city = Game.GetCities.Find(c => c.X == x && c.Y == y);
                        if (city != null)
                        {
                            Draw.City(g, city, true, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                        }

                        // Draw active unit if it's not moving
                        if (unitsHere.Count > 0)
                        {
                            // This tile has active unit/viewing piece
                            if (x == Game.ActiveXY[0] && y == Game.ActiveXY[1])
                            {
                                if (!viewPieceMode)
                                {
                                    // For first frame draw unit, for second not
                                    if (frame == 0)
                                    {
                                        Draw.Unit(g, Game.ActiveUnit, Game.ActiveUnit.IsInStack, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                                    }
                                }
                            }
                        }
                    }

                    // Gridlines
                    if (Game.Options.Grid)
                    {
                        foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                        {
                            coordsOffsetsPx = new int[] { coordsOffsets[0] * Game.Xpx, coordsOffsets[1] * Game.Ypx + Game.Ypx };
                            Draw.Grid(g, Game.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                        }
                    }

                    // City names
                    foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                    {
                        // Change coords of central offset
                        x = centralCoords[0] + coordsOffsets[0];
                        y = centralCoords[1] + coordsOffsets[1];

                        if (x >= 0 && y >= 0 && x < 2 * Map.Xdim && y < Map.Ydim)
                        {
                            break;                                                         // Make sure you're not drawing tiles outside map bounds
                        }
                        City city = Game.GetCities.Find(c => c.X == x && c.Y == y);
                        if (city != null)
                        {
                            Draw.CityName(g, city, Game.Zoom, new int[] { x, y });
                            //Bitmap cityNameBitmap = Draw.CityName(city, Game.Zoom);
                            //g.DrawImage(cityNameBitmap,
                            //    Game.Xpx * (coordsOffsets[0] + 1) - cityNameBitmap.Width / 2,
                            //    Game.Ypx * coordsOffsets[1] + 5 * 2 / Game.Ypx + Game.Ypx);
                        }
                    }

                    ////Viewing piece (is drawn on top of everything)
                    //if (MapPanel.ViewingPiecesMode)
                    //{
                    //    if (frame == 0)
                    //    {
                    //        g.DrawImage(Draw.ViewPiece, 0, 16);
                    //    }
                    //}
                }
                animationFrames.Add(_bitmap);
            }

            return(animationFrames);
        }
        // Draw resource map
        public static Bitmap CityResourcesMap(City city, int zoom)
        {
            var map = new Bitmap(4 * 8 * (8 + zoom), 4 * 4 * (8 + zoom));

            using (var g = Graphics.FromImage(map))
            {
                // First draw squares around city
                int          newX, newY;
                City         cityHere;
                List <IUnit> unitsHere;
                for (int y_ = -3; y_ <= 3; y_++)
                {
                    for (int x_ = -3; x_ <= 3; x_++)
                    {
                        if ((x_ == -1 && y_ == -3) || (x_ == 1 && y_ == -3) || (x_ == -2 && y_ == -2) || (x_ == 0 && y_ == -2) || (x_ == 2 && y_ == -2) || (x_ == -3 && y_ == -1) ||
                            (x_ == -1 && y_ == -1) || (x_ == 1 && y_ == -1) || (x_ == 3 && y_ == -1) || (x_ == -2 && y_ == 0) || (x_ == 0 && y_ == 0) || (x_ == 2 && y_ == 0) ||
                            (x_ == -3 && y_ == 1) || (x_ == -1 && y_ == 1) || (x_ == 1 && y_ == 1) || (x_ == 3 && y_ == 1) || (x_ == -2 && y_ == 2) || (x_ == 0 && y_ == 2) ||
                            (x_ == 2 && y_ == 2) || (x_ == -1 && y_ == 3) || (x_ == 1 && y_ == 3))
                        {
                            newX = city.X + x_;
                            newY = city.Y + y_;

                            // First draw blank tiles
                            using var blankPic = Images.Blank.Resize(zoom);
                            g.DrawImage(blankPic, 4 * (8 + zoom) * (x_ + 3), 2 * (8 + zoom) * (y_ + 3));
                            // Then draw tiles if they are visible
                            if (Map.IsTileVisibleC2(newX, newY, city.Owner.Id))
                            {
                                using var mapPic = Map.TileC2(newX, newY).Graphic.Resize(zoom);
                                g.DrawImage(mapPic, 4 * (8 + zoom) * (x_ + 3), 2 * (8 + zoom) * (y_ + 3));
                            }
                            // TODO: implement dithering on edges or depending on where invisible tiles are
                            // Draw cities
                            cityHere = Game.CityHere(newX, newY);
                            if (cityHere != null)
                            {
                                Draw.City(g, cityHere, false, zoom, new Point(4 * (8 + zoom) * (x_ + 3), 2 * (8 + zoom) * (y_ + 3) - 2 * (8 + zoom)));
                            }
                            //g.DrawImage(cityHere.Graphic(false, zoom), 4 * (8 + zoom) * (x_ + 3), 2 * (8 + zoom) * (y_ + 3) - 2 * (8 + zoom));
                            // Draw units
                            unitsHere = Game.UnitsHere(newX, newY).FindAll(unit => (unit.Owner != Game.ActiveCiv) && (unit.Type != Civ2engine.Enums.UnitType.Settlers));
                            //if (unitsHere.Count > 0 && cityHere == null)
                            //    g.DrawImage(unitsHere.Last().Graphic(true, zoom), 4 * (8 + zoom) * (x_ + 3), 2 * (8 + zoom) * (y_ + 3) - 2 * (8 + zoom));

                            // TODO: make sure you're not drawing beyond map edges
                            //if (newX >= 0 && newX < 2 * Data.MapXdim && newY >= 0 && newY < Data.MapYdim) image = TerrainBitmap((newX - (newY % 2)) / 2, newY);
                        }
                    }
                }

                // Then draw food/shield/trade icons around the city (21 squares around city)
                int[,] offsets = new int[21, 2] {
                    { 0, 0 }, { -1, -3 }, { -3, -1 }, { -3, 1 }, { -1, 3 }, { 1, 3 }, { 3, 1 }, { 3, -1 }, { 1, -3 }, { -2, -2 }, { -2, 2 }, { 2, 2 },
                    { 2, -2 }, { 0, -2 }, { -1, -1 }, { -2, 0 }, { -1, 1 }, { 0, 2 }, { 1, 1 }, { 2, 0 }, { 1, -1 }
                };                                                                                                                                          // offset of squares from city (0,0)
                int[] cityFood = city.FoodDistribution;
                int[] cityShld = city.ShieldDistribution;
                int[] cityTrad = city.TradeDistribution;
                for (int i = 0; i < 21; i++)
                {
                    if (city.DistributionWorkers[i])
                    {
                        // First count all icons on this square to determine the spacing between icons (10 = no spacing, 15 = no spacing @ 50% scaled)
                        int spacing;
                        switch (cityFood[i] + cityShld[i] + cityTrad[i])
                        {
                        case 1:
                        case 2: spacing = 11; break;       // normal=11, big = 17, 1 pixel gap

                        case 3: spacing = 10; break;       // normal=10, big = 15, no gap

                        case 4: spacing = 7; break;        // normal=7, big = 11

                        case 5: spacing = 5; break;        // normal=5, big = 8

                        case 6: spacing = 4; break;        // normal=4, big = 6

                        case 7:
                        case 8: spacing = 3; break;        // normal=3, big = 5

                        case 9: spacing = 2; break;        // normal=2, big = 3

                        case 10: spacing = 1; break;       // normal=1, big = 2

                        default: spacing = 1; break;       //  normal=1, big = 2
                        }

                        // First draw food, then shields, then trade icons
                        int x_offset = 4 * (8 + zoom) - ((cityFood[i] + cityShld[i] + cityTrad[i] - 1) * spacing + 15) / 2;
                        int y_offset = 9;
                        for (int j = 0; j < cityFood[i]; j++)
                        {
                            g.DrawImage(Images.CityFoodSmall, x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + j * spacing, y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom));
                        }
                        for (int j = 0; j < cityShld[i]; j++)
                        {
                            g.DrawImage(Images.CitySupportSmall, x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + (cityFood[i] + j) * spacing, y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom));
                        }
                        for (int j = 0; j < cityTrad[i]; j++)
                        {
                            g.DrawImage(Images.CityTradeSmall, x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + (cityFood[i] + cityShld[i] + j) * spacing, y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom));
                        }
                    }
                }
            }
            return(map);
        }