CrystalSpider.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System.Drawing;
  2. using Server.MirDatabase;
  3. using Server.MirEnvir;
  4. using S = ServerPackets;
  5. namespace Server.MirObjects.Monsters
  6. {
  7. public class CrystalSpider : MonsterObject
  8. {
  9. protected internal CrystalSpider(MonsterInfo info)
  10. : base(info)
  11. {
  12. }
  13. protected override bool InAttackRange()
  14. {
  15. if (Target.CurrentMap != CurrentMap) return false;
  16. if (Target.CurrentLocation == CurrentLocation) return false;
  17. int x = Math.Abs(Target.CurrentLocation.X - CurrentLocation.X);
  18. int y = Math.Abs(Target.CurrentLocation.Y - CurrentLocation.Y);
  19. if (x > 3 || y > 3) return false;
  20. return (x == 0) || (y == 0) || (x == y);
  21. }
  22. protected override void Attack()
  23. {
  24. if (!Target.IsAttackTarget(this))
  25. {
  26. Target = null;
  27. return;
  28. }
  29. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  30. bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1);
  31. if (!ranged) base.Attack();
  32. else
  33. {
  34. ActionTime = Envir.Time + 300;
  35. AttackTime = Envir.Time + AttackSpeed;
  36. ShockTime = 0;
  37. Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 });
  38. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  39. if (damage == 0) return;
  40. LineAttack(damage, 3, 300, DefenceType.MACAgility);
  41. }
  42. }
  43. protected override void CompleteAttack(IList<object> data)
  44. {
  45. MapObject target = (MapObject)data[0];
  46. int damage = (int)data[1];
  47. DefenceType defence = (DefenceType)data[2];
  48. bool attack = data.Count < 4 || (bool)data[3];
  49. if (target == null || !target.IsAttackTarget(this) || target.CurrentMap != CurrentMap || target.Node == null) return;
  50. if (!attack || target.Attacked(this, damage, defence) <= 0) return;
  51. PoisonTarget(target, 8, 5, PoisonType.Green, 2000);
  52. }
  53. protected override void LineAttack(int damage, int distance, int additionalDelay = 500, DefenceType defenceType = DefenceType.ACAgility, bool push = false)
  54. {
  55. for (int i = 1; i <= distance; i++)
  56. {
  57. Point target = Functions.PointMove(CurrentLocation, Direction, i);
  58. if (!CurrentMap.ValidPoint(target)) continue;
  59. Cell cell = CurrentMap.GetCell(target);
  60. if (cell.Objects == null) continue;
  61. for (int o = 0; o < cell.Objects.Count; o++)
  62. {
  63. MapObject ob = cell.Objects[o];
  64. if (ob.Race == ObjectType.Monster || ob.Race == ObjectType.Player)
  65. {
  66. if (!ob.IsAttackTarget(this)) continue;
  67. if (Envir.Random.Next(Settings.MagicResistWeight) >= ob.Stats[Stat.MagicResist])
  68. {
  69. int delay = Functions.MaxDistance(CurrentLocation, ob.CurrentLocation) * 50 + additionalDelay; //50 MS per Step
  70. DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, defenceType, true);
  71. ActionList.Add(action);
  72. }
  73. }
  74. else continue;
  75. break;
  76. }
  77. }
  78. }
  79. }
  80. }