protected override void OnInvoke(BaseAspect aspect)
        {
            if (aspect == null || aspect.Deleted)
            {
                return;
            }

            var map = aspect.Map;
            var x   = aspect.X;
            var y   = aspect.Y;
            var z   = aspect.Z;

            var count = Utility.RandomMinMax(5, 10);
            var sect  = 360 / count;

            var shift = Utility.RandomMinMax(0, sect);
            var range = Math.Max(3, aspect.RangePerception - 3);

            for (var i = 0; i < count; i++)
            {
                var t = Angle.GetPoint3D(x, y, z, shift + (i * sect), range);
                var l = aspect.PlotLine3D(t).TakeWhile(p => map.HasLand(p) && !map.HasWater(p));

                var q = new EffectQueue(range);

                var c = -1;

                foreach (var p in l)
                {
                    q.Add(
                        new EffectInfo(p, map, 14089, 0, 8, 15, EffectRender.Darken)
                    {
                        QueueIndex = ++c
                    });
                }

                if (q.Count == 0)
                {
                    q.Dispose();
                    continue;
                }

                q.Handler = fx =>
                {
                    var isEnd = fx.QueueIndex >= c;

                    if (!TryBurst(aspect, fx, ref isEnd) || isEnd)
                    {
                        q.Clear();
                    }
                };

                q.Callback = q.Dispose;

                Timer.DelayCall(
                    TimeSpan.FromSeconds(0.2 * i),
                    () =>
                {
                    aspect.Direction = aspect.GetDirection(t);

                    if (aspect.PlayAttackAnimation())
                    {
                        aspect.PlayAttackSound();
                    }

                    q.Process();
                });
            }
        }