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