コード例 #1
0
        public virtual void LaunchProjectile(Mobile from, Item projectile, IEntity target, Point3D targetloc, TimeSpan delay)
        {
            IShipProjectile pitem = projectile as IShipProjectile;

            if (pitem == null)
            {
                return;
            }

            int animationid  = pitem.AnimationID;
            int animationhue = pitem.AnimationHue;

            Effects.PlaySound(target, from.Map, Utility.RandomList(0x11B, 0x11C, 0x11D));

            // show the projectile moving to the target
            XmlBoatFight.SendMovingProjectileEffect(this, target, animationid, ProjectileLaunchPoint, targetloc, 7, 0, false, true, animationhue);

            // delayed damage at the target to account for travel distance of the projectile
            Timer.DelayCall(delay, new TimerStateCallback(DamageTarget_Callback),
                            new object[] { from, this, target, targetloc, projectile });

            return;
        }
コード例 #2
0
        public void OnHit(Mobile from, IShipWeapon weapon, IEntity target, Point3D targetloc)
        {
            if (weapon == null || from == null)
            {
                return;
            }

            // play explosion sound at target

            Effects.PlaySound(targetloc, weapon.Map, 0x11D);

            ArrayList damagelist = new ArrayList();

            // deal with the fact that for multis, the targetloc and the actual multi location may differ
            // so deal the multi damage first
            if (target is BaseMulti)
            {
                XmlBoatFight a = (XmlBoatFight)XmlAttach.FindAttachment(target, typeof(XmlBoatFight));

                if (a != null)
                {
                    damagelist.Add(a);
                }
            }

            // apply splash damage to objects with a siege attachment
            IPooledEnumerable itemlist = from.Map.GetItemsInRange(targetloc, Area);

            if (itemlist != null)
            {
                foreach (Item item in itemlist)
                {
                    if (item == null || item.Deleted)
                    {
                        continue;
                    }

                    XmlBoatFight a = (XmlBoatFight)XmlAttach.FindAttachment(item, typeof(XmlBoatFight));

                    if (a != null && !damagelist.Contains(a))
                    {
                        damagelist.Add(a);
                    }
                    else if (item is AddonComponent)
                    {
                        a = (XmlBoatFight)XmlAttach.FindAttachment(((AddonComponent)item).Addon, typeof(XmlBoatFight));

                        if (a != null && !damagelist.Contains(a))
                        {
                            damagelist.Add(a);
                        }
                    }
                }
            }

            int scaledfiredamage     = (int)(FireDamage * StructureDamageMultiplier * weapon.WeaponDamageFactor);
            int scaledphysicaldamage = (int)(PhysicalDamage * StructureDamageMultiplier * weapon.WeaponDamageFactor);

            foreach (XmlBoatFight a in damagelist)
            {
                // apply siege damage
                a.ApplyScaledDamage(from, scaledfiredamage, scaledphysicaldamage);


                #region HS Ships
                int HitsAfterDamage = a.Hits;
                int HitsMax         = a.HitsMax;

                if (target is BaseGalleon)
                {
                    BaseGalleon targetedGalleon = (BaseGalleon)target;
                    targetedGalleon.Durability = (ushort)(100 * HitsAfterDamage / HitsMax);
                }
                #endregion
            }

            // apply splash damage to mobiles
            ArrayList mobdamage = new ArrayList();

            IPooledEnumerable moblist = from.Map.GetMobilesInRange(targetloc, Area);
            if (moblist != null)
            {
                foreach (Mobile m in moblist)
                {
                    if (m == null || m.Deleted || !from.CanBeHarmful(m, false))
                    {
                        continue;
                    }

                    mobdamage.Add(m);
                }
            }

            int totaldamage = FireDamage + PhysicalDamage;
            if (totaldamage > 0)
            {
                int scaledmobdamage = (int)(totaldamage * MobDamageMultiplier * weapon.WeaponDamageFactor);
                int phys            = 100 * PhysicalDamage / totaldamage;
                int fire            = 100 * FireDamage / totaldamage;
                foreach (Mobile m in mobdamage)
                {
                    // AOS.Damage( Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy )
                    AOS.Damage(m, from, scaledmobdamage, phys, fire, 0, 0, 0);
                }
            }

            // consume the ammunition
            Consume(1);
            weapon.Projectile = this;
        }
コード例 #3
0
        public virtual bool AttackTarget(Mobile from, IEntity target, Point3D targetloc, bool checkLOS)
        {
            IShipProjectile projectile = _projectile as IShipProjectile;

            if (from == null || from.Map == null || projectile == null)
            {
                return(false);
            }

            if (!HasFiringAngle(targetloc))
            {
                from.SendMessage("No firing angle");
                return(false);
            }

            // check the target range
            int distance = (int)XmlBoatFight.GetDistance(targetloc, Location);

            int projectilerange = (int)(projectile.Range * WeaponRangeFactor);

            if (projectilerange < distance)
            {
                from.SendMessage("Out of range");
                return(false);
            }

            if (distance <= MinTargetRange)
            {
                from.SendMessage("Target is too close");
                return(false);
            }

            // check the target line of sight
            int height = 1;

            if (target is Item)
            {
                height = ((Item)target).ItemData.Height;
            }
            else if (target is Mobile)
            {
                height = 14;
            }

            Point3D adjustedloc = new Point3D(targetloc.X, targetloc.Y, targetloc.Z + height);

            if (checkLOS && !Map.LineOfSight(this, adjustedloc))
            {
                from.SendMessage("Cannot see target");
                return(false);
            }

            // ok, the projectile is being fired
            // calculate attack parameters
            double firingspeedbonus = projectile.FiringSpeed / 10.0;
            double dexbonus         = (double)from.Dex / 30.0;
            int    weaponskill      = (int)from.Skills[SkillName.ArmsLore].Value;

            int accuracybonus = projectile.AccuracyBonus;

            // calculate the cooldown time with dexterity bonus and firing speed bonus on top of the base delay
            double loadingdelay = WeaponLoadingDelay - dexbonus - firingspeedbonus;

            _nextFiringTime = DateTime.Now + TimeSpan.FromSeconds(loadingdelay);

            // calculate the accuracy based on distance and weapon skill
            int accuracy = distance * 10 - weaponskill + accuracybonus;

            if (Utility.Random(100) < accuracy)
            {
                from.SendMessage("Target missed");
                // consume the ammunition
                _projectile.Consume(1);
                // update the properties display
                Projectile = _projectile;
                return(true);
            }

            LaunchProjectile(from, _projectile, target, targetloc, TimeSpan.FromSeconds((double)distance * 0.08));

            return(true);
        }