/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="item">ItemID of item to generate.</param> /// <param name="hue">Hue of item to generate.</param> /// <param name="amount">Stackable amount of item to generate.</param> /// <param name="properties">Item properties packet.</param> public static void Generate(Stream stream, int itemID, int hue = 0, int amount = 0, QueryPropertiesResponsePacket properties = null) { UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions; if (itemDefinitions == null) { App.Window.ShowNotification(NotificationType.Error, "Item definitions not initialized"); return; } UltimaItemProperties itemProperties = Globals.Instance.ItemProperties; if (itemProperties == null) { App.Window.ShowNotification(NotificationType.Error, "Item properties not initialized"); return; } UltimaStringCollection clilocs = Globals.Instance.Clilocs; using (UltimaClassWriter writer = new UltimaClassWriter(stream)) { writer.WriteUsing("System"); writer.WriteUsing("Server"); writer.WriteUsing("Server.Items"); writer.WriteLine(); writer.BeginNamespace("Server.Items"); // Get item definition UltimaItemDefinition itemDefinition = null; if (itemDefinitions.Items.ContainsKey(itemID)) { itemDefinition = itemDefinitions.Items[itemID]; } string className = "GenericClass"; string baseClass = null; int nameCliloc = 0; string nameClilocText = null; string nameText = null; bool stackable = false; if (itemDefinition != null) { baseClass = itemDefinition.Class; } // Get class name if (properties != null && properties.Properties.Count > 0) { // Get name from name property QueryPropertiesProperty nameProperty = properties.Properties[0]; if (nameProperty.Cliloc == StackableCliloc) { // Get name from stackable cliloc UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser(nameProperty.Arguments); nameCliloc = nameArguments.GetCliloc(0); if (nameCliloc > 0) { if (clilocs != null) { nameClilocText = clilocs.GetString(nameCliloc); if (!String.IsNullOrEmpty(nameClilocText)) { className = UltimaClassWriter.BuildClassName(nameClilocText); } } } else { nameText = nameArguments[0]; if (!String.IsNullOrEmpty(nameText)) { className = UltimaClassWriter.BuildClassName(nameText); } } stackable = true; } else { // Get name from name cliloc nameCliloc = nameProperty.Cliloc; if (!IsString(nameCliloc)) { if (clilocs != null) { nameClilocText = clilocs.GetString(nameCliloc); if (!String.IsNullOrEmpty(nameClilocText)) { className = UltimaClassWriter.BuildClassName(nameClilocText); } } } else { nameText = nameProperty.Arguments; if (!String.IsNullOrEmpty(nameText)) { className = UltimaClassWriter.BuildClassName(nameText); } } } } else if (clilocs != null) { // Get name from itemID cliloc int itemIDCliloc = 0; if (itemID < 0x4000) { itemIDCliloc = OldItemCliloc + itemID; } else { itemIDCliloc = NewItemCliloc + itemID; } string clilocText = clilocs.GetString(itemIDCliloc); if (!String.IsNullOrEmpty(clilocText)) { className = UltimaClassWriter.BuildClassName(clilocText); } } // Check if container bool isContainer = false; if (baseClass == null && properties != null && properties.Properties.Count > 0) { for (int i = 1; i < properties.Properties.Count; i++) { QueryPropertiesProperty property = properties.Properties[i]; if (IsContainer(property.Cliloc)) { baseClass = "BaseContainer"; isContainer = true; break; } } } if (baseClass == null) { baseClass = "Item"; } writer.BeginClass(className, baseClass); // Name cliloc bool anyOverrides = false; if (nameCliloc > 0 && IsSpecial(itemID, nameCliloc)) { if (!String.IsNullOrEmpty(nameClilocText)) { writer.OverrideProperty("public", "int", "LabelNumber", nameCliloc.ToString(), nameClilocText); } else { writer.OverrideProperty("public", "int", "LabelNumber", nameCliloc.ToString()); } anyOverrides = true; } // Properties if (properties != null && properties.Properties.Count > 0) { Dictionary <int, UltimaItemProperty> constructorPropertyDefinitions = new Dictionary <int, UltimaItemProperty>(); List <QueryPropertiesProperty> constructorProperties = new List <QueryPropertiesProperty>(); List <QueryPropertiesProperty> unknownProperties = new List <QueryPropertiesProperty>(); List <QueryPropertiesProperty> damageProperties = new List <QueryPropertiesProperty>(); for (int i = 1; i < properties.Properties.Count; i++) { QueryPropertiesProperty property = properties.Properties[i]; if (IsDamage(property.Cliloc)) { damageProperties.Add(property); continue; } UltimaItemProperty propertyDefinition = null; if (itemDefinition != null) { Dictionary <int, UltimaItemProperty> groupProperties = null; UltimaItemDefinitionGroup group = itemDefinition.Parent; while (group.Parent != null) { group = group.Parent; } if (itemProperties.GroupProperties.TryGetValue(group.Name, out groupProperties)) { if (!groupProperties.TryGetValue(property.Cliloc, out propertyDefinition)) { itemProperties.Properties.TryGetValue(property.Cliloc, out propertyDefinition); } } else { itemProperties.Properties.TryGetValue(property.Cliloc, out propertyDefinition); } } else { itemProperties.Properties.TryGetValue(property.Cliloc, out propertyDefinition); } if (propertyDefinition != null) { UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser(property.Arguments); bool isConstructor = false; string propertyValue = null; if (propertyDefinition.Switch != null) { propertyDefinition.Switch.TryGetValue(property.Cliloc, out propertyValue); } foreach (UltimaItemPropertySetter setter in propertyDefinition.Setters) { if (!isConstructor && !setter.Overrides) { constructorProperties.Add(property); constructorPropertyDefinitions.Add(property.Cliloc, propertyDefinition); isConstructor = true; } if (setter.Overrides) { string argument = arguments[setter.Index]; string value = propertyValue; if (propertyValue == null) { value = GetPropertyValue(property.Cliloc, argument, setter); } writer.OverrideProperty("public", setter.ReturnType, setter.Name, value); anyOverrides = true; } } } else { unknownProperties.Add(property); } } if (anyOverrides) { writer.WriteLine(); } writer.WriteLineWithIndent("[Constructable]"); if (isContainer) { writer.BeginConstructor("public", className, null, String.Format("0x{0:X}", itemID)); } else { writer.BeginConstructor("public", className, null, ""); } // Name if (nameText != null) { writer.WriteLineWithIndent("Name = \"{0}\";", nameText); } // ItemID if (!isContainer && itemDefinition == null) { writer.WriteLineWithIndent("ItemID = 0x{0:X};", itemID); } // Hue if (hue > 0) { writer.WriteLineWithIndent("Hue = 0x{0:X};", hue); } // Stackable if (stackable) { writer.WriteLineWithIndent("Stackable = true;"); } if (amount > 1) { writer.WriteLineWithIndent("Amount = {0};", amount); } // Constructor variables foreach (QueryPropertiesProperty property in constructorProperties) { UltimaItemProperty propertyDefinition = constructorPropertyDefinitions[property.Cliloc]; UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser(property.Arguments); bool isSlayerSet = false; string propertyValue = null; if (propertyDefinition.Switch != null) { propertyDefinition.Switch.TryGetValue(property.Cliloc, out propertyValue); } foreach (UltimaItemPropertySetter setter in propertyDefinition.Setters) { if (!setter.Overrides) { string argument = arguments[setter.Index]; string value = propertyValue; if (value == null) { value = GetPropertyValue(property.Cliloc, argument, setter); } // Check if slayer 2 string setterName = setter.Name; if (isSlayerSet) { setterName += "2"; } if (setter.IsSlayer) { isSlayerSet = true; } // Write writer.WriteLineWithIndent(String.Format("{0} = {1};", setterName, value)); } } } // Write unknowns if (unknownProperties.Count > 0) { writer.WriteLine(); writer.WriteLineWithIndent("// Unknown properties"); foreach (QueryPropertiesProperty property in unknownProperties) { string clilocText = null; string format = "Found unknown property '{0}' with parameters '{1}'"; string notification = null; if (clilocs != null) { clilocText = GetPropertyDescription(property.Cliloc); } if (clilocText != null) { writer.WriteLineWithIndent(String.Format("//{0} = {1}; // Cliloc: {2}", property.Cliloc, property.Arguments, clilocText)); notification = String.Format(format, clilocText, property.Arguments); } else { writer.WriteLineWithIndent(String.Format("//{0} = {1};", property.Cliloc, property.Arguments)); notification = String.Format(format, property.Cliloc, property.Arguments); } App.Window.ShowNotification(NotificationType.Warning, notification); } } writer.EndConstructor(); // Write damage overwrite if (damageProperties.Count > 0) { int physicalDamage = 0; int fireDamage = 0; int coldDamage = 0; int poisonDamage = 0; int energyDamage = 0; int chaosDamage = 0; int directDamage = 0; foreach (QueryPropertiesProperty property in damageProperties) { UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser(property.Arguments); if (arguments.Length > 0) { int integer = 0; if (Int32.TryParse(arguments[0], out integer)) { if (property.Cliloc == 1060403) { physicalDamage = integer; } else if (property.Cliloc == 1060405) { fireDamage = integer; } else if (property.Cliloc == 1060404) { coldDamage = integer; } else if (property.Cliloc == 1060406) { poisonDamage = integer; } else if (property.Cliloc == 1060407) { energyDamage = integer; } else if (property.Cliloc == 1072846) { chaosDamage = integer; } else if (property.Cliloc == 1079978) { directDamage = integer; } } } } if (physicalDamage != 100) { writer.WriteLine(); writer.BeginOverrideMethod("public", "void", "GetDamageTypes", "Mobile wielder, out int phys, out int fire, out int cold, out int pois, out int nrgy, out int chaos, out int direct"); writer.WriteLineWithIndent("phys = {0};", physicalDamage); writer.WriteLineWithIndent("fire = {0};", fireDamage); writer.WriteLineWithIndent("cold = {0};", coldDamage); writer.WriteLineWithIndent("pois = {0};", poisonDamage); writer.WriteLineWithIndent("nrgy = {0};", energyDamage); writer.WriteLineWithIndent("chaos = {0};", chaosDamage); writer.WriteLineWithIndent("direct = {0};", directDamage); writer.EndMethod(); } } } else { writer.BeginConstructor("public", className); // Name if (nameText != null) { writer.WriteLineWithIndent("Name = \"{0}\";", nameText); } // ItemID writer.WriteLineWithIndent("ItemID = 0x{0:X};", itemID); // Hue if (hue > 0) { writer.WriteLineWithIndent("Hue = 0x{0:X};", hue); } // Stackable if (stackable) { writer.WriteLineWithIndent("Stackable = true;"); } if (amount > 1) { writer.WriteLineWithIndent("Amount = {0};", amount); } writer.EndConstructor(); } writer.WriteLine(); writer.WriteSerialConstructor(className); writer.WriteLine(); writer.WriteSerialize(); writer.WriteLine(); writer.WriteDeserialize(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification(NotificationType.Info, "Item generation complete"); } }
/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="gump">Gump to generate.</param> public static void Generate(Stream stream, GenericGumpPacket gump) { UltimaStringCollection clilocs = Globals.Instance.Clilocs; using (UltimaClassWriter writer = new UltimaClassWriter(stream)) { writer.WriteUsing("System"); writer.WriteUsing("Server"); writer.WriteUsing("Server.Gumps"); writer.WriteUsing("Server.Network"); writer.WriteLine(); writer.BeginNamespace("Server.Gumps"); string className = "GenericGump"; writer.BeginClass(className, "Gump"); writer.BeginConstructor("public", className, null, String.Format("{0}, {1}", gump.X, gump.Y)); for (int i = 0; i < gump.Entries.Count; i++) { GumpEntry entry = gump.Entries[i]; bool space = entry is GumpPage; if (space && i != 0) { writer.WriteLine(); } writer.WriteWithIndent(entry.GetRunUOLine()); // Comment int cliloc = 0; if (entry is GumpHtmlLocalized) { cliloc = (int)((GumpHtmlLocalized)entry).Number; } else if (entry is GumpHtmlLocalizedColor) { cliloc = (int)((GumpHtmlLocalizedColor)entry).Number; } else if (entry is GumpHtmlLocalizedArgs) { cliloc = (int)((GumpHtmlLocalizedArgs)entry).Number; } if (cliloc > 0 && clilocs != null) { string clilocText = clilocs.GetString(cliloc); if (!String.IsNullOrEmpty(clilocText)) { writer.WriteLine(" // {0}", clilocText); } else { writer.WriteLine(); } } else { writer.WriteLine(); } if (space && i < gump.Entries.Count) { writer.WriteLine(); } } writer.EndConstructor(); writer.WriteLine(); writer.BeginOverrideMethod("public", "void", "OnResponse", "NetState sender, RelayInfo info"); writer.EndMethod(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification(NotificationType.Info, "Gump generation complete"); } }
/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="item">ItemID of item to generate.</param> /// <param name="hue">Hue of item to generate.</param> /// <param name="amount">Stackable amount of item to generate.</param> /// <param name="properties">Item properties packet.</param> public static void Generate( Stream stream, MobileIncommingPacket mobile, MobileNamePacket name = null ) { using ( UltimaClassWriter writer = new UltimaClassWriter( stream ) ) { writer.WriteUsing( "System" ); writer.WriteUsing( "Server" ); writer.WriteUsing( "Server.Items" ); writer.WriteUsing( "Server.Mobiles" ); writer.WriteLine(); writer.BeginNamespace( "Server.Mobiles" ); string className = "GenericMobile"; string baseClass = "BaseCreature"; string baseClassParameters = String.Format( "AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4" ); bool isVendor = false; if ( name != null ) className = UltimaClassWriter.BuildClassName( name.MobileName ); if ( mobile.HasYellowHealthBar ) { // Most likely baseClass = "BaseVendor"; if ( name != null ) baseClassParameters = String.Format( "\"{0}\"", name.MobileName ); else baseClassParameters = String.Format( "\"{0}\"", className ); isVendor = true; } if ( name != null ) writer.WriteLineWithIndent( "[CorpseName( \"{0}\" corpse )]", name.MobileName.ToLower() ); else writer.WriteLineWithIndent( "[CorpseName( \"{0}\" corpse )]", className ); writer.BeginClass( className, baseClass ); writer.WriteLineWithIndent( "[Constructable]" ); writer.BeginConstructor( "public", className, baseClassParameters ); if ( !isVendor ) { if ( name != null ) writer.WriteLineWithIndent( "Name = \"{0}\";", name.MobileName ); else writer.WriteLineWithIndent( "Name = \"{0}\";", className ); writer.WriteLineWithIndent( "Body = 0x{0:X};", mobile.Body ); writer.WriteLineWithIndent( "BaseSoundID = 0; // TODO" ); if ( mobile.IsFemale ) writer.WriteLineWithIndent( "Female = true;" ); writer.WriteLine(); writer.WriteLineWithIndent( "SetDamageType( ResistanceType.Physical, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetDamageType( ResistanceType.Fire, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetDamageType( ResistanceType.Cold, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetDamageType( ResistanceType.Poison, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetDamageType( ResistanceType.Energy, 25 ); // TODO " ); writer.WriteLine(); writer.WriteLineWithIndent( "SetResistance( ResistanceType.Physical, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetResistance( ResistanceType.Fire, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetResistance( ResistanceType.Cold, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetResistance( ResistanceType.Poison, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetResistance( ResistanceType.Energy, 25 ); // TODO " ); writer.WriteLine(); writer.WriteLineWithIndent( "SetSkill( SkillName.MagicResist, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetSkill( SkillName.Tactics, 25 ); // TODO " ); writer.WriteLineWithIndent( "SetSkill( SkillName.Wrestling, 25 ); // TODO " ); writer.WriteLine(); writer.WriteLineWithIndent( "Fame = 0; // TODO" ); writer.WriteLineWithIndent( "Karma = 0; // TODO" ); writer.WriteLineWithIndent( "VirtualArmor = 0; // TODO" ); } else { if ( mobile.IsFemale ) writer.WriteLineWithIndent( "Female = true;" ); } writer.WriteLine(); // Items UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions; if ( itemDefinitions != null ) { bool hasItemDeclaration = false; foreach ( MobileItem item in mobile.Items ) { if ( itemDefinitions.Items.ContainsKey( item.ItemID ) ) { UltimaItemDefinition itemDefinition = itemDefinitions.Items[ item.ItemID ]; if ( !hasItemDeclaration ) { writer.WriteLineWithIndent( "Item item = null;" ); writer.WriteLine(); hasItemDeclaration = true; } writer.WriteLineWithIndent( "item = new {0}();", itemDefinition.Class ); if ( item.Hue > 0 ) writer.WriteLineWithIndent( "item.Hue = 0x{0:X};", item.Hue ); writer.WriteLineWithIndent( "AddItem( item );" ); writer.WriteLine(); } else App.Window.ShowNotification( NotificationType.Warning, String.Format( "Cannot find definition for item ID '0x{0:X}'. Skipping", item.ItemID ) ); } } else App.Window.ShowNotification( NotificationType.Warning, "Item definitions not initialized. Skipping mobile items" ); writer.EndConstructor(); writer.WriteSerialConstructor( className ); writer.WriteLine(); writer.BeginOverrideMethod( "public", "void", "GenerateLoot" ); writer.WriteLineWithIndent( "AddLoot( LootPack.Average );" ); writer.EndMethod(); writer.WriteSerialize(); writer.WriteLine(); writer.WriteDeserialize(); writer.EndClass(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification( NotificationType.Info, "Mobile generation complete" ); } }
/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="gump">Gump to generate.</param> public static void Generate( Stream stream, GenericGumpPacket gump ) { UltimaStringCollection clilocs = Globals.Instance.Clilocs; using ( UltimaClassWriter writer = new UltimaClassWriter( stream ) ) { writer.WriteUsing( "System" ); writer.WriteUsing( "Server" ); writer.WriteUsing( "Server.Gumps" ); writer.WriteUsing( "Server.Network" ); writer.WriteLine(); writer.BeginNamespace( "Server.Gumps" ); string className = "GenericGump"; writer.BeginClass( className, "Gump" ); writer.BeginConstructor( "public", className, null, String.Format( "{0}, {1}", gump.X, gump.Y ) ); for ( int i = 0; i < gump.Entries.Count; i++ ) { GumpEntry entry = gump.Entries[ i ]; bool space = entry is GumpPage; if ( space && i != 0 ) writer.WriteLine(); writer.WriteWithIndent( entry.GetRunUOLine() ); // Comment int cliloc = 0; if ( entry is GumpHtmlLocalized ) cliloc = (int) ( (GumpHtmlLocalized) entry ).Number; else if ( entry is GumpHtmlLocalizedColor ) cliloc = (int) ( (GumpHtmlLocalizedColor) entry ).Number; else if ( entry is GumpHtmlLocalizedArgs ) cliloc = (int) ( (GumpHtmlLocalizedArgs) entry ).Number; if ( cliloc > 0 && clilocs != null ) { string clilocText = clilocs.GetString( cliloc ); if ( !String.IsNullOrEmpty( clilocText ) ) writer.WriteLine( " // {0}", clilocText ); else writer.WriteLine(); } else writer.WriteLine(); if ( space && i < gump.Entries.Count ) writer.WriteLine(); } writer.EndConstructor(); writer.WriteLine(); writer.BeginOverrideMethod( "public", "void", "OnResponse", "NetState sender, RelayInfo info" ); writer.EndMethod(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification( NotificationType.Info, "Gump generation complete" ); } }
/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="item">ItemID of item to generate.</param> /// <param name="hue">Hue of item to generate.</param> /// <param name="amount">Stackable amount of item to generate.</param> /// <param name="properties">Item properties packet.</param> public static void Generate( Stream stream, int itemID, int hue = 0, int amount = 0, QueryPropertiesResponsePacket properties = null ) { UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions; if ( itemDefinitions == null ) { App.Window.ShowNotification( NotificationType.Error, "Item definitions not initialized" ); return; } UltimaItemProperties itemProperties = Globals.Instance.ItemProperties; if ( itemProperties == null ) { App.Window.ShowNotification( NotificationType.Error, "Item properties not initialized" ); return; } UltimaStringCollection clilocs = Globals.Instance.Clilocs; using ( UltimaClassWriter writer = new UltimaClassWriter( stream ) ) { writer.WriteUsing( "System" ); writer.WriteUsing( "Server" ); writer.WriteUsing( "Server.Items" ); writer.WriteLine(); writer.BeginNamespace( "Server.Items" ); // Get item definition UltimaItemDefinition itemDefinition = null; if ( itemDefinitions.Items.ContainsKey( itemID ) ) itemDefinition = itemDefinitions.Items[ itemID ]; string className = "GenericClass"; string baseClass = null; int nameCliloc = 0; string nameClilocText = null; string nameText = null; bool stackable = false; if ( itemDefinition != null ) baseClass = itemDefinition.Class; // Get class name if ( properties != null && properties.Properties.Count > 0 ) { // Get name from name property QueryPropertiesProperty nameProperty = properties.Properties[ 0 ]; if ( nameProperty.Cliloc == StackableCliloc ) { // Get name from stackable cliloc UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser( nameProperty.Arguments ); nameCliloc = nameArguments.GetCliloc( 0 ); if ( nameCliloc > 0 ) { if ( clilocs != null ) { nameClilocText = clilocs.GetString( nameCliloc ); if ( !String.IsNullOrEmpty( nameClilocText ) ) className = UltimaClassWriter.BuildClassName( nameClilocText ); } } else { nameText = nameArguments[ 0 ]; if ( !String.IsNullOrEmpty( nameText ) ) className = UltimaClassWriter.BuildClassName( nameText ); } stackable = true; } else { // Get name from name cliloc nameCliloc = nameProperty.Cliloc; if ( !IsString( nameCliloc ) ) { if ( clilocs != null ) { nameClilocText = clilocs.GetString( nameCliloc ); if ( !String.IsNullOrEmpty( nameClilocText ) ) className = UltimaClassWriter.BuildClassName( nameClilocText ); } } else { nameText = nameProperty.Arguments; if ( !String.IsNullOrEmpty( nameText ) ) className = UltimaClassWriter.BuildClassName( nameText ); } } } else if ( clilocs != null ) { // Get name from itemID cliloc int itemIDCliloc = 0; if ( itemID < 0x4000 ) itemIDCliloc = OldItemCliloc + itemID; else itemIDCliloc = NewItemCliloc + itemID; string clilocText = clilocs.GetString( itemIDCliloc ); if ( !String.IsNullOrEmpty( clilocText ) ) className = UltimaClassWriter.BuildClassName( clilocText ); } // Check if container bool isContainer = false; if ( baseClass == null && properties != null && properties.Properties.Count > 0 ) { for ( int i = 1; i < properties.Properties.Count; i++ ) { QueryPropertiesProperty property = properties.Properties[ i ]; if ( IsContainer( property.Cliloc ) ) { baseClass = "BaseContainer"; isContainer = true; break; } } } if ( baseClass == null ) baseClass = "Item"; writer.BeginClass( className, baseClass ); // Name cliloc bool anyOverrides = false; if ( nameCliloc > 0 && IsSpecial( itemID, nameCliloc ) ) { if ( !String.IsNullOrEmpty( nameClilocText ) ) writer.OverrideProperty( "public", "int", "LabelNumber", nameCliloc.ToString(), nameClilocText ); else writer.OverrideProperty( "public", "int", "LabelNumber", nameCliloc.ToString() ); anyOverrides = true; } // Properties if ( properties != null && properties.Properties.Count > 0 ) { Dictionary<int, UltimaItemProperty> constructorPropertyDefinitions = new Dictionary<int, UltimaItemProperty>(); List<QueryPropertiesProperty> constructorProperties = new List<QueryPropertiesProperty>(); List<QueryPropertiesProperty> unknownProperties = new List<QueryPropertiesProperty>(); List<QueryPropertiesProperty> damageProperties = new List<QueryPropertiesProperty>(); for ( int i = 1; i < properties.Properties.Count; i++ ) { QueryPropertiesProperty property = properties.Properties[ i ]; if ( IsDamage( property.Cliloc ) ) { damageProperties.Add( property ); continue; } UltimaItemProperty propertyDefinition = null; if ( itemDefinition != null ) { Dictionary<int, UltimaItemProperty> groupProperties = null; UltimaItemDefinitionGroup group = itemDefinition.Parent; while ( group.Parent != null ) group = group.Parent; if ( itemProperties.GroupProperties.TryGetValue( group.Name, out groupProperties ) ) { if ( !groupProperties.TryGetValue( property.Cliloc, out propertyDefinition ) ) itemProperties.Properties.TryGetValue( property.Cliloc, out propertyDefinition ); } else itemProperties.Properties.TryGetValue( property.Cliloc, out propertyDefinition ); } else itemProperties.Properties.TryGetValue( property.Cliloc, out propertyDefinition ); if ( propertyDefinition != null ) { UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser( property.Arguments ); bool isConstructor = false; string propertyValue = null; if ( propertyDefinition.Switch != null ) propertyDefinition.Switch.TryGetValue( property.Cliloc, out propertyValue ); foreach ( UltimaItemPropertySetter setter in propertyDefinition.Setters ) { if ( !isConstructor && !setter.Overrides ) { constructorProperties.Add( property ); constructorPropertyDefinitions.Add( property.Cliloc, propertyDefinition ); isConstructor = true; } if ( setter.Overrides ) { string argument = arguments[ setter.Index ]; string value = propertyValue; if ( propertyValue == null ) value = GetPropertyValue( property.Cliloc, argument, setter ); writer.OverrideProperty( "public", setter.ReturnType, setter.Name, value ); anyOverrides = true; } } } else unknownProperties.Add( property ); } if ( anyOverrides ) writer.WriteLine(); writer.WriteLineWithIndent( "[Constructable]" ); if ( isContainer ) writer.BeginConstructor( "public", className, null, String.Format( "0x{0:X}", itemID ) ); else writer.BeginConstructor( "public", className, null, "" ); // Name if ( nameText != null ) writer.WriteLineWithIndent( "Name = \"{0}\";", nameText ); // ItemID if ( !isContainer && itemDefinition == null ) writer.WriteLineWithIndent( "ItemID = 0x{0:X};", itemID ); // Hue if ( hue > 0 ) writer.WriteLineWithIndent( "Hue = 0x{0:X};", hue ); // Stackable if ( stackable ) writer.WriteLineWithIndent( "Stackable = true;" ); if ( amount > 1 ) writer.WriteLineWithIndent( "Amount = {0};", amount ); // Constructor variables foreach ( QueryPropertiesProperty property in constructorProperties ) { UltimaItemProperty propertyDefinition = constructorPropertyDefinitions[ property.Cliloc ]; UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser( property.Arguments ); bool isSlayerSet = false; string propertyValue = null; if ( propertyDefinition.Switch != null ) propertyDefinition.Switch.TryGetValue( property.Cliloc, out propertyValue ); foreach ( UltimaItemPropertySetter setter in propertyDefinition.Setters ) { if ( !setter.Overrides ) { string argument = arguments[ setter.Index ]; string value = propertyValue; if ( value == null ) value = GetPropertyValue( property.Cliloc, argument, setter ); // Check if slayer 2 string setterName = setter.Name; if ( isSlayerSet ) setterName += "2"; if ( setter.IsSlayer ) isSlayerSet = true; // Write writer.WriteLineWithIndent( String.Format( "{0} = {1};", setterName, value ) ); } } } // Write unknowns if ( unknownProperties.Count > 0 ) { writer.WriteLine(); writer.WriteLineWithIndent( "// Unknown properties" ); foreach ( QueryPropertiesProperty property in unknownProperties ) { string clilocText = null; string format = "Found unknown property '{0}' with parameters '{1}'"; string notification = null; if ( clilocs != null ) clilocText = GetPropertyDescription( property.Cliloc ); if ( clilocText != null ) { writer.WriteLineWithIndent( String.Format( "//{0} = {1}; // Cliloc: {2}", property.Cliloc, property.Arguments, clilocText ) ); notification = String.Format( format, clilocText, property.Arguments ); } else { writer.WriteLineWithIndent( String.Format( "//{0} = {1};", property.Cliloc, property.Arguments ) ); notification = String.Format( format, property.Cliloc, property.Arguments ); } App.Window.ShowNotification( NotificationType.Warning, notification ); } } writer.EndConstructor(); // Write damage overwrite if ( damageProperties.Count > 0 ) { int physicalDamage = 0; int fireDamage = 0; int coldDamage = 0; int poisonDamage = 0; int energyDamage = 0; int chaosDamage = 0; int directDamage = 0; foreach ( QueryPropertiesProperty property in damageProperties ) { UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser( property.Arguments ); if ( arguments.Length > 0 ) { int integer = 0; if ( Int32.TryParse( arguments[ 0 ], out integer ) ) { if ( property.Cliloc == 1060403 ) physicalDamage = integer; else if ( property.Cliloc == 1060405 ) fireDamage = integer; else if ( property.Cliloc == 1060404 ) coldDamage = integer; else if ( property.Cliloc == 1060406 ) poisonDamage = integer; else if ( property.Cliloc == 1060407 ) energyDamage = integer; else if ( property.Cliloc == 1072846 ) chaosDamage = integer; else if ( property.Cliloc == 1079978 ) directDamage = integer; } } } if ( physicalDamage != 100 ) { writer.WriteLine(); writer.BeginOverrideMethod( "public", "void", "GetDamageTypes", "Mobile wielder, out int phys, out int fire, out int cold, out int pois, out int nrgy, out int chaos, out int direct" ); writer.WriteLineWithIndent( "phys = {0};", physicalDamage ); writer.WriteLineWithIndent( "fire = {0};", fireDamage ); writer.WriteLineWithIndent( "cold = {0};", coldDamage ); writer.WriteLineWithIndent( "pois = {0};", poisonDamage ); writer.WriteLineWithIndent( "nrgy = {0};", energyDamage ); writer.WriteLineWithIndent( "chaos = {0};", chaosDamage ); writer.WriteLineWithIndent( "direct = {0};", directDamage ); writer.EndMethod(); } } } else { writer.BeginConstructor( "public", className ); // Name if ( nameText != null ) writer.WriteLineWithIndent( "Name = \"{0}\";", nameText ); // ItemID writer.WriteLineWithIndent( "ItemID = 0x{0:X};", itemID ); // Hue if ( hue > 0 ) writer.WriteLineWithIndent( "Hue = 0x{0:X};", hue ); // Stackable if ( stackable ) writer.WriteLineWithIndent( "Stackable = true;" ); if ( amount > 1 ) writer.WriteLineWithIndent( "Amount = {0};", amount ); writer.EndConstructor(); } writer.WriteLine(); writer.WriteSerialConstructor( className ); writer.WriteLine(); writer.WriteSerialize(); writer.WriteLine(); writer.WriteDeserialize(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification( NotificationType.Info, "Item generation complete" ); } }
/// <summary> /// Generates class and saves it to stream. /// </summary> /// <param name="stream">Stream to write to.</param> /// <param name="item">ItemID of item to generate.</param> /// <param name="hue">Hue of item to generate.</param> /// <param name="amount">Stackable amount of item to generate.</param> /// <param name="properties">Item properties packet.</param> public static void Generate(Stream stream, MobileIncommingPacket mobile, MobileNamePacket name = null) { using (UltimaClassWriter writer = new UltimaClassWriter(stream)) { writer.WriteUsing("System"); writer.WriteUsing("Server"); writer.WriteUsing("Server.Items"); writer.WriteUsing("Server.Mobiles"); writer.WriteLine(); writer.BeginNamespace("Server.Mobiles"); string className = "GenericMobile"; string baseClass = "BaseCreature"; string baseClassParameters = String.Format("AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4"); bool isVendor = false; if (name != null) { className = UltimaClassWriter.BuildClassName(name.MobileName); } if (mobile.HasYellowHealthBar) { // Most likely baseClass = "BaseVendor"; if (name != null) { baseClassParameters = String.Format("\"{0}\"", name.MobileName); } else { baseClassParameters = String.Format("\"{0}\"", className); } isVendor = true; } if (name != null) { writer.WriteLineWithIndent("[CorpseName( \"{0}\" corpse )]", name.MobileName.ToLower()); } else { writer.WriteLineWithIndent("[CorpseName( \"{0}\" corpse )]", className); } writer.BeginClass(className, baseClass); writer.WriteLineWithIndent("[Constructable]"); writer.BeginConstructor("public", className, baseClassParameters); if (!isVendor) { if (name != null) { writer.WriteLineWithIndent("Name = \"{0}\";", name.MobileName); } else { writer.WriteLineWithIndent("Name = \"{0}\";", className); } writer.WriteLineWithIndent("Body = 0x{0:X};", mobile.Body); writer.WriteLineWithIndent("BaseSoundID = 0; // TODO"); if (mobile.IsFemale) { writer.WriteLineWithIndent("Female = true;"); } writer.WriteLine(); writer.WriteLineWithIndent("SetDamageType( ResistanceType.Physical, 25 ); // TODO "); writer.WriteLineWithIndent("SetDamageType( ResistanceType.Fire, 25 ); // TODO "); writer.WriteLineWithIndent("SetDamageType( ResistanceType.Cold, 25 ); // TODO "); writer.WriteLineWithIndent("SetDamageType( ResistanceType.Poison, 25 ); // TODO "); writer.WriteLineWithIndent("SetDamageType( ResistanceType.Energy, 25 ); // TODO "); writer.WriteLine(); writer.WriteLineWithIndent("SetResistance( ResistanceType.Physical, 25 ); // TODO "); writer.WriteLineWithIndent("SetResistance( ResistanceType.Fire, 25 ); // TODO "); writer.WriteLineWithIndent("SetResistance( ResistanceType.Cold, 25 ); // TODO "); writer.WriteLineWithIndent("SetResistance( ResistanceType.Poison, 25 ); // TODO "); writer.WriteLineWithIndent("SetResistance( ResistanceType.Energy, 25 ); // TODO "); writer.WriteLine(); writer.WriteLineWithIndent("SetSkill( SkillName.MagicResist, 25 ); // TODO "); writer.WriteLineWithIndent("SetSkill( SkillName.Tactics, 25 ); // TODO "); writer.WriteLineWithIndent("SetSkill( SkillName.Wrestling, 25 ); // TODO "); writer.WriteLine(); writer.WriteLineWithIndent("Fame = 0; // TODO"); writer.WriteLineWithIndent("Karma = 0; // TODO"); writer.WriteLineWithIndent("VirtualArmor = 0; // TODO"); } else { if (mobile.IsFemale) { writer.WriteLineWithIndent("Female = true;"); } } writer.WriteLine(); // Items UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions; if (itemDefinitions != null) { bool hasItemDeclaration = false; foreach (MobileItem item in mobile.Items) { if (itemDefinitions.Items.ContainsKey(item.ItemID)) { UltimaItemDefinition itemDefinition = itemDefinitions.Items[item.ItemID]; if (!hasItemDeclaration) { writer.WriteLineWithIndent("Item item = null;"); writer.WriteLine(); hasItemDeclaration = true; } writer.WriteLineWithIndent("item = new {0}();", itemDefinition.Class); if (item.Hue > 0) { writer.WriteLineWithIndent("item.Hue = 0x{0:X};", item.Hue); } writer.WriteLineWithIndent("AddItem( item );"); writer.WriteLine(); } else { App.Window.ShowNotification(NotificationType.Warning, String.Format("Cannot find definition for item ID '0x{0:X}'. Skipping", item.ItemID)); } } } else { App.Window.ShowNotification(NotificationType.Warning, "Item definitions not initialized. Skipping mobile items"); } writer.EndConstructor(); writer.WriteSerialConstructor(className); writer.WriteLine(); writer.BeginOverrideMethod("public", "void", "GenerateLoot"); writer.WriteLineWithIndent("AddLoot( LootPack.Average );"); writer.EndMethod(); writer.WriteSerialize(); writer.WriteLine(); writer.WriteDeserialize(); writer.EndClass(); writer.EndClass(); writer.EndNamespace(); App.Window.ShowNotification(NotificationType.Info, "Mobile generation complete"); } }