예제 #1
0
    public void RecalculateTerrain(TriCell cell, bool buildable)
    {
        Vector3      nextCorner, prevCorner;
        EdgeVertices edge;

        for (TriDirection direction = TriDirection.VERT; direction <= TriDirection.RIGHT; direction++)
        {
            Vector3 center = cell.Position, v1, v2;
            //entityMenu.transform.localPosition = center + new Vector3(0, 20, 0);
            v1         = center + (cell.inverted ? -1 : 1) * TriMetrics.GetFirstSolidCorner(direction);
            v2         = center + (cell.inverted ? -1 : 1) * TriMetrics.GetSecondSolidCorner(direction);
            edge       = new EdgeVertices(v1, v2);
            nextCorner = (center + edge.v1) / 2f;
            prevCorner = (center + edge.v5) / 2f;
            AddTriangle(nextCorner, edge.v1, edge.v2);
            AddTriangle(prevCorner, edge.v4, edge.v5);
            AddTriangle(center, edge.v2, edge.v4);
            AddTriangle(center, edge.v4, prevCorner);
            AddTriangle(center, nextCorner, edge.v2);
            Color c = buildable ? Color.blue : Color.red;
            AddTriangleColor(c);
            AddTriangleColor(c);
            AddTriangleColor(c);
            AddTriangleColor(c);
            AddTriangleColor(c);
        }
    }
예제 #2
0
    public static Building Load(BinaryReader reader)
    {
        BuildingType type           = (BuildingType)reader.ReadInt32();
        TriDirection entDir         = (TriDirection)reader.ReadInt32();
        bool         underconstruct = reader.ReadBoolean();
        bool         working        = reader.ReadBoolean();
        float        constructTime  = reader.ReadSingle();
        Building     ret            = null;

        switch (type)
        {
        case BuildingType.INN:
            ret = Inn.Load(reader);
            break;

        case BuildingType.COMPANY:
            ret = Company.Load(reader);
            break;

        case BuildingType.WORKSITE:
            ret = Worksite.Load(reader);
            break;
        }
        ret.entranceDirection = entDir;
        ret.type           = type;
        ret.UnderConstruct = underconstruct;
        ret.Working        = working;
        ret.ConstructTime  = constructTime;
        return(ret);
    }
예제 #3
0
    void SetClimateData(int cellIndex, float moisture, float clouds)
    {
        TriDirection d = TriDirection.VERT;
        TriCell      current, k;
        ClimateData  t;

        current = k = grid.GetCell(cellIndex);
        for (int i = 0; i < 6; i++)
        {
            if (!k)
            {
                break;
            }

            t                = new ClimateData();
            t.moisture       = moisture;
            t.clouds         = clouds;
            climate[k.Index] = t;

            k = k.GetNeighbor(d);
            if (current.inverted)
            {
                d = d.Next();
            }
            else
            {
                d = d.Previous();
            }
        }
    }
예제 #4
0
 void Triangulate(TriCell cell)
 {
     for (TriDirection d = TriDirection.VERT; d <= TriDirection.RIGHT; d++)
     {
         Triangulate(d, cell);
     }
 }
예제 #5
0
    public void RecalculateTerrain(TriCell cell)
    {
        Vector3      nextCorner, prevCorner;
        EdgeVertices edge;

        for (TriDirection direction = TriDirection.VERT; direction <= TriDirection.RIGHT; direction++)
        {
            Vector3 center = cell.Position, v1, v2;
            v1         = center + (cell.inverted ? -1 : 1) * TriMetrics.GetFirstSolidCorner(direction);
            v2         = center + (cell.inverted ? -1 : 1) * TriMetrics.GetSecondSolidCorner(direction);
            edge       = new EdgeVertices(v1, v2);
            nextCorner = (center + edge.v1) / 2f;
            prevCorner = (center + edge.v5) / 2f;
            terrainSelectionViewer.AddTriangle(nextCorner, edge.v1, edge.v2);
            terrainSelectionViewer.AddTriangle(prevCorner, edge.v4, edge.v5);
            terrainSelectionViewer.AddTriangle(center, edge.v2, edge.v4);
            terrainSelectionViewer.AddTriangle(center, edge.v4, prevCorner);
            terrainSelectionViewer.AddTriangle(center, nextCorner, edge.v2);

            terrainSelectionViewer.AddTriangleColor(Color.blue);
            terrainSelectionViewer.AddTriangleColor(Color.blue);
            terrainSelectionViewer.AddTriangleColor(Color.blue);
            terrainSelectionViewer.AddTriangleColor(Color.blue);
            terrainSelectionViewer.AddTriangleColor(Color.blue);
        }
    }
