using System;
using Server.Gumps;
namespace Server.Items
{
[Flipable(0x14ED, 0x14EE)]
public class SOS : Item
{
public override int LabelNumber
{
get
{
if (IsAncient)
return 1063450; // an ancient SOS
//Iomega0318
if (keyQuest)
return 1127455; //a map to the boots of footless joe
return 1041081; // a waterstained SOS
}
}
private int m_Level;
private Map m_TargetMap;
private Point3D m_TargetLocation;
private int m_MessageIndex;
//Iomega0318
public readonly bool keyQuest;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsAncient
{
get
{
return (m_Level >= 4);
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int Level
{
get
{
return m_Level;
}
set
{
m_Level = Math.Max(1, Math.Min(value, 4));
UpdateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap
{
get
{
return m_TargetMap;
}
set
{
m_TargetMap = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Point3D TargetLocation
{
get
{
return m_TargetLocation;
}
set
{
m_TargetLocation = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int MessageIndex
{
get
{
return m_MessageIndex;
}
set
{
m_MessageIndex = value;
}
}
public void UpdateHue()
{
if (IsAncient)
Hue = 0x481;
else
Hue = 0;
}
[Constructable]
public SOS()
: this(Map.Trammel)
{
}
[Constructable]
public SOS(Map map)
: this(map, MessageInABottle.GetRandomLevel())
{
}
[Constructable]
public SOS(Map map, int level, bool isKeyQuest = false)
: base(0x14EE)
{
Weight = 1.0;
m_Level = level;
m_MessageIndex = Utility.Random(MessageEntry.Entries.Length);
m_TargetMap = map;
m_TargetLocation = FindLocation(m_TargetMap);
//Iomega0318
keyQuest = isKeyQuest;
UpdateHue();
}
public SOS(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)4); // version
writer.Write(m_Level);
writer.Write(m_TargetMap);
writer.Write(m_TargetLocation);
writer.Write(m_MessageIndex);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 4:
case 3:
case 2:
{
m_Level = reader.ReadInt();
goto case 1;
}
case 1:
{
m_TargetMap = reader.ReadMap();
m_TargetLocation = reader.ReadPoint3D();
m_MessageIndex = reader.ReadInt();
break;
}
case 0:
{
m_TargetMap = Map;
if (m_TargetMap == null || m_TargetMap == Map.Internal)
m_TargetMap = Map.Trammel;
m_TargetLocation = FindLocation(m_TargetMap);
m_MessageIndex = Utility.Random(MessageEntry.Entries.Length);
break;
}
}
if (version < 2)
m_Level = MessageInABottle.GetRandomLevel();
if (version < 3)
UpdateHue();
if (version < 4 && m_TargetMap == Map.Tokuno)
m_TargetMap = Map.Trammel;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
MessageEntry entry;
if (m_MessageIndex >= 0 && m_MessageIndex < MessageEntry.Entries.Length)
entry = MessageEntry.Entries[m_MessageIndex];
else
entry = MessageEntry.Entries[m_MessageIndex = Utility.Random(MessageEntry.Entries.Length)];
from.CloseGump(typeof(MessageGump));
from.SendGump(new MessageGump(entry, m_TargetMap, m_TargetLocation));
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
public virtual void OnSOSComplete(Container chest)
{
//Iomega0318
//This adds the key to the chest every time. It should be changed to whatever you want the probability to be
if (keyQuest && Utility.RandomDouble() < 0.1)
{
chest.AddItem(new AdventurerKey());
}
}
private static readonly int[] m_WaterTiles = new int[]
{
0x00A8, 0x00AB,
0x0136, 0x0137
};
private static readonly Rectangle2D[] m_BritRegions = new Rectangle2D[] { new Rectangle2D(0, 0, 5120, 4096) };
private static readonly Rectangle2D[] m_IlshRegions = new Rectangle2D[] { new Rectangle2D(1472, 272, 304, 240), new Rectangle2D(1240, 1000, 312, 160) };
private static readonly Rectangle2D[] m_MalasRegions = new Rectangle2D[] { new Rectangle2D(1376, 1520, 464, 280) };
private static readonly Rectangle2D[] m_TokunoRegions = new Rectangle2D[] { new Rectangle2D(10, 10, 1440, 1440) };
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 if (map == Map.Tokuno)
regions = m_TokunoRegions;
else
regions = new Rectangle2D[] { new Rectangle2D(0, 0, map.Width, map.Height) };
if (regions.Length == 0)
return Point3D.Zero;
for (int i = 0; i < 50; ++i)
{
Rectangle2D reg = regions[Utility.Random(regions.Length)];
int x = Utility.Random(reg.X, reg.Width);
int y = Utility.Random(reg.Y, reg.Height);
if (!ValidateDeepWater(map, x, y))
continue;
bool 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;
}
public static bool ValidateDeepWater(Map map, int x, int y)
{
int tileID = map.Tiles.GetLandTile(x, y).ID;
bool water = false;
for (int i = 0; !water && i < m_WaterTiles.Length; i += 2)
water = (tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1]);
return water;
}
#if false
private class MessageGump : Gump
{
public MessageGump( MessageEntry entry, Map map, Point3D loc ) : base( (640 - entry.Width) / 2, (480 - entry.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 ) )
fmt = String.Format( "{0}°{1}'{2},{3}°{4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W" );
else
fmt = "?????";
AddPage( 0 );
AddBackground( 0, 0, entry.Width, entry.Height, 2520 );
AddHtml( 38, 38, entry.Width - 83, entry.Height - 86, String.Format( entry.Message, fmt ), false, false );
}
}
#else
private class MessageGump : Gump
{
public MessageGump(MessageEntry entry, 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))
fmt = String.Format("{0}o {1}'{2}, {3}o {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
else
fmt = "?????";
AddPage(0);
if (Core.ML)
{
AddBackground(0, 0, 250, 350, 9390);
AddHtmlLocalized(30, 50, 190, 420, entry.Message, fmt, 0, false, false);
}
else
{
AddBackground(0, 40, 350, 300, 2520);
AddHtmlLocalized(30, 80, 285, 160, 1018326, true, true); /* 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(35, 240, 230, 20, entry.Message, fmt, 0, false, false);
AddButton(35, 265, 4005, 4007, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(70, 265, 100, 20, 1011036, false, false); // OKAY
}
}
}
#endif
private class MessageEntry
{
private readonly int m_Width;
private readonly int m_Height;
private readonly int m_Message;
public int Width
{
get
{
return m_Width;
}
}
public int Height
{
get
{
return m_Height;
}
}
public int Message
{
get
{
return m_Message;
}
}
public MessageEntry(int width, int height, int message)
{
m_Width = width;
m_Height = height;
m_Message = message;
}
private static readonly MessageEntry[] m_Entries = new MessageEntry[]
{
new MessageEntry(280, 180, 1153540),
new MessageEntry(280, 215, 1153546),
new MessageEntry(280, 285, 1153547),
new MessageEntry(280, 180, 1153537),
new MessageEntry(280, 215, 1153539),
new MessageEntry(280, 195, 1153543),
new MessageEntry(280, 265, 1153548),
new MessageEntry(280, 230, 1153544),
new MessageEntry(280, 285, 1153545),
new MessageEntry(280, 285, 1153549),
new MessageEntry(280, 160, 1153541),
new MessageEntry(280, 250, 1153538),
new MessageEntry(280, 250, 1153542),
new MessageEntry(280, 250, 1153550),
};
public static MessageEntry[] Entries
{
get
{
if (keyQuest)
new MessageEntry(280, 180, 1127456);
return m_Entries;
}
}
}
}
}