Example #1
0
 /// <summary>
 /// All the players at a certain position
 /// </summary>
 /// <param name="position">The tile to search</param>
 /// <returns>All the players at a certain position</returns>
 public IEnumerable<int> PlayersAtPosition(Tile position)
 {
     foreach (int player in _playerPositions.Keys)
     {
         if (_playerPositions[player] == position)
         { yield return player; }
     }
 }
Example #2
0
 private int SummarizeState(Tile tile)
 {
     int HashCode =
     tile.X * 200 ^
     tile.Y * 1000 ^
     (tile.EffectiveLightLevel > 0 ? tile.ImageName : String.Empty).GetHashCode() ^
     Math.Min(tile.EffectiveLightLevel, 10) * 5000 ^
     (tile.IsRevealed ? 1 : 2);
     return HashCode;
 }
        private void ScrollTileToCenter(Tile tile)
        {
            int x = tile.X * MapInfo.GridConfig.TileWidth;
            int y = tile.Y * MapInfo.GridConfig.TileHeight;
            x -= Parent.ClientSize.Width / 2;
            y -= Parent.ClientSize.Height / 2;

            if (Parent is Panel)
            { ((Panel)Parent).AutoScrollPosition = new Point(x, y); }
        }
Example #4
0
 /// <summary>
 /// Moves a player token and any light source at the players current location, to a new location
 /// </summary>
 /// <param name="player">The player to be moved</param>
 /// <param name="destination">The tile to move the player to</param>
 public void MovePlayer(int player, Tile destination)
 {
     Contract.Requires(destination != null);
     int lightSource = 0;
     Tile old = null;
     if (_playerPositions.TryGetValue(player, out old) && old != null)
     {
         bool stillPresent = false;
         foreach (int p in _playerPositions.Keys)
         {
             if (_playerPositions[p] == old && p != player)
             { stillPresent = true; }
         }
         old.IsPlayerPresent = stillPresent;
         lightSource = old.LightSource;
         old.LightSource = 0;
     }
     _playerPositions[player] = destination;
     destination.IsPlayerPresent = true;
     destination.LightSource = Math.Max(lightSource, destination.LightSource);
 }
 private void DoAction(Tile tile, Tile nearest, ClickAction action)
 {
     Contract.Requires(tile != null);
     if (MapInfo == null)
     { return; }
     switch (action)
     {
         case ClickAction.ToggleWallBlocksLOS:
             if (nearest == null) { return; }
             if (tile.NoLOSBetweenTiles.Contains(nearest))
             {
                 tile.NoLOSBetweenTiles.Remove(nearest);
                 nearest.NoLOSBetweenTiles.Remove(tile);
             }
             else
             {
                 tile.NoLOSBetweenTiles.Remove(nearest);
                 nearest.NoLOSBetweenTiles.Remove(tile);
                 tile.NoLOSBetweenTiles.Add(nearest);
                 nearest.NoLOSBetweenTiles.Add(tile);
             }
             break;
         case ClickAction.ToggleSecret:
             if (!tile.HasSecret) { return; }
             bool newState = !tile.IsRevealed;
             foreach (Tile t in tile.Search(5, false, (t => t.HasSecret && t.IsRevealed != newState)).Flatten())
             {
                 t.IsRevealed = newState;
             }
             break;
         case ClickAction.MovePlayerMarker1:
             Tile start = MapInfo.PositionOfPlayer(1);
             if (start != null)
             {
                 bool animate = AnimatePlayerMovement;
                 IEnumerable<Tile> path = start.FindShortestPath(tile);
                 if (path != null)
                 {
                     int count = 0;
                     foreach (Tile step in path)
                     {
                         count++;
                         if (count % 2 != 0 && !animate)
                         { continue; }
                         if (animate)
                         { PlayerFollowingPath.Enqueue(step); }
                         else
                         {
                             MapInfo.MovePlayer(1, step);
                             MapInfo.RecalculateLightAndLineOfSight(true);
                         }
                     }
                 }
                 if (!animate || path == null)
                 { MapInfo.MovePlayer(1, tile); }
             }
             else
             { MapInfo.MovePlayer(1, tile); }
             ScrollTileToCenter(tile);
             break;
         case ClickAction.MovePlayerMarker2:
             MapInfo.MovePlayer(2, tile);
             break;
         case ClickAction.MovePlayerMarker3:
             MapInfo.MovePlayer(3, tile);
             break;
         case ClickAction.ToggleLightCustom:
             tile.LightSource = tile.LightSource == CustomLightLevel ? 0 : CustomLightLevel;
             break;
         case ClickAction.ToggleLight100:
             tile.LightSource = tile.LightSource == 20 ? 0 : 20;
             break;
         case ClickAction.ToggleLight50:
             tile.LightSource = tile.LightSource == 10 ? 0 : 10;
             break;
         case ClickAction.ToggleLight10:
             tile.LightSource = tile.LightSource == 5 ? 0 : 5;
             break;
         default:
             //do nothing
             break;
     }
     MapInfo.RecalculateLightAndLineOfSight();
     Refresh();
 }
        private AllBorders DrawTileIcon(Tile tile, Graphics g, Rectangle r)
        {
            Contract.Requires(tile != null);
            Contract.Requires(g != null);
            Contract.Requires(r != null);

            AllBorders borderInfo = new AllBorders();
            borderInfo.noAdjacent = CompareTileBorders(tile);
            borderInfo.top = borderInfo.noAdjacent;
            borderInfo.left = borderInfo.noAdjacent;
            borderInfo.right = borderInfo.noAdjacent;
            borderInfo.bottom = borderInfo.noAdjacent;
            borderInfo.r = r;

            int tx = tile.X;
            int ty = tile.Y;
            foreach (Tile t in tile.AdjacentTiles)
            {
                if (t == null) { continue; }
                BorderDesc border = CompareTileBorders(tile, t);
                if (tx == t.X)
                {
                    if (t.Y == ty - 1)
                    { borderInfo.top = border; }
                    else if (t.Y == ty + 1)
                    { borderInfo.bottom = border; }
                }
                else if (ty == t.Y)
                {
                    if (t.X == tx - 1)
                    { borderInfo.left = border; }
                    else if (t.X == tx + 1)
                    { borderInfo.right = border; }
                }
            }
            if (!WallEditMode)
            {
                if (tile.HasSecret)
                {
                    if (tile.IsRevealed && _secretRevealedIcon != null)
                    {
                        g.DrawImage(_secretRevealedIcon, r);
                    }
                    else if (!tile.IsRevealed && _secretHiddenIcon != null)
                    {
                        g.DrawImage(_secretHiddenIcon, r);
                    }
                }
                if (tile.IsPlayerPresent)
                {
                    int first = Math.Max(1, MapInfo.PlayersAtPosition(tile).FirstOrDefault());
                    first = Math.Min(LineOfSightIcons.Count, first);
                    first -= 1;
                    g.DrawImage(LineOfSightIcons[first], r);
                }
                if (tile.LightSource > 0)
                {
                    int lastLevel = _lightLevels.FirstOrDefault();
                    foreach (int level in _lightLevels)
                    {
                        if (level <= tile.LightSource)
                        {
                            lastLevel = level;
                        }
                    }
                    Image icon;
                    if (_lightIcons.TryGetValue(lastLevel, out icon))
                    {
                        g.DrawImage(icon, r);
                    }
                }

                int alpha = (int)((double)(10 - tile.LightLevel) / 10 * 255 * .5);
                alpha = Math.Min(255, Math.Max(0, alpha));
                using (Brush lightBrush = new SolidBrush(Color.FromArgb(alpha, Color.Black)))
                {
                    g.FillRectangle(lightBrush, r);
                }
            }
            return borderInfo;
        }
Example #7
0
 private bool HasLOS(Tile target, IDictionary<int, Tile> tiles)
 {
     int tx = target.X;
     int ty = target.Y;
     int cx = X;
     int cy = Y;
     if (cx == tx && cy == ty)
     { return true; }
     double wiggle = 0.25;
     bool los = false;
     los |= CheckLine(cx, cy, tx, ty, tiles);
     los |= CheckLine(cx - wiggle, cy, tx, ty, tiles);
     los |= CheckLine(cx + wiggle, cy, tx, ty, tiles);
     los |= CheckLine(cx, cy - wiggle, tx, ty, tiles);
     los |= CheckLine(cx, cy + wiggle, tx, ty, tiles);
     return los;
 }
 private static BorderDesc CompareTileBorders(Tile current, Tile neighbor = null)
 {
     Contract.Requires(current != null);
     BorderDesc result = new BorderDesc();
     if (neighbor == null)
     {
         result.IsLightBorder = current.LightLevel >= 5;
         result.IsSecretHiddenBorder = current.HasSecret && !current.IsRevealed;
         result.IsSecretRevealedBorder = current.HasSecret && current.IsRevealed;
     }
     else
     {
         result.IsLightBorder = current.LightLevel >= 5 && neighbor.LightLevel < 5;
         result.IsSecretHiddenBorder = (current.HasSecret && !current.IsRevealed) && (!neighbor.HasSecret || neighbor.IsRevealed);
         result.IsSecretRevealedBorder = (current.HasSecret && current.IsRevealed) && (!neighbor.HasSecret || !neighbor.IsRevealed);
         result.IsBlocksLOSBorder = current.NoLOSBetweenTiles.Contains(neighbor);
     }
     return result;
 }
