示例#1
0
            public void DeleteFluidLine(FluidLine fluidLine)
            {
                List <FluidLine> fluidLineList;

                if (fluidLines.TryGetValue(fluidLine.y, out fluidLineList))
                {
                    foreach (FluidLine belowFluidLine in fluidLine.GetBelowLines())
                    {
                        belowFluidLine.RemoveAboveLine(fluidLine);
                    }

                    foreach (FluidLine aboveFluidLine in fluidLine.GetAboveLines())
                    {
                        aboveFluidLine.RemoveBelowLine(fluidLine);
                    }

                    if (!fluidLineList.Remove(fluidLine))
                    {
                        Debug.Log("[ERROR]DeleteFluidLine(): Couldnt find FluidLineList to remove from.");
                        Debug.Log("FluidLine = " + fluidLine.ToString());
                    }
                }

                activeLines.Remove(fluidLine);

                if (!fluidLine.JustCreated(UpdateID))
                {
                    deletedLines.Add(fluidLine);
                }
            }
示例#2
0
            private bool RemoveDropAtPosition(FluidLine fluidLine, int removePosition)
            {
                if (fluidLine.length <= 0)
                {
                    Debug.Log("[ERROR] Can't remove from an empty FluidLine.");
                    return(false);
                }

                if (fluidLine.length == 1)
                {
                    // nothing to do
                    DeleteFluidLine(fluidLine);
                    return(true);
                }

                if (removePosition >= 0 && removePosition < fluidLine.length)
                {
                    if (removePosition == 0)
                    {
                        // remove left
                        fluidLine.RemoveDropLeft();
                        return(true);
                    }
                    else if (removePosition == fluidLine.length - 1)
                    {
                        // remove right
                        fluidLine.RemoveDropRight();
                        return(true);
                    }
                    else
                    {
                        // remove in the middle. The two lines left and right exist
                        // because we arent removing the left or right end.

                        FluidLine rightFluidLine = fluidLine.Split(removePosition, UpdateID);
                        RegisterFluidLine(rightFluidLine);
                        if (rightFluidLine.length == 0)
                        {
                            Debug.Log("Adding empty FluidLine: " + rightFluidLine.ToString());
                        }
                        activeLines.Add(rightFluidLine);

                        return(true);
                    }
                }
                else
                {
                    Debug.Log("[ERROR] Remove position not inside the fluidLine.");
                    return(false);
                }
            }
示例#3
0
            public void FreeFluidLine(FluidLine fluidLine)
            {
                int index;

                //Debug.Log ("[DEBUG] Deleting Path of FluidLine = " + fluidLine.ToString ());

                if (fluidLineToPathIndexDictionary.TryGetValue(fluidLine, out index))
                {
                    // the path with index 0 always needs a non empty path or the PolygonCollider2D wont show
                    // -> submit feature request to unity
                    if (index == 0)
                    {
                        // find the first index that doesnt have an empty path
                        int replacementIndex = -1;
                        for (int i = 1; i < cachedPolygonCollider2D.pathCount; i++)
                        {
                            if (!freeIndices.Contains(i))
                            {
                                replacementIndex = i;
                                break;
                            }
                        }

                        bool replacemenetSuccessful = false;

                        if (replacementIndex > 0)
                        {
                            // find the corresponding FluidLine
                            FluidLine replacementFluidLine = null;
                            foreach (KeyValuePair <FluidLine, int> keyValuePair in fluidLineToPathIndexDictionary)
                            {
                                if (keyValuePair.Value == replacementIndex)
                                {
                                    replacementFluidLine = keyValuePair.Key;
                                    break;
                                }
                            }

                            if (replacementFluidLine != null)
                            {
                                cachedPolygonCollider2D.SetPath(0, cachedPolygonCollider2D.GetPath(replacementIndex));
                                cachedPolygonCollider2D.SetPath(replacementIndex, null);

                                // remove the fluidLine from the dictionary
                                fluidLineToPathIndexDictionary.Remove(fluidLine);
                                // free the replacement index
                                freeIndices.Add(replacementIndex);
                                // remove the replacementFluidLine from its old position
                                fluidLineToPathIndexDictionary.Remove(replacementFluidLine);
                                // insert it with index 0
                                fluidLineToPathIndexDictionary.Add(replacementFluidLine, 0);

                                replacemenetSuccessful = true;
                            }
                        }

                        if (!replacemenetSuccessful)
                        {
                            // no other FluidLine to replace Left means there are no more FluidLines in this FluidPart
                            fluidLineToPathIndexDictionary.Clear();
                            freeIndices.Clear();
                            this.pathCount = 0;
                            cachedPolygonCollider2D.pathCount = pathCount;
                        }
                    }
                    else
                    {
                        freeIndices.Add(index);
                        fluidLineToPathIndexDictionary.Remove(fluidLine);
                        cachedPolygonCollider2D.SetPath(index, null);
                    }
                }
                else
                {
                    Debug.Log("Deleted FluidLine didnt have a collider. Check for bug or explanation! FluidLine = " + fluidLine.ToString());
                }
            }
示例#4
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();
            }