Beispiel #1
0
    void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e)
    {
        EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f),
                                          Vector3.Lerp(center, e.v5, 0.5f));

        m.v3.y = e.v3.y;

        TriangulateEdgeStrip(m, color1, cell.TerrainTypeIndex, e, color1, cell.TerrainTypeIndex);
        TriangulateEdgeFan(center, m, cell.TerrainTypeIndex);

        if (!cell.IsUnderwater)
        {
            bool reversed = cell.HasIncomingRiver;
            TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, reversed, cell.RiverSurfaceY, 0.6f);

            center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY;
            rivers.AddTriangle(center, m.v2, m.v4);
            if (reversed)
            {
                rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f));
            }
            else
            {
                rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f),
                                     new Vector2(1f, 0.6f));
            }
        }
    }
Beispiel #2
0
 public void AddCell(int index, HexCell_Script cell)
 {
     cells[index] = cell;
     cell.chunk   = this;
     cell.transform.SetParent(transform, false);
     cell.uiRect.SetParent(gridCanvas.transform, false);
 }
Beispiel #3
0
    void TriangulateCornerCliffTerraces(Vector3 begin, HexCell_Script beginCell,
                                        Vector3 left, HexCell_Script leftCell,
                                        Vector3 right, HexCell_Script rightCell)
    {
        float b = 1f / (leftCell.Elevation - beginCell.Elevation);

        if (b < 0)
        {
            b = -b;
        }
        Vector3 boundary      = Vector3.Lerp(HexMetrics_Script.Perturb(begin), HexMetrics_Script.Perturb(left), b);
        Color   boundaryColor = Color.Lerp(color1, color2, b);

        Vector3 types;

        types.x = beginCell.TerrainTypeIndex;
        types.y = beginCell.TerrainTypeIndex;
        types.z = beginCell.TerrainTypeIndex;

        TriangulateBoundaryTriangle(right, color3, begin, color1, boundary, boundaryColor, types);

        if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            TriangulateBoundaryTriangle(left, color2, right, color3, boundary, boundaryColor, types);
        }
        else
        {
            terrain.AddTriangleUnperturbed(HexMetrics_Script.Perturb(left), HexMetrics_Script.Perturb(right), boundary);
            //Search for Rand Error
            terrain.AddTriangleColor(color2, color3, boundaryColor);
            terrain.AddTriangleTerrainTypes(types);
        }
    }
    void HandleInput()
    {
        HexCell_Script currentCell = GetCellUnderCursor();

        if (currentCell)
        {
            if (previousCell && previousCell != currentCell)
            {
                ValidateDrag(currentCell);
            }
            else
            {
                isDrag = false;
            }

            EditCells(currentCell);

            previousCell = currentCell;
            isDrag       = true;
        }
        else
        {
            previousCell = null;
        }
    }
Beispiel #5
0
    void TriangulateOpenWater(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor,
                              Vector3 center)
    {
        Vector3 c1 = center + HexMetrics_Script.GetFirstWaterCorner(direction);
        Vector3 c2 = center + HexMetrics_Script.GetSecondWaterCorner(direction);

        water.AddTriangle(center, c1, c2);

        if (direction <= HexDirection.SE && neighbor != null)
        {
            Vector3 bridge = HexMetrics_Script.GetWaterBridge(direction);
            Vector3 e1     = c1 + bridge;
            Vector3 e2     = c2 + bridge;

            water.AddQuad(c1, c2, e1, e2);

            if (direction <= HexDirection.E)
            {
                HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next());
                if (nextNeighbor == null || !nextNeighbor.IsUnderwater)
                {
                    return;
                }

                water.AddTriangle(c2, e2, c2 + HexMetrics_Script.GetWaterBridge(direction.Next()));
            }
        }
    }
 public void AddUnit(HexUnit_Script unit, HexCell_Script location, float orientation)
 {
     units.Add(unit);
     unit.transform.SetParent(transform, false);
     unit.Location    = location;
     unit.Orientation = orientation;
 }
