Ejemplo n.º 1
0
        /// <see cref="IMapEditorService.PlaceVespeneGeyser"/>
        public bool PlaceVespeneGeyser(RCIntVector position)
        {
            if (this.scenarioManager.ActiveScenario == null)
            {
                throw new InvalidOperationException("No active scenario!");
            }
            if (position == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("position");
            }

            RCIntVector navCellCoords = this.mapWindowBC.AttachedWindow.WindowToMapCoords(position).Round();
            IQuadTile   quadTileAtPos = this.scenarioManager.ActiveScenario.Map.GetCell(navCellCoords).ParentQuadTile;

            IScenarioElementType objectType        = this.scenarioManager.Metadata.GetElementType(VespeneGeyser.VESPENEGEYSER_TYPE_NAME);
            RCIntVector          objQuadSize       = this.scenarioManager.ActiveScenario.Map.CellToQuadSize(objectType.Area.Read().Size);
            RCIntVector          topLeftQuadCoords = quadTileAtPos.MapCoords - objQuadSize / 2;

            if (objectType.CheckPlacementConstraints(this.scenarioManager.ActiveScenario, topLeftQuadCoords, new RCSet <Entity>()).Count != 0)
            {
                return(false);
            }

            VespeneGeyser placedVespeneGeyser = new VespeneGeyser();

            this.scenarioManager.ActiveScenario.AddElementToScenario(placedVespeneGeyser);
            placedVespeneGeyser.AttachToMap(this.scenarioManager.ActiveScenario.Map.GetQuadTile(topLeftQuadCoords));
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Attaches this entity to the given quadratic tile on the map.
        /// </summary>
        /// <param name="topLeftTile">The quadratic tile at the top-left corner of this entity.</param>
        /// <param name="elementsToIgnore">An optional list of scenario elements to ignore during attach.</param>
        /// <returns>True if this entity was successfully attached to the map; otherwise false.</returns>
        /// <remarks>Note that the caller has to explicitly call MotionControl.Fix to fix this entity after calling this method.</remarks>
        public bool AttachToMap(IQuadTile topLeftTile, params ScenarioElement[] elementsToIgnore)
        {
            ICell       topLeftCell = topLeftTile.GetCell(new RCIntVector(0, 0));
            RCNumVector position    = topLeftCell.MapCoords - new RCNumVector(1, 1) / 2 - this.ElementType.Area.Read().Location;

            return(this.AttachToMap(position, elementsToIgnore));
        }
Ejemplo n.º 3
0
        /// <see cref="ITerrainObjectConstraint.Check"/>
        public RCSet <RCIntVector> Check(IMapAccess map, RCIntVector position)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            if (position == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("position");
            }

            RCSet <RCIntVector> retList       = new RCSet <RCIntVector>();
            RCIntVector         absQuadCoords = position + this.quadCoords;

            if (absQuadCoords.X >= 0 && absQuadCoords.X < map.Size.X &&
                absQuadCoords.Y >= 0 && absQuadCoords.Y < map.Size.Y)
            {
                IQuadTile checkedQuadTile = map.GetQuadTile(absQuadCoords);
                IIsoTile  checkedIsoTile  = checkedQuadTile.PrimaryIsoTile;
                if (checkedIsoTile.Type.TerrainA != this.terrainA ||
                    checkedIsoTile.Type.TerrainB != this.terrainB ||
                    !this.allowedCombinations.Contains(checkedIsoTile.Type.Combination))
                {
                    retList.Add(this.quadCoords);
                    foreach (IQuadTile neighbour in checkedQuadTile.Neighbours)
                    {
                        if (neighbour.PrimaryIsoTile == checkedIsoTile)
                        {
                            retList.Add(neighbour.MapCoords - position);
                        }
                    }
                }
            }
            return(retList);
        }
