コード例 #1
0
        /// <summary>
        /// Gets the current FOW-state at the given quadratic tile.
        /// </summary>
        /// <param name="quadCoords">The quadratic coordinates of the tile.</param>
        /// <returns>The current FOW-state at the given quadratic tile.</returns>
        public FOWTypeEnum GetFowStateAtQuadTile(RCIntVector quadCoords)
        {
            /// Consider FOWTypeEnum.None at coordinates outside of the map.
            if (quadCoords.X < 0 || quadCoords.X >= this.scenario.Map.Size.X || quadCoords.Y < 0 || quadCoords.Y >= this.scenario.Map.Size.Y)
            {
                return(FOWTypeEnum.None);
            }

            /// If the FOW-state of the given tile has not yet been cached or is invalid, then calculate and save it to the cache.
            if (this.scenario.CurrentFrameIndex != this.fowCacheMatrix[quadCoords.X, quadCoords.Y].LastFowStateUpdate)
            {
                bool        isFowRunning = false;
                FOWTypeEnum minimumFow   = FOWTypeEnum.Full;
                for (int idx = 0; idx < Player.MAX_PLAYERS; idx++)
                {
                    if (this.runningFows[idx] != null)
                    {
                        FOWTypeEnum fowAtQuadTile = this.runningFows[idx].GetFogOfWar(quadCoords);
                        if (fowAtQuadTile < minimumFow)
                        {
                            minimumFow = fowAtQuadTile;
                        }
                        isFowRunning = true;
                    }
                }

                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].LastFowStateUpdate = this.scenario.CurrentFrameIndex;
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].FowState           = isFowRunning ? minimumFow : FOWTypeEnum.None;
            }

            /// Return with the cached value.
            return(this.fowCacheMatrix[quadCoords.X, quadCoords.Y].FowState);
        }
コード例 #2
0
ファイル: FogOfWarBC.cs プロジェクト: kovacsgabor55/marsara
        /// <see cref="IFogOfWarBC.GetEntitySnapshotsInWindow"/>
        public IEnumerable <EntitySnapshot> GetEntitySnapshotsInWindow(RCIntRectangle quadWindow)
        {
            if (this.ActiveScenario == null)
            {
                throw new InvalidOperationException("No active scenario!");
            }
            if (this.runningFowsCount == 0)
            {
                yield break;
            }

            for (int column = quadWindow.Left; column < quadWindow.Right; column++)
            {
                for (int row = quadWindow.Top; row < quadWindow.Bottom; row++)
                {
                    RCIntVector quadCoords = new RCIntVector(column, row);

                    /// If the FOW is full at the current quadratic tile -> continue with the next.
                    FOWTypeEnum fowAtQuadTile = this.fowCacheMatrix.GetFowStateAtQuadTile(quadCoords);
                    if (fowAtQuadTile == FOWTypeEnum.Full)
                    {
                        continue;
                    }

                    /// Add the entity snapshot into the returned list.
                    EntitySnapshot snapshot = this.fowCacheMatrix.GetEntitySnapshotAtQuadTile(quadCoords);
                    if (snapshot != null)
                    {
                        yield return(snapshot);
                    }
                }
            }
        }
