public override IEnumerator spawnTiles() { _isCRSpawnTileRunning = true; _curYLevel = ( int )_thisTransform.position.y; _amountOfLineToBeCreated = TRAPHEIGHT; for (int line = 1; line <= _amountOfLineToBeCreated; line++) { _curWaterLine = spawnWaterLine(_curYLevel); while (_curWaterLine.curLevel < 3) { _timeBetweenLevelsCD = timeBetweenLevels; while (_timeBetweenLevelsCD > 0) { _timeBetweenLevelsCD -= Time.deltaTime; yield return(null); } updateWaterLevels(_curWaterLine); yield return(null); if (line == _amountOfLineToBeCreated && _curWaterLine.curLevel == 2) { break; } } _curYLevel++; } doneTrap(); _isCRSpawnTileRunning = false; }
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); } }
public static FluidLine NearestFluidLineTo(this IEnumerable <FluidLine> fluidLines, int xPosition) { if (fluidLines == null) { return(null); } else { FluidLine nearestFluidLine = null; int minimalDistance = int.MaxValue; int currentDistance; foreach (FluidLine fluidLine in fluidLines) { currentDistance = Mathf.Abs(fluidLine.x - xPosition); if (currentDistance < minimalDistance) { nearestFluidLine = fluidLine; minimalDistance = currentDistance; } currentDistance = Mathf.Abs(fluidLine.x + fluidLine.length - 1 - xPosition); if (currentDistance < minimalDistance) { nearestFluidLine = fluidLine; minimalDistance = currentDistance; } } return(nearestFluidLine); } }
public void UpdateFluidLineCollider(FluidLine fluidLine) { int index; //Debug.Log ("[DEBUG] Updating Collider of fluidLine = " + fluidLine.ToString ()); // does the fluidLine already has a collider? if (fluidLineToPathIndexDictionary.TryGetValue(fluidLine, out index)) { cachedPolygonCollider2D.SetPath(index, FluidLineToPath(fluidLine)); } else { if (freeIndices.Count > 0) { index = freeIndices[0]; freeIndices.RemoveAt(0); cachedPolygonCollider2D.SetPath(index, FluidLineToPath(fluidLine)); fluidLineToPathIndexDictionary.Add(fluidLine, index); } else { pathCount++; cachedPolygonCollider2D.pathCount = pathCount; cachedPolygonCollider2D.SetPath(pathCount - 1, FluidLineToPath(fluidLine)); fluidLineToPathIndexDictionary.Add(fluidLine, pathCount - 1); } } }
private FluidLine CreateFluidLine(int x, int y, int length) { FluidLine fluidLine = new FluidLine(x, y, length, UpdateID); RegisterFluidLine(fluidLine); return(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); } }
private Vector2[] FluidLineToPath(FluidLine fluidLine) { Vector2[] path = new Vector2[4]; float xf = (float)fluidLine.x * blockSize - cachedTransform.position.x; float yf = (float)fluidLine.y * blockSize - cachedTransform.position.y; float widthf = (float)fluidLine.length * blockSize; path[0] = new Vector2(xf, yf); path[1] = new Vector2(xf, yf + blockSize); path[2] = new Vector2(xf + widthf, yf + blockSize); path[3] = new Vector2(xf + widthf, yf); return(path); }
FluidLine spawnWaterLine(float yPos) { FluidLine waterLine = new FluidLine(-1); for (int x = ( int )_thisTransform.position.x; x < _thisTransform.position.x + TRAPWIDTH; x++) { GameObject newWater = new GameObject("water"); addDieCollider(newWater); newWater.transform.parent = _thisTransform; _childs.Add(newWater.transform); newWater.transform.position = new Vector3(x, yPos); SpriteRenderer sprite = newWater.AddComponent <SpriteRenderer>(); sprite.sortingOrder = 6; sprite.sharedMaterial = TrapsManager.Instance.trapsMaterial; waterLine.fluidSpots.Add(sprite); } updateWaterLevels(waterLine); return(waterLine); }
private FluidPart GetFluidPart(FluidLine fluidLine) { FluidPart fluidPart; if (fluidPartsByLines.TryGetValue(fluidLine, out fluidPart)) { return(fluidPart); } else { float xf = (float)fluidLine.x * blockSize; float yf = (float)fluidLine.y * blockSize; fluidPart = GetFluidPart(xf, yf); fluidPartsByLines.Add(fluidLine, fluidPart); return(fluidPart); } }
private void RegisterFluidLine(FluidLine fluidLine) { List <FluidLine> fluidLineList; // add the new FluidLine into the SortedDictionary of all FluidLines if (fluidLines.TryGetValue(fluidLine.y, out fluidLineList)) { fluidLineList.Add(fluidLine); } else { fluidLineList = new List <FluidLine>(); fluidLineList.Add(fluidLine); fluidLines.Add(fluidLine.y, fluidLineList); } // connect to above FluidLines if (fluidLines.TryGetValue(fluidLine.y + 1, out fluidLineList)) { foreach (FluidLine aboveFluidLine in fluidLineList) { if (fluidLine.VerticallyConnectedTo(aboveFluidLine)) { fluidLine.AddAboveLine(aboveFluidLine); aboveFluidLine.AddBelowLine(fluidLine); } } } // connect to below FluidLines if (fluidLines.TryGetValue(fluidLine.y - 1, out fluidLineList)) { foreach (FluidLine belowFluidLine in fluidLineList) { if (fluidLine.VerticallyConnectedTo(belowFluidLine)) { fluidLine.AddBelowLine(belowFluidLine); belowFluidLine.AddAboveLine(fluidLine); } } } }
void updateSnakeLevels(FluidLine snakeLine) { if (!trapFired) { return; } if (snakeLine.curLevel < 3) { snakeLine.curLevel++; foreach (SpriteRenderer sprite in snakeLine.fluidSpots) { if (!trapFired) { break; } if (sprite != null) { sprite.sprite = TrapsManager.Instance.snakeSprites[snakeLine.curLevel]; } } } }
void updateWaterLevels(FluidLine waterLine) { if (!trapFired) { return; } if (waterLine.curLevel < 3) { waterLine.curLevel++; foreach (SpriteRenderer sprite in waterLine.fluidSpots) { if (!trapFired) { break; } if (sprite != null) { sprite.sprite = TrapsManager.Instance.waterSprites[waterLine.curLevel]; } } } }
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(); }
public FluidLineKey(FluidLine fluidLine) { this.x = fluidLine.x; this.y = fluidLine.y; this.length = fluidLine.length; }
protected override void InitControl() { base.InitControl(); EnableDoubleBuffer = true; Anchor = AnchorAll; Bounds = new Rectangle(0, 0, 240, 300); BackColor = Theme.Current.PanelBackColor; GradientFill = Theme.Current.PanelGradinated; _accountInfo = Form1.Instance.DropBox.GetAccountInfo(); header.Title = "Info"; header.BackColor = Theme.Current.HeaderBackColor; header.ForeColor = Theme.Current.HeaderForeColor; header.GradientFill = Theme.Current.HeaderGradianted; header.BackButton.Click += new EventHandler(BackButton_Click); header.BackButton.BackColor = Theme.Current.HeaderBackButtonBackColor; header.BackButton.Visible = true; header.BackButton.Shape = ButtonShape.Back; header.BackButton.TextOffset = new Point(6, 0); header.BackButton.Text = "Back"; header.BackButton.GradientFill = Theme.Current.ButtonsGradianted; Controls.Add(header); //Add the controls to the panel here... var lblHeader = new FluidLabel(); lblHeader.Bounds = new Rectangle(10, 30, 150, 25); lblHeader.Font = new Font(FontFamily.GenericSerif, 14, FontStyle.Bold); lblHeader.Text = "DroppedBoxx"; Controls.Add(lblHeader); var lblVersion = new FluidLabel(); lblVersion.Bounds = new Rectangle(10, 60, 150, 25); lblVersion.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblVersion.Text = "Version: " + Form1.Version; Controls.Add(lblVersion); var lblSent = new FluidLabel(); lblSent.Bounds = new Rectangle(10, 75, 150, 25); lblSent.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblSent.Text = string.Format("Sent: {0:#,##0} KB", (Form1.Instance.DropBox.BytesSent / 1024)); Controls.Add(lblSent); var lblRecieved = new FluidLabel(); lblRecieved.Bounds = new Rectangle(10, 90, 150, 25); lblRecieved.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblRecieved.Text = string.Format("Recieved: {0:#,##0} KB", (Form1.Instance.DropBox.BytesRecieved / 1024)); Controls.Add(lblRecieved); var line1 = new FluidLine(0, 115, Width); line1.Anchor = AnchorLR; Controls.Add(line1); var lblAcHeader = new FluidLabel(); lblAcHeader.Bounds = new Rectangle(10, 120, 150, 25); lblAcHeader.Font = new Font(FontFamily.GenericSerif, 14, FontStyle.Bold); lblAcHeader.Text = "Account"; Controls.Add(lblAcHeader); if (_accountInfo != null) { var lblAcQ = new FluidLabel(); lblAcQ.Bounds = new Rectangle(10, 145, 150, 25); lblAcQ.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblAcQ.Text = string.Format("Quota: {0:#,##0} MB", (_accountInfo.Quota_Info.Quota / 1024 / 1024)); Controls.Add(lblAcQ); var lblAcU = new FluidLabel(); lblAcU.Bounds = new Rectangle(10, 160, 150, 25); lblAcU.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblAcU.Text = string.Format("Used: {0:#,##0} MB", (_accountInfo.Quota_Info.Normal / 1024 / 1024)); Controls.Add(lblAcU); var lblAcS = new FluidLabel(); lblAcS.Bounds = new Rectangle(10, 175, 150, 25); lblAcS.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblAcS.Text = string.Format("Shared: {0:#,##0} MB", (_accountInfo.Quota_Info.Shared / 1024 / 1024)); Controls.Add(lblAcS); } else { var lblNoInfo = new FluidLabel(); lblNoInfo.Bounds = new Rectangle(10, 145, 150, 45); lblNoInfo.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); lblNoInfo.Text = string.Format("Failed to get Account Info{0}Check Data Connection", Environment.NewLine); Controls.Add(lblNoInfo); } }
public void DebugDrawFluidTree(bool showTree, bool showLineLength) { if (activeLines.Count > 0) { foreach (FluidLine bottomFluidLine in GetFluidLines()) { HashSet <FluidLine> currentFluidLines = new HashSet <FluidLine>(); FluidLine[] currentFluidLinesArray; currentFluidLines.Add(bottomFluidLine); bool openEnds = true; // find all topLevel FluidLines = all lines with no lines above them and connected while (openEnds) { openEnds = false; currentFluidLinesArray = new FluidLine[currentFluidLines.Count]; currentFluidLines.CopyTo(currentFluidLinesArray); currentFluidLines.Clear(); for (int i = 0; i < currentFluidLinesArray.Length; i++) { if (currentFluidLinesArray[i].GetAboveLinesCount() > 0) { foreach (FluidLine aboveLine in currentFluidLinesArray[i].GetAboveLines()) { if (showTree) { Debug.DrawLine(new Vector3(((float)(currentFluidLinesArray[i].x) + 0.5f) * DataManager.instance.BlockSize, ((float)(currentFluidLinesArray[i].y) + 0.5f) * DataManager.instance.BlockSize, -2f), new Vector3(((float)(aboveLine.x) + 0.5f) * DataManager.instance.BlockSize, ((float)(aboveLine.y) + 0.5f) * DataManager.instance.BlockSize, -2f), Color.red, 0.1f); } if (showLineLength) { Debug.DrawLine(new Vector3(((float)(currentFluidLinesArray[i].x) + 0.5f) * DataManager.instance.BlockSize, ((float)(currentFluidLinesArray[i].y) + 0.5f) * DataManager.instance.BlockSize, -2f), new Vector3(((float)(currentFluidLinesArray[i].x + currentFluidLinesArray[i].length) + 0.5f) * DataManager.instance.BlockSize, ((float)(currentFluidLinesArray[i].y) + 0.5f) * DataManager.instance.BlockSize, -2f), Color.green, 0.1f); } if (aboveLine.GetAboveLinesCount() > 0) { currentFluidLines.Add(aboveLine); openEnds = true; } } } } } } } }
private bool RemoveDrop(FluidLine fluidLine, int flowingToPosition) { if (fluidLine.length == 0) { Debug.Log("[ERROR]RemoveTop(): Couldnt remove a drop from the top FluidLine."); return(false); } else if (fluidLine.length == 1) { //Debug.Log ("Removing drop at " + fluidLine.ToString ()); DeleteFluidLine(fluidLine); return(true); } else { IList <int> mostFreePositions = FindMostFreePositionsIn(fluidLine); //Debug.Log("Most Free positions = " + mostFreePositions.ToArray ().ElementsToString ()); if (mostFreePositions.Count == 1) { return(RemoveDropAtPosition(fluidLine, mostFreePositions.ElementAt(0))); } else { List <int> removeCandidates = new List <int>(); int maxSinkDistance = 0; // select the drops that are furthest away from their sink lines for (int i = 0; i < mostFreePositions.Count; i++) { if (fluidLine.SinkDistanceAt(mostFreePositions[i]) > maxSinkDistance) { removeCandidates.Clear(); removeCandidates.Add(mostFreePositions[i]); maxSinkDistance = fluidLine.SinkDistanceAt(mostFreePositions[i]); } else if (fluidLine.SinkDistanceAt(mostFreePositions[i]) == maxSinkDistance) { removeCandidates.Add(mostFreePositions[i]); } } // chose the closest one of those int distance; int maxDistance = 0; int maxDistancePosition = 0; foreach (int position in removeCandidates) { distance = Mathf.Abs(position - (flowingToPosition - fluidLine.x)); if (maxDistance <= distance) { maxDistance = distance; maxDistancePosition = position; } } //Debug.Log ("Removing drop in " + fluidLine.ToString () + " at position " + minDistancePosition); return(RemoveDropAtPosition(fluidLine, maxDistancePosition)); } } }
// returns all positions where a drop can be taken from this line in its current state. private IList <int> FindMostFreePositionsIn(FluidLine fluidLine) { if (fluidLine.length > 0) { bool[] connectedAbove = new bool[fluidLine.length]; bool[] connectedBelow = new bool[fluidLine.length]; for (int i = 0; i < fluidLine.length; i++) { foreach (FluidLine aboveLine in fluidLine.GetAboveLines()) { if (aboveLine.Contains(fluidLine.x + i)) { connectedAbove[i] = true; } } foreach (FluidLine belowLine in fluidLine.GetBelowLines()) { if (belowLine.Contains(fluidLine.x + i)) { connectedBelow[i] = true; } } if (!connectedBelow[i]) { if (TerrainManager.instance.GetBlock(((float)(fluidLine.x + i) + 0.5f) * DataManager.instance.BlockSize, ((float)(fluidLine.y - 1) + 0.5f) * DataManager.instance.BlockSize).Passable()) { connectedBelow[i] = true; } } } List <int> mostFreePositions = new List <int>(); // are there unconnected Drops? for (int i = 0; i < fluidLine.length; i++) { if (!connectedAbove[i] && !connectedBelow[i]) { mostFreePositions.Add(i); } } if (mostFreePositions.Count > 0) { return(mostFreePositions); } // are there Drops not connected above? for (int i = 0; i < fluidLine.length; i++) { if (!connectedAbove[i] && connectedBelow[i]) { mostFreePositions.Add(i); } } if (mostFreePositions.Count > 0) { return(mostFreePositions); } // are there Drops not connected below? for (int i = 0; i < fluidLine.length; i++) { if (!connectedBelow[i] && connectedAbove[i]) { mostFreePositions.Add(i); } } if (mostFreePositions.Count > 0) { return(mostFreePositions); } for (int i = 0; i < fluidLine.length; i++) { mostFreePositions.Add(i); } return(mostFreePositions); } else { Debug.Log("[ERROR] Trying to find a free drop in an empty line!"); return(null); } }
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()); } }
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); } }