示例#1
0
            private bool RemoveTop(FluidLine fluidLine, int flowingToXPosition)
            {
                if (fluidLine.GetFlowCapacity(UpdateID) == 0)
                {
                    return(false);
                }

                List <Stack <FluidLine> > topCandidates = new List <Stack <FluidLine> >();
                List <Stack <FluidLine> > activeFluidLineStacks;
                List <Stack <FluidLine> > newActiveFluidLineStacks = new List <Stack <FluidLine> >();

                Stack <FluidLine> fluidLineStack = new Stack <FluidLine>();

                fluidLineStack.Push(fluidLine);
                newActiveFluidLineStacks.Add(fluidLineStack);

                // find all topLevel FluidLines = all lines with no lines above them and connected
                while (newActiveFluidLineStacks.Count > 0)
                {
                    topCandidates.Clear();

                    activeFluidLineStacks    = newActiveFluidLineStacks;
                    newActiveFluidLineStacks = new List <Stack <FluidLine> >();

                    for (int i = 0; i < activeFluidLineStacks.Count; i++)
                    {
                        // is this the top line?
                        if (activeFluidLineStacks[i].Peek().GetAboveLinesCount() == 0)
                        {
                            topCandidates.Add(activeFluidLineStacks[i]);
                        }
                        else
                        {
                            bool noCapacity = true;
                            // have all lines above already reached max capacity
                            foreach (FluidLine aboveLine in activeFluidLineStacks[i].Peek().GetAboveLines())
                            {
                                if (aboveLine.GetFlowCapacity(UpdateID) > 0)
                                {
                                    noCapacity = false;
                                    break;
                                }
                            }

                            if (noCapacity)
                            {
                                topCandidates.Add(activeFluidLineStacks[i]);
                            }
                            else
                            {
                                foreach (FluidLine aboveLine in activeFluidLineStacks[i].Peek().GetAboveLines())
                                {
                                    if (aboveLine.GetFlowCapacity(UpdateID) > 0)
                                    {
                                        fluidLineStack = activeFluidLineStacks[i].Clone();
                                        fluidLineStack.Push(aboveLine);
                                        newActiveFluidLineStacks.Add(fluidLineStack);
                                    }
                                }
                            }
                        }
                    }
                }

                // no topCandidate found
                if (topCandidates.Count == 0)
                {
                    return(false);
                }

                // find the nearest top level FluidLine
                int minimalDistance = int.MaxValue;
                int currentDistance;
                int nearestFluidLineStackIndex = -1;

                for (int i = 0; i < topCandidates.Count; i++)
                {
                    currentDistance = Mathf.Abs(topCandidates[i].Peek().x - flowingToXPosition);
                    if (currentDistance < minimalDistance)
                    {
                        nearestFluidLineStackIndex = i;
                        minimalDistance            = currentDistance;
                    }

                    currentDistance = Mathf.Abs(topCandidates[i].Peek().x + topCandidates[i].Peek().length - 1 - flowingToXPosition);
                    if (currentDistance < minimalDistance)
                    {
                        nearestFluidLineStackIndex = i;
                        minimalDistance            = currentDistance;
                    }
                }

                // remove a drop from the chosen top level FluidLine and adjust
                // the remaining FlowCapacity of all participating FluidLines
                if (RemoveDrop(topCandidates[nearestFluidLineStackIndex].Pop(), flowingToXPosition))
                {
                    foreach (FluidLine flowPathFluidLine in topCandidates[nearestFluidLineStackIndex])
                    {
                        flowPathFluidLine.DecrementCapacity(UpdateID);
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }