Beispiel #1
0
        private void UnitsFromCity_Paint(object sender, PaintEventArgs e)
        {
            int count = 0;
            int row, col;
            int zoom = -3;  // norm=0.67, big=0.67*1.5=1

            foreach (IUnit unit in _thisCity.SupportedUnits)
            {
                col = count % 4;
                row = count / 4;
                Draw.Unit(e.Graphics, unit, false, zoom, new Point(8 * (8 + zoom) * col, (4 * (8 + zoom + 3)) * row));
                count++;

                if (count >= 8)
                {
                    break;
                }
            }
        }
Beispiel #2
0
        private void UnitsInCity_Paint(object sender, PaintEventArgs e)
        {
            int count = 0;
            int row;
            int col;
            int zoom = -2;  // zoom=-2(norm), 1(big)

            using var font = new Font("Arial", 9, FontStyle.Bold);
            foreach (IUnit unit in _thisCity.UnitsInCity)
            {
                col = count % 5;
                row = count / 5;
                Draw.Unit(e.Graphics, unit, false, zoom, new Point(8 * (8 + zoom) * col, 6 * (8 + zoom) * row + 5 * row));
                Draw.Text(e.Graphics, unit.HomeCity.Name.Substring(0, 3), font, Colors.Black, new Point(8 * (8 + zoom) * col + 8 * (8 + zoom) / 2, 6 * (8 + zoom) * row + 5 * row + 6 * (8 + zoom)), true, true, Color.FromArgb(135, 135, 135), 1, 1);  // TODO: doesn't work for <3 characters in city name
                count++;
            }

            // Trade text
            Draw.Text(e.Graphics, $"Supplies: {_thisCity.CommoditySupplied[0]}, {_thisCity.CommoditySupplied[2]}, {_thisCity.CommoditySupplied[2]}", font, Color.FromArgb(227, 83, 15), new Point(6, 135), false, false, Color.FromArgb(67, 67, 67), 1, 1);
            Draw.Text(e.Graphics, $"Demands: {_thisCity.CommodityDemanded[0]}, {_thisCity.CommodityDemanded[2]}, {_thisCity.CommodityDemanded[2]}", font, Color.FromArgb(227, 83, 15), new Point(6, 148), false, false, Color.FromArgb(67, 67, 67), 1, 1);
            Draw.Text(e.Graphics, $"{Game.GetCities[_thisCity.TradeRoutePartnerCity[0]].Name} {_thisCity.CommodityInRoute[0]}: +1", font, Color.FromArgb(227, 83, 15), new Point(6, 163), false, false, Color.FromArgb(67, 67, 67), 1, 1);
        }
        // Get attack animation frames
        public static List <Bitmap> UnitAttack(CombatEventArgs e)
        {
            var animationFrames = new List <Bitmap>();

            var map = e.Defender.Location.Map;
            // Which squares are to be drawn
            var coordsOffsetsToBeDrawn = new List <int[]>
            {
                new[] { -2, -4 },
                new[] { 0, -4 },
                new[] { 2, -4 },
                new[] { -3, -3 },
                new[] { -1, -3 },
                new[] { 1, -3 },
                new[] { 3, -3 },
                new[] { -2, -2 },
                new[] { 0, -2 },
                new[] { 2, -2 },
                new[] { -3, -1 },
                new[] { -1, -1 },
                new[] { 1, -1 },
                new[] { 3, -1 },
                new[] { -2, 0 },
                new[] { 0, 0 },
                new[] { 2, 0 },
                new[] { -3, 1 },
                new[] { -1, 1 },
                new[] { 1, 1 },
                new[] { 3, 1 },
                new[] { -2, 2 },
                new[] { 0, 2 },
                new[] { 2, 2 },
                new[] { -3, 3 },
                new[] { -1, 3 },
                new[] { 1, 3 },
                new[] { 3, 3 },
                new[] { -2, 4 },
                new[] { 0, 4 },
                new[] { 2, 4 }
            };


            var defenderX = e.Defender.Location.X;
            var defenderY = e.Defender.Location.Y;

            var attackerX = e.Attacker.Location.X;
            var attackerY = e.Attacker.Location.Y;

            // First draw main bitmap with everything except the moving unit
            int[] coordsOffsetsPx;
            var   mainBitmap = new Bitmap(6 * map.Xpx, 7 * map.Ypx, PixelFormat.Format32bppRgba);

            using (var g = new Graphics(mainBitmap))
            {
                g.FillRectangle(Brushes.Black, new Rectangle(0, 0, 6 * map.Xpx, 7 * map.Ypx));    // Fill bitmap with black (necessary for correct drawing if image is on upper map edge)

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

                    if (x < 0 || y < 0 || x >= map.XDimMax || y >= map.YDim)
                    {
                        continue;                                                         // Make sure you're not drawing tiles outside map bounds
                    }
                    // Tiles
                    var tile  = map.TileC2(x, y);
                    int civId = map.WhichCivsMapShown;
                    if (map.MapRevealed || tile.Visibility[civId])
                    {
                        Draw.Tile(g, x, y, map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));

                        // Implement dithering in all 4 directions if necessary
                        if (!map.MapRevealed)
                        {
                            for (int tileX = 0; tileX < 2; tileX++)
                            {
                                for (int tileY = 0; tileY < 2; tileY++)
                                {
                                    int[] offset = { -1, 1 };
                                    var   xNew   = x + offset[tileX];
                                    var   yNew   = y + offset[tileY];
                                    if (xNew >= 0 && xNew < map.XDimMax && yNew >= 0 && yNew < map.YDim) // Don't observe outside map limits
                                    {
                                        if (!map.IsTileVisibleC2(xNew, yNew, civId))                     // Surrounding tile is not visible -> dither
                                        {
                                            Draw.Dither(g, tileX, tileY, map.Zoom, new Point(coordsOffsetsPx[0] + map.Xpx * tileX, coordsOffsetsPx[1] + map.Ypx * tileY));
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Units
                    // If tile is with attacking & defending unit, draw these two first
                    // TODO: this won't draw correctly if unit is in city
                    if (x == attackerX && y == attackerY)
                    {
                        Draw.Unit(g, e.Attacker, e.Attacker.IsInStack, map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - map.Ypx));
                    }
                    else if (x == defenderX && y == defenderY)
                    {
                        Draw.Unit(g, e.Defender, e.Defender.IsInStack, map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - map.Ypx));
                    }
                    else if (tile.CityHere == null && tile.UnitsHere.Count > 0) // Other units
                    {
                        var unit = tile.GetTopUnit();
                        Draw.Unit(g, unit, unit.IsInStack, map.Zoom,
                                  new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - map.Ypx));
                    }

                    // Cities
                    if (tile.CityHere != null)
                    {
                        Draw.City(g, tile.CityHere, true, map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - map.Ypx));
                    }
                }

                // City names
                // Add additional coords for drawing city names
                coordsOffsetsToBeDrawn.Add(new[] { -3, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { -1, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { 1, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { 3, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, -2 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, -2 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, 0 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, 0 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, 2 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, 2 });
                foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                {
                    // Change coords of central offset
                    int x = attackerX + coordsOffsets[0];
                    int y = attackerY + coordsOffsets[1];

                    if (x < 0 || y < 0 || x >= map.XDimMax || y >= map.YDim)
                    {
                        continue;                                                        // Make sure you're not drawing tiles outside map bounds
                    }
                    var tile = map.TileC2(x, y);
                    if (tile.CityHere != null)
                    {
                        Draw.CityName(g, tile.CityHere, map.Zoom, new[] { coordsOffsets[0] + 2, coordsOffsets[1] + 3 });
                    }
                }
            }

            // Now draw the battle animation on top of attacking & defending unit
            // Number of battle rounds / 5 determines number of explosions (must be at least one). Each explosion has 8 frames.
            Point point;

            for (int explosion = 0; explosion < e.CombatRoundsAttackerWins.Count / 5; explosion++)
            {
                for (int frame = 0; frame < 8; frame++)
                {
                    // Make a clone of the main bitmap in order to draw frames with unit on it
                    var bitmapWithExplosions = new Bitmap(mainBitmap);
                    using (var g = new Graphics(bitmapWithExplosions))
                    {
                        // Draw changing HP of both units
                        foreach (var coordsOffsets in coordsOffsetsToBeDrawn)
                        {
                            var x = attackerX + coordsOffsets[0];
                            var y = attackerY + coordsOffsets[1];

                            if (x == attackerX && y == attackerY)
                            {
                                Draw.UnitShield(g, e.Attacker.Type, e.Attacker.Owner.Id, e.Attacker.Order, e.Attacker.IsInStack,
                                                e.Attacker.Hitpoints[explosion * 5], e.Attacker.HitpointsBase, map.Zoom,
                                                new Point(2 * map.Xpx, 2 * map.Ypx));
                                Draw.UnitSprite(g, e.Attacker.Type, false, false, map.Zoom,
                                                new Point(2 * map.Xpx, 2 * map.Ypx));
                            }
                            else if (x == defenderX && y == defenderY)
                            {
                                Draw.UnitShield(g, e.Defender.Type, e.Defender.Owner.Id, e.Defender.Order,
                                                e.Defender.IsInStack, e.Defender.Hitpoints[explosion * 5], e.Defender.HitpointsBase,
                                                map.Zoom,
                                                new Point((2 + coordsOffsets[0]) * map.Xpx, (2 + coordsOffsets[1]) * map.Ypx));
                                Draw.UnitSprite(g, e.Defender.Type, e.Defender.Order == OrderType.Sleep,
                                                e.Defender.Order == OrderType.Fortified, map.Zoom,
                                                new Point((2 + coordsOffsets[0]) * map.Xpx, (2 + coordsOffsets[1]) * map.Ypx));
                            }
                        }

                        // Draw explosion on defender
                        point = e.CombatRoundsAttackerWins[explosion]
                            ? new Point((int)(map.Xpx * (2.5 + defenderX - attackerX)),
                                        map.Ypx * (3 + (defenderY - attackerY)))
                            : new Point((int)(map.Xpx * 2.5), map.Ypx * 3);

                        Draw.BattleAnim(g, frame, map.Zoom, point);
                    }

                    animationFrames.Add(bitmapWithExplosions);
                }
            }
            return(animationFrames);
        }
        // Get animation frames for moving unit
        public static List <Bitmap> UnitMoving(Unit activeUnit)
        {
            List <Bitmap> animationFrames = new List <Bitmap>();

            var Map = activeUnit.CurrentLocation.Map;

            // Get coords of central tile & which squares are to be drawn
            int[]        activeUnitPrevXY       = activeUnit.PrevXY;
            List <int[]> coordsOffsetsToBeDrawn = new List <int[]>
            {
                new[] { -2, -4 },
                new[] { 0, -4 },
                new[] { 2, -4 },
                new[] { -3, -3 },
                new[] { -1, -3 },
                new[] { 1, -3 },
                new[] { 3, -3 },
                new[] { -2, -2 },
                new[] { 0, -2 },
                new[] { 2, -2 },
                new[] { -3, -1 },
                new[] { -1, -1 },
                new[] { 1, -1 },
                new[] { 3, -1 },
                new[] { -2, 0 },
                new[] { 0, 0 },
                new[] { 2, 0 },
                new[] { -3, 1 },
                new[] { -1, 1 },
                new[] { 1, 1 },
                new[] { 3, 1 },
                new[] { -2, 2 },
                new[] { 0, 2 },
                new[] { 2, 2 },
                new[] { -3, 3 },
                new[] { -1, 3 },
                new[] { 1, 3 },
                new[] { 3, 3 },
                new[] { -2, 4 },
                new[] { 0, 4 },
                new[] { 2, 4 }
            };

            // First draw main bitmap with everything except the moving unit
            int[] coordsOffsetsPx;
            var   _mainBitmap = new Bitmap(6 * Map.Xpx, 7 * Map.Ypx, PixelFormat.Format32bppRgba);

            using (var g = new Graphics(_mainBitmap))
            {
                g.FillRectangle(Brushes.Black, new Rectangle(0, 0, 6 * Map.Xpx, 7 * Map.Ypx));    // Fill bitmap with black (necessary for correct drawing if image is on upper map edge)

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

                    if (x < 0 || y < 0 || x >= Map.XDimMax || y >= Map.YDim)
                    {
                        continue;                                                        // Make sure you're not drawing tiles outside map bounds
                    }
                    // Tiles
                    int civId = Map.WhichCivsMapShown;
                    if (Map.IsTileVisibleC2(x, y, civId) || Map.MapRevealed)
                    {
                        Draw.Tile(g, x, y, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));

                        // Implement dithering in all 4 directions if necessary
                        if (!Map.MapRevealed)
                        {
                            for (int tileX = 0; tileX < 2; tileX++)
                            {
                                for (int tileY = 0; tileY < 2; tileY++)
                                {
                                    int[] offset = { -1, 1 };
                                    int   xNew   = x + offset[tileX];
                                    int   yNew   = y + offset[tileY];
                                    if (xNew >= 0 && xNew < Map.XDimMax && yNew >= 0 && yNew < Map.YDim) // Don't observe outside map limits
                                    {
                                        if (!Map.IsTileVisibleC2(xNew, yNew, civId))                     // Surrounding tile is not visible -> dither
                                        {
                                            Draw.Dither(g, tileX, tileY, Map.Zoom, new Point(coordsOffsetsPx[0] + Map.Xpx * tileX, coordsOffsetsPx[1] + Map.Ypx * tileY));
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Units
                    var tile = Map.TileC2(x, y);
                    if (tile.CityHere == null)
                    {
                        // If unit is ship, remove units that are in it & remove active unit
                        //var unitsHere = tile.UnitsHere.Where(u => u.InShip == null && u != activeUnit).ToList();


                        if (tile.UnitsHere.Count > 0 && tile.UnitsHere.Any(u => u != activeUnit))
                        {
                            var unit = tile.GetTopUnit(u => u != activeUnit);

                            Draw.Unit(g, unit, unit.IsInStack, Map.Zoom,
                                      new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - Map.Ypx));
                        }
                    }
                    else
                    {
                        // Cities
                        Draw.City(g, tile.CityHere, true, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - Map.Ypx));
                    }
                }

                // City names
                // Add additional coords for drawing city names
                coordsOffsetsToBeDrawn.Add(new[] { -3, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { -1, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { 1, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { 3, -5 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, -2 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, -2 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, 0 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, 0 });
                coordsOffsetsToBeDrawn.Add(new[] { -4, 2 });
                coordsOffsetsToBeDrawn.Add(new[] { 4, 2 });
                foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                {
                    // Change coords of central offset
                    int x = activeUnitPrevXY[0] + coordsOffsets[0];
                    int y = activeUnitPrevXY[1] + coordsOffsets[1];

                    if (x < 0 || y < 0 || x >= Map.XDimMax || y >= Map.YDim)
                    {
                        continue;                                                        // Make sure you're not drawing tiles outside map bounds
                    }
                    var tile = Map.TileC2(x, y);
                    if (tile.CityHere != null)
                    {
                        Draw.CityName(g, tile.CityHere, Map.Zoom, new[] { coordsOffsets[0] + 2, coordsOffsets[1] + 3 });
                    }
                }
            }

            // Now draw the moving unit on top of main bitmap
            int noFramesForOneMove = 8;

            for (int frame = 0; frame < noFramesForOneMove; frame++)
            {
                // Make a clone of the main bitmap in order to draw frames with unit on it
                var _bitmapWithMovingUnit = new Bitmap(_mainBitmap);
                using (var g = new Graphics(_bitmapWithMovingUnit))
                {
                    // Draw active unit on top of everything (except if it's city, then don't draw the unit in last frame)
                    if (!(frame == noFramesForOneMove - 1 && activeUnit.CurrentLocation.CityHere != null))
                    {
                        int[] unitDrawOffset = { activeUnit.X - activeUnit.PrevXY[0], activeUnit.Y - activeUnit.PrevXY[1] };
                        unitDrawOffset[0] *= Map.Xpx / noFramesForOneMove * (frame + 1);
                        unitDrawOffset[1] *= Map.Ypx / noFramesForOneMove * (frame + 1);
                        Draw.Unit(g, activeUnit, activeUnit.CarriedUnits.Count > 0, Map.Zoom, new Point(2 * Map.Xpx + unitDrawOffset[0], 2 * Map.Ypx + unitDrawOffset[1]));
                    }
                }
                animationFrames.Add(_bitmapWithMovingUnit);
            }

            return(animationFrames);
        }
        // Get animation frames for moving unit
        public static List <Bitmap> UnitMoving(IUnit activeUnit)
        {
            List <Bitmap> animationFrames = new List <Bitmap>();

            // Get coords of central tile & which squares are to be drawn
            int[]        activeUnitPrevXY       = activeUnit.PrevXY;
            List <int[]> coordsOffsetsToBeDrawn = new List <int[]>
            {
                new int[] { -2, -4 },
                new int[] { 0, -4 },
                new int[] { 2, -4 },
                new int[] { -3, -3 },
                new int[] { -1, -3 },
                new int[] { 1, -3 },
                new int[] { 3, -3 },
                new int[] { -2, -2 },
                new int[] { 0, -2 },
                new int[] { 2, -2 },
                new int[] { -3, -1 },
                new int[] { -1, -1 },
                new int[] { 1, -1 },
                new int[] { 3, -1 },
                new int[] { -2, 0 },
                new int[] { 0, 0 },
                new int[] { 2, 0 },
                new int[] { -3, 1 },
                new int[] { -1, 1 },
                new int[] { 1, 1 },
                new int[] { 3, 1 },
                new int[] { -2, 2 },
                new int[] { 0, 2 },
                new int[] { 2, 2 },
                new int[] { -3, 3 },
                new int[] { -1, 3 },
                new int[] { 1, 3 },
                new int[] { 3, 3 },
                new int[] { -2, 4 },
                new int[] { 0, 4 },
                new int[] { 2, 4 }
            };

            // First draw main bitmap with everything except the moving unit
            int[] coordsOffsetsPx;
            var   _mainBitmap = new Bitmap(6 * Map.Xpx, 7 * Map.Ypx, PixelFormat.Format32bppRgba);

            using (var g = new Graphics(_mainBitmap))
            {
                g.FillRectangle(Brushes.Black, new Rectangle(0, 0, 6 * Map.Xpx, 7 * Map.Ypx));    // Fill bitmap with black (necessary for correct drawing if image is on upper map edge)

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

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

                        // Implement dithering in all 4 directions if necessary
                        if (!Map.MapRevealed)
                        {
                            for (int tileX = 0; tileX < 2; tileX++)
                            {
                                for (int tileY = 0; tileY < 2; tileY++)
                                {
                                    int[] offset = new int[] { -1, 1 };
                                    int   xNew   = x + offset[tileX];
                                    int   yNew   = y + offset[tileY];
                                    if (xNew >= 0 && xNew < 2 * Map.Xdim && yNew >= 0 && yNew < Map.Ydim) // Don't observe outside map limits
                                    {
                                        if (!Map.IsTileVisibleC2(xNew, yNew, civId))                      // Surrounding tile is not visible -> dither
                                        {
                                            Draw.Dither(g, tileX, tileY, Map.Zoom, new Point(coordsOffsetsPx[0] + Map.Xpx * tileX, coordsOffsetsPx[1] + Map.Ypx * tileY));
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Units
                    List <IUnit> unitsHere = Game.UnitsHere(x, y);
                    // If active unit is in this list-- > remove it
                    if (unitsHere.Contains(activeUnit))
                    {
                        unitsHere.Remove(activeUnit);
                    }

                    if (unitsHere.Count > 0)
                    {
                        IUnit unit;
                        // If this is not tile with active unit or viewing piece, draw last unit on stack
                        if (!unitsHere.Contains(activeUnit))
                        {
                            unit = unitsHere.Last();
                            if (!unit.IsInCity)
                            {
                                Draw.Unit(g, unit, unitsHere.Count > 1, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - Map.Ypx));
                            }
                        }
                    }

                    // Cities
                    City city = Game.CityHere(x, y);
                    if (city != null)
                    {
                        Draw.City(g, city, true, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1] - Map.Ypx));
                    }
                }

                // City names
                // Add additional coords for drawing city names
                coordsOffsetsToBeDrawn.Add(new int[] { -3, -5 });
                coordsOffsetsToBeDrawn.Add(new int[] { -1, -5 });
                coordsOffsetsToBeDrawn.Add(new int[] { 1, -5 });
                coordsOffsetsToBeDrawn.Add(new int[] { 3, -5 });
                coordsOffsetsToBeDrawn.Add(new int[] { -4, -2 });
                coordsOffsetsToBeDrawn.Add(new int[] { 4, -2 });
                coordsOffsetsToBeDrawn.Add(new int[] { -4, 0 });
                coordsOffsetsToBeDrawn.Add(new int[] { 4, 0 });
                coordsOffsetsToBeDrawn.Add(new int[] { -4, 2 });
                coordsOffsetsToBeDrawn.Add(new int[] { 4, 2 });
                foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                {
                    // Change coords of central offset
                    int x = activeUnitPrevXY[0] + coordsOffsets[0];
                    int y = activeUnitPrevXY[1] + coordsOffsets[1];

                    if (x < 0 || y < 0 || x >= 2 * Map.Xdim || y >= Map.Ydim)
                    {
                        continue;                                                         // Make sure you're not drawing tiles outside map bounds
                    }
                    City city = Game.CityHere(x, y);
                    if (city != null)
                    {
                        Draw.CityName(g, city, Map.Zoom, new int[] { coordsOffsets[0] + 2, coordsOffsets[1] + 3 });
                    }
                }
            }

            // Now draw the moving unit on top of main bitmap
            int noFramesForOneMove = 8;

            for (int frame = 0; frame < noFramesForOneMove; frame++)
            {
                // Make a clone of the main bitmap in order to draw frames with unit on it
                var _bitmapWithMovingUnit = new Bitmap(_mainBitmap);
                using (var g = new Graphics(_bitmapWithMovingUnit))
                {
                    // Draw active unit on top of everything
                    //int[] activeUnitDrawOffset = new int[] { 0, 0 };
                    //switch (Game.ActiveUnit.PrevXY)
                    //{
                    //    case 0: activeUnitDrawOffset = new int[] { 1, -1 }; break;
                    //    case 1: activeUnitDrawOffset = new int[] { 2, 0 }; break;
                    //    case 2: activeUnitDrawOffset = new int[] { 1, 1 }; break;
                    //    case 3: activeUnitDrawOffset = new int[] { 0, 2 }; break;
                    //    case 4: activeUnitDrawOffset = new int[] { -1, 1 }; break;
                    //    case 5: activeUnitDrawOffset = new int[] { -2, 0 }; break;
                    //    case 6: activeUnitDrawOffset = new int[] { -1, -1 }; break;
                    //    case 7: activeUnitDrawOffset = new int[] { 0, -2 }; break;
                    //}
                    int[] unitDrawOffset = new int[] { activeUnit.X - activeUnit.PrevXY[0], activeUnit.Y - activeUnit.PrevXY[1] };
                    unitDrawOffset[0] *= Map.Xpx / noFramesForOneMove * (frame + 1);
                    unitDrawOffset[1] *= Map.Ypx / noFramesForOneMove * (frame + 1);

                    Draw.Unit(g, activeUnit, false, Map.Zoom, new Point(2 * Map.Xpx + unitDrawOffset[0], 2 * Map.Ypx + unitDrawOffset[1]));
                }
                animationFrames.Add(_bitmapWithMovingUnit);
            }

            return(animationFrames);
        }
        // Get animation frames for waiting unit/view piece
        public static List <Bitmap> Waiting(int[] activeXY)
        {
            var animationFrames = new List <Bitmap>();

            // Get coords of central tile & which squares are to be drawn
            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 * Map.Xpx, 3 * Map.Ypx, PixelFormat.Format32bppRgba);
                using (var g = new Graphics(_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 * Map.Xpx, 3 * Map.Ypx));

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

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

                        // Units
                        List <IUnit> unitsHere = Game.UnitsHere(x, y);
                        if (unitsHere.Count > 0 && Game.CityHere(x, y) == null)
                        {
                            IUnit unit;
                            // If this is not tile with active unit or viewing piece, draw last unit on stack
                            if (!(x == activeXY[0] && y == activeXY[1]) || Map.ViewPieceMode)
                            {
                                unit = unitsHere.Last();
                                Draw.Unit(g, unit, unit.IsInStack, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                            }
                        }

                        // City
                        City city = Game.CityHere(x, y);
                        if (city != null)
                        {
                            Draw.City(g, city, true, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                        }

                        // Draw active unit if it's not moving
                        if (unitsHere.Count > 0 && x == activeXY[0] && y == activeXY[1] && !Map.ViewPieceMode)
                        {
                            // Draw unit only for 1st frame
                            if (frame == 0)
                            {
                                Draw.Unit(g, Game.GetActiveUnit, Game.GetActiveUnit.IsInStack, Map.Zoom, new Point(coordsOffsetsPx[0], coordsOffsetsPx[1]));
                            }
                        }
                    }

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

                    // City names
                    coordsOffsetsToBeDrawn.Add(new int[] { -2, -2 });
                    coordsOffsetsToBeDrawn.Add(new int[] { 2, -2 });
                    coordsOffsetsToBeDrawn.Add(new int[] { -1, -3 });
                    coordsOffsetsToBeDrawn.Add(new int[] { 1, -3 });
                    foreach (int[] coordsOffsets in coordsOffsetsToBeDrawn)
                    {
                        // Change coords of central offset
                        x = activeXY[0] + coordsOffsets[0];
                        y = activeXY[1] + coordsOffsets[1];

                        if (x < 0 || y < 0 || x >= 2 * Map.Xdim || y >= Map.Ydim)
                        {
                            continue;                                                         // Make sure you're not drawing tiles outside map bounds
                        }
                        City city = Game.CityHere(x, y);
                        if (city != null)
                        {
                            Draw.CityName(g, city, Map.Zoom, new int[] { coordsOffsets[0], coordsOffsets[1] + 1 });
                        }
                    }

                    // View piece (is drawn on top of everything)
                    if (Map.ViewPieceMode)
                    {
                        if (frame == 1)
                        {
                            Draw.ViewPiece(g, Map.Zoom, new Point(0, Map.Ypx));
                        }
                    }
                }
                animationFrames.Add(_bitmap);
            }

            return(animationFrames);
        }
Beispiel #7
0
        /// <summary>
        /// Make a bitmap of a part of map.
        /// </summary>
        /// <param name="civ">Map view of a of tribe (tribe's id).</param>
        /// <param name="startX">Starting X-coord shown on map.</param>
        /// <param name="startY">Starting Y-coord shown on map.</param>
        /// <param name="width">Width of map shown.</param>
        /// <param name="height">Height of map shown.</param>
        /// <param name="flatEarth">Flat earth map?</param>
        /// <param name="mapRevealed">Is map revealed?</param>
        /// <param name="showActiveUnit"></param>
        /// <param name="highlightList"></param>
        /// <param name="pathDebug"></param>
        /// <returns></returns>
        public static Bitmap MapPart(int civ, int startX, int startY, int width, int height, bool flatEarth,
                                     bool mapRevealed, bool showActiveUnit, IList <Tile> highlightList, Dictionary <Tile, Route> pathDebug)
        {
            // Define a bitmap for drawing
            var mapPic = new Bitmap(Map.Xpx * (2 * width + 1), Map.Ypx * (height + 1), PixelFormat.Format32bppRgba);

            // 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 = new Graphics(mapPic);

            var activeUnit = Game.ActiveUnit;

            // Draw
            for (int _row = -2; _row < height + 2; _row++)
            {
                for (int _col = -2; _col < width; _col++)
                {
                    // Determine column index in civ2-style coords
                    int col = 2 * _col + (_row % 2);
                    int row = _row;

                    // Don't draw beyond borders
                    var xC2 = startX + col;
                    var yC2 = startY + row;
                    if (xC2 < 0 || yC2 < 0 || xC2 >= Map.XDimMax || yC2 >= Map.YDim)
                    {
                        continue;
                    }

                    var tile = Map.TileC2(xC2, yC2);
                    // Draw only if the tile is visible for each civ
                    if (!mapRevealed && !tile.Visibility[civ])
                    {
                        continue;
                    }

                    // Tiles
                    Draw.Tile(g, xC2, yC2, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * row));

                    // Implement dithering in all 4 directions where non-visible tiles are
                    if (!mapRevealed)
                    {
                        int[] offset = new int[] { -1, 1 };
                        for (int tileX = 0; tileX < 2; tileX++)
                        {
                            for (int tileY = 0; tileY < 2; tileY++)
                            {
                                int colNew = xC2 + offset[tileX];
                                int rowNew = yC2 + offset[tileY];
                                if (colNew >= 0 && colNew < Map.XDimMax && 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(MapImages.Terrains[Map.MapIndex].DitherMask[tileX * 2 + tileY], Map.Xpx * (col + tileX), Map.Ypx * (row + tileY));
                                    }
                                }
                            }
                        }
                    }

                    // Units
                    var unitsHere = tile.UnitsHere;
                    if (unitsHere.Count > 0 && (showActiveUnit || unitsHere.All(u => u != activeUnit)) && Map.IsCurrentlyVisible(tile))
                    {
                        Unit unit = unitsHere.Last();
                        if (unitsHere.Any(u => u.Domain == UnitGAS.Sea))
                        {
                            unit = unitsHere.Last(u => u.Domain == UnitGAS.Sea);                                                // Show naval unit
                        }
                        if (!unit.IsInCity)
                        {
                            Draw.Unit(g, unit, unitsHere.Count > 1, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * (row - 1)));
                        }
                    }

                    // Cities
                    var city = tile.CityHere;
                    if (city != null)
                    {
                        Draw.City(g, city, true, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * (row - 1)));
                        // Add city drawn on map & its position to list for drawing city names
                        cityList.Add(city);
                    }

                    if (highlightList != null && highlightList.Contains(tile))
                    {
                        Draw.ViewPiece(g, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * (row - 0)));
                    }

                    if (pathDebug != null && pathDebug.ContainsKey(tile))
                    {
                        g.DrawText(new Font("Times New Roman", 10.ZoomScale(Map.Zoom), FontStyle.Bold), Colors.Black, new Point(Map.Xpx * col + Map.Xpx, Map.Ypx * row),
                                   $"{pathDebug[tile].Steps}:{pathDebug[tile].Cost}");
                    }
                }
            }

            // 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, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * 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, Map.Zoom, destSq);
            }

            return(mapPic);
        }
        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);
            //}
        }
        // 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, bool flatEarth, bool mapRevealed)
        {
            // Define a bitmap for drawing
            var mapPic = new Bitmap(Map.Xpx * (2 * width + 1), Map.Ypx * (height + 1), PixelFormat.Format32bppRgba);

            // 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 = new Graphics(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
                        if (Map.IsTileVisibleC2(startX + col, startY + row, civ) || mapRevealed)
                        {
                            // Tiles
                            Draw.Tile(g, startX + col, startY + row, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * row));

                            // Implement dithering in all 4 directions where non-visible tiles are
                            if (!mapRevealed)
                            {
                                int[] offset = new int[] { -1, 1 };
                                for (int tileX = 0; tileX < 2; tileX++)
                                {
                                    for (int tileY = 0; tileY < 2; tileY++)
                                    {
                                        int colNew = startX + col + offset[tileX];
                                        int rowNew = startY + 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], Map.Xpx * (col + tileX), Map.Ypx * (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 (unitsHere.Contains(Game.GetActiveUnit) && Main.ViewPieceMode)
                                //{

                                //}
                                if (!unit.IsInCity)
                                {
                                    Draw.Unit(g, unit, unitsHere.Count > 1, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * (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, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * (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, Map.Zoom, new Point(Map.Xpx * col, Map.Ypx * 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, Map.Zoom, destSq);
                }
            }

            return(mapPic);
        }
Beispiel #10
0
        public SelectUnitDialog(Main parent, List <Unit> units) : base(parent, 514 + 2 * 11, 46 * Math.Min(units.Count, 9) + 38 + 46, 38, 46, "Select Unit To Activate")
        {
            var shownUnits = units.Take(9).ToList();

            radioBtnList = new RadioButtonList()
            {
                DataStore   = shownUnits,
                Orientation = Orientation.Vertical
            };
            radioBtnList.SelectedIndexChanged += (sender, e) => innerPanel.Invalidate();
            radioBtnList.GotFocus             += (sender, e) => innerPanel.Invalidate();
            Layout.Add(radioBtnList, 11 + 10, 40);

            innerPanel = new Drawable()
            {
                Size = new Size(514, 46 * shownUnits.Count)
            };
            innerPanel.Paint += (sender, e) =>
            {
                e.Graphics.AntiAlias = false;

                // Background
                var imgSize = MapImages.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(MapImages.PanelInnerWallpaper, col * imgSize.Width, row * imgSize.Height);
                    }
                }

                // Draw units, unit outline, text
                for (int row = 0; row < shownUnits.Count; row++)
                {
                    Draw.Unit(e.Graphics, shownUnits[row], false, -1, new Point(2, 2 + 46 * row));

                    string _homeCity = shownUnits[row].HomeCity == null ? "NONE" : shownUnits[row].HomeCity.Name;
                    Draw.Text(e.Graphics, $"{shownUnits[row].Owner.Adjective} {shownUnits[row].Name} ({_homeCity})", new Font("Times New Roman", 18), Color.FromArgb(51, 51, 51), new Point(61, 9 + 46 * row), false, false, Color.FromArgb(191, 191, 191), 1, 1);

                    using var _pen = new Pen(Color.FromArgb(223, 223, 223));
                    if (radioBtnList.SelectedIndex == row)
                    {
                        e.Graphics.DrawRectangle(_pen, new Rectangle(1, 1 + 46 * row, 57, 42));
                    }
                }
            };
            innerPanel.MouseDown += (sender, e) =>
            {
                int clickedRow = ((int)e.Location.Y - 1) / 46;

                shownUnits[clickedRow].Order = OrderType.NoOrders;

                radioBtnList.SelectedIndex = clickedRow;
                innerPanel.Invalidate();
            };
            Layout.Add(innerPanel, 11, 38);

            // Buttons
            DefaultButton = new Civ2button("OK", 258, 36, new Font("Times new roman", 11));
            AbortButton   = new Civ2button("Cancel", 258, 36, new Font("Times new roman", 11));
            Layout.Add(DefaultButton, 9, 42 + innerPanel.Height);
            Layout.Add(AbortButton, 11 + DefaultButton.Width, 42 + innerPanel.Height);

            DefaultButton.Click += (sender, e) =>
            {
                foreach (MenuItem item in parent.Menu.Items)
                {
                    item.Enabled = true;
                }
                SelectedIndex = radioBtnList.SelectedIndex;
                Close();
            };

            AbortButton.Click += (sender, e) =>
            {
                foreach (MenuItem item in parent.Menu.Items)
                {
                    item.Enabled = true;
                }
                SelectedIndex = int.MinValue;
                Close();
            };

            Content = Layout;
        }