Beispiel #7
0
    void TriangulateAdjacentToRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics_Script.GetSolidEdgeMiddle(direction) * (HexMetrics_Script.innerToOuter * 0.5f);
            }
            else if (cell.HasRiverThroughEdge(direction.Previous2()))
            {
                center += HexMetrics_Script.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()) &&
                 cell.HasRiverThroughEdge(direction.Next2()))
        {
            center += HexMetrics_Script.GetSecondSolidCorner(direction) * 0.25f;
        }

        EdgeVertices m = new EdgeVertices(Vector3.Lerp(center, e.v1, 0.5f),
                                          Vector3.Lerp(center, e.v5, 0.5f));

        TriangulateEdgeStrip(m, color1, cell.TerrainTypeIndex, e, color1, cell.TerrainTypeIndex);
        TriangulateEdgeFan(center, m, cell.TerrainTypeIndex);

        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
Beispiel #8
0
    public void SetOutgoingRiver(HexDirection direction)
    {
        if (HasOutgoingRiver && outgoingRiver == direction)
        {
            return;
        }

        HexCell_Script neighbor = GetNeighbor(direction);

        if (!IsValidRiverDestination(neighbor))
        {
            return;
        }

        RemoveOutgoingRiver();
        if (hasIncomingRiver && incomingRiver == direction)
        {
            RemoveIncomingRiver();
        }

        hasOutgoingRiver = true;
        outgoingRiver    = direction;
        specialIndex     = 0;
        //RefreshSelfOnly();

        neighbor.RemoveIncomingRiver();
        neighbor.hasIncomingRiver = true;
        neighbor.incomingRiver    = direction.Opposite();
        neighbor.specialIndex     = 0;
        //neighbor.RefreshSelfOnly();

        SetRoad((int)direction, false);
    }
    void CreateUnit()
    {
        HexCell_Script cell = GetCellUnderCursor();

        if (cell && !cell.Unit)
        {
            hexGrid.AddUnit(Instantiate(HexUnit_Script.unitPrefab), cell, Random.Range(0f, 360f));
        }
    }
    void ErodeLand()
    {
        List <HexCell_Script> erodibleCells = ListPool <HexCell_Script> .Get();

        for (int i = 0; i < cellCount; i++)
        {
            HexCell_Script cell = grid.GetCell(i);
            if (IsErodible(cell))
            {
                erodibleCells.Add(cell);
            }
        }

        int targetErodibleCount = (int)(erodibleCells.Count * (100 - erosionPercentage) * 0.01f);

        while (erodibleCells.Count > targetErodibleCount)
        {
            int            index      = Random.Range(0, erodibleCells.Count);
            HexCell_Script cell       = erodibleCells[index];
            HexCell_Script targetCell = GetErosionTarget(cell);

            cell.Elevation--;
            targetCell.Elevation++;

            if (!IsErodible(cell))
            {
                erodibleCells[index] = erodibleCells[erodibleCells.Count - 1];
                erodibleCells.RemoveAt(erodibleCells.Count - 1);
            }

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell_Script neigbor = cell.GetNeighbor(d);
                if (neigbor && neigbor.Elevation == cell.Elevation + 2 &&
                    !erodibleCells.Contains(neigbor))
                {
                    erodibleCells.Add(neigbor);
                }
            }

            if (IsErodible(targetCell) && !erodibleCells.Contains(targetCell))
            {
                erodibleCells.Add(targetCell);
            }

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell_Script neighbor = targetCell.GetNeighbor(d);
                if (neighbor && neighbor != cell && !IsErodible(neighbor) &&
                    neighbor.Elevation == targetCell.Elevation + 1)
                {
                    erodibleCells.Remove(neighbor);
                }
            }
        }
        ListPool <HexCell_Script> .Add(erodibleCells);
    }
    void DestroyUnit()
    {
        HexCell_Script cell = GetCellUnderCursor();

        if (cell && cell.Unit)
        {
            hexGrid.RemoveUnit(cell.Unit);
        }
    }
