using System; using Server; using Server.Mobiles; using System.Xml; namespace Server.Regions { public class DungeonTrapRegion : DungeonRegion { public DungeonTrapRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent) { } public override void OnLocationChanged(Mobile m, Point3D oldLocation) { base.OnLocationChanged(m, oldLocation); if (m is PlayerMobile pm && pm.Alive && pm.AccessLevel == AccessLevel.Player && m.Location != oldLocation) { // We are using 2% (0.02) base chance per step. if (Utility.RandomDouble() < 0.02) { EvaluateTrapSequence(pm); } } } private void EvaluateTrapSequence(PlayerMobile pm) { // --- TIER 1: PASSIVE SEARCHING (Detect Hidden) --- if (pm.Skills[SkillName.DetectHidden].Value >= 5.0) { if (pm.CheckSkill(SkillName.DetectHidden, 0.0, 125.0)) { pm.PlaySound(pm.Female ? 778 : 1049); // Plays a female/male gasp or sigh //pm.LocalOverheadMessage(Server.Network.MessageType.Emote, 0x3B2, false, "You notice a hidden floor mechanism and carefully step around it."); return; } } // --- TIER 2: TRAP AVOIDANCE (Remove Trap) --- if (pm.Skills[SkillName.RemoveTrap].Value >= 5.0) { if (pm.CheckSkill(SkillName.RemoveTrap, 0.0, 125.0)) { pm.PlaySound(0x241); //pm.LocalOverheadMessage(Server.Network.MessageType.Emote, 0x3B2, false, "Your experience with traps allows you to safely bypass a hidden trigger."); return; } } // --- TIER 3: LUCK --- // A simple scale: 1000 Luck = 10% chance to avoid. 2000 Luck = 20% chance. double luckChance = pm.Luck / 10000.0; if (Utility.RandomDouble() < luckChance) { pm.PlaySound(0x241); //pm.LocalOverheadMessage(Server.Network.MessageType.Emote, 0x3B2, false, "With luck on your side, the trap mechanism fails to trigger."); return; } // If they failed all three avoidance checks the trap is sprung. CustomDungeonTraps.TriggerRandomTrap(pm); } } }