/// <summary>
 /// Fait progresser le chargement du sort (si il n'a pas atteint son nombre de charges maximal) et son
 /// incantation si le possesseur du sort est en train de le lancer. Si le temps d'incantation écoulé est
 /// suffisant, déclenche l'effet du sort.
 /// </summary>
 /// <param name="ms"> Le temps écoule en millisecondes </param>
 public void Tick(int ms)
 {
     _cooldown.Tick(ms);
     if (_cooldown.IsEmpty() && CurrentCharges < _spellData.NbCharges)
     {
         CurrentCharges++;
         if (CurrentCharges < _spellData.NbCharges)
         {
             _cooldown.Value = _cooldown.ValueMax;
         }
     }
     if (_currentMs == DefaultMs)
     {
         return;
     }
     // Si le sort est en cours d'incantation
     _currentMs += ms;
     if (_currentMs <= _spellData.CastTimeMs * _spellData.PercentCast)
     {
         return;
     }
     if (CurrentCharges == _spellData.NbCharges)
     {
         _cooldown.Value = _cooldown.ValueMax;
     }
     CurrentCharges--;
     _spellData.Effect.Invoke(_owner, _target);
     _currentMs = DefaultMs;
 }
 /// <summary>
 /// Actualise l'acteur et le déplace suivant sa vitesse constante et le temps écoulé.
 /// Ensuite, actualise sa durée de vie et le retire du monde si celle-ci est écoulée, en créant un Residu si le
 /// projectile possède une animation de type Death.
 /// </summary>
 /// <param name="ms"> Le temps écoulé en millisecondes </param>
 public override void Tick(int ms)
 {
     base.Tick(ms);
     SpeedVector = Orientation * Speed;
     Move(SpeedVector * ((double)ms / 1000));
     _lifeTime.Tick(ms);
     if (_lifeTime.IsEmpty())
     {
         Kill();
     }
 }