Ejemplo n.º 1
0
        /// <summary>
        /// Creates a new collection of cursors.
        /// </summary>
        /// <param name="footprint">The footprint of the building.</param>
        public void Create(bool[,] footprint)
        {
            if (_cursors != null)
            {
                GameLogger.FatalError("Can't recreate a footprint cursor while one already exists!");
            }

            int xSize = footprint.GetLength(0);
            int zSize = footprint.GetLength(1);

            _cursors = new GridCursor[xSize, zSize];
            for (int x = 0; x < xSize; ++x)
            {
                for (int z = 0; z < zSize; ++z)
                {
                    if (footprint[x, z])
                    {
                        _cursors[x, z] = GridCursor.Create(_terrain, _validMaterial);
                    }
                    else
                    {
                        _cursors[x, z] = null;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Link actions that reference other GameObjects.
        /// All other GameObjects in dependent stores must already be Instantiated.
        /// </summary>
        /// <param name="data">UI GameData</param>
        protected override void LinkData(UIData data)
        {
            var toolbar = MainMenu.GetComponent <Toolbar>();

            // Link button children and actions
            foreach (var buttonGroupData in data.ButtonGroups)
            {
                var buttonGroup = _buttonGroups[buttonGroupData.Name];

                for (int i = 0; i < buttonGroupData.Buttons.Count; ++i)
                {
                    var buttonData = buttonGroupData.Buttons[i];
                    var button     = buttonGroup.Buttons[i];

                    // Link OnSelect Action -----------------------
                    if (buttonData.OnSelect is OpenSubMenuAction)
                    {
                        var openSubMenuAction  = buttonData.OnSelect as OpenSubMenuAction;
                        var openSubMenuButtons = GameDataStore.Get <ButtonGroup>(GameDataType.ButtonGroup, openSubMenuAction.ButtonGroupName);
                        if (openSubMenuButtons == null)
                        {
                            GameLogger.FatalError("OpenSubMenuAction could not link to non-existant button group '{0}'", openSubMenuAction.ButtonGroupName);
                        }
                        button.OnSelect = () => toolbar.OpenSubMenu(openSubMenuButtons);
                    }
                    else if (buttonData.OnSelect is OpenWindowAction)
                    {
                        var openWindowAction = buttonData.OnSelect as OpenWindowAction;
                        if (!WindowManager.TryGetWindow(openWindowAction.WindowName, out Window _))
                        {
                            GameLogger.FatalError("OpenWindowAction could not link to non-existant window '{0}'", openWindowAction.WindowName);
                        }

                        button.OnSelect = () => WindowManager.OpenWindow(openWindowAction.WindowName, null);
                    }
                    else if (buttonData.OnSelect is OpenWindowWithDataAction)
                    {
                        var openWindowAction = buttonData.OnSelect as OpenWindowWithDataAction;
                        if (!WindowManager.TryGetWindow(openWindowAction.WindowName, out Window _))
                        {
                            GameLogger.FatalError("OpenWindowWithDataAction could not link to non-existant window '{0}'", openWindowAction.WindowName);
                        }

                        button.OnSelect = () => WindowManager.OpenWindow(openWindowAction.WindowName, openWindowAction.DataType, openWindowAction.DataName);
                    }

                    // Link OnDeselect Action -----------------------
                    if (buttonData.OnDeselect is CloseSubMenuAction)
                    {
                        button.OnDeselect = () => toolbar.CloseSubMenu();
                    }
                    else if (buttonData.OnDeselect is CloseWindowAction)
                    {
                        button.OnDeselect = () => WindowManager.CloseWindow();
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the height of a mesh vertex in grid steps.
        /// (Remember, there is one more vertex than grid squares).
        /// </summary>
        /// <param name="x">X coordinate of the vertex.</param>
        /// <param name="z">Z coordinates of the vertex.</param>
        /// <returns>The height of the vertex in grid steps.</returns>
        public int GetVertexHeight(int x, int z)
        {
            if (x < 0 || x > CountX || z < 0 || z > CountZ)
            {
                GameLogger.FatalError("Attempted to GetVertexHeight out of range. ({0},{1})", x, z);
            }

            return(_vertexHeight[x, z]);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the height of a mesh vertex in world units.
        /// (Remember, there is one more vertex than grid squares).
        /// </summary>
        /// <param name="x">X coordinate of the vertex.</param>
        /// <param name="z">Z coordinates of the vertex.</param>
        /// <returns>The height of the vertex in Unity world units.</returns>
        public float GetVertexWorldHeight(int x, int z)
        {
            if (x < 0 || x > CountX || z < 0 || z > CountZ)
            {
                GameLogger.FatalError("Attempted to GetVertexWorldHeight out of range. ({0},{1})", x, z);
            }

            return(Convert.GridHeightToWorld(_vertexHeight[x, z]));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the submaterial id of the grid square.
        /// </summary>
        /// <param name="x">X coordinate of the grid square.</param>
        /// <param name="z">Z coordinate of the grid square.</param>
        /// <returns>Id of the submaterial used at the grid square.</returns>
        public int GetSubmaterial(int x, int z)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to get square submaterial outside of range! ({0},{1}) is outside of ({2},{3})", x, z, CountX, CountZ);
            }

            return(_gridData[x, z].SubmaterialIndex);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// You must call this method on a GameDataLoader before it starts!
        /// The GameObject must be disabled while doing this step otherwise
        /// the Awake and Start methods will not be called correctly.
        /// </summary>
        /// <param name="config"></param>
        protected void SetConfig(TextAsset config)
        {
            if (gameObject.activeSelf)
            {
                GameLogger.FatalError("Setting game data configuration on an active GameObject!");
            }

            Config = config;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// The state controller is starting.
        /// </summary>
        /// <param name="context">The construction to place.</param>
        public override void TransitionIn(object context)
        {
            _building = context as BuildingData;
            if (_building == null)
            {
                GameLogger.FatalError("PlacingConstructionController was not given a building data!");
            }

            _cursors.Create(_building.Footprint);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gets the height of a grid square in world units.
        /// </summary>
        /// <param name="x">X coordinate of the grid square.</param>
        /// <param name="z">Y coordinate of the grid square.</param>
        /// <returns>The height of the grid square in Unity world units.</returns>
        public float GetSquareWorldHeight(int x, int z, int corner = Vertex.Center)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to GetSquareWorldHeight out of range. ({0},{1})", x, z);
            }

            int centerIndex = _gridData[x, z].VertexIndex + corner;

            return(_vertices[centerIndex].y);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Set the grid square to be anchored by construction.
        /// </summary>
        /// <param name="x">The x grid coordinate.</param>
        /// <param name="z">The z grid coordinate.</param>
        public void RemoveAnchor(int x, int z)
        {
            if (x < 0 || x > _terrain.CountX || z < 0 || z > _terrain.CountZ)
            {
                GameLogger.FatalError("Attempted to remove anchor from grid outside of range! ({0},{1}) is outside of ({2},{3})", x, z, _terrain.CountX, _terrain.CountZ);
            }

            Assert.IsFalse(!_gridAnchored[x, z], "Trying to remove anchor from grid that is already free!");
            _gridAnchored[x, z]   = false;
            _vertexAnchored[x, z] = _vertexAnchored[x, z + 1] = _vertexAnchored[x + 1, z] = _vertexAnchored[x + 1, z + 1] = false;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Set the grid square to be anchored by construction.
        /// </summary>
        /// <param name="x">The x grid coordinate.</param>
        /// <param name="z">The z grid coordinate.</param>
        public void SetAnchored(int x, int z)
        {
            if (x < 0 || x > _terrain.CountX || z < 0 || z > _terrain.CountZ)
            {
                GameLogger.FatalError("Attempted to anchor grid outside of range! ({0},{1}) is outside of ({2},{3})", x, z, _terrain.CountX, _terrain.CountZ);
            }

            Assert.IsFalse(_gridAnchored[x, z], "Trying to anchor a grid that is already anchored!");
            _gridAnchored[x, z]   = true;
            _vertexAnchored[x, z] = _vertexAnchored[x, z + 1] = _vertexAnchored[x + 1, z] = _vertexAnchored[x + 1, z + 1] = true;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets if the grid square is flat or not.
        /// </summary>
        /// <param name="x">X coordinates of the grid square.</param>
        /// <param name="z">Z coorindates of the grid square.</param>
        /// <returns>True if the square is flat, false otherwise.</returns>
        public bool IsGridFlat(int x, int z)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to get IsGridFlat out of range. ({0},{1})", x, z);
            }

            return(_vertexHeight[x, z] == _vertexHeight[x + 1, z] &&
                   _vertexHeight[x, z] == _vertexHeight[x, z + 1] &&
                   _vertexHeight[x, z] == _vertexHeight[x + 1, z + 1]);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Set the height of a grid square.
        /// </summary>
        /// <param name="x">X coordinate of the grid square.</param>
        /// <param name="z">Y coordinate of the grid square.</param>
        /// <param name="height">The square height in grid steps.</param>
        public void SetSquareHeight(int x, int z, int gridHeight)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to set square height outside of range! ({0},{1}) is outside of ({2},{3})", x, z, CountX, CountZ);
            }

            SetVertexHeights(x, z, new int[, ] {
                { gridHeight, gridHeight }, { gridHeight, gridHeight }
            });
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Boldly retrieve a color that you are certain exists.
        /// Throws exception if the color doesn't exist.
        /// </summary>
        /// <param name="name">Name of the color.</param>
        /// <returns>The color. Or an exception to the face.</returns>
        public static Color GetColor(string name)
        {
            Color color = Color.magenta; // default to a garish color

            if (!Palette.TryGetValue(name, out color))
            {
                GameLogger.FatalError("Configuration attempted to load unrecognized color name '{0}'", name);
            }

            return(color);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// The state controller is starting.
        /// </summary>
        /// <param name="context">The construction to place.</param>
        public override void TransitionIn(object context)
        {
            var args = context as TerrainClickedArgs;

            if (args == null)
            {
                GameLogger.FatalError("EditingTerrainController was given incorrect context.");
            }

            _pathStart = _pathEnd = args.ClickLocation;
            _cursors.Place(_pathStart, _pathEnd, IsValidTerrainAlongLine());
        }
Ejemplo n.º 15
0
        public static UnityEngine.Object Load(ResourceType type, ResourceCategory category, string name, Type returnType)
        {
            string resourcePath = string.Format("{0}/{1}/{2}", type.ToString(), category.ToString(), name);

            UnityEngine.Object resource = Resources.Load(resourcePath, returnType);
            if (resource == null)
            {
                GameLogger.FatalError("ResourceLoader could not find resource {0}", resourcePath);
            }

            return(resource);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Open the window to display the game data.
        /// </summary>
        /// <param name="data">The game data</param>
        public override void Open(object data)
        {
            var buildingData = data as BuildingData;

            if (buildingData == null)
            {
                GameLogger.FatalError("ConstructionInfoWindow was passed invalid data. Data = {0}", data == null ? "null" : data.GetType().Name);
            }

            Title       = buildingData.Name;
            Description = WriteDescription(buildingData);
            ConstructionImage.sprite = buildingData.Icon;

            BuildButton.OnSelect = () => { Game.UI.WindowManager.OpenWindow("ConstructionPlacing", buildingData); };
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Open the window to display the game data.
        /// </summary>
        /// <param name="data">The game data</param>
        public override void Open(object data)
        {
            var buildingData = data as BuildingData;

            if (buildingData == null)
            {
                GameLogger.FatalError("ConstructionPlacingWindow was passed invalid data. Data = {0}", data == null ? "null" : data.GetType().Name);
            }

            Game.Campus.Terrain.Selectable.SelectionParent = this;
            Game.State.StartDoing(GameState.PlacingConstruction, data);

            TitleText.text      = string.Format("Constructing {0}", buildingData.Name);
            StopButton.OnSelect = () => { SelectionManager.UpdateSelection(SelectionParent.ToMainMenu()); };
        }
        /// <summary>
        /// Transition to SelectingTerrain state.
        /// </summary>
        /// <param name="context">The grid coordinate to edit.</param>
        public override void TransitionIn(object context)
        {
            var args = context as TerrainClickedArgs;

            if (args == null)
            {
                GameLogger.FatalError("EditingTerrainController was given incorrect context.");
            }

            _editingGridLocation = args.ClickLocation;

            _cursor.Activate();
            _cursor.Place(_editingGridLocation.x, _editingGridLocation.z);

            _mouseDragStartY       = Input.mousePosition.y;
            _mouseDragHeightChange = 0;
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Sets the submaterial on a grid square.
        /// </summary>
        /// <param name="x">X coordinate of the grid square.</param>
        /// <param name="z">Z coordinate of the grid square.</param>
        /// <param name="submaterialId">The id of the submaterial (the gridsheet on the material from left->right, top->bottom).</param>
        public void SetSubmaterial(int x, int z, int submaterialId, Rotation rotation = Rotation.deg0)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to set square material outside of range! ({0},{1}) is outside of ({2},{3})", x, z, CountX, CountZ);
            }

            int submaterialOffsetX = submaterialId % _submaterialCountX;
            int submaterialOffsetZ = submaterialId / _submaterialCountX;

            if (submaterialOffsetZ >= _submaterialCountZ)
            {
                throw new InvalidOperationException(string.Format("Submaterial index '{0}' is out of range for material {1} ({2}x{3}).", submaterialId, _material.name, _submaterialCountX, _submaterialCountZ));
            }

            float stepX = (1.0f / _submaterialCountX);
            float stepZ = (1.0f / _submaterialCountZ);

            int rotationOffset = 0;

            switch (rotation)
            {
            case Rotation.deg90:
                rotationOffset = 3;
                break;

            case Rotation.deg180:
                rotationOffset = 2;
                break;

            case Rotation.deg270:
                rotationOffset = 1;
                break;
            }

            var grid = _gridData[x, z];

            _uv[grid.VertexIndex + (Vertex.BottomLeft + rotationOffset) % 4]  = new Vector2(submaterialOffsetX * stepX + Constant.uvEpsilon, 1.0f - (submaterialOffsetZ + 1) * stepZ + Constant.uvEpsilon);
            _uv[grid.VertexIndex + (Vertex.BottomRight + rotationOffset) % 4] = new Vector2((submaterialOffsetX + 1) * stepX - Constant.uvEpsilon, 1.0f - (submaterialOffsetZ + 1) * stepZ + Constant.uvEpsilon);
            _uv[grid.VertexIndex + (Vertex.TopRight + rotationOffset) % 4]    = new Vector2((submaterialOffsetX + 1) * stepX - Constant.uvEpsilon, 1.0f - submaterialOffsetZ * stepZ - Constant.uvEpsilon);
            _uv[grid.VertexIndex + (Vertex.TopLeft + rotationOffset) % 4]     = new Vector2(submaterialOffsetX * stepX + Constant.uvEpsilon, 1.0f - submaterialOffsetZ * stepZ - Constant.uvEpsilon);
            _uv[grid.VertexIndex + Vertex.Center] = new Vector2(submaterialOffsetX * stepX + (stepX / 2), 1.0f - submaterialOffsetZ * stepZ - (stepZ / 2));
            grid.SubmaterialIndex = submaterialId;

            _mesh.uv = _uv;
        }
Ejemplo n.º 20
0
    /// <summary>
    /// Bootstrap the game state and data.
    /// </summary>
    protected void Awake()
    {
        InitLogging();
        GameLogger.Info("Game started.");

        lock (_singletonLock)
        {
            if (_singleton != null)
            {
                GameLogger.FatalError("It appears there are multiple root Game objects.");
            }

            _singleton = this;
        }

        GameLogger.Info("Creating game objects.");
        InitGameObjects();
    }
Ejemplo n.º 21
0
        /// <summary>
        /// Unity's Awake method.
        /// </summary>
        protected virtual void Awake()
        {
            try
            {
                GameData = GameDataSerializer.Load <T>(Config);
            }
            catch (Exception e)
            {
                GameLogger.FatalError("Failed to load game data for {0}. Ex = {1}", GetType().Name, e);
                return;
            }

            if (GameData == null)
            {
                GameLogger.FatalError("Null game data for {0}.", GetType().Name);
                return;
            }

            LoadDataInternal(GameData);
            LoadData(GameData);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Opens a window on the screen with custom (possibly null) data.
        /// </summary>
        /// <param name="name">Name of the window to open.</param>
        /// <param name="data">The data to pass to the window.</param>
        public void OpenWindow(string name, object data)
        {
            Window window = null;

            if (!_windows.TryGetValue(name, out window))
            {
                GameLogger.FatalError("Attempted to open non-existant window '{0}'", name);
                return;
            }

            CloseWindow();

            var selected = SelectionManager.Selected;

            if (selected != null)
            {
                window.SelectionParent = selected;
            }

            _openWindow = window;

            window.Open(data);
            window.gameObject.SetActive(true);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Set grid squares as anchored by construction.
        /// </summary>
        /// <param name="xBase">The starting x coordinate.</param>
        /// <param name="zBase">The starting z coordinate.</param>
        /// <param name="anchorGrid">Array of grid squares to set as anchored.</param>
        public void SetAnchoredGrid(int xBase, int zBase, bool[,] anchorGrid)
        {
            int xSize = anchorGrid.GetLength(0);
            int zSize = anchorGrid.GetLength(1);

            if (xBase < 0 || xBase + xSize > _terrain.CountX || zBase < 0 || zBase + zSize > _terrain.CountZ)
            {
                GameLogger.FatalError("Attempted to anchor grid outside of range! ({0},{1}) + ({2},{3}) is outside of ({4},{5})", xBase, zBase, xSize, zSize, _terrain.CountX, _terrain.CountZ);
            }

            for (int x = 0; x < xSize; ++x)
            {
                for (int z = 0; z < zSize; ++z)
                {
                    int gridX = xBase + x;
                    int gridZ = zBase + z;

                    if (anchorGrid[x, z])
                    {
                        SetAnchored(gridX, gridZ);
                    }
                }
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Free anchored grid squares.
        /// </summary>
        /// <param name="xBase">The starting x coordinate.</param>
        /// <param name="zBase">The starting z coordinate.</param>
        /// <param name="freeGrids">Array of grid squares to set as free.</param>
        public void RemoveAnchorGrid(int xBase, int zBase, bool[,] freeGrids)
        {
            int xSize = freeGrids.GetLength(0);
            int zSize = freeGrids.GetLength(1);

            if (xBase < 0 || xBase + xSize > _terrain.CountX || zBase < 0 || zBase + zSize > _terrain.CountZ)
            {
                GameLogger.FatalError("Attempted to remove anchor from outside of range! ({0},{1}) + ({2},{3}) is outside of ({4},{5})", xBase, zBase, xSize, zSize, _terrain.CountX, _terrain.CountZ);
            }

            for (int x = 0; x < xSize; ++x)
            {
                for (int z = 0; z < zSize; ++z)
                {
                    int gridX = xBase + x;
                    int gridZ = zBase + z;

                    if (freeGrids[x, z])
                    {
                        RemoveAnchor(gridX, gridZ);
                    }
                }
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Set the heights of several vertices in the grid.
        /// </summary>
        /// <param name="xBase">The starting x coordinate.</param>
        /// <param name="zBase">The starting z coordinate.</param>
        /// <param name="heights">The square heights in grid steps.</param>
        public void SetVertexHeights(int xBase, int zBase, int[,] gridHeights)
        {
            // Reminder: vertices are one larger than square grid
            //           the bounds of this method are [0, CountX] [0, CountZ] inclusive
            int xLength = gridHeights.GetLength(0);
            int zLength = gridHeights.GetLength(1);

            if (xBase < 0 || xBase + xLength > CountX + 1 || zBase < 0 || zBase + zLength > CountZ + 1)
            {
                GameLogger.FatalError("Attempted to set vertex height outside of range! ({0},{1}) + ({2},{3}) is outside of ({4},{5})", xBase, zBase, xLength, zLength, CountX + 1, CountZ + 1);
            }

            // 1st pass: set the corner vertices
            for (int x = 0; x < xLength; ++x)
            {
                for (int z = 0; z < zLength; ++z)
                {
                    _vertexHeight[xBase + x, zBase + z] = gridHeights[x, z];
                    float worldHeight = Convert.GridHeightToWorld(gridHeights[x, z]);

                    // there are potentially 4 overlaps for each corner vertex.
                    // keep them all in sync!
                    int leftX  = xBase + x - 1;
                    int rightX = xBase + x;
                    int downZ  = zBase + z - 1;
                    int upZ    = zBase + z;

                    if (leftX >= 0 && downZ >= 0)
                    {
                        int index = _gridData[leftX, downZ].VertexIndex + Vertex.TopRight;
                        _vertices[index].y = worldHeight;
                    }

                    if (leftX >= 0 && upZ < CountZ)
                    {
                        int index = _gridData[leftX, upZ].VertexIndex + Vertex.BottomRight;
                        _vertices[index].y = worldHeight;
                    }

                    if (rightX < CountX && downZ >= 0)
                    {
                        int index = _gridData[rightX, downZ].VertexIndex + Vertex.TopLeft;
                        _vertices[index].y = worldHeight;
                    }

                    if (rightX < CountX && upZ < CountZ)
                    {
                        int index = _gridData[rightX, upZ].VertexIndex + Vertex.BottomLeft;
                        _vertices[index].y = worldHeight;
                    }
                }
            }

            // 2nd pass: set the center vertices
            for (int x = -1; x < xLength + 1; ++x)
            {
                for (int z = -1; z < zLength + 1; ++z)
                {
                    int gridX = xBase + x;
                    int gridZ = zBase + z;

                    if (gridX >= 0 && gridX < CountX && gridZ >= 0 && gridZ < CountZ)
                    {
                        int   index     = _gridData[gridX, gridZ].VertexIndex;
                        float newHeight = Utils.GetMajorityOrAverage(
                            _vertices[index + Vertex.BottomLeft].y,
                            _vertices[index + Vertex.BottomRight].y,
                            _vertices[index + Vertex.TopRight].y,
                            _vertices[index + Vertex.TopLeft].y);

                        _vertices[index + Vertex.Center].y = newHeight;
                    }
                }
            }

            UpdateMesh();
        }
        /// <summary>
        /// Sets the material on a grid square.
        /// </summary>
        /// <param name="x">X coordinate of the grid square.</param>
        /// <param name="z">Z coordinate of the grid square.</param>
        /// <param name="materialId">The id of the material to use at the grid square.</param>
        /// <param name="submaterialId">The id of the submaterial (the gridsheet on the material).</param>
        public void SetMaterial(int x, int z, int materialId, int submaterialId = 0)
        {
            if (x < 0 || x >= CountX || z < 0 || z >= CountZ)
            {
                GameLogger.FatalError("Attempted to set square material outside of range! ({0},{1}) is outside of ({2},{3})", x, z, CountX, CountZ);
            }

            try
            {
                int oldMaterialId    = _gridData[x, z].MaterialIndex;
                int oldTriangleIndex = _gridData[x, z].TriangleIndex;

                if (oldMaterialId != materialId)
                {
                    List <int> oldSubmesh       = _triangles[oldMaterialId];
                    List <int> newSubmesh       = _triangles[materialId];
                    int        newTriangleIndex = newSubmesh.Count;

                    // Move the triangles out of the old material sub mesh and into the end of the new material sub mesh.
                    int toMoveCount = Vertex.TrianglesPerSquare * 3;
                    for (int i = 0; i < toMoveCount; ++i)
                    {
                        newSubmesh.Add(oldSubmesh[oldTriangleIndex + i]);
                    }

                    // Overwrite the old submesh triangle list with the last element.
                    // Remove elements only from the end of the List.
                    int oldSubmeshLength = oldSubmesh.Count;
                    for (int i = 0; i < toMoveCount; ++i)
                    {
                        oldSubmesh[oldTriangleIndex + toMoveCount - 1 - i] = oldSubmesh[oldSubmeshLength - 1 - i];
                        oldSubmesh.RemoveAt(oldSubmeshLength - 1 - i);
                    }

                    // keep our pointers state consistent
                    _gridDataTriLookup[materialId][newTriangleIndex] = _gridData[x, z];
                    _gridDataTriLookup[oldMaterialId].Remove(oldTriangleIndex);

                    _gridData[x, z].MaterialIndex = materialId;
                    _gridData[x, z].TriangleIndex = newTriangleIndex;

                    int displacedTriangleIndex = oldSubmeshLength - toMoveCount;
                    if (oldSubmesh.Count > 0 && displacedTriangleIndex != oldTriangleIndex)
                    {
                        GridData displacedGrid = _gridDataTriLookup[oldMaterialId][displacedTriangleIndex];

                        Assert.AreEqual(displacedTriangleIndex, displacedGrid.TriangleIndex, "Grid TriangleIndex reverse lookup is corrupt!!!");

                        displacedGrid.TriangleIndex = oldTriangleIndex;
                        _gridDataTriLookup[oldMaterialId][oldTriangleIndex] = displacedGrid;
                        _gridDataTriLookup[oldMaterialId].Remove(displacedTriangleIndex);
                    }
                }

                SetSubmaterial(x, z, submaterialId);

                UpdateMesh();
            }
            catch (Exception ex)
            {
                GameLogger.FatalError("Exception while updating terrain material! Ex = {0}", ex.ToString());
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Use reflection to load resources that have the resource attributes.
        /// </summary>
        /// <param name="gameData">The game data to load data on.</param>
        private void LoadDataInternal(object gameData)
        {
            PropertyInfo[] properties = gameData.GetType().GetProperties();
            Dictionary <string, PropertyInfo> propertiesDictionary = properties.ToDictionary(info => info.Name);

            foreach (var property in properties)
            {
                var colorPalette   = property.GetCustomAttribute <ColorPaletteAttribute>();
                var resourceLoader = property.GetCustomAttribute <ResourceLoaderAttribute>();

                // Case 1) The property has a ColorPaletteAttribute. Load the Color.
                if (colorPalette != null)
                {
                    string colorName = string.Empty;
                    if (!propertiesDictionary.TryGetValue(colorPalette.PropertyName, out PropertyInfo colorNameProperty))
                    {
                        GameLogger.FatalError("Could not link ColorPaletteAttribute property name '{0}' to a PropertyInfo.", colorPalette.PropertyName);
                        continue;
                    }
                    else
                    {
                        colorName = colorNameProperty.GetValue(gameData)?.ToString();
                        if (string.IsNullOrEmpty(colorName))
                        {
                            GameLogger.FatalError("Could not load a value from ColorPaletteAttribute property '{0}'.", colorPalette.PropertyName);
                            continue;
                        }
                    }

                    Color color = ColorPalette.GetColor(colorName);
                    property.SetValue(gameData, color);
                }
                // Case 2) The property has a ResourceLoaderAttribute. Load the Resource.
                else if (resourceLoader != null)
                {
                    string resourceName = resourceLoader.ResourceName;
                    if (string.IsNullOrEmpty(resourceName))
                    {
                        if (!propertiesDictionary.TryGetValue(resourceLoader.PropertyName, out PropertyInfo resourceNameProperty))
                        {
                            GameLogger.FatalError("Could not link ResourceLoaderAttribute property name '{0}' to a PropertyInfo.", resourceLoader.PropertyName);
                            continue;
                        }
                        else
                        {
                            resourceName = resourceNameProperty.GetValue(gameData)?.ToString();
                            if (string.IsNullOrEmpty(resourceName))
                            {
                                GameLogger.FatalError("Could not load a value from ResourceLoaderAttribute property '{0}'.", resourceLoader.PropertyName);
                                continue;
                            }
                        }
                    }

                    UnityEngine.Object resource = ResourceLoader.Load(resourceLoader.Type, resourceLoader.Category, resourceName, property.PropertyType);
                    property.SetValue(gameData, resource);
                }
                // Case 3) The type is from the GameData namespace. Recursively attempt to load data.
                else if (property.GetValue(gameData) != null &&
                         property.PropertyType.FullName.StartsWith("GameData"))
                {
                    object propertyValue = property.GetValue(gameData);
                    LoadDataInternal(propertyValue);
                }
                // Case 4) The type is an IEnumerable. Unspool the objects and recursively load data.
                else if (property.GetValue(gameData) != null &&
                         property.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
                {
                    // Case 2: Unspool an enumerable of GameData objects
                    foreach (object item in (IEnumerable)property.GetValue(gameData, null))
                    {
                        if (item.GetType().FullName.StartsWith("GameData"))
                        {
                            LoadDataInternal(item);
                        }
                    }
                }
            }
        }