#W# TreasureMaps: Maps now have there own gump. Level 6 maps are locked behind power scrolls. Need a min of 100.1 to attempt them.
This commit is contained in:
parent
c789630cd5
commit
555806150f
7 changed files with 116 additions and 202 deletions
58
Projects/UOContent/Gumps/TreasureLocationGump.cs
Normal file
58
Projects/UOContent/Gumps/TreasureLocationGump.cs
Normal file
|
|
@ -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, $"<CENTER><BASEFONT COLOR=#FFD700>Level {level} Treasure Map</BASEFONT></CENTER>", false, false);
|
||||
|
||||
// Fetch the narrative lore
|
||||
string flavorText = GetFlavorText(level, loc);
|
||||
|
||||
// Story Text Area
|
||||
AddHtml(25, 50, 300, 120, $"<BASEFONT COLOR=#FFFFFF>{flavorText}</BASEFONT>", false, false);
|
||||
|
||||
// Footer / Clean Coordinate Readout
|
||||
AddHtml(0, 180, 350, 20, $"<CENTER><BASEFONT COLOR=#AAAAAA>Facet: {map.Name}</BASEFONT></CENTER>", false, false);
|
||||
AddHtml(0, 205, 350, 20, $"<CENTER><BASEFONT COLOR=#FFFFFF>Target Coordinates: {loc.X}, {loc.Y}</BASEFONT></CENTER>", 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}."
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TreasureLocationGump>();
|
||||
pm.SendGump(new TreasureLocationGump(_level, ChestLocation, _chestMap));
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue