예제 #1
0
        /// <summary>
        /// Gets mobile name from name property.
        /// </summary>
        /// <param name="nameProperty">Name property.</param>
        /// <returns>Mobile name.</returns>
        public static string GetMobileName(QueryPropertiesProperty nameProperty)
        {
            // Get item cliloc
            int    cliloc = 0;
            string name   = null;

            if (UltimaItemGenerator.IsStackable(nameProperty.Cliloc))
            {
                // Get name from stackable cliloc
                UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser(nameProperty.Arguments);
                int nameCliloc = nameArguments.GetCliloc(0);

                if (nameCliloc > 0)
                {
                    cliloc = nameCliloc;
                }
                else
                {
                    name = nameArguments[0];
                }
            }
            else
            {
                // Get name from name cliloc
                if (nameProperty.Cliloc == 1050045)
                {
                    UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser(nameProperty.Arguments);

                    if (arguments.Length > 2)
                    {
                        name = arguments[1];
                    }
                }
                else
                {
                    cliloc = nameProperty.Cliloc;
                }
            }

            UltimaStringCollection clilocs = Globals.Instance.Clilocs;

            if (name == null)
            {
                if (clilocs != null)
                {
                    name = clilocs.GetString(cliloc);
                }

                if (String.IsNullOrEmpty(name))
                {
                    name = cliloc.ToString();
                }
            }

            return(name);
        }