Example #9
0
 public IEnumerable<Tile> FindShortestPath(Tile other)
 {
     if (other == null) { return null; }
     int totaldist = DistanceWalking(other);
     if (totaldist == -1) { return null; }
     List<Tile> pathToFollow = new List<Tile>();
     Tile current = this;
     Tile nextTile = current;
     while (true)
     {
         int lowestWalking = int.MaxValue;
         int lowestManhattan = int.MaxValue;
         foreach (Tile tile in current.AdjacentTiles)
         {
             if (current.NoLOSBetweenTiles.Contains(tile))
             { continue; }
             if (pathToFollow.Contains(tile))
             { continue; }
             int distW = tile.DistanceWalking(other);
             int distM = tile.DistanceManhattan(other);
             if (distW == -1)
             { continue; }
             if (distW <= lowestWalking)
             {
                 if (distW != lowestWalking || distM < lowestManhattan)
                 {
                     lowestWalking = distW;
                     lowestManhattan = distM;
                     nextTile = tile;
                 }
             }
         }
         pathToFollow.Add(current);
         if (nextTile == null) { return null; }
         if (current == other) { return pathToFollow; }
         current = nextTile;
         nextTile = null;
     }
 }
Example #10
0
 /// <summary>
 /// Returns the walking distance between two tiles without going outside the specified path
 /// </summary>
 /// <param name="other"></param>
 /// <param name="path">if null will use a default stepped search</param>
 /// <returns>Returns the walking distance between two tiles without going outside the specified path or -1 if the two tiles do not have any path between them</returns>
 public int DistanceWalking(Tile other, IEnumerable<IEnumerable<Tile>> path = null)
 {
     if (other == null) { return -1; }
     if (path == null)
     { return DistanceWalking(other, Search()); }
     int stepCounter = 0;
     foreach (IEnumerable<Tile> step in path)
     {
         if (step != null && step.Contains(other))
         { return stepCounter; }
         stepCounter++;
     }
     return -1;
 }