예제 #6
0
 public BuildCommand(TriCell location, TriDirection dir, Entity target)
 {
     this.location = location;
     this.dir      = dir;
     this.target   = target;
     type          = CommandType.BUILD;
 }
예제 #7
0
    public void StartCalculateTerrain()
    {
        terrainSelectionViewer.Clear();
        switch (terrainType)
        {
        case SizeType.HEX:
            TriCell      k    = selectedCell;
            int          elev = selectedCell.Elevation;
            TriDirection tDir = dir.Previous();
            for (int i = 0; i < 6; i++)
            {
                if (!k)
                {
                    break;
                }
                RecalculateTerrain(k);
                k    = k.GetNeighbor(tDir);
                tDir = tDir.Next();
            }
            break;

        case SizeType.SINGLE:
            RecalculateTerrain(selectedCell);
            break;
        }

        terrainSelectionViewer.Apply();
    }
예제 #8
0
    public static new BuildCommand Load(BinaryReader reader)
    {
        TriGrid      instance = TriGrid.Instance;
        TriCell      tCell    = instance.GetCell(TriCoordinates.Load(reader));
        TriDirection tDir     = (TriDirection)reader.ReadInt32();
        Entity       prefab   = TriIsland.GetBuildingPrefabs(reader.ReadInt32(), reader.ReadInt32(), 0);

        return(new BuildCommand(tCell, tDir, prefab));
    }
예제 #9
0
    public IEnumerator <Coroutine> LoadBuilding(string path)
    {
        ClearBuildings();
        using (BinaryReader reader = new BinaryReader(File.OpenRead(Path.Combine(path, "building.dat")))) {
            int header = reader.ReadInt32();
            if (header <= 0)
            {
                int counter = reader.ReadInt32();
                for (int i = 0; i < counter; i++)
                {
                    TriCoordinates coord  = TriCoordinates.Load(reader);
                    Building       loaded = Building.Load(reader);
                    if (loaded.type == BuildingType.HALL)
                    {
                        camp = loaded as Hall;
                    }
                    if (loaded)
                    {
                        loaded.ID                = i;
                        loaded.Location          = grid.GetCell(coord);
                        loaded.EntranceDirection = loaded.EntranceDirection;
                        switch (loaded.sizeType)
                        {
                        case SizeType.SINGLE:
                            loaded.Location.Statics = loaded;
                            break;

                        case SizeType.HEX:
                            TriCell      k    = loaded.Location;
                            TriDirection tDir = loaded.EntranceDirection.Previous();
                            for (int j = 0; j < 6; j++)
                            {
                                if (!k)
                                {
                                    break;
                                }
                                k.Statics = loaded;
                                k         = k.GetNeighbor(tDir);
                                tDir      = tDir.Next();
                            }
                            break;
                        }

                        loaded.transform.SetParent(BuildingGroup);
                        AddBuilding(loaded);
                    }
//                    if (i % Strings.refreshLimit == 0) yield return null;
                }
            }
            else
            {
                Debug.LogWarning("Unknown building format " + header);
            }
        }
        yield return(null);
    }
예제 #10
0
    public override List <BuildState> GetBuildStatus(TriCoordinates coord, TriDirection dir)
    {
        List <BuildState> ret  = new List <BuildState>();
        TriCell           cell = TriGrid.Instance.GetCell(coord);
        int elev = cell.Elevation;

        ret.Add(new BuildState(coord, cell.IsBuildable()));
        cell = cell.GetNeighbor(dir);
        ret.Add(new BuildState(cell.coordinates, cell.IsBuildable() && Mathf.Abs(elev - cell.Elevation) < 2));
        return(ret);
    }
예제 #11
0
    public void SetRiver(TriDirection direction)
    {
        if (!isRiver[(int)direction])
        {
            isRiver[(int)direction] = true;
            RefreshSelfOnly();

            TriCell neighbor = GetNeighbor(direction);
            neighbor.isRiver[(int)direction] = true;
            neighbor.RefreshSelfOnly();
        }
    }
