public static void Tile(Graphics g, int xC2, int yC2, int zoom, Point dest) { using var _tilePic = Images.MapTileGraphicC2(xC2, yC2).Resize(zoom); g.DrawImage(_tilePic, dest); }
// Draw resource map public static void CityResourcesMap(Graphics g, City city, int cityZoom, Point dest) { // Get normal zoom from city zoom (-1/0/1) int zoom = cityZoom * 3 - 2; int offsetX = 5 * (2 + cityZoom) / 2; int offsetY = 84 * (2 + cityZoom) / 2; // First draw squares around city int newX, newY; 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 = MapImages.Terrains[Map.MapIndex].Blank.Resize(zoom); g.DrawImage(blankPic, dest.X + offsetX + 4 * (8 + zoom) * (x_ + 3), dest.Y + offsetY + 2 * (8 + zoom) * (y_ + 3)); // Then draw tiles if they are visible if (!Map.IsValidTileC2(newX, newY)) { continue; } var tile = Map.TileC2(newX, newY); if (tile.Visibility[city.Owner.Id]) { g.DrawImage(Images.MapTileGraphicC2(newX, newY).Resize(zoom), dest.X + offsetX + 4 * (8 + zoom) * (x_ + 3), dest.Y + offsetY + 2 * (8 + zoom) * (y_ + 3)); // TODO: implement dithering on edges or depending on where invisible tiles are // Draw cities if (tile.CityHere != null) { City(g, tile.CityHere, false, zoom, new Point(dest.X + offsetX + 4 * (8 + zoom) * (x_ + 3), dest.Y + offsetY + 2 * (8 + zoom) * (y_ + 3) - 2 * (8 + zoom))); } else if (tile.UnitsHere.Count > 0) { var unit = tile.GetTopUnit(); if (unit != null && unit.AttackBase > 0) { Unit(g, unit, tile.UnitsHere.Count > 1, zoom, new Point(dest.X + offsetX + 4 * (8 + zoom) * (x_ + 3), dest.Y + offsetY + 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) var organization = city.OrganizationLevel; // // var hasSupermarket = city.ImprovementExists(ImprovementType.Supermarket); // var hasSuperhighways = city.ImprovementExists(ImprovementType.Superhighways); foreach (var tile in city.WorkedTiles) { var food = tile.GetFood(organization == 0); var shields = tile.GetShields(organization == 0); var trade = tile.GetTrade(organization); var spacing = (food + shields + trade) switch { 1 => 11, 2 => 11, 3 => 10, 4 => 7, 5 => 5, 6 => 4, 7 => 3, 8 => 3, 9 => 2, 10 => 1, _ => 1 }; spacing = (int)((float)spacing * (2.0 + (float)cityZoom) / 2.0); // Make spacing zoom dependent int x_offset = 4 * (8 + zoom) - ((food + shields + trade - 1) * spacing + 15) / 2; const int yConstant = 9; var combinedXOffsets = dest.X + offsetX + x_offset + (3 + tile.X - city.Location.X) * 4 * (8 + zoom); var combinedYOffsets = dest.Y + offsetY + yConstant + (3 + tile.Y - city.Location.Y) * 2 * (8 + zoom); // First draw food, then shields, then trade icons for (int j = 0; j < food; j++) { g.DrawImage(CityImages.FoodSmall.Resize(4 * cityZoom), combinedXOffsets + j * spacing, combinedYOffsets); } for (int j = 0; j < shields; j++) { g.DrawImage(CityImages.SupportSmall.Resize(4 * cityZoom), combinedXOffsets + (food + j) * spacing, combinedYOffsets); } for (int j = 0; j < trade; j++) { g.DrawImage(CityImages.TradeSmall.Resize(4 * cityZoom), combinedXOffsets + (food + shields + j) * spacing, combinedYOffsets); } } // 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 = (cityFood[i] + cityShld[i] + cityTrad[i]) switch // { // 1 => 11, // 2 => 11, // 3 => 10, // 4 => 7, // 5 => 5, // 6 => 4, // 7 => 3, // 8 => 3, // 9 => 2, // 10 => 1, // _ => 1 // }; // spacing = (int)((float)spacing * (2.0 + (float)cityZoom) / 2.0); // Make spacing zoom dependent // // // 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.Resize(4 * cityZoom), dest.X + offsetX + x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + j * spacing, dest.Y + offsetY + y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom)); // for (int j = 0; j < cityShld[i]; j++) g.DrawImage(Images.CitySupportSmall.Resize(4 * cityZoom), dest.X + offsetX + x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + (cityFood[i] + j) * spacing, dest.Y + offsetY + y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom)); // for (int j = 0; j < cityTrad[i]; j++) g.DrawImage(Images.CityTradeSmall.Resize(4 * cityZoom), dest.X + offsetX + x_offset + (3 + offsets[i, 0]) * 4 * (8 + zoom) + (cityFood[i] + cityShld[i] + j) * spacing, dest.Y + offsetY + y_offset + (3 + offsets[i, 1]) * 2 * (8 + zoom)); // } } }
// Draw resource map public static Bitmap CityResourcesMap(City city, int zoom) { var map = new Bitmap(4 * 8 * (8 + zoom), 4 * 4 * (8 + zoom), PixelFormat.Format32bppRgba); using (var g = new Graphics(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 = Images.MapTileGraphicC2(newX, newY).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.GetActiveCiv) && (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); }