Esempio n. 1
0
 public void AddLiquid(Tile tile, Tile.SubType type)
 {
     tile.ChangeTileType(Tile.TileType.Liquid, type);
     tile.CurrentVolume = 0;
     tile.NewVolume     = 1;
     tile.SaveVolume(_terrainGen, this);
 }
Esempio n. 2
0
    void SimulateLiquids()
    {
        if (LiquidTiles.Count == 0)
        {
            return;
        }

        var dictToList = LiquidTiles.Values.ToList();

        for (int i = 0; i < dictToList.Count; i++)
        {
            Tile liquid = dictToList[i];

            if (!VolumeChanged(liquid.CurrentVolume, liquid.NewVolume))
            {
                if (liquid.NoChangeCounter > 99)
                {
                    liquid.Settled = true;
                }
                else
                {
                    liquid.NoChangeCounter++;
                }
            }
            else
            {
                liquid.NoChangeCounter = 0;
                liquid.Settled         = false;
            }

            if (liquid.Settled)
            {
                continue;
            }

            float flow          = 0;
            float remainingmass = liquid.CurrentVolume;
            if (remainingmass <= 0)
            {
                continue;
            }

            //Below
            //tilePos.Set(liquid.GridPos.x, liquid.GridPos.y - 1);
            Tile downneighbour = _terrainGen.GetNeighbourTile(liquid, TerrainGenerator.Direction.Down);
            if (downneighbour == null)
            {
                continue;
            }

            if (downneighbour.TType != Tile.TileType.Solid)
            {
                if (liquid.NoChangeCounter == 0)
                {
                    downneighbour.NoChangeCounter = 0;
                    downneighbour.Settled         = false;
                }

                ////Stop different liquids from interacting?
                //if (downneighbour.TType == Tile.TileType.Liquid && downneighbour.SType != liquid.SType) continue;
                flow = getstable(remainingmass + downneighbour.CurrentVolume) - downneighbour.CurrentVolume;
                if (flow > minflow)
                {
                    flow *= 0.5f;
                }

                flow = Mathf.Clamp(flow, 0, Math.Min(maxspeed, remainingmass));

                //if (flow == 0) { noflowcount++; } else { downneighbour.Settled = false; }

                liquid.NewVolume        -= flow;
                downneighbour.NewVolume += flow;
                remainingmass           -= flow;

                if (!_liquidToCheck.ContainsKey(downneighbour.HashKey))
                {
                    _liquidToCheck.Add(downneighbour.HashKey, downneighbour);
                }
            }

            if (remainingmass <= 0)
            {
                continue;
            }

            //Left

            //tilePos.Set(liquid.GridPos.x - 1, liquid.GridPos.y);
            Tile leftneighbour = _terrainGen.GetNeighbourTile(liquid, TerrainGenerator.Direction.Left);
            if (leftneighbour == null)
            {
                continue;
            }

            if (leftneighbour.TType != Tile.TileType.Solid)
            {
                if (liquid.NoChangeCounter == 0)
                {
                    leftneighbour.NoChangeCounter = 0;
                    leftneighbour.Settled         = false;
                }
                ////Stop different liquids from interacting?
                //if (leftneighbour.TType == Tile.TileType.Liquid && leftneighbour.SType != liquid.SType) continue;

                flow = (liquid.CurrentVolume - leftneighbour.CurrentVolume) / 4;
                if (flow > minflow)
                {
                    flow *= 0.5f;
                }
                flow = Mathf.Clamp(flow, 0, remainingmass);

                //if (flow == 0) { noflowcount++; } else { leftneighbour.Settled = false; }

                liquid.NewVolume        -= flow;
                leftneighbour.NewVolume += flow;
                remainingmass           -= flow;

                if (!_liquidToCheck.ContainsKey(leftneighbour.HashKey))
                {
                    _liquidToCheck.Add(leftneighbour.HashKey, leftneighbour);
                }
            }

            if (remainingmass <= 0)
            {
                continue;
            }

            //Right
            //tilePos.Set(liquid.GridPos.x + 1, liquid.GridPos.y);
            Tile rightneighbour = _terrainGen.GetNeighbourTile(liquid, TerrainGenerator.Direction.Right);
            if (rightneighbour == null)
            {
                continue;
            }

            if (rightneighbour.TType != Tile.TileType.Solid)
            {
                if (liquid.NoChangeCounter == 0)
                {
                    rightneighbour.NoChangeCounter = 0;
                    rightneighbour.Settled         = false;
                }
                ////Stop different liquids from interacting?
                //if (rightneighbour.TType == Tile.TileType.Liquid && rightneighbour.SType != liquid.SType) continue;
                flow = (liquid.CurrentVolume - rightneighbour.CurrentVolume) / 4;
                if (flow > minflow)
                {
                    flow *= 0.5f;
                }
                flow = Mathf.Clamp(flow, 0, remainingmass);

                //if (flow == 0) { noflowcount++; } else { leftneighbour.Settled = false; }

                liquid.NewVolume         -= flow;
                rightneighbour.NewVolume += flow;
                remainingmass            -= flow;

                if (!_liquidToCheck.ContainsKey(rightneighbour.HashKey))
                {
                    _liquidToCheck.Add(rightneighbour.HashKey, rightneighbour);
                }
            }

            if (remainingmass <= 0)
            {
                continue;
            }

            //tilePos.Set(liquid.GridPos.x, liquid.GridPos.y + 1);
            Tile upneighbour = _terrainGen.GetNeighbourTile(liquid, TerrainGenerator.Direction.Up);
            if (upneighbour == null)
            {
                continue;
            }

            if (upneighbour.TType != Tile.TileType.Solid)
            {
                if (liquid.NoChangeCounter == 0)
                {
                    upneighbour.NoChangeCounter = 0;
                    upneighbour.Settled         = false;
                }
                ////Stop different liquids from interacting?
                //if (upneighbour.TType == Tile.TileType.Liquid && upneighbour.SType != liquid.SType) continue;

                flow = remainingmass - getstable(remainingmass + upneighbour.CurrentVolume);

                if (flow > minflow)
                {
                    flow *= 0.5f;
                }
                flow = Mathf.Clamp(flow, 0, Math.Min(maxspeed, remainingmass));

                //if (flow == 0) { noflowcount++; } else { leftneighbour.Settled = false; }

                liquid.NewVolume      -= flow;
                upneighbour.NewVolume += flow;
                remainingmass         -= flow;

                if (!_liquidToCheck.ContainsKey(upneighbour.HashKey))
                {
                    _liquidToCheck.Add(upneighbour.HashKey, upneighbour);
                }
            }
        }

        dictToList = _liquidToCheck.Values.ToList();
        for (int i = 0; i < dictToList.Count; i++)
        {
            Tile liquid = dictToList[i];

            if (liquid.Settled)
            {
                continue;
            }

            if (liquid.NewVolume > Minmass)
            {
                liquid.ChangeTileType(Tile.TileType.Liquid, Tile.SubType.Water);
                liquid.SaveVolume(_terrainGen, this);
            }
            else
            {
                liquid.ChangeTileType(Tile.TileType.Air, Tile.SubType.Air);
                LiquidTiles.Remove(liquid.HashKey);
                liquid.SaveVolume(_terrainGen, this);
            }
        }

        _liquidToCheck.Clear();

        dictToList = LiquidTiles.Values.ToList();
        for (int i = 0; i < dictToList.Count; i++)
        {
            Tile liquid = dictToList[i];

            if (liquid.Settled)
            {
                continue;
            }

            liquid.CurrentVolume = liquid.NewVolume;
            if (liquid.CurrentVolume > Minmass)
            {
                if (i != 0)
                {
                    liquidTypeSimulated = dictToList[i - 1].SType;
                }
                else
                {
                    liquidTypeSimulated = liquid.SType;
                }
                liquid.ChangeTileType(Tile.TileType.Liquid, Tile.SubType.Water);
                liquid.SaveVolume(_terrainGen, this);
            }
            else
            {
                liquid.ChangeTileType(Tile.TileType.Air, Tile.SubType.Air);
                _toRemove.Add(liquid);
                liquid.SaveVolume(_terrainGen, this);
            }
        }
        for (int i = 0; i < _toRemove.Count; i++)
        {
            LiquidTiles.Remove(_toRemove[i].HashKey);
        }

        _toRemove.Clear();
    }