public void HandleAttributeYou(OperationType operationType, Stack <Command> tickCommands) { if (operationType == OperationType.Wait) { return; } var moveDirection = GetOperationDirection(operationType); var mapXLength = m_logicGameManager.Map.GetLength(0); var mapYLength = m_logicGameManager.Map.GetLength(1); var scanDirection = Direction.Up; if (DirectionUtils.IsParallel(scanDirection, moveDirection)) { for (var i = 0; i < mapXLength; i++) { if (moveDirection == scanDirection) { HandleDirectionYou(moveDirection, new Vector2Int(i, -1), new Vector2Int(i, mapYLength), tickCommands); } else { HandleDirectionYou(moveDirection, new Vector2Int(i, mapYLength), new Vector2Int(i, -1), tickCommands); } } } scanDirection = Direction.Right; if (DirectionUtils.IsParallel(scanDirection, moveDirection)) { for (var j = 0; j < mapYLength; j++) { if (moveDirection == scanDirection) { HandleDirectionYou(moveDirection, new Vector2Int(-1, j), new Vector2Int(mapXLength, j), tickCommands); } else { HandleDirectionYou(moveDirection, new Vector2Int(mapXLength, j), new Vector2Int(-1, j), tickCommands); } } } }
private void HandleDirectionMove(Direction scanDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands, bool canBounce) { var scanDisplacement = DirectionUtils.DirectionToDisplacement(scanDirection); var impactBlocks = DictionaryPool <Block, int> .Get(); for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition; position += scanDisplacement) { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (!HasAttribute(block, AttributeCategory.Move) || !DirectionUtils.IsParallel(scanDirection, block.direction)) { continue; } var impactDirection = 1; var impactDisplacement = scanDisplacement; if (block.direction != scanDirection) { impactDirection = 2; impactDisplacement = Vector2Int.zero - scanDisplacement; } impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | impactDirection; if (HasAttribute(block, AttributeCategory.Push)) { for (var pushPosition = position + impactDisplacement; m_logicGameManager.InMap(pushPosition); pushPosition += impactDisplacement) { var pushBlocks = m_logicGameManager.Map[pushPosition.x, pushPosition.y]; var hasPush = false; foreach (var pushBlock in pushBlocks) { if (HasAttribute(pushBlock, AttributeCategory.Push)) { impactBlocks[pushBlock] = impactBlocks.GetOrDefault(pushBlock, 0) | impactDirection; hasPush = true; } } if (!hasPush) { break; } } } if (HasAttribute(block, AttributeCategory.Pull)) { for (var pullPosition = position - impactDisplacement; m_logicGameManager.InMap(pullPosition); pullPosition -= impactDisplacement) { var pullBlocks = m_logicGameManager.Map[pullPosition.x, pullPosition.y]; var hasPull = false; foreach (var pullBlock in pullBlocks) { if (HasAttribute(pullBlock, AttributeCategory.Pull)) { impactBlocks[pullBlock] = impactBlocks.GetOrDefault(pullBlock, 0) | impactDirection; hasPull = true; } } if (!hasPull) { break; } } } } } for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition; position -= scanDisplacement) { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (impactBlocks.GetOrDefault(block, 0) == 3) { impactBlocks[block] = 0; } } } HandlePreMove(impactBlocks, scanDisplacement, tickCommands); { var stopPosition = positiveEndPosition - scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~1; } } } } { var stopPosition = negativeEndPosition + scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~2; } } } } for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition + scanDisplacement; position -= scanDisplacement) { var hasStop = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push)) { if (impactBlocks.GetOrDefault(block, 0) != 1) { hasStop = true; break; } } } } if (hasStop) { var stopPosition = position - scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~1; } } } } } for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition - scanDisplacement; position += scanDisplacement) { var hasStop = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push)) { if (impactBlocks.GetOrDefault(block, 0) != 2) { hasStop = true; break; } } } } if (hasStop) { var stopPosition = position + scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~2; } } } } } foreach (var impactBlockPair in impactBlocks) { var block = impactBlockPair.Key; var impact = impactBlockPair.Value; if (canBounce) { if (HasAttribute(block, AttributeCategory.Move) && impact == 0) { block.direction = DirectionUtils.GetOppositeDirection(block.direction); } } else { if (impact == 1) { PerformMoveBlockCommand(block, scanDirection, 1, tickCommands); } else if (impact == 2) { PerformMoveBlockCommand(block, DirectionUtils.GetOppositeDirection(scanDirection), 1, tickCommands); } } } DictionaryPool <Block, int> .Release(impactBlocks); }