예제 #12
0
    public virtual List <BuildState> GetBuildStatus(TriCoordinates coord, TriDirection dir)
    {
        List <BuildState> ret  = new List <BuildState>();
        TriGrid           grid = TriGrid.Instance;
        TriCell           cell = grid.GetCell(coord);
        int elev = cell.Elevation;

        ret.Add(new BuildState(cell.coordinates, cell.IsBuildable()));
        cell = grid.GetCell(coord).GetNeighbor(dir);
        ret.Add(new BuildState(cell.coordinates, cell.IsBuildable() && Mathf.Abs(cell.Elevation - elev) < 2));
        return(ret);
    }
예제 #13
0
    public void RemoveRiver(TriDirection direction)
    {
        if (isRiver[(int)direction])
        {
            isRiver[(int)direction] = false;
            RefreshSelfOnly();

            TriCell neighbor = GetNeighbor(direction);
            neighbor.isRiver[(int)direction] = false;
            neighbor.RefreshSelfOnly();
        }
    }
예제 #14
0
    public Building CreateBuilding(TriDirection dir, TriCell cell, Building prefab)
    {
        List <BuildState> result = prefab.GetBuildStatus(cell.coordinates, dir);
        bool buildable           = true;

        foreach (BuildState i in result)
        {
            if (!i.value)
            {
                buildable = false;
            }
        }
        if (cell && buildable)
        {
            Building ret = Instantiate(prefab);
            ret.ID       = entities.BuildingCount;
            ret.Location = cell;
            switch (ret.sizeType)
            {
            case SizeType.SINGLE:
                cell.Statics = ret;
                break;

            case SizeType.HEX:
                TriCell      k    = cell;
                TriDirection tDir = dir.Previous();
                for (int i = 0; i < 6; i++)
                {
                    if (!k)
                    {
                        break;
                    }
                    k.Statics = ret;
                    k         = k.GetNeighbor(tDir);
                    tDir      = tDir.Next();
                }
                break;
            }
            ret.EntranceDirection = dir;
            ret.personList        = personList;
            entities.AddBuilding(ret);
            island.ShowSummary = island.ShowSummary;
            Debug.Log(ret + " built");
            return(ret);
        }
        else
        {
            Debug.Log("building failed");
            return(null);
        }
    }
예제 #15
0
    int CreateRiver(TriCell origin)
    {
        int          length    = 0;
        TriCell      cell      = origin;
        TriDirection direction = TriDirection.VERT;

        while (!cell.IsUnderwater)
        {
            flowDirections.Clear();
            for (TriDirection d = TriDirection.VERT; d <= TriDirection.RIGHT; d++)
            {
                TriCell neighbor = cell.GetNeighbor(d);
                if (!neighbor || neighbor.HasRiver)
                {
                    continue;
                }
                int delta = neighbor.Elevation - cell.Elevation;
                if (delta > 0)
                {
                    continue;
                }
                if (delta < 0)
                {
                    flowDirections.Add(d);
                    flowDirections.Add(d);
                    flowDirections.Add(d);
                }
                if (
                    length == 1 ||
                    (d != direction.Next2() && d != direction.Previous2())
                    )
                {
                    flowDirections.Add(d);
                }
                flowDirections.Add(d);
            }
            if (flowDirections.Count == 0)
            {
                return(length > 1 ? length : 0);
            }
            direction = flowDirections[Random.Range(0, flowDirections.Count)];
            cell.SetRiver(direction);
            cell.GetNeighbor(direction).SetRiver(direction);
            length += 1;
            cell    = cell.GetNeighbor(direction);
        }
        return(length);
    }
예제 #16
0
    public void CreateHall(TriDirection dir, TriCell cell)
    {
        Hall ret = (Hall)CreateBuilding(dir, cell, (Building)TriIsland.GetBuildingPrefabs((int)BuildingType.HALL, (int)HallType.BASE, 0));

        if (ret)
        {
            TriIsland.Instance.entities.camp = ret;
            for (int i = 0; i < 4; i++)
            {
                Unit t = CreateUnit(ret.EntranceLocation, (Unit)TriIsland.GetUnitPrefabs((int)UnitType.PERSON, 0));
                ((Human)t).Home = null;
                t.AddCommand(new GetInCommand(ret));
            }
            ret.Working = true;
        }
    }
예제 #17
0
 void ValidateDrag(TriCell currentCell)
 {
     for (
         dragDirection = TriDirection.VERT;
         dragDirection <= TriDirection.RIGHT;
         dragDirection++
         )
     {
         if (previousCell.GetNeighbor(dragDirection) == currentCell)
         {
             isDrag = true;
             return;
         }
     }
     isDrag = false;
 }
