示例#1
0
        /// <summary>
        /// Fait exploser la bombe, ce qui immobilise et blesse les ennemis proches.
        /// </summary>
        private void Explodes()
        {
            _hasExplosed = true;
            var damages = InitialDamages * _owner.SpellPowerRatio();
            var actors  = CollisionFunctions.GetCollidingActors(Position, ExplosionHitbox);

            foreach (var actor in actors)
            {
                var livingActor = actor as LivingActor;
                if (EnnemyWith(actor) && livingActor != null)
                {
                    livingActor.Damages(damages);
                    _owner.Heals(damages * _owner.VampirismRatio());
                    livingActor.LockMoves();
                    livingActor.CreateState(States.BombDebuff);
                }
            }
        }
        /// <summary>
        /// Vérifie si le délai est écoulé, auquel cas déclenche l'explosion, ce qui tue l'actor courant (et laisse son
        /// résidu de mort) et affecte tous les ennemis dans le rayon de l'explosion.
        /// </summary>
        /// <param name="ms"> Le temps écoulé en millisecondes </param>
        public override void Tick(int ms)
        {
            base.Tick(ms);
            if (!((AnimationHandler)SpriteHandler).IsFinished())
            {
                return;
            }

            // Si le délai est écoulé
            var damages = _data.Damage * _owner.SpellPowerRatio();

            foreach (var actor in CollisionFunctions.GetCollidingActors(Position, new Circle(_data.Size)))
            {
                var livingActor = actor as LivingActor;
                if (EnnemyWith(actor) && livingActor != null)
                {
                    livingActor.Damages(damages);
                    _owner.Heals(damages * _owner.VampirismRatio());
                    _data.Effect?.Invoke(_owner, Position, livingActor);
                }
            }
            Kill();
        }
        /// <summary>
        /// Crée un sort qui va infliger des dégâts aux ennemis situés dans un cercle en face du lanceur.
        /// Certaines données sont écrites par défaut :
        /// L'animation du posesseur lors de l'incantation du sort est de type Attack, le sort n'a pas de temps de
        /// recharge, le pourcentage du déclenchement de l'effet est de 1 (ce qui signifie que le sort est lancé à la
        /// fin de son incantation) et la portée du sort équivaut à deux fois la portée indiquée.
        /// Ces données prennent en compte les statistiques de son possesseur.
        /// </summary>
        /// <param name="damages"> Le sdégâts infligés </param>
        /// <param name="range"> La distance de l'acteur au cercle d'impact et le rayon de ce cercle </param>
        /// <param name="castTimeMs"> Le temps d'attaque </param>
        /// <param name="canMove"> Indique si le lanceur peut se déplacer pendant son attaque </param>
        public AttackSpellData(int damages, int range, int castTimeMs, bool canMove) :
            base((caster, target) =>
        {
            target           = caster.Muzzle(range);
            var livingCaster = caster as LivingActor;
            var heal         = livingCaster?.VampirismRatio() ?? 0.0;
            var actors       = CollisionFunctions.GetCollidingActors(target, new Circle(range));
            foreach (var actor in actors)
            {
                var livingActor = actor as LivingActor;

                if (livingActor != null && !caster.FriendWith(actor))
                {
                    livingActor.Damages(damages * caster.PhysicalDamagesRatio());
                    if (heal != 0.0)
                    {
                        livingCaster?.Heals(damages * livingCaster.VampirismRatio());
                    }
                }
            }
        }, AnimationType.Attack, 0, castTimeMs, 1, canMove, 2, range * 2)
        {
        }
        /// <summary>
        /// Récupère les acteurs dans la zone de détection derrière l'acteur associé, et utilise celui qui est le plus
        /// centré en bas de la zone de détection pour établir la nouvelle opacité.
        /// </summary>
        /// <param name="ms"> Le temps écoulé en millisecondes </param>
        public override void Tick(int ms)
        {
            var actors = CollisionFunctions.GetCollidingActors(_owner.Position - new Point(0, (double)_height / 2),
                                                               new Rectangle(_width * 2, _height * 2));
            var opacityMin = 1.0f;

            foreach (var actor in actors)
            {
                // Les acteurs neutres sont ignorés
                if (actor.Faction == Faction.Neutral)
                {
                    continue;
                }
                var    p = actor.Position;
                var    x = Math.Abs(_owner.Position.X - p.X);
                double y;
                if (p.Y > _owner.Position.Y)
                {
                    y = _height + 1;
                }
                else
                {
                    y = Math.Abs(_owner.Position.Y - p.Y);
                }
                if ((x > _width) ||
                    (y > _height))
                {
                    continue;
                }
                // Minimise l'opacité lorsque l'acteur est au milieu en abscisse et en bas en ordonnée
                var x2 = (float)Math.Min(1, x / _width) * (1 - _opacityMin) + _opacityMin;
                var y2 = (float)Math.Min(1, y / _height) * (1 - _opacityMin) + _opacityMin;
                opacityMin = Math.Min(Math.Max(x2, y2), opacityMin);
            }
            Opacity = opacityMin;
        }