// Helper for only adding CCs
    public void AddCC(string name, Locks cc, Locks interrupt = Locks.NONE, float duration = 0)
    {
        if (!effects.ContainsKey(name))
        {
            effects.Add(name, cc);
        }
        if (duration != 0)
        {
            StartCoroutine(RemoveEffectAfter(name, duration));
        }

        // Interrupt any kind of movement
        if (cc.HasFlag(Locks.Movement))
        {
            movingSpeed = Vector3.zero;
            // Interrupt dash
            if (interrupt.HasFlag(Locks.Dash) && Dashing)
            {
                // Reset dashing
                RemoveCC("Dashing");
                Dashing    = false;
                gravityMul = 1f;

                if (dashCoroutine != null)
                {
                    StopCoroutine(dashCoroutine);
                    dashCoroutine = null;
                }
            }
        }

        // If spells are prevented, turn off Crystal
        if (cc.HasFlag(Locks.Spells))
        {
            SwitchCrystal(value: false);

            // Interrupt spell casting
            if (interrupt.HasFlag(Locks.Spells) && Casting)
            {
                Casting = false;
            }
        }

        // If interaction is prevented, de-mark last interactable
        if (cc.HasFlag(Locks.Interaction) && lastMarked)
        {
            // Un-register player if it's a machine
            var m = lastMarked as MachineInterface;
            if (m)
            {
                m.PlayerIsNear(near: false);
            }

            // Un-focus
            lastMarked.marker.Off(focusColor);
            lastMarked = null;
        }
    }
    private void Movement()
    {
        // Get input
        var input = Vector3.zero;

        input.x = Owner.GetAxis("Horizontal");
        input.z = Owner.GetAxis("Vertical");

        // Compute rotation equivalent to moving direction
        var dir = Vector3.Min(input, input.normalized);

        if (input != Vector3.zero)
        {
            // Transform direction to be camera-dependent
            dir            = TranformToCamera(dir);
            targetRotation = Quaternion.LookRotation(dir);
        }

        // If burning
        if (locks.HasFlag(Locks.Burning))
        {
            // Can't stop moving
            Moving = true;
            float speedMul = Bobby.SpeedMultiplier * speed;

            if (input != Vector3.zero)
            {
                movingSpeed = dir * speedMul;
            }
            else
            {
                movingSpeed = MovingDir * speedMul;
            }
        }
        else
        // Modify speed to move character
        if (!locks.HasFlag(Locks.Movement))
        {
            if (input != Vector3.zero)
            {
                movingSpeed = dir * speed;
                Moving      = true;
            }
            else
            {
                // Ice is resbalizou
                //if (Game.manager is MeltingRace) movingSpeed = Vector3.Lerp (movingSpeed, Vector3.zero, Time.deltaTime * 0.5f);
                // :(((

                movingSpeed = Vector3.zero;
                Moving      = false;
            }
        }
        else
        {
            Moving = false;
        }
    }
    private void ReadEffects()
    {
        // Check if spells were originally blocked
        bool spellsWereBlocked = locks.HasFlag(Locks.Spells);

        locks = Locks.NONE;
        foreach (var e in effects)
        {
            // Resets CCs & then reads them every frame
            locks = locks.SetFlag(e.Value);
        }

        // Check if spells are NOW originally blocked
        bool spellsAreBlocked = locks.HasFlag(Locks.Spells);

        if (spellsWereBlocked && !spellsAreBlocked)
        {
            SwitchCrystal(value: true);
        }
    }