Example #11
0
 /// <summary>
 /// Returns the distance between two tiles based on their coordinates using manhattan style (diagonal movement not allowed)
 /// </summary>
 /// <param name="other"></param>
 /// <returns>the distance between two tiles based on their coordinates using manhattan style (diagonal movement not allowed)</returns>
 public int DistanceManhattan(Tile other)
 {
     Contract.Requires(other != null);
     Contract.Ensures(Contract.Result<int>() >= 0);
     return Util.Abs(X - other.X) + Util.Abs(Y - other.Y);
 }
        /**
         * Analyzes an section of an image to determine it's properties.
         * Specifcally if it is empty, if the two layers differ, and it generates a name that can be used to sufficiently uniquely identify a tile
         */
        private static Tile AnalyzeImageTile(Bitmap publicLayer, Bitmap secretLayer, Rectangle rect, DirectoryInfo saveTiles, int borderWidth)
        {
            Contract.Requires(publicLayer != null);
            Contract.Requires(rect.Width > 0);
            Contract.Requires(rect.Height > 0);
            Contract.Requires(rect.Left >= 0);
            Contract.Requires(rect.Top >= 0);

            Rectangle innerRect = new Rectangle(rect.X + borderWidth, rect.Y + borderWidth, rect.Width - borderWidth * 2, rect.Height - borderWidth * 2);
            if (innerRect.Left < 0 || innerRect.Top < 0)
            { throw new CodeContractsException(); }
            Tile result = new Tile();

            byte[] publicBytes = null;
            byte[] secretBytes = null;

            publicBytes = getBytes(publicLayer, innerRect);
            if (secretLayer != null && secretLayer != publicLayer)
            { secretBytes = getBytes(secretLayer, innerRect); }
            else
            { secretBytes = publicBytes; }

            if (publicBytes == null)
            { throw new CodeContractsException(); }
            int size = publicBytes.Length;

            bool PAllZero = true;
            bool PAllFF = true;
            bool SAllZero = true;
            bool SAllFF = true;
            bool AllSame = true;

            for (int i = 0; i < size; i++)
            {
                if (publicBytes[i] != 0) { PAllZero = false; }
                if (publicBytes[i] != 255) { PAllFF = false; }
            }
            if (secretBytes != null)
            {
                if (size > secretBytes.Length)
                { throw new CodeContractsException(); }
                for (int i = 0; i < size; i++)
                {
                    if (secretBytes[i] != 0) { SAllZero = false; }
                    if (secretBytes[i] != 255) { SAllFF = false; }
                    if (publicBytes[i] != secretBytes[i]) { AllSame = false; }
                }
            }

            //re-fetch image with wider borders
            innerRect = new Rectangle(rect.X + (borderWidth - 1), rect.Y + (borderWidth - 1), rect.Width - (borderWidth - 1) * 2, rect.Height - (borderWidth - 1) * 2);
            publicBytes = getBytes(publicLayer, innerRect);
            if (secretLayer != null && secretLayer != publicLayer)
            { secretBytes = getBytes(secretLayer, innerRect); }
            else
            { secretBytes = publicBytes; }

            String pName = makeName(publicBytes) + ".png";
            String sName = secretBytes != null ? makeName(secretBytes) + ".png" : pName;

            result.HasSecret = !AllSame;
            result.IsEmptyPublic = PAllZero || PAllFF;
            result.IsEmptySecret = SAllZero || SAllFF;

            result.ImageNamePublic = pName;
            result.ImageNameSecret = sName;

            if (saveTiles != null && !result.IsAlwaysEmpty)
            {
                String pFileName = Path.Combine(saveTiles.FullName, pName);
                String sFileName = Path.Combine(saveTiles.FullName, sName);
                if (String.IsNullOrWhiteSpace(pFileName) || String.IsNullOrWhiteSpace(sFileName))
                {
                    throw new CodeContractsException("This should never be called because I appended a literal string to both pName and sName");
                }
                SaveTile(publicLayer, rect, pFileName);
                if (!AllSame && secretLayer != null)
                {
                    SaveTile(secretLayer, rect, sFileName);
                }
            }
            return result;
        }
        public static MapInfo Deserialize(Stream stream, DirectoryInfo tileFolder, bool isCompressed = true)
        {
            Contract.Requires(stream != null);
            Contract.Requires(tileFolder != null);

            if (!tileFolder.Exists)
            { tileFolder.Create(); }
            foreach (FileInfo tile in tileFolder.GetFiles())
            { tile.Delete(); }
            MapInfoSerializeContainer container;
            if (isCompressed)
            {
                using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress))
                { container = Serializer.Deserialize<MapInfoSerializeContainer>(ds); }
            }
            else
            { container = Serializer.Deserialize<MapInfoSerializeContainer>(stream); }
            foreach (String tile in container.TileImages.Keys)
            {
                using (FileStream ts = new FileStream(Path.Combine(tileFolder.FullName, tile), FileMode.Create))
                {
                    byte[] bytes = container.TileImages[tile];
                    ts.Write(bytes, 0, bytes.Length);
                }
            }
            MapInfo map = new MapInfo();
            map.TileFolder = tileFolder;

            map.GridConfig.TileWidth = container.Grid.Width;
            map.GridConfig.TileHeight = container.Grid.Height;
            map.GridConfig.TileOffsetX = container.Grid.OffsetX;
            map.GridConfig.TileOffsetY = container.Grid.OffsetY;
            map.GridConfig.TileBorder = container.Grid.Border;

            map.PublicImage = LoadImage(container.PublicImage);
            map.SecretImage = LoadImage(container.SecretImage);

            Dictionary<MapInfoSerializeContainer.TileClass, Tile> convertedTiles = new Dictionary<MapInfoSerializeContainer.TileClass, Tile>();
            if (container.Tiles != null)
            {
                foreach (MapInfoSerializeContainer.TileClass serializedTile in container.Tiles)
                {
                    Tile tile = new Tile();
                    tile.X = serializedTile.X;
                    tile.Y = serializedTile.Y;
                    tile.IsEmptyPublic = serializedTile.EmptyPublic;
                    tile.IsEmptySecret = serializedTile.EmptySecret;
                    tile.HasSecret = serializedTile.HasSecret;
                    tile.IsRevealed = serializedTile.IsRevealed;
                    tile.ImageNamePublic = serializedTile.NamePublic;
                    tile.ImageNameSecret = serializedTile.NameSecret;
                    tile.LightLevel = serializedTile.LightLevel;
                    tile.LightSource = serializedTile.LightSource;
                    convertedTiles.Add(serializedTile, tile);
                    map.Tiles.Add(tile);
                }
                foreach (MapInfoSerializeContainer.TileClass serializedTile in container.Tiles)
                {
                    if (serializedTile.Adjacent == null)
                    { continue; }
                    Tile tile = convertedTiles[serializedTile];
                    foreach (MapInfoSerializeContainer.TileClass adjacent in serializedTile.Adjacent)
                    { tile.AdjacentTiles.Add(convertedTiles[adjacent]); }
                    if (serializedTile.NoLOS != null)
                    {
                        foreach (MapInfoSerializeContainer.TileClass noLOS in serializedTile.NoLOS)
                        { tile.NoLOSBetweenTiles.Add(convertedTiles[noLOS]); }
                    }
                }
            }
            int playerNum = 1;
            if (container.PlayerPositions != null)
            {
                foreach (MapInfoSerializeContainer.TileClass position in container.PlayerPositions)
                {
                    map.MovePlayer(playerNum++, convertedTiles[position]);
                }
            }
            return map;
        }