private bool MoveStickyBoxes(HashSet <StickyBox> visited, StickyBox box, IntVec dir) { bool firstBox = visited.Count == 0; IntVec ortho = new IntVec(-dir.Y, dir.X); // all connected sticky boxes, in row/column of move direction List <StickyBox> group = new List <StickyBox>(); // all boxes to the side of row/column, connected to group List <StickyBox> branches = new List <StickyBox>(); // move backwards var nextBox = CurrentState.EntityAt <StickyBox>(box.Pos - dir); while (nextBox != null) { var left = CurrentState.EntityAt <StickyBox>(nextBox.Pos - ortho); if (left != null) { branches.Add(left); } var right = CurrentState.EntityAt <StickyBox>(nextBox.Pos + ortho); if (right != null) { branches.Add(right); } if (!visited.Add(nextBox)) { break; } group.Add(nextBox); nextBox = CurrentState.EntityAt <StickyBox>(nextBox.Pos - dir); } // move forwards nextBox = CurrentState.EntityAt <StickyBox>(box.Pos); while (nextBox != null) { var left = CurrentState.EntityAt <StickyBox>(nextBox.Pos - ortho); if (left != null) { branches.Add(left); } var right = CurrentState.EntityAt <StickyBox>(nextBox.Pos + ortho); if (right != null) { branches.Add(right); } if (!visited.Add(nextBox)) { break; } group.Add(nextBox); nextBox = CurrentState.EntityAt <StickyBox>(nextBox.Pos + dir); } // can only move 1 wide groups! //if (firstBox && group.Count > 1) // return false; StickyBox farthest = group[group.Count - 1]; if (!CanMoveEntity(farthest, dir)) { return(false); } // move all boxes in group foreach (var s in group) { s.Pos += dir; } // execute all branches foreach (var s in branches) { // avoid duplicate movement if (visited.Contains(s)) { continue; } MoveStickyBoxes(visited, s, dir); } return(true); }
private bool TryMoveStickyBox(StickyBox box, IntVec dir) { HashSet <StickyBox> visited = new HashSet <StickyBox>(); return(MoveStickyBoxes(visited, box, dir)); }