public void ResolveCannonHit(Mobile from, Point3D targetLocation) { ArrayList validTargets = new ArrayList(); Map map = Map; BaseBoat boatFrom = BaseBoat.FindBoatAt(from.Location, map); BaseBoat targetBoat = BaseBoat.FindBoatAt(targetLocation, map); bool hitObject = false; bool hitBoat = false; bool showExplosion = true; IPooledEnumerable nearbyMobiles = map.GetMobilesInRange(targetLocation, BaseBoat.CannonExplosionRange); foreach (Mobile mobile in nearbyMobiles) { if (!validTargets.Contains(mobile)) { validTargets.Add(mobile); } } nearbyMobiles.Free(); List <Mobile> m_MobilesOnSourceBoat = new List <Mobile>(); List <Mobile> m_Targets = new List <Mobile>(); double baseCannonDamage = (double)(Utility.RandomMinMax(BaseBoat.CannonDamageMin, BaseBoat.CannonDamageMax)); if (m_Boat == null) { m_MobilesOnSourceBoat.Add(from); } else { baseCannonDamage = m_Boat.CannonDamageScalar * baseCannonDamage; m_MobilesOnSourceBoat = m_Boat.GetMobilesOnBoat(false, false); } bool targetLocationIsBoat = false; if (targetBoat != null) { targetLocationIsBoat = true; m_Targets = targetBoat.GetMobilesOnBoat(false, false); validTargets.Add(targetBoat); } else { m_Targets = new List <Mobile>(); } double damageDealt; for (int a = 0; a < validTargets.Count; ++a) { damageDealt = baseCannonDamage; object target = validTargets[a]; int d = 0; int damage = 0; bool largeCreatureHit = false; PlayerMobile pm_Target; BaseCreature bc_Target; //Large Boss-Size Creature Hit: Don't Deal Damage to Boat Underneath it if (target is Mobile) { bc_Target = target as BaseCreature; if (bc_Target != null) { if (bc_Target.IsChamp() || bc_Target.IsBoss() || bc_Target.IsLoHBoss() || bc_Target.IsEventBoss()) { largeCreatureHit = true; } } } if (target is Mobile) { Mobile mobile = target as Mobile; pm_Target = mobile as PlayerMobile; bc_Target = mobile as BaseCreature; if (!mobile.Alive) { continue; } //Mobile is somehow on boat that cannon is shooting from BaseBoat mobileBoat = BaseBoat.FindBoatAt(mobile.Location, mobile.Map); if (m_Boat != null && mobileBoat != null) { if (m_Boat == mobileBoat) { continue; } } hitObject = true; bool dealDamage = true; bool directHit = false; if (mobile.InRange(targetLocation, 0)) { directHit = true; } bool isOnWater = BaseBoat.IsWaterTile(mobile.Location, mobile.Map); if (from != null || (SpellHelper.ValidIndirectTarget(from, mobile) && from.CanBeHarmful(mobile, false))) { //Player if (pm_Target != null) { damageDealt *= BaseBoat.CannonPlayerDamageMultiplier; } //Creature if (bc_Target != null) { if (bc_Target.IsOceanCreature) { damageDealt *= BaseBoat.CannonOceanCreatureDamageMultiplier; } else { damageDealt *= BaseBoat.CannonMobileDamageMultiplier; } } if (!directHit) { damageDealt *= BaseBoat.CannonIndirectHitDamageMultiplier; } if (dealDamage) { from.DoHarmful(mobile); int finalDamage = (int)Math.Round(damageDealt); BaseCreature bc_Creature = mobile as BaseCreature; if (bc_Creature != null) { bool willKill = false; if (bc_Creature.Hits - finalDamage <= 0) { willKill = true; } bc_Creature.OnGotCannonHit(finalDamage, from, willKill); } new Blood().MoveToWorld(mobile.Location, mobile.Map); AOS.Damage(mobile, from, finalDamage, 100, 0, 0, 0, 0); } } } else if (target is DerelictCargo) { DerelictCargo crate = target as DerelictCargo; crate.TakeDamage(from, (int)damageDealt); } else if (target is BaseBoat && !largeCreatureHit) { BaseBoat boatTarget = target as BaseBoat; if (from != null && m_Boat != null && boatTarget != null) { //Somehow Hitting Own Boat if (m_Boat == boatTarget) { continue; } CannonDoHarmful(from, m_MobilesOnSourceBoat, m_Targets); hitObject = true; hitBoat = true; bool dealDamage = true; if (dealDamage) { DamageType damageType = boatTarget.GetDamageTypeByTargetingMode(m_Boat.TargetingMode); int finalDamage = (int)(Math.Round(damageDealt)); boatTarget.ReceiveDamage(from, m_Boat, finalDamage, damageType); } } } } if (hitObject) { IEntity explosionLocationEntity = new Entity(Serial.Zero, new Point3D(targetLocation.X, targetLocation.Y, targetLocation.Z - 1), map); int explosionHue = 0; int explosionSound = 0x307; if (m_Boat.MobileFactionType == MobileFactionType.Undead) { explosionHue = 2630; explosionSound = 0x56E; } if (showExplosion) { Effects.SendLocationParticles(explosionLocationEntity, Utility.RandomList(14013, 14015, 14027, 14012), 30, 7, explosionHue, 0, 5044, 0); Effects.PlaySound(explosionLocationEntity.Location, map, explosionSound); } } else { Splash(targetLocation, map); } }