예제 #18
0
    public static Natural Load(BinaryReader reader)
    {
        NaturalType  type   = (NaturalType)reader.ReadInt32();
        TriDirection entDir = (TriDirection)reader.ReadInt32();
        Natural      ret    = null;

        switch (type)
        {
        case NaturalType.TREE:
            ret = Tree.Load(reader);
            break;
        }
        ret.entranceDirection = entDir;
        ret.type = type;
        return(ret);
    }
예제 #19
0
    private void LateUpdate()
    {
        if (ordering)
        {
            tCell = GetRay();
            if (tCell)
            {
                nowCell = tCell;
            }
            if (Input.GetKeyDown(KeyCode.R))
            {
                dir = dir.Next();
            }
            if (subject && Input.GetKeyDown(KeyCode.Escape))
            {
                CancelCommand();
            }
            if (Input.GetMouseButtonDown(0))
            {
                switch (command.type)
                {
                case CommandType.CHANGEHOME:
                    ((ChangeHomeCommand)command).target = (Inn)nowCell.Statics;
                    break;

                case CommandType.CHANGEJOB:
                    ((ChangeJobCommand)command).target = (Company)nowCell.Statics;
                    break;

                case CommandType.CHANGEWORK:
                    ((ChangeWorkCommand)command).target = (Building)nowCell.Statics;
                    break;

                case CommandType.BUILD:
                    if (!IsBuildable())
                    {
                        Debug.Log("invalid build site.");
                        return;
                    }
                    ((BuildCommand)command).dir      = dir;
                    ((BuildCommand)command).location = nowCell;
                    break;
                }
                SendCommand();
            }
        }
    }
예제 #20
0
    void Triangulate(TriDirection direction, TriCell cell)
    {
        int inverter = 0;

        if (cell.inverted)
        {
            inverter = -1;
        }
        else
        {
            inverter = 1;
        }

        Vector3 center = cell.Position, v1, v2;

        v1 = center + inverter * TriMetrics.GetFirstSolidCorner(direction);
        v2 = center + inverter * TriMetrics.GetSecondSolidCorner(direction);
        EdgeVertices e = new EdgeVertices(v1, v2);

        if (cell.IsUnderwater)
        {
            TriangulateWater(center, e);
        }
        if (cell.HasRiverThroughEdge(direction))
        {
            TriangulateWithRiver(cell, direction, center, e, cell.Color);
        }
        else
        {
            TriangulateEdgeFan(center, e, cell.Color);
        }
        if (cell.inverted)
        {
            if (direction != TriDirection.LEFT)
            {
                TriangulateConnection(direction, cell, e, inverter);
            }
        }
        else
        {
            if (direction == TriDirection.LEFT)
            {
                TriangulateConnection(direction, cell, e, inverter);
            }
        }
    }
예제 #21
0
    public override void BindCells(bool flag)
    {
        TriCell      k    = Location;
        int          elev = k.Elevation;
        TriDirection tDir = EntranceDirection.Previous();

        for (int i = 0; i < 6; i++)
        {
            if (!k)
            {
                break;
            }
            k.Statics = flag?this:null;
            k         = k.GetNeighbor(tDir);
            tDir      = tDir.Next();
        }
    }
예제 #22
0
    void TriangulateConnection(TriDirection direction, TriCell cell, EdgeVertices e1, int inverter)
    {
        Vector3 center   = cell.transform.localPosition;
        TriCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            return;
        }
        Vector3 bridge = TriMetrics.GetBridge(direction);

        bridge.y = neighbor.Position.y - cell.Position.y;
        EdgeVertices e2 = new EdgeVertices(
            e1.v1 + bridge,
            e1.v5 + bridge
            );

        TriangulateEdgeStrip(terrain, e1, cell.Color, e2, neighbor.Color, cell.HasRiverThroughEdge(direction));
    }
예제 #23
0
    bool IsBuildable()
    {
        if (nowCell)
        {
            if (!nowCell.GetNeighbor(dir).IsBuildable())
            {
                return(false);
            }
            if (sizeType != null)
            {
                switch (sizeType)
                {
                case SizeType.HEX:
                    TriCell      k    = nowCell;
                    int          elev = nowCell.Elevation;
                    TriDirection tDir = dir.Previous();
                    for (int i = 0; i < 6; i++)
                    {
                        if (!k || !k.IsBuildable())
                        {
                            return(false);
                        }
                        k    = k.GetNeighbor(tDir);
                        tDir = tDir.Next();
                    }
                    return(true);

                case SizeType.SINGLE:
                    return(nowCell.IsBuildable());

                default:
                    return(false);
                }
            }
            return(true);
        }
        else
        {
            return(false);
        }
    }