コード例 #3
0
ファイル: FogOfWarTest.cs プロジェクト: kovacsgabor55/marsara
        /// <summary>
        /// Tests whether the FOWSpriteGroup for drawing the given type of Fog Of War is generated properly.
        /// </summary>
        private void FOWSpriteGroupTest(FOWTypeEnum fowType)
        {
            /// Load the Fog Of War sprite palette and create a FOWSpriteGroup out of it.
            string    fowSpritePalettePath             = System.IO.Path.Combine(FOW_SPRITEPALETTE_DIR, FOW_SPRITEPALETTE_FILE);
            XDocument fowSpritePaletteXml              = XDocument.Load(fowSpritePalettePath);
            ISpritePalette <FOWTypeEnum> spritePalette = XmlHelper.LoadSpritePalette(fowSpritePaletteXml.Root, fowType, FOW_SPRITEPALETTE_DIR);
            FOWSpriteGroup spriteGroup = new FOWSpriteGroup(spritePalette, fowType);

            spriteGroup.Load();

            /// Check that 2 UISprite instances are the same if and only if they images have the same bytes.
            PrivateObject    spriteGroupObj  = new PrivateObject(spriteGroup, new PrivateType(typeof(SpriteGroup)));
            List <UISprite>  fowSprites      = (List <UISprite>)spriteGroupObj.GetField("spriteList");
            RCSet <UISprite> savedFowSprites = new RCSet <UISprite>();

            for (int indexA = 0; indexA < fowSprites.Count - 1; indexA++)
            {
                if (fowSprites[indexA] == null)
                {
                    continue;
                }
                byte[] bytesOfSpriteA = fowSprites[indexA].Save();
                for (int indexB = indexA + 1; indexB < fowSprites.Count; indexB++)
                {
                    if (fowSprites[indexB] == null)
                    {
                        continue;
                    }
                    byte[] bytesOfSpriteB = fowSprites[indexB].Save();

                    if (StructuralComparisons.StructuralEqualityComparer.Equals(bytesOfSpriteA, bytesOfSpriteB))
                    {
                        Assert.AreEqual(fowSprites[indexA], fowSprites[indexB]);
                    }
                    else
                    {
                        Assert.AreNotEqual(fowSprites[indexA], fowSprites[indexB]);
                    }
                }

                if (savedFowSprites.Add(fowSprites[indexA]))
                {
                    string outputPath = System.IO.Path.Combine(OUTPUT_DIR, string.Format("{0}_{1}.png", fowType, Convert.ToString(indexA, 2).PadLeft(9, '0')));
                    File.WriteAllBytes(outputPath, bytesOfSpriteA);
                }
            }

            /// Destroy the FOWSpriteGroup object.
            spriteGroup.Unload();
        }
コード例 #4
0
ファイル: MinimapView.cs プロジェクト: kovacsgabor55/marsara
        /// <summary>
        /// Gets the FOW-status at the given minimap pixel.
        /// </summary>
        /// <param name="pixelCoords">The coordinates of the pixel on the minimap image.</param>
        /// <returns>The FOW-status at the given minimap pixel.</returns>
        private FOWTypeEnum GetFowStateAtPixel(RCIntVector pixelCoords)
        {
            RCIntRectangle quadRect       = this.MapWindowBC.Minimap.GetMinimapPixel(pixelCoords).CoveredQuadTiles;
            FOWTypeEnum    lowestFowState = FOWTypeEnum.Full;

            for (int column = quadRect.Left; column < quadRect.Right; column++)
            {
                for (int row = quadRect.Top; row < quadRect.Bottom; row++)
                {
                    FOWTypeEnum currentFowState = this.fogOfWarBC.GetFowState(new RCIntVector(column, row));
                    if (currentFowState == FOWTypeEnum.None)
                    {
                        lowestFowState = currentFowState;
                        break;
                    }
                    if ((int)currentFowState < (int)lowestFowState)
                    {
                        lowestFowState = currentFowState;
                    }
                }
            }
            return(lowestFowState);
        }
コード例 #5
0
        /// <summary>
        /// Constructs a FOWSpriteGroup instance from the given sprite palette.
        /// </summary>
        /// <param name="spritePalette">The sprite palette that contains the sprites for drawing the Fog Of War.</param>
        /// <param name="fowType">The type of the Fog Of War stored in this sprite-group.</param>
        public FOWSpriteGroup(ISpritePalette <FOWTypeEnum> spritePalette, FOWTypeEnum fowType)
        {
            if (spritePalette == null)
            {
                throw new ArgumentNullException("spritePalette");
            }
            if (fowType == FOWTypeEnum.None)
            {
                throw new ArgumentException("FOWSpriteGroup cannot store sprites for FOWTypeEnum.None!", "fowType");
            }
            if (spritePalette.TransparentColor == RCColor.Undefined)
            {
                throw new ArgumentException("Transparent color is not defined for FOW sprite palette!", "spritePalette");
            }

            this.spritePalette = spritePalette;
            this.fowType       = fowType;

            this.spriteIndices = new Dictionary <FOWTileFlagsEnum, int>();
            foreach (KeyValuePair <FOWTileFlagsEnum, string> item in SPRITE_NAMES)
            {
                this.spriteIndices[item.Key] = this.spritePalette.GetSpriteIndex(item.Value, this.fowType);
            }
        }
