PageRenderTime 32ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Scripts/Commands/Docs.cs

https://bitbucket.org/Kel/crepuscule
C# | 2386 lines | 1543 code | 121 blank | 722 comment | 129 complexity | 59a3a7f578505bc85c19cec3d109981f MD5 | raw file
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Reflection;
  5. using System.Collections;
  6. using Server;
  7. using Server.Items;
  8. //using Server.Engines.BulkOrders;
  9. namespace Server.Scripts.Commands
  10. {
  11. public class Docs
  12. {
  13. public static void Initialize()
  14. {
  15. Server.Commands.Register( "DocGen", AccessLevel.Administrator, new CommandEventHandler( DocGen_OnCommand ) );
  16. }
  17. [Usage( "DocGen" )]
  18. [Description( "Generates RunUO documentation." )]
  19. private static void DocGen_OnCommand( CommandEventArgs e )
  20. {
  21. World.Broadcast( 0x35, true, "Documentation is being generated, please wait." );
  22. DateTime startTime = DateTime.Now;
  23. Document();
  24. DateTime endTime = DateTime.Now;
  25. World.Broadcast( 0x35, true, "Documentation has been completed. The entire process took {0:F1} seconds.", (endTime - startTime).TotalSeconds );
  26. }
  27. private class MemberComparer : IComparer
  28. {
  29. public int Compare( object x, object y )
  30. {
  31. if ( x == y )
  32. return 0;
  33. ConstructorInfo aCtor = x as ConstructorInfo;
  34. ConstructorInfo bCtor = y as ConstructorInfo;
  35. PropertyInfo aProp = x as PropertyInfo;
  36. PropertyInfo bProp = y as PropertyInfo;
  37. MethodInfo aMethod = x as MethodInfo;
  38. MethodInfo bMethod = y as MethodInfo;
  39. bool aStatic = GetStaticFor( aCtor, aProp, aMethod );
  40. bool bStatic = GetStaticFor( bCtor, bProp, bMethod );
  41. if ( aStatic && !bStatic )
  42. return -1;
  43. else if ( !aStatic && bStatic )
  44. return 1;
  45. int v = 0;
  46. if ( aCtor != null )
  47. {
  48. if ( bCtor == null )
  49. v = -1;
  50. }
  51. else if ( bCtor != null )
  52. {
  53. if ( aCtor == null )
  54. v = 1;
  55. }
  56. else if ( aProp != null )
  57. {
  58. if ( bProp == null )
  59. v = -1;
  60. }
  61. else if ( bProp != null )
  62. {
  63. if ( aProp == null )
  64. v = 1;
  65. }
  66. if ( v == 0 )
  67. {
  68. v = GetNameFrom( aCtor, aProp, aMethod ).CompareTo( GetNameFrom( bCtor, bProp, bMethod ) );
  69. }
  70. if ( v == 0 && aCtor != null && bCtor != null )
  71. {
  72. v = aCtor.GetParameters().Length.CompareTo( bCtor.GetParameters().Length );
  73. }
  74. else if ( v == 0 && aMethod != null && bMethod != null )
  75. {
  76. v = aMethod.GetParameters().Length.CompareTo( bMethod.GetParameters().Length );
  77. }
  78. return v;
  79. }
  80. private bool GetStaticFor( ConstructorInfo ctor, PropertyInfo prop, MethodInfo method )
  81. {
  82. if ( ctor != null )
  83. return ctor.IsStatic;
  84. else if ( method != null )
  85. return method.IsStatic;
  86. if ( prop != null )
  87. {
  88. MethodInfo getMethod = prop.GetGetMethod();
  89. MethodInfo setMethod = prop.GetGetMethod();
  90. return (getMethod != null && getMethod.IsStatic) || (setMethod != null && setMethod.IsStatic);
  91. }
  92. return false;
  93. }
  94. private string GetNameFrom( ConstructorInfo ctor, PropertyInfo prop, MethodInfo method )
  95. {
  96. if ( ctor != null )
  97. return ctor.DeclaringType.Name;
  98. else if ( prop != null )
  99. return prop.Name;
  100. else if ( method != null )
  101. return method.Name;
  102. else
  103. return "";
  104. }
  105. }
  106. private class TypeComparer : IComparer
  107. {
  108. public int Compare( object x, object y )
  109. {
  110. if ( x == null && y == null )
  111. return 0;
  112. else if ( x == null )
  113. return -1;
  114. else if ( y == null )
  115. return 1;
  116. TypeInfo a = x as TypeInfo;
  117. TypeInfo b = y as TypeInfo;
  118. if ( a == null || b == null )
  119. throw new ArgumentException();
  120. return a.m_TypeName.CompareTo( b.m_TypeName );
  121. }
  122. }
  123. private class NamespaceComparer : IComparer
  124. {
  125. public int Compare( object x, object y )
  126. {
  127. DictionaryEntry a = (DictionaryEntry)x;
  128. DictionaryEntry b = (DictionaryEntry)y;
  129. return ((string)a.Key).CompareTo( (string)b.Key );
  130. }
  131. }
  132. private class TypeInfo
  133. {
  134. public Type m_Type, m_BaseType, m_Declaring;
  135. public string m_FileName, m_TypeName;
  136. public ArrayList m_Derived, m_Nested;
  137. public Type[] m_Interfaces;
  138. public StreamWriter m_Writer;
  139. public TypeInfo( Type type )
  140. {
  141. m_Type = type;
  142. m_BaseType = type.BaseType;
  143. m_Declaring = type.DeclaringType;
  144. m_Interfaces = type.GetInterfaces();
  145. m_TypeName = type.Name;
  146. m_FileName = Docs.GetFileName( "docs/types/", m_TypeName, ".html" );
  147. m_Writer = Docs.GetWriter( "docs/types/", m_FileName );
  148. }
  149. }
  150. public static string GetFileName( string root, string name, string ext )
  151. {
  152. int index = 0;
  153. string file = String.Concat( name, ext );
  154. while ( File.Exists( Path.Combine( root, file ) ) )
  155. file = String.Concat( name, ++index, ext );
  156. return file;
  157. }
  158. private static string[,] m_Aliases = new string[,]
  159. {
  160. { "System.Object", "<font color=\"blue\">object</font>" },
  161. { "System.String", "<font color=\"blue\">string</font>" },
  162. { "System.Boolean", "<font color=\"blue\">bool</font>" },
  163. { "System.Byte", "<font color=\"blue\">byte</font>" },
  164. { "System.SByte", "<font color=\"blue\">sbyte</font>" },
  165. { "System.Int16", "<font color=\"blue\">short</font>" },
  166. { "System.UInt16", "<font color=\"blue\">ushort</font>" },
  167. { "System.Int32", "<font color=\"blue\">int</font>" },
  168. { "System.UInt32", "<font color=\"blue\">uint</font>" },
  169. { "System.Int64", "<font color=\"blue\">long</font>" },
  170. { "System.UInt64", "<font color=\"blue\">ulong</font>" },
  171. { "System.Single", "<font color=\"blue\">float</font>" },
  172. { "System.Double", "<font color=\"blue\">double</font>" },
  173. { "System.Decimal", "<font color=\"blue\">decimal</font>" },
  174. { "System.Char", "<font color=\"blue\">char</font>" },
  175. { "System.Void", "<font color=\"blue\">void</font>" }
  176. };
  177. private static string m_RootDirectory = Path.GetDirectoryName( Environment.GetCommandLineArgs()[0] );
  178. private const string RefString = "<font color=\"blue\">ref</font> ";
  179. private static int m_AliasLength = m_Aliases.GetLength( 0 );
  180. public static string GetPair( Type varType, string name, bool ignoreRef )
  181. {
  182. string prepend = "";
  183. StringBuilder append = new StringBuilder();
  184. Type realType = varType;
  185. if ( varType.IsByRef )
  186. {
  187. if ( !ignoreRef )
  188. prepend = RefString;
  189. realType = varType.GetElementType();
  190. }
  191. if ( realType.IsPointer )
  192. {
  193. if ( realType.IsArray )
  194. {
  195. append.Append( '*' );
  196. do
  197. {
  198. append.Append( '[' );
  199. for ( int i = 1; i < realType.GetArrayRank(); ++i )
  200. append.Append( ',' );
  201. append.Append( ']' );
  202. realType = realType.GetElementType();
  203. } while ( realType.IsArray );
  204. append.Append( ' ' );
  205. }
  206. else
  207. {
  208. realType = realType.GetElementType();
  209. append.Append( " *" );
  210. }
  211. }
  212. else if ( realType.IsArray )
  213. {
  214. do
  215. {
  216. append.Append( '[' );
  217. for ( int i = 1; i < realType.GetArrayRank(); ++i )
  218. append.Append( ',' );
  219. append.Append( ']' );
  220. realType = realType.GetElementType();
  221. } while ( realType.IsArray );
  222. append.Append( ' ' );
  223. }
  224. else
  225. {
  226. append.Append( ' ' );
  227. }
  228. string fullName = realType.FullName;
  229. string aliased = null;// = realType.Name;
  230. TypeInfo info = (TypeInfo)m_Types[realType];
  231. if ( info != null )
  232. {
  233. aliased = String.Format( "<a href=\"{0}\">{1}</a>", info.m_FileName, info.m_TypeName );
  234. }
  235. else
  236. {
  237. for ( int i = 0; i < m_AliasLength; ++i )
  238. {
  239. if ( m_Aliases[i, 0] == fullName )
  240. {
  241. aliased = m_Aliases[i, 1];
  242. break;
  243. }
  244. }
  245. if ( aliased == null )
  246. aliased = realType.Name;
  247. }
  248. return String.Concat( prepend, aliased, append, name );
  249. }
  250. private static Hashtable m_Types;
  251. private static Hashtable m_Namespaces;
  252. private static void EnsureDirectory( string path )
  253. {
  254. path = Path.Combine( m_RootDirectory, path );
  255. if ( !Directory.Exists( path ) )
  256. Directory.CreateDirectory( path );
  257. }
  258. private static void DeleteDirectory( string path )
  259. {
  260. path = Path.Combine( m_RootDirectory, path );
  261. if ( Directory.Exists( path ) )
  262. Directory.Delete( path, true );
  263. }
  264. private static void Document()
  265. {
  266. DeleteDirectory( "docs/" );
  267. EnsureDirectory( "docs/" );
  268. EnsureDirectory( "docs/namespaces/" );
  269. EnsureDirectory( "docs/types/" );
  270. EnsureDirectory( "docs/bods/" );
  271. GenerateStyles();
  272. GenerateIndex();
  273. DocumentCommands();
  274. DocumentKeywords();
  275. DocumentBodies();
  276. //DocumentBulkOrders();
  277. m_Types = new Hashtable();
  278. m_Namespaces = new Hashtable();
  279. ArrayList assemblies = new ArrayList();
  280. assemblies.Add( Core.Assembly );
  281. foreach ( Assembly asm in ScriptCompiler.Assemblies )
  282. assemblies.Add( asm );
  283. Assembly[] asms = (Assembly[])assemblies.ToArray( typeof( Assembly ) );
  284. for ( int i = 0; i < asms.Length; ++i )
  285. LoadTypes( asms[i], asms );
  286. DocumentLoadedTypes();
  287. DocumentConstructableObjects();
  288. }
  289. private static void AddIndexLink( StreamWriter html, string filePath, string label, string desc )
  290. {
  291. html.WriteLine( " <h2><a href=\"{0}\" title=\"{1}\">{2}</a></h2>", filePath, desc, label );
  292. }
  293. private static void GenerateStyles()
  294. {
  295. using ( StreamWriter css = GetWriter( "docs/", "styles.css" ) )
  296. {
  297. css.WriteLine( "body { background-color: #FFFFFF; font-family: verdana, arial; font-size: 11px; }" );
  298. css.WriteLine( "a { color: #28435E; }" );
  299. css.WriteLine( "a:hover { color: #4878A9; }" );
  300. css.WriteLine( "td.header { background-color: #9696AA; font-weight: bold; font-size: 12px; }" );
  301. css.WriteLine( "td.lentry { background-color: #D7D7EB; width: 10%; }" );
  302. css.WriteLine( "td.rentry { background-color: #FFFFFF; width: 90%; }" );
  303. css.WriteLine( "td.entry { background-color: #FFFFFF; }" );
  304. css.WriteLine( "td { font-size: 11px; }" );
  305. css.WriteLine( ".tbl-border { background-color: #46465A; }" );
  306. css.WriteLine( "td.ir {{ background-color: #{0:X6}; }}", Iron );
  307. css.WriteLine( "td.du {{ background-color: #{0:X6}; }}", DullCopper );
  308. css.WriteLine( "td.sh {{ background-color: #{0:X6}; }}", ShadowIron );
  309. css.WriteLine( "td.co {{ background-color: #{0:X6}; }}", Copper );
  310. css.WriteLine( "td.br {{ background-color: #{0:X6}; }}", Bronze );
  311. css.WriteLine( "td.go {{ background-color: #{0:X6}; }}", Gold );
  312. css.WriteLine( "td.ag {{ background-color: #{0:X6}; }}", Agapite );
  313. css.WriteLine( "td.ve {{ background-color: #{0:X6}; }}", Verite );
  314. css.WriteLine( "td.va {{ background-color: #{0:X6}; }}", Valorite );
  315. css.WriteLine( "td.cl {{ background-color: #{0:X6}; }}", Cloth );
  316. css.WriteLine( "td.pl {{ background-color: #{0:X6}; }}", Plain );
  317. css.WriteLine( "td.sp {{ background-color: #{0:X6}; }}", Core.AOS ? SpinedAOS : SpinedLBR );
  318. css.WriteLine( "td.ho {{ background-color: #{0:X6}; }}", Core.AOS ? HornedAOS : HornedLBR );
  319. css.WriteLine( "td.ba {{ background-color: #{0:X6}; }}", Core.AOS ? BarbedAOS : BarbedLBR );
  320. }
  321. }
  322. private static void GenerateIndex()
  323. {
  324. using ( StreamWriter html = GetWriter( "docs/", "index.html" ) )
  325. {
  326. html.WriteLine( "<html>" );
  327. html.WriteLine( " <head>" );
  328. html.WriteLine( " <title>RunUO Documentation - Index</title>" );
  329. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />" );
  330. html.WriteLine( " </head>" );
  331. html.WriteLine( " <body>" );
  332. AddIndexLink( html, "commands.html", "Commands", "Every available command. This contains command name, usage, aliases, and description." );
  333. AddIndexLink( html, "objects.html", "Constructable Objects", "Every constructable item or npc. This contains object name and usage. Hover mouse over parameters to see type description." );
  334. AddIndexLink( html, "keywords.html", "Speech Keywords", "Lists speech keyword numbers and associated match patterns. These are used in some scripts for multi-language matching of client speech." );
  335. AddIndexLink( html, "bodies.html", "Body List", "Every usable body number and name. Table is generated from a UO:3D client datafile. If you do not have UO:3D installed, this may be blank." );
  336. AddIndexLink( html, "overview.html", "Class Overview", "Scripting reference. Contains every class type and contained methods in the core and scripts." );
  337. //AddIndexLink( html, "bods/bod_smith_rewards.html", "Bulk Order Rewards: Smithing", "Reference table for large and small smithing bulk order deed rewards." );
  338. //AddIndexLink( html, "bods/bod_tailor_rewards.html", "Bulk Order Rewards: Tailoring", "Reference table for large and small tailoring bulk order deed rewards." );
  339. html.WriteLine( " </body>" );
  340. html.WriteLine( "</html>" );
  341. }
  342. }
  343. private const int Iron = 0xCCCCDD;
  344. private const int DullCopper = 0xAAAAAA;
  345. private const int ShadowIron = 0x777799;
  346. private const int Copper = 0xDDCC99;
  347. private const int Bronze = 0xAA8866;
  348. private const int Gold = 0xDDCC55;
  349. private const int Agapite = 0xDDAAAA;
  350. private const int Verite = 0x99CC77;
  351. private const int Valorite = 0x88AABB;
  352. private const int Cloth = 0xDDDDDD;
  353. private const int Plain = 0xCCAA88;
  354. private const int SpinedAOS = 0x99BBBB;
  355. private const int HornedAOS = 0xCC8888;
  356. private const int BarbedAOS = 0xAABBAA;
  357. private const int SpinedLBR = 0xAA8833;
  358. private const int HornedLBR = 0xBBBBAA;
  359. private const int BarbedLBR = 0xCCAA88;
  360. /*
  361. private static void DocumentBulkOrders()
  362. {
  363. using ( StreamWriter html = GetWriter( "docs/bods/", "bod_smith_rewards.html" ) )
  364. {
  365. html.WriteLine( "<html>" );
  366. html.WriteLine( " <head>" );
  367. html.WriteLine( " <title>RunUO Documentation - Bulk Orders - Smith Rewards</title>" );
  368. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"../styles.css\" />" );
  369. html.WriteLine( " </head>" );
  370. html.WriteLine( " <body>" );
  371. SmallBOD sbod = new SmallSmithBOD();
  372. sbod.Type = typeof( Katana );
  373. sbod.Material = BulkMaterialType.None;
  374. sbod.AmountMax = 10;
  375. WriteSmithBODHeader( html, "(Small) Weapons" );
  376. sbod.RequireExceptional = false;
  377. DocumentSmithBOD( html, sbod.ComputeRewards(), "10, 15, 20: Normal", sbod.Material );
  378. sbod.RequireExceptional = true;
  379. DocumentSmithBOD( html, sbod.ComputeRewards(), "10, 15, 20: Exceptional", sbod.Material );
  380. WriteSmithBODFooter( html );
  381. html.WriteLine( " <br><br>" );
  382. html.WriteLine( " <br><br>" );
  383. sbod.Type = typeof( PlateArms );
  384. WriteSmithBODHeader( html, "(Small) Armor: Normal" );
  385. sbod.RequireExceptional = false;
  386. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Valorite; ++mat )
  387. {
  388. sbod.Material = mat;
  389. sbod.AmountMax = 10;
  390. DocumentSmithBOD( html, sbod.ComputeRewards(), "10, 15, 20", sbod.Material );
  391. }
  392. WriteSmithBODFooter( html );
  393. html.WriteLine( " <br><br>" );
  394. WriteSmithBODHeader( html, "(Small) Armor: Exceptional" );
  395. sbod.RequireExceptional = true;
  396. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Valorite; ++mat )
  397. {
  398. sbod.Material = mat;
  399. for ( int amt = 15; amt <= 20; amt += 5 )
  400. {
  401. sbod.AmountMax = amt;
  402. DocumentSmithBOD( html, sbod.ComputeRewards(), amt == 20 ? "20" : "10, 15", sbod.Material );
  403. }
  404. }
  405. WriteSmithBODFooter( html );
  406. html.WriteLine( " <br><br>" );
  407. html.WriteLine( " <br><br>" );
  408. sbod.Delete();
  409. WriteSmithLBOD( html, "Ringmail", LargeBulkEntry.LargeRing );
  410. WriteSmithLBOD( html, "Chainmail", LargeBulkEntry.LargeChain );
  411. WriteSmithLBOD( html, "Platemail", LargeBulkEntry.LargePlate );
  412. html.WriteLine( " </body>" );
  413. html.WriteLine( "</html>" );
  414. }
  415. using ( StreamWriter html = GetWriter( "docs/bods/", "bod_tailor_rewards.html" ) )
  416. {
  417. html.WriteLine( "<html>" );
  418. html.WriteLine( " <head>" );
  419. html.WriteLine( " <title>RunUO Documentation - Bulk Orders - Tailor Rewards</title>" );
  420. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"../styles.css\" />" );
  421. html.WriteLine( " </head>" );
  422. html.WriteLine( " <body>" );
  423. SmallBOD sbod = new SmallTailorBOD();
  424. WriteTailorBODHeader( html, "Small Bulk Order" );
  425. html.WriteLine( " <tr>" );
  426. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Regular: 10, 15</b></td>" );
  427. html.WriteLine( " </tr>" );
  428. sbod.AmountMax = 10;
  429. sbod.RequireExceptional = false;
  430. sbod.Type = typeof( SkullCap );
  431. sbod.Material = BulkMaterialType.None;
  432. DocumentTailorBOD( html, sbod.ComputeRewards(), "10, 15", sbod.Material, sbod.Type );
  433. sbod.Type = typeof( LeatherCap );
  434. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Barbed; ++mat )
  435. {
  436. if ( mat >= BulkMaterialType.DullCopper && mat <= BulkMaterialType.Valorite )
  437. continue;
  438. sbod.Material = mat;
  439. DocumentTailorBOD( html, sbod.ComputeRewards(), "10, 15", sbod.Material, sbod.Type );
  440. }
  441. html.WriteLine( " <tr>" );
  442. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Regular: 20</b></td>" );
  443. html.WriteLine( " </tr>" );
  444. sbod.AmountMax = 20;
  445. sbod.RequireExceptional = false;
  446. sbod.Type = typeof( SkullCap );
  447. sbod.Material = BulkMaterialType.None;
  448. DocumentTailorBOD( html, sbod.ComputeRewards(), "20", sbod.Material, sbod.Type );
  449. sbod.Type = typeof( LeatherCap );
  450. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Barbed; ++mat )
  451. {
  452. if ( mat >= BulkMaterialType.DullCopper && mat <= BulkMaterialType.Valorite )
  453. continue;
  454. sbod.Material = mat;
  455. DocumentTailorBOD( html, sbod.ComputeRewards(), "20", sbod.Material, sbod.Type );
  456. }
  457. html.WriteLine( " <tr>" );
  458. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Exceptional: 10, 15</b></td>" );
  459. html.WriteLine( " </tr>" );
  460. sbod.AmountMax = 10;
  461. sbod.RequireExceptional = true;
  462. sbod.Type = typeof( SkullCap );
  463. sbod.Material = BulkMaterialType.None;
  464. DocumentTailorBOD( html, sbod.ComputeRewards(), "10, 15", sbod.Material, sbod.Type );
  465. sbod.Type = typeof( LeatherCap );
  466. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Barbed; ++mat )
  467. {
  468. if ( mat >= BulkMaterialType.DullCopper && mat <= BulkMaterialType.Valorite )
  469. continue;
  470. sbod.Material = mat;
  471. DocumentTailorBOD( html, sbod.ComputeRewards(), "10, 15", sbod.Material, sbod.Type );
  472. }
  473. html.WriteLine( " <tr>" );
  474. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Exceptional: 20</b></td>" );
  475. html.WriteLine( " </tr>" );
  476. sbod.AmountMax = 20;
  477. sbod.RequireExceptional = true;
  478. sbod.Type = typeof( SkullCap );
  479. sbod.Material = BulkMaterialType.None;
  480. DocumentTailorBOD( html, sbod.ComputeRewards(), "20", sbod.Material, sbod.Type );
  481. sbod.Type = typeof( LeatherCap );
  482. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Barbed; ++mat )
  483. {
  484. if ( mat >= BulkMaterialType.DullCopper && mat <= BulkMaterialType.Valorite )
  485. continue;
  486. sbod.Material = mat;
  487. DocumentTailorBOD( html, sbod.ComputeRewards(), "20", sbod.Material, sbod.Type );
  488. }
  489. WriteTailorBODFooter( html );
  490. html.WriteLine( " <br><br>" );
  491. html.WriteLine( " <br><br>" );
  492. sbod.Delete();
  493. WriteTailorLBOD( html, "Large Bulk Order: 4-part", LargeBulkEntry.Gypsy, true, true );
  494. WriteTailorLBOD( html, "Large Bulk Order: 5-part", LargeBulkEntry.TownCrier, true, true );
  495. WriteTailorLBOD( html, "Large Bulk Order: 6-part", LargeBulkEntry.MaleLeatherSet, false, true );
  496. html.WriteLine( " </body>" );
  497. html.WriteLine( "</html>" );
  498. }
  499. }
  500. private static void WriteTailorLBOD( StreamWriter html, string name, SmallBulkEntry[] entries, bool expandCloth, bool expandPlain )
  501. {
  502. WriteTailorBODHeader( html, name );
  503. LargeBOD lbod = new LargeTailorBOD();
  504. lbod.Entries = LargeBulkEntry.ConvertEntries( lbod, entries );
  505. Type type = entries[0].Type;
  506. bool showCloth = !( type.IsSubclassOf( typeof( BaseArmor ) ) || type.IsSubclassOf( typeof( BaseShoes ) ) );
  507. html.WriteLine( " <tr>" );
  508. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Regular</b></td>" );
  509. html.WriteLine( " </tr>" );
  510. lbod.RequireExceptional = false;
  511. lbod.AmountMax = 10;
  512. if ( showCloth )
  513. {
  514. lbod.Material = BulkMaterialType.None;
  515. if ( expandCloth )
  516. {
  517. lbod.AmountMax = 10;
  518. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15", lbod.Material, type );
  519. lbod.AmountMax = 20;
  520. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, type );
  521. }
  522. else
  523. {
  524. lbod.AmountMax = 10;
  525. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, type );
  526. }
  527. }
  528. lbod.Material = BulkMaterialType.None;
  529. if ( expandPlain )
  530. {
  531. lbod.AmountMax = 10;
  532. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, typeof( LeatherCap ) );
  533. lbod.AmountMax = 20;
  534. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, typeof( LeatherCap ) );
  535. }
  536. else
  537. {
  538. lbod.AmountMax = 10;
  539. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, typeof( LeatherCap ) );
  540. }
  541. for ( BulkMaterialType mat = BulkMaterialType.Spined; mat <= BulkMaterialType.Barbed; ++mat )
  542. {
  543. lbod.Material = mat;
  544. lbod.AmountMax = 10;
  545. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15", lbod.Material, type );
  546. lbod.AmountMax = 20;
  547. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, type );
  548. }
  549. html.WriteLine( " <tr>" );
  550. html.WriteLine( " <td width=\"850\" colspan=\"21\" class=\"entry\"><b>Exceptional</b></td>" );
  551. html.WriteLine( " </tr>" );
  552. lbod.RequireExceptional = true;
  553. lbod.AmountMax = 10;
  554. if ( showCloth )
  555. {
  556. lbod.Material = BulkMaterialType.None;
  557. if ( expandCloth )
  558. {
  559. lbod.AmountMax = 10;
  560. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15", lbod.Material, type );
  561. lbod.AmountMax = 20;
  562. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, type );
  563. }
  564. else
  565. {
  566. lbod.AmountMax = 10;
  567. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, type );
  568. }
  569. }
  570. lbod.Material = BulkMaterialType.None;
  571. if ( expandPlain )
  572. {
  573. lbod.AmountMax = 10;
  574. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, typeof( LeatherCap ) );
  575. lbod.AmountMax = 20;
  576. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, typeof( LeatherCap ) );
  577. }
  578. else
  579. {
  580. lbod.AmountMax = 10;
  581. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material, typeof( LeatherCap ) );
  582. }
  583. for ( BulkMaterialType mat = BulkMaterialType.Spined; mat <= BulkMaterialType.Barbed; ++mat )
  584. {
  585. lbod.Material = mat;
  586. lbod.AmountMax = 10;
  587. DocumentTailorBOD( html, lbod.ComputeRewards(), "10, 15", lbod.Material, type );
  588. lbod.AmountMax = 20;
  589. DocumentTailorBOD( html, lbod.ComputeRewards(), "20", lbod.Material, type );
  590. }
  591. WriteTailorBODFooter( html );
  592. html.WriteLine( " <br><br>" );
  593. html.WriteLine( " <br><br>" );
  594. }
  595. private static void WriteTailorBODHeader( StreamWriter html, string title )
  596. {
  597. html.WriteLine( " <table width=\"850\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  598. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  599. html.WriteLine( " <table border=\"0\" width=\"850\" cellpadding=\"0\" cellspacing=\"1\">" );
  600. html.WriteLine( " <tr>" );
  601. html.WriteLine( " <td width=\"250\" rowspan=\"2\" class=\"entry\"><center>{0}</center></td>", title );
  602. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_1.jpg\" alt=\"Colored Cloth (Level 1)\" border=\"0\"></a></center></td>" );
  603. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_2.jpg\" alt=\"Colored Cloth (Level 2)\" border=\"0\"></a></center></td>" );
  604. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_3.jpg\" alt=\"Colored Cloth (Level 3)\" border=\"0\"></a></center></td>" );
  605. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_4.jpg\" alt=\"Colored Cloth (Level 4)\" border=\"0\"></a></center></td>" );
  606. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_5.jpg\" alt=\"Colored Cloth (Level 5)\" border=\"0\"></a></center></td>" );
  607. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_sandals_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_sandals.jpg\" alt=\"Colored Sandals\" border=\"0\"></a></center></td>" );
  608. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Power Scrolls</center></td>" );
  609. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_smallhides.jpg\" alt=\"Small Stretched Hide\"></center></td>" );
  610. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_mediumhides.jpg\" alt=\"Medium Stretched Hide\"></center></td>" );
  611. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_lighttapestry.jpg\" alt=\"Light Flower Tapestry\"></center></td>" );
  612. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_darktapestry.jpg\" alt=\"Dark Flower Tapestry\"></center></td>" );
  613. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_brownbearrug.jpg\" alt=\"Brown Bear Rug\"></center></td>" );
  614. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_polarbearrug.jpg\" alt=\"Polar Bear Rug\"></center></td>" );
  615. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_clothingbless.jpg\" alt=\"Clothing Bless Deed\"></center></td>" );
  616. html.WriteLine( " <td width=\"75\" colspan=\"3\" class=\"entry\"><center>Runic Kits</center></td>" );
  617. html.WriteLine( " </tr>" );
  618. html.WriteLine( " <tr>" );
  619. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center></td>" );
  620. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  621. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  622. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+20</small></center></td>" );
  623. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_spined.jpg\" alt=\"Runic Sewing Kit: Spined\"></center></td>" );
  624. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_horned.jpg\" alt=\"Runic Sewing Kit: Horned\"></center></td>" );
  625. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_barbed.jpg\" alt=\"Runic Sewing Kit: Barbed\"></center></td>" );
  626. html.WriteLine( " </tr>" );
  627. }
  628. private static void WriteTailorBODFooter( StreamWriter html )
  629. {
  630. html.WriteLine( " <tr>" );
  631. html.WriteLine( " <td width=\"250\" rowspan=\"2\" class=\"entry\">&nbsp;</td>" );
  632. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_1.jpg\" alt=\"Colored Cloth (Level 1)\" border=\"0\"></a></center></td>" );
  633. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_2.jpg\" alt=\"Colored Cloth (Level 2)\" border=\"0\"></a></center></td>" );
  634. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_3.jpg\" alt=\"Colored Cloth (Level 3)\" border=\"0\"></a></center></td>" );
  635. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_4.jpg\" alt=\"Colored Cloth (Level 4)\" border=\"0\"></a></center></td>" );
  636. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_cloth_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_cloth_5.jpg\" alt=\"Colored Cloth (Level 5)\" border=\"0\"></a></center></td>" );
  637. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><a href=\"http://www.runuo.com/images/bodreward_sandals_full.jpg\"><img src=\"http://www.runuo.com/images/bodreward_sandals.jpg\" alt=\"Colored Sandals\" border=\"0\"></a></center></td>" );
  638. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center></td>" );
  639. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  640. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  641. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+20</small></center></td>" );
  642. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_smallhides.jpg\" alt=\"Small Stretched Hide\"></center></td>" );
  643. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_mediumhides.jpg\" alt=\"Medium Stretched Hide\"></center></td>" );
  644. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_lighttapestry.jpg\" alt=\"Light Flower Tapestry\"></center></td>" );
  645. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_darktapestry.jpg\" alt=\"Dark Flower Tapestry\"></center></td>" );
  646. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_brownbearrug.jpg\" alt=\"Brown Bear Rug\"></center></td>" );
  647. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_polarbearrug.jpg\" alt=\"Polar Bear Rug\"></center></td>" );
  648. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_clothingbless.jpg\" alt=\"Clothing Bless Deed\"></center></td>" );
  649. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_spined.jpg\" alt=\"Runic Sewing Kit: Spined\"></center></td>" );
  650. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_horned.jpg\" alt=\"Runic Sewing Kit: Horned\"></center></td>" );
  651. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_runic_barbed.jpg\" alt=\"Runic Sewing Kit: Barbed\"></center></td>" );
  652. html.WriteLine( " </tr>" );
  653. html.WriteLine( " <tr>" );
  654. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Power Scrolls</center></td>" );
  655. html.WriteLine( " <td width=\"75\" colspan=\"3\" class=\"entry\"><center>Runic Kits</center></td>" );
  656. html.WriteLine( " </tr>" );
  657. html.WriteLine( " </table></td></tr></table>" );
  658. }
  659. private static void DocumentTailorBOD( StreamWriter html, ArrayList items, string amt, BulkMaterialType material, Type type )
  660. {
  661. bool[] rewards = new bool[20];
  662. for ( int i = 0; i < items.Count; ++i )
  663. {
  664. Item item = (Item)items[i];
  665. if ( item is Sandals )
  666. rewards[5] = true;
  667. else if ( item is SmallStretchedHideEastDeed || item is SmallStretchedHideSouthDeed )
  668. rewards[10] = true;
  669. else if ( item is MediumStretchedHideEastDeed || item is MediumStretchedHideSouthDeed )
  670. rewards[11] = true;
  671. else if ( item is LightFlowerTapestryEastDeed || item is LightFlowerTapestrySouthDeed )
  672. rewards[12] = true;
  673. else if ( item is DarkFlowerTapestryEastDeed || item is DarkFlowerTapestrySouthDeed )
  674. rewards[13] = true;
  675. else if ( item is BrownBearRugEastDeed || item is BrownBearRugSouthDeed )
  676. rewards[14] = true;
  677. else if ( item is PolarBearRugEastDeed || item is PolarBearRugSouthDeed )
  678. rewards[15] = true;
  679. else if ( item is ClothingBlessDeed )
  680. rewards[16] = true;
  681. else if ( item is PowerScroll )
  682. {
  683. PowerScroll ps = (PowerScroll)item;
  684. if ( ps.Value == 105.0 )
  685. rewards[6] = true;
  686. else if ( ps.Value == 110.0 )
  687. rewards[7] = true;
  688. else if ( ps.Value == 115.0 )
  689. rewards[8] = true;
  690. else if ( ps.Value == 120.0 )
  691. rewards[9] = true;
  692. }
  693. else if ( item is UncutCloth )
  694. {
  695. if ( item.Hue == 0x483 || item.Hue == 0x48C || item.Hue == 0x488 || item.Hue == 0x48A )
  696. rewards[0] = true;
  697. else if ( item.Hue == 0x495 || item.Hue == 0x48B || item.Hue == 0x486 || item.Hue == 0x485 )
  698. rewards[1] = true;
  699. else if ( item.Hue == 0x48D || item.Hue == 0x490 || item.Hue == 0x48E || item.Hue == 0x491 )
  700. rewards[2] = true;
  701. else if ( item.Hue == 0x48F || item.Hue == 0x494 || item.Hue == 0x484 || item.Hue == 0x497 )
  702. rewards[3] = true;
  703. else
  704. rewards[4] = true;
  705. }
  706. else if ( item is RunicSewingKit )
  707. {
  708. RunicSewingKit rkit = (RunicSewingKit)item;
  709. rewards[16 + CraftResources.GetIndex( rkit.Resource )] = true;
  710. }
  711. item.Delete();
  712. }
  713. string style = null;
  714. string name = null;
  715. switch ( material )
  716. {
  717. case BulkMaterialType.None:
  718. {
  719. if ( type.IsSubclassOf( typeof( BaseArmor ) ) || type.IsSubclassOf( typeof( BaseShoes ) ) )
  720. {
  721. style = "pl";
  722. name = "Plain";
  723. }
  724. else
  725. {
  726. style = "cl";
  727. name = "Cloth";
  728. }
  729. break;
  730. }
  731. case BulkMaterialType.Spined: style = "sp"; name = "Spined"; break;
  732. case BulkMaterialType.Horned: style = "ho"; name = "Horned"; break;
  733. case BulkMaterialType.Barbed: style = "ba"; name = "Barbed"; break;
  734. }
  735. html.WriteLine( " <tr>" );
  736. html.WriteLine( " <td width=\"250\" class=\"entry\">&nbsp;- {0} <font size=\"1pt\">{1}</font></td>", name, amt );
  737. int index = 0;
  738. while ( index < 20 )
  739. {
  740. if ( rewards[index] )
  741. {
  742. html.WriteLine( " <td width=\"25\" class=\"{0}\"><center><b>X</b></center></td>", style );
  743. ++index;
  744. }
  745. else
  746. {
  747. int count = 0;
  748. while ( index < 20 && !rewards[index] )
  749. {
  750. ++count;
  751. ++index;
  752. if ( index == 5 || index == 6 || index == 10 || index == 17 )
  753. break;
  754. }
  755. html.WriteLine( " <td width=\"{0}\"{1} class=\"entry\">&nbsp;</td>", count*25, count==1?"":String.Format( " colspan=\"{0}\"", count ) );
  756. }
  757. }
  758. html.WriteLine( " </tr>" );
  759. }
  760. private static void WriteSmithLBOD( StreamWriter html, string name, SmallBulkEntry[] entries )
  761. {
  762. LargeBOD lbod = new LargeSmithBOD();
  763. lbod.Entries = LargeBulkEntry.ConvertEntries( lbod, entries );
  764. WriteSmithBODHeader( html, String.Format( "(Large) {0}: Normal", name ) );
  765. lbod.RequireExceptional = false;
  766. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Valorite; ++mat )
  767. {
  768. lbod.Material = mat;
  769. lbod.AmountMax = 10;
  770. DocumentSmithBOD( html, lbod.ComputeRewards(), "10, 15, 20", lbod.Material );
  771. }
  772. WriteSmithBODFooter( html );
  773. html.WriteLine( " <br><br>" );
  774. WriteSmithBODHeader( html, String.Format( "(Large) {0}: Exceptional", name ) );
  775. lbod.RequireExceptional = true;
  776. for ( BulkMaterialType mat = BulkMaterialType.None; mat <= BulkMaterialType.Valorite; ++mat )
  777. {
  778. lbod.Material = mat;
  779. for ( int amt = 15; amt <= 20; amt += 5 )
  780. {
  781. lbod.AmountMax = amt;
  782. DocumentSmithBOD( html, lbod.ComputeRewards(), amt == 20 ? "20" : "10, 15", lbod.Material );
  783. }
  784. }
  785. WriteSmithBODFooter( html );
  786. html.WriteLine( " <br><br>" );
  787. html.WriteLine( " <br><br>" );
  788. }
  789. private static void WriteSmithBODHeader( StreamWriter html, string title )
  790. {
  791. html.WriteLine( " <table width=\"850\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  792. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  793. html.WriteLine( " <table border=\"0\" width=\"850\" cellpadding=\"0\" cellspacing=\"1\">" );
  794. html.WriteLine( " <tr>" );
  795. html.WriteLine( " <td width=\"250\" rowspan=\"2\" class=\"entry\"><center>{0}</center></td>", title );
  796. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_sturdytool.jpg\" alt=\"Sturdy Pickaxe/Shovel (150 uses)\"></center></td>" );
  797. html.WriteLine( " <td width=\"75\" colspan=\"3\" class=\"entry\"><center>Gloves</center></td>" );
  798. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_gargaxe.jpg\" alt=\"Gargoyles Pickaxe (100 uses)\"></center></td>" );
  799. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_prospectortool.jpg\" alt=\"Prospectors Tool (50 uses)\"></center></td>" );
  800. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_powder.jpg\" alt=\"Powder of Temperament (10 uses)\"></center></td>" );
  801. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_anvil.jpg\" alt=\"Colored Anvil\"></center></td>" );
  802. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Power Scrolls</center></td>" );
  803. html.WriteLine( " <td width=\"200\" colspan=\"8\" class=\"entry\"><center>Runic Hammers</center></td>" );
  804. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Ancient Hammers</center></td>" );
  805. html.WriteLine( " </tr>" );
  806. html.WriteLine( " <tr>" );
  807. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+1</small></center></td>" );
  808. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+3</small></center></td>" );
  809. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center></td>" );
  810. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center></td>" );
  811. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  812. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  813. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+20</small></center></td>" );
  814. html.WriteLine( " <td width=\"25\" class=\"du\"><center><small>Du</small></center></td>" );
  815. html.WriteLine( " <td width=\"25\" class=\"sh\"><center><small>Sh</small></center></td>" );
  816. html.WriteLine( " <td width=\"25\" class=\"co\"><center><small>Co</small></center></td>" );
  817. html.WriteLine( " <td width=\"25\" class=\"br\"><center><small>Br</small></center></td>" );
  818. html.WriteLine( " <td width=\"25\" class=\"go\"><center><small>Go</small></center></td>" );
  819. html.WriteLine( " <td width=\"25\" class=\"ag\"><center><small>Ag</small></center></td>" );
  820. html.WriteLine( " <td width=\"25\" class=\"ve\"><center><small>Ve</small></center></td>" );
  821. html.WriteLine( " <td width=\"25\" class=\"va\"><center><small>Va</small></center></td>" );
  822. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  823. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  824. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+30</small></center></td>" );
  825. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+60</small></center></td>" );
  826. html.WriteLine( " </tr>" );
  827. }
  828. private static void WriteSmithBODFooter( StreamWriter html )
  829. {
  830. html.WriteLine( " <tr>" );
  831. html.WriteLine( " <td width=\"250\" rowspan=\"2\" class=\"entry\">&nbsp;</td>" );
  832. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_sturdytool.jpg\" alt=\"Sturdy Pickaxe/Shovel (150 uses)\"></center></td>" );
  833. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+1</small></center>&nbsp;</td>" );
  834. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+3</small></center>&nbsp;</td>" );
  835. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center>&nbsp;</td>" );
  836. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_gargaxe.jpg\" alt=\"Gargoyles Pickaxe (100 uses)\"></center></td>" );
  837. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_prospectortool.jpg\" alt=\"Prospectors Tool (50 uses)\"></center></td>" );
  838. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_powder.jpg\" alt=\"Powder of Temperament (10 uses)\"></center></td>" );
  839. html.WriteLine( " <td width=\"25\" rowspan=\"2\" class=\"entry\"><center><img src=\"http://www.runuo.com/images/bodreward_anvil.jpg\" alt=\"Colored Anvil\"></center></td>" );
  840. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+5</small></center></td>" );
  841. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  842. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  843. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+20</small></center></td>" );
  844. html.WriteLine( " <td width=\"25\" class=\"du\"><center><small>Du</small></center></td>" );
  845. html.WriteLine( " <td width=\"25\" class=\"sh\"><center><small>Sh</small></center></td>" );
  846. html.WriteLine( " <td width=\"25\" class=\"co\"><center><small>Co</small></center></td>" );
  847. html.WriteLine( " <td width=\"25\" class=\"br\"><center><small>Br</small></center></td>" );
  848. html.WriteLine( " <td width=\"25\" class=\"go\"><center><small>Go</small></center></td>" );
  849. html.WriteLine( " <td width=\"25\" class=\"ag\"><center><small>Ag</small></center></td>" );
  850. html.WriteLine( " <td width=\"25\" class=\"ve\"><center><small>Ve</small></center></td>" );
  851. html.WriteLine( " <td width=\"25\" class=\"va\"><center><small>Va</small></center></td>" );
  852. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+10</small></center></td>" );
  853. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+15</small></center></td>" );
  854. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+30</small></center></td>" );
  855. html.WriteLine( " <td width=\"25\" class=\"entry\"><center><small>+60</small></center></td>" );
  856. html.WriteLine( " </tr>" );
  857. html.WriteLine( " <tr>" );
  858. html.WriteLine( " <td width=\"75\" colspan=\"3\" class=\"entry\"><center>Gloves</center></td>" );
  859. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Power Scrolls</center></td>" );
  860. html.WriteLine( " <td width=\"200\" colspan=\"8\" class=\"entry\"><center>Runic Hammers</center></td>" );
  861. html.WriteLine( " <td width=\"100\" colspan=\"4\" class=\"entry\"><center>Ancient Hammers</center></td>" );
  862. html.WriteLine( " </tr>" );
  863. html.WriteLine( " </table></td></tr></table>" );
  864. }
  865. private static void DocumentSmithBOD( StreamWriter html, ArrayList items, string amt, BulkMaterialType material )
  866. {
  867. bool[] rewards = new bool[24];
  868. for ( int i = 0; i < items.Count; ++i )
  869. {
  870. Item item = (Item)items[i];
  871. if ( item is SturdyPickaxe || item is SturdyShovel )
  872. rewards[0] = true;
  873. else if ( item is LeatherGlovesOfMining )
  874. rewards[1] = true;
  875. else if ( item is StuddedGlovesOfMining )
  876. rewards[2] = true;
  877. else if ( item is RingmailGlovesOfMining )
  878. rewards[3] = true;
  879. else if ( item is GargoylesPickaxe )
  880. rewards[4] = true;
  881. else if ( item is ProspectorsTool )
  882. rewards[5] = true;
  883. else if ( item is PowderOfTemperament )
  884. rewards[6] = true;
  885. else if ( item is ColoredAnvil )
  886. rewards[7] = true;
  887. else if ( item is PowerScroll )
  888. {
  889. PowerScroll ps = (PowerScroll)item;
  890. if ( ps.Value == 105.0 )
  891. rewards[8] = true;
  892. else if ( ps.Value == 110.0 )
  893. rewards[9] = true;
  894. else if ( ps.Value == 115.0 )
  895. rewards[10] = true;
  896. else if ( ps.Value == 120.0 )
  897. rewards[11] = true;
  898. }
  899. else if ( item is RunicHammer )
  900. {
  901. RunicHammer rh = (RunicHammer)item;
  902. rewards[11 + CraftResources.GetIndex( rh.Resource )] = true;
  903. }
  904. else if ( item is AncientSmithyHammer )
  905. {
  906. AncientSmithyHammer ash = (AncientSmithyHammer)item;
  907. if ( ash.Bonus == 10 )
  908. rewards[20] = true;
  909. else if ( ash.Bonus == 15 )
  910. rewards[21] = true;
  911. else if ( ash.Bonus == 30 )
  912. rewards[22] = true;
  913. else if ( ash.Bonus == 60 )
  914. rewards[23] = true;
  915. }
  916. item.Delete();
  917. }
  918. string style = null;
  919. string name = null;
  920. switch ( material )
  921. {
  922. case BulkMaterialType.None: style = "ir"; name = "Iron"; break;
  923. case BulkMaterialType.DullCopper: style = "du"; name = "Dull Copper"; break;
  924. case BulkMaterialType.ShadowIron: style = "sh"; name = "Shadow Iron"; break;
  925. case BulkMaterialType.Copper: style = "co"; name = "Copper"; break;
  926. case BulkMaterialType.Bronze: style = "br"; name = "Bronze"; break;
  927. case BulkMaterialType.Gold: style = "go"; name = "Gold"; break;
  928. case BulkMaterialType.Agapite: style = "ag"; name = "Agapite"; break;
  929. case BulkMaterialType.Verite: style = "ve"; name = "Verite"; break;
  930. case BulkMaterialType.Valorite: style = "va"; name = "Valorite"; break;
  931. }
  932. html.WriteLine( " <tr>" );
  933. html.WriteLine( " <td width=\"250\" class=\"entry\">{0} <font size=\"1pt\">{1}</font></td>", name, amt );
  934. int index = 0;
  935. while ( index < 24 )
  936. {
  937. if ( rewards[index] )
  938. {
  939. html.WriteLine( " <td width=\"25\" class=\"{0}\"><center><b>X</b></center></td>", style );
  940. ++index;
  941. }
  942. else
  943. {
  944. int count = 0;
  945. while ( index < 24 && !rewards[index] )
  946. {
  947. ++count;
  948. ++index;
  949. if ( index == 4 || index == 8 || index == 12 || index == 20 )
  950. break;
  951. }
  952. html.WriteLine( " <td width=\"{0}\"{1} class=\"entry\">&nbsp;</td>", count*25, count==1?"":String.Format( " colspan=\"{0}\"", count ) );
  953. }
  954. }
  955. html.WriteLine( " </tr>" );
  956. }
  957. */
  958. public static ArrayList LoadBodies()
  959. {
  960. ArrayList list = new ArrayList();
  961. string path = Core.FindDataFile( "models/models.txt" );
  962. if ( File.Exists( path ) )
  963. {
  964. using ( StreamReader ip = new StreamReader( path ) )
  965. {
  966. string line;
  967. while ( (line = ip.ReadLine()) != null )
  968. {
  969. line = line.Trim();
  970. if ( line.Length == 0 || line.StartsWith( "#" ) )
  971. continue;
  972. string[] split = line.Split( '\t' );
  973. if ( split.Length >= 9 )
  974. {
  975. Body body = Utility.ToInt32( split[0] );
  976. ModelBodyType type = (ModelBodyType)Utility.ToInt32( split[1] );
  977. string name = split[8];
  978. BodyEntry entry = new BodyEntry( body, type, name );
  979. if ( !list.Contains( entry ) )
  980. list.Add( entry );
  981. }
  982. }
  983. }
  984. }
  985. return list;
  986. }
  987. private static void DocumentBodies()
  988. {
  989. ArrayList list = LoadBodies();
  990. using ( StreamWriter html = GetWriter( "docs/", "bodies.html" ) )
  991. {
  992. html.WriteLine( "<html>" );
  993. html.WriteLine( " <head>" );
  994. html.WriteLine( " <title>RunUO Documentation - Body List</title>" );
  995. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />" );
  996. html.WriteLine( " </head>" );
  997. html.WriteLine( " <body>" );
  998. html.WriteLine( " <a name=\"Top\" />" );
  999. html.WriteLine( " <h4><a href=\"index.html\">Back to the index</a></h4>" );
  1000. if ( list.Count > 0 )
  1001. {
  1002. html.WriteLine( " <h2>Body List</h2>" );
  1003. list.Sort( new BodyEntrySorter() );
  1004. ModelBodyType lastType = ModelBodyType.Invalid;
  1005. for ( int i = 0; i < list.Count; ++i )
  1006. {
  1007. BodyEntry entry = (BodyEntry)list[i];
  1008. ModelBodyType type = entry.BodyType;
  1009. if ( type != lastType )
  1010. {
  1011. if ( lastType != ModelBodyType.Invalid )
  1012. html.WriteLine( " </table></td></tr></table><br>" );
  1013. lastType = type;
  1014. html.WriteLine( " <a name=\"{0}\" />", type );
  1015. switch ( type )
  1016. {
  1017. case ModelBodyType.Monsters: html.WriteLine( " <b>Monsters</b> | <a href=\"#Sea\">Sea</a> | <a href=\"#Animals\">Animals</a> | <a href=\"#Human\">Human</a> | <a href=\"#Equipment\">Equipment</a><br><br>" ); break;
  1018. case ModelBodyType.Sea: html.WriteLine( " <a href=\"#Top\">Monsters</a> | <b>Sea</b> | <a href=\"#Animals\">Animals</a> | <a href=\"#Human\">Human</a> | <a href=\"#Equipment\">Equipment</a><br><br>" ); break;
  1019. case ModelBodyType.Animals: html.WriteLine( " <a href=\"#Top\">Monsters</a> | <a href=\"#Sea\">Sea</a> | <b>Animals</b> | <a href=\"#Human\">Human</a> | <a href=\"#Equipment\">Equipment</a><br><br>" ); break;
  1020. case ModelBodyType.Human: html.WriteLine( " <a href=\"#Top\">Monsters</a> | <a href=\"#Sea\">Sea</a> | <a href=\"#Animals\">Animals</a> | <b>Human</b> | <a href=\"#Equipment\">Equipment</a><br><br>" ); break;
  1021. case ModelBodyType.Equipment: html.WriteLine( " <a href=\"#Top\">Monsters</a> | <a href=\"#Sea\">Sea</a> | <a href=\"#Animals\">Animals</a> | <a href=\"#Human\">Human</a> | <b>Equipment</b><br><br>" ); break;
  1022. }
  1023. html.WriteLine( " <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  1024. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  1025. html.WriteLine( " <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">" );
  1026. html.WriteLine( " <tr><td width=\"100%\" colspan=\"2\" class=\"header\">{0}</td></tr>", type );
  1027. }
  1028. html.WriteLine( " <tr><td class=\"lentry\">{0}</td><td class=\"rentry\">{1}</td></tr>", entry.Body.BodyID, entry.Name );
  1029. }
  1030. html.WriteLine( " </table>" );
  1031. }
  1032. else
  1033. {
  1034. html.WriteLine( " This feature requires a UO:3D installation." );
  1035. }
  1036. html.WriteLine( " </body>" );
  1037. html.WriteLine( "</html>" );
  1038. }
  1039. }
  1040. private static void DocumentKeywords()
  1041. {
  1042. ArrayList tables = LoadSpeechFile();
  1043. using ( StreamWriter html = GetWriter( "docs/", "keywords.html" ) )
  1044. {
  1045. html.WriteLine( "<html>" );
  1046. html.WriteLine( " <head>" );
  1047. html.WriteLine( " <title>RunUO Documentation - Speech Keywords</title>" );
  1048. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />" );
  1049. html.WriteLine( " </head>" );
  1050. html.WriteLine( " <body>" );
  1051. html.WriteLine( " <h4><a href=\"index.html\">Back to the index</a></h4>" );
  1052. html.WriteLine( " <h2>Speech Keywords</h2>" );
  1053. for ( int p = 0; p < 1 && p < tables.Count; ++p )
  1054. {
  1055. Hashtable table = (Hashtable)tables[p];
  1056. if ( p > 0 )
  1057. html.WriteLine( " <br>" );
  1058. html.WriteLine( " <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  1059. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  1060. html.WriteLine( " <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">" );
  1061. html.WriteLine( " <tr><td class=\"header\">Number</td><td class=\"header\">Text</td></tr>" );
  1062. ArrayList list = new ArrayList( table.Values );
  1063. list.Sort( new SpeechEntrySorter() );
  1064. for ( int i = 0; i < list.Count; ++i )
  1065. {
  1066. SpeechEntry entry = (SpeechEntry)list[i];
  1067. html.Write( " <tr><td class=\"lentry\">0x{0:X4}</td><td class=\"rentry\">", entry.Index );
  1068. entry.Strings.Sort();//( new EnglishPrioStringSorter() );
  1069. for ( int j = 0; j < entry.Strings.Count; ++j )
  1070. {
  1071. if ( j > 0 )
  1072. html.Write( "<br>" );
  1073. string v = (string)entry.Strings[j];
  1074. for ( int k = 0; k < v.Length; ++k )
  1075. {
  1076. char c = v[k];
  1077. if ( c == '<' )
  1078. html.Write( "&lt;" );
  1079. else if ( c == '>' )
  1080. html.Write( "&gt;" );
  1081. else if ( c == '&' )
  1082. html.Write( "&amp;" );
  1083. else if ( c == '"' )
  1084. html.Write( "&quot;" );
  1085. else if ( c == '\'' )
  1086. html.Write( "&apos;" );
  1087. else if ( c >= 0x20 && c < 0x80 )
  1088. html.Write( c );
  1089. else
  1090. html.Write( "&#{0};", (int)c );
  1091. }
  1092. }
  1093. html.WriteLine( "</td></tr>" );
  1094. }
  1095. html.WriteLine( " </table></td></tr></table>" );
  1096. }
  1097. html.WriteLine( " </body>" );
  1098. html.WriteLine( "</html>" );
  1099. }
  1100. }
  1101. private class SpeechEntry
  1102. {
  1103. private int m_Index;
  1104. private ArrayList m_Strings;
  1105. public int Index{ get{ return m_Index; } }
  1106. public ArrayList Strings{ get{ return m_Strings; } }
  1107. public SpeechEntry( int index )
  1108. {
  1109. m_Index = index;
  1110. m_Strings = new ArrayList();
  1111. }
  1112. }
  1113. private class SpeechEntrySorter : IComparer
  1114. {
  1115. public int Compare( object x, object y )
  1116. {
  1117. SpeechEntry a = (SpeechEntry)x;
  1118. SpeechEntry b = (SpeechEntry)y;
  1119. return a.Index.CompareTo( b.Index );
  1120. }
  1121. }
  1122. private static ArrayList LoadSpeechFile()
  1123. {
  1124. ArrayList tables = new ArrayList();
  1125. int lastIndex = -1;
  1126. Hashtable table = null;
  1127. string path = Core.FindDataFile( "Speech.mul" );
  1128. if ( File.Exists( path ) )
  1129. {
  1130. using ( FileStream ip = new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.Read ) )
  1131. {
  1132. BinaryReader bin = new BinaryReader( ip );
  1133. while ( bin.PeekChar() >= 0 )
  1134. {
  1135. int index = (bin.ReadByte() << 8) | bin.ReadByte();
  1136. int length = (bin.ReadByte() << 8) | bin.ReadByte();
  1137. string text = Encoding.UTF8.GetString( bin.ReadBytes( length ) ).Trim();
  1138. if ( text.Length == 0 )
  1139. continue;
  1140. if ( table == null || lastIndex > index )
  1141. {
  1142. if ( index == 0 && text == "*withdraw*" )
  1143. tables.Insert( 0, table = new Hashtable() );
  1144. else
  1145. tables.Add( table = new Hashtable() );
  1146. }
  1147. lastIndex = index;
  1148. SpeechEntry entry = (SpeechEntry)table[index];
  1149. if ( entry == null )
  1150. table[index] = entry = new SpeechEntry( index );
  1151. entry.Strings.Add( text );
  1152. }
  1153. }
  1154. }
  1155. return tables;
  1156. }
  1157. private class DocCommandEntry
  1158. {
  1159. private AccessLevel m_AccessLevel;
  1160. private string m_Name;
  1161. private string[] m_Aliases;
  1162. private string m_Usage;
  1163. private string m_Description;
  1164. public AccessLevel AccessLevel{ get{ return m_AccessLevel; } }
  1165. public string Name{ get{ return m_Name; } }
  1166. public string[] Aliases{ get{ return m_Aliases; } }
  1167. public string Usage{ get{ return m_Usage; } }
  1168. public string Description{ get{ return m_Description; } }
  1169. public DocCommandEntry( AccessLevel accessLevel, string name, string[] aliases, string usage, string description )
  1170. {
  1171. m_AccessLevel = accessLevel;
  1172. m_Name = name;
  1173. m_Aliases = aliases;
  1174. m_Usage = usage;
  1175. m_Description = description;
  1176. }
  1177. }
  1178. private class CommandEntrySorter : IComparer
  1179. {
  1180. public int Compare( object x, object y )
  1181. {
  1182. DocCommandEntry a = (DocCommandEntry)x;
  1183. DocCommandEntry b = (DocCommandEntry)y;
  1184. int v = b.AccessLevel.CompareTo( a.AccessLevel );
  1185. if ( v == 0 )
  1186. v = a.Name.CompareTo( b.Name );
  1187. return v;
  1188. }
  1189. }
  1190. private static void DocumentCommands()
  1191. {
  1192. using ( StreamWriter html = GetWriter( "docs/", "commands.html" ) )
  1193. {
  1194. html.WriteLine( "<html>" );
  1195. html.WriteLine( " <head>" );
  1196. html.WriteLine( " <title>RunUO Documentation - Commands</title>" );
  1197. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />" );
  1198. html.WriteLine( " </head>" );
  1199. html.WriteLine( " <body>" );
  1200. html.WriteLine( " <a name=\"Top\" />" );
  1201. html.WriteLine( " <h4><a href=\"index.html\">Back to the index</a></h4>" );
  1202. html.WriteLine( " <h2>Commands</h2>" );
  1203. ArrayList commands = new ArrayList( Server.Commands.Entries.Values );
  1204. ArrayList list = new ArrayList();
  1205. commands.Sort();
  1206. commands.Reverse();
  1207. Clean( commands );
  1208. for ( int i = 0; i < commands.Count; ++i )
  1209. {
  1210. CommandEntry e = (CommandEntry)commands[i];
  1211. MethodInfo mi = e.Handler.Method;
  1212. object[] attrs = mi.GetCustomAttributes( typeof( UsageAttribute ), false );
  1213. if ( attrs.Length == 0 )
  1214. continue;
  1215. UsageAttribute usage = attrs[0] as UsageAttribute;
  1216. attrs = mi.GetCustomAttributes( typeof( DescriptionAttribute ), false );
  1217. if ( attrs.Length == 0 )
  1218. continue;
  1219. DescriptionAttribute desc = attrs[0] as DescriptionAttribute;
  1220. if ( usage == null || desc == null )
  1221. continue;
  1222. attrs = mi.GetCustomAttributes( typeof( AliasesAttribute ), false );
  1223. AliasesAttribute aliases = ( attrs.Length == 0 ? null : attrs[0] as AliasesAttribute );
  1224. string descString = desc.Description.Replace( "<", "&lt;" ).Replace( ">", "&gt;" );
  1225. if ( aliases == null )
  1226. list.Add( new DocCommandEntry( e.AccessLevel, e.Command, null, usage.Usage, descString ) );
  1227. else
  1228. list.Add( new DocCommandEntry( e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString ) );
  1229. }
  1230. commands = TargetCommands.AllCommands;
  1231. for ( int i = 0; i < commands.Count; ++i )
  1232. {
  1233. BaseCommand command = (BaseCommand)commands[i];
  1234. string usage = command.Usage;
  1235. string desc = command.Description;
  1236. if ( usage == null || desc == null )
  1237. continue;
  1238. string[] cmds = command.Commands;
  1239. string cmd = cmds[0];
  1240. string[] aliases = new string[cmds.Length - 1];
  1241. for ( int j = 0; j < aliases.Length; ++j )
  1242. aliases[j] = cmds[j + 1];
  1243. desc = desc.Replace( "<", "&lt;" ).Replace( ">", "&gt;" );
  1244. if ( command.Supports != CommandSupport.Single )
  1245. {
  1246. StringBuilder sb = new StringBuilder( 50 + desc.Length );
  1247. sb.Append( "Modifiers: " );
  1248. if ( (command.Supports & CommandSupport.Global) != 0 )
  1249. sb.Append( "<i><a href=\"#Global\">Global</a></i>, " );
  1250. if ( (command.Supports & CommandSupport.Online) != 0 )
  1251. sb.Append( "<i><a href=\"#Online\">Online</a></i>, " );
  1252. if ( (command.Supports & CommandSupport.Region) != 0 )
  1253. sb.Append( "<i><a href=\"#Region\">Region</a></i>, " );
  1254. if ( (command.Supports & CommandSupport.Contained) != 0 )
  1255. sb.Append( "<i><a href=\"#Contained\">Contained</a></i>, " );
  1256. if ( (command.Supports & CommandSupport.Multi) != 0 )
  1257. sb.Append( "<i><a href=\"#Multi\">Multi</a></i>, " );
  1258. if ( (command.Supports & CommandSupport.Area) != 0 )
  1259. sb.Append( "<i><a href=\"#Area\">Area</a></i>, " );
  1260. if ( (command.Supports & CommandSupport.Self) != 0 )
  1261. sb.Append( "<i><a href=\"#Self\">Self</a></i>, " );
  1262. sb.Remove( sb.Length - 2, 2 );
  1263. sb.Append( "<br>" );
  1264. sb.Append( desc );
  1265. desc = sb.ToString();
  1266. }
  1267. list.Add( new DocCommandEntry( command.AccessLevel, cmd, aliases, usage, desc ) );
  1268. }
  1269. commands = BaseCommandImplementor.Implementors;
  1270. for ( int i = 0; i < commands.Count; ++i )
  1271. {
  1272. BaseCommandImplementor command = (BaseCommandImplementor)commands[i];
  1273. string usage = command.Usage;
  1274. string desc = command.Description;
  1275. if ( usage == null || desc == null )
  1276. continue;
  1277. string[] cmds = command.Accessors;
  1278. string cmd = cmds[0];
  1279. string[] aliases = new string[cmds.Length - 1];
  1280. for ( int j = 0; j < aliases.Length; ++j )
  1281. aliases[j] = cmds[j + 1];
  1282. desc = desc.Replace( "<", "&lt;" ).Replace( ">", "&gt;" );
  1283. list.Add( new DocCommandEntry( command.AccessLevel, cmd, aliases, usage, desc ) );
  1284. }
  1285. list.Sort( new CommandEntrySorter() );
  1286. AccessLevel last = AccessLevel.Player;
  1287. foreach ( DocCommandEntry e in list )
  1288. {
  1289. if ( e.AccessLevel != last )
  1290. {
  1291. if ( last != AccessLevel.Player )
  1292. html.WriteLine( " </table></td></tr></table><br>" );
  1293. last = e.AccessLevel;
  1294. html.WriteLine( " <a name=\"{0}\" />", last );
  1295. switch ( last )
  1296. {
  1297. case AccessLevel.Administrator: html.WriteLine( " <b>Administrator</b> | <a href=\"#GameMaster\">Game Master</a> | <a href=\"#Counselor\">Counselor</a> | <a href=\"#Player\">Player</a><br><br>" ); break;
  1298. case AccessLevel.GameMaster: html.WriteLine( " <a href=\"#Top\">Administrator</a> | <b>Game Master</b> | <a href=\"#Counselor\">Counselor</a> | <a href=\"#Player\">Player</a><br><br>" ); break;
  1299. case AccessLevel.Seer: html.WriteLine( " <a href=\"#Top\">Administrator</a> | <a href=\"#GameMaster\">Game Master</a> | <a href=\"#Counselor\">Counselor</a> | <a href=\"#Player\">Player</a><br><br>" ); break;
  1300. case AccessLevel.Counselor: html.WriteLine( " <a href=\"#Top\">Administrator</a> | <a href=\"#GameMaster\">Game Master</a> | <b>Counselor</b> | <a href=\"#Player\">Player</a><br><br>" ); break;
  1301. case AccessLevel.Player: html.WriteLine( " <a href=\"#Top\">Administrator</a> | <a href=\"#GameMaster\">Game Master</a> | <a href=\"#Counselor\">Counselor</a> | <b>Player</b><br><br>" ); break;
  1302. }
  1303. html.WriteLine( " <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  1304. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  1305. html.WriteLine( " <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">" );
  1306. html.WriteLine( " <tr><td colspan=\"2\" width=\"100%\" class=\"header\">{0}</td></tr>", last == AccessLevel.GameMaster ? "Game Master" : last.ToString() );
  1307. }
  1308. DocumentCommand( html, e );
  1309. }
  1310. html.WriteLine( " </table></td></tr></table>" );
  1311. html.WriteLine( " </body>" );
  1312. html.WriteLine( "</html>" );
  1313. }
  1314. }
  1315. private static void Clean( ArrayList list )
  1316. {
  1317. for ( int i = 0; i < list.Count; ++i )
  1318. {
  1319. CommandEntry e = (CommandEntry)list[i];
  1320. for ( int j = i + 1; j < list.Count; ++j )
  1321. {
  1322. CommandEntry c = (CommandEntry)list[j];
  1323. if ( e.Handler.Method == c.Handler.Method )
  1324. {
  1325. list.RemoveAt( j );
  1326. --j;
  1327. }
  1328. }
  1329. }
  1330. }
  1331. private static void DocumentCommand( StreamWriter html, DocCommandEntry e )
  1332. {
  1333. string usage = e.Usage;
  1334. string desc = e.Description;
  1335. string[] aliases = e.Aliases;
  1336. html.Write( " <tr><a name=\"{0}\" /><td class=\"lentry\">{0}</td>", e.Name );
  1337. if ( aliases == null || aliases.Length == 0 )
  1338. {
  1339. html.Write( "<td class=\"rentry\"><b>Usage: {0}</b><br>{1}</td>", usage.Replace( "<", "&lt;" ).Replace( ">", "&gt;" ), desc );
  1340. }
  1341. else
  1342. {
  1343. html.Write( "<td class=\"rentry\"><b>Usage: {0}</b><br>Alias{1}: ", usage.Replace( "<", "&lt;" ).Replace( ">", "&gt;" ), aliases.Length == 1 ? "" : "es" );
  1344. for ( int i = 0; i < aliases.Length; ++i )
  1345. {
  1346. if ( i != 0 )
  1347. html.Write( ", " );
  1348. html.Write( aliases[i] );
  1349. }
  1350. html.Write( "<br>{0}</td>", desc );
  1351. }
  1352. html.WriteLine( "</tr>" );
  1353. }
  1354. private static void LoadTypes( Assembly a, Assembly[] asms )
  1355. {
  1356. Type[] types = a.GetTypes();
  1357. for ( int i = 0; i < types.Length; ++i )
  1358. {
  1359. Type type = types[i];
  1360. string nspace = type.Namespace;
  1361. if ( nspace == null || type.IsSpecialName )
  1362. continue;
  1363. TypeInfo info = new TypeInfo( type );
  1364. m_Types[type] = info;
  1365. ArrayList nspaces = (ArrayList)m_Namespaces[nspace];
  1366. if ( nspaces == null )
  1367. m_Namespaces[nspace] = nspaces = new ArrayList();
  1368. nspaces.Add( info );
  1369. Type baseType = info.m_BaseType;
  1370. if ( baseType != null && InAssemblies( baseType, asms ) )
  1371. {
  1372. TypeInfo baseInfo = (TypeInfo)m_Types[baseType];
  1373. if ( baseInfo == null )
  1374. m_Types[baseType] = baseInfo = new TypeInfo( baseType );
  1375. if ( baseInfo.m_Derived == null )
  1376. baseInfo.m_Derived = new ArrayList();
  1377. baseInfo.m_Derived.Add( info );
  1378. }
  1379. Type decType = info.m_Declaring;
  1380. if ( decType != null )
  1381. {
  1382. TypeInfo decInfo = (TypeInfo)m_Types[decType];
  1383. if ( decInfo == null )
  1384. m_Types[decType] = decInfo = new TypeInfo( decType );
  1385. if ( decInfo.m_Nested == null )
  1386. decInfo.m_Nested = new ArrayList();
  1387. decInfo.m_Nested.Add( info );
  1388. }
  1389. for ( int j = 0; j < info.m_Interfaces.Length; ++j )
  1390. {
  1391. Type iface = info.m_Interfaces[j];
  1392. if ( !InAssemblies( iface, asms ) )
  1393. continue;
  1394. TypeInfo ifaceInfo = (TypeInfo)m_Types[iface];
  1395. if ( ifaceInfo == null )
  1396. m_Types[iface] = ifaceInfo = new TypeInfo( iface );
  1397. if ( ifaceInfo.m_Derived == null )
  1398. ifaceInfo.m_Derived = new ArrayList();
  1399. ifaceInfo.m_Derived.Add( info );
  1400. }
  1401. }
  1402. }
  1403. private static bool InAssemblies( Type t, Assembly[] asms )
  1404. {
  1405. Assembly a = t.Assembly;
  1406. for ( int i = 0; i < asms.Length; ++i )
  1407. if ( a == asms[i] )
  1408. return true;
  1409. return false;
  1410. }
  1411. private static StreamWriter GetWriter( string root, string name )
  1412. {
  1413. return new StreamWriter( Path.Combine( Path.Combine( m_RootDirectory, root ), name ) );
  1414. }
  1415. private static StreamWriter GetWriter( string path )
  1416. {
  1417. return new StreamWriter( Path.Combine( m_RootDirectory, path ) );
  1418. }
  1419. private static Type typeofItem = typeof( Item ), typeofMobile = typeof( Mobile ), typeofMap = typeof( Map );
  1420. private static Type typeofCustomEnum = typeof( CustomEnumAttribute );
  1421. private static bool IsConstructable( Type t, out bool isItem )
  1422. {
  1423. if ( isItem = typeofItem.IsAssignableFrom( t ) )
  1424. return true;
  1425. return typeofMobile.IsAssignableFrom( t );
  1426. }
  1427. private static bool IsConstructable( ConstructorInfo ctor )
  1428. {
  1429. return ctor.IsDefined( typeof( ConstructableAttribute ), false );
  1430. }
  1431. private static void DocumentConstructableObjects()
  1432. {
  1433. ArrayList types = new ArrayList( m_Types.Values );
  1434. types.Sort( new TypeComparer() );
  1435. ArrayList items = new ArrayList(), mobiles = new ArrayList();
  1436. for ( int i = 0; i < types.Count; ++i )
  1437. {
  1438. Type t = ((TypeInfo)types[i]).m_Type;
  1439. bool isItem;
  1440. if ( t.IsAbstract || !IsConstructable( t, out isItem ) )
  1441. continue;
  1442. ConstructorInfo[] ctors = t.GetConstructors();
  1443. bool anyConstructable = false;
  1444. for ( int j = 0; !anyConstructable && j < ctors.Length; ++j )
  1445. anyConstructable = IsConstructable( ctors[j] );
  1446. if ( anyConstructable )
  1447. {
  1448. (isItem ? items : mobiles).Add( t );
  1449. (isItem ? items : mobiles).Add( ctors );
  1450. }
  1451. }
  1452. using ( StreamWriter html = GetWriter( "docs/", "objects.html" ) )
  1453. {
  1454. html.WriteLine( "<html>" );
  1455. html.WriteLine( " <head>" );
  1456. html.WriteLine( " <title>RunUO Documentation - Constructable Objects</title>" );
  1457. html.WriteLine( " <link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" />" );
  1458. html.WriteLine( " </head>" );
  1459. html.WriteLine( " <body>" );
  1460. html.WriteLine( " <h4><a href=\"index.html\">Back to the index</a></h4>" );
  1461. html.WriteLine( " <h2>Constructable <a href=\"#items\">Items</a> and <a href=\"#mobiles\">Mobiles</a></h2>" );
  1462. html.WriteLine( " <a name=\"items\" />" );
  1463. html.WriteLine( " <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  1464. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  1465. html.WriteLine( " <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">" );
  1466. html.WriteLine( " <tr><td class=\"header\">Item Name</td><td class=\"header\">Usage</td></tr>" );
  1467. for ( int i = 0; i < items.Count; i += 2 )
  1468. DocumentConstructableObject( html, (Type)items[i], (ConstructorInfo[])items[i + 1] );
  1469. html.WriteLine( " </table></td></tr></table><br><br>" );
  1470. html.WriteLine( " <a name=\"mobiles\" />" );
  1471. html.WriteLine( " <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">" );
  1472. html.WriteLine( " <tr><td class=\"tbl-border\">" );
  1473. html.WriteLine( " <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">" );
  1474. html.WriteLine( " <tr><td class=\"header\">Mobile Name</td><td class=\"header\">Usage</td></tr>" );
  1475. for ( int i = 0; i < mobiles.Count; i += 2 )
  1476. DocumentConstructableObject( html, (Type)mobiles[i], (ConstructorInfo[])mobiles[i + 1] );
  1477. html.WriteLine( " </table></td></tr></table>" );
  1478. html.WriteLine( " </body>" );
  1479. html.WriteLine( "</html>" );
  1480. }
  1481. }
  1482. private static void DocumentConstructableObject( StreamWriter html, Type t, ConstructorInfo[] ctors )
  1483. {
  1484. html.Write( " <tr><td class=\"lentry\">{0}</td><td class=\"rentry\">", t.Name );
  1485. bool first = true;
  1486. for ( int i = 0; i < ctors.Length; ++i )
  1487. {
  1488. ConstructorInfo ctor = ctors[i];
  1489. if ( !IsConstructable( ctor ) )
  1490. continue;
  1491. if ( !first )
  1492. html.Write( "<br>" );
  1493. first = false;
  1494. html.Write( "{0}Add {1}", Server.Commands.CommandPrefix, t.Name );
  1495. ParameterInfo[] parms = ctor.GetParameters();
  1496. for ( int j = 0; j < parms.Length; ++j )
  1497. {
  1498. html.Write( " <a " );
  1499. TypeInfo typeInfo = (TypeInfo)m_Types[parms[j].ParameterType];
  1500. if ( typeInfo != null )
  1501. html.Write( "href=\"types/{0}\" ", typeInfo.m_FileName );
  1502. html.Write( "title=\"{0}\">{1}</a>", GetTooltipFor( parms[j] ), parms[j].Name );
  1503. }
  1504. }
  1505. html.WriteLine( "</td></tr>" );
  1506. }
  1507. private const string HtmlNewLine = "&#13;";
  1508. private static object[,] m_Tooltips = new object[,]
  1509. {
  1510. { typeof( Byte ), "Numeric value in the range from 0 to 255, inclusive." },
  1511. { typeof( SByte ), "Numeric value in the range from negative 128 to positive 127, inclusive." },
  1512. { typeof( UInt16 ), "Numeric value in the range from 0 to 65,535, inclusive." },
  1513. { typeof( Int16 ), "Numeric value in the range from negative 32,768 to positive 32,767, inclusive." },
  1514. { typeof( UInt32 ), "Numeric value in the range from 0 to 4,294,967,295, inclusive." },
  1515. { typeof( Int32 ), "Numeric value in the range from negative 2,147,483,648 to positive 2,147,483,647, inclusive." },
  1516. { typeof( UInt64 ), "Numeric value in the range from 0 through about 10^20." },
  1517. { typeof( Int64 ), "Numeric value in the approximate range from negative 10^19 through 10^19." },
  1518. { typeof( String ), "Text value. To specify a value containing spaces, encapsulate the value in quote characters:{0}{0}&quot;Spaced text example&quot;" },
  1519. { typeof( Boolean ), "Boolean value which can be either True or False." },
  1520. { typeof( Map ), "Map or facet name. Possible values include:{0}{0}- Felucca{0}- Trammel{0}- Ilshenar{0}- Malas" },
  1521. { typeof( Poison ), "Poison name or level. Possible values include:{0}{0}- Lesser{0}- Regular{0}- Greater{0}- Deadly{0}- Lethal" },
  1522. { typeof( Point3D ), "Three-dimensional coordinate value. Format as follows:{0}{0}&quot;(<x value>, <y value>, <z value>)&quot;" }
  1523. };
  1524. private static string GetTooltipFor( ParameterInfo param )
  1525. {
  1526. Type paramType = param.ParameterType;
  1527. for ( int i = 0; i < m_Tooltips.GetLength( 0 ); ++i )
  1528. {
  1529. Type checkType = (Type)m_Tooltips[i, 0];
  1530. if ( paramType == checkType )
  1531. return String.Format( (string)m_Tooltips[i, 1], HtmlNewLine );
  1532. }
  1533. if ( paramType.IsEnum )
  1534. {
  1535. StringBuilder sb = new StringBuilder();
  1536. sb.AppendFormat( "Enumeration value or name. Possible named values include:{0}", HtmlNewLine );
  1537. string[] names = Enum.GetNames( paramType );
  1538. for ( int i = 0; i < names.Length; ++i )
  1539. sb.AppendFormat( "{0}- {1}", HtmlNewLine, names[i] );
  1540. return sb.ToString();
  1541. }
  1542. else if ( paramType.IsDefined( typeofCustomEnum, false ) )
  1543. {
  1544. object[] attributes = paramType.GetCustomAttributes( typeofCustomEnum, false );
  1545. if ( attributes != null && attributes.Length > 0 )
  1546. {
  1547. CustomEnumAttribute attr = attributes[0] as CustomEnumAttribute;
  1548. if ( attr != null )
  1549. {
  1550. StringBuilder sb = new StringBuilder();
  1551. sb.AppendFormat( "Enumeration value or name. Possible named values include:{0}", HtmlNewLine );
  1552. string[] names = attr.Names;
  1553. for ( int i = 0; i < names.Length; ++i )
  1554. sb.AppendFormat( "{0}- {1}", HtmlNewLine, names[i] );
  1555. return sb.ToString();
  1556. }
  1557. }
  1558. }
  1559. else if ( paramType == typeofMap )
  1560. {
  1561. StringBuilder sb = new StringBuilder();
  1562. sb.AppendFormat( "Enumeration value or name. Possible named values include:{0}", HtmlNewLine );
  1563. string[] names = Map.GetMapNames();
  1564. for ( int i = 0; i < names.Length; ++i )
  1565. sb.AppendFormat( "{0}- {1}", HtmlNewLine, names[i] );
  1566. return sb.ToString();
  1567. }
  1568. return "";
  1569. }
  1570. private const string GetString = " <font color=\"blue\">get</font>;";
  1571. private const string SetString = " <font color=\"blue\">set</font>;";
  1572. private const string InString = "<font color=\"blue\">in</font> ";
  1573. private const string OutString = "<font color=\"blue\">out</font> ";
  1574. private const string VirtString = "<font color=\"blue\">virtual</font> ";
  1575. private const string CtorString ="(<font color=\"blue\">ctor</font>) ";
  1576. private const string StaticString = "(<font color=\"blue\">static</font>) ";
  1577. private static void DocumentLoadedTypes()
  1578. {
  1579. using ( StreamWriter indexHtml = GetWriter( "docs/", "overview.html" ) )
  1580. {
  1581. indexHtml.WriteLine( "<html>" );
  1582. indexHtml.WriteLine( " <head>" );
  1583. indexHtml.WriteLine( " <title>RunUO Documentation - Class Overview</title>" );
  1584. indexHtml.WriteLine( " </head>" );
  1585. indexHtml.WriteLine( " <body bgcolor=\"white\" style=\"font-family: Courier New\" text=\"#000000\" link=\"#000000\" vlink=\"#000000\" alink=\"#808080\">" );
  1586. indexHtml.WriteLine( " <h4><a href=\"index.html\">Back to the index</a></h4>" );
  1587. indexHtml.WriteLine( " <h2>Namespaces</h2>" );
  1588. ArrayList nspaces = new ArrayList( m_Namespaces );
  1589. nspaces.Sort( new NamespaceComparer() );
  1590. for ( int i = 0; i < nspaces.Count; ++i )
  1591. {
  1592. DictionaryEntry de = (DictionaryEntry)nspaces[i];
  1593. string name = (string)de.Key;
  1594. ArrayList types = (ArrayList)de.Value;
  1595. types.Sort( new TypeComparer() );
  1596. SaveNamespace( name, types, indexHtml );
  1597. }
  1598. indexHtml.WriteLine( " </body>" );
  1599. indexHtml.WriteLine( "</html>" );
  1600. }
  1601. }
  1602. private static void SaveNamespace( string name, ArrayList types, StreamWriter indexHtml )
  1603. {
  1604. string fileName = GetFileName( "docs/namespaces/", name, ".html" );
  1605. indexHtml.WriteLine( " <a href=\"namespaces/{0}\">{1}</a><br>", fileName, name );
  1606. using ( StreamWriter nsHtml = GetWriter( "docs/namespaces/", fileName ) )
  1607. {
  1608. nsHtml.WriteLine( "<html>" );
  1609. nsHtml.WriteLine( " <head>" );
  1610. nsHtml.WriteLine( " <title>RunUO Documentation - Class Overview - {0}</title>", name );
  1611. nsHtml.WriteLine( " </head>" );
  1612. nsHtml.WriteLine( " <body bgcolor=\"white\" style=\"font-family: Courier New\" text=\"#000000\" link=\"#000000\" vlink=\"#000000\" alink=\"#808080\">" );
  1613. nsHtml.WriteLine( " <h4><a href=\"../overview.html\">Back to the namespace index</a></h4>" );
  1614. nsHtml.WriteLine( " <h2>{0}</h2>", name );
  1615. for ( int i = 0; i < types.Count; ++i )
  1616. SaveType( (TypeInfo)types[i], nsHtml, fileName, name );
  1617. nsHtml.WriteLine( " </body>" );
  1618. nsHtml.WriteLine( "</html>" );
  1619. }
  1620. }
  1621. private static void SaveType( TypeInfo info, StreamWriter nsHtml, string nsFileName, string nsName )
  1622. {
  1623. if ( info.m_Declaring == null )
  1624. nsHtml.WriteLine( " <a href=\"../types/{0}\">{1}<br>", info.m_FileName, info.m_TypeName );
  1625. using ( StreamWriter typeHtml = info.m_Writer )
  1626. {
  1627. typeHtml.WriteLine( "<html>" );
  1628. typeHtml.WriteLine( " <head>" );
  1629. typeHtml.WriteLine( " <title>RunUO Documentation - Class Overview - {0}</title>", info.m_TypeName );
  1630. typeHtml.WriteLine( " </head>" );
  1631. typeHtml.WriteLine( " <body bgcolor=\"white\" style=\"font-family: Courier New\" text=\"#000000\" link=\"#000000\" vlink=\"#000000\" alink=\"#808080\">" );
  1632. typeHtml.WriteLine( " <h4><a href=\"../namespaces/{0}\">Back to {1}</a></h4>", nsFileName, nsName );
  1633. if ( info.m_Type.IsEnum )
  1634. WriteEnum( info, typeHtml );
  1635. else
  1636. WriteType( info, typeHtml );
  1637. typeHtml.WriteLine( " </body>" );
  1638. typeHtml.WriteLine( "</html>" );
  1639. }
  1640. }
  1641. private static void WriteEnum( TypeInfo info, StreamWriter typeHtml )
  1642. {
  1643. Type type = info.m_Type;
  1644. typeHtml.WriteLine( " <h2>{0} (Enum)</h2>", info.m_TypeName );
  1645. Array values = Enum.GetValues( type );
  1646. bool flags = type.IsDefined( typeof( FlagsAttribute ), false );
  1647. string format;
  1648. if ( flags )
  1649. format = " {0:G} = 0x{1:X}{2}<br>";
  1650. else
  1651. format = " {0:G} = {1:D}{2}<br>";
  1652. for ( int i = 0; i < values.Length; ++i )
  1653. {
  1654. object value = values.GetValue( i );
  1655. typeHtml.WriteLine( format, value, value, i < (values.Length - 1) ? "," : "" );
  1656. }
  1657. }
  1658. private static void WriteType( TypeInfo info, StreamWriter typeHtml )
  1659. {
  1660. Type type = info.m_Type;
  1661. typeHtml.Write( " <h2>" );
  1662. Type decType = info.m_Declaring;
  1663. if ( decType != null )
  1664. {
  1665. // We are a nested type
  1666. typeHtml.Write( '(' );
  1667. TypeInfo decInfo = (TypeInfo)m_Types[decType];
  1668. if ( decInfo == null )
  1669. typeHtml.Write( decType.Name );
  1670. else
  1671. typeHtml.Write( "<a href=\"{0}\">{1}</a>", decInfo.m_FileName, decInfo.m_TypeName );
  1672. typeHtml.Write( ") - " );
  1673. }
  1674. typeHtml.Write( info.m_TypeName );
  1675. Type[] ifaces = info.m_Interfaces;
  1676. Type baseType = info.m_BaseType;
  1677. int extendCount = 0;
  1678. if ( baseType != null && baseType != typeof( object ) && baseType != typeof( ValueType ) && !baseType.IsPrimitive )
  1679. {
  1680. typeHtml.Write( " : " );
  1681. TypeInfo baseInfo = (TypeInfo)m_Types[baseType];
  1682. if ( baseInfo == null )
  1683. typeHtml.Write( baseType.Name );
  1684. else
  1685. typeHtml.Write( "<a href=\"{0}\">{1}</a>", baseInfo.m_FileName, baseInfo.m_TypeName );
  1686. ++extendCount;
  1687. }
  1688. if ( ifaces.Length > 0 )
  1689. {
  1690. if ( extendCount == 0 )
  1691. typeHtml.Write( " : " );
  1692. for ( int i = 0; i < ifaces.Length; ++i )
  1693. {
  1694. Type iface = ifaces[i];
  1695. TypeInfo ifaceInfo = (TypeInfo)m_Types[iface];
  1696. if ( extendCount != 0 )
  1697. typeHtml.Write( ", " );
  1698. ++extendCount;
  1699. if ( ifaceInfo == null )
  1700. typeHtml.Write( iface.Name );
  1701. else
  1702. typeHtml.Write( "<a href=\"{0}\">{1}</a>", ifaceInfo.m_FileName, ifaceInfo.m_TypeName );
  1703. }
  1704. }
  1705. typeHtml.WriteLine( "</h2>" );
  1706. ArrayList derived = info.m_Derived;
  1707. if ( derived != null )
  1708. {
  1709. typeHtml.Write( "<h4>Derived Types: " );
  1710. derived.Sort( new TypeComparer() );
  1711. for ( int i = 0; i < derived.Count; ++i )
  1712. {
  1713. TypeInfo derivedInfo = (TypeInfo)derived[i];
  1714. if ( i != 0 )
  1715. typeHtml.Write( ", " );
  1716. typeHtml.Write( "<a href=\"{0}\">{1}</a>", derivedInfo.m_FileName, derivedInfo.m_TypeName );
  1717. }
  1718. typeHtml.WriteLine( "</h4>" );
  1719. }
  1720. ArrayList nested = info.m_Nested;
  1721. if ( nested != null )
  1722. {
  1723. typeHtml.Write( "<h4>Nested Types: " );
  1724. nested.Sort( new TypeComparer() );
  1725. for ( int i = 0; i < nested.Count; ++i )
  1726. {
  1727. TypeInfo nestedInfo = (TypeInfo)nested[i];
  1728. if ( i != 0 )
  1729. typeHtml.Write( ", " );
  1730. typeHtml.Write( "<a href=\"{0}\">{1}</a>", nestedInfo.m_FileName, nestedInfo.m_TypeName );
  1731. }
  1732. typeHtml.WriteLine( "</h4>" );
  1733. }
  1734. MemberInfo[] membs = type.GetMembers( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly );
  1735. Array.Sort( membs, new MemberComparer() );
  1736. for ( int i = 0; i < membs.Length; ++i )
  1737. {
  1738. MemberInfo mi = membs[i];
  1739. if ( mi is PropertyInfo )
  1740. WriteProperty( (PropertyInfo)mi, typeHtml );
  1741. else if ( mi is ConstructorInfo )
  1742. WriteCtor( info.m_TypeName, (ConstructorInfo)mi, typeHtml );
  1743. else if ( mi is MethodInfo )
  1744. WriteMethod( (MethodInfo)mi, typeHtml );
  1745. }
  1746. }
  1747. private static void WriteProperty( PropertyInfo pi, StreamWriter html )
  1748. {
  1749. html.Write( " " );
  1750. MethodInfo getMethod = pi.GetGetMethod();
  1751. MethodInfo setMethod = pi.GetSetMethod();
  1752. if ( (getMethod != null && getMethod.IsStatic) || (setMethod != null && setMethod.IsStatic) )
  1753. html.Write( StaticString );
  1754. html.Write( GetPair( pi.PropertyType, pi.Name, false ) );
  1755. html.Write( '(' );
  1756. if ( pi.CanRead )
  1757. html.Write( GetString );
  1758. if ( pi.CanWrite )
  1759. html.Write( SetString );
  1760. html.WriteLine( " )<br>" );
  1761. }
  1762. private static void WriteCtor( string name, ConstructorInfo ctor, StreamWriter html )
  1763. {
  1764. if ( ctor.IsStatic )
  1765. return;
  1766. html.Write( " " );
  1767. html.Write( CtorString );
  1768. html.Write( name );
  1769. html.Write( '(' );
  1770. ParameterInfo[] parms = ctor.GetParameters();
  1771. if ( parms.Length > 0 )
  1772. {
  1773. html.Write( ' ' );
  1774. for ( int i = 0; i < parms.Length; ++i )
  1775. {
  1776. ParameterInfo pi = parms[i];
  1777. if ( i != 0 )
  1778. html.Write( ", " );
  1779. if ( pi.IsIn )
  1780. html.Write( InString );
  1781. else if ( pi.IsOut )
  1782. html.Write( OutString );
  1783. html.Write( GetPair( pi.ParameterType, pi.Name, pi.IsOut ) );
  1784. }
  1785. html.Write( ' ' );
  1786. }
  1787. html.WriteLine( ")<br>" );
  1788. }
  1789. private static void WriteMethod( MethodInfo mi, StreamWriter html )
  1790. {
  1791. if ( mi.IsSpecialName )
  1792. return;
  1793. html.Write( " " );
  1794. if ( mi.IsStatic )
  1795. html.Write( StaticString );
  1796. if ( mi.IsVirtual )
  1797. html.Write( VirtString );
  1798. html.Write( GetPair( mi.ReturnType, mi.Name, false ) );
  1799. html.Write( '(' );
  1800. ParameterInfo[] parms = mi.GetParameters();
  1801. if ( parms.Length > 0 )
  1802. {
  1803. html.Write( ' ' );
  1804. for ( int i = 0; i < parms.Length; ++i )
  1805. {
  1806. ParameterInfo pi = parms[i];
  1807. if ( i != 0 )
  1808. html.Write( ", " );
  1809. if ( pi.IsIn )
  1810. html.Write( InString );
  1811. else if ( pi.IsOut )
  1812. html.Write( OutString );
  1813. html.Write( GetPair( pi.ParameterType, pi.Name, pi.IsOut ) );
  1814. }
  1815. html.Write( ' ' );
  1816. }
  1817. html.WriteLine( ")<br>" );
  1818. }
  1819. }
  1820. public enum ModelBodyType
  1821. {
  1822. Invalid = -1,
  1823. Monsters,
  1824. Sea,
  1825. Animals,
  1826. Human,
  1827. Equipment
  1828. }
  1829. public class BodyEntry
  1830. {
  1831. private Body m_Body;
  1832. private ModelBodyType m_BodyType;
  1833. private string m_Name;
  1834. public Body Body{ get{ return m_Body; } }
  1835. public ModelBodyType BodyType{ get{ return m_BodyType; } }
  1836. public string Name{ get{ return m_Name; } }
  1837. public BodyEntry( Body body, ModelBodyType bodyType, string name )
  1838. {
  1839. m_Body = body;
  1840. m_BodyType = bodyType;
  1841. m_Name = name;
  1842. }
  1843. public override bool Equals( object obj )
  1844. {
  1845. BodyEntry e = (BodyEntry)obj;
  1846. return ( m_Body == e.m_Body && m_BodyType == e.m_BodyType && m_Name == e.m_Name );
  1847. }
  1848. public override int GetHashCode()
  1849. {
  1850. return m_Body.BodyID ^ (int)m_BodyType ^ m_Name.GetHashCode();
  1851. }
  1852. }
  1853. public class BodyEntrySorter : IComparer
  1854. {
  1855. public int Compare( object x, object y )
  1856. {
  1857. BodyEntry a = (BodyEntry)x;
  1858. BodyEntry b = (BodyEntry)y;
  1859. int v = a.BodyType.CompareTo( b.BodyType );
  1860. if ( v == 0 )
  1861. v = a.Body.BodyID.CompareTo( b.Body.BodyID );
  1862. if ( v == 0 )
  1863. v = a.Name.CompareTo( b.Name );
  1864. return v;
  1865. }
  1866. }
  1867. }