public void AddSpecialFeature(HexCell cell, Vector3 position)
        {
            if (cell.specialIndex == 0)
            {
                return;                         // shouldn't happen, but guard against it all the same.)
            }
            position = HexMetrics.Perturb(position);
            var hash     = HexMetrics.SampleHashGrid(position);
            var rotation = Quaternion.Euler(0f, 360f * hash.e, 0f);

            Instantiate(special[cell.specialIndex - 1], position, rotation, m_Container);
        }
        public void AddFeature(HexCell cell, Vector3 position)
        {
            if (cell.isSpecial)
            {
                return;
            }
            var   hash        = HexMetrics.SampleHashGrid(position);
            var   prefab      = PickPrefab(urbanCollections, cell.urbanLevel, hash.a, hash.d);
            var   otherPrefab = PickPrefab(farmCollections, cell.farmLevel, hash.b, hash.d);
            float usedHash    = hash.a;

            if (prefab)
            {
                if (otherPrefab && hash.b < usedHash)
                {
                    prefab   = otherPrefab;
                    usedHash = hash.b;
                }
            }
            else if (otherPrefab)
            {
                prefab   = otherPrefab;
                usedHash = hash.b;
            }
            otherPrefab = PickPrefab(plantCollections, cell.plantLevel, hash.c, hash.d);
            if (prefab)
            {
                if (otherPrefab && hash.c < usedHash)
                {
                    prefab = otherPrefab;
                }
            }
            else if (otherPrefab)
            {
                prefab = otherPrefab;
            }
            else
            {
                return;
            }

            var instance = Instantiate(prefab, m_Container, false);

            position.y            += instance.localScale.y * 0.5f;
            instance.localPosition = HexMetrics.Perturb(position);
            instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f);
        }
        void AddWallSegment(Vector3 pivot, HexCell pivotCell,
                            Vector3 left, HexCell leftCell,
                            Vector3 right, HexCell rightCell)
        {
            if (pivotCell.isUnderWater)
            {
                return;
            }

            var hasLeftWall = !leftCell.isUnderWater &&
                              pivotCell.GetEdgeType(leftCell) != HexEdgeType.Cliff;
            var hasRightWall = !rightCell.isUnderWater &&
                               pivotCell.GetEdgeType(rightCell) != HexEdgeType.Cliff;

            if (hasLeftWall)
            {
                if (hasRightWall)
                {
                    var hash     = HexMetrics.SampleHashGrid((pivot + left + right) * (1f / 3f));
                    var hasTower = CanBuildTower(hash, leftCell, rightCell, pivotCell);
                    AddWallSegment(pivot, left, pivot, right, hasTower);
                }
                else if (leftCell.elevation < rightCell.elevation)
                {
                    AddWallWedge(pivot, left, right);
                }
                else
                {
                    AddWallCap(pivot, left);
                }
            }
            else if (hasRightWall)
            {
                if (rightCell.elevation < leftCell.elevation)
                {
                    AddWallWedge(right, pivot, left);
                }
                else
                {
                    AddWallCap(right, pivot);
                }
            }
        }