Beispiel #12
0
    public void AddSpecialFeature(HexCell_Script cell, Vector3 position)
    {
        Transform instance = Instantiate(specials[cell.SpecialIndex - 1]);

        instance.localPosition = HexMetrics_Script.Perturb(position);
        HexHash hash = HexMetrics_Script.SampleHashGrid(position);

        instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f);
        instance.SetParent(container, false);
    }
    void AddCellToChunk(int x, int z, HexCell_Script cell)
    {
        int chunkX = x / HexMetrics_Script.chunkSizeX;
        int chunkZ = z / HexMetrics_Script.chunkSizeZ;
        HexGridChunk_Script chunk = chunks[chunkX + chunkZ * chunkCountX];

        int localX = x - chunkX * HexMetrics_Script.chunkSizeX;
        int localZ = z - chunkZ * HexMetrics_Script.chunkSizeZ;

        chunk.AddCell(localX + localZ * HexMetrics_Script.chunkSizeX, cell);
    }
 void SetTerrainType()
 {
     for (int i = 0; i < cellCount; i++)
     {
         HexCell_Script cell = grid.GetCell(i);
         if (!cell.IsUnderwater)
         {
             cell.TerrainTypeIndex = cell.Elevation - cell.WaterLevel;
         }
     }
 }
    bool UpdateCurrentCell()
    {
        HexCell_Script cell = grid.GetCell(Camera.main.ScreenPointToRay(Input.mousePosition));

        if (cell != currentCell)
        {
            currentCell = cell;
            return(true);
        }
        return(false);
    }
    //public void Refresh()
    //{
    //    hexMesh.Triangulate(cells);
    //}

    void CreateCell(int x, int z, int i)
    {
        Vector3 position;

        position.x = (x + z * 0.5f - z / 2) * (HexMetrics_Script.innerRadius * 2f);
        position.y = 0f;
        position.z = z * (HexMetrics_Script.outerRadius * 1.5f);

        HexCell_Script cell = cells[i] = Instantiate <HexCell_Script>(cellPrefab);

        //cell.transform.SetParent(transform, false);
        cell.transform.localPosition = position;
        cell.coordinates             = HexCoordinates.FromOffsetCoordinates(x, z);
        //cell.Color = defaultColor;

        if (x > 0)
        {
            cell.SetNeighbor(HexDirection.W, cells[i - 1]);
        }
        if (z > 0)
        {
            if ((z & 1) == 0)
            {
                cell.SetNeighbor(HexDirection.SE, cells[i - cellCountX]);
                if (x > 0)
                {
                    cell.SetNeighbor(HexDirection.SW, cells[i - cellCountX - 1]);
                }
            }
            else
            {
                cell.SetNeighbor(HexDirection.SW, cells[i - cellCountX]);
                if (x < cellCountX - 1)
                {
                    cell.SetNeighbor(HexDirection.SE, cells[i - cellCountX + 1]);
                }
            }
        }

        Text label = Instantiate <Text>(cellLabelPrefab);

        //label.rectTransform.SetParent(gridCanvas.transform, false);
        label.rectTransform.anchoredPosition = new Vector2(position.x, position.z);
        //label.text = cell.coordinates.ToStringOnSeparateLines();

        cell.uiRect = label.rectTransform;

        cell.Elevation = 0;

        AddCellToChunk(x, z, cell);

        //Test
        cell.DisableHighlight();
    }
Beispiel #17
0
    public void AddFeature(HexCell_Script cell, Vector3 position)
    {
        if (cell.IsSpecial)
        {
            return;
        }

        HexHash hash = HexMetrics_Script.SampleHashGrid(position);
        //if (hash.a >= cell.UrbanLevel*0.25f)
        //    return;
        //Transform instance = Instantiate(urbanPrefabs[cell.UrbanLevel-1]);
        Transform prefab      = PickPrefab(urbanPrefabs, cell.UrbanLevel, hash.a, hash.d);
        Transform otherprefab = PickPrefab(farmPrefabs, cell.FarmLevel, hash.b, hash.d);

        float usedHash = hash.a;

        if (prefab)
        {
            if (otherprefab && hash.b < hash.a)
            {
                prefab   = otherprefab;
                usedHash = hash.b;
            }
        }
        else if (otherprefab)
        {
            prefab   = otherprefab;
            usedHash = hash.b;
        }
        otherprefab = PickPrefab(plantPrefabs, cell.PlantLevel, hash.c, hash.d);
        if (prefab)
        {
            if (otherprefab && hash.c < usedHash)
            {
                prefab = otherprefab;
            }
        }
        else if (otherprefab)
        {
            prefab = otherprefab;
        }
        else
        {
            return;
        }

        Transform instance = Instantiate(prefab);

        position.y            += instance.localScale.y * 0.5f;
        instance.localPosition = HexMetrics_Script.Perturb(position);
        instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f);
        instance.SetParent(container, false);
    }
