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(); }