Пример #1
0
        /// <summary>
        /// Create a new building
        /// </summary>
        /// <param name="position">Position of the new building</param>
        /// <param name="size">Size of the new building</param>
        /// <param name="data">Data about the building</param>
        /// <returns>True if the building was able to be created.</returns>
        public bool CreateBuilding(Pair<int> position, Pair<int> size, BuildingData data)
        {
            var newBuilding = new Building(position, size, data);
            this.Add(newBuilding);

            // Place this new building's Guid into the world grid
            var buildingIsoPosition = Geometry.ToIsometricGrid(position);
            for (int y = 0; y < data.Footprint.Length; ++y)
            {
                for (int x = 0; x < data.Footprint[y].Length; ++x)
                {
                    if (data.Footprint[y][x])
                    {
                        int gridX = this.WorldIsoToGridX(buildingIsoPosition.x + x - data.FootprintIndexOffsetX);
                        int gridY = this.WorldIsoToGridY(buildingIsoPosition.y + y - data.FootprintIndexOffsetY);

                        // Sanity checks before we place the building
                        if (gridX < 0 || gridX >= this.grid.Length || gridY < 0 || gridY >= this.grid.Length)
                        {
                            Logger.Log(LogLevel.Error, "Creating a building outside grid limits", string.Format("Trying to build building {0} at position: Iso: {1},{2} World: {3}, {4}. Outside world boundry of {5}", data.Name, gridX, gridY, position.x, position.y, this.grid.Length));
                            continue;
                        }

                        if (this.grid[gridY][gridX] != -1)
                        {
                            Logger.Log(LogLevel.Error, "Creating a building on top of another building", string.Format("Trying to build building {0} at position: Iso: {1},{2} World: {3}, {4}. Building {5} already exists at location.", data.Name, gridX, gridY, position.x, position.y, this.grid[gridY][gridX]));
                        }

                        this.grid[gridY][gridX] = newBuilding.Guid;
                    }
                }
            }

            return true;
        }
Пример #2
0
        /// <summary>
        /// Create an instance of a building ScreenElement
        /// </summary>
        public Building(Pair<int> position, Pair<int> size, BuildingData data)
            : base(position.y)
        {
            this.Clickable = true;
            this.Position = position;
            this.Size = size;
            this.data = data;

            this.deleteButton = new DeleteBuildingButton(this);
            this.deleteButton.Position = new Pair<int>(this.Position.x + this.Size.x + this.data.ImageOffsetX - (2 * this.deleteButton.Size.x / 3), this.Position.y + this.Size.y + this.data.ImageOffsetY - this.deleteButton.Size.y);
            this.deleteButton.Enabled = false;

            this.editButton = new EditBuildingButton(this);
            this.editButton.Position = new Pair<int>(this.Position.x + this.data.ImageOffsetX - (this.deleteButton.Size.x / 3), this.Position.y + this.Size.y + this.data.ImageOffsetY - this.deleteButton.Size.y);
            this.editButton.Enabled = false;
        }