예제 #2
0
        private int _MaxPropertyValue;         // Max global property value
        #endregion

        #region Methods
        /// <summary>
        /// Constructs a new instance of UltimaLootAnalyzer.
        /// </summary>
        /// <param name="names">List of the mobile names to analyze.</param>
        public UltimaLootAnalyzer(ObservableCollection <UltimaPacket> packets, List <string> names)
        {
            _Names              = names;
            _CorpseCount        = 0;
            _HueCounter         = new UltimaEnumPropertyCounter();
            _GoldCounter        = new UltimaSimpleCounter();
            _InstrumentCounters = new List <UltimaSimpleCounter>();
            _EquipmentCounters  = new List <UltimaSimpleCounter>();

            UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions;

            if (itemDefinitions == null)
            {
                throw new Exception("Item definitions not initialized");
            }

            UltimaItemProperties propertyDefinitions = Globals.Instance.ItemProperties;

            if (propertyDefinitions == null)
            {
                throw new Exception("Item property definitions not initialized");
            }

            // Initialize group
            UltimaItemDefinitionGroup goldGroup        = null;
            UltimaItemDefinitionGroup instrumentsGroup = null;

            _Groups            = new Dictionary <UltimaItemDefinitionGroup, UltimaSimpleCounter>();
            _DefaultGroup      = new UltimaDefaultLootGroup();
            _PropertiesPerItem = new List <UltimaSimpleCounter>();
            _Properties        = new Dictionary <int, UltimaPropertyCounter>();

            foreach (UltimaItemDefinitionGroup group in itemDefinitions.Groups)
            {
                if (group.Analyze)
                {
                    _Groups.Add(group, new UltimaSimpleCounter());
                }

                if (String.Equals(group.Name, "Gold", StringComparison.InvariantCultureIgnoreCase))
                {
                    goldGroup = group;
                }
                else if (String.Equals(group.Name, "Instruments", StringComparison.InvariantCultureIgnoreCase))
                {
                    instrumentsGroup = group;
                }
            }

            // Analyze packets
            Dictionary <uint, MobileIncommingPacket> mobiles = new Dictionary <uint, MobileIncommingPacket>();
            Dictionary <uint, uint> mobilesToCorpses         = new Dictionary <uint, uint>();
            Dictionary <uint, ContainerContentPacket>        corpsesToContainers = new Dictionary <uint, ContainerContentPacket>();
            Dictionary <uint, QueryPropertiesResponsePacket> itemsToProperties   = new Dictionary <uint, QueryPropertiesResponsePacket>();

            foreach (UltimaPacket packet in packets)
            {
                if (packet is MobileIncommingPacket)
                {
                    MobileIncommingPacket mobile = (MobileIncommingPacket)packet;

                    if (!mobiles.ContainsKey(mobile.Serial))
                    {
                        mobiles.Add(mobile.Serial, mobile);
                    }
                }
                else if (packet is DeathAnimationPacket)
                {
                    DeathAnimationPacket deathAnimation = (DeathAnimationPacket)packet;

                    if (!mobilesToCorpses.ContainsKey(deathAnimation.Serial))
                    {
                        mobilesToCorpses.Add(deathAnimation.Serial, deathAnimation.Corpse);
                    }
                }
                else if (packet is ContainerContentPacket)
                {
                    ContainerContentPacket containerContent = (ContainerContentPacket)packet;

                    if (!corpsesToContainers.ContainsKey(containerContent.Serial))
                    {
                        corpsesToContainers.Add(containerContent.Serial, containerContent);
                    }
                }
                else if (packet is QueryPropertiesResponsePacket)
                {
                    QueryPropertiesResponsePacket properties = (QueryPropertiesResponsePacket)packet;

                    if (!itemsToProperties.ContainsKey(properties.Serial))
                    {
                        itemsToProperties.Add(properties.Serial, properties);
                    }
                }
            }

            Dictionary <ContainerContentPacket, List <ItemStatistics> > validCorpses = new Dictionary <ContainerContentPacket, List <ItemStatistics> >();

            _MinPropertyCount = int.MaxValue;
            _MaxPropertyCount = int.MinValue;
            _MinPropertyValue = int.MaxValue;
            _MaxPropertyValue = int.MinValue;

            foreach (KeyValuePair <uint, uint> kvp in mobilesToCorpses)
            {
                MobileIncommingPacket         mobile           = null;
                ContainerContentPacket        corpseContainer  = null;
                ContainerContentPacket        container        = null;
                QueryPropertiesResponsePacket mobileProperties = null;

                if (!mobiles.TryGetValue(kvp.Key, out mobile))
                {
                    continue;
                }

                if (!itemsToProperties.TryGetValue(kvp.Key, out mobileProperties) || mobileProperties.Properties.Count == 0)
                {
                    continue;
                }

                if (!corpsesToContainers.TryGetValue(kvp.Value, out corpseContainer))
                {
                    continue;
                }

                if (corpseContainer.Items.Count > 0)
                {
                    ContainerItem corpse = corpseContainer.Items[0];

                    if (!corpsesToContainers.TryGetValue(corpse.Serial, out container))
                    {
                        continue;
                    }
                }
                else
                {
                    continue;
                }

                string mobileName = GetMobileName(mobileProperties.Properties[0]);

                if (names.Contains(mobileName))
                {
                    // Analyze corpse
                    StartAnalyzingCorpse();

                    List <ItemStatistics> validItems = new List <ItemStatistics>();
                    int  equipmentCount  = 0;
                    int  instrumentCount = 0;
                    bool foundGold       = false;

                    _HueCounter.Gotcha(mobile.Hue);
                    _CorpseCount += 1;

                    Trace.WriteLine("");
                    Trace.WriteLine("Found corpse with " + container.Items.Count);

                    foreach (ContainerItem item in container.Items)
                    {
                        QueryPropertiesResponsePacket properties      = null;
                        UltimaItemDefinition          itemDefinition  = null;
                        UltimaArmorDefinition         armorDefinition = null;
                        bool analyzed = false;

                        if (itemDefinitions.Items.ContainsKey(item.ItemID))
                        {
                            itemDefinition  = itemDefinitions.Items[item.ItemID];
                            armorDefinition = itemDefinition as UltimaArmorDefinition;
                        }

                        if (itemsToProperties.ContainsKey(item.Serial))
                        {
                            properties = itemsToProperties[item.Serial];
                        }

                        string name = GetItemName(properties.Properties[0]);

                        // EA always generates gold last
                        if (!foundGold)
                        {
                            if (itemDefinition != null)
                            {
                                UltimaItemDefinitionGroup group = itemDefinition.Parent;

                                while (group.Parent != null)
                                {
                                    group = group.Parent;
                                }

                                if (properties != null)
                                {
                                    QueryPropertiesProperty nameProperty = properties.Properties[0];

                                    // Treat stackable items as special
                                    if (!UltimaItemGenerator.IsStackable(nameProperty.Cliloc) &&
                                        !UltimaItemGenerator.IsString(nameProperty.Cliloc) &&
                                        !UltimaItemGenerator.IsSpecial(item.ItemID, nameProperty.Cliloc))
                                    {
                                        if (_Groups.ContainsKey(group))
                                        {
                                            _Groups[group].Gotcha();
                                            analyzed = true;

                                            int  propertiesPerItem = 0;
                                            int  minPropertyValue  = int.MaxValue;
                                            int  maxPropertyValue  = int.MinValue;
                                            bool isValidMinMax     = false;
                                            bool hasSpecialDamage  = false;

                                            foreach (QueryPropertiesProperty property in properties.Properties)
                                            {
                                                string propertyName = Globals.Instance.Clilocs.GetString(property.Cliloc);

                                                if (UltimaItemGenerator.IsDamage(property.Cliloc))
                                                {
                                                    if (property.Cliloc != 1060403)
                                                    {
                                                        if (!hasSpecialDamage)
                                                        {
                                                            propertiesPerItem += 1;
                                                        }

                                                        hasSpecialDamage = true;
                                                    }
                                                }
                                                else if (propertyDefinitions.Properties.ContainsKey(property.Cliloc))
                                                {
                                                    UltimaItemProperty propertyDefinition = propertyDefinitions.Properties[property.Cliloc];

                                                    if (propertyDefinition.IsRunic)
                                                    {
                                                        UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser(property.Arguments);
                                                        bool ignore = false;

                                                        if (arguments.Length > 0)
                                                        {
                                                            int integer = 0;

                                                            if (arguments.TryGetInteger(0, out integer))
                                                            {
                                                                if (armorDefinition != null)
                                                                {
                                                                    ignore = CheckIgnoreProperty(armorDefinition, propertyDefinition, ref integer);
                                                                }

                                                                if (!ignore)
                                                                {
                                                                    GetPropertyCounter(property.Cliloc, 1).Gotcha(integer);

                                                                    if (propertyDefinition.Max > propertyDefinition.Min)
                                                                    {
                                                                        int percentage = (integer - propertyDefinition.Min) * 100 / (propertyDefinition.Max - propertyDefinition.Min);

                                                                        if (percentage > maxPropertyValue)
                                                                        {
                                                                            maxPropertyValue = percentage;
                                                                        }

                                                                        if (percentage > _MaxPropertyValue)
                                                                        {
                                                                            _MaxPropertyValue = percentage;
                                                                        }

                                                                        if (percentage < minPropertyValue)
                                                                        {
                                                                            minPropertyValue = percentage;
                                                                        }

                                                                        if (percentage < _MinPropertyValue)
                                                                        {
                                                                            _MinPropertyValue = percentage;
                                                                        }

                                                                        isValidMinMax = true;
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                GetPropertyCounter(property.Cliloc, 2).Gotcha(arguments[0]);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            GetPropertyCounter(property.Cliloc).Gotcha(null);
                                                        }

                                                        if (!ignore)
                                                        {
                                                            propertiesPerItem++;
                                                        }
                                                    }
                                                }
                                            }

                                            // Count number of properties
                                            UltimaSimpleCounter counter = null;

                                            while (propertiesPerItem >= _PropertiesPerItem.Count)
                                            {
                                                _PropertiesPerItem.Add(counter = new UltimaSimpleCounter());
                                            }

                                            counter = _PropertiesPerItem[propertiesPerItem];
                                            counter.StartAnalyzing();
                                            counter.Gotcha();
                                            counter.EndAnalyzing();

                                            if (propertiesPerItem < _MinPropertyCount)
                                            {
                                                _MinPropertyCount = propertiesPerItem;
                                            }

                                            if (propertiesPerItem > _MaxPropertyCount)
                                            {
                                                _MaxPropertyCount = propertiesPerItem;
                                            }

                                            equipmentCount += 1;

                                            if (isValidMinMax)
                                            {
                                                validItems.Add(new ItemStatistics(item, propertiesPerItem, minPropertyValue, maxPropertyValue));
                                            }
                                            else
                                            {
                                                validItems.Add(new ItemStatistics(item, propertiesPerItem));
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Trace.WriteLine("Cannot find item definition for:" + String.Format("0x{0:X}", item.ItemID) + "," + name);
                            }

                            // Check if special item
                            if (itemDefinition != null && !analyzed)
                            {
                                UltimaItemDefinitionGroup group = itemDefinition.Parent;

                                if (group == goldGroup)
                                {
                                    _GoldCounter.Gotcha(item.Amount);
                                    analyzed  = true;
                                    foundGold = true;
                                }
                                else if (group == instrumentsGroup)
                                {
                                    analyzed = true;
                                }
                            }
                        }

                        if (!analyzed)
                        {
                            _DefaultGroup.AnalyzeItem(item.Serial, item.ItemID, item.Hue, item.Amount, properties);
                        }
                    }

                    Trace.WriteLine(equipmentCount);

                    // Count equipment
                    UltimaSimpleCounter equipmentCounter = null;

                    while (equipmentCount >= _EquipmentCounters.Count)
                    {
                        _EquipmentCounters.Add(equipmentCounter = new UltimaSimpleCounter());
                    }

                    equipmentCounter = _EquipmentCounters[equipmentCount];
                    equipmentCounter.StartAnalyzing();
                    equipmentCounter.Gotcha();
                    equipmentCounter.EndAnalyzing();

                    // Count instruments
                    UltimaSimpleCounter instrumentCounter = null;

                    while (instrumentCount >= _InstrumentCounters.Count)
                    {
                        _InstrumentCounters.Add(instrumentCounter = new UltimaSimpleCounter());
                    }

                    instrumentCounter = _InstrumentCounters[instrumentCount];
                    instrumentCounter.StartAnalyzing();
                    instrumentCounter.Gotcha();
                    instrumentCounter.EndAnalyzing();

                    if (validItems.Count > 0)
                    {
                        validCorpses.Add(container, validItems);
                    }

                    // Count corpses
                    EndAnalyzingCorpse();
                }
            }

            // Analyze items with max properties to determine property probabilities
            _MinPropertyCounts = new List <int>();
            _MaxPropertyCounts = new List <int>();
            _MinPropertyValues = new List <int>();
            _MaxPropertyValues = new List <int>();
            _ValidCorpseCount  = 0;

            foreach (KeyValuePair <ContainerContentPacket, List <ItemStatistics> > kvp in validCorpses)
            {
                // Only ones with max items are valid
                if (kvp.Value.Count == _EquipmentCounters.Count - 1)
                {
                    bool isValidMinMax = true;

                    foreach (ItemStatistics item in kvp.Value)
                    {
                        if (!item.IsValidMinMax)
                        {
                            isValidMinMax = false;
                            break;
                        }
                    }

                    kvp.Value.Sort(SortByCount);

                    if (_MinPropertyCounts.Count == 0)
                    {
                        foreach (ItemStatistics item in kvp.Value)
                        {
                            _MinPropertyCounts.Add(item.PropertyCount);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < kvp.Value.Count; i++)
                        {
                            int count = kvp.Value[i].PropertyCount;

                            if (count < _MinPropertyCounts[i])
                            {
                                _MinPropertyCounts[i] = count;
                            }
                        }
                    }

                    if (_MaxPropertyCounts.Count == 0)
                    {
                        foreach (ItemStatistics item in kvp.Value)
                        {
                            _MaxPropertyCounts.Add(item.PropertyCount);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < kvp.Value.Count; i++)
                        {
                            int count = kvp.Value[i].PropertyCount;

                            if (count > _MaxPropertyCounts[i])
                            {
                                _MaxPropertyCounts[i] = count;
                            }
                        }
                    }

                    if (isValidMinMax)
                    {
                        kvp.Value.Sort(SortByMin);

                        if (_MinPropertyValues.Count == 0)
                        {
                            foreach (ItemStatistics item in kvp.Value)
                            {
                                _MinPropertyValues.Add(item.MinPropertyValue);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < kvp.Value.Count; i++)
                            {
                                int min = kvp.Value[i].MinPropertyValue;

                                if (min < _MinPropertyValues[i])
                                {
                                    _MinPropertyValues[i] = min;
                                }
                            }
                        }

                        kvp.Value.Sort(SortByMax);

                        if (_MaxPropertyValues.Count == 0)
                        {
                            foreach (ItemStatistics item in kvp.Value)
                            {
                                _MaxPropertyValues.Add(item.MaxPropertyValue);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < kvp.Value.Count; i++)
                            {
                                int max = kvp.Value[i].MaxPropertyValue;

                                if (max > _MaxPropertyValues[i])
                                {
                                    _MaxPropertyValues[i] = max;
                                }
                            }
                        }
                    }

                    _ValidCorpseCount += 1;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Gets mobile name from name property.
        /// </summary>
        /// <param name="nameProperty">Name property.</param>
        /// <returns>Mobile name.</returns>
        public static string GetMobileName( QueryPropertiesProperty nameProperty )
        {
            // Get item cliloc
            int cliloc = 0;
            string name = null;

            if ( UltimaItemGenerator.IsStackable( nameProperty.Cliloc ) )
            {
                // Get name from stackable cliloc
                UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser( nameProperty.Arguments );
                int nameCliloc = nameArguments.GetCliloc( 0 );

                if ( nameCliloc > 0 )
                    cliloc = nameCliloc;
                else
                    name = nameArguments[ 0 ];
            }
            else
            {
                // Get name from name cliloc
                if ( nameProperty.Cliloc == 1050045 )
                {
                    UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser( nameProperty.Arguments );

                    if ( arguments.Length > 2 )
                        name = arguments[ 1 ];
                }
                else
                    cliloc = nameProperty.Cliloc;
            }

            UltimaStringCollection clilocs = Globals.Instance.Clilocs;

            if ( name == null )
            {
                if ( clilocs != null )
                    name = clilocs.GetString( cliloc );

                if ( String.IsNullOrEmpty( name ) )
                    name = cliloc.ToString();
            }

            return name;
        }
예제 #4
0
        private int _ValidCorpseCount; // Number of corpses with max equipment count

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Constructs a new instance of UltimaLootAnalyzer.
        /// </summary>
        /// <param name="names">List of the mobile names to analyze.</param>
        public UltimaLootAnalyzer( ObservableCollection<UltimaPacket> packets, List<string> names )
        {
            _Names = names;
            _CorpseCount = 0;
            _HueCounter = new UltimaEnumPropertyCounter();
            _GoldCounter = new UltimaSimpleCounter();
            _InstrumentCounters = new List<UltimaSimpleCounter>();
            _EquipmentCounters = new List<UltimaSimpleCounter>();

            UltimaItemDefinitions itemDefinitions = Globals.Instance.ItemDefinitions;

            if ( itemDefinitions == null )
                throw new Exception( "Item definitions not initialized" );

            UltimaItemProperties propertyDefinitions = Globals.Instance.ItemProperties;

            if ( propertyDefinitions == null )
                throw new Exception( "Item property definitions not initialized" );

            // Initialize group
            UltimaItemDefinitionGroup goldGroup = null;
            UltimaItemDefinitionGroup instrumentsGroup = null;

            _Groups = new Dictionary<UltimaItemDefinitionGroup, UltimaSimpleCounter>();
            _DefaultGroup = new UltimaDefaultLootGroup();
            _PropertiesPerItem = new List<UltimaSimpleCounter>();
            _Properties = new Dictionary<int, UltimaPropertyCounter>();

            foreach ( UltimaItemDefinitionGroup group in itemDefinitions.Groups )
            {
                if ( group.Analyze )
                    _Groups.Add( group, new UltimaSimpleCounter() );

                if ( String.Equals( group.Name, "Gold", StringComparison.InvariantCultureIgnoreCase ) )
                    goldGroup = group;
                else if ( String.Equals( group.Name, "Instruments", StringComparison.InvariantCultureIgnoreCase ) )
                    instrumentsGroup = group;
            }

            // Analyze packets
            Dictionary<uint, MobileIncommingPacket> mobiles = new Dictionary<uint, MobileIncommingPacket>();
            Dictionary<uint, uint> mobilesToCorpses = new Dictionary<uint, uint>();
            Dictionary<uint, ContainerContentPacket> corpsesToContainers = new Dictionary<uint, ContainerContentPacket>();
            Dictionary<uint, QueryPropertiesResponsePacket> itemsToProperties = new Dictionary<uint, QueryPropertiesResponsePacket>();

            foreach ( UltimaPacket packet in packets )
            {
                if ( packet is MobileIncommingPacket )
                {
                    MobileIncommingPacket mobile = (MobileIncommingPacket) packet;

                    if ( !mobiles.ContainsKey( mobile.Serial ) )
                        mobiles.Add( mobile.Serial, mobile );
                }
                else if ( packet is DeathAnimationPacket )
                {
                    DeathAnimationPacket deathAnimation = (DeathAnimationPacket) packet;

                    if ( !mobilesToCorpses.ContainsKey( deathAnimation.Serial ) )
                        mobilesToCorpses.Add( deathAnimation.Serial, deathAnimation.Corpse );
                }
                else if ( packet is ContainerContentPacket )
                {
                    ContainerContentPacket containerContent = (ContainerContentPacket) packet;

                    if ( !corpsesToContainers.ContainsKey( containerContent.Serial ) )
                        corpsesToContainers.Add( containerContent.Serial, containerContent );
                }
                else if ( packet is QueryPropertiesResponsePacket )
                {
                    QueryPropertiesResponsePacket properties = (QueryPropertiesResponsePacket) packet;

                    if ( !itemsToProperties.ContainsKey( properties.Serial ) )
                        itemsToProperties.Add( properties.Serial, properties );
                }
            }

            Dictionary<ContainerContentPacket, List<ItemStatistics>> validCorpses = new Dictionary<ContainerContentPacket, List<ItemStatistics>>();
            _MinPropertyCount = int.MaxValue;
            _MaxPropertyCount = int.MinValue;
            _MinPropertyValue = int.MaxValue;
            _MaxPropertyValue = int.MinValue;

            foreach ( KeyValuePair<uint, uint> kvp in mobilesToCorpses )
            {
                MobileIncommingPacket mobile = null;
                ContainerContentPacket corpseContainer = null;
                ContainerContentPacket container = null;
                QueryPropertiesResponsePacket mobileProperties = null;

                if ( !mobiles.TryGetValue( kvp.Key, out mobile ) )
                    continue;

                if ( !itemsToProperties.TryGetValue( kvp.Key, out mobileProperties ) || mobileProperties.Properties.Count == 0 )
                    continue;

                if ( !corpsesToContainers.TryGetValue( kvp.Value, out corpseContainer ) )
                    continue;

                if ( corpseContainer.Items.Count > 0 )
                {
                    ContainerItem corpse = corpseContainer.Items[ 0 ];

                    if ( !corpsesToContainers.TryGetValue( corpse.Serial, out container ) )
                        continue;
                }
                else
                    continue;

                string mobileName = GetMobileName( mobileProperties.Properties[ 0 ] );

                if ( names.Contains( mobileName ) )
                {
                    // Analyze corpse
                    StartAnalyzingCorpse();

                    List<ItemStatistics> validItems = new List<ItemStatistics>();
                    int equipmentCount = 0;
                    int instrumentCount = 0;
                    bool foundGold = false;

                    _HueCounter.Gotcha( mobile.Hue );
                    _CorpseCount += 1;

                    Trace.WriteLine( "" );
                    Trace.WriteLine( "Found corpse with " + container.Items.Count );

                    foreach ( ContainerItem item in container.Items )
                    {
                        QueryPropertiesResponsePacket properties = null;
                        UltimaItemDefinition itemDefinition = null;
                        UltimaArmorDefinition armorDefinition = null;
                        bool analyzed = false;

                        if ( itemDefinitions.Items.ContainsKey( item.ItemID ) )
                        {
                            itemDefinition = itemDefinitions.Items[ item.ItemID ];
                            armorDefinition = itemDefinition as UltimaArmorDefinition;
                        }

                        if ( itemsToProperties.ContainsKey( item.Serial ) )
                            properties = itemsToProperties[ item.Serial ];

                        string name = GetItemName( properties.Properties[ 0 ] );

                        // EA always generates gold last
                        if ( !foundGold )
                        {
                            if ( itemDefinition != null )
                            {
                                UltimaItemDefinitionGroup group = itemDefinition.Parent;

                                while ( group.Parent != null )
                                    group = group.Parent;

                                if ( properties != null )
                                {
                                    QueryPropertiesProperty nameProperty = properties.Properties[ 0 ];

                                    // Treat stackable items as special
                                    if ( !UltimaItemGenerator.IsStackable( nameProperty.Cliloc ) &&
                                        !UltimaItemGenerator.IsString( nameProperty.Cliloc ) &&
                                        !UltimaItemGenerator.IsSpecial( item.ItemID, nameProperty.Cliloc ) )
                                    {
                                        if ( _Groups.ContainsKey( group ) )
                                        {
                                            _Groups[ group ].Gotcha();
                                            analyzed = true;

                                            int propertiesPerItem = 0;
                                            int minPropertyValue = int.MaxValue;
                                            int maxPropertyValue = int.MinValue;
                                            bool isValidMinMax = false;
                                            bool hasSpecialDamage = false;

                                            foreach ( QueryPropertiesProperty property in properties.Properties )
                                            {
                                                string propertyName = Globals.Instance.Clilocs.GetString( property.Cliloc );

                                                if ( UltimaItemGenerator.IsDamage( property.Cliloc ) )
                                                {
                                                    if ( property.Cliloc != 1060403 )
                                                    {
                                                        if ( !hasSpecialDamage )
                                                            propertiesPerItem += 1;

                                                        hasSpecialDamage = true;
                                                    }
                                                }
                                                else if ( propertyDefinitions.Properties.ContainsKey( property.Cliloc ) )
                                                {
                                                    UltimaItemProperty propertyDefinition = propertyDefinitions.Properties[ property.Cliloc ];

                                                    if ( propertyDefinition.IsRunic )
                                                    {
                                                        UltimaClilocArgumentParser arguments = new UltimaClilocArgumentParser( property.Arguments );
                                                        bool ignore = false;

                                                        if ( arguments.Length > 0 )
                                                        {
                                                            int integer = 0;

                                                            if ( arguments.TryGetInteger( 0, out integer ) )
                                                            {
                                                                if ( armorDefinition != null )
                                                                    ignore = CheckIgnoreProperty( armorDefinition, propertyDefinition, ref integer );

                                                                if ( !ignore )
                                                                {
                                                                    GetPropertyCounter( property.Cliloc, 1 ).Gotcha( integer );

                                                                    if ( propertyDefinition.Max > propertyDefinition.Min )
                                                                    {
                                                                        int percentage = ( integer - propertyDefinition.Min ) * 100 / ( propertyDefinition.Max - propertyDefinition.Min );

                                                                        if ( percentage > maxPropertyValue )
                                                                            maxPropertyValue = percentage;

                                                                        if ( percentage > _MaxPropertyValue )
                                                                            _MaxPropertyValue = percentage;

                                                                        if ( percentage < minPropertyValue )
                                                                            minPropertyValue = percentage;

                                                                        if ( percentage < _MinPropertyValue )
                                                                            _MinPropertyValue = percentage;

                                                                        isValidMinMax = true;
                                                                    }
                                                                }
                                                            }
                                                            else
                                                                GetPropertyCounter( property.Cliloc, 2 ).Gotcha( arguments[ 0 ] );
                                                        }
                                                        else
                                                            GetPropertyCounter( property.Cliloc ).Gotcha( null );

                                                        if ( !ignore )
                                                            propertiesPerItem++;
                                                    }
                                                }
                                            }

                                            // Count number of properties
                                            UltimaSimpleCounter counter = null;

                                            while ( propertiesPerItem >= _PropertiesPerItem.Count )
                                                _PropertiesPerItem.Add( counter = new UltimaSimpleCounter() );

                                            counter = _PropertiesPerItem[ propertiesPerItem ];
                                            counter.StartAnalyzing();
                                            counter.Gotcha();
                                            counter.EndAnalyzing();

                                            if ( propertiesPerItem < _MinPropertyCount )
                                                _MinPropertyCount = propertiesPerItem;

                                            if ( propertiesPerItem > _MaxPropertyCount )
                                                _MaxPropertyCount = propertiesPerItem;

                                            equipmentCount += 1;

                                            if ( isValidMinMax )
                                                validItems.Add( new ItemStatistics( item, propertiesPerItem, minPropertyValue, maxPropertyValue ) );
                                            else
                                                validItems.Add( new ItemStatistics( item, propertiesPerItem ) );
                                        }
                                    }
                                }
                            }
                            else
                                Trace.WriteLine( "Cannot find item definition for:" + String.Format( "0x{0:X}", item.ItemID ) + "," + name );

                            // Check if special item
                            if ( itemDefinition != null && !analyzed )
                            {
                                UltimaItemDefinitionGroup group = itemDefinition.Parent;

                                if ( group == goldGroup )
                                {
                                    _GoldCounter.Gotcha( item.Amount );
                                    analyzed = true;
                                    foundGold = true;
                                }
                                else if ( group == instrumentsGroup )
                                {
                                    analyzed = true;
                                }
                            }
                        }

                        if ( !analyzed )
                            _DefaultGroup.AnalyzeItem( item.Serial, item.ItemID, item.Hue, item.Amount, properties );
                    }

                    Trace.WriteLine( equipmentCount );

                    // Count equipment
                    UltimaSimpleCounter equipmentCounter = null;

                    while ( equipmentCount >= _EquipmentCounters.Count )
                        _EquipmentCounters.Add( equipmentCounter = new UltimaSimpleCounter() );

                    equipmentCounter = _EquipmentCounters[ equipmentCount ];
                    equipmentCounter.StartAnalyzing();
                    equipmentCounter.Gotcha();
                    equipmentCounter.EndAnalyzing();

                    // Count instruments
                    UltimaSimpleCounter instrumentCounter = null;

                    while ( instrumentCount >= _InstrumentCounters.Count )
                        _InstrumentCounters.Add( instrumentCounter = new UltimaSimpleCounter() );

                    instrumentCounter = _InstrumentCounters[ instrumentCount ];
                    instrumentCounter.StartAnalyzing();
                    instrumentCounter.Gotcha();
                    instrumentCounter.EndAnalyzing();

                    if ( validItems.Count > 0 )
                        validCorpses.Add( container, validItems );

                    // Count corpses
                    EndAnalyzingCorpse();
                }
            }

            // Analyze items with max properties to determine property probabilities
            _MinPropertyCounts = new List<int>();
            _MaxPropertyCounts = new List<int>();
            _MinPropertyValues = new List<int>();
            _MaxPropertyValues = new List<int>();
            _ValidCorpseCount = 0;

            foreach ( KeyValuePair<ContainerContentPacket, List<ItemStatistics>> kvp in validCorpses )
            {
                // Only ones with max items are valid
                if ( kvp.Value.Count == _EquipmentCounters.Count - 1 )
                {
                    bool isValidMinMax = true;

                    foreach ( ItemStatistics item in kvp.Value )
                    {
                        if ( !item.IsValidMinMax )
                        {
                            isValidMinMax = false;
                            break;
                        }
                    }

                    kvp.Value.Sort( SortByCount );

                    if ( _MinPropertyCounts.Count == 0 )
                    {
                        foreach ( ItemStatistics item in kvp.Value )
                            _MinPropertyCounts.Add( item.PropertyCount );
                    }
                    else
                    {
                        for ( int i = 0; i < kvp.Value.Count; i++ )
                        {
                            int count = kvp.Value[ i ].PropertyCount;

                            if ( count < _MinPropertyCounts[ i ] )
                                _MinPropertyCounts[ i ] = count;
                        }
                    }

                    if ( _MaxPropertyCounts.Count == 0 )
                    {
                        foreach ( ItemStatistics item in kvp.Value )
                            _MaxPropertyCounts.Add( item.PropertyCount );
                    }
                    else
                    {
                        for ( int i = 0; i < kvp.Value.Count; i++ )
                        {
                            int count = kvp.Value[ i ].PropertyCount;

                            if ( count > _MaxPropertyCounts[ i ] )
                                _MaxPropertyCounts[ i ] = count;
                        }
                    }

                    if ( isValidMinMax )
                    {
                        kvp.Value.Sort( SortByMin );

                        if ( _MinPropertyValues.Count == 0 )
                        {
                            foreach ( ItemStatistics item in kvp.Value )
                                _MinPropertyValues.Add( item.MinPropertyValue );
                        }
                        else
                        {
                            for ( int i = 0; i < kvp.Value.Count; i++ )
                            {
                                int min = kvp.Value[ i ].MinPropertyValue;

                                if ( min < _MinPropertyValues[ i ] )
                                    _MinPropertyValues[ i ] = min;
                            }
                        }

                        kvp.Value.Sort( SortByMax );

                        if ( _MaxPropertyValues.Count == 0 )
                        {
                            foreach ( ItemStatistics item in kvp.Value )
                                _MaxPropertyValues.Add( item.MaxPropertyValue );
                        }
                        else
                        {
                            for ( int i = 0; i < kvp.Value.Count; i++ )
                            {
                                int max = kvp.Value[ i ].MaxPropertyValue;

                                if ( max > _MaxPropertyValues[ i ] )
                                    _MaxPropertyValues[ i ] = max;
                            }
                        }
                    }

                    _ValidCorpseCount += 1;
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Analyzes item.
        /// </summary>
        /// <param name="serial">Item serial.</param>
        /// <param name="itemID">Item ID.</param>
        /// <param name="hue">Item hue.</param>
        /// <param name="amount">Item amount.</param>
        /// <param name="properties">Item properties.</param>
        public void AnalyzeItem(uint serial, int itemID, int hue, int amount, QueryPropertiesResponsePacket properties)
        {
            // Get item cliloc
            int    cliloc = 0;
            string name   = null;

            if (properties != null && properties.Properties.Count > 0)
            {
                // Get name from name property
                QueryPropertiesProperty nameProperty = properties.Properties[0];

                if (UltimaItemGenerator.IsStackable(nameProperty.Cliloc))
                {
                    // Get name from stackable cliloc
                    UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser(nameProperty.Arguments);
                    int nameCliloc = nameArguments.GetCliloc(1);

                    if (nameCliloc > 0)
                    {
                        cliloc = nameCliloc;
                    }
                    else
                    {
                        name = nameArguments[1];
                    }
                }
                else
                {
                    // Get name from name cliloc
                    if (!UltimaItemGenerator.IsString(nameProperty.Cliloc))
                    {
                        cliloc = nameProperty.Cliloc;
                    }
                    else
                    {
                        name = nameProperty.Arguments;
                    }
                }
            }
            else
            {
                // Get name from item ID
                cliloc = UltimaItemGenerator.GetClilocFromItemID(itemID);
            }

            // Count
            UltimaItemCounter      counter = null;
            UltimaStringCollection clilocs = Globals.Instance.Clilocs;

            if (name == null)
            {
                if (clilocs != null)
                {
                    name = clilocs.GetString(cliloc);
                }

                if (String.IsNullOrEmpty(name))
                {
                    name = cliloc.ToString();
                }
            }

            if (!_Items.TryGetValue(name, out counter))
            {
                counter = new UltimaItemCounter(serial, name);
                _Items.Add(name, counter);
            }

            if (UltimaItemGenerator.IsStackable(cliloc))
            {
                amount = Math.Max(amount, 1);
            }
            else
            {
                amount = 1;
            }

            counter.Gotcha(hue, amount);
            _Counter.Gotcha(1);
        }
예제 #6
0
        /// <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");
            }
        }
예제 #7
0
        /// <summary>
        /// Analyzes item.
        /// </summary>
        /// <param name="serial">Item serial.</param>
        /// <param name="itemID">Item ID.</param>
        /// <param name="hue">Item hue.</param>
        /// <param name="amount">Item amount.</param>
        /// <param name="properties">Item properties.</param>
        public void AnalyzeItem( uint serial, int itemID, int hue, int amount, QueryPropertiesResponsePacket properties )
        {
            // Get item cliloc
            int cliloc = 0;
            string name = null;

            if ( properties != null && properties.Properties.Count > 0 )
            {
                // Get name from name property
                QueryPropertiesProperty nameProperty = properties.Properties[ 0 ];

                if ( UltimaItemGenerator.IsStackable( nameProperty.Cliloc ) )
                {
                    // Get name from stackable cliloc
                    UltimaClilocArgumentParser nameArguments = new UltimaClilocArgumentParser( nameProperty.Arguments );
                    int nameCliloc = nameArguments.GetCliloc( 1 );

                    if ( nameCliloc > 0 )
                        cliloc = nameCliloc;
                    else
                        name = nameArguments[1 ];
                }
                else
                {
                    // Get name from name cliloc
                    if ( !UltimaItemGenerator.IsString( nameProperty.Cliloc ) )
                        cliloc = nameProperty.Cliloc;
                    else
                        name = nameProperty.Arguments;
                }
            }
            else
            {
                // Get name from item ID
                cliloc = UltimaItemGenerator.GetClilocFromItemID( itemID );
            }

            // Count
            UltimaItemCounter counter = null;
            UltimaStringCollection clilocs = Globals.Instance.Clilocs;

            if ( name == null )
            {
                if ( clilocs != null )
                    name = clilocs.GetString( cliloc );

                if ( String.IsNullOrEmpty( name ) )
                    name = cliloc.ToString();
            }

            if ( !_Items.TryGetValue( name, out counter ) )
            {
                counter = new UltimaItemCounter( serial, name );
                _Items.Add( name, counter );
            }

            if ( UltimaItemGenerator.IsStackable( cliloc ) )
                amount = Math.Max( amount, 1 );
            else
                amount = 1;

            counter.Gotcha( hue, amount );
            _Counter.Gotcha( 1 );
        }
예제 #8
0
        /// <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" );
            }
        }