コード例 #6
0
        /// <summary>
        /// Calculates the FOW-flags for the given quadratic tile.
        /// </summary>
        /// <param name="quadCoords">The quadratic coordinates of the tile.</param>
        private void CalculateFowFlags(RCIntVector quadCoords)
        {
            FOWTypeEnum fowAtQuadCoords = this.GetFowStateAtQuadTile(quadCoords);

            if (fowAtQuadCoords == FOWTypeEnum.Full)
            {
                /// Full FOW-state -> draw only full FOW.
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].FullFowFlags    = FOWTileFlagsEnum.Current;
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].PartialFowFlags = FOWTileFlagsEnum.None;
            }
            else if (fowAtQuadCoords == FOWTypeEnum.Partial)
            {
                /// Partial FOW-state -> draw partial FOW and calculate full FOW-flags based on the neighbours.
                FOWTileFlagsEnum fullFowFlags = FOWTileFlagsEnum.None;
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.North;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.NorthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 0)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.East;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.SouthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.South;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.SouthWest;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 0)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.West;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.NorthWest;
                }
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].FullFowFlags    = fullFowFlags;
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].PartialFowFlags = FOWTileFlagsEnum.Current;
            }
            else if (fowAtQuadCoords == FOWTypeEnum.None)
            {
                /// No FOW -> calculate full & partial FOW-flags based on the neighbours.
                FOWTileFlagsEnum fullFowFlags = FOWTileFlagsEnum.None;
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.North;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.NorthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 0)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.East;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.SouthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.South;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.SouthWest;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 0)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.West;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, -1)) == FOWTypeEnum.Full)
                {
                    fullFowFlags |= FOWTileFlagsEnum.NorthWest;
                }
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].FullFowFlags = fullFowFlags;

                FOWTileFlagsEnum partialFowFlags = FOWTileFlagsEnum.None;
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, -1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.North;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, -1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.NorthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 0)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.East;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(1, 1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.SouthEast;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(0, 1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.South;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.SouthWest;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, 0)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.West;
                }
                if (this.GetFowStateAtQuadTile(quadCoords + new RCIntVector(-1, -1)) != FOWTypeEnum.None)
                {
                    partialFowFlags |= FOWTileFlagsEnum.NorthWest;
                }
                this.fowCacheMatrix[quadCoords.X, quadCoords.Y].PartialFowFlags = partialFowFlags;
            }
        }