Пример #3
0
        /// <summary>
        /// Create a new building
        /// </summary>
        /// <param name="position">Position of the new building</param>
        /// <param name="size">Size of the new building</param>
        /// <param name="data">Data about the building</param>
        /// <returns>True if the building was able to be created.</returns>
        public bool CreateBuilding(Pair <int> position, Pair <int> size, BuildingData data)
        {
            var newBuilding = new Building(position, size, data);

            this.Add(newBuilding);

            // Place this new building's Guid into the world grid
            var buildingIsoPosition = Geometry.ToIsometricGrid(position);

            for (int y = 0; y < data.Footprint.Length; ++y)
            {
                for (int x = 0; x < data.Footprint[y].Length; ++x)
                {
                    if (data.Footprint[y][x])
                    {
                        int gridX = this.WorldIsoToGridX(buildingIsoPosition.x + x - data.FootprintIndexOffsetX);
                        int gridY = this.WorldIsoToGridY(buildingIsoPosition.y + y - data.FootprintIndexOffsetY);

                        // Sanity checks before we place the building
                        if (gridX < 0 || gridX >= this.grid.Length || gridY < 0 || gridY >= this.grid.Length)
                        {
                            Logger.Log(LogLevel.Error, "Creating a building outside grid limits", string.Format("Trying to build building {0} at position: Iso: {1},{2} World: {3}, {4}. Outside world boundry of {5}", data.Name, gridX, gridY, position.x, position.y, this.grid.Length));
                            continue;
                        }

                        if (this.grid[gridY][gridX] != -1)
                        {
                            Logger.Log(LogLevel.Error, "Creating a building on top of another building", string.Format("Trying to build building {0} at position: Iso: {1},{2} World: {3}, {4}. Building {5} already exists at location.", data.Name, gridX, gridY, position.x, position.y, this.grid[gridY][gridX]));
                        }

                        this.grid[gridY][gridX] = newBuilding.Guid;
                    }
                }
            }

            return(true);
        }
Пример #4
0
        /// <summary>
        /// Load a building from Config
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        private BuildingData LoadBuilding(Config config, string key)
        {
            // Create the building data
            BuildingData data = new BuildingData();
            data.Key = key;
            data.Name = config.GetStringValue(key, "title", "");
            data.Type = DataType.Building;
            data.InToolbox = config.GetBoolValue(key, "toolbox", false);
            data.ImageName = config.GetStringValue(key, "image", "");
            data.IconImageName = config.GetStringValue(key, "icon", null);
            data.FootprintImageName = config.GetStringValue(key, "footprint", "");
            data.ImageOffsetY = config.GetIntValue(key, "imageOffsetY", 0);
            data.ImageOffsetX = config.GetIntValue(key, "imageOffsetX", 0);
            data.FootprintOffsetY = config.GetIntValue(key, "footprintOffsetY", 0);
            data.FootprintOffsetX = config.GetIntValue(key, "footprintOffsetX", 0);
            data.Cost = config.GetIntValue(key, "cost", 0);
            data.Specs = new Dictionary<BuildingStat, int>();

            // Load the specs into an enum and int pair
            var specsString = config.GetStringValue(key, "specs", "");
            if (!string.IsNullOrEmpty(specsString))
            {
                var specs = specsString.Split(';');
                foreach (var spec in specs)
                {
                    var nameValue = spec.Split(',');
                    if (nameValue.Length != 2)
                    {
                        string msg = string.Format("Invalid Catalog.ini file. Element {0} ({1}) did not have a name and value.", key, spec);
                        Logger.Log(LogLevel.Error, "LoadingCatalog", msg);
                        throw new Exception(msg);
                    }

                    try
                    {
                        BuildingStat stat = (BuildingStat)Enum.Parse(typeof(BuildingStat), nameValue[0]);
                        int value = Int32.Parse(nameValue[1]);
                        data.Specs.Add(stat, value);
                    }
                    catch (Exception e)
                    {
                        var msg = string.Format("Invalid Catalog.ini file. Element {0} ({1}) was an unrecognized BuildingStat-Int pair. ex: {2}", e.Message);
                        Logger.Log(LogLevel.Error, "LoadingCatalog", msg);
                        throw new Exception(msg);
                    }
                }
            }

            return data;
        }
Пример #5
0
 /// <summary>
 /// Create a ghost building to build a new type of building
 /// </summary>
 /// <param name="data"></param>
 public GhostBuilding(BuildingData data)
     : base(data)
 {
     this.Position = Input.IsoWorld.Clone();
 }
