public override void GetProperties(ObjectPropertyList list) { base.GetProperties(list); IShipWeapon weapon = Addon as IShipWeapon; if (weapon == null) { return; } if (weapon.Projectile == null || weapon.Projectile.Deleted) { //list.Add(1061169, "empty"); // range ~1_val~ list.Add(1042975); // It's empty } else { list.Add(500767); // Reloaded list.Add(1060658, "Type\t{0}", weapon.Projectile.Name); // ~1_val~: ~2_val~ ISiegeProjectile projectile = weapon.Projectile as ISiegeProjectile; if (projectile != null) { list.Add(1061169, projectile.Range.ToString()); // range ~1_val~ } } }
protected override void OnTick() { ISiegeProjectile pitem = m_Projectile as ISiegeProjectile; if (m_weapon != null && !m_weapon.Deleted && pitem != null) { int animationid = pitem.AnimationID; int animationhue = pitem.AnimationHue; switch (m_step) { case 0: case 4: m_weapon.DisplayLaunch(0); break; case 1: case 3: m_weapon.DisplayLaunch(1); break; case 2: m_weapon.DisplayLaunch(2); // launch sounds Effects.PlaySound(m_weapon, m_weapon.Map, 0x4C9); Effects.PlaySound(m_weapon, m_weapon.Map, 0x2B2); // show the projectile moving to the target /* * if (m_target is Mobile) * { * XmlSiege.SendMovingProjectileEffect(m_weapon, null, animationid, m_weapon.ProjectileLaunchPoint, m_targetloc, 7, 0, false, true, animationhue); * } * else * { * XmlSiege.SendMovingProjectileEffect(m_weapon, m_target, animationid, m_weapon.ProjectileLaunchPoint, m_targetloc, 7, 0, false, true, animationhue); * } * */ // delayed damage at the target to account for travel distance of the projectile Timer.DelayCall(m_damagedelay, new TimerStateCallback(m_weapon.DamageTarget_Callback), new object[] { m_from, m_weapon, m_target, m_targetloc, m_Projectile }); break; } // advance to the next step m_weapon.DoTimer(m_from, m_weapon, m_target, m_targetloc, m_Projectile, m_damagedelay, ++m_step); } }
public virtual void DamageTarget_Callback(object state) { object[] args = (object[])state; Mobile from = (Mobile)args[0]; BaseSiegeWeapon weapon = (BaseSiegeWeapon)args[1]; IEntity target = (IEntity)args[2]; Point3D targetloc = (Point3D)args[3]; Item pitem = (Item)args[4]; ISiegeProjectile projectile = pitem as ISiegeProjectile; if (projectile != null) { projectile.OnHit(from, weapon, target, targetloc); } }
public virtual void LaunchProjectile(Mobile from, Item projectile, IEntity target, Point3D targetloc, TimeSpan delay) { ISiegeProjectile pitem = projectile as ISiegeProjectile; if (pitem == null) { return; } int animationid = pitem.AnimationID; int animationhue = pitem.AnimationHue; // show the projectile moving to the target XmlSiege.SendMovingProjectileEffect(this, target, animationid, this.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; }
public virtual bool AttackTarget(Mobile from, IEntity target, Point3D targetloc, bool checkLOS) { ISiegeProjectile projectile = this.m_Projectile as ISiegeProjectile; if (from == null || from.Map == null || projectile == null) { return(false); } if (!this.HasFiringAngle(targetloc)) { from.SendMessage("No firing angle"); return(false); } // check the target range int distance = (int)XmlSiege.GetDistance(targetloc, this.Location); int projectilerange = (int)(projectile.Range * this.WeaponRangeFactor); if (projectilerange < distance) { from.SendMessage("Out of range"); return(false); } if (distance <= this.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 && !this.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 = this.WeaponLoadingDelay - dexbonus - firingspeedbonus; this.m_NextFiringTime = DateTime.UtcNow + 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 this.m_Projectile.Consume(1); // update the properties display this.Projectile = this.m_Projectile; return(true); } this.LaunchProjectile(from, this.m_Projectile, target, targetloc, TimeSpan.FromSeconds((double)distance * 0.08)); return(true); }
public virtual bool AttackTarget(Mobile from, IEntity target, Point3D targetloc, bool checkLOS) { ISiegeProjectile projectile = m_Projectile as ISiegeProjectile; 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)XmlSiege.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; // calculate the cooldown time with dexterity bonus and firing speed bonus on top of the base delay double loadingdelay = WeaponLoadingDelay - dexbonus - firingspeedbonus; m_NextFiringTime = DateTime.UtcNow + TimeSpan.FromSeconds(loadingdelay); LaunchProjectile(from, m_Projectile, target, targetloc, TimeSpan.FromSeconds((double)distance * 0.05)); return(true); }