예제 #1
0
        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);
            }
        }