예제 #24
0
    public Building CreateBuilding(TriDirection dir, TriCell cell, Building prefab)
    {
        if (cell && Entity.IsBuildable(dir, cell.coordinates, prefab.sizeType))
        {
            Building ret = Instantiate(prefab);
            ret.ID       = entities.BuildingCount;
            ret.Location = cell;
            switch (ret.sizeType)
            {
            case SizeType.SINGLE:
                cell.Statics = ret;
                break;

            case SizeType.HEX:
                TriCell      k    = cell;
                TriDirection tDir = dir.Previous();
                for (int i = 0; i < 6; i++)
                {
                    if (!k)
                    {
                        break;
                    }
                    k.Statics = ret;
                    k         = k.GetNeighbor(tDir);
                    tDir      = tDir.Next();
                }
                break;
            }
            ret.EntranceDirection = dir;
            ret.personList        = personList;
            entities.AddBuilding(ret);
            Debug.Log("camp built");
            return(ret);
        }
        else
        {
            Debug.Log("building failed");
            return(null);
        }
    }
예제 #25
0
    public override List <BuildState> GetBuildStatus(TriCoordinates coord, TriDirection dir)
    {
        List <BuildState> ret = new List <BuildState>();
        TriCell           k   = TriGrid.Instance.GetCell(coord);
        int          elev     = k.Elevation;
        TriDirection tDir     = dir.Previous();

        for (int i = 0; i < 6; i++)
        {
            if (!k)
            {
                break;
            }
            ret.Add(new BuildState(k.coordinates, k.IsBuildable() && elev == k.Elevation));
            k    = k.GetNeighbor(tDir);
            tDir = tDir.Next();
        }
        TriCell entrance = TriGrid.Instance.GetCell(coord).GetNeighbor(dir);

        ret.Add(new BuildState(entrance.coordinates, entrance.IsBuildable() && Mathf.Abs(entrance.GetNeighbor(dir).Elevation - elev) < 2));
        return(ret);
    }
예제 #26
0
    public static bool IsBuildable(TriDirection dir, TriCoordinates coord, SizeType sizeType)
    {
        switch (sizeType)
        {
        case SizeType.SINGLE:
            if (TriGrid.Instance.GetCell(coord).Statics)
            {
                return(false);
            }
            else
            {
                return(true);
            }

        case SizeType.HEX:
            TriCell      cell      = TriGrid.Instance.GetCell(coord);
            int          elevation = cell.Elevation;
            TriCell      k         = cell;
            int          elev      = cell.Elevation;
            TriDirection tDir      = dir.Previous();
            for (int i = 0; i < 6; i++)
            {
                if (!k || !k.IsBuildable())
                {
                    return(false);
                }
                if (elev != k.Elevation)
                {
                    return(false);
                }
                k    = k.GetNeighbor(tDir);
                tDir = tDir.Next();
            }
            return(true);

        default:
            return(false);
        }
    }
예제 #27
0
 public override void OnBuilt()
 {
     base.OnBuilt();
     if (workType == TerrainModdingType.LANDFILL)
     {
         TriCell k = Location;
         for (int j = 0; j < 3; j++)
         {
             TriDirection tDir = (TriDirection)j;
             for (int i = 0; i < 6; i++)
             {
                 k.Elevation = k.Elevation < 1 ? 1 : k.Elevation;
                 k           = k.GetNeighbor(tDir);
                 tDir        = tDir.Next();
             }
         }
     }
     else
     {
         location.Elevation += (int)workType;
     }
     SelfWorking = true;
     DeconstructionStart(null);
 }
예제 #28
0
    public void CalculateTerrain()
    {
        Clear();

        if (selector.nowCell)
        {
            TriCell neighbor = selector.nowCell.GetNeighbor(selector.dir);
            if (neighbor)
            {
                RecalculateTerrain(neighbor, neighbor.IsBuildable() && neighbor.Elevation <= selector.nowCell.Elevation + 1 && neighbor.Elevation >= selector.nowCell.Elevation - 1);
            }
            switch (selector.sizeType)
            {
            case SizeType.HEX:
                k = selector.nowCell;
                int          elev = selector.nowCell.Elevation;
                TriDirection tDir = selector.dir.Previous();
                for (int i = 0; i < 6; i++)
                {
                    if (!k)
                    {
                        break;
                    }
                    RecalculateTerrain(k, k.IsBuildable() && k.Elevation == elev);
                    k    = k.GetNeighbor(tDir);
                    tDir = tDir.Next();
                }
                break;

            case SizeType.SINGLE:
                RecalculateTerrain(selector.nowCell, selector.nowCell.IsBuildable());
                break;
            }
        }
        Apply();
    }
예제 #29
0
    void EditHex(TriCell cell)
    {
        TriCell      k        = cell;
        bool         inverted = cell.inverted;
        TriDirection d        = TriDirection.VERT;

        for (int i = 0; i < 6; i++)
        {
            if (!k)
            {
                break;
            }
            EditCell(k);
            k = k.GetNeighbor(d);
            if (inverted)
            {
                d = d.Next();
            }
            else
            {
                d = d.Previous();
            }
        }
    }
예제 #30
0
    void TriangulateWithRiver(TriCell cell, TriDirection direction, Vector3 center, EdgeVertices edge, Color color)
    {
        Vector3 riverOffset = new Vector3(0, TriMetrics.streamBedElevationOffset - TriMetrics.waterElevationOffset, 0);
        Vector3 nextCorner, prevCorner;

        nextCorner = (center + edge.v1) / 2f;
        prevCorner = (center + edge.v5) / 2f;
        Vector3 underCenter = center, underNextCorner = nextCorner, underPrevCorner = prevCorner;

        underCenter.y     += TriMetrics.streamBedElevationOffset;
        underNextCorner.y += TriMetrics.streamBedElevationOffset;
        underPrevCorner.y += TriMetrics.streamBedElevationOffset;

        EdgeVertices underEdge = edge;

        underEdge.v1.y += TriMetrics.streamBedElevationOffset;
        underEdge.v2.y += TriMetrics.streamBedElevationOffset;
        underEdge.v3.y += TriMetrics.streamBedElevationOffset;
        underEdge.v4.y += TriMetrics.streamBedElevationOffset;
        underEdge.v5.y += TriMetrics.streamBedElevationOffset;

        terrain.AddTriangle(nextCorner, edge.v1, edge.v2);
        terrain.AddTriangle(prevCorner, edge.v4, edge.v5);
        terrain.AddTriangle(underCenter, underEdge.v2, underEdge.v4);
        terrain.AddTriangleColor(color);
        terrain.AddTriangleColor(color);
        terrain.AddTriangleColor(color);

        if (!cell.IsUnderwater)
        {
            rivers.AddTriangle(underCenter - riverOffset, underEdge.v2 - riverOffset, underEdge.v4 - riverOffset);
            rivers.AddTriangleColor(Color.blue);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            terrain.AddTriangle(underEdge.v4, underPrevCorner, underCenter);
            terrain.AddTriangleColor(color);
            if (!cell.IsUnderwater)
            {
                rivers.AddTriangle(underEdge.v4 - riverOffset, underPrevCorner - riverOffset, underCenter - riverOffset);
                rivers.AddTriangleColor(Color.blue);
            }

            terrain.AddQuad(underPrevCorner, prevCorner, underEdge.v4, edge.v4);
            terrain.AddQuadColor(color, color);
        }
        else
        {
            terrain.AddTriangle(center, edge.v4, prevCorner);
            terrain.AddQuad(underCenter, center, underEdge.v4, edge.v4);
            terrain.AddTriangleColor(color);
            terrain.AddQuadColor(color, color);
        }
        if (cell.HasRiverThroughEdge(direction.Previous()))
        {
            terrain.AddTriangle(underEdge.v2, underCenter, underNextCorner);
            terrain.AddTriangleColor(color);

            if (!cell.IsUnderwater)
            {
                rivers.AddTriangle(underEdge.v2 - riverOffset, underCenter - riverOffset, underNextCorner - riverOffset);
                rivers.AddTriangleColor(Color.blue);
            }
            terrain.AddQuad(underEdge.v2, edge.v2, underNextCorner, nextCorner);
            terrain.AddQuadColor(color, color);
        }
        else
        {
            terrain.AddTriangle(center, nextCorner, edge.v2);
            terrain.AddQuad(underEdge.v2, edge.v2, underCenter, center);
            terrain.AddTriangleColor(color);
            terrain.AddQuadColor(color, color);
        }
    }