Ejemplo n.º 4
0
        /// <see cref="IScenarioLoader.LoadScenario"/>
        public Scenario LoadScenario(IMapAccess map, byte[] data)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            /// Load the packages from the byte array.
            int      offset   = 0;
            Scenario scenario = new Scenario(map);

            while (offset < data.Length)
            {
                int       parsedBytes;
                RCPackage package = RCPackage.Parse(data, offset, data.Length - offset, out parsedBytes);
                if (package == null || !package.IsCommitted)
                {
                    throw new SimulatorException("Syntax error!");
                }
                offset += parsedBytes;
                if (package.PackageFormat.ID == ScenarioFileFormat.MINERAL_FIELD)
                {
                    IQuadTile    quadTile     = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    MineralField mineralField = new MineralField();
                    mineralField.ResourceAmount.Write(package.ReadInt(2));
                    scenario.AddElementToScenario(mineralField);
                    mineralField.AttachToMap(quadTile);
                }
                else if (package.PackageFormat.ID == ScenarioFileFormat.VESPENE_GEYSER)
                {
                    IQuadTile     quadTile      = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    VespeneGeyser vespeneGeyser = new VespeneGeyser();
                    vespeneGeyser.ResourceAmount.Write(package.ReadInt(2));
                    scenario.AddElementToScenario(vespeneGeyser);
                    vespeneGeyser.AttachToMap(quadTile);
                }
                else if (package.PackageFormat.ID == ScenarioFileFormat.START_LOCATION)
                {
                    IQuadTile     quadTile      = map.GetQuadTile(new RCIntVector(package.ReadShort(0), package.ReadShort(1)));
                    StartLocation startLocation = new StartLocation(package.ReadByte(2));
                    scenario.AddElementToScenario(startLocation);
                    startLocation.AttachToMap(quadTile);
                }
            }

            /// Check the constraints of the visible entities.
            foreach (Entity entity in scenario.GetElementsOnMap <Entity>(MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects))
            {
                if (entity.CheckPlacementConstraints(entity.MapObject.QuadraticPosition.Location, new RCSet <Entity>()).Count != 0)
                {
                    throw new MapException(string.Format("Entity at {0} is voilating its placement constraints!", entity.MapObject.QuadraticPosition.Location));
                }
            }
            return(scenario);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Constructs a terrain object.
        /// </summary>
        /// <param name="map">The map that this terrain object belongs to.</param>
        /// <param name="type">The type of this terrain object.</param>
        /// <param name="mapCoords">The coordinates of the top-left quadratic tile of this terrain object.</param>
        public TerrainObject(IMapAccess map, ITerrainObjectType type, RCIntVector mapCoords)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (mapCoords == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("type");
            }
            if (type.Tileset != map.Tileset)
            {
                throw new MapException("Tileset of the TerrainObjectType and tileset of the map are not the same!");
            }

            this.mapCoords = mapCoords;
            this.type      = type;
            this.parentMap = map;

            this.cells = new Cell[this.type.QuadraticSize.X * MapStructure.NAVCELL_PER_QUAD,
                                  this.type.QuadraticSize.Y * MapStructure.NAVCELL_PER_QUAD];
            this.quadTiles = new QuadTile[this.type.QuadraticSize.X, this.type.QuadraticSize.Y];

            /// Set the references to the appropriate quadratic tiles and cells.
            for (int quadX = 0; quadX < this.type.QuadraticSize.X; quadX++)
            {
                for (int quadY = 0; quadY < this.type.QuadraticSize.Y; quadY++)
                {
                    RCIntVector relQuadCoords = new RCIntVector(quadX, quadY);
                    if (!this.type.IsExcluded(relQuadCoords))
                    {
                        IQuadTile currQuadTile = this.parentMap.GetQuadTile(this.mapCoords + relQuadCoords);
                        this.quadTiles[quadX, quadY] = currQuadTile;
                        for (int navX = 0; navX < MapStructure.NAVCELL_PER_QUAD; navX++)
                        {
                            for (int navY = 0; navY < MapStructure.NAVCELL_PER_QUAD; navY++)
                            {
                                RCIntVector relNavCoords = relQuadCoords * MapStructure.NAVCELL_PER_QUAD + new RCIntVector(navX, navY);
                                this.cells[relNavCoords.X, relNavCoords.Y] = currQuadTile.GetCell(new RCIntVector(navX, navY));
                            }
                        }
                    }
                }
            }
            /// TODO: Apply the cell data changesets!
            /// TODO: Attach this TerrainObject to the map!
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Implements visibility calculations when there is no running FogOfWars.
        /// </summary>
        /// <returns>The results of the visibility calculations.</returns>
        private FowVisibilityInfo CalculateVisibilityWithoutFow()
        {
            /// Collect the isometric & quadratic tiles that need to be updated.
            IMapAccess             map = this.ActiveScenario.Map;
            RCSet <IIsoTile>       isoTilesToUpdate       = new RCSet <IIsoTile>();
            RCSet <ITerrainObject> terrainObjectsToUpdate = new RCSet <ITerrainObject>();

            for (int column = this.quadTileWindow.Left; column < this.quadTileWindow.Right; column++)
            {
                for (int row = this.quadTileWindow.Top; row < this.quadTileWindow.Bottom; row++)
                {
                    /// Add the primary & secondary isometric tiles into the update lists.
                    IQuadTile quadTileToUpdate = map.GetQuadTile(new RCIntVector(column, row));
                    if (quadTileToUpdate.PrimaryIsoTile != null)
                    {
                        isoTilesToUpdate.Add(quadTileToUpdate.PrimaryIsoTile);
                    }
                    if (quadTileToUpdate.SecondaryIsoTile != null)
                    {
                        isoTilesToUpdate.Add(quadTileToUpdate.SecondaryIsoTile);
                    }
                    if (quadTileToUpdate.TerrainObject != null)
                    {
                        terrainObjectsToUpdate.Add(quadTileToUpdate.TerrainObject);
                    }
                }
            }

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

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

            /// Create the calculated visibility info.
            return(new FowVisibilityInfo
            {
                IsoTilesToUpdate = isoTilesToUpdate,
                TerrainObjectsToUpdate = terrainObjectsToUpdate,
                QuadTilesToUpdate = new List <IQuadTile>(),
                EntitySnapshotsToUpdate = new List <EntitySnapshot>(),
                GroundMapObjectsToUpdate = groundMapObjectsToUpdate,
                AirMapObjectsToUpdate = airMapObjectsToUpdate
            });
        }