Beispiel #18
0
    void TriangulateWithoutRiver(HexDirection direction, HexCell_Script cell, Vector3 center, EdgeVertices e)
    {
        TriangulateEdgeFan(center, e, cell.TerrainTypeIndex);

        if (cell.HasRoads)
        {
            Vector2 interpolators = GetRoadInterpolators(direction, cell);
            TriangulateRoad(center, Vector3.Lerp(center, e.v1, interpolators.x),
                            Vector3.Lerp(center, e.v5, interpolators.y), e,
                            cell.HasRoadThroughEdge(direction));
        }
    }
 void ValidateDrag(HexCell_Script currentCell)
 {
     for (dragDirection = HexDirection.NE; dragDirection <= HexDirection.NW; dragDirection++)
     {
         if (previousCell.GetNeighbor(dragDirection) == currentCell)
         {
             isDrag = true;
             return;
         }
     }
     isDrag = false;
 }
Beispiel #20
0
 public HexCell_Script Dequeue()
 {
     count--;
     for (; minimum < list.Count; minimum++)
     {
         HexCell_Script cell = list[minimum];
         if (cell != null)
         {
             list[minimum] = cell.NextWithSamePriority;
             return(cell);
         }
     }
     return(null);
 }
Beispiel #21
0
    public void RemoveIncomingRiver()
    {
        if (!hasIncomingRiver)
        {
            return;
        }
        hasIncomingRiver = false;
        RefreshSelfOnly();

        HexCell_Script neighbor = GetNeighbor(incomingRiver);

        neighbor.hasOutgoingRiver = false;
        neighbor.RefreshSelfOnly();
    }
    bool IsErodible(HexCell_Script cell)
    {
        int erodibleElevation = cell.Elevation - 2;

        for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
        {
            HexCell_Script neighbor = cell.GetNeighbor(d);
            if (neighbor && neighbor.Elevation <= erodibleElevation)
            {
                return(true);
            }
        }
        return(false);
    }
    int RaiseTerrain(int chunkSize, int budget, MapRegion region)
    {
        searchFrontierPhase++;
        HexCell_Script firstCell = GetRandomCell(region);

        firstCell.SearchPhase     = searchFrontierPhase;
        firstCell.Distance        = 0;
        firstCell.SearchHeuristic = 0;
        searchFrontier.Enqueue(firstCell);
        HexCoordinates center = firstCell.coordinates;

        int rise = Random.value < highRiseProbability ? 2 : 1;
        int size = 0;

        while (size < chunkSize && searchFrontier.Count > 0)
        {
            HexCell_Script current           = searchFrontier.Dequeue();
            int            originalElevation = current.Elevation;
            int            newElevation      = originalElevation + rise;
            if (newElevation > elevationMaximum)
            {
                continue;
            }

            current.Elevation = newElevation;

            if (originalElevation < waterLevel &&
                newElevation >= waterLevel && --budget == 0)
            {
                break;
            }

            size++;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell_Script neighbor = current.GetNeighbor(d);
                if (neighbor && neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = neighbor.coordinates.DistanceTo(center);
                    neighbor.SearchHeuristic = Random.value < jitterProbabitlity ? 1 : 0;;
                    searchFrontier.Enqueue(neighbor);
                }
            }
        }
        searchFrontier.Clear();

        return(budget);
    }
 public void FindPath(HexCell_Script fromCell, HexCell_Script toCell, int speed)
 {
     //StopAllCoroutines();
     //StartCoroutine(Search(fromCell,toCell,speed));
     System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
     sw.Start();
     ClearPath();
     currentPathFrom  = fromCell;
     currentPathTo    = toCell;
     currenPathExists = Search(fromCell, toCell, speed);
     ShowPath(speed);
     sw.Stop();
     Debug.Log(sw.ElapsedMilliseconds);
 }
