diff --git a/Distribution/Data/treasure.cfg b/Distribution/Data/treasure.cfg index 7ca58c917..b31a4d12a 100644 --- a/Distribution/Data/treasure.cfg +++ b/Distribution/Data/treasure.cfg @@ -1,193 +1 @@ -2643 851 -2672 392 -3404 238 -3369 637 -2740 435 -2770 345 -2781 289 -2836 233 -3014 250 -3082 202 -3246 245 -3375 458 -1314 317 -1470 229 -1504 366 -2340 645 -2350 688 -2395 723 -2433 767 -1319 889 -1414 771 -1529 753 -1555 806 -1511 967 -1510 1071 -1562 1058 -961 506 -1162 189 -2337 1159 -2392 1154 -2517 1066 -2458 1042 -1658 2030 -2062 1962 -2089 1987 -2097 1975 -2066 1979 -2058 1992 -2071 2007 -2093 2006 -2187 1991 -1689 1993 -1709 1964 -1726 1998 -1731 2016 -1743 2028 -1754 2020 -2033 1942 -2054 1962 -581 1455 -358 1337 -208 1444 -199 1461 -348 1565 -620 1706 -1027 1180 -1037 1975 -1042 1960 -1042 1903 -1034 1877 -1018 1859 -980 1849 -962 1858 -977 1879 -968 1884 -969 1893 -974 1992 -989 1992 -1024 1990 -2648 2167 -2956 2200 -2968 2170 -2957 2150 -2951 2177 -2629 2221 -2642 2289 -2682 2290 -2727 2309 -2782 2293 -2804 2255 -2850 2252 -2932 2240 -3425 2723 -3476 2761 -3594 2825 -4419 3117 -4471 3188 -4507 3227 -4496 3241 -4642 3369 -4694 3485 -4448 3130 -4453 3148 -4500 3108 -4513 3103 -4424 3152 -4466 3209 -4477 3230 -4477 3282 -2797 3452 -2803 3488 -2793 3519 -2831 3511 -2989 3606 -3035 3603 -1427 2405 -1466 2181 -1519 2214 -1523 2150 -1541 2115 -1534 2189 -1546 2221 -1595 2193 -1619 2236 -1654 2268 -1655 2304 -1433 2381 -1724 2288 -1703 2318 -1772 2321 -1758 2333 -1765 2430 -1647 2641 -1562 2705 -1670 2808 -1471 2340 -1562 2312 -1450 2301 -1437 2294 -1478 2273 -1464 2245 -1439 2217 -1383 2840 -1388 2984 -1415 3059 -1602 3012 -1664 3062 -2062 2144 -2178 2151 -2104 2123 -2098 2101 -2123 2120 -2130 2108 -2129 2132 -2153 2120 -2162 2148 -2186 2144 -492 2027 -477 2044 -451 2053 -468 2087 -465 2100 -958 2504 -1025 2702 -1290 2735 -2013 3269 -2149 3362 -2097 3384 -2039 3427 -2516 3999 -2453 3942 -2528 3982 -2513 3962 -2512 3918 -2513 3901 -2480 3908 -2421 3902 -2415 3920 -2422 3928 -2370 3428 -2341 3482 -2360 3507 -2387 3505 -2152 3950 -2157 3924 -2140 3940 -2143 3986 -2154 3983 -2162 3988 -2467 3581 -2527 3585 -2482 3624 -2535 3608 -1090 3110 -1094 3131 -1073 3133 -1076 3156 -1068 3182 -1096 3178 -1129 3403 -1135 3445 -1162 3469 -1128 3500 \ No newline at end of file +1889 2164 diff --git a/Projects/UOContent/Gumps/TreasureLocationGump.cs b/Projects/UOContent/Gumps/TreasureLocationGump.cs new file mode 100644 index 000000000..dcd8b5f60 --- /dev/null +++ b/Projects/UOContent/Gumps/TreasureLocationGump.cs @@ -0,0 +1,58 @@ +using System; +using Server; +using Server.Gumps; +using Server.Misc; // Needed for NameList.RandomName + +namespace Server.Gumps +{ + public class TreasureLocationGump : Gump + { + public TreasureLocationGump(int level, Point2D loc, Map map) : base(100, 100) + { + Closable = true; + Disposable = true; + Resizable = false; + + AddPage(0); + + AddBackground(0, 0, 350, 260, 9270); + AddAlphaRegion(10, 10, 330, 240); + + // Header + AddHtml(0, 15, 350, 20, $"
Level {level} Treasure Map
", false, false); + + // Fetch the narrative lore + string flavorText = GetFlavorText(level, loc); + + // Story Text Area + AddHtml(25, 50, 300, 120, $"{flavorText}", false, false); + + // Footer / Clean Coordinate Readout + AddHtml(0, 180, 350, 20, $"
Facet: {map.Name}
", false, false); + AddHtml(0, 205, 350, 20, $"
Target Coordinates: {loc.X}, {loc.Y}
", false, false); + } + + private string GetFlavorText(int level, Point2D loc) + { + // We use standard "male" or "female" generic name lists to ensure it never crashes looking for a custom list + string randomMage = NameList.RandomName(Utility.RandomBool() ? "male" : "female"); + + return level switch + { + 1 => $"In my haste I had to dump my treasure at {loc.X}, {loc.Y}. I hope to return for it soon before the scavengers find it.", + + 2 => $"The local guard patrol got too close. I buried the stash at {loc.X}, {loc.Y} and marked the spot. They'll never find it.", + + 3 => $"We lost half the crew to the beasts in these woods. I hid the remaining loot at {loc.X}, {loc.Y} so we can travel light.", + + 4 => $"The dead walk this land. I dared not carry the gold any further. I sealed it away at {loc.X}, {loc.Y}, but I fear they watch it now.", + + 5 => $"The Evil Mage {randomMage} found me! I stashed the treasure at {loc.X}, {loc.Y}. Be warned though, the treasure has a curse on it that I haven't figured out how to break yet.", + + 6 => $"A creature of ancient, unimaginable power claimed this territory. I buried the chest deep at {loc.X}, {loc.Y}. If you are reading this, I am already dead.", + + _ => $"A modest stash of goods hidden away at {loc.X}, {loc.Y}." + }; + } + } +} diff --git a/Projects/UOContent/Items/Maps/TreasureMap.cs b/Projects/UOContent/Items/Maps/TreasureMap.cs index fd2a9d75d..eeddf6b93 100644 --- a/Projects/UOContent/Items/Maps/TreasureMap.cs +++ b/Projects/UOContent/Items/Maps/TreasureMap.cs @@ -8,6 +8,7 @@ using Server.Engines.Harvest; using Server.Mobiles; using Server.Network; using Server.Targeting; +using Server.Gumps; namespace Server.Items; @@ -63,7 +64,7 @@ public partial class TreasureMap : MapItem public TreasureMap(int level, Map map) { _level = level; - _chestMap = map; + _chestMap = Map.Trammel; //map; _chestLocation = level == 0 ? GetRandomHavenLocation() : GetRandomLocation(); @@ -377,7 +378,7 @@ public partial class TreasureMap : MapItem 3 => 51.0, 4 => 61.0, 5 => 70.0, - 6 => 70.0, + 6 => 100.1, _ => 0.0 }; } @@ -452,7 +453,11 @@ public partial class TreasureMap : MapItem } from.PlaySound(0x249); - base.DisplayTo(from); + if (from is PlayerMobile pm) + { + pm.CloseGump(); + pm.SendGump(new TreasureLocationGump(_level, ChestLocation, _chestMap)); + } } public override void GetContextMenuEntries(Mobile from, ref PooledRefList list) diff --git a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs index a839a0858..267d5af18 100644 --- a/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs +++ b/Projects/UOContent/Items/Skill Items/Thief/LockPick.cs @@ -118,14 +118,39 @@ public partial class Lockpick : Item return; } - if (_from.Skills.Lockpicking.Value < _item.RequiredSkill) + // 1. Fetch default lock values (used for doors, house locks, standard crates) + double minSkill = _item.LockLevel; + double maxSkill = _item.MaxLockLevel; + double reqSkill = _item.RequiredSkill; + + // 2. Intercept TreasureMapChest to apply our custom tier math + if (_item is TreasureMapChest tmChest) { - // The LockLevel is higher thant the LockPicking of the player + minSkill = tmChest.Level switch + { + 1 => 15.0, + 2 => 35.0, + 3 => 55.0, + 4 => 75.0, + 5 => 90.0, + 6 => 100.1, // Requires Lockpicking Power Scroll + _ => tmChest.Level * 16.7 + }; + + reqSkill = minSkill; // Sets the floor so they can't even attempt it if too low + maxSkill = minSkill + 25.0; + } + + // 3. Apply the dynamic required skill + if (_from.Skills.Lockpicking.Value < reqSkill) + { + // The LockLevel is higher than the LockPicking of the player item.SendLocalizedMessageTo(_from, 502072); // You don't see how that lock can be manipulated. return; } - if (_from.CheckTargetSkill(SkillName.Lockpicking, _item, _item.LockLevel, _item.MaxLockLevel)) + // 4. Roll the dice using the dynamic min/max variables + if (_from.CheckTargetSkill(SkillName.Lockpicking, _item, minSkill, maxSkill)) { // Success! Pick the lock! item.SendLocalizedMessageTo(_from, 502076); // The lock quickly yields to your skill. diff --git a/Projects/UOContent/Skills/ItemIdentification.cs b/Projects/UOContent/Skills/ItemIdentification.cs index 19ddf585d..e3a160bda 100644 --- a/Projects/UOContent/Skills/ItemIdentification.cs +++ b/Projects/UOContent/Skills/ItemIdentification.cs @@ -21,7 +21,7 @@ public static class ItemIdentification from.SendLocalizedMessage(500343); // What do you wish to appraise and identify? from.Target = new InternalTarget(); - return TimeSpan.FromSeconds(1.0); + return TimeSpan.FromSeconds(3.0); } [PlayerVendorTarget] diff --git a/Projects/UOContent/Skills/RemoveTrap.cs b/Projects/UOContent/Skills/RemoveTrap.cs index 3a80f9e40..912d09804 100644 --- a/Projects/UOContent/Skills/RemoveTrap.cs +++ b/Projects/UOContent/Skills/RemoveTrap.cs @@ -28,7 +28,7 @@ namespace Server.SkillHandlers m.SendLocalizedMessage(502368); // Which trap will you attempt to disarm? } - return TimeSpan.FromSeconds(10.0); // 10 second delay before being able to re-use a skill + return TimeSpan.FromSeconds(5.0); // 5 second delay before being able to re-use a skill } private class InternalTarget : Target @@ -58,7 +58,19 @@ namespace Server.SkillHandlers from.PlaySound(0x241); - if (from.CheckTargetSkill(SkillName.RemoveTrap, targ, targ.TrapPower, targ.TrapPower + 30)) + double minSkill = targ.TrapLevel switch + { + 1 => 15.0, + 2 => 35.0, + 3 => 55.0, + 4 => 75.0, // Level 4: 75.0 Min + 5 => 90.0, // Level 5: 90.0 Min (GM has a 40% chance) + 6 => 100.1, // Level 6: 100.1 Min (Base GM has 0% chance. Requires Power Scroll) + _ => targ.TrapLevel * 16.7 // Fallback for custom Level 7+ maps + }; + double maxSkill = minSkill + 25.0; + + if (from.CheckTargetSkill(SkillName.RemoveTrap, targ, minSkill, maxSkill)) { targ.TrapPower = 0; targ.TrapLevel = 0; diff --git a/Projects/UOContent/Spells/Third/Telekinesis.cs b/Projects/UOContent/Spells/Third/Telekinesis.cs index 47051f92e..247500096 100644 --- a/Projects/UOContent/Spells/Third/Telekinesis.cs +++ b/Projects/UOContent/Spells/Third/Telekinesis.cs @@ -21,6 +21,12 @@ namespace Server.Spells.Third public void Target(Item item) { + if (item is TreasureMapChest) + { + Caster.SendLocalizedMessage(501857); // This spell won't work on that! + return; + } + var t = item as ITelekinesisable; if (!(t != null || item is Container)) {