/// <summary>
 /// 创建子魔法元素
 /// </summary>
 void createSubMagic(RoleBase caster, Space space, MagicArgs args, double angle, double width)
 {
     double radian = GlobalMethod.GetRadian(angle);
     double x = width * Math.Cos(radian) + args.Position.X;
     double y = width * Math.Sin(radian) + args.Position.Y;
     Point position = new Point(x, y);
     Point p = space.Terrain.GetCoordinateFromPosition(position);
     //障碍物的位置不能放魔法
     if (space.Terrain.InEffectiveRange(p)) {
         if ((args.SpaceLayer == SpaceLayers.Ground && space.Terrain.Matrix[(int)p.X, (int)p.Y] != 0) || args.SpaceLayer == SpaceLayers.Sky) {
             AnimationBase magic = new AnimationBase() { Code = args.ResCode, SpaceLayer = args.SpaceLayer, Position = position, Z = (int)y };
             EventHandler handler = null;
             magic.Disposed += handler = delegate {
                 magic.Disposed -= handler;
                 space.RemoveAnimation(magic);
             };
             space.AddAnimation(magic);
             //捕获圆范围内将要伤害的精灵表
             for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
                 RoleBase target = space.AllRoles()[i];
                 if (caster.IsHostileTo(target) && target.InCircle(position, args.Radius * args.Scale)) {
                     caster.CastingToEffect(target, args);
                 }
             }
         }
     }
 }
 void CreateSubMagic(RoleBase caster, Space space, MagicArgs args, int index)
 {
     AnimationBase animation = new AnimationBase() { Code = args.ResCode,  Z = targets[index].Z + 1, Effect = shiftHue };
     double offsetStartY = (caster.State == States.Riding ? (caster.Profession == Professions.Taoist ? 130 : 110) : 60) * caster.Scale;
     double offsetEndY = (targets[index].State == States.Riding ? 100 : 50) * caster.Scale;
     Point from = index == 0 ? new Point(args.Position.X, args.Position.Y - offsetStartY) : temp;
     Point to = new Point(targets[index].Position.X, targets[index].Position.Y - offsetEndY);
     temp = to;
     RotateTransform rotateTransform = new RotateTransform() {
         CenterX = animation.Center.X,
         CenterY = animation.Center.Y,
         Angle = GlobalMethod.GetAngle(to.Y - from.Y, to.X - from.X)
     };
     ScaleTransform scaleTransform = new ScaleTransform() {
         CenterX = animation.Center.X,
         CenterY = animation.Center.Y,
         ScaleX = (GlobalMethod.GetDistance(index == 0 ? args.Position : targets[index - 1].Position, targets[index].Position) / 440), //440为其实体宽度,这里用了硬编码
         ScaleY = caster.Scale
     };
     TransformGroup transformGroup = new TransformGroup();
     transformGroup.Children.Add(scaleTransform);
     transformGroup.Children.Add(rotateTransform);
     animation.RenderTransform = transformGroup;
     animation.Position = from;
     space.AddUIElement(animation);
     EventHandler handler = null;
     animation.End += handler = delegate {
         animation.End -= handler;
         space.RemoveAnimation(animation);
         if (index == targets.Count) { targets.Clear(); }
     };
     animation.HeartStart();
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     args.Position = args.MagicPosition == MagicPositions.Position ? args.Position : args.Destination;
     double angle = GlobalMethod.GetAngle(GlobalMethod.GetRadian(args.Position, args.Destination)) + 180;
     int count = 0;
     int number = 4;
     double width = 110 * args.Scale;
     EventHandler handler = null;
     DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(100) };
     timer.Tick += handler = delegate {
         if (count == args.Number) {
             timer.Tick -= handler;
             timer.Stop();
         } else {
             createSubMagic(space, args, number, angle, width);
             count++;
             number += 2;
             width += 110 * args.Scale;
         }
     };
     timer.Start();
     //捕获圆范围内将要伤害的精灵表
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         RoleBase target = space.AllRoles()[i];
         if (caster.IsHostileTo(target) && target.InCircle(args.Position, args.Radius * args.Scale)) {
             caster.CastingToEffect(target, args);
         }
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     targets.Add(args.Target);
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         if (targets.Count == args.Number) { break; }
         RoleBase target = space.AllRoles()[i];
         if (caster.IsHostileTo(target) && target.InCircle(args.Destination, args.Radius * args.Scale)) {
             if (target != args.Target) { targets.Add(target); }
         }
     }
     int index = 0;
     CreateSubMagic(caster, space, args, index);
     DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(200) };
     EventHandler handler = null;
     timer.Tick += handler = delegate {
         if (caster.IsHostileTo(targets[index])) { caster.CastingToEffect(targets[index], args); }
         index++;
         if (index == targets.Count) {
             timer.Stop();
             timer.Tick -= handler;
         } else {
             int newInterval = timer.Interval.Milliseconds - 30;
             if (newInterval <= 20) { newInterval = 20; }
             timer.Interval = TimeSpan.FromMilliseconds(newInterval);
             CreateSubMagic(caster, space, args, index);
         }
     };
     timer.Start();
 }
 void CreateSubMagic(RoleBase caster,RoleBase startTarget, RoleBase endTarget, Space space, MagicArgs args)
 {
     AnimationBase animation = new AnimationBase() { Code = args.ResCode, Z = startTarget.Z + 1 };
     double offsetStartY = (startTarget.State == States.Riding ? (startTarget.Profession == Professions.Taoist ? 130 : 110) : 60) * args.Scale;
     double offsetEndY = (endTarget.State == States.Riding ? 100 : 50) * args.Scale;
     Point from = new Point(startTarget.Position.X, startTarget.Position.Y - offsetStartY);
     Point to = new Point(endTarget.Position.X, endTarget.Position.Y - offsetEndY);
     RotateTransform rotateTransform = new RotateTransform() {
         CenterX = animation.Center.X,
         CenterY = animation.Center.Y,
         Angle = GlobalMethod.GetAngle(to.Y - from.Y, to.X - from.X)
     };
     ScaleTransform scaleTransform = new ScaleTransform() {
         CenterX = animation.Center.X,
         CenterY = animation.Center.Y,
         ScaleX = (GlobalMethod.GetDistance(startTarget.Position, endTarget.Position) / Convert.ToInt32(args.Tag)),
         ScaleY = args.Scale
     };
     TransformGroup transformGroup = new TransformGroup();
     transformGroup.Children.Add(scaleTransform);
     transformGroup.Children.Add(rotateTransform);
     animation.RenderTransform = transformGroup;
     animation.Position = from;
     space.AddUIElement(animation);
     EventHandler handler = null;
     animation.End += handler = delegate {
         animation.End -= handler;
         space.RemoveAnimation(animation);
     };
     animation.HeartStart();
 }
 /// <summary>
 /// 物理攻击使对方造成伤害
 /// </summary>
 /// <param name="target">目标角色</param>
 public void AttackToHurt(RoleBase target)
 {
     //模拟伤害计算
     int damage = this.ATK - target.DEF < 0 ? 0 : this.ATK - target.DEF + RandomSeed.Next(-this.ATK / 3, this.ATK / 2);
     //各种伤害情况判断(实际不这么写,需要真实的数值公式计算)
     if (damage == 0 || RandomSeed.Next(100) < target.DEX) {
         target.ChangeLife(0, ValueEffects.Failure);
         return;
     } else if (RandomSeed.Next(100) > 80) {
         //暴击
         target.ChangeLife(-damage * 2, ValueEffects.DoubleDecrease);
         target.Quiver(2);
     } else {
         target.ChangeLife(-damage, ValueEffects.Decrease);
     }
     //伤害后如果对象生命为0
     if (target.Life == 0) {
         this.Stop();
         this.Target = null;
         target.ChangeLife(0, ValueEffects.Death);
     } else {
         ////附加被攻击装饰特效及额外特效都均可写在武器的Info.xml中
         //if (this.AttactEffect != -1) {
         //    Animation animation = new Animation() { Code = this.AttactEffect, Coordinate = obj.Center };
         //    EventHandler handler = null;
         //    animation.Disposed += handler = delegate {
         //        animation.Disposed -= handler;
         //        obj.RemoveTemporaryEffect();
         //    };
         //    obj.AddTemporaryEffect(animation);
         //}
     }
 }
 /// <summary>
 /// 添加角色
 /// </summary>
 /// <param name="role">角色对象</param>
 public void AddRole(RoleBase role)
 {
     roleList.Add(role);
     space.Children.Add(role);
     AddShadow(role.ID, ShadowType);
     role.HeartStart();
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     targets.Add(args.Target);
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         RoleBase target = space.AllRoles()[i];
         if (caster.IsHostileTo(target) && target.InCircle(args.Destination, args.Radius * args.Scale)) {
             if (target != args.Target) { targets.Add(target); }
             if (targets.Count == args.Number) { break; }
         }
     }
     CreateSubMagic(caster, space, args);
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     int positionX = (int)args.Position.X, positionY = (int)args.Position.Y;
     int destinationX = (int)args.Destination.X, destinationY = (int)args.Destination.Y;
     int radius = (int)(100 * caster.Scale);
     for (int i = 0; i < args.Number; i++) {
         CircleMagic magic = new CircleMagic();
         args.Position = new Point(ObjectBase.RandomSeed.Next(positionX - radius, positionX + radius), ObjectBase.RandomSeed.Next(positionY - radius, positionY + radius));
         args.Destination = new Point(ObjectBase.RandomSeed.Next(destinationX - radius, destinationX + radius), ObjectBase.RandomSeed.Next(destinationY - radius, destinationY + radius));
         magic.Run(caster, space, args);
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     EventHandler handler = null;
     AnimationBase animation = new AnimationBase() {
         Code = (int)args.ResCode,
         Position = args.Target.Center,
         Z = -1,
     };
     animation.Disposed += handler = delegate {
         animation.Disposed -= handler;
         args.Target.RemoveEffect(EffectTypes.Cure);
     };
     args.Target.AddEffect(animation, EffectTypes.Cure);
     caster.CastingToEffect(args.Target, args);
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     double distance = GlobalMethod.GetDistance(args.Position, args.Destination);
     double speed = 2;
     caster.LinearShuttle(args.Destination, distance * speed);
     int count = 0;
     EventHandler timerHandler = null;
     DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(100) };
     timer.Tick += timerHandler = delegate {
         caster.Target = null;
         if (count == args.Number || caster.Action != Actions.Attack) {
             timer.Tick -= timerHandler;
             timer.Stop();
         } else {
             WriteableBitmap writeableBitmap = new WriteableBitmap((int)caster.OverallSize.X, (int)caster.OverallSize.Y);
             writeableBitmap.Render(caster.EquipEntity(EquipTypes.Overall), null);
             writeableBitmap.Invalidate();
             EntityObject chasingShadow = new EntityObject() {
                 RenderTransform = caster.RenderTransform,
                 ImageSource = writeableBitmap,
                 Center = caster.Center,
                 Position = caster.Position,
                 Z = caster.Z - 20
             };
             space.Children.Add(chasingShadow);
             Storyboard storyboard = new Storyboard();
             storyboard.Children.Add(GlobalMethod.CreateDoubleAnimation(chasingShadow,"Opacity",0.9,0,TimeSpan.FromMilliseconds(caster.HeartInterval * 3),null));
             EventHandler handler = null;
             storyboard.Completed += handler = delegate {
                 storyboard.Completed -= handler;
                 storyboard.Stop();
                 space.Children.Remove(chasingShadow);
             };
             storyboard.Begin();
             //每200毫秒伤害一次
             if (count % 2 == 0) {
                 for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
                     RoleBase target = space.AllRoles()[i];
                     if (caster.IsHostileTo(target) && target.InCircle(caster.Position, args.Radius * args.Scale)) {
                         caster.CastingToEffect(target, args);
                     }
                 }
             }
             count++;
         }
     };
     timer.Start();
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     int count = 0;
     caster.AttackToHurt(args.Target);
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         RoleBase target = space.AllRoles()[i];
         if (caster.IsHostileTo(target) && target.InCircle(args.Target.Position, args.Radius * args.Scale)) {
             if (target != args.Target) {
                 CreateSubMagic(caster, args.Target, target, space, args);
                 caster.CastingToEffect(target, args);
                 count++;
                 if (count == args.Number) { break; }
             }
         }
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     args.Position = args.MagicPosition == MagicPositions.Position ? args.Position : args.Destination;
     AnimationBase magic = new AnimationBase() { Code = args.ResCode, SpaceLayer = args.SpaceLayer, Position = args.Position, Z = args.MagicLayer == MagicLayers.Ground ? -1 : (int)args.Position.Y };
     EventHandler handler = null;
     magic.Disposed += handler = delegate {
         magic.Disposed -= handler;
         space.RemoveAnimation(magic);
     };
     space.AddAnimation(magic);
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         RoleBase target = space.AllRoles()[i];
         if (target.InCircle(args.Position, args.Radius * args.Scale)) {
             caster.CastingToEffect(target, args);
         }
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     double angle = GlobalMethod.GetAngle(GlobalMethod.GetRadian(args.Position, args.Destination)) + 180;
     double singleAngle = 10;
     double startAngle = angle - ((args.Number - 1) / 2 * singleAngle);
     double endAngle = angle + ((args.Number - 1) / 2 * singleAngle);
     for (int i = 0; i < args.Number; i++) {
         double otherAngle = startAngle + singleAngle * i;
         Bullet bullet = new Bullet(new BulletDatas() { Code = args.ResCode, Type = BulletTypes.Common }) {
             SpaceLayer = caster.SpaceLayer,
             Z = (int)args.Destination.Y,
         };
         double offsetX = bullet.Source.PixelWidth * bullet.Scale;
         double offsetStartY = (caster.State == States.Riding ? (caster.Profession == Professions.Taoist ? 130 : 110) : 60) * bullet.Scale;
         double offsetEndY = 80 * bullet.Scale;
         EventHandler handler = null;
         bullet.MoveCompleted += handler = delegate {
             bullet.MoveCompleted -= handler;
             space.RemoveUIElement(bullet);
         };
         space.AddUIElement(bullet);
         Point p = new Point(args.Destination.X + args.Radius * Math.Cos(GlobalMethod.GetRadian(otherAngle)), args.Destination.Y + args.Radius * Math.Sin(GlobalMethod.GetRadian(otherAngle)));
         bullet.Move(new Point(args.Position.X - offsetX, args.Position.Y - offsetStartY), new Point(p.X - offsetX, p.Y - offsetEndY), 0.6 / bullet.Scale, MoveModes.Normal);
     }
     double s0 = 0, s1 = 1, e0 = 0, e1 = 0;
     if (startAngle < 180 && endAngle > 180) {
         s0 = startAngle; e0 = 180; s1 = -180; e1 = endAngle - 360;
     } else if (startAngle >= 180) {
         s0 = startAngle - 360; e0 = endAngle - 360;
     } else {
         s0 = startAngle; e0 = endAngle;
     }
     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
         RoleBase target = space.AllRoles()[i];
         if (caster.IsHostileTo(target)) {
             double tempAngle = GlobalMethod.GetAngle(GlobalMethod.GetRadian(target.Position, args.Position));
             if ((tempAngle >= s0 && tempAngle <= e0) || (tempAngle >= s1 && tempAngle <= e1) || target.InCircle(args.Position, 50)) {
                 caster.CastingToEffect(target, args);
             }
         }
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     args.Position = args.MagicPosition == MagicPositions.Position ? args.Position : args.Destination;
     Point p = space.Terrain.GetCoordinateFromPosition(args.Position);
     if (space.Terrain.InEffectiveRange(p)) {
         if ((args.SpaceLayer == SpaceLayers.Ground && space.Terrain.Matrix[(int)p.X, (int)p.Y] != 0) || args.SpaceLayer == SpaceLayers.Sky) {
             AnimationBase magic = new AnimationBase() { Code = args.ResCode, SpaceLayer = args.SpaceLayer, Position = args.Position, Z = args.MagicLayer == MagicLayers.Ground ? -1 : (int)args.Position.Y, Loop = true };
             //magic.RenderTransform = new RotateTransform() {
             //    CenterX = magic.Center.X,
             //    CenterY = magic.Center.Y,
             //    Angle = GlobalMethod.GetAngle(args.Position.Y - caster.Position.Y, args.Position.X - caster.Position.X)
             //};
             EventHandler handler = null;
             magic.Disposed += handler = delegate {
                 magic.Disposed -= handler;
                 space.RemoveAnimation(magic);
             };
             space.AddAnimation(magic);
             int count = 0;
             DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(Convert.ToInt32(args.Tag)) };
             EventHandler timerHandler = null;
             timer.Tick += timerHandler = delegate {
                 if (count == args.Number) {
                     timer.Stop();
                     timer.Tick -= timerHandler;
                     magic.Dispose(magic, null);
                 } else {
                     for (int i = space.AllRoles().Count - 1; i >= 0; i--) {
                         RoleBase target = space.AllRoles()[i];
                         if (caster.IsHostileTo(target) && target.InCircle(args.Position, args.Radius * args.Scale)) {
                             //Targets.Add(target);
                             caster.CastingToEffect(target, args);
                         }
                     }
                 }
                 count++;
             };
             timer.Start();
         }
     }
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     args.Position = args.MagicPosition == MagicPositions.Position ? args.Position : args.Destination;
     double angle = GlobalMethod.GetAngle(GlobalMethod.GetRadian(args.Position, args.Destination)) + 180;
     double width = args.Radius * args.Scale;
     int count = 0;
     EventHandler handler = null;
     DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(Convert.ToInt32(args.Tag)) };
     timer.Tick += handler = delegate {
         if (count == args.Number) {
             timer.Tick -= handler;
             timer.Stop();
         } else {
             createSubMagic(caster, space, args, angle, width);
             timer.Interval = TimeSpan.FromMilliseconds(timer.Interval.Milliseconds-10);
             count++;
             width += args.Radius * args.Scale;
         }
     };
     timer.Start();
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     int count = 0;
     int positionX = (int)args.Position.X, positionY = (int)args.Position.Y;
     int destinationX = (int)args.Destination.X, destinationY = (int)args.Destination.Y;
     int radius = (int)(130 * caster.Scale);
     EventHandler handler = null;
     DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(150) };
     timer.Tick += handler = delegate {
         if (count == args.Number) {
             timer.Tick -= handler;
             timer.Stop();
         } else {
             CircleMagic magic = new CircleMagic();
             args.Position = new Point(ObjectBase.RandomSeed.Next(positionX - radius, positionX + radius), ObjectBase.RandomSeed.Next(positionY - radius, positionY + radius));
             args.Destination = new Point(ObjectBase.RandomSeed.Next(destinationX - radius, destinationX + radius), ObjectBase.RandomSeed.Next(destinationY - radius, destinationY + radius));
             magic.Run(caster, space, args);
             if (args.SpecialEffect == SpecialEffects.Shake) { space.Shake(Convert.ToInt32(args.Tag)); }
             count++;
         }
     };
     timer.Start();
 }
 void CreateSubMagic(RoleBase caster, Space space, MagicArgs args)
 {
     Bullet bullet = new Bullet(new BulletDatas() { Code = args.ResCode, Type = BulletTypes.Animation,Loop = true }) {
         SpaceLayer = caster.SpaceLayer,
         Z = (int)args.Destination.Y,
     };
     double offsetX = bullet.Offset.X * bullet.Scale;
     double offsetStartY = (caster.State == States.Riding ? (caster.Profession == Professions.Taoist ? 130 : 110) : 60) * bullet.Scale;
     double offsetEndY = (targets[index].State == States.Riding ? 100 : 70) * bullet.Scale;
     EventHandler handler = null;
     bullet.MoveCompleted += handler = delegate {
         bullet.MoveCompleted -= handler;
         space.RemoveUIElement(bullet);
         if (caster.IsHostileTo(targets[index])) { caster.CastingToEffect(targets[index], args); }
         index++;
         if (index == targets.Count) {
             targets.Clear();
         } else {
             CreateSubMagic(caster, space, args);
         }
     };
     space.AddUIElement(bullet);
     bullet.Move(new Point((index == 0 ? args.Position.X : targets[index - 1].Position.X) - offsetX, (index == 0 ? args.Position.Y : targets[index - 1].Position.Y) - offsetStartY), new Point(targets[index].Position.X - offsetX, targets[index].Position.Y - offsetEndY), 0.9 / bullet.Scale, MoveModes.Normal);
 }
 /// <summary>
 /// 魔法/技能攻击产生效果(伤害/治疗)
 /// </summary>
 public void CastingToEffect(RoleBase target, MagicArgs args)
 {
     //依据魔法实效类型处理
     switch (args.MagicEffectType) {
         case MagicEffectTypes.Gain:
             target.ChangeLife(Convert.ToInt32(args.Tag), ValueEffects.Increase);
             break;
         case MagicEffectTypes.Reduction:
             //模拟伤害计算
             int damage = RandomSeed.Next(this.MAG + args.EffectMin, this.MAG + args.EffectMax);
             if (RandomSeed.Next(100) > 90) {
                 target.ChangeLife(0, ValueEffects.Failure);
                 return;
             } else if (RandomSeed.Next(100) > 85) {
                 //暴击
                 target.ChangeLife(-damage * 2, ValueEffects.DoubleDecrease);
             } else {
                 target.ChangeLife(-damage, ValueEffects.Decrease);
             }
             //伤害后如果对象生命为0
             if (target.Life == 0) {
                 target.ChangeLife(0, ValueEffects.Death);
                 if (Action == Actions.Attack && !isSpecialMove) { this.Stop(); }
                 this.Target = null;
                 return;
             }
             break;
     }
     //显示魔法附加效果
     if (args.AdditionalEffect != AdditionalEffects.None) {
         EventHandler handler = null;
         AnimationBase animation = new AnimationBase() {
             Code = (int)args.AdditionalEffect,
             Position = target.Center,
             Z = 1000,
         };
         animation.Disposed += handler = (s0, e0) => {
             animation.Disposed -= handler;
             target.RemoveEffect(EffectTypes.Temporary);
         };
         target.AddEffect(animation, EffectTypes.Temporary);
     }
     //魔法特殊效果
     switch (args.SpecialEffect) {
         case SpecialEffects.Injure:
             target.Injure();
             break;
         case SpecialEffects.Bounce:
             target.BeBounce(args.Position, Convert.ToDouble(args.Tag), 500);
             break;
         case SpecialEffects.Knock:
             //target.BeKnock(40);
             break;
         case SpecialEffects.Freeze:
             //测试,50%几率命中
             if (RandomSeed.Next(100) > 50) {
                 target.BeFreeze(Convert.ToDouble(args.Tag));
             }
             break;
         case SpecialEffects.Petrifaction:
             //测试,50%几率命中
             if (RandomSeed.Next(100) > 50) {
                 target.BePetrifaction(Convert.ToDouble(args.Tag));
             }
             break;
         case SpecialEffects.Poison:
             target.BePoison(RandomSeed.Next(200, 500), Convert.ToDouble(args.Tag));
             break;
         case SpecialEffects.Quiver:
             target.Quiver(6);
             break;
     }
 }
 /// <summary>
 /// 移除角色
 /// </summary>
 /// <param name="role">角色对象</param>
 public void RemoveRole(RoleBase role)
 {
     roleList.Remove(role);
     space.Children.Remove(role);
     RemoveShadow(role.ID);
     role.ClearAttacher();
     role.Dispose(role, null);
 }
 /// <summary>
 /// 显示风中粒子
 /// </summary>
 /// <param name="role">所修饰角色</param>
 /// <param name="equipType">所参照的装备</param>
 /// <param name="particleType">粒子类型</param>
 /// <param name="color">颜色</param>
 /// <param name="amount">量</param>
 public void ShowWindParticles(RoleBase role, EquipTypes equipType, ParticleTypes particleType, double color, double amount)
 {
     ObjectBase equip = role.EquipEntity(equipType);
     if (!equip.IsVisible) { return; }
     int distance = 0;
     double speed = 0;
     if (role.Action == Actions.Stop) {
         distance = 40;
         speed = RandomSeed.Next(2000, 3000) * 0.01;
     } else {
         distance = 40;
         speed = RandomSeed.Next(1000, 1500) * 0.01;
     }
     int halfDistance = distance / 2;
     int obliqueDistance = distance * 2 / 3;
     Dispatcher.BeginInvoke(delegate {
         WriteableBitmap writeableBitmap = new WriteableBitmap(equip, null);
         if (writeableBitmap.Pixels.Count() != 0) {
             lock (writeableBitmap) {
                 writeableBitmap.Invalidate();
                 int z = 0;
                 if (equipType == EquipTypes.Weapon) {
                     if (role.State == States.Riding && role.Direction != Directions.South) {
                         z = role.Z + equip.Z + 5;
                     } else {
                         z = role.Z + equip.Z;
                     }
                 } else {
                     z = (role.Direction == Directions.North || role.Direction == Directions.NorthEast || role.Direction == Directions.NorthWest) ? role.Z : role.Z - 20;
                 }
                 z -= role.ZAddition;
                 Point position = equipType == EquipTypes.Overall ? role.Center : equip.Position;
                 Point2D destination = new Point2D();
                 EffectBase effect = null;
                 if (color == 0) {
                     effect = new MonoChrome() { FilterColor = Colors.White };
                 } else if (color == 1) {
                     effect = new MonoChrome() { FilterColor = Colors.Black };
                 } else {
                     effect = new ShiftHue() { HueShift = color };
                 }
                 switch (role.Direction) {
                     case Directions.North:
                         destination.X = 0; destination.Y = RandomSeed.Next(halfDistance, distance);
                         break;
                     case Directions.NorthEast:
                         destination.X = -RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = RandomSeed.Next(halfDistance, obliqueDistance);
                         break;
                     case Directions.East:
                         destination.X = -RandomSeed.Next(halfDistance, distance); destination.Y = 0;
                         break;
                     case Directions.SouthEast:
                         destination.X = -RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = -RandomSeed.Next(halfDistance, obliqueDistance);
                         break;
                     case Directions.South:
                         destination.X = 0; destination.Y = -RandomSeed.Next(halfDistance, distance);
                         break;
                     case Directions.SouthWest:
                         destination.X = RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = -RandomSeed.Next(halfDistance, obliqueDistance);
                         break;
                     case Directions.West:
                         destination.X = RandomSeed.Next(halfDistance, distance); destination.Y = 0;
                         break;
                     case Directions.NorthWest:
                         destination.X = RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = RandomSeed.Next(halfDistance, obliqueDistance);
                         break;
                 }
                 for (int i = 0; i < amount; i++) {
                     int x = RandomSeed.Next(0, writeableBitmap.PixelWidth);
                     int y = RandomSeed.Next(0, writeableBitmap.PixelHeight);
                     byte[] bytes = BitConverter.GetBytes(writeableBitmap.Pixels[writeableBitmap.PixelWidth * y + x]);
                     if (bytes[3] != 0) {
                         Particle particle = new Particle() { SpaceLayer = role.SpaceLayer, Z = z, Effect = effect, Source = GlobalMethod.GetImage(string.Format("Particle/{0}{1}.png", particleType, RandomSeed.Next(0, 3)), UriType.Project) };
                         space.Children.Add(particle);
                         EventHandler handler = null;
                         particle.Disposed += handler = (s, e) => {
                             Particle p = s as Particle;
                             p.Disposed -= handler;
                             space.Children.Remove(p);
                         };
                         double pX = (position.X - x) * particle.Scale;
                         double pY = (position.Y - y) * particle.Scale;
                         particle.Move(new Point(role.Position.X - pX, role.Position.Y - pY), new Point(role.Position.X - pX + destination.X * particle.Scale, role.Position.Y - pY + destination.Y * particle.Scale), speed, MoveModes.Opacity);
                     }
                 }
             }
         }
     });
 }
 /// <summary>
 /// 显示追影(停止动作时不显示)
 /// </summary>
 /// <param name="role">所修饰角色</param>
 /// <param name="equipType">所参照的装备</param>
 /// <param name="color">颜色</param>
 /// <param name="coefficient">系数</param>
 public void ShowChasingShadow(RoleBase role, EquipTypes equipType, Color color, double coefficient)
 {
     if (role.Action != Actions.Stop) {
         ObjectBase equip = role.EquipEntity(equipType);
         if (!equip.IsVisible) { return; }
         WriteableBitmap writeableBitmap = new WriteableBitmap((int)role.OverallSize.X, (int)role.OverallSize.Y);
         writeableBitmap.Render(equip, null);
         writeableBitmap.Invalidate();
         Rectangle rectangle = new Rectangle() { Width = role.OverallSize.X, Height = role.OverallSize.Y, Fill = new SolidColorBrush(color) };
         rectangle.OpacityMask = new ImageBrush() { ImageSource = writeableBitmap };
         writeableBitmap = new WriteableBitmap((int)role.OverallSize.X, (int)role.OverallSize.Y);
         writeableBitmap.Render(rectangle, null);
         writeableBitmap.Invalidate();
         EntityObject chasingShadow = new EntityObject() {
             RenderTransform = role.RenderTransform,
             ImageSource = writeableBitmap,
             Center = role.Center,
             Position = role.Position,
             Z = role.Z - 20
         };
         space.Children.Add(chasingShadow);
         Storyboard storyboard = new Storyboard();
         storyboard.Children.Add(GlobalMethod.CreateDoubleAnimation(chasingShadow,"Opacity",0.7,0, TimeSpan.FromMilliseconds(role.HeartInterval * coefficient),null));
         EventHandler handler = null;
         storyboard.Completed += handler = delegate {
             storyboard.Completed -= handler;
             storyboard.Stop();
             space.Children.Remove(chasingShadow);
         };
         storyboard.Begin();
     }
 }
 /// <summary>
 /// 设置影子与角色动作同步变形(真实光影)
 /// </summary>
 /// <param name="role">角色</param>
 public void SetShadowSyncTo(RoleBase role)
 {
     if (role.IsVisible && ShadowType == ShadowTypes.Reality) {
         EntityObject shadow = shadowList.SingleOrDefault(X => X.ID == role.ID);
         if (shadow != null) {
             WriteableBitmap writeableBitmap = new WriteableBitmap((int)role.OverallSize.X, (int)role.OverallSize.Y);
             writeableBitmap.Render(role.EquipEntity(EquipTypes.Overall), null);
             writeableBitmap.Invalidate();
             Rectangle rectangle = new Rectangle() { Width = role.OverallSize.X, Height = role.OverallSize.Y, Fill = new SolidColorBrush(Colors.Black) };
             rectangle.OpacityMask = new ImageBrush() { ImageSource = writeableBitmap };
             writeableBitmap = new WriteableBitmap((int)role.OverallSize.X, (int)role.OverallSize.Y);
             writeableBitmap.Render(rectangle, null);
             writeableBitmap.Invalidate();
             shadow.ImageSource = writeableBitmap;
             if (shadow.Projection == null) {
                 shadow.Projection = new PlaneProjection() {
                     GlobalOffsetX = -role.Center.X + shadow.Center.X,
                     GlobalOffsetY = -role.Center.Y + shadow.Center.Y,
                     LocalOffsetX = -48,
                     LocalOffsetY = 92,
                     RotationX = 86,
                     RotationY = 7.6
                 };
                 shadow.Opacity = 0.5;
             }
         }
     }
 }
 /// <summary>
 /// 根据中心角色的位置来显示/隐藏对象以提高性能
 /// </summary>
 /// <param name="role">中心角色(参照物)</param>
 public void SetRoleVisibleTo(RoleBase role)
 {
     roleList.ForEach(X => SetSpriteVisible(X, X.InSight(role) ? true : false));
 }
 /// <summary>
 /// 游戏中鼠标左键按下
 /// </summary>
 void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
     leader.ActionTrigger -= role_ActionDecide;
     mouseTimer.Start();
     Point p = e.GetPosition(space);
     List<RoleBase> hitRoles = HitRole(e.GetPosition(LayoutRoot));
     if (mouseButtonClickRole is NPC) {
         NPC npc = (mouseButtonClickRole as NPC);
         if (npc.Action == Actions.Stop) { npc.TurnToDefaultDirection(); }
     }
     bool IsHitRole = false;
     for (int i = 0; i < hitRoles.Count; i++) {
         if (hitRoles[i].InEntityRange(e.GetPosition(hitRoles[i]), (EntityDetectTypes)Convert.ToInt32(((ComboBoxItem)comboBox26.SelectedItem).Tag))) {
             bool isHostile = leader.IsHostileTo(hitRoles[i]);
             if (mouseButtonClickRole != hitRoles[i]) {
                 if (mouseButtonClickRole != null) {
                     //移除上一次点中角色选中特效
                     mouseButtonClickRole.RemoveEffect(EffectTypes.Selected);
                     //移除上一次点中角色的事件
                     mouseButtonClickRole.LifeChanged -= TargetInfo_LifeChanged;
                     mouseButtonClickRole.LifeMaxChanged -= TargetInfo_LifeChanged;
                 }
                 mouseButtonClickRole = hitRoles[i];
                 //注册选中角色更新生命值事件
                 hitRoles[i].LifeChanged += TargetInfo_LifeChanged;
                 hitRoles[i].LifeMaxChanged += TargetInfo_LifeChanged;
                 //更新HUD中目标角色资料
                 targetInfo.Update(hitRoles[i].FullName, hitRoles[i].Life, hitRoles[i].LifeMax);
                 //添加选中特效
                 EventHandler handler = null;
                 AnimationBase animation = new AnimationBase() {
                     Code = isHostile ? 5 : 4,
                     Position = hitRoles[i].Center,
                     Z = -1,
                     Loop = true
                 };
                 animation.Disposed += handler = (s0, e0) => {
                     animation.Disposed -= handler;
                     hitRoles[i].RemoveEffect(EffectTypes.Selected);
                 };
                 hitRoles[i].AddEffect(animation, EffectTypes.Selected);
             }
             //假如点到的是NPC
             if (hitRoles[i] is NPC) {
                 NPC npc = hitRoles[i] as NPC;
                 if (leader.SpaceLayer == npc.SpaceLayer) {
                     leader.TurnTowardsTo(npc.Position);
                     npc.TurnTowardsTo(leader.Position);
                     dramaDialogue.Show(npc.TaskInfo);
                 }
             } else {
                 //主角向敌对目标角色移动
                 if (isHostile) {
                     leader.Target = hitRoles[i];
                     leader.ActionTrigger += role_ActionDecide;
                     if (hitRoles[i].InCircle(leader.Position, leader.AttackRange)) {
                         leader.TurnTowardsTo(hitRoles[i].Position);
                         leader.Attack();
                     } else {
                         leader.MoveTo(hitRoles[i].Position);
                     }
                 }
             }
             targetInfo.IsVisible = true;
             IsHitRole = true;
             break;
         }
     }
     if (!IsHitRole) {
         leader.Target = null;
         targetInfo.IsVisible = false;
         //主角向目标点移动
         leader.MoveTo(p);
         //加入点击水滴特效
         EventHandler handler = null;
         AnimationBase animation = new AnimationBase() {
             Code = 3,
             Position = p,
             Z = -1
         };
         animation.Disposed += handler = delegate {
             animation.Disposed -= handler;
             space.RemoveAnimation(animation);
         };
         space.AddAnimation(animation);
     }
 }
 /// <summary>
 /// 游戏中鼠标移动
 /// </summary>
 void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
 {
     //假如鼠标一直处于按下状态,则主角每隔一段时间向按下的位置移动
     mousePositionOfSpace = e.GetPosition(space);
     //进行角色命中判断
     Point p = e.GetPosition(this);
     //移动图形鼠标
     cursor.Position = p;
     //首先判断是否命中某个角色
     List<RoleBase> hitRoles = HitRole(e.GetPosition(LayoutRoot));
     bool IsHitRole = false;
     for (int i = 0; i < hitRoles.Count; i++) {
         //鼠标位置为角色有效实体区域才算命中该角色
         if (hitRoles[i].InEntityRange(e.GetPosition(hitRoles[i]), (EntityDetectTypes)Convert.ToInt32(((ComboBoxItem)comboBox26.SelectedItem).Tag))) {
             //假如命中的角色于前一选中角色不同则更换选中角色
             if (mouseOverRole != hitRoles[i]) {
                 if (mouseOverRole != null) { mouseOverRole.ShineType = ShineTypes.None; }
                 mouseOverRole = hitRoles[i];
                 //假如主角与目标阵营敌对则更换鼠标指针为攻击图形
                 if (leader.IsHostileTo(hitRoles[i])) {
                     cursor.CursorType = CursorTypes.Attack;
                     hitRoles[i].ShineType = ShineTypes.Red;
                 } else {
                     cursor.CursorType = CursorTypes.Normal;
                     hitRoles[i].ShineType = ShineTypes.Yellow;
                 }
             }
             IsHitRole = true;
             break;
         }
     }
     //假如没有命中任何角色则将前一选中角色取消命中效果
     if (!IsHitRole) {
         if (mouseOverRole != null) { mouseOverRole.ShineType = ShineTypes.None; mouseOverRole = null; }
         cursor.CursorType = CursorTypes.Normal;
     }
 }
 /// <summary>
 /// 主角施法
 /// </summary>
 void LeaderCasting(Point p, int code, RoleBase target)
 {
     leader.Target = null;
     leader.TurnTowardsTo(p);
     leader.Casting(new MagicArgs() {
         Code = code,
         Level = leader.CurrentMagic.Level,
         SpaceLayer = leader.SpaceLayer,
         Scale = leader.Scale,
         Position = leader.Position,
         Destination = p,
         Target = target,
     });
 }
 /// <summary>
 /// 添加角色(带事件注册)
 /// </summary>
 /// <param name="role">角色对象</param>
 /// <param name="e">需注册的事件参数</param>
 public void AddRole(RoleBase role, RoleAddedEventArgs e)
 {
     AddRole(role);
     if (RoleAdded != null) { RoleAdded(role, e); }
 }
 /// <summary>
 /// 根据中心角色的位置来显示/隐藏对象以提高性能
 /// </summary>
 /// <param name="role">中心角色(参照物)</param>
 public void SetAnimationVisibleTo(RoleBase role)
 {
     animationList.ForEach(X => SetAnimationVisible(X, X.InSight(role) ? true : false));
 }
 public override void Run(RoleBase caster, Space space, MagicArgs args)
 {
     caster.ClearAttacher();
     for (int i = 0; i < args.Number; i++) {
         Point p = new Point(caster.Coordinate.X + RandomSeed.Next(-5, 5), caster.Coordinate.Y + RandomSeed.Next(-5, 5));
         if (!space.Terrain.InEffectiveRange(p) || (args.SpaceLayer == SpaceLayers.Ground && space.Terrain.Matrix[(int)p.X, (int)p.Y] == 0)) {
             p = caster.Coordinate;
         }
         AnimationBase magic = new AnimationBase() { Code = args.ResCode, SpaceLayer = args.SpaceLayer, Position = space.Terrain.GetPositionFromCoordinate(p), Z = args.MagicLayer == MagicLayers.Ground ? -1 : (int)args.Position.Y };
         EventHandler handler = null;
         magic.Disposed += handler = delegate {
             magic.Disposed -= handler;
             space.RemoveAnimation(magic);
         };
         space.AddAnimation(magic);
         //解析配置
         XElement xMonster = Infos["Monster"].DescendantsAndSelf("Monsters").Elements().Single(X => X.Attribute("ID").Value == args.AdditionalEffect.ToString());
         Monster monster = new Monster(space.Terrain) {
             ID = (int)xMonster.Attribute("ID") + countID,
             AttachID = caster.AttachID,
             Code = (int)xMonster.Attribute("Code"),
             ArmorCode = (int)xMonster.Attribute("ArmorCode"),
             AttackRange = (int)xMonster.Attribute("AttackRange"),
             FullName = string.Format("{0}的召唤兽", caster.FullName),
             Profession = Professions.Monster,
             Direction = caster.Direction,
             State = States.Walking,
             Camp = caster.Camp,
             LifeMax = Convert.ToDouble(args.Tag),
             Life = Convert.ToDouble(args.Tag),
             SpaceLayer = caster.SpaceLayer,
             Coordinate = p,
             TacticAI = TacticAIs.GuardMaster,
             ActionAI = ActionAIs.Simple,
             FullNameColor = Colors.Orange,
             ATK = ObjectBase.RandomSeed.Next(1300, 1600),
             DEF = ObjectBase.RandomSeed.Next(600, 900),
             MAG = ObjectBase.RandomSeed.Next(400, 500),
             DEX = ObjectBase.RandomSeed.Next(0, 30),
         };
         if (xMonster.Attribute("LearnedMagic").Value != string.Empty) {
             string[] str = xMonster.Attribute("LearnedMagic").Value.Split(',');
             for (int j = 0; j < str.Count(); j++) {
                 string[] value = str[j].Split('_');
                 monster.LearnedMagic.Add(Convert.ToInt32(value[0]), Convert.ToInt32(value[1]));
             }
         }
         space.AddRole(monster, new RoleAddedEventArgs() {
             RegisterDisposedEvent = (bool)xMonster.Attribute("RegisterDisposedEvent"),
             RegisterIntervalTriggerEvent = (bool)xMonster.Attribute("RegisterIntervalTriggerEvent"),
             RegisterActionTriggerEvent = (bool)xMonster.Attribute("RegisterActionTriggerEvent"),
             RegisterDoAttackEvent = (bool)xMonster.Attribute("RegisterDoAttackEvent"),
             RegisterDoCastingEvent = (bool)xMonster.Attribute("RegisterDoCastingEvent"),
             RegisterPositionChangedEvent = (bool)xMonster.Attribute("RegisterPositionChangedEvent"),
             RegisterLifeChangedEvent = (bool)xMonster.Attribute("RegisterLifeChangedEvent"),
         });
         monster.Master = caster;
         caster.AttachRoles.Add(monster);
         countID++;
         if (countID == 10000) { countID = 0; }
     }
 }