Ejemplo n.º 7
0
        /// <see cref="IMapEditorService.PlaceStartLocation"/>
        public bool PlaceStartLocation(RCIntVector position, int playerIndex)
        {
            if (this.scenarioManager.ActiveScenario == null)
            {
                throw new InvalidOperationException("No active scenario!");
            }
            if (position == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("position");
            }

            RCIntVector navCellCoords = this.mapWindowBC.AttachedWindow.WindowToMapCoords(position).Round();
            IQuadTile   quadTileAtPos = this.scenarioManager.ActiveScenario.Map.GetCell(navCellCoords).ParentQuadTile;

            IScenarioElementType objectType        = this.scenarioManager.Metadata.GetElementType(StartLocation.STARTLOCATION_TYPE_NAME);
            RCIntVector          objQuadSize       = this.scenarioManager.ActiveScenario.Map.CellToQuadSize(objectType.Area.Read().Size);
            RCIntVector          topLeftQuadCoords = quadTileAtPos.MapCoords - objQuadSize / 2;

            if (objectType.CheckPlacementConstraints(this.scenarioManager.ActiveScenario, topLeftQuadCoords, new RCSet <Entity>()).Count != 0)
            {
                return(false);
            }

            /// Check if a start location with the given player index already exists.
            RCSet <StartLocation> startLocations = this.scenarioManager.ActiveScenario.GetAllElements <StartLocation>();
            StartLocation         startLocation  = null;

            foreach (StartLocation sl in startLocations)
            {
                if (sl.PlayerIndex == playerIndex)
                {
                    startLocation = sl;
                    break;
                }
            }

            /// If a start location with the given player index already exists, change its quadratic coordinates,
            /// otherwise create a new start location.
            if (startLocation != null)
            {
                startLocation.DetachFromMap();
            }
            else
            {
                startLocation = new StartLocation(playerIndex);
                this.scenarioManager.ActiveScenario.AddElementToScenario(startLocation);
            }
            startLocation.AttachToMap(this.scenarioManager.ActiveScenario.Map.GetQuadTile(topLeftQuadCoords));
            return(true);
        }
Ejemplo n.º 8
0
        /// <see cref="Weapon.OnImpact"/>
        protected override void OnImpact(Missile impactedMissile)
        {
            IQuadTile launchQuadTile = impactedMissile.Scenario.Map.GetCell(impactedMissile.LaunchPosition.Round()).ParentQuadTile;
            IQuadTile impactQuadTile = impactedMissile.Scenario.Map.GetCell(impactedMissile.TargetEntity.MotionControl.PositionVector.Read().Round()).ParentQuadTile;

            /// TODO: Don't use the default random generator here because scenario update needs to be deterministic!
            bool makeDamage = impactedMissile.LaunchedFromAir ||
                              impactedMissile.TargetEntity.MotionControl.IsFlying ||
                              impactQuadTile.GroundLevel <= launchQuadTile.GroundLevel ||
                              RandomService.DefaultGenerator.Next(100) < LOW_TO_HIGH_GROUNDLEVEL_DAMAGE_PROBABILITY;

            if (makeDamage)
            {
                impactedMissile.TargetEntity.Biometrics.Damage(this.weaponData.DamageType.Read(), this.weaponData.Damage.Read(), impactedMissile.Owner == impactedMissile.TargetEntity.Owner);
            }
        }