コード例 #7
0
ファイル: FogOfWarBC.cs プロジェクト: kovacsgabor55/marsara
        /// <summary>
        /// Implements visibility calculations when at least 1 FogOfWar is running.
        /// </summary>
        /// <returns>The results of the visibility calculations.</returns>
        private FowVisibilityInfo CalculateVisibilityWithFow()
        {
            if (this.quadTileWindow == RCIntRectangle.Undefined)
            {
                throw new InvalidOperationException("Visibility window not defined!");
            }

            /// Collect the isometric & quadratic tiles that need to be updated.
            IMapAccess             map = this.ActiveScenario.Map;
            RCSet <IIsoTile>       isoTilesToUpdate        = new RCSet <IIsoTile>();
            RCSet <IQuadTile>      quadTilesToUpdate       = new RCSet <IQuadTile>();
            RCSet <ITerrainObject> terrainObjectsToUpdate  = new RCSet <ITerrainObject>();
            RCSet <EntitySnapshot> entitySnapshotsToUpdate = new RCSet <EntitySnapshot>();

            for (int column = this.quadTileWindow.Left; column < this.quadTileWindow.Right; column++)
            {
                for (int row = this.quadTileWindow.Top; row < this.quadTileWindow.Bottom; row++)
                {
                    RCIntVector quadCoords = new RCIntVector(column, row);

                    /// If the FOW is full at the current quadratic tile -> continue with the next.
                    FOWTypeEnum fowAtQuadTile = this.fowCacheMatrix.GetFowStateAtQuadTile(quadCoords);
                    if (fowAtQuadTile == FOWTypeEnum.Full)
                    {
                        continue;
                    }

                    /// Add the primary & secondary isometric tiles and all of their cutting quadratic tiles into the update lists.
                    IQuadTile quadTileToUpdate = map.GetQuadTile(quadCoords);
                    this.AddIsoTileToUpdate(quadTileToUpdate.PrimaryIsoTile, isoTilesToUpdate, quadTilesToUpdate);
                    this.AddIsoTileToUpdate(quadTileToUpdate.SecondaryIsoTile, isoTilesToUpdate, quadTilesToUpdate);

                    /// Add the terrain object and all of its cutting quadratic tiles into the update lists.
                    this.AddTerrainObjectToUpdate(quadTileToUpdate.TerrainObject, terrainObjectsToUpdate, quadTilesToUpdate);

                    /// Add the entity snapshot and all of its cutting quadratic tiles into the update lists.
                    EntitySnapshot entitySnapshotAtQuadTile = this.fowCacheMatrix.GetEntitySnapshotAtQuadTile(quadCoords);
                    this.AddEntitySnapshotToUpdate(entitySnapshotAtQuadTile, entitySnapshotsToUpdate, quadTilesToUpdate);
                }
            }

            /// Collect the currently visible map objects on the ground.
            RCSet <MapObject> groundObjectsOnMap = this.ActiveScenario.GetMapObjects(
                this.mapWindowBC.AttachedWindow.WindowMapCoords,
                MapObjectLayerEnum.GroundObjects,
                MapObjectLayerEnum.GroundMissiles);
            RCSet <MapObject> groundMapObjectsToUpdate = new RCSet <MapObject>();

            foreach (MapObject groundMapObj in groundObjectsOnMap)
            {
                bool breakLoop = false;
                for (int col = groundMapObj.QuadraticPosition.Left; !breakLoop && col < groundMapObj.QuadraticPosition.Right; col++)
                {
                    for (int row = groundMapObj.QuadraticPosition.Top; !breakLoop && row < groundMapObj.QuadraticPosition.Bottom; row++)
                    {
                        if (this.fowCacheMatrix.GetFowStateAtQuadTile(new RCIntVector(col, row)) == FOWTypeEnum.None)
                        {
                            /// Found at least 1 quadratic tile where the map objects is visible.
                            this.AddMapObjectToUpdate(groundMapObj, groundMapObjectsToUpdate, quadTilesToUpdate);
                            breakLoop = true;
                        }
                    }
                }
            }

            /// Collect the currently visible map objects in the air.
            RCSet <MapObject> airObjectsOnMap = this.ActiveScenario.GetMapObjects(
                this.mapWindowBC.AttachedWindow.WindowMapCoords,
                MapObjectLayerEnum.AirObjects,
                MapObjectLayerEnum.AirMissiles);
            RCSet <MapObject> airMapObjectsToUpdate = new RCSet <MapObject>();

            foreach (MapObject airMapObj in airObjectsOnMap)
            {
                bool breakLoop = false;
                for (int col = airMapObj.QuadraticPosition.Left; !breakLoop && col < airMapObj.QuadraticPosition.Right; col++)
                {
                    for (int row = airMapObj.QuadraticPosition.Top; !breakLoop && row < airMapObj.QuadraticPosition.Bottom; row++)
                    {
                        if (this.fowCacheMatrix.GetFowStateAtQuadTile(new RCIntVector(col, row)) == FOWTypeEnum.None)
                        {
                            /// Found at least 1 quadratic tile where the map objects is visible.
                            this.AddMapObjectToUpdate(airMapObj, airMapObjectsToUpdate, quadTilesToUpdate);
                            breakLoop = true;
                        }
                    }
                }
            }

            /// Create the calculated visibility info.
            return(new FowVisibilityInfo
            {
                IsoTilesToUpdate = isoTilesToUpdate,
                TerrainObjectsToUpdate = terrainObjectsToUpdate,
                QuadTilesToUpdate = quadTilesToUpdate,
                EntitySnapshotsToUpdate = entitySnapshotsToUpdate,
                GroundMapObjectsToUpdate = groundMapObjectsToUpdate,
                AirMapObjectsToUpdate = airMapObjectsToUpdate
            });
        }