Beispiel #25
0
    void AddWallSegment(Vector3 pivot, HexCell_Script pivotCell,
                        Vector3 left, HexCell_Script leftCell,
                        Vector3 right, HexCell_Script rightCell)
    {
        if (pivotCell.IsUnderwater)
        {
            return;
        }

        bool hasLeftWall = !leftCell.IsUnderwater &&
                           pivotCell.GetEdgeType(leftCell) != HexEdgeType.Cliff;
        bool hasRightWall = !rightCell.IsUnderwater &&
                            pivotCell.GetEdgeType(rightCell) != HexEdgeType.Cliff;


        if (hasLeftWall)
        {
            if (hasRightWall)
            {
                bool hasTower = false;
                if (leftCell.Elevation == rightCell.Elevation)
                {
                    HexHash hash = HexMetrics_Script.SampleHashGrid((pivot + left + right) * (1f / 3f));

                    hasTower = hash.e < HexMetrics_Script.wallTowerTreshold;
                }
                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);
            }
        }
    }
Beispiel #26
0
    Vector2 GetRoadInterpolators(HexDirection direction, HexCell_Script cell)
    {
        Vector2 interpolators;

        if (cell.HasRoadThroughEdge(direction))
        {
            interpolators.x = interpolators.y = 0.5f;
        }
        else
        {
            interpolators.x = cell.HasRoadThroughEdge(direction.Previous()) ? 0.5f : 0.25f;
            interpolators.y = cell.HasRoadThroughEdge(direction.Next()) ? 0.5f : 0.25f;
        }
        return(interpolators);
    }
Beispiel #27
0
 void Triangulate(HexCell_Script cell)
 {
     for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
     {
         Triangulate(d, cell);
     }
     if (!cell.IsUnderwater && !cell.HasRiver && !cell.HasRoads)
     {
         features.AddFeature(cell, cell.Position);
     }
     if (!cell.IsUnderwater && cell.IsSpecial)
     {
         features.AddSpecialFeature(cell, cell.Position);
     }
 }
Beispiel #28
0
    void TriangulateWater(HexDirection direction, HexCell_Script cell, Vector3 center)
    {
        center.y = cell.WaterSurfaceY;

        HexCell_Script neighbor = cell.GetNeighbor(direction);

        if (neighbor != null && !neighbor.IsUnderwater)
        {
            TriangulateWaterShore(direction, cell, neighbor, center);
        }
        else
        {
            TriangulateOpenWater(direction, cell, neighbor, center);
        }
    }
Beispiel #29
0
    void TriangulateWaterShore(HexDirection direction, HexCell_Script cell, HexCell_Script neighbor,
                               Vector3 center)
    {
        EdgeVertices e1 = new EdgeVertices(center + HexMetrics_Script.GetFirstWaterCorner(direction),
                                           center + HexMetrics_Script.GetSecondWaterCorner(direction));

        water.AddTriangle(center, e1.v1, e1.v2);
        water.AddTriangle(center, e1.v2, e1.v3);
        water.AddTriangle(center, e1.v3, e1.v4);
        water.AddTriangle(center, e1.v4, e1.v5);

        Vector3 center2 = neighbor.Position;

        center2.y = center.y;
        EdgeVertices e2 = new EdgeVertices(center2 + HexMetrics_Script.GetSecondSolidCorner(direction.Opposite()),
                                           center2 + HexMetrics_Script.GetFirstSolidCorner(direction.Opposite()));

        if (cell.HasRiverThroughEdge(direction))
        {
            TriangulateEstuary(e1, e2, cell.IncomingRiver == direction);
        }
        else
        {
            waterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
            waterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
            waterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
            waterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
            waterShore.AddQuadUV(0f, 0f, 0f, 1f);
        }
        HexCell_Script nextNeighbor = cell.GetNeighbor(direction.Next());

        if (nextNeighbor != null)
        {
            Vector3 v3 = nextNeighbor.Position + (nextNeighbor.IsUnderwater ?
                                                  HexMetrics_Script.GetFirstWaterCorner(direction.Previous()) :
                                                  HexMetrics_Script.GetFirstSolidCorner(direction.Previous()));
            v3.y = center.y;
            waterShore.AddTriangle(e1.v5, e2.v5, v3);

            waterShore.AddTriangleUV(
                new Vector2(0f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, nextNeighbor.IsUnderwater?0f:1f));
        }
    }
Beispiel #30
0
    public void Enqueue(HexCell_Script cell)
    {
        count++;
        int priority = cell.SearchPriority;

        if (priority < minimum)
        {
            minimum = priority;
        }
        while (priority >= list.Count)
        {
            list.Add(null);
        }
        cell.NextWithSamePriority = list[priority];
        list[priority]            = cell;
    }