using System.Drawing; using Server.MirDatabase; using S = ServerPackets; namespace Server.MirObjects.Monsters { /// /// Attack1 - Green Poison attack /// Attack2 - Purple Poison attack /// AttackRange1 - Ice Tornado (big range) /// AttackRange2 - Blizzard (big range) /// public class FlyingStatue : MonsterObject { public long _BlizzardCooldown; protected internal FlyingStatue(MonsterInfo info) : base(info) { } protected override bool InAttackRange() { return CurrentMap == Target.CurrentMap && Functions.InRange(CurrentLocation, Target.CurrentLocation, Info.ViewRange); } protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } ShockTime = 0; Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); bool ranged = CurrentLocation == Target.CurrentLocation || !Functions.InRange(CurrentLocation, Target.CurrentLocation, 1); ActionTime = Envir.Time + 600; AttackTime = Envir.Time + AttackSpeed; if (!ranged) { if (Envir.Random.Next(6) != 0) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); int damage = GetAttackPower(Stats[Stat.MinDC], Stats[Stat.MaxDC]); if (damage == 0) return; DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 1100, Target, damage, DefenceType.MACAgility); ActionList.Add(action); } else { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); int damage = GetAttackPower(Stats[Stat.MinMC], Stats[Stat.MaxMC]); if (damage == 0) return; DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 1100, Target, damage, DefenceType.MACAgility); ActionList.Add(action); } } else { SpawnIceTornado(); } } private void SpawnIceTornado() { Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, TargetID = Target.ObjectID, Type = 0 }); List targets = FindAllTargets(Info.ViewRange, CurrentLocation); var count = targets.Count; if (count == 0) return; var target = targets[Envir.Random.Next(count)]; var location = target.CurrentLocation; for (int y = location.Y - 1; y <= location.Y + 1; y++) { if (y < 0) continue; if (y >= CurrentMap.Height) break; for (int x = location.X - 1; x <= location.X + 1; x++) { if (x < 0) continue; if (x >= CurrentMap.Width) break; if (x == CurrentLocation.X && y == CurrentLocation.Y) continue; var cell = CurrentMap.GetCell(x, y); if (!cell.Valid) continue; int damage = GetAttackPower(Stats[Stat.MinMC], Stats[Stat.MaxMC]); var start = 500; SpellObject ob = new SpellObject { Spell = Spell.FlyingStatueIceTornado, Value = damage, ExpireTime = Envir.Time + 1500 + start, TickSpeed = 3000, CurrentLocation = new Point(x, y), CastLocation = location, Show = location.X == x && location.Y == y, CurrentMap = CurrentMap, Caster = this }; DelayedAction action = new DelayedAction(DelayedType.Spawn, Envir.Time + start, ob); CurrentMap.ActionList.Add(action); } } } public override void Spawned() { base.Spawned(); } protected override void ProcessTarget() { if (Target == null) return; if (InAttackRange() && CanAttack) { Attack(); return; } if (Envir.Time < ShockTime) { Target = null; return; } var hpPercent = (HP * 100) / Stats[Stat.HP]; bool halfHealth = hpPercent <= 50; int dist = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); if (dist >= Info.ViewRange || !halfHealth) MoveTo(Target.CurrentLocation); else { MirDirection dir = Functions.DirectionFromPoint(Target.CurrentLocation, CurrentLocation); if (Walk(dir)) return; switch (Envir.Random.Next(2)) //No favour { case 0: for (int i = 0; i < 7; i++) { dir = Functions.NextDir(dir); if (Walk(dir)) return; } break; default: for (int i = 0; i < 7; i++) { dir = Functions.PreviousDir(dir); if (Walk(dir)) return; } break; } } } } }