示例#1
0
            public void UpdateFluid()      //Fluid fluid)
            {
                int       flowX;           // the x value of the current fluidLine. This can change during flowingUpdate
                int       flowY;
                int       lineLength;
                bool      containsWater;
                FluidLine fluidLeft;
                FluidLine fluidRight;

                deletedLines.Clear();

                // check all active Lines
                foreach (FluidLine activeLine in activeLines)
                {
                    //Debug.Log ("Current Line = " + activeLine.ToString ());
                    //Debug.Log ("Active Lines = " + activeLines.ToString());

                    processedLine = activeLine;

                    /*Debug.DrawLine (new Vector3(((float)(processedLine.x) + 0.5f) * DataManager.instance.BlockSize,
                     *                          ((float)(processedLine.y) + 0.5f) * DataManager.instance.BlockSize,
                     *                          -2f),
                     *              new Vector3(((float)(processedLine.x + processedLine.length) + 0.5f) * DataManager.instance.BlockSize,
                     *          ((float)(processedLine.y) + 0.5f) * DataManager.instance.BlockSize,
                     *          -2f),
                     *              Color.red,
                     *              0.5f);
                     *
                     * fluid.ShowFluidUpdate(GetFluidLines (), GetDeletedFluidLines ());
                     * yield return new WaitForSeconds(0.2f);*/

                    if (processedLine.length == 0)
                    {
                        Debug.Log("Empty line detected " + processedLine.ToString());
                    }

                    // if the fluid has flown outside the map area
                    if (!TerrainManager.instance.InsideMap((float)(processedLine.x) * DataManager.instance.BlockSize, (float)(processedLine.y) * DataManager.instance.BlockSize) &&
                        !TerrainManager.instance.InsideMap((float)(processedLine.x + processedLine.length - 1) * DataManager.instance.BlockSize, (float)(processedLine.y) * DataManager.instance.BlockSize))
                    {
                        DeleteFluidLine(processedLine);
                        break;
                    }

                    // first check if the fluid can flow down
                    flowY = processedLine.y - 1;


                    // get the lines that might get changed below this fluidLine
                    List <FluidLine> allBelowFluidLines;
                    List <FluidLine> canFlowToFluidLines = new List <FluidLine>();
                    if (fluidLines.TryGetValue(flowY, out allBelowFluidLines))
                    {
                        foreach (FluidLine belowFluidLine in allBelowFluidLines)
                        {
                            if (processedLine.CanFlowTo(belowFluidLine))
                            {
                                canFlowToFluidLines.Add(belowFluidLine);
                            }
                        }
                    }

                    flowX      = processedLine.x;
                    lineLength = processedLine.length;

                    // Check all blocks underneath if the fluid can flow there
                    for (int j = 0; j < lineLength; j++)
                    {
                        if (TerrainManager.instance.GetBlock(((float)(flowX + j) + 0.5f) * DataManager.instance.BlockSize,
                                                             ((float)(flowY) + 0.5f) * DataManager.instance.BlockSize).Passable())
                        {
                            containsWater = false;
                            fluidLeft     = null;
                            fluidRight    = null;

                            // check all fluidLines to which this line can flow to,
                            // whether this block actually contains or is next to fluid
                            foreach (FluidLine fluidLine in canFlowToFluidLines)
                            {
                                if (fluidLine.Contains(flowX + j))
                                {
                                    containsWater = true;
                                    int waterAmount = 1;
                                    while (fluidLine.Contains(flowX + j + waterAmount) && (j + waterAmount - 1) < lineLength)
                                    {
                                        waterAmount++;
                                    }
                                    j += waterAmount - 1;
                                    break;
                                }
                                else if (fluidLine.Contains(flowX + j - 1))
                                {
                                    fluidLeft = fluidLine;
                                }
                                else if (fluidLine.Contains(flowX + j + 1))
                                {
                                    fluidRight = fluidLine;
                                }
                            }

                            if (!containsWater)
                            {
                                if (RemoveTop(processedLine, flowX + j))
                                {
                                    // Fill Block with water
                                    if (fluidLeft != null)
                                    {
                                        fluidLeft.AddRight(1, this);

                                        if (fluidRight != null)
                                        {
                                            if (fluidLeft.AddRight(fluidRight))
                                            {
                                                canFlowToFluidLines.Remove(fluidRight);
                                                DeleteFluidLine(fluidRight);
                                            }
                                            else
                                            {
                                                Debug.Log("[ERROR]Couldnt combine fluidLines!");
                                            }
                                        }
                                    }
                                    else if (fluidRight != null)
                                    {
                                        fluidRight.AddLeft(1, this);
                                    }
                                    else
                                    {
                                        FluidLine newFluidLine = CreateFluidLine(flowX + j, flowY, 1);
                                        canFlowToFluidLines.Add(newFluidLine);
                                        activeLines.Add(newFluidLine);
                                    }
                                }
                            }
                        }
                    }

                    // we are now looking on the same level on the left and right side instead of the level below
                    flowY = processedLine.y;

                    bool canFlowSideways = false;

                    // check if we can still flow sideways
                    if (processedLine.length > 0)
                    {
                        int capacityAbove = 0;

                        foreach (FluidLine aboveLine in processedLine.GetAboveLines())
                        {
                            capacityAbove += aboveLine.GetFlowCapacity(UpdateID);
                        }

                        if (capacityAbove > 0)
                        {
                            canFlowSideways = true;
                        }
                    }

                    if (canFlowSideways)
                    {
                        List <FluidLine> possibleNeighbours;
                        bool             leftContainsWater  = false;
                        bool             rightContainsWater = false;
                        FluidLine        leftNeighbour      = null;

                        if (fluidLines.TryGetValue(flowY, out possibleNeighbours))
                        {
                            foreach (FluidLine possibleNeighbour in possibleNeighbours)
                            {
                                if (leftNeighbour == null)
                                {
                                    // is there a fluidline with which this line needs to combine, if it flows left
                                    if (possibleNeighbour.x + possibleNeighbour.length == processedLine.x - 1)
                                    {
                                        leftNeighbour = possibleNeighbour;
                                    }
                                }

                                if (possibleNeighbour.Contains(processedLine.x - 1))
                                {
                                    leftContainsWater = true;
                                    leftNeighbour     = possibleNeighbour;
                                }

                                if (possibleNeighbour.Contains(processedLine.x + processedLine.length))
                                {
                                    rightContainsWater = true;
                                }
                            }
                        }
                        else
                        {
                            Debug.Log("[ERROR] Couldnt even find my own FluidLine.");
                        }

                        // check left side
                        if (leftContainsWater)
                        {
                            if (processedLine.AddLeft(leftNeighbour))
                            {
                                DeleteFluidLine(leftNeighbour);
                            }
                            else
                            {
                                Debug.Log("[ERROR]There are two lines directly next to each other, but combining them failed! Maybe check for overlap?");
                            }
                        }
                        else if (TerrainManager.instance.GetBlock(((float)(processedLine.x - 1) + 0.5f) * DataManager.instance.BlockSize,
                                                                  ((float)(flowY) + 0.5f) * DataManager.instance.BlockSize).Passable())
                        {
                            if (RemoveTop(processedLine, processedLine.x - 1))
                            {
                                // Fill Block with water
                                processedLine.AddLeft(1, this);

                                // combine with left FluidLine if there is one
                                if (leftNeighbour != null)
                                {
                                    if (processedLine.AddLeft(leftNeighbour))
                                    {
                                        DeleteFluidLine(leftNeighbour);
                                    }
                                    else
                                    {
                                        Debug.Log("[ERROR]There are two lines directly next to each other, but combining them failed! Maybe check for overlap?");
                                    }
                                }
                            }
                        }

                        // if the right side contains water, this line will be added to the rightNeighbour when its processed
                        if (!rightContainsWater)
                        {
                            bool canFlowRight = false;

                            // check if we can still flow to the right
                            if (processedLine.length > 0)
                            {
                                int capacityAbove = 0;

                                foreach (FluidLine aboveLine in processedLine.GetAboveLines())
                                {
                                    capacityAbove += aboveLine.GetFlowCapacity(UpdateID);
                                }

                                if (capacityAbove > 0)
                                {
                                    canFlowRight = true;
                                }
                            }

                            // still water above us?
                            if (canFlowRight)
                            {
                                if (TerrainManager.instance.GetBlock(((float)(processedLine.x + processedLine.length) + 0.5f) * DataManager.instance.BlockSize,
                                                                     ((float)(flowY) + 0.5f) * DataManager.instance.BlockSize).Passable())
                                {
                                    if (RemoveTop(processedLine, processedLine.x + processedLine.length))
                                    {
                                        // Fill Block with water
                                        processedLine.AddRight(1, this);
                                    }
                                }
                            }
                        }
                    }
                }

                IncrementUpdateID();
            }