using Server; using System; using Server.Items; using Server.Mobiles; using System.Collections.Generic; using Server.Spells; using Server.Spells.Necromancy; namespace Server.Engines.VvV { public enum VvVTrapType { Explosion = 1015027, // Explosion Poison = 1028000, // Poison Cold = 1113466, // Freezing Energy = 1154942, // Shocking Blade = 1154943, // Blades } public enum DeploymentType { Proximaty = 1154939, Tripwire = 1154940 } public class VvVTrap : Item, IRevealableItem { [CommandProperty(AccessLevel.GameMaster)] public Mobile Owner { get; set; } [CommandProperty(AccessLevel.GameMaster)] public DeploymentType DeploymentType { get; set; } [CommandProperty(AccessLevel.GameMaster)] public VvVTrap ParentTrap { get; set; } public List Links { get; set; } public override bool HandlesOnMovement { get { return true; } } public bool CheckWhenHidden { get { return true; } } public virtual int MinDamage { get { return 0; } } public virtual int MaxDamage { get { return 0; } } public virtual VvVTrapType TrapType { get { return VvVTrapType.Explosion; } } public static int HiddenID = 8600; public static int VisibleID = 39818; public VvVTrap(Mobile owner, DeploymentType type) : base(HiddenID) { Owner = owner; DeploymentType = type; Movable = false; Hue = 0x3D8; } public bool SetTripwire(VvVTrapKit deed, Point3D myLocation, Point3D wireLocation, Map map) { Links = new List(); MovementPath path = new MovementPath(myLocation, wireLocation, map); int x = myLocation.X; int y = myLocation.Y; if(path.Success) { for (int i = 0; i < path.Directions.Length; ++i) { Movement.Movement.Offset(path.Directions[i], ref x, ref y); Point3D p = new Point3D(x, y, this.Map.GetAverageZ(x, y)); if (p == myLocation) continue; VvVTrap trap = deed.ConstructTrap(Owner); Links.Add(trap); trap.ParentTrap = this; trap.MoveToWorld(p, map); } return true; } return false; } public override void OnMovement(Mobile m, Point3D oldLocation) { if(IsEnemy(m) && DeploymentType == DeploymentType.Proximaty && m.InRange(this.Location, 3) && ViceVsVirtueSystem.IsEnemy(m, Owner)) { Detonate(m); } } public bool CheckReveal(Mobile m) { if (!ViceVsVirtueSystem.IsVvV(m) || ItemID != VvVTrap.HiddenID) return false; return Utility.Random(100) <= m.Skills[SkillName.DetectHidden].Value; } public void OnRevealed(Mobile m) { ItemID = VisibleID; if (Links != null) { Links.ForEach(l => { if (!l.Deleted && l.ItemID == HiddenID) l.ItemID = VisibleID; }); } if (ParentTrap != null) { if (ParentTrap.ItemID == HiddenID) ParentTrap.ItemID = VisibleID; ParentTrap.OnRevealed(m); } } public bool CheckPassiveDetect(Mobile m) { if (m.InRange(this.Location, 6)) { int skill = (int)m.Skills[SkillName.DetectHidden].Value; if (skill >= 80 && Utility.Random(600) < skill) this.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x21, 500813, m.NetState); // [trapped] } return false; } public override bool OnMoveOver(Mobile m) { if(IsEnemy(m)) { Detonate(m); } return base.OnMoveOver(m); } public bool IsEnemy(Mobile m) { if(Owner == null) return true; return ViceVsVirtueSystem.IsVvV(m) && ViceVsVirtueSystem.IsVvV(Owner) && ViceVsVirtueSystem.IsEnemy(m, Owner); } public virtual void Detonate(Mobile m) { if(Owner != null) Owner.DoHarmful(m); Delete(); } public override void Delete() { base.Delete(); if (Links != null) { Links.ForEach(l => { if (!l.Deleted) l.Delete(); }); } if (ParentTrap != null && !ParentTrap.Deleted) ParentTrap.Delete(); } public VvVTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); writer.Write(Owner); writer.Write((int)DeploymentType); writer.Write(Links != null ? Links.Count : 0); if (Links != null) { Links.ForEach(l => writer.Write(l)); } writer.Write(ParentTrap); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); Owner = reader.ReadMobile(); DeploymentType = (DeploymentType)reader.ReadInt(); int count = reader.ReadInt(); for (int i = 0; i < count; i++) { if(Links == null) Links = new List(); VvVTrap link = reader.ReadItem() as VvVTrap; if (link != null) Links.Add(link); } ParentTrap = reader.ReadItem() as VvVTrap; } } public class VvVExplosionTrap : VvVTrap { public override int MinDamage { get { return 40; } } public override int MaxDamage { get { return 50; } } public VvVExplosionTrap(Mobile owner, DeploymentType type) : base(owner, type) { } public override void Detonate(Mobile m) { int dam = Utility.RandomMinMax(MinDamage, MaxDamage); if (DeploymentType == DeploymentType.Tripwire) dam *= 2; AOS.Damage(m, Owner, dam, 50, 50, 0, 0, 0); Effects.SendLocationEffect(this.GetWorldLocation(), this.Map, 0x36BD, 15, 10); Effects.PlaySound(this.GetWorldLocation(), this.Map, 0x307); base.Detonate(m); } public VvVExplosionTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); } } public class VvVPoisonTrap : VvVTrap { public override int MinDamage { get { return 25; } } public override int MaxDamage { get { return 35; } } public override VvVTrapType TrapType { get { return VvVTrapType.Poison; } } public VvVPoisonTrap(Mobile owner, DeploymentType type) : base(owner, type) { } public override void Detonate(Mobile m) { int dam = Utility.RandomMinMax(MinDamage, MaxDamage); if (DeploymentType == DeploymentType.Tripwire) dam *= 2; AOS.Damage(m, Owner, dam, 0, 0, 0, 100, 0); m.ApplyPoison(Owner, Poison.Deadly); Effects.SendTargetEffect(m, 0x1145, 3, 16); Effects.PlaySound(this.GetWorldLocation(), this.Map, 0x230); base.Detonate(m); } public VvVPoisonTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); } } public class VvVColdTrap : VvVTrap { public override int MinDamage { get { return 25; } } public override int MaxDamage { get { return 35; } } public override VvVTrapType TrapType { get { return VvVTrapType.Cold; } } public VvVColdTrap(Mobile owner, DeploymentType type) : base(owner, type) { } public override void Detonate(Mobile m) { int dam = Utility.RandomMinMax(MinDamage, MaxDamage); if (DeploymentType == DeploymentType.Tripwire) dam *= 2; AOS.Damage(m, Owner, dam, 0, 0, 100, 0, 0); m.FixedParticles(0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255); m.Paralyze(TimeSpan.FromSeconds(5)); Effects.SendLocationParticles(m, 0x374A, 1, 30, 97, 3, 9502, 0); Effects.PlaySound(this.GetWorldLocation(), this.Map, 0x1FB); base.Detonate(m); } public VvVColdTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); } } public class VvVEnergyTrap : VvVTrap { public override int MinDamage { get { return 25; } } public override int MaxDamage { get { return 35; } } public override VvVTrapType TrapType { get { return VvVTrapType.Energy; } } public VvVEnergyTrap(Mobile owner, DeploymentType type) : base(owner, type) { } public override void Detonate(Mobile m) { int dam = Utility.RandomMinMax(MinDamage, MaxDamage); if (DeploymentType == DeploymentType.Tripwire) dam *= 2; Effects.SendBoltEffect(m, true, 0); AOS.Damage(m, Owner, dam, 0, 0, 100, 0, 0); MortalStrike.BeginWound(m, TimeSpan.FromSeconds(3)); base.Detonate(m); } public VvVEnergyTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); } } public class VvVBladeTrap : VvVTrap { public override int MinDamage { get { return 25; } } public override int MaxDamage { get { return 35; } } public override VvVTrapType TrapType { get { return VvVTrapType.Blade; } } public VvVBladeTrap(Mobile owner, DeploymentType type) : base(owner, type) { } public override void Detonate(Mobile m) { int dam = Utility.RandomMinMax(MinDamage, MaxDamage); if (DeploymentType == DeploymentType.Tripwire) dam *= 2; AOS.Damage(m, Owner, dam, 100, 0, 0, 0, 0); Effects.SendLocationEffect(m.Location, m.Map, 0x11AD, 25, 10); Effects.PlaySound(m.Location, m.Map, 0x218); TransformContext context = TransformationSpellHelper.GetContext(m); if ((context != null && (context.Type == typeof(LichFormSpell) || context.Type == typeof(WraithFormSpell))) || (m is BaseCreature && ((BaseCreature)m).BleedImmune)) return; m.SendLocalizedMessage(1060160); // You are bleeding! BleedAttack.BeginBleed(m, Owner, false); base.Detonate(m); } public VvVBladeTrap(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); } } }