public override void OnThink() { base.OnThink(); if (Combatant != null && DateTime.UtcNow > m_NextMeteorRainAllowed && DateTime.UtcNow > m_NextAbilityAllowed) { double spawnPercent = (double)intervalCount / (double)totalIntervals; int meteors = 30 + (int)(Math.Ceiling(50 * spawnPercent)); int loops = (int)(Math.Ceiling((double)meteors / 10)); double stationaryDelay = loops + 2.5; m_NextMeteorRainAllowed = DateTime.UtcNow + NextMeteorRainDelay + TimeSpan.FromSeconds(stationaryDelay); m_NextAbilityAllowed = DateTime.UtcNow + NextAbilityAllowedDelay + TimeSpan.FromSeconds(stationaryDelay); PlaySound(GetAngerSound()); AIObject.NextMove = DateTime.UtcNow + TimeSpan.FromSeconds(stationaryDelay); LastSwingTime = LastSwingTime + TimeSpan.FromSeconds(stationaryDelay); NextSpellTime = NextSpellTime + TimeSpan.FromSeconds(stationaryDelay); NextCombatHealActionAllowed = NextCombatHealActionAllowed + TimeSpan.FromSeconds(stationaryDelay); NextCombatSpecialActionAllowed = NextCombatSpecialActionAllowed + TimeSpan.FromSeconds(stationaryDelay); NextCombatEpicActionAllowed = NextCombatEpicActionAllowed + TimeSpan.FromSeconds(stationaryDelay); Animate(23, 10, 1, true, false, 0); PublicOverheadMessage(MessageType.Regular, 0, false, "*rains down hellfire*"); Point3D location = Location; Map map = Map; Timer.DelayCall(TimeSpan.FromSeconds(1.0), delegate { if (this == null) { return; } if (this.Deleted) { return; } for (int a = 0; a < loops; a++) { Timer.DelayCall(TimeSpan.FromSeconds(a * 1), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Animate(23, 10, 1, true, false, 0); PlaySound(GetAngerSound()); Effects.PlaySound(location, map, 0x5CF); }); } for (int a = 0; a < meteors; a++) { Timer.DelayCall(TimeSpan.FromSeconds(a * .1), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Point3D meteorLocation = new Point3D(location.X + Utility.RandomMinMax(-8, 8), location.Y + Utility.RandomMinMax(-8, 8), location.Z); IEntity startLocation = new Entity(Serial.Zero, new Point3D(meteorLocation.X - 1, meteorLocation.Y - 1, meteorLocation.Z + 100), map); IEntity endLocation = new Entity(Serial.Zero, new Point3D(meteorLocation.X, meteorLocation.Y, meteorLocation.Z + 5), map); int particleSpeed = 8 + (int)(Math.Round(8 * (double)spawnPercent)); Effects.SendMovingParticles(startLocation, endLocation, 0x36D4, particleSpeed, 0, false, false, 2613, 0, 9501, 0, 0, 0x100); double impactDelay = .75 - (.375 * spawnPercent); Timer.DelayCall(TimeSpan.FromSeconds(impactDelay), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Effects.PlaySound(endLocation, map, 0x56E); Effects.SendLocationParticles(endLocation, 0x3709, 10, 20, 2613, 0, 5029, 0); Blood rocks = new Blood(); rocks.Name = "rocks"; rocks.Hue = 2615; rocks.ItemID = Utility.RandomList(4967, 4970, 4973); Point3D rockLocation = new Point3D(meteorLocation.X, meteorLocation.Y, meteorLocation.Z); rocks.MoveToWorld(rockLocation, map); double firefieldChance = .20 + (.20 * spawnPercent); if (Utility.RandomDouble() <= firefieldChance) { Timer.DelayCall(TimeSpan.FromSeconds(.25), delegate { SingleFireField singleFireField = new SingleFireField(null, 2613, 1, 30, 3, 5, false, false, true, -1, true); singleFireField.MoveToWorld(rockLocation, map); }); } IPooledEnumerable mobilesOnTile = map.GetMobilesInRange(meteorLocation, 1); Queue m_Queue = new Queue(); foreach (Mobile mobile in mobilesOnTile) { if (!mobile.CanBeDamaged() || !mobile.Alive || mobile.AccessLevel > AccessLevel.Player) { continue; } bool validTarget = false; PlayerMobile pm_Target = mobile as PlayerMobile; BaseCreature bc_Target = mobile as BaseCreature; if (pm_Target != null) { validTarget = true; } if (bc_Target != null) { if (bc_Target.Controlled && bc_Target.ControlMaster is PlayerMobile) { validTarget = true; } } if (validTarget) { m_Queue.Enqueue(mobile); } } mobilesOnTile.Free(); while (m_Queue.Count > 0) { Mobile mobile = (Mobile)m_Queue.Dequeue(); double damage = Utility.RandomMinMax((int)(Math.Round((double)DamageMin / 2)), DamageMin); if (mobile is BaseCreature) { damage *= 1.5; } new Blood().MoveToWorld(mobile.Location, mobile.Map); AOS.Damage(mobile, (int)damage, 0, 100, 0, 0, 0); } }); }); } }); return; } if (Combatant != null && DateTime.UtcNow > m_NextFireBlastAllowed && DateTime.UtcNow > m_NextAbilityAllowed) { if (Combatant.Alive && !Combatant.Hidden && InLOS(Combatant) && GetDistanceToSqrt(Combatant) <= 12) { m_NextFireBlastAllowed = DateTime.UtcNow + NextFireBlastDelay; m_NextAbilityAllowed = DateTime.UtcNow + NextAbilityAllowedDelay; double effectTime = 1.5; double actionsCooldown = 3; PlaySound(GetAngerSound()); AIObject.NextMove = DateTime.UtcNow + TimeSpan.FromSeconds(effectTime); LastSwingTime = LastSwingTime + TimeSpan.FromSeconds(effectTime); NextSpellTime = NextSpellTime + TimeSpan.FromSeconds(actionsCooldown); NextCombatHealActionAllowed = NextCombatHealActionAllowed + TimeSpan.FromSeconds(actionsCooldown); NextCombatSpecialActionAllowed = NextCombatSpecialActionAllowed + TimeSpan.FromSeconds(actionsCooldown); NextCombatEpicActionAllowed = NextCombatEpicActionAllowed + TimeSpan.FromSeconds(actionsCooldown); Animate(6, 10, 1, true, false, 0); int itemId = 0x573E; int itemHue = 0; Point3D location = Location; Point3D targetLocation = Combatant.Location; Map map = Combatant.Map; Timer.DelayCall(TimeSpan.FromSeconds(.5), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Effects.PlaySound(targetLocation, map, 0x5FC); IEntity startLocation = new Entity(Serial.Zero, new Point3D(location.X, location.Y, location.Z + 20), map); IEntity endLocation = new Entity(Serial.Zero, new Point3D(targetLocation.X, targetLocation.Y, targetLocation.Z + 10), map); Effects.SendMovingParticles(startLocation, endLocation, 0x36D4, 8, 0, false, false, 2613, 0, 9501, 0, 0, 0x100); double distance = GetDistanceToSqrt(targetLocation); double destinationDelay = (double)distance * .06; Timer.DelayCall(TimeSpan.FromSeconds(destinationDelay), delegate { double spawnPercent = (double)intervalCount / (double)totalIntervals; Effects.PlaySound(targetLocation, map, 0x357); Dictionary <Point3D, double> m_ExplosionLocations = new Dictionary <Point3D, double>(); m_ExplosionLocations.Add(targetLocation, 0); int radius = 2 + (int)(Math.Ceiling(6 * spawnPercent)); int minRange = -1 * radius; int maxRange = radius + 1; for (int a = minRange; a < maxRange; a++) { for (int b = minRange; b < maxRange; b++) { Point3D explosionPoint = new Point3D(targetLocation.X + a, targetLocation.Y + b, targetLocation.Z); int distanceFromCenter = Utility.GetDistance(targetLocation, explosionPoint); double fireburstChance = .25 + (.25 * spawnPercent); if (Utility.RandomDouble() <= fireburstChance) { if (!m_ExplosionLocations.ContainsKey(explosionPoint)) { m_ExplosionLocations.Add(explosionPoint, distance); } } } } foreach (KeyValuePair <Point3D, double> pair in m_ExplosionLocations) { Timer.DelayCall(TimeSpan.FromSeconds(pair.Value * .10), delegate { Point3D explosionLocation = pair.Key; SpellHelper.AdjustField(ref explosionLocation, map, 12, false); Effects.PlaySound(pair.Key, map, 0x56D); Effects.SendLocationParticles(EffectItem.Create(explosionLocation, map, TimeSpan.FromSeconds(0.5)), 0x36BD, 20, 10, 2613, 0, 5044, 0); IPooledEnumerable mobilesOnTile = map.GetMobilesInRange(pair.Key, 0); Queue m_Queue = new Queue(); foreach (Mobile mobile in mobilesOnTile) { if (!mobile.CanBeDamaged() || !mobile.Alive || mobile.AccessLevel > AccessLevel.Player) { continue; } bool validTarget = false; PlayerMobile pm_Target = mobile as PlayerMobile; BaseCreature bc_Target = mobile as BaseCreature; if (pm_Target != null) { validTarget = true; } if (bc_Target != null) { if (bc_Target.Controlled && bc_Target.ControlMaster is PlayerMobile) { validTarget = true; } } if (validTarget) { m_Queue.Enqueue(mobile); } } mobilesOnTile.Free(); while (m_Queue.Count > 0) { Mobile mobile = (Mobile)m_Queue.Dequeue(); double damage = DamageMin; if (mobile is BaseCreature) { damage *= 1.5; } new Blood().MoveToWorld(mobile.Location, mobile.Map); AOS.Damage(mobile, (int)damage, 0, 100, 0, 0, 0); } }); } }); }); } return; } if (Utility.RandomDouble() < .01 && DateTime.UtcNow > m_NextAIChangeAllowed) { Effects.PlaySound(Location, Map, GetAngerSound()); switch (Utility.RandomMinMax(1, 5)) { case 1: DictCombatTargetingWeight[CombatTargetingWeight.Player] = 0; DictCombatTargetingWeight[CombatTargetingWeight.Closest] = 0; DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0; DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints] = 0; break; case 2: DictCombatTargetingWeight[CombatTargetingWeight.Player] = 10; DictCombatTargetingWeight[CombatTargetingWeight.Closest] = 0; DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0; DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints] = 0; break; case 3: DictCombatTargetingWeight[CombatTargetingWeight.Player] = 0; DictCombatTargetingWeight[CombatTargetingWeight.Closest] = 10; DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0; DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints] = 0; break; case 4: DictCombatTargetingWeight[CombatTargetingWeight.Player] = 0; DictCombatTargetingWeight[CombatTargetingWeight.Closest] = 0; DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 10; DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints] = 0; break; case 5: DictCombatTargetingWeight[CombatTargetingWeight.Player] = 0; DictCombatTargetingWeight[CombatTargetingWeight.Closest] = 0; DictCombatTargetingWeight[CombatTargetingWeight.HighestHitPoints] = 0; DictCombatTargetingWeight[CombatTargetingWeight.LowestHitPoints] = 10; break; } m_NextAIChangeAllowed = DateTime.UtcNow + NextAIChangeDelay; } }
protected override void OnThrownAt(Mobile m, IEntity target) { if (m == null || m.Deleted || target == null) { return; } if (ImpactSound >= 0) { Effects.PlaySound(target.Location, target.Map, ImpactSound); } ThrownLast = DateTime.UtcNow; LastUsed = DateTime.UtcNow + ThrowRecovery; if (target is BaseCreature) { var creature = target as BaseCreature; if (creature.Alive) { m.DoHarmful(creature); creature.Damage(Utility.RandomMinMax(5, 20), m); } int range = 1; int zOffset = 10; Point3D src = target.Location.Clone3D(0, 0, zOffset); var points = src.GetAllPointsInRange(target.Map, range, range); Effects.PlaySound(target.Location, target.Map, 0x19C); Timer.DelayCall( TimeSpan.FromMilliseconds(100), () => { foreach (Point3D trg in points) { int bloodID = Utility.RandomMinMax(4650, 4655); new MovingEffectInfo(src, trg.Clone3D(0, 0, 2), target.Map, bloodID).MovingImpact( info => { var blood = new Blood { ItemID = bloodID }; blood.MoveToWorld(info.Target.Location, info.Map); Effects.PlaySound(info.Target, info.Map, 0x028); }); } }); } if (ThrowRecovery > TimeSpan.Zero) { if (UpdateTimer == null) { UpdateTimer = PollTimer.FromSeconds( 1.0, () => { ClearProperties(); Delta(ItemDelta.Properties); DateTime readyWhen = ThrownLast + ThrowRecovery; if (DateTime.UtcNow < readyWhen) { return; } m.EndAction(GetType()); if (UpdateTimer == null) { return; } UpdateTimer.Running = false; UpdateTimer = null; }); } else { UpdateTimer.Running = true; } } else { if (UpdateTimer != null) { UpdateTimer.Running = false; UpdateTimer = null; } ClearProperties(); Delta(ItemDelta.Properties); m.EndAction(GetType()); } }
public virtual void BeginTunnel() { if (this == null) { return; } if (Deleted || !Alive) { return; } int digSound = 0x247; CantWalk = true; Say("*begins to dig a tunnel back to its magical lair*"); SpecialAbilities.HinderSpecialAbility(1.0, this, this, 1.0, 1, true, digSound, false, "", "", "-1"); digging = true; //Dirt int dirtCount = Utility.RandomMinMax(2, 3); for (int b = 0; b < dirtCount; b++) { Blood dirt = new Blood(); dirt.Name = "dirt"; dirt.ItemID = Utility.RandomList(7681, 7682); Point3D dirtLocation = new Point3D(Location.X + Utility.RandomList(-2, -1, 1, 2), Location.Y + Utility.RandomList(-2, -1, 1, 2), Z); dirt.MoveToWorld(dirtLocation, Map); } new BunnyHole().MoveToWorld(Location, Map); Animate(3, 5, 1, true, false, 0); for (int a = 1; a < 5; a++) { Timer.DelayCall(TimeSpan.FromSeconds(a), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Animate(3, 5, 1, true, false, 0); Say("*digs*"); SpecialAbilities.HinderSpecialAbility(1.0, this, this, 1.0, 1, false, digSound, false, "", "", "-1"); //Dirt int extraDirtCount = Utility.RandomMinMax(2, 3); for (int b = 0; b < extraDirtCount; b++) { Blood extraDirt = new Blood(); extraDirt.Name = "dirt"; extraDirt.ItemID = Utility.RandomList(7681, 7682); Point3D extraDirtLocation = new Point3D(Location.X + Utility.RandomList(-2, -1, 1, 2), Location.Y + Utility.RandomList(-2, -1, 1, 2), Z); extraDirt.MoveToWorld(extraDirtLocation, Map); } }); } Timer.DelayCall(TimeSpan.FromSeconds(5.0), delegate { if (this == null) { return; } if (Deleted || !Alive) { return; } Say("*poof*"); Effects.PlaySound(Location, Map, 0x657); Effects.SendLocationParticles(EffectItem.Create(Location, Map, TimeSpan.FromSeconds(5)), 0x3728, 10, 10, 2023); Delete(); }); }