diff --git a/Projects/Server/Text/TextDefinitionExtensions.cs b/Projects/Server/Text/TextDefinitionExtensions.cs
index ddf95dfe4..7ceb037c5 100644
--- a/Projects/Server/Text/TextDefinitionExtensions.cs
+++ b/Projects/Server/Text/TextDefinitionExtensions.cs
@@ -27,8 +27,8 @@ public static class TextDefinitionExtensions
int y,
int width,
int height,
- bool back,
- bool scroll,
+ bool back = false,
+ bool scroll = false,
int numberColor = -1,
int stringColor = -1
)
@@ -70,6 +70,51 @@ public static class TextDefinitionExtensions
}
}
+ public static void AddHtmlText(
+ this TextDefinition def,
+ Gump g,
+ int x,
+ int y,
+ int width,
+ int height,
+ string args,
+ bool back = false,
+ bool scroll = false,
+ int numberColor = -1,
+ int stringColor = -1
+ )
+ {
+ if (def == null)
+ {
+ return;
+ }
+
+ if (def.Number > 0)
+ {
+ // 5 bits per RGB component (15 bit RGB)
+ g.AddHtmlLocalized(x, y, width, height, def.Number, args, numberColor >= 0 ? numberColor : 0x7FFF, back, scroll);
+ }
+ else if (def.String != null)
+ {
+ if (stringColor >= 0) // 8 bits per RGB component (24 bit RGB)
+ {
+ g.AddHtml(
+ x,
+ y,
+ width,
+ height,
+ $"{string.Format(def.String, args)}",
+ back,
+ scroll
+ );
+ }
+ else
+ {
+ g.AddHtml(x, y, width, height, string.Format(def.String, args), back, scroll);
+ }
+ }
+ }
+
public static void AddTo(this TextDefinition def, IPropertyList list)
{
if (def == null)
diff --git a/Projects/UOContent/Items/Resources/Arrows/Arrow.cs b/Projects/UOContent/Items/Resources/Arrows/Arrow.cs
index 0478b8d6e..e0ef7dd6c 100644
--- a/Projects/UOContent/Items/Resources/Arrows/Arrow.cs
+++ b/Projects/UOContent/Items/Resources/Arrows/Arrow.cs
@@ -2,7 +2,7 @@ using ModernUO.Serialization;
namespace Server.Items;
-[SerializationGenerator(0)]
+[SerializationGenerator(0, false)]
public partial class Arrow : Item, ICommodity
{
[Constructible]
diff --git a/Projects/UOContent/Items/Resources/Arrows/Bolt.cs b/Projects/UOContent/Items/Resources/Arrows/Bolt.cs
index 21e43d734..ed20748bf 100644
--- a/Projects/UOContent/Items/Resources/Arrows/Bolt.cs
+++ b/Projects/UOContent/Items/Resources/Arrows/Bolt.cs
@@ -2,7 +2,7 @@ using ModernUO.Serialization;
namespace Server.Items;
-[SerializationGenerator(0)]
+[SerializationGenerator(0, false)]
public partial class Bolt : Item, ICommodity
{
[Constructible]
diff --git a/Projects/UOContent/Items/Resources/Arrows/Feather.cs b/Projects/UOContent/Items/Resources/Arrows/Feather.cs
index 755d35b41..3a005da64 100644
--- a/Projects/UOContent/Items/Resources/Arrows/Feather.cs
+++ b/Projects/UOContent/Items/Resources/Arrows/Feather.cs
@@ -2,7 +2,7 @@ using ModernUO.Serialization;
namespace Server.Items;
-[SerializationGenerator(0)]
+[SerializationGenerator(0, false)]
public partial class Feather : Item, ICommodity
{
[Constructible]
diff --git a/Projects/UOContent/Items/Resources/Arrows/Shaft.cs b/Projects/UOContent/Items/Resources/Arrows/Shaft.cs
index 165aca730..0e7dafa90 100644
--- a/Projects/UOContent/Items/Resources/Arrows/Shaft.cs
+++ b/Projects/UOContent/Items/Resources/Arrows/Shaft.cs
@@ -2,7 +2,7 @@ using ModernUO.Serialization;
namespace Server.Items;
-[SerializationGenerator(0)]
+[SerializationGenerator(0, false)]
public partial class Shaft : Item, ICommodity
{
[Constructible]
diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/MessageInABottle.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/MessageInABottle.cs
index 9e4d5f050..24ab427af 100644
--- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/MessageInABottle.cs
+++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/MessageInABottle.cs
@@ -1,110 +1,62 @@
using System;
+using ModernUO.Serialization;
using Server.Network;
-namespace Server.Items
+namespace Server.Items;
+
+[SerializationGenerator(0, false)]
+public partial class MessageInABottle : Item
{
- public class MessageInABottle : Item
+ [SerializableField(1)]
+ private Map _targetMap;
+
+ [Constructible]
+ public MessageInABottle(Map map = null) : this(map, GetRandomLevel())
{
- private int m_Level;
+ }
- [Constructible]
- public MessageInABottle(Map map = null) : this(map, GetRandomLevel())
+ [Constructible]
+ public MessageInABottle(Map map, int level) : base(0x099F)
+ {
+ Weight = 1.0;
+ TargetMap = map ?? Map.Trammel;
+ _level = level;
+ }
+
+ public override int LabelNumber => 1041080; // a message in a bottle
+
+ [CommandProperty(AccessLevel.GameMaster)]
+ [SerializableProperty(0)]
+ public int Level
+ {
+ get => _level;
+ set
{
+ _level = Math.Max(1, Math.Min(value, 4));
+ this.MarkDirty();
+ }
+ }
+
+ public static int GetRandomLevel()
+ {
+ if (Core.AOS && Utility.Random(25) < 1)
+ {
+ return 4; // ancient
}
- [Constructible]
- public MessageInABottle(Map map, int level) : base(0x099F)
+ return Utility.RandomMinMax(1, 3);
+ }
+
+ public override void OnDoubleClick(Mobile from)
+ {
+ if (IsChildOf(from.Backpack))
{
- Weight = 1.0;
- TargetMap = map ?? Map.Trammel;
- m_Level = level;
+ ReplaceWith(new SOS(TargetMap, _level));
+ from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501891); // You extract the message from the bottle.
}
-
- public MessageInABottle(Serial serial) : base(serial)
+ else
{
- }
-
- public override int LabelNumber => 1041080; // a message in a bottle
-
- [CommandProperty(AccessLevel.GameMaster)]
- public Map TargetMap { get; set; }
-
- [CommandProperty(AccessLevel.GameMaster)]
- public int Level
- {
- get => m_Level;
- set => m_Level = Math.Max(1, Math.Min(value, 4));
- }
-
- public static int GetRandomLevel()
- {
- if (Core.AOS && Utility.Random(25) < 1)
- {
- return 4; // ancient
- }
-
- return Utility.RandomMinMax(1, 3);
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(3); // version
-
- writer.Write(m_Level);
-
- writer.Write(TargetMap);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- switch (version)
- {
- case 3:
- case 2:
- {
- m_Level = reader.ReadInt();
- goto case 1;
- }
- case 1:
- {
- TargetMap = reader.ReadMap();
- break;
- }
- case 0:
- {
- TargetMap = Map.Trammel;
- break;
- }
- }
-
- if (version < 2)
- {
- m_Level = GetRandomLevel();
- }
-
- if (version < 3 && TargetMap == Map.Tokuno)
- {
- TargetMap = Map.Trammel;
- }
- }
-
- public override void OnDoubleClick(Mobile from)
- {
- if (IsChildOf(from.Backpack))
- {
- ReplaceWith(new SOS(TargetMap, m_Level));
- from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501891); // You extract the message from the bottle.
- }
- else
- {
- from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
- }
+ from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
}
diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs
index 26a0f6b7a..20a277170 100644
--- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs
+++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/SOS.cs
@@ -1,397 +1,298 @@
using System;
+using ModernUO.Serialization;
using Server.Gumps;
-namespace Server.Items
+namespace Server.Items;
+
+[Flippable(0x14ED, 0x14EE)]
+[SerializationGenerator(0, false)]
+public partial class SOS : Item
{
- [Flippable(0x14ED, 0x14EE)]
- public class SOS : Item
+ // We can only speculate, but I lack of support for non-ascii arguments in localized html gumps is why this wasn't used.
+ // By default let's use the old gump, because we can.
+ private static bool UseNewMessages = false;
+
+ private static int[] WaterTiles =
{
- private static readonly int[] m_WaterTiles =
- {
- 0x00A8, 0x00AB,
- 0x0136, 0x0137
- };
+ 0x00A8, 0x00AB,
+ 0x0136, 0x0137
+ };
- private static readonly Rectangle2D[] m_BritRegions = { new(0, 0, 5120, 4096) };
+ private static Rectangle2D[] BritRegions = { new(0, 0, 5120, 4096) };
- private static readonly Rectangle2D[] m_IlshRegions =
- { new(1472, 272, 304, 240), new(1240, 1000, 312, 160) };
+ private static Rectangle2D[] IlshRegions =
+ { new(1472, 272, 304, 240), new(1240, 1000, 312, 160) };
- private static readonly Rectangle2D[] m_MalasRegions = { new(1376, 1520, 464, 280) };
+ private static Rectangle2D[] MalasRegions = { new(1376, 1520, 464, 280) };
- private int m_Level;
+ private static TextDefinition[] MessageEntries =
+ {
+ // Help! Ship going do...n heavy storms...precious cargo...st reach dest...current coordinates ~1_SEXTANT~...ve any survivors...ease!
+ 1153537,
+ // ...was a cad and a boor, no matter what momma s...rew him overboard! Oh, Anna, 'twas so exciting! Unfort...y he grabbe...est, and all his riches went with him! ...sked the captain, and he says we're at ~1_SEXTANT~ ... so maybe ...
+ 1153538,
+ // ...know that the wreck is near ~1_SEXTANT~ but have not found it. Could the message passed down in my family for generations be wrong? No... I swear on the soul of my grandfather, I will find...
+ 1153539,
+ // ...Ar! ~1_SEXTANT~ and, a fair wind! No chance...storms, though--ar! Is that a sea serp...
uh oh.
+ 1153540,
+ // WANTED: divers exp...d in shipwre...overy. Must have own vess...pply at ~1_SEXTANT~...good benefits, flexible hours...
+ 1153541,
+ // ...isaster indeed. Capt. McQ...overboard, fear the worst. These are t...ast days of the good ship Norr...ast known position was ~1_SEXTANT~ but ...'re beyond salvag...
+ 1153542,
+ // ...never expected an iceberg...silly woman on bow crushed instantly...send help to ~1_SEXTANT~...ey'll never forget the tragedy of the sinking of the...
+ 1153543,
+ // ...so I threw the treasure overboard, before the curse could get me too. But I was too late. Now I am doomed to wander these seas, a ghost forever. Join me: seek ye at ~1_SEXTANT~ if thou wishest my company...
+ 1153544,
+ // ...then the ship exploded. A dragon swooped over. The slime swallowed Bertie whole--he screamed, it was amazing. The sky glowed orange...A sextant reading put us at ~1_SEXTANT~. Norma was chattering about sailing over the edge of the world. I looked at my hands and saw through them..."
+ 1153545,
+ // ...been inside this whale for three days now. I've run out of food I can pick out of his teeth. I took a sextant reading through the blowhole: ~1_SEXTANT~. I'll never see my treasure again...
+ 1153546,
+ // ...grand adventure! Captain Quacklebush had me swab down the decks daily... ...pirates came, I was in the rigging practicing with my sextant. ~1_SEXTANT~ if I am not mistaken... ...scuttled the ship, and our precious cargo went with her and the screaming pirates, down to the bottom of the sea...
+ 1153547,
+ // ...nobody knew I was a girl. They just assumed I was another sailor...then we met the undine. ~1_SEXTANT~. It demanded sacrifice...I was youngest, they figured...grabbed the captain's treasure, screamed "It'll go down with me!" ...they took me up on it.
+ 1153548,
+ // ...trapped on a deserted island with a magic fountain supplying food, fresh water springs, gorgeous scenery, and my lovely young wife. I know the ship with all our life's earnings sank at ~1_SEXTANT ~ but I don't know what our coordinates are...someone has GOT to rescue me before Sunday's finals game or I'll go mad...
+ 1153549,
+ // ...round Jhelom towne we did roam, drinking all night. Got into a fight...hoisted sail on the morn, all crew aboard but the cook...ull breach, last known coordinates ~1_SEXTANT~...be better off in Stone's jail cell!
+ 1153550
+ };
- [Constructible]
- public SOS(Map map = null) : this(map, MessageInABottle.GetRandomLevel())
- {
- }
+ [SerializableField(1)]
+ [SerializedCommandProperty(AccessLevel.GameMaster)]
+ private Map _targetMap;
- [Constructible]
- public SOS(Map map, int level) : base(0x14EE)
- {
- Weight = 1.0;
+ [SerializableField(2)]
+ [SerializedCommandProperty(AccessLevel.GameMaster)]
+ private Point3D _targetLocation;
- m_Level = level;
- MessageIndex = Utility.Random(MessageEntry.Entries.Length);
- TargetMap = map ?? Map.Trammel;
- TargetLocation = FindLocation(TargetMap);
+ [SerializableField(3)]
+ [SerializedCommandProperty(AccessLevel.GameMaster)]
+ private int _messageIndex;
- UpdateHue();
- }
+ [Constructible]
+ public SOS(Map map = null) : this(map, MessageInABottle.GetRandomLevel())
+ {
+ }
- public SOS(Serial serial) : base(serial)
- {
- }
+ [Constructible]
+ public SOS(Map map, int level) : base(0x14EE)
+ {
+ Weight = 1.0;
- public override int LabelNumber
- {
- get
- {
- if (IsAncient)
- {
- return 1063450; // an ancient SOS
- }
+ _level = level;
+ MessageIndex = Utility.Random(MessageEntries.Length);
+ TargetMap = map ?? Map.Trammel;
+ TargetLocation = FindLocation(TargetMap);
- return 1041081; // a waterstained SOS
- }
- }
+ UpdateHue();
+ }
- [CommandProperty(AccessLevel.GameMaster)]
- public bool IsAncient => m_Level >= 4;
+ public SOS(Serial serial) : base(serial)
+ {
+ }
- [CommandProperty(AccessLevel.GameMaster)]
- public int Level
- {
- get => m_Level;
- set
- {
- m_Level = Math.Max(1, Math.Min(value, 4));
- UpdateHue();
- InvalidateProperties();
- }
- }
-
- [CommandProperty(AccessLevel.GameMaster)]
- public Map TargetMap { get; set; }
-
- [CommandProperty(AccessLevel.GameMaster)]
- public Point3D TargetLocation { get; set; }
-
- [CommandProperty(AccessLevel.GameMaster)]
- public int MessageIndex { get; set; }
-
- public void UpdateHue()
+ public override int LabelNumber
+ {
+ get
{
if (IsAncient)
{
- Hue = 0x481;
+ return 1063450; // an ancient SOS
+ }
+
+ return 1041081; // a waterstained SOS
+ }
+ }
+
+ [CommandProperty(AccessLevel.GameMaster)]
+ public bool IsAncient => _level >= 4;
+
+ [CommandProperty(AccessLevel.GameMaster)]
+ [SerializableProperty(0)]
+ public int Level
+ {
+ get => _level;
+ set
+ {
+ _level = Math.Max(1, Math.Min(value, 4));
+ UpdateHue();
+ InvalidateProperties();
+ this.MarkDirty();
+ }
+ }
+
+ public void UpdateHue() => Hue = IsAncient ? 0x481 : 0;
+
+ public override void OnDoubleClick(Mobile from)
+ {
+ if (IsChildOf(from.Backpack))
+ {
+ var entry = MessageIndex >= 0 && MessageIndex < MessageEntries.Length ? MessageEntries[MessageIndex] : null;
+
+ if (UseNewMessages || entry == null)
+ {
+ from.SendGump(new MessageGump(TargetMap, TargetLocation));
}
else
{
- Hue = 0;
+ from.SendGump(new OldMessageGump(entry, TargetMap, TargetLocation, from.Language));
}
}
-
- public override void Serialize(IGenericWriter writer)
+ else
{
- base.Serialize(writer);
-
- writer.Write(4); // version
-
- writer.Write(m_Level);
-
- writer.Write(TargetMap);
- writer.Write(TargetLocation);
- writer.Write(MessageIndex);
+ from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
+ }
- public override void Deserialize(IGenericReader reader)
+ public static Point3D FindLocation(Map map)
+ {
+ if (map == null || map == Map.Internal)
{
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- switch (version)
- {
- case 4:
- case 3:
- case 2:
- {
- m_Level = reader.ReadInt();
- goto case 1;
- }
- case 1:
- {
- TargetMap = reader.ReadMap();
- TargetLocation = reader.ReadPoint3D();
- MessageIndex = reader.ReadInt();
-
- break;
- }
- case 0:
- {
- TargetMap = Map;
-
- if (TargetMap == null || TargetMap == Map.Internal)
- {
- TargetMap = Map.Trammel;
- }
-
- TargetLocation = FindLocation(TargetMap);
- MessageIndex = Utility.Random(MessageEntry.Entries.Length);
-
- break;
- }
- }
-
- if (version < 2)
- {
- m_Level = MessageInABottle.GetRandomLevel();
- }
-
- if (version < 3)
- {
- UpdateHue();
- }
-
- if (version < 4 && TargetMap == Map.Tokuno)
- {
- TargetMap = Map.Trammel;
- }
- }
-
- public override void OnDoubleClick(Mobile from)
- {
- if (IsChildOf(from.Backpack))
- {
- MessageEntry entry;
-
- if (MessageIndex >= 0 && MessageIndex < MessageEntry.Entries.Length)
- {
- entry = MessageEntry.Entries[MessageIndex];
- }
- else
- {
- entry = MessageEntry.Entries[MessageIndex = Utility.Random(MessageEntry.Entries.Length)];
- }
-
- // from.CloseGump( typeof( MessageGump ) );
- from.SendGump(new MessageGump(entry, TargetMap, TargetLocation));
- }
- else
- {
- from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
- }
- }
-
- public static Point3D FindLocation(Map map)
- {
- if (map == null || map == Map.Internal)
- {
- return Point3D.Zero;
- }
-
- Rectangle2D[] regions;
-
- if (map == Map.Felucca || map == Map.Trammel)
- {
- regions = m_BritRegions;
- }
- else if (map == Map.Ilshenar)
- {
- regions = m_IlshRegions;
- }
- else if (map == Map.Malas)
- {
- regions = m_MalasRegions;
- }
- else
- {
- regions = new[] { new Rectangle2D(0, 0, map.Width, map.Height) };
- }
-
- if (regions.Length == 0)
- {
- return Point3D.Zero;
- }
-
- for (var i = 0; i < 50; ++i)
- {
- var reg = regions.RandomElement();
- var x = Utility.Random(reg.X, reg.Width);
- var y = Utility.Random(reg.Y, reg.Height);
-
- if (!ValidateDeepWater(map, x, y))
- {
- continue;
- }
-
- var valid = true;
-
- for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
- {
- if (!ValidateDeepWater(map, x + offset, y + offset))
- {
- valid = false;
- }
- else if (!ValidateDeepWater(map, x + offset, y - offset))
- {
- valid = false;
- }
- else if (!ValidateDeepWater(map, x - offset, y + offset))
- {
- valid = false;
- }
- else if (!ValidateDeepWater(map, x - offset, y - offset))
- {
- valid = false;
- }
- }
-
- if (valid)
- {
- return new Point3D(x, y, 0);
- }
- }
-
return Point3D.Zero;
}
- private static bool ValidateDeepWater(Map map, int x, int y)
+ Rectangle2D[] regions;
+
+ if (map == Map.Felucca || map == Map.Trammel)
{
- var tileID = map.Tiles.GetLandTile(x, y).ID;
- var water = false;
-
- for (var i = 0; !water && i < m_WaterTiles.Length; i += 2)
- {
- water = tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1];
- }
-
- return water;
+ regions = BritRegions;
+ }
+ else if (map == Map.Ilshenar)
+ {
+ regions = IlshRegions;
+ }
+ else if (map == Map.Malas)
+ {
+ regions = MalasRegions;
+ }
+ else
+ {
+ regions = new[] { new Rectangle2D(0, 0, map.Width, map.Height) };
}
- private class MessageGump : Gump
+ if (regions.Length == 0)
{
- public MessageGump(MessageEntry entry, Map map, Point3D loc) : base(150, 50)
+ return Point3D.Zero;
+ }
+
+ for (var i = 0; i < 50; ++i)
+ {
+ var reg = regions.RandomElement();
+ var x = Utility.Random(reg.X, reg.Width);
+ var y = Utility.Random(reg.Y, reg.Height);
+
+ if (!ValidateDeepWater(map, x, y))
{
- int xLong = 0, yLat = 0;
- int xMins = 0, yMins = 0;
- bool xEast = false, ySouth = false;
- string fmt;
+ continue;
+ }
- if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
+ var valid = true;
+
+ for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
+ {
+ if (!ValidateDeepWater(map, x + offset, y + offset))
{
- fmt = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}°{xMins}'{(xEast ? "E" : "W")}";
+ valid = false;
}
- else
+ else if (!ValidateDeepWater(map, x + offset, y - offset))
{
- fmt = "?????";
+ valid = false;
}
+ else if (!ValidateDeepWater(map, x - offset, y + offset))
+ {
+ valid = false;
+ }
+ else if (!ValidateDeepWater(map, x - offset, y - offset))
+ {
+ valid = false;
+ }
+ }
- AddPage(0);
-
- AddBackground(0, 40, 350, 300, 2520);
-
- /* This is a message hastily scribbled by a passenger aboard a sinking ship.
- * While it is probably too late to save the passengers and crew,
- * perhaps some treasure went down with the ship!
- * The message gives the ship's last known sextant co-ordinates.
- */
- AddHtmlLocalized(
- 30,
- 80,
- 285,
- 160,
- 1018326,
- true,
- true
- );
-
- AddHtml(35, 240, 230, 20, fmt);
-
- AddButton(35, 265, 4005, 4007, 0);
- AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
+ if (valid)
+ {
+ return new Point3D(x, y, 0);
}
}
- private class MessageEntry
+ return Point3D.Zero;
+ }
+
+ private static bool ValidateDeepWater(Map map, int x, int y)
+ {
+ var tileID = map.Tiles.GetLandTile(x, y).ID;
+ var water = false;
+
+ for (var i = 0; !water && i < WaterTiles.Length; i += 2)
{
- public MessageEntry(int width, int height, string message)
+ water = tileID >= WaterTiles[i] && tileID <= WaterTiles[i + 1];
+ }
+
+ return water;
+ }
+
+ private class MessageGump : Gump
+ {
+ public MessageGump(Map map, Point3D loc) : base(150, 50)
+ {
+ int xLong = 0, yLat = 0;
+ int xMins = 0, yMins = 0;
+ bool xEast = false, ySouth = false;
+ string fmt;
+
+ if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
- Width = width;
- Height = height;
- Message = message;
+ fmt = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}°{xMins}'{(xEast ? "E" : "W")}";
+ }
+ else
+ {
+ fmt = "?????";
}
- public int Width { get; }
+ AddPage(0);
- public int Height { get; }
+ AddBackground(0, 40, 350, 300, 2520);
- public string Message { get; }
+ /* This is a message hastily scribbled by a passenger aboard a sinking ship.
+ * While it is probably too late to save the passengers and crew,
+ * perhaps some treasure went down with the ship!
+ * The message gives the ship's last known sextant co-ordinates.
+ */
+ AddHtmlLocalized(30, 80, 285, 160, 1018326, true, true);
- public static MessageEntry[] Entries { get; } =
+ AddHtml(35, 240, 230, 20, fmt);
+
+ AddButton(35, 265, 4005, 4007, 0);
+ AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
+ }
+ }
+
+ private class OldMessageGump : Gump
+ {
+ private const int Width = 350;
+ private const int Height = 300;
+
+ public OldMessageGump(TextDefinition entry, Map map, Point3D loc, string lang) : base((640 - Width) / 2, (480 - Height) / 2)
+ {
+ int xLong = 0, yLat = 0;
+ int xMins = 0, yMins = 0;
+ bool xEast = false, ySouth = false;
+ string fmt;
+
+ if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
- new(
- 280,
- 180,
- "...Ar! {0} and a fair wind! No chance... storms, though--ar! Is that a sea serp...
uh oh."
- ),
- new(
- 280,
- 215,
- "...been inside this whale for three days now. I've run out of food I can pick out of his teeth. I took a sextant reading through the blowhole: {0}. I'll never see my treasure again..."
- ),
- new(
- 280,
- 285,
- "...grand adventure! Captain Quacklebush had me swab down the decks daily...
...pirates came, I was in the rigging practicing with my sextant. {0} if I am not mistaken...
....scuttled the ship, and our precious cargo went with her and the screaming pirates, down to the bottom of the sea..."
- ),
- new(
- 280,
- 180,
- "Help! Ship going dow...n heavy storms...precious cargo...st reach dest...current coordinates {0}...ve any survivors... ease!"
- ),
- new(
- 280,
- 215,
- "...know that the wreck is near {0} but have not found it. Could the message passed down in my family for generations be wrong? No... I swear on the soul of my grandfather, I will find..."
- ),
- new(
- 280,
- 195,
- "...never expected an iceberg...silly woman on bow crushed instantly...send help to {0}...ey'll never forget the tragedy of the sinking of the Miniscule..."
- ),
- new(
- 280,
- 265,
- "...nobody knew I was a girl. They just assumed I was another sailor...then we met the undine. {0}. It was demanded sacrifice...I was youngset, they figured...
...grabbed the captain's treasure, screamed, 'It'll go down with me!'
...they took me up on it."
- ),
- new(
- 280,
- 230,
- "...so I threw the treasure overboard, before the curse could get me too. But I was too late. Now I am doomed to wander these seas, a ghost forever. Join me: seek ye at {0} if thou wishest my company..."
- ),
- new(
- 280,
- 285,
- "...then the ship exploded. A dragon swooped by. The slime swallowed Bertie whole--he screamed, it was amazing. The sky glowed orange. A sextant reading put us at {0}. Norma was chattering about sailing over the edge of the world. I looked at my hands and saw through them..."
- ),
- new(
- 280,
- 285,
- "...trapped on a deserted island, with a magic fountain supplying wood, fresh water springs, gorgeous scenery, and my lovely young wife. I know the ship with all our life's earnings sank at {0} but I don't know what our coordinates are... someone has GOT to rescue me before Sunday's finals game or I'll go mad..."
- ),
- new(
- 280,
- 160,
- "WANTED: divers exp...d in shipwre...overy. Must have own vess...pply at {0}
...good benefits, flexible hours..."
- ),
- new(
- 280,
- 250,
- "...was a cad and a boor, no matter what momma s...rew him overboard! Oh, Anna, 'twas so exciting!
Unfort...y he grabbe...est, and all his riches went with him!
...sked the captain, and he says we're at {0}
...so maybe..."
- )
- };
+ fmt = $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}";
+ }
+ else
+ {
+ fmt = "?????";
+ }
+
+ AddPage(0);
+ AddBackground(0, 0, Width, Height, 2520);
+
+ // Gumps do not support non-ascii string arguments. Probably why this was not used on OSI
+ var message = entry.Number > 0 ? Localization.Format(entry.Number, lang, $"{fmt}") : string.Format(entry.String, fmt);
+ AddHtml(38, 38, Width - 83, Height - 86, message);
}
}
}
diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs
index a36fd7644..546809721 100644
--- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs
+++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/Sextant.cs
@@ -1,188 +1,171 @@
+using ModernUO.Serialization;
using Server.Network;
-namespace Server.Items
+namespace Server.Items;
+
+[SerializationGenerator(0, false)]
+public partial class Sextant : Item
{
- public class Sextant : Item
+ [Constructible]
+ public Sextant() : base(0x1058) => Weight = 2.0;
+
+ public override void OnDoubleClick(Mobile from)
{
- [Constructible]
- public Sextant() : base(0x1058) => Weight = 2.0;
+ int xLong = 0, yLat = 0;
+ int xMins = 0, yMins = 0;
+ bool xEast = false, ySouth = false;
- public Sextant(Serial serial) : base(serial)
+ if (Format(from.Location, from.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
+ var location = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}";
+ from.LocalOverheadMessage(MessageType.Regular, from.SpeechHue, false, location);
}
+ }
- public override void Serialize(IGenericWriter writer)
+ public static bool ComputeMapDetails(
+ Map map, int x, int y, out int xCenter, out int yCenter, out int xWidth,
+ out int yHeight
+ )
+ {
+ xWidth = 5120;
+ yHeight = 4096;
+
+ if (map == Map.Trammel || map == Map.Felucca)
{
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
-
- public override void OnDoubleClick(Mobile from)
- {
- int xLong = 0, yLat = 0;
- int xMins = 0, yMins = 0;
- bool xEast = false, ySouth = false;
-
- if (Format(from.Location, from.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
- {
- var location = $"{yLat}° {yMins}'{(ySouth ? "S" : "N")}, {xLong}' {xMins}'{(xEast ? "E" : "W")}";
- from.LocalOverheadMessage(MessageType.Regular, from.SpeechHue, false, location);
- }
- }
-
- public static bool ComputeMapDetails(
- Map map, int x, int y, out int xCenter, out int yCenter, out int xWidth,
- out int yHeight
- )
- {
- xWidth = 5120;
- yHeight = 4096;
-
- if (map == Map.Trammel || map == Map.Felucca)
- {
- if (x >= 0 && y >= 0 && x < 5120 && y < 4096)
- {
- xCenter = 1323;
- yCenter = 1624;
- }
- else if (x >= 5120 && y >= 2304 && x < 6144 && y < 4096)
- {
- xCenter = 5936;
- yCenter = 3112;
- }
- else
- {
- xCenter = 0;
- yCenter = 0;
- return false;
- }
- }
- else if (x >= 0 && y >= 0 && x < map.Width && y < map.Height)
+ if (x >= 0 && y >= 0 && x < 5120 && y < 4096)
{
xCenter = 1323;
yCenter = 1624;
}
+ else if (x >= 5120 && y >= 2304 && x < 6144 && y < 4096)
+ {
+ xCenter = 5936;
+ yCenter = 3112;
+ }
else
{
xCenter = 0;
yCenter = 0;
return false;
}
-
- return true;
}
-
- public static Point3D ReverseLookup(Map map, int xLong, int yLat, int xMins, int yMins, bool xEast, bool ySouth)
+ else if (x >= 0 && y >= 0 && x < map.Width && y < map.Height)
{
- if (map == null || map == Map.Internal)
- {
- return Point3D.Zero;
- }
-
- if (!ComputeMapDetails(map, 0, 0, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
- {
- return Point3D.Zero;
- }
-
- var absLong = xLong + (double)xMins / 60;
- var absLat = yLat + (double)yMins / 60;
-
- if (!xEast)
- {
- absLong = 360.0 - absLong;
- }
-
- if (!ySouth)
- {
- absLat = 360.0 - absLat;
- }
-
- var x = xCenter + (int)(absLong * xWidth / 360);
- var y = yCenter + (int)(absLat * yHeight / 360);
-
- if (x < 0)
- {
- x += xWidth;
- }
- else if (x >= xWidth)
- {
- x -= xWidth;
- }
-
- if (y < 0)
- {
- y += yHeight;
- }
- else if (y >= yHeight)
- {
- y -= yHeight;
- }
-
- var z = map.GetAverageZ(x, y);
-
- return new Point3D(x, y, z);
+ xCenter = 1323;
+ yCenter = 1624;
}
-
- public static bool Format(
- Point3D p, Map map, ref int xLong, ref int yLat, ref int xMins, ref int yMins,
- ref bool xEast, ref bool ySouth
- )
+ else
{
- if (map == null || map == Map.Internal)
- {
- return false;
- }
-
- int x = p.X, y = p.Y;
-
- if (!ComputeMapDetails(map, x, y, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
- {
- return false;
- }
-
- var absLong = (double)((x - xCenter) * 360) / xWidth;
- var absLat = (double)((y - yCenter) * 360) / yHeight;
-
- if (absLong > 180.0)
- {
- absLong = -180.0 + absLong % 180.0;
- }
-
- if (absLat > 180.0)
- {
- absLat = -180.0 + absLat % 180.0;
- }
-
- bool east = absLong >= 0, south = absLat >= 0;
-
- if (absLong < 0.0)
- {
- absLong = -absLong;
- }
-
- if (absLat < 0.0)
- {
- absLat = -absLat;
- }
-
- xLong = (int)absLong;
- yLat = (int)absLat;
-
- xMins = (int)(absLong % 1.0 * 60);
- yMins = (int)(absLat % 1.0 * 60);
-
- xEast = east;
- ySouth = south;
-
- return true;
+ xCenter = 0;
+ yCenter = 0;
+ return false;
}
+
+ return true;
+ }
+
+ public static Point3D ReverseLookup(Map map, int xLong, int yLat, int xMins, int yMins, bool xEast, bool ySouth)
+ {
+ if (map == null || map == Map.Internal)
+ {
+ return Point3D.Zero;
+ }
+
+ if (!ComputeMapDetails(map, 0, 0, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
+ {
+ return Point3D.Zero;
+ }
+
+ var absLong = xLong + (double)xMins / 60;
+ var absLat = yLat + (double)yMins / 60;
+
+ if (!xEast)
+ {
+ absLong = 360.0 - absLong;
+ }
+
+ if (!ySouth)
+ {
+ absLat = 360.0 - absLat;
+ }
+
+ var x = xCenter + (int)(absLong * xWidth / 360);
+ var y = yCenter + (int)(absLat * yHeight / 360);
+
+ if (x < 0)
+ {
+ x += xWidth;
+ }
+ else if (x >= xWidth)
+ {
+ x -= xWidth;
+ }
+
+ if (y < 0)
+ {
+ y += yHeight;
+ }
+ else if (y >= yHeight)
+ {
+ y -= yHeight;
+ }
+
+ var z = map.GetAverageZ(x, y);
+
+ return new Point3D(x, y, z);
+ }
+
+ public static bool Format(
+ Point3D p, Map map, ref int xLong, ref int yLat, ref int xMins, ref int yMins,
+ ref bool xEast, ref bool ySouth
+ )
+ {
+ if (map == null || map == Map.Internal)
+ {
+ return false;
+ }
+
+ int x = p.X, y = p.Y;
+
+ if (!ComputeMapDetails(map, x, y, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
+ {
+ return false;
+ }
+
+ var absLong = (double)((x - xCenter) * 360) / xWidth;
+ var absLat = (double)((y - yCenter) * 360) / yHeight;
+
+ if (absLong > 180.0)
+ {
+ absLong = -180.0 + absLong % 180.0;
+ }
+
+ if (absLat > 180.0)
+ {
+ absLat = -180.0 + absLat % 180.0;
+ }
+
+ bool east = absLong >= 0, south = absLat >= 0;
+
+ if (absLong < 0.0)
+ {
+ absLong = -absLong;
+ }
+
+ if (absLat < 0.0)
+ {
+ absLat = -absLat;
+ }
+
+ xLong = (int)absLong;
+ yLat = (int)absLat;
+
+ xMins = (int)(absLong % 1.0 * 60);
+ yMins = (int)(absLat % 1.0 * 60);
+
+ xEast = east;
+ ySouth = south;
+
+ return true;
}
}
diff --git a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs
index 641b457c5..d812f761a 100644
--- a/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs
+++ b/Projects/UOContent/Items/Skill Items/Fishing/Misc/ShipwreckedItem.cs
@@ -1,74 +1,58 @@
-namespace Server.Items
+using ModernUO.Serialization;
+
+namespace Server.Items;
+
+public interface IShipwreckedItem
{
- public interface IShipwreckedItem
+ bool IsShipwreckedItem { get; set; }
+}
+
+[SerializationGenerator(0, false)]
+public partial class ShipwreckedItem : Item, IDyable, IShipwreckedItem
+{
+ public ShipwreckedItem(int itemID) : base(itemID)
{
- bool IsShipwreckedItem { get; set; }
+ var weight = ItemData.Weight;
+
+ if (weight >= 255)
+ {
+ weight = 1;
+ }
+
+ Weight = weight;
}
- public class ShipwreckedItem : Item, IDyable, IShipwreckedItem
+ public bool Dye(Mobile from, DyeTub sender)
{
- public ShipwreckedItem(int itemID) : base(itemID)
+ if (Deleted)
{
- var weight = ItemData.Weight;
-
- if (weight >= 255)
- {
- weight = 1;
- }
-
- Weight = weight;
- }
-
- public ShipwreckedItem(Serial serial) : base(serial)
- {
- }
-
- public bool Dye(Mobile from, DyeTub sender)
- {
- if (Deleted)
- {
- return false;
- }
-
- if (ItemID >= 0x13A4 && ItemID <= 0x13AE)
- {
- Hue = sender.DyedHue;
- return true;
- }
-
- from.SendLocalizedMessage(sender.FailMessage);
return false;
}
- bool IShipwreckedItem.IsShipwreckedItem
+ if (ItemID >= 0x13A4 && ItemID <= 0x13AE)
{
- get => true;
- set { }
+ Hue = sender.DyedHue;
+ return true;
}
- public override void OnSingleClick(Mobile from)
- {
- LabelTo(from, 1050039, $"{LabelNumber:#}\t{1041645:#}");
- }
+ from.SendLocalizedMessage(sender.FailMessage);
+ return false;
+ }
- public override void AddNameProperties(IPropertyList list)
- {
- base.AddNameProperties(list);
- list.Add(1041645); // recovered from a shipwreck
- }
+ bool IShipwreckedItem.IsShipwreckedItem
+ {
+ get => true;
+ set { }
+ }
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
+ public override void OnSingleClick(Mobile from)
+ {
+ LabelTo(from, 1050039, $"{LabelNumber:#}\t{1041645:#}");
+ }
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
+ public override void AddNameProperties(IPropertyList list)
+ {
+ base.AddNameProperties(list);
+ list.Add(1041645); // recovered from a shipwreck
}
}
diff --git a/Projects/UOContent/Migrations/Server.Items.MessageInABottle.v0.json b/Projects/UOContent/Migrations/Server.Items.MessageInABottle.v0.json
new file mode 100644
index 000000000..b0388172e
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.MessageInABottle.v0.json
@@ -0,0 +1,22 @@
+{
+ "version": 0,
+ "type": "Server.Items.MessageInABottle",
+ "properties": [
+ {
+ "name": "Level",
+ "type": "int",
+ "rule": "PrimitiveTypeMigrationRule",
+ "ruleArguments": [
+ ""
+ ]
+ },
+ {
+ "name": "TargetMap",
+ "type": "Server.Map",
+ "rule": "PrimitiveUOTypeMigrationRule",
+ "ruleArguments": [
+ "Map"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.SOS.v0.json b/Projects/UOContent/Migrations/Server.Items.SOS.v0.json
new file mode 100644
index 000000000..f07c76d0f
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.SOS.v0.json
@@ -0,0 +1,38 @@
+{
+ "version": 0,
+ "type": "Server.Items.SOS",
+ "properties": [
+ {
+ "name": "Level",
+ "type": "int",
+ "rule": "PrimitiveTypeMigrationRule",
+ "ruleArguments": [
+ ""
+ ]
+ },
+ {
+ "name": "TargetMap",
+ "type": "Server.Map",
+ "rule": "PrimitiveUOTypeMigrationRule",
+ "ruleArguments": [
+ "Map"
+ ]
+ },
+ {
+ "name": "TargetLocation",
+ "type": "Server.Point3D",
+ "rule": "PrimitiveUOTypeMigrationRule",
+ "ruleArguments": [
+ "Point3D"
+ ]
+ },
+ {
+ "name": "MessageIndex",
+ "type": "int",
+ "rule": "PrimitiveTypeMigrationRule",
+ "ruleArguments": [
+ ""
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.Sextant.v0.json b/Projects/UOContent/Migrations/Server.Items.Sextant.v0.json
new file mode 100644
index 000000000..bc536871a
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.Sextant.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.Sextant"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.ShipwreckedItem.v0.json b/Projects/UOContent/Migrations/Server.Items.ShipwreckedItem.v0.json
new file mode 100644
index 000000000..cd975d0a7
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.ShipwreckedItem.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.ShipwreckedItem"
+}
\ No newline at end of file