Пример #1
0
        protected override void OnPerform()
        {
            var displacement = DirectionUtils.DirectionToDisplacement(m_targetDirection) * m_targetLength;

            m_logicGameManager.MoveBlock(m_block, m_block.position + displacement);
            m_block.direction = m_targetDirection;

            if (m_logicGameManager.BlockMoved != null)
            {
                m_logicGameManager.BlockMoved(m_block);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        private void HandleDirectionYou(Direction moveDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands)
        {
            var displacement = DirectionUtils.DirectionToDisplacement(moveDirection);

            var impactBlocks = DictionaryPool <Block, int> .Get();

            for (var position = negativeEndPosition + displacement; position != positiveEndPosition; position += displacement)
            {
                var hasYou = false;
                {
                    var blocks = m_logicGameManager.Map[position.x, position.y];
                    foreach (var block in blocks)
                    {
                        if (HasAttribute(block, AttributeCategory.You))
                        {
                            impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                            hasYou = true;
                        }
                    }
                }
                if (hasYou)
                {
                    for (var pullPosition = position - displacement; m_logicGameManager.InMap(pullPosition); pullPosition -= displacement)
                    {
                        var blocks  = m_logicGameManager.Map[pullPosition.x, pullPosition.y];
                        var hasPull = false;
                        foreach (var block in blocks)
                        {
                            if (HasAttribute(block, AttributeCategory.Pull))
                            {
                                impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                                hasPull             = true;
                            }
                        }
                        if (!hasPull)
                        {
                            break;
                        }
                    }
                    for (var pushPosition = position + displacement; m_logicGameManager.InMap(pushPosition); pushPosition += displacement)
                    {
                        var blocks  = m_logicGameManager.Map[pushPosition.x, pushPosition.y];
                        var hasPush = false;
                        foreach (var block in blocks)
                        {
                            if (HasAttribute(block, AttributeCategory.Push))
                            {
                                impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                                hasPush             = true;
                            }
                        }
                        if (!hasPush)
                        {
                            break;
                        }
                    }
                }
            }

            HandlePreMove(impactBlocks, displacement, tickCommands);

            {
                var stopPosition = positiveEndPosition - displacement;
                {
                    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] = 0;
                        }
                    }
                }
            }
            for (var position = positiveEndPosition - displacement; position != negativeEndPosition + displacement; position -= displacement)
            {
                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) == 0)
                            {
                                hasStop = true;
                                break;
                            }
                        }
                    }
                }
                if (hasStop)
                {
                    var stopPosition = position - displacement;
                    {
                        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] = 0;
                            }
                        }
                    }
                }
            }

            foreach (var impactBlockPair in impactBlocks)
            {
                var block  = impactBlockPair.Key;
                var impact = impactBlockPair.Value;

                if (impact == 1)
                {
                    PerformMoveBlockCommand(block, moveDirection, 1, tickCommands);
                }
            }

            DictionaryPool <Block, int> .Release(impactBlocks);
        }