void move(Direction dir) { Dictionary <MoveableScript, coord> desiredCoords = new Dictionary <MoveableScript, coord>(); //where pieces would move without collisions/walls Dictionary <MoveableScript, Direction> moveDirections = new Dictionary <MoveableScript, Direction>(); //directions pieces will actually move Dictionary <MoveableScript, int> collided = new Dictionary <MoveableScript, int>(); Dictionary <MoveableScript, coord> blockingCoords = new Dictionary <MoveableScript, coord>(); foreach (MoveableScript m in moveables) { Direction direction = m.GetAttemptedMoveDirection(dir, boardState.board); coord desired = m.GetAttemptedMoveCoords(dir, boardState.board, 1); if (boardState.board[desired.row, desired.col] / 10 == 5) { blockingCoords.Add(m, desired); desired = portalMap[desired]; } desiredCoords.Add(m, desired); //Check for collisions with lasers foreach (LaserScript laser in laserList) { // if laser is active && laser can collide with this moveable if (laser.data.isActive && laser.data.type != m.type) { //if moveable is jumping through a horizontal laser if ((direction == Direction.NORTH && m.GetCoords().row == laser.data.startRow) || (direction == Direction.SOUTH && desired.row == laser.data.startRow)) { if (laser.data.isBetweenCol(m.GetCoords().col)) { moveDirections[m] = Direction.NONE; desired = m.GetCoords(); desiredCoords[m] = desired; } } //if moveable is jumping through a vertical laser if ((direction == Direction.EAST && desired.col == laser.data.startCol) || (direction == Direction.WEST && m.GetCoords().col == laser.data.startCol)) { if (laser.data.isBetweenRow(m.GetCoords().row)) { moveDirections[m] = Direction.NONE; desired = m.GetCoords(); desiredCoords[m] = desired; } } } } // Check for collisions moving into the same spot foreach (MoveableScript other in moveables) { if (other == m || other == null) { continue; //Check for moving into same spot } else if ((desiredCoords.ContainsKey(other) && desiredCoords[other].Equals(desired)) || // classic move into blocked (desiredCoords.ContainsKey(other) && blockingCoords.ContainsKey(m) && desiredCoords[other].Equals(blockingCoords[m])) || // other is moving into my blocker (blockingCoords.ContainsKey(other) && blockingCoords[other].Equals(desired)) || // I am moving into other's blocker (blockingCoords.ContainsKey(other) && blockingCoords.ContainsKey(m) && blockingCoords[m].Equals(blockingCoords[other]))) //we share a blocker { moveDirections[other] = Direction.NONE; moveDirections[m] = Direction.NONE; dead = true; deathscript.playerDeath = true; if (desiredCoords.ContainsKey(player) && !desiredCoords[player].Equals(player.GetCoords()) || m.type == BoardCodes.PLAYER || other.type == BoardCodes.PLAYER) { collided.Add(m, 2); collided.Add(other, 2); } } } // Check for collisions moving through each other foreach (MoveableScript other in moveables) { if (other == null) { throw new System.NullReferenceException("One Entity in moveables is null!"); } else if (other == m) { continue; } else if ((desiredCoords.ContainsKey(other) && desiredCoords[other].Equals(m.GetCoords()) && desired.Equals(other.GetCoords())) || // classic close collision, other wants my space, I want other's space (desiredCoords.ContainsKey(other) && desiredCoords[other].Equals(m.GetCoords()) && blockingCoords.ContainsKey(m) && blockingCoords[m].Equals(other.GetCoords())) || // other wants my current space, other is in my blocker space (blockingCoords.ContainsKey(other) && blockingCoords[other].Equals(m.GetCoords()) && desiredCoords[m].Equals(other.GetCoords()))) // other is blocked by me, I want other's space { moveDirections [other] = Direction.NONE; moveDirections [m] = Direction.NONE; } } if (!moveDirections.ContainsKey(m)) { moveDirections.Add(m, m.GetAttemptedMoveDirection(dir, boardState.board)); } } // Check for collisions moving into pieces that couldn't move for (int i = 0; i < moveables.Count; i++) { foreach (MoveableScript m in moveables) { foreach (MoveableScript other in moveables) { if (other == m || other == null) { continue; } else if (moveDirections [other] == Direction.NONE && (other.GetCoords().Equals(desiredCoords [m]) || (blockingCoords.ContainsKey(m) && other.GetCoords().Equals(blockingCoords [m])))) { moveDirections [m] = Direction.NONE; collided [m] = 1; collided [other] = 1; //Debug.Log ("Couldn't move" + ":" + other.GetCoords ()); } else { //Debug.Log (moveDirections [other] + ":" + other.GetCoords ()); } } } } // make the moves if (moveDirections [player] != Direction.NONE) { Stack <MoveableScript> toDestroy = new Stack <MoveableScript>(); foreach (MoveableScript moveable in moveDirections.Keys) { moveable.ExecuteMove(moveDirections[moveable], 1, false); if (moveDirections [moveable] == Direction.NONE) { AudioManagerScript.instance.soundFx.PlayOneShot(moveable.collideSound, .5f); } // check for a swap coord c = moveable.GetCoords(); if (moveDirections[moveable] != Direction.NONE && swapCoords.Contains(c)) { needsSwap.Add(moveable); } else if (moveDirections[moveable] != Direction.NONE && portalCoords.Contains(c)) { coord cp = portalMap[c]; // overrides any existing moves moveable.EnterPortal(boardState.board, cp); } //check for button press if (boardState.board[c.row, c.col] >= 30 && boardState.board[c.row, c.col] < 40) { coord buttonCoord = new coord(c.row, c.col); buttonsPressed.Add(buttonCoords[buttonCoord]); } } moveDirections.Clear(); // destroy old objects int j = toDestroy.Count; for (int i = 0; i < j; i++) { MoveableScript ms = toDestroy.Pop(); GameObject.Destroy(ms.gameObject); } } else { if (!collided.ContainsKey(player)) { collided.Add(player, 1); } } foreach (MoveableScript m in collided.Keys) { m.ExecuteMove(Direction.NONE, collided[m], false); AudioManagerScript.instance.soundFx.PlayOneShot(m.collideSound, .5f); } recordDynamicState(); }