/* Package Name: CEO's Yet Another Arya Addon Generator (YAAAG) Author: CEO Version: 1.2 Public Release: 09/25/07 Purpose: Generates AddOns from statics, items, and tiles. Oh my! */ /* Modified to work with the new SA & High Seas items by Hammerhand */ // If you're using an SVN that supports List<> methods (remove the //s) to use those instead of arrays or add them for RC1. #define RC2 //#define DEBUG #undef DEBUG using System; using System.Collections; using System.IO; using Server; using Server.Items; using Server.Gumps; using Server.Commands; using System.Collections.Generic; using Server.ContextMenus; using Server.Network; using Server.Targeting; namespace Arya.Misc { public class AddonGenerator { /// /// Set this value if you wish the scripts to be output somewhere else rather than in the default RunUO\TheBox /// directory. This should be a full valid path on your computer /// /// Example: /// /// private static string m_CustomOutputDirector = @"C:\Program Files\RunUO\Scripts\Custom\Addons"; /// private static string m_CustomOutputDirectory = null; #region Template private const string m_SimpleCode = @" for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++) AddComponent( new AddonComponent( m_AddOnSimpleComponents[i,0] ), m_AddOnSimpleComponents[i,1], m_AddOnSimpleComponents[i,2], m_AddOnSimpleComponents[i,3] );"; private const string m_ComplexCode = @" for (int i = 0; i < m_AddOnComplexComponents.Length / 6; i++) AddComplexComponent( (BaseAddon)this, m_AddOnComplexComponents[i,0], m_AddOnComplexComponents[i,1], m_AddOnComplexComponents[i,2], m_AddOnComplexComponents[i,3], m_AddOnComplexComponents[i,4], m_AddOnComplexComponents[i,5] );"; private const string m_ComplexNameCode = @" private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource) { AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1); } private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount) { AddonComponent ac; ac = new AddonComponent(item); if (name != null && name.Length > 0) ac.Name = name; if (hue != 0) ac.Hue = hue; if (amount > 1) { ac.Stackable = true; ac.Amount = amount; } if (lightsource != -1) ac.Light = (LightType) lightsource; addon.AddComponent(ac, xoffset, yoffset, zoffset); }"; private const string m_Template = @" //////////////////////////////////////// // // // Generated by CEO's YAAAG - Ver 2 // // (Yet Another Arya Addon Generator) // // Modified by Hammerhand for // // SA & High Seas content // // // //////////////////////////////////////// using System; using Server; using Server.Items; namespace {namespace} { public class {name}Addon : BaseAddon { {simplelist} {complexlist} public override BaseAddonDeed Deed { get { return new {name}AddonDeed(); } } [ Constructable ] public {name}Addon() { {simplecomponentscode} {complexcomponentscode} {namedcomponentscode} } public {name}Addon( Serial serial ) : base( serial ) { } {complexnamecomponentscode} public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( 0 ); // Version } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } public class {name}AddonDeed : BaseAddonDeed { public override BaseAddon Addon { get { return new {name}Addon(); } } [Constructable] public {name}AddonDeed() { Name = ""{name}""; } public {name}AddonDeed( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( 0 ); // Version } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } }"; #endregion public static void Initialize() { CommandSystem.Register("AddonGen", AccessLevel.Administrator, new CommandEventHandler(OnAddonGen)); } #region Command [Usage("AddonGen [ [namespace]]"), Description("Brings up the addon script generator gump. When used with the name (and eventually namespace) parameter generates an addon script from the targeted region.")] private static void OnAddonGen(CommandEventArgs e) { object[] state = new object[18]; state[0] = ""; state[1] = "Server.Items"; state[2] = true; state[3] = false; state[4] = false; state[5] = true; state[6] = true; state[7] = true; state[8] = true; state[9] = -128; state[10] = 127; state[11] = state[13] = state[15] = 2; state[12] = state[14] = state[16] = 36653; if (e.Arguments.Length > 0) { state[0] = e.Arguments[0]; if (e.Arguments.Length > 1) state[1] = e.Arguments[1]; } e.Mobile.SendGump(new InternalGump(e.Mobile, state)); } #endregion private static void PickerCallback(Mobile from, Map map, Point3D start, Point3D end, object state) { object[] args = state as object[]; int m_SimpleComponents = 0; int m_ComplexComponents = 0; int m_NamedComponents = 0; int m_TotalComponents = 0; if (start.X > end.X) { int x = start.X; start.X = end.X; end.X = x; } if (start.Y > end.Y) { int y = start.Y; start.Y = end.Y; end.Y = y; } Rectangle2D bounds = new Rectangle2D(start, end); string name = args[0] as string; string ns = args[1] as string; bool getStatics = (bool)args[2]; bool getItems = (bool)args[3]; bool getTiles = (bool)args[4]; bool includeStaticRange = (bool)args[5]; bool includeItemRange = (bool)args[6]; bool includeTileRange = (bool)args[7]; bool includeZRange = (bool)args[8]; bool generateTest = (bool)args[17]; sbyte min = sbyte.MinValue; sbyte max = sbyte.MaxValue; int minStaticID = 2; int maxStaticID = 36653; int minItemID = 2; int maxItemID = 36653; int minTileID = 2; int maxTileID = 36653; try { min = sbyte.Parse(args[9] as string); } catch { } try { max = sbyte.Parse(args[10] as string); } catch { } try { minStaticID = int.Parse(args[11] as string); } catch { } try { maxStaticID = int.Parse(args[12] as string); } catch { } try { minItemID = int.Parse(args[13] as string); } catch { } try { maxItemID = int.Parse(args[14] as string); } catch { } try { minTileID = int.Parse(args[15] as string); } catch { } try { maxTileID = int.Parse(args[16] as string); } catch { } Hashtable tiles = new Hashtable(); if (getTiles) { for (int x = start.X; x <= end.X; x++) { for (int y = start.Y; y <= end.Y; y++) { #if RC2 StaticTile[] stlist = map.Tiles.GetStaticTiles(x, y, true); List list = new List(); List remove = new List(); #else ArrayList list = map.GetTilesAt(new Point2D(x, y), false, false, true); ArrayList remove = new ArrayList(); #endif foreach (StaticTile t in stlist) { list.Add(t); int id = t.ID - 36653; if (id < 2 || id > 36653) remove.Add(t); else if (includeZRange && (t.Z < min || t.Z > max)) remove.Add(t); else if (!includeZRange && (t.Z >= min && t.Z <= max)) remove.Add(t); else if (includeTileRange && (id < minTileID || id > maxTileID)) remove.Add(t); else if (!includeTileRange && (id >= minTileID && id <= maxTileID)) remove.Add(t); } foreach (StaticTile t in remove) { list.Remove(t); } if (list != null && list.Count > 0) { tiles[new Point2D(x, y)] = list; } } } } IPooledEnumerable en = map.GetItemsInBounds(bounds); ArrayList target = new ArrayList(); bool fail = false; try { foreach (object o in en) { if (getStatics) { Static s = o as Static; if (s == null) { } else if (s.Deleted) { } else if (includeZRange && (s.Z < min || s.Z > max)) continue; else if (!includeZRange && (s.Z >= min && s.Z <= max)) continue; else if (includeStaticRange && (s.ItemID < minStaticID || s.ItemID > maxStaticID)) continue; else if (!includeStaticRange && (s.ItemID >= minStaticID && s.ItemID <= maxStaticID)) continue; else { target.Add(o); #if DEBUG Console.WriteLine("Static={0}:{1}", s.GetType().ToString(), s.ItemID); #endif continue; } } if (getItems) { Static s = o as Static; if (s != null) // Don't want a static continue; Item i = o as Item; if (i == null) continue; else if (i.Deleted) continue; else if (i is BaseAddon) // Not a good idea to add a BaseAddOn for obvious reasons continue; else if (i.ItemID < 2 || i.ItemID > 36653) // This is not an Item within the normal artwork.. multi... etc.. Toss it continue; else if (includeZRange && (i.Z < min || i.Z > max)) continue; else if (!includeZRange && (i.Z >= min && i.Z <= max)) continue; else if (includeItemRange && (i.ItemID < minItemID || i.ItemID > maxItemID)) continue; else if (!includeItemRange && (i.ItemID >= minItemID && i.ItemID <= maxItemID)) continue; #if DEBUG Console.WriteLine("item={0}:{1}, {2}-map{3}", i.GetType().ToString(), i.ItemID, i.Deleted, i.Map); #endif target.Add(o); } } } catch (Exception err) { Console.WriteLine(err.ToString()); from.SendMessage(0x40, "The targeted components have been modified. Please retry."); fail = true; } finally { en.Free(); } if (fail) return; if (target.Count == 0 && tiles.Keys.Count == 0) { from.SendMessage(0x40, "No components have been selected."); from.SendGump(new InternalGump(from, args)); return; } // Get center Point3D center = new Point3D(); center.Z = 127; int x1 = bounds.End.X; int y1 = bounds.End.Y; int x2 = bounds.Start.X; int y2 = bounds.Start.Y; // Get correct bounds foreach (Item item in target) { if (item.Z < center.Z) { center.Z = item.Z; } x1 = Math.Min(x1, item.X); y1 = Math.Min(y1, item.Y); x2 = Math.Max(x2, item.X); y2 = Math.Max(y2, item.Y); } CEOIdentifyAddon IdentifyAddon = null; if (generateTest) IdentifyAddon = new CEOIdentifyAddon("init"); foreach (Point2D p in tiles.Keys) { #if RC2 List list = tiles[p] as List; #else ArrayList list = tiles[p] as ArrayList; #endif if (list == null) { Console.WriteLine("The list is null... "); return; } foreach (StaticTile t in list) { if (t.Z < center.Z) { center.Z = t.Z; } } x1 = Math.Min(x1, p.X); y1 = Math.Min(y1, p.Y); x2 = Math.Max(x2, p.X); y2 = Math.Max(y2, p.Y); } center.X = x1 + ((x2 - x1) / 2); center.Y = y1 + ((y2 - y1) / 2); // Build items System.Text.StringBuilder nc = new System.Text.StringBuilder(); nc.Append("\n"); System.Text.StringBuilder sl = new System.Text.StringBuilder(); sl.Append("private static int[,] m_AddOnSimpleComponents = new int[,] {\n\t\t\t "); System.Text.StringBuilder cl = new System.Text.StringBuilder(); cl.Append("private static int[,] m_AddOnComplexComponents = new int[,] {\n\t\t\t "); System.Text.StringBuilder sc = new System.Text.StringBuilder(); sc.Append("// "); System.Text.StringBuilder cc = new System.Text.StringBuilder(); cc.Append("// "); int simplecount = 0; int complexcount = 0; // Tiles foreach (Point2D p in tiles.Keys) { #if RC2 List list = tiles[p] as List; #else ArrayList list = tiles[p] as ArrayList; #endif int xOffset = p.X - center.X; int yOffset = p.Y - center.Y; foreach (StaticTile t in list) { int zOffset = t.Z - center.Z; int id = t.ID - 36653; m_SimpleComponents++; simplecount++; m_TotalComponents++; sc.AppendFormat("{0}\t ", m_TotalComponents); if (simplecount > 1) sl.Append(", "); sl.Append("{"); sl.AppendFormat("{0}, {1}, {2}, {3}", id, xOffset, yOffset, zOffset); sl.Append("}"); if (simplecount % 3 == 0) { sl.AppendFormat("{0}\n\t\t\t", sc.ToString()); sc.Length = 0; sc.Append("// "); } if (generateTest) AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, 0, -1, string.Format("({0}):{1},{2},{3}", m_TotalComponents, xOffset, yOffset, zOffset), 0); } } // Statics & Items foreach (Item item in target) { if (item.Deleted) continue; int xOffset = item.X - center.X; int yOffset = item.Y - center.Y; int zOffset = item.Z - center.Z; int id = item.ItemID; if (((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource) || (item.Hue != 0) || (item.Name != null) || item.Amount > 1) // Use old method { if (item.Name != null || item.Amount != 0) // Have to do this one the old method { m_NamedComponents++; m_TotalComponents++; int lightsource = -1; if ((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource) lightsource = (int)item.Light; nc.AppendFormat("\t\t\tAddComplexComponent( (BaseAddon) this, {0}, {1}, {2}, {3}, {4}, {5}, \"{6}\", {7});// {8}\n", id, xOffset, yOffset, zOffset, item.Hue, lightsource, item.Name, item.Amount, m_TotalComponents); if (generateTest) AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), item.Amount); } else //if (item.Hue != 0 || (item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource) { int lightsource = -1; if ((item.ItemData.Flags & TileFlag.LightSource) == TileFlag.LightSource) lightsource = (int)item.Light; m_ComplexComponents++; m_TotalComponents++; cc.AppendFormat("{0}\t", m_TotalComponents); complexcount++; if (complexcount > 1) cl.Append(", "); cl.Append("{"); cl.AppendFormat("{0}, {1}, {2}, {3}, {4}, {5} ", id, xOffset, yOffset, zOffset, item.Hue, lightsource); cl.Append("}"); if (complexcount % 3 == 0) { cl.AppendFormat("{0}\n\t\t\t", cc.ToString()); cc.Length = 0; cc.Append("// "); } if (generateTest) AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), 0); } } else // Add data to static table { m_SimpleComponents++; m_TotalComponents++; sc.AppendFormat("{0}\t", m_TotalComponents); simplecount++; if (simplecount > 1) sl.Append(", "); sl.Append("{"); sl.AppendFormat("{0}, {1}, {2}, {3}", id, xOffset, yOffset, zOffset); sl.Append("}"); if (simplecount % 3 == 0) { sl.AppendFormat("{0}\n\t\t\t", sc.ToString()); sc.Length = 0; sc.Append("// "); } if (generateTest) AddIdentifyAddOnComponent(IdentifyAddon, id, xOffset, yOffset, zOffset, item.Hue, -1, string.Format("({0},{1}): {2}, {3}, {4}", m_TotalComponents, id, xOffset, yOffset, zOffset), 0); } } if (sc.Length > 4) sl.AppendFormat("{0}\n", sc.ToString()); if (cc.Length > 4) cl.AppendFormat("{0}\n", cc.ToString()); if (m_SimpleComponents > 0) sl.Append("\t\t};\n\n"); if (m_ComplexComponents > 0) cl.Append("\t\t};\n\n"); string output = m_Template.Replace("{name}", name); output = output.Replace("{simplelist}", m_SimpleComponents > 0 ? sl.ToString() : ""); output = output.Replace("{simplecomponentscode}", m_SimpleComponents > 0 ? m_SimpleCode : ""); output = output.Replace("{complexlist}", m_ComplexComponents > 0 ? cl.ToString() : ""); output = output.Replace("{complexcomponentscode}", m_ComplexComponents > 0 ? m_ComplexCode : ""); output = output.Replace("{namedcomponentscode}", m_NamedComponents > 0 ? nc.ToString() : ""); output = output.Replace("{complexnamecomponentscode}", (m_ComplexComponents > 0 || m_NamedComponents > 0) ? m_ComplexNameCode : ""); output = output.Replace("{namespace}", ns); StreamWriter writer = null; string path = null; if (m_CustomOutputDirectory != null) path = Path.Combine(m_CustomOutputDirectory, string.Format(@"TheBox\{0}Addon.cs", name)); else path = Path.Combine(Core.BaseDirectory, string.Format(@"TheBox\{0}Addon.cs", name)); fail = false; try { string folder = Path.GetDirectoryName(path); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } writer = new StreamWriter(path, false); writer.Write(output); } catch { from.SendMessage(0x40, "An error occurred when writing the file."); fail = true; } finally { if (writer != null) writer.Close(); } if (!fail) { from.SendMessage(0x40, "Script saved to {0}", path); from.SendMessage(0x40, "Total components in AddOn: {0}", m_TotalComponents); if (generateTest && IdentifyAddon != null) { from.SendMessage(0x37, "Now target a land tile to place a your addon."); from.Target = new InternalTarget(IdentifyAddon); } } } private static void AddIdentifyAddOnComponent(CEOIdentifyAddon ai, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount) { if (ai == null) return; AddonComponent ac; ac = new AddonComponent(item); if (name != null && name.Length > 0) ac.Name = name; if (hue != 0) ac.Hue = hue; if (amount > 1) // Note: a warning will show on the console regarding a non-stackable item.... { ac.Stackable = true; ac.Amount = amount; } if (lightsource != -1) ac.Light = (LightType)lightsource; ai.AddComponent(ac, xoffset, yoffset, zoffset); } private class InternalTarget : Target { private CEOIdentifyAddon m_IdentifyAddon; public InternalTarget(CEOIdentifyAddon IdentifyAddon) : base(12, false, TargetFlags.None) { m_IdentifyAddon = IdentifyAddon; CheckLOS = true; AllowGround = true; DisallowMultis = true; Range = 15; } protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) { if (m_IdentifyAddon != null) m_IdentifyAddon.Delete(); } protected override void OnTarget(Mobile from, object o) { if (o != null) { if (o is LandTarget) { LandTarget l = o as LandTarget; m_IdentifyAddon.MoveToWorld(l.Location, from.Map); } else { from.SendMessage(37, "Use must target a land tile to place your addon."); if (m_IdentifyAddon != null) m_IdentifyAddon.Delete(); } } } } #region Gump private class InternalGump : Gump { private const int LabelHue = 0x480; private const int TitleHue = 0x35; private object[] m_State; public InternalGump(Mobile m, object[] state) : base(100, 50) { m.CloseGump(typeof(InternalGump)); m_State = state; MakeGump(); } private void MakeGump() { Closable = true; Disposable = true; Dragable = true; Resizable = false; AddPage(0); AddBackground(0, 0, 440, 260, 9260); //AddAlphaRegion(10, 10, 430, 260); //uncomment this line if you like see-thru menus AddHtml(0, 15, 440, 20, Center(Color("CEO's Yet Another Arya Addon Generator(YAAAG)", 0x000080)), false, false); int x = 40; AddLabel(20, x, LabelHue, @"Name"); AddImageTiled(95, x, 165, 18, 9274); AddTextEntry(95, x, 165, 20, LabelHue, 0, m_State[0] as string); // Name x += 20; AddLabel(20, x, LabelHue, @"Namespace"); AddImageTiled(95, x, 165, 18, 9274); AddTextEntry(95, x, 165, 20, LabelHue, 1, m_State[1] as string); // Namespace AddLabel(340, x, TitleHue, @"ID Range"); x += 20; AddLabel(20, x, TitleHue, @"Export"); AddLabel(170, x, TitleHue, @"ID Range"); AddLabel(320, x, TitleHue, @"Include/Exclude"); x += 25; // Export Statics, Items, and Tiles string[] exportString = new string[] { "Statics", "Items", "Tiles" }; for (int i = 0; i < 3; i++) { DisplayExportLine(x, i, ((bool)m_State[i + 2]), ((bool)m_State[i + 5]), exportString[i], m_State[11 + (i * 2)].ToString(), m_State[12 + (i * 2)].ToString()); x += (i < 2 ? 25 : 15); } AddImageTiled(15, x + 15, 420, 1, 9304); x += 25; // Z Range AddCheck(350, x, 9026, 9027, ((bool)m_State[8]), 6); AddLabel(20, x, LabelHue, @"Z Range"); AddImageTiled(115, x + 15, 50, 1, 9274); AddTextEntry(115, x - 5, 50, 20, LabelHue, 2, m_State[9].ToString()); AddLabel(185, x, LabelHue, @"to"); AddImageTiled(225, x + 15, 50, 1, 9274); AddTextEntry(225, x - 5, 50, 20, LabelHue, 3, m_State[10].ToString()); x += 25; // Buttons AddButton(20, x, 4020, 4021, 0, GumpButtonType.Reply, 0); AddLabel(55, x, LabelHue, @"Cancel"); AddButton(155, x, 4005, 4006, 1, GumpButtonType.Reply, 0); AddLabel(195, x, LabelHue, @"Generate"); AddButton(300, x, 4005, 4006, 2, GumpButtonType.Reply, 0); AddLabel(340, x, LabelHue, @"Test & Gen"); } private void DisplayExportLine(int x, int index, bool state, bool include, string heading, string min, string max) { AddCheck(20, x, 9026, 9027, state, index); AddLabel(40, x, LabelHue, heading); AddImageTiled(115, x + 15, 50, 1, 9274); AddTextEntry(115, x - 5, 50, 20, LabelHue, 4 + (index * 2), min);// Tile ID Min AddLabel(185, x, LabelHue, @"to"); AddImageTiled(225, x + 15, 50, 1, 9274); AddTextEntry(225, x - 5, 50, 20, LabelHue, 5 + (index * 2), max);// Tile ID Max AddCheck(350, x, 9026, 9027, include, index + 3); // Include or Exclude compare? } private string Center(string text) { return String.Format("
{0}
", text); } private string Color(string text, int color) { return String.Format("{1}", color, text); } public override void OnResponse(Server.Network.NetState sender, RelayInfo info) { if (info.ButtonID == 0) return; else if (info.ButtonID == 1) m_State[17] = false; else m_State[17] = true; foreach (TextRelay text in info.TextEntries) m_State[text.EntryID < 2 ? text.EntryID : text.EntryID + 7] = text.Text; // Reset checks for (int x = 2; x <= 8; x++) m_State[x] = false; foreach (int check in info.Switches) m_State[check + 2] = true; // Offset by 2 in the state object if (Verify(sender.Mobile, m_State)) { BoundingBoxPicker.Begin(sender.Mobile, new BoundingBoxCallback(AddonGenerator.PickerCallback), m_State); } else { sender.Mobile.SendMessage(0x40, "Please review the generation parameters, some are invalid."); sender.Mobile.SendGump(new InternalGump(sender.Mobile, m_State)); } } private static bool Verify(Mobile from, object[] state) { if (state[0] == null || (state[0] as string).Length == 0) { from.SendMessage(0x40, "Name field is invalid or missing."); return false; } if (state[1] == null || (state[1] as string).Length == 0) { from.SendMessage(0x40, "Namespace field is invalid or missing."); return false; } if (!((bool)state[2] || (bool)state[3] || (bool)state[4])) { from.SendMessage(0x40, "You must have least one Export button selected. (Static/Items/Tiles)"); return false; } string[] errors = new string[] {"Z Range Min", "Z Range Max","Static Min ID", "Static Max ID", "Item Min ID", "Item Max ID", "Tile Min ID", "Tile Max ID"}; for (int x = 0; x < 8; x++) if (!CheckNumber(x < 2 ? 0 : 1, state[x + 9] as string, errors[x], from)) return false; return true; } private static bool CheckNumber(int numType, string number, string error, Mobile from) { sbyte sbyteTemp; int intTemp; try { if (numType == 0) sbyteTemp = sbyte.Parse(number); else intTemp = int.Parse(number); } catch { from.SendMessage(0x40, "There's a problem with the {0} field.", error); return false; } return true; } } #endregion } } #region CEOIdentifyAddon namespace Server.Items { public class CEOIdentifyAddon : BaseAddon { [Constructable] public CEOIdentifyAddon(string init) { // Nothing really here, just prevents adding a null contruct via [add command } [Constructable] public CEOIdentifyAddon() { this.Delete(); } public CEOIdentifyAddon(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); // Version } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); if (this.Map == null || this.Map == Map.Internal) this.Delete(); // Remove it because it's most } public void ReDeed(Mobile m) { this.Delete(); } } } #endregion