Ejemplo n.º 9
0
        /// <see cref="IMapEditor.PlaceTerrainObject"/>
        public ITerrainObject PlaceTerrainObject(IMapAccess targetMap, IQuadTile targetTile, ITerrainObjectType type)
        {
            if (targetMap == null)
            {
                throw new ArgumentNullException("targetMap");
            }
            if (targetTile == null)
            {
                throw new ArgumentNullException("targetTile");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (targetMap.Tileset != type.Tileset)
            {
                throw new InvalidOperationException("The tileset of the terrain object type must be the same as the tileset of the map!");
            }

            /// TODO: Avoid this downcast!
            MapAccess targetMapObj = targetMap as MapAccess;

            if (targetMapObj == null)
            {
                throw new ArgumentException("The given map cannot be handled by the MapEditor!", "targetMap");
            }

            if (type.CheckConstraints(targetMap, targetTile.MapCoords).Count != 0)
            {
                return(null);
            }
            if (type.CheckTerrainObjectIntersections(targetMap, targetTile.MapCoords).Count != 0)
            {
                return(null);
            }

            /// TODO: Might be better to create the TerrainObject with a factory?
            ITerrainObject newObj = new TerrainObject(targetMap, type, targetTile.MapCoords);

            foreach (ICellDataChangeSet changeset in newObj.Type.CellDataChangesets)
            {
                changeset.Apply(newObj);
            }
            targetMapObj.AttachTerrainObject(newObj);
            return(newObj);
        }
Ejemplo n.º 10
0
        /// <see cref="IMapEditorService.PlaceTerrainObject"/>
        public bool PlaceTerrainObject(RCIntVector position, string terrainObject)
        {
            if (this.scenarioManager.ActiveScenario == null)
            {
                throw new InvalidOperationException("No active scenario!");
            }
            if (position == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("position");
            }
            if (terrainObject == null)
            {
                throw new ArgumentNullException("terrainObject");
            }

            ITerrainObjectType terrainObjType    = this.scenarioManager.ActiveScenario.Map.Tileset.GetTerrainObjectType(terrainObject);
            RCIntVector        navCellCoords     = this.mapWindowBC.AttachedWindow.WindowToMapCoords(position).Round();
            IQuadTile          quadTileAtPos     = this.scenarioManager.ActiveScenario.Map.GetCell(navCellCoords).ParentQuadTile;
            RCIntVector        topLeftQuadCoords = quadTileAtPos.MapCoords - terrainObjType.QuadraticSize / 2;

            ITerrainObject placedTerrainObject = null;

            if (topLeftQuadCoords.X >= 0 && topLeftQuadCoords.Y >= 0 &&
                topLeftQuadCoords.X < this.scenarioManager.ActiveScenario.Map.Size.X && topLeftQuadCoords.Y < this.scenarioManager.ActiveScenario.Map.Size.Y)
            {
                IQuadTile targetQuadTile = this.scenarioManager.ActiveScenario.Map.GetQuadTile(topLeftQuadCoords);
                placedTerrainObject = this.mapEditor.PlaceTerrainObject(this.scenarioManager.ActiveScenario.Map, targetQuadTile, terrainObjType);
            }

            if (placedTerrainObject != null)
            {
                RCNumRectangle terrObjRect = new RCNumRectangle(this.scenarioManager.ActiveScenario.Map.GetQuadTile(placedTerrainObject.MapCoords).GetCell(new RCIntVector(0, 0)).MapCoords, placedTerrainObject.CellSize)
                                             - new RCNumVector(1, 1) / 2;
                foreach (Entity affectedEntity in this.scenarioManager.ActiveScenario.GetElementsOnMap <Entity>(terrObjRect, MapObjectLayerEnum.AirObjects, MapObjectLayerEnum.GroundObjects))
                {
                    if (affectedEntity.CheckPlacementConstraints(affectedEntity.MapObject.QuadraticPosition.Location, new RCSet <Entity>()).Count != 0)
                    {
                        affectedEntity.DetachFromMap();
                        this.scenarioManager.ActiveScenario.RemoveElementFromScenario(affectedEntity);
                        affectedEntity.Dispose();
                    }
                }
            }
            return(placedTerrainObject != null);
        }
Ejemplo n.º 11
0
        /// <see cref="PostponedCmdExecution.ContinueImpl_i"/>
        protected override void InitializeImpl_i()
        {
            IQuadTile   topLeftTile  = this.Scenario.Map.GetQuadTile(this.topLeftQuadTile.Read());
            ICell       topLeftCell  = topLeftTile.GetCell(new RCIntVector(0, 0));
            RCNumVector landPosition = topLeftCell.MapCoords - new RCNumVector(1, 1) / 2 - this.recipientEntity.Read().ElementType.Area.Read().Location;

            if (landPosition.Y - Constants.MAX_VTOL_TRANSITION >= 0)
            {
                this.targetPosition.Write(landPosition - new RCNumVector(0, Constants.MAX_VTOL_TRANSITION));
                this.landOnTheSpot.Write(0x00);
            }
            else
            {
                this.targetPosition.Write(landPosition);
                this.landOnTheSpot.Write(0x01);
            }
            this.recipientEntity.Read().MotionControl.StartMoving(this.targetPosition.Read());
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Collects the terrain objects to render into the given list.
        /// </summary>
        /// <param name="targetList">The target list.</param>
        private void CollectTerrainObjectSprites(ref List <SpriteRenderInfo> targetList)
        {
            /// Collect the terrain objects that need to be rendered.
            RCSet <ITerrainObject> terrainObjectsToRender = new RCSet <ITerrainObject>();

            for (int column = this.MapWindowBC.FullWindow.QuadTileWindow.Left; column < this.MapWindowBC.FullWindow.QuadTileWindow.Right; column++)
            {
                for (int row = this.MapWindowBC.FullWindow.QuadTileWindow.Top; row < this.MapWindowBC.FullWindow.QuadTileWindow.Bottom; row++)
                {
                    /// Add the primary & secondary isometric tiles & the terrain objects into the render lists.
                    IQuadTile quadTileToUpdate = this.Map.GetQuadTile(new RCIntVector(column, row));
                    if (quadTileToUpdate.TerrainObject != null && terrainObjectsToRender.Add(quadTileToUpdate.TerrainObject))
                    {
                        targetList.Add(this.ConvertTerrainObjectToSpriteInst(quadTileToUpdate.TerrainObject));
                    }
                }
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Detaches the given terrain object from the map structure.
 /// </summary>
 /// <param name="terrainObj">The terrain object to be detached.</param>
 /// <exception cref="InvalidOperationException">If the given terrain object was not attached to this map.</exception>
 public void DetachTerrainObject(ITerrainObject terrainObj)
 {
     if (!this.terrainObjects.Remove(terrainObj))
     {
         throw new InvalidOperationException("The given terrain object was not attached to this map!");
     }
     for (int x = 0; x < terrainObj.Type.QuadraticSize.X; x++)
     {
         for (int y = 0; y < terrainObj.Type.QuadraticSize.Y; y++)
         {
             IQuadTile quadTile = terrainObj.GetQuadTile(new RCIntVector(x, y));
             if (quadTile != null)
             {
                 QuadTile quadTileObj = this.mapStructure.GetQuadTile(quadTile.MapCoords);
                 quadTileObj.DetachTerrainObject();
             }
         }
     }
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Adds the given entity snapshot and all of its cutting quadratic tiles into the update lists.
 /// </summary>
 /// <param name="snapshot">The entity snapshot to add.</param>
 /// <param name="snapshotUpdateList">The snapshot update list.</param>
 /// <param name="quadTileUpdateList">The quadratic update list.</param>
 private void AddEntitySnapshotToUpdate(EntitySnapshot snapshot, RCSet <EntitySnapshot> snapshotUpdateList, RCSet <IQuadTile> quadTileUpdateList)
 {
     if (snapshot != null && snapshotUpdateList.Add(snapshot))
     {
         for (int col = snapshot.QuadraticPosition.Left; col < snapshot.QuadraticPosition.Right; col++)
         {
             for (int row = snapshot.QuadraticPosition.Top; row < snapshot.QuadraticPosition.Bottom; row++)
             {
                 IQuadTile quadTileToUpdate = this.ActiveScenario.Map.GetQuadTile(new RCIntVector(col, row));
                 if (quadTileToUpdate != null &&
                     (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                      this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                 {
                     quadTileUpdateList.Add(quadTileToUpdate);
                 }
             }
         }
     }
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Adds the given terrain object and all of its cutting quadratic tiles into the update lists.
 /// </summary>
 /// <param name="terrainObj">The terrain object to add.</param>
 /// <param name="terrainObjUpdateList">The terrain object update list.</param>
 /// <param name="quadTileUpdateList">The quadratic update list.</param>
 private void AddTerrainObjectToUpdate(ITerrainObject terrainObj, RCSet <ITerrainObject> terrainObjUpdateList, RCSet <IQuadTile> quadTileUpdateList)
 {
     if (terrainObj != null && terrainObjUpdateList.Add(terrainObj))
     {
         for (int col = 0; col < terrainObj.Type.QuadraticSize.X; col++)
         {
             for (int row = 0; row < terrainObj.Type.QuadraticSize.Y; row++)
             {
                 IQuadTile quadTileToUpdate = terrainObj.GetQuadTile(new RCIntVector(col, row));
                 if (quadTileToUpdate != null &&
                     (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                      this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                 {
                     quadTileUpdateList.Add(quadTileToUpdate);
                 }
             }
         }
     }
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Converts a rectangle of cells to a rectangle of quadratic tiles.
        /// </summary>
        /// <param name="cellRect">The cell rectangle to convert.</param>
        /// <returns>The quadratic rectangle.</returns>
        public RCIntRectangle CellToQuadRect(RCIntRectangle cellRect)
        {
            if (cellRect == RCIntRectangle.Undefined)
            {
                throw new ArgumentNullException("cellRect");
            }

            RCIntVector    topLeftNavCellCoords     = new RCIntVector(Math.Min(this.CellSize.X - 1, Math.Max(0, cellRect.Left)), Math.Min(this.CellSize.Y - 1, Math.Max(0, cellRect.Top)));
            RCIntVector    bottomRightNavCellCoords = new RCIntVector(Math.Min(this.CellSize.X - 1, Math.Max(0, cellRect.Right - 1)), Math.Min(this.CellSize.Y - 1, Math.Max(0, cellRect.Bottom - 1)));
            IQuadTile      topLeftQuadTile          = this.GetCell(topLeftNavCellCoords).ParentQuadTile;
            IQuadTile      bottomRightQuadTile      = this.GetCell(bottomRightNavCellCoords).ParentQuadTile;
            RCIntRectangle quadTileWindow           = new RCIntRectangle(
                topLeftQuadTile.MapCoords.X,
                topLeftQuadTile.MapCoords.Y,
                bottomRightQuadTile.MapCoords.X - topLeftQuadTile.MapCoords.X + 1,
                bottomRightQuadTile.MapCoords.Y - topLeftQuadTile.MapCoords.Y + 1);

            return(quadTileWindow);
        }
Ejemplo n.º 17
0
        /// <see cref="ITargetPositionListener.SelectTargetPosition"/>
        public void SelectTargetPosition(RCNumVector targetPosition)
        {
            if (this.placeSelectedBuilding)
            {
                /// A position for the current selection is being selected.
                int[] currentSelection = this.selectionManagerBC.CurrentSelection.ToArray();
                if (currentSelection.Length != 1)
                {
                    throw new InvalidOperationException("The number of the currently selected entities must be 1!");
                }

                Building selectedBuilding = this.scenarioManagerBC.ActiveScenario.GetElement <Building>(currentSelection[0]);
                if (selectedBuilding == null)
                {
                    throw new InvalidOperationException("The currently selected entity doesn't exist or is not a building!");
                }

                IQuadTile   quadTileAtPos     = this.scenarioManagerBC.ActiveScenario.Map.GetCell(targetPosition.Round()).ParentQuadTile;
                RCIntVector objQuadSize       = this.scenarioManagerBC.ActiveScenario.Map.CellToQuadSize(selectedBuilding.ElementType.Area.Read().Size);
                RCIntVector topLeftQuadCoords = quadTileAtPos.MapCoords - objQuadSize / 2;
                this.CommandBuilder.TargetPosition = topLeftQuadCoords;
            }
            else if (this.buildingTypeName != null)
            {
                /// A position for a building type is being selected.
                IBuildingType buildingType = this.scenarioManagerBC.Metadata.GetBuildingType(this.buildingTypeName);
                if (buildingType == null)
                {
                    throw new InvalidOperationException(string.Format("Building type '{0}' is not defined in the metadata!", this.buildingTypeName));
                }

                IQuadTile   quadTileAtPos     = this.scenarioManagerBC.ActiveScenario.Map.GetCell(targetPosition.Round()).ParentQuadTile;
                RCIntVector objQuadSize       = this.scenarioManagerBC.ActiveScenario.Map.CellToQuadSize(buildingType.Area.Read().Size);
                RCIntVector topLeftQuadCoords = quadTileAtPos.MapCoords - objQuadSize / 2;
                this.CommandBuilder.TargetPosition = topLeftQuadCoords;
            }
            else
            {
                /// A point on the map is being selected.
                this.CommandBuilder.TargetPosition = targetPosition;
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Calculates the quadratic coordinates currently visible by the owner entity.
        /// </summary>
        /// <returns>The quadratic coordinates currently visible by the owner entity.</returns>
        private RCSet <RCIntVector> CalculateVisibleQuadCoords()
        {
            IQuadTile           currentQuadTile = this.owner.Read().Scenario.Map.GetCell(this.owner.Read().MotionControl.PositionVector.Read().Round()).ParentQuadTile;
            RCSet <RCIntVector> retList         = new RCSet <RCIntVector>();

            foreach (RCIntVector relativeQuadCoord in this.owner.Read().ElementType.RelativeQuadCoordsInSight)
            {
                RCIntVector otherQuadCoords = currentQuadTile.MapCoords + relativeQuadCoord;
                if (otherQuadCoords.X >= 0 && otherQuadCoords.X < this.owner.Read().Scenario.Map.Size.X&&
                    otherQuadCoords.Y >= 0 && otherQuadCoords.Y < this.owner.Read().Scenario.Map.Size.Y)
                {
                    IQuadTile otherQuadTile = this.owner.Read().Scenario.Map.GetQuadTile(otherQuadCoords);
                    if (this.owner.Read().MotionControl.IsFlying || currentQuadTile.GroundLevel >= otherQuadTile.GroundLevel)
                    {
                        retList.Add(otherQuadTile.MapCoords);
                    }
                }
            }
            return(retList);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Collects the isometric tiles to render into the given list.
        /// </summary>
        /// <param name="targetList">The target list.</param>
        private void CollectIsoTileSprites(ref List <SpriteRenderInfo> targetList)
        {
            /// Collect the isometric tiles that need to be rendered.
            RCSet <IIsoTile> isoTilesToRender = new RCSet <IIsoTile>();

            for (int column = this.MapWindowBC.FullWindow.QuadTileWindow.Left; column < this.MapWindowBC.FullWindow.QuadTileWindow.Right; column++)
            {
                for (int row = this.MapWindowBC.FullWindow.QuadTileWindow.Top; row < this.MapWindowBC.FullWindow.QuadTileWindow.Bottom; row++)
                {
                    /// Add the primary & secondary isometric tiles into the render list.
                    IQuadTile quadTileToUpdate = this.Map.GetQuadTile(new RCIntVector(column, row));
                    if (quadTileToUpdate.PrimaryIsoTile != null && isoTilesToRender.Add(quadTileToUpdate.PrimaryIsoTile))
                    {
                        targetList.Add(this.ConvertIsoTileToSpriteInst(quadTileToUpdate.PrimaryIsoTile));
                    }
                    if (quadTileToUpdate.SecondaryIsoTile != null && isoTilesToRender.Add(quadTileToUpdate.SecondaryIsoTile))
                    {
                        targetList.Add(this.ConvertIsoTileToSpriteInst(quadTileToUpdate.SecondaryIsoTile));
                    }
                }
            }
        }
        /// <see cref="EntityPlacementConstraint.CheckImpl"/>
        protected override RCSet <RCIntVector> CheckImpl(Scenario scenario, RCIntVector position, RCSet <Entity> entitiesToIgnore)
        {
            RCIntRectangle      objArea = new RCIntRectangle(position, scenario.Map.CellToQuadSize(this.EntityType.Area.Read().Size));
            RCSet <RCIntVector> retList = new RCSet <RCIntVector>();

            for (int absY = objArea.Top; absY < objArea.Bottom; absY++)
            {
                for (int absX = objArea.Left; absX < objArea.Right; absX++)
                {
                    RCIntVector absQuadCoords = new RCIntVector(absX, absY);
                    if (absQuadCoords.X >= 0 && absQuadCoords.X < scenario.Map.Size.X &&
                        absQuadCoords.Y >= 0 && absQuadCoords.Y < scenario.Map.Size.Y)
                    {
                        IQuadTile checkedQuadTile = scenario.Map.GetQuadTile(absQuadCoords);
                        if (!checkedQuadTile.IsBuildable)
                        {
                            retList.Add(absQuadCoords - position);
                        }
                    }
                }
            }
            return(retList);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Adds the given map object and all of its cutting quadratic tiles into the update lists.
        /// </summary>
        /// <param name="mapObj">The map object to add.</param>
        /// <param name="mapObjectUpdateList">The map object update list.</param>
        /// <param name="quadTileUpdateList">The quadratic update list.</param>
        private void AddMapObjectToUpdate(MapObject mapObj, RCSet <MapObject> mapObjectUpdateList, RCSet <IQuadTile> quadTileUpdateList)
        {
            if (mapObj != null && mapObjectUpdateList.Add(mapObj))
            {
                for (int col = mapObj.QuadraticPosition.Left; col < mapObj.QuadraticPosition.Right; col++)
                {
                    for (int row = mapObj.QuadraticPosition.Top; row < mapObj.QuadraticPosition.Bottom; row++)
                    {
                        IQuadTile quadTileToUpdate = this.ActiveScenario.Map.GetQuadTile(new RCIntVector(col, row));
                        if (quadTileToUpdate != null &&
                            (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                             this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                        {
                            quadTileUpdateList.Add(quadTileToUpdate);
                        }
                    }
                }

                if (mapObj.QuadraticShadowPosition != RCIntRectangle.Undefined)
                {
                    for (int col = mapObj.QuadraticShadowPosition.Left; col < mapObj.QuadraticShadowPosition.Right; col++)
                    {
                        for (int row = mapObj.QuadraticShadowPosition.Top; row < mapObj.QuadraticShadowPosition.Bottom; row++)
                        {
                            IQuadTile quadTileToUpdate = this.ActiveScenario.Map.GetQuadTile(new RCIntVector(col, row));
                            if (quadTileToUpdate != null &&
                                (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                                 this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                            {
                                quadTileUpdateList.Add(quadTileToUpdate);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 22
0
        /// <see cref="IObjectPlacementView.GetObjectPlacementBox"/>
        public ObjectPlacementBox GetObjectPlacementBox(RCIntVector position)
        {
            /// Calculate the top-left quadratic coordinates based on the retrieved object rectangles relative to the quadratic tile at the incoming position.
            RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > objRectsRelativeToQuadTileAtPos = this.GetObjectRelativeQuadRectangles();

            if (objRectsRelativeToQuadTileAtPos.Count == 0)
            {
                return(new ObjectPlacementBox
                {
                    Sprites = new List <SpriteRenderInfo>(),
                    IllegalParts = new List <RCIntRectangle>(),
                    LegalParts = new List <RCIntRectangle>()
                });
            }
            RCIntVector navCellCoords     = this.MapWindowBC.AttachedWindow.WindowToMapCoords(position).Round();
            IQuadTile   quadTileAtPos     = this.Map.GetCell(navCellCoords).ParentQuadTile;
            RCIntVector topLeftQuadCoords = quadTileAtPos.MapCoords;

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToQuadTileAtPos)
            {
                RCIntVector rectTopLeftQuadCoords = topLeftQuadCoords + relativeRect.Item1.Location;
                if (rectTopLeftQuadCoords.X < topLeftQuadCoords.X && rectTopLeftQuadCoords.Y < topLeftQuadCoords.Y ||
                    rectTopLeftQuadCoords.X < topLeftQuadCoords.X && rectTopLeftQuadCoords.Y == topLeftQuadCoords.Y ||
                    rectTopLeftQuadCoords.X == topLeftQuadCoords.X && rectTopLeftQuadCoords.Y < topLeftQuadCoords.Y)
                {
                    topLeftQuadCoords = rectTopLeftQuadCoords;
                }
            }

            /// Calculate the object rectangles relative to the calculated top-left quadratic coordinates.
            RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > objRectsRelativeToTopLeftQuadTile = new RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> >();

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToQuadTileAtPos)
            {
                objRectsRelativeToTopLeftQuadTile.Add(Tuple.Create(
                                                          new RCIntRectangle(
                                                              relativeRect.Item1.Location + quadTileAtPos.MapCoords - topLeftQuadCoords,
                                                              relativeRect.Item1.Size),
                                                          relativeRect.Item2));
            }

            /// Get the sprites to be displayed, translate their DisplayCoordinates accordingly from the top-left quadratic tile,
            /// and collect the violating quadratic coordinates.
            ObjectPlacementBox placementBox = new ObjectPlacementBox
            {
                Sprites      = new List <SpriteRenderInfo>(),
                IllegalParts = new List <RCIntRectangle>(),
                LegalParts   = new List <RCIntRectangle>()
            };
            RCSet <RCIntVector> violatingQuadCoords = this.CheckObjectConstraints(topLeftQuadCoords);

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToTopLeftQuadTile)
            {
                RCIntVector topLeftDisplayCoords =
                    this.MapWindowBC.AttachedWindow.QuadToWindowRect(new RCIntRectangle(topLeftQuadCoords + relativeRect.Item1.Location, new RCIntVector(1, 1))).Location;
                for (int i = 0; i < relativeRect.Item2.Length; i++)
                {
                    relativeRect.Item2[i].DisplayCoords += topLeftDisplayCoords;
                    placementBox.Sprites.Add(relativeRect.Item2[i]);
                }
                for (int x = relativeRect.Item1.Left; x < relativeRect.Item1.Right; x++)
                {
                    for (int y = relativeRect.Item1.Top; y < relativeRect.Item1.Bottom; y++)
                    {
                        RCIntVector    relativeQuadCoords = new RCIntVector(x, y);
                        RCIntVector    absQuadCoords      = topLeftQuadCoords + relativeQuadCoords;
                        RCIntRectangle partRect           =
                            this.MapWindowBC.AttachedWindow.QuadToWindowRect(new RCIntRectangle(absQuadCoords, new RCIntVector(1, 1)));
                        if (violatingQuadCoords.Contains(relativeQuadCoords))
                        {
                            placementBox.IllegalParts.Add(partRect);
                        }
                        else
                        {
                            placementBox.LegalParts.Add(partRect);
                        }
                    }
                }
            }

            return(placementBox);
        }
Ejemplo n.º 23
0
        /// <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
            });
        }