SepTaoist.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using System.Drawing;
  2. using System.Linq;
  3. using Server.MirDatabase;
  4. using Server.MirEnvir;
  5. using S = ServerPackets;
  6. namespace Server.MirObjects.Monsters
  7. {
  8. public class SepTaoist : MonsterObject
  9. {
  10. public long FearTime, DecreaseMPTime;
  11. public byte AttackRange = 5;
  12. public bool Summoned;
  13. protected internal SepTaoist(MonsterInfo info)
  14. : base(info)
  15. {
  16. }
  17. protected override bool InAttackRange()
  18. {
  19. return CurrentMap == Target.CurrentMap && Functions.InRange(CurrentLocation, Target.CurrentLocation, Info.ViewRange);
  20. }
  21. protected override void Attack()
  22. {
  23. if (!Target.IsAttackTarget(this))
  24. {
  25. Target = null;
  26. return;
  27. }
  28. ShockTime = 0;
  29. ActionTime = Envir.Time + 300;
  30. AttackTime = Envir.Time + AttackSpeed;
  31. int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]);
  32. if (damage == 0) return;
  33. Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation);
  34. DelayedAction action;
  35. int delay = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation) * 50 + 500; //50 MS per Step
  36. if (!Target.PoisonList.Any(x => x.PType == PoisonType.Green) && !Target.PoisonList.Any(x => x.PType == PoisonType.Red))
  37. {
  38. Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = Spell.Poisoning, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Cast = true, Level = 3 });
  39. int power = GetAttackPower(Stats[Stat.MinSC], Stats[Stat.MaxSC]);
  40. Target.ApplyPoison(new Poison
  41. {
  42. Duration = power + ((Envir.Random.Next(0, 3) + 1) * 7),
  43. Owner = this,
  44. PType = PoisonType.Green,
  45. TickSpeed = 2000,
  46. Value = power / 15 + 4
  47. }, this);
  48. return;
  49. }
  50. else if (Target.PoisonList.Any(x => x.PType == PoisonType.Green) && !Target.PoisonList.Any(x => x.PType == PoisonType.Red))
  51. {
  52. Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = Spell.Poisoning, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Cast = true, Level = 3 });
  53. int power = GetAttackPower(Stats[Stat.MinSC], Stats[Stat.MaxSC]);
  54. Target.ApplyPoison(new Poison
  55. {
  56. Duration = power + ((Envir.Random.Next(0, 3) + 1) * 7),
  57. Owner = this,
  58. PType = PoisonType.Red,
  59. TickSpeed = 2000,
  60. }, this);
  61. return;
  62. }
  63. else if (!Target.PoisonList.Any(x => x.PType == PoisonType.Green) && Target.PoisonList.Any(x => x.PType == PoisonType.Red))
  64. {
  65. Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = Spell.Poisoning, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Cast = true, Level = 3 });
  66. int power = GetAttackPower(Stats[Stat.MinSC], Stats[Stat.MaxSC]);
  67. Target.ApplyPoison(new Poison
  68. {
  69. Duration = power + ((Envir.Random.Next(0, 3) + 1) * 7),
  70. Owner = this,
  71. PType = PoisonType.Green,
  72. TickSpeed = 2000,
  73. }, this);
  74. return;
  75. }
  76. if (!Target.Buffs.Any(e => e.Type == BuffType.Curse) && Envir.Random.Next(8) == 0)
  77. {
  78. Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = Spell.Curse, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Cast = true, Level = 3 });
  79. PoisonTarget(Target, 1, 5, PoisonType.Slow, 1000);
  80. return;
  81. }
  82. Broadcast(new S.ObjectMagic { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Spell = Spell.SoulFireBall, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Cast = true, Level = 3 });
  83. action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, Target, damage, DefenceType.MACAgility);
  84. ActionList.Add(action);
  85. if (Target.Dead)
  86. FindTarget();
  87. }
  88. protected override void ProcessTarget()
  89. {
  90. if (Target == null || !CanAttack) return;
  91. if (!InAttackRange())
  92. {
  93. if (CurrentLocation == Target.CurrentLocation)
  94. {
  95. MirDirection direction = (MirDirection)Envir.Random.Next(8);
  96. int rotation = Envir.Random.Next(2) == 0 ? 1 : -1;
  97. for (int d = 0; d < 8; d++)
  98. {
  99. if (Walk(direction)) break;
  100. direction = Functions.ShiftDirection(direction, rotation);
  101. }
  102. }
  103. else
  104. MoveTo(Target.CurrentLocation);
  105. }
  106. if (!CanAttack) return;
  107. if (InAttackRange() && Envir.Time < FearTime)
  108. {
  109. Attack();
  110. return;
  111. }
  112. FearTime = Envir.Time + 5000;
  113. if (Envir.Time < ShockTime)
  114. {
  115. Target = null;
  116. return;
  117. }
  118. int dist = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation);
  119. if (dist < AttackRange)
  120. {
  121. MirDirection dir = Functions.DirectionFromPoint(Target.CurrentLocation, CurrentLocation);
  122. if (Walk(dir)) return;
  123. switch (Envir.Random.Next(2)) //No favour
  124. {
  125. case 0:
  126. for (int i = 0; i < 7; i++)
  127. {
  128. dir = Functions.NextDir(dir);
  129. if (Walk(dir))
  130. return;
  131. }
  132. break;
  133. default:
  134. for (int i = 0; i < 7; i++)
  135. {
  136. dir = Functions.PreviousDir(dir);
  137. if (Walk(dir))
  138. return;
  139. }
  140. break;
  141. }
  142. }
  143. }
  144. public bool Walk(MirDirection dir, bool br = false)
  145. {
  146. if (!CanMove) return false;
  147. var temploc = Functions.PointMove(CurrentLocation, dir, 1);
  148. if (!CurrentMap.ValidPoint(temploc)) return false;
  149. var cell = CurrentMap.GetCell(temploc);
  150. if (cell.Objects != null)
  151. for (int i = 0; i < cell.Objects.Count; i++)
  152. {
  153. MapObject ob = cell.Objects[i];
  154. if (!ob.Blocking) continue;
  155. return false;
  156. }
  157. Point location = Functions.PointMove(CurrentLocation, dir, 2);
  158. if (!CurrentMap.ValidPoint(location)) return false;
  159. cell = CurrentMap.GetCell(location);
  160. bool isBreak = br;
  161. if (cell.Objects != null)
  162. for (int i = 0; i < cell.Objects.Count; i++)
  163. {
  164. MapObject ob = cell.Objects[i];
  165. if (!ob.Blocking) continue;
  166. isBreak = true;
  167. break;
  168. }
  169. if (isBreak)
  170. {
  171. location = Functions.PointMove(CurrentLocation, dir, 1);
  172. if (!CurrentMap.ValidPoint(location)) return false;
  173. cell = CurrentMap.GetCell(location);
  174. if (cell.Objects != null)
  175. for (int i = 0; i < cell.Objects.Count; i++)
  176. {
  177. MapObject ob = cell.Objects[i];
  178. if (!ob.Blocking) continue;
  179. return false;
  180. }
  181. }
  182. CurrentMap.GetCell(CurrentLocation).Remove(this);
  183. Direction = dir;
  184. RemoveObjects(dir, 1);
  185. CurrentLocation = location;
  186. CurrentMap.GetCell(CurrentLocation).Add(this);
  187. AddObjects(dir, 1);
  188. if (Hidden)
  189. {
  190. Hidden = false;
  191. for (int i = 0; i < Buffs.Count; i++)
  192. {
  193. if (Buffs[i].Type != BuffType.Hiding) continue;
  194. Buffs[i].ExpireTime = 0;
  195. break;
  196. }
  197. }
  198. CellTime = Envir.Time + 500;
  199. ActionTime = Envir.Time + 300;
  200. MoveTime = Envir.Time + MoveSpeed;
  201. if (MoveTime > AttackTime)
  202. AttackTime = MoveTime;
  203. InSafeZone = CurrentMap.GetSafeZone(CurrentLocation) != null;
  204. if (isBreak)
  205. Broadcast(new S.ObjectWalk { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
  206. else
  207. Broadcast(new S.ObjectRun { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
  208. cell = CurrentMap.GetCell(CurrentLocation);
  209. for (int i = 0; i < cell.Objects.Count; i++)
  210. {
  211. if (cell.Objects[i].Race != ObjectType.Spell) continue;
  212. SpellObject ob = (SpellObject)cell.Objects[i];
  213. ob.ProcessSpell(this);
  214. //break;
  215. }
  216. return true;
  217. }
  218. public override void Die()
  219. {
  220. if (Dead) return;
  221. HP = 0;
  222. Dead = true;
  223. DeadTime = 0;
  224. Broadcast(new S.ObjectDied { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = (byte)(Master != null ? 1 : 0) });
  225. if (EXPOwner != null && Master == null && EXPOwner.Race == ObjectType.Player) EXPOwner.WinExp(Experience, Level);
  226. if (Respawn != null)
  227. Respawn.Count--;
  228. if (Master == null)
  229. Drop();
  230. Master = null;
  231. PoisonList.Clear();
  232. Envir.MonsterCount--;
  233. if (CurrentMap != null)
  234. CurrentMap.MonsterCount--;
  235. }
  236. public override Packet GetInfo()
  237. {
  238. PlayerObject master = null;
  239. short weapon = -1;
  240. short armour = 0;
  241. byte wing = 0;
  242. if (Master != null && Master is PlayerObject)
  243. master = (PlayerObject)Master;
  244. if (master != null)
  245. {
  246. weapon = master.Looks_Weapon;
  247. armour = master.Looks_Armour;
  248. wing = master.Looks_Wings;
  249. }
  250. return new S.ObjectPlayer
  251. {
  252. ObjectID = ObjectID,
  253. Name = master != null ? master.Name : Name,
  254. NameColour = NameColour,
  255. Class = MirClass.Taoist,
  256. Gender = master != null ? master.Gender : Envir.Random.Next(2) == 0 ? MirGender.Male : MirGender.Female,
  257. Location = CurrentLocation,
  258. Direction = Direction,
  259. Hair = master != null ? master.Hair : (byte)Envir.Random.Next(0, 5),
  260. Weapon = 31,
  261. Armour = 8,
  262. Light = master != null ? master.Light : Light,
  263. Poison = CurrentPoison,
  264. Dead = Dead,
  265. Hidden = Hidden,
  266. Effect = SpellEffect.None,
  267. WingEffect = wing,
  268. Extra = Summoned,
  269. TransformType = -1,
  270. };
  271. }
  272. }
  273. }