#W# Initial Commit: Avatars Conquest
This commit is contained in:
commit
5df497787a
7510 changed files with 416048 additions and 0 deletions
241
Scripts/Engines/Help/HelpGump.cs
Normal file
241
Scripts/Engines/Help/HelpGump.cs
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Menus;
|
||||
using Server.Menus.Questions;
|
||||
using Server.Accounting;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Misc;
|
||||
using Server.Items;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class HelpGump : Gump
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.HelpRequest += new HelpRequestEventHandler( EventSink_HelpRequest );
|
||||
}
|
||||
|
||||
private static void EventSink_HelpRequest( HelpRequestEventArgs e )
|
||||
{
|
||||
foreach ( Gump g in e.Mobile.NetState.Gumps )
|
||||
{
|
||||
if ( g is HelpGump )
|
||||
return;
|
||||
}
|
||||
|
||||
e.Mobile.SendGump( new HelpGump( e.Mobile, 1 ) );
|
||||
}
|
||||
|
||||
public static bool CheckCombat( Mobile m )
|
||||
{
|
||||
for ( int i = 0; i < m.Aggressed.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = m.Aggressed[i];
|
||||
|
||||
if ( DateTime.Now - info.LastCombatTime < TimeSpan.FromSeconds( 30.0 ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public HelpGump( Mobile from, int page ) : base( 25, 50 )
|
||||
{
|
||||
this.Closable=true;
|
||||
this.Disposable=true;
|
||||
this.Dragable=true;
|
||||
this.Resizable=false;
|
||||
|
||||
|
||||
|
||||
|
||||
AddPage(0);
|
||||
AddImage(0, 0, 2520);
|
||||
AddImage(38, 0, 2521);
|
||||
AddImage(208, 0, 2522);
|
||||
AddImage(0, 38, 2523);
|
||||
AddImage(0, 150, 2523);
|
||||
AddImage(0, 262, 2523);
|
||||
AddImage(0, 374, 2523);
|
||||
AddImage(0, 486, 2523);
|
||||
AddImage(209, 38, 2525);
|
||||
AddImage(209, 150, 2525);
|
||||
AddImage(209, 262, 2525);
|
||||
AddImage(209, 374, 2525);
|
||||
AddImage(209, 486, 2525);
|
||||
AddImage(0, 598, 2526);
|
||||
AddImage(38, 598, 2527);
|
||||
AddImage(208, 598, 2528);
|
||||
AddImage(37, 37, 2524);
|
||||
AddImage(36, 146, 2524);
|
||||
AddImage(36, 255, 2524);
|
||||
AddImage(37, 362, 2524);
|
||||
AddImage(35, 472, 2524);
|
||||
AddImage(36, 486, 2524);
|
||||
AddImage(40, 38, 2524);
|
||||
AddImage(41, 147, 2524);
|
||||
AddImage(41, 252, 2524);
|
||||
AddImage(39, 349, 2524);
|
||||
AddImage(39, 439, 2524);
|
||||
AddImage(39, 488, 2524);
|
||||
AddImage(246, 32, 2520);
|
||||
AddImage(284, 32, 2521);
|
||||
AddImage(1127, 32, 2522);
|
||||
AddImage(246, 70, 2523);
|
||||
AddImage(246, 182, 2523);
|
||||
AddImage(246, 294, 2523);
|
||||
AddImage(246, 406, 2523);
|
||||
AddImage(246, 518, 2523);
|
||||
AddImage(1128, 70, 2525);
|
||||
AddImage(1128, 182, 2525);
|
||||
AddImage(1128, 294, 2525);
|
||||
AddImage(1128, 406, 2525);
|
||||
AddImage(1128, 518, 2525);
|
||||
AddImage(246, 630, 2526);
|
||||
AddImage(284, 630, 2527);
|
||||
AddImage(1127, 630, 2528);
|
||||
AddImage(283, 69, 2524);
|
||||
AddImage(282, 178, 2524);
|
||||
AddImage(282, 287, 2524);
|
||||
AddImage(283, 394, 2524);
|
||||
AddImage(281, 504, 2524);
|
||||
AddImage(282, 518, 2524);
|
||||
AddImage(286, 70, 2524);
|
||||
AddImage(287, 179, 2524);
|
||||
AddImage(287, 284, 2524);
|
||||
AddImage(285, 381, 2524);
|
||||
AddImage(285, 471, 2524);
|
||||
AddImage(285, 520, 2524);
|
||||
AddImage(454, 32, 2534);
|
||||
AddImage(454, 630, 2535);
|
||||
AddImage(453, 69, 2524);
|
||||
AddImage(452, 178, 2524);
|
||||
AddImage(452, 287, 2524);
|
||||
AddImage(453, 394, 2524);
|
||||
AddImage(451, 504, 2524);
|
||||
AddImage(452, 518, 2524);
|
||||
AddImage(456, 70, 2524);
|
||||
AddImage(457, 179, 2524);
|
||||
AddImage(457, 284, 2524);
|
||||
AddImage(455, 381, 2524);
|
||||
AddImage(455, 471, 2524);
|
||||
AddImage(455, 520, 2524);
|
||||
AddImage(624, 32, 2521);
|
||||
AddImage(624, 630, 2527);
|
||||
AddImage(623, 69, 2524);
|
||||
AddImage(622, 178, 2524);
|
||||
AddImage(622, 287, 2524);
|
||||
AddImage(623, 394, 2524);
|
||||
AddImage(621, 504, 2524);
|
||||
AddImage(622, 518, 2524);
|
||||
AddImage(626, 70, 2524);
|
||||
AddImage(627, 179, 2524);
|
||||
AddImage(627, 284, 2524);
|
||||
AddImage(625, 381, 2524);
|
||||
AddImage(625, 471, 2524);
|
||||
AddImage(625, 520, 2524);
|
||||
AddImage(792, 32, 2534);
|
||||
AddImage(792, 630, 2535);
|
||||
AddImage(791, 69, 2524);
|
||||
AddImage(790, 178, 2524);
|
||||
AddImage(790, 287, 2524);
|
||||
AddImage(791, 394, 2524);
|
||||
AddImage(789, 504, 2524);
|
||||
AddImage(790, 518, 2524);
|
||||
AddImage(794, 70, 2524);
|
||||
AddImage(795, 179, 2524);
|
||||
AddImage(795, 284, 2524);
|
||||
AddImage(793, 381, 2524);
|
||||
AddImage(793, 471, 2524);
|
||||
AddImage(793, 520, 2524);
|
||||
AddImage(960, 32, 2521);
|
||||
AddImage(960, 630, 2527);
|
||||
AddImage(959, 69, 2524);
|
||||
AddImage(958, 178, 2524);
|
||||
AddImage(958, 287, 2524);
|
||||
AddImage(959, 394, 2524);
|
||||
AddImage(957, 504, 2524);
|
||||
AddImage(958, 518, 2524);
|
||||
AddImage(962, 70, 2524);
|
||||
AddImage(963, 179, 2524);
|
||||
AddImage(963, 284, 2524);
|
||||
AddImage(961, 381, 2524);
|
||||
AddImage(961, 471, 2524);
|
||||
AddImage(961, 520, 2524);
|
||||
|
||||
|
||||
AddHtml( 26, 14, 200, 20, @"<BODY><BASEFONT Color=#2a335d><BIG><CENTER>HELP</CENTER></BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
|
||||
int v = 35;
|
||||
int b = 60;
|
||||
int i = 15;
|
||||
int s = 0;
|
||||
string c = "5c4c32";
|
||||
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 1, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Basics</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 2, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Trades</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 3, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Guilds</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 4, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Homes</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 5, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Ships</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
s++; i=i+30; if ( page == s ){ c = "2a335d"; } else { c = "5c4c32"; }
|
||||
AddButton(v, i, 2536, 2536, 6, GumpButtonType.Reply, 0);
|
||||
AddHtml( b, i+2, 156, 20, @"<BODY><BASEFONT Color=#" + c + "><BIG>Skills</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
|
||||
AddHtml( 298, 46, 604, 20, @"<BODY><BASEFONT Color=#2a335d><BIG>" + ( HelpText( page, 1 ) ).ToUpper() + "</BIG></BASEFONT></BODY>", (bool)false, (bool)false);
|
||||
|
||||
|
||||
AddHtml( 284, 79, 844, 547, @"<BODY><BASEFONT Color=#5c4c32><BIG>" + HelpText( page, 3 ) + "</BIG></BASEFONT></BODY>", (bool)false, (bool)(bool.Parse(HelpText( page, 2 ))));
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState state, RelayInfo info )
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
if ( info.ButtonID > 0 )
|
||||
from.SendGump( new Server.Engines.Help.HelpGump( from, info.ButtonID ) );
|
||||
}
|
||||
|
||||
public static string HelpText( int page, int part )
|
||||
{
|
||||
string val = "";
|
||||
|
||||
if ( page == 1 ){ val = HPBasics.HelpPageBasics( part ); }
|
||||
else if ( page == 2 ){ val = HPTrades.HelpPageTrades( part ); }
|
||||
else if ( page == 3 ){ val = HPGuilds.HelpPageGuilds( part ); }
|
||||
else if ( page == 4 ){ val = HPHomes.HelpPageHomes( part ); }
|
||||
else if ( page == 5 ){ val = HPShips.HelpPageShips( part ); }
|
||||
else if ( page == 6 ){ val = HPSkills.HelpPageSkills( part ); }
|
||||
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Scripts/Engines/Help/Index/HelpPageBasics.cs
Normal file
28
Scripts/Engines/Help/Index/HelpPageBasics.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPBasics
|
||||
{
|
||||
public static string HelpPageBasics( int part )
|
||||
{
|
||||
string title = "Basics";
|
||||
string scroll = "false";
|
||||
|
||||
string text = @"This is the main page!
|
||||
|
||||
|
||||
|
||||
";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Scripts/Engines/Help/Index/HelpPageGuilds.cs
Normal file
73
Scripts/Engines/Help/Index/HelpPageGuilds.cs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPGuilds
|
||||
{
|
||||
public static string HelpPageGuilds( int part )
|
||||
{
|
||||
|
||||
string title = "Guilds";
|
||||
string scroll = "true";
|
||||
|
||||
string text = @"Player characters can start their own guilds, where they need only a guildstone and a house. Deeds for guildstones can be purchase from a provisioner.
|
||||
|
||||
There are also local guilds one can join. Some join them for increased learning, and thus quicker acquisition of skills. Other guild also may provide an advantage toward a trade skill. Search the towns and cities for a guildmaster of your desired guild. Single click on them and choose the JOIN option. They will tell you the price to join, where you can hand them the gold if you have it. If you are already a member of a guild, they will inform you that you need to resign from that guild first. Find your current guildmaster, and single click on them to choose the RESIGN option. Then you can join another guild. If you have over 4 murders reported against you, you will not be able to join any guilds and you will be suspended from any guild you are a member of. The exceptions to this are the Assassins Guild and Thieves Guild. Guildmasters will sell things to members as well.
|
||||
|
||||
Below are the various local guilds you can join:
|
||||
|
||||
ALCHEMISTS GUILD
|
||||
Members of this guild have an advantage toward creating potions.
|
||||
|
||||
ASSASSINS GUILD
|
||||
This dark guild usually attracts members that want an increased learning in fencing, hiding, poisoning, and stealth.
|
||||
|
||||
BARDS GUILD
|
||||
Musicians join this guild to have an increased learning in music, discordance, peacemaking, and provocation.
|
||||
|
||||
BLACKSMITHS GUILD
|
||||
Guild members have an advantage toward mining and blacksmithing.
|
||||
|
||||
CARPENTERS GUILD
|
||||
Members have an advantage toward the woodworking trade.
|
||||
|
||||
HEALERS GUILD
|
||||
Those that join this guild have a much increased learning in using bandages. Only guild members are able to resurrect another with bandages.
|
||||
|
||||
LIBRARIANS GUILD
|
||||
Those that work on scribing magic scrolls, drawing maps, or deciphering treasure maps often join this guild to get an advantage in doing such tasks.
|
||||
|
||||
MAGES GUILD
|
||||
Joining this guild gives the aspiring wizard an improved learning in magery, meditation, and concentration.
|
||||
|
||||
MARINERS GUILD
|
||||
Fisherman often join this guild to have a much improved chance of acquiring things below the surface of the sea. Mariner guild members can also dock or launch their ship from any shore in the land.
|
||||
|
||||
RANGERS GUILD
|
||||
Members of this guild get an advantage when crafting bows, arrows, or bolts. Rangers also have an increased learning in archery, tactics, and tracking.
|
||||
|
||||
TAILORS GUILD
|
||||
Having an advantage in the tailoring trade come with membership in this guild.
|
||||
|
||||
THIEVES GUILD
|
||||
Those seeking to pilfer things that don't belong to them, will seek out this guild. Members have an increased learning in hiding, lockpicking, stealing, and stealth.
|
||||
|
||||
TINKERS GUILD
|
||||
Members of this guild get an advantage when creating things within this trade.
|
||||
|
||||
WARRIORS GUILD
|
||||
Those seeking to be great warriors, eventually join this elite guild. Members have an increased learning in bludgeoning, fencing, parrying, swords, and tactics.
|
||||
|
||||
";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Engines/Help/Index/HelpPageHomes.cs
Normal file
86
Scripts/Engines/Help/Index/HelpPageHomes.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPHomes
|
||||
{
|
||||
public static string HelpPageHomes( int part )
|
||||
{
|
||||
|
||||
string title = "Trades";
|
||||
string scroll = "true";
|
||||
|
||||
string text = @"Trades are secondary skills you can use to produce or create items. All characters can use any of the trades available in the game as the base value of trade skills is 10. The proficiency in trades is dependent on the character's statistics (strength, intelligence, and dexterity). The higher the appropriate statistics, the better the trade skill. Most trades are influenced by a primary attribute, and slightly affected by a secondary attribute. These are listed with the trades below, where the primary is first, followed by the secondary. If you are a member of the associated guild, you will get a bonus of 20 to the trade(s). Like ordinary skills, trade skills cannot be higher than 100. Trade skills are not a part of a characters overall regular skill cap. The trade skills are listed below:
|
||||
|
||||
ALCHEMY
|
||||
- Int / Dex
|
||||
- Alchemists Guild
|
||||
Get some empty bottles, a mortar & pestle, and some reagents to start creating potions. Reagents used are black pearl, bloodmoss, garlic, ginseng, mandrake root, nightshade, spiders silk, and sulfurous ash.
|
||||
|
||||
BLACKSMITHING
|
||||
- Str / Dex
|
||||
- Blacksmiths Guild
|
||||
Using a tool like tongs or a hammer, with some ingots, and you can begin crafting armor and weapons. You can also repair such items that are made of metal, but you need to be near an anvil and forge to perform this trade.
|
||||
|
||||
CARPENTRY
|
||||
- Dex / Str
|
||||
- Carpentry Guild
|
||||
Tools, like a saw, can be used with logs to create items like chairs, tables, or staves. You can also create stone chairs or stone tables if you have the right amount of ore.
|
||||
|
||||
CARTOGRAPHY
|
||||
- Int / Dex
|
||||
- Librarians Guild
|
||||
With a mapmaking pen and some blank scrolls, you can start mapping the area around you. These maps can come in handy as sea charts as well, plotting courses to give to your ship's tillerman. A good cartographer can also decipher treasure maps, to discover where they are buried.
|
||||
|
||||
COOKING
|
||||
- Int / Dex
|
||||
Using an item like a frying pan, you can take various ingredients to create edible foods. Some ingredients can be purchases where others can be acquired from gardens. You can also harvest wheat and use a nearby mill to create some flour.
|
||||
|
||||
FISHING
|
||||
- Str / Dex
|
||||
- Mariners Guild
|
||||
Grab a fishing pole, place it in your hand, and use it to cast a line onto the water. This trade is mostly a way to feed yourself with fresh fish, but some use the skill to help them learn the fates of discovered messages in bottles. Also using fishing nets is something fisherman do.
|
||||
|
||||
FLETCHING
|
||||
- Dex / Str
|
||||
- Rangers Guild
|
||||
With some fletching tools, you can take some logs and create bows and arrows. For arrows you will need some feathers, but killing some birds will help with that. Use a bladed item (dagger, sword, etc.) on a dead bird to cut the feathers off. You can also repair bows.
|
||||
|
||||
INSCRIPTION
|
||||
- Int / Dex
|
||||
- Librarians Guild
|
||||
Using a scribe pen and some blank scrolls, mages often use this to create scrolls from the spells they have learned. Creating a scroll requires a spellbook with the spell already in it, and also the reagents required to cast the spell.
|
||||
|
||||
LUMBERJACKING
|
||||
- Str / Dex
|
||||
- Carpentry Guild
|
||||
Grab an axe, double click it, and then target a tree to chop some wood. Logs are pretty heavy so you may want to acquire a pack mule from the local stable master to help you haul it away. Logs can be used for carpentry or fletching.
|
||||
|
||||
MINING
|
||||
- Str
|
||||
- Blacksmiths Guild
|
||||
With a shovel or pickaxe, you can go along a mountainside or into a cave and dig up some ore. Ore is pretty heavy so you may want to acquire a pack mule from the local stable master to help you haul it away. Using the ore on a forge will turn that into ingots you can use for blacksmithing.
|
||||
|
||||
TAILORING
|
||||
- Dex / Int
|
||||
- Tailors Guild
|
||||
A sewing kit can be used to make some elegant clothing, leather armor, and even stitch bones together to make some horrific bone armor. You can repair such armor with this trade as well. Leather can be acquired from skinning many slain creatures by using a bladed item (dagger, sword, etc.) on the dead creature. Using scissors on the acquired hides will turn it into leather you can use. Bones can be found on slain skeletal creatures. To acquire cloth, you can buy it or you can pick the cotton and flax from gardens and use that on a spinning wheel. Then you can use the thread on a loom to make some cloth. You can do something similar by sheering sheep. Using scissors on the bolts of cloth will produce sheets of cloth you can craft with. Using scissors on cut cloth will turn that into bandages, which is used with the healing skill.
|
||||
|
||||
TINKERING
|
||||
- Dex / Int
|
||||
- Tinkers Guild
|
||||
Tinkering is a handy craft as it allows you to make many tools that are used for other trades. With a set of tinker tools, and usually some ingots, you can create such items. You can even crush gems into a crystal powder and make glass items like bottles and vials. Just drop some gems onto a mortar and pestle and you will grind it into this fine powder.
|
||||
|
||||
";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Scripts/Engines/Help/Index/HelpPageShips.cs
Normal file
60
Scripts/Engines/Help/Index/HelpPageShips.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPShips
|
||||
{
|
||||
public static string HelpPageShips( int part )
|
||||
{
|
||||
string days = ((int)(Server.Misc.Settings. BoatDelete())).ToString();
|
||||
|
||||
string title = "Ships";
|
||||
string scroll = "true";
|
||||
|
||||
string text = @"If one wants to venture out onto the high seas, they will need to acquire a ship. Shipwrights sell such vessels, but sometimes a provisioner may have a small ship for sale as well. When you buy a ship, you will be given a deed that you would use near a dock to launch your new ship. When you choose a valid place for your ship, it will appear on the sea where a key will be provided in your backpack and another in your chest back at the inn. You can use this key by double clicking it and then selecting the side plank doors of the ship to either lock or unlock them.
|
||||
|
||||
To board your ship, you can double click the side door of the boat to extend the plank. You can then double click the plank to board your ship. To disembark, double click the door again to extend the plank and then walk onto it. You may have to step on and off a couple of times until you disembark onto land.
|
||||
|
||||
While on your ship, double click the tillerman to have a navigation window open. This will help you navigate your ship on the sea. If you want to rename your ship, then select the shipwright sign symbol on the lower right of this window. There is also a small X button near that if you want to close the navigation window. Much of the other buttons consists of arrows to steer your ship, drop or raise the anchor, and even extend or close the planks.
|
||||
|
||||
To dock your ship, you must first ensure that the hold is clear and the deck is clean. Then drop the anchor and disembark your ship. Once on shore, you can double click the tillerman to get a confirmation window about docking your ship. If this window does not appear, wait a few seconds and try again. Docking your ship will place a small ship model in your backpack that you can take with you and launch elsewhere.
|
||||
|
||||
Ships come in different sizes, and you should buy a ship that will hold the amount of goods you need it to. Below is a list of ships you can get:
|
||||
|
||||
Small Ship
|
||||
Hold: 1,000 stones of weight
|
||||
|
||||
Small Dragon Ship
|
||||
Hold: 1,400 stones of weight
|
||||
|
||||
Medium Ship
|
||||
Hold: 1,800 stones of weight
|
||||
|
||||
Medium Dragon Ship
|
||||
Hold: 2,200 stones of weight
|
||||
|
||||
Large Ship
|
||||
Hold: 2,600 stones of weight
|
||||
|
||||
Large Dragon Ship
|
||||
Hold: 3,200 stones of weight
|
||||
|
||||
Each ship has a hold at the front, that you can access like any other container by double clicking it. You cannot dock a ship while there are items in this hold or on the deck. You must be near a dock to launch or dock your ship. Being near a home you own will also allow you to do these actions. A member of the Mariners Guild can launch or dock their ship from any shore in the land.
|
||||
|
||||
Ships not only allow you to travel to far off lands, but they also provide different types of items to be fished up from the sea as opposed to just fishing from the shore. You could battle hideous sea creatures, or find a message in a bottle that contains a note to some sunken treasure.
|
||||
|
||||
An unattended ship will eventually have its hold rot and sink into the ocean. ";
|
||||
|
||||
text = text + "This will occur if nobody uses the ship within about " + days + " real world days.";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
107
Scripts/Engines/Help/Index/HelpPageSkills.cs
Normal file
107
Scripts/Engines/Help/Index/HelpPageSkills.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPSkills
|
||||
{
|
||||
public static string HelpPageSkills( int part )
|
||||
{
|
||||
string days = ((int)(Server.Misc.Settings. BoatDelete())).ToString();
|
||||
|
||||
string title = "Skills";
|
||||
string scroll = "true";
|
||||
|
||||
string text = @"There are 25 available skills, and they rank from 0 to 100. Some of your attributes (strength, dexterity, or intelligence) can affect these values. A character has the opportunity to acquire a total of 700 skill points that can be gained. Once a character acquires 700 skill points, they can gain no more. A character can manage these gains and losses, however, and they would do that by using the SKILLS button on their character's PAPERDOLL. Each skill has arrows that can be set to gain, lower, or lock. So if you want to train a new skill, but are out of available points to gain, you can set a current skill to lower. If you want a skill to stop advancing, you can lock it at that value.
|
||||
|
||||
Some skills are used naturally during gameplay, while others have an action button associated with it. You can identify these on the SKILLS window if they have a blue gem icon on the left. You can click this gem to activate the skill, you or can click and drag the skill name from the SKILLS window, onto the view screen. A button will appear that will let you use the skill, and you can place that quick button wherever you want.
|
||||
|
||||
Below are the available skills, and a description of each:
|
||||
|
||||
ARCHERY
|
||||
Determines the accuracy and effectiveness with bows and crossbows. You can do some rudimentary practicing on archery buttes.
|
||||
|
||||
BLUDGEONING
|
||||
This skill is used for blunt weapons like staves, maces, mauls, whips, or clubs. You can do some rudimentary practicing on training dummies. Attacks can provide a bonus when averaging a warrior's skill with bludgeoning, swords, and fencing weapons.
|
||||
|
||||
CONCENTRATION
|
||||
Wizards often practice this skill, that makes their spells more effective. It also helps them use less mana for casting spells.
|
||||
|
||||
DISCORDANCE
|
||||
This is a bardic ability, where a musical instrument can be used to play a song that causes another to fight less effectively.
|
||||
|
||||
DODGING
|
||||
This provides the ability to dodge physical attacks from others. It is influenced by dexterity and the amount of armor worn. The more armor (and heavier the armor) being worn will reduce the chance to dodge. It may also help one avoid dungeon floor and wall traps.
|
||||
|
||||
FENCING
|
||||
This skill is used for piercing weapons like spears, pikes, rapiers, daggers, forks, or a kryss. You can do some rudimentary practicing on training dummies. Attacks can provide a bonus when averaging a warrior's skill with bludgeoning, swords, and fencing weapons.
|
||||
|
||||
HAND-TO-HAND
|
||||
Using your bare hands for combat isn't the most effective of offensive skills, but it does provide ways for mages to be more defensive and effective. It has the benefits of faster spell casting and faster spell casting recovery. It also helps mages perhaps avoid having their spells interrupted. You can do some rudimentary practicing on training dummies.
|
||||
|
||||
HEALING
|
||||
Bandages are used for this skill, and will allow for one to heal another or even cure poisons if talented enough. As a healer gets better with this skill, their ability to wrap a bandage is quicker. Those in the Healers Guild are said to be able to resurrect others with this method.
|
||||
|
||||
HIDING
|
||||
This allows one to hide from others. Someone with revealing magic, or a good searching skill, may be able to find you. Hiding is also important for being able to walk around stealthily.
|
||||
|
||||
LOCKPICKING
|
||||
Using lockpicks, a good thief can bypass almost any locked chest or dungeon door. Where most leave a dungeon with treasure, thieves often leave with much more since they can open what others cannot.
|
||||
|
||||
MAGERY
|
||||
The art of magic can be powerful. Seek a mage to acquire a spellbook and some scrolls to get started. Do not forget to buy reagents, as spells require them to cast. The spellbook will inform you on everything you need to know about magery. Hovering your cursor over the spell page icon will briefly describe the spell for you.
|
||||
|
||||
MEDITATION
|
||||
The ability to regain mana quickly is quite beneficial for a mage. This skill improves that recovery.
|
||||
|
||||
MUSICIANSHIP
|
||||
This is the art of playing musical instruments. Without this skill, then a bard would not be able to use skills like discordance, peacemaking, and provocation.
|
||||
|
||||
PARRYING
|
||||
Wielding a shield, a warrior can possibly avoid or reduce damages from physical attacks.
|
||||
|
||||
PEACEMAKING
|
||||
Using this skill with an instrument will put even the angriest monster at ease, making them calm and unwilling to fight.
|
||||
|
||||
POISONING
|
||||
Using poisons on bladed weapons, can only be accomplished with this skill. The better the skill, the deadlier of poisons one can use. Use the skill on a bottle of poison, and select the edged weapon you wish to poison. Whenever you strike an opponent with the weapon, they will also be poisoned if they are not immune to such things. If you ever want to wipe the poison off of the blade, then use an oil cloth to clean it.
|
||||
|
||||
PROVOCATION
|
||||
Playing the proper musical tune will cause creatures to fight each other instead of you or your comrades.
|
||||
|
||||
REMOVE TRAPS
|
||||
This skill can actively be used on containers and dungeon doors, and passively checked when passing near dungeon floor and wall traps. If successful, you would render the trap useless.
|
||||
|
||||
RESISTING SPELLS
|
||||
The ability to avoid the effects of spells, or lessen the negative effects of spells, is determined by this skill.
|
||||
|
||||
SEARCHING
|
||||
If you want to find a hidden creature, then you would use this skill to do that. This skill is also helpful in finding more treasure in dungeons, from both creatures and containers. Searching for more treasure is also enhanced if you have recently been magically night sighted. Holding a lit lantern, torch, or candle in your hands also enhances the search for hidden treasure.
|
||||
|
||||
STEALING
|
||||
Stealing is seldom employed by thieves to take things from citizens, but more used for taking from monstrous creatures or murderous humanoids. You can double click a creature to open their pack, or double click a human to open their PAPERDOLL and then double click their backpack. Your stealing skill will be tested to see if you can peek into the pack. If you manage to open it, then you can try to take things from it. You must have both hands free to steal, and you cannot steal things from creatures if they are too heavy. Stealing is also used to take things from ornate dungeon chests, that require a sleight of hand to grab before they magically vanishing. Stealing from these chests do not have the weight restriction as creatures have, so you can attempt to steal anything within the chest. You can do some rudimentary practicing on pickpocket dips.
|
||||
|
||||
STEALTH
|
||||
The better your hiding skill, the better you can use the stealth skill. Walking around without being noticed can be beneficial to anyone, but this skill is often used by rangers, thieves, and assassins. The amount and weight of equipped armor pieces will affect this ability, so the lighter your gear the easier it is to sneak around. Wearing heavier armor can help you get better with this skill.
|
||||
|
||||
SWORDSMANSHIP
|
||||
This skill is used for sharp weapons like swords, axes, and polearms like halberds. You can do some rudimentary practicing on training dummies. Attacks can provide a bonus when averaging a warrior's skill with bludgeoning, swords, and fencing weapons.
|
||||
|
||||
TACTICS
|
||||
This is a general warrior skill, that allows for more effective attacks with weapons. Archers also can benefit from this with their ranged weapons, as well as those that fight hand-to-hand.
|
||||
|
||||
TRACKING
|
||||
Following the path of nearby creatures can come in handy when hunting for prey. The better you are at tracking, the further you can track them.
|
||||
|
||||
";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Engines/Help/Index/HelpPageTrades.cs
Normal file
86
Scripts/Engines/Help/Index/HelpPageTrades.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class HPTrades
|
||||
{
|
||||
public static string HelpPageTrades( int part )
|
||||
{
|
||||
|
||||
string title = "Trades";
|
||||
string scroll = "true";
|
||||
|
||||
string text = @"Trades are secondary skills you can use to produce or create items. All characters can use any of the trades available in the game as the base value of trade skills is 10. The proficiency in trades is dependent on the character's statistics (strength, intelligence, and dexterity). The higher the appropriate statistics, the better the trade skill. Most trades are influenced by a primary attribute, and slightly affected by a secondary attribute. These are listed with the trades below, where the primary is first, followed by the secondary. If you are a member of the associated guild, you will get a bonus of 20 to the trade(s). Like ordinary skills, trade skills cannot be higher than 100. Trade skills are not a part of a character's overall regular skill cap. The trade skills are listed below:
|
||||
|
||||
ALCHEMY
|
||||
- Int / Dex
|
||||
- Alchemists Guild
|
||||
Get some empty bottles, a mortar & pestle, and some reagents to start creating potions. Reagents used are black pearl, bloodmoss, garlic, ginseng, mandrake root, nightshade, spiders silk, and sulfurous ash.
|
||||
|
||||
BLACKSMITHING
|
||||
- Str / Dex
|
||||
- Blacksmiths Guild
|
||||
Using a tool like tongs or a hammer, with some ingots, and you can begin crafting armor and weapons. You can also repair such items that are made of metal, but you need to be near an anvil and forge to perform this trade.
|
||||
|
||||
CARPENTRY
|
||||
- Dex / Str
|
||||
- Carpentry Guild
|
||||
Tools, like a saw, can be used with logs to create items like chairs, tables, or staves. You can also create stone chairs or stone tables if you have the right amount of ore.
|
||||
|
||||
CARTOGRAPHY
|
||||
- Int / Dex
|
||||
- Librarians Guild
|
||||
With a mapmaking pen and some blank scrolls, you can start mapping the area around you. These maps can come in handy as sea charts as well, plotting courses to give to your ship's tillerman. A good cartographer can also decipher treasure maps, to discover where they are buried. If you discover the location of a buried treasure, get yourself a shovel and travel to that location. Use the shovel on the map and you should start digging it up. Be careful when removing treasure from the chest, as monsters will surely be guarding it from trespassers.
|
||||
|
||||
COOKING
|
||||
- Int / Dex
|
||||
Using an item like a frying pan, you can take various ingredients to create edible foods. Some ingredients can be purchases where others can be acquired from gardens. You can also harvest wheat and use a nearby mill to create some flour.
|
||||
|
||||
FISHING
|
||||
- Str / Dex
|
||||
- Mariners Guild
|
||||
Grab a fishing pole, place it in your hand, and use it to cast a line onto the water. This trade is mostly a way to feed yourself with fresh fish, but some use the skill to help them learn the fates of discovered messages in bottles. Also using fishing nets is something fisherman do.
|
||||
|
||||
FLETCHING
|
||||
- Dex / Str
|
||||
- Rangers Guild
|
||||
With some fletching tools, you can take some logs and create bows and arrows. For arrows you will need some feathers, but killing some birds will help with that. Use a bladed item (dagger, sword, etc.) on a dead bird to cut the feathers off. You can also repair bows.
|
||||
|
||||
INSCRIPTION
|
||||
- Int / Dex
|
||||
- Librarians Guild
|
||||
Using a scribe pen and some blank scrolls, mages often use this to create scrolls from the spells they have learned. Creating a scroll requires a spellbook with the spell already in it, and also the reagents required to cast the spell.
|
||||
|
||||
LUMBERJACKING
|
||||
- Str / Dex
|
||||
- Carpentry Guild
|
||||
Grab an axe, double click it, and then target a tree to chop some wood. Logs are pretty heavy so you may want to acquire a pack mule from the local stable master to help you haul it away. Logs can be used for carpentry or fletching. Logs can get a bit heavy, so using your axe on them will turn them into lighter weight boards.
|
||||
|
||||
MINING
|
||||
- Str
|
||||
- Blacksmiths Guild
|
||||
With a shovel or pickaxe, you can go along a mountainside or into a cave and dig up some ore. Ore is pretty heavy so you may want to acquire a pack mule from the local stable master to help you haul it away. Using the ore on a forge will turn that into ingots you can use for blacksmithing.
|
||||
|
||||
TAILORING
|
||||
- Dex / Int
|
||||
- Tailors Guild
|
||||
A sewing kit can be used to make some elegant clothing, leather armor, and even stitch bones together to make some horrific bone armor. You can repair such armor with this trade as well. Leather can be acquired from skinning many slain creatures by using a bladed item (dagger, sword, etc.) on the dead creature. Using scissors on the acquired hides will turn it into leather you can use. Bones can be found on slain skeletal creatures. To acquire cloth, you can buy it or you can pick the cotton and flax from gardens and use that on a spinning wheel. Then you can use the thread on a loom to make some cloth. You can do something similar by sheering sheep. Using scissors on the bolts of cloth will produce sheets of cloth you can craft with. Using scissors on cut cloth will turn that into bandages, which is used with the healing skill.
|
||||
|
||||
TINKERING
|
||||
- Dex / Int
|
||||
- Tinkers Guild
|
||||
Tinkering is a handy craft as it allows you to make many tools that are used for other trades. With a set of tinker tools, and usually some ingots, you can create such items. You can even crush gems into a crystal powder and make glass items like bottles and vials. Just drop some gems onto a mortar and pestle and you will grind it into this fine powder.
|
||||
|
||||
";
|
||||
|
||||
if ( part == 1 )
|
||||
return title;
|
||||
else if ( part == 2 )
|
||||
return scroll;
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Scripts/Engines/Help/PagePrompt.cs
Normal file
30
Scripts/Engines/Help/PagePrompt.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
using Server.Prompts;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PagePrompt : Prompt
|
||||
{
|
||||
private PageType m_Type;
|
||||
|
||||
public PagePrompt( PageType type )
|
||||
{
|
||||
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, m_Type ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Scripts/Engines/Help/PagePromptGump.cs
Normal file
61
Scripts/Engines/Help/PagePromptGump.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PagePromptGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private PageType m_Type;
|
||||
|
||||
public PagePromptGump( Mobile from, PageType type ) : base( 0, 0 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Type = type;
|
||||
|
||||
from.CloseGump( typeof( PagePromptGump ) );
|
||||
|
||||
AddBackground( 50, 50, 540, 350, 2600 );
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddHtmlLocalized( 264, 80, 200, 24, 1062524, false, false ); // Enter Description
|
||||
AddHtmlLocalized( 120, 108, 420, 48, 1062638, false, false ); // Please enter a brief description (up to 200 characters) of your problem:
|
||||
|
||||
AddBackground( 100, 148, 440, 200, 3500 );
|
||||
AddTextEntry( 120, 168, 400, 200, 1153, 0, "" );
|
||||
|
||||
AddButton( 175, 355, 2074, 2075, 1, GumpButtonType.Reply, 0 ); // Okay
|
||||
AddButton( 405, 355, 2073, 2072, 0, GumpButtonType.Reply, 0 ); // Cancel
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID == 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
m_From.SendMessage( 0x35, "You must enter a description." );
|
||||
m_From.SendGump( new PagePromptGump( m_From, m_Type ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
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( m_From, text, m_Type ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
395
Scripts/Engines/Help/PageQueue.cs
Normal file
395
Scripts/Engines/Help/PageQueue.cs
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Net.Mail;
|
||||
using System.IO;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Misc;
|
||||
using Server.Accounting;
|
||||
using Server.Engines.Reports;
|
||||
using Server.Commands;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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[]
|
||||
{
|
||||
PageType.VerbalHarassment
|
||||
};
|
||||
|
||||
private 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;
|
||||
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Message;
|
||||
}
|
||||
}
|
||||
|
||||
public PageType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
}
|
||||
|
||||
public Point3D PageLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_PageLocation;
|
||||
}
|
||||
}
|
||||
|
||||
public Map PageMap
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_PageMap;
|
||||
}
|
||||
}
|
||||
|
||||
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.Now;
|
||||
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 TimeSpan StatusDelay = TimeSpan.FromMinutes( 2.0 );
|
||||
|
||||
private 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 :
|
||||
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.
|
||||
|
||||
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 PageQueue
|
||||
{
|
||||
private static ArrayList m_List = new ArrayList();
|
||||
private static Hashtable m_KeyedByHandler = new Hashtable();
|
||||
private static Hashtable m_KeyedBySender = new Hashtable();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Pages", AccessLevel.Counselor, new CommandEventHandler( 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() );
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage( "The page queue is empty." );
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if ( m != null && m.AccessLevel >= AccessLevel.Counselor && m.AutoPageNotify && !IsHandling( m ) )
|
||||
m.SendMessage( "A new page has been placed in the queue." );
|
||||
|
||||
if ( m != null && m.AccessLevel >= AccessLevel.Counselor && m.AutoPageNotify && m.LastMoveTime >= (DateTime.Now - TimeSpan.FromMinutes( 10.0 )) )
|
||||
isStaffOnline = true;
|
||||
}
|
||||
|
||||
if ( !isStaffOnline )
|
||||
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.SpeechLogPageAddresses != null && entry.SpeechLog != null )
|
||||
SendEmail( entry );
|
||||
}
|
||||
|
||||
private static void SendEmail( PageEntry entry )
|
||||
{
|
||||
Mobile sender = entry.Sender;
|
||||
DateTime time = DateTime.Now;
|
||||
|
||||
MailMessage mail = new MailMessage( "RunUO", Email.SpeechLogPageAddresses );
|
||||
|
||||
mail.Subject = "RunUO Speech Log Page Forwarding";
|
||||
|
||||
using ( StringWriter writer = new StringWriter() )
|
||||
{
|
||||
writer.WriteLine( "RunUO Speech Log Page - {0}", PageQueue.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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
834
Scripts/Engines/Help/PageQueueGump.cs
Normal file
834
Scripts/Engines/Help/PageQueueGump.cs
Normal file
|
|
@ -0,0 +1,834 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class MessageSentGump : Gump
|
||||
{
|
||||
private string m_Name, m_Text;
|
||||
private 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 );
|
||||
|
||||
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 PageEntry[] m_List;
|
||||
|
||||
public PageQueueGump() : base( 30, 30 )
|
||||
{
|
||||
Add( new GumpPage( 0 ) );
|
||||
//Add( new GumpBackground( 0, 0, 410, 448, 9200 ) );
|
||||
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.Sender.NetState == null )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Add( new GumpButton( 368, 12, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (i / 5) + 1 ) );
|
||||
Add( new GumpLabel( 298, 12, 2100, "Next Page" ) );
|
||||
Add( new GumpPage( (i / 5) + 1 ) );
|
||||
Add( new GumpButton( 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 ) );
|
||||
Add( new GumpButton( 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.SendMessage( "That page has been removed." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PredefinedResponse
|
||||
{
|
||||
private string m_Title;
|
||||
private string m_Message;
|
||||
|
||||
public string Title{ get{ return m_Title; } set{ m_Title = value; } }
|
||||
public string Message{ get{ return m_Message; } set{ m_Message = value; } }
|
||||
|
||||
public PredefinedResponse( string title, string message )
|
||||
{
|
||||
m_Title = title;
|
||||
m_Message = message;
|
||||
}
|
||||
|
||||
private static ArrayList m_List;
|
||||
|
||||
public static ArrayList List
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_List == null )
|
||||
m_List = Load();
|
||||
|
||||
return m_List;
|
||||
}
|
||||
}
|
||||
|
||||
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/Config/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/Config/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;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
private Mobile m_From;
|
||||
private 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 )
|
||||
{
|
||||
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 );
|
||||
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 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 PageEntry m_Entry;
|
||||
private Mobile m_Mobile;
|
||||
|
||||
private static int[] m_AccessLevelHues = new int[]
|
||||
{
|
||||
2100,
|
||||
2122,
|
||||
2117,
|
||||
2129,
|
||||
2415,
|
||||
2415,
|
||||
2415
|
||||
};
|
||||
|
||||
public PageEntryGump( Mobile m, PageEntry entry ) : base( 30, 30 )
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Entry = entry;
|
||||
|
||||
int buttons = 0;
|
||||
|
||||
int bottom = 356;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
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.SendMessage( "That page has been removed." );
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 0: // close
|
||||
{
|
||||
if ( m_Entry.Handler != state.Mobile )
|
||||
{
|
||||
PageQueueGump g = new PageQueueGump();
|
||||
|
||||
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 pages 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 pages 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();
|
||||
|
||||
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();
|
||||
|
||||
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 );
|
||||
m_Entry.Sender.SendGump( new MessageSentGump( m_Entry.Sender, state.Mobile.Name, 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/Engines/Help/PageResponseGump.cs
Normal file
39
Scripts/Engines/Help/PageResponseGump.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class PageResponseGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private string m_Name, m_Text;
|
||||
|
||||
public PageResponseGump( Mobile from, string name, string text ) : base( 0, 0 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Name = name;
|
||||
m_Text = text;
|
||||
|
||||
AddBackground( 50, 25, 540, 430, 2600 );
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddHtmlLocalized( 150, 40, 360, 40, 1062610, false, false ); // <CENTER><U>Ultima Online Help Response</U></CENTER>
|
||||
|
||||
AddHtml( 80, 90, 480, 290, String.Format( "{0} tells {1}: {2}", name, from.Name, text ), true, true );
|
||||
|
||||
AddHtmlLocalized( 80, 390, 480, 40, 1062611, false, false ); // Clicking the OKAY button will remove the reponse you have received.
|
||||
AddButton( 400, 417, 2074, 2075, 1, GumpButtonType.Reply, 0 ); // OKAY
|
||||
|
||||
AddButton( 475, 417, 2073, 2072, 0, GumpButtonType.Reply, 0 ); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID != 1 )
|
||||
m_From.SendGump( new MessageSentGump( m_From, m_Name, m_Text ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Scripts/Engines/Help/SpeechLog.cs
Normal file
148
Scripts/Engines/Help/SpeechLog.cs
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
using Server.Commands;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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 Queue<SpeechLogEntry> m_Queue;
|
||||
|
||||
public int Count{ get{ return m_Queue.Count; } }
|
||||
|
||||
public SpeechLog()
|
||||
{
|
||||
m_Queue = new Queue<SpeechLogEntry>();
|
||||
}
|
||||
|
||||
public void Add( Mobile from, string speech )
|
||||
{
|
||||
Add( new SpeechLogEntry( from, speech ) );
|
||||
}
|
||||
|
||||
public void Add( SpeechLogEntry entry )
|
||||
{
|
||||
if ( MaxLength > 0 && m_Queue.Count >= MaxLength )
|
||||
m_Queue.Dequeue();
|
||||
|
||||
Clean();
|
||||
|
||||
m_Queue.Enqueue( entry );
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
while ( m_Queue.Count > 0 )
|
||||
{
|
||||
SpeechLogEntry entry = (SpeechLogEntry) m_Queue.Peek();
|
||||
|
||||
if ( DateTime.Now - entry.Created > EntryDuration )
|
||||
m_Queue.Dequeue();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo( SpeechLogEntry[] array, int index )
|
||||
{
|
||||
m_Queue.CopyTo( array, index );
|
||||
}
|
||||
|
||||
#region IEnumerable<SpeechLogEntry> Members
|
||||
|
||||
IEnumerator<SpeechLogEntry> IEnumerable<SpeechLogEntry>.GetEnumerator()
|
||||
{
|
||||
return m_Queue.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_Queue.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class SpeechLogEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private string m_Speech;
|
||||
private DateTime m_Created;
|
||||
|
||||
public Mobile From{ get{ return m_From; } }
|
||||
public string Speech{ get{ return m_Speech; } }
|
||||
public DateTime Created{ get{ return m_Created; } }
|
||||
|
||||
public SpeechLogEntry( Mobile from, string speech )
|
||||
{
|
||||
m_From = from;
|
||||
m_Speech = speech;
|
||||
m_Created = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
112
Scripts/Engines/Help/SpeechLogGump.cs
Normal file
112
Scripts/Engines/Help/SpeechLogGump.cs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Accounting;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Help
|
||||
{
|
||||
public class SpeechLogGump : Gump
|
||||
{
|
||||
public static readonly int MaxEntriesPerPage = 30;
|
||||
|
||||
private Mobile m_Player;
|
||||
private List<SpeechLogEntry> m_Log;
|
||||
private 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 )
|
||||
{
|
||||
m_Player = player;
|
||||
m_Log = log;
|
||||
m_Page = page;
|
||||
|
||||
AddImageTiled( 0, 0, 300, 425, 0xA40 );
|
||||
AddAlphaRegion( 1, 1, 298, 423 );
|
||||
|
||||
string playerName = player.Name;
|
||||
string playerAccount = player.Account is Account ? player.Account.Username : "???";
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
AddHtml( 10, 40, 280, 350, sLog, false, true );
|
||||
|
||||
if ( page > 0 )
|
||||
AddButton( 10, 395, 0xFAE, 0xFB0, 1, GumpButtonType.Reply, 0 ); // Previous page
|
||||
|
||||
AddLabel( 45, 395, 0x481, String.Format( "Current page: {0}/{1}", page + 1, lastPage + 1 ) );
|
||||
|
||||
if ( page < lastPage )
|
||||
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 ( m_Page - 1 >= 0 )
|
||||
from.SendGump( new SpeechLogGump( m_Player, m_Log, m_Page - 1 ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Next page
|
||||
{
|
||||
if ( ( m_Page + 1 ) * MaxEntriesPerPage < m_Log.Count )
|
||||
from.SendGump( new SpeechLogGump( m_Player, m_Log, m_Page + 1 ) );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
237
Scripts/Engines/Help/StuckMenu.cs
Normal file
237
Scripts/Engines/Help/StuckMenu.cs
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Menus.Questions
|
||||
{
|
||||
public class StuckMenuEntry
|
||||
{
|
||||
private int m_Name;
|
||||
private Point3D[] m_Locations;
|
||||
|
||||
public int Name{ get{ return m_Name; } }
|
||||
public Point3D[] Locations{ get{ return m_Locations; } }
|
||||
|
||||
public StuckMenuEntry( int name, Point3D[] locations )
|
||||
{
|
||||
m_Name = name;
|
||||
m_Locations = locations;
|
||||
}
|
||||
}
|
||||
|
||||
public class StuckMenu : Gump
|
||||
{
|
||||
private static 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 Mobile m_Mobile, m_Sender;
|
||||
private 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 = 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 ( 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 = m_Entries;
|
||||
|
||||
if ( index >= 0 && index < entries.Length )
|
||||
Teleport( entries[index] );
|
||||
}
|
||||
}
|
||||
|
||||
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 Mobile m_Mobile;
|
||||
private DateTime m_End;
|
||||
|
||||
public CloseTimer( Mobile m ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 1.0 ) )
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_End = DateTime.Now + TimeSpan.FromMinutes( 3.0 );
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_Mobile.NetState == null || DateTime.Now > m_End )
|
||||
{
|
||||
m_Mobile.Frozen = false;
|
||||
m_Mobile.CloseGump( typeof( StuckMenu ) );
|
||||
|
||||
Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Frozen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TeleportTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private StuckMenuEntry m_Destination;
|
||||
private 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.Now + delay;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( DateTime.Now < m_End )
|
||||
{
|
||||
m_Mobile.Frozen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Frozen = false;
|
||||
Stop();
|
||||
|
||||
int idx = Utility.Random( m_Destination.Locations.Length );
|
||||
Point3D dest = m_Destination.Locations[idx];
|
||||
|
||||
Map destMap = Map.Britannia;
|
||||
|
||||
Mobiles.BaseCreature.TeleportPets( m_Mobile, dest, destMap );
|
||||
m_Mobile.MoveToWorld( dest, destMap );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue