Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
313
Scripts/Services/Help/HelpGump.cs
Normal file
313
Scripts/Services/Help/HelpGump.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Menus.Questions;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class ContainedMenu : QuestionMenu
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
public ContainedMenu(Mobile from)
|
||||
: base("You already have an open help request. We will have someone assist you as soon as possible. What would you like to do?", new string[] { "Leave my old help request like it is.", "Remove my help request from the queue." })
|
||||
{
|
||||
this.m_From = from;
|
||||
}
|
||||
|
||||
public override void OnCancel(NetState state)
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(1005306, "", 0x35); // Help request unchanged.
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, int index)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(1005306, "", 0x35); // Help request unchanged.
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
PageEntry entry = PageQueue.GetEntry(this.m_From);
|
||||
|
||||
if (entry != null && entry.Handler == null)
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(1005307, "", 0x35); // Removed help request.
|
||||
entry.AddResponse(entry.Sender, "[Canceled]");
|
||||
PageQueue.Remove(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(1005306, "", 0x35); // Help request unchanged.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HelpGump : Gump
|
||||
{
|
||||
public static readonly string SupportWebsite = Config.Get("General.SupportWebsite", default(string));
|
||||
|
||||
public HelpGump(Mobile from)
|
||||
: base(0, 0)
|
||||
{
|
||||
from.CloseGump(typeof(HelpGump));
|
||||
|
||||
bool isYoung = IsYoung(from);
|
||||
|
||||
this.AddBackground(50, 25, 540, 430, 2600);
|
||||
|
||||
this.AddPage(0);
|
||||
|
||||
this.AddHtmlLocalized(150, 50, 360, 40, 1001002, false, false); // <CENTER><U>Ultima Online Help Menu</U></CENTER>
|
||||
this.AddButton(425, 415, 2073, 2072, 0, GumpButtonType.Reply, 0); // Close
|
||||
|
||||
this.AddPage(1);
|
||||
|
||||
if (isYoung)
|
||||
{
|
||||
this.AddButton(80, 75, 5540, 5541, 9, GumpButtonType.Reply, 2);
|
||||
this.AddHtml(110, 75, 450, 58, @"<BODY><BASEFONT COLOR=BLACK><u>Young Player Haven Transport.</u> Select this option if you want to be transported to Haven.</BODY>", true, true);
|
||||
|
||||
this.AddButton(80, 140, 5540, 5541, 1, GumpButtonType.Reply, 2);
|
||||
this.AddHtml(110, 140, 450, 58, @"<u>General question about Ultima Online.</u> Select this option if you have a general gameplay question, need help learning to use a skill, or if you would like to search the UO Knowledge Base.", true, true);
|
||||
|
||||
this.AddButton(80, 205, 5540, 5541, 2, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 205, 450, 58, @"<u>My character is physically stuck in the game.</u> This choice only covers cases where your character is physically stuck in a location they cannot move out of. This option will only work two times in 24 hours.", true, true);
|
||||
|
||||
this.AddButton(80, 270, 5540, 5541, 0, GumpButtonType.Page, 3);
|
||||
this.AddHtml(110, 270, 450, 58, @"<u>Another player is harassing me.</u> Another player is verbally harassing your character. When you select this option you will be sending a text log to Origin Systems. To see what constitutes harassment please visit " + (SupportWebsite == null ? "http://support.uo.com/gm_9.html" : SupportWebsite) + ".", true, true);
|
||||
|
||||
this.AddButton(80, 335, 5540, 5541, 0, GumpButtonType.Page, 2);
|
||||
this.AddHtml(110, 335, 450, 58, @"<u>Other.</u> If you are experiencing a problem in the game that does not fall into one of the other categories or is not addressed on the Support web page (located at " + (SupportWebsite == null ? "http://support.uo.com" : SupportWebsite) + "), please use this option.", true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AddButton(80, 90, 5540, 5541, 1, GumpButtonType.Reply, 2);
|
||||
this.AddHtml(110, 90, 450, 74, @"<u>General question about Ultima Online.</u> Select this option if you have a general gameplay question, need help learning to use a skill, or if you would like to search the UO Knowledge Base.", true, true);
|
||||
|
||||
this.AddButton(80, 170, 5540, 5541, 2, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 170, 450, 74, @"<u>My character is physically stuck in the game.</u> This choice only covers cases where your character is physically stuck in a location they cannot move out of. This option will only work two times in 24 hours.", true, true);
|
||||
|
||||
this.AddButton(80, 250, 5540, 5541, 0, GumpButtonType.Page, 3);
|
||||
this.AddHtml(110, 250, 450, 74, @"<u>Another player is harassing me.</u> Another player is verbally harassing your character. When you select this option you will be sending a text log to Origin Systems. To see what constitutes harassment please visit " + (SupportWebsite == null ? "http://support.uo.com/gm_9.html" : SupportWebsite) + ".", true, true);
|
||||
|
||||
this.AddButton(80, 330, 5540, 5541, 0, GumpButtonType.Page, 2);
|
||||
this.AddHtml(110, 330, 450, 74, @"<u>Other.</u> If you are experiencing a problem in the game that does not fall into one of the other categories or is not addressed on the Support web page (located at " + (SupportWebsite == null ? "http://support.uo.com" : SupportWebsite) + "), please use this option.", true, true);
|
||||
}
|
||||
|
||||
this.AddPage(2);
|
||||
|
||||
this.AddButton(80, 90, 5540, 5541, 3, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 90, 450, 74, @"<u>Report a bug or contact Origin.</u> Use this option to launch your web browser and mail in a bug report. Your report will be read by our Quality Assurance Staff. We apologize for not being able to reply to individual reports. ", true, true);
|
||||
|
||||
this.AddButton(80, 170, 5540, 5541, 4, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 170, 450, 74, @"<u>Suggestion for the Game.</u> If you'd like to make a suggestion for the game, it should be directed to the Development Team Members who participate in the discussion forums on the UO.Com web site. Choosing this option will take you to the Discussion Forums. ", true, true);
|
||||
|
||||
this.AddButton(80, 250, 5540, 5541, 5, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 250, 450, 74, @"<u>Account Management</u> For questions regarding your account such as forgotten passwords, payment options, account activation, and account transfer, please choose this option.", true, true);
|
||||
|
||||
this.AddButton(80, 330, 5540, 5541, 6, GumpButtonType.Reply, 0);
|
||||
this.AddHtml(110, 330, 450, 74, @"<u>Other.</u> If you are experiencing a problem in the game that does not fall into one of the other categories or is not addressed on the Support web page (located at " + (SupportWebsite == null ? "http://support.uo.com" : SupportWebsite) + ", and requires in-game assistance, use this option. ", true, true);
|
||||
|
||||
this.AddPage(3);
|
||||
|
||||
this.AddButton(80, 90, 5540, 5541, 7, GumpButtonType.Reply, 0);
|
||||
this.AddHtmlLocalized(110, 90, 450, 145, 1062572, true, true); /* <U><CENTER>Another player is harassing me (or Exploiting).</CENTER></U><BR>
|
||||
* VERBAL HARASSMENT<BR>
|
||||
* Use this option when another player is verbally harassing your character.
|
||||
* Verbal harassment behaviors include but are not limited to, using bad language, threats etc..
|
||||
* Before you submit a complaint be sure you understand what constitutes harassment
|
||||
* <A HREF="http://uo.custhelp.com/cgi-bin/uo.cfg/php/enduser/std_adp.php?p_faqid=40">– what is verbal harassment? -</A>
|
||||
* and that you have followed these steps:<BR>
|
||||
* 1. You have asked the player to stop and they have continued.<BR>
|
||||
* 2. You have tried to remove yourself from the situation.<BR>
|
||||
* 3. You have done nothing to instigate or further encourage the harassment.<BR>
|
||||
* 4. You have added the player to your ignore list.
|
||||
* <A HREF="http://uo.custhelp.com/cgi-bin/uo.cfg/php/enduser/std_adp.php?p_faqid=138">- How do I ignore a player?</A><BR>
|
||||
* 5. You have read and understand Origin’s definition of harassment.<BR>
|
||||
* 6. Your account information is up to date. (Including a current email address)<BR>
|
||||
* *If these steps have not been taken, GMs may be unable to take action against the offending player.<BR>
|
||||
* **A chat log will be review by a GM to assess the validity of this complaint.
|
||||
* Abuse of this system is a violation of the Rules of Conduct.<BR>
|
||||
* EXPLOITING<BR>
|
||||
* Use this option to report someone who may be exploiting or cheating.
|
||||
* <A HREF="http://uo.custhelp.com/cgi-bin/uo.cfg/php/enduser/std_adp.php?p_faqid=41">– What constitutes an exploit?</a>
|
||||
*/
|
||||
|
||||
this.AddButton(80, 240, 5540, 5541, 8, GumpButtonType.Reply, 0);
|
||||
this.AddHtmlLocalized(110, 240, 450, 145, 1062573, true, true); /* <U><CENTER>Another player is harassing me using game mechanics.</CENTER></U><BR>
|
||||
* <BR>
|
||||
* PHYSICAL HARASSMENT<BR>
|
||||
* Use this option when another player is harassing your character using game mechanics.
|
||||
* Physical harassment includes but is not limited to luring, Kill Stealing, and any act that causes a players death in Trammel.
|
||||
* Before you submit a complaint be sure you understand what constitutes harassment
|
||||
* <A HREF="http://uo.custhelp.com/cgi-bin/uo.cfg/php/enduser/std_adp.php?p_faqid=59"> – what is physical harassment?</A>
|
||||
* and that you have followed these steps:<BR>
|
||||
* 1. You have asked the player to stop and they have continued.<BR>
|
||||
* 2. You have tried to remove yourself from the situation.<BR>
|
||||
* 3. You have done nothing to instigate or further encourage the harassment.<BR>
|
||||
* 4. You have added the player to your ignore list.
|
||||
* <A HREF="http://uo.custhelp.com/cgi-bin/uo.cfg/php/enduser/std_adp.php?p_faqid=138"> - how do I ignore a player?</A><BR>
|
||||
* 5. You have read and understand Origin’s definition of harassment.<BR>
|
||||
* 6. Your account information is up to date. (Including a current email address)<BR>
|
||||
* *If these steps have not been taken, GMs may be unable to take action against the offending player.<BR>
|
||||
* **This issue will be reviewed by a GM to assess the validity of this complaint.
|
||||
* Abuse of this system is a violation of the Rules of Conduct.
|
||||
*/
|
||||
|
||||
this.AddButton(150, 390, 5540, 5541, 0, GumpButtonType.Page, 1);
|
||||
this.AddHtmlLocalized(180, 390, 335, 40, 1001015, false, false); // NO - I meant to ask for help with another matter.
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.HelpRequest += new HelpRequestEventHandler(EventSink_HelpRequest);
|
||||
}
|
||||
|
||||
public static bool CheckCombat(Mobile m)
|
||||
{
|
||||
for (int i = 0; i < m.Aggressed.Count; ++i)
|
||||
{
|
||||
AggressorInfo info = m.Aggressed[i];
|
||||
|
||||
if (DateTime.UtcNow - info.LastCombatTime < TimeSpan.FromSeconds(30.0))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
PageType type = (PageType)(-1);
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 0: // Close/Cancel
|
||||
{
|
||||
from.SendLocalizedMessage(501235, "", 0x35); // Help request aborted.
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // General question
|
||||
{
|
||||
type = PageType.Question;
|
||||
break;
|
||||
}
|
||||
case 2: // Stuck
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house != null && house.IsAosRules)
|
||||
{
|
||||
from.Location = house.BanLocation;
|
||||
}
|
||||
else if (from.Region.IsPartOf<Server.Regions.Jail>())
|
||||
{
|
||||
from.SendLocalizedMessage(1114345, "", 0x35); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if (Factions.Sigil.ExistsOn(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
}
|
||||
else if (from.CanUseStuckMenu() && from.Region.CanUseStuckMenu(from) && !CheckCombat(from) && !from.Frozen && !from.Criminal && (Core.AOS || from.Kills < 5))
|
||||
{
|
||||
StuckMenu menu = new StuckMenu(from, from, true);
|
||||
|
||||
menu.BeginClose();
|
||||
|
||||
from.SendGump(menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = PageType.Stuck;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // Report bug or contact Origin
|
||||
{
|
||||
type = PageType.Bug;
|
||||
break;
|
||||
}
|
||||
case 4: // Game suggestion
|
||||
{
|
||||
type = PageType.Suggestion;
|
||||
break;
|
||||
}
|
||||
case 5: // Account management
|
||||
{
|
||||
type = PageType.Account;
|
||||
break;
|
||||
}
|
||||
case 6: // Other
|
||||
{
|
||||
type = PageType.Other;
|
||||
break;
|
||||
}
|
||||
case 7: // Harassment: verbal/exploit
|
||||
{
|
||||
type = PageType.VerbalHarassment;
|
||||
break;
|
||||
}
|
||||
case 8: // Harassment: physical
|
||||
{
|
||||
type = PageType.PhysicalHarassment;
|
||||
break;
|
||||
}
|
||||
case 9: // Young player transport
|
||||
{
|
||||
if (IsYoung(from))
|
||||
{
|
||||
if (from.Region.IsPartOf<Regions.Jail>())
|
||||
{
|
||||
from.SendLocalizedMessage(1114345, "", 0x35); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if (from.Region.IsPartOf("Haven Island"))
|
||||
{
|
||||
from.SendLocalizedMessage(1041529); // You're already in Haven
|
||||
}
|
||||
else
|
||||
{
|
||||
from.MoveToWorld(new Point3D(3503, 2574, 14), Map.Trammel);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type != (PageType)(-1) && PageQueue.CheckAllowedToPage(from))
|
||||
from.SendGump(new PagePromptGump(from, type));
|
||||
}
|
||||
|
||||
private static void EventSink_HelpRequest(HelpRequestEventArgs e)
|
||||
{
|
||||
foreach (Gump g in e.Mobile.NetState.Gumps)
|
||||
{
|
||||
if (g is HelpGump)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PageQueue.CheckAllowedToPage(e.Mobile))
|
||||
return;
|
||||
|
||||
if (PageQueue.Contains(e.Mobile))
|
||||
e.Mobile.SendMenu(new ContainedMenu(e.Mobile));
|
||||
else
|
||||
e.Mobile.SendGump(new HelpGump(e.Mobile));
|
||||
}
|
||||
|
||||
private static bool IsYoung(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile)
|
||||
return ((PlayerMobile)m).Young;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
Scripts/Services/Help/HelpPersistence.cs
Normal file
96
Scripts/Services/Help/HelpPersistence.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
#region References
|
||||
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public static class HelpPersistence
|
||||
{
|
||||
private static readonly string _FilePath = Path.Combine("Saves", "Help", "Pages.bin");
|
||||
|
||||
|
||||
[CallPriority(900)]
|
||||
public static void Configure()
|
||||
{
|
||||
EventSink.WorldSave += OnSave;
|
||||
EventSink.WorldLoad += OnLoad;
|
||||
}
|
||||
|
||||
private static void OnSave(WorldSaveEventArgs e)
|
||||
{
|
||||
Persistence.Serialize(
|
||||
_FilePath,
|
||||
writer =>
|
||||
{
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(ResponseEntry.Entries.Count);
|
||||
|
||||
foreach (var entry in ResponseEntry.Entries)
|
||||
entry.Serialize(writer);
|
||||
|
||||
writer.Write(PageQueue.List.Count);
|
||||
|
||||
foreach (PageEntry pe in PageQueue.List)
|
||||
{
|
||||
writer.Write(pe.Sender);
|
||||
writer.Write(pe.Message);
|
||||
writer.Write((int)pe.Type);
|
||||
writer.Write(pe.Handler);
|
||||
writer.Write(pe.Sent);
|
||||
writer.Write(pe.PageLocation);
|
||||
writer.Write(pe.PageMap);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void OnLoad()
|
||||
{
|
||||
Persistence.Deserialize(
|
||||
_FilePath,
|
||||
reader =>
|
||||
{
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
var c = reader.ReadInt();
|
||||
|
||||
for (var i = 0; i < c; ++i)
|
||||
{
|
||||
new ResponseEntry(reader);
|
||||
}
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
var count = reader.ReadInt();
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var sender = reader.ReadMobile();
|
||||
var message = reader.ReadString();
|
||||
var type = (PageType)reader.ReadInt();
|
||||
PageEntry pe = new PageEntry(sender, message, type)
|
||||
{
|
||||
Handler = reader.ReadMobile(),
|
||||
Sent = reader.ReadDateTime(),
|
||||
PageLocation = reader.ReadPoint3D(),
|
||||
PageMap = reader.ReadMap()
|
||||
};
|
||||
pe.Stop();
|
||||
|
||||
PageQueue.Enqueue(pe);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Scripts/Services/Help/PagePrompt.cs
Normal file
28
Scripts/Services/Help/PagePrompt.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using Server.Prompts;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PagePrompt : Prompt
|
||||
{
|
||||
private readonly PageType m_Type;
|
||||
public PagePrompt(PageType type)
|
||||
{
|
||||
this.m_Type = type;
|
||||
}
|
||||
|
||||
public override void OnCancel(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(501235, "", 0x35); // Help request aborted.
|
||||
}
|
||||
|
||||
public override void OnResponse(Mobile from, string text)
|
||||
{
|
||||
from.SendLocalizedMessage(501234, "", 0x35); /* The next available Counselor/Game Master will respond as soon as possible.
|
||||
* Please check your Journal for messages every few minutes.
|
||||
*/
|
||||
|
||||
PageQueue.Enqueue(new PageEntry(from, text, this.m_Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Scripts/Services/Help/PagePromptGump.cs
Normal file
60
Scripts/Services/Help/PagePromptGump.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PagePromptGump : Gump
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly PageType m_Type;
|
||||
public PagePromptGump(Mobile from, PageType type)
|
||||
: base(0, 0)
|
||||
{
|
||||
this.m_From = from;
|
||||
this.m_Type = type;
|
||||
|
||||
from.CloseGump(typeof(PagePromptGump));
|
||||
|
||||
this.AddBackground(50, 50, 540, 350, 2600);
|
||||
|
||||
this.AddPage(0);
|
||||
|
||||
this.AddHtmlLocalized(264, 80, 200, 24, 1062524, false, false); // Enter Description
|
||||
this.AddHtmlLocalized(120, 108, 420, 48, 1062638, false, false); // Please enter a brief description (up to 200 characters) of your problem:
|
||||
|
||||
this.AddBackground(100, 148, 440, 200, 3500);
|
||||
this.AddTextEntry(120, 168, 400, 200, 1153, 0, "");
|
||||
|
||||
this.AddButton(175, 355, 2074, 2075, 1, GumpButtonType.Reply, 0); // Okay
|
||||
this.AddButton(405, 355, 2073, 2072, 0, GumpButtonType.Reply, 0); // Cancel
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0)
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(501235, "", 0x35); // Help request aborted.
|
||||
}
|
||||
else
|
||||
{
|
||||
TextRelay entry = info.GetTextEntry(0);
|
||||
string text = (entry == null ? "" : entry.Text.Trim());
|
||||
|
||||
if (text.Length == 0)
|
||||
{
|
||||
this.m_From.SendMessage(0x35, "You must enter a description.");
|
||||
this.m_From.SendGump(new PagePromptGump(this.m_From, this.m_Type));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(501234, "", 0x35); /* The next available Counselor/Game Master will respond as soon as possible.
|
||||
* Please check your Journal for messages every few minutes.
|
||||
*/
|
||||
|
||||
PageQueue.Enqueue(new PageEntry(this.m_From, text, this.m_Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
588
Scripts/Services/Help/PageQueue.cs
Normal file
588
Scripts/Services/Help/PageQueue.cs
Normal file
@@ -0,0 +1,588 @@
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Mail;
|
||||
using System.Linq;
|
||||
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.Engines.Reports;
|
||||
using Server.Gumps;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public enum PageType
|
||||
{
|
||||
Bug,
|
||||
Stuck,
|
||||
Account,
|
||||
Question,
|
||||
Suggestion,
|
||||
Other,
|
||||
VerbalHarassment,
|
||||
PhysicalHarassment
|
||||
}
|
||||
|
||||
public class PageEntry
|
||||
{
|
||||
// What page types should have a speech log as attachment?
|
||||
public static readonly PageType[] SpeechLogAttachment = new[] {PageType.VerbalHarassment};
|
||||
|
||||
private readonly Mobile m_Sender;
|
||||
private Mobile m_Handler;
|
||||
private DateTime m_Sent;
|
||||
private string m_Message;
|
||||
private PageType m_Type;
|
||||
private Point3D m_PageLocation;
|
||||
private Map m_PageMap;
|
||||
private List<SpeechLogEntry> m_SpeechLog;
|
||||
|
||||
public static readonly string SupportEmail = Config.Get("General.SupportEmail", default(string));
|
||||
public static readonly string SupportWebsite = Config.Get("General.SupportWebsite", default(string));
|
||||
|
||||
private readonly PageInfo m_PageInfo;
|
||||
|
||||
public PageInfo PageInfo { get { return m_PageInfo; } }
|
||||
|
||||
public Mobile Sender { get { return m_Sender; } }
|
||||
|
||||
public Mobile Handler
|
||||
{
|
||||
get { return m_Handler; }
|
||||
set
|
||||
{
|
||||
PageQueue.OnHandlerChanged(m_Handler, value, this);
|
||||
m_Handler = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime Sent
|
||||
{
|
||||
get { return m_Sent; }
|
||||
set { m_Sent = value; }
|
||||
}
|
||||
|
||||
public string Message
|
||||
{
|
||||
get { return m_Message; }
|
||||
set { m_Message = value; }
|
||||
}
|
||||
|
||||
public PageType Type
|
||||
{
|
||||
get { return m_Type; }
|
||||
set { m_Type = value; }
|
||||
}
|
||||
|
||||
public Point3D PageLocation
|
||||
{
|
||||
get { return m_PageLocation; }
|
||||
set { m_PageLocation = value; }
|
||||
}
|
||||
|
||||
public Map PageMap
|
||||
{
|
||||
get { return m_PageMap; }
|
||||
set { m_PageMap = value; }
|
||||
}
|
||||
|
||||
public List<SpeechLogEntry> SpeechLog { get { return m_SpeechLog; } }
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
}
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
public void AddResponse(Mobile mob, string text)
|
||||
{
|
||||
if (m_PageInfo != null)
|
||||
{
|
||||
lock (m_PageInfo)
|
||||
m_PageInfo.Responses.Add(PageInfo.GetAccount(mob), text);
|
||||
|
||||
if (PageInfo.ResFromResp(text) != PageResolution.None)
|
||||
{
|
||||
m_PageInfo.UpdateResolver();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PageEntry(Mobile sender, string message, PageType type)
|
||||
{
|
||||
m_Sender = sender;
|
||||
m_Sent = DateTime.UtcNow;
|
||||
m_Message = Utility.FixHtml(message);
|
||||
m_Type = type;
|
||||
m_PageLocation = sender.Location;
|
||||
m_PageMap = sender.Map;
|
||||
|
||||
PlayerMobile pm = sender as PlayerMobile;
|
||||
if (pm != null && pm.SpeechLog != null && Array.IndexOf(SpeechLogAttachment, type) >= 0)
|
||||
{
|
||||
m_SpeechLog = new List<SpeechLogEntry>(pm.SpeechLog);
|
||||
}
|
||||
|
||||
m_Timer = new InternalTimer(this);
|
||||
m_Timer.Start();
|
||||
|
||||
StaffHistory history = Reports.Reports.StaffHistory;
|
||||
|
||||
if (history != null)
|
||||
{
|
||||
m_PageInfo = new PageInfo(this);
|
||||
|
||||
history.AddPage(m_PageInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private static readonly TimeSpan StatusDelay = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
private readonly PageEntry m_Entry;
|
||||
|
||||
public InternalTimer(PageEntry entry)
|
||||
: base(TimeSpan.FromSeconds(1.0), StatusDelay)
|
||||
{
|
||||
m_Entry = entry;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
int index = PageQueue.IndexOf(m_Entry);
|
||||
|
||||
if (m_Entry.Sender.NetState != null && index != -1)
|
||||
{
|
||||
m_Entry.Sender.SendLocalizedMessage(1008077, true, (index + 1).ToString());
|
||||
// Thank you for paging. Queue status :
|
||||
if(SupportEmail == null || SupportWebsite == null)
|
||||
{
|
||||
m_Entry.Sender.SendLocalizedMessage(1008084);
|
||||
// You can reference our website at www.uo.com or contact us at support@uo.com. To cancel your page, please select the help button again and select cancel.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Entry.Sender.SendMessage("You can reference our website at " + SupportWebsite + " or contact us at " + SupportEmail + ". To cancel your page, please select the help button again and select cancel.");
|
||||
}
|
||||
|
||||
if (m_Entry.Handler != null && m_Entry.Handler.NetState == null)
|
||||
{
|
||||
m_Entry.Handler = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index != -1)
|
||||
{
|
||||
m_Entry.AddResponse(m_Entry.Sender, "[Logout]");
|
||||
}
|
||||
|
||||
PageQueue.Remove(m_Entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ResponseEntry
|
||||
{
|
||||
public static readonly TimeSpan ExpirationPeriod = TimeSpan.FromDays(7);
|
||||
|
||||
public static List<ResponseEntry> Entries { get; set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Entries = new List<ResponseEntry>();
|
||||
|
||||
EventSink.Login += new LoginEventHandler(Login);
|
||||
EventSink.BeforeWorldSave += new BeforeWorldSaveEventHandler(BeforeSave);
|
||||
}
|
||||
|
||||
public static void Login(LoginEventArgs args)
|
||||
{
|
||||
Mobile m = args.Mobile;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2.0), () =>
|
||||
{
|
||||
List<ResponseEntry> entries = Entries.Where(e => e.Sender == m).ToList();
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
entry.SendGump();
|
||||
}
|
||||
|
||||
ColUtility.Free(entries);
|
||||
});
|
||||
}
|
||||
|
||||
public static void BeforeSave(BeforeWorldSaveEventArgs args)
|
||||
{
|
||||
var list = Entries.Where(e => e.Expired).ToList();
|
||||
|
||||
foreach (var entry in list)
|
||||
{
|
||||
Entries.Remove(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddEntry(ResponseEntry entry)
|
||||
{
|
||||
if (!Entries.Contains(entry))
|
||||
{
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Sender { get; set; }
|
||||
public Mobile Handler { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
public bool Expired { get { return Expires < DateTime.UtcNow; } }
|
||||
|
||||
public ResponseEntry(Mobile sender, Mobile handler, string message)
|
||||
{
|
||||
Sender = sender;
|
||||
Handler = handler;
|
||||
Message = message;
|
||||
|
||||
Expires = DateTime.UtcNow + ExpirationPeriod;
|
||||
|
||||
AddEntry(this);
|
||||
}
|
||||
|
||||
public void SendGump()
|
||||
{
|
||||
if (Sender.NetState != null)
|
||||
{
|
||||
Sender.SendGump(new MessageSentGump(Sender, Handler != null ? Handler.Name : "Staff", Message));
|
||||
Entries.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
public ResponseEntry(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Sender = reader.ReadMobile();
|
||||
Handler = reader.ReadMobile();
|
||||
Message = reader.ReadString();
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
if (Sender != null && !Expired)
|
||||
{
|
||||
AddEntry(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Sender);
|
||||
writer.Write(Handler);
|
||||
writer.Write(Message);
|
||||
writer.Write(Expires);
|
||||
}
|
||||
}
|
||||
|
||||
public class PageQueue
|
||||
{
|
||||
private static readonly ArrayList m_List = new ArrayList();
|
||||
private static readonly Hashtable m_KeyedByHandler = new Hashtable();
|
||||
private static readonly Hashtable m_KeyedBySender = new Hashtable();
|
||||
|
||||
public static readonly bool ShowStaffOffline = Config.Get("General.ShowStaffOffline", true);
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Pages", AccessLevel.Counselor, Pages_OnCommand);
|
||||
}
|
||||
|
||||
public static bool CheckAllowedToPage(Mobile from)
|
||||
{
|
||||
PlayerMobile pm = from as PlayerMobile;
|
||||
|
||||
if (pm == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pm.DesignContext != null)
|
||||
{
|
||||
from.SendLocalizedMessage(500182); // You cannot request help while customizing a house or transferring a character.
|
||||
return false;
|
||||
}
|
||||
else if (pm.PagingSquelched)
|
||||
{
|
||||
from.SendMessage("You cannot request help, sorry.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetPageTypeName(PageType type)
|
||||
{
|
||||
if (type == PageType.VerbalHarassment)
|
||||
{
|
||||
return "Verbal Harassment";
|
||||
}
|
||||
else if (type == PageType.PhysicalHarassment)
|
||||
{
|
||||
return "Physical Harassment";
|
||||
}
|
||||
else
|
||||
{
|
||||
return type.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnHandlerChanged(Mobile old, Mobile value, PageEntry entry)
|
||||
{
|
||||
if (old != null)
|
||||
{
|
||||
m_KeyedByHandler.Remove(old);
|
||||
}
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
m_KeyedByHandler[value] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("Pages")]
|
||||
[Description("Opens the page queue menu.")]
|
||||
private static void Pages_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
PageEntry entry = (PageEntry)m_KeyedByHandler[e.Mobile];
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
e.Mobile.SendGump(new PageEntryGump(e.Mobile, entry));
|
||||
}
|
||||
else if (m_List.Count > 0)
|
||||
{
|
||||
e.Mobile.SendGump(new PageQueueGump(e.Mobile));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("The page queue is empty.");
|
||||
}
|
||||
}
|
||||
|
||||
#region Page In Queue Gump
|
||||
public static void Pages_OnCalled(Mobile from)
|
||||
{
|
||||
PageEntry entry = (PageEntry)m_KeyedByHandler[from];
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
from.SendGump(new PageEntryGump(from, entry));
|
||||
}
|
||||
else if (m_List.Count > 0)
|
||||
{
|
||||
from.SendGump(new PageQueueGump(from));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("The page queue is empty.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static bool IsHandling(Mobile check)
|
||||
{
|
||||
return m_KeyedByHandler.ContainsKey(check);
|
||||
}
|
||||
|
||||
public static bool Contains(Mobile sender)
|
||||
{
|
||||
return m_KeyedBySender.ContainsKey(sender);
|
||||
}
|
||||
|
||||
public static int IndexOf(PageEntry e)
|
||||
{
|
||||
return m_List.IndexOf(e);
|
||||
}
|
||||
|
||||
public static void Cancel(Mobile sender)
|
||||
{
|
||||
Remove((PageEntry)m_KeyedBySender[sender]);
|
||||
}
|
||||
|
||||
public static void Remove(PageEntry e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.Stop();
|
||||
|
||||
m_List.Remove(e);
|
||||
m_KeyedBySender.Remove(e.Sender);
|
||||
|
||||
if (e.Handler != null)
|
||||
{
|
||||
m_KeyedByHandler.Remove(e.Handler);
|
||||
}
|
||||
}
|
||||
|
||||
public static PageEntry GetEntry(Mobile sender)
|
||||
{
|
||||
return (PageEntry)m_KeyedBySender[sender];
|
||||
}
|
||||
|
||||
public static void Remove(Mobile sender)
|
||||
{
|
||||
Remove(GetEntry(sender));
|
||||
}
|
||||
|
||||
public static ArrayList List { get { return m_List; } }
|
||||
|
||||
public static void Enqueue(PageEntry entry)
|
||||
{
|
||||
m_List.Add(entry);
|
||||
m_KeyedBySender[entry.Sender] = entry;
|
||||
|
||||
bool isStaffOnline = false;
|
||||
|
||||
foreach (NetState ns in NetState.Instances)
|
||||
{
|
||||
Mobile m = ns.Mobile;
|
||||
|
||||
#region Page In Queue Gump
|
||||
if (m != null && m.IsStaff() && m.AutoPageNotify && !IsHandling(m))
|
||||
{
|
||||
m.CloseGump(typeof(PageInQueueGump));
|
||||
m.SendGump(new PageInQueueGump(m));
|
||||
//m.SendMessage( "A new page has been placed in the queue." );
|
||||
}
|
||||
#endregion
|
||||
|
||||
if (m != null && m.IsStaff() && m.AutoPageNotify && m.LastMoveTime - Core.TickCount < 600000)
|
||||
{
|
||||
isStaffOnline = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStaffOnline && ShowStaffOffline)
|
||||
{
|
||||
entry.Sender.SendMessage(
|
||||
"We are sorry, but no staff members are currently available to assist you. Your page will remain in the queue until one becomes available, or until you cancel it manually.");
|
||||
}
|
||||
|
||||
if (Email.FromAddress != null && Email.SpeechLogPageAddresses != null && entry.SpeechLog != null)
|
||||
{
|
||||
SendEmail(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendEmail(PageEntry entry)
|
||||
{
|
||||
Mobile sender = entry.Sender;
|
||||
DateTime time = DateTime.UtcNow;
|
||||
|
||||
MailMessage mail = new MailMessage(Email.FromAddress, Email.SpeechLogPageAddresses);
|
||||
|
||||
mail.Subject = "ServUO Speech Log Page Forwarding";
|
||||
|
||||
using (StringWriter writer = new StringWriter())
|
||||
{
|
||||
writer.WriteLine("ServUO Speech Log Page - {0}", GetPageTypeName(entry.Type));
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine(
|
||||
"From: '{0}', Account: '{1}'", sender.RawName, sender.Account is Account ? sender.Account.Username : "???");
|
||||
writer.WriteLine("Location: {0} [{1}]", sender.Location, sender.Map);
|
||||
writer.WriteLine(
|
||||
"Sent on: {0}/{1:00}/{2:00} {3}:{4:00}:{5:00}",
|
||||
time.Year,
|
||||
time.Month,
|
||||
time.Day,
|
||||
time.Hour,
|
||||
time.Minute,
|
||||
time.Second);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine("Message:");
|
||||
writer.WriteLine("'{0}'", entry.Message);
|
||||
writer.WriteLine();
|
||||
|
||||
writer.WriteLine("Speech Log");
|
||||
writer.WriteLine("==========");
|
||||
|
||||
foreach (SpeechLogEntry logEntry in entry.SpeechLog)
|
||||
{
|
||||
Mobile from = logEntry.From;
|
||||
string fromName = from.RawName;
|
||||
string fromAccount = from.Account is Account ? from.Account.Username : "???";
|
||||
DateTime created = logEntry.Created;
|
||||
string speech = logEntry.Speech;
|
||||
|
||||
writer.WriteLine(
|
||||
"{0}:{1:00}:{2:00} - {3} ({4}): '{5}'",
|
||||
created.Hour,
|
||||
created.Minute,
|
||||
created.Second,
|
||||
fromName,
|
||||
fromAccount,
|
||||
speech);
|
||||
}
|
||||
|
||||
mail.Body = writer.ToString();
|
||||
}
|
||||
|
||||
Email.AsyncSend(mail);
|
||||
}
|
||||
}
|
||||
|
||||
public class PageInQueueGump : Gump
|
||||
{
|
||||
public PageInQueueGump(Mobile owner)
|
||||
: base(180, 50)
|
||||
{
|
||||
Closable = false;
|
||||
Disposable = true;
|
||||
Dragable = true;
|
||||
Resizable = false;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 241, 93, 2620);
|
||||
AddHtml(7, 10, 227, 25, @"<CENTER>There Is A Page In Queue", true, false);
|
||||
AddHtml(7, 58, 227, 25, @"<CENTER>" + DateTime.UtcNow, true, false);
|
||||
AddButton(90, 35, 247, 248, 1, GumpButtonType.Reply, 0);
|
||||
AddImage(18, 39, 57);
|
||||
AddImage(193, 39, 59);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
from.SendGump(new PageQueueGump(from));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
887
Scripts/Services/Help/PageQueueGump.cs
Normal file
887
Scripts/Services/Help/PageQueueGump.cs
Normal file
@@ -0,0 +1,887 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class MessageSentGump : Gump
|
||||
{
|
||||
private readonly string m_Name;
|
||||
private readonly string m_Text;
|
||||
private readonly Mobile m_Mobile;
|
||||
|
||||
public MessageSentGump(Mobile mobile, string name, string text)
|
||||
: base(30, 30)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Text = text;
|
||||
m_Mobile = mobile;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 92, 75, 0xA3C);
|
||||
|
||||
if (mobile != null && mobile.NetState != null && mobile.NetState.IsEnhancedClient)
|
||||
AddBackground(5, 7, 82, 61, 9300);
|
||||
else
|
||||
{
|
||||
AddImageTiled(5, 7, 82, 61, 0xA40);
|
||||
AddAlphaRegion(5, 7, 82, 61);
|
||||
}
|
||||
|
||||
AddImageTiled(9, 11, 21, 53, 0xBBC);
|
||||
|
||||
AddButton(10, 12, 0x7D2, 0x7D2, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(34, 28, 65, 24, 3001002, 0xFFFFFF, false, false); // Message
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
m_Mobile.SendGump(new PageResponseGump(m_Mobile, m_Name, m_Text));
|
||||
//m_Mobile.SendMessage( 0x482, "{0} tells you:", m_Name );
|
||||
//m_Mobile.SendMessage( 0x482, m_Text );
|
||||
}
|
||||
}
|
||||
|
||||
public class PageQueueGump : Gump
|
||||
{
|
||||
private readonly PageEntry[] m_List;
|
||||
public PageQueueGump(Mobile m)
|
||||
: base(30, 30)
|
||||
{
|
||||
Add(new GumpPage(0));
|
||||
|
||||
if (m != null && m.NetState != null && m.NetState.IsEnhancedClient)
|
||||
AddBackground(1, 1, 408, 446, 9300);
|
||||
else
|
||||
{
|
||||
Add(new GumpImageTiled(0, 0, 410, 448, 0xA40));
|
||||
Add(new GumpAlphaRegion(1, 1, 408, 446));
|
||||
}
|
||||
|
||||
Add(new GumpLabel(180, 12, 2100, "Page Queue"));
|
||||
|
||||
ArrayList list = PageQueue.List;
|
||||
|
||||
for (int i = 0; i < list.Count;)
|
||||
{
|
||||
PageEntry e = (PageEntry)list[i];
|
||||
|
||||
if (e.Sender.Deleted)
|
||||
{
|
||||
e.AddResponse(e.Sender, "[Logout]");
|
||||
PageQueue.Remove(e);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
m_List = (PageEntry[])list.ToArray(typeof(PageEntry));
|
||||
|
||||
if (m_List.Length > 0)
|
||||
{
|
||||
Add(new GumpPage(1));
|
||||
|
||||
for (int i = 0; i < m_List.Length; ++i)
|
||||
{
|
||||
PageEntry e = m_List[i];
|
||||
|
||||
if (i >= 5 && (i % 5) == 0)
|
||||
{
|
||||
AddButton(368, 12, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (i / 5) + 1);
|
||||
Add(new GumpLabel(298, 12, 2100, "Next Page"));
|
||||
Add(new GumpPage((i / 5) + 1));
|
||||
AddButton(12, 12, 0xFAE, 0xFB0, 0, GumpButtonType.Page, (i / 5));
|
||||
Add(new GumpLabel(48, 12, 2100, "Previous Page"));
|
||||
}
|
||||
|
||||
string typeString = PageQueue.GetPageTypeName(e.Type);
|
||||
|
||||
string html = String.Format("[{0}] {1} <basefont color=#{2:X6}>[<u>{3}</u>]</basefont>", typeString, e.Message, e.Handler == null ? 0xFF0000 : 0xFF, e.Handler == null ? "Unhandled" : "Handling");
|
||||
|
||||
Add(new GumpHtml(12, 44 + ((i % 5) * 80), 350, 70, html, true, true));
|
||||
AddButton(370, 44 + ((i % 5) * 80) + 24, 0xFA5, 0xFA7, i + 1, GumpButtonType.Reply, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(new GumpLabel(12, 44, 2100, "The page queue is empty."));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID >= 1 && info.ButtonID <= m_List.Length)
|
||||
{
|
||||
if (PageQueue.List.IndexOf(m_List[info.ButtonID - 1]) >= 0)
|
||||
{
|
||||
PageEntryGump g = new PageEntryGump(state.Mobile, m_List[info.ButtonID - 1]);
|
||||
|
||||
g.SendTo(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Mobile.SendGump(new PageQueueGump(state.Mobile));
|
||||
state.Mobile.SendMessage("That page has been removed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PredefinedResponse
|
||||
{
|
||||
private static ArrayList m_List;
|
||||
private string m_Title;
|
||||
private string m_Message;
|
||||
public PredefinedResponse(string title, string message)
|
||||
{
|
||||
m_Title = title;
|
||||
m_Message = message;
|
||||
}
|
||||
|
||||
public static ArrayList List
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_List == null)
|
||||
m_List = Load();
|
||||
|
||||
return m_List;
|
||||
}
|
||||
}
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Title;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Title = value;
|
||||
}
|
||||
}
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Message;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Message = value;
|
||||
}
|
||||
}
|
||||
public static PredefinedResponse Add(string title, string message)
|
||||
{
|
||||
if (m_List == null)
|
||||
m_List = Load();
|
||||
|
||||
PredefinedResponse resp = new PredefinedResponse(title, message);
|
||||
|
||||
m_List.Add(resp);
|
||||
Save();
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
if (m_List == null)
|
||||
m_List = Load();
|
||||
|
||||
try
|
||||
{
|
||||
string path = Path.Combine(Core.BaseDirectory, "Data/pageresponse.cfg");
|
||||
|
||||
using (StreamWriter op = new StreamWriter(path))
|
||||
{
|
||||
for (int i = 0; i < m_List.Count; ++i)
|
||||
{
|
||||
PredefinedResponse resp = (PredefinedResponse)m_List[i];
|
||||
|
||||
op.WriteLine("{0}\t{1}", resp.Title, resp.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList Load()
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
string path = Path.Combine(Core.BaseDirectory, "Data/pageresponse.cfg");
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
string line;
|
||||
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
line = line.Trim();
|
||||
|
||||
if (line.Length == 0 || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
string[] split = line.Split('\t');
|
||||
|
||||
if (split.Length == 2)
|
||||
list.Add(new PredefinedResponse(split[0], split[1]));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public class PredefGump : Gump
|
||||
{
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private readonly Mobile m_From;
|
||||
private readonly PredefinedResponse m_Response;
|
||||
|
||||
public PredefGump(Mobile from, PredefinedResponse response)
|
||||
: base(30, 30)
|
||||
{
|
||||
m_From = from;
|
||||
m_Response = response;
|
||||
|
||||
from.CloseGump(typeof(PredefGump));
|
||||
|
||||
bool canEdit = (from.AccessLevel >= AccessLevel.GameMaster);
|
||||
|
||||
AddPage(0);
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
if (from != null && from.NetState != null && from.NetState.IsEnhancedClient)
|
||||
AddBackground(1, 1, 408, 446, 9300);
|
||||
else
|
||||
{
|
||||
AddImageTiled(0, 0, 410, 448, 0xA40);
|
||||
AddAlphaRegion(1, 1, 408, 446);
|
||||
}
|
||||
|
||||
AddHtml(10, 10, 390, 20, Color(Center("Predefined Responses"), LabelColor32), false, false);
|
||||
|
||||
ArrayList list = PredefinedResponse.List;
|
||||
|
||||
AddPage(1);
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < list.Count; ++i)
|
||||
{
|
||||
if (i >= 5 && (i % 5) == 0)
|
||||
{
|
||||
AddButton(368, 10, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (i / 5) + 1);
|
||||
AddLabel(298, 10, 2100, "Next Page");
|
||||
AddPage((i / 5) + 1);
|
||||
AddButton(12, 10, 0xFAE, 0xFB0, 0, GumpButtonType.Page, i / 5);
|
||||
AddLabel(48, 10, 2100, "Previous Page");
|
||||
}
|
||||
|
||||
PredefinedResponse resp = (PredefinedResponse)list[i];
|
||||
|
||||
string html = String.Format("<u>{0}</u><br>{1}", resp.Title, resp.Message);
|
||||
|
||||
AddHtml(12, 44 + ((i % 5) * 80), 350, 70, html, true, true);
|
||||
|
||||
if (canEdit)
|
||||
{
|
||||
AddButton(370, 44 + ((i % 5) * 80) + 24, 0xFA5, 0xFA7, 2 + (i * 3), GumpButtonType.Reply, 0);
|
||||
|
||||
if (i > 0)
|
||||
AddButton(377, 44 + ((i % 5) * 80) + 2, 0x15E0, 0x15E4, 3 + (i * 3), GumpButtonType.Reply, 0);
|
||||
else
|
||||
AddImage(377, 44 + ((i % 5) * 80) + 2, 0x25E4);
|
||||
|
||||
if (i < (list.Count - 1))
|
||||
AddButton(377, 44 + ((i % 5) * 80) + 70 - 2 - 16, 0x15E2, 0x15E6, 4 + (i * 3), GumpButtonType.Reply, 0);
|
||||
else
|
||||
AddImage(377, 44 + ((i % 5) * 80) + 70 - 2 - 16, 0x25E8);
|
||||
}
|
||||
}
|
||||
|
||||
if (canEdit)
|
||||
{
|
||||
if (i >= 5 && (i % 5) == 0)
|
||||
{
|
||||
AddButton(368, 10, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (i / 5) + 1);
|
||||
AddLabel(298, 10, 2100, "Next Page");
|
||||
AddPage((i / 5) + 1);
|
||||
AddButton(12, 10, 0xFAE, 0xFB0, 0, GumpButtonType.Page, i / 5);
|
||||
AddLabel(48, 10, 2100, "Previous Page");
|
||||
}
|
||||
|
||||
AddButton(12, 44 + ((i % 5) * 80), 0xFAB, 0xFAD, 1, GumpButtonType.Reply, 0);
|
||||
AddHtml(45, 44 + ((i % 5) * 80), 200, 20, Color("New Response", LabelColor32), false, false);
|
||||
}
|
||||
}
|
||||
else if (canEdit)
|
||||
{
|
||||
AddImageTiled(0, 0, 410, 250, 0xA40);
|
||||
|
||||
if (from.NetState.IsEnhancedClient)
|
||||
AddBackground(1, 1, 408, 248, 9300);
|
||||
else
|
||||
AddAlphaRegion(1, 1, 408, 248);
|
||||
|
||||
AddHtml(10, 10, 390, 20, Color(Center("Predefined Response Editor"), LabelColor32), false, false);
|
||||
|
||||
AddButton(10, 40, 0xFB1, 0xFB3, 1, GumpButtonType.Reply, 0);
|
||||
AddHtml(45, 40, 200, 20, Color("Remove", LabelColor32), false, false);
|
||||
|
||||
AddButton(10, 70, 0xFA5, 0xFA7, 2, GumpButtonType.Reply, 0);
|
||||
AddHtml(45, 70, 200, 20, Color("Title:", LabelColor32), false, false);
|
||||
AddTextInput(10, 90, 300, 20, 0, response.Title);
|
||||
|
||||
AddButton(10, 120, 0xFA5, 0xFA7, 3, GumpButtonType.Reply, 0);
|
||||
AddHtml(45, 120, 200, 20, Color("Message:", LabelColor32), false, false);
|
||||
AddTextInput(10, 140, 390, 100, 1, response.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text)
|
||||
{
|
||||
return String.Format("<CENTER>{0}</CENTER>", text);
|
||||
}
|
||||
|
||||
public string Color(string text, int color)
|
||||
{
|
||||
return String.Format("<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text);
|
||||
}
|
||||
|
||||
public void AddTextInput(int x, int y, int w, int h, int id, string def)
|
||||
{
|
||||
AddImageTiled(x, y, w, h, 0xA40);
|
||||
AddImageTiled(x + 1, y + 1, w - 2, h - 2, 0xBBC);
|
||||
AddTextEntry(x + 3, y + 1, w - 4, h - 2, 0x480, id, def);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_From.AccessLevel < AccessLevel.Administrator)
|
||||
return;
|
||||
|
||||
if (m_Response == null)
|
||||
{
|
||||
int index = info.ButtonID - 1;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
PredefinedResponse resp = new PredefinedResponse("", "");
|
||||
|
||||
ArrayList list = PredefinedResponse.List;
|
||||
list.Add(resp);
|
||||
|
||||
m_From.SendGump(new PredefGump(m_From, resp));
|
||||
}
|
||||
else
|
||||
{
|
||||
--index;
|
||||
|
||||
int type = index % 3;
|
||||
index /= 3;
|
||||
|
||||
ArrayList list = PredefinedResponse.List;
|
||||
|
||||
if (index >= 0 && index < list.Count)
|
||||
{
|
||||
PredefinedResponse resp = (PredefinedResponse)list[index];
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case 0: // edit
|
||||
{
|
||||
m_From.SendGump(new PredefGump(m_From, resp));
|
||||
break;
|
||||
}
|
||||
case 1: // move up
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
list.RemoveAt(index);
|
||||
list.Insert(index - 1, resp);
|
||||
|
||||
PredefinedResponse.Save();
|
||||
m_From.SendGump(new PredefGump(m_From, null));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // move down
|
||||
{
|
||||
if (index < (list.Count - 1))
|
||||
{
|
||||
list.RemoveAt(index);
|
||||
list.Insert(index + 1, resp);
|
||||
|
||||
PredefinedResponse.Save();
|
||||
m_From.SendGump(new PredefGump(m_From, null));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList list = PredefinedResponse.List;
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
list.Remove(m_Response);
|
||||
|
||||
PredefinedResponse.Save();
|
||||
m_From.SendGump(new PredefGump(m_From, null));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
TextRelay te = info.GetTextEntry(0);
|
||||
|
||||
if (te != null)
|
||||
m_Response.Title = te.Text;
|
||||
|
||||
PredefinedResponse.Save();
|
||||
m_From.SendGump(new PredefGump(m_From, m_Response));
|
||||
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
TextRelay te = info.GetTextEntry(1);
|
||||
|
||||
if (te != null)
|
||||
m_Response.Message = te.Text;
|
||||
|
||||
PredefinedResponse.Save();
|
||||
m_From.SendGump(new PredefGump(m_From, m_Response));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PageEntryGump : Gump
|
||||
{
|
||||
private static readonly int[] m_AccessLevelHues = new int[]
|
||||
{
|
||||
2100, //Player
|
||||
2122, //VIP
|
||||
2122, //Counselor
|
||||
2117, //Decorator
|
||||
2117, //Spawner
|
||||
2117, //GameMaster
|
||||
2129, //Seer
|
||||
2415, //Admin
|
||||
2415, //Developer
|
||||
2415, //CoOwner
|
||||
2415 //Owner
|
||||
};
|
||||
|
||||
private readonly PageEntry m_Entry;
|
||||
private readonly Mobile m_Mobile;
|
||||
|
||||
public PageEntryGump(Mobile m, PageEntry entry)
|
||||
: base(30, 30)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Entry = entry;
|
||||
|
||||
int buttons = 0;
|
||||
|
||||
int bottom = 356;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
if (m != null && m.NetState != null && m.NetState.IsEnhancedClient)
|
||||
AddBackground(1, 1, 408, 454, 9300);
|
||||
else
|
||||
{
|
||||
AddImageTiled(0, 0, 410, 456, 0xA40);
|
||||
AddAlphaRegion(1, 1, 408, 454);
|
||||
}
|
||||
|
||||
AddPage(1);
|
||||
|
||||
AddLabel(18, 18, 2100, "Sent:");
|
||||
AddLabelCropped(128, 18, 264, 20, 2100, entry.Sent.ToString());
|
||||
|
||||
AddLabel(18, 38, 2100, "Sender:");
|
||||
AddLabelCropped(128, 38, 264, 20, 2100, String.Format("{0} {1} [{2}]", entry.Sender.RawName, entry.Sender.Location, entry.Sender.Map));
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFAB, 0xFAD, 8, GumpButtonType.Reply, 0);
|
||||
AddImageTiled(52, bottom - (buttons * 22) + 1, 340, 80, 0xA40/*0xBBC*//*0x2458*/);
|
||||
AddImageTiled(53, bottom - (buttons * 22) + 2, 338, 78, 0xBBC/*0x2426*/);
|
||||
AddTextEntry(55, bottom - (buttons++ * 22) + 2, 336, 78, 0x480, 0, "");
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA5, 0xFA7, 0, GumpButtonType.Page, 2);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Predefined Response");
|
||||
|
||||
if (entry.Sender != m)
|
||||
{
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Go to Sender");
|
||||
}
|
||||
|
||||
AddLabel(18, 58, 2100, "Handler:");
|
||||
|
||||
if (entry.Handler == null)
|
||||
{
|
||||
AddLabelCropped(128, 58, 264, 20, 2100, "Unhandled");
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFB1, 0xFB3, 5, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Delete Page");
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFB7, 0xFB9, 4, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Handle Page");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLabelCropped(128, 58, 264, 20, m_AccessLevelHues[(int)entry.Handler.AccessLevel], entry.Handler.Name);
|
||||
|
||||
if (entry.Handler != m)
|
||||
{
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA5, 0xFA7, 2, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Go to Handler");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA2, 0xFA4, 6, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Abandon Page");
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFB7, 0xFB9, 7, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Page Handled");
|
||||
}
|
||||
}
|
||||
|
||||
AddLabel(18, 78, 2100, "Page Location:");
|
||||
AddLabelCropped(128, 78, 264, 20, 2100, String.Format("{0} [{1}]", entry.PageLocation, entry.PageMap));
|
||||
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA5, 0xFA7, 3, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "Go to Page Location");
|
||||
|
||||
if (entry.SpeechLog != null)
|
||||
{
|
||||
AddButton(18, bottom - (buttons * 22), 0xFA5, 0xFA7, 10, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, bottom - (buttons++ * 22), 2100, "View Speech Log");
|
||||
}
|
||||
|
||||
AddLabel(18, 98, 2100, "Page Type:");
|
||||
AddLabelCropped(128, 98, 264, 20, 2100, PageQueue.GetPageTypeName(entry.Type));
|
||||
|
||||
AddLabel(18, 118, 2100, "Message:");
|
||||
AddHtml(128, 118, 250, 100, entry.Message, true, true);
|
||||
|
||||
AddPage(2);
|
||||
|
||||
ArrayList preresp = PredefinedResponse.List;
|
||||
|
||||
AddButton(18, 18, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
|
||||
AddButton(410 - 18 - 32, 18, 0xFAB, 0xFAC, 9, GumpButtonType.Reply, 0);
|
||||
|
||||
if (preresp.Count == 0)
|
||||
{
|
||||
AddLabel(52, 18, 2100, "There are no predefined responses.");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLabel(52, 18, 2100, "Back");
|
||||
|
||||
for (int i = 0; i < preresp.Count; ++i)
|
||||
{
|
||||
AddButton(18, 40 + (i * 22), 0xFA5, 0xFA7, 100 + i, GumpButtonType.Reply, 0);
|
||||
AddLabel(52, 40 + (i * 22), 2100, ((PredefinedResponse)preresp[i]).Title);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void Resend(NetState state)
|
||||
{
|
||||
PageEntryGump g = new PageEntryGump(m_Mobile, m_Entry);
|
||||
|
||||
g.SendTo(state);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 0 && PageQueue.List.IndexOf(m_Entry) < 0)
|
||||
{
|
||||
state.Mobile.SendGump(new PageQueueGump(state.Mobile));
|
||||
state.Mobile.SendMessage("That page has been removed.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 0: // close
|
||||
{
|
||||
if (m_Entry.Handler != state.Mobile)
|
||||
{
|
||||
PageQueueGump g = new PageQueueGump(state.Mobile);
|
||||
|
||||
g.SendTo(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // go to sender
|
||||
{
|
||||
Mobile m = state.Mobile;
|
||||
|
||||
if (m_Entry.Sender.Deleted)
|
||||
{
|
||||
m.SendMessage("That character no longer exists.");
|
||||
}
|
||||
else if (m_Entry.Sender.Map == null || m_Entry.Sender.Map == Map.Internal)
|
||||
{
|
||||
m.SendMessage("That character is not in the world.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Go Sender]");
|
||||
m.MoveToWorld(m_Entry.Sender.Location, m_Entry.Sender.Map);
|
||||
|
||||
m.SendMessage("You have been teleported to that page's sender.");
|
||||
|
||||
Resend(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // go to handler
|
||||
{
|
||||
Mobile m = state.Mobile;
|
||||
Mobile h = m_Entry.Handler;
|
||||
|
||||
if (h != null)
|
||||
{
|
||||
if (h.Deleted)
|
||||
{
|
||||
m.SendMessage("That character no longer exists.");
|
||||
}
|
||||
else if (h.Map == null || h.Map == Map.Internal)
|
||||
{
|
||||
m.SendMessage("That character is not in the world.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Go Handler]");
|
||||
m.MoveToWorld(h.Location, h.Map);
|
||||
|
||||
m.SendMessage("You have been teleported to that page's handler.");
|
||||
Resend(state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage("Nobody is handling that page.");
|
||||
Resend(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // go to page location
|
||||
{
|
||||
Mobile m = state.Mobile;
|
||||
|
||||
if (m_Entry.PageMap == null || m_Entry.PageMap == Map.Internal)
|
||||
{
|
||||
m.SendMessage("That location is not in the world.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Go PageLoc]");
|
||||
m.MoveToWorld(m_Entry.PageLocation, m_Entry.PageMap);
|
||||
|
||||
state.Mobile.SendMessage("You have been teleported to the original page location.");
|
||||
|
||||
Resend(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 4: // handle page
|
||||
{
|
||||
if (m_Entry.Handler == null)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Handling]");
|
||||
m_Entry.Handler = state.Mobile;
|
||||
|
||||
state.Mobile.SendMessage("You are now handling the page.");
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Mobile.SendMessage("Someone is already handling that page.");
|
||||
}
|
||||
|
||||
Resend(state);
|
||||
|
||||
break;
|
||||
}
|
||||
case 5: // delete page
|
||||
{
|
||||
if (m_Entry.Handler == null)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Deleting]");
|
||||
PageQueue.Remove(m_Entry);
|
||||
|
||||
state.Mobile.SendMessage("You delete the page.");
|
||||
|
||||
PageQueueGump g = new PageQueueGump(state.Mobile);
|
||||
|
||||
g.SendTo(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Mobile.SendMessage("Someone is handling that page, it can not be deleted.");
|
||||
|
||||
Resend(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 6: // abandon page
|
||||
{
|
||||
if (m_Entry.Handler == state.Mobile)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Abandoning]");
|
||||
state.Mobile.SendMessage("You abandon the page.");
|
||||
|
||||
m_Entry.Handler = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Mobile.SendMessage("You are not handling that page.");
|
||||
}
|
||||
|
||||
Resend(state);
|
||||
|
||||
break;
|
||||
}
|
||||
case 7: // page handled
|
||||
{
|
||||
if (m_Entry.Handler == state.Mobile)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Handled]");
|
||||
PageQueue.Remove(m_Entry);
|
||||
|
||||
m_Entry.Handler = null;
|
||||
|
||||
state.Mobile.SendMessage("You mark the page as handled, and remove it from the queue.");
|
||||
|
||||
PageQueueGump g = new PageQueueGump(state.Mobile);
|
||||
|
||||
g.SendTo(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Mobile.SendMessage("You are not handling that page.");
|
||||
|
||||
Resend(state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 8: // Send message
|
||||
{
|
||||
TextRelay text = info.GetTextEntry(0);
|
||||
|
||||
if (text != null)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[Response] " + text.Text);
|
||||
|
||||
if (m_Entry.Sender.NetState != null)
|
||||
{
|
||||
m_Entry.Sender.SendGump(new MessageSentGump(m_Entry.Sender, state.Mobile.Name, text.Text));
|
||||
}
|
||||
else
|
||||
{
|
||||
ResponseEntry.AddEntry(new ResponseEntry(m_Entry.Sender, state.Mobile, text.Text));
|
||||
}
|
||||
//m_Entry.Sender.SendMessage( 0x482, "{0} tells you:", state.Mobile.Name );
|
||||
//m_Entry.Sender.SendMessage( 0x482, text.Text );
|
||||
}
|
||||
|
||||
Resend(state);
|
||||
|
||||
break;
|
||||
}
|
||||
case 9: // predef overview
|
||||
{
|
||||
Resend(state);
|
||||
state.Mobile.SendGump(new PredefGump(state.Mobile, null));
|
||||
|
||||
break;
|
||||
}
|
||||
case 10: // View Speech Log
|
||||
{
|
||||
Resend(state);
|
||||
|
||||
if (m_Entry.SpeechLog != null)
|
||||
{
|
||||
Gump gump = new SpeechLogGump(m_Entry.Sender, m_Entry.SpeechLog);
|
||||
state.Mobile.SendGump(gump);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
int index = info.ButtonID - 100;
|
||||
ArrayList preresp = PredefinedResponse.List;
|
||||
|
||||
if (index >= 0 && index < preresp.Count)
|
||||
{
|
||||
m_Entry.AddResponse(state.Mobile, "[PreDef] " + ((PredefinedResponse)preresp[index]).Title);
|
||||
m_Entry.Sender.SendGump(new MessageSentGump(m_Entry.Sender, state.Mobile.Name, ((PredefinedResponse)preresp[index]).Message));
|
||||
}
|
||||
|
||||
Resend(state);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Scripts/Services/Help/PageResponseGump.cs
Normal file
39
Scripts/Services/Help/PageResponseGump.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PageResponseGump : Gump
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly string m_Name;
|
||||
private readonly string m_Text;
|
||||
public PageResponseGump(Mobile from, string name, string text)
|
||||
: base(0, 0)
|
||||
{
|
||||
this.m_From = from;
|
||||
this.m_Name = name;
|
||||
this.m_Text = text;
|
||||
|
||||
this.AddBackground(50, 25, 540, 430, 2600);
|
||||
|
||||
this.AddPage(0);
|
||||
|
||||
this.AddHtmlLocalized(150, 40, 360, 40, 1062610, false, false); // <CENTER><U>Ultima Online Help Response</U></CENTER>
|
||||
|
||||
this.AddHtml(80, 90, 480, 290, String.Format("{0} tells {1}: {2}", name, from.Name, text), true, true);
|
||||
|
||||
this.AddHtmlLocalized(80, 390, 480, 40, 1062611, false, false); // Clicking the OKAY button will remove the reponse you have received.
|
||||
this.AddButton(400, 417, 2074, 2075, 1, GumpButtonType.Reply, 0); // OKAY
|
||||
|
||||
this.AddButton(475, 417, 2073, 2072, 0, GumpButtonType.Reply, 0); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 1)
|
||||
this.m_From.SendGump(new MessageSentGump(this.m_From, this.m_Name, this.m_Text));
|
||||
}
|
||||
}
|
||||
}
|
||||
172
Scripts/Services/Help/SpeechLog.cs
Normal file
172
Scripts/Services/Help/SpeechLog.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class SpeechLog : IEnumerable<SpeechLogEntry>
|
||||
{
|
||||
// Are speech logs enabled?
|
||||
public static readonly bool Enabled = true;
|
||||
|
||||
// How long should we maintain each speech entry?
|
||||
public static readonly TimeSpan EntryDuration = TimeSpan.FromMinutes(20.0);
|
||||
|
||||
// What is the maximum number of entries a log can contain? (0 -> no limit)
|
||||
public static readonly int MaxLength = 0;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("SpeechLog", AccessLevel.GameMaster, new CommandEventHandler(SpeechLog_OnCommand));
|
||||
}
|
||||
|
||||
[Usage("SpeechLog")]
|
||||
[Description("Opens the speech log of a given target.")]
|
||||
private static void SpeechLog_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
from.SendMessage("Target a player to view his speech log.");
|
||||
e.Mobile.Target = new SpeechLogTarget();
|
||||
}
|
||||
|
||||
private class SpeechLogTarget : Target
|
||||
{
|
||||
public SpeechLogTarget()
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
PlayerMobile pm = targeted as PlayerMobile;
|
||||
|
||||
if (pm == null)
|
||||
{
|
||||
from.SendMessage("Speech logs aren't supported on that target.");
|
||||
}
|
||||
else if (from != targeted && from.AccessLevel <= pm.AccessLevel && from.AccessLevel != AccessLevel.Owner)
|
||||
{
|
||||
from.SendMessage("You don't have the required access level to view {0} speech log.", pm.Female ? "her" : "his");
|
||||
}
|
||||
else if (pm.SpeechLog == null)
|
||||
{
|
||||
from.SendMessage("{0} has no speech log.", pm.Female ? "She" : "He");
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandLogging.WriteLine(from, "{0} {1} viewing speech log of {2}", from.AccessLevel, CommandLogging.Format(from), CommandLogging.Format(targeted));
|
||||
|
||||
Gump gump = new SpeechLogGump(pm, pm.SpeechLog);
|
||||
from.SendGump(gump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Queue<SpeechLogEntry> m_Queue;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Queue.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public SpeechLog()
|
||||
{
|
||||
this.m_Queue = new Queue<SpeechLogEntry>();
|
||||
}
|
||||
|
||||
public void Add(Mobile from, string speech)
|
||||
{
|
||||
this.Add(new SpeechLogEntry(from, speech));
|
||||
}
|
||||
|
||||
public void Add(SpeechLogEntry entry)
|
||||
{
|
||||
if (MaxLength > 0 && this.m_Queue.Count >= MaxLength)
|
||||
this.m_Queue.Dequeue();
|
||||
|
||||
this.Clean();
|
||||
|
||||
this.m_Queue.Enqueue(entry);
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
while (this.m_Queue.Count > 0)
|
||||
{
|
||||
SpeechLogEntry entry = (SpeechLogEntry)this.m_Queue.Peek();
|
||||
|
||||
if (DateTime.UtcNow - entry.Created > EntryDuration)
|
||||
this.m_Queue.Dequeue();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(SpeechLogEntry[] array, int index)
|
||||
{
|
||||
this.m_Queue.CopyTo(array, index);
|
||||
}
|
||||
|
||||
#region IEnumerable<SpeechLogEntry> Members
|
||||
|
||||
IEnumerator<SpeechLogEntry> IEnumerable<SpeechLogEntry>.GetEnumerator()
|
||||
{
|
||||
return this.m_Queue.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.m_Queue.GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class SpeechLogEntry
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly string m_Speech;
|
||||
private DateTime m_Created;
|
||||
|
||||
public Mobile From
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_From;
|
||||
}
|
||||
}
|
||||
public string Speech
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Speech;
|
||||
}
|
||||
}
|
||||
public DateTime Created
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Created;
|
||||
}
|
||||
set { this.m_Created = value; }
|
||||
}
|
||||
|
||||
public SpeechLogEntry(Mobile from, string speech)
|
||||
{
|
||||
this.m_From = from;
|
||||
this.m_Speech = speech;
|
||||
this.m_Created = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Scripts/Services/Help/SpeechLogGump.cs
Normal file
109
Scripts/Services/Help/SpeechLogGump.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Accounting;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class SpeechLogGump : Gump
|
||||
{
|
||||
public static readonly int MaxEntriesPerPage = 30;
|
||||
private readonly Mobile m_Player;
|
||||
private readonly List<SpeechLogEntry> m_Log;
|
||||
private readonly int m_Page;
|
||||
public SpeechLogGump(Mobile player, SpeechLog log)
|
||||
: this(player, new List<SpeechLogEntry>(log))
|
||||
{
|
||||
}
|
||||
|
||||
public SpeechLogGump(Mobile player, List<SpeechLogEntry> log)
|
||||
: this(player, log, (log.Count - 1) / MaxEntriesPerPage)
|
||||
{
|
||||
}
|
||||
|
||||
public SpeechLogGump(Mobile player, List<SpeechLogEntry> log, int page)
|
||||
: base(500, 30)
|
||||
{
|
||||
this.m_Player = player;
|
||||
this.m_Log = log;
|
||||
this.m_Page = page;
|
||||
|
||||
this.AddImageTiled(0, 0, 300, 425, 0xA40);
|
||||
this.AddAlphaRegion(1, 1, 298, 423);
|
||||
|
||||
string playerName = player.Name;
|
||||
string playerAccount = player.Account is Account ? player.Account.Username : "???";
|
||||
|
||||
this.AddHtml(10, 10, 280, 20, String.Format("<basefont color=#A0A0FF><center>SPEECH LOG - {0} (<i>{1}</i>)</center></basefont>", playerName, Utility.FixHtml(playerAccount)), false, false);
|
||||
|
||||
int lastPage = (log.Count - 1) / MaxEntriesPerPage;
|
||||
|
||||
string sLog;
|
||||
|
||||
if (page < 0 || page > lastPage)
|
||||
{
|
||||
sLog = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
int max = log.Count - (lastPage - page) * MaxEntriesPerPage;
|
||||
int min = Math.Max(max - MaxEntriesPerPage, 0);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (int i = min; i < max; i++)
|
||||
{
|
||||
SpeechLogEntry entry = log[i];
|
||||
|
||||
Mobile m = entry.From;
|
||||
|
||||
string name = m.Name;
|
||||
string account = m.Account is Account ? m.Account.Username : "???";
|
||||
string speech = entry.Speech;
|
||||
|
||||
if (i != min)
|
||||
builder.Append("<br>");
|
||||
|
||||
builder.AppendFormat("<u>{0}</u> (<i>{1}</i>): {2}", name, Utility.FixHtml(account), Utility.FixHtml(speech));
|
||||
}
|
||||
|
||||
sLog = builder.ToString();
|
||||
}
|
||||
|
||||
this.AddHtml(10, 40, 280, 350, sLog, false, true);
|
||||
|
||||
if (page > 0)
|
||||
this.AddButton(10, 395, 0xFAE, 0xFB0, 1, GumpButtonType.Reply, 0); // Previous page
|
||||
|
||||
this.AddLabel(45, 395, 0x481, String.Format("Current page: {0}/{1}", page + 1, lastPage + 1));
|
||||
|
||||
if (page < lastPage)
|
||||
this.AddButton(261, 395, 0xFA5, 0xFA7, 2, GumpButtonType.Reply, 0); // Next page
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 1: // Previous page
|
||||
{
|
||||
if (this.m_Page - 1 >= 0)
|
||||
from.SendGump(new SpeechLogGump(this.m_Player, this.m_Log, this.m_Page - 1));
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Next page
|
||||
{
|
||||
if ((this.m_Page + 1) * MaxEntriesPerPage < this.m_Log.Count)
|
||||
from.SendGump(new SpeechLogGump(this.m_Player, this.m_Log, this.m_Page + 1));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
360
Scripts/Services/Help/StuckMenu.cs
Normal file
360
Scripts/Services/Help/StuckMenu.cs
Normal file
@@ -0,0 +1,360 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using System.Linq;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Menus.Questions
|
||||
{
|
||||
public class StuckMenuEntry
|
||||
{
|
||||
private readonly int m_Name;
|
||||
private readonly Point3D[] m_Locations;
|
||||
public StuckMenuEntry(int name, Point3D[] locations)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Locations = locations;
|
||||
}
|
||||
|
||||
public int Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
public Point3D[] Locations
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Locations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class StuckMenu : Gump
|
||||
{
|
||||
private static readonly StuckMenuEntry[] m_Entries = new StuckMenuEntry[]
|
||||
{
|
||||
// Britain
|
||||
new StuckMenuEntry(1011028, new Point3D[]
|
||||
{
|
||||
new Point3D(1522, 1757, 28),
|
||||
new Point3D(1519, 1619, 10),
|
||||
new Point3D(1457, 1538, 30),
|
||||
new Point3D(1607, 1568, 20),
|
||||
new Point3D(1643, 1680, 18)
|
||||
}),
|
||||
|
||||
// Trinsic
|
||||
new StuckMenuEntry(1011029, new Point3D[]
|
||||
{
|
||||
new Point3D(2005, 2754, 30),
|
||||
new Point3D(1993, 2827, 0),
|
||||
new Point3D(2044, 2883, 0),
|
||||
new Point3D(1876, 2859, 20),
|
||||
new Point3D(1865, 2687, 0)
|
||||
}),
|
||||
|
||||
// Vesper
|
||||
new StuckMenuEntry(1011030, new Point3D[]
|
||||
{
|
||||
new Point3D(2973, 891, 0),
|
||||
new Point3D(3003, 776, 0),
|
||||
new Point3D(2910, 727, 0),
|
||||
new Point3D(2865, 804, 0),
|
||||
new Point3D(2832, 927, 0)
|
||||
}),
|
||||
|
||||
// Minoc
|
||||
new StuckMenuEntry(1011031, new Point3D[]
|
||||
{
|
||||
new Point3D(2498, 392, 0),
|
||||
new Point3D(2433, 541, 0),
|
||||
new Point3D(2445, 501, 15),
|
||||
new Point3D(2501, 469, 15),
|
||||
new Point3D(2444, 420, 15)
|
||||
}),
|
||||
|
||||
// Yew
|
||||
new StuckMenuEntry(1011032, new Point3D[]
|
||||
{
|
||||
new Point3D(490, 1166, 0),
|
||||
new Point3D(652, 1098, 0),
|
||||
new Point3D(650, 1013, 0),
|
||||
new Point3D(536, 979, 0),
|
||||
new Point3D(464, 970, 0)
|
||||
}),
|
||||
|
||||
// Cove
|
||||
new StuckMenuEntry(1011033, new Point3D[]
|
||||
{
|
||||
new Point3D(2230, 1159, 0),
|
||||
new Point3D(2218, 1203, 0),
|
||||
new Point3D(2247, 1194, 0),
|
||||
new Point3D(2236, 1224, 0),
|
||||
new Point3D(2273, 1231, 0)
|
||||
})
|
||||
};
|
||||
|
||||
private static readonly StuckMenuEntry[] m_T2AEntries = new StuckMenuEntry[]
|
||||
{
|
||||
// Papua
|
||||
new StuckMenuEntry(1011057, new Point3D[]
|
||||
{
|
||||
new Point3D(5720, 3109, -1),
|
||||
new Point3D(5677, 3176, -3),
|
||||
new Point3D(5678, 3227, 0),
|
||||
new Point3D(5769, 3206, -2),
|
||||
new Point3D(5777, 3270, -1)
|
||||
}),
|
||||
|
||||
// Delucia
|
||||
new StuckMenuEntry(1011058, new Point3D[]
|
||||
{
|
||||
new Point3D(5216, 4033, 37),
|
||||
new Point3D(5262, 4049, 37),
|
||||
new Point3D(5284, 4006, 37),
|
||||
new Point3D(5189, 3971, 39),
|
||||
new Point3D(5243, 3960, 37)
|
||||
})
|
||||
};
|
||||
|
||||
private static readonly StuckMenuEntry[] m_TerMurEntries = new StuckMenuEntry[]
|
||||
{
|
||||
// Royal City
|
||||
new StuckMenuEntry(1112571, new Point3D[]
|
||||
{
|
||||
new Point3D(750, 3440, -20),
|
||||
new Point3D(709, 3444, -20),
|
||||
new Point3D(802, 3431, -10),
|
||||
new Point3D(848, 3450, -19),
|
||||
new Point3D(738, 3486, -19)
|
||||
}),
|
||||
|
||||
// Holy City
|
||||
new StuckMenuEntry(1112572, new Point3D[]
|
||||
{
|
||||
new Point3D(997, 3869, -42),
|
||||
new Point3D(961, 3921, -42),
|
||||
new Point3D(996, 3962, -42)
|
||||
})
|
||||
};
|
||||
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly Mobile m_Sender;
|
||||
private readonly bool m_MarkUse;
|
||||
private Timer m_Timer;
|
||||
|
||||
public StuckMenu(Mobile beholder, Mobile beheld, bool markUse)
|
||||
: base(150, 50)
|
||||
{
|
||||
m_Sender = beholder;
|
||||
m_Mobile = beheld;
|
||||
m_MarkUse = markUse;
|
||||
|
||||
Closable = false;
|
||||
Dragable = false;
|
||||
Disposable = false;
|
||||
|
||||
AddBackground(0, 0, 270, 320, 2600);
|
||||
|
||||
AddHtmlLocalized(50, 20, 250, 35, 1011027, false, false); // Chose a town:
|
||||
|
||||
StuckMenuEntry[] entries = IsTerMur(beheld) ? m_TerMurEntries : IsInSecondAgeArea(beheld) ? m_T2AEntries : m_Entries;
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
StuckMenuEntry entry = entries[i];
|
||||
|
||||
AddButton(50, 55 + 35 * i, 208, 209, i + 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(75, 55 + 35 * i, 335, 40, entry.Name, false, false);
|
||||
}
|
||||
|
||||
AddButton(55, 263, 4005, 4007, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(90, 265, 200, 35, 1011012, false, false); // CANCEL
|
||||
}
|
||||
|
||||
public void BeginClose()
|
||||
{
|
||||
StopClose();
|
||||
|
||||
m_Timer = new CloseTimer(m_Mobile);
|
||||
m_Timer.Start();
|
||||
|
||||
m_Mobile.Frozen = true;
|
||||
}
|
||||
|
||||
public void StopClose()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
|
||||
m_Mobile.Frozen = false;
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
StopClose();
|
||||
|
||||
if (Factions.Sigil.ExistsOn(m_Mobile))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
}
|
||||
else if (info.ButtonID == 0)
|
||||
{
|
||||
if (m_Mobile == m_Sender)
|
||||
m_Mobile.SendLocalizedMessage(1010588); // You choose not to go to any city.
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = info.ButtonID - 1;
|
||||
StuckMenuEntry[] entries = IsTerMur(m_Mobile) ? m_TerMurEntries : IsInSecondAgeArea(m_Mobile) ? m_T2AEntries : m_Entries;
|
||||
|
||||
if (index >= 0 && index < entries.Length)
|
||||
Teleport(entries[index]);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsInSecondAgeArea(Mobile m)
|
||||
{
|
||||
if (m.Map != Map.Trammel && m.Map != Map.Felucca)
|
||||
return false;
|
||||
|
||||
if (m.X >= 5120 && m.Y >= 2304)
|
||||
return true;
|
||||
|
||||
if (m.Region.IsPartOf("Terathan Keep"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsTerMur(Mobile m)
|
||||
{
|
||||
return m.Map == Map.TerMur && !SpellHelper.IsEodon(m.Map, m.Location);
|
||||
}
|
||||
|
||||
private void Teleport(StuckMenuEntry entry)
|
||||
{
|
||||
if (m_MarkUse)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1010589); // You will be teleported within the next two minutes.
|
||||
|
||||
new TeleportTimer(m_Mobile, entry, TimeSpan.FromSeconds(10.0 + (Utility.RandomDouble() * 110.0))).Start();
|
||||
|
||||
m_Mobile.UsedStuckMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
new TeleportTimer(m_Mobile, entry, TimeSpan.Zero).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private class CloseTimer : Timer
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly DateTime m_End;
|
||||
public CloseTimer(Mobile m)
|
||||
: base(TimeSpan.Zero, TimeSpan.FromSeconds(1.0))
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_End = DateTime.UtcNow + TimeSpan.FromMinutes(3.0);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Mobile.NetState == null || DateTime.UtcNow > m_End)
|
||||
{
|
||||
m_Mobile.Frozen = false;
|
||||
m_Mobile.CloseGump(typeof(StuckMenu));
|
||||
|
||||
Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Frozen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TeleportTimer : Timer
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly StuckMenuEntry m_Destination;
|
||||
private readonly DateTime m_End;
|
||||
public TeleportTimer(Mobile mobile, StuckMenuEntry destination, TimeSpan delay)
|
||||
: base(TimeSpan.Zero, TimeSpan.FromSeconds(1.0))
|
||||
{
|
||||
Priority = TimerPriority.TwoFiftyMS;
|
||||
|
||||
m_Mobile = mobile;
|
||||
m_Destination = destination;
|
||||
m_End = DateTime.UtcNow + delay;
|
||||
}
|
||||
|
||||
private void MovePetsOfLoggedCharacter(Point3D dest, Map destMap)
|
||||
{
|
||||
Map fromMap = m_Mobile.LogoutMap;
|
||||
Point3D fromLoc = m_Mobile.LogoutLocation;
|
||||
|
||||
var move = fromMap.GetMobilesInRange(fromLoc, 3).Where(m => m is BaseCreature).Cast<BaseCreature>()
|
||||
.Where(pet => pet.Controlled && pet.ControlMaster == m_Mobile && pet.ControlOrder == OrderType.Guard || pet.ControlOrder == OrderType.Follow || pet.ControlOrder == OrderType.Come).ToList();
|
||||
|
||||
move.ForEach(x => x.MoveToWorld(dest, destMap));
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (DateTime.UtcNow < m_End)
|
||||
{
|
||||
m_Mobile.Frozen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Frozen = false;
|
||||
Stop();
|
||||
|
||||
if (Factions.Sigil.ExistsOn(m_Mobile))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = Utility.Random(m_Destination.Locations.Length);
|
||||
Point3D dest = m_Destination.Locations[idx];
|
||||
|
||||
Map destMap;
|
||||
if (m_Mobile.Map == Map.Trammel || SpellHelper.IsEodon(m_Mobile.Map, m_Mobile.Location))
|
||||
destMap = Map.Trammel;
|
||||
else if (m_Mobile.Map == Map.Felucca)
|
||||
destMap = Map.Felucca;
|
||||
else if (m_Mobile.Map == Map.TerMur && !SpellHelper.IsEodon(m_Mobile.Map, m_Mobile.Location))
|
||||
destMap = Map.TerMur;
|
||||
else if (m_Mobile.Map == Map.Internal)
|
||||
destMap = m_Mobile.LogoutMap == Map.Felucca ? Map.Felucca : Map.Trammel;
|
||||
else
|
||||
destMap = m_Mobile.Murderer ? Map.Felucca : Map.Trammel;
|
||||
|
||||
if (destMap == Map.Trammel && Siege.SiegeShard)
|
||||
destMap = Map.Felucca;
|
||||
|
||||
if (m_Mobile.Map != Map.Internal)
|
||||
{
|
||||
Mobiles.BaseCreature.TeleportPets(m_Mobile, dest, destMap);
|
||||
m_Mobile.MoveToWorld(dest, destMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for shards without auto stabling
|
||||
MovePetsOfLoggedCharacter(dest, destMap);
|
||||
|
||||
m_Mobile.LogoutLocation = dest;
|
||||
m_Mobile.LogoutMap = destMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user