Пример #6
0
        /// <summary>
        /// Load all of the image content for the buildings
        /// </summary>
        /// <param name="contentMan">XNA Content manager</param>
        public void LoadContent(ContentManager contentMan)
        {
            foreach (var element in this.catalog)
            {
                Texture2D image = contentMan.Load <Texture2D>(element.Value.ImageName);

                int size = image.Width * image.Height;
                element.Value.Image = image;

                Texture2D iconimage = contentMan.Load <Texture2D>(element.Value.IconImageName);
                element.Value.IconImage = iconimage;

                if (element.Value is BuildingData)
                {
                    BuildingData buildingData = element.Value as BuildingData;

                    Color[] imageData = new Color[size];
                    image.GetData <Color>(imageData, 0, size);
                    buildingData.ImageData = imageData;

                    Texture2D footimage = contentMan.Load <Texture2D>(buildingData.FootprintImageName);
                    buildingData.FootprintImage = footimage;

                    size = footimage.Width * footimage.Height;
                    Color[] footimageData = new Color[size];
                    footimage.GetData <Color>(footimageData, 0, size);

                    // I spent waaay too much time thinking about this, so it's entirely possible that I'm overlooking a simpler solution.
                    // I'm looping over the footprint image mask to determine which squares each building takes up.
                    // You can specify an offset to the center of the building mask in buildings.ini (just like you can for the center of the image; note: these two centers should be the same)
                    // Using that center value, we find if the center is on a type0 (first grid piece lines up with the left side) or a type1 (first grid piece is one half width from the left side)
                    bool isType0      = buildingData.FootprintOffsetX % Constants.TILE_WIDTH == 0;
                    int  worldYOffset = ((buildingData.FootprintOffsetX % Constants.TILE_WIDTH == 0) ^ (buildingData.FootprintOffsetY % Constants.TILE_HEIGHT == 0)) ? Constants.TILE_HEIGHT / 2 : 0;

                    int minFootprintX = (-footimage.Width + Constants.TILE_WIDTH / 2) / Constants.TILE_WIDTH;
                    int maxFootprintX = (footimage.Height - worldYOffset - Constants.TILE_HEIGHT / 2) / Constants.TILE_HEIGHT;
                    // int minFootprintY = 0;
                    int maxFootprintY = maxFootprintX - minFootprintX + 1;

                    buildingData.Footprint = new bool[maxFootprintY][];
                    for (int i = 0; i < maxFootprintY; ++i)
                    {
                        buildingData.Footprint[i] = new bool[maxFootprintY];
                    }

                    int startCenterX         = buildingData.FootprintOffsetX + Constants.TILE_WIDTH / 2;
                    int startCenterY         = -1 * buildingData.FootprintOffsetY + Constants.TILE_HEIGHT / 2 - worldYOffset;
                    var isometricCenterIndex = Geometry.ToIsometricGrid(new Pair <int>(startCenterX, startCenterY));
                    buildingData.FootprintIndexOffsetX = isometricCenterIndex.x - minFootprintX;
                    buildingData.FootprintIndexOffsetY = isometricCenterIndex.y;

                    for (int y = 0; y <= footimage.Height - Constants.TILE_HEIGHT; y += Constants.TILE_HEIGHT / 2)
                    {
                        int xStart = (isType0 ^ ((int)Math.Abs(y - buildingData.FootprintOffsetY) % Constants.TILE_HEIGHT == 0)) ? Constants.TILE_WIDTH / 2 : 0;
                        for (int x = xStart; x <= footimage.Width - Constants.TILE_WIDTH; x += Constants.TILE_WIDTH)
                        {
                            int qX = x + Constants.TILE_WIDTH / 2;
                            int qY = y + Constants.TILE_HEIGHT / 2 - worldYOffset;
                            var isometricQueryPosition = Geometry.ToIsometricGrid(new Pair <int>(qX, qY));
                            buildingData.Footprint[isometricQueryPosition.y][isometricQueryPosition.x - minFootprintX] = footimageData[qX + qY * footimage.Width] != Color.Transparent;
                        }
                    }
                }
            }
        }